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