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