1 /* $XConsortium: xdmauth.c,v 1.14 95/07/10 21:18:07 gildea Exp $ */
4 Copyright (c) 1988 X Consortium
6 Permission is hereby granted, free of charge, to any person obtaining
7 a copy of this software and associated documentation files (the
8 "Software"), to deal in the Software without restriction, including
9 without limitation the rights to use, copy, modify, merge, publish,
10 distribute, sublicense, and/or sell copies of the Software, and to
11 permit persons to whom the Software is furnished to do so, subject to
12 the following conditions:
14 The above copyright notice and this permission notice shall be included
15 in all copies or substantial portions of the Software.
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 OTHER DEALINGS IN THE SOFTWARE.
25 Except as contained in this notice, the name of the X Consortium shall
26 not be used in advertising or otherwise to promote the sale, use or
27 other dealings in this Software without prior written authorization
28 from the X Consortium.
33 * XDM-AUTHENTICATION-1 (XDMCP authentication) and
34 * XDM-AUTHORIZATION-1 (client authorization) protocols
36 * Author: Keith Packard, MIT X Consortium
43 #include "dixstruct.h"
47 static Bool authFromXDMCP;
54 /* XDM-AUTHENTICATION-1 */
56 static XdmAuthKeyRec privateKey;
57 static char XdmAuthenticationName[] = "XDM-AUTHENTICATION-1";
58 #define XdmAuthenticationNameLen (sizeof XdmAuthenticationName - 1)
59 static XdmAuthKeyRec rho;
61 static Bool XdmAuthenticationValidator (privateData, incomingData, packet_type)
62 ARRAY8Ptr privateData, incomingData;
63 xdmOpCode packet_type;
65 XdmAuthKeyPtr incoming;
67 XdmcpUnwrap (incomingData->data, &privateKey,
68 incomingData->data,incomingData->length);
72 if (incomingData->length != 8)
74 incoming = (XdmAuthKeyPtr) incomingData->data;
75 XdmcpDecrementKey (incoming);
76 return XdmcpCompareKeys (incoming, &rho);
82 XdmAuthenticationGenerator (privateData, outgoingData, packet_type)
83 ARRAY8Ptr privateData, outgoingData;
84 xdmOpCode packet_type;
86 outgoingData->length = 0;
87 outgoingData->data = 0;
91 if (XdmcpAllocARRAY8 (outgoingData, 8))
92 XdmcpWrap (&rho, &privateKey, outgoingData->data, 8);
98 XdmAuthenticationAddAuth (name_len, name, data_len, data)
99 int name_len, data_len;
103 XdmcpUnwrap (data, &privateKey, data, data_len);
104 authFromXDMCP = TRUE;
105 ret = AddAuthorization (name_len, name, data_len, data);
106 authFromXDMCP = FALSE;
111 #define atox(c) ('0' <= c && c <= '9' ? c - '0' : \
112 'a' <= c && c <= 'f' ? c - 'a' + 10 : \
113 'A' <= c && c <= 'F' ? c - 'A' + 10 : -1)
116 HexToBinary (in, out, len)
127 bottom = atox(in[1]);
130 *out++ = (top << 4) | bottom;
141 XdmAuthenticationInit (cookie, cookie_len)
145 bzero (privateKey.data, 8);
146 if (!strncmp (cookie, "0x", 2) || !strncmp (cookie, "0X", 2))
148 if (cookie_len > 2 + 2 * 8)
149 cookie_len = 2 + 2 * 8;
150 HexToBinary (cookie + 2, (char *)privateKey.data, cookie_len - 2);
156 memmove (privateKey.data + 1, cookie, cookie_len);
158 XdmcpGenerateKey (&rho);
159 XdmcpRegisterAuthentication (XdmAuthenticationName, XdmAuthenticationNameLen,
162 XdmAuthenticationValidator,
163 XdmAuthenticationGenerator,
164 XdmAuthenticationAddAuth);
169 /* XDM-AUTHORIZATION-1 */
170 typedef struct _XdmAuthorization {
171 struct _XdmAuthorization *next;
175 } XdmAuthorizationRec, *XdmAuthorizationPtr;
177 static XdmAuthorizationPtr xdmAuth;
179 typedef struct _XdmClientAuth {
180 struct _XdmClientAuth *next;
184 } XdmClientAuthRec, *XdmClientAuthPtr;
186 static XdmClientAuthPtr xdmClients;
187 static long clockOffset;
188 static Bool gotClock;
190 #define TwentyMinutes (20 * 60)
191 #define TwentyFiveMinutes (25 * 60)
194 XdmClientAuthCompare (a, b)
195 XdmClientAuthPtr a, b;
199 if (!XdmcpCompareKeys (&a->rho, &b->rho))
201 for (i = 0; i < 6; i++)
202 if (a->client[i] != b->client[i])
204 return a->time == b->time;
208 XdmClientAuthDecode (plain, auth)
209 unsigned char *plain;
210 XdmClientAuthPtr auth;
215 for (i = 0; i < 8; i++)
217 auth->rho.data[i] = plain[j];
220 for (i = 0; i < 6; i++)
222 auth->client[i] = plain[j];
226 for (i = 0; i < 4; i++)
228 auth->time |= plain[j] << ((3 - i) << 3);
234 XdmClientAuthTimeout (now)
237 XdmClientAuthPtr client, next, prev;
240 for (client = xdmClients; client; client=next)
243 if (abs (now - client->time) > TwentyFiveMinutes)
256 static XdmClientAuthPtr
257 XdmAuthorizationValidate (plain, length, rho, xclient, reason)
258 unsigned char *plain;
264 XdmClientAuthPtr client, existing;
268 if (length != (192 / 8)) {
270 *reason = "Bad XDM authorization key length";
273 client = (XdmClientAuthPtr) xalloc (sizeof (XdmClientAuthRec));
276 XdmClientAuthDecode (plain, client);
277 if (!XdmcpCompareKeys (&client->rho, rho))
281 *reason = "Invalid XDM-AUTHORIZATION-1 key value";
284 for (i = 18; i < 24; i++)
288 *reason = "Invalid XDM-AUTHORIZATION-1 key value";
292 int family, addr_len;
295 if (_XSERVTransGetPeerAddr(((OsCommPtr)xclient->osPrivate)->trans_conn,
296 &family, &addr_len, &addr) == 0
297 && _XSERVTransConvertAddress(&family, &addr_len, &addr) == 0) {
299 if (family == FamilyInternet &&
300 memcmp((char *)addr, client->client, 4) != 0) {
304 *reason = "Invalid XDM-AUTHORIZATION-1 key value";
315 clockOffset = client->time - now;
319 XdmClientAuthTimeout (now);
320 if (abs (client->time - now) > TwentyMinutes)
324 *reason = "Excessive XDM-AUTHORIZATION-1 time offset";
327 for (existing = xdmClients; existing; existing=existing->next)
329 if (XdmClientAuthCompare (existing, client))
333 *reason = "XDM authorization key matches an existing client!";
341 XdmAddCookie (data_length, data, id)
342 unsigned short data_length;
346 XdmAuthorizationPtr new;
347 unsigned char *rho_bits, *key_bits;
351 case 16: /* auth from files is 16 bytes long */
354 /* R5 xdm sent bogus authorization data in the accept packet,
355 * but we can recover */
357 key_bits = (unsigned char *) data;
362 rho_bits = (unsigned char *) data;
363 key_bits = (unsigned char *) (data + 8);
366 case 8: /* auth from XDMCP is 8 bytes long */
368 key_bits = (unsigned char *) data;
373 /* the first octet of the key must be zero */
374 if (key_bits[0] != '\0')
376 new = (XdmAuthorizationPtr) xalloc (sizeof (XdmAuthorizationRec));
381 memmove (new->key.data, key_bits, (int) 8);
382 memmove (new->rho.data, rho_bits, (int) 8);
388 XdmCheckCookie (cookie_length, cookie, xclient, reason)
389 unsigned short cookie_length;
394 XdmAuthorizationPtr auth;
395 XdmClientAuthPtr client;
396 unsigned char *plain;
398 /* Auth packets must be a multiple of 8 bytes long */
399 if (cookie_length & 7)
401 plain = (unsigned char *) xalloc (cookie_length);
404 for (auth = xdmAuth; auth; auth=auth->next) {
405 XdmcpUnwrap (cookie, &auth->key, plain, cookie_length);
406 if (client = XdmAuthorizationValidate (plain, cookie_length, &auth->rho, xclient, reason))
408 client->next = xdmClients;
421 XdmAuthorizationPtr auth, next_auth;
422 XdmClientAuthPtr client, next_client;
424 for (auth = xdmAuth; auth; auth=next_auth)
426 next_auth = auth->next;
430 for (client = xdmClients; client; client=next_client)
432 next_client = client->next;
435 xdmClients = (XdmClientAuthPtr) 0;
440 XdmToID (cookie_length, cookie)
441 unsigned short cookie_length;
444 XdmAuthorizationPtr auth;
445 XdmClientAuthPtr client;
446 unsigned char *plain;
448 plain = (unsigned char *) xalloc (cookie_length);
451 for (auth = xdmAuth; auth; auth=auth->next) {
452 XdmcpUnwrap (cookie, &auth->key, plain, cookie_length);
453 if (client = XdmAuthorizationValidate (plain, cookie_length, &auth->rho, NULL, NULL))
465 XdmFromID (id, data_lenp, datap)
467 unsigned short *data_lenp;
470 XdmAuthorizationPtr auth;
472 for (auth = xdmAuth; auth; auth=auth->next) {
473 if (id == auth->id) {
475 *datap = (char *) &auth->rho;
483 XdmRemoveCookie (data_length, data)
484 unsigned short data_length;
487 XdmAuthorizationPtr auth, prev;
488 XdmAuthKeyPtr key_bits, rho_bits;
494 rho_bits = (XdmAuthKeyPtr) data;
495 key_bits = (XdmAuthKeyPtr) (data + 8);
499 key_bits = (XdmAuthKeyPtr) data;
504 for (auth = xdmAuth; auth; auth=auth->next) {
505 if (XdmcpCompareKeys (rho_bits, &auth->rho) &&
506 XdmcpCompareKeys (key_bits, &auth->key))
509 prev->next = auth->next;
511 xdmAuth = auth->next;