genauth.c 9.7 KB

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