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];
144 LOCK_GLOBAL_MUTEX code = ka_CellToRealm(cell, realm, 0 /*local */ );
145 if (code) /* just take his word for it */
146 strncpy(realm, cell, sizeof(realm));
147 else /* for backward compatibility */
148 lcstring(realm, realm, sizeof(realm));
150 StringToKey(str, realm, key);
152 Andrew_StringToKey(str, realm, key);
155 /* This prints out a prompt and reads a string from the terminal, turning off
156 echoing. If verify is requested it requests that the string be entered
157 again and the two strings are compared. The string is then converted to a
158 DES encryption key. */
161 KAREADPW - some error returned from read_pw_string
165 ka_ReadPassword(char *prompt, int verify, char *cell,
166 struct ktc_encryptionKey *key)
168 char password[BUFSIZ];
171 LOCK_GLOBAL_MUTEX memset(key, 0, sizeof(struct ktc_encryptionKey));
172 code = read_pw_string(password, sizeof(password), prompt, verify);
174 UNLOCK_GLOBAL_MUTEX return KAREADPW;
176 if (strlen(password) == 0) {
177 UNLOCK_GLOBAL_MUTEX return KANULLPASSWORD;
179 ka_StringToKey(password, cell, key);
180 UNLOCK_GLOBAL_MUTEX return 0;
183 /* This performs the backslash quoting defined by AC_ParseLoginName. */
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;
313 LOCK_GLOBAL_MUTEX if (inited) {
314 UNLOCK_GLOBAL_MUTEX return 0;
317 initialize_U_error_table();
318 initialize_KA_error_table();
319 initialize_RXK_error_table();
320 initialize_KTC_error_table();
321 initialize_ACFG_error_table();
322 code = ka_CellConfig(AFSDIR_CLIENT_ETC_DIRPATH);
323 UNLOCK_GLOBAL_MUTEX if (code)
332 struct ktc_encryptionKey key;
335 char name[MAXKTCNAMELEN];
336 char instance[MAXKTCNAMELEN];
337 char cell[MAXKTCREALMLEN];
339 printf("Enter login:");
340 fgets(line, 255, stdin);
341 ka_ParseLoginName(line, name, instance, cell);
342 printf("'%s' '%s' '%s'\n", name, instance, cell);