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>
21 #include "afs/sysincludes.h"
22 #include "afsincludes.h"
24 #include "afs/pthread_glock.h"
25 #include "afs/cellconfig.h"
26 #include "afs/afsutil.h"
28 #include "afs/kauth.h"
29 #include "afs/kautils.h"
30 #include "afs/pthread_glock.h"
33 #else /* defined(UKERNEL) */
35 #include <afs/pthread_glock.h>
52 #include <afs/cellconfig.h>
54 #include <afs/afsutil.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(key);
108 StringToKey(char *str, char *cell, /* cell for password */
109 struct ktc_encryptionKey *key)
111 des_key_schedule schedule;
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(password, ivec, passlen, schedule, 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(password, key, passlen, schedule, ivec);
134 des_fixup_key_parity(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. */
199 if ((c >= '0') && (c <= '7')) {
201 c = (c * 8) + (str[++(*ip)] - '0');
202 c = (c * 8) + (str[++(*ip)] - '0');
208 /* This routine parses a string that might be entered by a user from the
209 terminal. It defines a syntax to allow a user to specify his identity in
210 terms of his name, instance and cell with a single string. These three
211 output strings must be allocated by the caller to their maximum length. The
212 syntax is very simple: the first dot ('.') separates the name from the
213 instance and the first atsign ('@') begins the cell name. A backslash ('\')
214 can be used to quote these special characters. A backslash followed by an
215 octal digit (zero through seven) introduces a three digit octal number which
216 is interpreted as the ascii value of a single character. */
219 KABADARGUMENT - if no output parameters are specified.
220 KABADNAME - if a component of the user name is too long or if a cell was
221 specified but the cell parameter was null.
225 ka_ParseLoginName(char *login, char name[MAXKTCNAMELEN],
226 char inst[MAXKTCNAMELEN], char cell[MAXKTCREALMLEN])
228 int login_len = strlen(login);
237 return KABADARGUMENT;
246 while (i < login_len) {
248 c = map_char(login, &i);
252 name[j] = 0; /* finish name */
253 reading = READCELL; /* but instance is null */
257 if (inst && (rc == '.')) {
258 name[j] = 0; /* finish name */
263 if (j >= MAXKTCNAMELEN - 1)
271 inst[j] = 0; /* finish name */
276 if (j >= MAXKTCNAMELEN - 1)
283 if (j >= MAXKTCREALMLEN - 1)
290 if (reading == READNAME)
292 else if (reading == READINST) {
297 } else if (reading == READCELL) {
304 /* the cell is really an authDomain and therefore is really a realm */
306 ucstring(cell, cell, MAXKTCREALMLEN);
310 /* Client side applications should call this to initialize error tables and
311 connect to the correct CellServDB file. */
315 { /* reserved for future use. */
317 static int inited = 0;
325 initialize_U_error_table();
326 initialize_KA_error_table();
327 initialize_RXK_error_table();
328 initialize_KTC_error_table();
329 initialize_ACFG_error_table();
330 code = ka_CellConfig(AFSDIR_CLIENT_ETC_DIRPATH);
341 struct ktc_encryptionKey key;
344 char name[MAXKTCNAMELEN];
345 char instance[MAXKTCNAMELEN];
346 char cell[MAXKTCREALMLEN];
348 printf("Enter login:");
349 fgets(line, 255, stdin);
350 ka_ParseLoginName(line, name, instance, cell);
351 printf("'%s' '%s' '%s'\n", name, instance, cell);