Initial import of the CDE 2.1.30 sources from the Open Group.
[oweals/cde.git] / cde / programs / dtlogin / xdmauth.c
1 /* $TOG: xdmauth.c /main/4 1997/03/14 13:45:35 barstow $ */
2 /* (c) Copyright 1997 The Open Group */
3 /*                                                                      *
4  * (c) Copyright 1993, 1994 Hewlett-Packard Company                     *
5  * (c) Copyright 1993, 1994 International Business Machines Corp.       *
6  * (c) Copyright 1993, 1994 Sun Microsystems, Inc.                      *
7  * (c) Copyright 1993, 1994 Novell, Inc.                                *
8  */
9
10 /*
11  * @DEC_COPYRIGHT@
12  */
13 /*
14  * HISTORY
15  * $Log$
16  * Revision 1.1.2.3  1995/06/06  20:25:50  Chris_Beute
17  *      Code snapshot merge from March 15 and SIA changes
18  *      [1995/05/31  20:17:31  Chris_Beute]
19  *
20  * Revision 1.1.2.2  1995/04/21  13:05:43  Peter_Derr
21  *      dtlogin auth key fixes from deltacde
22  *      [1995/04/12  19:21:36  Peter_Derr]
23  * 
24  *      xdm R6 version used to handle XDM-AUTHORIZATION-1
25  *      [1995/04/12  18:06:02  Peter_Derr]
26  * 
27  * $EndLog$
28  */
29 /*
30
31 Copyright (c) 1988  X Consortium
32
33 Permission is hereby granted, free of charge, to any person obtaining
34 a copy of this software and associated documentation files (the
35 "Software"), to deal in the Software without restriction, including
36 without limitation the rights to use, copy, modify, merge, publish,
37 distribute, sublicense, and/or sell copies of the Software, and to
38 permit persons to whom the Software is furnished to do so, subject to
39 the following conditions:
40
41 The above copyright notice and this permission notice shall be included
42 in all copies or substantial portions of the Software.
43
44 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
45 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
46 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
47 IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
48 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
49 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
50 OTHER DEALINGS IN THE SOFTWARE.
51
52 Except as contained in this notice, the name of the X Consortium shall
53 not be used in advertising or otherwise to promote the sale, use or
54 other dealings in this Software without prior written authorization
55 from the X Consortium.
56
57 */
58
59 /*
60  * xdm - display manager daemon
61  * Author:  Keith Packard, MIT X Consortium
62  *
63  * xdmauth
64  *
65  * generate authorization data for XDM-AUTHORIZATION-1 as per XDMCP spec
66  */
67
68 #include "dm.h"
69
70 #ifdef HASXDMAUTH
71
72 static char     auth_name[256];
73 static int      auth_name_len;
74
75 XdmPrintDataHex (s, a, l)
76     char            *s;
77     char            *a;
78     int             l;
79 {
80     int i;
81
82     Debug ("%s", s);
83     for (i = 0; i < l; i++)
84         Debug (" %02x", a[i] & 0xff);
85     Debug ("\n");
86 }
87
88 #ifdef notdef                   /* not used */
89 XdmPrintKey (s, k)
90     char            *s;
91     XdmAuthKeyRec   *k;
92 {
93     XdmPrintDataHex (s, (char *) k->data, 8);
94 }
95 #endif
96
97 #ifdef XDMCP
98 XdmPrintArray8Hex (s, a)
99     char        *s;
100     ARRAY8Ptr   a;
101 {
102     XdmPrintDataHex (s, (char *) a->data, a->length);
103 }
104 #endif
105
106 XdmInitAuth (name_len, name)
107 #if NeedWidePrototypes
108     unsigned int name_len;
109 #else
110     unsigned short name_len;
111 #endif /* NeedWidePrototypes */
112     char            *name;
113 {
114     if (name_len > 256)
115         name_len = 256;
116     auth_name_len = name_len;
117     memmove( auth_name, name, name_len);
118 }
119
120 /*
121  * Generate authorization for XDM-AUTHORIZATION-1 
122  *
123  * When being used with XDMCP, 8 bytes are generated for the session key
124  * (sigma), as the random number (rho) is already shared between xdm and
125  * the server.  Otherwise, we'll prepend a random number to pass in the file
126  * between xdm and the server (16 bytes total)
127  */
128
129 Xauth *
130 XdmGetAuthHelper (namelen, name, includeRho)
131     unsigned short  namelen;
132     char            *name;
133     int     includeRho;
134 {
135     Xauth   *new;
136     new = (Xauth *) malloc (sizeof (Xauth));
137
138     if (!new)
139         return (Xauth *) 0;
140     new->family = FamilyWild;
141     new->address_length = 0;
142     new->address = 0;
143     new->number_length = 0;
144     new->number = 0;
145     if (includeRho)
146         new->data_length = 16;
147     else
148         new->data_length = 8;
149
150     new->data = (char *) malloc (new->data_length);
151     if (!new->data)
152     {
153         free ((char *) new);
154         return (Xauth *) 0;
155     }
156     new->name = (char *) malloc (namelen);
157     if (!new->name)
158     {
159         free ((char *) new->data);
160         free ((char *) new);
161         return (Xauth *) 0;
162     }
163     memmove( (char *)new->name, name, namelen);
164     new->name_length = namelen;
165     GenerateAuthData ((char *)new->data, new->data_length);
166     /*
167      * set the first byte of the session key to zero as it
168      * is a DES key and only uses 56 bits
169      */
170     ((char *)new->data)[new->data_length - 8] = '\0';
171     XdmPrintDataHex ("Local server auth", (char *)new->data, new->data_length);
172     return new;
173 }
174
175 Xauth *
176 XdmGetAuth (namelen, name)
177 #if NeedWidePrototypes
178     unsigned int namelen;
179 #else
180     unsigned short namelen;
181 #endif /* NeedWidePrototypes */
182     char            *name;
183 {
184     return XdmGetAuthHelper (namelen, name, TRUE);
185 }
186
187 #ifdef XDMCP
188
189 XdmGetXdmcpAuth (pdpy,authorizationNameLen, authorizationName)
190     struct protoDisplay *pdpy;
191 #if NeedWidePrototypes
192     unsigned int authorizationNameLen;
193 #else
194     unsigned short authorizationNameLen;
195 #endif /* NeedWidePrototypes */
196     char                *authorizationName;
197 {
198     Xauth   *fileauth, *xdmcpauth;
199
200     if (pdpy->fileAuthorization && pdpy->xdmcpAuthorization)
201         return;
202     xdmcpauth = XdmGetAuthHelper (authorizationNameLen, authorizationName, FALSE);
203     if (!xdmcpauth)
204         return;
205     fileauth = (Xauth *) malloc (sizeof (Xauth));
206     if (!fileauth)
207     {
208         XauDisposeAuth(xdmcpauth);
209         return;
210     }
211     /* build the file auth from the XDMCP auth */
212     *fileauth = *xdmcpauth;
213     fileauth->name = malloc (xdmcpauth->name_length);
214     fileauth->data = malloc (16);
215     fileauth->data_length = 16;
216     if (!fileauth->name || !fileauth->data)
217     {
218         XauDisposeAuth (xdmcpauth);
219         if (fileauth->name)
220             free ((char *) fileauth->name);
221         if (fileauth->data)
222             free ((char *) fileauth->data);
223         free ((char *) fileauth);
224         return;
225     }
226     /*
227      * for the file authorization, prepend the random number (rho)
228      * which is simply the number we've been passing back and
229      * forth via XDMCP
230      */
231     memmove( fileauth->name, xdmcpauth->name, xdmcpauth->name_length);
232     memmove( fileauth->data, pdpy->authenticationData.data, 8);
233     memmove( fileauth->data + 8, xdmcpauth->data, 8);
234     XdmPrintDataHex ("Accept packet auth", xdmcpauth->data, xdmcpauth->data_length);
235     XdmPrintDataHex ("Auth file auth", fileauth->data, fileauth->data_length);
236     /* encrypt the session key for its trip back to the server */
237     XdmcpWrap (xdmcpauth->data, &pdpy->key, xdmcpauth->data, 8);
238     pdpy->fileAuthorization = fileauth;
239     pdpy->xdmcpAuthorization = xdmcpauth;
240 }
241
242 #define atox(c) ('0' <= c && c <= '9' ? c - '0' : \
243                  'a' <= c && c <= 'f' ? c - 'a' + 10 : \
244                  'A' <= c && c <= 'F' ? c - 'A' + 10 : -1)
245
246 static
247 HexToBinary (key)
248     char    *key;
249 {
250     char    *out, *in;
251     int     top, bottom;
252
253     in = key + 2;
254     out= key;
255     while (in[0] && in[1])
256     {
257         top = atox(in[0]);
258         if (top == -1)
259             return 0;
260         bottom = atox(in[1]);
261         if (bottom == -1)
262             return 0;
263         *out++ = (top << 4) | bottom;
264         in += 2;
265     }
266     if (in[0])
267         return 0;
268     *out++ = '\0';
269     return 1;
270 }
271
272 /*
273  * Search the Keys file for the entry matching this display.  This
274  * routine accepts either plain ascii strings for keys, or hex-encoded numbers
275  */
276
277 XdmGetKey (pdpy, displayID)
278     struct protoDisplay *pdpy;
279     ARRAY8Ptr           displayID;
280 {
281     FILE    *keys;
282     char    line[1024], id[1024], key[1024];
283     int     keylen;
284
285     Debug ("Lookup key for %*.*s\n", displayID->length, displayID->length, displayID->data);
286     keys = fopen (keyFile, "r");
287     if (!keys)
288         return FALSE;
289     while (fgets (line, sizeof (line) -  1, keys))
290     {
291         if (line[0] == '#' || sscanf (line, "%s %s", id, key) != 2)
292             continue;
293         bzero(line, sizeof(line));
294         Debug ("Key entry \"%s\" \"%s\"\n", id, key);
295         if (strlen (id) == displayID->length &&
296             !strncmp (id, (char *)displayID->data, displayID->length))
297         {
298             if (!strncmp (key, "0x", 2) || !strncmp (key, "0X", 2))
299                 if (!HexToBinary (key))
300                     break;
301             keylen = strlen (key);
302             while (keylen < 7)
303                 key[keylen++] = '\0';
304             pdpy->key.data[0] = '\0';
305             memmove( pdpy->key.data + 1, key, 7);
306             bzero(key, sizeof(key));
307             fclose (keys);
308             return TRUE;
309         }
310     }
311     bzero(line, sizeof(line));
312     bzero(key, sizeof(key));
313     fclose (keys);
314     return FALSE;
315 }
316
317 /*ARGSUSED*/
318 XdmCheckAuthentication (pdpy, displayID, authenticationName, authenticationData)
319     struct protoDisplay *pdpy;
320     ARRAY8Ptr           displayID, authenticationName, authenticationData;
321 {
322     XdmAuthKeyPtr   incoming;
323
324     if (!XdmGetKey (pdpy, displayID))
325         return FALSE;
326     if (authenticationData->length != 8)
327         return FALSE;
328     XdmcpUnwrap (authenticationData->data, &pdpy->key,
329                   authenticationData->data, 8);
330     XdmPrintArray8Hex ("Request packet auth", authenticationData);
331     if (!XdmcpCopyARRAY8(authenticationData, &pdpy->authenticationData))
332         return FALSE;
333     incoming = (XdmAuthKeyPtr) authenticationData->data;
334     XdmcpIncrementKey (incoming);
335     XdmcpWrap (authenticationData->data, &pdpy->key,
336                   authenticationData->data, 8);
337     return TRUE;
338 }
339
340 #endif /* XDMCP */
341 #endif /* HASXDMAUTH (covering the entire file) */