diff options
author | Markus Friedl <markus@cvs.openbsd.org> | 2002-06-05 19:57:13 +0000 |
---|---|---|
committer | Markus Friedl <markus@cvs.openbsd.org> | 2002-06-05 19:57:13 +0000 |
commit | e7d6f5686e00520ad4da065f650de48cf22887e0 (patch) | |
tree | 1a41b8694536b5f5ef3171accbb9a77476e16f05 /usr.bin | |
parent | 8584ed4323d1717cecdf8ef24361d6714bc405d3 (diff) |
ssh-add -x for lock and -X for unlocking the agent.
todo: encrypt private keys with locked...
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/ssh/authfd.c | 22 | ||||
-rw-r--r-- | usr.bin/ssh/authfd.h | 7 | ||||
-rw-r--r-- | usr.bin/ssh/ssh-add.1 | 8 | ||||
-rw-r--r-- | usr.bin/ssh/ssh-add.c | 38 | ||||
-rw-r--r-- | usr.bin/ssh/ssh-agent.c | 69 |
5 files changed, 137 insertions, 7 deletions
diff --git a/usr.bin/ssh/authfd.c b/usr.bin/ssh/authfd.c index f3050d64db2..c9c22d46d4a 100644 --- a/usr.bin/ssh/authfd.c +++ b/usr.bin/ssh/authfd.c @@ -35,7 +35,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: authfd.c,v 1.49 2002/03/21 22:44:05 rees Exp $"); +RCSID("$OpenBSD: authfd.c,v 1.50 2002/06/05 19:57:12 markus Exp $"); #include <openssl/evp.h> @@ -207,6 +207,26 @@ ssh_close_authentication_connection(AuthenticationConnection *auth) xfree(auth); } +/* Lock/unlock agent */ +int +ssh_lock_agent(AuthenticationConnection *auth, int lock, const char *password) +{ + int type; + Buffer msg; + + buffer_init(&msg); + buffer_put_char(&msg, lock ? SSH_AGENTC_LOCK : SSH_AGENTC_UNLOCK); + buffer_put_cstring(&msg, password); + + if (ssh_request_reply(auth, &msg, &msg) == 0) { + buffer_free(&msg); + return 0; + } + type = buffer_get_char(&msg); + buffer_free(&msg); + return decode_reply(type); +} + /* * Returns the first authentication identity held by the agent. */ diff --git a/usr.bin/ssh/authfd.h b/usr.bin/ssh/authfd.h index e8a0ec88f48..b075cfa1019 100644 --- a/usr.bin/ssh/authfd.h +++ b/usr.bin/ssh/authfd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: authfd.h,v 1.24 2002/03/21 22:44:05 rees Exp $ */ +/* $OpenBSD: authfd.h,v 1.25 2002/06/05 19:57:12 markus Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -42,6 +42,10 @@ #define SSH_AGENTC_ADD_SMARTCARD_KEY 20 #define SSH_AGENTC_REMOVE_SMARTCARD_KEY 21 +/* lock/unlock the agent */ +#define SSH_AGENTC_LOCK 22 +#define SSH_AGENTC_UNLOCK 23 + /* extended failure messages */ #define SSH2_AGENT_FAILURE 30 @@ -67,6 +71,7 @@ Key *ssh_get_next_identity(AuthenticationConnection *, char **, int); int ssh_add_identity(AuthenticationConnection *, Key *, const char *); int ssh_remove_identity(AuthenticationConnection *, Key *); int ssh_remove_all_identities(AuthenticationConnection *, int); +int ssh_lock_agent(AuthenticationConnection *, int, const char *); int ssh_update_card(AuthenticationConnection *, int, const char *, const char *); int diff --git a/usr.bin/ssh/ssh-add.1 b/usr.bin/ssh/ssh-add.1 index 163fc45edff..3f462773e0b 100644 --- a/usr.bin/ssh/ssh-add.1 +++ b/usr.bin/ssh/ssh-add.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-add.1,v 1.31 2002/06/05 16:35:45 markus Exp $ +.\" $OpenBSD: ssh-add.1,v 1.32 2002/06/05 19:57:12 markus Exp $ .\" .\" -*- nroff -*- .\" @@ -45,7 +45,7 @@ .Nd adds RSA or DSA identities to the authentication agent .Sh SYNOPSIS .Nm ssh-add -.Op Fl lLdD +.Op Fl lLdDxX .Op Ar .Nm ssh-add .Fl s Ar reader @@ -83,6 +83,10 @@ Lists public key parameters of all identities currently represented by the agent Instead of adding the identity, removes the identity from the agent. .It Fl D Deletes all identities from the agent. +.It Fl x +Lock the agent with a password. +.It Fl X +Unlock the agent. .It Fl s Ar reader Add key in smartcard .Ar reader . diff --git a/usr.bin/ssh/ssh-add.c b/usr.bin/ssh/ssh-add.c index 8a2e43e9173..976ee4841de 100644 --- a/usr.bin/ssh/ssh-add.c +++ b/usr.bin/ssh/ssh-add.c @@ -35,7 +35,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh-add.c,v 1.53 2002/03/21 22:44:05 rees Exp $"); +RCSID("$OpenBSD: ssh-add.c,v 1.54 2002/06/05 19:57:12 markus Exp $"); #include <openssl/evp.h> @@ -223,6 +223,34 @@ list_identities(AuthenticationConnection *ac, int do_fp) } static int +lock_agent(AuthenticationConnection *ac, int lock) +{ + char prompt[100], *p1, *p2; + int passok = 1, ret = -1; + + strlcpy(prompt, "Enter lock password: ", sizeof(prompt)); + p1 = read_passphrase(prompt, RP_ALLOW_STDIN); + if (lock) { + strlcpy(prompt, "Again: ", sizeof prompt); + p2 = read_passphrase(prompt, RP_ALLOW_STDIN); + if (strcmp(p1, p2) != 0) { + fprintf(stderr, "Passwords do not match.\n"); + passok = 0; + } + memset(p2, 0, strlen(p2)); + xfree(p2); + } + if (passok && ssh_lock_agent(ac, lock, p1)) { + fprintf(stderr, "Agent %slocked.\n", lock ? "" : "un"); + ret = 0; + } else + fprintf(stderr, "Failed to %slock agent.\n", lock ? "" : "un"); + memset(p1, 0, strlen(p1)); + xfree(p1); + return -1; +} + +static int do_file(AuthenticationConnection *ac, int deleting, char *file) { if (deleting) { @@ -267,7 +295,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, "lLdDe:s:")) != -1) { + while ((ch = getopt(argc, argv, "lLdDxXe:s:")) != -1) { switch (ch) { case 'l': case 'L': @@ -275,6 +303,12 @@ main(int argc, char **argv) ret = 1; goto done; break; + case 'x': + case 'X': + if (lock_agent(ac, ch == 'x' ? 1 : 0) == -1) + ret = 1; + goto done; + break; case 'd': deleting = 1; break; diff --git a/usr.bin/ssh/ssh-agent.c b/usr.bin/ssh/ssh-agent.c index c178c6d54cc..8ebfa4df66d 100644 --- a/usr.bin/ssh/ssh-agent.c +++ b/usr.bin/ssh/ssh-agent.c @@ -35,7 +35,7 @@ #include "includes.h" #include <sys/queue.h> -RCSID("$OpenBSD: ssh-agent.c,v 1.87 2002/06/05 16:48:54 markus Exp $"); +RCSID("$OpenBSD: ssh-agent.c,v 1.88 2002/06/05 19:57:12 markus Exp $"); #include <openssl/evp.h> #include <openssl/md5.h> @@ -95,6 +95,10 @@ pid_t parent_pid = -1; char socket_name[1024]; char socket_dir[1024]; +/* locking */ +int locked = 0; +char *lock_passwd = NULL; + extern char *__progname; static void @@ -438,6 +442,48 @@ send: success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); } +/* XXX todo: encrypt sensitive data with passphrase */ +static void +process_lock_agent(SocketEntry *e, int lock) +{ + char *passwd; + int success = 0; + + passwd = buffer_get_string(&e->request, NULL); + if (locked && !lock && strcmp(passwd, lock_passwd) == 0) { + locked = 0; + memset(lock_passwd, 0, strlen(lock_passwd)); + xfree(lock_passwd); + lock_passwd = NULL; + success = 1; + } else if (!locked && lock) { + locked = 1; + lock_passwd = xstrdup(passwd); + success = 1; + } + memset(passwd, 0, strlen(passwd)); + xfree(passwd); + + buffer_put_int(&e->output, 1); + buffer_put_char(&e->output, + success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); + return; +} + +static void +no_identities(SocketEntry *e, u_int type) +{ + Buffer msg; + + buffer_init(&msg); + buffer_put_char(&msg, + (type == SSH_AGENTC_REQUEST_RSA_IDENTITIES) ? + SSH_AGENT_RSA_IDENTITIES_ANSWER : SSH2_AGENT_IDENTITIES_ANSWER); + buffer_put_int(&msg, 0); + buffer_put_int(&e->output, buffer_len(&msg)); + buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg)); + buffer_free(&msg); +} #ifdef SMARTCARD static void @@ -553,8 +599,29 @@ process_message(SocketEntry *e) buffer_consume(&e->input, msg_len); type = buffer_get_char(&e->request); + /* check wheter agent is locked */ + if (locked && type != SSH_AGENTC_UNLOCK) { + buffer_clear(&e->request); + switch (type) { + case SSH_AGENTC_REQUEST_RSA_IDENTITIES: + case SSH2_AGENTC_REQUEST_IDENTITIES: + /* send empty lists */ + no_identities(e, type); + break; + default: + /* send a fail message for all other request types */ + buffer_put_int(&e->output, 1); + buffer_put_char(&e->output, SSH_AGENT_FAILURE); + } + return; + } + debug("type %d", type); switch (type) { + case SSH_AGENTC_LOCK: + case SSH_AGENTC_UNLOCK: + process_lock_agent(e, type == SSH_AGENTC_LOCK); + break; /* ssh1 */ case SSH_AGENTC_RSA_CHALLENGE: process_authentication_challenge1(e); |