Annotation of src/usr.bin/ssh/ssh-agent.c, Revision 1.204
1.204 ! markus 1: /* $OpenBSD: ssh-agent.c,v 1.203 2015/05/15 05:44:21 dtucker Exp $ */
1.1 deraadt 2: /*
1.22 deraadt 3: * Author: Tatu Ylonen <ylo@cs.hut.fi>
4: * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5: * All rights reserved
6: * The authentication agent program.
1.33 markus 7: *
1.35 deraadt 8: * As far as I am concerned, the code I have written for this software
9: * can be used freely for any purpose. Any derived versions of this
10: * software must be clearly marked as such, and if the derived work is
11: * incompatible with the protocol description in the RFC file, it must be
12: * called by a name other than "ssh" or "Secure Shell".
13: *
1.56 markus 14: * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
1.35 deraadt 15: *
16: * Redistribution and use in source and binary forms, with or without
17: * modification, are permitted provided that the following conditions
18: * are met:
19: * 1. Redistributions of source code must retain the above copyright
20: * notice, this list of conditions and the following disclaimer.
21: * 2. Redistributions in binary form must reproduce the above copyright
22: * notice, this list of conditions and the following disclaimer in the
23: * documentation and/or other materials provided with the distribution.
24: *
25: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
26: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
29: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1.22 deraadt 35: */
1.1 deraadt 36:
1.196 deraadt 37: #include <sys/param.h> /* MIN MAX */
1.151 deraadt 38: #include <sys/types.h>
1.153 djm 39: #include <sys/time.h>
1.78 provos 40: #include <sys/queue.h>
1.127 stevesk 41: #include <sys/resource.h>
1.141 stevesk 42: #include <sys/socket.h>
1.189 djm 43: #include <sys/stat.h>
1.128 stevesk 44: #include <sys/un.h>
1.126 stevesk 45:
1.185 markus 46: #ifdef WITH_OPENSSL
1.146 stevesk 47: #include <openssl/evp.h>
1.185 markus 48: #endif
1.146 stevesk 49:
1.143 stevesk 50: #include <errno.h>
1.142 stevesk 51: #include <fcntl.h>
1.126 stevesk 52: #include <paths.h>
1.129 stevesk 53: #include <signal.h>
1.149 stevesk 54: #include <stdlib.h>
1.150 stevesk 55: #include <stdio.h>
1.146 stevesk 56: #include <string.h>
1.196 deraadt 57: #include <limits.h>
1.145 stevesk 58: #include <time.h>
1.144 stevesk 59: #include <unistd.h>
1.203 dtucker 60: #include <util.h>
1.194 markus 61:
1.151 deraadt 62: #include "xmalloc.h"
1.1 deraadt 63: #include "ssh.h"
64: #include "rsa.h"
1.194 markus 65: #include "sshbuf.h"
66: #include "sshkey.h"
1.32 markus 67: #include "authfd.h"
1.37 markus 68: #include "compat.h"
1.47 markus 69: #include "log.h"
1.107 markus 70: #include "misc.h"
1.182 markus 71: #include "digest.h"
1.194 markus 72: #include "ssherr.h"
1.7 deraadt 73:
1.163 markus 74: #ifdef ENABLE_PKCS11
75: #include "ssh-pkcs11.h"
1.71 jakob 76: #endif
1.59 markus 77:
1.73 stevesk 78: typedef enum {
79: AUTH_UNUSED,
80: AUTH_SOCKET,
81: AUTH_CONNECTION
82: } sock_type;
83:
1.21 markus 84: typedef struct {
85: int fd;
1.73 stevesk 86: sock_type type;
1.194 markus 87: struct sshbuf *input;
88: struct sshbuf *output;
89: struct sshbuf *request;
1.1 deraadt 90: } SocketEntry;
91:
1.45 markus 92: u_int sockets_alloc = 0;
1.1 deraadt 93: SocketEntry *sockets = NULL;
94:
1.78 provos 95: typedef struct identity {
96: TAILQ_ENTRY(identity) next;
1.194 markus 97: struct sshkey *key;
1.21 markus 98: char *comment;
1.163 markus 99: char *provider;
1.174 dtucker 100: time_t death;
1.107 markus 101: u_int confirm;
1.1 deraadt 102: } Identity;
103:
1.33 markus 104: typedef struct {
105: int nentries;
1.78 provos 106: TAILQ_HEAD(idqueue, identity) idlist;
1.33 markus 107: } Idtab;
108:
109: /* private key table, one per protocol version */
110: Idtab idtable[3];
1.1 deraadt 111:
112: int max_fd = 0;
113:
1.11 markus 114: /* pid of shell == parent of agent */
1.29 deraadt 115: pid_t parent_pid = -1;
1.176 dtucker 116: time_t parent_alive_interval = 0;
1.10 markus 117:
1.187 djm 118: /* pid of process for which cleanup_socket is applicable */
119: pid_t cleanup_pid = 0;
120:
1.10 markus 121: /* pathname and directory for AUTH_SOCKET */
1.196 deraadt 122: char socket_name[PATH_MAX];
123: char socket_dir[PATH_MAX];
1.10 markus 124:
1.88 markus 125: /* locking */
1.203 dtucker 126: #define LOCK_SIZE 32
127: #define LOCK_SALT_SIZE 16
128: #define LOCK_ROUNDS 1
1.88 markus 129: int locked = 0;
1.203 dtucker 130: char lock_passwd[LOCK_SIZE];
131: char lock_salt[LOCK_SALT_SIZE];
1.88 markus 132:
1.20 markus 133: extern char *__progname;
134:
1.174 dtucker 135: /* Default lifetime in seconds (0 == forever) */
136: static long lifetime = 0;
1.106 marc 137:
1.192 djm 138: static int fingerprint_hash = SSH_FP_HASH_DEFAULT;
139:
1.55 itojun 140: static void
1.101 stevesk 141: close_socket(SocketEntry *e)
142: {
143: close(e->fd);
144: e->fd = -1;
145: e->type = AUTH_UNUSED;
1.194 markus 146: sshbuf_free(e->input);
147: sshbuf_free(e->output);
148: sshbuf_free(e->request);
1.101 stevesk 149: }
150:
151: static void
1.33 markus 152: idtab_init(void)
1.1 deraadt 153: {
1.33 markus 154: int i;
1.96 deraadt 155:
1.74 deraadt 156: for (i = 0; i <=2; i++) {
1.78 provos 157: TAILQ_INIT(&idtable[i].idlist);
1.33 markus 158: idtable[i].nentries = 0;
159: }
160: }
161:
162: /* return private key table for requested protocol version */
1.55 itojun 163: static Idtab *
1.33 markus 164: idtab_lookup(int version)
165: {
166: if (version < 1 || version > 2)
167: fatal("internal error, bad protocol version %d", version);
168: return &idtable[version];
169: }
170:
1.89 markus 171: static void
172: free_identity(Identity *id)
173: {
1.194 markus 174: sshkey_free(id->key);
1.173 djm 175: free(id->provider);
176: free(id->comment);
177: free(id);
1.89 markus 178: }
179:
1.33 markus 180: /* return matching private key for given public key */
1.78 provos 181: static Identity *
1.194 markus 182: lookup_identity(struct sshkey *key, int version)
1.33 markus 183: {
1.78 provos 184: Identity *id;
185:
1.33 markus 186: Idtab *tab = idtab_lookup(version);
1.78 provos 187: TAILQ_FOREACH(id, &tab->idlist, next) {
1.194 markus 188: if (sshkey_equal(key, id->key))
1.78 provos 189: return (id);
1.33 markus 190: }
1.78 provos 191: return (NULL);
192: }
193:
1.107 markus 194: /* Check confirmation of keysign request */
195: static int
196: confirm_key(Identity *id)
197: {
1.122 djm 198: char *p;
1.107 markus 199: int ret = -1;
200:
1.194 markus 201: p = sshkey_fingerprint(id->key, fingerprint_hash, SSH_FP_DEFAULT);
1.197 djm 202: if (p != NULL &&
203: ask_permission("Allow use of key %s?\nKey fingerprint %s.",
1.122 djm 204: id->comment, p))
205: ret = 0;
1.173 djm 206: free(p);
1.122 djm 207:
1.107 markus 208: return (ret);
209: }
210:
1.194 markus 211: static void
212: send_status(SocketEntry *e, int success)
213: {
214: int r;
215:
216: if ((r = sshbuf_put_u32(e->output, 1)) != 0 ||
217: (r = sshbuf_put_u8(e->output, success ?
218: SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE)) != 0)
219: fatal("%s: buffer error: %s", __func__, ssh_err(r));
220: }
221:
1.33 markus 222: /* send list of supported public keys to 'client' */
1.55 itojun 223: static void
1.33 markus 224: process_request_identities(SocketEntry *e, int version)
225: {
226: Idtab *tab = idtab_lookup(version);
1.96 deraadt 227: Identity *id;
1.194 markus 228: struct sshbuf *msg;
229: int r;
1.1 deraadt 230:
1.194 markus 231: if ((msg = sshbuf_new()) == NULL)
232: fatal("%s: sshbuf_new failed", __func__);
233: if ((r = sshbuf_put_u8(msg, (version == 1) ?
234: SSH_AGENT_RSA_IDENTITIES_ANSWER :
235: SSH2_AGENT_IDENTITIES_ANSWER)) != 0 ||
236: (r = sshbuf_put_u32(msg, tab->nentries)) != 0)
237: fatal("%s: buffer error: %s", __func__, ssh_err(r));
1.78 provos 238: TAILQ_FOREACH(id, &tab->idlist, next) {
1.39 markus 239: if (id->key->type == KEY_RSA1) {
1.185 markus 240: #ifdef WITH_SSH1
1.194 markus 241: if ((r = sshbuf_put_u32(msg,
242: BN_num_bits(id->key->rsa->n))) != 0 ||
243: (r = sshbuf_put_bignum1(msg,
244: id->key->rsa->e)) != 0 ||
245: (r = sshbuf_put_bignum1(msg,
246: id->key->rsa->n)) != 0)
247: fatal("%s: buffer error: %s",
248: __func__, ssh_err(r));
1.185 markus 249: #endif
1.33 markus 250: } else {
1.45 markus 251: u_char *blob;
1.194 markus 252: size_t blen;
253:
254: if ((r = sshkey_to_blob(id->key, &blob, &blen)) != 0) {
255: error("%s: sshkey_to_blob: %s", __func__,
256: ssh_err(r));
257: continue;
258: }
259: if ((r = sshbuf_put_string(msg, blob, blen)) != 0)
260: fatal("%s: buffer error: %s",
261: __func__, ssh_err(r));
1.173 djm 262: free(blob);
1.33 markus 263: }
1.194 markus 264: if ((r = sshbuf_put_cstring(msg, id->comment)) != 0)
265: fatal("%s: buffer error: %s", __func__, ssh_err(r));
1.21 markus 266: }
1.194 markus 267: if ((r = sshbuf_put_stringb(e->output, msg)) != 0)
268: fatal("%s: buffer error: %s", __func__, ssh_err(r));
269: sshbuf_free(msg);
1.1 deraadt 270: }
271:
1.185 markus 272: #ifdef WITH_SSH1
1.33 markus 273: /* ssh1 only */
1.55 itojun 274: static void
1.33 markus 275: process_authentication_challenge1(SocketEntry *e)
1.1 deraadt 276: {
1.96 deraadt 277: u_char buf[32], mdbuf[16], session_id[16];
278: u_int response_type;
279: BIGNUM *challenge;
1.78 provos 280: Identity *id;
1.194 markus 281: int r, len;
282: struct sshbuf *msg;
1.182 markus 283: struct ssh_digest_ctx *md;
1.194 markus 284: struct sshkey *key;
1.21 markus 285:
1.194 markus 286: if ((msg = sshbuf_new()) == NULL)
287: fatal("%s: sshbuf_new failed", __func__);
288: if ((key = sshkey_new(KEY_RSA1)) == NULL)
289: fatal("%s: sshkey_new failed", __func__);
1.76 markus 290: if ((challenge = BN_new()) == NULL)
1.194 markus 291: fatal("%s: BN_new failed", __func__);
1.33 markus 292:
1.194 markus 293: if ((r = sshbuf_get_u32(e->request, NULL)) != 0 || /* ignored */
294: (r = sshbuf_get_bignum1(e->request, key->rsa->e)) != 0 ||
295: (r = sshbuf_get_bignum1(e->request, key->rsa->n)) != 0 ||
296: (r = sshbuf_get_bignum1(e->request, challenge)))
297: fatal("%s: buffer error: %s", __func__, ssh_err(r));
1.21 markus 298:
1.33 markus 299: /* Only protocol 1.1 is supported */
1.194 markus 300: if (sshbuf_len(e->request) == 0)
1.33 markus 301: goto failure;
1.194 markus 302: if ((r = sshbuf_get(e->request, session_id, sizeof(session_id))) != 0 ||
303: (r = sshbuf_get_u32(e->request, &response_type)) != 0)
304: fatal("%s: buffer error: %s", __func__, ssh_err(r));
1.33 markus 305: if (response_type != 1)
306: goto failure;
307:
1.78 provos 308: id = lookup_identity(key, 1);
1.107 markus 309: if (id != NULL && (!id->confirm || confirm_key(id) == 0)) {
1.194 markus 310: struct sshkey *private = id->key;
1.33 markus 311: /* Decrypt the challenge using the private key. */
1.194 markus 312: if ((r = rsa_private_decrypt(challenge, challenge,
313: private->rsa) != 0)) {
314: fatal("%s: rsa_public_encrypt: %s", __func__,
315: ssh_err(r));
316: goto failure; /* XXX ? */
317: }
1.33 markus 318:
1.194 markus 319: /* The response is MD5 of decrypted challenge plus session id */
1.33 markus 320: len = BN_num_bytes(challenge);
321: if (len <= 0 || len > 32) {
1.194 markus 322: logit("%s: bad challenge length %d", __func__, len);
1.33 markus 323: goto failure;
324: }
325: memset(buf, 0, 32);
326: BN_bn2bin(challenge, buf + 32 - len);
1.182 markus 327: if ((md = ssh_digest_start(SSH_DIGEST_MD5)) == NULL ||
328: ssh_digest_update(md, buf, 32) < 0 ||
329: ssh_digest_update(md, session_id, 16) < 0 ||
330: ssh_digest_final(md, mdbuf, sizeof(mdbuf)) < 0)
331: fatal("%s: md5 failed", __func__);
332: ssh_digest_free(md);
1.33 markus 333:
334: /* Send the response. */
1.194 markus 335: if ((r = sshbuf_put_u8(msg, SSH_AGENT_RSA_RESPONSE)) != 0 ||
336: (r = sshbuf_put(msg, mdbuf, sizeof(mdbuf))) != 0)
337: fatal("%s: buffer error: %s", __func__, ssh_err(r));
1.33 markus 338: goto send;
339: }
1.21 markus 340:
1.194 markus 341: failure:
1.33 markus 342: /* Unknown identity or protocol error. Send failure. */
1.194 markus 343: if ((r = sshbuf_put_u8(msg, SSH_AGENT_FAILURE)) != 0)
344: fatal("%s: buffer error: %s", __func__, ssh_err(r));
345: send:
346: if ((r = sshbuf_put_stringb(e->output, msg)) != 0)
347: fatal("%s: buffer error: %s", __func__, ssh_err(r));
348: sshkey_free(key);
1.33 markus 349: BN_clear_free(challenge);
1.194 markus 350: sshbuf_free(msg);
1.33 markus 351: }
1.185 markus 352: #endif
1.33 markus 353:
354: /* ssh2 only */
1.55 itojun 355: static void
1.33 markus 356: process_sign_request2(SocketEntry *e)
357: {
1.45 markus 358: u_char *blob, *data, *signature = NULL;
1.194 markus 359: size_t blen, dlen, slen = 0;
360: u_int compat = 0, flags;
361: int r, ok = -1;
362: struct sshbuf *msg;
363: struct sshkey *key;
1.195 djm 364: struct identity *id;
1.194 markus 365:
1.195 djm 366: if ((msg = sshbuf_new()) == NULL)
367: fatal("%s: sshbuf_new failed", __func__);
1.194 markus 368: if ((r = sshbuf_get_string(e->request, &blob, &blen)) != 0 ||
369: (r = sshbuf_get_string(e->request, &data, &dlen)) != 0 ||
370: (r = sshbuf_get_u32(e->request, &flags)) != 0)
371: fatal("%s: buffer error: %s", __func__, ssh_err(r));
1.37 markus 372: if (flags & SSH_AGENT_OLD_SIGNATURE)
1.194 markus 373: compat = SSH_BUG_SIGBLOB;
1.195 djm 374: if ((r = sshkey_from_blob(blob, blen, &key)) != 0) {
1.194 markus 375: error("%s: cannot parse key blob: %s", __func__, ssh_err(ok));
1.195 djm 376: goto send;
377: }
378: if ((id = lookup_identity(key, 2)) == NULL) {
379: verbose("%s: %s key not found", __func__, sshkey_type(key));
380: goto send;
381: }
382: if (id->confirm && confirm_key(id) != 0) {
383: verbose("%s: user refused key", __func__);
384: goto send;
385: }
386: if ((r = sshkey_sign(id->key, &signature, &slen,
387: data, dlen, compat)) != 0) {
388: error("%s: sshkey_sign: %s", __func__, ssh_err(ok));
389: goto send;
1.33 markus 390: }
1.195 djm 391: /* Success */
392: ok = 0;
393: send:
394: sshkey_free(key);
1.33 markus 395: if (ok == 0) {
1.194 markus 396: if ((r = sshbuf_put_u8(msg, SSH2_AGENT_SIGN_RESPONSE)) != 0 ||
397: (r = sshbuf_put_string(msg, signature, slen)) != 0)
398: fatal("%s: buffer error: %s", __func__, ssh_err(r));
399: } else if ((r = sshbuf_put_u8(msg, SSH_AGENT_FAILURE)) != 0)
400: fatal("%s: buffer error: %s", __func__, ssh_err(r));
401:
402: if ((r = sshbuf_put_stringb(e->output, msg)) != 0)
403: fatal("%s: buffer error: %s", __func__, ssh_err(r));
404:
405: sshbuf_free(msg);
1.173 djm 406: free(data);
407: free(blob);
408: free(signature);
1.1 deraadt 409: }
410:
1.33 markus 411: /* shared */
1.55 itojun 412: static void
1.33 markus 413: process_remove_identity(SocketEntry *e, int version)
1.1 deraadt 414: {
1.194 markus 415: size_t blen;
416: int r, success = 0;
417: struct sshkey *key = NULL;
1.45 markus 418: u_char *blob;
1.186 djm 419: #ifdef WITH_SSH1
420: u_int bits;
421: #endif /* WITH_SSH1 */
1.21 markus 422:
1.74 deraadt 423: switch (version) {
1.186 djm 424: #ifdef WITH_SSH1
1.33 markus 425: case 1:
1.194 markus 426: if ((key = sshkey_new(KEY_RSA1)) == NULL) {
427: error("%s: sshkey_new failed", __func__);
428: return;
429: }
430: if ((r = sshbuf_get_u32(e->request, &bits)) != 0 ||
431: (r = sshbuf_get_bignum1(e->request, key->rsa->e)) != 0 ||
432: (r = sshbuf_get_bignum1(e->request, key->rsa->n)) != 0)
433: fatal("%s: buffer error: %s", __func__, ssh_err(r));
434:
435: if (bits != sshkey_size(key))
436: logit("Warning: identity keysize mismatch: "
437: "actual %u, announced %u",
438: sshkey_size(key), bits);
1.33 markus 439: break;
1.186 djm 440: #endif /* WITH_SSH1 */
1.33 markus 441: case 2:
1.194 markus 442: if ((r = sshbuf_get_string(e->request, &blob, &blen)) != 0)
443: fatal("%s: buffer error: %s", __func__, ssh_err(r));
444: if ((r = sshkey_from_blob(blob, blen, &key)) != 0)
445: error("%s: sshkey_from_blob failed: %s",
446: __func__, ssh_err(r));
1.173 djm 447: free(blob);
1.33 markus 448: break;
449: }
450: if (key != NULL) {
1.78 provos 451: Identity *id = lookup_identity(key, version);
452: if (id != NULL) {
1.23 markus 453: /*
454: * We have this key. Free the old key. Since we
1.124 djm 455: * don't want to leave empty slots in the middle of
1.40 markus 456: * the array, we actually free the key there and move
457: * all the entries between the empty slot and the end
458: * of the array.
1.23 markus 459: */
1.33 markus 460: Idtab *tab = idtab_lookup(version);
1.38 markus 461: if (tab->nentries < 1)
462: fatal("process_remove_identity: "
463: "internal error: tab->nentries %d",
464: tab->nentries);
1.78 provos 465: TAILQ_REMOVE(&tab->idlist, id, next);
466: free_identity(id);
1.33 markus 467: tab->nentries--;
468: success = 1;
1.21 markus 469: }
1.194 markus 470: sshkey_free(key);
1.33 markus 471: }
1.194 markus 472: send_status(e, success);
1.1 deraadt 473: }
474:
1.55 itojun 475: static void
1.33 markus 476: process_remove_all_identities(SocketEntry *e, int version)
1.1 deraadt 477: {
1.33 markus 478: Idtab *tab = idtab_lookup(version);
1.78 provos 479: Identity *id;
1.21 markus 480:
481: /* Loop over all identities and clear the keys. */
1.78 provos 482: for (id = TAILQ_FIRST(&tab->idlist); id;
483: id = TAILQ_FIRST(&tab->idlist)) {
484: TAILQ_REMOVE(&tab->idlist, id, next);
485: free_identity(id);
1.21 markus 486: }
487:
488: /* Mark that there are no identities. */
1.33 markus 489: tab->nentries = 0;
1.21 markus 490:
491: /* Send success. */
1.194 markus 492: send_status(e, 1);
1.1 deraadt 493: }
494:
1.155 dtucker 495: /* removes expired keys and returns number of seconds until the next expiry */
1.174 dtucker 496: static time_t
1.89 markus 497: reaper(void)
498: {
1.175 dtucker 499: time_t deadline = 0, now = monotime();
1.89 markus 500: Identity *id, *nxt;
501: int version;
1.96 deraadt 502: Idtab *tab;
1.89 markus 503:
504: for (version = 1; version < 3; version++) {
505: tab = idtab_lookup(version);
506: for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) {
507: nxt = TAILQ_NEXT(id, next);
1.155 dtucker 508: if (id->death == 0)
509: continue;
510: if (now >= id->death) {
1.154 dtucker 511: debug("expiring key '%s'", id->comment);
1.89 markus 512: TAILQ_REMOVE(&tab->idlist, id, next);
513: free_identity(id);
514: tab->nentries--;
1.155 dtucker 515: } else
516: deadline = (deadline == 0) ? id->death :
517: MIN(deadline, id->death);
1.89 markus 518: }
519: }
1.155 dtucker 520: if (deadline == 0 || deadline <= now)
521: return 0;
522: else
523: return (deadline - now);
1.89 markus 524: }
525:
1.194 markus 526: /*
527: * XXX this and the corresponding serialisation function probably belongs
528: * in key.c
529: */
1.198 djm 530: #ifdef WITH_SSH1
1.194 markus 531: static int
532: agent_decode_rsa1(struct sshbuf *m, struct sshkey **kp)
533: {
534: struct sshkey *k = NULL;
535: int r = SSH_ERR_INTERNAL_ERROR;
536:
537: *kp = NULL;
538: if ((k = sshkey_new_private(KEY_RSA1)) == NULL)
539: return SSH_ERR_ALLOC_FAIL;
540:
541: if ((r = sshbuf_get_u32(m, NULL)) != 0 || /* ignored */
542: (r = sshbuf_get_bignum1(m, k->rsa->n)) != 0 ||
543: (r = sshbuf_get_bignum1(m, k->rsa->e)) != 0 ||
544: (r = sshbuf_get_bignum1(m, k->rsa->d)) != 0 ||
545: (r = sshbuf_get_bignum1(m, k->rsa->iqmp)) != 0 ||
546: /* SSH1 and SSL have p and q swapped */
547: (r = sshbuf_get_bignum1(m, k->rsa->q)) != 0 || /* p */
548: (r = sshbuf_get_bignum1(m, k->rsa->p)) != 0) /* q */
549: goto out;
550:
551: /* Generate additional parameters */
552: if ((r = rsa_generate_additional_parameters(k->rsa)) != 0)
553: goto out;
554: /* enable blinding */
555: if (RSA_blinding_on(k->rsa, NULL) != 1) {
556: r = SSH_ERR_LIBCRYPTO_ERROR;
557: goto out;
558: }
559:
560: r = 0; /* success */
561: out:
562: if (r == 0)
563: *kp = k;
564: else
565: sshkey_free(k);
566: return r;
567: }
1.198 djm 568: #endif /* WITH_SSH1 */
1.194 markus 569:
1.89 markus 570: static void
1.33 markus 571: process_add_identity(SocketEntry *e, int version)
1.1 deraadt 572: {
1.96 deraadt 573: Idtab *tab = idtab_lookup(version);
1.157 canacar 574: Identity *id;
1.194 markus 575: int success = 0, confirm = 0;
576: u_int seconds;
577: char *comment = NULL;
1.174 dtucker 578: time_t death = 0;
1.194 markus 579: struct sshkey *k = NULL;
580: u_char ctype;
581: int r = SSH_ERR_INTERNAL_ERROR;
1.33 markus 582:
583: switch (version) {
1.186 djm 584: #ifdef WITH_SSH1
1.33 markus 585: case 1:
1.194 markus 586: r = agent_decode_rsa1(e->request, &k);
1.33 markus 587: break;
1.186 djm 588: #endif /* WITH_SSH1 */
1.33 markus 589: case 2:
1.194 markus 590: r = sshkey_private_deserialize(e->request, &k);
1.33 markus 591: break;
592: }
1.194 markus 593: if (r != 0 || k == NULL ||
594: (r = sshbuf_get_cstring(e->request, &comment, NULL)) != 0) {
595: error("%s: decode private key: %s", __func__, ssh_err(r));
596: goto err;
597: }
1.186 djm 598:
1.194 markus 599: while (sshbuf_len(e->request)) {
600: if ((r = sshbuf_get_u8(e->request, &ctype)) != 0) {
601: error("%s: buffer error: %s", __func__, ssh_err(r));
602: goto err;
603: }
604: switch (ctype) {
1.94 markus 605: case SSH_AGENT_CONSTRAIN_LIFETIME:
1.194 markus 606: if ((r = sshbuf_get_u32(e->request, &seconds)) != 0) {
607: error("%s: bad lifetime constraint: %s",
608: __func__, ssh_err(r));
609: goto err;
610: }
611: death = monotime() + seconds;
1.94 markus 612: break;
1.107 markus 613: case SSH_AGENT_CONSTRAIN_CONFIRM:
614: confirm = 1;
615: break;
1.94 markus 616: default:
1.194 markus 617: error("%s: Unknown constraint %d", __func__, ctype);
618: err:
619: sshbuf_reset(e->request);
1.173 djm 620: free(comment);
1.194 markus 621: sshkey_free(k);
1.158 djm 622: goto send;
1.94 markus 623: }
624: }
1.194 markus 625:
1.158 djm 626: success = 1;
1.106 marc 627: if (lifetime && !death)
1.175 dtucker 628: death = monotime() + lifetime;
1.157 canacar 629: if ((id = lookup_identity(k, version)) == NULL) {
1.163 markus 630: id = xcalloc(1, sizeof(Identity));
1.78 provos 631: id->key = k;
632: TAILQ_INSERT_TAIL(&tab->idlist, id, next);
1.33 markus 633: /* Increment the number of identities. */
634: tab->nentries++;
635: } else {
1.194 markus 636: sshkey_free(k);
1.173 djm 637: free(id->comment);
1.33 markus 638: }
1.157 canacar 639: id->comment = comment;
640: id->death = death;
641: id->confirm = confirm;
1.33 markus 642: send:
1.194 markus 643: send_status(e, success);
1.1 deraadt 644: }
645:
1.88 markus 646: /* XXX todo: encrypt sensitive data with passphrase */
647: static void
648: process_lock_agent(SocketEntry *e, int lock)
649: {
1.203 dtucker 650: int r, success = 0, delay;
651: char *passwd, passwdhash[LOCK_SIZE];
652: static u_int fail_count = 0;
653: size_t pwlen;
654:
655: if ((r = sshbuf_get_cstring(e->request, &passwd, &pwlen)) != 0)
656: fatal("%s: buffer error: %s", __func__, ssh_err(r));
657: if (pwlen == 0) {
658: debug("empty password not supported");
659: } else if (locked && !lock) {
660: if (bcrypt_pbkdf(passwd, pwlen, lock_salt, sizeof(lock_salt),
661: passwdhash, sizeof(passwdhash), LOCK_ROUNDS) < 0)
662: fatal("bcrypt_pbkdf");
663: if (timingsafe_bcmp(passwdhash, lock_passwd, LOCK_SIZE) == 0) {
664: debug("agent unlocked");
665: locked = 0;
666: fail_count = 0;
667: explicit_bzero(lock_passwd, sizeof(lock_passwd));
668: success = 1;
669: } else {
670: /* delay in 0.1s increments up to 10s */
671: if (fail_count < 100)
672: fail_count++;
673: delay = 100000 * fail_count;
674: debug("unlock failed, delaying %0.1lf seconds",
675: (double)delay/1000000);
676: usleep(delay);
677: }
678: explicit_bzero(passwdhash, sizeof(passwdhash));
1.88 markus 679: } else if (!locked && lock) {
1.203 dtucker 680: debug("agent locked");
1.88 markus 681: locked = 1;
1.203 dtucker 682: arc4random_buf(lock_salt, sizeof(lock_salt));
683: if (bcrypt_pbkdf(passwd, pwlen, lock_salt, sizeof(lock_salt),
684: lock_passwd, sizeof(lock_passwd), LOCK_ROUNDS) < 0)
685: fatal("bcrypt_pbkdf");
1.88 markus 686: success = 1;
687: }
1.203 dtucker 688: explicit_bzero(passwd, pwlen);
1.173 djm 689: free(passwd);
1.194 markus 690: send_status(e, success);
1.88 markus 691: }
692:
693: static void
694: no_identities(SocketEntry *e, u_int type)
695: {
1.194 markus 696: struct sshbuf *msg;
697: int r;
1.88 markus 698:
1.194 markus 699: if ((msg = sshbuf_new()) == NULL)
700: fatal("%s: sshbuf_new failed", __func__);
701: if ((r = sshbuf_put_u8(msg,
1.88 markus 702: (type == SSH_AGENTC_REQUEST_RSA_IDENTITIES) ?
1.194 markus 703: SSH_AGENT_RSA_IDENTITIES_ANSWER :
704: SSH2_AGENT_IDENTITIES_ANSWER)) != 0 ||
705: (r = sshbuf_put_u32(msg, 0)) != 0 ||
706: (r = sshbuf_put_stringb(e->output, msg)) != 0)
707: fatal("%s: buffer error: %s", __func__, ssh_err(r));
708: sshbuf_free(msg);
1.88 markus 709: }
1.59 markus 710:
1.163 markus 711: #ifdef ENABLE_PKCS11
1.59 markus 712: static void
1.158 djm 713: process_add_smartcard_key(SocketEntry *e)
1.59 markus 714: {
1.163 markus 715: char *provider = NULL, *pin;
1.194 markus 716: int r, i, version, count = 0, success = 0, confirm = 0;
717: u_int seconds;
1.174 dtucker 718: time_t death = 0;
1.194 markus 719: u_char type;
720: struct sshkey **keys = NULL, *k;
1.84 markus 721: Identity *id;
1.59 markus 722: Idtab *tab;
1.75 deraadt 723:
1.194 markus 724: if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 ||
725: (r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0)
726: fatal("%s: buffer error: %s", __func__, ssh_err(r));
727:
728: while (sshbuf_len(e->request)) {
729: if ((r = sshbuf_get_u8(e->request, &type)) != 0)
730: fatal("%s: buffer error: %s", __func__, ssh_err(r));
731: switch (type) {
1.110 djm 732: case SSH_AGENT_CONSTRAIN_LIFETIME:
1.194 markus 733: if ((r = sshbuf_get_u32(e->request, &seconds)) != 0)
734: fatal("%s: buffer error: %s",
735: __func__, ssh_err(r));
736: death = monotime() + seconds;
1.110 djm 737: break;
738: case SSH_AGENT_CONSTRAIN_CONFIRM:
739: confirm = 1;
740: break;
741: default:
1.158 djm 742: error("process_add_smartcard_key: "
743: "Unknown constraint type %d", type);
744: goto send;
1.110 djm 745: }
746: }
747: if (lifetime && !death)
1.175 dtucker 748: death = monotime() + lifetime;
1.110 djm 749:
1.163 markus 750: count = pkcs11_add_provider(provider, pin, &keys);
751: for (i = 0; i < count; i++) {
1.84 markus 752: k = keys[i];
753: version = k->type == KEY_RSA1 ? 1 : 2;
754: tab = idtab_lookup(version);
755: if (lookup_identity(k, version) == NULL) {
1.163 markus 756: id = xcalloc(1, sizeof(Identity));
1.84 markus 757: id->key = k;
1.163 markus 758: id->provider = xstrdup(provider);
759: id->comment = xstrdup(provider); /* XXX */
1.110 djm 760: id->death = death;
761: id->confirm = confirm;
1.84 markus 762: TAILQ_INSERT_TAIL(&tab->idlist, id, next);
763: tab->nentries++;
764: success = 1;
765: } else {
1.194 markus 766: sshkey_free(k);
1.84 markus 767: }
768: keys[i] = NULL;
1.59 markus 769: }
770: send:
1.173 djm 771: free(pin);
772: free(provider);
773: free(keys);
1.194 markus 774: send_status(e, success);
1.59 markus 775: }
776:
777: static void
778: process_remove_smartcard_key(SocketEntry *e)
779: {
1.163 markus 780: char *provider = NULL, *pin = NULL;
1.194 markus 781: int r, version, success = 0;
1.163 markus 782: Identity *id, *nxt;
1.84 markus 783: Idtab *tab;
1.59 markus 784:
1.194 markus 785: if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 ||
786: (r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0)
787: fatal("%s: buffer error: %s", __func__, ssh_err(r));
1.173 djm 788: free(pin);
1.59 markus 789:
1.163 markus 790: for (version = 1; version < 3; version++) {
791: tab = idtab_lookup(version);
792: for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) {
793: nxt = TAILQ_NEXT(id, next);
1.181 djm 794: /* Skip file--based keys */
795: if (id->provider == NULL)
796: continue;
1.163 markus 797: if (!strcmp(provider, id->provider)) {
798: TAILQ_REMOVE(&tab->idlist, id, next);
799: free_identity(id);
800: tab->nentries--;
801: }
1.59 markus 802: }
803: }
1.163 markus 804: if (pkcs11_del_provider(provider) == 0)
805: success = 1;
806: else
807: error("process_remove_smartcard_key:"
808: " pkcs11_del_provider failed");
1.173 djm 809: free(provider);
1.194 markus 810: send_status(e, success);
1.59 markus 811: }
1.163 markus 812: #endif /* ENABLE_PKCS11 */
1.59 markus 813:
1.33 markus 814: /* dispatch incoming messages */
815:
1.55 itojun 816: static void
1.2 provos 817: process_message(SocketEntry *e)
1.1 deraadt 818: {
1.194 markus 819: u_int msg_len;
820: u_char type;
821: const u_char *cp;
822: int r;
1.89 markus 823:
1.194 markus 824: if (sshbuf_len(e->input) < 5)
1.21 markus 825: return; /* Incomplete message. */
1.194 markus 826: cp = sshbuf_ptr(e->input);
827: msg_len = PEEK_U32(cp);
1.21 markus 828: if (msg_len > 256 * 1024) {
1.101 stevesk 829: close_socket(e);
1.21 markus 830: return;
831: }
1.194 markus 832: if (sshbuf_len(e->input) < msg_len + 4)
1.21 markus 833: return;
1.87 markus 834:
835: /* move the current input to e->request */
1.194 markus 836: sshbuf_reset(e->request);
837: if ((r = sshbuf_get_stringb(e->input, e->request)) != 0 ||
838: (r = sshbuf_get_u8(e->request, &type)) != 0)
839: fatal("%s: buffer error: %s", __func__, ssh_err(r));
1.21 markus 840:
1.88 markus 841: /* check wheter agent is locked */
842: if (locked && type != SSH_AGENTC_UNLOCK) {
1.194 markus 843: sshbuf_reset(e->request);
1.88 markus 844: switch (type) {
845: case SSH_AGENTC_REQUEST_RSA_IDENTITIES:
846: case SSH2_AGENTC_REQUEST_IDENTITIES:
847: /* send empty lists */
848: no_identities(e, type);
849: break;
850: default:
851: /* send a fail message for all other request types */
1.194 markus 852: send_status(e, 0);
1.88 markus 853: }
854: return;
855: }
856:
1.59 markus 857: debug("type %d", type);
1.21 markus 858: switch (type) {
1.88 markus 859: case SSH_AGENTC_LOCK:
860: case SSH_AGENTC_UNLOCK:
861: process_lock_agent(e, type == SSH_AGENTC_LOCK);
862: break;
1.185 markus 863: #ifdef WITH_SSH1
1.33 markus 864: /* ssh1 */
865: case SSH_AGENTC_RSA_CHALLENGE:
866: process_authentication_challenge1(e);
867: break;
1.21 markus 868: case SSH_AGENTC_REQUEST_RSA_IDENTITIES:
1.33 markus 869: process_request_identities(e, 1);
1.21 markus 870: break;
871: case SSH_AGENTC_ADD_RSA_IDENTITY:
1.94 markus 872: case SSH_AGENTC_ADD_RSA_ID_CONSTRAINED:
1.33 markus 873: process_add_identity(e, 1);
1.21 markus 874: break;
875: case SSH_AGENTC_REMOVE_RSA_IDENTITY:
1.33 markus 876: process_remove_identity(e, 1);
1.21 markus 877: break;
1.199 djm 878: #endif
1.21 markus 879: case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES:
1.199 djm 880: process_remove_all_identities(e, 1); /* safe for !WITH_SSH1 */
1.33 markus 881: break;
882: /* ssh2 */
883: case SSH2_AGENTC_SIGN_REQUEST:
884: process_sign_request2(e);
885: break;
886: case SSH2_AGENTC_REQUEST_IDENTITIES:
887: process_request_identities(e, 2);
888: break;
889: case SSH2_AGENTC_ADD_IDENTITY:
1.94 markus 890: case SSH2_AGENTC_ADD_ID_CONSTRAINED:
1.33 markus 891: process_add_identity(e, 2);
892: break;
893: case SSH2_AGENTC_REMOVE_IDENTITY:
894: process_remove_identity(e, 2);
895: break;
896: case SSH2_AGENTC_REMOVE_ALL_IDENTITIES:
897: process_remove_all_identities(e, 2);
1.21 markus 898: break;
1.163 markus 899: #ifdef ENABLE_PKCS11
1.59 markus 900: case SSH_AGENTC_ADD_SMARTCARD_KEY:
1.110 djm 901: case SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED:
1.59 markus 902: process_add_smartcard_key(e);
1.75 deraadt 903: break;
1.59 markus 904: case SSH_AGENTC_REMOVE_SMARTCARD_KEY:
905: process_remove_smartcard_key(e);
1.75 deraadt 906: break;
1.163 markus 907: #endif /* ENABLE_PKCS11 */
1.21 markus 908: default:
909: /* Unknown message. Respond with failure. */
910: error("Unknown message %d", type);
1.194 markus 911: sshbuf_reset(e->request);
912: send_status(e, 0);
1.21 markus 913: break;
914: }
1.1 deraadt 915: }
916:
1.55 itojun 917: static void
1.73 stevesk 918: new_socket(sock_type type, int fd)
1.1 deraadt 919: {
1.112 markus 920: u_int i, old_alloc, new_alloc;
1.96 deraadt 921:
1.119 djm 922: set_nonblock(fd);
1.21 markus 923:
924: if (fd > max_fd)
925: max_fd = fd;
926:
927: for (i = 0; i < sockets_alloc; i++)
928: if (sockets[i].type == AUTH_UNUSED) {
929: sockets[i].fd = fd;
1.194 markus 930: if ((sockets[i].input = sshbuf_new()) == NULL)
931: fatal("%s: sshbuf_new failed", __func__);
932: if ((sockets[i].output = sshbuf_new()) == NULL)
933: fatal("%s: sshbuf_new failed", __func__);
934: if ((sockets[i].request = sshbuf_new()) == NULL)
935: fatal("%s: sshbuf_new failed", __func__);
1.112 markus 936: sockets[i].type = type;
1.21 markus 937: return;
938: }
939: old_alloc = sockets_alloc;
1.112 markus 940: new_alloc = sockets_alloc + 10;
1.200 deraadt 941: sockets = xreallocarray(sockets, new_alloc, sizeof(sockets[0]));
1.112 markus 942: for (i = old_alloc; i < new_alloc; i++)
1.21 markus 943: sockets[i].type = AUTH_UNUSED;
1.112 markus 944: sockets_alloc = new_alloc;
1.21 markus 945: sockets[old_alloc].fd = fd;
1.194 markus 946: if ((sockets[old_alloc].input = sshbuf_new()) == NULL)
947: fatal("%s: sshbuf_new failed", __func__);
948: if ((sockets[old_alloc].output = sshbuf_new()) == NULL)
949: fatal("%s: sshbuf_new failed", __func__);
950: if ((sockets[old_alloc].request = sshbuf_new()) == NULL)
951: fatal("%s: sshbuf_new failed", __func__);
1.112 markus 952: sockets[old_alloc].type = type;
1.1 deraadt 953: }
954:
1.55 itojun 955: static int
1.155 dtucker 956: prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, u_int *nallocp,
957: struct timeval **tvpp)
1.1 deraadt 958: {
1.174 dtucker 959: u_int i, sz;
1.46 markus 960: int n = 0;
1.155 dtucker 961: static struct timeval tv;
1.174 dtucker 962: time_t deadline;
1.46 markus 963:
964: for (i = 0; i < sockets_alloc; i++) {
1.21 markus 965: switch (sockets[i].type) {
966: case AUTH_SOCKET:
967: case AUTH_CONNECTION:
1.46 markus 968: n = MAX(n, sockets[i].fd);
1.21 markus 969: break;
970: case AUTH_UNUSED:
971: break;
972: default:
973: fatal("Unknown socket type %d", sockets[i].type);
974: break;
975: }
1.46 markus 976: }
977:
978: sz = howmany(n+1, NFDBITS) * sizeof(fd_mask);
1.66 markus 979: if (*fdrp == NULL || sz > *nallocp) {
1.173 djm 980: free(*fdrp);
981: free(*fdwp);
1.46 markus 982: *fdrp = xmalloc(sz);
983: *fdwp = xmalloc(sz);
1.66 markus 984: *nallocp = sz;
1.46 markus 985: }
1.66 markus 986: if (n < *fdl)
987: debug("XXX shrink: %d < %d", n, *fdl);
988: *fdl = n;
1.46 markus 989: memset(*fdrp, 0, sz);
990: memset(*fdwp, 0, sz);
991:
992: for (i = 0; i < sockets_alloc; i++) {
993: switch (sockets[i].type) {
994: case AUTH_SOCKET:
995: case AUTH_CONNECTION:
996: FD_SET(sockets[i].fd, *fdrp);
1.194 markus 997: if (sshbuf_len(sockets[i].output) > 0)
1.46 markus 998: FD_SET(sockets[i].fd, *fdwp);
999: break;
1000: default:
1001: break;
1002: }
1003: }
1.155 dtucker 1004: deadline = reaper();
1005: if (parent_alive_interval != 0)
1006: deadline = (deadline == 0) ? parent_alive_interval :
1007: MIN(deadline, parent_alive_interval);
1008: if (deadline == 0) {
1009: *tvpp = NULL;
1010: } else {
1011: tv.tv_sec = deadline;
1012: tv.tv_usec = 0;
1013: *tvpp = &tv;
1014: }
1.46 markus 1015: return (1);
1.21 markus 1016: }
1017:
1.55 itojun 1018: static void
1.21 markus 1019: after_select(fd_set *readset, fd_set *writeset)
1020: {
1.96 deraadt 1021: struct sockaddr_un sunaddr;
1.26 markus 1022: socklen_t slen;
1.21 markus 1023: char buf[1024];
1.194 markus 1024: int len, sock, r;
1.162 djm 1025: u_int i, orig_alloc;
1.103 markus 1026: uid_t euid;
1027: gid_t egid;
1.21 markus 1028:
1.162 djm 1029: for (i = 0, orig_alloc = sockets_alloc; i < orig_alloc; i++)
1.21 markus 1030: switch (sockets[i].type) {
1031: case AUTH_UNUSED:
1032: break;
1033: case AUTH_SOCKET:
1034: if (FD_ISSET(sockets[i].fd, readset)) {
1.26 markus 1035: slen = sizeof(sunaddr);
1.46 markus 1036: sock = accept(sockets[i].fd,
1.131 deraadt 1037: (struct sockaddr *)&sunaddr, &slen);
1.21 markus 1038: if (sock < 0) {
1.81 stevesk 1039: error("accept from AUTH_SOCKET: %s",
1040: strerror(errno));
1.103 markus 1041: break;
1042: }
1043: if (getpeereid(sock, &euid, &egid) < 0) {
1044: error("getpeereid %d failed: %s",
1045: sock, strerror(errno));
1046: close(sock);
1047: break;
1048: }
1.105 markus 1049: if ((euid != 0) && (getuid() != euid)) {
1.103 markus 1050: error("uid mismatch: "
1.104 stevesk 1051: "peer euid %u != uid %u",
1052: (u_int) euid, (u_int) getuid());
1.103 markus 1053: close(sock);
1.21 markus 1054: break;
1055: }
1056: new_socket(AUTH_CONNECTION, sock);
1057: }
1058: break;
1059: case AUTH_CONNECTION:
1.194 markus 1060: if (sshbuf_len(sockets[i].output) > 0 &&
1.21 markus 1061: FD_ISSET(sockets[i].fd, writeset)) {
1.162 djm 1062: len = write(sockets[i].fd,
1.194 markus 1063: sshbuf_ptr(sockets[i].output),
1064: sshbuf_len(sockets[i].output));
1.162 djm 1065: if (len == -1 && (errno == EAGAIN ||
1066: errno == EINTR))
1067: continue;
1.21 markus 1068: if (len <= 0) {
1.101 stevesk 1069: close_socket(&sockets[i]);
1.21 markus 1070: break;
1071: }
1.194 markus 1072: if ((r = sshbuf_consume(sockets[i].output,
1073: len)) != 0)
1074: fatal("%s: buffer error: %s",
1075: __func__, ssh_err(r));
1.21 markus 1076: }
1077: if (FD_ISSET(sockets[i].fd, readset)) {
1.162 djm 1078: len = read(sockets[i].fd, buf, sizeof(buf));
1079: if (len == -1 && (errno == EAGAIN ||
1080: errno == EINTR))
1081: continue;
1.21 markus 1082: if (len <= 0) {
1.101 stevesk 1083: close_socket(&sockets[i]);
1.21 markus 1084: break;
1085: }
1.194 markus 1086: if ((r = sshbuf_put(sockets[i].input,
1087: buf, len)) != 0)
1088: fatal("%s: buffer error: %s",
1089: __func__, ssh_err(r));
1.190 dtucker 1090: explicit_bzero(buf, sizeof(buf));
1.21 markus 1091: process_message(&sockets[i]);
1092: }
1093: break;
1094: default:
1095: fatal("Unknown type %d", sockets[i].type);
1096: }
1.1 deraadt 1097: }
1098:
1.55 itojun 1099: static void
1.113 markus 1100: cleanup_socket(void)
1.15 markus 1101: {
1.187 djm 1102: if (cleanup_pid != 0 && getpid() != cleanup_pid)
1103: return;
1104: debug("%s: cleanup", __func__);
1.48 deraadt 1105: if (socket_name[0])
1106: unlink(socket_name);
1107: if (socket_dir[0])
1108: rmdir(socket_dir);
1.10 markus 1109: }
1110:
1.114 markus 1111: void
1.15 markus 1112: cleanup_exit(int i)
1113: {
1.113 markus 1114: cleanup_socket();
1115: _exit(i);
1.15 markus 1116: }
1117:
1.135 deraadt 1118: /*ARGSUSED*/
1.55 itojun 1119: static void
1.48 deraadt 1120: cleanup_handler(int sig)
1121: {
1.113 markus 1122: cleanup_socket();
1.163 markus 1123: #ifdef ENABLE_PKCS11
1124: pkcs11_terminate();
1125: #endif
1.48 deraadt 1126: _exit(2);
1.113 markus 1127: }
1128:
1.68 markus 1129: static void
1.155 dtucker 1130: check_parent_exists(void)
1.68 markus 1131: {
1.172 dtucker 1132: /*
1133: * If our parent has exited then getppid() will return (pid_t)1,
1134: * so testing for that should be safe.
1135: */
1136: if (parent_pid != -1 && getppid() != parent_pid) {
1.68 markus 1137: /* printf("Parent has died - Authentication agent exiting.\n"); */
1.155 dtucker 1138: cleanup_socket();
1139: _exit(2);
1.68 markus 1140: }
1.48 deraadt 1141: }
1142:
1.55 itojun 1143: static void
1.50 itojun 1144: usage(void)
1.15 markus 1145: {
1.184 deraadt 1146: fprintf(stderr,
1.202 jmc 1147: "usage: ssh-agent [-c | -s] [-Dd] [-a bind_address] [-E fingerprint_hash]\n"
1.193 jmc 1148: " [-t life] [command [arg ...]]\n"
1.184 deraadt 1149: " ssh-agent [-c | -s] -k\n");
1.21 markus 1150: exit(1);
1.15 markus 1151: }
1152:
1.2 provos 1153: int
1154: main(int ac, char **av)
1.1 deraadt 1155: {
1.201 djm 1156: int c_flag = 0, d_flag = 0, D_flag = 0, k_flag = 0, s_flag = 0;
1.154 dtucker 1157: int sock, fd, ch, result, saved_errno;
1.120 avsm 1158: u_int nalloc;
1.96 deraadt 1159: char *shell, *format, *pidstr, *agentsocket = NULL;
1160: fd_set *readsetp = NULL, *writesetp = NULL;
1.41 markus 1161: struct rlimit rlim;
1.96 deraadt 1162: extern int optind;
1.98 stevesk 1163: extern char *optarg;
1.21 markus 1164: pid_t pid;
1.96 deraadt 1165: char pidstrbuf[1 + 3 * sizeof pid];
1.155 dtucker 1166: struct timeval *tvp = NULL;
1.161 tobias 1167: size_t len;
1.189 djm 1168: mode_t prev_mask;
1.123 djm 1169:
1170: /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
1171: sanitise_stdfd();
1.99 markus 1172:
1173: /* drop */
1174: setegid(getgid());
1175: setgid(getgid());
1.53 markus 1176:
1.185 markus 1177: #ifdef WITH_OPENSSL
1.170 djm 1178: OpenSSL_add_all_algorithms();
1.185 markus 1179: #endif
1.21 markus 1180:
1.201 djm 1181: while ((ch = getopt(ac, av, "cDdksE:a:t:")) != -1) {
1.21 markus 1182: switch (ch) {
1.192 djm 1183: case 'E':
1184: fingerprint_hash = ssh_digest_alg_by_name(optarg);
1185: if (fingerprint_hash == -1)
1186: fatal("Invalid hash algorithm \"%s\"", optarg);
1187: break;
1.21 markus 1188: case 'c':
1189: if (s_flag)
1190: usage();
1191: c_flag++;
1192: break;
1193: case 'k':
1194: k_flag++;
1195: break;
1196: case 's':
1197: if (c_flag)
1198: usage();
1199: s_flag++;
1200: break;
1.57 markus 1201: case 'd':
1.201 djm 1202: if (d_flag || D_flag)
1.57 markus 1203: usage();
1204: d_flag++;
1205: break;
1.201 djm 1206: case 'D':
1207: if (d_flag || D_flag)
1208: usage();
1209: D_flag++;
1210: break;
1.86 markus 1211: case 'a':
1212: agentsocket = optarg;
1.106 marc 1213: break;
1214: case 't':
1215: if ((lifetime = convtime(optarg)) == -1) {
1216: fprintf(stderr, "Invalid lifetime\n");
1217: usage();
1218: }
1.86 markus 1219: break;
1.21 markus 1220: default:
1221: usage();
1222: }
1223: }
1224: ac -= optind;
1225: av += optind;
1226:
1.201 djm 1227: if (ac > 0 && (c_flag || k_flag || s_flag || d_flag || D_flag))
1.21 markus 1228: usage();
1229:
1.85 markus 1230: if (ac == 0 && !c_flag && !s_flag) {
1.21 markus 1231: shell = getenv("SHELL");
1.161 tobias 1232: if (shell != NULL && (len = strlen(shell)) > 2 &&
1233: strncmp(shell + len - 3, "csh", 3) == 0)
1.21 markus 1234: c_flag = 1;
1235: }
1236: if (k_flag) {
1.136 deraadt 1237: const char *errstr = NULL;
1238:
1.21 markus 1239: pidstr = getenv(SSH_AGENTPID_ENV_NAME);
1240: if (pidstr == NULL) {
1241: fprintf(stderr, "%s not set, cannot kill agent\n",
1.46 markus 1242: SSH_AGENTPID_ENV_NAME);
1.21 markus 1243: exit(1);
1244: }
1.136 deraadt 1245: pid = (int)strtonum(pidstr, 2, INT_MAX, &errstr);
1246: if (errstr) {
1247: fprintf(stderr,
1248: "%s=\"%s\", which is not a good PID: %s\n",
1249: SSH_AGENTPID_ENV_NAME, pidstr, errstr);
1.21 markus 1250: exit(1);
1251: }
1252: if (kill(pid, SIGTERM) == -1) {
1253: perror("kill");
1254: exit(1);
1255: }
1256: format = c_flag ? "unsetenv %s;\n" : "unset %s;\n";
1.140 djm 1257: printf(format, SSH_AUTHSOCKET_ENV_NAME);
1258: printf(format, SSH_AGENTPID_ENV_NAME);
1.91 mpech 1259: printf("echo Agent pid %ld killed;\n", (long)pid);
1.21 markus 1260: exit(0);
1261: }
1262: parent_pid = getpid();
1263:
1.86 markus 1264: if (agentsocket == NULL) {
1265: /* Create private directory for agent socket */
1.171 djm 1266: mktemp_proto(socket_dir, sizeof(socket_dir));
1.86 markus 1267: if (mkdtemp(socket_dir) == NULL) {
1268: perror("mkdtemp: private socket dir");
1269: exit(1);
1270: }
1.91 mpech 1271: snprintf(socket_name, sizeof socket_name, "%s/agent.%ld", socket_dir,
1272: (long)parent_pid);
1.86 markus 1273: } else {
1274: /* Try to use specified agent socket */
1275: socket_dir[0] = '\0';
1276: strlcpy(socket_name, agentsocket, sizeof socket_name);
1.21 markus 1277: }
1278:
1.23 markus 1279: /*
1280: * Create socket early so it will exist before command gets run from
1281: * the parent.
1282: */
1.189 djm 1283: prev_mask = umask(0177);
1.188 millert 1284: sock = unix_listener(socket_name, SSH_LISTEN_BACKLOG, 0);
1.21 markus 1285: if (sock < 0) {
1.188 millert 1286: /* XXX - unix_listener() calls error() not perror() */
1.121 djm 1287: *socket_name = '\0'; /* Don't unlink any existing file */
1.21 markus 1288: cleanup_exit(1);
1289: }
1.189 djm 1290: umask(prev_mask);
1.46 markus 1291:
1.23 markus 1292: /*
1293: * Fork, and have the parent execute the command, if any, or present
1294: * the socket data. The child continues as the authentication agent.
1295: */
1.201 djm 1296: if (D_flag || d_flag) {
1297: log_init(__progname,
1298: d_flag ? SYSLOG_LEVEL_DEBUG3 : SYSLOG_LEVEL_INFO,
1299: SYSLOG_FACILITY_AUTH, 1);
1.57 markus 1300: format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n";
1301: printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name,
1302: SSH_AUTHSOCKET_ENV_NAME);
1.91 mpech 1303: printf("echo Agent pid %ld;\n", (long)parent_pid);
1.57 markus 1304: goto skip;
1305: }
1.21 markus 1306: pid = fork();
1307: if (pid == -1) {
1308: perror("fork");
1.81 stevesk 1309: cleanup_exit(1);
1.21 markus 1310: }
1311: if (pid != 0) { /* Parent - execute the given command. */
1312: close(sock);
1.91 mpech 1313: snprintf(pidstrbuf, sizeof pidstrbuf, "%ld", (long)pid);
1.21 markus 1314: if (ac == 0) {
1315: format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n";
1316: printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name,
1.46 markus 1317: SSH_AUTHSOCKET_ENV_NAME);
1.21 markus 1318: printf(format, SSH_AGENTPID_ENV_NAME, pidstrbuf,
1.46 markus 1319: SSH_AGENTPID_ENV_NAME);
1.91 mpech 1320: printf("echo Agent pid %ld;\n", (long)pid);
1.21 markus 1321: exit(0);
1322: }
1.36 deraadt 1323: if (setenv(SSH_AUTHSOCKET_ENV_NAME, socket_name, 1) == -1 ||
1324: setenv(SSH_AGENTPID_ENV_NAME, pidstrbuf, 1) == -1) {
1325: perror("setenv");
1326: exit(1);
1327: }
1.21 markus 1328: execvp(av[0], av);
1329: perror(av[0]);
1330: exit(1);
1331: }
1.81 stevesk 1332: /* child */
1333: log_init(__progname, SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_AUTH, 0);
1.67 stevesk 1334:
1335: if (setsid() == -1) {
1.81 stevesk 1336: error("setsid: %s", strerror(errno));
1.67 stevesk 1337: cleanup_exit(1);
1338: }
1339:
1340: (void)chdir("/");
1.107 markus 1341: if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
1342: /* XXX might close listen socket */
1343: (void)dup2(fd, STDIN_FILENO);
1344: (void)dup2(fd, STDOUT_FILENO);
1345: (void)dup2(fd, STDERR_FILENO);
1346: if (fd > 2)
1347: close(fd);
1348: }
1.21 markus 1349:
1.41 markus 1350: /* deny core dumps, since memory contains unencrypted private keys */
1351: rlim.rlim_cur = rlim.rlim_max = 0;
1352: if (setrlimit(RLIMIT_CORE, &rlim) < 0) {
1.81 stevesk 1353: error("setrlimit RLIMIT_CORE: %s", strerror(errno));
1.21 markus 1354: cleanup_exit(1);
1355: }
1.57 markus 1356:
1357: skip:
1.187 djm 1358:
1359: cleanup_pid = getpid();
1.163 markus 1360:
1361: #ifdef ENABLE_PKCS11
1362: pkcs11_init(0);
1363: #endif
1.21 markus 1364: new_socket(AUTH_SOCKET, sock);
1.155 dtucker 1365: if (ac > 0)
1366: parent_alive_interval = 10;
1.33 markus 1367: idtab_init();
1.61 markus 1368: signal(SIGPIPE, SIG_IGN);
1.201 djm 1369: signal(SIGINT, (d_flag | D_flag) ? cleanup_handler : SIG_IGN);
1.48 deraadt 1370: signal(SIGHUP, cleanup_handler);
1371: signal(SIGTERM, cleanup_handler);
1.66 markus 1372: nalloc = 0;
1373:
1.21 markus 1374: while (1) {
1.155 dtucker 1375: prepare_select(&readsetp, &writesetp, &max_fd, &nalloc, &tvp);
1376: result = select(max_fd + 1, readsetp, writesetp, NULL, tvp);
1.154 dtucker 1377: saved_errno = errno;
1.155 dtucker 1378: if (parent_alive_interval != 0)
1379: check_parent_exists();
1380: (void) reaper(); /* remove expired keys */
1.154 dtucker 1381: if (result < 0) {
1382: if (saved_errno == EINTR)
1.21 markus 1383: continue;
1.154 dtucker 1384: fatal("select: %s", strerror(saved_errno));
1385: } else if (result > 0)
1386: after_select(readsetp, writesetp);
1.15 markus 1387: }
1.21 markus 1388: /* NOTREACHED */
1.1 deraadt 1389: }