From 53d81483f0bcea8af2207583bb6e83c187d522fc Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 22 Jan 2003 11:47:19 +1100 Subject: - (djm) OpenBSD CVS Sync - marc@cvs.openbsd.org 2003/01/21 18:14:36 [ssh-agent.1 ssh-agent.c] Add a -t life option to ssh-agent that set the default lifetime. The default can still be overriden by using -t in ssh-add. OK markus@ --- ssh-agent.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'ssh-agent.c') diff --git a/ssh-agent.c b/ssh-agent.c index cca720ee2..554f8942a 100644 --- a/ssh-agent.c +++ b/ssh-agent.c @@ -35,7 +35,7 @@ #include "includes.h" #include "openbsd-compat/sys-queue.h" -RCSID("$OpenBSD: ssh-agent.c,v 1.105 2002/10/01 20:34:12 markus Exp $"); +RCSID("$OpenBSD: ssh-agent.c,v 1.106 2003/01/21 18:14:36 marc Exp $"); #include #include @@ -106,6 +106,9 @@ extern char *__progname; char *__progname; #endif +/* Default lifetime (0 == forever) */ +static int lifetime = 0; + static void close_socket(SocketEntry *e) { @@ -468,6 +471,8 @@ process_add_identity(SocketEntry *e, int version) break; } } + if (lifetime && !death) + death = time(NULL) + lifetime; if (lookup_identity(k, version) == NULL) { Identity *id = xmalloc(sizeof(Identity)); id->key = k; @@ -930,6 +935,7 @@ usage(void) fprintf(stderr, " -k Kill the current agent.\n"); fprintf(stderr, " -d Debug mode.\n"); fprintf(stderr, " -a socket Bind agent socket to given name.\n"); + fprintf(stderr, " -t life Default identity lifetime (seconds).\n"); exit(1); } @@ -961,7 +967,7 @@ main(int ac, char **av) init_rng(); seed_rng(); - while ((ch = getopt(ac, av, "cdksa:")) != -1) { + while ((ch = getopt(ac, av, "cdksa:t:")) != -1) { switch (ch) { case 'c': if (s_flag) @@ -984,6 +990,12 @@ main(int ac, char **av) case 'a': agentsocket = optarg; break; + case 't': + if ((lifetime = convtime(optarg)) == -1) { + fprintf(stderr, "Invalid lifetime\n"); + usage(); + } + break; default: usage(); } -- cgit v1.2.3 From 6c71179f6839ab49e4e8a91209eef85dc190d5f1 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 24 Jan 2003 11:36:23 +1100 Subject: - markus@cvs.openbsd.org 2003/01/23 13:50:27 [authfd.c authfd.h readpass.c ssh-add.1 ssh-add.c ssh-agent.c] ssh-add -c, prompt user for confirmation (using ssh-askpass) when private agent key is used; with djm@; test by dugsong@, djm@; ok deraadt@ --- ChangeLog | 7 ++++++- authfd.c | 10 ++++++---- authfd.h | 6 ++++-- readpass.c | 16 ++++++++++++---- ssh-add.1 | 12 ++++++++++-- ssh-add.c | 17 ++++++++++++++--- ssh-agent.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++-------- 7 files changed, 98 insertions(+), 24 deletions(-) (limited to 'ssh-agent.c') diff --git a/ChangeLog b/ChangeLog index 7ecd2f7fa..2fb0b941e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,11 @@ - jmc@cvs.openbsd.org 2003/01/23 08:58:47 [sshd_config.5] typos; ok millert@ + - markus@cvs.openbsd.org 2003/01/23 13:50:27 + [authfd.c authfd.h readpass.c ssh-add.1 ssh-add.c ssh-agent.c] + ssh-add -c, prompt user for confirmation (using ssh-askpass) when + private agent key is used; with djm@; test by dugsong@, djm@; + ok deraadt@ 20030123 - (djm) OpenBSD CVS Sync @@ -1062,4 +1067,4 @@ save auth method before monitor_reset_key_state(); bugzilla bug #284; ok provos@ -$Id: ChangeLog,v 1.2583 2003/01/24 00:34:52 djm Exp $ +$Id: ChangeLog,v 1.2584 2003/01/24 00:36:23 djm Exp $ diff --git a/authfd.c b/authfd.c index f04e0858b..a186e0117 100644 --- a/authfd.c +++ b/authfd.c @@ -35,7 +35,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: authfd.c,v 1.57 2002/09/11 18:27:26 stevesk Exp $"); +RCSID("$OpenBSD: authfd.c,v 1.58 2003/01/23 13:50:27 markus Exp $"); #include @@ -499,10 +499,10 @@ ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment) int ssh_add_identity_constrained(AuthenticationConnection *auth, Key *key, - const char *comment, u_int life) + const char *comment, u_int life, u_int confirm) { Buffer msg; - int type, constrained = (life != 0); + int type, constrained = (life || confirm); buffer_init(&msg); @@ -532,6 +532,8 @@ ssh_add_identity_constrained(AuthenticationConnection *auth, Key *key, buffer_put_char(&msg, SSH_AGENT_CONSTRAIN_LIFETIME); buffer_put_int(&msg, life); } + if (confirm != 0) + buffer_put_char(&msg, SSH_AGENT_CONSTRAIN_CONFIRM); } if (ssh_request_reply(auth, &msg, &msg) == 0) { buffer_free(&msg); @@ -545,7 +547,7 @@ ssh_add_identity_constrained(AuthenticationConnection *auth, Key *key, int ssh_add_identity(AuthenticationConnection *auth, Key *key, const char *comment) { - return ssh_add_identity_constrained(auth, key, comment, 0); + return ssh_add_identity_constrained(auth, key, comment, 0, 0); } /* diff --git a/authfd.h b/authfd.h index 38ee49e88..2a8751ec1 100644 --- a/authfd.h +++ b/authfd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: authfd.h,v 1.31 2002/09/11 18:27:25 stevesk Exp $ */ +/* $OpenBSD: authfd.h,v 1.32 2003/01/23 13:50:27 markus Exp $ */ /* * Author: Tatu Ylonen @@ -51,6 +51,7 @@ #define SSH2_AGENTC_ADD_ID_CONSTRAINED 25 #define SSH_AGENT_CONSTRAIN_LIFETIME 1 +#define SSH_AGENT_CONSTRAIN_CONFIRM 2 /* extended failure messages */ #define SSH2_AGENT_FAILURE 30 @@ -76,7 +77,8 @@ int ssh_get_num_identities(AuthenticationConnection *, int); Key *ssh_get_first_identity(AuthenticationConnection *, char **, int); Key *ssh_get_next_identity(AuthenticationConnection *, char **, int); int ssh_add_identity(AuthenticationConnection *, Key *, const char *); -int ssh_add_identity_constrained(AuthenticationConnection *, Key *, const char *, u_int); +int ssh_add_identity_constrained(AuthenticationConnection *, Key *, + const char *, u_int, u_int); int ssh_remove_identity(AuthenticationConnection *, Key *); int ssh_remove_all_identities(AuthenticationConnection *, int); int ssh_lock_agent(AuthenticationConnection *, int, const char *); diff --git a/readpass.c b/readpass.c index 96b7e84b4..95ec5d873 100644 --- a/readpass.c +++ b/readpass.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: readpass.c,v 1.27 2002/03/26 15:58:46 markus Exp $"); +RCSID("$OpenBSD: readpass.c,v 1.28 2003/01/23 13:50:27 markus Exp $"); #include "xmalloc.h" #include "readpass.h" @@ -46,11 +46,11 @@ ssh_askpass(char *askpass, const char *msg) fatal("internal error: askpass undefined"); if (pipe(p) < 0) { error("ssh_askpass: pipe: %s", strerror(errno)); - return xstrdup(""); + return NULL; } if ((pid = fork()) < 0) { error("ssh_askpass: fork: %s", strerror(errno)); - return xstrdup(""); + return NULL; } if (pid == 0) { seteuid(getuid()); @@ -79,6 +79,11 @@ ssh_askpass(char *askpass, const char *msg) if (errno != EINTR) break; + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { + memset(buf, 0, sizeof(buf)); + return NULL; + } + buf[strcspn(buf, "\r\n")] = '\0'; pass = xstrdup(buf); memset(buf, 0, sizeof(buf)); @@ -115,7 +120,10 @@ read_passphrase(const char *prompt, int flags) askpass = getenv(SSH_ASKPASS_ENV); else askpass = _PATH_SSH_ASKPASS_DEFAULT; - return ssh_askpass(askpass, prompt); + if ((ret = ssh_askpass(askpass, prompt)) == NULL) + if (!(flags & RP_ALLOW_EOF)) + return xstrdup(""); + return ret; } if (readpassphrase(prompt, buf, sizeof buf, rppflags) == NULL) { diff --git a/ssh-add.1 b/ssh-add.1 index 2a34a5133..66a8f9715 100644 --- a/ssh-add.1 +++ b/ssh-add.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-add.1,v 1.35 2002/06/19 00:27:55 deraadt Exp $ +.\" $OpenBSD: ssh-add.1,v 1.36 2003/01/23 13:50:27 markus Exp $ .\" .\" -*- nroff -*- .\" @@ -45,7 +45,7 @@ .Nd adds RSA or DSA identities to the authentication agent .Sh SYNOPSIS .Nm ssh-add -.Op Fl lLdDxX +.Op Fl lLdDxXc .Op Fl t Ar life .Op Ar .Nm ssh-add @@ -93,6 +93,14 @@ Set a maximum lifetime when adding identities to an agent. The lifetime may be specified in seconds or in a time format specified in .Xr sshd 8 . +.It Fl c +Indicates that added identities should be subject to confirmation before +being used for authentication. Confirmation is performed by the +.Ev SSH_ASKPASS +program mentioned below. Successful confirmation is signaled by a zero +exit status from the +.Ev SSH_ASKPASS +program, rather than text entered into the requester. .It Fl s Ar reader Add key in smartcard .Ar reader . diff --git a/ssh-add.c b/ssh-add.c index 4f4ab3a06..0c2ce163c 100644 --- a/ssh-add.c +++ b/ssh-add.c @@ -35,7 +35,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh-add.c,v 1.64 2002/11/21 23:03:51 deraadt Exp $"); +RCSID("$OpenBSD: ssh-add.c,v 1.65 2003/01/23 13:50:27 markus Exp $"); #include @@ -70,6 +70,9 @@ static char *default_files[] = { /* Default lifetime (0 == forever) */ static int lifetime = 0; +/* User has to confirm key use */ +static int confirm = 0; + /* we keep a cache of one passphrases */ static char *pass = NULL; static void @@ -165,12 +168,16 @@ add_file(AuthenticationConnection *ac, const char *filename) } } - if (ssh_add_identity_constrained(ac, private, comment, lifetime)) { + if (ssh_add_identity_constrained(ac, private, comment, lifetime, + confirm)) { fprintf(stderr, "Identity added: %s (%s)\n", filename, comment); ret = 0; if (lifetime != 0) fprintf(stderr, "Lifetime set to %d seconds\n", lifetime); + if (confirm != 0) + fprintf(stderr, + "The user has to confirm each use of the key\n"); } else if (ssh_add_identity(ac, private, comment)) { fprintf(stderr, "Identity added: %s (%s)\n", filename, comment); ret = 0; @@ -292,6 +299,7 @@ usage(void) fprintf(stderr, " -x Lock agent.\n"); fprintf(stderr, " -X Unlock agent.\n"); fprintf(stderr, " -t life Set lifetime (in seconds) when adding identities.\n"); + fprintf(stderr, " -c Require confirmation to sign using identities\n"); #ifdef SMARTCARD fprintf(stderr, " -s reader Add key in smartcard reader.\n"); fprintf(stderr, " -e reader Remove key in smartcard reader.\n"); @@ -319,7 +327,7 @@ main(int argc, char **argv) fprintf(stderr, "Could not open a connection to your authentication agent.\n"); exit(2); } - while ((ch = getopt(argc, argv, "lLdDxXe:s:t:")) != -1) { + while ((ch = getopt(argc, argv, "lLcdDxXe:s:t:")) != -1) { switch (ch) { case 'l': case 'L': @@ -333,6 +341,9 @@ main(int argc, char **argv) ret = 1; goto done; break; + case 'c': + confirm = 1; + break; case 'd': deleting = 1; break; diff --git a/ssh-agent.c b/ssh-agent.c index 554f8942a..b18dd980c 100644 --- a/ssh-agent.c +++ b/ssh-agent.c @@ -35,7 +35,7 @@ #include "includes.h" #include "openbsd-compat/sys-queue.h" -RCSID("$OpenBSD: ssh-agent.c,v 1.106 2003/01/21 18:14:36 marc Exp $"); +RCSID("$OpenBSD: ssh-agent.c,v 1.107 2003/01/23 13:50:27 markus Exp $"); #include #include @@ -50,6 +50,8 @@ RCSID("$OpenBSD: ssh-agent.c,v 1.106 2003/01/21 18:14:36 marc Exp $"); #include "authfd.h" #include "compat.h" #include "log.h" +#include "readpass.h" +#include "misc.h" #ifdef SMARTCARD #include "scard.h" @@ -77,6 +79,7 @@ typedef struct identity { Key *key; char *comment; u_int death; + u_int confirm; } Identity; typedef struct { @@ -162,6 +165,30 @@ lookup_identity(Key *key, int version) return (NULL); } +/* Check confirmation of keysign request */ +static int +confirm_key(Identity *id) +{ + char *p, prompt[1024]; + int ret = -1; + + p = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX); + snprintf(prompt, sizeof(prompt), "Allow use of key %s?\n" + "Key fingerprint %s.", id->comment, p); + xfree(p); + p = read_passphrase(prompt, RP_ALLOW_EOF); + if (p != NULL) { + /* + * Accept empty responses and responses consisting + * of the word "yes" as affirmative. + */ + if (*p == '\0' || *p == '\n' || strcasecmp(p, "yes") == 0) + ret = 0; + xfree(p); + } + return (ret); +} + /* send list of supported public keys to 'client' */ static void process_request_identities(SocketEntry *e, int version) @@ -225,7 +252,7 @@ process_authentication_challenge1(SocketEntry *e) goto failure; id = lookup_identity(key, 1); - if (id != NULL) { + if (id != NULL && (!id->confirm || confirm_key(id) == 0)) { Key *private = id->key; /* Decrypt the challenge using the private key. */ if (rsa_private_decrypt(challenge, challenge, private->rsa) <= 0) @@ -285,7 +312,7 @@ process_sign_request2(SocketEntry *e) key = key_from_blob(blob, blen); if (key != NULL) { Identity *id = lookup_identity(key, 2); - if (id != NULL) + if (id != NULL && (!id->confirm || confirm_key(id) == 0)) ok = key_sign(id->key, &signature, &slen, data, dlen); } key_free(key); @@ -405,7 +432,7 @@ static void process_add_identity(SocketEntry *e, int version) { Idtab *tab = idtab_lookup(version); - int type, success = 0, death = 0; + int type, success = 0, death = 0, confirm = 0; char *type_name, *comment; Key *k = NULL; @@ -467,6 +494,9 @@ process_add_identity(SocketEntry *e, int version) case SSH_AGENT_CONSTRAIN_LIFETIME: death = time(NULL) + buffer_get_int(&e->request); break; + case SSH_AGENT_CONSTRAIN_CONFIRM: + confirm = 1; + break; default: break; } @@ -478,6 +508,7 @@ process_add_identity(SocketEntry *e, int version) id->key = k; id->comment = comment; id->death = death; + id->confirm = confirm; TAILQ_INSERT_TAIL(&tab->idlist, id, next); /* Increment the number of identities. */ tab->nentries++; @@ -562,6 +593,7 @@ process_add_smartcard_key (SocketEntry *e) id->key = k; id->comment = xstrdup("smartcard key"); id->death = 0; + id->confirm = 0; TAILQ_INSERT_TAIL(&tab->idlist, id, next); tab->nentries++; success = 1; @@ -942,7 +974,8 @@ usage(void) int main(int ac, char **av) { - int sock, c_flag = 0, d_flag = 0, k_flag = 0, s_flag = 0, ch, nalloc; + int c_flag = 0, d_flag = 0, k_flag = 0, s_flag = 0; + int sock, fd, ch, nalloc; char *shell, *format, *pidstr, *agentsocket = NULL; fd_set *readsetp = NULL, *writesetp = NULL; struct sockaddr_un sunaddr; @@ -1128,9 +1161,14 @@ main(int ac, char **av) } (void)chdir("/"); - close(0); - close(1); - close(2); + if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { + /* XXX might close listen socket */ + (void)dup2(fd, STDIN_FILENO); + (void)dup2(fd, STDOUT_FILENO); + (void)dup2(fd, STDERR_FILENO); + if (fd > 2) + close(fd); + } #ifdef HAVE_SETRLIMIT /* deny core dumps, since memory contains unencrypted private keys */ -- cgit v1.2.3 From c51d0735a4a68ddcd927f003ffb3fc917cb207c2 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sat, 15 Mar 2003 11:37:09 +1100 Subject: - markus@cvs.openbsd.org 2003/03/13 11:44:50 [ssh-agent.c] ssh-agent is similar to ssh-keysign (allows other processes to use private rsa keys). however, it gets key over socket and not from a file, so we have to do blinding here as well. --- ChangeLog | 7 ++++++- ssh-agent.c | 13 ++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) (limited to 'ssh-agent.c') diff --git a/ChangeLog b/ChangeLog index 961f12c7e..c692c2785 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,11 @@ - markus@cvs.openbsd.org 2003/03/13 11:42:19 [authfile.c ssh-keysign.c] move RSA_blinding_on to generic key load method + - markus@cvs.openbsd.org 2003/03/13 11:44:50 + [ssh-agent.c] + ssh-agent is similar to ssh-keysign (allows other processes to use + private rsa keys). however, it gets key over socket and not from + a file, so we have to do blinding here as well. 20030310 - (djm) OpenBSD CVS Sync @@ -1209,4 +1214,4 @@ save auth method before monitor_reset_key_state(); bugzilla bug #284; ok provos@ -$Id: ChangeLog,v 1.2628 2003/03/15 00:36:18 djm Exp $ +$Id: ChangeLog,v 1.2629 2003/03/15 00:37:09 djm Exp $ diff --git a/ssh-agent.c b/ssh-agent.c index b18dd980c..eb593de73 100644 --- a/ssh-agent.c +++ b/ssh-agent.c @@ -35,7 +35,7 @@ #include "includes.h" #include "openbsd-compat/sys-queue.h" -RCSID("$OpenBSD: ssh-agent.c,v 1.107 2003/01/23 13:50:27 markus Exp $"); +RCSID("$OpenBSD: ssh-agent.c,v 1.108 2003/03/13 11:44:50 markus Exp $"); #include #include @@ -483,6 +483,17 @@ process_add_identity(SocketEntry *e, int version) } break; } + /* enable blinding */ + switch (k->type) { + case KEY_RSA: + case KEY_RSA1: + if (RSA_blinding_on(k->rsa, NULL) != 1) { + error("process_add_identity: RSA_blinding_on failed"); + key_free(k); + goto send; + } + break; + } comment = buffer_get_string(&e->request, NULL); if (k == NULL) { xfree(comment); -- cgit v1.2.3