- 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@
This commit is contained in:
Damien Miller 2011-05-05 14:17:18 +10:00
parent 8cb1cda1e3
commit 2ce12ef1ac
5 changed files with 99 additions and 49 deletions

View File

@ -65,6 +65,9 @@
certificate options are supposed to be packed in lexical order of certificate options are supposed to be packed in lexical order of
option name (though we don't actually enforce this at present). option name (though we don't actually enforce this at present).
Move one up that was out of sequence Move one up that was out of sequence
- 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@
20110221 20110221
- (dtucker) [contrib/cygwin/ssh-host-config] From Corinna: revamp of the - (dtucker) [contrib/cygwin/ssh-host-config] From Corinna: revamp of the

View File

@ -1,4 +1,4 @@
/* $OpenBSD: authfile.c,v 1.87 2010/11/29 18:57:04 markus Exp $ */ /* $OpenBSD: authfile.c,v 1.88 2011/05/04 21:15:29 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -69,6 +69,8 @@
#include "misc.h" #include "misc.h"
#include "atomicio.h" #include "atomicio.h"
#define MAX_KEY_FILE_SIZE (1024 * 1024)
/* Version identification string for SSH v1 identity files. */ /* Version identification string for SSH v1 identity files. */
static const char authfile_id_string[] = static const char authfile_id_string[] =
"SSH PRIVATE KEY FILE FORMAT 1.1\n"; "SSH PRIVATE KEY FILE FORMAT 1.1\n";
@ -312,12 +314,12 @@ key_parse_public_rsa1(Buffer *blob, char **commentp)
return pub; return pub;
} }
/* Load the contents of a key file into a buffer */ /* Load a key from a fd into a buffer */
static int int
key_load_file(int fd, const char *filename, Buffer *blob) key_load_file(int fd, const char *filename, Buffer *blob)
{ {
u_char buf[1024];
size_t len; size_t len;
u_char *cp;
struct stat st; struct stat st;
if (fstat(fd, &st) < 0) { if (fstat(fd, &st) < 0) {
@ -325,30 +327,45 @@ key_load_file(int fd, const char *filename, Buffer *blob)
filename == NULL ? "" : filename, filename == NULL ? "" : filename,
filename == NULL ? "" : " ", filename == NULL ? "" : " ",
strerror(errno)); strerror(errno));
close(fd);
return 0; return 0;
} }
if (st.st_size > 1*1024*1024) { if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
st.st_size > MAX_KEY_FILE_SIZE) {
toobig:
error("%s: key file %.200s%stoo large", __func__, error("%s: key file %.200s%stoo large", __func__,
filename == NULL ? "" : filename, filename == NULL ? "" : filename,
filename == NULL ? "" : " "); filename == NULL ? "" : " ");
close(fd);
return 0; return 0;
} }
len = (size_t)st.st_size; /* truncated */
buffer_init(blob); buffer_init(blob);
cp = buffer_append_space(blob, len); for (;;) {
if ((len = atomicio(read, fd, buf, sizeof(buf))) == 0) {
if (atomicio(read, fd, cp, len) != len) { if (errno == EPIPE)
debug("%s: read from key file %.200s%sfailed: %.100s", __func__, break;
filename == NULL ? "" : filename, debug("%s: read from key file %.200s%sfailed: %.100s",
filename == NULL ? "" : " ", __func__, filename == NULL ? "" : filename,
strerror(errno)); filename == NULL ? "" : " ", strerror(errno));
buffer_clear(blob);
bzero(buf, sizeof(buf));
return 0;
}
buffer_append(blob, buf, len);
if (buffer_len(blob) > MAX_KEY_FILE_SIZE) {
buffer_clear(blob);
bzero(buf, sizeof(buf));
goto toobig;
}
}
bzero(buf, sizeof(buf));
if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
st.st_size != buffer_len(blob)) {
debug("%s: key file %.200s%schanged size while reading",
__func__, filename == NULL ? "" : filename,
filename == NULL ? "" : " ");
buffer_clear(blob); buffer_clear(blob);
close(fd);
return 0; return 0;
} }
return 1; return 1;
} }
@ -669,12 +686,39 @@ key_load_private_type(int type, const char *filename, const char *passphrase,
return ret; return ret;
} }
Key *
key_parse_private(Buffer *buffer, const char *filename,
const char *passphrase, char **commentp)
{
Key *pub, *prv;
Buffer pubcopy;
buffer_init(&pubcopy);
buffer_append(&pubcopy, buffer_ptr(buffer), buffer_len(buffer));
/* it's a SSH v1 key if the public key part is readable */
pub = key_parse_public_rsa1(&pubcopy, commentp);
buffer_free(&pubcopy);
if (pub == NULL) {
prv = key_parse_private_type(buffer, KEY_UNSPEC,
passphrase, NULL);
/* use the filename as a comment for PEM */
if (commentp && prv)
*commentp = xstrdup(filename);
} else {
key_free(pub);
/* key_parse_public_rsa1() has already loaded the comment */
prv = key_parse_private_type(buffer, KEY_RSA1, passphrase,
NULL);
}
return prv;
}
Key * Key *
key_load_private(const char *filename, const char *passphrase, key_load_private(const char *filename, const char *passphrase,
char **commentp) char **commentp)
{ {
Key *pub, *prv; Key *prv;
Buffer buffer, pubcopy; Buffer buffer;
int fd; int fd;
fd = open(filename, O_RDONLY); fd = open(filename, O_RDONLY);
@ -697,23 +741,7 @@ key_load_private(const char *filename, const char *passphrase,
} }
close(fd); close(fd);
buffer_init(&pubcopy); prv = key_parse_private(&buffer, filename, passphrase, commentp);
buffer_append(&pubcopy, buffer_ptr(&buffer), buffer_len(&buffer));
/* it's a SSH v1 key if the public key part is readable */
pub = key_parse_public_rsa1(&pubcopy, commentp);
buffer_free(&pubcopy);
if (pub == NULL) {
prv = key_parse_private_type(&buffer, KEY_UNSPEC,
passphrase, NULL);
/* use the filename as a comment for PEM */
if (commentp && prv)
*commentp = xstrdup(filename);
} else {
key_free(pub);
/* key_parse_public_rsa1() has already loaded the comment */
prv = key_parse_private_type(&buffer, KEY_RSA1, passphrase,
NULL);
}
buffer_free(&buffer); buffer_free(&buffer);
return prv; return prv;
} }

View File

@ -1,4 +1,4 @@
/* $OpenBSD: authfile.h,v 1.15 2010/08/04 05:42:47 djm Exp $ */ /* $OpenBSD: authfile.h,v 1.16 2011/05/04 21:15:29 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -16,9 +16,11 @@
#define AUTHFILE_H #define AUTHFILE_H
int key_save_private(Key *, const char *, const char *, const char *); int key_save_private(Key *, const char *, const char *, const char *);
int key_load_file(int, const char *, Buffer *);
Key *key_load_cert(const char *); Key *key_load_cert(const char *);
Key *key_load_public(const char *, char **); Key *key_load_public(const char *, char **);
Key *key_load_public_type(int, const char *, char **); Key *key_load_public_type(int, const char *, char **);
Key *key_parse_private(Buffer *, const char *, const char *, char **);
Key *key_load_private(const char *, const char *, char **); Key *key_load_private(const char *, const char *, char **);
Key *key_load_private_cert(int, const char *, const char *, int *); Key *key_load_private_cert(int, const char *, const char *, int *);
Key *key_load_private_type(int, const char *, const char *, char **, int *); Key *key_load_private_type(int, const char *, const char *, char **, int *);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-add.c,v 1.100 2010/08/31 12:33:38 djm Exp $ */ /* $OpenBSD: ssh-add.c,v 1.101 2011/05/04 21:15:29 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -145,8 +145,12 @@ add_file(AuthenticationConnection *ac, const char *filename)
char *comment = NULL; char *comment = NULL;
char msg[1024], *certpath; char msg[1024], *certpath;
int fd, perms_ok, ret = -1; int fd, perms_ok, ret = -1;
Buffer keyblob;
if ((fd = open(filename, O_RDONLY)) < 0) { if (strcmp(filename, "-") == 0) {
fd = STDIN_FILENO;
filename = "(stdin)";
} else if ((fd = open(filename, O_RDONLY)) < 0) {
perror(filename); perror(filename);
return -1; return -1;
} }
@ -155,18 +159,28 @@ add_file(AuthenticationConnection *ac, const char *filename)
* Since we'll try to load a keyfile multiple times, permission errors * Since we'll try to load a keyfile multiple times, permission errors
* will occur multiple times, so check perms first and bail if wrong. * will occur multiple times, so check perms first and bail if wrong.
*/ */
perms_ok = key_perm_ok(fd, filename); if (fd != STDIN_FILENO) {
close(fd); perms_ok = key_perm_ok(fd, filename);
if (!perms_ok) if (!perms_ok) {
close(fd);
return -1;
}
}
buffer_init(&keyblob);
if (!key_load_file(fd, filename, &keyblob)) {
buffer_free(&keyblob);
close(fd);
return -1; return -1;
}
close(fd);
/* At first, try empty passphrase */ /* At first, try empty passphrase */
private = key_load_private(filename, "", &comment); private = key_parse_private(&keyblob, filename, "", &comment);
if (comment == NULL) if (comment == NULL)
comment = xstrdup(filename); comment = xstrdup(filename);
/* try last */ /* try last */
if (private == NULL && pass != NULL) if (private == NULL && pass != NULL)
private = key_load_private(filename, pass, NULL); private = key_parse_private(&keyblob, filename, pass, NULL);
if (private == NULL) { if (private == NULL) {
/* clear passphrase since it did not work */ /* clear passphrase since it did not work */
clear_pass(); clear_pass();
@ -177,9 +191,11 @@ add_file(AuthenticationConnection *ac, const char *filename)
if (strcmp(pass, "") == 0) { if (strcmp(pass, "") == 0) {
clear_pass(); clear_pass();
xfree(comment); xfree(comment);
buffer_free(&keyblob);
return -1; return -1;
} }
private = key_load_private(filename, pass, &comment); private = key_parse_private(&keyblob, filename, pass,
&comment);
if (private != NULL) if (private != NULL)
break; break;
clear_pass(); clear_pass();
@ -187,6 +203,7 @@ add_file(AuthenticationConnection *ac, const char *filename)
"Bad passphrase, try again for %.200s: ", comment); "Bad passphrase, try again for %.200s: ", comment);
} }
} }
buffer_free(&keyblob);
if (ssh_add_identity_constrained(ac, private, comment, lifetime, if (ssh_add_identity_constrained(ac, private, comment, lifetime,
confirm)) { confirm)) {

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-keygen.c,v 1.209 2011/04/12 04:23:50 djm Exp $ */ /* $OpenBSD: ssh-keygen.c,v 1.210 2011/04/18 00:46:05 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -1453,6 +1453,9 @@ prepare_options_buf(Buffer *c, int which)
if ((which & OPTIONS_CRITICAL) != 0 && if ((which & OPTIONS_CRITICAL) != 0 &&
certflags_command != NULL) certflags_command != NULL)
add_string_option(c, "force-command", certflags_command); add_string_option(c, "force-command", certflags_command);
if ((which & OPTIONS_EXTENSIONS) != 0 &&
(certflags_flags & CERTOPT_X_FWD) != 0)
add_flag_option(c, "permit-X11-forwarding");
if ((which & OPTIONS_EXTENSIONS) != 0 && if ((which & OPTIONS_EXTENSIONS) != 0 &&
(certflags_flags & CERTOPT_AGENT_FWD) != 0) (certflags_flags & CERTOPT_AGENT_FWD) != 0)
add_flag_option(c, "permit-agent-forwarding"); add_flag_option(c, "permit-agent-forwarding");
@ -1465,9 +1468,6 @@ prepare_options_buf(Buffer *c, int which)
if ((which & OPTIONS_EXTENSIONS) != 0 && if ((which & OPTIONS_EXTENSIONS) != 0 &&
(certflags_flags & CERTOPT_USER_RC) != 0) (certflags_flags & CERTOPT_USER_RC) != 0)
add_flag_option(c, "permit-user-rc"); add_flag_option(c, "permit-user-rc");
if ((which & OPTIONS_EXTENSIONS) != 0 &&
(certflags_flags & CERTOPT_X_FWD) != 0)
add_flag_option(c, "permit-X11-forwarding");
if ((which & OPTIONS_CRITICAL) != 0 && if ((which & OPTIONS_CRITICAL) != 0 &&
certflags_src_addr != NULL) certflags_src_addr != NULL)
add_string_option(c, "source-address", certflags_src_addr); add_string_option(c, "source-address", certflags_src_addr);