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

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