📄 xdmauth.c
字号:
/* $XConsortium: xdmauth.c,v 1.14 95/07/10 21:18:07 gildea Exp $ *//*Copyright (c) 1988 X ConsortiumPermission is hereby granted, free of charge, to any person obtaininga copy of this software and associated documentation files (the"Software"), to deal in the Software without restriction, includingwithout limitation the rights to use, copy, modify, merge, publish,distribute, sublicense, and/or sell copies of the Software, and topermit persons to whom the Software is furnished to do so, subject tothe following conditions:The above copyright notice and this permission notice shall be includedin all copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESSOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OFMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OROTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OROTHER DEALINGS IN THE SOFTWARE.Except as contained in this notice, the name of the X Consortium shallnot be used in advertising or otherwise to promote the sale, use orother dealings in this Software without prior written authorizationfrom the X Consortium.*//* * XDM-AUTHENTICATION-1 (XDMCP authentication) and * XDM-AUTHORIZATION-1 (client authorization) protocols * * Author: Keith Packard, MIT X Consortium */#include "X.h"#include "Xtrans.h"#include "os.h"#include "osdep.h"#include "dixstruct.h"#ifdef HASXDMAUTHstatic Bool authFromXDMCP;#ifdef XDMCP#include "Xmd.h"#undef REQUEST#include "Xdmcp.h"/* XDM-AUTHENTICATION-1 */static XdmAuthKeyRec privateKey;static char XdmAuthenticationName[] = "XDM-AUTHENTICATION-1";#define XdmAuthenticationNameLen (sizeof XdmAuthenticationName - 1)static XdmAuthKeyRec rho;static Bool XdmAuthenticationValidator (privateData, incomingData, packet_type) ARRAY8Ptr privateData, incomingData; xdmOpCode packet_type;{ XdmAuthKeyPtr incoming; XdmcpUnwrap (incomingData->data, &privateKey, incomingData->data,incomingData->length); switch (packet_type) { case ACCEPT: if (incomingData->length != 8) return FALSE; incoming = (XdmAuthKeyPtr) incomingData->data; XdmcpDecrementKey (incoming); return XdmcpCompareKeys (incoming, &rho); } return FALSE;}static BoolXdmAuthenticationGenerator (privateData, outgoingData, packet_type) ARRAY8Ptr privateData, outgoingData; xdmOpCode packet_type;{ outgoingData->length = 0; outgoingData->data = 0; switch (packet_type) { case REQUEST: if (XdmcpAllocARRAY8 (outgoingData, 8)) XdmcpWrap (&rho, &privateKey, outgoingData->data, 8); } return TRUE;}static BoolXdmAuthenticationAddAuth (name_len, name, data_len, data) int name_len, data_len; char *name, *data;{ Bool ret; XdmcpUnwrap (data, &privateKey, data, data_len); authFromXDMCP = TRUE; ret = AddAuthorization (name_len, name, data_len, data); authFromXDMCP = FALSE; return ret;}#define atox(c) ('0' <= c && c <= '9' ? c - '0' : \ 'a' <= c && c <= 'f' ? c - 'a' + 10 : \ 'A' <= c && c <= 'F' ? c - 'A' + 10 : -1)static intHexToBinary (in, out, len) char *out, *in; int len;{ int top, bottom; while (len > 0) { top = atox(in[0]); if (top == -1) return 0; bottom = atox(in[1]); if (bottom == -1) return 0; *out++ = (top << 4) | bottom; in += 2; len -= 2; } if (len) return 0; *out++ = '\0'; return 1;}voidXdmAuthenticationInit (cookie, cookie_len) char *cookie; int cookie_len;{ bzero (privateKey.data, 8); if (!strncmp (cookie, "0x", 2) || !strncmp (cookie, "0X", 2)) { if (cookie_len > 2 + 2 * 8) cookie_len = 2 + 2 * 8; HexToBinary (cookie + 2, (char *)privateKey.data, cookie_len - 2); } else { if (cookie_len > 7) cookie_len = 7; memmove (privateKey.data + 1, cookie, cookie_len); } XdmcpGenerateKey (&rho); XdmcpRegisterAuthentication (XdmAuthenticationName, XdmAuthenticationNameLen, &rho, sizeof (rho), XdmAuthenticationValidator, XdmAuthenticationGenerator, XdmAuthenticationAddAuth);}#endif /* XDMCP *//* XDM-AUTHORIZATION-1 */typedef struct _XdmAuthorization { struct _XdmAuthorization *next; XdmAuthKeyRec rho; XdmAuthKeyRec key; XID id;} XdmAuthorizationRec, *XdmAuthorizationPtr;static XdmAuthorizationPtr xdmAuth;typedef struct _XdmClientAuth { struct _XdmClientAuth *next; XdmAuthKeyRec rho; char client[6]; long time;} XdmClientAuthRec, *XdmClientAuthPtr;static XdmClientAuthPtr xdmClients;static long clockOffset;static Bool gotClock;#define TwentyMinutes (20 * 60)#define TwentyFiveMinutes (25 * 60)static BoolXdmClientAuthCompare (a, b) XdmClientAuthPtr a, b;{ int i; if (!XdmcpCompareKeys (&a->rho, &b->rho)) return FALSE; for (i = 0; i < 6; i++) if (a->client[i] != b->client[i]) return FALSE; return a->time == b->time;}static voidXdmClientAuthDecode (plain, auth) unsigned char *plain; XdmClientAuthPtr auth;{ int i, j; j = 0; for (i = 0; i < 8; i++) { auth->rho.data[i] = plain[j]; ++j; } for (i = 0; i < 6; i++) { auth->client[i] = plain[j]; ++j; } auth->time = 0; for (i = 0; i < 4; i++) { auth->time |= plain[j] << ((3 - i) << 3); j++; }}static voidXdmClientAuthTimeout (now) long now;{ XdmClientAuthPtr client, next, prev; prev = 0; for (client = xdmClients; client; client=next) { next = client->next; if (abs (now - client->time) > TwentyFiveMinutes) { if (prev) prev->next = next; else xdmClients = next; xfree (client); } else prev = client; }}static XdmClientAuthPtrXdmAuthorizationValidate (plain, length, rho, xclient, reason) unsigned char *plain; int length; XdmAuthKeyPtr rho; ClientPtr xclient; char **reason;{ XdmClientAuthPtr client, existing; long now; int i; if (length != (192 / 8)) { if (reason) *reason = "Bad XDM authorization key length"; return NULL; } client = (XdmClientAuthPtr) xalloc (sizeof (XdmClientAuthRec)); if (!client) return NULL; XdmClientAuthDecode (plain, client); if (!XdmcpCompareKeys (&client->rho, rho)) { xfree (client); if (reason) *reason = "Invalid XDM-AUTHORIZATION-1 key value"; return NULL; } for (i = 18; i < 24; i++) if (plain[i] != 0) { xfree (client); if (reason) *reason = "Invalid XDM-AUTHORIZATION-1 key value"; return NULL; } if (xclient) { int family, addr_len; Xtransaddr *addr; if (_XSERVTransGetPeerAddr(((OsCommPtr)xclient->osPrivate)->trans_conn, &family, &addr_len, &addr) == 0 && _XSERVTransConvertAddress(&family, &addr_len, &addr) == 0) {#ifdef TCPCONN if (family == FamilyInternet && memcmp((char *)addr, client->client, 4) != 0) { xfree (client); xfree (addr); if (reason) *reason = "Invalid XDM-AUTHORIZATION-1 key value"; return NULL; }#endif xfree (addr); } } now = time(0); if (!gotClock) { clockOffset = client->time - now; gotClock = TRUE; } now += clockOffset; XdmClientAuthTimeout (now); if (abs (client->time - now) > TwentyMinutes) { xfree (client); if (reason) *reason = "Excessive XDM-AUTHORIZATION-1 time offset"; return NULL; } for (existing = xdmClients; existing; existing=existing->next) { if (XdmClientAuthCompare (existing, client)) { xfree (client); if (reason) *reason = "XDM authorization key matches an existing client!"; return NULL; } } return client;}intXdmAddCookie (data_length, data, id)unsigned short data_length;char *data;XID id;{ XdmAuthorizationPtr new; unsigned char *rho_bits, *key_bits; switch (data_length) { case 16: /* auth from files is 16 bytes long */ if (authFromXDMCP) { /* R5 xdm sent bogus authorization data in the accept packet, * but we can recover */ rho_bits = rho.data; key_bits = (unsigned char *) data; key_bits[0] = '\0'; } else { rho_bits = (unsigned char *) data; key_bits = (unsigned char *) (data + 8); } break; case 8: /* auth from XDMCP is 8 bytes long */ rho_bits = rho.data; key_bits = (unsigned char *) data; break; default: return 0; } /* the first octet of the key must be zero */ if (key_bits[0] != '\0') return 0; new = (XdmAuthorizationPtr) xalloc (sizeof (XdmAuthorizationRec)); if (!new) return 0; new->next = xdmAuth; xdmAuth = new; memmove (new->key.data, key_bits, (int) 8); memmove (new->rho.data, rho_bits, (int) 8); new->id = id; return 1;}XIDXdmCheckCookie (cookie_length, cookie, xclient, reason) unsigned short cookie_length; char *cookie; ClientPtr xclient; char **reason;{ XdmAuthorizationPtr auth; XdmClientAuthPtr client; unsigned char *plain; /* Auth packets must be a multiple of 8 bytes long */ if (cookie_length & 7) return (XID) -1; plain = (unsigned char *) xalloc (cookie_length); if (!plain) return (XID) -1; for (auth = xdmAuth; auth; auth=auth->next) { XdmcpUnwrap (cookie, &auth->key, plain, cookie_length); if (client = XdmAuthorizationValidate (plain, cookie_length, &auth->rho, xclient, reason)) { client->next = xdmClients; xdmClients = client; xfree (plain); return auth->id; } } xfree (plain); return (XID) -1;}intXdmResetCookie (){ XdmAuthorizationPtr auth, next_auth; XdmClientAuthPtr client, next_client; for (auth = xdmAuth; auth; auth=next_auth) { next_auth = auth->next; xfree (auth); } xdmAuth = 0; for (client = xdmClients; client; client=next_client) { next_client = client->next; xfree (client); } xdmClients = (XdmClientAuthPtr) 0; return 1;}XIDXdmToID (cookie_length, cookie)unsigned short cookie_length;char *cookie;{ XdmAuthorizationPtr auth; XdmClientAuthPtr client; unsigned char *plain; plain = (unsigned char *) xalloc (cookie_length); if (!plain) return (XID) -1; for (auth = xdmAuth; auth; auth=auth->next) { XdmcpUnwrap (cookie, &auth->key, plain, cookie_length); if (client = XdmAuthorizationValidate (plain, cookie_length, &auth->rho, NULL, NULL)) { xfree (client); xfree (cookie); return auth->id; } } xfree (cookie); return (XID) -1;}intXdmFromID (id, data_lenp, datap)XID id;unsigned short *data_lenp;char **datap;{ XdmAuthorizationPtr auth; for (auth = xdmAuth; auth; auth=auth->next) { if (id == auth->id) { *data_lenp = 16; *datap = (char *) &auth->rho; return 1; } } return 0;}intXdmRemoveCookie (data_length, data)unsigned short data_length;char *data;{ XdmAuthorizationPtr auth, prev; XdmAuthKeyPtr key_bits, rho_bits; prev = 0; switch (data_length) { case 16: rho_bits = (XdmAuthKeyPtr) data; key_bits = (XdmAuthKeyPtr) (data + 8); break; case 8: rho_bits = ρ key_bits = (XdmAuthKeyPtr) data; break; default: return 0; } for (auth = xdmAuth; auth; auth=auth->next) { if (XdmcpCompareKeys (rho_bits, &auth->rho) && XdmcpCompareKeys (key_bits, &auth->key)) { if (prev) prev->next = auth->next; else xdmAuth = auth->next; xfree (auth); return 1; } } return 0;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -