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