summaryrefslogtreecommitdiff
path: root/authfile.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2011-05-05 14:17:18 +1000
committerDamien Miller <djm@mindrot.org>2011-05-05 14:17:18 +1000
commit2ce12ef1ac96c47b386168459cf7264fdc6faf95 (patch)
treef22a2364e250199fc1c83504b8489a37665c3607 /authfile.c
parent8cb1cda1e3a24c6f73b96822f36762c1c80ae147 (diff)
- djm@cvs.openbsd.org 2011/05/04 21:15:29
[authfile.c authfile.h ssh-add.c] allow "ssh-add - < key"; feedback and ok markus@
Diffstat (limited to 'authfile.c')
-rw-r--r--authfile.c100
1 files changed, 64 insertions, 36 deletions
diff --git a/authfile.c b/authfile.c
index a49850c89..608d1d06f 100644
--- a/authfile.c
+++ b/authfile.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: authfile.c,v 1.87 2010/11/29 18:57:04 markus Exp $ */ 1/* $OpenBSD: authfile.c,v 1.88 2011/05/04 21:15:29 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -69,6 +69,8 @@
69#include "misc.h" 69#include "misc.h"
70#include "atomicio.h" 70#include "atomicio.h"
71 71
72#define MAX_KEY_FILE_SIZE (1024 * 1024)
73
72/* Version identification string for SSH v1 identity files. */ 74/* Version identification string for SSH v1 identity files. */
73static const char authfile_id_string[] = 75static const char authfile_id_string[] =
74 "SSH PRIVATE KEY FILE FORMAT 1.1\n"; 76 "SSH PRIVATE KEY FILE FORMAT 1.1\n";
@@ -312,12 +314,12 @@ key_parse_public_rsa1(Buffer *blob, char **commentp)
312 return pub; 314 return pub;
313} 315}
314 316
315/* Load the contents of a key file into a buffer */ 317/* Load a key from a fd into a buffer */
316static int 318int
317key_load_file(int fd, const char *filename, Buffer *blob) 319key_load_file(int fd, const char *filename, Buffer *blob)
318{ 320{
321 u_char buf[1024];
319 size_t len; 322 size_t len;
320 u_char *cp;
321 struct stat st; 323 struct stat st;
322 324
323 if (fstat(fd, &st) < 0) { 325 if (fstat(fd, &st) < 0) {
@@ -325,30 +327,45 @@ key_load_file(int fd, const char *filename, Buffer *blob)
325 filename == NULL ? "" : filename, 327 filename == NULL ? "" : filename,
326 filename == NULL ? "" : " ", 328 filename == NULL ? "" : " ",
327 strerror(errno)); 329 strerror(errno));
328 close(fd);
329 return 0; 330 return 0;
330 } 331 }
331 if (st.st_size > 1*1024*1024) { 332 if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
333 st.st_size > MAX_KEY_FILE_SIZE) {
334 toobig:
332 error("%s: key file %.200s%stoo large", __func__, 335 error("%s: key file %.200s%stoo large", __func__,
333 filename == NULL ? "" : filename, 336 filename == NULL ? "" : filename,
334 filename == NULL ? "" : " "); 337 filename == NULL ? "" : " ");
335 close(fd);
336 return 0; 338 return 0;
337 } 339 }
338 len = (size_t)st.st_size; /* truncated */
339
340 buffer_init(blob); 340 buffer_init(blob);
341 cp = buffer_append_space(blob, len); 341 for (;;) {
342 342 if ((len = atomicio(read, fd, buf, sizeof(buf))) == 0) {
343 if (atomicio(read, fd, cp, len) != len) { 343 if (errno == EPIPE)
344 debug("%s: read from key file %.200s%sfailed: %.100s", __func__, 344 break;
345 filename == NULL ? "" : filename, 345 debug("%s: read from key file %.200s%sfailed: %.100s",
346 filename == NULL ? "" : " ", 346 __func__, filename == NULL ? "" : filename,
347 strerror(errno)); 347 filename == NULL ? "" : " ", strerror(errno));
348 buffer_clear(blob);
349 bzero(buf, sizeof(buf));
350 return 0;
351 }
352 buffer_append(blob, buf, len);
353 if (buffer_len(blob) > MAX_KEY_FILE_SIZE) {
354 buffer_clear(blob);
355 bzero(buf, sizeof(buf));
356 goto toobig;
357 }
358 }
359 bzero(buf, sizeof(buf));
360 if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
361 st.st_size != buffer_len(blob)) {
362 debug("%s: key file %.200s%schanged size while reading",
363 __func__, filename == NULL ? "" : filename,
364 filename == NULL ? "" : " ");
348 buffer_clear(blob); 365 buffer_clear(blob);
349 close(fd);
350 return 0; 366 return 0;
351 } 367 }
368
352 return 1; 369 return 1;
353} 370}
354 371
@@ -670,11 +687,38 @@ key_load_private_type(int type, const char *filename, const char *passphrase,
670} 687}
671 688
672Key * 689Key *
690key_parse_private(Buffer *buffer, const char *filename,
691 const char *passphrase, char **commentp)
692{
693 Key *pub, *prv;
694 Buffer pubcopy;
695
696 buffer_init(&pubcopy);
697 buffer_append(&pubcopy, buffer_ptr(buffer), buffer_len(buffer));
698 /* it's a SSH v1 key if the public key part is readable */
699 pub = key_parse_public_rsa1(&pubcopy, commentp);
700 buffer_free(&pubcopy);
701 if (pub == NULL) {
702 prv = key_parse_private_type(buffer, KEY_UNSPEC,
703 passphrase, NULL);
704 /* use the filename as a comment for PEM */
705 if (commentp && prv)
706 *commentp = xstrdup(filename);
707 } else {
708 key_free(pub);
709 /* key_parse_public_rsa1() has already loaded the comment */
710 prv = key_parse_private_type(buffer, KEY_RSA1, passphrase,
711 NULL);
712 }
713 return prv;
714}
715
716Key *
673key_load_private(const char *filename, const char *passphrase, 717key_load_private(const char *filename, const char *passphrase,
674 char **commentp) 718 char **commentp)
675{ 719{
676 Key *pub, *prv; 720 Key *prv;
677 Buffer buffer, pubcopy; 721 Buffer buffer;
678 int fd; 722 int fd;
679 723
680 fd = open(filename, O_RDONLY); 724 fd = open(filename, O_RDONLY);
@@ -697,23 +741,7 @@ key_load_private(const char *filename, const char *passphrase,
697 } 741 }
698 close(fd); 742 close(fd);
699 743
700 buffer_init(&pubcopy); 744 prv = key_parse_private(&buffer, filename, passphrase, commentp);
701 buffer_append(&pubcopy, buffer_ptr(&buffer), buffer_len(&buffer));
702 /* it's a SSH v1 key if the public key part is readable */
703 pub = key_parse_public_rsa1(&pubcopy, commentp);
704 buffer_free(&pubcopy);
705 if (pub == NULL) {
706 prv = key_parse_private_type(&buffer, KEY_UNSPEC,
707 passphrase, NULL);
708 /* use the filename as a comment for PEM */
709 if (commentp && prv)
710 *commentp = xstrdup(filename);
711 } else {
712 key_free(pub);
713 /* key_parse_public_rsa1() has already loaded the comment */
714 prv = key_parse_private_type(&buffer, KEY_RSA1, passphrase,
715 NULL);
716 }
717 buffer_free(&buffer); 745 buffer_free(&buffer);
718 return prv; 746 return prv;
719} 747}