6fc12fd512417f9832fc4a4b90e363ed1f2b8097
[oweals/cde.git] / cde / programs / dtlogin / genauth.c
1 /* $TOG: genauth.c /main/6 1997/03/25 12:33:13 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.2  1995/04/21  13:05:23  Peter_Derr
17  *      dtlogin auth key fixes from deltacde
18  *      [1995/04/14  18:03:41  Peter_Derr]
19  *
20  *      R6 xdm code used in dtlogin.
21  *      [1995/04/10  16:52:31  Peter_Derr]
22  *
23  * Revision 1.1.3.3  1995/02/20  21:03:19  Peter_Derr
24  *      merge XC fix-11
25  *      [1995/02/20  20:13:02  Peter_Derr]
26  * 
27  * Revision 1.1.3.2  1994/07/13  19:26:25  Peter_Derr
28  *      Include Wrap.h to get definitions for XDM-AUTHENTICATION-1
29  *      authorization mechanism.
30  *      [1994/07/13  12:15:59  Peter_Derr]
31  * 
32  * $EndLog$
33  */
34 #ifndef lint
35 static char *rcsid = "@(#)$RCSfile: genauth.c $ $Revision: /main/6 $ (DEC) $Date: 1997/03/25 12:33:13 $";
36 #endif
37 /*
38
39 Copyright (c) 1988  X Consortium
40
41 Permission is hereby granted, free of charge, to any person obtaining
42 a copy of this software and associated documentation files (the
43 "Software"), to deal in the Software without restriction, including
44 without limitation the rights to use, copy, modify, merge, publish,
45 distribute, sublicense, and/or sell copies of the Software, and to
46 permit persons to whom the Software is furnished to do so, subject to
47 the following conditions:
48
49 The above copyright notice and this permission notice shall be included
50 in all copies or substantial portions of the Software.
51
52 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
53 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
54 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
55 IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
56 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
57 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
58 OTHER DEALINGS IN THE SOFTWARE.
59
60 Except as contained in this notice, the name of the X Consortium shall
61 not be used in advertising or otherwise to promote the sale, use or
62 other dealings in this Software without prior written authorization
63 from the X Consortium.
64
65 */
66
67 /*
68  * xdm - display manager daemon
69  * Author:  Keith Packard, MIT X Consortium
70  */
71
72 # include   <X11/Xauth.h>
73 # include   <X11/Xos.h>
74 # include   "dm.h"
75
76 #include <errno.h>
77
78 #ifdef X_NOT_STDC_ENV
79 #define Time_t long
80 extern Time_t time ();
81 extern int errno;
82 #else
83 #include <time.h>
84 #define Time_t time_t
85 #endif
86
87 #ifndef DONT_USE_DES
88 # ifndef USE_CRYPT
89 #  ifdef AIXV3
90 #   define USE_CRYPT
91 #  endif
92 #  ifdef ultrix
93 #   define USE_CRYPT
94 #  endif
95 #  ifdef hpux
96 #   define USE_CRYPT
97 #  endif
98 #  ifdef macII
99 #   define USE_CRYPT
100 #  endif
101 #  ifdef sun
102 #   define USE_CRYPT
103 #   if (OSMAJORVERSION >= 4)
104      /* avoid strange sun crypt hackery */
105 #    define crypt _crypt
106 #   endif
107 #  endif
108 # endif
109 #endif
110
111 #if !defined (DONT_USE_DES) && !defined (USE_CRYPT)
112 # define USE_ENCRYPT
113 #endif
114
115 #ifdef HASXDMAUTH
116 static unsigned char    key[8];
117 #else
118 static long             key[2];
119 #endif
120
121 static sumFile (char *name, long sum[2]);
122
123 #ifdef HASXDMAUTH
124
125 typedef unsigned char auth_cblock[8];   /* block size */
126
127 typedef struct auth_ks_struct { auth_cblock _; } auth_wrapper_schedule[16];
128
129 extern void _XdmcpWrapperToOddParity();
130
131 static
132 longtochars (l, c)
133     long            l;
134     unsigned char    *c;
135 {
136     c[0] = (l >> 24) & 0xff;
137     c[1] = (l >> 16) & 0xff;
138     c[2] = (l >> 8) & 0xff;
139     c[3] = l & 0xff;
140 }
141
142 static
143 InitXdmcpWrapper ()
144 {
145     long            sum[2];
146     unsigned char   tmpkey[8];
147 /*
148  * randomFile is and xdm resource not defined in dtlogin.
149  *
150  *   if (!sumFile (randomFile, sum)) {
151  */
152     if (!sumFile ("/dev/mem", sum)) {
153         sum[0] = time ((Time_t *) 0);
154         sum[1] = time ((Time_t *) 0);
155     }
156     longtochars (sum[0], tmpkey+0);
157     longtochars (sum[1], tmpkey+4);
158     tmpkey[0] = 0;
159     _XdmcpWrapperToOddParity (tmpkey, key);
160 }
161
162 #endif /* HASXDMAUTH */
163
164 #ifndef HASXDMAUTH
165 /* A random number generator that is more unpredictable
166    than that shipped with some systems.
167    This code is taken from the C standard. */
168
169 static unsigned long int next = 1;
170
171 static int
172 xdm_rand()
173 {
174     next = next * 1103515245 + 12345;
175     return (unsigned int)(next/65536) % 32768;
176 }
177
178 static void
179 xdm_srand(seed)
180     unsigned int seed;
181 {
182     next = seed;
183 }
184 #endif /* no HASXDMAUTH */
185
186 #ifdef USE_ENCRYPT
187 static
188 bitsToBytes (bits, bytes)
189 unsigned long   bits[2];
190 char    bytes[64];
191 {
192     int bit, byte;
193     int i;
194
195     i = 0;
196     for (byte = 0; byte < 2; byte++)
197         for (bit = 0; bit < 32; bit++)
198             bytes[i++] = ((bits[byte] & (1 << bit)) != 0);
199 }
200 #endif /* USE_ENCRYPT */
201
202 # define FILE_LIMIT     1024    /* no more than this many buffers */
203
204 static
205 sumFile (name, sum)
206 char    *name;
207 long    sum[2];
208 {
209     long    buf[1024*2];
210     int     cnt;
211     int     fd;
212     int     loops;
213     int     reads;
214     int     i;
215     int     ret_status = 0;
216
217     fd = open (name, 0);
218     if (fd < 0) {
219         LogError((unsigned char *) "Cannot open randomFile \"%s\", errno = %d\n", name, errno);
220         return 0;
221     }
222 #ifdef FRAGILE_DEV_MEM
223     if (strcmp(name, "/dev/mem") == 0) lseek (fd, (off_t) 0x100000, SEEK_SET);
224 #endif
225     reads = FILE_LIMIT;
226     sum[0] = 0;
227     sum[1] = 0;
228     while ((cnt = read (fd, (char *) buf, sizeof (buf))) > 0 && --reads > 0) {
229         loops = cnt / (2 * sizeof (long));
230         for (i = 0; i < loops; i+= 2) {
231             sum[0] += buf[i];
232             sum[1] += buf[i+1];
233             ret_status = 1;
234         }
235     }
236     if (cnt < 0)
237         LogError((unsigned char *) "Cannot read randomFile \"%s\", errno = %d\n", name, errno);
238     close (fd);
239     return ret_status;
240 }
241
242
243 GenerateAuthData (auth, len)
244 char    *auth;
245 int     len;
246 {
247     long            ldata[2];
248
249 #ifdef ITIMER_REAL
250     {
251         struct timeval  now;
252
253         X_GETTIMEOFDAY (&now);
254         ldata[0] = now.tv_sec;
255         ldata[1] = now.tv_usec;
256     }
257 #else
258     {
259         long    time ();
260
261         ldata[0] = time ((long *) 0);
262         ldata[1] = getpid ();
263     }
264 #endif /* ITIMER_REAL */
265
266 #ifdef HASXDMAUTH
267     {
268         int                 bit;
269         int                 i;
270         auth_wrapper_schedule    schedule;
271         unsigned char       tdata[8];
272         static int          xdmcpAuthInited;
273     
274         longtochars (ldata[0], tdata+0);
275         longtochars (ldata[1], tdata+4);
276         if (!xdmcpAuthInited)
277         {
278             InitXdmcpWrapper ();
279             xdmcpAuthInited = 1;
280         }
281         _XdmcpAuthSetup (key, schedule);
282         for (i = 0; i < len; i++) {
283             auth[i] = 0;
284             for (bit = 1; bit < 256; bit <<= 1) {
285                 _XdmcpAuthDoIt (tdata, tdata, schedule, 1);
286                 if (tdata[0] + tdata[1] & 0x4)
287                     auth[i] |= bit;
288             }
289         }
290     }
291 #else
292
293     InitCryptoKey ();
294
295 #if defined(USE_CRYPT)
296     {
297         int         i, j, k;
298         char    *result, *crypt ();
299         char    cdata[9];
300         long    sdata;
301     
302         for (j = 0; j < 2; j++)
303         {
304             sdata = ldata[j];
305             for (i = 0; i < 4; i++)
306             {
307                 k = j * 4 + i;
308                 cdata[k] = sdata & 0xff;
309                 if (cdata[k] == 0)
310                     cdata[k] = 1;
311                 sdata >>= 8;
312             }
313         }
314         cdata[8] = '\0';
315         for (i = 0; i < len; i += 4)
316         {
317             result = crypt (cdata, (const char *) key);
318             k = 4;
319             if (i + k > len)
320                 k = len - i;
321             for (j = 0; j < k; j++)
322                 auth[i + j] = result[2 + j];
323             for (j = 0; j < 8; j++)
324                 cdata[j] = result[2 + j];
325         }
326     }
327 #elif defined(USE_ENCRYPT)
328     {
329         char    key_bits[64];
330         char    data_bits[64];
331         int         bit;
332         int         i;
333     
334         bitsToBytes (key, key_bits);
335         bitsToBytes (ldata, data_bits);
336         setkey (key_bits);
337         for (i = 0; i < len; i++) {
338             auth[i] = 0;
339             for (bit = 1; bit < 256; bit <<= 1) {
340                 encrypt (data_bits, 0);
341                 if (data_bits[bit])
342                     auth[i] |= bit;
343             }
344         }
345     }
346 #else
347     {
348         int         seed;
349         int         value;
350         int         i;
351     
352         seed = (ldata[0] + key[0]) +
353               ((ldata[1] + key[1]) << 16);
354         xdm_srand (seed);
355         for (i = 0; i < len; i++)
356         {
357             value = xdm_rand ();
358             auth[i] = (value & 0xff00)  >> 8;
359         }
360         value = len;
361         if (value > sizeof (key))
362             value = sizeof (key);
363         memmove( (char *) key, auth, value);
364     }
365 #endif
366 #endif
367 }
368
369 #ifndef HASXDMAUTH
370
371 static int  cryptoInited = 0;
372
373 int 
374 InitCryptoKey( void )
375 {
376     char    *key_file = "/dev/mem";
377     
378     if (cryptoInited)
379         return;
380
381     /*
382      *  If the sumFile fails to produce a result
383      *  use the time of day.
384      */
385     if (!sumFile (key_file, key)) {
386
387 #ifdef ITIMER_REAL
388       {
389         struct timeval  now;
390         struct timezone zone;
391         gettimeofday (&now, &zone);
392         key[0] = now.tv_sec;
393         key[1] = now.tv_usec;
394       }
395 #else
396       {
397         long    time ();
398         
399         key[0] = time ((long *) 0);
400         key[1] = getpid ();
401       }
402 #endif
403
404     }
405     cryptoInited = 1;
406 }
407
408 #endif /* HASXDMAUTH */