7 /* from %OpenBSD: skeylogin.c,v 1.32 1999/08/16 14:46:56 millert Exp % */
10 #define ROUND(x) (((x)[0] << 24) + (((x)[1]) << 16) + (((x)[2]) << 8) + \
23 if ((strlen(s) % sizeof(u_int32_t)) == 0)
24 target = strlen(s); /* Multiple of 4 */
26 target = strlen(s) - (strlen(s) % sizeof(u_int32_t));
28 for (i = 0, len = 0; len < target; len += 4)
34 skey_fake_keyinfo(char *username)
38 u_char hseed[SKEY_MAX_SEED_LEN], flg = 1, *up;
39 char pbuf[SKEY_MAX_PW_LEN+1];
40 static char skeyprompt[SKEY_MAX_CHALLENGE+1];
47 * Base first 4 chars of seed on hostname.
48 * Add some filler for short hostnames if necessary.
50 if (gethostname(pbuf, sizeof(pbuf)) == -1)
53 for (p = pbuf; *p && isalnum(*p); p++)
54 if (isalpha(*p) && isupper(*p))
56 if (*p && pbuf - p < 4)
57 (void)strncpy(p, "asjd", 4 - (pbuf - p));
60 /* Hash the username if possible */
61 if ((up = SHA1Data(username, strlen(username), NULL)) != NULL) {
66 /* Collapse the hash */
67 ptr = hash_collapse(up);
68 memset(up, 0, strlen(up));
70 /* See if the random file's there, else use ctime */
71 if ((fd = open(_SKEY_RAND_FILE_PATH_, O_RDONLY)) != -1
72 && fstat(fd, &sb) == 0 &&
73 sb.st_size > (off_t)SKEY_MAX_SEED_LEN &&
74 lseek(fd, ptr % (sb.st_size - SKEY_MAX_SEED_LEN),
75 SEEK_SET) != -1 && read(fd, hseed,
76 SKEY_MAX_SEED_LEN) == SKEY_MAX_SEED_LEN) {
79 secretlen = SKEY_MAX_SEED_LEN;
81 } else if (!stat(_PATH_MEM, &sb) || !stat("/", &sb)) {
84 secretlen = strlen(secret);
89 /* Put that in your pipe and smoke it */
91 /* Hash secret value with username */
93 SHA1Update(&ctx, secret, secretlen);
94 SHA1Update(&ctx, username, strlen(username));
98 memset(secret, 0, secretlen);
100 /* Now hash the hash */
102 SHA1Update(&ctx, up, strlen(up));
105 ptr = hash_collapse(up + 4);
107 for (i = 4; i < 9; i++) {
108 pbuf[i] = (ptr % 10) + '0';
113 /* Sequence number */
114 ptr = ((up[2] + up[3]) % 99) + 1;
116 memset(up, 0, 20); /* SHA1 specific */
119 (void)snprintf(skeyprompt, sizeof skeyprompt,
121 SKEY_MAX_HASHNAME_LEN,
122 skey_get_algorithm(),
123 ptr, SKEY_MAX_SEED_LEN,
126 /* Base last 8 chars of seed on username */
132 /* Pad remainder with zeros */
138 *p++ = (*u++ % 10) + '0';
142 (void)snprintf(skeyprompt, sizeof skeyprompt,
144 SKEY_MAX_HASHNAME_LEN,
145 skey_get_algorithm(),
146 99, SKEY_MAX_SEED_LEN, pbuf);