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