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