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