[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.16

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.16    ! markus     10: RCSID("$Id: ssh-add.c,v 1.1.1.1 2000/01/28 15:35:34 markus Exp $");
        !            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"
                     18: #include "authfd.h"
1.11      markus     19: #include "fingerprint.h"
1.16    ! markus     20: #include "key.h"
        !            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.12      markus     99:
1.16    ! markus    100:        public = key_new(KEY_RSA);
        !           101:        if (!load_public_key(filename, public, &saved_comment)) {
1.12      markus    102:                printf("Bad key file %s: %s\n", filename, strerror(errno));
                    103:                return;
                    104:        }
1.16    ! markus    105:        key_free(public);
1.12      markus    106:
1.15      markus    107:        if (!interactive && getenv("DISPLAY")) {
                    108:                if (getenv(SSH_ASKPASS_ENV))
                    109:                        askpass = getenv(SSH_ASKPASS_ENV);
                    110:                else
                    111:                        askpass = SSH_ASKPASS_DEFAULT;
                    112:        }
1.14      markus    113:
1.12      markus    114:        /* At first, try empty passphrase */
1.16    ! markus    115:        private = key_new(KEY_RSA);
        !           116:        success = load_private_key(filename, "", private, &comment);
1.12      markus    117:        if (!success) {
1.14      markus    118:                printf("Need passphrase for %.200s\n", filename);
                    119:                if (!interactive && askpass == NULL) {
1.12      markus    120:                        xfree(saved_comment);
                    121:                        return;
                    122:                }
1.14      markus    123:                snprintf(msg, sizeof msg, "Enter passphrase for %.200s", saved_comment);
1.12      markus    124:                for (;;) {
1.14      markus    125:                        char *pass;
                    126:                        if (interactive) {
                    127:                                snprintf(buf, sizeof buf, "%s: ", msg);
                    128:                                pass = read_passphrase(buf, 1);
                    129:                        } else {
                    130:                                pass = ssh_askpass(askpass, msg);
                    131:                        }
1.12      markus    132:                        if (strcmp(pass, "") == 0) {
                    133:                                xfree(pass);
                    134:                                xfree(saved_comment);
                    135:                                return;
                    136:                        }
1.16    ! markus    137:                        success = load_private_key(filename, pass, private, &comment);
1.12      markus    138:                        memset(pass, 0, strlen(pass));
                    139:                        xfree(pass);
                    140:                        if (success)
                    141:                                break;
1.14      markus    142:                        strlcpy(msg, "Bad passphrase, try again", sizeof msg);
1.12      markus    143:                }
                    144:        }
                    145:        xfree(saved_comment);
                    146:
1.16    ! markus    147:        if (ssh_add_identity(ac, private->rsa, comment))
1.12      markus    148:                fprintf(stderr, "Identity added: %s (%s)\n", filename, comment);
                    149:        else
                    150:                fprintf(stderr, "Could not add identity: %s\n", filename);
1.16    ! markus    151:        key_free(private);
1.12      markus    152:        xfree(comment);
1.1       deraadt   153: }
                    154:
1.2       provos    155: void
1.11      markus    156: list_identities(AuthenticationConnection *ac, int fp)
1.1       deraadt   157: {
1.12      markus    158:        BIGNUM *e, *n;
                    159:        int status;
                    160:        char *comment;
                    161:        int had_identities;
                    162:
                    163:        e = BN_new();
                    164:        n = BN_new();
                    165:        had_identities = 0;
                    166:        for (status = ssh_get_first_identity(ac, e, n, &comment);
                    167:             status;
                    168:             status = ssh_get_next_identity(ac, e, n, &comment)) {
                    169:                unsigned int bits = BN_num_bits(n);
                    170:                had_identities = 1;
                    171:                if (fp) {
                    172:                        printf("%d %s %s\n", bits, fingerprint(e, n), comment);
                    173:                } else {
                    174:                        char *ebuf, *nbuf;
                    175:                        ebuf = BN_bn2dec(e);
                    176:                        if (ebuf == NULL) {
                    177:                                error("list_identities: BN_bn2dec(e) failed.");
                    178:                        } else {
                    179:                                nbuf = BN_bn2dec(n);
                    180:                                if (nbuf == NULL) {
                    181:                                        error("list_identities: BN_bn2dec(n) failed.");
                    182:                                } else {
                    183:                                        printf("%d %s %s %s\n", bits, ebuf, nbuf, comment);
                    184:                                        free(nbuf);
                    185:                                }
                    186:                                free(ebuf);
                    187:                        }
                    188:                }
                    189:                xfree(comment);
                    190:        }
                    191:        BN_clear_free(e);
                    192:        BN_clear_free(n);
                    193:        if (!had_identities)
                    194:                printf("The agent has no identities.\n");
1.1       deraadt   195: }
                    196:
1.2       provos    197: int
1.7       markus    198: main(int argc, char **argv)
1.1       deraadt   199: {
1.12      markus    200:        AuthenticationConnection *ac = NULL;
                    201:        struct passwd *pw;
                    202:        char buf[1024];
                    203:        int no_files = 1;
                    204:        int i;
                    205:        int deleting = 0;
                    206:
                    207:        /* check if RSA support exists */
                    208:        if (rsa_alive() == 0) {
                    209:                extern char *__progname;
                    210:
                    211:                fprintf(stderr,
                    212:                        "%s: no RSA support in libssl and libcrypto.  See ssl(8).\n",
                    213:                        __progname);
                    214:                exit(1);
                    215:        }
                    216:        /* At first, get a connection to the authentication agent. */
                    217:        ac = ssh_get_authentication_connection();
                    218:        if (ac == NULL) {
                    219:                fprintf(stderr, "Could not open a connection to your authentication agent.\n");
                    220:                exit(1);
                    221:        }
                    222:        for (i = 1; i < argc; i++) {
                    223:                if ((strcmp(argv[i], "-l") == 0) ||
                    224:                    (strcmp(argv[i], "-L") == 0)) {
                    225:                        list_identities(ac, argv[i][1] == 'l' ? 1 : 0);
                    226:                        /* Don't default-add/delete if -l. */
                    227:                        no_files = 0;
                    228:                        continue;
                    229:                }
                    230:                if (strcmp(argv[i], "-d") == 0) {
                    231:                        deleting = 1;
                    232:                        continue;
                    233:                }
                    234:                if (strcmp(argv[i], "-D") == 0) {
                    235:                        delete_all(ac);
                    236:                        no_files = 0;
                    237:                        continue;
                    238:                }
                    239:                no_files = 0;
                    240:                if (deleting)
                    241:                        delete_file(ac, argv[i]);
                    242:                else
                    243:                        add_file(ac, argv[i]);
                    244:        }
                    245:        if (no_files) {
                    246:                pw = getpwuid(getuid());
                    247:                if (!pw) {
                    248:                        fprintf(stderr, "No user found with uid %d\n", (int) getuid());
                    249:                        ssh_close_authentication_connection(ac);
                    250:                        exit(1);
                    251:                }
                    252:                snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, SSH_CLIENT_IDENTITY);
                    253:                if (deleting)
                    254:                        delete_file(ac, buf);
                    255:                else
                    256:                        add_file(ac, buf);
                    257:        }
                    258:        ssh_close_authentication_connection(ac);
                    259:        exit(0);
1.1       deraadt   260: }