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