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