]> andersk Git - gssapi-openssh.git/blobdiff - openssh/ssh-agent.c
Import of OpenSSH 3.6.1p1
[gssapi-openssh.git] / openssh / ssh-agent.c
index cca720ee2717a03606a7884cf2c33d16fab7472a..eb593de73f12e7b86e064b12fa100e8298a1e54e 100644 (file)
@@ -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.108 2003/03/13 11:44:50 markus Exp $");
 
 #include <openssl/evp.h>
 #include <openssl/md5.h>
@@ -50,6 +50,8 @@ RCSID("$OpenBSD: ssh-agent.c,v 1.105 2002/10/01 20:34:12 markus 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 {
@@ -106,6 +109,9 @@ extern char *__progname;
 char *__progname;
 #endif
 
+/* Default lifetime (0 == forever) */
+static int lifetime = 0;
+
 static void
 close_socket(SocketEntry *e)
 {
@@ -159,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)
@@ -222,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)
@@ -282,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);
@@ -402,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;
 
@@ -453,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);
@@ -464,15 +505,21 @@ 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;
                }
        }
+       if (lifetime && !death)
+               death = time(NULL) + lifetime;
        if (lookup_identity(k, version) == NULL) {
                Identity *id = xmalloc(sizeof(Identity));
                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++;
@@ -557,6 +604,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;
@@ -930,13 +978,15 @@ 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);
 }
 
 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;
@@ -961,7 +1011,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 +1034,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();
                }
@@ -1116,9 +1172,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.0397380000000001 seconds and 4 git commands to generate.