]> andersk Git - openssh.git/commitdiff
- markus@cvs.openbsd.org 2003/01/23 13:50:27
authordjm <djm>
Fri, 24 Jan 2003 00:36:23 +0000 (00:36 +0000)
committerdjm <djm>
Fri, 24 Jan 2003 00:36:23 +0000 (00:36 +0000)
     [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
authfd.c
authfd.h
readpass.c
ssh-add.1
ssh-add.c
ssh-agent.c

index 20e8be2399c2e603ba4c4d17fe5306f040450905..43c50412fda6212c227b74e4ba339ebf09834b08 100644 (file)
--- 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
index f04e0858b04806e2da4c53e59dbcb702bbf8ddf3..a186e01175b0004fa5e5722671abfde52b6cb55a 100644 (file)
--- 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 <openssl/evp.h>
 
@@ -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);
 }
 
 /*
index 38ee49e88523fa67b688002de056b6200c24ef48..2a8751ec18bf503f33db3eff77e0273d392f9c6a 100644 (file)
--- 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 <ylo@cs.hut.fi>
@@ -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 *);
index 96b7e84b44fcee486b4f6e1e54defdd339ab5128..95ec5d8738987db9b7a7fdfdeb6c795f26104487 100644 (file)
@@ -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) {
index 2a34a513317500c1d91e7a0080135a567e766093..66a8f9715aed72a61080877f348b30fe02b2478b 100644 (file)
--- 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 .
index 4f4ab3a06b4cb780648caf72fb86e9b6fe4f7872..0c2ce163cf6d36470d9c40d571439cb9b38698b2 100644 (file)
--- 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 <openssl/evp.h>
 
@@ -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;
index 554f8942a67d3392089bbcca698e1244ae09ecbb..b18dd980c2a3a8f8fd4f98921fb21803a39770a2 100644 (file)
@@ -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 <openssl/evp.h>
 #include <openssl/md5.h>
@@ -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 */
This page took 0.087945 seconds and 5 git commands to generate.