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>
24 #include "afs/sysincludes.h"
25 #include "afsincludes.h"
27 #include "afs/pthread_glock.h"
28 #include "afs/cellconfig.h"
29 #include "afs/afsutil.h"
31 #include "afs/kauth.h"
32 #include "afs/kautils.h"
33 #include "afs/pthread_glock.h"
36 #else /* defined(UKERNEL) */
38 #include <afs/pthread_glock.h>
55 #include <afs/cellconfig.h>
57 #include <afs/afsutil.h>
60 #endif /* defined(UKERNEL) */
63 /* This defines the Andrew string_to_key function. It accepts a password
64 string as input and converts it via a one-way encryption algorithm to a DES
65 encryption key. It is compatible with the original Andrew authentication
66 service password database. */
69 Andrew_StringToKey(char *str, char *cell, /* cell for password */
70 struct ktc_encryptionKey *key)
72 char password[8 + 1]; /* crypt's limit is 8 chars anyway */
76 memset(key, 0, sizeof(struct ktc_encryptionKey));
78 strncpy(password, cell, 8);
79 passlen = strlen(str);
83 for (i = 0; i < passlen; i++)
84 password[i] ^= str[i];
86 for (i = 0; i < 8; i++)
87 if (password[i] == '\0')
90 /* crypt only considers the first 8 characters of password but for some
91 * reason returns eleven characters of result (plus the two salt chars). */
92 strncpy((char *)key, (char *)crypt(password, "p1") + 2,
93 sizeof(struct ktc_encryptionKey));
95 /* parity is inserted into the LSB so leftshift each byte up one bit. This
96 * allows ascii characters with a zero MSB to retain as much significance
99 char *keybytes = (char *)key;
102 for (i = 0; i < 8; i++) {
103 temp = (unsigned int)keybytes[i];
104 keybytes[i] = (unsigned char)(temp << 1);
107 des_fixup_key_parity(key);
111 StringToKey(char *str, char *cell, /* cell for password */
112 struct ktc_encryptionKey *key)
114 des_key_schedule schedule;
117 char password[BUFSIZ];
120 strncpy(password, str, sizeof(password));
121 if ((passlen = strlen(password)) < sizeof(password) - 1)
122 strncat(password, cell, sizeof(password) - passlen);
123 if ((passlen = strlen(password)) > sizeof(password))
124 passlen = sizeof(password);
126 memcpy(ivec, "kerberos", 8);
127 memcpy(temp_key, "kerberos", 8);
128 des_fixup_key_parity(temp_key);
129 des_key_sched(temp_key, schedule);
130 des_cbc_cksum(password, ivec, passlen, schedule, ivec);
132 memcpy(temp_key, ivec, 8);
133 des_fixup_key_parity(temp_key);
134 des_key_sched(temp_key, schedule);
135 des_cbc_cksum(password, key, passlen, schedule, ivec);
137 des_fixup_key_parity(key);
141 ka_StringToKey(char *str, char *cell, /* cell for password */
142 struct ktc_encryptionKey *key)
144 char realm[MAXKTCREALMLEN];
148 code = ka_CellToRealm(cell, realm, 0 /*local */ );
149 if (code) /* just take his word for it */
150 strncpy(realm, cell, sizeof(realm));
151 else /* for backward compatibility */
152 lcstring(realm, realm, sizeof(realm));
154 StringToKey(str, realm, key);
156 Andrew_StringToKey(str, realm, key);
160 /* This prints out a prompt and reads a string from the terminal, turning off
161 echoing. If verify is requested it requests that the string be entered
162 again and the two strings are compared. The string is then converted to a
163 DES encryption key. */
166 KAREADPW - some error returned from read_pw_string
170 ka_ReadPassword(char *prompt, int verify, char *cell,
171 struct ktc_encryptionKey *key)
173 char password[BUFSIZ];
177 memset(key, 0, sizeof(struct ktc_encryptionKey));
178 code = read_pw_string(password, sizeof(password), prompt, verify);
183 if (strlen(password) == 0) {
185 return KANULLPASSWORD;
187 ka_StringToKey(password, cell, key);
192 /* This performs the backslash quoting defined by AC_ParseLoginName. */
202 if ((c >= '0') && (c <= '7')) {
204 c = (c * 8) + (str[++(*ip)] - '0');
205 c = (c * 8) + (str[++(*ip)] - '0');
211 /* This routine parses a string that might be entered by a user from the
212 terminal. It defines a syntax to allow a user to specify his identity in
213 terms of his name, instance and cell with a single string. These three
214 output strings must be allocated by the caller to their maximum length. The
215 syntax is very simple: the first dot ('.') separates the name from the
216 instance and the first atsign ('@') begins the cell name. A backslash ('\')
217 can be used to quote these special characters. A backslash followed by an
218 octal digit (zero through seven) introduces a three digit octal number which
219 is interpreted as the ascii value of a single character. */
222 KABADARGUMENT - if no output parameters are specified.
223 KABADNAME - if a component of the user name is too long or if a cell was
224 specified but the cell parameter was null.
228 ka_ParseLoginName(char *login, char name[MAXKTCNAMELEN],
229 char inst[MAXKTCNAMELEN], char cell[MAXKTCREALMLEN])
231 int login_len = strlen(login);
240 return KABADARGUMENT;
249 while (i < login_len) {
251 c = map_char(login, &i);
255 name[j] = 0; /* finish name */
256 reading = READCELL; /* but instance is null */
260 if (inst && (rc == '.')) {
261 name[j] = 0; /* finish name */
266 if (j >= MAXKTCNAMELEN - 1)
274 inst[j] = 0; /* finish name */
279 if (j >= MAXKTCNAMELEN - 1)
286 if (j >= MAXKTCREALMLEN - 1)
293 if (reading == READNAME)
295 else if (reading == READINST) {
300 } else if (reading == READCELL) {
307 /* the cell is really an authDomain and therefore is really a realm */
309 ucstring(cell, cell, MAXKTCREALMLEN);
313 /* Client side applications should call this to initialize error tables and
314 connect to the correct CellServDB file. */
318 { /* reserved for future use. */
320 static int inited = 0;
328 initialize_U_error_table();
329 initialize_KA_error_table();
330 initialize_RXK_error_table();
331 initialize_KTC_error_table();
332 initialize_ACFG_error_table();
333 code = ka_CellConfig(AFSDIR_CLIENT_ETC_DIRPATH);
344 struct ktc_encryptionKey key;
347 char name[MAXKTCNAMELEN];
348 char instance[MAXKTCNAMELEN];
349 char cell[MAXKTCREALMLEN];
351 printf("Enter login:");
352 fgets(line, 255, stdin);
353 ka_ParseLoginName(line, name, instance, cell);
354 printf("'%s' '%s' '%s'\n", name, instance, cell);