Convert uses of XKeycodeToKeysym (deprecated) to XkbKeycodeToKeysym
[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 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: 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 #if !defined(DONT_USE_DES) && !defined(USE_CRYPT)
110 # if defined(AIXV3) || defined(hpux) || defined(__FreeBSD__)
111 #  define USE_CRYPT
112 # elif defined(__OpenBSD__)
113 #  define DONT_USE_DES
114 # elif defined(sun)
115 #  define USE_CRYPT
116 #  if (OSMAJORVERSION >= 4)
117     /* avoid strange sun crypt hackery */
118 #   define crypt _crypt
119 #  endif
120 # endif
121 # define USE_ENCRYPT
122 #endif
123
124 #ifdef HASXDMAUTH
125 static unsigned char    key[8];
126 #else
127 static long             key[2];
128 #endif
129
130 static sumFile (char *name, long sum[2]);
131
132 #ifdef HASXDMAUTH
133
134 typedef unsigned char auth_cblock[8];   /* block size */
135
136 typedef struct auth_ks_struct { auth_cblock _; } auth_wrapper_schedule[16];
137
138 extern void _XdmcpWrapperToOddParity();
139
140 static void
141 longtochars (long l, unsigned char *c)
142 {
143     c[0] = (l >> 24) & 0xff;
144     c[1] = (l >> 16) & 0xff;
145     c[2] = (l >> 8) & 0xff;
146     c[3] = l & 0xff;
147 }
148
149 static void
150 InitXdmcpWrapper (void)
151 {
152     long            sum[2];
153     unsigned char   tmpkey[8];
154 /*
155  * randomFile is and xdm resource not defined in dtlogin.
156  *
157  *   if (!sumFile (randomFile, sum)) {
158  */
159     if (!sumFile ("/dev/mem", sum)) {
160         sum[0] = time ((Time_t *) 0);
161         sum[1] = time ((Time_t *) 0);
162     }
163     longtochars (sum[0], tmpkey+0);
164     longtochars (sum[1], tmpkey+4);
165     tmpkey[0] = 0;
166     _XdmcpWrapperToOddParity (tmpkey, key);
167 }
168
169 #endif /* HASXDMAUTH */
170
171 #ifndef HASXDMAUTH
172 /* A random number generator that is more unpredictable
173    than that shipped with some systems.
174    This code is taken from the C standard. */
175
176 static unsigned long int next = 1;
177
178 static int
179 xdm_rand(void)
180 {
181     next = next * 1103515245 + 12345;
182     return (unsigned int)(next/65536) % 32768;
183 }
184
185 static void
186 xdm_srand(unsigned int seed)
187 {
188     next = seed;
189 }
190 #endif /* no HASXDMAUTH */
191
192 #ifdef USE_ENCRYPT
193 static void
194 bitsToBytes (unsigned long bits[2], char bytes[64])
195 {
196     int bit, byte;
197     int i;
198
199     i = 0;
200     for (byte = 0; byte < 2; byte++)
201         for (bit = 0; bit < 32; bit++)
202             bytes[i++] = ((bits[byte] & (1 << bit)) != 0);
203 }
204 #endif /* USE_ENCRYPT */
205
206 # define FILE_LIMIT     1024    /* no more than this many buffers */
207
208 /* for linux/csrg we use a simpler method to get 2 random longs from
209  *  the OS's random number device.
210  */
211
212 #if defined(__linux__) || defined(CSRG_BASED) || defined(sun)
213 #define READ_LIMIT (sizeof (long) * 2)
214
215 static int
216 sumFile (char *name, long sum[2])
217 {
218   long    buf[2];
219   int     fd;
220   int     ret_status = 0;
221
222   if ( (fd = open (name, 0)) < 0 )
223     {
224       LogError((unsigned char *) "Cannot open randomFile \"%s\", errno = %d\n",
225                name, errno);
226       return 0;
227     }
228
229   sum[0] = 0;
230   sum[1] = 0;
231
232   if (read(fd, (char *)buf, READ_LIMIT) != READ_LIMIT)
233     {
234       LogError((unsigned char *) "Could not read %d bytes from '%s'\n",
235                READ_LIMIT, name);
236       /* cheap fallback */
237       sum[0] = (long)time((Time_t *) 0);
238       sum[1] = sum[0];
239     }
240   else
241     {
242       sum[0] = buf[0];
243       sum[1] = buf[1];
244       ret_status = 1;
245     }
246
247   close(fd);
248   return ret_status;
249 }
250
251 #undef READ_LIMIT
252
253 #else /* linux || CSRG_BASED */
254
255 static int
256 sumFile (char *name, long sum[2])
257 {
258     long    buf[1024*2];
259     int     cnt;
260     int     fd;
261     int     loops;
262     int     reads;
263     int     i;
264     int     ret_status = 0;
265
266     fd = open (name, 0);
267     if (fd < 0) {
268         LogError((unsigned char *) "Cannot open randomFile \"%s\", errno = %d\n", name, errno);
269         return 0;
270     }
271 #ifdef FRAGILE_DEV_MEM
272     if (strcmp(name, "/dev/mem") == 0) lseek (fd, (off_t) 0x100000, SEEK_SET);
273 #endif
274     reads = FILE_LIMIT;
275     sum[0] = 0;
276     sum[1] = 0;
277     while ((cnt = read (fd, (char *) buf, sizeof (buf))) > 0 && --reads > 0) {
278         loops = cnt / (2 * sizeof (long));
279         for (i = 0; i < loops; i+= 2) {
280             sum[0] += buf[i];
281             sum[1] += buf[i+1];
282             ret_status = 1;
283         }
284     }
285     if (cnt < 0)
286         LogError((unsigned char *) "Cannot read randomFile \"%s\", errno = %d\n", name, errno);
287     close (fd);
288     return ret_status;
289 }
290 #endif /* linux || CSRG_BASED */
291
292 void
293 GenerateAuthData (char *auth, int len)
294 {
295     long            ldata[2];
296
297 #ifdef ITIMER_REAL
298     {
299         struct timeval  now;
300
301         X_GETTIMEOFDAY (&now);
302         ldata[0] = now.tv_sec;
303         ldata[1] = now.tv_usec;
304     }
305 #else
306     {
307         long    time ();
308
309         ldata[0] = time ((long *) 0);
310         ldata[1] = getpid ();
311     }
312 #endif /* ITIMER_REAL */
313
314 #ifdef HASXDMAUTH
315     {
316         int                 bit;
317         int                 i;
318         auth_wrapper_schedule    schedule;
319         unsigned char       tdata[8];
320         static int          xdmcpAuthInited;
321     
322         longtochars (ldata[0], tdata+0);
323         longtochars (ldata[1], tdata+4);
324         if (!xdmcpAuthInited)
325         {
326             InitXdmcpWrapper ();
327             xdmcpAuthInited = 1;
328         }
329         _XdmcpAuthSetup (key, schedule);
330         for (i = 0; i < len; i++) {
331             auth[i] = 0;
332             for (bit = 1; bit < 256; bit <<= 1) {
333                 _XdmcpAuthDoIt (tdata, tdata, schedule, 1);
334                 if (tdata[0] + tdata[1] & 0x4)
335                     auth[i] |= bit;
336             }
337         }
338     }
339 #else
340
341     InitCryptoKey ();
342
343 #if defined(USE_CRYPT)
344     {
345         int         i, j, k;
346         char    *result, *crypt ();
347         char    cdata[9];
348         long    sdata;
349     
350         for (j = 0; j < 2; j++)
351         {
352             sdata = ldata[j];
353             for (i = 0; i < 4; i++)
354             {
355                 k = j * 4 + i;
356                 cdata[k] = sdata & 0xff;
357                 if (cdata[k] == 0)
358                     cdata[k] = 1;
359                 sdata >>= 8;
360             }
361         }
362         cdata[8] = '\0';
363         for (i = 0; i < len; i += 4)
364         {
365             result = crypt (cdata, (const char *) key);
366             k = 4;
367             if (i + k > len)
368                 k = len - i;
369             for (j = 0; j < k; j++)
370                 auth[i + j] = result[2 + j];
371             for (j = 0; j < 8; j++)
372                 cdata[j] = result[2 + j];
373         }
374     }
375 #elif defined(USE_ENCRYPT)
376     {
377         char    key_bits[64];
378         char    data_bits[64];
379         int         bit;
380         int         i;
381     
382         bitsToBytes (key, key_bits);
383         bitsToBytes (ldata, data_bits);
384         setkey (key_bits);
385         for (i = 0; i < len; i++) {
386             auth[i] = 0;
387             for (bit = 1; bit < 256; bit <<= 1) {
388                 encrypt (data_bits, 0);
389                 if (data_bits[bit])
390                     auth[i] |= bit;
391             }
392         }
393     }
394 #else
395     {
396         int         seed;
397         int         value;
398         int         i;
399     
400         seed = (ldata[0] + key[0]) +
401               ((ldata[1] + key[1]) << 16);
402         xdm_srand (seed);
403         for (i = 0; i < len; i++)
404         {
405             value = xdm_rand ();
406             auth[i] = (value & 0xff00)  >> 8;
407         }
408         value = len;
409         if (value > sizeof (key))
410             value = sizeof (key);
411         memmove( (char *) key, auth, value);
412     }
413 #endif
414 #endif
415 }
416
417 #ifndef HASXDMAUTH
418
419 static int  cryptoInited = 0;
420
421 int 
422 InitCryptoKey( void )
423 {
424 #if defined(__linux__)
425     /* non-blocking */
426     char    *key_file = "/dev/urandom";
427 #elif defined(CSRG_BASED) || defined(sun)
428     /* non-blocking */
429     char    *key_file = "/dev/random";
430 #else
431 # warning "Using /dev/mem for random bits."
432     /* JET - this seems like a really bad idea. */
433     char    *key_file = "/dev/mem";
434 #endif    
435     if (cryptoInited)
436         return 0;
437
438     /*
439      *  If the sumFile fails to produce a result
440      *  use the time of day.
441      */
442     if (!sumFile (key_file, key)) {
443
444 #ifdef ITIMER_REAL
445       {
446         struct timeval  now;
447         struct timezone zone;
448         gettimeofday (&now, &zone);
449         key[0] = now.tv_sec;
450         key[1] = now.tv_usec;
451       }
452 #else
453       {
454         long    time ();
455         
456         key[0] = time ((long *) 0);
457         key[1] = getpid ();
458       }
459 #endif
460
461     }
462     cryptoInited = 1;
463
464     return 1;
465 }
466
467 #endif /* HASXDMAUTH */