summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog3
-rw-r--r--authfile.c100
-rw-r--r--authfile.h4
-rw-r--r--ssh-add.c33
-rw-r--r--ssh-keygen.c8
5 files changed, 99 insertions, 49 deletions
diff --git a/ChangeLog b/ChangeLog
index 7cc6a2345..6a324c716 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -65,6 +65,9 @@
65 certificate options are supposed to be packed in lexical order of 65 certificate options are supposed to be packed in lexical order of
66 option name (though we don't actually enforce this at present). 66 option name (though we don't actually enforce this at present).
67 Move one up that was out of sequence 67 Move one up that was out of sequence
68 - djm@cvs.openbsd.org 2011/05/04 21:15:29
69 [authfile.c authfile.h ssh-add.c]
70 allow "ssh-add - < key"; feedback and ok markus@
68 71
6920110221 7220110221
70 - (dtucker) [contrib/cygwin/ssh-host-config] From Corinna: revamp of the 73 - (dtucker) [contrib/cygwin/ssh-host-config] From Corinna: revamp of the
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}
diff --git a/authfile.h b/authfile.h
index 6745dc062..78349beb5 100644
--- a/authfile.h
+++ b/authfile.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: authfile.h,v 1.15 2010/08/04 05:42:47 djm Exp $ */ 1/* $OpenBSD: authfile.h,v 1.16 2011/05/04 21:15:29 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -16,9 +16,11 @@
16#define AUTHFILE_H 16#define AUTHFILE_H
17 17
18int key_save_private(Key *, const char *, const char *, const char *); 18int key_save_private(Key *, const char *, const char *, const char *);
19int key_load_file(int, const char *, Buffer *);
19Key *key_load_cert(const char *); 20Key *key_load_cert(const char *);
20Key *key_load_public(const char *, char **); 21Key *key_load_public(const char *, char **);
21Key *key_load_public_type(int, const char *, char **); 22Key *key_load_public_type(int, const char *, char **);
23Key *key_parse_private(Buffer *, const char *, const char *, char **);
22Key *key_load_private(const char *, const char *, char **); 24Key *key_load_private(const char *, const char *, char **);
23Key *key_load_private_cert(int, const char *, const char *, int *); 25Key *key_load_private_cert(int, const char *, const char *, int *);
24Key *key_load_private_type(int, const char *, const char *, char **, int *); 26Key *key_load_private_type(int, const char *, const char *, char **, int *);
diff --git a/ssh-add.c b/ssh-add.c
index 94b68ac18..6d5e2a957 100644
--- a/ssh-add.c
+++ b/ssh-add.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-add.c,v 1.100 2010/08/31 12:33:38 djm Exp $ */ 1/* $OpenBSD: ssh-add.c,v 1.101 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
@@ -145,8 +145,12 @@ add_file(AuthenticationConnection *ac, const char *filename)
145 char *comment = NULL; 145 char *comment = NULL;
146 char msg[1024], *certpath; 146 char msg[1024], *certpath;
147 int fd, perms_ok, ret = -1; 147 int fd, perms_ok, ret = -1;
148 Buffer keyblob;
148 149
149 if ((fd = open(filename, O_RDONLY)) < 0) { 150 if (strcmp(filename, "-") == 0) {
151 fd = STDIN_FILENO;
152 filename = "(stdin)";
153 } else if ((fd = open(filename, O_RDONLY)) < 0) {
150 perror(filename); 154 perror(filename);
151 return -1; 155 return -1;
152 } 156 }
@@ -155,18 +159,28 @@ add_file(AuthenticationConnection *ac, const char *filename)
155 * Since we'll try to load a keyfile multiple times, permission errors 159 * Since we'll try to load a keyfile multiple times, permission errors
156 * will occur multiple times, so check perms first and bail if wrong. 160 * will occur multiple times, so check perms first and bail if wrong.
157 */ 161 */
158 perms_ok = key_perm_ok(fd, filename); 162 if (fd != STDIN_FILENO) {
159 close(fd); 163 perms_ok = key_perm_ok(fd, filename);
160 if (!perms_ok) 164 if (!perms_ok) {
165 close(fd);
166 return -1;
167 }
168 }
169 buffer_init(&keyblob);
170 if (!key_load_file(fd, filename, &keyblob)) {
171 buffer_free(&keyblob);
172 close(fd);
161 return -1; 173 return -1;
174 }
175 close(fd);
162 176
163 /* At first, try empty passphrase */ 177 /* At first, try empty passphrase */
164 private = key_load_private(filename, "", &comment); 178 private = key_parse_private(&keyblob, filename, "", &comment);
165 if (comment == NULL) 179 if (comment == NULL)
166 comment = xstrdup(filename); 180 comment = xstrdup(filename);
167 /* try last */ 181 /* try last */
168 if (private == NULL && pass != NULL) 182 if (private == NULL && pass != NULL)
169 private = key_load_private(filename, pass, NULL); 183 private = key_parse_private(&keyblob, filename, pass, NULL);
170 if (private == NULL) { 184 if (private == NULL) {
171 /* clear passphrase since it did not work */ 185 /* clear passphrase since it did not work */
172 clear_pass(); 186 clear_pass();
@@ -177,9 +191,11 @@ add_file(AuthenticationConnection *ac, const char *filename)
177 if (strcmp(pass, "") == 0) { 191 if (strcmp(pass, "") == 0) {
178 clear_pass(); 192 clear_pass();
179 xfree(comment); 193 xfree(comment);
194 buffer_free(&keyblob);
180 return -1; 195 return -1;
181 } 196 }
182 private = key_load_private(filename, pass, &comment); 197 private = key_parse_private(&keyblob, filename, pass,
198 &comment);
183 if (private != NULL) 199 if (private != NULL)
184 break; 200 break;
185 clear_pass(); 201 clear_pass();
@@ -187,6 +203,7 @@ add_file(AuthenticationConnection *ac, const char *filename)
187 "Bad passphrase, try again for %.200s: ", comment); 203 "Bad passphrase, try again for %.200s: ", comment);
188 } 204 }
189 } 205 }
206 buffer_free(&keyblob);
190 207
191 if (ssh_add_identity_constrained(ac, private, comment, lifetime, 208 if (ssh_add_identity_constrained(ac, private, comment, lifetime,
192 confirm)) { 209 confirm)) {
diff --git a/ssh-keygen.c b/ssh-keygen.c
index b52fc39cf..49e4eee10 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-keygen.c,v 1.209 2011/04/12 04:23:50 djm Exp $ */ 1/* $OpenBSD: ssh-keygen.c,v 1.210 2011/04/18 00:46:05 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -1454,6 +1454,9 @@ prepare_options_buf(Buffer *c, int which)
1454 certflags_command != NULL) 1454 certflags_command != NULL)
1455 add_string_option(c, "force-command", certflags_command); 1455 add_string_option(c, "force-command", certflags_command);
1456 if ((which & OPTIONS_EXTENSIONS) != 0 && 1456 if ((which & OPTIONS_EXTENSIONS) != 0 &&
1457 (certflags_flags & CERTOPT_X_FWD) != 0)
1458 add_flag_option(c, "permit-X11-forwarding");
1459 if ((which & OPTIONS_EXTENSIONS) != 0 &&
1457 (certflags_flags & CERTOPT_AGENT_FWD) != 0) 1460 (certflags_flags & CERTOPT_AGENT_FWD) != 0)
1458 add_flag_option(c, "permit-agent-forwarding"); 1461 add_flag_option(c, "permit-agent-forwarding");
1459 if ((which & OPTIONS_EXTENSIONS) != 0 && 1462 if ((which & OPTIONS_EXTENSIONS) != 0 &&
@@ -1465,9 +1468,6 @@ prepare_options_buf(Buffer *c, int which)
1465 if ((which & OPTIONS_EXTENSIONS) != 0 && 1468 if ((which & OPTIONS_EXTENSIONS) != 0 &&
1466 (certflags_flags & CERTOPT_USER_RC) != 0) 1469 (certflags_flags & CERTOPT_USER_RC) != 0)
1467 add_flag_option(c, "permit-user-rc"); 1470 add_flag_option(c, "permit-user-rc");
1468 if ((which & OPTIONS_EXTENSIONS) != 0 &&
1469 (certflags_flags & CERTOPT_X_FWD) != 0)
1470 add_flag_option(c, "permit-X11-forwarding");
1471 if ((which & OPTIONS_CRITICAL) != 0 && 1471 if ((which & OPTIONS_CRITICAL) != 0 &&
1472 certflags_src_addr != NULL) 1472 certflags_src_addr != NULL)
1473 add_string_option(c, "source-address", certflags_src_addr); 1473 add_string_option(c, "source-address", certflags_src_addr);