105b261ecSmrg/*
205b261ecSmrg
305b261ecSmrgCopyright 1988, 1998  The Open Group
405b261ecSmrg
505b261ecSmrgPermission to use, copy, modify, distribute, and sell this software and its
605b261ecSmrgdocumentation for any purpose is hereby granted without fee, provided that
705b261ecSmrgthe above copyright notice appear in all copies and that both that
805b261ecSmrgcopyright notice and this permission notice appear in supporting
905b261ecSmrgdocumentation.
1005b261ecSmrg
1105b261ecSmrgThe above copyright notice and this permission notice shall be included
1205b261ecSmrgin all copies or substantial portions of the Software.
1305b261ecSmrg
1405b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1505b261ecSmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1605b261ecSmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
1705b261ecSmrgIN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
1805b261ecSmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
1905b261ecSmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2005b261ecSmrgOTHER DEALINGS IN THE SOFTWARE.
2105b261ecSmrg
2205b261ecSmrgExcept as contained in this notice, the name of The Open Group shall
2305b261ecSmrgnot be used in advertising or otherwise to promote the sale, use or
2405b261ecSmrgother dealings in this Software without prior written authorization
2505b261ecSmrgfrom The Open Group.
2605b261ecSmrg
2705b261ecSmrg*/
2805b261ecSmrg
2905b261ecSmrg/*
3005b261ecSmrg * MIT-MAGIC-COOKIE-1 authorization scheme
3105b261ecSmrg * Author:  Keith Packard, MIT X Consortium
3205b261ecSmrg */
3305b261ecSmrg
3405b261ecSmrg#ifdef HAVE_DIX_CONFIG_H
3505b261ecSmrg#include <dix-config.h>
3605b261ecSmrg#endif
3705b261ecSmrg
3805b261ecSmrg#include <X11/X.h>
3905b261ecSmrg#include "os.h"
4005b261ecSmrg#include "osdep.h"
4105b261ecSmrg#include "dixstruct.h"
4205b261ecSmrg
4305b261ecSmrgstatic struct auth {
4435c4bbdfSmrg    struct auth *next;
4535c4bbdfSmrg    unsigned short len;
4635c4bbdfSmrg    char *data;
4735c4bbdfSmrg    XID id;
4805b261ecSmrg} *mit_auth;
4905b261ecSmrg
5005b261ecSmrgint
5135c4bbdfSmrgMitAddCookie(unsigned short data_length, const char *data, XID id)
5205b261ecSmrg{
5335c4bbdfSmrg    struct auth *new;
5405b261ecSmrg
5535c4bbdfSmrg    new = malloc(sizeof(struct auth));
5605b261ecSmrg    if (!new)
5735c4bbdfSmrg        return 0;
586747b715Smrg    new->data = malloc((unsigned) data_length);
5905b261ecSmrg    if (!new->data) {
6035c4bbdfSmrg        free(new);
6135c4bbdfSmrg        return 0;
6205b261ecSmrg    }
6305b261ecSmrg    new->next = mit_auth;
6405b261ecSmrg    mit_auth = new;
6505b261ecSmrg    memmove(new->data, data, (int) data_length);
6605b261ecSmrg    new->len = data_length;
6705b261ecSmrg    new->id = id;
6805b261ecSmrg    return 1;
6905b261ecSmrg}
7005b261ecSmrg
7105b261ecSmrgXID
7235c4bbdfSmrgMitCheckCookie(unsigned short data_length,
7335c4bbdfSmrg               const char *data, ClientPtr client, const char **reason)
7405b261ecSmrg{
7535c4bbdfSmrg    struct auth *auth;
7605b261ecSmrg
7735c4bbdfSmrg    for (auth = mit_auth; auth; auth = auth->next) {
7805b261ecSmrg        if (data_length == auth->len &&
798199d687Smrg            timingsafe_memcmp(data, auth->data, (int) data_length) == 0)
8035c4bbdfSmrg            return auth->id;
8105b261ecSmrg    }
8205b261ecSmrg    *reason = "Invalid MIT-MAGIC-COOKIE-1 key";
8305b261ecSmrg    return (XID) -1;
8405b261ecSmrg}
8505b261ecSmrg
8605b261ecSmrgint
8735c4bbdfSmrgMitResetCookie(void)
8805b261ecSmrg{
8935c4bbdfSmrg    struct auth *auth, *next;
9005b261ecSmrg
9135c4bbdfSmrg    for (auth = mit_auth; auth; auth = next) {
9235c4bbdfSmrg        next = auth->next;
9335c4bbdfSmrg        free(auth->data);
9435c4bbdfSmrg        free(auth);
9505b261ecSmrg    }
9605b261ecSmrg    mit_auth = 0;
9705b261ecSmrg    return 0;
9805b261ecSmrg}
9905b261ecSmrg
10005b261ecSmrgint
10135c4bbdfSmrgMitFromID(XID id, unsigned short *data_lenp, char **datap)
10205b261ecSmrg{
10335c4bbdfSmrg    struct auth *auth;
10435c4bbdfSmrg
10535c4bbdfSmrg    for (auth = mit_auth; auth; auth = auth->next) {
10635c4bbdfSmrg        if (id == auth->id) {
10735c4bbdfSmrg            *data_lenp = auth->len;
10835c4bbdfSmrg            *datap = auth->data;
10935c4bbdfSmrg            return 1;
11035c4bbdfSmrg        }
11105b261ecSmrg    }
11205b261ecSmrg    return 0;
11305b261ecSmrg}
11405b261ecSmrg
11505b261ecSmrgint
11635c4bbdfSmrgMitRemoveCookie(unsigned short data_length, const char *data)
11705b261ecSmrg{
11835c4bbdfSmrg    struct auth *auth, *prev;
11905b261ecSmrg
12005b261ecSmrg    prev = 0;
12135c4bbdfSmrg    for (auth = mit_auth; auth; prev = auth, auth = auth->next) {
12235c4bbdfSmrg        if (data_length == auth->len &&
12335c4bbdfSmrg            memcmp(data, auth->data, data_length) == 0) {
12435c4bbdfSmrg            if (prev)
12535c4bbdfSmrg                prev->next = auth->next;
12635c4bbdfSmrg            else
12735c4bbdfSmrg                mit_auth = auth->next;
12835c4bbdfSmrg            free(auth->data);
12935c4bbdfSmrg            free(auth);
13035c4bbdfSmrg            return 1;
13135c4bbdfSmrg        }
13205b261ecSmrg    }
13305b261ecSmrg    return 0;
13405b261ecSmrg}
13505b261ecSmrg
13635c4bbdfSmrgstatic char cookie[16];         /* 128 bits */
13705b261ecSmrg
13805b261ecSmrgXID
13935c4bbdfSmrgMitGenerateCookie(unsigned data_length,
14035c4bbdfSmrg                  const char *data,
14135c4bbdfSmrg                  XID id, unsigned *data_length_return, char **data_return)
14205b261ecSmrg{
14305b261ecSmrg    int i = 0;
14405b261ecSmrg    int status;
14505b261ecSmrg
14635c4bbdfSmrg    while (data_length--) {
14735c4bbdfSmrg        cookie[i++] += *data++;
14835c4bbdfSmrg        if (i >= sizeof(cookie))
14935c4bbdfSmrg            i = 0;
15005b261ecSmrg    }
15135c4bbdfSmrg    GenerateRandomData(sizeof(cookie), cookie);
15235c4bbdfSmrg    status = MitAddCookie(sizeof(cookie), cookie, id);
15335c4bbdfSmrg    if (!status) {
15435c4bbdfSmrg        id = -1;
15505b261ecSmrg    }
15635c4bbdfSmrg    else {
15735c4bbdfSmrg        *data_return = cookie;
15835c4bbdfSmrg        *data_length_return = sizeof(cookie);
15905b261ecSmrg    }
16005b261ecSmrg    return id;
16105b261ecSmrg}
162