- 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
option name (though we don't actually enforce this at present).
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
- (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>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -69,6 +69,8 @@
#include "misc.h"
#include "atomicio.h"
#define MAX_KEY_FILE_SIZE (1024 * 1024)
/* Version identification string for SSH v1 identity files. */
static const char authfile_id_string[] =
"SSH PRIVATE KEY FILE FORMAT 1.1\n";
@ -312,12 +314,12 @@ key_parse_public_rsa1(Buffer *blob, char **commentp)
return pub;
}
/* Load the contents of a key file into a buffer */
static int
/* Load a key from a fd into a buffer */
int
key_load_file(int fd, const char *filename, Buffer *blob)
{
u_char buf[1024];
size_t len;
u_char *cp;
struct stat st;
if (fstat(fd, &st) < 0) {
@ -325,30 +327,45 @@ key_load_file(int fd, const char *filename, Buffer *blob)
filename == NULL ? "" : filename,
filename == NULL ? "" : " ",
strerror(errno));
close(fd);
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__,
filename == NULL ? "" : filename,
filename == NULL ? "" : " ");
close(fd);
return 0;
}
len = (size_t)st.st_size; /* truncated */
buffer_init(blob);
cp = buffer_append_space(blob, len);
if (atomicio(read, fd, cp, len) != len) {
debug("%s: read from key file %.200s%sfailed: %.100s", __func__,
filename == NULL ? "" : filename,
filename == NULL ? "" : " ",
strerror(errno));
for (;;) {
if ((len = atomicio(read, fd, buf, sizeof(buf))) == 0) {
if (errno == EPIPE)
break;
debug("%s: read from key file %.200s%sfailed: %.100s",
__func__, filename == NULL ? "" : filename,
filename == NULL ? "" : " ", strerror(errno));
buffer_clear(blob);
close(fd);
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);
return 0;
}
return 1;
}
@ -669,12 +686,39 @@ key_load_private_type(int type, const char *filename, const char *passphrase,
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_load_private(const char *filename, const char *passphrase,
char **commentp)
{
Key *pub, *prv;
Buffer buffer, pubcopy;
Key *prv;
Buffer buffer;
int fd;
fd = open(filename, O_RDONLY);
@ -697,23 +741,7 @@ key_load_private(const char *filename, const char *passphrase,
}
close(fd);
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);
}
prv = key_parse_private(&buffer, filename, passphrase, commentp);
buffer_free(&buffer);
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>
@ -16,9 +16,11 @@
#define AUTHFILE_H
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_public(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_cert(int, const char *, const 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>
* 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 msg[1024], *certpath;
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);
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
* will occur multiple times, so check perms first and bail if wrong.
*/
if (fd != STDIN_FILENO) {
perms_ok = key_perm_ok(fd, filename);
if (!perms_ok) {
close(fd);
if (!perms_ok)
return -1;
}
}
buffer_init(&keyblob);
if (!key_load_file(fd, filename, &keyblob)) {
buffer_free(&keyblob);
close(fd);
return -1;
}
close(fd);
/* At first, try empty passphrase */
private = key_load_private(filename, "", &comment);
private = key_parse_private(&keyblob, filename, "", &comment);
if (comment == NULL)
comment = xstrdup(filename);
/* try last */
if (private == NULL && pass != NULL)
private = key_load_private(filename, pass, NULL);
private = key_parse_private(&keyblob, filename, pass, NULL);
if (private == NULL) {
/* clear passphrase since it did not work */
clear_pass();
@ -177,9 +191,11 @@ add_file(AuthenticationConnection *ac, const char *filename)
if (strcmp(pass, "") == 0) {
clear_pass();
xfree(comment);
buffer_free(&keyblob);
return -1;
}
private = key_load_private(filename, pass, &comment);
private = key_parse_private(&keyblob, filename, pass,
&comment);
if (private != NULL)
break;
clear_pass();
@ -187,6 +203,7 @@ add_file(AuthenticationConnection *ac, const char *filename)
"Bad passphrase, try again for %.200s: ", comment);
}
}
buffer_free(&keyblob);
if (ssh_add_identity_constrained(ac, private, comment, lifetime,
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>
* 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 &&
certflags_command != NULL)
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 &&
(certflags_flags & CERTOPT_AGENT_FWD) != 0)
add_flag_option(c, "permit-agent-forwarding");
@ -1465,9 +1468,6 @@ prepare_options_buf(Buffer *c, int which)
if ((which & OPTIONS_EXTENSIONS) != 0 &&
(certflags_flags & CERTOPT_USER_RC) != 0)
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 &&
certflags_src_addr != NULL)
add_string_option(c, "source-address", certflags_src_addr);