2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
11 * Revision 2.2 90/08/20 11:15:39
12 * Include permit_xprt.h.
13 * Cleanup line length.
15 /* See RCS log for older history. */
18 #include "../afs/param.h"
19 #include "../afs/sysincludes.h"
20 #include "../afs/afsincludes.h"
21 #include "../afs/stds.h"
22 #include "../afs/pthread_glock.h"
23 #include "../afs/cellconfig.h"
24 #include "../afs/afsutil.h"
25 #include "../afs/auth.h"
26 #include "../afsint/kauth.h"
27 #include "../afs/kautils.h"
28 #include "../afs/pthread_glock.h"
29 #include "../des/des.h"
31 #include "../afs/permit_xprt.h"
32 #else /* defined(UKERNEL) */
33 #include <afs/param.h>
35 #include <afs/pthread_glock.h>
41 #include <afs/cellconfig.h>
43 #include <afs/afsutil.h>
47 #include "../permit_xprt.h"
48 #endif /* defined(UKERNEL) */
51 /* This defines the Andrew string_to_key function. It accepts a password
52 string as input and converts it via a one-way encryption algorithm to a DES
53 encryption key. It is compatible with the original Andrew authentication
54 service password database. */
56 static void Andrew_StringToKey (
58 char *cell, /* cell for password */
59 struct ktc_encryptionKey *key)
60 { char password[8+1]; /* crypt's limit is 8 chars anyway */
64 bzero (key, sizeof(struct ktc_encryptionKey));
66 strncpy (password, cell, 8);
67 passlen = strlen (str);
68 if (passlen > 8) passlen = 8;
70 for (i=0; i<passlen; i++)
71 password[i] ^= str[i];
74 if (password[i] == '\0') password[i] = 'X';
76 /* crypt only considers the first 8 characters of password but for some
77 reason returns eleven characters of result (plus the two salt chars). */
79 (char *)crypt(password, "p1") + 2,
80 sizeof(struct ktc_encryptionKey));
82 /* parity is inserted into the LSB so leftshift each byte up one bit. This
83 allows ascii characters with a zero MSB to retain as much significance
85 { char *keybytes = (char *)key;
88 for (i = 0; i < 8; i++) {
89 temp = (unsigned int) keybytes[i];
90 keybytes[i] = (unsigned char) (temp << 1);
93 des_fixup_key_parity (key);
96 static void StringToKey (
98 char *cell, /* cell for password */
99 struct ktc_encryptionKey *key)
100 { des_key_schedule schedule;
103 char password[BUFSIZ];
106 strncpy (password, str, sizeof(password));
107 if ((passlen = strlen (password)) < sizeof(password)-1)
108 strncat (password, cell, sizeof(password)-passlen);
109 if ((passlen = strlen(password)) > sizeof(password))
110 passlen = sizeof(password);
112 bcopy ("kerberos", ivec, 8);
113 bcopy ("kerberos", temp_key, 8);
114 des_fixup_key_parity (temp_key);
115 des_key_sched (temp_key, schedule);
116 des_cbc_cksum (password, ivec, passlen, schedule, ivec);
118 bcopy (ivec, temp_key, 8);
119 des_fixup_key_parity (temp_key);
120 des_key_sched (temp_key, schedule);
121 des_cbc_cksum (password, key, passlen, schedule, ivec);
123 des_fixup_key_parity (key);
126 void ka_StringToKey (
128 char *cell, /* cell for password */
129 struct ktc_encryptionKey *key)
131 char realm[MAXKTCREALMLEN];
135 code = ka_CellToRealm (cell, realm, 0/*local*/);
136 if (code) /* just take his word for it */
137 strncpy (realm, cell, sizeof(realm));
138 else /* for backward compatibility */
139 lcstring (realm, realm, sizeof(realm));
140 if (strlen(str) > 8) StringToKey (str, realm, key);
141 else Andrew_StringToKey (str, realm, key);
145 /* This prints out a prompt and reads a string from the terminal, turning off
146 echoing. If verify is requested it requests that the string be entered
147 again and the two strings are compared. The string is then converted to a
148 DES encryption key. */
151 KAREADPW - some error returned from read_pw_string
154 afs_int32 ka_ReadPassword (
158 struct ktc_encryptionKey *key)
160 char password[BUFSIZ];
164 bzero (key, sizeof(struct ktc_encryptionKey));
165 code = read_pw_string (password, sizeof(password), prompt, verify);
170 if (strlen(password) == 0) {
172 return KANULLPASSWORD;
174 ka_StringToKey (password, cell, key);
179 /* This performs the backslash quoting defined by AC_ParseLoginName. */
181 static char map_char (str, ip)
187 if ((c >= '0') && (c <= '7')) {
189 c = (c * 8) + (str[++(*ip)] - '0');
190 c = (c * 8) + (str[++(*ip)] - '0');
195 /* This routine parses a string that might be entered by a user from the
196 terminal. It defines a syntax to allow a user to specify his identity in
197 terms of his name, instance and cell with a single string. These three
198 output strings must be allocated by the caller to their maximum length. The
199 syntax is very simple: the first dot ('.') separates the name from the
200 instance and the first atsign ('@') begins the cell name. A backslash ('\')
201 can be used to quote these special characters. A backslash followed by an
202 octal digit (zero through seven) introduces a three digit octal number which
203 is interpreted as the ascii value of a single character. */
206 KABADARGUMENT - if no output parameters are specified.
207 KABADNAME - if a component of the user name is too long or if a cell was
208 specified but the cell parameter was null.
211 afs_int32 ka_ParseLoginName (
213 char name[MAXKTCNAMELEN],
214 char inst[MAXKTCNAMELEN],
215 char cell[MAXKTCREALMLEN])
217 int login_len = strlen (login);
225 if (!name) return KABADARGUMENT;
227 if (inst) strcpy (inst, "");
228 if (cell) strcpy (cell, "");
232 while (i < login_len) {
234 c = map_char (login, &i);
238 name[j] = 0; /* finish name */
239 reading = READCELL; /* but instance is null */
243 if (inst && (rc == '.')) {
244 name[j] = 0; /* finish name */
249 if (j >= MAXKTCNAMELEN-1) return KABADNAME;
253 if (!inst) return KABADNAME;
255 inst[j] = 0; /* finish name */
260 if (j >= MAXKTCNAMELEN-1) return KABADNAME;
264 if (!cell) return KABADNAME;
265 if (j >= MAXKTCREALMLEN-1) return KABADNAME;
271 if (reading == READNAME) name[j] = 0;
272 else if (reading == READINST) {
273 if (inst) inst[j] = 0;
274 else return KABADNAME;
276 else if (reading == READCELL) {
277 if (cell) cell[j] = 0;
278 else return KABADNAME;
281 /* the cell is really an authDomain and therefore is really a realm */
282 if (cell) ucstring (cell, cell, MAXKTCREALMLEN);
286 /* Client side applications should call this to initialize error tables and
287 connect to the correct CellServDB file. */
289 afs_int32 ka_Init(int flags) /* reserved for future use. */
292 static int inited = 0;
300 initialize_u_error_table();
301 initialize_ka_error_table();
302 initialize_rxk_error_table();
303 initialize_ktc_error_table();
304 initialize_acfg_error_table();
305 code = ka_CellConfig (AFSDIR_CLIENT_ETC_DIRPATH);
308 if (code) return code;
314 { struct ktc_encryptionKey key;
317 char name[MAXKTCNAMELEN];
318 char instance[MAXKTCNAMELEN];
319 char cell[MAXKTCREALMLEN];
321 printf("Enter login:");
322 fgets (line, 255, stdin);
323 ka_ParseLoginName (line, name, instance, cell);
324 printf ("'%s' '%s' '%s'\n", name, instance, cell);