ssh-agent.c revision 1.33
1/*	$NetBSD: ssh-agent.c,v 1.33 2022/02/23 19:07:20 christos Exp $	*/
2/* $OpenBSD: ssh-agent.c,v 1.287 2022/01/14 03:43:48 djm Exp $ */
3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
5 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
6 *                    All rights reserved
7 * The authentication agent program.
8 *
9 * As far as I am concerned, the code I have written for this software
10 * can be used freely for any purpose.  Any derived versions of this
11 * software must be clearly marked as such, and if the derived work is
12 * incompatible with the protocol description in the RFC file, it must be
13 * called by a name other than "ssh" or "Secure Shell".
14 *
15 * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
19 * are met:
20 * 1. Redistributions of source code must retain the above copyright
21 *    notice, this list of conditions and the following disclaimer.
22 * 2. Redistributions in binary form must reproduce the above copyright
23 *    notice, this list of conditions and the following disclaimer in the
24 *    documentation and/or other materials provided with the distribution.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37
38#include "includes.h"
39__RCSID("$NetBSD: ssh-agent.c,v 1.33 2022/02/23 19:07:20 christos Exp $");
40
41#include <sys/param.h>	/* MIN MAX */
42#include <sys/types.h>
43#include <sys/time.h>
44#include <sys/queue.h>
45#include <sys/resource.h>
46#include <sys/socket.h>
47#include <sys/stat.h>
48#include <sys/un.h>
49#include <sys/wait.h>
50
51#ifdef WITH_OPENSSL
52#include <openssl/evp.h>
53#endif
54
55#include <errno.h>
56#include <fcntl.h>
57#include <paths.h>
58#include <poll.h>
59#include <signal.h>
60#include <stdlib.h>
61#include <stdio.h>
62#include <string.h>
63#include <stdarg.h>
64#include <limits.h>
65#include <time.h>
66#include <unistd.h>
67#include <util.h>
68
69#include "xmalloc.h"
70#include "ssh.h"
71#include "ssh2.h"
72#include "sshbuf.h"
73#include "sshkey.h"
74#include "authfd.h"
75#include "compat.h"
76#include "log.h"
77#include "misc.h"
78#include "getpeereid.h"
79#include "digest.h"
80#include "ssherr.h"
81#include "match.h"
82#include "msg.h"
83#include "ssherr.h"
84#include "pathnames.h"
85#include "ssh-pkcs11.h"
86#include "sk-api.h"
87#include "myproposal.h"
88
89#ifndef DEFAULT_ALLOWED_PROVIDERS
90# define DEFAULT_ALLOWED_PROVIDERS "/usr/lib*/*,/usr/pkg/lib*/*"
91#endif
92
93/* Maximum accepted message length */
94#define AGENT_MAX_LEN		(256*1024)
95/* Maximum bytes to read from client socket */
96#define AGENT_RBUF_LEN		(4096)
97/* Maximum number of recorded session IDs/hostkeys per connection */
98#define AGENT_MAX_SESSION_IDS		16
99/* Maximum size of session ID */
100#define AGENT_MAX_SID_LEN		128
101/* Maximum number of destination constraints to accept on a key */
102#define AGENT_MAX_DEST_CONSTRAINTS	1024
103
104/* XXX store hostkey_sid in a refcounted tree */
105
106typedef enum {
107	AUTH_UNUSED = 0,
108	AUTH_SOCKET = 1,
109	AUTH_CONNECTION = 2,
110} sock_type;
111
112struct hostkey_sid {
113	struct sshkey *key;
114	struct sshbuf *sid;
115	int forwarded;
116};
117
118typedef struct socket_entry {
119	int fd;
120	sock_type type;
121	struct sshbuf *input;
122	struct sshbuf *output;
123	struct sshbuf *request;
124	size_t nsession_ids;
125	struct hostkey_sid *session_ids;
126} SocketEntry;
127
128u_int sockets_alloc = 0;
129SocketEntry *sockets = NULL;
130
131typedef struct identity {
132	TAILQ_ENTRY(identity) next;
133	struct sshkey *key;
134	char *comment;
135	char *provider;
136	time_t death;
137	u_int confirm;
138	char *sk_provider;
139	struct dest_constraint *dest_constraints;
140	size_t ndest_constraints;
141} Identity;
142
143struct idtable {
144	int nentries;
145	TAILQ_HEAD(idqueue, identity) idlist;
146};
147
148/* private key table */
149struct idtable *idtab;
150
151int max_fd = 0;
152
153/* pid of shell == parent of agent */
154pid_t parent_pid = -1;
155time_t parent_alive_interval = 0;
156
157/* pid of process for which cleanup_socket is applicable */
158pid_t cleanup_pid = 0;
159
160/* pathname and directory for AUTH_SOCKET */
161char socket_name[PATH_MAX];
162char socket_dir[PATH_MAX];
163
164/* Pattern-list of allowed PKCS#11/Security key paths */
165static char *allowed_providers;
166
167/* locking */
168#define LOCK_SIZE	32
169#define LOCK_SALT_SIZE	16
170#define LOCK_ROUNDS	1
171int locked = 0;
172u_char lock_pwhash[LOCK_SIZE];
173u_char lock_salt[LOCK_SALT_SIZE];
174
175extern char *__progname;
176
177/* Default lifetime in seconds (0 == forever) */
178static int lifetime = 0;
179
180static int fingerprint_hash = SSH_FP_HASH_DEFAULT;
181
182/* Refuse signing of non-SSH messages for web-origin FIDO keys */
183static int restrict_websafe = 1;
184
185static void
186close_socket(SocketEntry *e)
187{
188	size_t i;
189
190	close(e->fd);
191	sshbuf_free(e->input);
192	sshbuf_free(e->output);
193	sshbuf_free(e->request);
194	for (i = 0; i < e->nsession_ids; i++) {
195		sshkey_free(e->session_ids[i].key);
196		sshbuf_free(e->session_ids[i].sid);
197	}
198	free(e->session_ids);
199	memset(e, '\0', sizeof(*e));
200	e->fd = -1;
201	e->type = AUTH_UNUSED;
202}
203
204static void
205idtab_init(void)
206{
207	idtab = xcalloc(1, sizeof(*idtab));
208	TAILQ_INIT(&idtab->idlist);
209	idtab->nentries = 0;
210}
211
212static void
213free_dest_constraint_hop(struct dest_constraint_hop *dch)
214{
215	u_int i;
216
217	if (dch == NULL)
218		return;
219	free(dch->user);
220	free(dch->hostname);
221	for (i = 0; i < dch->nkeys; i++)
222		sshkey_free(dch->keys[i]);
223	free(dch->keys);
224	free(dch->key_is_ca);
225}
226
227static void
228free_dest_constraints(struct dest_constraint *dcs, size_t ndcs)
229{
230	size_t i;
231
232	for (i = 0; i < ndcs; i++) {
233		free_dest_constraint_hop(&dcs[i].from);
234		free_dest_constraint_hop(&dcs[i].to);
235	}
236	free(dcs);
237}
238
239static void
240free_identity(Identity *id)
241{
242	sshkey_free(id->key);
243	free(id->provider);
244	free(id->comment);
245	free(id->sk_provider);
246	free_dest_constraints(id->dest_constraints, id->ndest_constraints);
247	free(id);
248}
249
250/*
251 * Match 'key' against the key/CA list in a destination constraint hop
252 * Returns 0 on success or -1 otherwise.
253 */
254static int
255match_key_hop(const char *tag, const struct sshkey *key,
256    const struct dest_constraint_hop *dch)
257{
258	const char *reason = NULL;
259	const char *hostname = dch->hostname ? dch->hostname : "(ORIGIN)";
260	u_int i;
261	char *fp;
262
263	if (key == NULL)
264		return -1;
265	/* XXX logspam */
266	if ((fp = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT,
267	    SSH_FP_DEFAULT)) == NULL)
268		fatal_f("fingerprint failed");
269	debug3_f("%s: entering hostname %s, requested key %s %s, %u keys avail",
270	    tag, hostname, sshkey_type(key), fp, dch->nkeys);
271	free(fp);
272	for (i = 0; i < dch->nkeys; i++) {
273		if (dch->keys[i] == NULL)
274			return -1;
275		/* XXX logspam */
276		if ((fp = sshkey_fingerprint(dch->keys[i], SSH_FP_HASH_DEFAULT,
277		    SSH_FP_DEFAULT)) == NULL)
278			fatal_f("fingerprint failed");
279		debug3_f("%s: key %u: %s%s %s", tag, i,
280		    dch->key_is_ca[i] ? "CA " : "",
281		    sshkey_type(dch->keys[i]), fp);
282		free(fp);
283		if (!sshkey_is_cert(key)) {
284			/* plain key */
285			if (dch->key_is_ca[i] ||
286			    !sshkey_equal(key, dch->keys[i]))
287				continue;
288			return 0;
289		}
290		/* certificate */
291		if (!dch->key_is_ca[i])
292			continue;
293		if (key->cert == NULL || key->cert->signature_key == NULL)
294			return -1; /* shouldn't happen */
295		if (!sshkey_equal(key->cert->signature_key, dch->keys[i]))
296			continue;
297		if (sshkey_cert_check_host(key, hostname, 1,
298		    SSH_ALLOWED_CA_SIGALGS, &reason) != 0) {
299			debug_f("cert %s / hostname %s rejected: %s",
300			    key->cert->key_id, hostname, reason);
301			continue;
302		}
303		return 0;
304	}
305	return -1;
306}
307
308/* Check destination constraints on an identity against the hostkey/user */
309static int
310permitted_by_dest_constraints(const struct sshkey *fromkey,
311    const struct sshkey *tokey, Identity *id, const char *user,
312    const char **hostnamep)
313{
314	size_t i;
315	struct dest_constraint *d;
316
317	if (hostnamep != NULL)
318		*hostnamep = NULL;
319	for (i = 0; i < id->ndest_constraints; i++) {
320		d = id->dest_constraints + i;
321		/* XXX remove logspam */
322		debug2_f("constraint %zu %s%s%s (%u keys) > %s%s%s (%u keys)",
323		    i, d->from.user ? d->from.user : "",
324		    d->from.user ? "@" : "",
325		    d->from.hostname ? d->from.hostname : "(ORIGIN)",
326		    d->from.nkeys,
327		    d->to.user ? d->to.user : "", d->to.user ? "@" : "",
328		    d->to.hostname ? d->to.hostname : "(ANY)", d->to.nkeys);
329
330		/* Match 'from' key */
331		if (fromkey == NULL) {
332			/* We are matching the first hop */
333			if (d->from.hostname != NULL || d->from.nkeys != 0)
334				continue;
335		} else if (match_key_hop("from", fromkey, &d->from) != 0)
336			continue;
337
338		/* Match 'to' key */
339		if (tokey != NULL && match_key_hop("to", tokey, &d->to) != 0)
340			continue;
341
342		/* Match user if specified */
343		if (d->to.user != NULL && user != NULL &&
344		    !match_pattern(user, d->to.user))
345			continue;
346
347		/* successfully matched this constraint */
348		if (hostnamep != NULL)
349			*hostnamep = d->to.hostname;
350		debug2_f("allowed for hostname %s",
351		    d->to.hostname == NULL ? "*" : d->to.hostname);
352		return 0;
353	}
354	/* no match */
355	debug2_f("%s identity \"%s\" not permitted for this destination",
356	    sshkey_type(id->key), id->comment);
357	return -1;
358}
359
360/*
361 * Check whether hostkeys on a SocketEntry and the optionally specified user
362 * are permitted by the destination constraints on the Identity.
363 * Returns 0 on success or -1 otherwise.
364 */
365static int
366identity_permitted(Identity *id, SocketEntry *e, char *user,
367    const char **forward_hostnamep, const char **last_hostnamep)
368{
369	size_t i;
370	const char **hp;
371	struct hostkey_sid *hks;
372	const struct sshkey *fromkey = NULL;
373	const char *test_user;
374	char *fp1, *fp2;
375
376	/* XXX remove logspam */
377	debug3_f("entering: key %s comment \"%s\", %zu socket bindings, "
378	    "%zu constraints", sshkey_type(id->key), id->comment,
379	    e->nsession_ids, id->ndest_constraints);
380	if (id->ndest_constraints == 0)
381		return 0; /* unconstrained */
382	if (e->nsession_ids == 0)
383		return 0; /* local use */
384	/*
385	 * Walk through the hops recorded by session_id and try to find a
386	 * constraint that satisfies each.
387	 */
388	for (i = 0; i < e->nsession_ids; i++) {
389		hks = e->session_ids + i;
390		if (hks->key == NULL)
391			fatal_f("internal error: no bound key");
392		/* XXX remove logspam */
393		fp1 = fp2 = NULL;
394		if (fromkey != NULL &&
395		    (fp1 = sshkey_fingerprint(fromkey, SSH_FP_HASH_DEFAULT,
396		    SSH_FP_DEFAULT)) == NULL)
397			fatal_f("fingerprint failed");
398		if ((fp2 = sshkey_fingerprint(hks->key, SSH_FP_HASH_DEFAULT,
399		    SSH_FP_DEFAULT)) == NULL)
400			fatal_f("fingerprint failed");
401		debug3_f("socketentry fd=%d, entry %zu %s, "
402		    "from hostkey %s %s to user %s hostkey %s %s",
403		    e->fd, i, hks->forwarded ? "FORWARD" : "AUTH",
404		    fromkey ? sshkey_type(fromkey) : "(ORIGIN)",
405		    fromkey ? fp1 : "", user ? user : "(ANY)",
406		    sshkey_type(hks->key), fp2);
407		free(fp1);
408		free(fp2);
409		/*
410		 * Record the hostnames for the initial forwarding and
411		 * the final destination.
412		 */
413		hp = NULL;
414		if (i == e->nsession_ids - 1)
415			hp = last_hostnamep;
416		else if (i == 0)
417			hp = forward_hostnamep;
418		/* Special handling for final recorded binding */
419		test_user = NULL;
420		if (i == e->nsession_ids - 1) {
421			/* Can only check user at final hop */
422			test_user = user;
423			/*
424			 * user is only presented for signature requests.
425			 * If this is the case, make sure last binding is not
426			 * for a forwarding.
427			 */
428			if (hks->forwarded && user != NULL) {
429				error_f("tried to sign on forwarding hop");
430				return -1;
431			}
432		} else if (!hks->forwarded) {
433			error_f("tried to forward though signing bind");
434			return -1;
435		}
436		if (permitted_by_dest_constraints(fromkey, hks->key, id,
437		    test_user, hp) != 0)
438			return -1;
439		fromkey = hks->key;
440	}
441	/*
442	 * Another special case: if the last bound session ID was for a
443	 * forwarding, and this function is not being called to check a sign
444	 * request (i.e. no 'user' supplied), then only permit the key if
445	 * there is a permission that would allow it to be used at another
446	 * destination. This hides keys that are allowed to be used to
447	 * authenticate *to* a host but not permitted for *use* beyond it.
448	 */
449	hks = &e->session_ids[e->nsession_ids - 1];
450	if (hks->forwarded && user == NULL &&
451	    permitted_by_dest_constraints(hks->key, NULL, id,
452	    NULL, NULL) != 0) {
453		debug3_f("key permitted at host but not after");
454		return -1;
455	}
456
457	/* success */
458	return 0;
459}
460
461/* return matching private key for given public key */
462static Identity *
463lookup_identity(struct sshkey *key)
464{
465	Identity *id;
466
467	TAILQ_FOREACH(id, &idtab->idlist, next) {
468		if (sshkey_equal(key, id->key))
469			return (id);
470	}
471	return (NULL);
472}
473
474/* Check confirmation of keysign request */
475static int
476confirm_key(Identity *id, const char *extra)
477{
478	char *p;
479	int ret = -1;
480
481	p = sshkey_fingerprint(id->key, fingerprint_hash, SSH_FP_DEFAULT);
482	if (p != NULL &&
483	    ask_permission("Allow use of key %s?\nKey fingerprint %s.%s%s",
484	    id->comment, p,
485	    extra == NULL ? "" : "\n", extra == NULL ? "" : extra))
486		ret = 0;
487	free(p);
488
489	return (ret);
490}
491
492static void
493send_status(SocketEntry *e, int success)
494{
495	int r;
496
497	if ((r = sshbuf_put_u32(e->output, 1)) != 0 ||
498	    (r = sshbuf_put_u8(e->output, success ?
499	    SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE)) != 0)
500		fatal_fr(r, "compose");
501}
502
503/* send list of supported public keys to 'client' */
504static void
505process_request_identities(SocketEntry *e)
506{
507	Identity *id;
508	struct sshbuf *msg, *keys;
509	int r;
510	u_int nentries = 0;
511
512	debug2_f("entering");
513
514	if ((msg = sshbuf_new()) == NULL || (keys = sshbuf_new()) == NULL)
515		fatal_f("sshbuf_new failed");
516	TAILQ_FOREACH(id, &idtab->idlist, next) {
517		/* identity not visible, don't include in response */
518		if (identity_permitted(id, e, NULL, NULL, NULL) != 0)
519			continue;
520		if ((r = sshkey_puts_opts(id->key, keys,
521		    SSHKEY_SERIALIZE_INFO)) != 0 ||
522		    (r = sshbuf_put_cstring(keys, id->comment)) != 0) {
523			error_fr(r, "compose key/comment");
524			continue;
525		}
526		nentries++;
527	}
528	debug2_f("replying with %u allowed of %u available keys",
529	    nentries, idtab->nentries);
530	if ((r = sshbuf_put_u8(msg, SSH2_AGENT_IDENTITIES_ANSWER)) != 0 ||
531	    (r = sshbuf_put_u32(msg, nentries)) != 0 ||
532	    (r = sshbuf_putb(msg, keys)) != 0)
533		fatal_fr(r, "compose");
534	if ((r = sshbuf_put_stringb(e->output, msg)) != 0)
535		fatal_fr(r, "enqueue");
536	sshbuf_free(msg);
537	sshbuf_free(keys);
538}
539
540
541static const char *
542agent_decode_alg(struct sshkey *key, u_int flags)
543{
544	if (key->type == KEY_RSA) {
545		if (flags & SSH_AGENT_RSA_SHA2_256)
546			return "rsa-sha2-256";
547		else if (flags & SSH_AGENT_RSA_SHA2_512)
548			return "rsa-sha2-512";
549	} else if (key->type == KEY_RSA_CERT) {
550		if (flags & SSH_AGENT_RSA_SHA2_256)
551			return "rsa-sha2-256-cert-v01@openssh.com";
552		else if (flags & SSH_AGENT_RSA_SHA2_512)
553			return "rsa-sha2-512-cert-v01@openssh.com";
554	}
555	return NULL;
556}
557
558/*
559 * Attempt to parse the contents of a buffer as a SSH publickey userauth
560 * request, checking its contents for consistency and matching the embedded
561 * key against the one that is being used for signing.
562 * Note: does not modify msg buffer.
563 * Optionally extract the username, session ID and/or hostkey from the request.
564 */
565static int
566parse_userauth_request(struct sshbuf *msg, const struct sshkey *expected_key,
567    char **userp, struct sshbuf **sess_idp, struct sshkey **hostkeyp)
568{
569	struct sshbuf *b = NULL, *sess_id = NULL;
570	char *user = NULL, *service = NULL, *method = NULL, *pkalg = NULL;
571	int r;
572	u_char t, sig_follows;
573	struct sshkey *mkey = NULL, *hostkey = NULL;
574
575	if (userp != NULL)
576		*userp = NULL;
577	if (sess_idp != NULL)
578		*sess_idp = NULL;
579	if (hostkeyp != NULL)
580		*hostkeyp = NULL;
581	if ((b = sshbuf_fromb(msg)) == NULL)
582		fatal_f("sshbuf_fromb");
583
584	/* SSH userauth request */
585	if ((r = sshbuf_froms(b, &sess_id)) != 0)
586		goto out;
587	if (sshbuf_len(sess_id) == 0) {
588		r = SSH_ERR_INVALID_FORMAT;
589		goto out;
590	}
591	if ((r = sshbuf_get_u8(b, &t)) != 0 || /* SSH2_MSG_USERAUTH_REQUEST */
592	    (r = sshbuf_get_cstring(b, &user, NULL)) != 0 || /* server user */
593	    (r = sshbuf_get_cstring(b, &service, NULL)) != 0 || /* service */
594	    (r = sshbuf_get_cstring(b, &method, NULL)) != 0 || /* method */
595	    (r = sshbuf_get_u8(b, &sig_follows)) != 0 || /* sig-follows */
596	    (r = sshbuf_get_cstring(b, &pkalg, NULL)) != 0 || /* alg */
597	    (r = sshkey_froms(b, &mkey)) != 0) /* key */
598		goto out;
599	if (t != SSH2_MSG_USERAUTH_REQUEST ||
600	    sig_follows != 1 ||
601	    strcmp(service, "ssh-connection") != 0 ||
602	    !sshkey_equal(expected_key, mkey) ||
603	    sshkey_type_from_name(pkalg) != expected_key->type) {
604		r = SSH_ERR_INVALID_FORMAT;
605		goto out;
606	}
607	if (strcmp(method, "publickey-hostbound-v00@openssh.com") == 0) {
608		if ((r = sshkey_froms(b, &hostkey)) != 0)
609			goto out;
610	} else if (strcmp(method, "publickey") != 0) {
611		r = SSH_ERR_INVALID_FORMAT;
612		goto out;
613	}
614	if (sshbuf_len(b) != 0) {
615		r = SSH_ERR_INVALID_FORMAT;
616		goto out;
617	}
618	/* success */
619	r = 0;
620	debug3_f("well formed userauth");
621	if (userp != NULL) {
622		*userp = user;
623		user = NULL;
624	}
625	if (sess_idp != NULL) {
626		*sess_idp = sess_id;
627		sess_id = NULL;
628	}
629	if (hostkeyp != NULL) {
630		*hostkeyp = hostkey;
631		hostkey = NULL;
632	}
633 out:
634	sshbuf_free(b);
635	sshbuf_free(sess_id);
636	free(user);
637	free(service);
638	free(method);
639	free(pkalg);
640	sshkey_free(mkey);
641	sshkey_free(hostkey);
642	return r;
643}
644
645/*
646 * Attempt to parse the contents of a buffer as a SSHSIG signature request.
647 * Note: does not modify buffer.
648 */
649static int
650parse_sshsig_request(struct sshbuf *msg)
651{
652	int r;
653	struct sshbuf *b;
654
655	if ((b = sshbuf_fromb(msg)) == NULL)
656		fatal_f("sshbuf_fromb");
657
658	if ((r = sshbuf_cmp(b, 0, "SSHSIG", 6)) != 0 ||
659	    (r = sshbuf_consume(b, 6)) != 0 ||
660	    (r = sshbuf_get_cstring(b, NULL, NULL)) != 0 || /* namespace */
661	    (r = sshbuf_get_string_direct(b, NULL, NULL)) != 0 || /* reserved */
662	    (r = sshbuf_get_cstring(b, NULL, NULL)) != 0 || /* hashalg */
663	    (r = sshbuf_get_string_direct(b, NULL, NULL)) != 0) /* H(msg) */
664		goto out;
665	if (sshbuf_len(b) != 0) {
666		r = SSH_ERR_INVALID_FORMAT;
667		goto out;
668	}
669	/* success */
670	r = 0;
671 out:
672	sshbuf_free(b);
673	return r;
674}
675
676/*
677 * This function inspects a message to be signed by a FIDO key that has a
678 * web-like application string (i.e. one that does not begin with "ssh:".
679 * It checks that the message is one of those expected for SSH operations
680 * (pubkey userauth, sshsig, CA key signing) to exclude signing challenges
681 * for the web.
682 */
683static int
684check_websafe_message_contents(struct sshkey *key, struct sshbuf *data)
685{
686	if (parse_userauth_request(data, key, NULL, NULL, NULL) == 0) {
687		debug_f("signed data matches public key userauth request");
688		return 1;
689	}
690	if (parse_sshsig_request(data) == 0) {
691		debug_f("signed data matches SSHSIG signature request");
692		return 1;
693	}
694
695	/* XXX check CA signature operation */
696
697	error("web-origin key attempting to sign non-SSH message");
698	return 0;
699}
700
701static int
702buf_equal(const struct sshbuf *a, const struct sshbuf *b)
703{
704	if (sshbuf_ptr(a) == NULL || sshbuf_ptr(b) == NULL)
705		return SSH_ERR_INVALID_ARGUMENT;
706	if (sshbuf_len(a) != sshbuf_len(b))
707		return SSH_ERR_INVALID_FORMAT;
708	if (timingsafe_bcmp(sshbuf_ptr(a), sshbuf_ptr(b), sshbuf_len(a)) != 0)
709		return SSH_ERR_INVALID_FORMAT;
710	return 0;
711}
712
713/* ssh2 only */
714static void
715process_sign_request2(SocketEntry *e)
716{
717	u_char *signature = NULL;
718	size_t slen = 0;
719	u_int compat = 0, flags;
720	int r, ok = -1, retried = 0;
721	char *fp = NULL, *pin = NULL, *prompt = NULL;
722	char *user = NULL, *sig_dest = NULL;
723	const char *fwd_host = NULL, *dest_host = NULL;
724	struct sshbuf *msg = NULL, *data = NULL, *sid = NULL;
725	struct sshkey *key = NULL, *hostkey = NULL;
726	struct identity *id;
727	struct notifier_ctx *notifier = NULL;
728
729	debug_f("entering");
730
731	if ((msg = sshbuf_new()) == NULL || (data = sshbuf_new()) == NULL)
732		fatal_f("sshbuf_new failed");
733	if ((r = sshkey_froms(e->request, &key)) != 0 ||
734	    (r = sshbuf_get_stringb(e->request, data)) != 0 ||
735	    (r = sshbuf_get_u32(e->request, &flags)) != 0) {
736		error_fr(r, "parse");
737		goto send;
738	}
739
740	if ((id = lookup_identity(key)) == NULL) {
741		verbose_f("%s key not found", sshkey_type(key));
742		goto send;
743	}
744	if ((fp = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT,
745	    SSH_FP_DEFAULT)) == NULL)
746		fatal_f("fingerprint failed");
747
748	if (id->ndest_constraints != 0) {
749		if (e->nsession_ids == 0) {
750			logit_f("refusing use of destination-constrained key "
751			    "to sign on unbound connection");
752			goto send;
753		}
754		if (parse_userauth_request(data, key, &user, &sid,
755		    &hostkey) != 0) {
756			logit_f("refusing use of destination-constrained key "
757			   "to sign an unidentified signature");
758			goto send;
759		}
760		/* XXX logspam */
761		debug_f("user=%s", user);
762		if (identity_permitted(id, e, user, &fwd_host, &dest_host) != 0)
763			goto send;
764		/* XXX display fwd_host/dest_host in askpass UI */
765		/*
766		 * Ensure that the session ID is the most recent one
767		 * registered on the socket - it should have been bound by
768		 * ssh immediately before userauth.
769		 */
770		if (buf_equal(sid,
771		    e->session_ids[e->nsession_ids - 1].sid) != 0) {
772			error_f("unexpected session ID (%zu listed) on "
773			    "signature request for target user %s with "
774			    "key %s %s", e->nsession_ids, user,
775			    sshkey_type(id->key), fp);
776			goto send;
777		}
778		/*
779		 * Ensure that the hostkey embedded in the signature matches
780		 * the one most recently bound to the socket. An exception is
781		 * made for the initial forwarding hop.
782		 */
783		if (e->nsession_ids > 1 && hostkey == NULL) {
784			error_f("refusing use of destination-constrained key: "
785			    "no hostkey recorded in signature for forwarded "
786			    "connection");
787			goto send;
788		}
789		if (hostkey != NULL && !sshkey_equal(hostkey,
790		    e->session_ids[e->nsession_ids - 1].key)) {
791			error_f("refusing use of destination-constrained key: "
792			    "mismatch between hostkey in request and most "
793			    "recently bound session");
794			goto send;
795		}
796		xasprintf(&sig_dest, "public key authentication request for "
797		    "user \"%s\" to listed host", user);
798	}
799	if (id->confirm && confirm_key(id, sig_dest) != 0) {
800		verbose_f("user refused key");
801		goto send;
802	}
803	if (sshkey_is_sk(id->key)) {
804		if (strncmp(id->key->sk_application, "ssh:", 4) != 0 &&
805		    !check_websafe_message_contents(key, data)) {
806			/* error already logged */
807			goto send;
808		}
809		if ((id->key->sk_flags & SSH_SK_USER_VERIFICATION_REQD)) {
810			/* XXX include sig_dest */
811			xasprintf(&prompt, "Enter PIN%sfor %s key %s: ",
812			    (id->key->sk_flags & SSH_SK_USER_PRESENCE_REQD) ?
813			    " and confirm user presence " : " ",
814			    sshkey_type(id->key), fp);
815			pin = read_passphrase(prompt, RP_USE_ASKPASS);
816			free(prompt);
817			prompt = NULL;
818		} else if ((id->key->sk_flags & SSH_SK_USER_PRESENCE_REQD)) {
819			notifier = notify_start(0,
820			    "Confirm user presence for key %s %s%s%s",
821			    sshkey_type(id->key), fp,
822			    sig_dest == NULL ? "" : "\n",
823			    sig_dest == NULL ? "" : sig_dest);
824		}
825	}
826 retry_pin:
827	if ((r = sshkey_sign(id->key, &signature, &slen,
828	    sshbuf_ptr(data), sshbuf_len(data), agent_decode_alg(key, flags),
829	    id->sk_provider, pin, compat)) != 0) {
830		debug_fr(r, "sshkey_sign");
831		if (pin == NULL && !retried && sshkey_is_sk(id->key) &&
832		    r == SSH_ERR_KEY_WRONG_PASSPHRASE) {
833			if (notifier) {
834				notify_complete(notifier, NULL);
835				notifier = NULL;
836			}
837			/* XXX include sig_dest */
838			xasprintf(&prompt, "Enter PIN%sfor %s key %s: ",
839			    (id->key->sk_flags & SSH_SK_USER_PRESENCE_REQD) ?
840			    " and confirm user presence " : " ",
841			    sshkey_type(id->key), fp);
842			pin = read_passphrase(prompt, RP_USE_ASKPASS);
843			retried = 1;
844			goto retry_pin;
845		}
846		error_fr(r, "sshkey_sign");
847		goto send;
848	}
849	/* Success */
850	ok = 0;
851 send:
852	notify_complete(notifier, "User presence confirmed");
853
854	if (ok == 0) {
855		if ((r = sshbuf_put_u8(msg, SSH2_AGENT_SIGN_RESPONSE)) != 0 ||
856		    (r = sshbuf_put_string(msg, signature, slen)) != 0)
857			fatal_fr(r, "compose");
858	} else if ((r = sshbuf_put_u8(msg, SSH_AGENT_FAILURE)) != 0)
859		fatal_fr(r, "compose failure");
860
861	if ((r = sshbuf_put_stringb(e->output, msg)) != 0)
862		fatal_fr(r, "enqueue");
863
864	sshbuf_free(sid);
865	sshbuf_free(data);
866	sshbuf_free(msg);
867	sshkey_free(key);
868	sshkey_free(hostkey);
869	free(fp);
870	free(signature);
871	free(sig_dest);
872	free(user);
873	free(prompt);
874	if (pin != NULL)
875		freezero(pin, strlen(pin));
876}
877
878/* shared */
879static void
880process_remove_identity(SocketEntry *e)
881{
882	int r, success = 0;
883	struct sshkey *key = NULL;
884	Identity *id;
885
886	debug2_f("entering");
887	if ((r = sshkey_froms(e->request, &key)) != 0) {
888		error_fr(r, "parse key");
889		goto done;
890	}
891	if ((id = lookup_identity(key)) == NULL) {
892		debug_f("key not found");
893		goto done;
894	}
895	/* identity not visible, cannot be removed */
896	if (identity_permitted(id, e, NULL, NULL, NULL) != 0)
897		goto done; /* error already logged */
898	/* We have this key, free it. */
899	if (idtab->nentries < 1)
900		fatal_f("internal error: nentries %d", idtab->nentries);
901	TAILQ_REMOVE(&idtab->idlist, id, next);
902	free_identity(id);
903	idtab->nentries--;
904	success = 1;
905 done:
906	sshkey_free(key);
907	send_status(e, success);
908}
909
910static void
911process_remove_all_identities(SocketEntry *e)
912{
913	Identity *id;
914
915	debug2_f("entering");
916	/* Loop over all identities and clear the keys. */
917	for (id = TAILQ_FIRST(&idtab->idlist); id;
918	    id = TAILQ_FIRST(&idtab->idlist)) {
919		TAILQ_REMOVE(&idtab->idlist, id, next);
920		free_identity(id);
921	}
922
923	/* Mark that there are no identities. */
924	idtab->nentries = 0;
925
926	/* Send success. */
927	send_status(e, 1);
928}
929
930/* removes expired keys and returns number of seconds until the next expiry */
931static time_t
932reaper(void)
933{
934	time_t deadline = 0, now = monotime();
935	Identity *id, *nxt;
936
937	for (id = TAILQ_FIRST(&idtab->idlist); id; id = nxt) {
938		nxt = TAILQ_NEXT(id, next);
939		if (id->death == 0)
940			continue;
941		if (now >= id->death) {
942			debug("expiring key '%s'", id->comment);
943			TAILQ_REMOVE(&idtab->idlist, id, next);
944			free_identity(id);
945			idtab->nentries--;
946		} else
947			deadline = (deadline == 0) ? id->death :
948			    MINIMUM(deadline, id->death);
949	}
950	if (deadline == 0 || deadline <= now)
951		return 0;
952	else
953		return (deadline - now);
954}
955
956static int
957parse_dest_constraint_hop(struct sshbuf *b, struct dest_constraint_hop *dch)
958{
959	u_char key_is_ca;
960	size_t elen = 0;
961	int r;
962	struct sshkey *k = NULL;
963	char *fp;
964
965	memset(dch, '\0', sizeof(*dch));
966	if ((r = sshbuf_get_cstring(b, &dch->user, NULL)) != 0 ||
967	    (r = sshbuf_get_cstring(b, &dch->hostname, NULL)) != 0 ||
968	    (r = sshbuf_get_string_direct(b, NULL, &elen)) != 0) {
969		error_fr(r, "parse");
970		goto out;
971	}
972	if (elen != 0) {
973		error_f("unsupported extensions (len %zu)", elen);
974		r = SSH_ERR_FEATURE_UNSUPPORTED;
975		goto out;
976	}
977	if (*dch->hostname == '\0') {
978		free(dch->hostname);
979		dch->hostname = NULL;
980	}
981	if (*dch->user == '\0') {
982		free(dch->user);
983		dch->user = NULL;
984	}
985	while (sshbuf_len(b) != 0) {
986		dch->keys = xrecallocarray(dch->keys, dch->nkeys,
987		    dch->nkeys + 1, sizeof(*dch->keys));
988		dch->key_is_ca = xrecallocarray(dch->key_is_ca, dch->nkeys,
989		    dch->nkeys + 1, sizeof(*dch->key_is_ca));
990		if ((r = sshkey_froms(b, &k)) != 0 ||
991		    (r = sshbuf_get_u8(b, &key_is_ca)) != 0)
992			goto out;
993		if ((fp = sshkey_fingerprint(k, SSH_FP_HASH_DEFAULT,
994		    SSH_FP_DEFAULT)) == NULL)
995			fatal_f("fingerprint failed");
996		debug3_f("%s%s%s: adding %skey %s %s",
997		    dch->user == NULL ? "" : dch->user,
998		    dch->user == NULL ? "" : "@",
999		    dch->hostname, key_is_ca ? "CA " : "", sshkey_type(k), fp);
1000		free(fp);
1001		dch->keys[dch->nkeys] = k;
1002		dch->key_is_ca[dch->nkeys] = key_is_ca != 0;
1003		dch->nkeys++;
1004		k = NULL; /* transferred */
1005	}
1006	/* success */
1007	r = 0;
1008 out:
1009	sshkey_free(k);
1010	return r;
1011}
1012
1013static int
1014parse_dest_constraint(struct sshbuf *m, struct dest_constraint *dc)
1015{
1016	struct sshbuf *b = NULL, *frombuf = NULL, *tobuf = NULL;
1017	int r;
1018	size_t elen = 0;
1019
1020	debug3_f("entering");
1021
1022	memset(dc, '\0', sizeof(*dc));
1023	if ((r = sshbuf_froms(m, &b)) != 0 ||
1024	    (r = sshbuf_froms(b, &frombuf)) != 0 ||
1025	    (r = sshbuf_froms(b, &tobuf)) != 0 ||
1026	    (r = sshbuf_get_string_direct(b, NULL, &elen)) != 0) {
1027		error_fr(r, "parse");
1028		goto out;
1029	}
1030	if ((r = parse_dest_constraint_hop(frombuf, &dc->from) != 0) ||
1031	    (r = parse_dest_constraint_hop(tobuf, &dc->to) != 0))
1032		goto out; /* already logged */
1033	if (elen != 0) {
1034		error_f("unsupported extensions (len %zu)", elen);
1035		r = SSH_ERR_FEATURE_UNSUPPORTED;
1036		goto out;
1037	}
1038	debug2_f("parsed %s (%u keys) > %s%s%s (%u keys)",
1039	    dc->from.hostname ? dc->from.hostname : "(ORIGIN)", dc->from.nkeys,
1040	    dc->to.user ? dc->to.user : "", dc->to.user ? "@" : "",
1041	    dc->to.hostname ? dc->to.hostname : "(ANY)", dc->to.nkeys);
1042	/* check consistency */
1043	if ((dc->from.hostname == NULL) != (dc->from.nkeys == 0) ||
1044	    dc->from.user != NULL) {
1045		error_f("inconsistent \"from\" specification");
1046		r = SSH_ERR_INVALID_FORMAT;
1047		goto out;
1048	}
1049	if (dc->to.hostname == NULL || dc->to.nkeys == 0) {
1050		error_f("incomplete \"to\" specification");
1051		r = SSH_ERR_INVALID_FORMAT;
1052		goto out;
1053	}
1054	/* success */
1055	r = 0;
1056 out:
1057	sshbuf_free(b);
1058	sshbuf_free(frombuf);
1059	sshbuf_free(tobuf);
1060	return r;
1061}
1062
1063static int
1064parse_key_constraint_extension(struct sshbuf *m, char **sk_providerp,
1065    struct dest_constraint **dcsp, size_t *ndcsp)
1066{
1067	char *ext_name = NULL;
1068	int r;
1069	struct sshbuf *b = NULL;
1070
1071	if ((r = sshbuf_get_cstring(m, &ext_name, NULL)) != 0) {
1072		error_fr(r, "parse constraint extension");
1073		goto out;
1074	}
1075	debug_f("constraint ext %s", ext_name);
1076	if (strcmp(ext_name, "sk-provider@openssh.com") == 0) {
1077		if (sk_providerp == NULL) {
1078			error_f("%s not valid here", ext_name);
1079			r = SSH_ERR_INVALID_FORMAT;
1080			goto out;
1081		}
1082		if (*sk_providerp != NULL) {
1083			error_f("%s already set", ext_name);
1084			r = SSH_ERR_INVALID_FORMAT;
1085			goto out;
1086		}
1087		if ((r = sshbuf_get_cstring(m, sk_providerp, NULL)) != 0) {
1088			error_fr(r, "parse %s", ext_name);
1089			goto out;
1090		}
1091	} else if (strcmp(ext_name,
1092	    "restrict-destination-v00@openssh.com") == 0) {
1093		if (*dcsp != NULL) {
1094			error_f("%s already set", ext_name);
1095			goto out;
1096		}
1097		if ((r = sshbuf_froms(m, &b)) != 0) {
1098			error_fr(r, "parse %s outer", ext_name);
1099			goto out;
1100		}
1101		while (sshbuf_len(b) != 0) {
1102			if (*ndcsp >= AGENT_MAX_DEST_CONSTRAINTS) {
1103				error_f("too many %s constraints", ext_name);
1104				goto out;
1105			}
1106			*dcsp = xrecallocarray(*dcsp, *ndcsp, *ndcsp + 1,
1107			    sizeof(**dcsp));
1108			if ((r = parse_dest_constraint(b,
1109			    *dcsp + (*ndcsp)++)) != 0)
1110				goto out; /* error already logged */
1111		}
1112	} else {
1113		error_f("unsupported constraint \"%s\"", ext_name);
1114		r = SSH_ERR_FEATURE_UNSUPPORTED;
1115		goto out;
1116	}
1117	/* success */
1118	r = 0;
1119 out:
1120	free(ext_name);
1121	sshbuf_free(b);
1122	return r;
1123}
1124
1125static int
1126parse_key_constraints(struct sshbuf *m, struct sshkey *k, time_t *deathp,
1127    u_int *secondsp, int *confirmp, char **sk_providerp,
1128    struct dest_constraint **dcsp, size_t *ndcsp)
1129{
1130	u_char ctype;
1131	int r;
1132	u_int seconds, maxsign = 0;
1133
1134	while (sshbuf_len(m)) {
1135		if ((r = sshbuf_get_u8(m, &ctype)) != 0) {
1136			error_fr(r, "parse constraint type");
1137			goto out;
1138		}
1139		switch (ctype) {
1140		case SSH_AGENT_CONSTRAIN_LIFETIME:
1141			if (*deathp != 0) {
1142				error_f("lifetime already set");
1143				r = SSH_ERR_INVALID_FORMAT;
1144				goto out;
1145			}
1146			if ((r = sshbuf_get_u32(m, &seconds)) != 0) {
1147				error_fr(r, "parse lifetime constraint");
1148				goto out;
1149			}
1150			*deathp = monotime() + seconds;
1151			*secondsp = seconds;
1152			break;
1153		case SSH_AGENT_CONSTRAIN_CONFIRM:
1154			if (*confirmp != 0) {
1155				error_f("confirm already set");
1156				r = SSH_ERR_INVALID_FORMAT;
1157				goto out;
1158			}
1159			*confirmp = 1;
1160			break;
1161		case SSH_AGENT_CONSTRAIN_MAXSIGN:
1162			if (k == NULL) {
1163				error_f("maxsign not valid here");
1164				r = SSH_ERR_INVALID_FORMAT;
1165				goto out;
1166			}
1167			if (maxsign != 0) {
1168				error_f("maxsign already set");
1169				r = SSH_ERR_INVALID_FORMAT;
1170				goto out;
1171			}
1172			if ((r = sshbuf_get_u32(m, &maxsign)) != 0) {
1173				error_fr(r, "parse maxsign constraint");
1174				goto out;
1175			}
1176			if ((r = sshkey_enable_maxsign(k, maxsign)) != 0) {
1177				error_fr(r, "enable maxsign");
1178				goto out;
1179			}
1180			break;
1181		case SSH_AGENT_CONSTRAIN_EXTENSION:
1182			if ((r = parse_key_constraint_extension(m,
1183			    sk_providerp, dcsp, ndcsp)) != 0)
1184				goto out; /* error already logged */
1185			break;
1186		default:
1187			error_f("Unknown constraint %d", ctype);
1188			r = SSH_ERR_FEATURE_UNSUPPORTED;
1189			goto out;
1190		}
1191	}
1192	/* success */
1193	r = 0;
1194 out:
1195	return r;
1196}
1197
1198static void
1199process_add_identity(SocketEntry *e)
1200{
1201	Identity *id;
1202	int success = 0, confirm = 0;
1203	char *fp, *comment = NULL, *sk_provider = NULL;
1204	char canonical_provider[PATH_MAX];
1205	time_t death = 0;
1206	u_int seconds = 0;
1207	struct dest_constraint *dest_constraints = NULL;
1208	size_t ndest_constraints = 0;
1209	struct sshkey *k = NULL;
1210	int r = SSH_ERR_INTERNAL_ERROR;
1211
1212	debug2_f("entering");
1213	if ((r = sshkey_private_deserialize(e->request, &k)) != 0 ||
1214	    k == NULL ||
1215	    (r = sshbuf_get_cstring(e->request, &comment, NULL)) != 0) {
1216		error_fr(r, "parse");
1217		goto out;
1218	}
1219	if (parse_key_constraints(e->request, k, &death, &seconds, &confirm,
1220	    &sk_provider, &dest_constraints, &ndest_constraints) != 0) {
1221		error_f("failed to parse constraints");
1222		sshbuf_reset(e->request);
1223		goto out;
1224	}
1225
1226	if (sk_provider != NULL) {
1227		if (!sshkey_is_sk(k)) {
1228			error("Cannot add provider: %s is not an "
1229			    "authenticator-hosted key", sshkey_type(k));
1230			goto out;
1231		}
1232		if (strcasecmp(sk_provider, "internal") == 0) {
1233			debug_f("internal provider");
1234		} else {
1235			if (realpath(sk_provider, canonical_provider) == NULL) {
1236				verbose("failed provider \"%.100s\": "
1237				    "realpath: %s", sk_provider,
1238				    strerror(errno));
1239				goto out;
1240			}
1241			free(sk_provider);
1242			sk_provider = xstrdup(canonical_provider);
1243			if (match_pattern_list(sk_provider,
1244			    allowed_providers, 0) != 1) {
1245				error("Refusing add key: "
1246				    "provider %s not allowed", sk_provider);
1247				goto out;
1248			}
1249		}
1250	}
1251	if ((r = sshkey_shield_private(k)) != 0) {
1252		error_fr(r, "shield private");
1253		goto out;
1254	}
1255	if (lifetime && !death)
1256		death = monotime() + lifetime;
1257	if ((id = lookup_identity(k)) == NULL) {
1258		id = xcalloc(1, sizeof(Identity));
1259		TAILQ_INSERT_TAIL(&idtab->idlist, id, next);
1260		/* Increment the number of identities. */
1261		idtab->nentries++;
1262	} else {
1263		/* identity not visible, do not update */
1264		if (identity_permitted(id, e, NULL, NULL, NULL) != 0)
1265			goto out; /* error already logged */
1266		/* key state might have been updated */
1267		sshkey_free(id->key);
1268		free(id->comment);
1269		free(id->sk_provider);
1270		free_dest_constraints(id->dest_constraints,
1271		    id->ndest_constraints);
1272	}
1273	/* success */
1274	id->key = k;
1275	id->comment = comment;
1276	id->death = death;
1277	id->confirm = confirm;
1278	id->sk_provider = sk_provider;
1279	id->dest_constraints = dest_constraints;
1280	id->ndest_constraints = ndest_constraints;
1281
1282	if ((fp = sshkey_fingerprint(k, SSH_FP_HASH_DEFAULT,
1283	    SSH_FP_DEFAULT)) == NULL)
1284		fatal_f("sshkey_fingerprint failed");
1285	debug_f("add %s %s \"%.100s\" (life: %u) (confirm: %u) "
1286	    "(provider: %s) (destination constraints: %zu)",
1287	    sshkey_ssh_name(k), fp, comment, seconds, confirm,
1288	    sk_provider == NULL ? "none" : sk_provider, ndest_constraints);
1289	free(fp);
1290	/* transferred */
1291	k = NULL;
1292	comment = NULL;
1293	sk_provider = NULL;
1294	dest_constraints = NULL;
1295	ndest_constraints = 0;
1296	success = 1;
1297 out:
1298	free(sk_provider);
1299	free(comment);
1300	sshkey_free(k);
1301	free_dest_constraints(dest_constraints, ndest_constraints);
1302	send_status(e, success);
1303}
1304
1305/* XXX todo: encrypt sensitive data with passphrase */
1306static void
1307process_lock_agent(SocketEntry *e, int lock)
1308{
1309	int r, success = 0, delay;
1310	char *passwd;
1311	u_char passwdhash[LOCK_SIZE];
1312	static u_int fail_count = 0;
1313	size_t pwlen;
1314
1315	debug2_f("entering");
1316	/*
1317	 * This is deliberately fatal: the user has requested that we lock,
1318	 * but we can't parse their request properly. The only safe thing to
1319	 * do is abort.
1320	 */
1321	if ((r = sshbuf_get_cstring(e->request, &passwd, &pwlen)) != 0)
1322		fatal_fr(r, "parse");
1323	if (pwlen == 0) {
1324		debug("empty password not supported");
1325	} else if (locked && !lock) {
1326		if (bcrypt_pbkdf(passwd, pwlen, (uint8_t *)lock_salt, sizeof(lock_salt),
1327		    (uint8_t *)passwdhash, sizeof(passwdhash), LOCK_ROUNDS) < 0)
1328			fatal("bcrypt_pbkdf");
1329		if (timingsafe_bcmp(passwdhash, lock_pwhash, LOCK_SIZE) == 0) {
1330			debug("agent unlocked");
1331			locked = 0;
1332			fail_count = 0;
1333			explicit_bzero(lock_pwhash, sizeof(lock_pwhash));
1334			success = 1;
1335		} else {
1336			/* delay in 0.1s increments up to 10s */
1337			if (fail_count < 100)
1338				fail_count++;
1339			delay = 100000 * fail_count;
1340			debug("unlock failed, delaying %0.1lf seconds",
1341			    (double)delay/1000000);
1342			usleep(delay);
1343		}
1344		explicit_bzero(passwdhash, sizeof(passwdhash));
1345	} else if (!locked && lock) {
1346		debug("agent locked");
1347		locked = 1;
1348		arc4random_buf(lock_salt, sizeof(lock_salt));
1349		if (bcrypt_pbkdf(passwd, pwlen, lock_salt, sizeof(lock_salt),
1350		    lock_pwhash, sizeof(lock_pwhash), LOCK_ROUNDS) < 0)
1351			fatal("bcrypt_pbkdf");
1352		success = 1;
1353	}
1354	freezero(passwd, pwlen);
1355	send_status(e, success);
1356}
1357
1358static void
1359no_identities(SocketEntry *e)
1360{
1361	struct sshbuf *msg;
1362	int r;
1363
1364	if ((msg = sshbuf_new()) == NULL)
1365		fatal_f("sshbuf_new failed");
1366	if ((r = sshbuf_put_u8(msg, SSH2_AGENT_IDENTITIES_ANSWER)) != 0 ||
1367	    (r = sshbuf_put_u32(msg, 0)) != 0 ||
1368	    (r = sshbuf_put_stringb(e->output, msg)) != 0)
1369		fatal_fr(r, "compose");
1370	sshbuf_free(msg);
1371}
1372
1373#ifdef ENABLE_PKCS11
1374static void
1375process_add_smartcard_key(SocketEntry *e)
1376{
1377	char *provider = NULL, *pin = NULL, canonical_provider[PATH_MAX];
1378	char **comments = NULL;
1379	int r, i, count = 0, success = 0, confirm = 0;
1380	u_int seconds = 0;
1381	time_t death = 0;
1382	struct sshkey **keys = NULL, *k;
1383	Identity *id;
1384	struct dest_constraint *dest_constraints = NULL;
1385	size_t ndest_constraints = 0;
1386
1387	debug2_f("entering");
1388	if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 ||
1389	    (r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0) {
1390		error_fr(r, "parse");
1391		goto send;
1392	}
1393	if (parse_key_constraints(e->request, NULL, &death, &seconds, &confirm,
1394	    NULL, &dest_constraints, &ndest_constraints) != 0) {
1395		error_f("failed to parse constraints");
1396		goto send;
1397	}
1398	if (realpath(provider, canonical_provider) == NULL) {
1399		verbose("failed PKCS#11 add of \"%.100s\": realpath: %s",
1400		    provider, strerror(errno));
1401		goto send;
1402	}
1403	if (match_pattern_list(canonical_provider, allowed_providers, 0) != 1) {
1404		verbose("refusing PKCS#11 add of \"%.100s\": "
1405		    "provider not allowed", canonical_provider);
1406		goto send;
1407	}
1408	debug_f("add %.100s", canonical_provider);
1409	if (lifetime && !death)
1410		death = monotime() + lifetime;
1411
1412	count = pkcs11_add_provider(canonical_provider, pin, &keys, &comments);
1413	for (i = 0; i < count; i++) {
1414		k = keys[i];
1415		if (lookup_identity(k) == NULL) {
1416			id = xcalloc(1, sizeof(Identity));
1417			id->key = k;
1418			keys[i] = NULL; /* transferred */
1419			id->provider = xstrdup(canonical_provider);
1420			if (*comments[i] != '\0') {
1421				id->comment = comments[i];
1422				comments[i] = NULL; /* transferred */
1423			} else {
1424				id->comment = xstrdup(canonical_provider);
1425			}
1426			id->death = death;
1427			id->confirm = confirm;
1428			id->dest_constraints = dest_constraints;
1429			id->ndest_constraints = ndest_constraints;
1430			dest_constraints = NULL; /* transferred */
1431			ndest_constraints = 0;
1432			TAILQ_INSERT_TAIL(&idtab->idlist, id, next);
1433			idtab->nentries++;
1434			success = 1;
1435		}
1436		/* XXX update constraints for existing keys */
1437		sshkey_free(keys[i]);
1438		free(comments[i]);
1439	}
1440send:
1441	free(pin);
1442	free(provider);
1443	free(keys);
1444	free(comments);
1445	free_dest_constraints(dest_constraints, ndest_constraints);
1446	send_status(e, success);
1447}
1448
1449static void
1450process_remove_smartcard_key(SocketEntry *e)
1451{
1452	char *provider = NULL, *pin = NULL, canonical_provider[PATH_MAX];
1453	int r, success = 0;
1454	Identity *id, *nxt;
1455
1456	debug2_f("entering");
1457	if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 ||
1458	    (r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0) {
1459		error_fr(r, "parse");
1460		goto send;
1461	}
1462	free(pin);
1463
1464	if (realpath(provider, canonical_provider) == NULL) {
1465		verbose("failed PKCS#11 add of \"%.100s\": realpath: %s",
1466		    provider, strerror(errno));
1467		goto send;
1468	}
1469
1470	debug_f("remove %.100s", canonical_provider);
1471	for (id = TAILQ_FIRST(&idtab->idlist); id; id = nxt) {
1472		nxt = TAILQ_NEXT(id, next);
1473		/* Skip file--based keys */
1474		if (id->provider == NULL)
1475			continue;
1476		if (!strcmp(canonical_provider, id->provider)) {
1477			TAILQ_REMOVE(&idtab->idlist, id, next);
1478			free_identity(id);
1479			idtab->nentries--;
1480		}
1481	}
1482	if (pkcs11_del_provider(canonical_provider) == 0)
1483		success = 1;
1484	else
1485		error_f("pkcs11_del_provider failed");
1486send:
1487	free(provider);
1488	send_status(e, success);
1489}
1490#endif /* ENABLE_PKCS11 */
1491
1492static int
1493process_ext_session_bind(SocketEntry *e)
1494{
1495	int r, sid_match, key_match;
1496	struct sshkey *key = NULL;
1497	struct sshbuf *sid = NULL, *sig = NULL;
1498	char *fp = NULL;
1499	size_t i;
1500	u_char fwd = 0;
1501
1502	debug2_f("entering");
1503	if ((r = sshkey_froms(e->request, &key)) != 0 ||
1504	    (r = sshbuf_froms(e->request, &sid)) != 0 ||
1505	    (r = sshbuf_froms(e->request, &sig)) != 0 ||
1506	    (r = sshbuf_get_u8(e->request, &fwd)) != 0) {
1507		error_fr(r, "parse");
1508		goto out;
1509	}
1510	if ((fp = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT,
1511	    SSH_FP_DEFAULT)) == NULL)
1512		fatal_f("fingerprint failed");
1513	/* check signature with hostkey on session ID */
1514	if ((r = sshkey_verify(key, sshbuf_ptr(sig), sshbuf_len(sig),
1515	    sshbuf_ptr(sid), sshbuf_len(sid), NULL, 0, NULL)) != 0) {
1516		error_fr(r, "sshkey_verify for %s %s", sshkey_type(key), fp);
1517		goto out;
1518	}
1519	/* check whether sid/key already recorded */
1520	for (i = 0; i < e->nsession_ids; i++) {
1521		if (!e->session_ids[i].forwarded) {
1522			error_f("attempt to bind session ID to socket "
1523			    "previously bound for authentication attempt");
1524			r = -1;
1525			goto out;
1526		}
1527		sid_match = buf_equal(sid, e->session_ids[i].sid) == 0;
1528		key_match = sshkey_equal(key, e->session_ids[i].key);
1529		if (sid_match && key_match) {
1530			debug_f("session ID already recorded for %s %s",
1531			    sshkey_type(key), fp);
1532			r = 0;
1533			goto out;
1534		} else if (sid_match) {
1535			error_f("session ID recorded against different key "
1536			    "for %s %s", sshkey_type(key), fp);
1537			r = -1;
1538			goto out;
1539		}
1540		/*
1541		 * new sid with previously-seen key can happen, e.g. multiple
1542		 * connections to the same host.
1543		 */
1544	}
1545	/* record new key/sid */
1546	if (e->nsession_ids >= AGENT_MAX_SESSION_IDS) {
1547		error_f("too many session IDs recorded");
1548		goto out;
1549	}
1550	e->session_ids = xrecallocarray(e->session_ids, e->nsession_ids,
1551	    e->nsession_ids + 1, sizeof(*e->session_ids));
1552	i = e->nsession_ids++;
1553	debug_f("recorded %s %s (slot %zu of %d)", sshkey_type(key), fp, i,
1554	    AGENT_MAX_SESSION_IDS);
1555	e->session_ids[i].key = key;
1556	e->session_ids[i].forwarded = fwd != 0;
1557	key = NULL; /* transferred */
1558	/* can't transfer sid; it's refcounted and scoped to request's life */
1559	if ((e->session_ids[i].sid = sshbuf_new()) == NULL)
1560		fatal_f("sshbuf_new");
1561	if ((r = sshbuf_putb(e->session_ids[i].sid, sid)) != 0)
1562		fatal_fr(r, "sshbuf_putb session ID");
1563	/* success */
1564	r = 0;
1565 out:
1566	sshkey_free(key);
1567	sshbuf_free(sid);
1568	sshbuf_free(sig);
1569	return r == 0 ? 1 : 0;
1570}
1571
1572static void
1573process_extension(SocketEntry *e)
1574{
1575	int r, success = 0;
1576	char *name;
1577
1578	debug2_f("entering");
1579	if ((r = sshbuf_get_cstring(e->request, &name, NULL)) != 0) {
1580		error_fr(r, "parse");
1581		goto send;
1582	}
1583	if (strcmp(name, "session-bind@openssh.com") == 0)
1584		success = process_ext_session_bind(e);
1585	else
1586		debug_f("unsupported extension \"%s\"", name);
1587	free(name);
1588send:
1589	send_status(e, success);
1590}
1591/*
1592 * dispatch incoming message.
1593 * returns 1 on success, 0 for incomplete messages or -1 on error.
1594 */
1595static int
1596process_message(u_int socknum)
1597{
1598	u_int msg_len;
1599	u_char type;
1600	const u_char *cp;
1601	int r;
1602	SocketEntry *e;
1603
1604	if (socknum >= sockets_alloc)
1605		fatal_f("sock %u >= allocated %u", socknum, sockets_alloc);
1606	e = &sockets[socknum];
1607
1608	if (sshbuf_len(e->input) < 5)
1609		return 0;		/* Incomplete message header. */
1610	cp = sshbuf_ptr(e->input);
1611	msg_len = PEEK_U32(cp);
1612	if (msg_len > AGENT_MAX_LEN) {
1613		debug_f("socket %u (fd=%d) message too long %u > %u",
1614		    socknum, e->fd, msg_len, AGENT_MAX_LEN);
1615		return -1;
1616	}
1617	if (sshbuf_len(e->input) < msg_len + 4)
1618		return 0;		/* Incomplete message body. */
1619
1620	/* move the current input to e->request */
1621	sshbuf_reset(e->request);
1622	if ((r = sshbuf_get_stringb(e->input, e->request)) != 0 ||
1623	    (r = sshbuf_get_u8(e->request, &type)) != 0) {
1624		if (r == SSH_ERR_MESSAGE_INCOMPLETE ||
1625		    r == SSH_ERR_STRING_TOO_LARGE) {
1626			error_fr(r, "parse");
1627			return -1;
1628		}
1629		fatal_fr(r, "parse");
1630	}
1631
1632	debug_f("socket %u (fd=%d) type %d", socknum, e->fd, type);
1633
1634	/* check whether agent is locked */
1635	if (locked && type != SSH_AGENTC_UNLOCK) {
1636		sshbuf_reset(e->request);
1637		switch (type) {
1638		case SSH2_AGENTC_REQUEST_IDENTITIES:
1639			/* send empty lists */
1640			no_identities(e);
1641			break;
1642		default:
1643			/* send a fail message for all other request types */
1644			send_status(e, 0);
1645		}
1646		return 1;
1647	}
1648
1649	switch (type) {
1650	case SSH_AGENTC_LOCK:
1651	case SSH_AGENTC_UNLOCK:
1652		process_lock_agent(e, type == SSH_AGENTC_LOCK);
1653		break;
1654	case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES:
1655		process_remove_all_identities(e); /* safe for !WITH_SSH1 */
1656		break;
1657	/* ssh2 */
1658	case SSH2_AGENTC_SIGN_REQUEST:
1659		process_sign_request2(e);
1660		break;
1661	case SSH2_AGENTC_REQUEST_IDENTITIES:
1662		process_request_identities(e);
1663		break;
1664	case SSH2_AGENTC_ADD_IDENTITY:
1665	case SSH2_AGENTC_ADD_ID_CONSTRAINED:
1666		process_add_identity(e);
1667		break;
1668	case SSH2_AGENTC_REMOVE_IDENTITY:
1669		process_remove_identity(e);
1670		break;
1671	case SSH2_AGENTC_REMOVE_ALL_IDENTITIES:
1672		process_remove_all_identities(e);
1673		break;
1674#ifdef ENABLE_PKCS11
1675	case SSH_AGENTC_ADD_SMARTCARD_KEY:
1676	case SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED:
1677		process_add_smartcard_key(e);
1678		break;
1679	case SSH_AGENTC_REMOVE_SMARTCARD_KEY:
1680		process_remove_smartcard_key(e);
1681		break;
1682#endif /* ENABLE_PKCS11 */
1683	case SSH_AGENTC_EXTENSION:
1684		process_extension(e);
1685		break;
1686	default:
1687		/* Unknown message.  Respond with failure. */
1688		error("Unknown message %d", type);
1689		sshbuf_reset(e->request);
1690		send_status(e, 0);
1691		break;
1692	}
1693	return 1;
1694}
1695
1696static void
1697new_socket(sock_type type, int fd)
1698{
1699	u_int i, old_alloc, new_alloc;
1700
1701	debug_f("type = %s", type == AUTH_CONNECTION ? "CONNECTION" :
1702	    (type == AUTH_SOCKET ? "SOCKET" : "UNKNOWN"));
1703	set_nonblock(fd);
1704
1705	if (fd > max_fd)
1706		max_fd = fd;
1707
1708	for (i = 0; i < sockets_alloc; i++)
1709		if (sockets[i].type == AUTH_UNUSED) {
1710			sockets[i].fd = fd;
1711			if ((sockets[i].input = sshbuf_new()) == NULL ||
1712			    (sockets[i].output = sshbuf_new()) == NULL ||
1713			    (sockets[i].request = sshbuf_new()) == NULL)
1714				fatal_f("sshbuf_new failed");
1715			sockets[i].type = type;
1716			return;
1717		}
1718	old_alloc = sockets_alloc;
1719	new_alloc = sockets_alloc + 10;
1720	sockets = xrecallocarray(sockets, old_alloc, new_alloc,
1721	    sizeof(sockets[0]));
1722	for (i = old_alloc; i < new_alloc; i++)
1723		sockets[i].type = AUTH_UNUSED;
1724	sockets_alloc = new_alloc;
1725	sockets[old_alloc].fd = fd;
1726	if ((sockets[old_alloc].input = sshbuf_new()) == NULL ||
1727	    (sockets[old_alloc].output = sshbuf_new()) == NULL ||
1728	    (sockets[old_alloc].request = sshbuf_new()) == NULL)
1729		fatal_f("sshbuf_new failed");
1730	sockets[old_alloc].type = type;
1731}
1732
1733static int
1734handle_socket_read(u_int socknum)
1735{
1736	struct sockaddr_un sunaddr;
1737	socklen_t slen;
1738	uid_t euid;
1739	gid_t egid;
1740	int fd;
1741
1742	slen = sizeof(sunaddr);
1743	fd = accept(sockets[socknum].fd, (struct sockaddr *)&sunaddr, &slen);
1744	if (fd == -1) {
1745		error("accept from AUTH_SOCKET: %s", strerror(errno));
1746		return -1;
1747	}
1748	if (getpeereid(fd, &euid, &egid) == -1) {
1749		error("getpeereid %d failed: %s", fd, strerror(errno));
1750		close(fd);
1751		return -1;
1752	}
1753	if ((euid != 0) && (getuid() != euid)) {
1754		error("uid mismatch: peer euid %u != uid %u",
1755		    (u_int) euid, (u_int) getuid());
1756		close(fd);
1757		return -1;
1758	}
1759	new_socket(AUTH_CONNECTION, fd);
1760	return 0;
1761}
1762
1763static int
1764handle_conn_read(u_int socknum)
1765{
1766	char buf[AGENT_RBUF_LEN];
1767	ssize_t len;
1768	int r;
1769
1770	if ((len = read(sockets[socknum].fd, buf, sizeof(buf))) <= 0) {
1771		if (len == -1) {
1772			if (errno == EAGAIN || errno == EINTR)
1773				return 0;
1774			error_f("read error on socket %u (fd %d): %s",
1775			    socknum, sockets[socknum].fd, strerror(errno));
1776		}
1777		return -1;
1778	}
1779	if ((r = sshbuf_put(sockets[socknum].input, buf, len)) != 0)
1780		fatal_fr(r, "compose");
1781	explicit_bzero(buf, sizeof(buf));
1782	for (;;) {
1783		if ((r = process_message(socknum)) == -1)
1784			return -1;
1785		else if (r == 0)
1786			break;
1787	}
1788	return 0;
1789}
1790
1791static int
1792handle_conn_write(u_int socknum)
1793{
1794	ssize_t len;
1795	int r;
1796
1797	if (sshbuf_len(sockets[socknum].output) == 0)
1798		return 0; /* shouldn't happen */
1799	if ((len = write(sockets[socknum].fd,
1800	    sshbuf_ptr(sockets[socknum].output),
1801	    sshbuf_len(sockets[socknum].output))) <= 0) {
1802		if (len == -1) {
1803			if (errno == EAGAIN || errno == EINTR)
1804				return 0;
1805			error_f("read error on socket %u (fd %d): %s",
1806			    socknum, sockets[socknum].fd, strerror(errno));
1807		}
1808		return -1;
1809	}
1810	if ((r = sshbuf_consume(sockets[socknum].output, len)) != 0)
1811		fatal_fr(r, "consume");
1812	return 0;
1813}
1814
1815static void
1816after_poll(struct pollfd *pfd, size_t npfd, u_int maxfds)
1817{
1818	size_t i;
1819	u_int socknum, activefds = npfd;
1820
1821	for (i = 0; i < npfd; i++) {
1822		if (pfd[i].revents == 0)
1823			continue;
1824		/* Find sockets entry */
1825		for (socknum = 0; socknum < sockets_alloc; socknum++) {
1826			if (sockets[socknum].type != AUTH_SOCKET &&
1827			    sockets[socknum].type != AUTH_CONNECTION)
1828				continue;
1829			if (pfd[i].fd == sockets[socknum].fd)
1830				break;
1831		}
1832		if (socknum >= sockets_alloc) {
1833			error_f("no socket for fd %d", pfd[i].fd);
1834			continue;
1835		}
1836		/* Process events */
1837		switch (sockets[socknum].type) {
1838		case AUTH_SOCKET:
1839			if ((pfd[i].revents & (POLLIN|POLLERR)) == 0)
1840				break;
1841			if (npfd > maxfds) {
1842				debug3("out of fds (active %u >= limit %u); "
1843				    "skipping accept", activefds, maxfds);
1844				break;
1845			}
1846			if (handle_socket_read(socknum) == 0)
1847				activefds++;
1848			break;
1849		case AUTH_CONNECTION:
1850			if ((pfd[i].revents & (POLLIN|POLLHUP|POLLERR)) != 0 &&
1851			    handle_conn_read(socknum) != 0)
1852				goto close_sock;
1853			if ((pfd[i].revents & (POLLOUT|POLLHUP)) != 0 &&
1854			    handle_conn_write(socknum) != 0) {
1855 close_sock:
1856				if (activefds == 0)
1857					fatal("activefds == 0 at close_sock");
1858				close_socket(&sockets[socknum]);
1859				activefds--;
1860				break;
1861			}
1862			break;
1863		default:
1864			break;
1865		}
1866	}
1867}
1868
1869static int
1870prepare_poll(struct pollfd **pfdp, size_t *npfdp, int *timeoutp, u_int maxfds)
1871{
1872	struct pollfd *pfd = *pfdp;
1873	size_t i, j, npfd = 0;
1874	time_t deadline;
1875	int r;
1876
1877	/* Count active sockets */
1878	for (i = 0; i < sockets_alloc; i++) {
1879		switch (sockets[i].type) {
1880		case AUTH_SOCKET:
1881		case AUTH_CONNECTION:
1882			npfd++;
1883			break;
1884		case AUTH_UNUSED:
1885			break;
1886		default:
1887			fatal("Unknown socket type %d", sockets[i].type);
1888			break;
1889		}
1890	}
1891	if (npfd != *npfdp &&
1892	    (pfd = recallocarray(pfd, *npfdp, npfd, sizeof(*pfd))) == NULL)
1893		fatal_f("recallocarray failed");
1894	*pfdp = pfd;
1895	*npfdp = npfd;
1896
1897	for (i = j = 0; i < sockets_alloc; i++) {
1898		switch (sockets[i].type) {
1899		case AUTH_SOCKET:
1900			if (npfd > maxfds) {
1901				debug3("out of fds (active %zu >= limit %u); "
1902				    "skipping arming listener", npfd, maxfds);
1903				break;
1904			}
1905			pfd[j].fd = sockets[i].fd;
1906			pfd[j].revents = 0;
1907			pfd[j].events = POLLIN;
1908			j++;
1909			break;
1910		case AUTH_CONNECTION:
1911			pfd[j].fd = sockets[i].fd;
1912			pfd[j].revents = 0;
1913			/*
1914			 * Only prepare to read if we can handle a full-size
1915			 * input read buffer and enqueue a max size reply..
1916			 */
1917			if ((r = sshbuf_check_reserve(sockets[i].input,
1918			    AGENT_RBUF_LEN)) == 0 &&
1919			    (r = sshbuf_check_reserve(sockets[i].output,
1920			    AGENT_MAX_LEN)) == 0)
1921				pfd[j].events = POLLIN;
1922			else if (r != SSH_ERR_NO_BUFFER_SPACE)
1923				fatal_fr(r, "reserve");
1924			if (sshbuf_len(sockets[i].output) > 0)
1925				pfd[j].events |= POLLOUT;
1926			j++;
1927			break;
1928		default:
1929			break;
1930		}
1931	}
1932	deadline = reaper();
1933	if (parent_alive_interval != 0)
1934		deadline = (deadline == 0) ? parent_alive_interval :
1935		    MINIMUM(deadline, parent_alive_interval);
1936	if (deadline == 0) {
1937		*timeoutp = -1; /* INFTIM */
1938	} else {
1939		if (deadline > INT_MAX / 1000)
1940			*timeoutp = INT_MAX / 1000;
1941		else
1942			*timeoutp = deadline * 1000;
1943	}
1944	return (1);
1945}
1946
1947static void
1948cleanup_socket(void)
1949{
1950	if (cleanup_pid != 0 && getpid() != cleanup_pid)
1951		return;
1952	debug_f("cleanup");
1953	if (socket_name[0])
1954		unlink(socket_name);
1955	if (socket_dir[0])
1956		rmdir(socket_dir);
1957}
1958
1959void
1960cleanup_exit(int i)
1961{
1962	cleanup_socket();
1963	_exit(i);
1964}
1965
1966/*ARGSUSED*/
1967__dead static void
1968cleanup_handler(int sig)
1969{
1970	cleanup_socket();
1971#ifdef ENABLE_PKCS11
1972	pkcs11_terminate();
1973#endif
1974	_exit(2);
1975}
1976
1977static void
1978check_parent_exists(void)
1979{
1980	/*
1981	 * If our parent has exited then getppid() will return (pid_t)1,
1982	 * so testing for that should be safe.
1983	 */
1984	if (parent_pid != -1 && getppid() != parent_pid) {
1985		/* printf("Parent has died - Authentication agent exiting.\n"); */
1986		cleanup_socket();
1987		_exit(2);
1988	}
1989}
1990
1991__dead static void
1992usage(void)
1993{
1994	fprintf(stderr,
1995	    "usage: ssh-agent [-c | -s] [-Dd] [-a bind_address] [-E fingerprint_hash]\n"
1996	    "                 [-P allowed_providers] [-t life]\n"
1997	    "       ssh-agent [-a bind_address] [-E fingerprint_hash] [-P allowed_providers]\n"
1998	    "                 [-t life] command [arg ...]\n"
1999	    "       ssh-agent [-c | -s] -k\n");
2000	exit(1);
2001}
2002
2003static void
2004csh_setenv(const char *name, const char *value)
2005{
2006	printf("setenv %s %s;\n", name, value);
2007}
2008
2009static void
2010csh_unsetenv(const char *name)
2011{
2012	printf("unsetenv %s;\n", name);
2013}
2014
2015static void
2016sh_setenv(const char *name, const char *value)
2017{
2018	printf("%s=%s; export %s;\n", name, value, name);
2019}
2020
2021static void
2022sh_unsetenv(const char *name)
2023{
2024	printf("unset %s;\n", name);
2025}
2026int
2027main(int ac, char **av)
2028{
2029	int c_flag = 0, d_flag = 0, D_flag = 0, k_flag = 0, s_flag = 0;
2030	int sock, ch, result, saved_errno;
2031	char *shell, *pidstr, *agentsocket = NULL;
2032	struct rlimit rlim;
2033	void (*f_setenv)(const char *, const char *);
2034	void (*f_unsetenv)(const char *);
2035	extern int optind;
2036	extern char *optarg;
2037	pid_t pid;
2038	char pidstrbuf[1 + 3 * sizeof pid];
2039	size_t len;
2040	mode_t prev_mask;
2041	int timeout = -1; /* INFTIM */
2042	struct pollfd *pfd = NULL;
2043	size_t npfd = 0;
2044	u_int maxfds;
2045
2046	/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
2047	sanitise_stdfd();
2048
2049	/* drop */
2050	setegid(getgid());
2051	setgid(getgid());
2052
2053	if (getrlimit(RLIMIT_NOFILE, &rlim) == -1)
2054		fatal("%s: getrlimit: %s", __progname, strerror(errno));
2055
2056#ifdef WITH_OPENSSL
2057	OpenSSL_add_all_algorithms();
2058#endif
2059
2060	while ((ch = getopt(ac, av, "cDdksE:a:O:P:t:")) != -1) {
2061		switch (ch) {
2062		case 'E':
2063			fingerprint_hash = ssh_digest_alg_by_name(optarg);
2064			if (fingerprint_hash == -1)
2065				fatal("Invalid hash algorithm \"%s\"", optarg);
2066			break;
2067		case 'c':
2068			if (s_flag)
2069				usage();
2070			c_flag++;
2071			break;
2072		case 'k':
2073			k_flag++;
2074			break;
2075		case 'O':
2076			if (strcmp(optarg, "no-restrict-websafe") == 0)
2077				restrict_websafe  = 0;
2078			else
2079				fatal("Unknown -O option");
2080			break;
2081		case 'P':
2082			if (allowed_providers != NULL)
2083				fatal("-P option already specified");
2084			allowed_providers = xstrdup(optarg);
2085			break;
2086		case 's':
2087			if (c_flag)
2088				usage();
2089			s_flag++;
2090			break;
2091		case 'd':
2092			if (d_flag || D_flag)
2093				usage();
2094			d_flag++;
2095			break;
2096		case 'D':
2097			if (d_flag || D_flag)
2098				usage();
2099			D_flag++;
2100			break;
2101		case 'a':
2102			agentsocket = optarg;
2103			break;
2104		case 't':
2105			if ((lifetime = convtime(optarg)) == -1) {
2106				fprintf(stderr, "Invalid lifetime\n");
2107				usage();
2108			}
2109			break;
2110		default:
2111			usage();
2112		}
2113	}
2114	ac -= optind;
2115	av += optind;
2116
2117	if (ac > 0 && (c_flag || k_flag || s_flag || d_flag || D_flag))
2118		usage();
2119
2120	if (allowed_providers == NULL)
2121		allowed_providers = xstrdup(DEFAULT_ALLOWED_PROVIDERS);
2122
2123	if (ac == 0 && !c_flag && !s_flag) {
2124		shell = getenv("SHELL");
2125		if (shell != NULL && (len = strlen(shell)) > 2 &&
2126		    strncmp(shell + len - 3, "csh", 3) == 0)
2127			c_flag = 1;
2128	}
2129	if (c_flag) {
2130		f_setenv = csh_setenv;
2131		f_unsetenv = csh_unsetenv;
2132	} else {
2133		f_setenv = sh_setenv;
2134		f_unsetenv = sh_unsetenv;
2135	}
2136	if (k_flag) {
2137		const char *errstr = NULL;
2138
2139		pidstr = getenv(SSH_AGENTPID_ENV_NAME);
2140		if (pidstr == NULL) {
2141			fprintf(stderr, "%s not set, cannot kill agent\n",
2142			    SSH_AGENTPID_ENV_NAME);
2143			exit(1);
2144		}
2145		pid = (int)strtonum(pidstr, 2, INT_MAX, &errstr);
2146		if (errstr) {
2147			fprintf(stderr,
2148			    "%s=\"%s\", which is not a good PID: %s\n",
2149			    SSH_AGENTPID_ENV_NAME, pidstr, errstr);
2150			exit(1);
2151		}
2152		if (kill(pid, SIGTERM) == -1) {
2153			perror("kill");
2154			exit(1);
2155		}
2156		(*f_unsetenv)(SSH_AUTHSOCKET_ENV_NAME);
2157		(*f_unsetenv)(SSH_AGENTPID_ENV_NAME);
2158		printf("echo Agent pid %ld killed;\n", (long)pid);
2159		exit(0);
2160	}
2161
2162	/*
2163	 * Minimum file descriptors:
2164	 * stdio (3) + listener (1) + syslog (1 maybe) + connection (1) +
2165	 * a few spare for libc / stack protectors / sanitisers, etc.
2166	 */
2167#define SSH_AGENT_MIN_FDS (3+1+1+1+4)
2168	if (rlim.rlim_cur < SSH_AGENT_MIN_FDS)
2169		fatal("%s: file descriptor rlimit %lld too low (minimum %u)",
2170		    __progname, (long long)rlim.rlim_cur, SSH_AGENT_MIN_FDS);
2171	maxfds = rlim.rlim_cur - SSH_AGENT_MIN_FDS;
2172
2173	parent_pid = getpid();
2174
2175	if (agentsocket == NULL) {
2176		/* Create private directory for agent socket */
2177		mktemp_proto(socket_dir, sizeof(socket_dir));
2178		if (mkdtemp(socket_dir) == NULL) {
2179			perror("mkdtemp: private socket dir");
2180			exit(1);
2181		}
2182		snprintf(socket_name, sizeof socket_name, "%s/agent.%ld", socket_dir,
2183		    (long)parent_pid);
2184	} else {
2185		/* Try to use specified agent socket */
2186		socket_dir[0] = '\0';
2187		strlcpy(socket_name, agentsocket, sizeof socket_name);
2188	}
2189
2190	/*
2191	 * Create socket early so it will exist before command gets run from
2192	 * the parent.
2193	 */
2194	prev_mask = umask(0177);
2195	sock = unix_listener(socket_name, SSH_LISTEN_BACKLOG, 0);
2196	if (sock < 0) {
2197		/* XXX - unix_listener() calls error() not perror() */
2198		*socket_name = '\0'; /* Don't unlink any existing file */
2199		cleanup_exit(1);
2200	}
2201	umask(prev_mask);
2202
2203	/*
2204	 * Fork, and have the parent execute the command, if any, or present
2205	 * the socket data.  The child continues as the authentication agent.
2206	 */
2207	if (D_flag || d_flag) {
2208		log_init(__progname,
2209		    d_flag ? SYSLOG_LEVEL_DEBUG3 : SYSLOG_LEVEL_INFO,
2210		    SYSLOG_FACILITY_AUTH, 1);
2211		if (c_flag)
2212			printf("setenv %s %s;\n",
2213			    SSH_AUTHSOCKET_ENV_NAME, socket_name);
2214		else
2215			printf("%s=%s; export %s;\n",
2216			    SSH_AUTHSOCKET_ENV_NAME, socket_name,
2217			    SSH_AUTHSOCKET_ENV_NAME);
2218		printf("echo Agent pid %ld;\n", (long)parent_pid);
2219		fflush(stdout);
2220		goto skip;
2221	}
2222	pid = fork();
2223	if (pid == -1) {
2224		perror("fork");
2225		cleanup_exit(1);
2226	}
2227	if (pid != 0) {		/* Parent - execute the given command. */
2228		close(sock);
2229		snprintf(pidstrbuf, sizeof pidstrbuf, "%ld", (long)pid);
2230		if (ac == 0) {
2231			(*f_setenv)(SSH_AUTHSOCKET_ENV_NAME, socket_name);
2232			(*f_setenv)(SSH_AGENTPID_ENV_NAME, pidstrbuf);
2233			printf("echo Agent pid %ld;\n", (long)pid);
2234			exit(0);
2235		}
2236		if (setenv(SSH_AUTHSOCKET_ENV_NAME, socket_name, 1) == -1 ||
2237		    setenv(SSH_AGENTPID_ENV_NAME, pidstrbuf, 1) == -1) {
2238			perror("setenv");
2239			exit(1);
2240		}
2241		execvp(av[0], av);
2242		perror(av[0]);
2243		exit(1);
2244	}
2245	/* child */
2246	log_init(__progname, SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_AUTH, 0);
2247
2248	if (setsid() == -1) {
2249		error("setsid: %s", strerror(errno));
2250		cleanup_exit(1);
2251	}
2252
2253	(void)chdir("/");
2254	if (stdfd_devnull(1, 1, 1) == -1)
2255		error_f("stdfd_devnull failed");
2256
2257	/* deny core dumps, since memory contains unencrypted private keys */
2258	rlim.rlim_cur = rlim.rlim_max = 0;
2259	if (setrlimit(RLIMIT_CORE, &rlim) == -1) {
2260		error("setrlimit RLIMIT_CORE: %s", strerror(errno));
2261		cleanup_exit(1);
2262	}
2263
2264skip:
2265
2266	cleanup_pid = getpid();
2267
2268#ifdef ENABLE_PKCS11
2269	pkcs11_init(0);
2270#endif
2271	new_socket(AUTH_SOCKET, sock);
2272	if (ac > 0)
2273		parent_alive_interval = 10;
2274	idtab_init();
2275	ssh_signal(SIGPIPE, SIG_IGN);
2276	ssh_signal(SIGINT, (d_flag | D_flag) ? cleanup_handler : SIG_IGN);
2277	ssh_signal(SIGHUP, cleanup_handler);
2278	ssh_signal(SIGTERM, cleanup_handler);
2279
2280#ifdef __OpenBSD__
2281	if (pledge("stdio rpath cpath unix id proc exec", NULL) == -1)
2282		fatal("%s: pledge: %s", __progname, strerror(errno));
2283#endif
2284
2285	while (1) {
2286		prepare_poll(&pfd, &npfd, &timeout, maxfds);
2287		result = poll(pfd, npfd, timeout);
2288		saved_errno = errno;
2289		if (parent_alive_interval != 0)
2290			check_parent_exists();
2291		(void) reaper();	/* remove expired keys */
2292		if (result == -1) {
2293			if (saved_errno == EINTR)
2294				continue;
2295			fatal("poll: %s", strerror(saved_errno));
2296		} else if (result > 0)
2297			after_poll(pfd, npfd, maxfds);
2298	}
2299	/* NOTREACHED */
2300}
2301