diff options
Diffstat (limited to 'auth-skey.c')
-rw-r--r-- | auth-skey.c | 215 |
1 files changed, 0 insertions, 215 deletions
diff --git a/auth-skey.c b/auth-skey.c deleted file mode 100644 index 7088b790c..000000000 --- a/auth-skey.c +++ /dev/null | |||
@@ -1,215 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 1999,2000 Markus Friedl. All rights reserved. | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * 1. Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * 2. Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * | ||
13 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | ||
14 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
15 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
16 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
17 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
18 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
19 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
20 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
22 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
23 | */ | ||
24 | |||
25 | #include "includes.h" | ||
26 | RCSID("$OpenBSD: auth-skey.c,v 1.9 2000/10/19 16:41:13 deraadt Exp $"); | ||
27 | |||
28 | #ifdef SKEY | ||
29 | #include "ssh.h" | ||
30 | #include "packet.h" | ||
31 | #include <openssl/sha.h> | ||
32 | |||
33 | /* from %OpenBSD: skeylogin.c,v 1.32 1999/08/16 14:46:56 millert Exp % */ | ||
34 | |||
35 | /* | ||
36 | * try skey authentication, | ||
37 | * return 1 on success, 0 on failure, -1 if skey is not available | ||
38 | */ | ||
39 | |||
40 | int | ||
41 | auth_skey_password(struct passwd * pw, const char *password) | ||
42 | { | ||
43 | if (strncasecmp(password, "s/key", 5) == 0) { | ||
44 | char *skeyinfo = skey_keyinfo(pw->pw_name); | ||
45 | if (skeyinfo == NULL) { | ||
46 | debug("generating fake skeyinfo for %.100s.", | ||
47 | pw->pw_name); | ||
48 | skeyinfo = skey_fake_keyinfo(pw->pw_name); | ||
49 | } | ||
50 | if (skeyinfo != NULL) | ||
51 | packet_send_debug("%s", skeyinfo); | ||
52 | /* Try again. */ | ||
53 | return 0; | ||
54 | } else if (skey_haskey(pw->pw_name) == 0 && | ||
55 | skey_passcheck(pw->pw_name, (char *) password) != -1) { | ||
56 | /* Authentication succeeded. */ | ||
57 | return 1; | ||
58 | } | ||
59 | /* Fall back to ordinary passwd authentication. */ | ||
60 | return -1; | ||
61 | } | ||
62 | |||
63 | /* from %OpenBSD: skeylogin.c,v 1.32 1999/08/16 14:46:56 millert Exp % */ | ||
64 | |||
65 | #define ROUND(x) (((x)[0] << 24) + (((x)[1]) << 16) + (((x)[2]) << 8) + \ | ||
66 | ((x)[3])) | ||
67 | |||
68 | /* | ||
69 | * hash_collapse() | ||
70 | */ | ||
71 | static u_int32_t | ||
72 | hash_collapse(s) | ||
73 | u_char *s; | ||
74 | { | ||
75 | int len, target; | ||
76 | u_int32_t i; | ||
77 | |||
78 | if ((strlen(s) % sizeof(u_int32_t)) == 0) | ||
79 | target = strlen(s); /* Multiple of 4 */ | ||
80 | else | ||
81 | target = strlen(s) - (strlen(s) % sizeof(u_int32_t)); | ||
82 | |||
83 | for (i = 0, len = 0; len < target; len += 4) | ||
84 | i ^= ROUND(s + len); | ||
85 | |||
86 | return i; | ||
87 | } | ||
88 | |||
89 | char * | ||
90 | skey_fake_keyinfo(char *username) | ||
91 | { | ||
92 | int i; | ||
93 | u_int ptr; | ||
94 | u_char hseed[SKEY_MAX_SEED_LEN], flg = 1, *up; | ||
95 | char pbuf[SKEY_MAX_PW_LEN+1]; | ||
96 | static char skeyprompt[SKEY_MAX_CHALLENGE+1]; | ||
97 | char *secret = NULL; | ||
98 | size_t secretlen = 0; | ||
99 | SHA_CTX ctx; | ||
100 | char *p, *u; | ||
101 | |||
102 | /* | ||
103 | * Base first 4 chars of seed on hostname. | ||
104 | * Add some filler for short hostnames if necessary. | ||
105 | */ | ||
106 | if (gethostname(pbuf, sizeof(pbuf)) == -1) | ||
107 | *(p = pbuf) = '.'; | ||
108 | else | ||
109 | for (p = pbuf; *p && isalnum(*p); p++) | ||
110 | if (isalpha(*p) && isupper(*p)) | ||
111 | *p = tolower(*p); | ||
112 | if (*p && pbuf - p < 4) | ||
113 | (void)strncpy(p, "asjd", 4 - (pbuf - p)); | ||
114 | pbuf[4] = '\0'; | ||
115 | |||
116 | /* Hash the username if possible */ | ||
117 | up = malloc(SHA_DIGEST_LENGTH); | ||
118 | if (up != NULL) { | ||
119 | struct stat sb; | ||
120 | time_t t; | ||
121 | int fd; | ||
122 | |||
123 | SHA1_Init(&ctx); | ||
124 | SHA1_Update(&ctx, username, strlen(username)); | ||
125 | SHA1_Final(up, &ctx); | ||
126 | |||
127 | /* Collapse the hash */ | ||
128 | ptr = hash_collapse(up); | ||
129 | memset(up, 0, strlen(up)); | ||
130 | |||
131 | /* See if the random file's there, else use ctime */ | ||
132 | if ((fd = open(_SKEY_RAND_FILE_PATH_, O_RDONLY)) != -1 | ||
133 | && fstat(fd, &sb) == 0 && | ||
134 | sb.st_size > (off_t)SKEY_MAX_SEED_LEN && | ||
135 | lseek(fd, ptr % (sb.st_size - SKEY_MAX_SEED_LEN), | ||
136 | SEEK_SET) != -1 && read(fd, hseed, | ||
137 | SKEY_MAX_SEED_LEN) == SKEY_MAX_SEED_LEN) { | ||
138 | close(fd); | ||
139 | fd = -1; | ||
140 | secret = hseed; | ||
141 | secretlen = SKEY_MAX_SEED_LEN; | ||
142 | flg = 0; | ||
143 | } else if (!stat(_PATH_MEM, &sb) || !stat("/", &sb)) { | ||
144 | t = sb.st_ctime; | ||
145 | secret = ctime(&t); | ||
146 | secretlen = strlen(secret); | ||
147 | flg = 0; | ||
148 | } | ||
149 | if (fd != -1) | ||
150 | close(fd); | ||
151 | } | ||
152 | |||
153 | /* Put that in your pipe and smoke it */ | ||
154 | if (flg == 0) { | ||
155 | /* Hash secret value with username */ | ||
156 | SHA1_Init(&ctx); | ||
157 | SHA1_Update(&ctx, secret, secretlen); | ||
158 | SHA1_Update(&ctx, username, strlen(username)); | ||
159 | SHA1_Final(up, &ctx); | ||
160 | |||
161 | /* Zero out */ | ||
162 | memset(secret, 0, secretlen); | ||
163 | |||
164 | /* Now hash the hash */ | ||
165 | SHA1_Init(&ctx); | ||
166 | SHA1_Update(&ctx, up, strlen(up)); | ||
167 | SHA1_Final(up, &ctx); | ||
168 | |||
169 | ptr = hash_collapse(up + 4); | ||
170 | |||
171 | for (i = 4; i < 9; i++) { | ||
172 | pbuf[i] = (ptr % 10) + '0'; | ||
173 | ptr /= 10; | ||
174 | } | ||
175 | pbuf[i] = '\0'; | ||
176 | |||
177 | /* Sequence number */ | ||
178 | ptr = ((up[2] + up[3]) % 99) + 1; | ||
179 | |||
180 | memset(up, 0, SHA_DIGEST_LENGTH); /* SHA1 specific */ | ||
181 | free(up); | ||
182 | |||
183 | (void)snprintf(skeyprompt, sizeof skeyprompt, | ||
184 | "otp-%.*s %d %.*s", | ||
185 | SKEY_MAX_HASHNAME_LEN, | ||
186 | skey_get_algorithm(), | ||
187 | ptr, SKEY_MAX_SEED_LEN, | ||
188 | pbuf); | ||
189 | } else { | ||
190 | /* Base last 8 chars of seed on username */ | ||
191 | u = username; | ||
192 | i = 8; | ||
193 | p = &pbuf[4]; | ||
194 | do { | ||
195 | if (*u == 0) { | ||
196 | /* Pad remainder with zeros */ | ||
197 | while (--i >= 0) | ||
198 | *p++ = '0'; | ||
199 | break; | ||
200 | } | ||
201 | |||
202 | *p++ = (*u++ % 10) + '0'; | ||
203 | } while (--i != 0); | ||
204 | pbuf[12] = '\0'; | ||
205 | |||
206 | (void)snprintf(skeyprompt, sizeof skeyprompt, | ||
207 | "otp-%.*s %d %.*s", | ||
208 | SKEY_MAX_HASHNAME_LEN, | ||
209 | skey_get_algorithm(), | ||
210 | 99, SKEY_MAX_SEED_LEN, pbuf); | ||
211 | } | ||
212 | return skeyprompt; | ||
213 | } | ||
214 | |||
215 | #endif /* SKEY */ | ||