10 #include <openssl/sha.h>
16 /* from %OpenBSD: skeylogin.c,v 1.32 1999/08/16 14:46:56 millert Exp % */
19 * try skey authentication,
20 * return 1 on success, 0 on failure, -1 if skey is not available
24 auth_skey_password(struct passwd * pw, const char *password)
26 if (strncasecmp(password, "s/key", 5) == 0) {
27 char *skeyinfo = skey_keyinfo(pw->pw_name);
28 if (skeyinfo == NULL) {
29 debug("generating fake skeyinfo for %.100s.",
31 skeyinfo = skey_fake_keyinfo(pw->pw_name);
34 packet_send_debug(skeyinfo);
37 } else if (skey_haskey(pw->pw_name) == 0 &&
38 skey_passcheck(pw->pw_name, (char *) password) != -1) {
39 /* Authentication succeeded. */
42 /* Fall back to ordinary passwd authentication. */
46 /* from %OpenBSD: skeylogin.c,v 1.32 1999/08/16 14:46:56 millert Exp % */
48 #define ROUND(x) (((x)[0] << 24) + (((x)[1]) << 16) + (((x)[2]) << 8) + \
61 if ((strlen(s) % sizeof(u_int32_t)) == 0)
62 target = strlen(s); /* Multiple of 4 */
64 target = strlen(s) - (strlen(s) % sizeof(u_int32_t));
66 for (i = 0, len = 0; len < target; len += 4)
73 skey_fake_keyinfo(char *username)
77 u_char hseed[SKEY_MAX_SEED_LEN], flg = 1, *up;
78 char pbuf[SKEY_MAX_PW_LEN+1];
79 static char skeyprompt[SKEY_MAX_CHALLENGE+1];
84 char md[SHA_DIGEST_LENGTH];
87 * Base first 4 chars of seed on hostname.
88 * Add some filler for short hostnames if necessary.
90 if (gethostname(pbuf, sizeof(pbuf)) == -1)
93 for (p = pbuf; *p && isalnum(*p); p++)
94 if (isalpha(*p) && isupper(*p))
96 if (*p && pbuf - p < 4)
97 (void)strncpy(p, "asjd", 4 - (pbuf - p));
100 /* Hash the username if possible */
101 up = malloc(SHA_DIGEST_LENGTH);
108 SHA1_Update(&ctx, username, strlen(username));
111 /* Collapse the hash */
112 ptr = hash_collapse(up);
113 memset(up, 0, strlen(up));
115 /* See if the random file's there, else use ctime */
116 if ((fd = open(_SKEY_RAND_FILE_PATH_, O_RDONLY)) != -1
117 && fstat(fd, &sb) == 0 &&
118 sb.st_size > (off_t)SKEY_MAX_SEED_LEN &&
119 lseek(fd, ptr % (sb.st_size - SKEY_MAX_SEED_LEN),
120 SEEK_SET) != -1 && read(fd, hseed,
121 SKEY_MAX_SEED_LEN) == SKEY_MAX_SEED_LEN) {
125 secretlen = SKEY_MAX_SEED_LEN;
127 } else if (!stat(_PATH_MEM, &sb) || !stat("/", &sb)) {
130 secretlen = strlen(secret);
137 /* Put that in your pipe and smoke it */
139 /* Hash secret value with username */
141 SHA1_Update(&ctx, secret, secretlen);
142 SHA1_Update(&ctx, username, strlen(username));
146 memset(secret, 0, secretlen);
148 /* Now hash the hash */
150 SHA1_Update(&ctx, up, strlen(up));
153 ptr = hash_collapse(up + 4);
155 for (i = 4; i < 9; i++) {
156 pbuf[i] = (ptr % 10) + '0';
161 /* Sequence number */
162 ptr = ((up[2] + up[3]) % 99) + 1;
164 memset(up, 0, SHA_DIGEST_LENGTH); /* SHA1 specific */
167 (void)snprintf(skeyprompt, sizeof skeyprompt,
169 SKEY_MAX_HASHNAME_LEN,
170 skey_get_algorithm(),
171 ptr, SKEY_MAX_SEED_LEN,
174 /* Base last 8 chars of seed on username */
180 /* Pad remainder with zeros */
186 *p++ = (*u++ % 10) + '0';
190 (void)snprintf(skeyprompt, sizeof skeyprompt,
192 SKEY_MAX_HASHNAME_LEN,
193 skey_get_algorithm(),
194 99, SKEY_MAX_SEED_LEN, pbuf);