xdmauth.c revision 05b261ec
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 * XDM-AUTHENTICATION-1 (XDMCP authentication) and
3105b261ecSmrg * XDM-AUTHORIZATION-1 (client authorization) protocols
3205b261ecSmrg *
3305b261ecSmrg * Author:  Keith Packard, MIT X Consortium
3405b261ecSmrg */
3505b261ecSmrg
3605b261ecSmrg#ifdef HAVE_DIX_CONFIG_H
3705b261ecSmrg#include <dix-config.h>
3805b261ecSmrg#endif
3905b261ecSmrg
4005b261ecSmrg#include <stdio.h>
4105b261ecSmrg#include <X11/X.h>
4205b261ecSmrg#define XSERV_t
4305b261ecSmrg#define TRANS_SERVER
4405b261ecSmrg#define TRANS_REOPEN
4505b261ecSmrg#include <X11/Xtrans/Xtrans.h>
4605b261ecSmrg#include "os.h"
4705b261ecSmrg#include "osdep.h"
4805b261ecSmrg#include "dixstruct.h"
4905b261ecSmrg
5005b261ecSmrg#ifdef HASXDMAUTH
5105b261ecSmrg
5205b261ecSmrgstatic Bool authFromXDMCP;
5305b261ecSmrg
5405b261ecSmrg#ifdef XDMCP
5505b261ecSmrg#include <X11/Xmd.h>
5605b261ecSmrg#undef REQUEST
5705b261ecSmrg#include <X11/Xdmcp.h>
5805b261ecSmrg
5905b261ecSmrg/* XDM-AUTHENTICATION-1 */
6005b261ecSmrg
6105b261ecSmrgstatic XdmAuthKeyRec	privateKey;
6205b261ecSmrgstatic char XdmAuthenticationName[] = "XDM-AUTHENTICATION-1";
6305b261ecSmrg#define XdmAuthenticationNameLen (sizeof XdmAuthenticationName - 1)
6405b261ecSmrgstatic XdmAuthKeyRec	rho;
6505b261ecSmrg
6605b261ecSmrgstatic Bool
6705b261ecSmrgXdmAuthenticationValidator (ARRAY8Ptr privateData, ARRAY8Ptr incomingData,
6805b261ecSmrg    xdmOpCode packet_type)
6905b261ecSmrg{
7005b261ecSmrg    XdmAuthKeyPtr	incoming;
7105b261ecSmrg
7205b261ecSmrg    XdmcpUnwrap (incomingData->data, &privateKey,
7305b261ecSmrg			      incomingData->data,incomingData->length);
7405b261ecSmrg    if (packet_type == ACCEPT) {
7505b261ecSmrg    	if (incomingData->length != 8)
7605b261ecSmrg	    return FALSE;
7705b261ecSmrg    	incoming = (XdmAuthKeyPtr) incomingData->data;
7805b261ecSmrg    	XdmcpDecrementKey (incoming);
7905b261ecSmrg    	return XdmcpCompareKeys (incoming, &rho);
8005b261ecSmrg    }
8105b261ecSmrg    return FALSE;
8205b261ecSmrg}
8305b261ecSmrg
8405b261ecSmrgstatic Bool
8505b261ecSmrgXdmAuthenticationGenerator (ARRAY8Ptr privateData, ARRAY8Ptr outgoingData,
8605b261ecSmrg    xdmOpCode packet_type)
8705b261ecSmrg{
8805b261ecSmrg    outgoingData->length = 0;
8905b261ecSmrg    outgoingData->data = 0;
9005b261ecSmrg    if (packet_type == REQUEST) {
9105b261ecSmrg	if (XdmcpAllocARRAY8 (outgoingData, 8))
9205b261ecSmrg	    XdmcpWrap (&rho, &privateKey, outgoingData->data, 8);
9305b261ecSmrg    }
9405b261ecSmrg    return TRUE;
9505b261ecSmrg}
9605b261ecSmrg
9705b261ecSmrgstatic Bool
9805b261ecSmrgXdmAuthenticationAddAuth (int name_len, char *name,
9905b261ecSmrg    int data_len, char *data)
10005b261ecSmrg{
10105b261ecSmrg    Bool    ret;
10205b261ecSmrg    XdmcpUnwrap (data, (unsigned char *)&privateKey, data, data_len);
10305b261ecSmrg    authFromXDMCP = TRUE;
10405b261ecSmrg    ret = AddAuthorization (name_len, name, data_len, data);
10505b261ecSmrg    authFromXDMCP = FALSE;
10605b261ecSmrg    return ret;
10705b261ecSmrg}
10805b261ecSmrg
10905b261ecSmrg
11005b261ecSmrg#define atox(c)	('0' <= c && c <= '9' ? c - '0' : \
11105b261ecSmrg		 'a' <= c && c <= 'f' ? c - 'a' + 10 : \
11205b261ecSmrg		 'A' <= c && c <= 'F' ? c - 'A' + 10 : -1)
11305b261ecSmrg
11405b261ecSmrgstatic int
11505b261ecSmrgHexToBinary (char *in, char *out, int len)
11605b261ecSmrg{
11705b261ecSmrg    int	    top, bottom;
11805b261ecSmrg
11905b261ecSmrg    while (len > 0)
12005b261ecSmrg    {
12105b261ecSmrg	top = atox(in[0]);
12205b261ecSmrg	if (top == -1)
12305b261ecSmrg	    return 0;
12405b261ecSmrg	bottom = atox(in[1]);
12505b261ecSmrg	if (bottom == -1)
12605b261ecSmrg	    return 0;
12705b261ecSmrg	*out++ = (top << 4) | bottom;
12805b261ecSmrg	in += 2;
12905b261ecSmrg	len -= 2;
13005b261ecSmrg    }
13105b261ecSmrg    if (len)
13205b261ecSmrg	return 0;
13305b261ecSmrg    *out++ = '\0';
13405b261ecSmrg    return 1;
13505b261ecSmrg}
13605b261ecSmrg
13705b261ecSmrgvoid
13805b261ecSmrgXdmAuthenticationInit (char *cookie, int cookie_len)
13905b261ecSmrg{
14005b261ecSmrg    bzero (privateKey.data, 8);
14105b261ecSmrg    if (!strncmp (cookie, "0x", 2) || !strncmp (cookie, "0X", 2))
14205b261ecSmrg    {
14305b261ecSmrg	if (cookie_len > 2 + 2 * 8)
14405b261ecSmrg	    cookie_len = 2 + 2 * 8;
14505b261ecSmrg	HexToBinary (cookie + 2, (char *)privateKey.data, cookie_len - 2);
14605b261ecSmrg    }
14705b261ecSmrg    else
14805b261ecSmrg    {
14905b261ecSmrg    	if (cookie_len > 7)
15005b261ecSmrg	    cookie_len = 7;
15105b261ecSmrg    	memmove (privateKey.data + 1, cookie, cookie_len);
15205b261ecSmrg    }
15305b261ecSmrg    XdmcpGenerateKey (&rho);
15405b261ecSmrg    XdmcpRegisterAuthentication (XdmAuthenticationName, XdmAuthenticationNameLen,
15505b261ecSmrg				 (unsigned char *)&rho,
15605b261ecSmrg				 sizeof (rho),
15705b261ecSmrg				 (ValidatorFunc)XdmAuthenticationValidator,
15805b261ecSmrg				 (GeneratorFunc)XdmAuthenticationGenerator,
15905b261ecSmrg				 (AddAuthorFunc)XdmAuthenticationAddAuth);
16005b261ecSmrg}
16105b261ecSmrg
16205b261ecSmrg#endif /* XDMCP */
16305b261ecSmrg
16405b261ecSmrg/* XDM-AUTHORIZATION-1 */
16505b261ecSmrgtypedef struct _XdmAuthorization {
16605b261ecSmrg    struct _XdmAuthorization	*next;
16705b261ecSmrg    XdmAuthKeyRec		rho;
16805b261ecSmrg    XdmAuthKeyRec		key;
16905b261ecSmrg    XID				id;
17005b261ecSmrg} XdmAuthorizationRec, *XdmAuthorizationPtr;
17105b261ecSmrg
17205b261ecSmrgstatic XdmAuthorizationPtr xdmAuth;
17305b261ecSmrg
17405b261ecSmrgtypedef struct _XdmClientAuth {
17505b261ecSmrg    struct _XdmClientAuth   *next;
17605b261ecSmrg    XdmAuthKeyRec	    rho;
17705b261ecSmrg    char		    client[6];
17805b261ecSmrg    long		    time;
17905b261ecSmrg} XdmClientAuthRec, *XdmClientAuthPtr;
18005b261ecSmrg
18105b261ecSmrgstatic XdmClientAuthPtr    xdmClients;
18205b261ecSmrgstatic long	    clockOffset;
18305b261ecSmrgstatic Bool	    gotClock;
18405b261ecSmrg
18505b261ecSmrg#define TwentyMinutes	(20 * 60)
18605b261ecSmrg#define TwentyFiveMinutes (25 * 60)
18705b261ecSmrg
18805b261ecSmrgstatic Bool
18905b261ecSmrgXdmClientAuthCompare (XdmClientAuthPtr a, XdmClientAuthPtr b)
19005b261ecSmrg{
19105b261ecSmrg    int	i;
19205b261ecSmrg
19305b261ecSmrg    if (!XdmcpCompareKeys (&a->rho, &b->rho))
19405b261ecSmrg	return FALSE;
19505b261ecSmrg    for (i = 0; i < 6; i++)
19605b261ecSmrg	if (a->client[i] != b->client[i])
19705b261ecSmrg	    return FALSE;
19805b261ecSmrg    return a->time == b->time;
19905b261ecSmrg}
20005b261ecSmrg
20105b261ecSmrgstatic void
20205b261ecSmrgXdmClientAuthDecode (unsigned char *plain, XdmClientAuthPtr auth)
20305b261ecSmrg{
20405b261ecSmrg    int	    i, j;
20505b261ecSmrg
20605b261ecSmrg    j = 0;
20705b261ecSmrg    for (i = 0; i < 8; i++)
20805b261ecSmrg    {
20905b261ecSmrg	auth->rho.data[i] = plain[j];
21005b261ecSmrg	++j;
21105b261ecSmrg    }
21205b261ecSmrg    for (i = 0; i < 6; i++)
21305b261ecSmrg    {
21405b261ecSmrg	auth->client[i] = plain[j];
21505b261ecSmrg	++j;
21605b261ecSmrg    }
21705b261ecSmrg    auth->time = 0;
21805b261ecSmrg    for (i = 0; i < 4; i++)
21905b261ecSmrg    {
22005b261ecSmrg	auth->time |= plain[j] << ((3 - i) << 3);
22105b261ecSmrg	j++;
22205b261ecSmrg    }
22305b261ecSmrg}
22405b261ecSmrg
22505b261ecSmrgstatic void
22605b261ecSmrgXdmClientAuthTimeout (long now)
22705b261ecSmrg{
22805b261ecSmrg    XdmClientAuthPtr	client, next, prev;
22905b261ecSmrg
23005b261ecSmrg    prev = 0;
23105b261ecSmrg    for (client = xdmClients; client; client=next)
23205b261ecSmrg    {
23305b261ecSmrg	next = client->next;
23405b261ecSmrg	if (abs (now - client->time) > TwentyFiveMinutes)
23505b261ecSmrg	{
23605b261ecSmrg	    if (prev)
23705b261ecSmrg		prev->next = next;
23805b261ecSmrg	    else
23905b261ecSmrg		xdmClients = next;
24005b261ecSmrg	    xfree (client);
24105b261ecSmrg	}
24205b261ecSmrg	else
24305b261ecSmrg	    prev = client;
24405b261ecSmrg    }
24505b261ecSmrg}
24605b261ecSmrg
24705b261ecSmrgstatic XdmClientAuthPtr
24805b261ecSmrgXdmAuthorizationValidate (unsigned char *plain, int length,
24905b261ecSmrg    XdmAuthKeyPtr rho, ClientPtr xclient, char **reason)
25005b261ecSmrg{
25105b261ecSmrg    XdmClientAuthPtr	client, existing;
25205b261ecSmrg    long		now;
25305b261ecSmrg    int			i;
25405b261ecSmrg
25505b261ecSmrg    if (length != (192 / 8)) {
25605b261ecSmrg	if (reason)
25705b261ecSmrg	    *reason = "Bad XDM authorization key length";
25805b261ecSmrg	return NULL;
25905b261ecSmrg    }
26005b261ecSmrg    client = (XdmClientAuthPtr) xalloc (sizeof (XdmClientAuthRec));
26105b261ecSmrg    if (!client)
26205b261ecSmrg	return NULL;
26305b261ecSmrg    XdmClientAuthDecode (plain, client);
26405b261ecSmrg    if (!XdmcpCompareKeys (&client->rho, rho))
26505b261ecSmrg    {
26605b261ecSmrg	xfree (client);
26705b261ecSmrg	if (reason)
26805b261ecSmrg	    *reason = "Invalid XDM-AUTHORIZATION-1 key (failed key comparison)";
26905b261ecSmrg	return NULL;
27005b261ecSmrg    }
27105b261ecSmrg    for (i = 18; i < 24; i++)
27205b261ecSmrg	if (plain[i] != 0) {
27305b261ecSmrg	    xfree (client);
27405b261ecSmrg	    if (reason)
27505b261ecSmrg		*reason = "Invalid XDM-AUTHORIZATION-1 key (failed NULL check)";
27605b261ecSmrg	    return NULL;
27705b261ecSmrg	}
27805b261ecSmrg    if (xclient) {
27905b261ecSmrg	int family, addr_len;
28005b261ecSmrg	Xtransaddr *addr;
28105b261ecSmrg
28205b261ecSmrg	if (_XSERVTransGetPeerAddr(((OsCommPtr)xclient->osPrivate)->trans_conn,
28305b261ecSmrg				   &family, &addr_len, &addr) == 0
28405b261ecSmrg	    && _XSERVTransConvertAddress(&family, &addr_len, &addr) == 0) {
28505b261ecSmrg#if defined(TCPCONN) || defined(STREAMSCONN)
28605b261ecSmrg	    if (family == FamilyInternet &&
28705b261ecSmrg		memcmp((char *)addr, client->client, 4) != 0) {
28805b261ecSmrg		xfree (client);
28905b261ecSmrg		xfree (addr);
29005b261ecSmrg		if (reason)
29105b261ecSmrg		    *reason = "Invalid XDM-AUTHORIZATION-1 key (failed address comparison)";
29205b261ecSmrg		return NULL;
29305b261ecSmrg
29405b261ecSmrg	    }
29505b261ecSmrg#endif
29605b261ecSmrg	    xfree (addr);
29705b261ecSmrg	}
29805b261ecSmrg    }
29905b261ecSmrg    now = time(0);
30005b261ecSmrg    if (!gotClock)
30105b261ecSmrg    {
30205b261ecSmrg	clockOffset = client->time - now;
30305b261ecSmrg	gotClock = TRUE;
30405b261ecSmrg    }
30505b261ecSmrg    now += clockOffset;
30605b261ecSmrg    XdmClientAuthTimeout (now);
30705b261ecSmrg    if (abs (client->time - now) > TwentyMinutes)
30805b261ecSmrg    {
30905b261ecSmrg	xfree (client);
31005b261ecSmrg	if (reason)
31105b261ecSmrg	    *reason = "Excessive XDM-AUTHORIZATION-1 time offset";
31205b261ecSmrg	return NULL;
31305b261ecSmrg    }
31405b261ecSmrg    for (existing = xdmClients; existing; existing=existing->next)
31505b261ecSmrg    {
31605b261ecSmrg	if (XdmClientAuthCompare (existing, client))
31705b261ecSmrg	{
31805b261ecSmrg	    xfree (client);
31905b261ecSmrg	    if (reason)
32005b261ecSmrg		*reason = "XDM authorization key matches an existing client!";
32105b261ecSmrg	    return NULL;
32205b261ecSmrg	}
32305b261ecSmrg    }
32405b261ecSmrg    return client;
32505b261ecSmrg}
32605b261ecSmrg
32705b261ecSmrgint
32805b261ecSmrgXdmAddCookie (unsigned short data_length, char *data, XID id)
32905b261ecSmrg{
33005b261ecSmrg    XdmAuthorizationPtr	new;
33105b261ecSmrg    unsigned char	*rho_bits, *key_bits;
33205b261ecSmrg
33305b261ecSmrg    switch (data_length)
33405b261ecSmrg    {
33505b261ecSmrg    case 16:		    /* auth from files is 16 bytes long */
33605b261ecSmrg#ifdef XDMCP
33705b261ecSmrg	if (authFromXDMCP)
33805b261ecSmrg	{
33905b261ecSmrg	    /* R5 xdm sent bogus authorization data in the accept packet,
34005b261ecSmrg	     * but we can recover */
34105b261ecSmrg	    rho_bits = rho.data;
34205b261ecSmrg	    key_bits = (unsigned char *) data;
34305b261ecSmrg	    key_bits[0] = '\0';
34405b261ecSmrg	}
34505b261ecSmrg	else
34605b261ecSmrg#endif
34705b261ecSmrg	{
34805b261ecSmrg	    rho_bits = (unsigned char *) data;
34905b261ecSmrg	    key_bits = (unsigned char *) (data + 8);
35005b261ecSmrg	}
35105b261ecSmrg	break;
35205b261ecSmrg#ifdef XDMCP
35305b261ecSmrg    case 8:		    /* auth from XDMCP is 8 bytes long */
35405b261ecSmrg	rho_bits = rho.data;
35505b261ecSmrg	key_bits = (unsigned char *) data;
35605b261ecSmrg	break;
35705b261ecSmrg#endif
35805b261ecSmrg    default:
35905b261ecSmrg	return 0;
36005b261ecSmrg    }
36105b261ecSmrg    /* the first octet of the key must be zero */
36205b261ecSmrg    if (key_bits[0] != '\0')
36305b261ecSmrg	return 0;
36405b261ecSmrg    new = (XdmAuthorizationPtr) xalloc (sizeof (XdmAuthorizationRec));
36505b261ecSmrg    if (!new)
36605b261ecSmrg	return 0;
36705b261ecSmrg    new->next = xdmAuth;
36805b261ecSmrg    xdmAuth = new;
36905b261ecSmrg    memmove (new->key.data, key_bits, (int) 8);
37005b261ecSmrg    memmove (new->rho.data, rho_bits, (int) 8);
37105b261ecSmrg    new->id = id;
37205b261ecSmrg    return 1;
37305b261ecSmrg}
37405b261ecSmrg
37505b261ecSmrgXID
37605b261ecSmrgXdmCheckCookie (unsigned short cookie_length, char *cookie,
37705b261ecSmrg    ClientPtr xclient, char **reason)
37805b261ecSmrg{
37905b261ecSmrg    XdmAuthorizationPtr	auth;
38005b261ecSmrg    XdmClientAuthPtr	client;
38105b261ecSmrg    unsigned char	*plain;
38205b261ecSmrg
38305b261ecSmrg    /* Auth packets must be a multiple of 8 bytes long */
38405b261ecSmrg    if (cookie_length & 7)
38505b261ecSmrg	return (XID) -1;
38605b261ecSmrg    plain = (unsigned char *) xalloc (cookie_length);
38705b261ecSmrg    if (!plain)
38805b261ecSmrg	return (XID) -1;
38905b261ecSmrg    for (auth = xdmAuth; auth; auth=auth->next) {
39005b261ecSmrg	XdmcpUnwrap (cookie, (unsigned char *)&auth->key, plain, cookie_length);
39105b261ecSmrg	if ((client = XdmAuthorizationValidate (plain, cookie_length, &auth->rho, xclient, reason)) != NULL)
39205b261ecSmrg	{
39305b261ecSmrg	    client->next = xdmClients;
39405b261ecSmrg	    xdmClients = client;
39505b261ecSmrg	    xfree (plain);
39605b261ecSmrg	    return auth->id;
39705b261ecSmrg	}
39805b261ecSmrg    }
39905b261ecSmrg    xfree (plain);
40005b261ecSmrg    return (XID) -1;
40105b261ecSmrg}
40205b261ecSmrg
40305b261ecSmrgint
40405b261ecSmrgXdmResetCookie (void)
40505b261ecSmrg{
40605b261ecSmrg    XdmAuthorizationPtr	auth, next_auth;
40705b261ecSmrg    XdmClientAuthPtr	client, next_client;
40805b261ecSmrg
40905b261ecSmrg    for (auth = xdmAuth; auth; auth=next_auth)
41005b261ecSmrg    {
41105b261ecSmrg	next_auth = auth->next;
41205b261ecSmrg	xfree (auth);
41305b261ecSmrg    }
41405b261ecSmrg    xdmAuth = 0;
41505b261ecSmrg    for (client = xdmClients; client; client=next_client)
41605b261ecSmrg    {
41705b261ecSmrg	next_client = client->next;
41805b261ecSmrg	xfree (client);
41905b261ecSmrg    }
42005b261ecSmrg    xdmClients = (XdmClientAuthPtr) 0;
42105b261ecSmrg    return 1;
42205b261ecSmrg}
42305b261ecSmrg
42405b261ecSmrgXID
42505b261ecSmrgXdmToID (unsigned short cookie_length, char *cookie)
42605b261ecSmrg{
42705b261ecSmrg    XdmAuthorizationPtr	auth;
42805b261ecSmrg    XdmClientAuthPtr	client;
42905b261ecSmrg    unsigned char	*plain;
43005b261ecSmrg
43105b261ecSmrg    plain = (unsigned char *) xalloc (cookie_length);
43205b261ecSmrg    if (!plain)
43305b261ecSmrg	return (XID) -1;
43405b261ecSmrg    for (auth = xdmAuth; auth; auth=auth->next) {
43505b261ecSmrg	XdmcpUnwrap (cookie, (unsigned char *)&auth->key, plain, cookie_length);
43605b261ecSmrg	if ((client = XdmAuthorizationValidate (plain, cookie_length, &auth->rho, NULL, NULL)) != NULL)
43705b261ecSmrg	{
43805b261ecSmrg	    xfree (client);
43905b261ecSmrg	    xfree (cookie);
44005b261ecSmrg	    xfree (plain);
44105b261ecSmrg	    return auth->id;
44205b261ecSmrg	}
44305b261ecSmrg    }
44405b261ecSmrg    xfree (cookie);
44505b261ecSmrg    xfree (plain);
44605b261ecSmrg    return (XID) -1;
44705b261ecSmrg}
44805b261ecSmrg
44905b261ecSmrgint
45005b261ecSmrgXdmFromID (XID id, unsigned short *data_lenp, char **datap)
45105b261ecSmrg{
45205b261ecSmrg    XdmAuthorizationPtr	auth;
45305b261ecSmrg
45405b261ecSmrg    for (auth = xdmAuth; auth; auth=auth->next) {
45505b261ecSmrg	if (id == auth->id) {
45605b261ecSmrg	    *data_lenp = 16;
45705b261ecSmrg	    *datap = (char *) &auth->rho;
45805b261ecSmrg	    return 1;
45905b261ecSmrg	}
46005b261ecSmrg    }
46105b261ecSmrg    return 0;
46205b261ecSmrg}
46305b261ecSmrg
46405b261ecSmrgint
46505b261ecSmrgXdmRemoveCookie (unsigned short data_length, char *data)
46605b261ecSmrg{
46705b261ecSmrg    XdmAuthorizationPtr	auth;
46805b261ecSmrg    XdmAuthKeyPtr	key_bits, rho_bits;
46905b261ecSmrg
47005b261ecSmrg    switch (data_length)
47105b261ecSmrg    {
47205b261ecSmrg    case 16:
47305b261ecSmrg	rho_bits = (XdmAuthKeyPtr) data;
47405b261ecSmrg	key_bits = (XdmAuthKeyPtr) (data + 8);
47505b261ecSmrg	break;
47605b261ecSmrg#ifdef XDMCP
47705b261ecSmrg    case 8:
47805b261ecSmrg	rho_bits = &rho;
47905b261ecSmrg	key_bits = (XdmAuthKeyPtr) data;
48005b261ecSmrg	break;
48105b261ecSmrg#endif
48205b261ecSmrg    default:
48305b261ecSmrg	return 0;
48405b261ecSmrg    }
48505b261ecSmrg    for (auth = xdmAuth; auth; auth=auth->next) {
48605b261ecSmrg	if (XdmcpCompareKeys (rho_bits, &auth->rho) &&
48705b261ecSmrg	    XdmcpCompareKeys (key_bits, &auth->key))
48805b261ecSmrg 	{
48905b261ecSmrg	    xdmAuth = auth->next;
49005b261ecSmrg	    xfree (auth);
49105b261ecSmrg	    return 1;
49205b261ecSmrg	}
49305b261ecSmrg    }
49405b261ecSmrg    return 0;
49505b261ecSmrg}
49605b261ecSmrg
49705b261ecSmrg#endif
498