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>
11 #include <afs/param.h>
14 #include <afs/pthread_glock.h>
22 #if !defined(__USE_XOPEN)
27 #include <afs/cellconfig.h>
29 #include <afs/afsutil.h>
31 #include <des_prototypes.h>
36 /* This defines the Andrew string_to_key function. It accepts a password
37 string as input and converts it via a one-way encryption algorithm to a DES
38 encryption key. It is compatible with the original Andrew authentication
39 service password database. */
42 Andrew_StringToKey(char *str
, char *cell
, /* cell for password */
43 struct ktc_encryptionKey
*key
)
45 char password
[8 + 1]; /* crypt's limit is 8 chars anyway */
49 memset(key
, 0, sizeof(struct ktc_encryptionKey
));
51 strncpy(password
, cell
, 8);
52 passlen
= strlen(str
);
56 for (i
= 0; i
< passlen
; i
++)
57 password
[i
] ^= str
[i
];
59 for (i
= 0; i
< 8; i
++)
60 if (password
[i
] == '\0')
63 /* crypt only considers the first 8 characters of password but for some
64 * reason returns eleven characters of result (plus the two salt chars). */
65 strncpy((char *)key
, (char *)crypt(password
, "p1") + 2,
66 sizeof(struct ktc_encryptionKey
));
68 /* parity is inserted into the LSB so leftshift each byte up one bit. This
69 * allows ascii characters with a zero MSB to retain as much significance
72 char *keybytes
= (char *)key
;
75 for (i
= 0; i
< 8; i
++) {
76 temp
= (unsigned int)keybytes
[i
];
77 keybytes
[i
] = (unsigned char)(temp
<< 1);
80 des_fixup_key_parity(ktc_to_cblock(key
));
84 StringToKey(char *str
, char *cell
, /* cell for password */
85 struct ktc_encryptionKey
*key
)
87 des_key_schedule schedule
;
88 unsigned char temp_key
[8];
90 char password
[BUFSIZ
];
93 strncpy(password
, str
, sizeof(password
));
94 if ((passlen
= strlen(password
)) < sizeof(password
) - 1)
95 strncat(password
, cell
, sizeof(password
) - passlen
);
96 if ((passlen
= strlen(password
)) > sizeof(password
))
97 passlen
= sizeof(password
);
99 memcpy(ivec
, "kerberos", 8);
100 memcpy(temp_key
, "kerberos", 8);
101 des_fixup_key_parity(temp_key
);
102 des_key_sched(temp_key
, schedule
);
103 des_cbc_cksum(charptr_to_cblockptr(password
), charptr_to_cblockptr(ivec
), passlen
, schedule
, charptr_to_cblockptr(ivec
));
105 memcpy(temp_key
, ivec
, 8);
106 des_fixup_key_parity(temp_key
);
107 des_key_sched(temp_key
, schedule
);
108 des_cbc_cksum(charptr_to_cblockptr(password
), ktc_to_cblockptr(key
), passlen
, schedule
, charptr_to_cblockptr(ivec
));
110 des_fixup_key_parity(ktc_to_cblock(key
));
114 ka_StringToKey(char *str
, char *cell
, /* cell for password */
115 struct ktc_encryptionKey
*key
)
117 char realm
[MAXKTCREALMLEN
];
121 code
= ka_CellToRealm(cell
, realm
, 0 /*local */ );
122 if (code
) /* just take his word for it */
123 strncpy(realm
, cell
, sizeof(realm
));
124 else /* for backward compatibility */
125 lcstring(realm
, realm
, sizeof(realm
));
127 StringToKey(str
, realm
, key
);
129 Andrew_StringToKey(str
, realm
, key
);
133 /* This prints out a prompt and reads a string from the terminal, turning off
134 echoing. If verify is requested it requests that the string be entered
135 again and the two strings are compared. The string is then converted to a
136 DES encryption key. */
139 KAREADPW - some error returned from read_pw_string
143 ka_ReadPassword(char *prompt
, int verify
, char *cell
,
144 struct ktc_encryptionKey
*key
)
146 char password
[BUFSIZ
];
150 memset(key
, 0, sizeof(struct ktc_encryptionKey
));
151 code
= read_pw_string(password
, sizeof(password
), prompt
, verify
);
156 if (strlen(password
) == 0) {
158 return KANULLPASSWORD
;
160 ka_StringToKey(password
, cell
, key
);
165 /* This performs the backslash quoting defined by AC_ParseLoginName. */
168 map_char(char *str
, int *ip
)
173 if ((c
>= '0') && (c
<= '7')) {
175 c
= (c
* 8) + (str
[++(*ip
)] - '0');
176 c
= (c
* 8) + (str
[++(*ip
)] - '0');
182 /* This routine parses a string that might be entered by a user from the
183 terminal. It defines a syntax to allow a user to specify his identity in
184 terms of his name, instance and cell with a single string. These three
185 output strings must be allocated by the caller to their maximum length. The
186 syntax is very simple: the first dot ('.') separates the name from the
187 instance and the first atsign ('@') begins the cell name. A backslash ('\')
188 can be used to quote these special characters. A backslash followed by an
189 octal digit (zero through seven) introduces a three digit octal number which
190 is interpreted as the ascii value of a single character. */
193 KABADARGUMENT - if no output parameters are specified.
194 KABADNAME - if a component of the user name is too long or if a cell was
195 specified but the cell parameter was null.
199 ka_ParseLoginName(char *login
, char name
[MAXKTCNAMELEN
],
200 char inst
[MAXKTCNAMELEN
], char cell
[MAXKTCREALMLEN
])
202 int login_len
= strlen(login
);
211 return KABADARGUMENT
;
220 while (i
< login_len
) {
222 c
= map_char(login
, &i
);
226 name
[j
] = 0; /* finish name */
227 reading
= READCELL
; /* but instance is null */
231 if (inst
&& (rc
== '.')) {
232 name
[j
] = 0; /* finish name */
237 if (j
>= MAXKTCNAMELEN
- 1)
245 inst
[j
] = 0; /* finish name */
250 if (j
>= MAXKTCNAMELEN
- 1)
257 if (j
>= MAXKTCREALMLEN
- 1)
264 if (reading
== READNAME
)
266 else if (reading
== READINST
) {
271 } else if (reading
== READCELL
) {
278 /* the cell is really an authDomain and therefore is really a realm */
280 ucstring(cell
, cell
, MAXKTCREALMLEN
);
284 /* Client side applications should call this to initialize error tables and
285 connect to the correct CellServDB file. */
289 { /* reserved for future use. */
291 static int inited
= 0;
299 initialize_U_error_table();
300 initialize_KA_error_table();
301 initialize_RXK_error_table();
302 initialize_KTC_error_table();
303 initialize_ACFG_error_table();
304 code
= ka_CellConfig(AFSDIR_CLIENT_ETC_DIRPATH
);
315 struct ktc_encryptionKey key
;
318 char name
[MAXKTCNAMELEN
];
319 char instance
[MAXKTCNAMELEN
];
320 char cell
[MAXKTCREALMLEN
];
322 printf("Enter login:");
323 fgets(line
, 255, stdin
);
324 ka_ParseLoginName(line
, name
, instance
, cell
);
325 printf("'%s' '%s' '%s'\n", name
, instance
, cell
);