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