1
/* $Xorg: xdmauth.c,v 1.4 2001/02/09 02:05:24 xorgcvs Exp $ */
4
Copyright 1988, 1998 The Open Group
6
Permission to use, copy, modify, distribute, and sell this software and its
7
documentation for any purpose is hereby granted without fee, provided that
8
the above copyright notice appear in all copies and that both that
9
copyright notice and this permission notice appear in supporting
12
The above copyright notice and this permission notice shall be included
13
in all copies or substantial portions of the Software.
15
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
19
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21
OTHER DEALINGS IN THE SOFTWARE.
23
Except as contained in this notice, the name of The Open Group shall
24
not be used in advertising or otherwise to promote the sale, use or
25
other dealings in this Software without prior written authorization
29
/* $XFree86: xdmauth.c,v 1.7 2002/11/05 05:50:34 keithp Exp $ */
32
* XDM-AUTHENTICATION-1 (XDMCP authentication) and
33
* XDM-AUTHORIZATION-1 (client authorization) protocols
35
* Author: Keith Packard, MIT X Consortium
38
#ifdef HAVE_DIX_CONFIG_H
39
#include <dix-config.h>
44
#include <X11/Xtrans/Xtrans.h>
47
#include "dixstruct.h"
51
static Bool authFromXDMCP;
56
#include <X11/Xdmcp.h>
58
/* XDM-AUTHENTICATION-1 */
60
static XdmAuthKeyRec privateKey;
61
static char XdmAuthenticationName[] = "XDM-AUTHENTICATION-1";
62
#define XdmAuthenticationNameLen (sizeof XdmAuthenticationName - 1)
63
static XdmAuthKeyRec rho;
66
XdmAuthenticationValidator (ARRAY8Ptr privateData, ARRAY8Ptr incomingData,
67
xdmOpCode packet_type)
69
XdmAuthKeyPtr incoming;
71
XdmcpUnwrap (incomingData->data, &privateKey,
72
incomingData->data,incomingData->length);
76
if (incomingData->length != 8)
78
incoming = (XdmAuthKeyPtr) incomingData->data;
79
XdmcpDecrementKey (incoming);
80
return XdmcpCompareKeys (incoming, &rho);
86
XdmAuthenticationGenerator (ARRAY8Ptr privateData, ARRAY8Ptr outgoingData,
87
xdmOpCode packet_type)
89
outgoingData->length = 0;
90
outgoingData->data = 0;
94
if (XdmcpAllocARRAY8 (outgoingData, 8))
95
XdmcpWrap (&rho, &privateKey, outgoingData->data, 8);
101
XdmAuthenticationAddAuth (int name_len, char *name,
102
int data_len, char *data)
105
XdmcpUnwrap (data, (unsigned char *)&privateKey, data, data_len);
106
authFromXDMCP = TRUE;
107
ret = AddAuthorization (name_len, name, data_len, data);
108
authFromXDMCP = FALSE;
113
#define atox(c) ('0' <= c && c <= '9' ? c - '0' : \
114
'a' <= c && c <= 'f' ? c - 'a' + 10 : \
115
'A' <= c && c <= 'F' ? c - 'A' + 10 : -1)
118
HexToBinary (char *in, char *out, int len)
127
bottom = atox(in[1]);
130
*out++ = (top << 4) | bottom;
141
XdmAuthenticationInit (char *cookie, int cookie_len)
143
bzero (privateKey.data, 8);
144
if (!strncmp (cookie, "0x", 2) || !strncmp (cookie, "0X", 2))
146
if (cookie_len > 2 + 2 * 8)
147
cookie_len = 2 + 2 * 8;
148
HexToBinary (cookie + 2, (char *)privateKey.data, cookie_len - 2);
154
memmove (privateKey.data + 1, cookie, cookie_len);
156
XdmcpGenerateKey (&rho);
157
XdmcpRegisterAuthentication (XdmAuthenticationName, XdmAuthenticationNameLen,
158
(unsigned char *)&rho,
160
XdmAuthenticationValidator,
161
XdmAuthenticationGenerator,
162
XdmAuthenticationAddAuth);
167
/* XDM-AUTHORIZATION-1 */
168
typedef struct _XdmAuthorization {
169
struct _XdmAuthorization *next;
173
} XdmAuthorizationRec, *XdmAuthorizationPtr;
175
static XdmAuthorizationPtr xdmAuth;
177
typedef struct _XdmClientAuth {
178
struct _XdmClientAuth *next;
182
} XdmClientAuthRec, *XdmClientAuthPtr;
184
static XdmClientAuthPtr xdmClients;
185
static long clockOffset;
186
static Bool gotClock;
188
#define TwentyMinutes (20 * 60)
189
#define TwentyFiveMinutes (25 * 60)
192
XdmClientAuthCompare (XdmClientAuthPtr a, XdmClientAuthPtr b)
196
if (!XdmcpCompareKeys (&a->rho, &b->rho))
198
for (i = 0; i < 6; i++)
199
if (a->client[i] != b->client[i])
201
return a->time == b->time;
205
XdmClientAuthDecode (unsigned char *plain, XdmClientAuthPtr auth)
210
for (i = 0; i < 8; i++)
212
auth->rho.data[i] = plain[j];
215
for (i = 0; i < 6; i++)
217
auth->client[i] = plain[j];
221
for (i = 0; i < 4; i++)
223
auth->time |= plain[j] << ((3 - i) << 3);
229
XdmClientAuthTimeout (long now)
231
XdmClientAuthPtr client, next, prev;
234
for (client = xdmClients; client; client=next)
237
if (abs (now - client->time) > TwentyFiveMinutes)
250
static XdmClientAuthPtr
251
XdmAuthorizationValidate (unsigned char *plain, int length,
252
XdmAuthKeyPtr rho, ClientPtr xclient, char **reason)
254
XdmClientAuthPtr client, existing;
258
if (length != (192 / 8)) {
260
*reason = "Bad XDM authorization key length";
263
client = (XdmClientAuthPtr) xalloc (sizeof (XdmClientAuthRec));
266
XdmClientAuthDecode (plain, client);
267
if (!XdmcpCompareKeys (&client->rho, rho))
271
*reason = "Invalid XDM-AUTHORIZATION-1 key (failed key comparison)";
274
for (i = 18; i < 24; i++)
278
*reason = "Invalid XDM-AUTHORIZATION-1 key (failed NULL check)";
282
int family, addr_len;
285
if (_XSERVTransGetPeerAddr(((OsCommPtr)xclient->osPrivate)->trans_conn,
286
&family, &addr_len, &addr) == 0
287
&& _XSERVTransConvertAddress(&family, &addr_len, &addr) == 0) {
288
#if defined(TCPCONN) || defined(STREAMSCONN)
289
if (family == FamilyInternet &&
290
memcmp((char *)addr, client->client, 4) != 0) {
294
*reason = "Invalid XDM-AUTHORIZATION-1 key (failed address comparison)";
305
clockOffset = client->time - now;
309
XdmClientAuthTimeout (now);
310
if (abs (client->time - now) > TwentyMinutes)
314
*reason = "Excessive XDM-AUTHORIZATION-1 time offset";
317
for (existing = xdmClients; existing; existing=existing->next)
319
if (XdmClientAuthCompare (existing, client))
323
*reason = "XDM authorization key matches an existing client!";
331
XdmAddCookie (unsigned short data_length, char *data, XID id)
333
XdmAuthorizationPtr new;
334
unsigned char *rho_bits, *key_bits;
338
case 16: /* auth from files is 16 bytes long */
342
/* R5 xdm sent bogus authorization data in the accept packet,
343
* but we can recover */
345
key_bits = (unsigned char *) data;
351
rho_bits = (unsigned char *) data;
352
key_bits = (unsigned char *) (data + 8);
356
case 8: /* auth from XDMCP is 8 bytes long */
358
key_bits = (unsigned char *) data;
364
/* the first octet of the key must be zero */
365
if (key_bits[0] != '\0')
367
new = (XdmAuthorizationPtr) xalloc (sizeof (XdmAuthorizationRec));
372
memmove (new->key.data, key_bits, (int) 8);
373
memmove (new->rho.data, rho_bits, (int) 8);
379
XdmCheckCookie (unsigned short cookie_length, char *cookie,
380
ClientPtr xclient, char **reason)
382
XdmAuthorizationPtr auth;
383
XdmClientAuthPtr client;
384
unsigned char *plain;
386
/* Auth packets must be a multiple of 8 bytes long */
387
if (cookie_length & 7)
389
plain = (unsigned char *) xalloc (cookie_length);
392
for (auth = xdmAuth; auth; auth=auth->next) {
393
XdmcpUnwrap (cookie, (unsigned char *)&auth->key, plain, cookie_length);
394
if ((client = XdmAuthorizationValidate (plain, cookie_length, &auth->rho, xclient, reason)) != NULL)
396
client->next = xdmClients;
407
XdmResetCookie (void)
409
XdmAuthorizationPtr auth, next_auth;
410
XdmClientAuthPtr client, next_client;
412
for (auth = xdmAuth; auth; auth=next_auth)
414
next_auth = auth->next;
418
for (client = xdmClients; client; client=next_client)
420
next_client = client->next;
423
xdmClients = (XdmClientAuthPtr) 0;
428
XdmToID (unsigned short cookie_length, char *cookie)
430
XdmAuthorizationPtr auth;
431
XdmClientAuthPtr client;
432
unsigned char *plain;
434
plain = (unsigned char *) xalloc (cookie_length);
437
for (auth = xdmAuth; auth; auth=auth->next) {
438
XdmcpUnwrap (cookie, (unsigned char *)&auth->key, plain, cookie_length);
439
if ((client = XdmAuthorizationValidate (plain, cookie_length, &auth->rho, NULL, NULL)) != NULL)
451
XdmFromID (XID id, unsigned short *data_lenp, char **datap)
453
XdmAuthorizationPtr auth;
455
for (auth = xdmAuth; auth; auth=auth->next) {
456
if (id == auth->id) {
458
*datap = (char *) &auth->rho;
466
XdmRemoveCookie (unsigned short data_length, char *data)
468
XdmAuthorizationPtr auth, prev;
469
XdmAuthKeyPtr key_bits, rho_bits;
475
rho_bits = (XdmAuthKeyPtr) data;
476
key_bits = (XdmAuthKeyPtr) (data + 8);
481
key_bits = (XdmAuthKeyPtr) data;
487
for (auth = xdmAuth; auth; auth=auth->next) {
488
if (XdmcpCompareKeys (rho_bits, &auth->rho) &&
489
XdmcpCompareKeys (key_bits, &auth->key))
492
prev->next = auth->next;
494
xdmAuth = auth->next;