home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / server / os / xdmauth.c.orig < prev    next >
Encoding:
Text File  |  1991-07-24  |  9.2 KB  |  433 lines

  1. /*
  2.  * XDM-AUTHENTICATION-1 (XDMCP authentication) and
  3.  * XDM-AUTHORIZATION-1 (client authorization) protocols
  4.  *
  5.  * $XConsortium: xdmauth.c,v 1.5 91/07/24 18:36:20 keith Exp $
  6.  *
  7.  * Copyright 1988 Massachusetts Institute of Technology
  8.  *
  9.  * Permission to use, copy, modify, and distribute this software and its
  10.  * documentation for any purpose and without fee is hereby granted, provided
  11.  * that the above copyright notice appear in all copies and that both that
  12.  * copyright notice and this permission notice appear in supporting
  13.  * documentation, and that the name of M.I.T. not be used in advertising or
  14.  * publicity pertaining to distribution of the software without specific,
  15.  * written prior permission.  M.I.T. makes no representations about the
  16.  * suitability of this software for any purpose.  It is provided "as is"
  17.  * without express or implied warranty.
  18.  *
  19.  * Author:  Keith Packard, MIT X Consortium
  20.  */
  21.  
  22. #include "X.h"
  23. #include "os.h"
  24.  
  25. #ifdef HASXDMAUTH
  26.  
  27. #ifdef XDMCP
  28. #include "Xmd.h"
  29. #include "Xdmcp.h"
  30.  
  31. /* XDM-AUTHENTICATION-1 */
  32.  
  33. static XdmAuthKeyRec    privateKey;
  34. static char XdmAuthenticationName[] = "XDM-AUTHENTICATION-1";
  35. #define XdmAuthenticationNameLen (sizeof XdmAuthenticationName - 1)
  36. static XdmAuthKeyRec    rho;
  37.  
  38. static Bool XdmAuthenticationValidator (privateData, incomingData, packet_type)
  39.     ARRAY8Ptr    privateData, incomingData;
  40.     xdmOpCode    packet_type;
  41. {
  42.     XdmAuthKeyPtr    incoming;
  43.  
  44.     XdmcpUnwrap (incomingData->data, &privateKey,
  45.                   incomingData->data,incomingData->length);
  46.     switch (packet_type)
  47.     {
  48.     case ACCEPT:
  49.         if (incomingData->length != 8)
  50.         return FALSE;
  51.         incoming = (XdmAuthKeyPtr) incomingData->data;
  52.         XdmcpDecrementKey (incoming);
  53.         return XdmcpCompareKeys (incoming, &rho);
  54.     }
  55.     return FALSE;
  56. }
  57.  
  58. static Bool
  59. XdmAuthenticationGenerator (privateData, outgoingData, packet_type)
  60.     ARRAY8Ptr    privateData, outgoingData;
  61.     xdmOpCode    packet_type;
  62. {
  63.     outgoingData->length = 0;
  64.     outgoingData->data = 0;
  65.     switch (packet_type)
  66.     {
  67.     case REQUEST:
  68.     if (XdmcpAllocARRAY8 (outgoingData, 8))
  69.         XdmcpWrap (&rho, &privateKey, outgoingData->data, 8);
  70.     }
  71.     return TRUE;
  72. }
  73.  
  74. static Bool
  75. XdmAuthenticationAddAuth (name_len, name, data_len, data)
  76.     int        name_len, data_len;
  77.     char    *name, *data;
  78. {
  79.     XdmcpUnwrap (data, &privateKey, data, data_len);
  80.     AddAuthorization (name_len, name, data_len, data);
  81. }
  82.  
  83.  
  84. #define atox(c)    ('0' <= c && c <= '9' ? c - '0' : \
  85.          'a' <= c && c <= 'f' ? c - 'a' + 10 : \
  86.          'A' <= c && c <= 'F' ? c - 'A' + 10 : -1)
  87.  
  88. static
  89. HexToBinary (in, out, len)
  90.     char    *out, *in;
  91. {
  92.     int        top, bottom;
  93.  
  94.     while (len > 0)
  95.     {
  96.     top = atox(in[0]);
  97.     if (top == -1)
  98.         return 0;
  99.     bottom = atox(in[1]);
  100.     if (bottom == -1)
  101.         return 0;
  102.     *out++ = (top << 4) | bottom;
  103.     in += 2;
  104.     len -= 2;
  105.     }
  106.     if (len)
  107.     return 0;
  108.     *out++ = '\0';
  109.     return 1;
  110. }
  111.  
  112. XdmAuthenticationInit (cookie, cookie_len)
  113.     char    *cookie;
  114.     int        cookie_len;
  115. {
  116.     bzero (privateKey.data, 8);
  117.     if (!strncmp (cookie, "0x", 2) || !strncmp (cookie, "0X", 2))
  118.     {
  119.     if (cookie_len > 2 + 2 * 8)
  120.         cookie_len = 2 + 2 * 8;
  121.     HexToBinary (cookie + 2, privateKey.data, cookie_len - 2);
  122.     }
  123.     else
  124.     {
  125.         if (cookie_len > 7)
  126.         cookie_len = 7;
  127.         bcopy (cookie, privateKey.data + 1, cookie_len);
  128.     }
  129.     XdmcpGenerateKey (&rho);
  130.     XdmcpRegisterAuthentication (XdmAuthenticationName, XdmAuthenticationNameLen,
  131.                  &rho,
  132.                  sizeof (rho),
  133.                  XdmAuthenticationValidator,
  134.                  XdmAuthenticationGenerator,
  135.                  XdmAuthenticationAddAuth);
  136. }
  137.  
  138. #endif /* XDMCP */
  139.  
  140. /* XDM-AUTHORIZATION-1 */
  141. typedef struct _XdmAuthorization {
  142.     struct _XdmAuthorization    *next;
  143.     XdmAuthKeyRec        rho;
  144.     XdmAuthKeyRec        key;
  145.     XID                id;
  146. } XdmAuthorizationRec, *XdmAuthorizationPtr;
  147.  
  148. XdmAuthorizationPtr xdmAuth;
  149.  
  150. typedef struct _XdmClientAuth {
  151.     struct _XdmClientAuth   *next;
  152.     XdmAuthKeyRec        rho;
  153.     char            client[6];
  154.     long            time;
  155. } XdmClientAuthRec, *XdmClientAuthPtr;
  156.  
  157. XdmClientAuthPtr    xdmClients;
  158. static long        clockOffset;
  159. static Bool        gotClock;
  160.  
  161. #define TwentyMinutes    (20 * 60)
  162.  
  163. static Bool
  164. XdmClientAuthCompare (a, b)
  165.     XdmClientAuthPtr    a, b;
  166. {
  167.     int    i;
  168.  
  169.     if (!XdmcpCompareKeys (&a->rho, &b->rho))
  170.     return FALSE;
  171.     for (i = 0; i < 6; i++)
  172.     if (a->client[i] != b->client[i])
  173.         return FALSE;
  174.     return a->time == b->time;
  175. }
  176.  
  177. static
  178. XdmClientAuthDecode (plain, auth)
  179.     unsigned char    *plain;
  180.     XdmClientAuthPtr    auth;
  181. {
  182.     int        i, j;
  183.  
  184.     j = 0;
  185.     for (i = 0; i < 8; i++)
  186.     {
  187.     auth->rho.data[i] = plain[j];
  188.     ++j;
  189.     }
  190.     for (i = 0; i < 6; i++)
  191.     {
  192.     auth->client[i] = plain[j];
  193.     ++j;
  194.     }
  195.     auth->time = 0;
  196.     for (i = 0; i < 4; i++)
  197.     {
  198.     auth->time |= plain[j] << ((3 - i) << 3);
  199.     j++;
  200.     }
  201. }
  202.  
  203. XdmClientAuthTimeout (now)
  204.     long    now;
  205. {
  206.     XdmClientAuthPtr    client, next, prev;
  207.  
  208.     prev = 0;
  209.     for (client = xdmClients; client; client=next)
  210.     {
  211.     next = client->next;
  212.     if (abs (now - client->time) > TwentyMinutes)
  213.     {
  214.         if (prev)
  215.         prev->next = next;
  216.         else
  217.         xdmClients = next;
  218.         xfree (client);
  219.     }
  220.     else
  221.         prev = client;
  222.     }
  223. }
  224.  
  225. static XdmClientAuthPtr
  226. XdmAuthorizationValidate (plain, length, rho)
  227.     char        *plain;
  228.     int            length;
  229.     XdmAuthKeyPtr    rho;
  230. {
  231.     XdmClientAuthPtr    client, existing;
  232.     long        now;
  233.  
  234.     if (length != (192 / 8))
  235.     return NULL;
  236.     client = (XdmClientAuthPtr) xalloc (sizeof (XdmClientAuthRec));
  237.     if (!client)
  238.     return NULL;
  239.     XdmClientAuthDecode (plain, client);
  240.     if (!XdmcpCompareKeys (&client->rho, rho))
  241.     {
  242.     xfree (client);
  243.     return NULL;
  244.     }
  245.     now = time(0);
  246.     if (!gotClock)
  247.     {
  248.     clockOffset = client->time - now;
  249.     gotClock = TRUE;
  250.     }
  251.     now += clockOffset;
  252.     XdmClientAuthTimeout (now);
  253.     if (abs (client->time - now) > TwentyMinutes)
  254.     {
  255.     xfree (client);
  256.     return NULL;
  257.     }
  258.     for (existing = xdmClients; existing; existing=existing->next)
  259.     {
  260.     if (XdmClientAuthCompare (existing, client))
  261.     {
  262.         xfree (client);
  263.         return NULL;
  264.     }
  265.     }
  266.     return client;
  267. }
  268.  
  269. int
  270. XdmAddCookie (data_length, data, id)
  271. unsigned short    data_length;
  272. char    *data;
  273. XID    id;
  274. {
  275.     XdmAuthorizationPtr    new;
  276.     unsigned char    *rho_bits, *key_bits;
  277.  
  278.     switch (data_length)
  279.     {
  280.     case 16:            /* auth from files is 16 bytes long */
  281.     rho_bits = (unsigned char *) data;
  282.     key_bits = (unsigned char *) (data + 8);
  283.     break;
  284.     case 8:            /* auth from XDMCP is 8 bytes long */
  285.     rho_bits = rho.data;
  286.     key_bits = (unsigned char *) data;
  287.     break;
  288.     default:
  289.     return 0;
  290.     }
  291.     /* the first octet of the key must be zero */
  292.     if (key_bits[0] != '\0')
  293.     return 0;
  294.     new = (XdmAuthorizationPtr) xalloc (sizeof (XdmAuthorizationRec));
  295.     if (!new)
  296.     return 0;
  297.     new->next = xdmAuth;
  298.     xdmAuth = new;
  299.     bcopy (key_bits, new->key.data, (int) 8);
  300.     bcopy (rho_bits, new->rho.data, (int) 8);
  301.     new->id = id;
  302.     return 1;
  303. }
  304.  
  305. XID
  306. XdmCheckCookie (cookie_length, cookie)
  307. unsigned short    cookie_length;
  308. char    *cookie;
  309. {
  310.     XdmAuthorizationPtr    auth;
  311.     XdmClientAuthPtr    client;
  312.     char        *plain;
  313.  
  314.     /* Auth packets must be a multiple of 8 bytes long */
  315.     if (cookie_length & 7)
  316.     return (XID) -1;
  317.     plain = (char *) xalloc (cookie_length);
  318.     if (!plain)
  319.     return (XID) -1;
  320.     for (auth = xdmAuth; auth; auth=auth->next) {
  321.     XdmcpUnwrap (cookie, &auth->key, plain, cookie_length);
  322.     if (client = XdmAuthorizationValidate (plain, cookie_length, &auth->rho))
  323.     {
  324.         client->next = xdmClients;
  325.         xdmClients = client;
  326.         xfree (plain);
  327.         return auth->id;
  328.     }
  329.     }
  330.     xfree (plain);
  331.     return (XID) -1;
  332. }
  333.  
  334. int
  335. XdmResetCookie ()
  336. {
  337.     XdmAuthorizationPtr    auth, next_auth;
  338.     XdmClientAuthPtr    client, next_client;
  339.  
  340.     for (auth = xdmAuth; auth; auth=next_auth)
  341.     {
  342.     next_auth = auth->next;
  343.     xfree (auth);
  344.     }
  345.     xdmAuth = 0;
  346.     for (client = xdmClients; client; client=next_client)
  347.     {
  348.     next_client = client->next;
  349.     xfree (client);
  350.     }
  351.     xdmClients = (XdmClientAuthPtr) 0;
  352. }
  353.  
  354. XID
  355. XdmToID (cookie_length, cookie)
  356. unsigned short    cookie_length;
  357. char    *cookie;
  358. {
  359.     XdmAuthorizationPtr    auth;
  360.     XdmClientAuthPtr    client;
  361.     char        *plain;
  362.  
  363.     plain = (char *) xalloc (cookie_length);
  364.     if (!plain)
  365.     return (XID) -1;
  366.     for (auth = xdmAuth; auth; auth=auth->next) {
  367.     XdmcpUnwrap (cookie, &auth->key, plain, cookie_length);
  368.     if (client = XdmAuthorizationValidate (plain, cookie_length, &auth->rho))
  369.     {
  370.         xfree (client);
  371.         xfree (cookie);
  372.         return auth->id;
  373.     }
  374.     }
  375.     xfree (cookie);
  376.     return (XID) -1;
  377. }
  378.  
  379. XdmFromID (id, data_lenp, datap)
  380. XID id;
  381. unsigned short    *data_lenp;
  382. char    **datap;
  383. {
  384.     XdmAuthorizationPtr    auth;
  385.  
  386.     for (auth = xdmAuth; auth; auth=auth->next) {
  387.     if (id == auth->id) {
  388.         *data_lenp = 16;
  389.         *datap = (char *) &auth->rho;
  390.         return 1;
  391.     }
  392.     }
  393.     return 0;
  394. }
  395.  
  396. XdmRemoveCookie (data_length, data)
  397. unsigned short    data_length;
  398. char    *data;
  399. {
  400.     XdmAuthorizationPtr    auth, prev;
  401.     XdmAuthKeyPtr    key_bits, rho_bits;
  402.  
  403.     prev = 0;
  404.     switch (data_length)
  405.     {
  406.     case 16:
  407.     rho_bits = (XdmAuthKeyPtr) data;
  408.     key_bits = (XdmAuthKeyPtr) (data + 8);
  409.     break;
  410.     case 8:
  411.     rho_bits = ρ
  412.     key_bits = (XdmAuthKeyPtr) data;
  413.     break;
  414.     default:
  415.     return;
  416.     }
  417.     for (auth = xdmAuth; auth; auth=auth->next) {
  418.     if (XdmcpCompareKeys (rho_bits, &auth->rho) &&
  419.         XdmcpCompareKeys (key_bits, &auth->key))
  420.      {
  421.         if (prev)
  422.         prev->next = auth->next;
  423.         else
  424.         xdmAuth = auth->next;
  425.         xfree (auth);
  426.         return 1;
  427.     }
  428.     }
  429.     return 0;
  430. }
  431.  
  432. #endif
  433.