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
10 #include <afsconfig.h>
12 #include "afs/param.h"
14 #include <afs/param.h>
22 #include "afs/sysincludes.h"
23 #include "afsincludes.h"
25 #include "afs/pthread_glock.h"
26 #include "afs/cellconfig.h"
27 #include "afs/afsutil.h"
29 #include "afs/kauth.h"
30 #include "afs/kautils.h"
31 #include "afs/pthread_glock.h"
34 #else /* defined(UKERNEL) */
36 #include <afs/pthread_glock.h>
47 #include <afs/cellconfig.h>
49 #include <afs/afsutil.h>
52 #endif /* defined(UKERNEL) */
55 /* This defines the Andrew string_to_key function. It accepts a password
56 string as input and converts it via a one-way encryption algorithm to a DES
57 encryption key. It is compatible with the original Andrew authentication
58 service password database. */
61 Andrew_StringToKey(char *str, char *cell, /* cell for password */
62 struct ktc_encryptionKey *key)
64 char password[8 + 1]; /* crypt's limit is 8 chars anyway */
68 memset(key, 0, sizeof(struct ktc_encryptionKey));
70 strncpy(password, cell, 8);
71 passlen = strlen(str);
75 for (i = 0; i < passlen; i++)
76 password[i] ^= str[i];
78 for (i = 0; i < 8; i++)
79 if (password[i] == '\0')
82 /* crypt only considers the first 8 characters of password but for some
83 * reason returns eleven characters of result (plus the two salt chars). */
84 strncpy((char *)key, (char *)crypt(password, "p1") + 2,
85 sizeof(struct ktc_encryptionKey));
87 /* parity is inserted into the LSB so leftshift each byte up one bit. This
88 * allows ascii characters with a zero MSB to retain as much significance
91 char *keybytes = (char *)key;
94 for (i = 0; i < 8; i++) {
95 temp = (unsigned int)keybytes[i];
96 keybytes[i] = (unsigned char)(temp << 1);
99 des_fixup_key_parity(key);
103 StringToKey(char *str, char *cell, /* cell for password */
104 struct ktc_encryptionKey *key)
106 des_key_schedule schedule;
109 char password[BUFSIZ];
112 strncpy(password, str, sizeof(password));
113 if ((passlen = strlen(password)) < sizeof(password) - 1)
114 strncat(password, cell, sizeof(password) - passlen);
115 if ((passlen = strlen(password)) > sizeof(password))
116 passlen = sizeof(password);
118 memcpy(ivec, "kerberos", 8);
119 memcpy(temp_key, "kerberos", 8);
120 des_fixup_key_parity(temp_key);
121 des_key_sched(temp_key, schedule);
122 des_cbc_cksum(password, ivec, passlen, schedule, ivec);
124 memcpy(temp_key, ivec, 8);
125 des_fixup_key_parity(temp_key);
126 des_key_sched(temp_key, schedule);
127 des_cbc_cksum(password, key, passlen, schedule, ivec);
129 des_fixup_key_parity(key);
133 ka_StringToKey(char *str, char *cell, /* cell for password */
134 struct ktc_encryptionKey *key)
136 char realm[MAXKTCREALMLEN];
140 code = ka_CellToRealm(cell, realm, 0 /*local */ );
141 if (code) /* just take his word for it */
142 strncpy(realm, cell, sizeof(realm));
143 else /* for backward compatibility */
144 lcstring(realm, realm, sizeof(realm));
146 StringToKey(str, realm, key);
148 Andrew_StringToKey(str, realm, key);
152 /* This prints out a prompt and reads a string from the terminal, turning off
153 echoing. If verify is requested it requests that the string be entered
154 again and the two strings are compared. The string is then converted to a
155 DES encryption key. */
158 KAREADPW - some error returned from read_pw_string
162 ka_ReadPassword(char *prompt, int verify, char *cell,
163 struct ktc_encryptionKey *key)
165 char password[BUFSIZ];
169 memset(key, 0, sizeof(struct ktc_encryptionKey));
170 code = read_pw_string(password, sizeof(password), prompt, verify);
175 if (strlen(password) == 0) {
177 return KANULLPASSWORD;
179 ka_StringToKey(password, cell, key);
184 /* This performs the backslash quoting defined by AC_ParseLoginName. */
194 if ((c >= '0') && (c <= '7')) {
196 c = (c * 8) + (str[++(*ip)] - '0');
197 c = (c * 8) + (str[++(*ip)] - '0');
203 /* This routine parses a string that might be entered by a user from the
204 terminal. It defines a syntax to allow a user to specify his identity in
205 terms of his name, instance and cell with a single string. These three
206 output strings must be allocated by the caller to their maximum length. The
207 syntax is very simple: the first dot ('.') separates the name from the
208 instance and the first atsign ('@') begins the cell name. A backslash ('\')
209 can be used to quote these special characters. A backslash followed by an
210 octal digit (zero through seven) introduces a three digit octal number which
211 is interpreted as the ascii value of a single character. */
214 KABADARGUMENT - if no output parameters are specified.
215 KABADNAME - if a component of the user name is too long or if a cell was
216 specified but the cell parameter was null.
220 ka_ParseLoginName(char *login, char name[MAXKTCNAMELEN],
221 char inst[MAXKTCNAMELEN], char cell[MAXKTCREALMLEN])
223 int login_len = strlen(login);
232 return KABADARGUMENT;
241 while (i < login_len) {
243 c = map_char(login, &i);
247 name[j] = 0; /* finish name */
248 reading = READCELL; /* but instance is null */
252 if (inst && (rc == '.')) {
253 name[j] = 0; /* finish name */
258 if (j >= MAXKTCNAMELEN - 1)
266 inst[j] = 0; /* finish name */
271 if (j >= MAXKTCNAMELEN - 1)
278 if (j >= MAXKTCREALMLEN - 1)
285 if (reading == READNAME)
287 else if (reading == READINST) {
292 } else if (reading == READCELL) {
299 /* the cell is really an authDomain and therefore is really a realm */
301 ucstring(cell, cell, MAXKTCREALMLEN);
305 /* Client side applications should call this to initialize error tables and
306 connect to the correct CellServDB file. */
310 { /* reserved for future use. */
312 static int inited = 0;
320 initialize_U_error_table();
321 initialize_KA_error_table();
322 initialize_RXK_error_table();
323 initialize_KTC_error_table();
324 initialize_ACFG_error_table();
325 code = ka_CellConfig(AFSDIR_CLIENT_ETC_DIRPATH);
336 struct ktc_encryptionKey key;
339 char name[MAXKTCNAMELEN];
340 char instance[MAXKTCNAMELEN];
341 char cell[MAXKTCREALMLEN];
343 printf("Enter login:");
344 fgets(line, 255, stdin);
345 ka_ParseLoginName(line, name, instance, cell);
346 printf("'%s' '%s' '%s'\n", name, instance, cell);