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>
49 #include <afs/cellconfig.h>
51 #include <afs/afsutil.h>
54 #endif /* defined(UKERNEL) */
57 /* This defines the Andrew string_to_key function. It accepts a password
58 string as input and converts it via a one-way encryption algorithm to a DES
59 encryption key. It is compatible with the original Andrew authentication
60 service password database. */
63 Andrew_StringToKey(char *str, char *cell, /* cell for password */
64 struct ktc_encryptionKey *key)
66 char password[8 + 1]; /* crypt's limit is 8 chars anyway */
70 memset(key, 0, sizeof(struct ktc_encryptionKey));
72 strncpy(password, cell, 8);
73 passlen = strlen(str);
77 for (i = 0; i < passlen; i++)
78 password[i] ^= str[i];
80 for (i = 0; i < 8; i++)
81 if (password[i] == '\0')
84 /* crypt only considers the first 8 characters of password but for some
85 * reason returns eleven characters of result (plus the two salt chars). */
86 strncpy((char *)key, (char *)crypt(password, "p1") + 2,
87 sizeof(struct ktc_encryptionKey));
89 /* parity is inserted into the LSB so leftshift each byte up one bit. This
90 * allows ascii characters with a zero MSB to retain as much significance
93 char *keybytes = (char *)key;
96 for (i = 0; i < 8; i++) {
97 temp = (unsigned int)keybytes[i];
98 keybytes[i] = (unsigned char)(temp << 1);
101 des_fixup_key_parity(key);
105 StringToKey(char *str, char *cell, /* cell for password */
106 struct ktc_encryptionKey *key)
108 des_key_schedule schedule;
111 char password[BUFSIZ];
114 strncpy(password, str, sizeof(password));
115 if ((passlen = strlen(password)) < sizeof(password) - 1)
116 strncat(password, cell, sizeof(password) - passlen);
117 if ((passlen = strlen(password)) > sizeof(password))
118 passlen = sizeof(password);
120 memcpy(ivec, "kerberos", 8);
121 memcpy(temp_key, "kerberos", 8);
122 des_fixup_key_parity(temp_key);
123 des_key_sched(temp_key, schedule);
124 des_cbc_cksum(password, ivec, passlen, schedule, ivec);
126 memcpy(temp_key, ivec, 8);
127 des_fixup_key_parity(temp_key);
128 des_key_sched(temp_key, schedule);
129 des_cbc_cksum(password, key, passlen, schedule, ivec);
131 des_fixup_key_parity(key);
135 ka_StringToKey(char *str, char *cell, /* cell for password */
136 struct ktc_encryptionKey *key)
138 char realm[MAXKTCREALMLEN];
142 code = ka_CellToRealm(cell, realm, 0 /*local */ );
143 if (code) /* just take his word for it */
144 strncpy(realm, cell, sizeof(realm));
145 else /* for backward compatibility */
146 lcstring(realm, realm, sizeof(realm));
148 StringToKey(str, realm, key);
150 Andrew_StringToKey(str, realm, key);
154 /* This prints out a prompt and reads a string from the terminal, turning off
155 echoing. If verify is requested it requests that the string be entered
156 again and the two strings are compared. The string is then converted to a
157 DES encryption key. */
160 KAREADPW - some error returned from read_pw_string
164 ka_ReadPassword(char *prompt, int verify, char *cell,
165 struct ktc_encryptionKey *key)
167 char password[BUFSIZ];
171 memset(key, 0, sizeof(struct ktc_encryptionKey));
172 code = read_pw_string(password, sizeof(password), prompt, verify);
177 if (strlen(password) == 0) {
179 return KANULLPASSWORD;
181 ka_StringToKey(password, cell, key);
186 /* This performs the backslash quoting defined by AC_ParseLoginName. */
196 if ((c >= '0') && (c <= '7')) {
198 c = (c * 8) + (str[++(*ip)] - '0');
199 c = (c * 8) + (str[++(*ip)] - '0');
205 /* This routine parses a string that might be entered by a user from the
206 terminal. It defines a syntax to allow a user to specify his identity in
207 terms of his name, instance and cell with a single string. These three
208 output strings must be allocated by the caller to their maximum length. The
209 syntax is very simple: the first dot ('.') separates the name from the
210 instance and the first atsign ('@') begins the cell name. A backslash ('\')
211 can be used to quote these special characters. A backslash followed by an
212 octal digit (zero through seven) introduces a three digit octal number which
213 is interpreted as the ascii value of a single character. */
216 KABADARGUMENT - if no output parameters are specified.
217 KABADNAME - if a component of the user name is too long or if a cell was
218 specified but the cell parameter was null.
222 ka_ParseLoginName(char *login, char name[MAXKTCNAMELEN],
223 char inst[MAXKTCNAMELEN], char cell[MAXKTCREALMLEN])
225 int login_len = strlen(login);
234 return KABADARGUMENT;
243 while (i < login_len) {
245 c = map_char(login, &i);
249 name[j] = 0; /* finish name */
250 reading = READCELL; /* but instance is null */
254 if (inst && (rc == '.')) {
255 name[j] = 0; /* finish name */
260 if (j >= MAXKTCNAMELEN - 1)
268 inst[j] = 0; /* finish name */
273 if (j >= MAXKTCNAMELEN - 1)
280 if (j >= MAXKTCREALMLEN - 1)
287 if (reading == READNAME)
289 else if (reading == READINST) {
294 } else if (reading == READCELL) {
301 /* the cell is really an authDomain and therefore is really a realm */
303 ucstring(cell, cell, MAXKTCREALMLEN);
307 /* Client side applications should call this to initialize error tables and
308 connect to the correct CellServDB file. */
312 { /* reserved for future use. */
314 static int inited = 0;
322 initialize_U_error_table();
323 initialize_KA_error_table();
324 initialize_RXK_error_table();
325 initialize_KTC_error_table();
326 initialize_ACFG_error_table();
327 code = ka_CellConfig(AFSDIR_CLIENT_ETC_DIRPATH);
338 struct ktc_encryptionKey key;
341 char name[MAXKTCNAMELEN];
342 char instance[MAXKTCNAMELEN];
343 char cell[MAXKTCREALMLEN];
345 printf("Enter login:");
346 fgets(line, 255, stdin);
347 ka_ParseLoginName(line, name, instance, cell);
348 printf("'%s' '%s' '%s'\n", name, instance, cell);