xref: /openbsd-src/usr.bin/ssh/servconf.c (revision 7350f337b9e3eb4461d99580e625c7ef148d107c)
1 
2 /* $OpenBSD: servconf.c,v 1.351 2019/04/18 18:56:16 dtucker Exp $ */
3 /*
4  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5  *                    All rights reserved
6  *
7  * As far as I am concerned, the code I have written for this software
8  * can be used freely for any purpose.  Any derived versions of this
9  * software must be clearly marked as such, and if the derived work is
10  * incompatible with the protocol description in the RFC file, it must be
11  * called by a name other than "ssh" or "Secure Shell".
12  */
13 
14 #include <sys/types.h>
15 #include <sys/socket.h>
16 #include <sys/queue.h>
17 #include <sys/sysctl.h>
18 
19 #include <netinet/in.h>
20 #include <netinet/ip.h>
21 #include <net/route.h>
22 
23 #include <ctype.h>
24 #include <netdb.h>
25 #include <pwd.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <signal.h>
30 #include <unistd.h>
31 #include <limits.h>
32 #include <stdarg.h>
33 #include <errno.h>
34 #include <util.h>
35 
36 #include "xmalloc.h"
37 #include "ssh.h"
38 #include "log.h"
39 #include "sshbuf.h"
40 #include "misc.h"
41 #include "servconf.h"
42 #include "compat.h"
43 #include "pathnames.h"
44 #include "cipher.h"
45 #include "sshkey.h"
46 #include "kex.h"
47 #include "mac.h"
48 #include "match.h"
49 #include "channels.h"
50 #include "groupaccess.h"
51 #include "canohost.h"
52 #include "packet.h"
53 #include "ssherr.h"
54 #include "hostfile.h"
55 #include "auth.h"
56 #include "myproposal.h"
57 #include "digest.h"
58 
59 static void add_listen_addr(ServerOptions *, const char *,
60     const char *, int);
61 static void add_one_listen_addr(ServerOptions *, const char *,
62     const char *, int);
63 
64 /* Use of privilege separation or not */
65 extern int use_privsep;
66 extern struct sshbuf *cfg;
67 
68 /* Initializes the server options to their default values. */
69 
70 void
71 initialize_server_options(ServerOptions *options)
72 {
73 	memset(options, 0, sizeof(*options));
74 	options->num_ports = 0;
75 	options->ports_from_cmdline = 0;
76 	options->queued_listen_addrs = NULL;
77 	options->num_queued_listens = 0;
78 	options->listen_addrs = NULL;
79 	options->num_listen_addrs = 0;
80 	options->address_family = -1;
81 	options->routing_domain = NULL;
82 	options->num_host_key_files = 0;
83 	options->num_host_cert_files = 0;
84 	options->host_key_agent = NULL;
85 	options->pid_file = NULL;
86 	options->login_grace_time = -1;
87 	options->permit_root_login = PERMIT_NOT_SET;
88 	options->ignore_rhosts = -1;
89 	options->ignore_user_known_hosts = -1;
90 	options->print_motd = -1;
91 	options->print_lastlog = -1;
92 	options->x11_forwarding = -1;
93 	options->x11_display_offset = -1;
94 	options->x11_use_localhost = -1;
95 	options->permit_tty = -1;
96 	options->permit_user_rc = -1;
97 	options->xauth_location = NULL;
98 	options->strict_modes = -1;
99 	options->tcp_keep_alive = -1;
100 	options->log_facility = SYSLOG_FACILITY_NOT_SET;
101 	options->log_level = SYSLOG_LEVEL_NOT_SET;
102 	options->hostbased_authentication = -1;
103 	options->hostbased_uses_name_from_packet_only = -1;
104 	options->hostbased_key_types = NULL;
105 	options->hostkeyalgorithms = NULL;
106 	options->pubkey_authentication = -1;
107 	options->pubkey_key_types = NULL;
108 	options->kerberos_authentication = -1;
109 	options->kerberos_or_local_passwd = -1;
110 	options->kerberos_ticket_cleanup = -1;
111 	options->kerberos_get_afs_token = -1;
112 	options->gss_authentication=-1;
113 	options->gss_cleanup_creds = -1;
114 	options->gss_strict_acceptor = -1;
115 	options->password_authentication = -1;
116 	options->kbd_interactive_authentication = -1;
117 	options->challenge_response_authentication = -1;
118 	options->permit_empty_passwd = -1;
119 	options->permit_user_env = -1;
120 	options->permit_user_env_whitelist = NULL;
121 	options->compression = -1;
122 	options->rekey_limit = -1;
123 	options->rekey_interval = -1;
124 	options->allow_tcp_forwarding = -1;
125 	options->allow_streamlocal_forwarding = -1;
126 	options->allow_agent_forwarding = -1;
127 	options->num_allow_users = 0;
128 	options->num_deny_users = 0;
129 	options->num_allow_groups = 0;
130 	options->num_deny_groups = 0;
131 	options->ciphers = NULL;
132 	options->macs = NULL;
133 	options->kex_algorithms = NULL;
134 	options->ca_sign_algorithms = NULL;
135 	options->fwd_opts.gateway_ports = -1;
136 	options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
137 	options->fwd_opts.streamlocal_bind_unlink = -1;
138 	options->num_subsystems = 0;
139 	options->max_startups_begin = -1;
140 	options->max_startups_rate = -1;
141 	options->max_startups = -1;
142 	options->max_authtries = -1;
143 	options->max_sessions = -1;
144 	options->banner = NULL;
145 	options->use_dns = -1;
146 	options->client_alive_interval = -1;
147 	options->client_alive_count_max = -1;
148 	options->num_authkeys_files = 0;
149 	options->num_accept_env = 0;
150 	options->num_setenv = 0;
151 	options->permit_tun = -1;
152 	options->permitted_opens = NULL;
153 	options->permitted_listens = NULL;
154 	options->adm_forced_command = NULL;
155 	options->chroot_directory = NULL;
156 	options->authorized_keys_command = NULL;
157 	options->authorized_keys_command_user = NULL;
158 	options->revoked_keys_file = NULL;
159 	options->trusted_user_ca_keys = NULL;
160 	options->authorized_principals_file = NULL;
161 	options->authorized_principals_command = NULL;
162 	options->authorized_principals_command_user = NULL;
163 	options->ip_qos_interactive = -1;
164 	options->ip_qos_bulk = -1;
165 	options->version_addendum = NULL;
166 	options->fingerprint_hash = -1;
167 	options->disable_forwarding = -1;
168 	options->expose_userauth_info = -1;
169 }
170 
171 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
172 static int
173 option_clear_or_none(const char *o)
174 {
175 	return o == NULL || strcasecmp(o, "none") == 0;
176 }
177 
178 static void
179 assemble_algorithms(ServerOptions *o)
180 {
181 	char *all_cipher, *all_mac, *all_kex, *all_key, *all_sig;
182 	int r;
183 
184 	all_cipher = cipher_alg_list(',', 0);
185 	all_mac = mac_alg_list(',');
186 	all_kex = kex_alg_list(',');
187 	all_key = sshkey_alg_list(0, 0, 1, ',');
188 	all_sig = sshkey_alg_list(0, 1, 1, ',');
189 #define ASSEMBLE(what, defaults, all) \
190 	do { \
191 		if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \
192 			fatal("%s: %s: %s", __func__, #what, ssh_err(r)); \
193 	} while (0)
194 	ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, all_cipher);
195 	ASSEMBLE(macs, KEX_SERVER_MAC, all_mac);
196 	ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, all_kex);
197 	ASSEMBLE(hostkeyalgorithms, KEX_DEFAULT_PK_ALG, all_key);
198 	ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key);
199 	ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key);
200 	ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, all_sig);
201 #undef ASSEMBLE
202 	free(all_cipher);
203 	free(all_mac);
204 	free(all_kex);
205 	free(all_key);
206 	free(all_sig);
207 }
208 
209 static void
210 array_append2(const char *file, const int line, const char *directive,
211     char ***array, int **iarray, u_int *lp, const char *s, int i)
212 {
213 
214 	if (*lp >= INT_MAX)
215 		fatal("%s line %d: Too many %s entries", file, line, directive);
216 
217 	if (iarray != NULL) {
218 		*iarray = xrecallocarray(*iarray, *lp, *lp + 1,
219 		    sizeof(**iarray));
220 		(*iarray)[*lp] = i;
221 	}
222 
223 	*array = xrecallocarray(*array, *lp, *lp + 1, sizeof(**array));
224 	(*array)[*lp] = xstrdup(s);
225 	(*lp)++;
226 }
227 
228 static void
229 array_append(const char *file, const int line, const char *directive,
230     char ***array, u_int *lp, const char *s)
231 {
232 	array_append2(file, line, directive, array, NULL, lp, s, 0);
233 }
234 
235 void
236 servconf_add_hostkey(const char *file, const int line,
237     ServerOptions *options, const char *path, int userprovided)
238 {
239 	char *apath = derelativise_path(path);
240 
241 	array_append2(file, line, "HostKey",
242 	    &options->host_key_files, &options->host_key_file_userprovided,
243 	    &options->num_host_key_files, apath, userprovided);
244 	free(apath);
245 }
246 
247 void
248 servconf_add_hostcert(const char *file, const int line,
249     ServerOptions *options, const char *path)
250 {
251 	char *apath = derelativise_path(path);
252 
253 	array_append(file, line, "HostCertificate",
254 	    &options->host_cert_files, &options->num_host_cert_files, apath);
255 	free(apath);
256 }
257 
258 void
259 fill_default_server_options(ServerOptions *options)
260 {
261 	u_int i;
262 
263 	if (options->num_host_key_files == 0) {
264 		/* fill default hostkeys */
265 		servconf_add_hostkey("[default]", 0, options,
266 		    _PATH_HOST_RSA_KEY_FILE, 0);
267 		servconf_add_hostkey("[default]", 0, options,
268 		    _PATH_HOST_ECDSA_KEY_FILE, 0);
269 		servconf_add_hostkey("[default]", 0, options,
270 		    _PATH_HOST_ED25519_KEY_FILE, 0);
271 #ifdef WITH_XMSS
272 		servconf_add_hostkey("[default]", 0, options,
273 		    _PATH_HOST_XMSS_KEY_FILE, 0);
274 #endif /* WITH_XMSS */
275 	}
276 	/* No certificates by default */
277 	if (options->num_ports == 0)
278 		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
279 	if (options->address_family == -1)
280 		options->address_family = AF_UNSPEC;
281 	if (options->listen_addrs == NULL)
282 		add_listen_addr(options, NULL, NULL, 0);
283 	if (options->pid_file == NULL)
284 		options->pid_file = xstrdup(_PATH_SSH_DAEMON_PID_FILE);
285 	if (options->login_grace_time == -1)
286 		options->login_grace_time = 120;
287 	if (options->permit_root_login == PERMIT_NOT_SET)
288 		options->permit_root_login = PERMIT_NO_PASSWD;
289 	if (options->ignore_rhosts == -1)
290 		options->ignore_rhosts = 1;
291 	if (options->ignore_user_known_hosts == -1)
292 		options->ignore_user_known_hosts = 0;
293 	if (options->print_motd == -1)
294 		options->print_motd = 1;
295 	if (options->print_lastlog == -1)
296 		options->print_lastlog = 1;
297 	if (options->x11_forwarding == -1)
298 		options->x11_forwarding = 0;
299 	if (options->x11_display_offset == -1)
300 		options->x11_display_offset = 10;
301 	if (options->x11_use_localhost == -1)
302 		options->x11_use_localhost = 1;
303 	if (options->xauth_location == NULL)
304 		options->xauth_location = xstrdup(_PATH_XAUTH);
305 	if (options->permit_tty == -1)
306 		options->permit_tty = 1;
307 	if (options->permit_user_rc == -1)
308 		options->permit_user_rc = 1;
309 	if (options->strict_modes == -1)
310 		options->strict_modes = 1;
311 	if (options->tcp_keep_alive == -1)
312 		options->tcp_keep_alive = 1;
313 	if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
314 		options->log_facility = SYSLOG_FACILITY_AUTH;
315 	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
316 		options->log_level = SYSLOG_LEVEL_INFO;
317 	if (options->hostbased_authentication == -1)
318 		options->hostbased_authentication = 0;
319 	if (options->hostbased_uses_name_from_packet_only == -1)
320 		options->hostbased_uses_name_from_packet_only = 0;
321 	if (options->pubkey_authentication == -1)
322 		options->pubkey_authentication = 1;
323 	if (options->kerberos_authentication == -1)
324 		options->kerberos_authentication = 0;
325 	if (options->kerberos_or_local_passwd == -1)
326 		options->kerberos_or_local_passwd = 1;
327 	if (options->kerberos_ticket_cleanup == -1)
328 		options->kerberos_ticket_cleanup = 1;
329 	if (options->kerberos_get_afs_token == -1)
330 		options->kerberos_get_afs_token = 0;
331 	if (options->gss_authentication == -1)
332 		options->gss_authentication = 0;
333 	if (options->gss_cleanup_creds == -1)
334 		options->gss_cleanup_creds = 1;
335 	if (options->gss_strict_acceptor == -1)
336 		options->gss_strict_acceptor = 1;
337 	if (options->password_authentication == -1)
338 		options->password_authentication = 1;
339 	if (options->kbd_interactive_authentication == -1)
340 		options->kbd_interactive_authentication = 0;
341 	if (options->challenge_response_authentication == -1)
342 		options->challenge_response_authentication = 1;
343 	if (options->permit_empty_passwd == -1)
344 		options->permit_empty_passwd = 0;
345 	if (options->permit_user_env == -1) {
346 		options->permit_user_env = 0;
347 		options->permit_user_env_whitelist = NULL;
348 	}
349 	if (options->compression == -1)
350 		options->compression = COMP_DELAYED;
351 	if (options->rekey_limit == -1)
352 		options->rekey_limit = 0;
353 	if (options->rekey_interval == -1)
354 		options->rekey_interval = 0;
355 	if (options->allow_tcp_forwarding == -1)
356 		options->allow_tcp_forwarding = FORWARD_ALLOW;
357 	if (options->allow_streamlocal_forwarding == -1)
358 		options->allow_streamlocal_forwarding = FORWARD_ALLOW;
359 	if (options->allow_agent_forwarding == -1)
360 		options->allow_agent_forwarding = 1;
361 	if (options->fwd_opts.gateway_ports == -1)
362 		options->fwd_opts.gateway_ports = 0;
363 	if (options->max_startups == -1)
364 		options->max_startups = 100;
365 	if (options->max_startups_rate == -1)
366 		options->max_startups_rate = 30;		/* 30% */
367 	if (options->max_startups_begin == -1)
368 		options->max_startups_begin = 10;
369 	if (options->max_authtries == -1)
370 		options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
371 	if (options->max_sessions == -1)
372 		options->max_sessions = DEFAULT_SESSIONS_MAX;
373 	if (options->use_dns == -1)
374 		options->use_dns = 0;
375 	if (options->client_alive_interval == -1)
376 		options->client_alive_interval = 0;
377 	if (options->client_alive_count_max == -1)
378 		options->client_alive_count_max = 3;
379 	if (options->num_authkeys_files == 0) {
380 		array_append("[default]", 0, "AuthorizedKeysFiles",
381 		    &options->authorized_keys_files,
382 		    &options->num_authkeys_files,
383 		    _PATH_SSH_USER_PERMITTED_KEYS);
384 		array_append("[default]", 0, "AuthorizedKeysFiles",
385 		    &options->authorized_keys_files,
386 		    &options->num_authkeys_files,
387 		    _PATH_SSH_USER_PERMITTED_KEYS2);
388 	}
389 	if (options->permit_tun == -1)
390 		options->permit_tun = SSH_TUNMODE_NO;
391 	if (options->ip_qos_interactive == -1)
392 		options->ip_qos_interactive = IPTOS_DSCP_AF21;
393 	if (options->ip_qos_bulk == -1)
394 		options->ip_qos_bulk = IPTOS_DSCP_CS1;
395 	if (options->version_addendum == NULL)
396 		options->version_addendum = xstrdup("");
397 	if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
398 		options->fwd_opts.streamlocal_bind_mask = 0177;
399 	if (options->fwd_opts.streamlocal_bind_unlink == -1)
400 		options->fwd_opts.streamlocal_bind_unlink = 0;
401 	if (options->fingerprint_hash == -1)
402 		options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
403 	if (options->disable_forwarding == -1)
404 		options->disable_forwarding = 0;
405 	if (options->expose_userauth_info == -1)
406 		options->expose_userauth_info = 0;
407 
408 	assemble_algorithms(options);
409 
410 	/* Turn privilege separation and sandboxing on by default */
411 	if (use_privsep == -1)
412 		use_privsep = PRIVSEP_ON;
413 
414 #define CLEAR_ON_NONE(v) \
415 	do { \
416 		if (option_clear_or_none(v)) { \
417 			free(v); \
418 			v = NULL; \
419 		} \
420 	} while(0)
421 	CLEAR_ON_NONE(options->pid_file);
422 	CLEAR_ON_NONE(options->xauth_location);
423 	CLEAR_ON_NONE(options->banner);
424 	CLEAR_ON_NONE(options->trusted_user_ca_keys);
425 	CLEAR_ON_NONE(options->revoked_keys_file);
426 	CLEAR_ON_NONE(options->authorized_principals_file);
427 	CLEAR_ON_NONE(options->adm_forced_command);
428 	CLEAR_ON_NONE(options->chroot_directory);
429 	CLEAR_ON_NONE(options->routing_domain);
430 	for (i = 0; i < options->num_host_key_files; i++)
431 		CLEAR_ON_NONE(options->host_key_files[i]);
432 	for (i = 0; i < options->num_host_cert_files; i++)
433 		CLEAR_ON_NONE(options->host_cert_files[i]);
434 #undef CLEAR_ON_NONE
435 
436 	/* Similar handling for AuthenticationMethods=any */
437 	if (options->num_auth_methods == 1 &&
438 	    strcmp(options->auth_methods[0], "any") == 0) {
439 		free(options->auth_methods[0]);
440 		options->auth_methods[0] = NULL;
441 		options->num_auth_methods = 0;
442 	}
443 }
444 
445 /* Keyword tokens. */
446 typedef enum {
447 	sBadOption,		/* == unknown option */
448 	sPort, sHostKeyFile, sLoginGraceTime,
449 	sPermitRootLogin, sLogFacility, sLogLevel,
450 	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
451 	sKerberosGetAFSToken, sChallengeResponseAuthentication,
452 	sPasswordAuthentication, sKbdInteractiveAuthentication,
453 	sListenAddress, sAddressFamily,
454 	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
455 	sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
456 	sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive,
457 	sPermitUserEnvironment, sAllowTcpForwarding, sCompression,
458 	sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
459 	sIgnoreUserKnownHosts, sCiphers, sMacs, sPidFile,
460 	sGatewayPorts, sPubkeyAuthentication, sPubkeyAcceptedKeyTypes,
461 	sXAuthLocation, sSubsystem, sMaxStartups, sMaxAuthTries, sMaxSessions,
462 	sBanner, sUseDNS, sHostbasedAuthentication,
463 	sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes,
464 	sHostKeyAlgorithms,
465 	sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
466 	sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
467 	sAcceptEnv, sSetEnv, sPermitTunnel,
468 	sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory,
469 	sUsePrivilegeSeparation, sAllowAgentForwarding,
470 	sHostCertificate,
471 	sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
472 	sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser,
473 	sKexAlgorithms, sCASignatureAlgorithms, sIPQoS, sVersionAddendum,
474 	sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
475 	sAuthenticationMethods, sHostKeyAgent, sPermitUserRC,
476 	sStreamLocalBindMask, sStreamLocalBindUnlink,
477 	sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding,
478 	sExposeAuthInfo, sRDomain,
479 	sDeprecated, sIgnore, sUnsupported
480 } ServerOpCodes;
481 
482 #define SSHCFG_GLOBAL	0x01	/* allowed in main section of sshd_config */
483 #define SSHCFG_MATCH	0x02	/* allowed inside a Match section */
484 #define SSHCFG_ALL	(SSHCFG_GLOBAL|SSHCFG_MATCH)
485 
486 /* Textual representation of the tokens. */
487 static struct {
488 	const char *name;
489 	ServerOpCodes opcode;
490 	u_int flags;
491 } keywords[] = {
492 	{ "port", sPort, SSHCFG_GLOBAL },
493 	{ "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
494 	{ "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL },		/* alias */
495 	{ "hostkeyagent", sHostKeyAgent, SSHCFG_GLOBAL },
496 	{ "pidfile", sPidFile, SSHCFG_GLOBAL },
497 	{ "serverkeybits", sDeprecated, SSHCFG_GLOBAL },
498 	{ "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
499 	{ "keyregenerationinterval", sDeprecated, SSHCFG_GLOBAL },
500 	{ "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
501 	{ "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
502 	{ "loglevel", sLogLevel, SSHCFG_ALL },
503 	{ "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
504 	{ "rhostsrsaauthentication", sDeprecated, SSHCFG_ALL },
505 	{ "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
506 	{ "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_ALL },
507 	{ "hostbasedacceptedkeytypes", sHostbasedAcceptedKeyTypes, SSHCFG_ALL },
508 	{ "hostkeyalgorithms", sHostKeyAlgorithms, SSHCFG_GLOBAL },
509 	{ "rsaauthentication", sDeprecated, SSHCFG_ALL },
510 	{ "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
511 	{ "pubkeyacceptedkeytypes", sPubkeyAcceptedKeyTypes, SSHCFG_ALL },
512 	{ "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
513 #ifdef KRB5
514 	{ "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
515 	{ "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
516 	{ "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
517 	{ "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
518 #else
519 	{ "kerberosauthentication", sUnsupported, SSHCFG_ALL },
520 	{ "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
521 	{ "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
522 	{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
523 #endif
524 	{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
525 	{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
526 #ifdef GSSAPI
527 	{ "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
528 	{ "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
529 	{ "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
530 #else
531 	{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
532 	{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
533 	{ "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
534 #endif
535 	{ "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
536 	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
537 	{ "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
538 	{ "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
539 	{ "checkmail", sDeprecated, SSHCFG_GLOBAL },
540 	{ "listenaddress", sListenAddress, SSHCFG_GLOBAL },
541 	{ "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
542 	{ "printmotd", sPrintMotd, SSHCFG_GLOBAL },
543 	{ "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
544 	{ "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
545 	{ "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
546 	{ "x11forwarding", sX11Forwarding, SSHCFG_ALL },
547 	{ "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
548 	{ "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
549 	{ "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
550 	{ "strictmodes", sStrictModes, SSHCFG_GLOBAL },
551 	{ "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL },
552 	{ "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
553 	{ "uselogin", sDeprecated, SSHCFG_GLOBAL },
554 	{ "compression", sCompression, SSHCFG_GLOBAL },
555 	{ "rekeylimit", sRekeyLimit, SSHCFG_ALL },
556 	{ "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
557 	{ "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL },	/* obsolete alias */
558 	{ "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
559 	{ "allowagentforwarding", sAllowAgentForwarding, SSHCFG_ALL },
560 	{ "allowusers", sAllowUsers, SSHCFG_ALL },
561 	{ "denyusers", sDenyUsers, SSHCFG_ALL },
562 	{ "allowgroups", sAllowGroups, SSHCFG_ALL },
563 	{ "denygroups", sDenyGroups, SSHCFG_ALL },
564 	{ "ciphers", sCiphers, SSHCFG_GLOBAL },
565 	{ "macs", sMacs, SSHCFG_GLOBAL },
566 	{ "protocol", sIgnore, SSHCFG_GLOBAL },
567 	{ "gatewayports", sGatewayPorts, SSHCFG_ALL },
568 	{ "subsystem", sSubsystem, SSHCFG_GLOBAL },
569 	{ "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
570 	{ "maxauthtries", sMaxAuthTries, SSHCFG_ALL },
571 	{ "maxsessions", sMaxSessions, SSHCFG_ALL },
572 	{ "banner", sBanner, SSHCFG_ALL },
573 	{ "usedns", sUseDNS, SSHCFG_GLOBAL },
574 	{ "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
575 	{ "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
576 	{ "clientaliveinterval", sClientAliveInterval, SSHCFG_ALL },
577 	{ "clientalivecountmax", sClientAliveCountMax, SSHCFG_ALL },
578 	{ "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_ALL },
579 	{ "authorizedkeysfile2", sDeprecated, SSHCFG_ALL },
580 	{ "useprivilegeseparation", sDeprecated, SSHCFG_GLOBAL},
581 	{ "acceptenv", sAcceptEnv, SSHCFG_ALL },
582 	{ "setenv", sSetEnv, SSHCFG_ALL },
583 	{ "permittunnel", sPermitTunnel, SSHCFG_ALL },
584 	{ "permittty", sPermitTTY, SSHCFG_ALL },
585 	{ "permituserrc", sPermitUserRC, SSHCFG_ALL },
586 	{ "match", sMatch, SSHCFG_ALL },
587 	{ "permitopen", sPermitOpen, SSHCFG_ALL },
588 	{ "permitlisten", sPermitListen, SSHCFG_ALL },
589 	{ "forcecommand", sForceCommand, SSHCFG_ALL },
590 	{ "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
591 	{ "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
592 	{ "revokedkeys", sRevokedKeys, SSHCFG_ALL },
593 	{ "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
594 	{ "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
595 	{ "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
596 	{ "ipqos", sIPQoS, SSHCFG_ALL },
597 	{ "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL },
598 	{ "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL },
599 	{ "authorizedprincipalscommand", sAuthorizedPrincipalsCommand, SSHCFG_ALL },
600 	{ "authorizedprincipalscommanduser", sAuthorizedPrincipalsCommandUser, SSHCFG_ALL },
601 	{ "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
602 	{ "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL },
603 	{ "streamlocalbindmask", sStreamLocalBindMask, SSHCFG_ALL },
604 	{ "streamlocalbindunlink", sStreamLocalBindUnlink, SSHCFG_ALL },
605 	{ "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL },
606 	{ "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL },
607 	{ "disableforwarding", sDisableForwarding, SSHCFG_ALL },
608 	{ "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL },
609 	{ "rdomain", sRDomain, SSHCFG_ALL },
610 	{ "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL },
611 	{ NULL, sBadOption, 0 }
612 };
613 
614 static struct {
615 	int val;
616 	char *text;
617 } tunmode_desc[] = {
618 	{ SSH_TUNMODE_NO, "no" },
619 	{ SSH_TUNMODE_POINTOPOINT, "point-to-point" },
620 	{ SSH_TUNMODE_ETHERNET, "ethernet" },
621 	{ SSH_TUNMODE_YES, "yes" },
622 	{ -1, NULL }
623 };
624 
625 /* Returns an opcode name from its number */
626 
627 static const char *
628 lookup_opcode_name(ServerOpCodes code)
629 {
630 	u_int i;
631 
632 	for (i = 0; keywords[i].name != NULL; i++)
633 		if (keywords[i].opcode == code)
634 			return(keywords[i].name);
635 	return "UNKNOWN";
636 }
637 
638 
639 /*
640  * Returns the number of the token pointed to by cp or sBadOption.
641  */
642 
643 static ServerOpCodes
644 parse_token(const char *cp, const char *filename,
645 	    int linenum, u_int *flags)
646 {
647 	u_int i;
648 
649 	for (i = 0; keywords[i].name; i++)
650 		if (strcasecmp(cp, keywords[i].name) == 0) {
651 			*flags = keywords[i].flags;
652 			return keywords[i].opcode;
653 		}
654 
655 	error("%s: line %d: Bad configuration option: %s",
656 	    filename, linenum, cp);
657 	return sBadOption;
658 }
659 
660 char *
661 derelativise_path(const char *path)
662 {
663 	char *expanded, *ret, cwd[PATH_MAX];
664 
665 	if (strcasecmp(path, "none") == 0)
666 		return xstrdup("none");
667 	expanded = tilde_expand_filename(path, getuid());
668 	if (path_absolute(expanded))
669 		return expanded;
670 	if (getcwd(cwd, sizeof(cwd)) == NULL)
671 		fatal("%s: getcwd: %s", __func__, strerror(errno));
672 	xasprintf(&ret, "%s/%s", cwd, expanded);
673 	free(expanded);
674 	return ret;
675 }
676 
677 static void
678 add_listen_addr(ServerOptions *options, const char *addr,
679     const char *rdomain, int port)
680 {
681 	u_int i;
682 
683 	if (port > 0)
684 		add_one_listen_addr(options, addr, rdomain, port);
685 	else {
686 		for (i = 0; i < options->num_ports; i++) {
687 			add_one_listen_addr(options, addr, rdomain,
688 			    options->ports[i]);
689 		}
690 	}
691 }
692 
693 static void
694 add_one_listen_addr(ServerOptions *options, const char *addr,
695     const char *rdomain, int port)
696 {
697 	struct addrinfo hints, *ai, *aitop;
698 	char strport[NI_MAXSERV];
699 	int gaierr;
700 	u_int i;
701 
702 	/* Find listen_addrs entry for this rdomain */
703 	for (i = 0; i < options->num_listen_addrs; i++) {
704 		if (rdomain == NULL && options->listen_addrs[i].rdomain == NULL)
705 			break;
706 		if (rdomain == NULL || options->listen_addrs[i].rdomain == NULL)
707 			continue;
708 		if (strcmp(rdomain, options->listen_addrs[i].rdomain) == 0)
709 			break;
710 	}
711 	if (i >= options->num_listen_addrs) {
712 		/* No entry for this rdomain; allocate one */
713 		if (i >= INT_MAX)
714 			fatal("%s: too many listen addresses", __func__);
715 		options->listen_addrs = xrecallocarray(options->listen_addrs,
716 		    options->num_listen_addrs, options->num_listen_addrs + 1,
717 		    sizeof(*options->listen_addrs));
718 		i = options->num_listen_addrs++;
719 		if (rdomain != NULL)
720 			options->listen_addrs[i].rdomain = xstrdup(rdomain);
721 	}
722 	/* options->listen_addrs[i] points to the addresses for this rdomain */
723 
724 	memset(&hints, 0, sizeof(hints));
725 	hints.ai_family = options->address_family;
726 	hints.ai_socktype = SOCK_STREAM;
727 	hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
728 	snprintf(strport, sizeof strport, "%d", port);
729 	if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
730 		fatal("bad addr or host: %s (%s)",
731 		    addr ? addr : "<NULL>",
732 		    ssh_gai_strerror(gaierr));
733 	for (ai = aitop; ai->ai_next; ai = ai->ai_next)
734 		;
735 	ai->ai_next = options->listen_addrs[i].addrs;
736 	options->listen_addrs[i].addrs = aitop;
737 }
738 
739 /* Returns nonzero if the routing domain name is valid */
740 static int
741 valid_rdomain(const char *name)
742 {
743 	const char *errstr;
744 	long long num;
745 	struct rt_tableinfo info;
746 	int mib[6];
747 	size_t miblen = sizeof(mib);
748 
749 	if (name == NULL)
750 		return 1;
751 
752 	num = strtonum(name, 0, 255, &errstr);
753 	if (errstr != NULL)
754 		return 0;
755 
756 	/* Check whether the table actually exists */
757 	memset(mib, 0, sizeof(mib));
758 	mib[0] = CTL_NET;
759 	mib[1] = PF_ROUTE;
760 	mib[4] = NET_RT_TABLE;
761 	mib[5] = (int)num;
762 	if (sysctl(mib, 6, &info, &miblen, NULL, 0) == -1)
763 		return 0;
764 
765 	return 1;
766 }
767 
768 /*
769  * Queue a ListenAddress to be processed once we have all of the Ports
770  * and AddressFamily options.
771  */
772 static void
773 queue_listen_addr(ServerOptions *options, const char *addr,
774     const char *rdomain, int port)
775 {
776 	struct queued_listenaddr *qla;
777 
778 	options->queued_listen_addrs = xrecallocarray(
779 	    options->queued_listen_addrs,
780 	    options->num_queued_listens, options->num_queued_listens + 1,
781 	    sizeof(*options->queued_listen_addrs));
782 	qla = &options->queued_listen_addrs[options->num_queued_listens++];
783 	qla->addr = xstrdup(addr);
784 	qla->port = port;
785 	qla->rdomain = rdomain == NULL ? NULL : xstrdup(rdomain);
786 }
787 
788 /*
789  * Process queued (text) ListenAddress entries.
790  */
791 static void
792 process_queued_listen_addrs(ServerOptions *options)
793 {
794 	u_int i;
795 	struct queued_listenaddr *qla;
796 
797 	if (options->num_ports == 0)
798 		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
799 	if (options->address_family == -1)
800 		options->address_family = AF_UNSPEC;
801 
802 	for (i = 0; i < options->num_queued_listens; i++) {
803 		qla = &options->queued_listen_addrs[i];
804 		add_listen_addr(options, qla->addr, qla->rdomain, qla->port);
805 		free(qla->addr);
806 		free(qla->rdomain);
807 	}
808 	free(options->queued_listen_addrs);
809 	options->queued_listen_addrs = NULL;
810 	options->num_queued_listens = 0;
811 }
812 
813 /*
814  * Inform channels layer of permitopen options for a single forwarding
815  * direction (local/remote).
816  */
817 static void
818 process_permitopen_list(struct ssh *ssh, ServerOpCodes opcode,
819     char **opens, u_int num_opens)
820 {
821 	u_int i;
822 	int port;
823 	char *host, *arg, *oarg, ch;
824 	int where = opcode == sPermitOpen ? FORWARD_LOCAL : FORWARD_REMOTE;
825 	const char *what = lookup_opcode_name(opcode);
826 
827 	channel_clear_permission(ssh, FORWARD_ADM, where);
828 	if (num_opens == 0)
829 		return; /* permit any */
830 
831 	/* handle keywords: "any" / "none" */
832 	if (num_opens == 1 && strcmp(opens[0], "any") == 0)
833 		return;
834 	if (num_opens == 1 && strcmp(opens[0], "none") == 0) {
835 		channel_disable_admin(ssh, where);
836 		return;
837 	}
838 	/* Otherwise treat it as a list of permitted host:port */
839 	for (i = 0; i < num_opens; i++) {
840 		oarg = arg = xstrdup(opens[i]);
841 		ch = '\0';
842 		host = hpdelim2(&arg, &ch);
843 		if (host == NULL || ch == '/')
844 			fatal("%s: missing host in %s", __func__, what);
845 		host = cleanhostname(host);
846 		if (arg == NULL || ((port = permitopen_port(arg)) < 0))
847 			fatal("%s: bad port number in %s", __func__, what);
848 		/* Send it to channels layer */
849 		channel_add_permission(ssh, FORWARD_ADM,
850 		    where, host, port);
851 		free(oarg);
852 	}
853 }
854 
855 /*
856  * Inform channels layer of permitopen options from configuration.
857  */
858 void
859 process_permitopen(struct ssh *ssh, ServerOptions *options)
860 {
861 	process_permitopen_list(ssh, sPermitOpen,
862 	    options->permitted_opens, options->num_permitted_opens);
863 	process_permitopen_list(ssh, sPermitListen,
864 	    options->permitted_listens,
865 	    options->num_permitted_listens);
866 }
867 
868 struct connection_info *
869 get_connection_info(struct ssh *ssh, int populate, int use_dns)
870 {
871 	static struct connection_info ci;
872 
873 	if (ssh == NULL || !populate)
874 		return &ci;
875 	ci.host = auth_get_canonical_hostname(ssh, use_dns);
876 	ci.address = ssh_remote_ipaddr(ssh);
877 	ci.laddress = ssh_local_ipaddr(ssh);
878 	ci.lport = ssh_local_port(ssh);
879 	ci.rdomain = ssh_packet_rdomain_in(ssh);
880 	return &ci;
881 }
882 
883 /*
884  * The strategy for the Match blocks is that the config file is parsed twice.
885  *
886  * The first time is at startup.  activep is initialized to 1 and the
887  * directives in the global context are processed and acted on.  Hitting a
888  * Match directive unsets activep and the directives inside the block are
889  * checked for syntax only.
890  *
891  * The second time is after a connection has been established but before
892  * authentication.  activep is initialized to 2 and global config directives
893  * are ignored since they have already been processed.  If the criteria in a
894  * Match block is met, activep is set and the subsequent directives
895  * processed and actioned until EOF or another Match block unsets it.  Any
896  * options set are copied into the main server config.
897  *
898  * Potential additions/improvements:
899  *  - Add Match support for pre-kex directives, eg. Ciphers.
900  *
901  *  - Add a Tag directive (idea from David Leonard) ala pf, eg:
902  *	Match Address 192.168.0.*
903  *		Tag trusted
904  *	Match Group wheel
905  *		Tag trusted
906  *	Match Tag trusted
907  *		AllowTcpForwarding yes
908  *		GatewayPorts clientspecified
909  *		[...]
910  *
911  *  - Add a PermittedChannelRequests directive
912  *	Match Group shell
913  *		PermittedChannelRequests session,forwarded-tcpip
914  */
915 
916 static int
917 match_cfg_line_group(const char *grps, int line, const char *user)
918 {
919 	int result = 0;
920 	struct passwd *pw;
921 
922 	if (user == NULL)
923 		goto out;
924 
925 	if ((pw = getpwnam(user)) == NULL) {
926 		debug("Can't match group at line %d because user %.100s does "
927 		    "not exist", line, user);
928 	} else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
929 		debug("Can't Match group because user %.100s not in any group "
930 		    "at line %d", user, line);
931 	} else if (ga_match_pattern_list(grps) != 1) {
932 		debug("user %.100s does not match group list %.100s at line %d",
933 		    user, grps, line);
934 	} else {
935 		debug("user %.100s matched group list %.100s at line %d", user,
936 		    grps, line);
937 		result = 1;
938 	}
939 out:
940 	ga_free();
941 	return result;
942 }
943 
944 static void
945 match_test_missing_fatal(const char *criteria, const char *attrib)
946 {
947 	fatal("'Match %s' in configuration but '%s' not in connection "
948 	    "test specification.", criteria, attrib);
949 }
950 
951 /*
952  * All of the attributes on a single Match line are ANDed together, so we need
953  * to check every attribute and set the result to zero if any attribute does
954  * not match.
955  */
956 static int
957 match_cfg_line(char **condition, int line, struct connection_info *ci)
958 {
959 	int result = 1, attributes = 0, port;
960 	char *arg, *attrib, *cp = *condition;
961 
962 	if (ci == NULL)
963 		debug3("checking syntax for 'Match %s'", cp);
964 	else
965 		debug3("checking match for '%s' user %s host %s addr %s "
966 		    "laddr %s lport %d", cp, ci->user ? ci->user : "(null)",
967 		    ci->host ? ci->host : "(null)",
968 		    ci->address ? ci->address : "(null)",
969 		    ci->laddress ? ci->laddress : "(null)", ci->lport);
970 
971 	while ((attrib = strdelim(&cp)) && *attrib != '\0') {
972 		attributes++;
973 		if (strcasecmp(attrib, "all") == 0) {
974 			if (attributes != 1 ||
975 			    ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
976 				error("'all' cannot be combined with other "
977 				    "Match attributes");
978 				return -1;
979 			}
980 			*condition = cp;
981 			return 1;
982 		}
983 		if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
984 			error("Missing Match criteria for %s", attrib);
985 			return -1;
986 		}
987 		if (strcasecmp(attrib, "user") == 0) {
988 			if (ci == NULL || (ci->test && ci->user == NULL)) {
989 				result = 0;
990 				continue;
991 			}
992 			if (ci->user == NULL)
993 				match_test_missing_fatal("User", "user");
994 			if (match_usergroup_pattern_list(ci->user, arg) != 1)
995 				result = 0;
996 			else
997 				debug("user %.100s matched 'User %.100s' at "
998 				    "line %d", ci->user, arg, line);
999 		} else if (strcasecmp(attrib, "group") == 0) {
1000 			if (ci == NULL || (ci->test && ci->user == NULL)) {
1001 				result = 0;
1002 				continue;
1003 			}
1004 			if (ci->user == NULL)
1005 				match_test_missing_fatal("Group", "user");
1006 			switch (match_cfg_line_group(arg, line, ci->user)) {
1007 			case -1:
1008 				return -1;
1009 			case 0:
1010 				result = 0;
1011 			}
1012 		} else if (strcasecmp(attrib, "host") == 0) {
1013 			if (ci == NULL || (ci->test && ci->host == NULL)) {
1014 				result = 0;
1015 				continue;
1016 			}
1017 			if (ci->host == NULL)
1018 				match_test_missing_fatal("Host", "host");
1019 			if (match_hostname(ci->host, arg) != 1)
1020 				result = 0;
1021 			else
1022 				debug("connection from %.100s matched 'Host "
1023 				    "%.100s' at line %d", ci->host, arg, line);
1024 		} else if (strcasecmp(attrib, "address") == 0) {
1025 			if (ci == NULL || (ci->test && ci->address == NULL)) {
1026 				result = 0;
1027 				continue;
1028 			}
1029 			if (ci->address == NULL)
1030 				match_test_missing_fatal("Address", "addr");
1031 			switch (addr_match_list(ci->address, arg)) {
1032 			case 1:
1033 				debug("connection from %.100s matched 'Address "
1034 				    "%.100s' at line %d", ci->address, arg, line);
1035 				break;
1036 			case 0:
1037 			case -1:
1038 				result = 0;
1039 				break;
1040 			case -2:
1041 				return -1;
1042 			}
1043 		} else if (strcasecmp(attrib, "localaddress") == 0){
1044 			if (ci == NULL || (ci->test && ci->laddress == NULL)) {
1045 				result = 0;
1046 				continue;
1047 			}
1048 			if (ci->laddress == NULL)
1049 				match_test_missing_fatal("LocalAddress",
1050 				    "laddr");
1051 			switch (addr_match_list(ci->laddress, arg)) {
1052 			case 1:
1053 				debug("connection from %.100s matched "
1054 				    "'LocalAddress %.100s' at line %d",
1055 				    ci->laddress, arg, line);
1056 				break;
1057 			case 0:
1058 			case -1:
1059 				result = 0;
1060 				break;
1061 			case -2:
1062 				return -1;
1063 			}
1064 		} else if (strcasecmp(attrib, "localport") == 0) {
1065 			if ((port = a2port(arg)) == -1) {
1066 				error("Invalid LocalPort '%s' on Match line",
1067 				    arg);
1068 				return -1;
1069 			}
1070 			if (ci == NULL || (ci->test && ci->lport == -1)) {
1071 				result = 0;
1072 				continue;
1073 			}
1074 			if (ci->lport == 0)
1075 				match_test_missing_fatal("LocalPort", "lport");
1076 			/* TODO support port lists */
1077 			if (port == ci->lport)
1078 				debug("connection from %.100s matched "
1079 				    "'LocalPort %d' at line %d",
1080 				    ci->laddress, port, line);
1081 			else
1082 				result = 0;
1083 		} else if (strcasecmp(attrib, "rdomain") == 0) {
1084 			if (ci == NULL || (ci->test && ci->rdomain == NULL)) {
1085 				result = 0;
1086 				continue;
1087 			}
1088 			if (ci->rdomain == NULL)
1089 				match_test_missing_fatal("RDomain", "rdomain");
1090 			if (match_pattern_list(ci->rdomain, arg, 0) != 1)
1091 				result = 0;
1092 			else
1093 				debug("user %.100s matched 'RDomain %.100s' at "
1094 				    "line %d", ci->rdomain, arg, line);
1095 		} else {
1096 			error("Unsupported Match attribute %s", attrib);
1097 			return -1;
1098 		}
1099 	}
1100 	if (attributes == 0) {
1101 		error("One or more attributes required for Match");
1102 		return -1;
1103 	}
1104 	if (ci != NULL)
1105 		debug3("match %sfound", result ? "" : "not ");
1106 	*condition = cp;
1107 	return result;
1108 }
1109 
1110 #define WHITESPACE " \t\r\n"
1111 
1112 /* Multistate option parsing */
1113 struct multistate {
1114 	char *key;
1115 	int value;
1116 };
1117 static const struct multistate multistate_flag[] = {
1118 	{ "yes",			1 },
1119 	{ "no",				0 },
1120 	{ NULL, -1 }
1121 };
1122 static const struct multistate multistate_addressfamily[] = {
1123 	{ "inet",			AF_INET },
1124 	{ "inet6",			AF_INET6 },
1125 	{ "any",			AF_UNSPEC },
1126 	{ NULL, -1 }
1127 };
1128 static const struct multistate multistate_permitrootlogin[] = {
1129 	{ "without-password",		PERMIT_NO_PASSWD },
1130 	{ "prohibit-password",		PERMIT_NO_PASSWD },
1131 	{ "forced-commands-only",	PERMIT_FORCED_ONLY },
1132 	{ "yes",			PERMIT_YES },
1133 	{ "no",				PERMIT_NO },
1134 	{ NULL, -1 }
1135 };
1136 static const struct multistate multistate_compression[] = {
1137 	{ "yes",			COMP_DELAYED },
1138 	{ "delayed",			COMP_DELAYED },
1139 	{ "no",				COMP_NONE },
1140 	{ NULL, -1 }
1141 };
1142 static const struct multistate multistate_gatewayports[] = {
1143 	{ "clientspecified",		2 },
1144 	{ "yes",			1 },
1145 	{ "no",				0 },
1146 	{ NULL, -1 }
1147 };
1148 static const struct multistate multistate_tcpfwd[] = {
1149 	{ "yes",			FORWARD_ALLOW },
1150 	{ "all",			FORWARD_ALLOW },
1151 	{ "no",				FORWARD_DENY },
1152 	{ "remote",			FORWARD_REMOTE },
1153 	{ "local",			FORWARD_LOCAL },
1154 	{ NULL, -1 }
1155 };
1156 
1157 int
1158 process_server_config_line(ServerOptions *options, char *line,
1159     const char *filename, int linenum, int *activep,
1160     struct connection_info *connectinfo)
1161 {
1162 	char ch, *cp, ***chararrayptr, **charptr, *arg, *arg2, *p;
1163 	int cmdline = 0, *intptr, value, value2, n, port;
1164 	SyslogFacility *log_facility_ptr;
1165 	LogLevel *log_level_ptr;
1166 	ServerOpCodes opcode;
1167 	u_int i, *uintptr, uvalue, flags = 0;
1168 	size_t len;
1169 	long long val64;
1170 	const struct multistate *multistate_ptr;
1171 	const char *errstr;
1172 
1173 	/* Strip trailing whitespace. Allow \f (form feed) at EOL only */
1174 	if ((len = strlen(line)) == 0)
1175 		return 0;
1176 	for (len--; len > 0; len--) {
1177 		if (strchr(WHITESPACE "\f", line[len]) == NULL)
1178 			break;
1179 		line[len] = '\0';
1180 	}
1181 
1182 	cp = line;
1183 	if ((arg = strdelim(&cp)) == NULL)
1184 		return 0;
1185 	/* Ignore leading whitespace */
1186 	if (*arg == '\0')
1187 		arg = strdelim(&cp);
1188 	if (!arg || !*arg || *arg == '#')
1189 		return 0;
1190 	intptr = NULL;
1191 	charptr = NULL;
1192 	opcode = parse_token(arg, filename, linenum, &flags);
1193 
1194 	if (activep == NULL) { /* We are processing a command line directive */
1195 		cmdline = 1;
1196 		activep = &cmdline;
1197 	}
1198 	if (*activep && opcode != sMatch)
1199 		debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
1200 	if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
1201 		if (connectinfo == NULL) {
1202 			fatal("%s line %d: Directive '%s' is not allowed "
1203 			    "within a Match block", filename, linenum, arg);
1204 		} else { /* this is a directive we have already processed */
1205 			while (arg)
1206 				arg = strdelim(&cp);
1207 			return 0;
1208 		}
1209 	}
1210 
1211 	switch (opcode) {
1212 	case sBadOption:
1213 		return -1;
1214 	case sPort:
1215 		/* ignore ports from configfile if cmdline specifies ports */
1216 		if (options->ports_from_cmdline)
1217 			return 0;
1218 		if (options->num_ports >= MAX_PORTS)
1219 			fatal("%s line %d: too many ports.",
1220 			    filename, linenum);
1221 		arg = strdelim(&cp);
1222 		if (!arg || *arg == '\0')
1223 			fatal("%s line %d: missing port number.",
1224 			    filename, linenum);
1225 		options->ports[options->num_ports++] = a2port(arg);
1226 		if (options->ports[options->num_ports-1] <= 0)
1227 			fatal("%s line %d: Badly formatted port number.",
1228 			    filename, linenum);
1229 		break;
1230 
1231 	case sLoginGraceTime:
1232 		intptr = &options->login_grace_time;
1233  parse_time:
1234 		arg = strdelim(&cp);
1235 		if (!arg || *arg == '\0')
1236 			fatal("%s line %d: missing time value.",
1237 			    filename, linenum);
1238 		if ((value = convtime(arg)) == -1)
1239 			fatal("%s line %d: invalid time value.",
1240 			    filename, linenum);
1241 		if (*activep && *intptr == -1)
1242 			*intptr = value;
1243 		break;
1244 
1245 	case sListenAddress:
1246 		arg = strdelim(&cp);
1247 		if (arg == NULL || *arg == '\0')
1248 			fatal("%s line %d: missing address",
1249 			    filename, linenum);
1250 		/* check for bare IPv6 address: no "[]" and 2 or more ":" */
1251 		if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
1252 		    && strchr(p+1, ':') != NULL) {
1253 			port = 0;
1254 			p = arg;
1255 		} else {
1256 			arg2 = NULL;
1257 			ch = '\0';
1258 			p = hpdelim2(&arg, &ch);
1259 			if (p == NULL || ch == '/')
1260 				fatal("%s line %d: bad address:port usage",
1261 				    filename, linenum);
1262 			p = cleanhostname(p);
1263 			if (arg == NULL)
1264 				port = 0;
1265 			else if ((port = a2port(arg)) <= 0)
1266 				fatal("%s line %d: bad port number",
1267 				    filename, linenum);
1268 		}
1269 		/* Optional routing table */
1270 		arg2 = NULL;
1271 		if ((arg = strdelim(&cp)) != NULL) {
1272 			if (strcmp(arg, "rdomain") != 0 ||
1273 			    (arg2 = strdelim(&cp)) == NULL)
1274 				fatal("%s line %d: bad ListenAddress syntax",
1275 				    filename, linenum);
1276 			if (!valid_rdomain(arg2))
1277 				fatal("%s line %d: bad routing domain",
1278 				    filename, linenum);
1279 		}
1280 
1281 		queue_listen_addr(options, p, arg2, port);
1282 
1283 		break;
1284 
1285 	case sAddressFamily:
1286 		intptr = &options->address_family;
1287 		multistate_ptr = multistate_addressfamily;
1288  parse_multistate:
1289 		arg = strdelim(&cp);
1290 		if (!arg || *arg == '\0')
1291 			fatal("%s line %d: missing argument.",
1292 			    filename, linenum);
1293 		value = -1;
1294 		for (i = 0; multistate_ptr[i].key != NULL; i++) {
1295 			if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
1296 				value = multistate_ptr[i].value;
1297 				break;
1298 			}
1299 		}
1300 		if (value == -1)
1301 			fatal("%s line %d: unsupported option \"%s\".",
1302 			    filename, linenum, arg);
1303 		if (*activep && *intptr == -1)
1304 			*intptr = value;
1305 		break;
1306 
1307 	case sHostKeyFile:
1308 		arg = strdelim(&cp);
1309 		if (!arg || *arg == '\0')
1310 			fatal("%s line %d: missing file name.",
1311 			    filename, linenum);
1312 		if (*activep) {
1313 			servconf_add_hostkey(filename, linenum,
1314 			    options, arg, 1);
1315 		}
1316 		break;
1317 
1318 	case sHostKeyAgent:
1319 		charptr = &options->host_key_agent;
1320 		arg = strdelim(&cp);
1321 		if (!arg || *arg == '\0')
1322 			fatal("%s line %d: missing socket name.",
1323 			    filename, linenum);
1324 		if (*activep && *charptr == NULL)
1325 			*charptr = !strcmp(arg, SSH_AUTHSOCKET_ENV_NAME) ?
1326 			    xstrdup(arg) : derelativise_path(arg);
1327 		break;
1328 
1329 	case sHostCertificate:
1330 		arg = strdelim(&cp);
1331 		if (!arg || *arg == '\0')
1332 			fatal("%s line %d: missing file name.",
1333 			    filename, linenum);
1334 		if (*activep)
1335 			servconf_add_hostcert(filename, linenum, options, arg);
1336 		break;
1337 
1338 	case sPidFile:
1339 		charptr = &options->pid_file;
1340  parse_filename:
1341 		arg = strdelim(&cp);
1342 		if (!arg || *arg == '\0')
1343 			fatal("%s line %d: missing file name.",
1344 			    filename, linenum);
1345 		if (*activep && *charptr == NULL) {
1346 			*charptr = derelativise_path(arg);
1347 			/* increase optional counter */
1348 			if (intptr != NULL)
1349 				*intptr = *intptr + 1;
1350 		}
1351 		break;
1352 
1353 	case sPermitRootLogin:
1354 		intptr = &options->permit_root_login;
1355 		multistate_ptr = multistate_permitrootlogin;
1356 		goto parse_multistate;
1357 
1358 	case sIgnoreRhosts:
1359 		intptr = &options->ignore_rhosts;
1360  parse_flag:
1361 		multistate_ptr = multistate_flag;
1362 		goto parse_multistate;
1363 
1364 	case sIgnoreUserKnownHosts:
1365 		intptr = &options->ignore_user_known_hosts;
1366 		goto parse_flag;
1367 
1368 	case sHostbasedAuthentication:
1369 		intptr = &options->hostbased_authentication;
1370 		goto parse_flag;
1371 
1372 	case sHostbasedUsesNameFromPacketOnly:
1373 		intptr = &options->hostbased_uses_name_from_packet_only;
1374 		goto parse_flag;
1375 
1376 	case sHostbasedAcceptedKeyTypes:
1377 		charptr = &options->hostbased_key_types;
1378  parse_keytypes:
1379 		arg = strdelim(&cp);
1380 		if (!arg || *arg == '\0')
1381 			fatal("%s line %d: Missing argument.",
1382 			    filename, linenum);
1383 		if (*arg != '-' &&
1384 		    !sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1))
1385 			fatal("%s line %d: Bad key types '%s'.",
1386 			    filename, linenum, arg ? arg : "<NONE>");
1387 		if (*activep && *charptr == NULL)
1388 			*charptr = xstrdup(arg);
1389 		break;
1390 
1391 	case sHostKeyAlgorithms:
1392 		charptr = &options->hostkeyalgorithms;
1393 		goto parse_keytypes;
1394 
1395 	case sCASignatureAlgorithms:
1396 		charptr = &options->ca_sign_algorithms;
1397 		goto parse_keytypes;
1398 
1399 	case sPubkeyAuthentication:
1400 		intptr = &options->pubkey_authentication;
1401 		goto parse_flag;
1402 
1403 	case sPubkeyAcceptedKeyTypes:
1404 		charptr = &options->pubkey_key_types;
1405 		goto parse_keytypes;
1406 
1407 	case sKerberosAuthentication:
1408 		intptr = &options->kerberos_authentication;
1409 		goto parse_flag;
1410 
1411 	case sKerberosOrLocalPasswd:
1412 		intptr = &options->kerberos_or_local_passwd;
1413 		goto parse_flag;
1414 
1415 	case sKerberosTicketCleanup:
1416 		intptr = &options->kerberos_ticket_cleanup;
1417 		goto parse_flag;
1418 
1419 	case sKerberosGetAFSToken:
1420 		intptr = &options->kerberos_get_afs_token;
1421 		goto parse_flag;
1422 
1423 	case sGssAuthentication:
1424 		intptr = &options->gss_authentication;
1425 		goto parse_flag;
1426 
1427 	case sGssCleanupCreds:
1428 		intptr = &options->gss_cleanup_creds;
1429 		goto parse_flag;
1430 
1431 	case sGssStrictAcceptor:
1432 		intptr = &options->gss_strict_acceptor;
1433 		goto parse_flag;
1434 
1435 	case sPasswordAuthentication:
1436 		intptr = &options->password_authentication;
1437 		goto parse_flag;
1438 
1439 	case sKbdInteractiveAuthentication:
1440 		intptr = &options->kbd_interactive_authentication;
1441 		goto parse_flag;
1442 
1443 	case sChallengeResponseAuthentication:
1444 		intptr = &options->challenge_response_authentication;
1445 		goto parse_flag;
1446 
1447 	case sPrintMotd:
1448 		intptr = &options->print_motd;
1449 		goto parse_flag;
1450 
1451 	case sPrintLastLog:
1452 		intptr = &options->print_lastlog;
1453 		goto parse_flag;
1454 
1455 	case sX11Forwarding:
1456 		intptr = &options->x11_forwarding;
1457 		goto parse_flag;
1458 
1459 	case sX11DisplayOffset:
1460 		intptr = &options->x11_display_offset;
1461  parse_int:
1462 		arg = strdelim(&cp);
1463 		if ((errstr = atoi_err(arg, &value)) != NULL)
1464 			fatal("%s line %d: integer value %s.",
1465 			    filename, linenum, errstr);
1466 		if (*activep && *intptr == -1)
1467 			*intptr = value;
1468 		break;
1469 
1470 	case sX11UseLocalhost:
1471 		intptr = &options->x11_use_localhost;
1472 		goto parse_flag;
1473 
1474 	case sXAuthLocation:
1475 		charptr = &options->xauth_location;
1476 		goto parse_filename;
1477 
1478 	case sPermitTTY:
1479 		intptr = &options->permit_tty;
1480 		goto parse_flag;
1481 
1482 	case sPermitUserRC:
1483 		intptr = &options->permit_user_rc;
1484 		goto parse_flag;
1485 
1486 	case sStrictModes:
1487 		intptr = &options->strict_modes;
1488 		goto parse_flag;
1489 
1490 	case sTCPKeepAlive:
1491 		intptr = &options->tcp_keep_alive;
1492 		goto parse_flag;
1493 
1494 	case sEmptyPasswd:
1495 		intptr = &options->permit_empty_passwd;
1496 		goto parse_flag;
1497 
1498 	case sPermitUserEnvironment:
1499 		intptr = &options->permit_user_env;
1500 		charptr = &options->permit_user_env_whitelist;
1501 		arg = strdelim(&cp);
1502 		if (!arg || *arg == '\0')
1503 			fatal("%s line %d: missing argument.",
1504 			    filename, linenum);
1505 		value = 0;
1506 		p = NULL;
1507 		if (strcmp(arg, "yes") == 0)
1508 			value = 1;
1509 		else if (strcmp(arg, "no") == 0)
1510 			value = 0;
1511 		else {
1512 			/* Pattern-list specified */
1513 			value = 1;
1514 			p = xstrdup(arg);
1515 		}
1516 		if (*activep && *intptr == -1) {
1517 			*intptr = value;
1518 			*charptr = p;
1519 			p = NULL;
1520 		}
1521 		free(p);
1522 		break;
1523 
1524 	case sCompression:
1525 		intptr = &options->compression;
1526 		multistate_ptr = multistate_compression;
1527 		goto parse_multistate;
1528 
1529 	case sRekeyLimit:
1530 		arg = strdelim(&cp);
1531 		if (!arg || *arg == '\0')
1532 			fatal("%.200s line %d: Missing argument.", filename,
1533 			    linenum);
1534 		if (strcmp(arg, "default") == 0) {
1535 			val64 = 0;
1536 		} else {
1537 			if (scan_scaled(arg, &val64) == -1)
1538 				fatal("%.200s line %d: Bad number '%s': %s",
1539 				    filename, linenum, arg, strerror(errno));
1540 			if (val64 != 0 && val64 < 16)
1541 				fatal("%.200s line %d: RekeyLimit too small",
1542 				    filename, linenum);
1543 		}
1544 		if (*activep && options->rekey_limit == -1)
1545 			options->rekey_limit = val64;
1546 		if (cp != NULL) { /* optional rekey interval present */
1547 			if (strcmp(cp, "none") == 0) {
1548 				(void)strdelim(&cp);	/* discard */
1549 				break;
1550 			}
1551 			intptr = &options->rekey_interval;
1552 			goto parse_time;
1553 		}
1554 		break;
1555 
1556 	case sGatewayPorts:
1557 		intptr = &options->fwd_opts.gateway_ports;
1558 		multistate_ptr = multistate_gatewayports;
1559 		goto parse_multistate;
1560 
1561 	case sUseDNS:
1562 		intptr = &options->use_dns;
1563 		goto parse_flag;
1564 
1565 	case sLogFacility:
1566 		log_facility_ptr = &options->log_facility;
1567 		arg = strdelim(&cp);
1568 		value = log_facility_number(arg);
1569 		if (value == SYSLOG_FACILITY_NOT_SET)
1570 			fatal("%.200s line %d: unsupported log facility '%s'",
1571 			    filename, linenum, arg ? arg : "<NONE>");
1572 		if (*log_facility_ptr == -1)
1573 			*log_facility_ptr = (SyslogFacility) value;
1574 		break;
1575 
1576 	case sLogLevel:
1577 		log_level_ptr = &options->log_level;
1578 		arg = strdelim(&cp);
1579 		value = log_level_number(arg);
1580 		if (value == SYSLOG_LEVEL_NOT_SET)
1581 			fatal("%.200s line %d: unsupported log level '%s'",
1582 			    filename, linenum, arg ? arg : "<NONE>");
1583 		if (*activep && *log_level_ptr == -1)
1584 			*log_level_ptr = (LogLevel) value;
1585 		break;
1586 
1587 	case sAllowTcpForwarding:
1588 		intptr = &options->allow_tcp_forwarding;
1589 		multistate_ptr = multistate_tcpfwd;
1590 		goto parse_multistate;
1591 
1592 	case sAllowStreamLocalForwarding:
1593 		intptr = &options->allow_streamlocal_forwarding;
1594 		multistate_ptr = multistate_tcpfwd;
1595 		goto parse_multistate;
1596 
1597 	case sAllowAgentForwarding:
1598 		intptr = &options->allow_agent_forwarding;
1599 		goto parse_flag;
1600 
1601 	case sDisableForwarding:
1602 		intptr = &options->disable_forwarding;
1603 		goto parse_flag;
1604 
1605 	case sAllowUsers:
1606 		while ((arg = strdelim(&cp)) && *arg != '\0') {
1607 			if (match_user(NULL, NULL, NULL, arg) == -1)
1608 				fatal("%s line %d: invalid AllowUsers pattern: "
1609 				    "\"%.100s\"", filename, linenum, arg);
1610 			if (!*activep)
1611 				continue;
1612 			array_append(filename, linenum, "AllowUsers",
1613 			    &options->allow_users, &options->num_allow_users,
1614 			    arg);
1615 		}
1616 		break;
1617 
1618 	case sDenyUsers:
1619 		while ((arg = strdelim(&cp)) && *arg != '\0') {
1620 			if (match_user(NULL, NULL, NULL, arg) == -1)
1621 				fatal("%s line %d: invalid DenyUsers pattern: "
1622 				    "\"%.100s\"", filename, linenum, arg);
1623 			if (!*activep)
1624 				continue;
1625 			array_append(filename, linenum, "DenyUsers",
1626 			    &options->deny_users, &options->num_deny_users,
1627 			    arg);
1628 		}
1629 		break;
1630 
1631 	case sAllowGroups:
1632 		while ((arg = strdelim(&cp)) && *arg != '\0') {
1633 			if (!*activep)
1634 				continue;
1635 			array_append(filename, linenum, "AllowGroups",
1636 			    &options->allow_groups, &options->num_allow_groups,
1637 			    arg);
1638 		}
1639 		break;
1640 
1641 	case sDenyGroups:
1642 		while ((arg = strdelim(&cp)) && *arg != '\0') {
1643 			if (!*activep)
1644 				continue;
1645 			array_append(filename, linenum, "DenyGroups",
1646 			    &options->deny_groups, &options->num_deny_groups,
1647 			    arg);
1648 		}
1649 		break;
1650 
1651 	case sCiphers:
1652 		arg = strdelim(&cp);
1653 		if (!arg || *arg == '\0')
1654 			fatal("%s line %d: Missing argument.", filename, linenum);
1655 		if (*arg != '-' && !ciphers_valid(*arg == '+' ? arg + 1 : arg))
1656 			fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1657 			    filename, linenum, arg ? arg : "<NONE>");
1658 		if (options->ciphers == NULL)
1659 			options->ciphers = xstrdup(arg);
1660 		break;
1661 
1662 	case sMacs:
1663 		arg = strdelim(&cp);
1664 		if (!arg || *arg == '\0')
1665 			fatal("%s line %d: Missing argument.", filename, linenum);
1666 		if (*arg != '-' && !mac_valid(*arg == '+' ? arg + 1 : arg))
1667 			fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1668 			    filename, linenum, arg ? arg : "<NONE>");
1669 		if (options->macs == NULL)
1670 			options->macs = xstrdup(arg);
1671 		break;
1672 
1673 	case sKexAlgorithms:
1674 		arg = strdelim(&cp);
1675 		if (!arg || *arg == '\0')
1676 			fatal("%s line %d: Missing argument.",
1677 			    filename, linenum);
1678 		if (*arg != '-' &&
1679 		    !kex_names_valid(*arg == '+' ? arg + 1 : arg))
1680 			fatal("%s line %d: Bad SSH2 KexAlgorithms '%s'.",
1681 			    filename, linenum, arg ? arg : "<NONE>");
1682 		if (options->kex_algorithms == NULL)
1683 			options->kex_algorithms = xstrdup(arg);
1684 		break;
1685 
1686 	case sSubsystem:
1687 		if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1688 			fatal("%s line %d: too many subsystems defined.",
1689 			    filename, linenum);
1690 		}
1691 		arg = strdelim(&cp);
1692 		if (!arg || *arg == '\0')
1693 			fatal("%s line %d: Missing subsystem name.",
1694 			    filename, linenum);
1695 		if (!*activep) {
1696 			arg = strdelim(&cp);
1697 			break;
1698 		}
1699 		for (i = 0; i < options->num_subsystems; i++)
1700 			if (strcmp(arg, options->subsystem_name[i]) == 0)
1701 				fatal("%s line %d: Subsystem '%s' already defined.",
1702 				    filename, linenum, arg);
1703 		options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1704 		arg = strdelim(&cp);
1705 		if (!arg || *arg == '\0')
1706 			fatal("%s line %d: Missing subsystem command.",
1707 			    filename, linenum);
1708 		options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1709 
1710 		/* Collect arguments (separate to executable) */
1711 		p = xstrdup(arg);
1712 		len = strlen(p) + 1;
1713 		while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1714 			len += 1 + strlen(arg);
1715 			p = xreallocarray(p, 1, len);
1716 			strlcat(p, " ", len);
1717 			strlcat(p, arg, len);
1718 		}
1719 		options->subsystem_args[options->num_subsystems] = p;
1720 		options->num_subsystems++;
1721 		break;
1722 
1723 	case sMaxStartups:
1724 		arg = strdelim(&cp);
1725 		if (!arg || *arg == '\0')
1726 			fatal("%s line %d: Missing MaxStartups spec.",
1727 			    filename, linenum);
1728 		if ((n = sscanf(arg, "%d:%d:%d",
1729 		    &options->max_startups_begin,
1730 		    &options->max_startups_rate,
1731 		    &options->max_startups)) == 3) {
1732 			if (options->max_startups_begin >
1733 			    options->max_startups ||
1734 			    options->max_startups_rate > 100 ||
1735 			    options->max_startups_rate < 1)
1736 				fatal("%s line %d: Illegal MaxStartups spec.",
1737 				    filename, linenum);
1738 		} else if (n != 1)
1739 			fatal("%s line %d: Illegal MaxStartups spec.",
1740 			    filename, linenum);
1741 		else
1742 			options->max_startups = options->max_startups_begin;
1743 		break;
1744 
1745 	case sMaxAuthTries:
1746 		intptr = &options->max_authtries;
1747 		goto parse_int;
1748 
1749 	case sMaxSessions:
1750 		intptr = &options->max_sessions;
1751 		goto parse_int;
1752 
1753 	case sBanner:
1754 		charptr = &options->banner;
1755 		goto parse_filename;
1756 
1757 	/*
1758 	 * These options can contain %X options expanded at
1759 	 * connect time, so that you can specify paths like:
1760 	 *
1761 	 * AuthorizedKeysFile	/etc/ssh_keys/%u
1762 	 */
1763 	case sAuthorizedKeysFile:
1764 		if (*activep && options->num_authkeys_files == 0) {
1765 			while ((arg = strdelim(&cp)) && *arg != '\0') {
1766 				arg = tilde_expand_filename(arg, getuid());
1767 				array_append(filename, linenum,
1768 				    "AuthorizedKeysFile",
1769 				    &options->authorized_keys_files,
1770 				    &options->num_authkeys_files, arg);
1771 				free(arg);
1772 			}
1773 		}
1774 		return 0;
1775 
1776 	case sAuthorizedPrincipalsFile:
1777 		charptr = &options->authorized_principals_file;
1778 		arg = strdelim(&cp);
1779 		if (!arg || *arg == '\0')
1780 			fatal("%s line %d: missing file name.",
1781 			    filename, linenum);
1782 		if (*activep && *charptr == NULL) {
1783 			*charptr = tilde_expand_filename(arg, getuid());
1784 			/* increase optional counter */
1785 			if (intptr != NULL)
1786 				*intptr = *intptr + 1;
1787 		}
1788 		break;
1789 
1790 	case sClientAliveInterval:
1791 		intptr = &options->client_alive_interval;
1792 		goto parse_time;
1793 
1794 	case sClientAliveCountMax:
1795 		intptr = &options->client_alive_count_max;
1796 		goto parse_int;
1797 
1798 	case sAcceptEnv:
1799 		while ((arg = strdelim(&cp)) && *arg != '\0') {
1800 			if (strchr(arg, '=') != NULL)
1801 				fatal("%s line %d: Invalid environment name.",
1802 				    filename, linenum);
1803 			if (!*activep)
1804 				continue;
1805 			array_append(filename, linenum, "AcceptEnv",
1806 			    &options->accept_env, &options->num_accept_env,
1807 			    arg);
1808 		}
1809 		break;
1810 
1811 	case sSetEnv:
1812 		uvalue = options->num_setenv;
1813 		while ((arg = strdelimw(&cp)) && *arg != '\0') {
1814 			if (strchr(arg, '=') == NULL)
1815 				fatal("%s line %d: Invalid environment.",
1816 				    filename, linenum);
1817 			if (!*activep || uvalue != 0)
1818 				continue;
1819 			array_append(filename, linenum, "SetEnv",
1820 			    &options->setenv, &options->num_setenv, arg);
1821 		}
1822 		break;
1823 
1824 	case sPermitTunnel:
1825 		intptr = &options->permit_tun;
1826 		arg = strdelim(&cp);
1827 		if (!arg || *arg == '\0')
1828 			fatal("%s line %d: Missing yes/point-to-point/"
1829 			    "ethernet/no argument.", filename, linenum);
1830 		value = -1;
1831 		for (i = 0; tunmode_desc[i].val != -1; i++)
1832 			if (strcmp(tunmode_desc[i].text, arg) == 0) {
1833 				value = tunmode_desc[i].val;
1834 				break;
1835 			}
1836 		if (value == -1)
1837 			fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1838 			    "no argument: %s", filename, linenum, arg);
1839 		if (*activep && *intptr == -1)
1840 			*intptr = value;
1841 		break;
1842 
1843 	case sMatch:
1844 		if (cmdline)
1845 			fatal("Match directive not supported as a command-line "
1846 			   "option");
1847 		value = match_cfg_line(&cp, linenum, connectinfo);
1848 		if (value < 0)
1849 			fatal("%s line %d: Bad Match condition", filename,
1850 			    linenum);
1851 		*activep = value;
1852 		break;
1853 
1854 	case sPermitListen:
1855 	case sPermitOpen:
1856 		if (opcode == sPermitListen) {
1857 			uintptr = &options->num_permitted_listens;
1858 			chararrayptr = &options->permitted_listens;
1859 		} else {
1860 			uintptr = &options->num_permitted_opens;
1861 			chararrayptr = &options->permitted_opens;
1862 		}
1863 		arg = strdelim(&cp);
1864 		if (!arg || *arg == '\0')
1865 			fatal("%s line %d: missing %s specification",
1866 			    filename, linenum, lookup_opcode_name(opcode));
1867 		uvalue = *uintptr;	/* modified later */
1868 		if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) {
1869 			if (*activep && uvalue == 0) {
1870 				*uintptr = 1;
1871 				*chararrayptr = xcalloc(1,
1872 				    sizeof(**chararrayptr));
1873 				(*chararrayptr)[0] = xstrdup(arg);
1874 			}
1875 			break;
1876 		}
1877 		for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1878 			if (opcode == sPermitListen &&
1879 			    strchr(arg, ':') == NULL) {
1880 				/*
1881 				 * Allow bare port number for PermitListen
1882 				 * to indicate a wildcard listen host.
1883 				 */
1884 				xasprintf(&arg2, "*:%s", arg);
1885 			} else {
1886 				arg2 = xstrdup(arg);
1887 				ch = '\0';
1888 				p = hpdelim2(&arg, &ch);
1889 				if (p == NULL || ch == '/') {
1890 					fatal("%s line %d: missing host in %s",
1891 					    filename, linenum,
1892 					    lookup_opcode_name(opcode));
1893 				}
1894 				p = cleanhostname(p);
1895 			}
1896 			if (arg == NULL ||
1897 			    ((port = permitopen_port(arg)) < 0)) {
1898 				fatal("%s line %d: bad port number in %s",
1899 				    filename, linenum,
1900 				    lookup_opcode_name(opcode));
1901 			}
1902 			if (*activep && uvalue == 0) {
1903 				array_append(filename, linenum,
1904 				    lookup_opcode_name(opcode),
1905 				    chararrayptr, uintptr, arg2);
1906 			}
1907 			free(arg2);
1908 		}
1909 		break;
1910 
1911 	case sForceCommand:
1912 		if (cp == NULL || *cp == '\0')
1913 			fatal("%.200s line %d: Missing argument.", filename,
1914 			    linenum);
1915 		len = strspn(cp, WHITESPACE);
1916 		if (*activep && options->adm_forced_command == NULL)
1917 			options->adm_forced_command = xstrdup(cp + len);
1918 		return 0;
1919 
1920 	case sChrootDirectory:
1921 		charptr = &options->chroot_directory;
1922 
1923 		arg = strdelim(&cp);
1924 		if (!arg || *arg == '\0')
1925 			fatal("%s line %d: missing file name.",
1926 			    filename, linenum);
1927 		if (*activep && *charptr == NULL)
1928 			*charptr = xstrdup(arg);
1929 		break;
1930 
1931 	case sTrustedUserCAKeys:
1932 		charptr = &options->trusted_user_ca_keys;
1933 		goto parse_filename;
1934 
1935 	case sRevokedKeys:
1936 		charptr = &options->revoked_keys_file;
1937 		goto parse_filename;
1938 
1939 	case sIPQoS:
1940 		arg = strdelim(&cp);
1941 		if ((value = parse_ipqos(arg)) == -1)
1942 			fatal("%s line %d: Bad IPQoS value: %s",
1943 			    filename, linenum, arg);
1944 		arg = strdelim(&cp);
1945 		if (arg == NULL)
1946 			value2 = value;
1947 		else if ((value2 = parse_ipqos(arg)) == -1)
1948 			fatal("%s line %d: Bad IPQoS value: %s",
1949 			    filename, linenum, arg);
1950 		if (*activep) {
1951 			options->ip_qos_interactive = value;
1952 			options->ip_qos_bulk = value2;
1953 		}
1954 		break;
1955 
1956 	case sVersionAddendum:
1957 		if (cp == NULL || *cp == '\0')
1958 			fatal("%.200s line %d: Missing argument.", filename,
1959 			    linenum);
1960 		len = strspn(cp, WHITESPACE);
1961 		if (*activep && options->version_addendum == NULL) {
1962 			if (strcasecmp(cp + len, "none") == 0)
1963 				options->version_addendum = xstrdup("");
1964 			else if (strchr(cp + len, '\r') != NULL)
1965 				fatal("%.200s line %d: Invalid argument",
1966 				    filename, linenum);
1967 			else
1968 				options->version_addendum = xstrdup(cp + len);
1969 		}
1970 		return 0;
1971 
1972 	case sAuthorizedKeysCommand:
1973 		if (cp == NULL)
1974 			fatal("%.200s line %d: Missing argument.", filename,
1975 			    linenum);
1976 		len = strspn(cp, WHITESPACE);
1977 		if (*activep && options->authorized_keys_command == NULL) {
1978 			if (cp[len] != '/' && strcasecmp(cp + len, "none") != 0)
1979 				fatal("%.200s line %d: AuthorizedKeysCommand "
1980 				    "must be an absolute path",
1981 				    filename, linenum);
1982 			options->authorized_keys_command = xstrdup(cp + len);
1983 		}
1984 		return 0;
1985 
1986 	case sAuthorizedKeysCommandUser:
1987 		charptr = &options->authorized_keys_command_user;
1988 
1989 		arg = strdelim(&cp);
1990 		if (!arg || *arg == '\0')
1991 			fatal("%s line %d: missing AuthorizedKeysCommandUser "
1992 			    "argument.", filename, linenum);
1993 		if (*activep && *charptr == NULL)
1994 			*charptr = xstrdup(arg);
1995 		break;
1996 
1997 	case sAuthorizedPrincipalsCommand:
1998 		if (cp == NULL)
1999 			fatal("%.200s line %d: Missing argument.", filename,
2000 			    linenum);
2001 		len = strspn(cp, WHITESPACE);
2002 		if (*activep &&
2003 		    options->authorized_principals_command == NULL) {
2004 			if (cp[len] != '/' && strcasecmp(cp + len, "none") != 0)
2005 				fatal("%.200s line %d: "
2006 				    "AuthorizedPrincipalsCommand must be "
2007 				    "an absolute path", filename, linenum);
2008 			options->authorized_principals_command =
2009 			    xstrdup(cp + len);
2010 		}
2011 		return 0;
2012 
2013 	case sAuthorizedPrincipalsCommandUser:
2014 		charptr = &options->authorized_principals_command_user;
2015 
2016 		arg = strdelim(&cp);
2017 		if (!arg || *arg == '\0')
2018 			fatal("%s line %d: missing "
2019 			    "AuthorizedPrincipalsCommandUser argument.",
2020 			    filename, linenum);
2021 		if (*activep && *charptr == NULL)
2022 			*charptr = xstrdup(arg);
2023 		break;
2024 
2025 	case sAuthenticationMethods:
2026 		if (options->num_auth_methods == 0) {
2027 			value = 0; /* seen "any" pseudo-method */
2028 			value2 = 0; /* successfully parsed any method */
2029 			while ((arg = strdelim(&cp)) && *arg != '\0') {
2030 				if (strcmp(arg, "any") == 0) {
2031 					if (options->num_auth_methods > 0) {
2032 						fatal("%s line %d: \"any\" "
2033 						    "must appear alone in "
2034 						    "AuthenticationMethods",
2035 						    filename, linenum);
2036 					}
2037 					value = 1;
2038 				} else if (value) {
2039 					fatal("%s line %d: \"any\" must appear "
2040 					    "alone in AuthenticationMethods",
2041 					    filename, linenum);
2042 				} else if (auth2_methods_valid(arg, 0) != 0) {
2043 					fatal("%s line %d: invalid "
2044 					    "authentication method list.",
2045 					    filename, linenum);
2046 				}
2047 				value2 = 1;
2048 				if (!*activep)
2049 					continue;
2050 				array_append(filename, linenum,
2051 				    "AuthenticationMethods",
2052 				    &options->auth_methods,
2053 				    &options->num_auth_methods, arg);
2054 			}
2055 			if (value2 == 0) {
2056 				fatal("%s line %d: no AuthenticationMethods "
2057 				    "specified", filename, linenum);
2058 			}
2059 		}
2060 		return 0;
2061 
2062 	case sStreamLocalBindMask:
2063 		arg = strdelim(&cp);
2064 		if (!arg || *arg == '\0')
2065 			fatal("%s line %d: missing StreamLocalBindMask "
2066 			    "argument.", filename, linenum);
2067 		/* Parse mode in octal format */
2068 		value = strtol(arg, &p, 8);
2069 		if (arg == p || value < 0 || value > 0777)
2070 			fatal("%s line %d: Bad mask.", filename, linenum);
2071 		if (*activep)
2072 			options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
2073 		break;
2074 
2075 	case sStreamLocalBindUnlink:
2076 		intptr = &options->fwd_opts.streamlocal_bind_unlink;
2077 		goto parse_flag;
2078 
2079 	case sFingerprintHash:
2080 		arg = strdelim(&cp);
2081 		if (!arg || *arg == '\0')
2082 			fatal("%.200s line %d: Missing argument.",
2083 			    filename, linenum);
2084 		if ((value = ssh_digest_alg_by_name(arg)) == -1)
2085 			fatal("%.200s line %d: Invalid hash algorithm \"%s\".",
2086 			    filename, linenum, arg);
2087 		if (*activep)
2088 			options->fingerprint_hash = value;
2089 		break;
2090 
2091 	case sExposeAuthInfo:
2092 		intptr = &options->expose_userauth_info;
2093 		goto parse_flag;
2094 
2095 	case sRDomain:
2096 		charptr = &options->routing_domain;
2097 		arg = strdelim(&cp);
2098 		if (!arg || *arg == '\0')
2099 			fatal("%.200s line %d: Missing argument.",
2100 			    filename, linenum);
2101 		if (strcasecmp(arg, "none") != 0 && strcmp(arg, "%D") != 0 &&
2102 		    !valid_rdomain(arg))
2103 			fatal("%s line %d: bad routing domain",
2104 			    filename, linenum);
2105 		if (*activep && *charptr == NULL)
2106 			*charptr = xstrdup(arg);
2107 		break;
2108 
2109 	case sDeprecated:
2110 	case sIgnore:
2111 	case sUnsupported:
2112 		do_log2(opcode == sIgnore ?
2113 		    SYSLOG_LEVEL_DEBUG2 : SYSLOG_LEVEL_INFO,
2114 		    "%s line %d: %s option %s", filename, linenum,
2115 		    opcode == sUnsupported ? "Unsupported" : "Deprecated", arg);
2116 		while (arg)
2117 		    arg = strdelim(&cp);
2118 		break;
2119 
2120 	default:
2121 		fatal("%s line %d: Missing handler for opcode %s (%d)",
2122 		    filename, linenum, arg, opcode);
2123 	}
2124 	if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
2125 		fatal("%s line %d: garbage at end of line; \"%.200s\".",
2126 		    filename, linenum, arg);
2127 	return 0;
2128 }
2129 
2130 /* Reads the server configuration file. */
2131 
2132 void
2133 load_server_config(const char *filename, struct sshbuf *conf)
2134 {
2135 	char *line = NULL, *cp;
2136 	size_t linesize = 0;
2137 	FILE *f;
2138 	int r, lineno = 0;
2139 
2140 	debug2("%s: filename %s", __func__, filename);
2141 	if ((f = fopen(filename, "r")) == NULL) {
2142 		perror(filename);
2143 		exit(1);
2144 	}
2145 	sshbuf_reset(conf);
2146 	while (getline(&line, &linesize, f) != -1) {
2147 		lineno++;
2148 		/*
2149 		 * Trim out comments and strip whitespace
2150 		 * NB - preserve newlines, they are needed to reproduce
2151 		 * line numbers later for error messages
2152 		 */
2153 		if ((cp = strchr(line, '#')) != NULL)
2154 			memcpy(cp, "\n", 2);
2155 		cp = line + strspn(line, " \t\r");
2156 		if ((r = sshbuf_put(conf, cp, strlen(cp))) != 0)
2157 			fatal("%s: buffer error: %s", __func__, ssh_err(r));
2158 	}
2159 	free(line);
2160 	if ((r = sshbuf_put_u8(conf, 0)) != 0)
2161 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
2162 	fclose(f);
2163 	debug2("%s: done config len = %zu", __func__, sshbuf_len(conf));
2164 }
2165 
2166 void
2167 parse_server_match_config(ServerOptions *options,
2168    struct connection_info *connectinfo)
2169 {
2170 	ServerOptions mo;
2171 
2172 	initialize_server_options(&mo);
2173 	parse_server_config(&mo, "reprocess config", cfg, connectinfo);
2174 	copy_set_server_options(options, &mo, 0);
2175 }
2176 
2177 int parse_server_match_testspec(struct connection_info *ci, char *spec)
2178 {
2179 	char *p;
2180 
2181 	while ((p = strsep(&spec, ",")) && *p != '\0') {
2182 		if (strncmp(p, "addr=", 5) == 0) {
2183 			ci->address = xstrdup(p + 5);
2184 		} else if (strncmp(p, "host=", 5) == 0) {
2185 			ci->host = xstrdup(p + 5);
2186 		} else if (strncmp(p, "user=", 5) == 0) {
2187 			ci->user = xstrdup(p + 5);
2188 		} else if (strncmp(p, "laddr=", 6) == 0) {
2189 			ci->laddress = xstrdup(p + 6);
2190 		} else if (strncmp(p, "rdomain=", 8) == 0) {
2191 			ci->rdomain = xstrdup(p + 8);
2192 		} else if (strncmp(p, "lport=", 6) == 0) {
2193 			ci->lport = a2port(p + 6);
2194 			if (ci->lport == -1) {
2195 				fprintf(stderr, "Invalid port '%s' in test mode"
2196 				   " specification %s\n", p+6, p);
2197 				return -1;
2198 			}
2199 		} else {
2200 			fprintf(stderr, "Invalid test mode specification %s\n",
2201 			   p);
2202 			return -1;
2203 		}
2204 	}
2205 	return 0;
2206 }
2207 
2208 /*
2209  * Copy any supported values that are set.
2210  *
2211  * If the preauth flag is set, we do not bother copying the string or
2212  * array values that are not used pre-authentication, because any that we
2213  * do use must be explicitly sent in mm_getpwnamallow().
2214  */
2215 void
2216 copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
2217 {
2218 #define M_CP_INTOPT(n) do {\
2219 	if (src->n != -1) \
2220 		dst->n = src->n; \
2221 } while (0)
2222 
2223 	M_CP_INTOPT(password_authentication);
2224 	M_CP_INTOPT(gss_authentication);
2225 	M_CP_INTOPT(pubkey_authentication);
2226 	M_CP_INTOPT(kerberos_authentication);
2227 	M_CP_INTOPT(hostbased_authentication);
2228 	M_CP_INTOPT(hostbased_uses_name_from_packet_only);
2229 	M_CP_INTOPT(kbd_interactive_authentication);
2230 	M_CP_INTOPT(permit_root_login);
2231 	M_CP_INTOPT(permit_empty_passwd);
2232 
2233 	M_CP_INTOPT(allow_tcp_forwarding);
2234 	M_CP_INTOPT(allow_streamlocal_forwarding);
2235 	M_CP_INTOPT(allow_agent_forwarding);
2236 	M_CP_INTOPT(disable_forwarding);
2237 	M_CP_INTOPT(expose_userauth_info);
2238 	M_CP_INTOPT(permit_tun);
2239 	M_CP_INTOPT(fwd_opts.gateway_ports);
2240 	M_CP_INTOPT(fwd_opts.streamlocal_bind_unlink);
2241 	M_CP_INTOPT(x11_display_offset);
2242 	M_CP_INTOPT(x11_forwarding);
2243 	M_CP_INTOPT(x11_use_localhost);
2244 	M_CP_INTOPT(permit_tty);
2245 	M_CP_INTOPT(permit_user_rc);
2246 	M_CP_INTOPT(max_sessions);
2247 	M_CP_INTOPT(max_authtries);
2248 	M_CP_INTOPT(client_alive_count_max);
2249 	M_CP_INTOPT(client_alive_interval);
2250 	M_CP_INTOPT(ip_qos_interactive);
2251 	M_CP_INTOPT(ip_qos_bulk);
2252 	M_CP_INTOPT(rekey_limit);
2253 	M_CP_INTOPT(rekey_interval);
2254 	M_CP_INTOPT(log_level);
2255 
2256 	/*
2257 	 * The bind_mask is a mode_t that may be unsigned, so we can't use
2258 	 * M_CP_INTOPT - it does a signed comparison that causes compiler
2259 	 * warnings.
2260 	 */
2261 	if (src->fwd_opts.streamlocal_bind_mask != (mode_t)-1) {
2262 		dst->fwd_opts.streamlocal_bind_mask =
2263 		    src->fwd_opts.streamlocal_bind_mask;
2264 	}
2265 
2266 	/* M_CP_STROPT and M_CP_STRARRAYOPT should not appear before here */
2267 #define M_CP_STROPT(n) do {\
2268 	if (src->n != NULL && dst->n != src->n) { \
2269 		free(dst->n); \
2270 		dst->n = src->n; \
2271 	} \
2272 } while(0)
2273 #define M_CP_STRARRAYOPT(s, num_s) do {\
2274 	u_int i; \
2275 	if (src->num_s != 0) { \
2276 		for (i = 0; i < dst->num_s; i++) \
2277 			free(dst->s[i]); \
2278 		free(dst->s); \
2279 		dst->s = xcalloc(src->num_s, sizeof(*dst->s)); \
2280 		for (i = 0; i < src->num_s; i++) \
2281 			dst->s[i] = xstrdup(src->s[i]); \
2282 		dst->num_s = src->num_s; \
2283 	} \
2284 } while(0)
2285 
2286 	/* See comment in servconf.h */
2287 	COPY_MATCH_STRING_OPTS();
2288 
2289 	/* Arguments that accept '+...' need to be expanded */
2290 	assemble_algorithms(dst);
2291 
2292 	/*
2293 	 * The only things that should be below this point are string options
2294 	 * which are only used after authentication.
2295 	 */
2296 	if (preauth)
2297 		return;
2298 
2299 	/* These options may be "none" to clear a global setting */
2300 	M_CP_STROPT(adm_forced_command);
2301 	if (option_clear_or_none(dst->adm_forced_command)) {
2302 		free(dst->adm_forced_command);
2303 		dst->adm_forced_command = NULL;
2304 	}
2305 	M_CP_STROPT(chroot_directory);
2306 	if (option_clear_or_none(dst->chroot_directory)) {
2307 		free(dst->chroot_directory);
2308 		dst->chroot_directory = NULL;
2309 	}
2310 }
2311 
2312 #undef M_CP_INTOPT
2313 #undef M_CP_STROPT
2314 #undef M_CP_STRARRAYOPT
2315 
2316 void
2317 parse_server_config(ServerOptions *options, const char *filename,
2318     struct sshbuf *conf, struct connection_info *connectinfo)
2319 {
2320 	int active, linenum, bad_options = 0;
2321 	char *cp, *obuf, *cbuf;
2322 
2323 	debug2("%s: config %s len %zu", __func__, filename, sshbuf_len(conf));
2324 
2325 	if ((obuf = cbuf = sshbuf_dup_string(conf)) == NULL)
2326 		fatal("%s: sshbuf_dup_string failed", __func__);
2327 	active = connectinfo ? 0 : 1;
2328 	linenum = 1;
2329 	while ((cp = strsep(&cbuf, "\n")) != NULL) {
2330 		if (process_server_config_line(options, cp, filename,
2331 		    linenum++, &active, connectinfo) != 0)
2332 			bad_options++;
2333 	}
2334 	free(obuf);
2335 	if (bad_options > 0)
2336 		fatal("%s: terminating, %d bad configuration options",
2337 		    filename, bad_options);
2338 	process_queued_listen_addrs(options);
2339 }
2340 
2341 static const char *
2342 fmt_multistate_int(int val, const struct multistate *m)
2343 {
2344 	u_int i;
2345 
2346 	for (i = 0; m[i].key != NULL; i++) {
2347 		if (m[i].value == val)
2348 			return m[i].key;
2349 	}
2350 	return "UNKNOWN";
2351 }
2352 
2353 static const char *
2354 fmt_intarg(ServerOpCodes code, int val)
2355 {
2356 	if (val == -1)
2357 		return "unset";
2358 	switch (code) {
2359 	case sAddressFamily:
2360 		return fmt_multistate_int(val, multistate_addressfamily);
2361 	case sPermitRootLogin:
2362 		return fmt_multistate_int(val, multistate_permitrootlogin);
2363 	case sGatewayPorts:
2364 		return fmt_multistate_int(val, multistate_gatewayports);
2365 	case sCompression:
2366 		return fmt_multistate_int(val, multistate_compression);
2367 	case sAllowTcpForwarding:
2368 		return fmt_multistate_int(val, multistate_tcpfwd);
2369 	case sAllowStreamLocalForwarding:
2370 		return fmt_multistate_int(val, multistate_tcpfwd);
2371 	case sFingerprintHash:
2372 		return ssh_digest_alg_name(val);
2373 	default:
2374 		switch (val) {
2375 		case 0:
2376 			return "no";
2377 		case 1:
2378 			return "yes";
2379 		default:
2380 			return "UNKNOWN";
2381 		}
2382 	}
2383 }
2384 
2385 static void
2386 dump_cfg_int(ServerOpCodes code, int val)
2387 {
2388 	printf("%s %d\n", lookup_opcode_name(code), val);
2389 }
2390 
2391 static void
2392 dump_cfg_oct(ServerOpCodes code, int val)
2393 {
2394 	printf("%s 0%o\n", lookup_opcode_name(code), val);
2395 }
2396 
2397 static void
2398 dump_cfg_fmtint(ServerOpCodes code, int val)
2399 {
2400 	printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
2401 }
2402 
2403 static void
2404 dump_cfg_string(ServerOpCodes code, const char *val)
2405 {
2406 	printf("%s %s\n", lookup_opcode_name(code),
2407 	    val == NULL ? "none" : val);
2408 }
2409 
2410 static void
2411 dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals)
2412 {
2413 	u_int i;
2414 
2415 	for (i = 0; i < count; i++)
2416 		printf("%s %s\n", lookup_opcode_name(code), vals[i]);
2417 }
2418 
2419 static void
2420 dump_cfg_strarray_oneline(ServerOpCodes code, u_int count, char **vals)
2421 {
2422 	u_int i;
2423 
2424 	if (count <= 0 && code != sAuthenticationMethods)
2425 		return;
2426 	printf("%s", lookup_opcode_name(code));
2427 	for (i = 0; i < count; i++)
2428 		printf(" %s",  vals[i]);
2429 	if (code == sAuthenticationMethods && count == 0)
2430 		printf(" any");
2431 	printf("\n");
2432 }
2433 
2434 static char *
2435 format_listen_addrs(struct listenaddr *la)
2436 {
2437 	int r;
2438 	struct addrinfo *ai;
2439 	char addr[NI_MAXHOST], port[NI_MAXSERV];
2440 	char *laddr1 = xstrdup(""), *laddr2 = NULL;
2441 
2442 	/*
2443 	 * ListenAddress must be after Port.  add_one_listen_addr pushes
2444 	 * addresses onto a stack, so to maintain ordering we need to
2445 	 * print these in reverse order.
2446 	 */
2447 	for (ai = la->addrs; ai; ai = ai->ai_next) {
2448 		if ((r = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
2449 		    sizeof(addr), port, sizeof(port),
2450 		    NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
2451 			error("getnameinfo: %.100s", ssh_gai_strerror(r));
2452 			continue;
2453 		}
2454 		laddr2 = laddr1;
2455 		if (ai->ai_family == AF_INET6) {
2456 			xasprintf(&laddr1, "listenaddress [%s]:%s%s%s\n%s",
2457 			    addr, port,
2458 			    la->rdomain == NULL ? "" : " rdomain ",
2459 			    la->rdomain == NULL ? "" : la->rdomain,
2460 			    laddr2);
2461 		} else {
2462 			xasprintf(&laddr1, "listenaddress %s:%s%s%s\n%s",
2463 			    addr, port,
2464 			    la->rdomain == NULL ? "" : " rdomain ",
2465 			    la->rdomain == NULL ? "" : la->rdomain,
2466 			    laddr2);
2467 		}
2468 		free(laddr2);
2469 	}
2470 	return laddr1;
2471 }
2472 
2473 void
2474 dump_config(ServerOptions *o)
2475 {
2476 	char *s;
2477 	u_int i;
2478 
2479 	/* these are usually at the top of the config */
2480 	for (i = 0; i < o->num_ports; i++)
2481 		printf("port %d\n", o->ports[i]);
2482 	dump_cfg_fmtint(sAddressFamily, o->address_family);
2483 
2484 	for (i = 0; i < o->num_listen_addrs; i++) {
2485 		s = format_listen_addrs(&o->listen_addrs[i]);
2486 		printf("%s", s);
2487 		free(s);
2488 	}
2489 
2490 	/* integer arguments */
2491 	dump_cfg_int(sLoginGraceTime, o->login_grace_time);
2492 	dump_cfg_int(sX11DisplayOffset, o->x11_display_offset);
2493 	dump_cfg_int(sMaxAuthTries, o->max_authtries);
2494 	dump_cfg_int(sMaxSessions, o->max_sessions);
2495 	dump_cfg_int(sClientAliveInterval, o->client_alive_interval);
2496 	dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max);
2497 	dump_cfg_oct(sStreamLocalBindMask, o->fwd_opts.streamlocal_bind_mask);
2498 
2499 	/* formatted integer arguments */
2500 	dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login);
2501 	dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts);
2502 	dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts);
2503 	dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication);
2504 	dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly,
2505 	    o->hostbased_uses_name_from_packet_only);
2506 	dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication);
2507 #ifdef KRB5
2508 	dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication);
2509 	dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd);
2510 	dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup);
2511 	dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
2512 #endif
2513 #ifdef GSSAPI
2514 	dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
2515 	dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
2516 #endif
2517 	dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
2518 	dump_cfg_fmtint(sKbdInteractiveAuthentication,
2519 	    o->kbd_interactive_authentication);
2520 	dump_cfg_fmtint(sChallengeResponseAuthentication,
2521 	    o->challenge_response_authentication);
2522 	dump_cfg_fmtint(sPrintMotd, o->print_motd);
2523 	dump_cfg_fmtint(sPrintLastLog, o->print_lastlog);
2524 	dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding);
2525 	dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost);
2526 	dump_cfg_fmtint(sPermitTTY, o->permit_tty);
2527 	dump_cfg_fmtint(sPermitUserRC, o->permit_user_rc);
2528 	dump_cfg_fmtint(sStrictModes, o->strict_modes);
2529 	dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive);
2530 	dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd);
2531 	dump_cfg_fmtint(sCompression, o->compression);
2532 	dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports);
2533 	dump_cfg_fmtint(sUseDNS, o->use_dns);
2534 	dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
2535 	dump_cfg_fmtint(sAllowAgentForwarding, o->allow_agent_forwarding);
2536 	dump_cfg_fmtint(sDisableForwarding, o->disable_forwarding);
2537 	dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding);
2538 	dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2539 	dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash);
2540 	dump_cfg_fmtint(sExposeAuthInfo, o->expose_userauth_info);
2541 
2542 	/* string arguments */
2543 	dump_cfg_string(sPidFile, o->pid_file);
2544 	dump_cfg_string(sXAuthLocation, o->xauth_location);
2545 	dump_cfg_string(sCiphers, o->ciphers ? o->ciphers : KEX_SERVER_ENCRYPT);
2546 	dump_cfg_string(sMacs, o->macs ? o->macs : KEX_SERVER_MAC);
2547 	dump_cfg_string(sBanner, o->banner);
2548 	dump_cfg_string(sForceCommand, o->adm_forced_command);
2549 	dump_cfg_string(sChrootDirectory, o->chroot_directory);
2550 	dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);
2551 	dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
2552 	dump_cfg_string(sAuthorizedPrincipalsFile,
2553 	    o->authorized_principals_file);
2554 	dump_cfg_string(sVersionAddendum, *o->version_addendum == '\0'
2555 	    ? "none" : o->version_addendum);
2556 	dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command);
2557 	dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user);
2558 	dump_cfg_string(sAuthorizedPrincipalsCommand, o->authorized_principals_command);
2559 	dump_cfg_string(sAuthorizedPrincipalsCommandUser, o->authorized_principals_command_user);
2560 	dump_cfg_string(sHostKeyAgent, o->host_key_agent);
2561 	dump_cfg_string(sKexAlgorithms,
2562 	    o->kex_algorithms ? o->kex_algorithms : KEX_SERVER_KEX);
2563 	dump_cfg_string(sCASignatureAlgorithms, o->ca_sign_algorithms ?
2564 	    o->ca_sign_algorithms : SSH_ALLOWED_CA_SIGALGS);
2565 	dump_cfg_string(sHostbasedAcceptedKeyTypes, o->hostbased_key_types ?
2566 	    o->hostbased_key_types : KEX_DEFAULT_PK_ALG);
2567 	dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms ?
2568 	    o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG);
2569 	dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ?
2570 	    o->pubkey_key_types : KEX_DEFAULT_PK_ALG);
2571 	dump_cfg_string(sRDomain, o->routing_domain);
2572 
2573 	/* string arguments requiring a lookup */
2574 	dump_cfg_string(sLogLevel, log_level_name(o->log_level));
2575 	dump_cfg_string(sLogFacility, log_facility_name(o->log_facility));
2576 
2577 	/* string array arguments */
2578 	dump_cfg_strarray_oneline(sAuthorizedKeysFile, o->num_authkeys_files,
2579 	    o->authorized_keys_files);
2580 	dump_cfg_strarray(sHostKeyFile, o->num_host_key_files,
2581 	     o->host_key_files);
2582 	dump_cfg_strarray(sHostCertificate, o->num_host_cert_files,
2583 	     o->host_cert_files);
2584 	dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users);
2585 	dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users);
2586 	dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups);
2587 	dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups);
2588 	dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env);
2589 	dump_cfg_strarray(sSetEnv, o->num_setenv, o->setenv);
2590 	dump_cfg_strarray_oneline(sAuthenticationMethods,
2591 	    o->num_auth_methods, o->auth_methods);
2592 
2593 	/* other arguments */
2594 	for (i = 0; i < o->num_subsystems; i++)
2595 		printf("subsystem %s %s\n", o->subsystem_name[i],
2596 		    o->subsystem_args[i]);
2597 
2598 	printf("maxstartups %d:%d:%d\n", o->max_startups_begin,
2599 	    o->max_startups_rate, o->max_startups);
2600 
2601 	s = NULL;
2602 	for (i = 0; tunmode_desc[i].val != -1; i++) {
2603 		if (tunmode_desc[i].val == o->permit_tun) {
2604 			s = tunmode_desc[i].text;
2605 			break;
2606 		}
2607 	}
2608 	dump_cfg_string(sPermitTunnel, s);
2609 
2610 	printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
2611 	printf("%s\n", iptos2str(o->ip_qos_bulk));
2612 
2613 	printf("rekeylimit %llu %d\n", (unsigned long long)o->rekey_limit,
2614 	    o->rekey_interval);
2615 
2616 	printf("permitopen");
2617 	if (o->num_permitted_opens == 0)
2618 		printf(" any");
2619 	else {
2620 		for (i = 0; i < o->num_permitted_opens; i++)
2621 			printf(" %s", o->permitted_opens[i]);
2622 	}
2623 	printf("\n");
2624 	printf("permitlisten");
2625 	if (o->num_permitted_listens == 0)
2626 		printf(" any");
2627 	else {
2628 		for (i = 0; i < o->num_permitted_listens; i++)
2629 			printf(" %s", o->permitted_listens[i]);
2630 	}
2631 	printf("\n");
2632 
2633 	if (o->permit_user_env_whitelist == NULL) {
2634 		dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env);
2635 	} else {
2636 		printf("permituserenvironment %s\n",
2637 		    o->permit_user_env_whitelist);
2638 	}
2639 
2640 }
2641