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 = ρ 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