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