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>
19 #if defined(HAVE_UNISTD_H) && !defined(__USE_XOPEN)
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/des_prototypes.h"
35 #else /* defined(UKERNEL) */
37 #include <afs/pthread_glock.h>
45 #if !defined(__USE_XOPEN)
50 #include <afs/cellconfig.h>
52 #include <afs/afsutil.h>
54 #include <des_prototypes.h>
57 #endif /* defined(UKERNEL) */
60 /* This defines the Andrew string_to_key function. It accepts a password
61 string as input and converts it via a one-way encryption algorithm to a DES
62 encryption key. It is compatible with the original Andrew authentication
63 service password database. */
66 Andrew_StringToKey(char *str, char *cell, /* cell for password */
67 struct ktc_encryptionKey *key)
69 char password[8 + 1]; /* crypt's limit is 8 chars anyway */
73 memset(key, 0, sizeof(struct ktc_encryptionKey));
75 strncpy(password, cell, 8);
76 passlen = strlen(str);
80 for (i = 0; i < passlen; i++)
81 password[i] ^= str[i];
83 for (i = 0; i < 8; i++)
84 if (password[i] == '\0')
87 /* crypt only considers the first 8 characters of password but for some
88 * reason returns eleven characters of result (plus the two salt chars). */
89 strncpy((char *)key, (char *)crypt(password, "p1") + 2,
90 sizeof(struct ktc_encryptionKey));
92 /* parity is inserted into the LSB so leftshift each byte up one bit. This
93 * allows ascii characters with a zero MSB to retain as much significance
96 char *keybytes = (char *)key;
99 for (i = 0; i < 8; i++) {
100 temp = (unsigned int)keybytes[i];
101 keybytes[i] = (unsigned char)(temp << 1);
104 des_fixup_key_parity(ktc_to_cblock(key));
108 StringToKey(char *str, char *cell, /* cell for password */
109 struct ktc_encryptionKey *key)
111 des_key_schedule schedule;
112 unsigned char temp_key[8];
114 char password[BUFSIZ];
117 strncpy(password, str, sizeof(password));
118 if ((passlen = strlen(password)) < sizeof(password) - 1)
119 strncat(password, cell, sizeof(password) - passlen);
120 if ((passlen = strlen(password)) > sizeof(password))
121 passlen = sizeof(password);
123 memcpy(ivec, "kerberos", 8);
124 memcpy(temp_key, "kerberos", 8);
125 des_fixup_key_parity(temp_key);
126 des_key_sched(temp_key, schedule);
127 des_cbc_cksum(charptr_to_cblockptr(password), charptr_to_cblockptr(ivec), passlen, schedule, charptr_to_cblockptr(ivec));
129 memcpy(temp_key, ivec, 8);
130 des_fixup_key_parity(temp_key);
131 des_key_sched(temp_key, schedule);
132 des_cbc_cksum(charptr_to_cblockptr(password), ktc_to_cblockptr(key), passlen, schedule, charptr_to_cblockptr(ivec));
134 des_fixup_key_parity(ktc_to_cblock(key));
138 ka_StringToKey(char *str, char *cell, /* cell for password */
139 struct ktc_encryptionKey *key)
141 char realm[MAXKTCREALMLEN];
145 code = ka_CellToRealm(cell, realm, 0 /*local */ );
146 if (code) /* just take his word for it */
147 strncpy(realm, cell, sizeof(realm));
148 else /* for backward compatibility */
149 lcstring(realm, realm, sizeof(realm));
151 StringToKey(str, realm, key);
153 Andrew_StringToKey(str, realm, key);
157 /* This prints out a prompt and reads a string from the terminal, turning off
158 echoing. If verify is requested it requests that the string be entered
159 again and the two strings are compared. The string is then converted to a
160 DES encryption key. */
163 KAREADPW - some error returned from read_pw_string
167 ka_ReadPassword(char *prompt, int verify, char *cell,
168 struct ktc_encryptionKey *key)
170 char password[BUFSIZ];
174 memset(key, 0, sizeof(struct ktc_encryptionKey));
175 code = read_pw_string(password, sizeof(password), prompt, verify);
180 if (strlen(password) == 0) {
182 return KANULLPASSWORD;
184 ka_StringToKey(password, cell, key);
189 /* This performs the backslash quoting defined by AC_ParseLoginName. */
192 map_char(char *str, int *ip)
197 if ((c >= '0') && (c <= '7')) {
199 c = (c * 8) + (str[++(*ip)] - '0');
200 c = (c * 8) + (str[++(*ip)] - '0');
206 /* This routine parses a string that might be entered by a user from the
207 terminal. It defines a syntax to allow a user to specify his identity in
208 terms of his name, instance and cell with a single string. These three
209 output strings must be allocated by the caller to their maximum length. The
210 syntax is very simple: the first dot ('.') separates the name from the
211 instance and the first atsign ('@') begins the cell name. A backslash ('\')
212 can be used to quote these special characters. A backslash followed by an
213 octal digit (zero through seven) introduces a three digit octal number which
214 is interpreted as the ascii value of a single character. */
217 KABADARGUMENT - if no output parameters are specified.
218 KABADNAME - if a component of the user name is too long or if a cell was
219 specified but the cell parameter was null.
223 ka_ParseLoginName(char *login, char name[MAXKTCNAMELEN],
224 char inst[MAXKTCNAMELEN], char cell[MAXKTCREALMLEN])
226 int login_len = strlen(login);
235 return KABADARGUMENT;
244 while (i < login_len) {
246 c = map_char(login, &i);
250 name[j] = 0; /* finish name */
251 reading = READCELL; /* but instance is null */
255 if (inst && (rc == '.')) {
256 name[j] = 0; /* finish name */
261 if (j >= MAXKTCNAMELEN - 1)
269 inst[j] = 0; /* finish name */
274 if (j >= MAXKTCNAMELEN - 1)
281 if (j >= MAXKTCREALMLEN - 1)
288 if (reading == READNAME)
290 else if (reading == READINST) {
295 } else if (reading == READCELL) {
302 /* the cell is really an authDomain and therefore is really a realm */
304 ucstring(cell, cell, MAXKTCREALMLEN);
308 /* Client side applications should call this to initialize error tables and
309 connect to the correct CellServDB file. */
313 { /* reserved for future use. */
315 static int inited = 0;
323 initialize_U_error_table();
324 initialize_KA_error_table();
325 initialize_RXK_error_table();
326 initialize_KTC_error_table();
327 initialize_ACFG_error_table();
328 code = ka_CellConfig(AFSDIR_CLIENT_ETC_DIRPATH);
339 struct ktc_encryptionKey key;
342 char name[MAXKTCNAMELEN];
343 char instance[MAXKTCNAMELEN];
344 char cell[MAXKTCREALMLEN];
346 printf("Enter login:");
347 fgets(line, 255, stdin);
348 ka_ParseLoginName(line, name, instance, cell);
349 printf("'%s' '%s' '%s'\n", name, instance, cell);