xref: /freebsd/crypto/openssh/sshd-auth.c (revision 8e28d84935f2f0ee081d44f9803f3052b960e50b)
1*8e28d849SEd Maste /* $OpenBSD: sshd-auth.c,v 1.3 2025/01/16 06:37:10 dtucker Exp $ */
2*8e28d849SEd Maste /*
3*8e28d849SEd Maste  * SSH2 implementation:
4*8e28d849SEd Maste  * Privilege Separation:
5*8e28d849SEd Maste  *
6*8e28d849SEd Maste  * Copyright (c) 2000, 2001, 2002 Markus Friedl.  All rights reserved.
7*8e28d849SEd Maste  * Copyright (c) 2002 Niels Provos.  All rights reserved.
8*8e28d849SEd Maste  *
9*8e28d849SEd Maste  * Redistribution and use in source and binary forms, with or without
10*8e28d849SEd Maste  * modification, are permitted provided that the following conditions
11*8e28d849SEd Maste  * are met:
12*8e28d849SEd Maste  * 1. Redistributions of source code must retain the above copyright
13*8e28d849SEd Maste  *    notice, this list of conditions and the following disclaimer.
14*8e28d849SEd Maste  * 2. Redistributions in binary form must reproduce the above copyright
15*8e28d849SEd Maste  *    notice, this list of conditions and the following disclaimer in the
16*8e28d849SEd Maste  *    documentation and/or other materials provided with the distribution.
17*8e28d849SEd Maste  *
18*8e28d849SEd Maste  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19*8e28d849SEd Maste  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20*8e28d849SEd Maste  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21*8e28d849SEd Maste  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22*8e28d849SEd Maste  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23*8e28d849SEd Maste  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24*8e28d849SEd Maste  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25*8e28d849SEd Maste  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26*8e28d849SEd Maste  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27*8e28d849SEd Maste  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*8e28d849SEd Maste  */
29*8e28d849SEd Maste 
30*8e28d849SEd Maste #include "includes.h"
31*8e28d849SEd Maste 
32*8e28d849SEd Maste #include <sys/types.h>
33*8e28d849SEd Maste #include <sys/ioctl.h>
34*8e28d849SEd Maste #include <sys/wait.h>
35*8e28d849SEd Maste #include <sys/stat.h>
36*8e28d849SEd Maste #include <sys/socket.h>
37*8e28d849SEd Maste #include <sys/time.h>
38*8e28d849SEd Maste 
39*8e28d849SEd Maste #include "openbsd-compat/sys-tree.h"
40*8e28d849SEd Maste #include "openbsd-compat/sys-queue.h"
41*8e28d849SEd Maste 
42*8e28d849SEd Maste #include <errno.h>
43*8e28d849SEd Maste #include <fcntl.h>
44*8e28d849SEd Maste #include <netdb.h>
45*8e28d849SEd Maste #ifdef HAVE_PATHS_H
46*8e28d849SEd Maste # include <paths.h>
47*8e28d849SEd Maste #endif
48*8e28d849SEd Maste #include <pwd.h>
49*8e28d849SEd Maste #include <grp.h>
50*8e28d849SEd Maste #include <signal.h>
51*8e28d849SEd Maste #include <stdio.h>
52*8e28d849SEd Maste #include <stdlib.h>
53*8e28d849SEd Maste #include <string.h>
54*8e28d849SEd Maste #include <stdarg.h>
55*8e28d849SEd Maste #include <unistd.h>
56*8e28d849SEd Maste #include <limits.h>
57*8e28d849SEd Maste 
58*8e28d849SEd Maste #ifdef WITH_OPENSSL
59*8e28d849SEd Maste #include <openssl/bn.h>
60*8e28d849SEd Maste #include <openssl/evp.h>
61*8e28d849SEd Maste #endif
62*8e28d849SEd Maste 
63*8e28d849SEd Maste #include "xmalloc.h"
64*8e28d849SEd Maste #include "ssh.h"
65*8e28d849SEd Maste #include "ssh2.h"
66*8e28d849SEd Maste #include "sshpty.h"
67*8e28d849SEd Maste #include "packet.h"
68*8e28d849SEd Maste #include "log.h"
69*8e28d849SEd Maste #include "sshbuf.h"
70*8e28d849SEd Maste #include "misc.h"
71*8e28d849SEd Maste #include "match.h"
72*8e28d849SEd Maste #include "servconf.h"
73*8e28d849SEd Maste #include "uidswap.h"
74*8e28d849SEd Maste #include "compat.h"
75*8e28d849SEd Maste #include "cipher.h"
76*8e28d849SEd Maste #include "digest.h"
77*8e28d849SEd Maste #include "sshkey.h"
78*8e28d849SEd Maste #include "kex.h"
79*8e28d849SEd Maste #include "authfile.h"
80*8e28d849SEd Maste #include "pathnames.h"
81*8e28d849SEd Maste #include "atomicio.h"
82*8e28d849SEd Maste #include "canohost.h"
83*8e28d849SEd Maste #include "hostfile.h"
84*8e28d849SEd Maste #include "auth.h"
85*8e28d849SEd Maste #include "authfd.h"
86*8e28d849SEd Maste #include "msg.h"
87*8e28d849SEd Maste #include "dispatch.h"
88*8e28d849SEd Maste #include "channels.h"
89*8e28d849SEd Maste #include "session.h"
90*8e28d849SEd Maste #include "monitor.h"
91*8e28d849SEd Maste #ifdef GSSAPI
92*8e28d849SEd Maste #include "ssh-gss.h"
93*8e28d849SEd Maste #endif
94*8e28d849SEd Maste #include "monitor_wrap.h"
95*8e28d849SEd Maste #include "auth-options.h"
96*8e28d849SEd Maste #include "version.h"
97*8e28d849SEd Maste #include "ssherr.h"
98*8e28d849SEd Maste #include "sk-api.h"
99*8e28d849SEd Maste #include "srclimit.h"
100*8e28d849SEd Maste #include "ssh-sandbox.h"
101*8e28d849SEd Maste #include "dh.h"
102*8e28d849SEd Maste 
103*8e28d849SEd Maste /* Privsep fds */
104*8e28d849SEd Maste #define PRIVSEP_MONITOR_FD		(STDERR_FILENO + 1)
105*8e28d849SEd Maste #define PRIVSEP_LOG_FD			(STDERR_FILENO + 2)
106*8e28d849SEd Maste #define PRIVSEP_MIN_FREE_FD		(STDERR_FILENO + 3)
107*8e28d849SEd Maste 
108*8e28d849SEd Maste extern char *__progname;
109*8e28d849SEd Maste 
110*8e28d849SEd Maste /* Server configuration options. */
111*8e28d849SEd Maste ServerOptions options;
112*8e28d849SEd Maste 
113*8e28d849SEd Maste /* Name of the server configuration file. */
114*8e28d849SEd Maste char *config_file_name = _PATH_SERVER_CONFIG_FILE;
115*8e28d849SEd Maste 
116*8e28d849SEd Maste /*
117*8e28d849SEd Maste  * Debug mode flag.  This can be set on the command line.  If debug
118*8e28d849SEd Maste  * mode is enabled, extra debugging output will be sent to the system
119*8e28d849SEd Maste  * log, the daemon will not go to background, and will exit after processing
120*8e28d849SEd Maste  * the first connection.
121*8e28d849SEd Maste  */
122*8e28d849SEd Maste int debug_flag = 0;
123*8e28d849SEd Maste 
124*8e28d849SEd Maste /* Flag indicating that the daemon is being started from inetd. */
125*8e28d849SEd Maste static int inetd_flag = 0;
126*8e28d849SEd Maste 
127*8e28d849SEd Maste /* Saved arguments to main(). */
128*8e28d849SEd Maste static char **saved_argv;
129*8e28d849SEd Maste static int saved_argc;
130*8e28d849SEd Maste 
131*8e28d849SEd Maste 
132*8e28d849SEd Maste /* Daemon's agent connection */
133*8e28d849SEd Maste int auth_sock = -1;
134*8e28d849SEd Maste static int have_agent = 0;
135*8e28d849SEd Maste 
136*8e28d849SEd Maste u_int		num_hostkeys;
137*8e28d849SEd Maste struct sshkey	**host_pubkeys;		/* all public host keys */
138*8e28d849SEd Maste struct sshkey	**host_certificates;	/* all public host certificates */
139*8e28d849SEd Maste 
140*8e28d849SEd Maste /* record remote hostname or ip */
141*8e28d849SEd Maste u_int utmp_len = HOST_NAME_MAX+1;
142*8e28d849SEd Maste 
143*8e28d849SEd Maste /* variables used for privilege separation */
144*8e28d849SEd Maste struct monitor *pmonitor = NULL;
145*8e28d849SEd Maste int privsep_is_preauth = 1;
146*8e28d849SEd Maste static int privsep_chroot = 1;
147*8e28d849SEd Maste 
148*8e28d849SEd Maste /* global connection state and authentication contexts */
149*8e28d849SEd Maste Authctxt *the_authctxt = NULL;
150*8e28d849SEd Maste struct ssh *the_active_state;
151*8e28d849SEd Maste 
152*8e28d849SEd Maste /* global key/cert auth options. XXX move to permanent ssh->authctxt? */
153*8e28d849SEd Maste struct sshauthopt *auth_opts = NULL;
154*8e28d849SEd Maste 
155*8e28d849SEd Maste /* sshd_config buffer */
156*8e28d849SEd Maste struct sshbuf *cfg;
157*8e28d849SEd Maste 
158*8e28d849SEd Maste /* Included files from the configuration file */
159*8e28d849SEd Maste struct include_list includes = TAILQ_HEAD_INITIALIZER(includes);
160*8e28d849SEd Maste 
161*8e28d849SEd Maste /* message to be displayed after login */
162*8e28d849SEd Maste struct sshbuf *loginmsg;
163*8e28d849SEd Maste 
164*8e28d849SEd Maste /* Prototypes for various functions defined later in this file. */
165*8e28d849SEd Maste static void do_ssh2_kex(struct ssh *);
166*8e28d849SEd Maste 
167*8e28d849SEd Maste /* Unprivileged user */
168*8e28d849SEd Maste struct passwd *privsep_pw = NULL;
169*8e28d849SEd Maste 
170*8e28d849SEd Maste #ifndef HAVE_PLEDGE
171*8e28d849SEd Maste static struct ssh_sandbox *box;
172*8e28d849SEd Maste #endif
173*8e28d849SEd Maste 
174*8e28d849SEd Maste /* XXX stub */
175*8e28d849SEd Maste int
mm_is_monitor(void)176*8e28d849SEd Maste mm_is_monitor(void)
177*8e28d849SEd Maste {
178*8e28d849SEd Maste 	return 0;
179*8e28d849SEd Maste }
180*8e28d849SEd Maste 
181*8e28d849SEd Maste static void
privsep_child_demote(void)182*8e28d849SEd Maste privsep_child_demote(void)
183*8e28d849SEd Maste {
184*8e28d849SEd Maste 	gid_t gidset[1];
185*8e28d849SEd Maste 
186*8e28d849SEd Maste #ifndef HAVE_PLEDGE
187*8e28d849SEd Maste 	if ((box = ssh_sandbox_init(pmonitor)) == NULL)
188*8e28d849SEd Maste 		fatal_f("ssh_sandbox_init failed");
189*8e28d849SEd Maste #endif
190*8e28d849SEd Maste 	/* Demote the child */
191*8e28d849SEd Maste 	if (privsep_chroot) {
192*8e28d849SEd Maste 		/* Change our root directory */
193*8e28d849SEd Maste 		if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1)
194*8e28d849SEd Maste 			fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR,
195*8e28d849SEd Maste 			    strerror(errno));
196*8e28d849SEd Maste 		if (chdir("/") == -1)
197*8e28d849SEd Maste 			fatal("chdir(\"/\"): %s", strerror(errno));
198*8e28d849SEd Maste 
199*8e28d849SEd Maste 		/*
200*8e28d849SEd Maste 		 * Drop our privileges
201*8e28d849SEd Maste 		 * NB. Can't use setusercontext() after chroot.
202*8e28d849SEd Maste 		 */
203*8e28d849SEd Maste 		debug3("privsep user:group %u:%u", (u_int)privsep_pw->pw_uid,
204*8e28d849SEd Maste 		    (u_int)privsep_pw->pw_gid);
205*8e28d849SEd Maste 		gidset[0] = privsep_pw->pw_gid;
206*8e28d849SEd Maste 		if (setgroups(1, gidset) == -1)
207*8e28d849SEd Maste 			fatal("setgroups: %.100s", strerror(errno));
208*8e28d849SEd Maste 		permanently_set_uid(privsep_pw);
209*8e28d849SEd Maste 	}
210*8e28d849SEd Maste 
211*8e28d849SEd Maste 	/* sandbox ourselves */
212*8e28d849SEd Maste #ifdef HAVE_PLEDGE
213*8e28d849SEd Maste 	if (pledge("stdio", NULL) == -1)
214*8e28d849SEd Maste 		fatal_f("pledge()");
215*8e28d849SEd Maste #else
216*8e28d849SEd Maste 	ssh_sandbox_child(box);
217*8e28d849SEd Maste #endif
218*8e28d849SEd Maste }
219*8e28d849SEd Maste 
220*8e28d849SEd Maste static void
append_hostkey_type(struct sshbuf * b,const char * s)221*8e28d849SEd Maste append_hostkey_type(struct sshbuf *b, const char *s)
222*8e28d849SEd Maste {
223*8e28d849SEd Maste 	int r;
224*8e28d849SEd Maste 
225*8e28d849SEd Maste 	if (match_pattern_list(s, options.hostkeyalgorithms, 0) != 1) {
226*8e28d849SEd Maste 		debug3_f("%s key not permitted by HostkeyAlgorithms", s);
227*8e28d849SEd Maste 		return;
228*8e28d849SEd Maste 	}
229*8e28d849SEd Maste 	if ((r = sshbuf_putf(b, "%s%s", sshbuf_len(b) > 0 ? "," : "", s)) != 0)
230*8e28d849SEd Maste 		fatal_fr(r, "sshbuf_putf");
231*8e28d849SEd Maste }
232*8e28d849SEd Maste 
233*8e28d849SEd Maste static char *
list_hostkey_types(void)234*8e28d849SEd Maste list_hostkey_types(void)
235*8e28d849SEd Maste {
236*8e28d849SEd Maste 	struct sshbuf *b;
237*8e28d849SEd Maste 	struct sshkey *key;
238*8e28d849SEd Maste 	char *ret;
239*8e28d849SEd Maste 	u_int i;
240*8e28d849SEd Maste 
241*8e28d849SEd Maste 	if ((b = sshbuf_new()) == NULL)
242*8e28d849SEd Maste 		fatal_f("sshbuf_new failed");
243*8e28d849SEd Maste 	for (i = 0; i < options.num_host_key_files; i++) {
244*8e28d849SEd Maste 		key = host_pubkeys[i];
245*8e28d849SEd Maste 		if (key == NULL)
246*8e28d849SEd Maste 			continue;
247*8e28d849SEd Maste 		switch (key->type) {
248*8e28d849SEd Maste 		case KEY_RSA:
249*8e28d849SEd Maste 			/* for RSA we also support SHA2 signatures */
250*8e28d849SEd Maste 			append_hostkey_type(b, "rsa-sha2-512");
251*8e28d849SEd Maste 			append_hostkey_type(b, "rsa-sha2-256");
252*8e28d849SEd Maste 			/* FALLTHROUGH */
253*8e28d849SEd Maste 		case KEY_DSA:
254*8e28d849SEd Maste 		case KEY_ECDSA:
255*8e28d849SEd Maste 		case KEY_ED25519:
256*8e28d849SEd Maste 		case KEY_ECDSA_SK:
257*8e28d849SEd Maste 		case KEY_ED25519_SK:
258*8e28d849SEd Maste 		case KEY_XMSS:
259*8e28d849SEd Maste 			append_hostkey_type(b, sshkey_ssh_name(key));
260*8e28d849SEd Maste 			break;
261*8e28d849SEd Maste 		}
262*8e28d849SEd Maste 		/* If the private key has a cert peer, then list that too */
263*8e28d849SEd Maste 		key = host_certificates[i];
264*8e28d849SEd Maste 		if (key == NULL)
265*8e28d849SEd Maste 			continue;
266*8e28d849SEd Maste 		switch (key->type) {
267*8e28d849SEd Maste 		case KEY_RSA_CERT:
268*8e28d849SEd Maste 			/* for RSA we also support SHA2 signatures */
269*8e28d849SEd Maste 			append_hostkey_type(b,
270*8e28d849SEd Maste 			    "rsa-sha2-512-cert-v01@openssh.com");
271*8e28d849SEd Maste 			append_hostkey_type(b,
272*8e28d849SEd Maste 			    "rsa-sha2-256-cert-v01@openssh.com");
273*8e28d849SEd Maste 			/* FALLTHROUGH */
274*8e28d849SEd Maste 		case KEY_DSA_CERT:
275*8e28d849SEd Maste 		case KEY_ECDSA_CERT:
276*8e28d849SEd Maste 		case KEY_ED25519_CERT:
277*8e28d849SEd Maste 		case KEY_ECDSA_SK_CERT:
278*8e28d849SEd Maste 		case KEY_ED25519_SK_CERT:
279*8e28d849SEd Maste 		case KEY_XMSS_CERT:
280*8e28d849SEd Maste 			append_hostkey_type(b, sshkey_ssh_name(key));
281*8e28d849SEd Maste 			break;
282*8e28d849SEd Maste 		}
283*8e28d849SEd Maste 	}
284*8e28d849SEd Maste 	if ((ret = sshbuf_dup_string(b)) == NULL)
285*8e28d849SEd Maste 		fatal_f("sshbuf_dup_string failed");
286*8e28d849SEd Maste 	sshbuf_free(b);
287*8e28d849SEd Maste 	debug_f("%s", ret);
288*8e28d849SEd Maste 	return ret;
289*8e28d849SEd Maste }
290*8e28d849SEd Maste 
291*8e28d849SEd Maste struct sshkey *
get_hostkey_public_by_type(int type,int nid,struct ssh * ssh)292*8e28d849SEd Maste get_hostkey_public_by_type(int type, int nid, struct ssh *ssh)
293*8e28d849SEd Maste {
294*8e28d849SEd Maste 	u_int i;
295*8e28d849SEd Maste 	struct sshkey *key;
296*8e28d849SEd Maste 
297*8e28d849SEd Maste 	for (i = 0; i < options.num_host_key_files; i++) {
298*8e28d849SEd Maste 		switch (type) {
299*8e28d849SEd Maste 		case KEY_RSA_CERT:
300*8e28d849SEd Maste 		case KEY_DSA_CERT:
301*8e28d849SEd Maste 		case KEY_ECDSA_CERT:
302*8e28d849SEd Maste 		case KEY_ED25519_CERT:
303*8e28d849SEd Maste 		case KEY_ECDSA_SK_CERT:
304*8e28d849SEd Maste 		case KEY_ED25519_SK_CERT:
305*8e28d849SEd Maste 		case KEY_XMSS_CERT:
306*8e28d849SEd Maste 			key = host_certificates[i];
307*8e28d849SEd Maste 			break;
308*8e28d849SEd Maste 		default:
309*8e28d849SEd Maste 			key = host_pubkeys[i];
310*8e28d849SEd Maste 			break;
311*8e28d849SEd Maste 		}
312*8e28d849SEd Maste 		if (key == NULL || key->type != type)
313*8e28d849SEd Maste 			continue;
314*8e28d849SEd Maste 		switch (type) {
315*8e28d849SEd Maste 		case KEY_ECDSA:
316*8e28d849SEd Maste 		case KEY_ECDSA_SK:
317*8e28d849SEd Maste 		case KEY_ECDSA_CERT:
318*8e28d849SEd Maste 		case KEY_ECDSA_SK_CERT:
319*8e28d849SEd Maste 			if (key->ecdsa_nid != nid)
320*8e28d849SEd Maste 				continue;
321*8e28d849SEd Maste 			/* FALLTHROUGH */
322*8e28d849SEd Maste 		default:
323*8e28d849SEd Maste 			return key;
324*8e28d849SEd Maste 		}
325*8e28d849SEd Maste 	}
326*8e28d849SEd Maste 	return NULL;
327*8e28d849SEd Maste }
328*8e28d849SEd Maste 
329*8e28d849SEd Maste /* XXX remove */
330*8e28d849SEd Maste struct sshkey *
get_hostkey_private_by_type(int type,int nid,struct ssh * ssh)331*8e28d849SEd Maste get_hostkey_private_by_type(int type, int nid, struct ssh *ssh)
332*8e28d849SEd Maste {
333*8e28d849SEd Maste 	return NULL;
334*8e28d849SEd Maste }
335*8e28d849SEd Maste 
336*8e28d849SEd Maste /* XXX remove */
337*8e28d849SEd Maste struct sshkey *
get_hostkey_by_index(int ind)338*8e28d849SEd Maste get_hostkey_by_index(int ind)
339*8e28d849SEd Maste {
340*8e28d849SEd Maste 	return NULL;
341*8e28d849SEd Maste }
342*8e28d849SEd Maste 
343*8e28d849SEd Maste struct sshkey *
get_hostkey_public_by_index(int ind,struct ssh * ssh)344*8e28d849SEd Maste get_hostkey_public_by_index(int ind, struct ssh *ssh)
345*8e28d849SEd Maste {
346*8e28d849SEd Maste 	if (ind < 0 || (u_int)ind >= options.num_host_key_files)
347*8e28d849SEd Maste 		return (NULL);
348*8e28d849SEd Maste 	return host_pubkeys[ind];
349*8e28d849SEd Maste }
350*8e28d849SEd Maste 
351*8e28d849SEd Maste int
get_hostkey_index(struct sshkey * key,int compare,struct ssh * ssh)352*8e28d849SEd Maste get_hostkey_index(struct sshkey *key, int compare, struct ssh *ssh)
353*8e28d849SEd Maste {
354*8e28d849SEd Maste 	u_int i;
355*8e28d849SEd Maste 
356*8e28d849SEd Maste 	for (i = 0; i < options.num_host_key_files; i++) {
357*8e28d849SEd Maste 		if (sshkey_is_cert(key)) {
358*8e28d849SEd Maste 			if (key == host_certificates[i] ||
359*8e28d849SEd Maste 			    (compare && host_certificates[i] &&
360*8e28d849SEd Maste 			    sshkey_equal(key, host_certificates[i])))
361*8e28d849SEd Maste 				return (i);
362*8e28d849SEd Maste 		} else {
363*8e28d849SEd Maste 			if (key == host_pubkeys[i] ||
364*8e28d849SEd Maste 			    (compare && host_pubkeys[i] &&
365*8e28d849SEd Maste 			    sshkey_equal(key, host_pubkeys[i])))
366*8e28d849SEd Maste 				return (i);
367*8e28d849SEd Maste 		}
368*8e28d849SEd Maste 	}
369*8e28d849SEd Maste 	return (-1);
370*8e28d849SEd Maste }
371*8e28d849SEd Maste 
372*8e28d849SEd Maste static void
usage(void)373*8e28d849SEd Maste usage(void)
374*8e28d849SEd Maste {
375*8e28d849SEd Maste 	fprintf(stderr, "%s, %s\n", SSH_VERSION, SSH_OPENSSL_VERSION);
376*8e28d849SEd Maste 	fprintf(stderr,
377*8e28d849SEd Maste "usage: sshd [-46DdeGiqTtV] [-C connection_spec] [-c host_cert_file]\n"
378*8e28d849SEd Maste "            [-E log_file] [-f config_file] [-g login_grace_time]\n"
379*8e28d849SEd Maste "            [-h host_key_file] [-o option] [-p port] [-u len]\n"
380*8e28d849SEd Maste 	);
381*8e28d849SEd Maste 	exit(1);
382*8e28d849SEd Maste }
383*8e28d849SEd Maste 
384*8e28d849SEd Maste static void
parse_hostkeys(struct sshbuf * hostkeys)385*8e28d849SEd Maste parse_hostkeys(struct sshbuf *hostkeys)
386*8e28d849SEd Maste {
387*8e28d849SEd Maste 	int r;
388*8e28d849SEd Maste 	u_int num_keys = 0;
389*8e28d849SEd Maste 	struct sshkey *k;
390*8e28d849SEd Maste 	const u_char *cp;
391*8e28d849SEd Maste 	size_t len;
392*8e28d849SEd Maste 
393*8e28d849SEd Maste 	while (sshbuf_len(hostkeys) != 0) {
394*8e28d849SEd Maste 		if (num_keys > 2048)
395*8e28d849SEd Maste 			fatal_f("too many hostkeys");
396*8e28d849SEd Maste 		host_pubkeys = xrecallocarray(host_pubkeys,
397*8e28d849SEd Maste 		    num_keys, num_keys + 1, sizeof(*host_pubkeys));
398*8e28d849SEd Maste 		host_certificates = xrecallocarray(host_certificates,
399*8e28d849SEd Maste 		    num_keys, num_keys + 1, sizeof(*host_certificates));
400*8e28d849SEd Maste 		/* public key */
401*8e28d849SEd Maste 		k = NULL;
402*8e28d849SEd Maste 		if ((r = sshbuf_get_string_direct(hostkeys, &cp, &len)) != 0)
403*8e28d849SEd Maste 			fatal_fr(r, "extract pubkey");
404*8e28d849SEd Maste 		if (len != 0 && (r = sshkey_from_blob(cp, len, &k)) != 0)
405*8e28d849SEd Maste 			fatal_fr(r, "parse pubkey");
406*8e28d849SEd Maste 		host_pubkeys[num_keys] = k;
407*8e28d849SEd Maste 		if (k)
408*8e28d849SEd Maste 			debug2_f("key %u: %s", num_keys, sshkey_ssh_name(k));
409*8e28d849SEd Maste 		/* certificate */
410*8e28d849SEd Maste 		k = NULL;
411*8e28d849SEd Maste 		if ((r = sshbuf_get_string_direct(hostkeys, &cp, &len)) != 0)
412*8e28d849SEd Maste 			fatal_fr(r, "extract pubkey");
413*8e28d849SEd Maste 		if (len != 0 && (r = sshkey_from_blob(cp, len, &k)) != 0)
414*8e28d849SEd Maste 			fatal_fr(r, "parse pubkey");
415*8e28d849SEd Maste 		host_certificates[num_keys] = k;
416*8e28d849SEd Maste 		if (k)
417*8e28d849SEd Maste 			debug2_f("cert %u: %s", num_keys, sshkey_ssh_name(k));
418*8e28d849SEd Maste 		num_keys++;
419*8e28d849SEd Maste 	}
420*8e28d849SEd Maste 	num_hostkeys = num_keys;
421*8e28d849SEd Maste }
422*8e28d849SEd Maste 
423*8e28d849SEd Maste static void
recv_privsep_state(struct ssh * ssh,struct sshbuf * conf,uint64_t * timing_secretp)424*8e28d849SEd Maste recv_privsep_state(struct ssh *ssh, struct sshbuf *conf,
425*8e28d849SEd Maste     uint64_t *timing_secretp)
426*8e28d849SEd Maste {
427*8e28d849SEd Maste 	struct sshbuf *hostkeys;
428*8e28d849SEd Maste 
429*8e28d849SEd Maste 	debug3_f("begin");
430*8e28d849SEd Maste 
431*8e28d849SEd Maste 	mm_get_state(ssh, &includes, conf, NULL, timing_secretp,
432*8e28d849SEd Maste 	    &hostkeys, NULL, NULL, NULL, NULL);
433*8e28d849SEd Maste 	parse_hostkeys(hostkeys);
434*8e28d849SEd Maste 
435*8e28d849SEd Maste 	sshbuf_free(hostkeys);
436*8e28d849SEd Maste 
437*8e28d849SEd Maste 	debug3_f("done");
438*8e28d849SEd Maste }
439*8e28d849SEd Maste 
440*8e28d849SEd Maste /*
441*8e28d849SEd Maste  * Main program for the daemon.
442*8e28d849SEd Maste  */
443*8e28d849SEd Maste int
main(int ac,char ** av)444*8e28d849SEd Maste main(int ac, char **av)
445*8e28d849SEd Maste {
446*8e28d849SEd Maste 	struct ssh *ssh = NULL;
447*8e28d849SEd Maste 	extern char *optarg;
448*8e28d849SEd Maste 	extern int optind;
449*8e28d849SEd Maste 	int r, opt, have_key = 0;
450*8e28d849SEd Maste 	int sock_in = -1, sock_out = -1, rexeced_flag = 0;
451*8e28d849SEd Maste 	char *line, *logfile = NULL;
452*8e28d849SEd Maste 	u_int i;
453*8e28d849SEd Maste 	mode_t new_umask;
454*8e28d849SEd Maste 	Authctxt *authctxt;
455*8e28d849SEd Maste 	struct connection_info *connection_info = NULL;
456*8e28d849SEd Maste 	sigset_t sigmask;
457*8e28d849SEd Maste 	uint64_t timing_secret = 0;
458*8e28d849SEd Maste 
459*8e28d849SEd Maste 	closefrom(PRIVSEP_MIN_FREE_FD);
460*8e28d849SEd Maste 	sigemptyset(&sigmask);
461*8e28d849SEd Maste 	sigprocmask(SIG_SETMASK, &sigmask, NULL);
462*8e28d849SEd Maste 
463*8e28d849SEd Maste #ifdef HAVE_SECUREWARE
464*8e28d849SEd Maste 	(void)set_auth_parameters(ac, av);
465*8e28d849SEd Maste #endif
466*8e28d849SEd Maste 	__progname = ssh_get_progname(av[0]);
467*8e28d849SEd Maste 
468*8e28d849SEd Maste 	/* Save argv. Duplicate so setproctitle emulation doesn't clobber it */
469*8e28d849SEd Maste 	saved_argc = ac;
470*8e28d849SEd Maste 	saved_argv = xcalloc(ac + 1, sizeof(*saved_argv));
471*8e28d849SEd Maste 	for (i = 0; (int)i < ac; i++)
472*8e28d849SEd Maste 		saved_argv[i] = xstrdup(av[i]);
473*8e28d849SEd Maste 	saved_argv[i] = NULL;
474*8e28d849SEd Maste 
475*8e28d849SEd Maste 	seed_rng();
476*8e28d849SEd Maste 
477*8e28d849SEd Maste #ifndef HAVE_SETPROCTITLE
478*8e28d849SEd Maste 	/* Prepare for later setproctitle emulation */
479*8e28d849SEd Maste 	compat_init_setproctitle(ac, av);
480*8e28d849SEd Maste 	av = saved_argv;
481*8e28d849SEd Maste #endif
482*8e28d849SEd Maste 
483*8e28d849SEd Maste 	/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
484*8e28d849SEd Maste 	sanitise_stdfd();
485*8e28d849SEd Maste 
486*8e28d849SEd Maste 	/* Initialize configuration options to their default values. */
487*8e28d849SEd Maste 	initialize_server_options(&options);
488*8e28d849SEd Maste 
489*8e28d849SEd Maste 	/* Parse command-line arguments. */
490*8e28d849SEd Maste 	while ((opt = getopt(ac, av,
491*8e28d849SEd Maste 	    "C:E:b:c:f:g:h:k:o:p:u:46DGQRTdeiqrtV")) != -1) {
492*8e28d849SEd Maste 		switch (opt) {
493*8e28d849SEd Maste 		case '4':
494*8e28d849SEd Maste 			options.address_family = AF_INET;
495*8e28d849SEd Maste 			break;
496*8e28d849SEd Maste 		case '6':
497*8e28d849SEd Maste 			options.address_family = AF_INET6;
498*8e28d849SEd Maste 			break;
499*8e28d849SEd Maste 		case 'f':
500*8e28d849SEd Maste 			config_file_name = optarg;
501*8e28d849SEd Maste 			break;
502*8e28d849SEd Maste 		case 'c':
503*8e28d849SEd Maste 			servconf_add_hostcert("[command-line]", 0,
504*8e28d849SEd Maste 			    &options, optarg);
505*8e28d849SEd Maste 			break;
506*8e28d849SEd Maste 		case 'd':
507*8e28d849SEd Maste 			if (debug_flag == 0) {
508*8e28d849SEd Maste 				debug_flag = 1;
509*8e28d849SEd Maste 				options.log_level = SYSLOG_LEVEL_DEBUG1;
510*8e28d849SEd Maste 			} else if (options.log_level < SYSLOG_LEVEL_DEBUG3)
511*8e28d849SEd Maste 				options.log_level++;
512*8e28d849SEd Maste 			break;
513*8e28d849SEd Maste 		case 'D':
514*8e28d849SEd Maste 			/* ignore */
515*8e28d849SEd Maste 			break;
516*8e28d849SEd Maste 		case 'E':
517*8e28d849SEd Maste 			logfile = optarg;
518*8e28d849SEd Maste 			/* FALLTHROUGH */
519*8e28d849SEd Maste 		case 'e':
520*8e28d849SEd Maste 			/* ignore */
521*8e28d849SEd Maste 			break;
522*8e28d849SEd Maste 		case 'i':
523*8e28d849SEd Maste 			inetd_flag = 1;
524*8e28d849SEd Maste 			break;
525*8e28d849SEd Maste 		case 'r':
526*8e28d849SEd Maste 			/* ignore */
527*8e28d849SEd Maste 			break;
528*8e28d849SEd Maste 		case 'R':
529*8e28d849SEd Maste 			rexeced_flag = 1;
530*8e28d849SEd Maste 			break;
531*8e28d849SEd Maste 		case 'Q':
532*8e28d849SEd Maste 			/* ignored */
533*8e28d849SEd Maste 			break;
534*8e28d849SEd Maste 		case 'q':
535*8e28d849SEd Maste 			options.log_level = SYSLOG_LEVEL_QUIET;
536*8e28d849SEd Maste 			break;
537*8e28d849SEd Maste 		case 'b':
538*8e28d849SEd Maste 			/* protocol 1, ignored */
539*8e28d849SEd Maste 			break;
540*8e28d849SEd Maste 		case 'p':
541*8e28d849SEd Maste 			options.ports_from_cmdline = 1;
542*8e28d849SEd Maste 			if (options.num_ports >= MAX_PORTS) {
543*8e28d849SEd Maste 				fprintf(stderr, "too many ports.\n");
544*8e28d849SEd Maste 				exit(1);
545*8e28d849SEd Maste 			}
546*8e28d849SEd Maste 			options.ports[options.num_ports++] = a2port(optarg);
547*8e28d849SEd Maste 			if (options.ports[options.num_ports-1] <= 0) {
548*8e28d849SEd Maste 				fprintf(stderr, "Bad port number.\n");
549*8e28d849SEd Maste 				exit(1);
550*8e28d849SEd Maste 			}
551*8e28d849SEd Maste 			break;
552*8e28d849SEd Maste 		case 'g':
553*8e28d849SEd Maste 			if ((options.login_grace_time = convtime(optarg)) == -1) {
554*8e28d849SEd Maste 				fprintf(stderr, "Invalid login grace time.\n");
555*8e28d849SEd Maste 				exit(1);
556*8e28d849SEd Maste 			}
557*8e28d849SEd Maste 			break;
558*8e28d849SEd Maste 		case 'k':
559*8e28d849SEd Maste 			/* protocol 1, ignored */
560*8e28d849SEd Maste 			break;
561*8e28d849SEd Maste 		case 'h':
562*8e28d849SEd Maste 			servconf_add_hostkey("[command-line]", 0,
563*8e28d849SEd Maste 			    &options, optarg, 1);
564*8e28d849SEd Maste 			break;
565*8e28d849SEd Maste 		case 't':
566*8e28d849SEd Maste 		case 'T':
567*8e28d849SEd Maste 		case 'G':
568*8e28d849SEd Maste 			fatal("test/dump modes not supported");
569*8e28d849SEd Maste 			break;
570*8e28d849SEd Maste 		case 'C':
571*8e28d849SEd Maste 			connection_info = server_get_connection_info(ssh, 0, 0);
572*8e28d849SEd Maste 			if (parse_server_match_testspec(connection_info,
573*8e28d849SEd Maste 			    optarg) == -1)
574*8e28d849SEd Maste 				exit(1);
575*8e28d849SEd Maste 			break;
576*8e28d849SEd Maste 		case 'u':
577*8e28d849SEd Maste 			utmp_len = (u_int)strtonum(optarg, 0, HOST_NAME_MAX+1+1, NULL);
578*8e28d849SEd Maste 			if (utmp_len > HOST_NAME_MAX+1) {
579*8e28d849SEd Maste 				fprintf(stderr, "Invalid utmp length.\n");
580*8e28d849SEd Maste 				exit(1);
581*8e28d849SEd Maste 			}
582*8e28d849SEd Maste 			break;
583*8e28d849SEd Maste 		case 'o':
584*8e28d849SEd Maste 			line = xstrdup(optarg);
585*8e28d849SEd Maste 			if (process_server_config_line(&options, line,
586*8e28d849SEd Maste 			    "command-line", 0, NULL, NULL, &includes) != 0)
587*8e28d849SEd Maste 				exit(1);
588*8e28d849SEd Maste 			free(line);
589*8e28d849SEd Maste 			break;
590*8e28d849SEd Maste 		case 'V':
591*8e28d849SEd Maste 			fprintf(stderr, "%s, %s\n",
592*8e28d849SEd Maste 			    SSH_VERSION, SSH_OPENSSL_VERSION);
593*8e28d849SEd Maste 			exit(0);
594*8e28d849SEd Maste 		default:
595*8e28d849SEd Maste 			usage();
596*8e28d849SEd Maste 			break;
597*8e28d849SEd Maste 		}
598*8e28d849SEd Maste 	}
599*8e28d849SEd Maste 
600*8e28d849SEd Maste 	if (!rexeced_flag)
601*8e28d849SEd Maste 		fatal("sshd-auth should not be executed directly");
602*8e28d849SEd Maste 
603*8e28d849SEd Maste #ifdef WITH_OPENSSL
604*8e28d849SEd Maste 	OpenSSL_add_all_algorithms();
605*8e28d849SEd Maste #endif
606*8e28d849SEd Maste 
607*8e28d849SEd Maste 	/* If requested, redirect the logs to the specified logfile. */
608*8e28d849SEd Maste 	if (logfile != NULL) {
609*8e28d849SEd Maste 		char *cp, pid_s[32];
610*8e28d849SEd Maste 
611*8e28d849SEd Maste 		snprintf(pid_s, sizeof(pid_s), "%ld", (unsigned long)getpid());
612*8e28d849SEd Maste 		cp = percent_expand(logfile,
613*8e28d849SEd Maste 		    "p", pid_s,
614*8e28d849SEd Maste 		    "P", "sshd-auth",
615*8e28d849SEd Maste 		    (char *)NULL);
616*8e28d849SEd Maste 		log_redirect_stderr_to(cp);
617*8e28d849SEd Maste 		free(cp);
618*8e28d849SEd Maste 	}
619*8e28d849SEd Maste 
620*8e28d849SEd Maste 	log_init(__progname,
621*8e28d849SEd Maste 	    options.log_level == SYSLOG_LEVEL_NOT_SET ?
622*8e28d849SEd Maste 	    SYSLOG_LEVEL_INFO : options.log_level,
623*8e28d849SEd Maste 	    options.log_facility == SYSLOG_FACILITY_NOT_SET ?
624*8e28d849SEd Maste 	    SYSLOG_FACILITY_AUTH : options.log_facility, 1);
625*8e28d849SEd Maste 
626*8e28d849SEd Maste 	/* XXX can't use monitor_init(); it makes fds */
627*8e28d849SEd Maste 	pmonitor = xcalloc(1, sizeof(*pmonitor));
628*8e28d849SEd Maste 	pmonitor->m_sendfd = pmonitor->m_log_recvfd = -1;
629*8e28d849SEd Maste 	pmonitor->m_recvfd = PRIVSEP_MONITOR_FD;
630*8e28d849SEd Maste 	pmonitor->m_log_sendfd = PRIVSEP_LOG_FD;
631*8e28d849SEd Maste 	set_log_handler(mm_log_handler, pmonitor);
632*8e28d849SEd Maste 
633*8e28d849SEd Maste 	/* Check that there are no remaining arguments. */
634*8e28d849SEd Maste 	if (optind < ac) {
635*8e28d849SEd Maste 		fprintf(stderr, "Extra argument %s.\n", av[optind]);
636*8e28d849SEd Maste 		exit(1);
637*8e28d849SEd Maste 	}
638*8e28d849SEd Maste 
639*8e28d849SEd Maste 	/* Connection passed by stdin/out */
640*8e28d849SEd Maste 	if (inetd_flag) {
641*8e28d849SEd Maste 		/*
642*8e28d849SEd Maste 		 * NB. must be different fd numbers for the !socket case,
643*8e28d849SEd Maste 		 * as packet_connection_is_on_socket() depends on this.
644*8e28d849SEd Maste 		 */
645*8e28d849SEd Maste 		sock_in = dup(STDIN_FILENO);
646*8e28d849SEd Maste 		sock_out = dup(STDOUT_FILENO);
647*8e28d849SEd Maste 	} else {
648*8e28d849SEd Maste 		/* rexec case; accept()ed socket in ancestor listener */
649*8e28d849SEd Maste 		sock_in = sock_out = dup(STDIN_FILENO);
650*8e28d849SEd Maste 	}
651*8e28d849SEd Maste 
652*8e28d849SEd Maste 	if (stdfd_devnull(1, 1, 0) == -1)
653*8e28d849SEd Maste 		error("stdfd_devnull failed");
654*8e28d849SEd Maste 	debug("network sockets: %d, %d", sock_in, sock_out);
655*8e28d849SEd Maste 
656*8e28d849SEd Maste 	/*
657*8e28d849SEd Maste 	 * Register our connection.  This turns encryption off because we do
658*8e28d849SEd Maste 	 * not have a key.
659*8e28d849SEd Maste 	 */
660*8e28d849SEd Maste 	if ((ssh = ssh_packet_set_connection(NULL, sock_in, sock_out)) == NULL)
661*8e28d849SEd Maste 		fatal("Unable to create connection");
662*8e28d849SEd Maste 	the_active_state = ssh;
663*8e28d849SEd Maste 	ssh_packet_set_server(ssh);
664*8e28d849SEd Maste 	pmonitor->m_pkex = &ssh->kex;
665*8e28d849SEd Maste 
666*8e28d849SEd Maste 	/* Fetch our configuration */
667*8e28d849SEd Maste 	if ((cfg = sshbuf_new()) == NULL)
668*8e28d849SEd Maste 		fatal("sshbuf_new config buf failed");
669*8e28d849SEd Maste 	setproctitle("%s", "[session-auth early]");
670*8e28d849SEd Maste 	recv_privsep_state(ssh, cfg, &timing_secret);
671*8e28d849SEd Maste 	parse_server_config(&options, "rexec", cfg, &includes, NULL, 1);
672*8e28d849SEd Maste 	/* Fill in default values for those options not explicitly set. */
673*8e28d849SEd Maste 	fill_default_server_options(&options);
674*8e28d849SEd Maste 	options.timing_secret = timing_secret; /* XXX eliminate from unpriv */
675*8e28d849SEd Maste 
676*8e28d849SEd Maste 	/* Reinit logging in case config set Level, Facility or Verbose. */
677*8e28d849SEd Maste 	log_init(__progname, options.log_level, options.log_facility, 1);
678*8e28d849SEd Maste 
679*8e28d849SEd Maste 	debug("sshd-auth version %s, %s", SSH_VERSION, SSH_OPENSSL_VERSION);
680*8e28d849SEd Maste 
681*8e28d849SEd Maste 	/* Store privilege separation user for later use if required. */
682*8e28d849SEd Maste 	privsep_chroot = (getuid() == 0 || geteuid() == 0);
683*8e28d849SEd Maste 	if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) {
684*8e28d849SEd Maste 		if (privsep_chroot || options.kerberos_authentication)
685*8e28d849SEd Maste 			fatal("Privilege separation user %s does not exist",
686*8e28d849SEd Maste 			    SSH_PRIVSEP_USER);
687*8e28d849SEd Maste 	} else {
688*8e28d849SEd Maste 		privsep_pw = pwcopy(privsep_pw);
689*8e28d849SEd Maste 		freezero(privsep_pw->pw_passwd, strlen(privsep_pw->pw_passwd));
690*8e28d849SEd Maste 		privsep_pw->pw_passwd = xstrdup("*");
691*8e28d849SEd Maste 	}
692*8e28d849SEd Maste 	endpwent();
693*8e28d849SEd Maste 
694*8e28d849SEd Maste #ifdef WITH_OPENSSL
695*8e28d849SEd Maste 	if (options.moduli_file != NULL)
696*8e28d849SEd Maste 		dh_set_moduli_file(options.moduli_file);
697*8e28d849SEd Maste #endif
698*8e28d849SEd Maste 
699*8e28d849SEd Maste 	if (options.host_key_agent) {
700*8e28d849SEd Maste 		if (strcmp(options.host_key_agent, SSH_AUTHSOCKET_ENV_NAME))
701*8e28d849SEd Maste 			setenv(SSH_AUTHSOCKET_ENV_NAME,
702*8e28d849SEd Maste 			    options.host_key_agent, 1);
703*8e28d849SEd Maste 		if ((r = ssh_get_authentication_socket(NULL)) == 0)
704*8e28d849SEd Maste 			have_agent = 1;
705*8e28d849SEd Maste 		else
706*8e28d849SEd Maste 			error_r(r, "Could not connect to agent \"%s\"",
707*8e28d849SEd Maste 			    options.host_key_agent);
708*8e28d849SEd Maste 	}
709*8e28d849SEd Maste 
710*8e28d849SEd Maste 	if (options.num_host_key_files != num_hostkeys) {
711*8e28d849SEd Maste 		fatal("internal error: hostkeys confused (config %u recvd %u)",
712*8e28d849SEd Maste 		    options.num_host_key_files, num_hostkeys);
713*8e28d849SEd Maste 	}
714*8e28d849SEd Maste 
715*8e28d849SEd Maste 	for (i = 0; i < options.num_host_key_files; i++) {
716*8e28d849SEd Maste 		if (host_pubkeys[i] != NULL) {
717*8e28d849SEd Maste 			have_key = 1;
718*8e28d849SEd Maste 			break;
719*8e28d849SEd Maste 		}
720*8e28d849SEd Maste 	}
721*8e28d849SEd Maste 	if (!have_key)
722*8e28d849SEd Maste 		fatal("internal error: received no hostkeys");
723*8e28d849SEd Maste 
724*8e28d849SEd Maste 	/* Ensure that umask disallows at least group and world write */
725*8e28d849SEd Maste 	new_umask = umask(0077) | 0022;
726*8e28d849SEd Maste 	(void) umask(new_umask);
727*8e28d849SEd Maste 
728*8e28d849SEd Maste 	/* Initialize the log (it is reinitialized below in case we forked). */
729*8e28d849SEd Maste 	log_init(__progname, options.log_level, options.log_facility, 1);
730*8e28d849SEd Maste 	set_log_handler(mm_log_handler, pmonitor);
731*8e28d849SEd Maste 	for (i = 0; i < options.num_log_verbose; i++)
732*8e28d849SEd Maste 		log_verbose_add(options.log_verbose[i]);
733*8e28d849SEd Maste 
734*8e28d849SEd Maste 	/*
735*8e28d849SEd Maste 	 * Chdir to the root directory so that the current disk can be
736*8e28d849SEd Maste 	 * unmounted if desired.
737*8e28d849SEd Maste 	 */
738*8e28d849SEd Maste 	if (chdir("/") == -1)
739*8e28d849SEd Maste 		error("chdir(\"/\"): %s", strerror(errno));
740*8e28d849SEd Maste 
741*8e28d849SEd Maste 	/* This is the child authenticating a new connection. */
742*8e28d849SEd Maste 	setproctitle("%s", "[session-auth]");
743*8e28d849SEd Maste 
744*8e28d849SEd Maste 	/* Executed child processes don't need these. */
745*8e28d849SEd Maste 	fcntl(sock_out, F_SETFD, FD_CLOEXEC);
746*8e28d849SEd Maste 	fcntl(sock_in, F_SETFD, FD_CLOEXEC);
747*8e28d849SEd Maste 
748*8e28d849SEd Maste 	ssh_signal(SIGPIPE, SIG_IGN);
749*8e28d849SEd Maste 	ssh_signal(SIGALRM, SIG_DFL);
750*8e28d849SEd Maste 	ssh_signal(SIGHUP, SIG_DFL);
751*8e28d849SEd Maste 	ssh_signal(SIGTERM, SIG_DFL);
752*8e28d849SEd Maste 	ssh_signal(SIGQUIT, SIG_DFL);
753*8e28d849SEd Maste 	ssh_signal(SIGCHLD, SIG_DFL);
754*8e28d849SEd Maste 
755*8e28d849SEd Maste 	/* Prepare the channels layer */
756*8e28d849SEd Maste 	channel_init_channels(ssh);
757*8e28d849SEd Maste 	channel_set_af(ssh, options.address_family);
758*8e28d849SEd Maste 	server_process_channel_timeouts(ssh);
759*8e28d849SEd Maste 	server_process_permitopen(ssh);
760*8e28d849SEd Maste 
761*8e28d849SEd Maste 	ssh_packet_set_nonblocking(ssh);
762*8e28d849SEd Maste 
763*8e28d849SEd Maste 	/* allocate authentication context */
764*8e28d849SEd Maste 	authctxt = xcalloc(1, sizeof(*authctxt));
765*8e28d849SEd Maste 	ssh->authctxt = authctxt;
766*8e28d849SEd Maste 
767*8e28d849SEd Maste 	/* XXX global for cleanup, access from other modules */
768*8e28d849SEd Maste 	the_authctxt = authctxt;
769*8e28d849SEd Maste 
770*8e28d849SEd Maste 	/* Set default key authentication options */
771*8e28d849SEd Maste 	if ((auth_opts = sshauthopt_new_with_keys_defaults()) == NULL)
772*8e28d849SEd Maste 		fatal("allocation failed");
773*8e28d849SEd Maste 
774*8e28d849SEd Maste 	/* prepare buffer to collect messages to display to user after login */
775*8e28d849SEd Maste 	if ((loginmsg = sshbuf_new()) == NULL)
776*8e28d849SEd Maste 		fatal("sshbuf_new loginmsg failed");
777*8e28d849SEd Maste 	auth_debug_reset();
778*8e28d849SEd Maste 
779*8e28d849SEd Maste 	/* Enable challenge-response authentication for privilege separation */
780*8e28d849SEd Maste 	privsep_challenge_enable();
781*8e28d849SEd Maste 
782*8e28d849SEd Maste #ifdef GSSAPI
783*8e28d849SEd Maste 	/* Cache supported mechanism OIDs for later use */
784*8e28d849SEd Maste 	ssh_gssapi_prepare_supported_oids();
785*8e28d849SEd Maste #endif
786*8e28d849SEd Maste 
787*8e28d849SEd Maste 	privsep_child_demote();
788*8e28d849SEd Maste 
789*8e28d849SEd Maste 	/* perform the key exchange */
790*8e28d849SEd Maste 	/* authenticate user and start session */
791*8e28d849SEd Maste 	do_ssh2_kex(ssh);
792*8e28d849SEd Maste 	do_authentication2(ssh);
793*8e28d849SEd Maste 
794*8e28d849SEd Maste 	/*
795*8e28d849SEd Maste 	 * The unprivileged child now transfers the current keystate and exits.
796*8e28d849SEd Maste 	 */
797*8e28d849SEd Maste 	mm_send_keystate(ssh, pmonitor);
798*8e28d849SEd Maste 	ssh_packet_clear_keys(ssh);
799*8e28d849SEd Maste 	exit(0);
800*8e28d849SEd Maste }
801*8e28d849SEd Maste 
802*8e28d849SEd Maste int
sshd_hostkey_sign(struct ssh * ssh,struct sshkey * privkey,struct sshkey * pubkey,u_char ** signature,size_t * slenp,const u_char * data,size_t dlen,const char * alg)803*8e28d849SEd Maste sshd_hostkey_sign(struct ssh *ssh, struct sshkey *privkey,
804*8e28d849SEd Maste     struct sshkey *pubkey, u_char **signature, size_t *slenp,
805*8e28d849SEd Maste     const u_char *data, size_t dlen, const char *alg)
806*8e28d849SEd Maste {
807*8e28d849SEd Maste 	if (privkey) {
808*8e28d849SEd Maste 		if (mm_sshkey_sign(ssh, privkey, signature, slenp,
809*8e28d849SEd Maste 		    data, dlen, alg, options.sk_provider, NULL,
810*8e28d849SEd Maste 		    ssh->compat) < 0)
811*8e28d849SEd Maste 			fatal_f("privkey sign failed");
812*8e28d849SEd Maste 	} else {
813*8e28d849SEd Maste 		if (mm_sshkey_sign(ssh, pubkey, signature, slenp,
814*8e28d849SEd Maste 		    data, dlen, alg, options.sk_provider, NULL,
815*8e28d849SEd Maste 		    ssh->compat) < 0)
816*8e28d849SEd Maste 			fatal_f("pubkey sign failed");
817*8e28d849SEd Maste 	}
818*8e28d849SEd Maste 	return 0;
819*8e28d849SEd Maste }
820*8e28d849SEd Maste 
821*8e28d849SEd Maste /* SSH2 key exchange */
822*8e28d849SEd Maste static void
do_ssh2_kex(struct ssh * ssh)823*8e28d849SEd Maste do_ssh2_kex(struct ssh *ssh)
824*8e28d849SEd Maste {
825*8e28d849SEd Maste 	char *hkalgs = NULL, *myproposal[PROPOSAL_MAX];
826*8e28d849SEd Maste 	const char *compression = NULL;
827*8e28d849SEd Maste 	struct kex *kex;
828*8e28d849SEd Maste 	int r;
829*8e28d849SEd Maste 
830*8e28d849SEd Maste 	if (options.rekey_limit || options.rekey_interval)
831*8e28d849SEd Maste 		ssh_packet_set_rekey_limits(ssh, options.rekey_limit,
832*8e28d849SEd Maste 		    options.rekey_interval);
833*8e28d849SEd Maste 
834*8e28d849SEd Maste 	if (options.compression == COMP_NONE)
835*8e28d849SEd Maste 		compression = "none";
836*8e28d849SEd Maste 	hkalgs = list_hostkey_types();
837*8e28d849SEd Maste 
838*8e28d849SEd Maste 	kex_proposal_populate_entries(ssh, myproposal, options.kex_algorithms,
839*8e28d849SEd Maste 	    options.ciphers, options.macs, compression, hkalgs);
840*8e28d849SEd Maste 
841*8e28d849SEd Maste 	free(hkalgs);
842*8e28d849SEd Maste 
843*8e28d849SEd Maste 	/* start key exchange */
844*8e28d849SEd Maste 	if ((r = kex_setup(ssh, myproposal)) != 0)
845*8e28d849SEd Maste 		fatal_r(r, "kex_setup");
846*8e28d849SEd Maste 	kex_set_server_sig_algs(ssh, options.pubkey_accepted_algos);
847*8e28d849SEd Maste 	kex = ssh->kex;
848*8e28d849SEd Maste 
849*8e28d849SEd Maste #ifdef WITH_OPENSSL
850*8e28d849SEd Maste 	kex->kex[KEX_DH_GRP1_SHA1] = kex_gen_server;
851*8e28d849SEd Maste 	kex->kex[KEX_DH_GRP14_SHA1] = kex_gen_server;
852*8e28d849SEd Maste 	kex->kex[KEX_DH_GRP14_SHA256] = kex_gen_server;
853*8e28d849SEd Maste 	kex->kex[KEX_DH_GRP16_SHA512] = kex_gen_server;
854*8e28d849SEd Maste 	kex->kex[KEX_DH_GRP18_SHA512] = kex_gen_server;
855*8e28d849SEd Maste 	kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
856*8e28d849SEd Maste 	kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
857*8e28d849SEd Maste # ifdef OPENSSL_HAS_ECC
858*8e28d849SEd Maste 	kex->kex[KEX_ECDH_SHA2] = kex_gen_server;
859*8e28d849SEd Maste # endif /* OPENSSL_HAS_ECC */
860*8e28d849SEd Maste #endif /* WITH_OPENSSL */
861*8e28d849SEd Maste 	kex->kex[KEX_C25519_SHA256] = kex_gen_server;
862*8e28d849SEd Maste 	kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server;
863*8e28d849SEd Maste 	kex->kex[KEX_KEM_MLKEM768X25519_SHA256] = kex_gen_server;
864*8e28d849SEd Maste 	kex->load_host_public_key=&get_hostkey_public_by_type;
865*8e28d849SEd Maste 	kex->load_host_private_key=&get_hostkey_private_by_type;
866*8e28d849SEd Maste 	kex->host_key_index=&get_hostkey_index;
867*8e28d849SEd Maste 	kex->sign = sshd_hostkey_sign;
868*8e28d849SEd Maste 
869*8e28d849SEd Maste 	ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &kex->done);
870*8e28d849SEd Maste 	kex_proposal_free_entries(myproposal);
871*8e28d849SEd Maste 
872*8e28d849SEd Maste #ifdef DEBUG_KEXDH
873*8e28d849SEd Maste 	/* send 1st encrypted/maced/compressed message */
874*8e28d849SEd Maste 	if ((r = sshpkt_start(ssh, SSH2_MSG_IGNORE)) != 0 ||
875*8e28d849SEd Maste 	    (r = sshpkt_put_cstring(ssh, "markus")) != 0 ||
876*8e28d849SEd Maste 	    (r = sshpkt_send(ssh)) != 0 ||
877*8e28d849SEd Maste 	    (r = ssh_packet_write_wait(ssh)) != 0)
878*8e28d849SEd Maste 		fatal_fr(r, "send test");
879*8e28d849SEd Maste #endif
880*8e28d849SEd Maste 	debug("KEX done");
881*8e28d849SEd Maste }
882*8e28d849SEd Maste 
883*8e28d849SEd Maste /* server specific fatal cleanup */
884*8e28d849SEd Maste void
cleanup_exit(int i)885*8e28d849SEd Maste cleanup_exit(int i)
886*8e28d849SEd Maste {
887*8e28d849SEd Maste 	_exit(i);
888*8e28d849SEd Maste }
889