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