diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | authfd.c | 22 | ||||
-rw-r--r-- | authfd.h | 7 | ||||
-rw-r--r-- | ssh-add.1 | 8 | ||||
-rw-r--r-- | ssh-add.c | 38 | ||||
-rw-r--r-- | ssh-agent.c | 69 |
6 files changed, 142 insertions, 8 deletions
@@ -110,6 +110,10 @@ | |||
110 | [ssh-agent.c] | 110 | [ssh-agent.c] |
111 | copy current request into an extra buffer and just flush this | 111 | copy current request into an extra buffer and just flush this |
112 | request on errors, ok provos@ | 112 | request on errors, ok provos@ |
113 | - markus@cvs.openbsd.org 2002/06/05 19:57:12 | ||
114 | [authfd.c authfd.h ssh-add.1 ssh-add.c ssh-agent.c] | ||
115 | ssh-add -x for lock and -X for unlocking the agent. | ||
116 | todo: encrypt private keys with locked... | ||
113 | 117 | ||
114 | 20020604 | 118 | 20020604 |
115 | - (stevesk) [channels.c] bug #164 patch from YOSHIFUJI Hideaki (changed | 119 | - (stevesk) [channels.c] bug #164 patch from YOSHIFUJI Hideaki (changed |
@@ -794,4 +798,4 @@ | |||
794 | - (stevesk) entropy.c: typo in debug message | 798 | - (stevesk) entropy.c: typo in debug message |
795 | - (djm) ssh-keygen -i needs seeded RNG; report from markus@ | 799 | - (djm) ssh-keygen -i needs seeded RNG; report from markus@ |
796 | 800 | ||
797 | $Id: ChangeLog,v 1.2173 2002/06/06 21:48:57 mouring Exp $ | 801 | $Id: ChangeLog,v 1.2174 2002/06/06 21:52:03 mouring Exp $ |
@@ -35,7 +35,7 @@ | |||
35 | */ | 35 | */ |
36 | 36 | ||
37 | #include "includes.h" | 37 | #include "includes.h" |
38 | RCSID("$OpenBSD: authfd.c,v 1.49 2002/03/21 22:44:05 rees Exp $"); | 38 | RCSID("$OpenBSD: authfd.c,v 1.50 2002/06/05 19:57:12 markus Exp $"); |
39 | 39 | ||
40 | #include <openssl/evp.h> | 40 | #include <openssl/evp.h> |
41 | 41 | ||
@@ -207,6 +207,26 @@ ssh_close_authentication_connection(AuthenticationConnection *auth) | |||
207 | xfree(auth); | 207 | xfree(auth); |
208 | } | 208 | } |
209 | 209 | ||
210 | /* Lock/unlock agent */ | ||
211 | int | ||
212 | ssh_lock_agent(AuthenticationConnection *auth, int lock, const char *password) | ||
213 | { | ||
214 | int type; | ||
215 | Buffer msg; | ||
216 | |||
217 | buffer_init(&msg); | ||
218 | buffer_put_char(&msg, lock ? SSH_AGENTC_LOCK : SSH_AGENTC_UNLOCK); | ||
219 | buffer_put_cstring(&msg, password); | ||
220 | |||
221 | if (ssh_request_reply(auth, &msg, &msg) == 0) { | ||
222 | buffer_free(&msg); | ||
223 | return 0; | ||
224 | } | ||
225 | type = buffer_get_char(&msg); | ||
226 | buffer_free(&msg); | ||
227 | return decode_reply(type); | ||
228 | } | ||
229 | |||
210 | /* | 230 | /* |
211 | * Returns the first authentication identity held by the agent. | 231 | * Returns the first authentication identity held by the agent. |
212 | */ | 232 | */ |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: authfd.h,v 1.24 2002/03/21 22:44:05 rees Exp $ */ | 1 | /* $OpenBSD: authfd.h,v 1.25 2002/06/05 19:57:12 markus Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -42,6 +42,10 @@ | |||
42 | #define SSH_AGENTC_ADD_SMARTCARD_KEY 20 | 42 | #define SSH_AGENTC_ADD_SMARTCARD_KEY 20 |
43 | #define SSH_AGENTC_REMOVE_SMARTCARD_KEY 21 | 43 | #define SSH_AGENTC_REMOVE_SMARTCARD_KEY 21 |
44 | 44 | ||
45 | /* lock/unlock the agent */ | ||
46 | #define SSH_AGENTC_LOCK 22 | ||
47 | #define SSH_AGENTC_UNLOCK 23 | ||
48 | |||
45 | /* extended failure messages */ | 49 | /* extended failure messages */ |
46 | #define SSH2_AGENT_FAILURE 30 | 50 | #define SSH2_AGENT_FAILURE 30 |
47 | 51 | ||
@@ -67,6 +71,7 @@ Key *ssh_get_next_identity(AuthenticationConnection *, char **, int); | |||
67 | int ssh_add_identity(AuthenticationConnection *, Key *, const char *); | 71 | int ssh_add_identity(AuthenticationConnection *, Key *, const char *); |
68 | int ssh_remove_identity(AuthenticationConnection *, Key *); | 72 | int ssh_remove_identity(AuthenticationConnection *, Key *); |
69 | int ssh_remove_all_identities(AuthenticationConnection *, int); | 73 | int ssh_remove_all_identities(AuthenticationConnection *, int); |
74 | int ssh_lock_agent(AuthenticationConnection *, int, const char *); | ||
70 | int ssh_update_card(AuthenticationConnection *, int, const char *, const char *); | 75 | int ssh_update_card(AuthenticationConnection *, int, const char *, const char *); |
71 | 76 | ||
72 | int | 77 | int |
@@ -1,4 +1,4 @@ | |||
1 | .\" $OpenBSD: ssh-add.1,v 1.31 2002/06/05 16:35:45 markus Exp $ | 1 | .\" $OpenBSD: ssh-add.1,v 1.32 2002/06/05 19:57:12 markus Exp $ |
2 | .\" | 2 | .\" |
3 | .\" -*- nroff -*- | 3 | .\" -*- nroff -*- |
4 | .\" | 4 | .\" |
@@ -45,7 +45,7 @@ | |||
45 | .Nd adds RSA or DSA identities to the authentication agent | 45 | .Nd adds RSA or DSA identities to the authentication agent |
46 | .Sh SYNOPSIS | 46 | .Sh SYNOPSIS |
47 | .Nm ssh-add | 47 | .Nm ssh-add |
48 | .Op Fl lLdD | 48 | .Op Fl lLdDxX |
49 | .Op Ar | 49 | .Op Ar |
50 | .Nm ssh-add | 50 | .Nm ssh-add |
51 | .Fl s Ar reader | 51 | .Fl s Ar reader |
@@ -83,6 +83,10 @@ Lists public key parameters of all identities currently represented by the agent | |||
83 | Instead of adding the identity, removes the identity from the agent. | 83 | Instead of adding the identity, removes the identity from the agent. |
84 | .It Fl D | 84 | .It Fl D |
85 | Deletes all identities from the agent. | 85 | Deletes all identities from the agent. |
86 | .It Fl x | ||
87 | Lock the agent with a password. | ||
88 | .It Fl X | ||
89 | Unlock the agent. | ||
86 | .It Fl s Ar reader | 90 | .It Fl s Ar reader |
87 | Add key in smartcard | 91 | Add key in smartcard |
88 | .Ar reader . | 92 | .Ar reader . |
@@ -35,7 +35,7 @@ | |||
35 | */ | 35 | */ |
36 | 36 | ||
37 | #include "includes.h" | 37 | #include "includes.h" |
38 | RCSID("$OpenBSD: ssh-add.c,v 1.53 2002/03/21 22:44:05 rees Exp $"); | 38 | RCSID("$OpenBSD: ssh-add.c,v 1.54 2002/06/05 19:57:12 markus Exp $"); |
39 | 39 | ||
40 | #include <openssl/evp.h> | 40 | #include <openssl/evp.h> |
41 | 41 | ||
@@ -229,6 +229,34 @@ list_identities(AuthenticationConnection *ac, int do_fp) | |||
229 | } | 229 | } |
230 | 230 | ||
231 | static int | 231 | static int |
232 | lock_agent(AuthenticationConnection *ac, int lock) | ||
233 | { | ||
234 | char prompt[100], *p1, *p2; | ||
235 | int passok = 1, ret = -1; | ||
236 | |||
237 | strlcpy(prompt, "Enter lock password: ", sizeof(prompt)); | ||
238 | p1 = read_passphrase(prompt, RP_ALLOW_STDIN); | ||
239 | if (lock) { | ||
240 | strlcpy(prompt, "Again: ", sizeof prompt); | ||
241 | p2 = read_passphrase(prompt, RP_ALLOW_STDIN); | ||
242 | if (strcmp(p1, p2) != 0) { | ||
243 | fprintf(stderr, "Passwords do not match.\n"); | ||
244 | passok = 0; | ||
245 | } | ||
246 | memset(p2, 0, strlen(p2)); | ||
247 | xfree(p2); | ||
248 | } | ||
249 | if (passok && ssh_lock_agent(ac, lock, p1)) { | ||
250 | fprintf(stderr, "Agent %slocked.\n", lock ? "" : "un"); | ||
251 | ret = 0; | ||
252 | } else | ||
253 | fprintf(stderr, "Failed to %slock agent.\n", lock ? "" : "un"); | ||
254 | memset(p1, 0, strlen(p1)); | ||
255 | xfree(p1); | ||
256 | return -1; | ||
257 | } | ||
258 | |||
259 | static int | ||
232 | do_file(AuthenticationConnection *ac, int deleting, char *file) | 260 | do_file(AuthenticationConnection *ac, int deleting, char *file) |
233 | { | 261 | { |
234 | if (deleting) { | 262 | if (deleting) { |
@@ -277,7 +305,7 @@ main(int argc, char **argv) | |||
277 | fprintf(stderr, "Could not open a connection to your authentication agent.\n"); | 305 | fprintf(stderr, "Could not open a connection to your authentication agent.\n"); |
278 | exit(2); | 306 | exit(2); |
279 | } | 307 | } |
280 | while ((ch = getopt(argc, argv, "lLdDe:s:")) != -1) { | 308 | while ((ch = getopt(argc, argv, "lLdDxXe:s:")) != -1) { |
281 | switch (ch) { | 309 | switch (ch) { |
282 | case 'l': | 310 | case 'l': |
283 | case 'L': | 311 | case 'L': |
@@ -285,6 +313,12 @@ main(int argc, char **argv) | |||
285 | ret = 1; | 313 | ret = 1; |
286 | goto done; | 314 | goto done; |
287 | break; | 315 | break; |
316 | case 'x': | ||
317 | case 'X': | ||
318 | if (lock_agent(ac, ch == 'x' ? 1 : 0) == -1) | ||
319 | ret = 1; | ||
320 | goto done; | ||
321 | break; | ||
288 | case 'd': | 322 | case 'd': |
289 | deleting = 1; | 323 | deleting = 1; |
290 | break; | 324 | break; |
diff --git a/ssh-agent.c b/ssh-agent.c index 13a88afd9..d9567af5c 100644 --- a/ssh-agent.c +++ b/ssh-agent.c | |||
@@ -35,7 +35,7 @@ | |||
35 | 35 | ||
36 | #include "includes.h" | 36 | #include "includes.h" |
37 | #include "openbsd-compat/fake-queue.h" | 37 | #include "openbsd-compat/fake-queue.h" |
38 | RCSID("$OpenBSD: ssh-agent.c,v 1.87 2002/06/05 16:48:54 markus Exp $"); | 38 | RCSID("$OpenBSD: ssh-agent.c,v 1.88 2002/06/05 19:57:12 markus Exp $"); |
39 | 39 | ||
40 | #include <openssl/evp.h> | 40 | #include <openssl/evp.h> |
41 | #include <openssl/md5.h> | 41 | #include <openssl/md5.h> |
@@ -95,6 +95,10 @@ pid_t parent_pid = -1; | |||
95 | char socket_name[1024]; | 95 | char socket_name[1024]; |
96 | char socket_dir[1024]; | 96 | char socket_dir[1024]; |
97 | 97 | ||
98 | /* locking */ | ||
99 | int locked = 0; | ||
100 | char *lock_passwd = NULL; | ||
101 | |||
98 | #ifdef HAVE___PROGNAME | 102 | #ifdef HAVE___PROGNAME |
99 | extern char *__progname; | 103 | extern char *__progname; |
100 | #else | 104 | #else |
@@ -442,6 +446,48 @@ send: | |||
442 | success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); | 446 | success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); |
443 | } | 447 | } |
444 | 448 | ||
449 | /* XXX todo: encrypt sensitive data with passphrase */ | ||
450 | static void | ||
451 | process_lock_agent(SocketEntry *e, int lock) | ||
452 | { | ||
453 | char *passwd; | ||
454 | int success = 0; | ||
455 | |||
456 | passwd = buffer_get_string(&e->request, NULL); | ||
457 | if (locked && !lock && strcmp(passwd, lock_passwd) == 0) { | ||
458 | locked = 0; | ||
459 | memset(lock_passwd, 0, strlen(lock_passwd)); | ||
460 | xfree(lock_passwd); | ||
461 | lock_passwd = NULL; | ||
462 | success = 1; | ||
463 | } else if (!locked && lock) { | ||
464 | locked = 1; | ||
465 | lock_passwd = xstrdup(passwd); | ||
466 | success = 1; | ||
467 | } | ||
468 | memset(passwd, 0, strlen(passwd)); | ||
469 | xfree(passwd); | ||
470 | |||
471 | buffer_put_int(&e->output, 1); | ||
472 | buffer_put_char(&e->output, | ||
473 | success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); | ||
474 | return; | ||
475 | } | ||
476 | |||
477 | static void | ||
478 | no_identities(SocketEntry *e, u_int type) | ||
479 | { | ||
480 | Buffer msg; | ||
481 | |||
482 | buffer_init(&msg); | ||
483 | buffer_put_char(&msg, | ||
484 | (type == SSH_AGENTC_REQUEST_RSA_IDENTITIES) ? | ||
485 | SSH_AGENT_RSA_IDENTITIES_ANSWER : SSH2_AGENT_IDENTITIES_ANSWER); | ||
486 | buffer_put_int(&msg, 0); | ||
487 | buffer_put_int(&e->output, buffer_len(&msg)); | ||
488 | buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg)); | ||
489 | buffer_free(&msg); | ||
490 | } | ||
445 | 491 | ||
446 | #ifdef SMARTCARD | 492 | #ifdef SMARTCARD |
447 | static void | 493 | static void |
@@ -557,8 +603,29 @@ process_message(SocketEntry *e) | |||
557 | buffer_consume(&e->input, msg_len); | 603 | buffer_consume(&e->input, msg_len); |
558 | type = buffer_get_char(&e->request); | 604 | type = buffer_get_char(&e->request); |
559 | 605 | ||
606 | /* check wheter agent is locked */ | ||
607 | if (locked && type != SSH_AGENTC_UNLOCK) { | ||
608 | buffer_clear(&e->request); | ||
609 | switch (type) { | ||
610 | case SSH_AGENTC_REQUEST_RSA_IDENTITIES: | ||
611 | case SSH2_AGENTC_REQUEST_IDENTITIES: | ||
612 | /* send empty lists */ | ||
613 | no_identities(e, type); | ||
614 | break; | ||
615 | default: | ||
616 | /* send a fail message for all other request types */ | ||
617 | buffer_put_int(&e->output, 1); | ||
618 | buffer_put_char(&e->output, SSH_AGENT_FAILURE); | ||
619 | } | ||
620 | return; | ||
621 | } | ||
622 | |||
560 | debug("type %d", type); | 623 | debug("type %d", type); |
561 | switch (type) { | 624 | switch (type) { |
625 | case SSH_AGENTC_LOCK: | ||
626 | case SSH_AGENTC_UNLOCK: | ||
627 | process_lock_agent(e, type == SSH_AGENTC_LOCK); | ||
628 | break; | ||
562 | /* ssh1 */ | 629 | /* ssh1 */ |
563 | case SSH_AGENTC_RSA_CHALLENGE: | 630 | case SSH_AGENTC_RSA_CHALLENGE: |
564 | process_authentication_challenge1(e); | 631 | process_authentication_challenge1(e); |