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