xref: /freebsd/crypto/openssh/ssh-agent.c (revision 09e8dea79366f1e5b3a73e8a271b26e4b6bf2e6a)
1 /*
2  * Author: Tatu Ylonen <ylo@cs.hut.fi>
3  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4  *                    All rights reserved
5  * The authentication agent program.
6  *
7  * As far as I am concerned, the code I have written for this software
8  * can be used freely for any purpose.  Any derived versions of this
9  * software must be clearly marked as such, and if the derived work is
10  * incompatible with the protocol description in the RFC file, it must be
11  * called by a name other than "ssh" or "Secure Shell".
12  *
13  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
14  *
15  * Redistribution and use in source and binary forms, with or without
16  * modification, are permitted provided that the following conditions
17  * are met:
18  * 1. Redistributions of source code must retain the above copyright
19  *    notice, this list of conditions and the following disclaimer.
20  * 2. Redistributions in binary form must reproduce the above copyright
21  *    notice, this list of conditions and the following disclaimer in the
22  *    documentation and/or other materials provided with the distribution.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 #include "includes.h"
37 #include <sys/queue.h>
38 RCSID("$OpenBSD: ssh-agent.c,v 1.95 2002/06/19 00:27:55 deraadt Exp $");
39 RCSID("$FreeBSD$");
40 
41 #include <openssl/evp.h>
42 #include <openssl/md5.h>
43 
44 #include "ssh.h"
45 #include "rsa.h"
46 #include "buffer.h"
47 #include "bufaux.h"
48 #include "xmalloc.h"
49 #include "getput.h"
50 #include "key.h"
51 #include "authfd.h"
52 #include "compat.h"
53 #include "log.h"
54 
55 #ifdef SMARTCARD
56 #include "scard.h"
57 #endif
58 
59 typedef enum {
60 	AUTH_UNUSED,
61 	AUTH_SOCKET,
62 	AUTH_CONNECTION
63 } sock_type;
64 
65 typedef struct {
66 	int fd;
67 	sock_type type;
68 	Buffer input;
69 	Buffer output;
70 	Buffer request;
71 } SocketEntry;
72 
73 u_int sockets_alloc = 0;
74 SocketEntry *sockets = NULL;
75 
76 typedef struct identity {
77 	TAILQ_ENTRY(identity) next;
78 	Key *key;
79 	char *comment;
80 	u_int death;
81 } Identity;
82 
83 typedef struct {
84 	int nentries;
85 	TAILQ_HEAD(idqueue, identity) idlist;
86 } Idtab;
87 
88 /* private key table, one per protocol version */
89 Idtab idtable[3];
90 
91 int max_fd = 0;
92 
93 /* pid of shell == parent of agent */
94 pid_t parent_pid = -1;
95 
96 /* pathname and directory for AUTH_SOCKET */
97 char socket_name[1024];
98 char socket_dir[1024];
99 
100 /* locking */
101 int locked = 0;
102 char *lock_passwd = NULL;
103 
104 extern char *__progname;
105 
106 static void
107 idtab_init(void)
108 {
109 	int i;
110 	for (i = 0; i <=2; i++) {
111 		TAILQ_INIT(&idtable[i].idlist);
112 		idtable[i].nentries = 0;
113 	}
114 }
115 
116 /* return private key table for requested protocol version */
117 static Idtab *
118 idtab_lookup(int version)
119 {
120 	if (version < 1 || version > 2)
121 		fatal("internal error, bad protocol version %d", version);
122 	return &idtable[version];
123 }
124 
125 static void
126 free_identity(Identity *id)
127 {
128 	key_free(id->key);
129 	xfree(id->comment);
130 	xfree(id);
131 }
132 
133 /* return matching private key for given public key */
134 static Identity *
135 lookup_identity(Key *key, int version)
136 {
137 	Identity *id;
138 
139 	Idtab *tab = idtab_lookup(version);
140 	TAILQ_FOREACH(id, &tab->idlist, next) {
141 		if (key_equal(key, id->key))
142 			return (id);
143 	}
144 	return (NULL);
145 }
146 
147 /* send list of supported public keys to 'client' */
148 static void
149 process_request_identities(SocketEntry *e, int version)
150 {
151 	Idtab *tab = idtab_lookup(version);
152 	Buffer msg;
153 	Identity *id;
154 
155 	buffer_init(&msg);
156 	buffer_put_char(&msg, (version == 1) ?
157 	    SSH_AGENT_RSA_IDENTITIES_ANSWER : SSH2_AGENT_IDENTITIES_ANSWER);
158 	buffer_put_int(&msg, tab->nentries);
159 	TAILQ_FOREACH(id, &tab->idlist, next) {
160 		if (id->key->type == KEY_RSA1) {
161 			buffer_put_int(&msg, BN_num_bits(id->key->rsa->n));
162 			buffer_put_bignum(&msg, id->key->rsa->e);
163 			buffer_put_bignum(&msg, id->key->rsa->n);
164 		} else {
165 			u_char *blob;
166 			u_int blen;
167 			key_to_blob(id->key, &blob, &blen);
168 			buffer_put_string(&msg, blob, blen);
169 			xfree(blob);
170 		}
171 		buffer_put_cstring(&msg, id->comment);
172 	}
173 	buffer_put_int(&e->output, buffer_len(&msg));
174 	buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg));
175 	buffer_free(&msg);
176 }
177 
178 /* ssh1 only */
179 static void
180 process_authentication_challenge1(SocketEntry *e)
181 {
182 	Identity *id;
183 	Key *key;
184 	BIGNUM *challenge;
185 	int i, len;
186 	Buffer msg;
187 	MD5_CTX md;
188 	u_char buf[32], mdbuf[16], session_id[16];
189 	u_int response_type;
190 
191 	buffer_init(&msg);
192 	key = key_new(KEY_RSA1);
193 	if ((challenge = BN_new()) == NULL)
194 		fatal("process_authentication_challenge1: BN_new failed");
195 
196 	buffer_get_int(&e->request);				/* ignored */
197 	buffer_get_bignum(&e->request, key->rsa->e);
198 	buffer_get_bignum(&e->request, key->rsa->n);
199 	buffer_get_bignum(&e->request, challenge);
200 
201 	/* Only protocol 1.1 is supported */
202 	if (buffer_len(&e->request) == 0)
203 		goto failure;
204 	buffer_get(&e->request, session_id, 16);
205 	response_type = buffer_get_int(&e->request);
206 	if (response_type != 1)
207 		goto failure;
208 
209 	id = lookup_identity(key, 1);
210 	if (id != NULL) {
211 		Key *private = id->key;
212 		/* Decrypt the challenge using the private key. */
213 		if (rsa_private_decrypt(challenge, challenge, private->rsa) <= 0)
214 			goto failure;
215 
216 		/* The response is MD5 of decrypted challenge plus session id. */
217 		len = BN_num_bytes(challenge);
218 		if (len <= 0 || len > 32) {
219 			log("process_authentication_challenge: bad challenge length %d", len);
220 			goto failure;
221 		}
222 		memset(buf, 0, 32);
223 		BN_bn2bin(challenge, buf + 32 - len);
224 		MD5_Init(&md);
225 		MD5_Update(&md, buf, 32);
226 		MD5_Update(&md, session_id, 16);
227 		MD5_Final(mdbuf, &md);
228 
229 		/* Send the response. */
230 		buffer_put_char(&msg, SSH_AGENT_RSA_RESPONSE);
231 		for (i = 0; i < 16; i++)
232 			buffer_put_char(&msg, mdbuf[i]);
233 		goto send;
234 	}
235 
236 failure:
237 	/* Unknown identity or protocol error.  Send failure. */
238 	buffer_put_char(&msg, SSH_AGENT_FAILURE);
239 send:
240 	buffer_put_int(&e->output, buffer_len(&msg));
241 	buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg));
242 	key_free(key);
243 	BN_clear_free(challenge);
244 	buffer_free(&msg);
245 }
246 
247 /* ssh2 only */
248 static void
249 process_sign_request2(SocketEntry *e)
250 {
251 	extern int datafellows;
252 	Key *key;
253 	u_char *blob, *data, *signature = NULL;
254 	u_int blen, dlen, slen = 0;
255 	int flags;
256 	Buffer msg;
257 	int ok = -1;
258 
259 	datafellows = 0;
260 
261 	blob = buffer_get_string(&e->request, &blen);
262 	data = buffer_get_string(&e->request, &dlen);
263 
264 	flags = buffer_get_int(&e->request);
265 	if (flags & SSH_AGENT_OLD_SIGNATURE)
266 		datafellows = SSH_BUG_SIGBLOB;
267 
268 	key = key_from_blob(blob, blen);
269 	if (key != NULL) {
270 		Identity *id = lookup_identity(key, 2);
271 		if (id != NULL)
272 			ok = key_sign(id->key, &signature, &slen, data, dlen);
273 	}
274 	key_free(key);
275 	buffer_init(&msg);
276 	if (ok == 0) {
277 		buffer_put_char(&msg, SSH2_AGENT_SIGN_RESPONSE);
278 		buffer_put_string(&msg, signature, slen);
279 	} else {
280 		buffer_put_char(&msg, SSH_AGENT_FAILURE);
281 	}
282 	buffer_put_int(&e->output, buffer_len(&msg));
283 	buffer_append(&e->output, buffer_ptr(&msg),
284 	    buffer_len(&msg));
285 	buffer_free(&msg);
286 	xfree(data);
287 	xfree(blob);
288 	if (signature != NULL)
289 		xfree(signature);
290 }
291 
292 /* shared */
293 static void
294 process_remove_identity(SocketEntry *e, int version)
295 {
296 	Key *key = NULL;
297 	u_char *blob;
298 	u_int blen;
299 	u_int bits;
300 	int success = 0;
301 
302 	switch (version) {
303 	case 1:
304 		key = key_new(KEY_RSA1);
305 		bits = buffer_get_int(&e->request);
306 		buffer_get_bignum(&e->request, key->rsa->e);
307 		buffer_get_bignum(&e->request, key->rsa->n);
308 
309 		if (bits != key_size(key))
310 			log("Warning: identity keysize mismatch: actual %d, announced %d",
311 			    key_size(key), bits);
312 		break;
313 	case 2:
314 		blob = buffer_get_string(&e->request, &blen);
315 		key = key_from_blob(blob, blen);
316 		xfree(blob);
317 		break;
318 	}
319 	if (key != NULL) {
320 		Identity *id = lookup_identity(key, version);
321 		if (id != NULL) {
322 			/*
323 			 * We have this key.  Free the old key.  Since we
324 			 * don\'t want to leave empty slots in the middle of
325 			 * the array, we actually free the key there and move
326 			 * all the entries between the empty slot and the end
327 			 * of the array.
328 			 */
329 			Idtab *tab = idtab_lookup(version);
330 			if (tab->nentries < 1)
331 				fatal("process_remove_identity: "
332 				    "internal error: tab->nentries %d",
333 				    tab->nentries);
334 			TAILQ_REMOVE(&tab->idlist, id, next);
335 			free_identity(id);
336 			tab->nentries--;
337 			success = 1;
338 		}
339 		key_free(key);
340 	}
341 	buffer_put_int(&e->output, 1);
342 	buffer_put_char(&e->output,
343 	    success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
344 }
345 
346 static void
347 process_remove_all_identities(SocketEntry *e, int version)
348 {
349 	Idtab *tab = idtab_lookup(version);
350 	Identity *id;
351 
352 	/* Loop over all identities and clear the keys. */
353 	for (id = TAILQ_FIRST(&tab->idlist); id;
354 	    id = TAILQ_FIRST(&tab->idlist)) {
355 		TAILQ_REMOVE(&tab->idlist, id, next);
356 		free_identity(id);
357 	}
358 
359 	/* Mark that there are no identities. */
360 	tab->nentries = 0;
361 
362 	/* Send success. */
363 	buffer_put_int(&e->output, 1);
364 	buffer_put_char(&e->output, SSH_AGENT_SUCCESS);
365 }
366 
367 static void
368 reaper(void)
369 {
370 	Idtab *tab;
371 	Identity *id, *nxt;
372 	int version;
373 	u_int now = time(NULL);
374 
375 	for (version = 1; version < 3; version++) {
376 		tab = idtab_lookup(version);
377 		for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) {
378 			nxt = TAILQ_NEXT(id, next);
379 			if (id->death != 0 && now >= id->death) {
380 				TAILQ_REMOVE(&tab->idlist, id, next);
381 				free_identity(id);
382 				tab->nentries--;
383 			}
384 		}
385 	}
386 }
387 
388 static void
389 process_add_identity(SocketEntry *e, int version)
390 {
391 	Key *k = NULL;
392 	char *type_name;
393 	char *comment;
394 	int type, success = 0, death = 0;
395 	Idtab *tab = idtab_lookup(version);
396 
397 	switch (version) {
398 	case 1:
399 		k = key_new_private(KEY_RSA1);
400 		buffer_get_int(&e->request);			/* ignored */
401 		buffer_get_bignum(&e->request, k->rsa->n);
402 		buffer_get_bignum(&e->request, k->rsa->e);
403 		buffer_get_bignum(&e->request, k->rsa->d);
404 		buffer_get_bignum(&e->request, k->rsa->iqmp);
405 
406 		/* SSH and SSL have p and q swapped */
407 		buffer_get_bignum(&e->request, k->rsa->q);	/* p */
408 		buffer_get_bignum(&e->request, k->rsa->p);	/* q */
409 
410 		/* Generate additional parameters */
411 		rsa_generate_additional_parameters(k->rsa);
412 		break;
413 	case 2:
414 		type_name = buffer_get_string(&e->request, NULL);
415 		type = key_type_from_name(type_name);
416 		xfree(type_name);
417 		switch (type) {
418 		case KEY_DSA:
419 			k = key_new_private(type);
420 			buffer_get_bignum2(&e->request, k->dsa->p);
421 			buffer_get_bignum2(&e->request, k->dsa->q);
422 			buffer_get_bignum2(&e->request, k->dsa->g);
423 			buffer_get_bignum2(&e->request, k->dsa->pub_key);
424 			buffer_get_bignum2(&e->request, k->dsa->priv_key);
425 			break;
426 		case KEY_RSA:
427 			k = key_new_private(type);
428 			buffer_get_bignum2(&e->request, k->rsa->n);
429 			buffer_get_bignum2(&e->request, k->rsa->e);
430 			buffer_get_bignum2(&e->request, k->rsa->d);
431 			buffer_get_bignum2(&e->request, k->rsa->iqmp);
432 			buffer_get_bignum2(&e->request, k->rsa->p);
433 			buffer_get_bignum2(&e->request, k->rsa->q);
434 
435 			/* Generate additional parameters */
436 			rsa_generate_additional_parameters(k->rsa);
437 			break;
438 		default:
439 			buffer_clear(&e->request);
440 			goto send;
441 		}
442 		break;
443 	}
444 	comment = buffer_get_string(&e->request, NULL);
445 	if (k == NULL) {
446 		xfree(comment);
447 		goto send;
448 	}
449 	success = 1;
450 	while (buffer_len(&e->request)) {
451 		switch (buffer_get_char(&e->request)) {
452 		case SSH_AGENT_CONSTRAIN_LIFETIME:
453 			death = time(NULL) + buffer_get_int(&e->request);
454 			break;
455 		default:
456 			break;
457 		}
458 	}
459 	if (lookup_identity(k, version) == NULL) {
460 		Identity *id = xmalloc(sizeof(Identity));
461 		id->key = k;
462 		id->comment = comment;
463 		id->death = death;
464 		TAILQ_INSERT_TAIL(&tab->idlist, id, next);
465 		/* Increment the number of identities. */
466 		tab->nentries++;
467 	} else {
468 		key_free(k);
469 		xfree(comment);
470 	}
471 send:
472 	buffer_put_int(&e->output, 1);
473 	buffer_put_char(&e->output,
474 	    success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
475 }
476 
477 /* XXX todo: encrypt sensitive data with passphrase */
478 static void
479 process_lock_agent(SocketEntry *e, int lock)
480 {
481 	char *passwd;
482 	int success = 0;
483 
484 	passwd = buffer_get_string(&e->request, NULL);
485 	if (locked && !lock && strcmp(passwd, lock_passwd) == 0) {
486 		locked = 0;
487 		memset(lock_passwd, 0, strlen(lock_passwd));
488 		xfree(lock_passwd);
489 		lock_passwd = NULL;
490 		success = 1;
491 	} else if (!locked && lock) {
492 		locked = 1;
493 		lock_passwd = xstrdup(passwd);
494 		success = 1;
495 	}
496 	memset(passwd, 0, strlen(passwd));
497 	xfree(passwd);
498 
499 	buffer_put_int(&e->output, 1);
500 	buffer_put_char(&e->output,
501 	    success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
502 }
503 
504 static void
505 no_identities(SocketEntry *e, u_int type)
506 {
507 	Buffer msg;
508 
509 	buffer_init(&msg);
510 	buffer_put_char(&msg,
511 	    (type == SSH_AGENTC_REQUEST_RSA_IDENTITIES) ?
512 	    SSH_AGENT_RSA_IDENTITIES_ANSWER : SSH2_AGENT_IDENTITIES_ANSWER);
513 	buffer_put_int(&msg, 0);
514 	buffer_put_int(&e->output, buffer_len(&msg));
515 	buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg));
516 	buffer_free(&msg);
517 }
518 
519 #ifdef SMARTCARD
520 static void
521 process_add_smartcard_key (SocketEntry *e)
522 {
523 	Identity *id;
524 	Idtab *tab;
525 	Key **keys, *k;
526 	char *sc_reader_id = NULL, *pin;
527 	int i, version, success = 0;
528 
529 	sc_reader_id = buffer_get_string(&e->request, NULL);
530 	pin = buffer_get_string(&e->request, NULL);
531 	keys = sc_get_keys(sc_reader_id, pin);
532 	xfree(sc_reader_id);
533 	xfree(pin);
534 
535 	if (keys == NULL || keys[0] == NULL) {
536 		error("sc_get_keys failed");
537 		goto send;
538 	}
539 	for (i = 0; keys[i] != NULL; i++) {
540 		k = keys[i];
541 		version = k->type == KEY_RSA1 ? 1 : 2;
542 		tab = idtab_lookup(version);
543 		if (lookup_identity(k, version) == NULL) {
544 			id = xmalloc(sizeof(Identity));
545 			id->key = k;
546 			id->comment = xstrdup("smartcard key");
547 			id->death = 0;
548 			TAILQ_INSERT_TAIL(&tab->idlist, id, next);
549 			tab->nentries++;
550 			success = 1;
551 		} else {
552 			key_free(k);
553 		}
554 		keys[i] = NULL;
555 	}
556 	xfree(keys);
557 send:
558 	buffer_put_int(&e->output, 1);
559 	buffer_put_char(&e->output,
560 	    success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
561 }
562 
563 static void
564 process_remove_smartcard_key(SocketEntry *e)
565 {
566 	Identity *id;
567 	Idtab *tab;
568 	Key **keys, *k = NULL;
569 	char *sc_reader_id = NULL, *pin;
570 	int i, version, success = 0;
571 
572 	sc_reader_id = buffer_get_string(&e->request, NULL);
573 	pin = buffer_get_string(&e->request, NULL);
574 	keys = sc_get_keys(sc_reader_id, pin);
575 	xfree(sc_reader_id);
576 	xfree(pin);
577 
578 	if (keys == NULL || keys[0] == NULL) {
579 		error("sc_get_keys failed");
580 		goto send;
581 	}
582 	for (i = 0; keys[i] != NULL; i++) {
583 		k = keys[i];
584 		version = k->type == KEY_RSA1 ? 1 : 2;
585 		if ((id = lookup_identity(k, version)) != NULL) {
586 			tab = idtab_lookup(version);
587 			TAILQ_REMOVE(&tab->idlist, id, next);
588 			tab->nentries--;
589 			free_identity(id);
590 			success = 1;
591 		}
592 		key_free(k);
593 		keys[i] = NULL;
594 	}
595 	xfree(keys);
596 send:
597 	buffer_put_int(&e->output, 1);
598 	buffer_put_char(&e->output,
599 	    success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
600 }
601 #endif /* SMARTCARD */
602 
603 /* dispatch incoming messages */
604 
605 static void
606 process_message(SocketEntry *e)
607 {
608 	u_int msg_len;
609 	u_int type;
610 	u_char *cp;
611 
612 	/* kill dead keys */
613 	reaper();
614 
615 	if (buffer_len(&e->input) < 5)
616 		return;		/* Incomplete message. */
617 	cp = buffer_ptr(&e->input);
618 	msg_len = GET_32BIT(cp);
619 	if (msg_len > 256 * 1024) {
620 		shutdown(e->fd, SHUT_RDWR);
621 		close(e->fd);
622 		e->type = AUTH_UNUSED;
623 		buffer_free(&e->input);
624 		buffer_free(&e->output);
625 		buffer_free(&e->request);
626 		return;
627 	}
628 	if (buffer_len(&e->input) < msg_len + 4)
629 		return;
630 
631 	/* move the current input to e->request */
632 	buffer_consume(&e->input, 4);
633 	buffer_clear(&e->request);
634 	buffer_append(&e->request, buffer_ptr(&e->input), msg_len);
635 	buffer_consume(&e->input, msg_len);
636 	type = buffer_get_char(&e->request);
637 
638 	/* check wheter agent is locked */
639 	if (locked && type != SSH_AGENTC_UNLOCK) {
640 		buffer_clear(&e->request);
641 		switch (type) {
642 		case SSH_AGENTC_REQUEST_RSA_IDENTITIES:
643 		case SSH2_AGENTC_REQUEST_IDENTITIES:
644 			/* send empty lists */
645 			no_identities(e, type);
646 			break;
647 		default:
648 			/* send a fail message for all other request types */
649 			buffer_put_int(&e->output, 1);
650 			buffer_put_char(&e->output, SSH_AGENT_FAILURE);
651 		}
652 		return;
653 	}
654 
655 	debug("type %d", type);
656 	switch (type) {
657 	case SSH_AGENTC_LOCK:
658 	case SSH_AGENTC_UNLOCK:
659 		process_lock_agent(e, type == SSH_AGENTC_LOCK);
660 		break;
661 	/* ssh1 */
662 	case SSH_AGENTC_RSA_CHALLENGE:
663 		process_authentication_challenge1(e);
664 		break;
665 	case SSH_AGENTC_REQUEST_RSA_IDENTITIES:
666 		process_request_identities(e, 1);
667 		break;
668 	case SSH_AGENTC_ADD_RSA_IDENTITY:
669 	case SSH_AGENTC_ADD_RSA_ID_CONSTRAINED:
670 		process_add_identity(e, 1);
671 		break;
672 	case SSH_AGENTC_REMOVE_RSA_IDENTITY:
673 		process_remove_identity(e, 1);
674 		break;
675 	case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES:
676 		process_remove_all_identities(e, 1);
677 		break;
678 	/* ssh2 */
679 	case SSH2_AGENTC_SIGN_REQUEST:
680 		process_sign_request2(e);
681 		break;
682 	case SSH2_AGENTC_REQUEST_IDENTITIES:
683 		process_request_identities(e, 2);
684 		break;
685 	case SSH2_AGENTC_ADD_IDENTITY:
686 	case SSH2_AGENTC_ADD_ID_CONSTRAINED:
687 		process_add_identity(e, 2);
688 		break;
689 	case SSH2_AGENTC_REMOVE_IDENTITY:
690 		process_remove_identity(e, 2);
691 		break;
692 	case SSH2_AGENTC_REMOVE_ALL_IDENTITIES:
693 		process_remove_all_identities(e, 2);
694 		break;
695 #ifdef SMARTCARD
696 	case SSH_AGENTC_ADD_SMARTCARD_KEY:
697 		process_add_smartcard_key(e);
698 		break;
699 	case SSH_AGENTC_REMOVE_SMARTCARD_KEY:
700 		process_remove_smartcard_key(e);
701 		break;
702 #endif /* SMARTCARD */
703 	default:
704 		/* Unknown message.  Respond with failure. */
705 		error("Unknown message %d", type);
706 		buffer_clear(&e->request);
707 		buffer_put_int(&e->output, 1);
708 		buffer_put_char(&e->output, SSH_AGENT_FAILURE);
709 		break;
710 	}
711 }
712 
713 static void
714 new_socket(sock_type type, int fd)
715 {
716 	u_int i, old_alloc;
717 	if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
718 		error("fcntl O_NONBLOCK: %s", strerror(errno));
719 
720 	if (fd > max_fd)
721 		max_fd = fd;
722 
723 	for (i = 0; i < sockets_alloc; i++)
724 		if (sockets[i].type == AUTH_UNUSED) {
725 			sockets[i].fd = fd;
726 			sockets[i].type = type;
727 			buffer_init(&sockets[i].input);
728 			buffer_init(&sockets[i].output);
729 			buffer_init(&sockets[i].request);
730 			return;
731 		}
732 	old_alloc = sockets_alloc;
733 	sockets_alloc += 10;
734 	if (sockets)
735 		sockets = xrealloc(sockets, sockets_alloc * sizeof(sockets[0]));
736 	else
737 		sockets = xmalloc(sockets_alloc * sizeof(sockets[0]));
738 	for (i = old_alloc; i < sockets_alloc; i++)
739 		sockets[i].type = AUTH_UNUSED;
740 	sockets[old_alloc].type = type;
741 	sockets[old_alloc].fd = fd;
742 	buffer_init(&sockets[old_alloc].input);
743 	buffer_init(&sockets[old_alloc].output);
744 	buffer_init(&sockets[old_alloc].request);
745 }
746 
747 static int
748 prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, int *nallocp)
749 {
750 	u_int i, sz;
751 	int n = 0;
752 
753 	for (i = 0; i < sockets_alloc; i++) {
754 		switch (sockets[i].type) {
755 		case AUTH_SOCKET:
756 		case AUTH_CONNECTION:
757 			n = MAX(n, sockets[i].fd);
758 			break;
759 		case AUTH_UNUSED:
760 			break;
761 		default:
762 			fatal("Unknown socket type %d", sockets[i].type);
763 			break;
764 		}
765 	}
766 
767 	sz = howmany(n+1, NFDBITS) * sizeof(fd_mask);
768 	if (*fdrp == NULL || sz > *nallocp) {
769 		if (*fdrp)
770 			xfree(*fdrp);
771 		if (*fdwp)
772 			xfree(*fdwp);
773 		*fdrp = xmalloc(sz);
774 		*fdwp = xmalloc(sz);
775 		*nallocp = sz;
776 	}
777 	if (n < *fdl)
778 		debug("XXX shrink: %d < %d", n, *fdl);
779 	*fdl = n;
780 	memset(*fdrp, 0, sz);
781 	memset(*fdwp, 0, sz);
782 
783 	for (i = 0; i < sockets_alloc; i++) {
784 		switch (sockets[i].type) {
785 		case AUTH_SOCKET:
786 		case AUTH_CONNECTION:
787 			FD_SET(sockets[i].fd, *fdrp);
788 			if (buffer_len(&sockets[i].output) > 0)
789 				FD_SET(sockets[i].fd, *fdwp);
790 			break;
791 		default:
792 			break;
793 		}
794 	}
795 	return (1);
796 }
797 
798 static void
799 after_select(fd_set *readset, fd_set *writeset)
800 {
801 	u_int i;
802 	int len, sock;
803 	socklen_t slen;
804 	char buf[1024];
805 	struct sockaddr_un sunaddr;
806 
807 	for (i = 0; i < sockets_alloc; i++)
808 		switch (sockets[i].type) {
809 		case AUTH_UNUSED:
810 			break;
811 		case AUTH_SOCKET:
812 			if (FD_ISSET(sockets[i].fd, readset)) {
813 				slen = sizeof(sunaddr);
814 				sock = accept(sockets[i].fd,
815 				    (struct sockaddr *) &sunaddr, &slen);
816 				if (sock < 0) {
817 					error("accept from AUTH_SOCKET: %s",
818 					    strerror(errno));
819 					break;
820 				}
821 				new_socket(AUTH_CONNECTION, sock);
822 			}
823 			break;
824 		case AUTH_CONNECTION:
825 			if (buffer_len(&sockets[i].output) > 0 &&
826 			    FD_ISSET(sockets[i].fd, writeset)) {
827 				do {
828 					len = write(sockets[i].fd,
829 					    buffer_ptr(&sockets[i].output),
830 					    buffer_len(&sockets[i].output));
831 					if (len == -1 && (errno == EAGAIN ||
832 					    errno == EINTR))
833 						continue;
834 					break;
835 				} while (1);
836 				if (len <= 0) {
837 					shutdown(sockets[i].fd, SHUT_RDWR);
838 					close(sockets[i].fd);
839 					sockets[i].type = AUTH_UNUSED;
840 					buffer_free(&sockets[i].input);
841 					buffer_free(&sockets[i].output);
842 					buffer_free(&sockets[i].request);
843 					break;
844 				}
845 				buffer_consume(&sockets[i].output, len);
846 			}
847 			if (FD_ISSET(sockets[i].fd, readset)) {
848 				do {
849 					len = read(sockets[i].fd, buf, sizeof(buf));
850 					if (len == -1 && (errno == EAGAIN ||
851 					    errno == EINTR))
852 						continue;
853 					break;
854 				} while (1);
855 				if (len <= 0) {
856 					shutdown(sockets[i].fd, SHUT_RDWR);
857 					close(sockets[i].fd);
858 					sockets[i].type = AUTH_UNUSED;
859 					buffer_free(&sockets[i].input);
860 					buffer_free(&sockets[i].output);
861 					buffer_free(&sockets[i].request);
862 					break;
863 				}
864 				buffer_append(&sockets[i].input, buf, len);
865 				process_message(&sockets[i]);
866 			}
867 			break;
868 		default:
869 			fatal("Unknown type %d", sockets[i].type);
870 		}
871 }
872 
873 static void
874 cleanup_socket(void *p)
875 {
876 	if (socket_name[0])
877 		unlink(socket_name);
878 	if (socket_dir[0])
879 		rmdir(socket_dir);
880 }
881 
882 static void
883 cleanup_exit(int i)
884 {
885 	cleanup_socket(NULL);
886 	exit(i);
887 }
888 
889 static void
890 cleanup_handler(int sig)
891 {
892 	cleanup_socket(NULL);
893 	_exit(2);
894 }
895 
896 static void
897 check_parent_exists(int sig)
898 {
899 	int save_errno = errno;
900 
901 	if (parent_pid != -1 && kill(parent_pid, 0) < 0) {
902 		/* printf("Parent has died - Authentication agent exiting.\n"); */
903 		cleanup_handler(sig); /* safe */
904 	}
905 	signal(SIGALRM, check_parent_exists);
906 	alarm(10);
907 	errno = save_errno;
908 }
909 
910 static void
911 usage(void)
912 {
913 	fprintf(stderr, "Usage: %s [options] [command [args ...]]\n",
914 	    __progname);
915 	fprintf(stderr, "Options:\n");
916 	fprintf(stderr, "  -c          Generate C-shell commands on stdout.\n");
917 	fprintf(stderr, "  -s          Generate Bourne shell commands on stdout.\n");
918 	fprintf(stderr, "  -k          Kill the current agent.\n");
919 	fprintf(stderr, "  -d          Debug mode.\n");
920 	fprintf(stderr, "  -a socket   Bind agent socket to given name.\n");
921 	exit(1);
922 }
923 
924 int
925 main(int ac, char **av)
926 {
927 	int sock, c_flag = 0, d_flag = 0, k_flag = 0, s_flag = 0, ch, nalloc;
928 	struct sockaddr_un sunaddr;
929 	struct rlimit rlim;
930 	pid_t pid;
931 	char *shell, *format, *pidstr, pidstrbuf[1 + 3 * sizeof pid];
932 	char *agentsocket = NULL;
933 	extern int optind;
934 	fd_set *readsetp = NULL, *writesetp = NULL;
935 
936 	SSLeay_add_all_algorithms();
937 
938 	while ((ch = getopt(ac, av, "cdksa:")) != -1) {
939 		switch (ch) {
940 		case 'c':
941 			if (s_flag)
942 				usage();
943 			c_flag++;
944 			break;
945 		case 'k':
946 			k_flag++;
947 			break;
948 		case 's':
949 			if (c_flag)
950 				usage();
951 			s_flag++;
952 			break;
953 		case 'd':
954 			if (d_flag)
955 				usage();
956 			d_flag++;
957 			break;
958 		case 'a':
959 			agentsocket = optarg;
960 			break;
961 		default:
962 			usage();
963 		}
964 	}
965 	ac -= optind;
966 	av += optind;
967 
968 	if (ac > 0 && (c_flag || k_flag || s_flag || d_flag))
969 		usage();
970 
971 	if (ac == 0 && !c_flag && !s_flag) {
972 		shell = getenv("SHELL");
973 		if (shell != NULL && strncmp(shell + strlen(shell) - 3, "csh", 3) == 0)
974 			c_flag = 1;
975 	}
976 	if (k_flag) {
977 		pidstr = getenv(SSH_AGENTPID_ENV_NAME);
978 		if (pidstr == NULL) {
979 			fprintf(stderr, "%s not set, cannot kill agent\n",
980 			    SSH_AGENTPID_ENV_NAME);
981 			exit(1);
982 		}
983 		pid = atoi(pidstr);
984 		if (pid < 1) {
985 			fprintf(stderr, "%s=\"%s\", which is not a good PID\n",
986 			    SSH_AGENTPID_ENV_NAME, pidstr);
987 			exit(1);
988 		}
989 		if (kill(pid, SIGTERM) == -1) {
990 			perror("kill");
991 			exit(1);
992 		}
993 		format = c_flag ? "unsetenv %s;\n" : "unset %s;\n";
994 		printf(format, SSH_AUTHSOCKET_ENV_NAME);
995 		printf(format, SSH_AGENTPID_ENV_NAME);
996 		printf("echo Agent pid %ld killed;\n", (long)pid);
997 		exit(0);
998 	}
999 	parent_pid = getpid();
1000 
1001 	if (agentsocket == NULL) {
1002 		/* Create private directory for agent socket */
1003 		strlcpy(socket_dir, "/tmp/ssh-XXXXXXXX", sizeof socket_dir);
1004 		if (mkdtemp(socket_dir) == NULL) {
1005 			perror("mkdtemp: private socket dir");
1006 			exit(1);
1007 		}
1008 		snprintf(socket_name, sizeof socket_name, "%s/agent.%ld", socket_dir,
1009 		    (long)parent_pid);
1010 	} else {
1011 		/* Try to use specified agent socket */
1012 		socket_dir[0] = '\0';
1013 		strlcpy(socket_name, agentsocket, sizeof socket_name);
1014 	}
1015 
1016 	/*
1017 	 * Create socket early so it will exist before command gets run from
1018 	 * the parent.
1019 	 */
1020 	sock = socket(AF_UNIX, SOCK_STREAM, 0);
1021 	if (sock < 0) {
1022 		perror("socket");
1023 		cleanup_exit(1);
1024 	}
1025 	memset(&sunaddr, 0, sizeof(sunaddr));
1026 	sunaddr.sun_family = AF_UNIX;
1027 	strlcpy(sunaddr.sun_path, socket_name, sizeof(sunaddr.sun_path));
1028 	sunaddr.sun_len = SUN_LEN(&sunaddr) + 1;
1029 	if (bind(sock, (struct sockaddr *)&sunaddr, sunaddr.sun_len) < 0) {
1030 		perror("bind");
1031 		cleanup_exit(1);
1032 	}
1033 	if (listen(sock, 5) < 0) {
1034 		perror("listen");
1035 		cleanup_exit(1);
1036 	}
1037 
1038 	/*
1039 	 * Fork, and have the parent execute the command, if any, or present
1040 	 * the socket data.  The child continues as the authentication agent.
1041 	 */
1042 	if (d_flag) {
1043 		log_init(__progname, SYSLOG_LEVEL_DEBUG1, SYSLOG_FACILITY_AUTH, 1);
1044 		format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n";
1045 		printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name,
1046 		    SSH_AUTHSOCKET_ENV_NAME);
1047 		printf("echo Agent pid %ld;\n", (long)parent_pid);
1048 		goto skip;
1049 	}
1050 	pid = fork();
1051 	if (pid == -1) {
1052 		perror("fork");
1053 		cleanup_exit(1);
1054 	}
1055 	if (pid != 0) {		/* Parent - execute the given command. */
1056 		close(sock);
1057 		snprintf(pidstrbuf, sizeof pidstrbuf, "%ld", (long)pid);
1058 		if (ac == 0) {
1059 			format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n";
1060 			printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name,
1061 			    SSH_AUTHSOCKET_ENV_NAME);
1062 			printf(format, SSH_AGENTPID_ENV_NAME, pidstrbuf,
1063 			    SSH_AGENTPID_ENV_NAME);
1064 			printf("echo Agent pid %ld;\n", (long)pid);
1065 			exit(0);
1066 		}
1067 		if (setenv(SSH_AUTHSOCKET_ENV_NAME, socket_name, 1) == -1 ||
1068 		    setenv(SSH_AGENTPID_ENV_NAME, pidstrbuf, 1) == -1) {
1069 			perror("setenv");
1070 			exit(1);
1071 		}
1072 		execvp(av[0], av);
1073 		perror(av[0]);
1074 		exit(1);
1075 	}
1076 	/* child */
1077 	log_init(__progname, SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_AUTH, 0);
1078 
1079 	if (setsid() == -1) {
1080 		error("setsid: %s", strerror(errno));
1081 		cleanup_exit(1);
1082 	}
1083 
1084 	(void)chdir("/");
1085 	close(0);
1086 	close(1);
1087 	close(2);
1088 
1089 	/* deny core dumps, since memory contains unencrypted private keys */
1090 	rlim.rlim_cur = rlim.rlim_max = 0;
1091 	if (setrlimit(RLIMIT_CORE, &rlim) < 0) {
1092 		error("setrlimit RLIMIT_CORE: %s", strerror(errno));
1093 		cleanup_exit(1);
1094 	}
1095 
1096 skip:
1097 	fatal_add_cleanup(cleanup_socket, NULL);
1098 	new_socket(AUTH_SOCKET, sock);
1099 	if (ac > 0) {
1100 		signal(SIGALRM, check_parent_exists);
1101 		alarm(10);
1102 	}
1103 	idtab_init();
1104 	if (!d_flag)
1105 		signal(SIGINT, SIG_IGN);
1106 	signal(SIGPIPE, SIG_IGN);
1107 	signal(SIGHUP, cleanup_handler);
1108 	signal(SIGTERM, cleanup_handler);
1109 	nalloc = 0;
1110 
1111 	while (1) {
1112 		prepare_select(&readsetp, &writesetp, &max_fd, &nalloc);
1113 		if (select(max_fd + 1, readsetp, writesetp, NULL, NULL) < 0) {
1114 			if (errno == EINTR)
1115 				continue;
1116 			fatal("select: %s", strerror(errno));
1117 		}
1118 		after_select(readsetp, writesetp);
1119 	}
1120 	/* NOTREACHED */
1121 }
1122