[BACK]Return to ssh-add.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Annotation of src/usr.bin/ssh/ssh-add.c, Revision 1.18

1.1       deraadt     1: /*
1.13      deraadt     2:  * Author: Tatu Ylonen <ylo@cs.hut.fi>
                      3:  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
                      4:  *                    All rights reserved
                      5:  * Created: Thu Apr  6 00:52:24 1995 ylo
                      6:  * Adds an identity to the authentication server, or removes an identity.
                      7:  */
1.1       deraadt     8:
                      9: #include "includes.h"
1.18    ! markus     10: RCSID("$OpenBSD: ssh-add.c,v 1.17 2000/06/20 01:39:44 markus Exp $");
1.16      markus     11:
                     12: #include <openssl/rsa.h>
                     13: #include <openssl/dsa.h>
1.1       deraadt    14:
                     15: #include "rsa.h"
                     16: #include "ssh.h"
                     17: #include "xmalloc.h"
1.11      markus     18: #include "fingerprint.h"
1.16      markus     19: #include "key.h"
1.18    ! markus     20: #include "authfd.h"
1.16      markus     21: #include "authfile.h"
1.1       deraadt    22:
1.2       provos     23: void
1.7       markus     24: delete_file(AuthenticationConnection *ac, const char *filename)
1.1       deraadt    25: {
1.16      markus     26:        Key *public;
1.12      markus     27:        char *comment;
1.1       deraadt    28:
1.16      markus     29:        public = key_new(KEY_RSA);
                     30:        if (!load_public_key(filename, public, &comment)) {
1.12      markus     31:                printf("Bad key file %s: %s\n", filename, strerror(errno));
                     32:                return;
                     33:        }
1.16      markus     34:        if (ssh_remove_identity(ac, public->rsa))
1.12      markus     35:                fprintf(stderr, "Identity removed: %s (%s)\n", filename, comment);
                     36:        else
                     37:                fprintf(stderr, "Could not remove identity: %s\n", filename);
1.16      markus     38:        key_free(public);
1.12      markus     39:        xfree(comment);
1.1       deraadt    40: }
                     41:
1.2       provos     42: void
1.7       markus     43: delete_all(AuthenticationConnection *ac)
1.1       deraadt    44: {
1.12      markus     45:        /* Send a request to remove all identities. */
                     46:        if (ssh_remove_all_identities(ac))
                     47:                fprintf(stderr, "All identities removed.\n");
                     48:        else
                     49:                fprintf(stderr, "Failed to remove all identitities.\n");
1.1       deraadt    50: }
                     51:
1.14      markus     52: char *
                     53: ssh_askpass(char *askpass, char *msg)
                     54: {
                     55:        pid_t pid;
                     56:        size_t len;
                     57:        char *nl, *pass;
                     58:        int p[2], status;
                     59:        char buf[1024];
                     60:
                     61:        if (askpass == NULL)
                     62:                fatal("internal error: askpass undefined");
                     63:        if (pipe(p) < 0)
                     64:                fatal("ssh_askpass: pipe: %s", strerror(errno));
                     65:        if ((pid = fork()) < 0)
                     66:                fatal("ssh_askpass: fork: %s", strerror(errno));
                     67:        if (pid == 0) {
                     68:                close(p[0]);
                     69:                if (dup2(p[1], STDOUT_FILENO) < 0)
                     70:                        fatal("ssh_askpass: dup2: %s", strerror(errno));
                     71:                execlp(askpass, askpass, msg, (char *) 0);
                     72:                fatal("ssh_askpass: exec(%s): %s", askpass, strerror(errno));
                     73:        }
                     74:        close(p[1]);
                     75:        len = read(p[0], buf, sizeof buf);
                     76:        close(p[0]);
                     77:        while (waitpid(pid, &status, 0) < 0)
                     78:                if (errno != EINTR)
                     79:                        break;
                     80:        if (len <= 1)
                     81:                return xstrdup("");
                     82:        nl = strchr(buf, '\n');
                     83:        if (nl)
                     84:                *nl = '\0';
                     85:        pass = xstrdup(buf);
                     86:        memset(buf, 0, sizeof(buf));
                     87:        return pass;
                     88: }
                     89:
1.2       provos     90: void
1.7       markus     91: add_file(AuthenticationConnection *ac, const char *filename)
1.1       deraadt    92: {
1.16      markus     93:        Key *public;
                     94:        Key *private;
1.14      markus     95:        char *saved_comment, *comment, *askpass = NULL;
                     96:        char buf[1024], msg[1024];
1.12      markus     97:        int success;
1.14      markus     98:        int interactive = isatty(STDIN_FILENO);
1.18    ! markus     99:        int type = KEY_RSA;
1.12      markus    100:
1.18    ! markus    101:        /*
        !           102:         * try to load the public key. right now this only works for RSA,
        !           103:         * since DSA keys are fully encrypted
        !           104:         */
1.16      markus    105:        public = key_new(KEY_RSA);
                    106:        if (!load_public_key(filename, public, &saved_comment)) {
1.18    ! markus    107:                /* ok, so we will asume this is a DSA key */
        !           108:                type = KEY_DSA;
        !           109:                saved_comment = xstrdup(filename);
1.12      markus    110:        }
1.16      markus    111:        key_free(public);
1.12      markus    112:
1.15      markus    113:        if (!interactive && getenv("DISPLAY")) {
                    114:                if (getenv(SSH_ASKPASS_ENV))
                    115:                        askpass = getenv(SSH_ASKPASS_ENV);
                    116:                else
                    117:                        askpass = SSH_ASKPASS_DEFAULT;
                    118:        }
1.14      markus    119:
1.12      markus    120:        /* At first, try empty passphrase */
1.18    ! markus    121:        private = key_new(type);
1.16      markus    122:        success = load_private_key(filename, "", private, &comment);
1.12      markus    123:        if (!success) {
1.14      markus    124:                printf("Need passphrase for %.200s\n", filename);
                    125:                if (!interactive && askpass == NULL) {
1.12      markus    126:                        xfree(saved_comment);
                    127:                        return;
                    128:                }
1.14      markus    129:                snprintf(msg, sizeof msg, "Enter passphrase for %.200s", saved_comment);
1.12      markus    130:                for (;;) {
1.14      markus    131:                        char *pass;
                    132:                        if (interactive) {
                    133:                                snprintf(buf, sizeof buf, "%s: ", msg);
                    134:                                pass = read_passphrase(buf, 1);
                    135:                        } else {
                    136:                                pass = ssh_askpass(askpass, msg);
                    137:                        }
1.12      markus    138:                        if (strcmp(pass, "") == 0) {
                    139:                                xfree(pass);
                    140:                                xfree(saved_comment);
                    141:                                return;
                    142:                        }
1.16      markus    143:                        success = load_private_key(filename, pass, private, &comment);
1.12      markus    144:                        memset(pass, 0, strlen(pass));
                    145:                        xfree(pass);
                    146:                        if (success)
                    147:                                break;
1.14      markus    148:                        strlcpy(msg, "Bad passphrase, try again", sizeof msg);
1.12      markus    149:                }
                    150:        }
                    151:        xfree(saved_comment);
                    152:
1.18    ! markus    153:        if (ssh_add_identity(ac, private, comment))
1.12      markus    154:                fprintf(stderr, "Identity added: %s (%s)\n", filename, comment);
                    155:        else
                    156:                fprintf(stderr, "Could not add identity: %s\n", filename);
1.16      markus    157:        key_free(private);
1.12      markus    158:        xfree(comment);
1.1       deraadt   159: }
                    160:
1.2       provos    161: void
1.11      markus    162: list_identities(AuthenticationConnection *ac, int fp)
1.1       deraadt   163: {
1.12      markus    164:        BIGNUM *e, *n;
                    165:        int status;
                    166:        char *comment;
                    167:        int had_identities;
                    168:
                    169:        e = BN_new();
                    170:        n = BN_new();
                    171:        had_identities = 0;
                    172:        for (status = ssh_get_first_identity(ac, e, n, &comment);
                    173:             status;
                    174:             status = ssh_get_next_identity(ac, e, n, &comment)) {
                    175:                unsigned int bits = BN_num_bits(n);
                    176:                had_identities = 1;
                    177:                if (fp) {
                    178:                        printf("%d %s %s\n", bits, fingerprint(e, n), comment);
                    179:                } else {
                    180:                        char *ebuf, *nbuf;
                    181:                        ebuf = BN_bn2dec(e);
                    182:                        if (ebuf == NULL) {
                    183:                                error("list_identities: BN_bn2dec(e) failed.");
                    184:                        } else {
                    185:                                nbuf = BN_bn2dec(n);
                    186:                                if (nbuf == NULL) {
                    187:                                        error("list_identities: BN_bn2dec(n) failed.");
                    188:                                } else {
                    189:                                        printf("%d %s %s %s\n", bits, ebuf, nbuf, comment);
                    190:                                        free(nbuf);
                    191:                                }
                    192:                                free(ebuf);
                    193:                        }
                    194:                }
                    195:                xfree(comment);
                    196:        }
                    197:        BN_clear_free(e);
                    198:        BN_clear_free(n);
                    199:        if (!had_identities)
                    200:                printf("The agent has no identities.\n");
1.1       deraadt   201: }
                    202:
1.2       provos    203: int
1.7       markus    204: main(int argc, char **argv)
1.1       deraadt   205: {
1.12      markus    206:        AuthenticationConnection *ac = NULL;
                    207:        struct passwd *pw;
                    208:        char buf[1024];
                    209:        int no_files = 1;
                    210:        int i;
                    211:        int deleting = 0;
                    212:
                    213:        /* check if RSA support exists */
                    214:        if (rsa_alive() == 0) {
                    215:                extern char *__progname;
                    216:
                    217:                fprintf(stderr,
                    218:                        "%s: no RSA support in libssl and libcrypto.  See ssl(8).\n",
                    219:                        __progname);
                    220:                exit(1);
                    221:        }
                    222:        /* At first, get a connection to the authentication agent. */
                    223:        ac = ssh_get_authentication_connection();
                    224:        if (ac == NULL) {
                    225:                fprintf(stderr, "Could not open a connection to your authentication agent.\n");
                    226:                exit(1);
                    227:        }
                    228:        for (i = 1; i < argc; i++) {
                    229:                if ((strcmp(argv[i], "-l") == 0) ||
                    230:                    (strcmp(argv[i], "-L") == 0)) {
                    231:                        list_identities(ac, argv[i][1] == 'l' ? 1 : 0);
                    232:                        /* Don't default-add/delete if -l. */
                    233:                        no_files = 0;
                    234:                        continue;
                    235:                }
                    236:                if (strcmp(argv[i], "-d") == 0) {
                    237:                        deleting = 1;
                    238:                        continue;
                    239:                }
                    240:                if (strcmp(argv[i], "-D") == 0) {
                    241:                        delete_all(ac);
                    242:                        no_files = 0;
                    243:                        continue;
                    244:                }
                    245:                no_files = 0;
                    246:                if (deleting)
                    247:                        delete_file(ac, argv[i]);
                    248:                else
                    249:                        add_file(ac, argv[i]);
                    250:        }
                    251:        if (no_files) {
                    252:                pw = getpwuid(getuid());
                    253:                if (!pw) {
                    254:                        fprintf(stderr, "No user found with uid %d\n", (int) getuid());
                    255:                        ssh_close_authentication_connection(ac);
                    256:                        exit(1);
                    257:                }
                    258:                snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, SSH_CLIENT_IDENTITY);
                    259:                if (deleting)
                    260:                        delete_file(ac, buf);
                    261:                else
                    262:                        add_file(ac, buf);
                    263:        }
                    264:        ssh_close_authentication_connection(ac);
                    265:        exit(0);
1.1       deraadt   266: }