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"
33 #include <des_prototypes.h>
35 #else /* defined(UKERNEL) */
37 #include <afs/pthread_glock.h>
48 #include <afs/cellconfig.h>
50 #include <afs/afsutil.h>
53 #endif /* defined(UKERNEL) */
56 /* This defines the Andrew string_to_key function. It accepts a password
57 string as input and converts it via a one-way encryption algorithm to a DES
58 encryption key. It is compatible with the original Andrew authentication
59 service password database. */
62 Andrew_StringToKey(char *str, char *cell, /* cell for password */
63 struct ktc_encryptionKey *key)
65 char password[8 + 1]; /* crypt's limit is 8 chars anyway */
69 memset(key, 0, sizeof(struct ktc_encryptionKey));
71 strncpy(password, cell, 8);
72 passlen = strlen(str);
76 for (i = 0; i < passlen; i++)
77 password[i] ^= str[i];
79 for (i = 0; i < 8; i++)
80 if (password[i] == '\0')
83 /* crypt only considers the first 8 characters of password but for some
84 * reason returns eleven characters of result (plus the two salt chars). */
85 strncpy((char *)key, (char *)crypt(password, "p1") + 2,
86 sizeof(struct ktc_encryptionKey));
88 /* parity is inserted into the LSB so leftshift each byte up one bit. This
89 * allows ascii characters with a zero MSB to retain as much significance
92 char *keybytes = (char *)key;
95 for (i = 0; i < 8; i++) {
96 temp = (unsigned int)keybytes[i];
97 keybytes[i] = (unsigned char)(temp << 1);
100 des_fixup_key_parity(key);
104 StringToKey(char *str, char *cell, /* cell for password */
105 struct ktc_encryptionKey *key)
107 des_key_schedule schedule;
110 char password[BUFSIZ];
113 strncpy(password, str, sizeof(password));
114 if ((passlen = strlen(password)) < sizeof(password) - 1)
115 strncat(password, cell, sizeof(password) - passlen);
116 if ((passlen = strlen(password)) > sizeof(password))
117 passlen = sizeof(password);
119 memcpy(ivec, "kerberos", 8);
120 memcpy(temp_key, "kerberos", 8);
121 des_fixup_key_parity(temp_key);
122 des_key_sched(temp_key, schedule);
123 des_cbc_cksum(password, ivec, passlen, schedule, ivec);
125 memcpy(temp_key, ivec, 8);
126 des_fixup_key_parity(temp_key);
127 des_key_sched(temp_key, schedule);
128 des_cbc_cksum(password, key, passlen, schedule, ivec);
130 des_fixup_key_parity(key);
134 ka_StringToKey(char *str, char *cell, /* cell for password */
135 struct ktc_encryptionKey *key)
137 char realm[MAXKTCREALMLEN];
141 code = ka_CellToRealm(cell, realm, 0 /*local */ );
142 if (code) /* just take his word for it */
143 strncpy(realm, cell, sizeof(realm));
144 else /* for backward compatibility */
145 lcstring(realm, realm, sizeof(realm));
147 StringToKey(str, realm, key);
149 Andrew_StringToKey(str, realm, key);
153 /* This prints out a prompt and reads a string from the terminal, turning off
154 echoing. If verify is requested it requests that the string be entered
155 again and the two strings are compared. The string is then converted to a
156 DES encryption key. */
159 KAREADPW - some error returned from read_pw_string
163 ka_ReadPassword(char *prompt, int verify, char *cell,
164 struct ktc_encryptionKey *key)
166 char password[BUFSIZ];
170 memset(key, 0, sizeof(struct ktc_encryptionKey));
171 code = read_pw_string(password, sizeof(password), prompt, verify);
176 if (strlen(password) == 0) {
178 return KANULLPASSWORD;
180 ka_StringToKey(password, cell, key);
185 /* This performs the backslash quoting defined by AC_ParseLoginName. */
188 map_char(char *str, int *ip)
193 if ((c >= '0') && (c <= '7')) {
195 c = (c * 8) + (str[++(*ip)] - '0');
196 c = (c * 8) + (str[++(*ip)] - '0');
202 /* This routine parses a string that might be entered by a user from the
203 terminal. It defines a syntax to allow a user to specify his identity in
204 terms of his name, instance and cell with a single string. These three
205 output strings must be allocated by the caller to their maximum length. The
206 syntax is very simple: the first dot ('.') separates the name from the
207 instance and the first atsign ('@') begins the cell name. A backslash ('\')
208 can be used to quote these special characters. A backslash followed by an
209 octal digit (zero through seven) introduces a three digit octal number which
210 is interpreted as the ascii value of a single character. */
213 KABADARGUMENT - if no output parameters are specified.
214 KABADNAME - if a component of the user name is too long or if a cell was
215 specified but the cell parameter was null.
219 ka_ParseLoginName(char *login, char name[MAXKTCNAMELEN],
220 char inst[MAXKTCNAMELEN], char cell[MAXKTCREALMLEN])
222 int login_len = strlen(login);
231 return KABADARGUMENT;
240 while (i < login_len) {
242 c = map_char(login, &i);
246 name[j] = 0; /* finish name */
247 reading = READCELL; /* but instance is null */
251 if (inst && (rc == '.')) {
252 name[j] = 0; /* finish name */
257 if (j >= MAXKTCNAMELEN - 1)
265 inst[j] = 0; /* finish name */
270 if (j >= MAXKTCNAMELEN - 1)
277 if (j >= MAXKTCREALMLEN - 1)
284 if (reading == READNAME)
286 else if (reading == READINST) {
291 } else if (reading == READCELL) {
298 /* the cell is really an authDomain and therefore is really a realm */
300 ucstring(cell, cell, MAXKTCREALMLEN);
304 /* Client side applications should call this to initialize error tables and
305 connect to the correct CellServDB file. */
309 { /* reserved for future use. */
311 static int inited = 0;
319 initialize_U_error_table();
320 initialize_KA_error_table();
321 initialize_RXK_error_table();
322 initialize_KTC_error_table();
323 initialize_ACFG_error_table();
324 code = ka_CellConfig(AFSDIR_CLIENT_ETC_DIRPATH);
335 struct ktc_encryptionKey key;
338 char name[MAXKTCNAMELEN];
339 char instance[MAXKTCNAMELEN];
340 char cell[MAXKTCREALMLEN];
342 printf("Enter login:");
343 fgets(line, 255, stdin);
344 ka_ParseLoginName(line, name, instance, cell);
345 printf("'%s' '%s' '%s'\n", name, instance, cell);