From 3db7f994db9ab39eec38e76bee096b1201a73e3f Mon Sep 17 00:00:00 2001 From: mouring Date: Thu, 6 Jun 2002 21:52:03 +0000 Subject: [PATCH] - markus@cvs.openbsd.org 2002/06/05 19:57:12 [authfd.c authfd.h ssh-add.1 ssh-add.c ssh-agent.c] ssh-add -x for lock and -X for unlocking the agent. todo: encrypt private keys with locked... --- ChangeLog | 4 ++++ authfd.c | 22 ++++++++++++++++- authfd.h | 7 +++++- ssh-add.1 | 8 +++++-- ssh-add.c | 38 +++++++++++++++++++++++++++-- ssh-agent.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 6 files changed, 141 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 87f3a4c7..cbdb087b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -110,6 +110,10 @@ [ssh-agent.c] copy current request into an extra buffer and just flush this request on errors, ok provos@ + - markus@cvs.openbsd.org 2002/06/05 19:57:12 + [authfd.c authfd.h ssh-add.1 ssh-add.c ssh-agent.c] + ssh-add -x for lock and -X for unlocking the agent. + todo: encrypt private keys with locked... 20020604 - (stevesk) [channels.c] bug #164 patch from YOSHIFUJI Hideaki (changed diff --git a/authfd.c b/authfd.c index f3050d64..c9c22d46 100644 --- a/authfd.c +++ b/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 @@ -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/authfd.h b/authfd.h index e8a0ec88..b075cfa1 100644 --- a/authfd.h +++ b/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 @@ -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/ssh-add.1 b/ssh-add.1 index 163fc45e..3f462773 100644 --- a/ssh-add.1 +++ b/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/ssh-add.c b/ssh-add.c index d24d761a..ecf4666d 100644 --- a/ssh-add.c +++ b/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 @@ -228,6 +228,34 @@ list_identities(AuthenticationConnection *ac, int do_fp) return 0; } +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) { @@ -277,7 +305,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': @@ -285,6 +313,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/ssh-agent.c b/ssh-agent.c index 13a88afd..d9567af5 100644 --- a/ssh-agent.c +++ b/ssh-agent.c @@ -35,7 +35,7 @@ #include "includes.h" #include "openbsd-compat/fake-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 #include @@ -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; + #ifdef HAVE___PROGNAME extern char *__progname; #else @@ -442,6 +446,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 @@ -557,8 +603,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); -- 2.45.1