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