comparison svr-authpubkey.c @ 51:095d689fed16

- Hostkey checking is mostly there, just aren't appending yet. - Rearranged various bits of the fingerprint/base64 type code, so it can be shared between versions
author Matt Johnston <matt@ucc.asn.au>
date Sun, 08 Aug 2004 16:17:05 +0000
parents 45edf30ea0a6
children eee77ac31ccc
comparison
equal deleted inserted replaced
49:cc59bfcdee17 51:095d689fed16
36 #include "algo.h" 36 #include "algo.h"
37 37
38 #ifdef DROPBEAR_PUBKEY_AUTH 38 #ifdef DROPBEAR_PUBKEY_AUTH
39 39
40 #define MIN_AUTHKEYS_LINE 10 /* "ssh-rsa AB" - short but doesn't matter */ 40 #define MIN_AUTHKEYS_LINE 10 /* "ssh-rsa AB" - short but doesn't matter */
41 #define MAX_AUTHKEYS_LINE 1000 /* max length of a line in authkeys */ 41 #define MAX_AUTHKEYS_LINE 4200 /* max length of a line in authkeys */
42 42
43 static int checkpubkey(unsigned char* algo, unsigned int algolen, 43 static int checkpubkey(unsigned char* algo, unsigned int algolen,
44 unsigned char* keyblob, unsigned int keybloblen); 44 unsigned char* keyblob, unsigned int keybloblen);
45 static int checkpubkeyperms(); 45 static int checkpubkeyperms();
46 static void send_msg_userauth_pk_ok(unsigned char* algo, unsigned int algolen, 46 static void send_msg_userauth_pk_ok(unsigned char* algo, unsigned int algolen,
47 unsigned char* keyblob, unsigned int keybloblen); 47 unsigned char* keyblob, unsigned int keybloblen);
48 static int checkfileperm(char * filename); 48 static int checkfileperm(char * filename);
49 static int getauthline(buffer * line, FILE * authfile);
50 49
51 /* process a pubkey auth request, sending success or failure message as 50 /* process a pubkey auth request, sending success or failure message as
52 * appropriate */ 51 * appropriate */
53 void svr_auth_pubkey() { 52 void svr_auth_pubkey() {
54 53
100 buf_putstring(signbuf, ses.session_id, SHA1_HASH_SIZE); 99 buf_putstring(signbuf, ses.session_id, SHA1_HASH_SIZE);
101 buf_putbytes(signbuf, ses.payload->data, ses.payload->pos); 100 buf_putbytes(signbuf, ses.payload->data, ses.payload->pos);
102 buf_setpos(signbuf, 0); 101 buf_setpos(signbuf, 0);
103 102
104 /* ... and finally verify the signature */ 103 /* ... and finally verify the signature */
105 fp = sign_key_fingerprint(key, type); 104 fp = sign_key_fingerprint(keyblob, keybloblen);
106 if (buf_verify(ses.payload, key, buf_getptr(signbuf, signbuf->len), 105 if (buf_verify(ses.payload, key, buf_getptr(signbuf, signbuf->len),
107 signbuf->len) == DROPBEAR_SUCCESS) { 106 signbuf->len) == DROPBEAR_SUCCESS) {
108 dropbear_log(LOG_NOTICE, 107 dropbear_log(LOG_NOTICE,
109 "pubkey auth succeeded for '%s' with key %s", 108 "pubkey auth succeeded for '%s' with key %s",
110 ses.authstate.printableuser, fp); 109 ses.authstate.printableuser, fp);
158 157
159 FILE * authfile = NULL; 158 FILE * authfile = NULL;
160 char * filename = NULL; 159 char * filename = NULL;
161 int ret = DROPBEAR_FAILURE; 160 int ret = DROPBEAR_FAILURE;
162 buffer * line = NULL; 161 buffer * line = NULL;
163 buffer * decodekey = NULL;
164 unsigned long decodekeylen;
165 unsigned char* filealgo = NULL;
166 unsigned int filealgolen;
167 unsigned int len, pos; 162 unsigned int len, pos;
168 163
169 TRACE(("enter checkpubkey")); 164 TRACE(("enter checkpubkey"));
170 165
171 /* check that we can use the algo */ 166 /* check that we can use the algo */
200 195
201 line = buf_new(MAX_AUTHKEYS_LINE); 196 line = buf_new(MAX_AUTHKEYS_LINE);
202 197
203 /* iterate through the lines */ 198 /* iterate through the lines */
204 do { 199 do {
205 /* free reused vars */ 200
206 if (decodekey) { 201 if (buf_getline(line, authfile) == DROPBEAR_FAILURE) {
207 buf_free(decodekey);
208 decodekey = NULL;
209 }
210 m_free(filealgo);
211
212 if (getauthline(line, authfile) == DROPBEAR_FAILURE) {
213 /* EOF reached */ 202 /* EOF reached */
214 TRACE(("checkpubkey: authorized_keys EOF reached")); 203 TRACE(("checkpubkey: authorized_keys EOF reached"));
215 break; 204 break;
216 } 205 }
217 206
241 buf_setpos(line, pos); 230 buf_setpos(line, pos);
242 buf_setlen(line, line->pos + len); 231 buf_setlen(line, line->pos + len);
243 232
244 TRACE(("checkpubkey: line pos = %d len = %d", line->pos, line->len)); 233 TRACE(("checkpubkey: line pos = %d len = %d", line->pos, line->len));
245 234
246 /* now we have the actual data */ 235 ret = cmp_base64_key(keyblob, keybloblen, algo, algolen, line);
247 decodekeylen = (line->len - line->pos) * 2; 236 if (ret == DROPBEAR_SUCCESS) {
248 decodekey = buf_new(decodekeylen); 237 break;
249 if (base64_decode(buf_getptr(line, line->len - line->pos), 238 }
250 line->len - line->pos, 239
251 buf_getwriteptr(decodekey, decodekey->size), 240 /* We continue to the next line otherwise */
252 &decodekeylen) != CRYPT_OK) {
253 TRACE(("checkpubkey: base64 decode failed"));
254 continue;
255 }
256 TRACE(("checkpubkey: base64_decode success"));
257 buf_incrlen(decodekey, decodekeylen);
258
259 /* compare the keys */
260 if (decodekeylen != keybloblen || memcmp(
261 buf_getptr(decodekey, decodekey->len),
262 keyblob, decodekey->len) != 0) {
263 TRACE(("checkpubkey: compare failed"));
264 continue;
265 }
266
267 /* and also check that the algo specified and the algo in the key
268 * itself match */
269 filealgo = buf_getstring(decodekey, &filealgolen);
270 if (filealgolen != algolen || memcmp(filealgo, algo, algolen) != 0) {
271 TRACE(("checkpubkey: algo match failed"));
272 continue;
273 }
274
275 /* now we know this key is good */
276 ret = DROPBEAR_SUCCESS;
277 break;
278 241
279 } while (1); 242 } while (1);
280 243
281 out: 244 out:
282 if (authfile) { 245 if (authfile) {
283 fclose(authfile); 246 fclose(authfile);
284 } 247 }
285 if (line) { 248 if (line) {
286 buf_free(line); 249 buf_free(line);
287 } 250 }
288 if (decodekey) {
289 buf_free(decodekey);
290 }
291 m_free(filename); 251 m_free(filename);
292 m_free(filealgo);
293 TRACE(("leave checkpubkey: ret=%d", ret)); 252 TRACE(("leave checkpubkey: ret=%d", ret));
294 return ret; 253 return ret;
295 } 254 }
296 255
297 /* get a line from the file into buffer in the style expected for an
298 * authkeys file.
299 * Will return DROPBEAR_SUCCESS if data is read, or DROPBEAR_FAILURE on EOF.*/
300 static int getauthline(buffer * line, FILE * authfile) {
301
302 int c = EOF;
303
304 TRACE(("enter getauthline"));
305
306 buf_setpos(line, 0);
307 buf_setlen(line, 0);
308
309 while (line->pos < line->size) {
310 c = fgetc(authfile); /*getc() is weird with some uClibc systems*/
311 if (c == EOF || c == '\n' || c == '\r') {
312 goto out;
313 }
314 buf_putbyte(line, (unsigned char)c);
315 }
316
317 TRACE(("leave getauthline: line too long"));
318 return DROPBEAR_FAILURE;
319
320 out:
321
322 buf_setpos(line, 0);
323
324 /* if we didn't read anything before EOF or error, exit */
325 if (c == EOF && line->pos == 0) {
326 TRACE(("leave getauthline: failure"));
327 return DROPBEAR_FAILURE;
328 } else {
329 TRACE(("leave getauthline: success"));
330 return DROPBEAR_SUCCESS;
331 }
332
333 TRACE(("leave getauthline"));
334 }
335 256
336 /* Returns DROPBEAR_SUCCESS if file permissions for pubkeys are ok, 257 /* Returns DROPBEAR_SUCCESS if file permissions for pubkeys are ok,
337 * DROPBEAR_FAILURE otherwise. 258 * DROPBEAR_FAILURE otherwise.
338 * Checks that the user's homedir, ~/.ssh, and 259 * Checks that the user's homedir, ~/.ssh, and
339 * ~/.ssh/authorized_keys are all owned by either root or the user, and are 260 * ~/.ssh/authorized_keys are all owned by either root or the user, and are