Skip to content

Commit

Permalink
- [email protected] 2011/05/04 21:15:29
Browse files Browse the repository at this point in the history
     [authfile.c authfile.h ssh-add.c]
     allow "ssh-add - < key"; feedback and ok markus@
  • Loading branch information
djmdjm committed May 5, 2011
1 parent 8cb1cda commit 2ce12ef
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 49 deletions.
3 changes: 3 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -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
- [email protected] 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
Expand Down
100 changes: 64 additions & 36 deletions authfile.c
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>
* Copyright (c) 1995 Tatu Ylonen <[email protected]>, Espoo, Finland
Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -312,43 +314,58 @@ 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) {
error("%s: fstat of key file %.200s%sfailed: %.100s", __func__,
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);
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);
close(fd);
return 0;
}

return 1;
}

Expand Down Expand Up @@ -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);
Expand All @@ -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;
}
Expand Down
4 changes: 3 additions & 1 deletion authfile.h
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>
Expand All @@ -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 *);
Expand Down
33 changes: 25 additions & 8 deletions ssh-add.c
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>
* Copyright (c) 1995 Tatu Ylonen <[email protected]>, Espoo, Finland
Expand Down Expand Up @@ -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;
}
Expand All @@ -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.
*/
perms_ok = key_perm_ok(fd, filename);
close(fd);
if (!perms_ok)
if (fd != STDIN_FILENO) {
perms_ok = key_perm_ok(fd, filename);
if (!perms_ok) {
close(fd);
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();
Expand All @@ -177,16 +191,19 @@ 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();
snprintf(msg, sizeof msg,
"Bad passphrase, try again for %.200s: ", comment);
}
}
buffer_free(&keyblob);

if (ssh_add_identity_constrained(ac, private, comment, lifetime,
confirm)) {
Expand Down
8 changes: 4 additions & 4 deletions ssh-keygen.c
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>
* Copyright (c) 1994 Tatu Ylonen <[email protected]>, Espoo, Finland
Expand Down Expand Up @@ -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");
Expand All @@ -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);
Expand Down

0 comments on commit 2ce12ef

Please sign in to comment.