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