Annotation of src/usr.bin/ssh/auth-skey.c, Revision 1.2
1.1 markus 1: #include "includes.h"
1.2 ! deraadt 2: RCSID("$Id: auth-skey.c,v 1.1 1999/10/07 21:45:02 markus Exp $");
1.1 markus 3:
4: #include "ssh.h"
5: #include <sha1.h>
6:
7: /* from %OpenBSD: skeylogin.c,v 1.32 1999/08/16 14:46:56 millert Exp % */
8:
9:
10: #define ROUND(x) (((x)[0] << 24) + (((x)[1]) << 16) + (((x)[2]) << 8) + \
11: ((x)[3]))
12:
13: /*
14: * hash_collapse()
15: */
16: static u_int32_t
17: hash_collapse(s)
18: u_char *s;
19: {
20: int len, target;
21: u_int32_t i;
22:
23: if ((strlen(s) % sizeof(u_int32_t)) == 0)
24: target = strlen(s); /* Multiple of 4 */
25: else
26: target = strlen(s) - (strlen(s) % sizeof(u_int32_t));
27:
28: for (i = 0, len = 0; len < target; len += 4)
29: i ^= ROUND(s + len);
30:
31: return i;
32: }
33: char *
34: skey_fake_keyinfo(char *username)
35: {
36: int i;
37: u_int ptr;
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];
41: char *secret = NULL;
42: size_t secretlen = 0;
43: SHA1_CTX ctx;
44: char *p, *u;
45:
46: /*
47: * Base first 4 chars of seed on hostname.
48: * Add some filler for short hostnames if necessary.
49: */
50: if (gethostname(pbuf, sizeof(pbuf)) == -1)
51: *(p = pbuf) = '.';
52: else
53: for (p = pbuf; *p && isalnum(*p); p++)
54: if (isalpha(*p) && isupper(*p))
55: *p = tolower(*p);
56: if (*p && pbuf - p < 4)
57: (void)strncpy(p, "asjd", 4 - (pbuf - p));
58: pbuf[4] = '\0';
59:
60: /* Hash the username if possible */
61: if ((up = SHA1Data(username, strlen(username), NULL)) != NULL) {
62: struct stat sb;
63: time_t t;
64: int fd;
65:
66: /* Collapse the hash */
67: ptr = hash_collapse(up);
68: memset(up, 0, strlen(up));
69:
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) {
77: close(fd);
78: secret = hseed;
79: secretlen = SKEY_MAX_SEED_LEN;
80: flg = 0;
81: } else if (!stat(_PATH_MEM, &sb) || !stat("/", &sb)) {
82: t = sb.st_ctime;
83: secret = ctime(&t);
84: secretlen = strlen(secret);
85: flg = 0;
86: }
87: }
88:
89: /* Put that in your pipe and smoke it */
90: if (flg == 0) {
91: /* Hash secret value with username */
92: SHA1Init(&ctx);
93: SHA1Update(&ctx, secret, secretlen);
94: SHA1Update(&ctx, username, strlen(username));
95: SHA1End(&ctx, up);
96:
97: /* Zero out */
98: memset(secret, 0, secretlen);
99:
100: /* Now hash the hash */
101: SHA1Init(&ctx);
102: SHA1Update(&ctx, up, strlen(up));
103: SHA1End(&ctx, up);
104:
105: ptr = hash_collapse(up + 4);
106:
107: for (i = 4; i < 9; i++) {
108: pbuf[i] = (ptr % 10) + '0';
109: ptr /= 10;
110: }
111: pbuf[i] = '\0';
112:
113: /* Sequence number */
114: ptr = ((up[2] + up[3]) % 99) + 1;
115:
116: memset(up, 0, 20); /* SHA1 specific */
117: free(up);
118:
1.2 ! deraadt 119: (void)snprintf(skeyprompt, sizeof skeyprompt,
1.1 markus 120: "otp-%.*s %d %.*s",
121: SKEY_MAX_HASHNAME_LEN,
122: skey_get_algorithm(),
123: ptr, SKEY_MAX_SEED_LEN,
124: pbuf);
125: } else {
126: /* Base last 8 chars of seed on username */
127: u = username;
128: i = 8;
129: p = &pbuf[4];
130: do {
131: if (*u == 0) {
132: /* Pad remainder with zeros */
133: while (--i >= 0)
134: *p++ = '0';
135: break;
136: }
137:
138: *p++ = (*u++ % 10) + '0';
139: } while (--i != 0);
140: pbuf[12] = '\0';
141:
1.2 ! deraadt 142: (void)snprintf(skeyprompt, sizeof skeyprompt,
! 143: "otp-%.*s %d %.*s",
1.1 markus 144: SKEY_MAX_HASHNAME_LEN,
145: skey_get_algorithm(),
146: 99, SKEY_MAX_SEED_LEN, pbuf);
147: }
148: return skeyprompt;
149: }