xref: /dragonfly/crypto/openssh/ssh-agent.c (revision bcb3e04d)
1 /* $OpenBSD: ssh-agent.c,v 1.166 2010/04/16 01:47:26 djm Exp $ */
2 /*
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.
7  *
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  *
14  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
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.
35  */
36 
37 #include "includes.h"
38 
39 #include <sys/types.h>
40 #include <sys/param.h>
41 #include <sys/resource.h>
42 #include <sys/stat.h>
43 #include <sys/socket.h>
44 #ifdef HAVE_SYS_TIME_H
45 # include <sys/time.h>
46 #endif
47 #ifdef HAVE_SYS_UN_H
48 # include <sys/un.h>
49 #endif
50 #include "openbsd-compat/sys-queue.h"
51 
52 #include <openssl/evp.h>
53 #include <openssl/md5.h>
54 #include "openbsd-compat/openssl-compat.h"
55 
56 #include <errno.h>
57 #include <fcntl.h>
58 #ifdef HAVE_PATHS_H
59 # include <paths.h>
60 #endif
61 #include <signal.h>
62 #include <stdarg.h>
63 #include <stdio.h>
64 #include <stdlib.h>
65 #include <time.h>
66 #include <string.h>
67 #include <unistd.h>
68 
69 #include "xmalloc.h"
70 #include "ssh.h"
71 #include "rsa.h"
72 #include "buffer.h"
73 #include "key.h"
74 #include "authfd.h"
75 #include "compat.h"
76 #include "log.h"
77 #include "misc.h"
78 
79 #ifdef ENABLE_PKCS11
80 #include "ssh-pkcs11.h"
81 #endif
82 
83 #if defined(HAVE_SYS_PRCTL_H)
84 #include <sys/prctl.h>	/* For prctl() and PR_SET_DUMPABLE */
85 #endif
86 
87 typedef enum {
88 	AUTH_UNUSED,
89 	AUTH_SOCKET,
90 	AUTH_CONNECTION
91 } sock_type;
92 
93 typedef struct {
94 	int fd;
95 	sock_type type;
96 	Buffer input;
97 	Buffer output;
98 	Buffer request;
99 } SocketEntry;
100 
101 u_int sockets_alloc = 0;
102 SocketEntry *sockets = NULL;
103 
104 typedef struct identity {
105 	TAILQ_ENTRY(identity) next;
106 	Key *key;
107 	char *comment;
108 	char *provider;
109 	u_int death;
110 	u_int confirm;
111 } Identity;
112 
113 typedef struct {
114 	int nentries;
115 	TAILQ_HEAD(idqueue, identity) idlist;
116 } Idtab;
117 
118 /* private key table, one per protocol version */
119 Idtab idtable[3];
120 
121 int max_fd = 0;
122 
123 /* pid of shell == parent of agent */
124 pid_t parent_pid = -1;
125 u_int parent_alive_interval = 0;
126 
127 /* pathname and directory for AUTH_SOCKET */
128 char socket_name[MAXPATHLEN];
129 char socket_dir[MAXPATHLEN];
130 
131 /* locking */
132 int locked = 0;
133 char *lock_passwd = NULL;
134 
135 extern char *__progname;
136 
137 /* Default lifetime (0 == forever) */
138 static int lifetime = 0;
139 
140 static void
141 close_socket(SocketEntry *e)
142 {
143 	close(e->fd);
144 	e->fd = -1;
145 	e->type = AUTH_UNUSED;
146 	buffer_free(&e->input);
147 	buffer_free(&e->output);
148 	buffer_free(&e->request);
149 }
150 
151 static void
152 idtab_init(void)
153 {
154 	int i;
155 
156 	for (i = 0; i <=2; i++) {
157 		TAILQ_INIT(&idtable[i].idlist);
158 		idtable[i].nentries = 0;
159 	}
160 }
161 
162 /* return private key table for requested protocol version */
163 static Idtab *
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 
171 static void
172 free_identity(Identity *id)
173 {
174 	key_free(id->key);
175 	if (id->provider != NULL)
176 		xfree(id->provider);
177 	xfree(id->comment);
178 	xfree(id);
179 }
180 
181 /* return matching private key for given public key */
182 static Identity *
183 lookup_identity(Key *key, int version)
184 {
185 	Identity *id;
186 
187 	Idtab *tab = idtab_lookup(version);
188 	TAILQ_FOREACH(id, &tab->idlist, next) {
189 		if (key_equal(key, id->key))
190 			return (id);
191 	}
192 	return (NULL);
193 }
194 
195 /* Check confirmation of keysign request */
196 static int
197 confirm_key(Identity *id)
198 {
199 	char *p;
200 	int ret = -1;
201 
202 	p = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX);
203 	if (ask_permission("Allow use of key %s?\nKey fingerprint %s.",
204 	    id->comment, p))
205 		ret = 0;
206 	xfree(p);
207 
208 	return (ret);
209 }
210 
211 /* send list of supported public keys to 'client' */
212 static void
213 process_request_identities(SocketEntry *e, int version)
214 {
215 	Idtab *tab = idtab_lookup(version);
216 	Identity *id;
217 	Buffer msg;
218 
219 	buffer_init(&msg);
220 	buffer_put_char(&msg, (version == 1) ?
221 	    SSH_AGENT_RSA_IDENTITIES_ANSWER : SSH2_AGENT_IDENTITIES_ANSWER);
222 	buffer_put_int(&msg, tab->nentries);
223 	TAILQ_FOREACH(id, &tab->idlist, next) {
224 		if (id->key->type == KEY_RSA1) {
225 			buffer_put_int(&msg, BN_num_bits(id->key->rsa->n));
226 			buffer_put_bignum(&msg, id->key->rsa->e);
227 			buffer_put_bignum(&msg, id->key->rsa->n);
228 		} else {
229 			u_char *blob;
230 			u_int blen;
231 			key_to_blob(id->key, &blob, &blen);
232 			buffer_put_string(&msg, blob, blen);
233 			xfree(blob);
234 		}
235 		buffer_put_cstring(&msg, id->comment);
236 	}
237 	buffer_put_int(&e->output, buffer_len(&msg));
238 	buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg));
239 	buffer_free(&msg);
240 }
241 
242 /* ssh1 only */
243 static void
244 process_authentication_challenge1(SocketEntry *e)
245 {
246 	u_char buf[32], mdbuf[16], session_id[16];
247 	u_int response_type;
248 	BIGNUM *challenge;
249 	Identity *id;
250 	int i, len;
251 	Buffer msg;
252 	MD5_CTX md;
253 	Key *key;
254 
255 	buffer_init(&msg);
256 	key = key_new(KEY_RSA1);
257 	if ((challenge = BN_new()) == NULL)
258 		fatal("process_authentication_challenge1: BN_new failed");
259 
260 	(void) buffer_get_int(&e->request);			/* ignored */
261 	buffer_get_bignum(&e->request, key->rsa->e);
262 	buffer_get_bignum(&e->request, key->rsa->n);
263 	buffer_get_bignum(&e->request, challenge);
264 
265 	/* Only protocol 1.1 is supported */
266 	if (buffer_len(&e->request) == 0)
267 		goto failure;
268 	buffer_get(&e->request, session_id, 16);
269 	response_type = buffer_get_int(&e->request);
270 	if (response_type != 1)
271 		goto failure;
272 
273 	id = lookup_identity(key, 1);
274 	if (id != NULL && (!id->confirm || confirm_key(id) == 0)) {
275 		Key *private = id->key;
276 		/* Decrypt the challenge using the private key. */
277 		if (rsa_private_decrypt(challenge, challenge, private->rsa) <= 0)
278 			goto failure;
279 
280 		/* The response is MD5 of decrypted challenge plus session id. */
281 		len = BN_num_bytes(challenge);
282 		if (len <= 0 || len > 32) {
283 			logit("process_authentication_challenge: bad challenge length %d", len);
284 			goto failure;
285 		}
286 		memset(buf, 0, 32);
287 		BN_bn2bin(challenge, buf + 32 - len);
288 		MD5_Init(&md);
289 		MD5_Update(&md, buf, 32);
290 		MD5_Update(&md, session_id, 16);
291 		MD5_Final(mdbuf, &md);
292 
293 		/* Send the response. */
294 		buffer_put_char(&msg, SSH_AGENT_RSA_RESPONSE);
295 		for (i = 0; i < 16; i++)
296 			buffer_put_char(&msg, mdbuf[i]);
297 		goto send;
298 	}
299 
300 failure:
301 	/* Unknown identity or protocol error.  Send failure. */
302 	buffer_put_char(&msg, SSH_AGENT_FAILURE);
303 send:
304 	buffer_put_int(&e->output, buffer_len(&msg));
305 	buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg));
306 	key_free(key);
307 	BN_clear_free(challenge);
308 	buffer_free(&msg);
309 }
310 
311 /* ssh2 only */
312 static void
313 process_sign_request2(SocketEntry *e)
314 {
315 	u_char *blob, *data, *signature = NULL;
316 	u_int blen, dlen, slen = 0;
317 	extern int datafellows;
318 	int odatafellows;
319 	int ok = -1, flags;
320 	Buffer msg;
321 	Key *key;
322 
323 	datafellows = 0;
324 
325 	blob = buffer_get_string(&e->request, &blen);
326 	data = buffer_get_string(&e->request, &dlen);
327 
328 	flags = buffer_get_int(&e->request);
329 	odatafellows = datafellows;
330 	if (flags & SSH_AGENT_OLD_SIGNATURE)
331 		datafellows = SSH_BUG_SIGBLOB;
332 
333 	key = key_from_blob(blob, blen);
334 	if (key != NULL) {
335 		Identity *id = lookup_identity(key, 2);
336 		if (id != NULL && (!id->confirm || confirm_key(id) == 0))
337 			ok = key_sign(id->key, &signature, &slen, data, dlen);
338 		key_free(key);
339 	}
340 	buffer_init(&msg);
341 	if (ok == 0) {
342 		buffer_put_char(&msg, SSH2_AGENT_SIGN_RESPONSE);
343 		buffer_put_string(&msg, signature, slen);
344 	} else {
345 		buffer_put_char(&msg, SSH_AGENT_FAILURE);
346 	}
347 	buffer_put_int(&e->output, buffer_len(&msg));
348 	buffer_append(&e->output, buffer_ptr(&msg),
349 	    buffer_len(&msg));
350 	buffer_free(&msg);
351 	xfree(data);
352 	xfree(blob);
353 	if (signature != NULL)
354 		xfree(signature);
355 	datafellows = odatafellows;
356 }
357 
358 /* shared */
359 static void
360 process_remove_identity(SocketEntry *e, int version)
361 {
362 	u_int blen, bits;
363 	int success = 0;
364 	Key *key = NULL;
365 	u_char *blob;
366 
367 	switch (version) {
368 	case 1:
369 		key = key_new(KEY_RSA1);
370 		bits = buffer_get_int(&e->request);
371 		buffer_get_bignum(&e->request, key->rsa->e);
372 		buffer_get_bignum(&e->request, key->rsa->n);
373 
374 		if (bits != key_size(key))
375 			logit("Warning: identity keysize mismatch: actual %u, announced %u",
376 			    key_size(key), bits);
377 		break;
378 	case 2:
379 		blob = buffer_get_string(&e->request, &blen);
380 		key = key_from_blob(blob, blen);
381 		xfree(blob);
382 		break;
383 	}
384 	if (key != NULL) {
385 		Identity *id = lookup_identity(key, version);
386 		if (id != NULL) {
387 			/*
388 			 * We have this key.  Free the old key.  Since we
389 			 * don't want to leave empty slots in the middle of
390 			 * the array, we actually free the key there and move
391 			 * all the entries between the empty slot and the end
392 			 * of the array.
393 			 */
394 			Idtab *tab = idtab_lookup(version);
395 			if (tab->nentries < 1)
396 				fatal("process_remove_identity: "
397 				    "internal error: tab->nentries %d",
398 				    tab->nentries);
399 			TAILQ_REMOVE(&tab->idlist, id, next);
400 			free_identity(id);
401 			tab->nentries--;
402 			success = 1;
403 		}
404 		key_free(key);
405 	}
406 	buffer_put_int(&e->output, 1);
407 	buffer_put_char(&e->output,
408 	    success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
409 }
410 
411 static void
412 process_remove_all_identities(SocketEntry *e, int version)
413 {
414 	Idtab *tab = idtab_lookup(version);
415 	Identity *id;
416 
417 	/* Loop over all identities and clear the keys. */
418 	for (id = TAILQ_FIRST(&tab->idlist); id;
419 	    id = TAILQ_FIRST(&tab->idlist)) {
420 		TAILQ_REMOVE(&tab->idlist, id, next);
421 		free_identity(id);
422 	}
423 
424 	/* Mark that there are no identities. */
425 	tab->nentries = 0;
426 
427 	/* Send success. */
428 	buffer_put_int(&e->output, 1);
429 	buffer_put_char(&e->output, SSH_AGENT_SUCCESS);
430 }
431 
432 /* removes expired keys and returns number of seconds until the next expiry */
433 static u_int
434 reaper(void)
435 {
436 	u_int deadline = 0, now = time(NULL);
437 	Identity *id, *nxt;
438 	int version;
439 	Idtab *tab;
440 
441 	for (version = 1; version < 3; version++) {
442 		tab = idtab_lookup(version);
443 		for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) {
444 			nxt = TAILQ_NEXT(id, next);
445 			if (id->death == 0)
446 				continue;
447 			if (now >= id->death) {
448 				debug("expiring key '%s'", id->comment);
449 				TAILQ_REMOVE(&tab->idlist, id, next);
450 				free_identity(id);
451 				tab->nentries--;
452 			} else
453 				deadline = (deadline == 0) ? id->death :
454 				    MIN(deadline, id->death);
455 		}
456 	}
457 	if (deadline == 0 || deadline <= now)
458 		return 0;
459 	else
460 		return (deadline - now);
461 }
462 
463 static void
464 process_add_identity(SocketEntry *e, int version)
465 {
466 	Idtab *tab = idtab_lookup(version);
467 	Identity *id;
468 	int type, success = 0, death = 0, confirm = 0;
469 	char *type_name, *comment;
470 	Key *k = NULL;
471 	u_char *cert;
472 	u_int len;
473 
474 	switch (version) {
475 	case 1:
476 		k = key_new_private(KEY_RSA1);
477 		(void) buffer_get_int(&e->request);		/* ignored */
478 		buffer_get_bignum(&e->request, k->rsa->n);
479 		buffer_get_bignum(&e->request, k->rsa->e);
480 		buffer_get_bignum(&e->request, k->rsa->d);
481 		buffer_get_bignum(&e->request, k->rsa->iqmp);
482 
483 		/* SSH and SSL have p and q swapped */
484 		buffer_get_bignum(&e->request, k->rsa->q);	/* p */
485 		buffer_get_bignum(&e->request, k->rsa->p);	/* q */
486 
487 		/* Generate additional parameters */
488 		rsa_generate_additional_parameters(k->rsa);
489 		break;
490 	case 2:
491 		type_name = buffer_get_string(&e->request, NULL);
492 		type = key_type_from_name(type_name);
493 		xfree(type_name);
494 		switch (type) {
495 		case KEY_DSA:
496 			k = key_new_private(type);
497 			buffer_get_bignum2(&e->request, k->dsa->p);
498 			buffer_get_bignum2(&e->request, k->dsa->q);
499 			buffer_get_bignum2(&e->request, k->dsa->g);
500 			buffer_get_bignum2(&e->request, k->dsa->pub_key);
501 			buffer_get_bignum2(&e->request, k->dsa->priv_key);
502 			break;
503 		case KEY_DSA_CERT_V00:
504 		case KEY_DSA_CERT:
505 			cert = buffer_get_string(&e->request, &len);
506 			if ((k = key_from_blob(cert, len)) == NULL)
507 				fatal("Certificate parse failed");
508 			xfree(cert);
509 			key_add_private(k);
510 			buffer_get_bignum2(&e->request, k->dsa->priv_key);
511 			break;
512 		case KEY_RSA:
513 			k = key_new_private(type);
514 			buffer_get_bignum2(&e->request, k->rsa->n);
515 			buffer_get_bignum2(&e->request, k->rsa->e);
516 			buffer_get_bignum2(&e->request, k->rsa->d);
517 			buffer_get_bignum2(&e->request, k->rsa->iqmp);
518 			buffer_get_bignum2(&e->request, k->rsa->p);
519 			buffer_get_bignum2(&e->request, k->rsa->q);
520 
521 			/* Generate additional parameters */
522 			rsa_generate_additional_parameters(k->rsa);
523 			break;
524 		case KEY_RSA_CERT_V00:
525 		case KEY_RSA_CERT:
526 			cert = buffer_get_string(&e->request, &len);
527 			if ((k = key_from_blob(cert, len)) == NULL)
528 				fatal("Certificate parse failed");
529 			xfree(cert);
530 			key_add_private(k);
531 			buffer_get_bignum2(&e->request, k->rsa->d);
532 			buffer_get_bignum2(&e->request, k->rsa->iqmp);
533 			buffer_get_bignum2(&e->request, k->rsa->p);
534 			buffer_get_bignum2(&e->request, k->rsa->q);
535 			break;
536 		default:
537 			buffer_clear(&e->request);
538 			goto send;
539 		}
540 		break;
541 	}
542 	/* enable blinding */
543 	switch (k->type) {
544 	case KEY_RSA:
545 	case KEY_RSA_CERT_V00:
546 	case KEY_RSA_CERT:
547 	case KEY_RSA1:
548 		if (RSA_blinding_on(k->rsa, NULL) != 1) {
549 			error("process_add_identity: RSA_blinding_on failed");
550 			key_free(k);
551 			goto send;
552 		}
553 		break;
554 	}
555 	comment = buffer_get_string(&e->request, NULL);
556 	if (k == NULL) {
557 		xfree(comment);
558 		goto send;
559 	}
560 	while (buffer_len(&e->request)) {
561 		switch ((type = buffer_get_char(&e->request))) {
562 		case SSH_AGENT_CONSTRAIN_LIFETIME:
563 			death = time(NULL) + buffer_get_int(&e->request);
564 			break;
565 		case SSH_AGENT_CONSTRAIN_CONFIRM:
566 			confirm = 1;
567 			break;
568 		default:
569 			error("process_add_identity: "
570 			    "Unknown constraint type %d", type);
571 			xfree(comment);
572 			key_free(k);
573 			goto send;
574 		}
575 	}
576 	success = 1;
577 	if (lifetime && !death)
578 		death = time(NULL) + lifetime;
579 	if ((id = lookup_identity(k, version)) == NULL) {
580 		id = xcalloc(1, sizeof(Identity));
581 		id->key = k;
582 		TAILQ_INSERT_TAIL(&tab->idlist, id, next);
583 		/* Increment the number of identities. */
584 		tab->nentries++;
585 	} else {
586 		key_free(k);
587 		xfree(id->comment);
588 	}
589 	id->comment = comment;
590 	id->death = death;
591 	id->confirm = confirm;
592 send:
593 	buffer_put_int(&e->output, 1);
594 	buffer_put_char(&e->output,
595 	    success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
596 }
597 
598 /* XXX todo: encrypt sensitive data with passphrase */
599 static void
600 process_lock_agent(SocketEntry *e, int lock)
601 {
602 	int success = 0;
603 	char *passwd;
604 
605 	passwd = buffer_get_string(&e->request, NULL);
606 	if (locked && !lock && strcmp(passwd, lock_passwd) == 0) {
607 		locked = 0;
608 		memset(lock_passwd, 0, strlen(lock_passwd));
609 		xfree(lock_passwd);
610 		lock_passwd = NULL;
611 		success = 1;
612 	} else if (!locked && lock) {
613 		locked = 1;
614 		lock_passwd = xstrdup(passwd);
615 		success = 1;
616 	}
617 	memset(passwd, 0, strlen(passwd));
618 	xfree(passwd);
619 
620 	buffer_put_int(&e->output, 1);
621 	buffer_put_char(&e->output,
622 	    success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
623 }
624 
625 static void
626 no_identities(SocketEntry *e, u_int type)
627 {
628 	Buffer msg;
629 
630 	buffer_init(&msg);
631 	buffer_put_char(&msg,
632 	    (type == SSH_AGENTC_REQUEST_RSA_IDENTITIES) ?
633 	    SSH_AGENT_RSA_IDENTITIES_ANSWER : SSH2_AGENT_IDENTITIES_ANSWER);
634 	buffer_put_int(&msg, 0);
635 	buffer_put_int(&e->output, buffer_len(&msg));
636 	buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg));
637 	buffer_free(&msg);
638 }
639 
640 #ifdef ENABLE_PKCS11
641 static void
642 process_add_smartcard_key(SocketEntry *e)
643 {
644 	char *provider = NULL, *pin;
645 	int i, type, version, count = 0, success = 0, death = 0, confirm = 0;
646 	Key **keys = NULL, *k;
647 	Identity *id;
648 	Idtab *tab;
649 
650 	provider = buffer_get_string(&e->request, NULL);
651 	pin = buffer_get_string(&e->request, NULL);
652 
653 	while (buffer_len(&e->request)) {
654 		switch ((type = buffer_get_char(&e->request))) {
655 		case SSH_AGENT_CONSTRAIN_LIFETIME:
656 			death = time(NULL) + buffer_get_int(&e->request);
657 			break;
658 		case SSH_AGENT_CONSTRAIN_CONFIRM:
659 			confirm = 1;
660 			break;
661 		default:
662 			error("process_add_smartcard_key: "
663 			    "Unknown constraint type %d", type);
664 			goto send;
665 		}
666 	}
667 	if (lifetime && !death)
668 		death = time(NULL) + lifetime;
669 
670 	count = pkcs11_add_provider(provider, pin, &keys);
671 	for (i = 0; i < count; i++) {
672 		k = keys[i];
673 		version = k->type == KEY_RSA1 ? 1 : 2;
674 		tab = idtab_lookup(version);
675 		if (lookup_identity(k, version) == NULL) {
676 			id = xcalloc(1, sizeof(Identity));
677 			id->key = k;
678 			id->provider = xstrdup(provider);
679 			id->comment = xstrdup(provider); /* XXX */
680 			id->death = death;
681 			id->confirm = confirm;
682 			TAILQ_INSERT_TAIL(&tab->idlist, id, next);
683 			tab->nentries++;
684 			success = 1;
685 		} else {
686 			key_free(k);
687 		}
688 		keys[i] = NULL;
689 	}
690 send:
691 	if (pin)
692 		xfree(pin);
693 	if (provider)
694 		xfree(provider);
695 	if (keys)
696 		xfree(keys);
697 	buffer_put_int(&e->output, 1);
698 	buffer_put_char(&e->output,
699 	    success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
700 }
701 
702 static void
703 process_remove_smartcard_key(SocketEntry *e)
704 {
705 	char *provider = NULL, *pin = NULL;
706 	int version, success = 0;
707 	Identity *id, *nxt;
708 	Idtab *tab;
709 
710 	provider = buffer_get_string(&e->request, NULL);
711 	pin = buffer_get_string(&e->request, NULL);
712 	xfree(pin);
713 
714 	for (version = 1; version < 3; version++) {
715 		tab = idtab_lookup(version);
716 		for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) {
717 			nxt = TAILQ_NEXT(id, next);
718 			if (!strcmp(provider, id->provider)) {
719 				TAILQ_REMOVE(&tab->idlist, id, next);
720 				free_identity(id);
721 				tab->nentries--;
722 			}
723 		}
724 	}
725 	if (pkcs11_del_provider(provider) == 0)
726 		success = 1;
727 	else
728 		error("process_remove_smartcard_key:"
729 		    " pkcs11_del_provider failed");
730 	xfree(provider);
731 	buffer_put_int(&e->output, 1);
732 	buffer_put_char(&e->output,
733 	    success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
734 }
735 #endif /* ENABLE_PKCS11 */
736 
737 /* dispatch incoming messages */
738 
739 static void
740 process_message(SocketEntry *e)
741 {
742 	u_int msg_len, type;
743 	u_char *cp;
744 
745 	if (buffer_len(&e->input) < 5)
746 		return;		/* Incomplete message. */
747 	cp = buffer_ptr(&e->input);
748 	msg_len = get_u32(cp);
749 	if (msg_len > 256 * 1024) {
750 		close_socket(e);
751 		return;
752 	}
753 	if (buffer_len(&e->input) < msg_len + 4)
754 		return;
755 
756 	/* move the current input to e->request */
757 	buffer_consume(&e->input, 4);
758 	buffer_clear(&e->request);
759 	buffer_append(&e->request, buffer_ptr(&e->input), msg_len);
760 	buffer_consume(&e->input, msg_len);
761 	type = buffer_get_char(&e->request);
762 
763 	/* check wheter agent is locked */
764 	if (locked && type != SSH_AGENTC_UNLOCK) {
765 		buffer_clear(&e->request);
766 		switch (type) {
767 		case SSH_AGENTC_REQUEST_RSA_IDENTITIES:
768 		case SSH2_AGENTC_REQUEST_IDENTITIES:
769 			/* send empty lists */
770 			no_identities(e, type);
771 			break;
772 		default:
773 			/* send a fail message for all other request types */
774 			buffer_put_int(&e->output, 1);
775 			buffer_put_char(&e->output, SSH_AGENT_FAILURE);
776 		}
777 		return;
778 	}
779 
780 	debug("type %d", type);
781 	switch (type) {
782 	case SSH_AGENTC_LOCK:
783 	case SSH_AGENTC_UNLOCK:
784 		process_lock_agent(e, type == SSH_AGENTC_LOCK);
785 		break;
786 	/* ssh1 */
787 	case SSH_AGENTC_RSA_CHALLENGE:
788 		process_authentication_challenge1(e);
789 		break;
790 	case SSH_AGENTC_REQUEST_RSA_IDENTITIES:
791 		process_request_identities(e, 1);
792 		break;
793 	case SSH_AGENTC_ADD_RSA_IDENTITY:
794 	case SSH_AGENTC_ADD_RSA_ID_CONSTRAINED:
795 		process_add_identity(e, 1);
796 		break;
797 	case SSH_AGENTC_REMOVE_RSA_IDENTITY:
798 		process_remove_identity(e, 1);
799 		break;
800 	case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES:
801 		process_remove_all_identities(e, 1);
802 		break;
803 	/* ssh2 */
804 	case SSH2_AGENTC_SIGN_REQUEST:
805 		process_sign_request2(e);
806 		break;
807 	case SSH2_AGENTC_REQUEST_IDENTITIES:
808 		process_request_identities(e, 2);
809 		break;
810 	case SSH2_AGENTC_ADD_IDENTITY:
811 	case SSH2_AGENTC_ADD_ID_CONSTRAINED:
812 		process_add_identity(e, 2);
813 		break;
814 	case SSH2_AGENTC_REMOVE_IDENTITY:
815 		process_remove_identity(e, 2);
816 		break;
817 	case SSH2_AGENTC_REMOVE_ALL_IDENTITIES:
818 		process_remove_all_identities(e, 2);
819 		break;
820 #ifdef ENABLE_PKCS11
821 	case SSH_AGENTC_ADD_SMARTCARD_KEY:
822 	case SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED:
823 		process_add_smartcard_key(e);
824 		break;
825 	case SSH_AGENTC_REMOVE_SMARTCARD_KEY:
826 		process_remove_smartcard_key(e);
827 		break;
828 #endif /* ENABLE_PKCS11 */
829 	default:
830 		/* Unknown message.  Respond with failure. */
831 		error("Unknown message %d", type);
832 		buffer_clear(&e->request);
833 		buffer_put_int(&e->output, 1);
834 		buffer_put_char(&e->output, SSH_AGENT_FAILURE);
835 		break;
836 	}
837 }
838 
839 static void
840 new_socket(sock_type type, int fd)
841 {
842 	u_int i, old_alloc, new_alloc;
843 
844 	set_nonblock(fd);
845 
846 	if (fd > max_fd)
847 		max_fd = fd;
848 
849 	for (i = 0; i < sockets_alloc; i++)
850 		if (sockets[i].type == AUTH_UNUSED) {
851 			sockets[i].fd = fd;
852 			buffer_init(&sockets[i].input);
853 			buffer_init(&sockets[i].output);
854 			buffer_init(&sockets[i].request);
855 			sockets[i].type = type;
856 			return;
857 		}
858 	old_alloc = sockets_alloc;
859 	new_alloc = sockets_alloc + 10;
860 	sockets = xrealloc(sockets, new_alloc, sizeof(sockets[0]));
861 	for (i = old_alloc; i < new_alloc; i++)
862 		sockets[i].type = AUTH_UNUSED;
863 	sockets_alloc = new_alloc;
864 	sockets[old_alloc].fd = fd;
865 	buffer_init(&sockets[old_alloc].input);
866 	buffer_init(&sockets[old_alloc].output);
867 	buffer_init(&sockets[old_alloc].request);
868 	sockets[old_alloc].type = type;
869 }
870 
871 static int
872 prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, u_int *nallocp,
873     struct timeval **tvpp)
874 {
875 	u_int i, sz, deadline;
876 	int n = 0;
877 	static struct timeval tv;
878 
879 	for (i = 0; i < sockets_alloc; i++) {
880 		switch (sockets[i].type) {
881 		case AUTH_SOCKET:
882 		case AUTH_CONNECTION:
883 			n = MAX(n, sockets[i].fd);
884 			break;
885 		case AUTH_UNUSED:
886 			break;
887 		default:
888 			fatal("Unknown socket type %d", sockets[i].type);
889 			break;
890 		}
891 	}
892 
893 	sz = howmany(n+1, NFDBITS) * sizeof(fd_mask);
894 	if (*fdrp == NULL || sz > *nallocp) {
895 		if (*fdrp)
896 			xfree(*fdrp);
897 		if (*fdwp)
898 			xfree(*fdwp);
899 		*fdrp = xmalloc(sz);
900 		*fdwp = xmalloc(sz);
901 		*nallocp = sz;
902 	}
903 	if (n < *fdl)
904 		debug("XXX shrink: %d < %d", n, *fdl);
905 	*fdl = n;
906 	memset(*fdrp, 0, sz);
907 	memset(*fdwp, 0, sz);
908 
909 	for (i = 0; i < sockets_alloc; i++) {
910 		switch (sockets[i].type) {
911 		case AUTH_SOCKET:
912 		case AUTH_CONNECTION:
913 			FD_SET(sockets[i].fd, *fdrp);
914 			if (buffer_len(&sockets[i].output) > 0)
915 				FD_SET(sockets[i].fd, *fdwp);
916 			break;
917 		default:
918 			break;
919 		}
920 	}
921 	deadline = reaper();
922 	if (parent_alive_interval != 0)
923 		deadline = (deadline == 0) ? parent_alive_interval :
924 		    MIN(deadline, parent_alive_interval);
925 	if (deadline == 0) {
926 		*tvpp = NULL;
927 	} else {
928 		tv.tv_sec = deadline;
929 		tv.tv_usec = 0;
930 		*tvpp = &tv;
931 	}
932 	return (1);
933 }
934 
935 static void
936 after_select(fd_set *readset, fd_set *writeset)
937 {
938 	struct sockaddr_un sunaddr;
939 	socklen_t slen;
940 	char buf[1024];
941 	int len, sock;
942 	u_int i, orig_alloc;
943 	uid_t euid;
944 	gid_t egid;
945 
946 	for (i = 0, orig_alloc = sockets_alloc; i < orig_alloc; i++)
947 		switch (sockets[i].type) {
948 		case AUTH_UNUSED:
949 			break;
950 		case AUTH_SOCKET:
951 			if (FD_ISSET(sockets[i].fd, readset)) {
952 				slen = sizeof(sunaddr);
953 				sock = accept(sockets[i].fd,
954 				    (struct sockaddr *)&sunaddr, &slen);
955 				if (sock < 0) {
956 					error("accept from AUTH_SOCKET: %s",
957 					    strerror(errno));
958 					break;
959 				}
960 				if (getpeereid(sock, &euid, &egid) < 0) {
961 					error("getpeereid %d failed: %s",
962 					    sock, strerror(errno));
963 					close(sock);
964 					break;
965 				}
966 				if ((euid != 0) && (getuid() != euid)) {
967 					error("uid mismatch: "
968 					    "peer euid %u != uid %u",
969 					    (u_int) euid, (u_int) getuid());
970 					close(sock);
971 					break;
972 				}
973 				new_socket(AUTH_CONNECTION, sock);
974 			}
975 			break;
976 		case AUTH_CONNECTION:
977 			if (buffer_len(&sockets[i].output) > 0 &&
978 			    FD_ISSET(sockets[i].fd, writeset)) {
979 				len = write(sockets[i].fd,
980 				    buffer_ptr(&sockets[i].output),
981 				    buffer_len(&sockets[i].output));
982 				if (len == -1 && (errno == EAGAIN ||
983 				    errno == EWOULDBLOCK ||
984 				    errno == EINTR))
985 					continue;
986 				if (len <= 0) {
987 					close_socket(&sockets[i]);
988 					break;
989 				}
990 				buffer_consume(&sockets[i].output, len);
991 			}
992 			if (FD_ISSET(sockets[i].fd, readset)) {
993 				len = read(sockets[i].fd, buf, sizeof(buf));
994 				if (len == -1 && (errno == EAGAIN ||
995 				    errno == EWOULDBLOCK ||
996 				    errno == EINTR))
997 					continue;
998 				if (len <= 0) {
999 					close_socket(&sockets[i]);
1000 					break;
1001 				}
1002 				buffer_append(&sockets[i].input, buf, len);
1003 				process_message(&sockets[i]);
1004 			}
1005 			break;
1006 		default:
1007 			fatal("Unknown type %d", sockets[i].type);
1008 		}
1009 }
1010 
1011 static void
1012 cleanup_socket(void)
1013 {
1014 	if (socket_name[0])
1015 		unlink(socket_name);
1016 	if (socket_dir[0])
1017 		rmdir(socket_dir);
1018 }
1019 
1020 void
1021 cleanup_exit(int i)
1022 {
1023 	cleanup_socket();
1024 	_exit(i);
1025 }
1026 
1027 /*ARGSUSED*/
1028 static void
1029 cleanup_handler(int sig)
1030 {
1031 	cleanup_socket();
1032 #ifdef ENABLE_PKCS11
1033 	pkcs11_terminate();
1034 #endif
1035 	_exit(2);
1036 }
1037 
1038 static void
1039 check_parent_exists(void)
1040 {
1041 	if (parent_pid != -1 && kill(parent_pid, 0) < 0) {
1042 		/* printf("Parent has died - Authentication agent exiting.\n"); */
1043 		cleanup_socket();
1044 		_exit(2);
1045 	}
1046 }
1047 
1048 static void
1049 usage(void)
1050 {
1051 	fprintf(stderr, "usage: %s [options] [command [arg ...]]\n",
1052 	    __progname);
1053 	fprintf(stderr, "Options:\n");
1054 	fprintf(stderr, "  -c          Generate C-shell commands on stdout.\n");
1055 	fprintf(stderr, "  -s          Generate Bourne shell commands on stdout.\n");
1056 	fprintf(stderr, "  -k          Kill the current agent.\n");
1057 	fprintf(stderr, "  -d          Debug mode.\n");
1058 	fprintf(stderr, "  -a socket   Bind agent socket to given name.\n");
1059 	fprintf(stderr, "  -t life     Default identity lifetime (seconds).\n");
1060 	exit(1);
1061 }
1062 
1063 int
1064 main(int ac, char **av)
1065 {
1066 	int c_flag = 0, d_flag = 0, k_flag = 0, s_flag = 0;
1067 	int sock, fd, ch, result, saved_errno;
1068 	u_int nalloc;
1069 	char *shell, *format, *pidstr, *agentsocket = NULL;
1070 	fd_set *readsetp = NULL, *writesetp = NULL;
1071 	struct sockaddr_un sunaddr;
1072 #ifdef HAVE_SETRLIMIT
1073 	struct rlimit rlim;
1074 #endif
1075 	int prev_mask;
1076 	extern int optind;
1077 	extern char *optarg;
1078 	pid_t pid;
1079 	char pidstrbuf[1 + 3 * sizeof pid];
1080 	struct timeval *tvp = NULL;
1081 	size_t len;
1082 
1083 	/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
1084 	sanitise_stdfd();
1085 
1086 	/* drop */
1087 	setegid(getgid());
1088 	setgid(getgid());
1089 	setuid(geteuid());
1090 
1091 #if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE)
1092 	/* Disable ptrace on Linux without sgid bit */
1093 	prctl(PR_SET_DUMPABLE, 0);
1094 #endif
1095 
1096 	SSLeay_add_all_algorithms();
1097 
1098 	__progname = ssh_get_progname(av[0]);
1099 	init_rng();
1100 	seed_rng();
1101 
1102 	while ((ch = getopt(ac, av, "cdksa:t:")) != -1) {
1103 		switch (ch) {
1104 		case 'c':
1105 			if (s_flag)
1106 				usage();
1107 			c_flag++;
1108 			break;
1109 		case 'k':
1110 			k_flag++;
1111 			break;
1112 		case 's':
1113 			if (c_flag)
1114 				usage();
1115 			s_flag++;
1116 			break;
1117 		case 'd':
1118 			if (d_flag)
1119 				usage();
1120 			d_flag++;
1121 			break;
1122 		case 'a':
1123 			agentsocket = optarg;
1124 			break;
1125 		case 't':
1126 			if ((lifetime = convtime(optarg)) == -1) {
1127 				fprintf(stderr, "Invalid lifetime\n");
1128 				usage();
1129 			}
1130 			break;
1131 		default:
1132 			usage();
1133 		}
1134 	}
1135 	ac -= optind;
1136 	av += optind;
1137 
1138 	if (ac > 0 && (c_flag || k_flag || s_flag || d_flag))
1139 		usage();
1140 
1141 	if (ac == 0 && !c_flag && !s_flag) {
1142 		shell = getenv("SHELL");
1143 		if (shell != NULL && (len = strlen(shell)) > 2 &&
1144 		    strncmp(shell + len - 3, "csh", 3) == 0)
1145 			c_flag = 1;
1146 	}
1147 	if (k_flag) {
1148 		const char *errstr = NULL;
1149 
1150 		pidstr = getenv(SSH_AGENTPID_ENV_NAME);
1151 		if (pidstr == NULL) {
1152 			fprintf(stderr, "%s not set, cannot kill agent\n",
1153 			    SSH_AGENTPID_ENV_NAME);
1154 			exit(1);
1155 		}
1156 		pid = (int)strtonum(pidstr, 2, INT_MAX, &errstr);
1157 		if (errstr) {
1158 			fprintf(stderr,
1159 			    "%s=\"%s\", which is not a good PID: %s\n",
1160 			    SSH_AGENTPID_ENV_NAME, pidstr, errstr);
1161 			exit(1);
1162 		}
1163 		if (kill(pid, SIGTERM) == -1) {
1164 			perror("kill");
1165 			exit(1);
1166 		}
1167 		format = c_flag ? "unsetenv %s;\n" : "unset %s;\n";
1168 		printf(format, SSH_AUTHSOCKET_ENV_NAME);
1169 		printf(format, SSH_AGENTPID_ENV_NAME);
1170 		printf("echo Agent pid %ld killed;\n", (long)pid);
1171 		exit(0);
1172 	}
1173 	parent_pid = getpid();
1174 
1175 	if (agentsocket == NULL) {
1176 		/* Create private directory for agent socket */
1177 		strlcpy(socket_dir, "/tmp/ssh-XXXXXXXXXX", sizeof socket_dir);
1178 		if (mkdtemp(socket_dir) == NULL) {
1179 			perror("mkdtemp: private socket dir");
1180 			exit(1);
1181 		}
1182 		snprintf(socket_name, sizeof socket_name, "%s/agent.%ld", socket_dir,
1183 		    (long)parent_pid);
1184 	} else {
1185 		/* Try to use specified agent socket */
1186 		socket_dir[0] = '\0';
1187 		strlcpy(socket_name, agentsocket, sizeof socket_name);
1188 	}
1189 
1190 	/*
1191 	 * Create socket early so it will exist before command gets run from
1192 	 * the parent.
1193 	 */
1194 	sock = socket(AF_UNIX, SOCK_STREAM, 0);
1195 	if (sock < 0) {
1196 		perror("socket");
1197 		*socket_name = '\0'; /* Don't unlink any existing file */
1198 		cleanup_exit(1);
1199 	}
1200 	memset(&sunaddr, 0, sizeof(sunaddr));
1201 	sunaddr.sun_family = AF_UNIX;
1202 	strlcpy(sunaddr.sun_path, socket_name, sizeof(sunaddr.sun_path));
1203 	prev_mask = umask(0177);
1204 	if (bind(sock, (struct sockaddr *) &sunaddr, sizeof(sunaddr)) < 0) {
1205 		perror("bind");
1206 		*socket_name = '\0'; /* Don't unlink any existing file */
1207 		umask(prev_mask);
1208 		cleanup_exit(1);
1209 	}
1210 	umask(prev_mask);
1211 	if (listen(sock, SSH_LISTEN_BACKLOG) < 0) {
1212 		perror("listen");
1213 		cleanup_exit(1);
1214 	}
1215 
1216 	/*
1217 	 * Fork, and have the parent execute the command, if any, or present
1218 	 * the socket data.  The child continues as the authentication agent.
1219 	 */
1220 	if (d_flag) {
1221 		log_init(__progname, SYSLOG_LEVEL_DEBUG1, SYSLOG_FACILITY_AUTH, 1);
1222 		format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n";
1223 		printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name,
1224 		    SSH_AUTHSOCKET_ENV_NAME);
1225 		printf("echo Agent pid %ld;\n", (long)parent_pid);
1226 		goto skip;
1227 	}
1228 	pid = fork();
1229 	if (pid == -1) {
1230 		perror("fork");
1231 		cleanup_exit(1);
1232 	}
1233 	if (pid != 0) {		/* Parent - execute the given command. */
1234 		close(sock);
1235 		snprintf(pidstrbuf, sizeof pidstrbuf, "%ld", (long)pid);
1236 		if (ac == 0) {
1237 			format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n";
1238 			printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name,
1239 			    SSH_AUTHSOCKET_ENV_NAME);
1240 			printf(format, SSH_AGENTPID_ENV_NAME, pidstrbuf,
1241 			    SSH_AGENTPID_ENV_NAME);
1242 			printf("echo Agent pid %ld;\n", (long)pid);
1243 			exit(0);
1244 		}
1245 		if (setenv(SSH_AUTHSOCKET_ENV_NAME, socket_name, 1) == -1 ||
1246 		    setenv(SSH_AGENTPID_ENV_NAME, pidstrbuf, 1) == -1) {
1247 			perror("setenv");
1248 			exit(1);
1249 		}
1250 		execvp(av[0], av);
1251 		perror(av[0]);
1252 		exit(1);
1253 	}
1254 	/* child */
1255 	log_init(__progname, SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_AUTH, 0);
1256 
1257 	if (setsid() == -1) {
1258 		error("setsid: %s", strerror(errno));
1259 		cleanup_exit(1);
1260 	}
1261 
1262 	(void)chdir("/");
1263 	if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
1264 		/* XXX might close listen socket */
1265 		(void)dup2(fd, STDIN_FILENO);
1266 		(void)dup2(fd, STDOUT_FILENO);
1267 		(void)dup2(fd, STDERR_FILENO);
1268 		if (fd > 2)
1269 			close(fd);
1270 	}
1271 
1272 #ifdef HAVE_SETRLIMIT
1273 	/* deny core dumps, since memory contains unencrypted private keys */
1274 	rlim.rlim_cur = rlim.rlim_max = 0;
1275 	if (setrlimit(RLIMIT_CORE, &rlim) < 0) {
1276 		error("setrlimit RLIMIT_CORE: %s", strerror(errno));
1277 		cleanup_exit(1);
1278 	}
1279 #endif
1280 
1281 skip:
1282 
1283 #ifdef ENABLE_PKCS11
1284 	pkcs11_init(0);
1285 #endif
1286 	new_socket(AUTH_SOCKET, sock);
1287 	if (ac > 0)
1288 		parent_alive_interval = 10;
1289 	idtab_init();
1290 	if (!d_flag)
1291 		signal(SIGINT, SIG_IGN);
1292 	signal(SIGPIPE, SIG_IGN);
1293 	signal(SIGHUP, cleanup_handler);
1294 	signal(SIGTERM, cleanup_handler);
1295 	nalloc = 0;
1296 
1297 	while (1) {
1298 		prepare_select(&readsetp, &writesetp, &max_fd, &nalloc, &tvp);
1299 		result = select(max_fd + 1, readsetp, writesetp, NULL, tvp);
1300 		saved_errno = errno;
1301 		if (parent_alive_interval != 0)
1302 			check_parent_exists();
1303 		(void) reaper();	/* remove expired keys */
1304 		if (result < 0) {
1305 			if (saved_errno == EINTR)
1306 				continue;
1307 			fatal("select: %s", strerror(saved_errno));
1308 		} else if (result > 0)
1309 			after_select(readsetp, writesetp);
1310 	}
1311 	/* NOTREACHED */
1312 }
1313