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