Home | History | Annotate | Line # | Download | only in dist
      1 /*	$NetBSD: servconf.c,v 1.52 2026/04/08 18:58:41 christos Exp $	*/
      2 /* $OpenBSD: servconf.c,v 1.446 2026/04/02 07:38:14 djm Exp $ */
      3 
      4 /*
      5  * Copyright (c) 1995 Tatu Ylonen <ylo (at) cs.hut.fi>, Espoo, Finland
      6  *                    All rights reserved
      7  *
      8  * As far as I am concerned, the code I have written for this software
      9  * can be used freely for any purpose.  Any derived versions of this
     10  * software must be clearly marked as such, and if the derived work is
     11  * incompatible with the protocol description in the RFC file, it must be
     12  * called by a name other than "ssh" or "Secure Shell".
     13  */
     14 
     15 #include "includes.h"
     16 __RCSID("$NetBSD: servconf.c,v 1.52 2026/04/08 18:58:41 christos Exp $");
     17 #include <sys/types.h>
     18 #include <sys/socket.h>
     19 #include <sys/queue.h>
     20 #include <sys/param.h>
     21 #include <sys/sysctl.h>
     22 #include <sys/stat.h>
     23 
     24 #include <netinet/in.h>
     25 #include <netinet/ip.h>
     26 #include <net/route.h>
     27 
     28 #include <ctype.h>
     29 #include <glob.h>
     30 #include <netdb.h>
     31 #include <pwd.h>
     32 #include <stdio.h>
     33 #include <stdlib.h>
     34 #include <string.h>
     35 #include <signal.h>
     36 #include <unistd.h>
     37 #include <limits.h>
     38 #include <stdarg.h>
     39 #include <errno.h>
     40 #include <util.h>
     41 #include <time.h>
     42 
     43 #ifdef KRB4
     44 #include <krb.h>
     45 #ifdef AFS
     46 #include <kafs.h>
     47 #endif /* AFS */
     48 #endif /* KRB4 */
     49 
     50 #include "xmalloc.h"
     51 #include "ssh.h"
     52 #include "log.h"
     53 #include "sshbuf.h"
     54 #include "misc.h"
     55 #include "servconf.h"
     56 #include "pathnames.h"
     57 #include "cipher.h"
     58 #include "sshkey.h"
     59 #include "kex.h"
     60 #include "mac.h"
     61 #include "match.h"
     62 #include "channels.h"
     63 #include "groupaccess.h"
     64 #include "canohost.h"
     65 #include "packet.h"
     66 #include "ssherr.h"
     67 #include "hostfile.h"
     68 #include "auth.h"
     69 #include "fmt_scaled.h"
     70 
     71 #if !defined(SSHD_PAM_SERVICE)
     72 # define SSHD_PAM_SERVICE		"sshd"
     73 #endif
     74 #ifdef WITH_LDAP_PUBKEY
     75 #include "ldapauth.h"
     76 #endif
     77 #include "myproposal.h"
     78 #include "digest.h"
     79 #include "version.h"
     80 
     81 static void add_listen_addr(ServerOptions *, const char *,
     82     const char *, int);
     83 static void add_one_listen_addr(ServerOptions *, const char *,
     84     const char *, int);
     85 static void parse_server_config_depth(ServerOptions *options,
     86     const char *filename, struct sshbuf *conf, struct include_list *includes,
     87     struct connection_info *connectinfo, int flags, int *activep, int depth);
     88 
     89 extern struct sshbuf *cfg;
     90 
     91 /* Initializes the server options to their default values. */
     92 
     93 void
     94 initialize_server_options(ServerOptions *options)
     95 {
     96 	memset(options, 0, sizeof(*options));
     97 
     98 	/* Portable-specific options */
     99 	options->use_pam = -1;
    100 	options->pam_service_name = NULL;
    101 
    102 	/* Standard Options */
    103 	options->num_ports = 0;
    104 	options->ports_from_cmdline = 0;
    105 	options->queued_listen_addrs = NULL;
    106 	options->num_queued_listens = 0;
    107 	options->listen_addrs = NULL;
    108 	options->num_listen_addrs = 0;
    109 	options->address_family = -1;
    110 	options->routing_domain = NULL;
    111 	options->num_host_key_files = 0;
    112 	options->num_host_cert_files = 0;
    113 	options->host_key_agent = NULL;
    114 	options->pid_file = NULL;
    115 	options->login_grace_time = -1;
    116 	options->permit_root_login = PERMIT_NOT_SET;
    117 	options->ignore_rhosts = -1;
    118 	options->ignore_root_rhosts = -1;
    119 	options->ignore_user_known_hosts = -1;
    120 	options->print_motd = -1;
    121 	options->print_lastlog = -1;
    122 	options->x11_forwarding = -1;
    123 	options->x11_display_offset = -1;
    124 	options->x11_use_localhost = -1;
    125 	options->permit_tty = -1;
    126 	options->permit_user_rc = -1;
    127 	options->xauth_location = NULL;
    128 	options->strict_modes = -1;
    129 	options->tcp_keep_alive = -1;
    130 	options->log_facility = SYSLOG_FACILITY_NOT_SET;
    131 	options->log_level = SYSLOG_LEVEL_NOT_SET;
    132 	options->num_log_verbose = 0;
    133 	options->log_verbose = NULL;
    134 	options->hostbased_authentication = -1;
    135 	options->hostbased_uses_name_from_packet_only = -1;
    136 	options->hostbased_accepted_algos = NULL;
    137 	options->hostkeyalgorithms = NULL;
    138 	options->pubkey_authentication = -1;
    139 	options->pubkey_auth_options = -1;
    140 	options->pubkey_accepted_algos = NULL;
    141 	options->kerberos_authentication = -1;
    142 	options->kerberos_or_local_passwd = -1;
    143 	options->kerberos_ticket_cleanup = -1;
    144 #if defined(AFS) || defined(KRB5)
    145 	options->kerberos_tgt_passing = -1;
    146 #endif
    147 #ifdef AFS
    148 	options->afs_token_passing = -1;
    149 #endif
    150 	options->kerberos_get_afs_token = -1;
    151 	options->gss_authentication=-1;
    152 	options->gss_cleanup_creds = -1;
    153 	options->gss_deleg_creds = -1;
    154 	options->gss_strict_acceptor = -1;
    155 	options->password_authentication = -1;
    156 	options->kbd_interactive_authentication = -1;
    157 	options->permit_empty_passwd = -1;
    158 	options->permit_user_env = -1;
    159 	options->permit_user_env_allowlist = NULL;
    160 	options->compression = -1;
    161 	options->rekey_limit = -1;
    162 	options->rekey_interval = -1;
    163 	options->allow_tcp_forwarding = -1;
    164 	options->allow_streamlocal_forwarding = -1;
    165 	options->allow_agent_forwarding = -1;
    166 	options->num_allow_users = 0;
    167 	options->num_deny_users = 0;
    168 	options->num_allow_groups = 0;
    169 	options->num_deny_groups = 0;
    170 	options->ciphers = NULL;
    171 #ifdef WITH_LDAP_PUBKEY
    172 	/* XXX dirty */
    173 	options->lpk.ld = NULL;
    174 	options->lpk.on = -1;
    175 	options->lpk.servers = NULL;
    176 	options->lpk.u_basedn = NULL;
    177 	options->lpk.g_basedn = NULL;
    178 	options->lpk.binddn = NULL;
    179 	options->lpk.bindpw = NULL;
    180 	options->lpk.sgroup = NULL;
    181 	options->lpk.filter = NULL;
    182 	options->lpk.fgroup = NULL;
    183 	options->lpk.l_conf = NULL;
    184 	options->lpk.tls = -1;
    185 	options->lpk.b_timeout.tv_sec = -1;
    186 	options->lpk.s_timeout.tv_sec = -1;
    187 	options->lpk.flags = FLAG_EMPTY;
    188 	options->lpk.pub_key_attr = NULL;
    189 #endif
    190 	options->macs = NULL;
    191 	options->kex_algorithms = NULL;
    192 	options->ca_sign_algorithms = NULL;
    193 	options->fwd_opts.gateway_ports = -1;
    194 	options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
    195 	options->fwd_opts.streamlocal_bind_unlink = -1;
    196 	options->num_subsystems = 0;
    197 	options->max_startups_begin = -1;
    198 	options->max_startups_rate = -1;
    199 	options->max_startups = -1;
    200 	options->per_source_max_startups = -1;
    201 	options->per_source_masklen_ipv4 = -1;
    202 	options->per_source_masklen_ipv6 = -1;
    203 	options->per_source_penalty_exempt = NULL;
    204 	options->per_source_penalty.enabled = -1;
    205 	options->per_source_penalty.max_sources4 = -1;
    206 	options->per_source_penalty.max_sources6 = -1;
    207 	options->per_source_penalty.overflow_mode = -1;
    208 	options->per_source_penalty.overflow_mode6 = -1;
    209 	options->per_source_penalty.penalty_crash = -1.0;
    210 	options->per_source_penalty.penalty_authfail = -1.0;
    211 	options->per_source_penalty.penalty_invaliduser = -1.0;
    212 	options->per_source_penalty.penalty_noauth = -1.0;
    213 	options->per_source_penalty.penalty_grace = -1.0;
    214 	options->per_source_penalty.penalty_refuseconnection = -1.0;
    215 	options->per_source_penalty.penalty_max = -1.0;
    216 	options->per_source_penalty.penalty_min = -1.0;
    217 	options->max_authtries = -1;
    218 	options->max_sessions = -1;
    219 	options->banner = NULL;
    220 	options->use_dns = -1;
    221 	options->client_alive_interval = -1;
    222 	options->client_alive_count_max = -1;
    223 	options->num_authkeys_files = 0;
    224 	options->num_accept_env = 0;
    225 	options->num_setenv = 0;
    226 	options->permit_tun = -1;
    227 	options->permitted_opens = NULL;
    228 	options->permitted_listens = NULL;
    229 	options->adm_forced_command = NULL;
    230 	options->chroot_directory = NULL;
    231 	options->authorized_keys_command = NULL;
    232 	options->authorized_keys_command_user = NULL;
    233 	options->revoked_keys_files = NULL;
    234 	options->num_revoked_keys_files = 0;
    235 	options->sk_provider = NULL;
    236 	options->trusted_user_ca_keys = NULL;
    237 	options->authorized_principals_file = NULL;
    238 	options->authorized_principals_command = NULL;
    239 	options->authorized_principals_command_user = NULL;
    240 	options->ip_qos_interactive = -1;
    241 	options->ip_qos_bulk = -1;
    242 	options->version_addendum = NULL;
    243 	options->fingerprint_hash = -1;
    244 	options->disable_forwarding = -1;
    245 	options->expose_userauth_info = -1;
    246 	options->required_rsa_size = -1;
    247 	options->channel_timeouts = NULL;
    248 	options->num_channel_timeouts = 0;
    249 	options->unused_connection_timeout = -1;
    250 	options->sshd_session_path = NULL;
    251 	options->sshd_auth_path = NULL;
    252 	options->refuse_connection = -1;
    253 	options->none_enabled = -1;
    254 	options->tcp_rcv_buf_poll = -1;
    255 	options->hpn_disabled = -1;
    256 	options->hpn_buffer_size = -1;
    257 }
    258 
    259 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
    260 static int
    261 option_clear_or_none(const char *o)
    262 {
    263 	return o == NULL || strcasecmp(o, "none") == 0;
    264 }
    265 
    266 static void
    267 assemble_algorithms(ServerOptions *o)
    268 {
    269 	char *all_cipher, *all_mac, *all_kex, *all_key, *all_sig;
    270 	char *def_cipher, *def_mac, *def_kex, *def_key, *def_sig;
    271 	int r;
    272 
    273 	all_cipher = cipher_alg_list(',', 0);
    274 	all_mac = mac_alg_list(',');
    275 	all_kex = kex_alg_list(',');
    276 	all_key = sshkey_alg_list(0, 0, 1, ',');
    277 	all_sig = sshkey_alg_list(0, 1, 1, ',');
    278 	/* remove unsupported algos from default lists */
    279 	def_cipher = match_filter_allowlist(KEX_SERVER_ENCRYPT, all_cipher);
    280 	def_mac = match_filter_allowlist(KEX_SERVER_MAC, all_mac);
    281 	def_kex = match_filter_allowlist(KEX_SERVER_KEX, all_kex);
    282 	def_key = match_filter_allowlist(KEX_DEFAULT_PK_ALG, all_key);
    283 	def_sig = match_filter_allowlist(SSH_ALLOWED_CA_SIGALGS, all_sig);
    284 #define ASSEMBLE(what, defaults, all) \
    285 	do { \
    286 		if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \
    287 			fatal_fr(r, "%s", #what); \
    288 	} while (0)
    289 	ASSEMBLE(ciphers, def_cipher, all_cipher);
    290 	ASSEMBLE(macs, def_mac, all_mac);
    291 	ASSEMBLE(kex_algorithms, def_kex, all_kex);
    292 	ASSEMBLE(hostkeyalgorithms, def_key, all_key);
    293 	ASSEMBLE(hostbased_accepted_algos, def_key, all_key);
    294 	ASSEMBLE(pubkey_accepted_algos, def_key, all_key);
    295 	ASSEMBLE(ca_sign_algorithms, def_sig, all_sig);
    296 #undef ASSEMBLE
    297 	free(all_cipher);
    298 	free(all_mac);
    299 	free(all_kex);
    300 	free(all_key);
    301 	free(all_sig);
    302 	free(def_cipher);
    303 	free(def_mac);
    304 	free(def_kex);
    305 	free(def_key);
    306 	free(def_sig);
    307 }
    308 
    309 void
    310 servconf_add_hostkey(const char *file, const int line,
    311     ServerOptions *options, const char *path, int userprovided)
    312 {
    313 	char *apath = derelativise_path(path);
    314 
    315 	opt_array_append2(file, line, "HostKey",
    316 	    &options->host_key_files, &options->host_key_file_userprovided,
    317 	    &options->num_host_key_files, apath, userprovided);
    318 	free(apath);
    319 }
    320 
    321 void
    322 servconf_add_hostcert(const char *file, const int line,
    323     ServerOptions *options, const char *path)
    324 {
    325 	char *apath = derelativise_path(path);
    326 
    327 	opt_array_append(file, line, "HostCertificate",
    328 	    &options->host_cert_files, &options->num_host_cert_files, apath);
    329 	free(apath);
    330 }
    331 
    332 void
    333 fill_default_server_options(ServerOptions *options)
    334 {
    335 	/* needed for hpn socket tests */
    336 	int sock;
    337 	int socksize;
    338 	socklen_t socksizelen = sizeof(int);
    339 
    340 	/* Portable-specific options */
    341 	if (options->use_pam == -1)
    342 		options->use_pam = 0;
    343 	if (options->pam_service_name == NULL)
    344 		options->pam_service_name = xstrdup(SSHD_PAM_SERVICE);
    345 
    346 	/* Standard Options */
    347 	u_int i;
    348 
    349 	if (options->num_host_key_files == 0) {
    350 		/* fill default hostkeys for protocols */
    351 		servconf_add_hostkey("[default]", 0, options,
    352 		    _PATH_HOST_RSA_KEY_FILE, 0);
    353 		servconf_add_hostkey("[default]", 0, options,
    354 		    _PATH_HOST_ECDSA_KEY_FILE, 0);
    355 		servconf_add_hostkey("[default]", 0, options,
    356 		    _PATH_HOST_ED25519_KEY_FILE, 0);
    357 	}
    358 	/* No certificates by default */
    359 	if (options->num_ports == 0)
    360 		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
    361 	if (options->address_family == -1)
    362 		options->address_family = AF_UNSPEC;
    363 	if (options->listen_addrs == NULL)
    364 		add_listen_addr(options, NULL, NULL, 0);
    365 	if (options->pid_file == NULL)
    366 		options->pid_file = xstrdup(_PATH_SSH_DAEMON_PID_FILE);
    367 	if (options->moduli_file == NULL)
    368 		options->moduli_file = xstrdup(_PATH_DH_MODULI);
    369 	if (options->login_grace_time == -1)
    370 		options->login_grace_time = 120;
    371 	if (options->permit_root_login == PERMIT_NOT_SET)
    372 		options->permit_root_login = PERMIT_NO_PASSWD;
    373 	if (options->ignore_rhosts == -1)
    374 		options->ignore_rhosts = 1;
    375 	if (options->ignore_root_rhosts == -1)
    376 		options->ignore_root_rhosts = options->ignore_rhosts;
    377 	if (options->ignore_user_known_hosts == -1)
    378 		options->ignore_user_known_hosts = 0;
    379 	if (options->print_motd == -1)
    380 		options->print_motd = 1;
    381 	if (options->print_lastlog == -1)
    382 		options->print_lastlog = 1;
    383 	if (options->x11_forwarding == -1)
    384 		options->x11_forwarding = 0;
    385 	if (options->x11_display_offset == -1)
    386 		options->x11_display_offset = 10;
    387 	if (options->x11_use_localhost == -1)
    388 		options->x11_use_localhost = 1;
    389 	if (options->xauth_location == NULL)
    390 		options->xauth_location = xstrdup(_PATH_XAUTH);
    391 	if (options->permit_tty == -1)
    392 		options->permit_tty = 1;
    393 	if (options->permit_user_rc == -1)
    394 		options->permit_user_rc = 1;
    395 	if (options->strict_modes == -1)
    396 		options->strict_modes = 1;
    397 	if (options->tcp_keep_alive == -1)
    398 		options->tcp_keep_alive = 1;
    399 	if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
    400 		options->log_facility = SYSLOG_FACILITY_AUTH;
    401 	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
    402 		options->log_level = SYSLOG_LEVEL_INFO;
    403 	if (options->hostbased_authentication == -1)
    404 		options->hostbased_authentication = 0;
    405 	if (options->hostbased_uses_name_from_packet_only == -1)
    406 		options->hostbased_uses_name_from_packet_only = 0;
    407 	if (options->pubkey_authentication == -1)
    408 		options->pubkey_authentication = 1;
    409 	if (options->pubkey_auth_options == -1)
    410 		options->pubkey_auth_options = 0;
    411 	if (options->kerberos_authentication == -1)
    412 		options->kerberos_authentication = 0;
    413 	if (options->kerberos_or_local_passwd == -1)
    414 		options->kerberos_or_local_passwd = 1;
    415 	if (options->kerberos_ticket_cleanup == -1)
    416 		options->kerberos_ticket_cleanup = 1;
    417 #if defined(AFS) || defined(KRB5)
    418 	if (options->kerberos_tgt_passing == -1)
    419 		options->kerberos_tgt_passing = 0;
    420 #endif
    421 #ifdef AFS
    422 	if (options->afs_token_passing == -1)
    423 		options->afs_token_passing = 0;
    424 #endif
    425 	if (options->kerberos_get_afs_token == -1)
    426 		options->kerberos_get_afs_token = 0;
    427 	if (options->gss_authentication == -1)
    428 		options->gss_authentication = 0;
    429 	if (options->gss_cleanup_creds == -1)
    430 		options->gss_cleanup_creds = 1;
    431 	if (options->gss_deleg_creds == -1)
    432 		options->gss_deleg_creds = 1;
    433 	if (options->gss_strict_acceptor == -1)
    434 		options->gss_strict_acceptor = 1;
    435 	if (options->password_authentication == -1)
    436 		options->password_authentication = 1;
    437 	if (options->kbd_interactive_authentication == -1)
    438 		options->kbd_interactive_authentication = 1;
    439 	if (options->permit_empty_passwd == -1)
    440 		options->permit_empty_passwd = 0;
    441 	if (options->permit_user_env == -1) {
    442 		options->permit_user_env = 0;
    443 		options->permit_user_env_allowlist = NULL;
    444 	}
    445 	if (options->compression == -1)
    446 #ifdef WITH_ZLIB
    447 		options->compression = COMP_DELAYED;
    448 #else
    449 		options->compression = COMP_NONE;
    450 #endif
    451 
    452 	if (options->rekey_limit == -1)
    453 		options->rekey_limit = 0;
    454 	if (options->rekey_interval == -1)
    455 		options->rekey_interval = 0;
    456 	if (options->allow_tcp_forwarding == -1)
    457 		options->allow_tcp_forwarding = FORWARD_ALLOW;
    458 	if (options->allow_streamlocal_forwarding == -1)
    459 		options->allow_streamlocal_forwarding = FORWARD_ALLOW;
    460 	if (options->allow_agent_forwarding == -1)
    461 		options->allow_agent_forwarding = 1;
    462 	if (options->fwd_opts.gateway_ports == -1)
    463 		options->fwd_opts.gateway_ports = 0;
    464 	if (options->max_startups == -1)
    465 		options->max_startups = 100;
    466 	if (options->max_startups_rate == -1)
    467 		options->max_startups_rate = 30;		/* 30% */
    468 	if (options->max_startups_begin == -1)
    469 		options->max_startups_begin = 10;
    470 	if (options->per_source_max_startups == -1)
    471 		options->per_source_max_startups = INT_MAX;
    472 	if (options->per_source_masklen_ipv4 == -1)
    473 		options->per_source_masklen_ipv4 = 32;
    474 	if (options->per_source_masklen_ipv6 == -1)
    475 		options->per_source_masklen_ipv6 = 128;
    476 	if (options->per_source_penalty.enabled == -1)
    477 		options->per_source_penalty.enabled = 1;
    478 	if (options->per_source_penalty.max_sources4 == -1)
    479 		options->per_source_penalty.max_sources4 = 65536;
    480 	if (options->per_source_penalty.max_sources6 == -1)
    481 		options->per_source_penalty.max_sources6 = 65536;
    482 	if (options->per_source_penalty.overflow_mode == -1)
    483 		options->per_source_penalty.overflow_mode = PER_SOURCE_PENALTY_OVERFLOW_PERMISSIVE;
    484 	if (options->per_source_penalty.overflow_mode6 == -1)
    485 		options->per_source_penalty.overflow_mode6 = options->per_source_penalty.overflow_mode;
    486 	if (options->per_source_penalty.penalty_crash < 0.0)
    487 		options->per_source_penalty.penalty_crash = 90.0;
    488 	if (options->per_source_penalty.penalty_grace < 0.0)
    489 		options->per_source_penalty.penalty_grace = 10.0;
    490 	if (options->per_source_penalty.penalty_authfail < 0.0)
    491 		options->per_source_penalty.penalty_authfail = 5.0;
    492 	if (options->per_source_penalty.penalty_invaliduser < 0.0)
    493 		options->per_source_penalty.penalty_invaliduser = 5.0;
    494 	if (options->per_source_penalty.penalty_noauth < 0.0)
    495 		options->per_source_penalty.penalty_noauth = 1.0;
    496 	if (options->per_source_penalty.penalty_refuseconnection < 0.0)
    497 		options->per_source_penalty.penalty_refuseconnection = 10.0;
    498 	if (options->per_source_penalty.penalty_min < 0.0)
    499 		options->per_source_penalty.penalty_min = 15.0;
    500 	if (options->per_source_penalty.penalty_max < 0.0)
    501 		options->per_source_penalty.penalty_max = 600.0;
    502 	if (options->max_authtries == -1)
    503 		options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
    504 	if (options->max_sessions == -1)
    505 		options->max_sessions = DEFAULT_SESSIONS_MAX;
    506 	if (options->use_dns == -1)
    507 		options->use_dns = 0;
    508 	if (options->client_alive_interval == -1)
    509 		options->client_alive_interval = 0;
    510 	if (options->client_alive_count_max == -1)
    511 		options->client_alive_count_max = 3;
    512 	if (options->num_authkeys_files == 0) {
    513 		opt_array_append("[default]", 0, "AuthorizedKeysFiles",
    514 		    &options->authorized_keys_files,
    515 		    &options->num_authkeys_files,
    516 		    _PATH_SSH_USER_PERMITTED_KEYS);
    517 		opt_array_append("[default]", 0, "AuthorizedKeysFiles",
    518 		    &options->authorized_keys_files,
    519 		    &options->num_authkeys_files,
    520 		    _PATH_SSH_USER_PERMITTED_KEYS2);
    521 	}
    522 	if (options->permit_tun == -1)
    523 		options->permit_tun = SSH_TUNMODE_NO;
    524 	if (options->ip_qos_interactive == -1)
    525 		options->ip_qos_interactive = IPTOS_DSCP_EF;
    526 	if (options->ip_qos_bulk == -1)
    527 		options->ip_qos_bulk = IPTOS_DSCP_CS0;
    528 	if (options->version_addendum == NULL)
    529 		options->version_addendum = xstrdup("");
    530 
    531 	if (options->hpn_disabled == -1)
    532 		options->hpn_disabled = 0;
    533 
    534 	if (options->hpn_buffer_size == -1) {
    535 		/* option not explicitly set. Now we have to figure out */
    536 		/* what value to use */
    537 		if (options->hpn_disabled == 1) {
    538 			options->hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT;
    539 		} else {
    540 			/* get the current RCV size and set it to that */
    541 			/*create a socket but don't connect it */
    542 			/* we use that the get the rcv socket size */
    543 			sock = socket(AF_INET, SOCK_STREAM, 0);
    544 			getsockopt(sock, SOL_SOCKET, SO_RCVBUF,
    545 				   &socksize, &socksizelen);
    546 			close(sock);
    547 			options->hpn_buffer_size = socksize;
    548 			debug ("HPN Buffer Size: %d", options->hpn_buffer_size);
    549 
    550 		}
    551 	} else {
    552 		/* we have to do this incase the user sets both values in a contradictory */
    553 		/* manner. hpn_disabled overrrides hpn_buffer_size*/
    554 		if (options->hpn_disabled <= 0) {
    555 			if (options->hpn_buffer_size == 0)
    556 				options->hpn_buffer_size = 1;
    557 			/* limit the maximum buffer to 64MB */
    558 			if (options->hpn_buffer_size > 64*1024) {
    559 				options->hpn_buffer_size = 64*1024*1024;
    560 			} else {
    561 				options->hpn_buffer_size *= 1024;
    562 			}
    563 		} else
    564 			options->hpn_buffer_size = CHAN_TCP_WINDOW_DEFAULT;
    565 	}
    566 
    567 #ifdef WITH_LDAP_PUBKEY
    568 	if (options->lpk.on == -1)
    569 	    options->lpk.on = _DEFAULT_LPK_ON;
    570 	if (options->lpk.servers == NULL)
    571 	    options->lpk.servers = _DEFAULT_LPK_SERVERS;
    572 	if (options->lpk.u_basedn == NULL)
    573 	    options->lpk.u_basedn = _DEFAULT_LPK_UDN;
    574 	if (options->lpk.g_basedn == NULL)
    575 	    options->lpk.g_basedn = _DEFAULT_LPK_GDN;
    576 	if (options->lpk.binddn == NULL)
    577 	    options->lpk.binddn = _DEFAULT_LPK_BINDDN;
    578 	if (options->lpk.bindpw == NULL)
    579 	    options->lpk.bindpw = _DEFAULT_LPK_BINDPW;
    580 	if (options->lpk.sgroup == NULL)
    581 	    options->lpk.sgroup = _DEFAULT_LPK_SGROUP;
    582 	if (options->lpk.filter == NULL)
    583 	    options->lpk.filter = _DEFAULT_LPK_FILTER;
    584 	if (options->lpk.tls == -1)
    585 	    options->lpk.tls = _DEFAULT_LPK_TLS;
    586 	if (options->lpk.b_timeout.tv_sec == -1)
    587 	    options->lpk.b_timeout.tv_sec = _DEFAULT_LPK_BTIMEOUT;
    588 	if (options->lpk.s_timeout.tv_sec == -1)
    589 	    options->lpk.s_timeout.tv_sec = _DEFAULT_LPK_STIMEOUT;
    590 	if (options->lpk.l_conf == NULL)
    591 	    options->lpk.l_conf = _DEFAULT_LPK_LDP;
    592 	if (options->lpk.pub_key_attr == NULL)
    593 	    options->lpk.pub_key_attr = __UNCONST(_DEFAULT_LPK_PUB);
    594 #endif
    595 
    596 	if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
    597 		options->fwd_opts.streamlocal_bind_mask = 0177;
    598 	if (options->fwd_opts.streamlocal_bind_unlink == -1)
    599 		options->fwd_opts.streamlocal_bind_unlink = 0;
    600 	if (options->fingerprint_hash == -1)
    601 		options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
    602 	if (options->disable_forwarding == -1)
    603 		options->disable_forwarding = 0;
    604 	if (options->expose_userauth_info == -1)
    605 		options->expose_userauth_info = 0;
    606 	if (options->sk_provider == NULL)
    607 		options->sk_provider = xstrdup("internal");
    608 	if (options->required_rsa_size == -1)
    609 		options->required_rsa_size = SSH_RSA_MINIMUM_MODULUS_SIZE;
    610 	if (options->unused_connection_timeout == -1)
    611 		options->unused_connection_timeout = 0;
    612 	if (options->sshd_session_path == NULL)
    613 		options->sshd_session_path = xstrdup(_PATH_SSHD_SESSION);
    614 	if (options->sshd_auth_path == NULL)
    615 		options->sshd_auth_path = xstrdup(_PATH_SSHD_AUTH);
    616 	if (options->refuse_connection == -1)
    617 		options->refuse_connection = 0;
    618 
    619 	assemble_algorithms(options);
    620 
    621 #define CLEAR_ON_NONE(v) \
    622 	do { \
    623 		if (option_clear_or_none(v)) { \
    624 			free(v); \
    625 			v = NULL; \
    626 		} \
    627 	} while(0)
    628 #define CLEAR_ON_NONE_ARRAY(v, nv, none) \
    629 	do { \
    630 		if (options->nv == 1 && \
    631 		    strcasecmp(options->v[0], none) == 0) { \
    632 			free(options->v[0]); \
    633 			free(options->v); \
    634 			options->v = NULL; \
    635 			options->nv = 0; \
    636 		} \
    637 	} while (0)
    638 	CLEAR_ON_NONE(options->pid_file);
    639 	CLEAR_ON_NONE(options->xauth_location);
    640 	CLEAR_ON_NONE(options->banner);
    641 	CLEAR_ON_NONE(options->trusted_user_ca_keys);
    642 	CLEAR_ON_NONE(options->sk_provider);
    643 	CLEAR_ON_NONE(options->authorized_principals_file);
    644 	CLEAR_ON_NONE(options->adm_forced_command);
    645 	CLEAR_ON_NONE(options->chroot_directory);
    646 	CLEAR_ON_NONE(options->routing_domain);
    647 	CLEAR_ON_NONE(options->host_key_agent);
    648 	CLEAR_ON_NONE(options->per_source_penalty_exempt);
    649 
    650 	for (i = 0; i < options->num_host_key_files; i++)
    651 		CLEAR_ON_NONE(options->host_key_files[i]);
    652 	for (i = 0; i < options->num_host_cert_files; i++)
    653 		CLEAR_ON_NONE(options->host_cert_files[i]);
    654 
    655 	CLEAR_ON_NONE_ARRAY(channel_timeouts, num_channel_timeouts, "none");
    656 	CLEAR_ON_NONE_ARRAY(auth_methods, num_auth_methods, "any");
    657 	CLEAR_ON_NONE_ARRAY(revoked_keys_files, num_revoked_keys_files, "none");
    658 	CLEAR_ON_NONE_ARRAY(authorized_keys_files, num_authkeys_files, "none");
    659 #undef CLEAR_ON_NONE
    660 #undef CLEAR_ON_NONE_ARRAY
    661 }
    662 
    663 /* Keyword tokens. */
    664 typedef enum {
    665 	sBadOption,		/* == unknown option */
    666 	/* Portable-specific options */
    667 	sUsePAM, sPAMServiceName,
    668 	/* Standard Options */
    669 	sPort, sHostKeyFile, sLoginGraceTime,
    670 	sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose,
    671 	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
    672 	sKerberosGetAFSToken,
    673 	sKerberosTgtPassing,
    674 	sPasswordAuthentication,
    675 	sKbdInteractiveAuthentication, sListenAddress, sAddressFamily,
    676 	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
    677 	sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
    678 	sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive,
    679 	sPermitUserEnvironment, sAllowTcpForwarding, sCompression,
    680 	sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
    681 	sIgnoreUserKnownHosts, sCiphers, sMacs, sPidFile, sModuliFile,
    682 	sGatewayPorts, sPubkeyAuthentication, sPubkeyAcceptedAlgorithms,
    683 	sXAuthLocation, sSubsystem, sMaxStartups, sMaxAuthTries, sMaxSessions,
    684 	sBanner, sUseDNS, sHostbasedAuthentication,
    685 	sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedAlgorithms,
    686 	sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize,
    687 	sPerSourcePenalties, sPerSourcePenaltyExemptList,
    688 	sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
    689 	sGssAuthentication, sGssCleanupCreds, sGssDelegateCreds, sGssStrictAcceptor,
    690 	sAcceptEnv, sSetEnv, sPermitTunnel,
    691 	sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory,
    692 	sUsePrivilegeSeparation, sAllowAgentForwarding,
    693 	sHostCertificate, sInclude,
    694 	sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
    695 	sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser,
    696 	sKexAlgorithms, sCASignatureAlgorithms, sIPQoS, sVersionAddendum,
    697 	sIgnoreRootRhosts,
    698 	sNoneEnabled, sTcpRcvBufPoll,sHPNDisabled, sHPNBufferSize,
    699 	sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
    700 	sAuthenticationMethods, sHostKeyAgent, sPermitUserRC,
    701 	sStreamLocalBindMask, sStreamLocalBindUnlink,
    702 	sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding,
    703 	sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider,
    704 	sRequiredRSASize, sChannelTimeout, sUnusedConnectionTimeout,
    705 	sSshdSessionPath, sSshdAuthPath, sRefuseConnection,
    706 	sDeprecated, sIgnore, sUnsupported
    707 #ifdef WITH_LDAP_PUBKEY
    708 	,sLdapPublickey, sLdapServers, sLdapUserDN
    709 	,sLdapGroupDN, sBindDN, sBindPw, sMyGroup
    710 	,sLdapFilter, sForceTLS, sBindTimeout
    711 	,sSearchTimeout, sLdapConf ,sLpkPubKeyAttr
    712 #endif
    713 } ServerOpCodes;
    714 
    715 #define SSHCFG_GLOBAL		0x01	/* allowed in main section of config */
    716 #define SSHCFG_MATCH		0x02	/* allowed inside a Match section */
    717 #define SSHCFG_ALL		(SSHCFG_GLOBAL|SSHCFG_MATCH)
    718 #define SSHCFG_NEVERMATCH	0x04  /* Match never matches; internal only */
    719 #define SSHCFG_MATCH_ONLY	0x08  /* Match only in conditional blocks; internal only */
    720 
    721 /* Textual representation of the tokens. */
    722 static struct {
    723 	const char *name;
    724 	ServerOpCodes opcode;
    725 	u_int flags;
    726 } keywords[] = {
    727 	/* Portable-specific options */
    728 #ifdef USE_PAM
    729 	{ "usepam", sUsePAM, SSHCFG_GLOBAL },
    730 	{ "pamservicename", sPAMServiceName, SSHCFG_ALL },
    731 #else
    732 	{ "usepam", sUnsupported, SSHCFG_GLOBAL },
    733 	{ "pamservicename", sUnsupported, SSHCFG_ALL },
    734 #endif
    735 	/* Standard Options */
    736 	{ "port", sPort, SSHCFG_GLOBAL },
    737 	{ "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
    738 	{ "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL },		/* alias */
    739 	{ "hostkeyagent", sHostKeyAgent, SSHCFG_GLOBAL },
    740 	{ "pidfile", sPidFile, SSHCFG_GLOBAL },
    741 	{ "modulifile", sModuliFile, SSHCFG_GLOBAL },
    742 	{ "serverkeybits", sDeprecated, SSHCFG_GLOBAL },
    743 	{ "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
    744 	{ "keyregenerationinterval", sDeprecated, SSHCFG_GLOBAL },
    745 	{ "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
    746 	{ "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
    747 	{ "loglevel", sLogLevel, SSHCFG_ALL },
    748 	{ "logverbose", sLogVerbose, SSHCFG_ALL },
    749 	{ "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
    750 	{ "rhostsrsaauthentication", sDeprecated, SSHCFG_ALL },
    751 	{ "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
    752 	{ "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_ALL },
    753 	{ "hostbasedacceptedalgorithms", sHostbasedAcceptedAlgorithms, SSHCFG_ALL },
    754 	{ "hostbasedacceptedkeytypes", sHostbasedAcceptedAlgorithms, SSHCFG_ALL }, /* obsolete */
    755 	{ "hostkeyalgorithms", sHostKeyAlgorithms, SSHCFG_GLOBAL },
    756 	{ "rsaauthentication", sDeprecated, SSHCFG_ALL },
    757 	{ "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
    758 	{ "pubkeyacceptedalgorithms", sPubkeyAcceptedAlgorithms, SSHCFG_ALL },
    759 	{ "pubkeyacceptedkeytypes", sPubkeyAcceptedAlgorithms, SSHCFG_ALL }, /* obsolete */
    760 	{ "pubkeyauthoptions", sPubkeyAuthOptions, SSHCFG_ALL },
    761 	{ "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
    762 #ifdef KRB5
    763 	{ "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
    764 	{ "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
    765 	{ "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
    766 	{ "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
    767 #else
    768 	{ "kerberosauthentication", sUnsupported, SSHCFG_ALL },
    769 	{ "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
    770 	{ "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
    771 	{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
    772 #endif
    773 #if defined(AFS) || defined(KRB5)
    774 	{ "kerberostgtpassing", sKerberosTgtPassing, SSHCFG_GLOBAL },
    775 #else
    776 	{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
    777 #endif
    778 	{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
    779 #ifdef GSSAPI
    780 	{ "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
    781 	{ "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
    782 	{ "gssapidelegatecredentials", sGssDelegateCreds, SSHCFG_GLOBAL },
    783 	{ "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
    784 #else
    785 	{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
    786 	{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
    787 	{ "gssapidelegatecredentials", sUnsupported, SSHCFG_GLOBAL },
    788 	{ "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
    789 #endif
    790 	{ "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
    791 	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
    792 	{ "challengeresponseauthentication", sKbdInteractiveAuthentication, SSHCFG_GLOBAL },
    793 	{ "skeyauthentication", sKbdInteractiveAuthentication, SSHCFG_GLOBAL }, /* alias */
    794 	{ "checkmail", sDeprecated, SSHCFG_GLOBAL },
    795 	{ "listenaddress", sListenAddress, SSHCFG_GLOBAL },
    796 	{ "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
    797 	{ "printmotd", sPrintMotd, SSHCFG_GLOBAL },
    798 	{ "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
    799 	{ "ignorerhosts", sIgnoreRhosts, SSHCFG_ALL },
    800 	{ "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
    801 	{ "x11forwarding", sX11Forwarding, SSHCFG_ALL },
    802 	{ "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
    803 	{ "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
    804 	{ "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
    805 	{ "strictmodes", sStrictModes, SSHCFG_GLOBAL },
    806 	{ "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL },
    807 	{ "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
    808 	{ "uselogin", sDeprecated, SSHCFG_GLOBAL },
    809 	{ "compression", sCompression, SSHCFG_GLOBAL },
    810 	{ "rekeylimit", sRekeyLimit, SSHCFG_ALL },
    811 	{ "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
    812 	{ "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL },	/* obsolete alias */
    813 	{ "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
    814 	{ "allowagentforwarding", sAllowAgentForwarding, SSHCFG_ALL },
    815 	{ "allowusers", sAllowUsers, SSHCFG_ALL },
    816 	{ "denyusers", sDenyUsers, SSHCFG_ALL },
    817 	{ "allowgroups", sAllowGroups, SSHCFG_ALL },
    818 	{ "denygroups", sDenyGroups, SSHCFG_ALL },
    819 	{ "ciphers", sCiphers, SSHCFG_GLOBAL },
    820 	{ "macs", sMacs, SSHCFG_GLOBAL },
    821 	{ "protocol", sIgnore, SSHCFG_GLOBAL },
    822 	{ "gatewayports", sGatewayPorts, SSHCFG_ALL },
    823 	{ "subsystem", sSubsystem, SSHCFG_ALL },
    824 	{ "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
    825 	{ "persourcemaxstartups", sPerSourceMaxStartups, SSHCFG_GLOBAL },
    826 	{ "persourcenetblocksize", sPerSourceNetBlockSize, SSHCFG_GLOBAL },
    827 	{ "persourcepenalties", sPerSourcePenalties, SSHCFG_GLOBAL },
    828 	{ "persourcepenaltyexemptlist", sPerSourcePenaltyExemptList, SSHCFG_GLOBAL },
    829 	{ "maxauthtries", sMaxAuthTries, SSHCFG_ALL },
    830 	{ "maxsessions", sMaxSessions, SSHCFG_ALL },
    831 	{ "banner", sBanner, SSHCFG_ALL },
    832 	{ "usedns", sUseDNS, SSHCFG_GLOBAL },
    833 	{ "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
    834 	{ "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
    835 	{ "clientaliveinterval", sClientAliveInterval, SSHCFG_ALL },
    836 	{ "clientalivecountmax", sClientAliveCountMax, SSHCFG_ALL },
    837 	{ "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_ALL },
    838 	{ "authorizedkeysfile2", sDeprecated, SSHCFG_ALL },
    839 #ifdef WITH_LDAP_PUBKEY
    840 	{ _DEFAULT_LPK_TOKEN, sLdapPublickey, SSHCFG_GLOBAL },
    841 	{ _DEFAULT_SRV_TOKEN, sLdapServers, SSHCFG_GLOBAL },
    842 	{ _DEFAULT_USR_TOKEN, sLdapUserDN, SSHCFG_GLOBAL },
    843 	{ _DEFAULT_GRP_TOKEN, sLdapGroupDN, SSHCFG_GLOBAL },
    844 	{ _DEFAULT_BDN_TOKEN, sBindDN, SSHCFG_GLOBAL },
    845 	{ _DEFAULT_BPW_TOKEN, sBindPw, SSHCFG_GLOBAL },
    846 	{ _DEFAULT_MYG_TOKEN, sMyGroup, SSHCFG_GLOBAL },
    847 	{ _DEFAULT_FIL_TOKEN, sLdapFilter, SSHCFG_GLOBAL },
    848 	{ _DEFAULT_TLS_TOKEN, sForceTLS, SSHCFG_GLOBAL },
    849 	{ _DEFAULT_BTI_TOKEN, sBindTimeout, SSHCFG_GLOBAL },
    850 	{ _DEFAULT_STI_TOKEN, sSearchTimeout, SSHCFG_GLOBAL },
    851 	{ _DEFAULT_LDP_TOKEN, sLdapConf, SSHCFG_GLOBAL },
    852 	{ "LpkPubKeyAttr", sLpkPubKeyAttr, SSHCFG_GLOBAL },
    853 #endif
    854 	{ "useprivilegeseparation", sDeprecated, SSHCFG_GLOBAL},
    855 	{ "acceptenv", sAcceptEnv, SSHCFG_ALL },
    856 	{ "setenv", sSetEnv, SSHCFG_ALL },
    857 	{ "permittunnel", sPermitTunnel, SSHCFG_ALL },
    858 	{ "permittty", sPermitTTY, SSHCFG_ALL },
    859 	{ "permituserrc", sPermitUserRC, SSHCFG_ALL },
    860 	{ "match", sMatch, SSHCFG_ALL },
    861 	{ "permitopen", sPermitOpen, SSHCFG_ALL },
    862 	{ "permitlisten", sPermitListen, SSHCFG_ALL },
    863 	{ "forcecommand", sForceCommand, SSHCFG_ALL },
    864 	{ "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
    865 	{ "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
    866 	{ "revokedkeys", sRevokedKeys, SSHCFG_ALL },
    867 	{ "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
    868 	{ "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
    869 	{ "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
    870 	{ "include", sInclude, SSHCFG_ALL },
    871 	{ "ipqos", sIPQoS, SSHCFG_ALL },
    872 	{ "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL },
    873 	{ "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL },
    874 	{ "authorizedprincipalscommand", sAuthorizedPrincipalsCommand, SSHCFG_ALL },
    875 	{ "authorizedprincipalscommanduser", sAuthorizedPrincipalsCommandUser, SSHCFG_ALL },
    876 	{ "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
    877 	{ "noneenabled", sNoneEnabled, SSHCFG_ALL },
    878 	{ "hpndisabled", sHPNDisabled, SSHCFG_ALL },
    879 	{ "hpnbuffersize", sHPNBufferSize, SSHCFG_ALL },
    880 	{ "tcprcvbufpoll", sTcpRcvBufPoll, SSHCFG_ALL },
    881 	{ "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL },
    882 	{ "streamlocalbindmask", sStreamLocalBindMask, SSHCFG_ALL },
    883 	{ "streamlocalbindunlink", sStreamLocalBindUnlink, SSHCFG_ALL },
    884 	{ "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL },
    885 	{ "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL },
    886 	{ "disableforwarding", sDisableForwarding, SSHCFG_ALL },
    887 	{ "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL },
    888 	{ "rdomain", sRDomain, SSHCFG_ALL },
    889 	{ "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL },
    890 	{ "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL },
    891 	{ "requiredrsasize", sRequiredRSASize, SSHCFG_ALL },
    892 	{ "channeltimeout", sChannelTimeout, SSHCFG_ALL },
    893 	{ "unusedconnectiontimeout", sUnusedConnectionTimeout, SSHCFG_ALL },
    894 	{ "sshdsessionpath", sSshdSessionPath, SSHCFG_GLOBAL },
    895 	{ "sshdauthpath", sSshdAuthPath, SSHCFG_GLOBAL },
    896 	{ "refuseconnection", sRefuseConnection, SSHCFG_ALL },
    897 	{ NULL, sBadOption, 0 }
    898 };
    899 
    900 static struct {
    901 	int val;
    902 	const char *text;
    903 } tunmode_desc[] = {
    904 	{ SSH_TUNMODE_NO, "no" },
    905 	{ SSH_TUNMODE_POINTOPOINT, "point-to-point" },
    906 	{ SSH_TUNMODE_ETHERNET, "ethernet" },
    907 	{ SSH_TUNMODE_YES, "yes" },
    908 	{ -1, NULL }
    909 };
    910 
    911 /* Returns an opcode name from its number */
    912 
    913 static const char *
    914 lookup_opcode_name(ServerOpCodes code)
    915 {
    916 	u_int i;
    917 
    918 	for (i = 0; keywords[i].name != NULL; i++)
    919 		if (keywords[i].opcode == code)
    920 			return(keywords[i].name);
    921 	return "UNKNOWN";
    922 }
    923 
    924 
    925 /*
    926  * Returns the number of the token pointed to by cp or sBadOption.
    927  */
    928 
    929 static ServerOpCodes
    930 parse_token(const char *cp, const char *filename,
    931 	    int linenum, u_int *flags)
    932 {
    933 	u_int i;
    934 
    935 	for (i = 0; keywords[i].name; i++)
    936 		if (strcasecmp(cp, keywords[i].name) == 0) {
    937 		        debug ("Config token is %s", keywords[i].name);
    938 			*flags = keywords[i].flags;
    939 			return keywords[i].opcode;
    940 		}
    941 
    942 	error("%s: line %d: Bad configuration option: %s",
    943 	    filename, linenum, cp);
    944 	return sBadOption;
    945 }
    946 
    947 char *
    948 derelativise_path(const char *path)
    949 {
    950 	char *expanded, *ret, cwd[PATH_MAX];
    951 
    952 	if (strcasecmp(path, "none") == 0)
    953 		return xstrdup("none");
    954 	expanded = tilde_expand_filename(path, getuid());
    955 	if (path_absolute(expanded))
    956 		return expanded;
    957 	if (getcwd(cwd, sizeof(cwd)) == NULL)
    958 		fatal_f("getcwd: %s", strerror(errno));
    959 	xasprintf(&ret, "%s/%s", cwd, expanded);
    960 	free(expanded);
    961 	return ret;
    962 }
    963 
    964 static void
    965 add_listen_addr(ServerOptions *options, const char *addr,
    966     const char *rdomain, int port)
    967 {
    968 	u_int i;
    969 
    970 	if (port > 0)
    971 		add_one_listen_addr(options, addr, rdomain, port);
    972 	else {
    973 		for (i = 0; i < options->num_ports; i++) {
    974 			add_one_listen_addr(options, addr, rdomain,
    975 			    options->ports[i]);
    976 		}
    977 	}
    978 }
    979 
    980 static void
    981 add_one_listen_addr(ServerOptions *options, const char *addr,
    982     const char *rdomain, int port)
    983 {
    984 	struct addrinfo hints, *ai, *aitop;
    985 	char strport[NI_MAXSERV];
    986 	int gaierr;
    987 	u_int i;
    988 
    989 	/* Find listen_addrs entry for this rdomain */
    990 	for (i = 0; i < options->num_listen_addrs; i++) {
    991 		if (rdomain == NULL && options->listen_addrs[i].rdomain == NULL)
    992 			break;
    993 		if (rdomain == NULL || options->listen_addrs[i].rdomain == NULL)
    994 			continue;
    995 		if (strcmp(rdomain, options->listen_addrs[i].rdomain) == 0)
    996 			break;
    997 	}
    998 	if (i >= options->num_listen_addrs) {
    999 		/* No entry for this rdomain; allocate one */
   1000 		if (i >= INT_MAX)
   1001 			fatal_f("too many listen addresses");
   1002 		options->listen_addrs = xrecallocarray(options->listen_addrs,
   1003 		    options->num_listen_addrs, options->num_listen_addrs + 1,
   1004 		    sizeof(*options->listen_addrs));
   1005 		i = options->num_listen_addrs++;
   1006 		if (rdomain != NULL)
   1007 			options->listen_addrs[i].rdomain = xstrdup(rdomain);
   1008 	}
   1009 	/* options->listen_addrs[i] points to the addresses for this rdomain */
   1010 
   1011 	memset(&hints, 0, sizeof(hints));
   1012 	hints.ai_family = options->address_family;
   1013 	hints.ai_socktype = SOCK_STREAM;
   1014 	hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
   1015 	snprintf(strport, sizeof strport, "%d", port);
   1016 	if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
   1017 		fatal("bad addr or host: %s (%s)",
   1018 		    addr ? addr : "<NULL>",
   1019 		    ssh_gai_strerror(gaierr));
   1020 	for (ai = aitop; ai->ai_next; ai = ai->ai_next)
   1021 		;
   1022 	ai->ai_next = options->listen_addrs[i].addrs;
   1023 	options->listen_addrs[i].addrs = aitop;
   1024 }
   1025 
   1026 /* Returns nonzero if the routing domain name is valid */
   1027 static int
   1028 valid_rdomain(const char *name)
   1029 {
   1030 #ifdef NET_RT_TABLE
   1031 	const char *errstr;
   1032 	long long num;
   1033 	struct rt_tableinfo info;
   1034 	int mib[6];
   1035 	size_t miblen = sizeof(mib);
   1036 
   1037 	if (name == NULL)
   1038 		return 1;
   1039 
   1040 	num = strtonum(name, 0, 255, &errstr);
   1041 	if (errstr != NULL)
   1042 		return 0;
   1043 
   1044 	/* Check whether the table actually exists */
   1045 	memset(mib, 0, sizeof(mib));
   1046 	mib[0] = CTL_NET;
   1047 	mib[1] = PF_ROUTE;
   1048 	mib[4] = NET_RT_TABLE;
   1049 	mib[5] = (int)num;
   1050 	if (sysctl(mib, 6, &info, &miblen, NULL, 0) == -1)
   1051 		return 0;
   1052 
   1053 	return 1;
   1054 #else
   1055 	return 0;
   1056 #endif
   1057 }
   1058 
   1059 /*
   1060  * Queue a ListenAddress to be processed once we have all of the Ports
   1061  * and AddressFamily options.
   1062  */
   1063 static void
   1064 queue_listen_addr(ServerOptions *options, const char *addr,
   1065     const char *rdomain, int port)
   1066 {
   1067 	struct queued_listenaddr *qla;
   1068 
   1069 	options->queued_listen_addrs = xrecallocarray(
   1070 	    options->queued_listen_addrs,
   1071 	    options->num_queued_listens, options->num_queued_listens + 1,
   1072 	    sizeof(*options->queued_listen_addrs));
   1073 	qla = &options->queued_listen_addrs[options->num_queued_listens++];
   1074 	qla->addr = xstrdup(addr);
   1075 	qla->port = port;
   1076 	qla->rdomain = rdomain == NULL ? NULL : xstrdup(rdomain);
   1077 }
   1078 
   1079 /*
   1080  * Process queued (text) ListenAddress entries.
   1081  */
   1082 static void
   1083 process_queued_listen_addrs(ServerOptions *options)
   1084 {
   1085 	u_int i;
   1086 	struct queued_listenaddr *qla;
   1087 
   1088 	if (options->num_ports == 0)
   1089 		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
   1090 	if (options->address_family == -1)
   1091 		options->address_family = AF_UNSPEC;
   1092 
   1093 	for (i = 0; i < options->num_queued_listens; i++) {
   1094 		qla = &options->queued_listen_addrs[i];
   1095 		add_listen_addr(options, qla->addr, qla->rdomain, qla->port);
   1096 		free(qla->addr);
   1097 		free(qla->rdomain);
   1098 	}
   1099 	free(options->queued_listen_addrs);
   1100 	options->queued_listen_addrs = NULL;
   1101 	options->num_queued_listens = 0;
   1102 }
   1103 
   1104 /*
   1105  * The strategy for the Match blocks is that the config file is parsed twice.
   1106  *
   1107  * The first time is at startup.  activep is initialized to 1 and the
   1108  * directives in the global context are processed and acted on.  Hitting a
   1109  * Match directive unsets activep and the directives inside the block are
   1110  * checked for syntax only.
   1111  *
   1112  * The second time is after a connection has been established but before
   1113  * authentication.  activep is initialized to 2 and global config directives
   1114  * are ignored since they have already been processed.  If the criteria in a
   1115  * Match block is met, activep is set and the subsequent directives
   1116  * processed and actioned until EOF or another Match block unsets it.  Any
   1117  * options set are copied into the main server config.
   1118  *
   1119  * Potential additions/improvements:
   1120  *  - Add Match support for pre-kex directives, eg. Ciphers.
   1121  *
   1122  *  - Add a Tag directive (idea from David Leonard) ala pf, eg:
   1123  *	Match Address 192.168.0.*
   1124  *		Tag trusted
   1125  *	Match Group wheel
   1126  *		Tag trusted
   1127  *	Match Tag trusted
   1128  *		AllowTcpForwarding yes
   1129  *		GatewayPorts clientspecified
   1130  *		[...]
   1131  *
   1132  *  - Add a PermittedChannelRequests directive
   1133  *	Match Group shell
   1134  *		PermittedChannelRequests session,forwarded-tcpip
   1135  */
   1136 
   1137 static int
   1138 match_cfg_line_group(const char *grps, int line, const char *user)
   1139 {
   1140 	int result = 0;
   1141 	struct passwd *pw;
   1142 
   1143 	if (user == NULL)
   1144 		goto out;
   1145 
   1146 	if ((pw = getpwnam(user)) == NULL) {
   1147 		debug("Can't match group at line %d because user %.100s does "
   1148 		    "not exist", line, user);
   1149 	} else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
   1150 		debug("Can't Match group because user %.100s not in any group "
   1151 		    "at line %d", user, line);
   1152 	} else if (ga_match_pattern_list(grps) != 1) {
   1153 		debug("user %.100s does not match group list %.100s at line %d",
   1154 		    user, grps, line);
   1155 	} else {
   1156 		debug("user %.100s matched group list %.100s at line %d", user,
   1157 		    grps, line);
   1158 		result = 1;
   1159 	}
   1160 out:
   1161 	ga_free();
   1162 	return result;
   1163 }
   1164 
   1165 __dead static void
   1166 match_test_missing_fatal(const char *criteria, const char *attrib)
   1167 {
   1168 	fatal("'Match %s' in configuration but '%s' not in connection "
   1169 	    "test specification.", criteria, attrib);
   1170 }
   1171 
   1172 /*
   1173  * All of the attributes on a single Match line are ANDed together, so we need
   1174  * to check every attribute and set the result to zero if any attribute does
   1175  * not match.
   1176  */
   1177 static int
   1178 match_cfg_line(const char *full_line, int *acp, char ***avp,
   1179     int line, struct connection_info *ci)
   1180 {
   1181 	int result = 1, attributes = 0, port;
   1182 	char *arg, *attrib = NULL, *oattrib;
   1183 
   1184 	if (ci == NULL) {
   1185 		debug3("checking syntax for 'Match %s' on line %d",
   1186 		    full_line, line);
   1187 	} else {
   1188 		debug3("checking match for '%s' user %s%s host %s addr %s "
   1189 		    "laddr %s lport %d on line %d", full_line,
   1190 		    ci->user ? ci->user : "(null)",
   1191 		    ci->user_invalid ? " (invalid)" : "",
   1192 		    ci->host ? ci->host : "(null)",
   1193 		    ci->address ? ci->address : "(null)",
   1194 		    ci->laddress ? ci->laddress : "(null)", ci->lport, line);
   1195 	}
   1196 
   1197 	while ((oattrib = argv_next(acp, avp)) != NULL) {
   1198 		/* Terminate on comment */
   1199 		if (*oattrib == '#') {
   1200 			argv_consume(acp); /* mark all arguments consumed */
   1201 			break;
   1202 		}
   1203 		attrib = xstrdup(oattrib);
   1204 		arg = NULL;
   1205 		attributes++;
   1206 		/* Criterion "all" has no argument and must appear alone */
   1207 		if (strcasecmp(attrib, "all") == 0) {
   1208 			if (attributes > 1 ||
   1209 			    ((arg = argv_next(acp, avp)) != NULL &&
   1210 			    *arg != '\0' && *arg != '#')) {
   1211 				error("'all' cannot be combined with other "
   1212 				    "Match attributes");
   1213 				result = -1;
   1214 				goto out;
   1215 			}
   1216 			if (arg != NULL && *arg == '#')
   1217 				argv_consume(acp); /* consume remaining args */
   1218 			result = 1;
   1219 			goto out;
   1220 		}
   1221 		/* Criterion "invalid-user" also has no argument */
   1222 		if (strcasecmp(attrib, "invalid-user") == 0) {
   1223 			if (ci == NULL) {
   1224 				result = 0;
   1225 				goto next;
   1226 			}
   1227 			if (ci->user_invalid == 0)
   1228 				result = 0;
   1229 			else
   1230 				debug("matched invalid-user at line %d", line);
   1231 			goto next;
   1232 		}
   1233 
   1234 		/* Keep this list in sync with below */
   1235 		if (strprefix(attrib, "user=", 1) != NULL ||
   1236 		    strprefix(attrib, "group=", 1) != NULL ||
   1237 		    strprefix(attrib, "host=", 1) != NULL ||
   1238 		    strprefix(attrib, "address=", 1) != NULL ||
   1239 		    strprefix(attrib, "localaddress=", 1) != NULL ||
   1240 		    strprefix(attrib, "localport=", 1) != NULL ||
   1241 		    strprefix(attrib, "rdomain=", 1) != NULL ||
   1242 		    strprefix(attrib, "version=", 1) != NULL) {
   1243 			arg = strchr(attrib, '=');
   1244 			*(arg++) = '\0';
   1245 		} else {
   1246 			arg = argv_next(acp, avp);
   1247 		}
   1248 
   1249 		/* All other criteria require an argument */
   1250 		if (arg == NULL || *arg == '\0' || *arg == '#') {
   1251 			error("Missing Match criteria for %s", attrib);
   1252 			result = -1;
   1253 			goto out;
   1254 		}
   1255 		if (strcasecmp(attrib, "user") == 0) {
   1256 			if (ci == NULL || (ci->test && ci->user == NULL)) {
   1257 				result = 0;
   1258 				goto next;
   1259 			}
   1260 			if (ci->user == NULL)
   1261 				match_test_missing_fatal("User", "user");
   1262 			if (match_usergroup_pattern_list(ci->user, arg) != 1)
   1263 				result = 0;
   1264 			else
   1265 				debug("user %.100s matched 'User %.100s' at "
   1266 				    "line %d", ci->user, arg, line);
   1267 		} else if (strcasecmp(attrib, "group") == 0) {
   1268 			if (ci == NULL || (ci->test && ci->user == NULL)) {
   1269 				result = 0;
   1270 				goto next;
   1271 			}
   1272 			if (ci->user == NULL)
   1273 				match_test_missing_fatal("Group", "user");
   1274 			switch (match_cfg_line_group(arg, line, ci->user)) {
   1275 			case -1:
   1276 				result = -1;
   1277 				goto out;
   1278 			case 0:
   1279 				result = 0;
   1280 			}
   1281 		} else if (strcasecmp(attrib, "host") == 0) {
   1282 			if (ci == NULL || (ci->test && ci->host == NULL)) {
   1283 				result = 0;
   1284 				goto next;
   1285 			}
   1286 			if (ci->host == NULL)
   1287 				match_test_missing_fatal("Host", "host");
   1288 			if (match_hostname(ci->host, arg) != 1)
   1289 				result = 0;
   1290 			else
   1291 				debug("connection from %.100s matched 'Host "
   1292 				    "%.100s' at line %d", ci->host, arg, line);
   1293 		} else if (strcasecmp(attrib, "address") == 0) {
   1294 			if (ci == NULL || (ci->test && ci->address == NULL)) {
   1295 				if (addr_match_list(NULL, arg) != 0)
   1296 					fatal("Invalid Match address argument "
   1297 					    "'%s' at line %d", arg, line);
   1298 				result = 0;
   1299 				goto next;
   1300 			}
   1301 			if (ci->address == NULL)
   1302 				match_test_missing_fatal("Address", "addr");
   1303 			switch (addr_match_list(ci->address, arg)) {
   1304 			case 1:
   1305 				debug("connection from %.100s matched 'Address "
   1306 				    "%.100s' at line %d", ci->address, arg, line);
   1307 				break;
   1308 			case 0:
   1309 			case -1:
   1310 				result = 0;
   1311 				break;
   1312 			case -2:
   1313 				result = -1;
   1314 				goto out;
   1315 			}
   1316 		} else if (strcasecmp(attrib, "localaddress") == 0){
   1317 			if (ci == NULL || (ci->test && ci->laddress == NULL)) {
   1318 				if (addr_match_list(NULL, arg) != 0)
   1319 					fatal("Invalid Match localaddress "
   1320 					    "argument '%s' at line %d", arg,
   1321 					    line);
   1322 				result = 0;
   1323 				goto next;
   1324 			}
   1325 			if (ci->laddress == NULL)
   1326 				match_test_missing_fatal("LocalAddress",
   1327 				    "laddr");
   1328 			switch (addr_match_list(ci->laddress, arg)) {
   1329 			case 1:
   1330 				debug("connection from %.100s matched "
   1331 				    "'LocalAddress %.100s' at line %d",
   1332 				    ci->laddress, arg, line);
   1333 				break;
   1334 			case 0:
   1335 			case -1:
   1336 				result = 0;
   1337 				break;
   1338 			case -2:
   1339 				result = -1;
   1340 				goto out;
   1341 			}
   1342 		} else if (strcasecmp(attrib, "localport") == 0) {
   1343 			if ((port = a2port(arg)) == -1) {
   1344 				error("Invalid LocalPort '%s' on Match line",
   1345 				    arg);
   1346 				result = -1;
   1347 				goto out;
   1348 			}
   1349 			if (ci == NULL || (ci->test && ci->lport == -1)) {
   1350 				result = 0;
   1351 				goto next;
   1352 			}
   1353 			if (ci->lport == 0)
   1354 				match_test_missing_fatal("LocalPort", "lport");
   1355 			/* TODO support port lists */
   1356 			if (port == ci->lport)
   1357 				debug("connection from %.100s matched "
   1358 				    "'LocalPort %d' at line %d",
   1359 				    ci->laddress, port, line);
   1360 			else
   1361 				result = 0;
   1362 		} else if (strcasecmp(attrib, "rdomain") == 0) {
   1363 			if (ci == NULL || (ci->test && ci->rdomain == NULL)) {
   1364 				result = 0;
   1365 				goto next;
   1366 			}
   1367 			if (ci->rdomain == NULL)
   1368 				match_test_missing_fatal("RDomain", "rdomain");
   1369 			if (match_pattern_list(ci->rdomain, arg, 0) != 1)
   1370 				result = 0;
   1371 			else
   1372 				debug("connection RDomain %.100s matched "
   1373 				    "'RDomain %.100s' at line %d",
   1374 				    ci->rdomain, arg, line);
   1375 		} else if (strcasecmp(attrib, "version") == 0) {
   1376 			if (match_pattern_list(SSH_RELEASE, arg, 0) != 1)
   1377 				result = 0;
   1378 			else
   1379 				debug("version %.100s matched "
   1380 				    "'version %.100s' at line %d",
   1381 				    SSH_RELEASE, arg, line);
   1382 		} else {
   1383 			error("Unsupported Match attribute %s", oattrib);
   1384 			result = -1;
   1385 			goto out;
   1386 		}
   1387  next:
   1388 		free(attrib);
   1389 		attrib = NULL;
   1390 	}
   1391 	if (attributes == 0) {
   1392 		error("One or more attributes required for Match");
   1393 		return -1;
   1394 	}
   1395  out:
   1396 	if (ci != NULL && result != -1)
   1397 		debug3("match %sfound on line %d", result ? "" : "not ", line);
   1398 	free(attrib);
   1399 	return result;
   1400 }
   1401 
   1402 #define WHITESPACE " \t\r\n"
   1403 
   1404 /* Multistate option parsing */
   1405 struct multistate {
   1406 	const char *key;
   1407 	int value;
   1408 };
   1409 static const struct multistate multistate_flag[] = {
   1410 	{ "yes",			1 },
   1411 	{ "no",				0 },
   1412 	{ NULL, -1 }
   1413 };
   1414 static const struct multistate multistate_ignore_rhosts[] = {
   1415 	{ "yes",			IGNORE_RHOSTS_YES },
   1416 	{ "no",				IGNORE_RHOSTS_NO },
   1417 	{ "shosts-only",		IGNORE_RHOSTS_SHOSTS },
   1418 	{ NULL, -1 }
   1419 };
   1420 static const struct multistate multistate_addressfamily[] = {
   1421 	{ "inet",			AF_INET },
   1422 	{ "inet6",			AF_INET6 },
   1423 	{ "any",			AF_UNSPEC },
   1424 	{ NULL, -1 }
   1425 };
   1426 static const struct multistate multistate_permitrootlogin[] = {
   1427 	{ "prohibit-password",		PERMIT_NO_PASSWD },
   1428 	{ "without-password",		PERMIT_NO_PASSWD },
   1429 	{ "forced-commands-only",	PERMIT_FORCED_ONLY },
   1430 	{ "yes",			PERMIT_YES },
   1431 	{ "no",				PERMIT_NO },
   1432 	{ NULL, -1 }
   1433 };
   1434 static const struct multistate multistate_compression[] = {
   1435 #ifdef WITH_ZLIB
   1436 	{ "yes",			COMP_DELAYED },
   1437 	{ "delayed",			COMP_DELAYED },
   1438 #endif
   1439 	{ "no",				COMP_NONE },
   1440 	{ NULL, -1 }
   1441 };
   1442 static const struct multistate multistate_gatewayports[] = {
   1443 	{ "clientspecified",		2 },
   1444 	{ "yes",			1 },
   1445 	{ "no",				0 },
   1446 	{ NULL, -1 }
   1447 };
   1448 static const struct multistate multistate_tcpfwd[] = {
   1449 	{ "yes",			FORWARD_ALLOW },
   1450 	{ "all",			FORWARD_ALLOW },
   1451 	{ "no",				FORWARD_DENY },
   1452 	{ "remote",			FORWARD_REMOTE },
   1453 	{ "local",			FORWARD_LOCAL },
   1454 	{ NULL, -1 }
   1455 };
   1456 
   1457 static int
   1458 process_server_config_line_depth(ServerOptions *options, char *line,
   1459     const char *filename, int linenum, int *activep,
   1460     struct connection_info *connectinfo, int *inc_flags, int depth,
   1461     struct include_list *includes)
   1462 {
   1463 	char *str, ***chararrayptr, **charptr, *arg, *arg2, *p, *keyword;
   1464 	int cmdline = 0, *intptr, value, value2, value3, n, port, oactive, r;
   1465 	double dvalue, *doubleptr = NULL;
   1466 	int ca_only = 0, found = 0;
   1467 	SyslogFacility *log_facility_ptr;
   1468 	LogLevel *log_level_ptr;
   1469 #ifdef WITH_LDAP_PUBKEY
   1470  	unsigned long lvalue;
   1471 #endif
   1472 	time_t *timetptr __unused;
   1473 	ServerOpCodes opcode;
   1474 	u_int i, *uintptr, flags = 0;
   1475 	size_t len;
   1476 	long long val64;
   1477 	const struct multistate *multistate_ptr;
   1478 	const char *errstr;
   1479 	struct include_item *item;
   1480 	glob_t gbuf;
   1481 	char **oav = NULL, **av;
   1482 	int oac = 0, ac;
   1483 	int ret = -1;
   1484 	char **strs = NULL; /* string array arguments; freed implicitly */
   1485 	u_int nstrs = 0;
   1486 
   1487 	/* Strip trailing whitespace. Allow \f (form feed) at EOL only */
   1488 	if ((len = strlen(line)) == 0)
   1489 		return 0;
   1490 	for (len--; len > 0; len--) {
   1491 		if (strchr(WHITESPACE "\f", line[len]) == NULL)
   1492 			break;
   1493 		line[len] = '\0';
   1494 	}
   1495 
   1496 	str = line;
   1497 	if ((keyword = strdelim(&str)) == NULL)
   1498 		return 0;
   1499 	/* Ignore leading whitespace */
   1500 	if (*keyword == '\0')
   1501 		keyword = strdelim(&str);
   1502 	if (!keyword || !*keyword || *keyword == '#')
   1503 		return 0;
   1504 	if (str == NULL || *str == '\0') {
   1505 		error("%s line %d: no argument after keyword \"%s\"",
   1506 		    filename, linenum, keyword);
   1507 		return -1;
   1508 	}
   1509 	intptr = NULL;
   1510 	timetptr = NULL;
   1511 	charptr = NULL;
   1512 	opcode = parse_token(keyword, filename, linenum, &flags);
   1513 
   1514 	if (argv_split(str, &oac, &oav, 1) != 0) {
   1515 		error("%s line %d: invalid quotes", filename, linenum);
   1516 		return -1;
   1517 	}
   1518 	ac = oac;
   1519 	av = oav;
   1520 
   1521 	if (activep == NULL) { /* We are processing a command line directive */
   1522 		cmdline = 1;
   1523 		activep = &cmdline;
   1524 	}
   1525 	if (*activep && opcode != sMatch && opcode != sInclude)
   1526 		debug3("%s:%d setting %s %s", filename, linenum, keyword, str);
   1527 	if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
   1528 		if (connectinfo == NULL) {
   1529 			fatal("%s line %d: Directive '%s' is not allowed "
   1530 			    "within a Match block", filename, linenum, keyword);
   1531 		} else { /* this is a directive we have already processed */
   1532 			ret = 0;
   1533 			goto out;
   1534 		}
   1535 	}
   1536 
   1537 	switch (opcode) {
   1538 	/* Portable-specific options */
   1539 	case sUsePAM:
   1540 		intptr = &options->use_pam;
   1541 		goto parse_flag;
   1542 	case sPAMServiceName:
   1543 		charptr = &options->pam_service_name;
   1544 		arg = argv_next(&ac, &av);
   1545 		if (!arg || *arg == '\0') {
   1546 			fatal("%s line %d: missing argument.",
   1547 			    filename, linenum);
   1548 		}
   1549 		if (*activep && *charptr == NULL)
   1550 			*charptr = xstrdup(arg);
   1551 		break;
   1552 
   1553 	/* Standard Options */
   1554 	case sBadOption:
   1555 		goto out;
   1556 	case sPort:
   1557 		/* ignore ports from configfile if cmdline specifies ports */
   1558 		if (options->ports_from_cmdline) {
   1559 			argv_consume(&ac);
   1560 			break;
   1561 		}
   1562 		if (options->num_ports >= MAX_PORTS)
   1563 			fatal("%s line %d: too many ports.",
   1564 			    filename, linenum);
   1565 		arg = argv_next(&ac, &av);
   1566 		if (!arg || *arg == '\0')
   1567 			fatal("%s line %d: missing port number.",
   1568 			    filename, linenum);
   1569 		options->ports[options->num_ports++] = a2port(arg);
   1570 		if (options->ports[options->num_ports-1] <= 0)
   1571 			fatal("%s line %d: Badly formatted port number.",
   1572 			    filename, linenum);
   1573 		break;
   1574 
   1575 	case sLoginGraceTime:
   1576 		intptr = &options->login_grace_time;
   1577  parse_time:
   1578 		arg = argv_next(&ac, &av);
   1579 		if (!arg || *arg == '\0')
   1580 			fatal("%s line %d: missing time value.",
   1581 			    filename, linenum);
   1582 		if ((value = convtime(arg)) == -1)
   1583 			fatal("%s line %d: invalid time value.",
   1584 			    filename, linenum);
   1585 		if (*activep && *intptr == -1)
   1586 			*intptr = value;
   1587 		break;
   1588 
   1589 	case sListenAddress:
   1590 		arg = argv_next(&ac, &av);
   1591 		if (arg == NULL || *arg == '\0')
   1592 			fatal("%s line %d: missing address",
   1593 			    filename, linenum);
   1594 		/* check for bare IPv6 address: no "[]" and 2 or more ":" */
   1595 		if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
   1596 		    && strchr(p+1, ':') != NULL) {
   1597 			port = 0;
   1598 			p = arg;
   1599 		} else {
   1600 			arg2 = NULL;
   1601 			p = hpdelim(&arg);
   1602 			if (p == NULL)
   1603 				fatal("%s line %d: bad address:port usage",
   1604 				    filename, linenum);
   1605 			p = cleanhostname(p);
   1606 			if (arg == NULL)
   1607 				port = 0;
   1608 			else if ((port = a2port(arg)) <= 0)
   1609 				fatal("%s line %d: bad port number",
   1610 				    filename, linenum);
   1611 		}
   1612 		/* Optional routing table */
   1613 		arg2 = NULL;
   1614 		if ((arg = argv_next(&ac, &av)) != NULL) {
   1615 			if (strcmp(arg, "rdomain") != 0 ||
   1616 			    (arg2 = argv_next(&ac, &av)) == NULL)
   1617 				fatal("%s line %d: bad ListenAddress syntax",
   1618 				    filename, linenum);
   1619 			if (!valid_rdomain(arg2))
   1620 				fatal("%s line %d: bad routing domain",
   1621 				    filename, linenum);
   1622 		}
   1623 		queue_listen_addr(options, p, arg2, port);
   1624 
   1625 		break;
   1626 
   1627 	case sAddressFamily:
   1628 		intptr = &options->address_family;
   1629 		multistate_ptr = multistate_addressfamily;
   1630  parse_multistate:
   1631 		arg = argv_next(&ac, &av);
   1632 		if (!arg || *arg == '\0')
   1633 			fatal("%s line %d: missing argument.",
   1634 			    filename, linenum);
   1635 		value = -1;
   1636 		for (i = 0; multistate_ptr[i].key != NULL; i++) {
   1637 			if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
   1638 				value = multistate_ptr[i].value;
   1639 				break;
   1640 			}
   1641 		}
   1642 		if (value == -1)
   1643 			fatal("%s line %d: unsupported option \"%s\".",
   1644 			    filename, linenum, arg);
   1645 		if (*activep && *intptr == -1)
   1646 			*intptr = value;
   1647 		break;
   1648 
   1649 	case sHostKeyFile:
   1650 		arg = argv_next(&ac, &av);
   1651 		if (!arg || *arg == '\0')
   1652 			fatal("%s line %d: missing file name.",
   1653 			    filename, linenum);
   1654 		if (*activep) {
   1655 			servconf_add_hostkey(filename, linenum,
   1656 			    options, arg, 1);
   1657 		}
   1658 		break;
   1659 
   1660 	case sHostKeyAgent:
   1661 		charptr = &options->host_key_agent;
   1662 		arg = argv_next(&ac, &av);
   1663 		if (!arg || *arg == '\0')
   1664 			fatal("%s line %d: missing socket name.",
   1665 			    filename, linenum);
   1666 		if (*activep && *charptr == NULL)
   1667 			*charptr = !strcmp(arg, SSH_AUTHSOCKET_ENV_NAME) ?
   1668 			    xstrdup(arg) : derelativise_path(arg);
   1669 		break;
   1670 
   1671 	case sHostCertificate:
   1672 		arg = argv_next(&ac, &av);
   1673 		if (!arg || *arg == '\0')
   1674 			fatal("%s line %d: missing file name.",
   1675 			    filename, linenum);
   1676 		if (*activep)
   1677 			servconf_add_hostcert(filename, linenum, options, arg);
   1678 		break;
   1679 
   1680 	case sPidFile:
   1681 		charptr = &options->pid_file;
   1682  parse_filename:
   1683 		arg = argv_next(&ac, &av);
   1684 		if (!arg || *arg == '\0')
   1685 			fatal("%s line %d: missing file name.",
   1686 			    filename, linenum);
   1687 		if (*activep && *charptr == NULL) {
   1688 			*charptr = derelativise_path(arg);
   1689 			/* increase optional counter */
   1690 			if (intptr != NULL)
   1691 				*intptr = *intptr + 1;
   1692 		}
   1693 		break;
   1694 
   1695 	case sModuliFile:
   1696 		charptr = &options->moduli_file;
   1697 		goto parse_filename;
   1698 
   1699 	case sPermitRootLogin:
   1700 		intptr = &options->permit_root_login;
   1701 		multistate_ptr = multistate_permitrootlogin;
   1702 		goto parse_multistate;
   1703 
   1704 	case sIgnoreRhosts:
   1705 		intptr = &options->ignore_rhosts;
   1706 		multistate_ptr = multistate_ignore_rhosts;
   1707 		goto parse_multistate;
   1708 
   1709 	case sIgnoreRootRhosts:
   1710 		intptr = &options->ignore_root_rhosts;
   1711 		goto parse_flag;
   1712 
   1713 	case sNoneEnabled:
   1714 		intptr = &options->none_enabled;
   1715 		goto parse_flag;
   1716 
   1717 	case sTcpRcvBufPoll:
   1718 		intptr = &options->tcp_rcv_buf_poll;
   1719 		goto parse_flag;
   1720 
   1721 	case sHPNDisabled:
   1722 		intptr = &options->hpn_disabled;
   1723 		goto parse_flag;
   1724 
   1725 	case sHPNBufferSize:
   1726 		intptr = &options->hpn_buffer_size;
   1727 		goto parse_int;
   1728 
   1729 	case sIgnoreUserKnownHosts:
   1730 		intptr = &options->ignore_user_known_hosts;
   1731  parse_flag:
   1732 		multistate_ptr = multistate_flag;
   1733 		goto parse_multistate;
   1734 
   1735 	case sHostbasedAuthentication:
   1736 		intptr = &options->hostbased_authentication;
   1737 		goto parse_flag;
   1738 
   1739 	case sHostbasedUsesNameFromPacketOnly:
   1740 		intptr = &options->hostbased_uses_name_from_packet_only;
   1741 		goto parse_flag;
   1742 
   1743 	case sHostbasedAcceptedAlgorithms:
   1744 		charptr = &options->hostbased_accepted_algos;
   1745 		ca_only = 0;
   1746  parse_pubkey_algos:
   1747 		arg = argv_next(&ac, &av);
   1748 		if (!arg || *arg == '\0')
   1749 			fatal("%s line %d: Missing argument.",
   1750 			    filename, linenum);
   1751 		if (*arg != '-' &&
   1752 		    !sshkey_names_valid2(*arg == '+' || *arg == '^' ?
   1753 		    arg + 1 : arg, 1, ca_only))
   1754 			fatal("%s line %d: Bad key types '%s'.",
   1755 			    filename, linenum, arg ? arg : "<NONE>");
   1756 		if (*activep && *charptr == NULL)
   1757 			*charptr = xstrdup(arg);
   1758 		break;
   1759 
   1760 	case sHostKeyAlgorithms:
   1761 		charptr = &options->hostkeyalgorithms;
   1762 		ca_only = 0;
   1763 		goto parse_pubkey_algos;
   1764 
   1765 	case sCASignatureAlgorithms:
   1766 		charptr = &options->ca_sign_algorithms;
   1767 		ca_only = 1;
   1768 		goto parse_pubkey_algos;
   1769 
   1770 	case sPubkeyAuthentication:
   1771 		intptr = &options->pubkey_authentication;
   1772 		ca_only = 0;
   1773 		goto parse_flag;
   1774 
   1775 	case sPubkeyAcceptedAlgorithms:
   1776 		charptr = &options->pubkey_accepted_algos;
   1777 		ca_only = 0;
   1778 		goto parse_pubkey_algos;
   1779 
   1780 	case sPubkeyAuthOptions:
   1781 		intptr = &options->pubkey_auth_options;
   1782 		value = 0;
   1783 		while ((arg = argv_next(&ac, &av)) != NULL) {
   1784 			if (strcasecmp(arg, "none") == 0)
   1785 				continue;
   1786 			if (strcasecmp(arg, "touch-required") == 0)
   1787 				value |= PUBKEYAUTH_TOUCH_REQUIRED;
   1788 			else if (strcasecmp(arg, "verify-required") == 0)
   1789 				value |= PUBKEYAUTH_VERIFY_REQUIRED;
   1790 			else {
   1791 				error("%s line %d: unsupported %s option %s",
   1792 				    filename, linenum, keyword, arg);
   1793 				goto out;
   1794 			}
   1795 		}
   1796 		if (*activep && *intptr == -1)
   1797 			*intptr = value;
   1798 		break;
   1799 
   1800 	case sKerberosAuthentication:
   1801 		intptr = &options->kerberos_authentication;
   1802 		goto parse_flag;
   1803 
   1804 	case sKerberosOrLocalPasswd:
   1805 		intptr = &options->kerberos_or_local_passwd;
   1806 		goto parse_flag;
   1807 
   1808 	case sKerberosTicketCleanup:
   1809 		intptr = &options->kerberos_ticket_cleanup;
   1810 		goto parse_flag;
   1811 
   1812 	case sKerberosTgtPassing:
   1813 		intptr = &options->kerberos_tgt_passing;
   1814 		goto parse_flag;
   1815 
   1816 	case sKerberosGetAFSToken:
   1817 		intptr = &options->kerberos_get_afs_token;
   1818 		goto parse_flag;
   1819 
   1820 	case sGssAuthentication:
   1821 		intptr = &options->gss_authentication;
   1822 		goto parse_flag;
   1823 
   1824 	case sGssCleanupCreds:
   1825 		intptr = &options->gss_cleanup_creds;
   1826 		goto parse_flag;
   1827 
   1828 	case sGssDelegateCreds:
   1829 		intptr = &options->gss_deleg_creds;
   1830 		goto parse_flag;
   1831 
   1832 	case sGssStrictAcceptor:
   1833 		intptr = &options->gss_strict_acceptor;
   1834 		goto parse_flag;
   1835 
   1836 	case sPasswordAuthentication:
   1837 		intptr = &options->password_authentication;
   1838 		goto parse_flag;
   1839 
   1840 	case sKbdInteractiveAuthentication:
   1841 		intptr = &options->kbd_interactive_authentication;
   1842 		goto parse_flag;
   1843 
   1844 	case sPrintMotd:
   1845 		intptr = &options->print_motd;
   1846 		goto parse_flag;
   1847 
   1848 	case sPrintLastLog:
   1849 		intptr = &options->print_lastlog;
   1850 		goto parse_flag;
   1851 
   1852 	case sX11Forwarding:
   1853 		intptr = &options->x11_forwarding;
   1854 		goto parse_flag;
   1855 
   1856 	case sX11DisplayOffset:
   1857 		intptr = &options->x11_display_offset;
   1858  parse_int:
   1859 		arg = argv_next(&ac, &av);
   1860 		if ((errstr = atoi_err(arg, &value)) != NULL)
   1861 			fatal("%s line %d: %s integer value %s.",
   1862 			    filename, linenum, keyword, errstr);
   1863 		if (*activep && *intptr == -1)
   1864 			*intptr = value;
   1865 		break;
   1866 
   1867 	case sX11UseLocalhost:
   1868 		intptr = &options->x11_use_localhost;
   1869 		goto parse_flag;
   1870 
   1871 	case sXAuthLocation:
   1872 		charptr = &options->xauth_location;
   1873 		goto parse_filename;
   1874 
   1875 	case sPermitTTY:
   1876 		intptr = &options->permit_tty;
   1877 		goto parse_flag;
   1878 
   1879 	case sPermitUserRC:
   1880 		intptr = &options->permit_user_rc;
   1881 		goto parse_flag;
   1882 
   1883 	case sStrictModes:
   1884 		intptr = &options->strict_modes;
   1885 		goto parse_flag;
   1886 
   1887 	case sTCPKeepAlive:
   1888 		intptr = &options->tcp_keep_alive;
   1889 		goto parse_flag;
   1890 
   1891 	case sEmptyPasswd:
   1892 		intptr = &options->permit_empty_passwd;
   1893 		goto parse_flag;
   1894 
   1895 	case sPermitUserEnvironment:
   1896 		intptr = &options->permit_user_env;
   1897 		charptr = &options->permit_user_env_allowlist;
   1898 		arg = argv_next(&ac, &av);
   1899 		if (!arg || *arg == '\0')
   1900 			fatal("%s line %d: %s missing argument.",
   1901 			    filename, linenum, keyword);
   1902 		value = 0;
   1903 		p = NULL;
   1904 		if (strcmp(arg, "yes") == 0)
   1905 			value = 1;
   1906 		else if (strcmp(arg, "no") == 0)
   1907 			value = 0;
   1908 		else {
   1909 			/* Pattern-list specified */
   1910 			value = 1;
   1911 			p = xstrdup(arg);
   1912 		}
   1913 		if (*activep && *intptr == -1) {
   1914 			*intptr = value;
   1915 			*charptr = p;
   1916 			p = NULL;
   1917 		}
   1918 		free(p);
   1919 		break;
   1920 
   1921 	case sCompression:
   1922 		intptr = &options->compression;
   1923 		multistate_ptr = multistate_compression;
   1924 		goto parse_multistate;
   1925 
   1926 	case sRekeyLimit:
   1927 		arg = argv_next(&ac, &av);
   1928 		if (!arg || *arg == '\0')
   1929 			fatal("%s line %d: %s missing argument.",
   1930 			    filename, linenum, keyword);
   1931 		if (strcmp(arg, "default") == 0) {
   1932 			val64 = 0;
   1933 		} else {
   1934 			if (scan_scaled(arg, &val64) == -1)
   1935 				fatal("%.200s line %d: Bad %s number '%s': %s",
   1936 				    filename, linenum, keyword,
   1937 				    arg, strerror(errno));
   1938 			if (val64 != 0 && val64 < 16)
   1939 				fatal("%.200s line %d: %s too small",
   1940 				    filename, linenum, keyword);
   1941 		}
   1942 		if (*activep && options->rekey_limit == -1)
   1943 			options->rekey_limit = val64;
   1944 		if (ac != 0) { /* optional rekey interval present */
   1945 			if (strcmp(av[0], "none") == 0) {
   1946 				(void)argv_next(&ac, &av);	/* discard */
   1947 				break;
   1948 			}
   1949 			intptr = &options->rekey_interval;
   1950 			goto parse_time;
   1951 		}
   1952 		break;
   1953 
   1954 	case sGatewayPorts:
   1955 		intptr = &options->fwd_opts.gateway_ports;
   1956 		multistate_ptr = multistate_gatewayports;
   1957 		goto parse_multistate;
   1958 
   1959 	case sUseDNS:
   1960 		intptr = &options->use_dns;
   1961 		goto parse_flag;
   1962 
   1963 	case sLogFacility:
   1964 		log_facility_ptr = &options->log_facility;
   1965 		arg = argv_next(&ac, &av);
   1966 		value = log_facility_number(arg);
   1967 		if (value == SYSLOG_FACILITY_NOT_SET)
   1968 			fatal("%.200s line %d: unsupported log facility '%s'",
   1969 			    filename, linenum, arg ? arg : "<NONE>");
   1970 		if (*log_facility_ptr == -1)
   1971 			*log_facility_ptr = (SyslogFacility) value;
   1972 		break;
   1973 
   1974 	case sLogLevel:
   1975 		log_level_ptr = &options->log_level;
   1976 		arg = argv_next(&ac, &av);
   1977 		value = log_level_number(arg);
   1978 		if (value == SYSLOG_LEVEL_NOT_SET)
   1979 			fatal("%.200s line %d: unsupported log level '%s'",
   1980 			    filename, linenum, arg ? arg : "<NONE>");
   1981 		if (*activep && *log_level_ptr == -1)
   1982 			*log_level_ptr = (LogLevel) value;
   1983 		break;
   1984 
   1985 	case sLogVerbose:
   1986 		found = options->num_log_verbose == 0;
   1987 		while ((arg = argv_next(&ac, &av)) != NULL) {
   1988 			if (*arg == '\0') {
   1989 				error("%s line %d: keyword %s empty argument",
   1990 				    filename, linenum, keyword);
   1991 				goto out;
   1992 			}
   1993 			/* Allow "none" only in first position */
   1994 			if (strcasecmp(arg, "none") == 0) {
   1995 				if (nstrs > 0 || ac > 0) {
   1996 					error("%s line %d: keyword %s \"none\" "
   1997 					    "argument must appear alone.",
   1998 					    filename, linenum, keyword);
   1999 					goto out;
   2000 				}
   2001 			}
   2002 			opt_array_append(filename, linenum, keyword,
   2003 			    &strs, &nstrs, arg);
   2004 		}
   2005 		if (nstrs == 0) {
   2006 			fatal("%s line %d: no %s specified",
   2007 			    filename, linenum, keyword);
   2008 		}
   2009 		if (found && *activep) {
   2010 			options->log_verbose = strs;
   2011 			options->num_log_verbose = nstrs;
   2012 			strs = NULL; /* transferred */
   2013 			nstrs = 0;
   2014 		}
   2015 		break;
   2016 
   2017 	case sAllowTcpForwarding:
   2018 		intptr = &options->allow_tcp_forwarding;
   2019 		multistate_ptr = multistate_tcpfwd;
   2020 		goto parse_multistate;
   2021 
   2022 	case sAllowStreamLocalForwarding:
   2023 		intptr = &options->allow_streamlocal_forwarding;
   2024 		multistate_ptr = multistate_tcpfwd;
   2025 		goto parse_multistate;
   2026 
   2027 	case sAllowAgentForwarding:
   2028 		intptr = &options->allow_agent_forwarding;
   2029 		goto parse_flag;
   2030 
   2031 	case sDisableForwarding:
   2032 		intptr = &options->disable_forwarding;
   2033 		goto parse_flag;
   2034 
   2035 	case sAllowUsers:
   2036 		chararrayptr = &options->allow_users;
   2037 		uintptr = &options->num_allow_users;
   2038  parse_allowdenyusers:
   2039 		/* XXX appends to list; doesn't respect first-match-wins */
   2040 		while ((arg = argv_next(&ac, &av)) != NULL) {
   2041 			if (*arg == '\0' ||
   2042 			    match_user(NULL, NULL, NULL, arg) == -1)
   2043 				fatal("%s line %d: invalid %s pattern: \"%s\"",
   2044 				    filename, linenum, keyword, arg);
   2045 			found = 1;
   2046 			if (!*activep)
   2047 				continue;
   2048 			opt_array_append(filename, linenum, keyword,
   2049 			    chararrayptr, uintptr, arg);
   2050 		}
   2051 		if (!found) {
   2052 			fatal("%s line %d: no %s specified",
   2053 			    filename, linenum, keyword);
   2054 		}
   2055 		break;
   2056 
   2057 	case sDenyUsers:
   2058 		chararrayptr = &options->deny_users;
   2059 		uintptr = &options->num_deny_users;
   2060 		goto parse_allowdenyusers;
   2061 
   2062 	case sAllowGroups:
   2063 		chararrayptr = &options->allow_groups;
   2064 		uintptr = &options->num_allow_groups;
   2065 		/* XXX appends to list; doesn't respect first-match-wins */
   2066  parse_allowdenygroups:
   2067 		while ((arg = argv_next(&ac, &av)) != NULL) {
   2068 			if (*arg == '\0')
   2069 				fatal("%s line %d: empty %s pattern",
   2070 				    filename, linenum, keyword);
   2071 			found = 1;
   2072 			if (!*activep)
   2073 				continue;
   2074 			opt_array_append(filename, linenum, keyword,
   2075 			    chararrayptr, uintptr, arg);
   2076 		}
   2077 		if (!found) {
   2078 			fatal("%s line %d: no %s specified",
   2079 			    filename, linenum, keyword);
   2080 		}
   2081 		break;
   2082 
   2083 	case sDenyGroups:
   2084 		chararrayptr = &options->deny_groups;
   2085 		uintptr = &options->num_deny_groups;
   2086 		goto parse_allowdenygroups;
   2087 
   2088 	case sCiphers:
   2089 		arg = argv_next(&ac, &av);
   2090 		if (!arg || *arg == '\0')
   2091 			fatal("%s line %d: %s missing argument.",
   2092 			    filename, linenum, keyword);
   2093 		if (*arg != '-' &&
   2094 		    !ciphers_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg))
   2095 			fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
   2096 			    filename, linenum, arg ? arg : "<NONE>");
   2097 		if (options->ciphers == NULL)
   2098 			options->ciphers = xstrdup(arg);
   2099 		break;
   2100 
   2101 	case sMacs:
   2102 		arg = argv_next(&ac, &av);
   2103 		if (!arg || *arg == '\0')
   2104 			fatal("%s line %d: %s missing argument.",
   2105 			    filename, linenum, keyword);
   2106 		if (*arg != '-' &&
   2107 		    !mac_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg))
   2108 			fatal("%s line %d: Bad SSH2 mac spec '%s'.",
   2109 			    filename, linenum, arg ? arg : "<NONE>");
   2110 		if (options->macs == NULL)
   2111 			options->macs = xstrdup(arg);
   2112 		break;
   2113 
   2114 	case sKexAlgorithms:
   2115 		arg = argv_next(&ac, &av);
   2116 		if (!arg || *arg == '\0')
   2117 			fatal("%s line %d: %s missing argument.",
   2118 			    filename, linenum, keyword);
   2119 		if (*arg != '-' &&
   2120 		    !kex_names_valid(*arg == '+' || *arg == '^' ?
   2121 		    arg + 1 : arg))
   2122 			fatal("%s line %d: Bad SSH2 KexAlgorithms '%s'.",
   2123 			    filename, linenum, arg ? arg : "<NONE>");
   2124 		if (options->kex_algorithms == NULL)
   2125 			options->kex_algorithms = xstrdup(arg);
   2126 		break;
   2127 
   2128 	case sSubsystem:
   2129 		if ((arg = argv_next(&ac, &av)) == NULL || *arg == '\0' ||
   2130 		   ((arg2 = argv_next(&ac, &av)) == NULL || *arg2 == '\0'))
   2131 			fatal("%s line %d: %s missing argument.",
   2132 			    filename, linenum, keyword);
   2133 		if (!*activep) {
   2134 			argv_consume(&ac);
   2135 			break;
   2136 		}
   2137 		found = 0;
   2138 		for (i = 0; i < options->num_subsystems; i++) {
   2139 			if (strcmp(arg, options->subsystem_name[i]) == 0) {
   2140 				found = 1;
   2141 				break;
   2142 			}
   2143 		}
   2144 		if (found) {
   2145 			debug("%s line %d: Subsystem '%s' already defined.",
   2146 			    filename, linenum, arg);
   2147 			argv_consume(&ac);
   2148 			break;
   2149 		}
   2150 		options->subsystem_name = xrecallocarray(
   2151 		    options->subsystem_name, options->num_subsystems,
   2152 		    options->num_subsystems + 1,
   2153 		    sizeof(*options->subsystem_name));
   2154 		options->subsystem_command = xrecallocarray(
   2155 		    options->subsystem_command, options->num_subsystems,
   2156 		    options->num_subsystems + 1,
   2157 		    sizeof(*options->subsystem_command));
   2158 		options->subsystem_args = xrecallocarray(
   2159 		    options->subsystem_args, options->num_subsystems,
   2160 		    options->num_subsystems + 1,
   2161 		    sizeof(*options->subsystem_args));
   2162 		options->subsystem_name[options->num_subsystems] = xstrdup(arg);
   2163 		options->subsystem_command[options->num_subsystems] =
   2164 		    xstrdup(arg2);
   2165 		/* Collect arguments (separate to executable) */
   2166 		arg = argv_assemble(1, &arg2); /* quote command correctly */
   2167 		arg2 = argv_assemble(ac, av); /* rest of command */
   2168 		xasprintf(&options->subsystem_args[options->num_subsystems],
   2169 		    "%s%s%s", arg, *arg2 == '\0' ? "" : " ", arg2);
   2170 		free(arg2);
   2171 		free(arg);
   2172 		argv_consume(&ac);
   2173 		options->num_subsystems++;
   2174 		break;
   2175 
   2176 	case sMaxStartups:
   2177 		arg = argv_next(&ac, &av);
   2178 		if (!arg || *arg == '\0')
   2179 			fatal("%s line %d: %s missing argument.",
   2180 			    filename, linenum, keyword);
   2181 		/* begin:rate:max */
   2182 		if ((n = sscanf(arg, "%d:%d:%d",
   2183 		    &value, &value2, &value3)) == 3) {
   2184 			if (value > value3 || value2 > 100 || value2 < 1)
   2185 				fatal("%s line %d: Invalid %s spec.",
   2186 				    filename, linenum, keyword);
   2187 		} else if (n == 1) {
   2188 			value3 = value;
   2189 			value2 = -1;
   2190 		} else {
   2191 			fatal("%s line %d: Invalid %s spec.",
   2192 			    filename, linenum, keyword);
   2193 		}
   2194 		if (value <= 0 || value3 <= 0)
   2195 			fatal("%s line %d: Invalid %s spec.",
   2196 			    filename, linenum, keyword);
   2197 		if (*activep && options->max_startups == -1) {
   2198 			options->max_startups_begin = value;
   2199 			options->max_startups_rate = value2;
   2200 			options->max_startups = value3;
   2201 		}
   2202 		break;
   2203 
   2204 	case sPerSourceNetBlockSize:
   2205 		arg = argv_next(&ac, &av);
   2206 		if (!arg || *arg == '\0')
   2207 			fatal("%s line %d: %s missing argument.",
   2208 			    filename, linenum, keyword);
   2209 		switch (n = sscanf(arg, "%d:%d", &value, &value2)) {
   2210 		case 2:
   2211 			if (value2 < 0 || value2 > 128)
   2212 				n = -1;
   2213 			/* FALLTHROUGH */
   2214 		case 1:
   2215 			if (value < 0 || value > 32)
   2216 				n = -1;
   2217 		}
   2218 		if (n != 1 && n != 2)
   2219 			fatal("%s line %d: Invalid %s spec.",
   2220 			    filename, linenum, keyword);
   2221 		if (*activep && options->per_source_masklen_ipv4 == -1) {
   2222 			options->per_source_masklen_ipv4 = value;
   2223 			if (n == 2)
   2224 				options->per_source_masklen_ipv6 = value2;
   2225 		}
   2226 		break;
   2227 
   2228 	case sPerSourceMaxStartups:
   2229 		arg = argv_next(&ac, &av);
   2230 		if (!arg || *arg == '\0')
   2231 			fatal("%s line %d: %s missing argument.",
   2232 			    filename, linenum, keyword);
   2233 		if (strcmp(arg, "none") == 0) { /* no limit */
   2234 			value = INT_MAX;
   2235 		} else {
   2236 			if ((errstr = atoi_err(arg, &value)) != NULL)
   2237 				fatal("%s line %d: %s integer value %s.",
   2238 				    filename, linenum, keyword, errstr);
   2239 		}
   2240 		if (*activep && options->per_source_max_startups == -1)
   2241 			options->per_source_max_startups = value;
   2242 		break;
   2243 
   2244 	case sPerSourcePenaltyExemptList:
   2245 		charptr = &options->per_source_penalty_exempt;
   2246 		arg = argv_next(&ac, &av);
   2247 		if (!arg || *arg == '\0')
   2248 			fatal("%s line %d: missing argument.",
   2249 			    filename, linenum);
   2250 		if (addr_match_list(NULL, arg) != 0) {
   2251 			fatal("%s line %d: keyword %s "
   2252 			    "invalid address argument.",
   2253 			    filename, linenum, keyword);
   2254 		}
   2255 		if (*activep && *charptr == NULL)
   2256 			*charptr = xstrdup(arg);
   2257 		break;
   2258 
   2259 	case sPerSourcePenalties:
   2260 		while ((arg = argv_next(&ac, &av)) != NULL) {
   2261 			const char *q = NULL;
   2262 
   2263 			found = 1;
   2264 			intptr = NULL;
   2265 			doubleptr = NULL;
   2266 			value = -1;
   2267 			value2 = 0;
   2268 			/* Allow no/yes only in first position */
   2269 			if (strcasecmp(arg, "no") == 0 ||
   2270 			    (value2 = (strcasecmp(arg, "yes") == 0))) {
   2271 				if (ac > 0) {
   2272 					fatal("%s line %d: keyword %s \"%s\" "
   2273 					    "argument must appear alone.",
   2274 					    filename, linenum, keyword, arg);
   2275 				}
   2276 				if (*activep &&
   2277 				    options->per_source_penalty.enabled == -1)
   2278 					options->per_source_penalty.enabled = value2;
   2279 				continue;
   2280 			} else if ((q = strprefix(arg, "crash:", 0)) != NULL) {
   2281 				doubleptr = &options->per_source_penalty.penalty_crash;
   2282 			} else if ((q = strprefix(arg, "authfail:", 0)) != NULL) {
   2283 				doubleptr = &options->per_source_penalty.penalty_authfail;
   2284 			} else if ((q = strprefix(arg, "invaliduser:", 0)) != NULL) {
   2285 				doubleptr = &options->per_source_penalty.penalty_invaliduser;
   2286 			} else if ((q = strprefix(arg, "noauth:", 0)) != NULL) {
   2287 				doubleptr = &options->per_source_penalty.penalty_noauth;
   2288 			} else if ((q = strprefix(arg, "grace-exceeded:", 0)) != NULL) {
   2289 				doubleptr = &options->per_source_penalty.penalty_grace;
   2290 			} else if ((q = strprefix(arg, "refuseconnection:", 0)) != NULL) {
   2291 				doubleptr = &options->per_source_penalty.penalty_refuseconnection;
   2292 			} else if ((q = strprefix(arg, "max:", 0)) != NULL) {
   2293 				doubleptr = &options->per_source_penalty.penalty_max;
   2294 			} else if ((q = strprefix(arg, "min:", 0)) != NULL) {
   2295 				doubleptr = &options->per_source_penalty.penalty_min;
   2296 			} else if ((q = strprefix(arg, "max-sources4:", 0)) != NULL) {
   2297 				intptr = &options->per_source_penalty.max_sources4;
   2298 				if ((errstr = atoi_err(q, &value)) != NULL)
   2299 					fatal("%s line %d: %s value %s.",
   2300 					    filename, linenum, keyword, errstr);
   2301 			} else if ((q = strprefix(arg, "max-sources6:", 0)) != NULL) {
   2302 				intptr = &options->per_source_penalty.max_sources6;
   2303 				if ((errstr = atoi_err(q, &value)) != NULL)
   2304 					fatal("%s line %d: %s value %s.",
   2305 					    filename, linenum, keyword, errstr);
   2306 			} else if (strcmp(arg, "overflow:deny-all") == 0) {
   2307 				intptr = &options->per_source_penalty.overflow_mode;
   2308 				value = PER_SOURCE_PENALTY_OVERFLOW_DENY_ALL;
   2309 			} else if (strcmp(arg, "overflow:permissive") == 0) {
   2310 				intptr = &options->per_source_penalty.overflow_mode;
   2311 				value = PER_SOURCE_PENALTY_OVERFLOW_PERMISSIVE;
   2312 			} else if (strcmp(arg, "overflow6:deny-all") == 0) {
   2313 				intptr = &options->per_source_penalty.overflow_mode6;
   2314 				value = PER_SOURCE_PENALTY_OVERFLOW_DENY_ALL;
   2315 			} else if (strcmp(arg, "overflow6:permissive") == 0) {
   2316 				intptr = &options->per_source_penalty.overflow_mode6;
   2317 				value = PER_SOURCE_PENALTY_OVERFLOW_PERMISSIVE;
   2318 			} else {
   2319 				fatal("%s line %d: unsupported %s keyword %s",
   2320 				    filename, linenum, keyword, arg);
   2321 			}
   2322 
   2323 			if (doubleptr != NULL) {
   2324 				if ((dvalue = convtime_double(q)) < 0) {
   2325 					fatal("%s line %d: invalid %s time value.",
   2326 					    filename, linenum, keyword);
   2327 				}
   2328 				if (*activep && *doubleptr < 0.0) {
   2329 					*doubleptr = dvalue;
   2330 					options->per_source_penalty.enabled = 1;
   2331 				}
   2332 			} else if (intptr != NULL) {
   2333 				if (*activep && *intptr == -1) {
   2334 					*intptr = value;
   2335 					options->per_source_penalty.enabled = 1;
   2336 				}
   2337 			} else {
   2338 				fatal_f("%s line %d: internal error",
   2339 				    filename, linenum);
   2340 			}
   2341 		}
   2342 		if (!found) {
   2343 			fatal("%s line %d: no %s specified",
   2344 			    filename, linenum, keyword);
   2345 		}
   2346 		break;
   2347 
   2348 	case sMaxAuthTries:
   2349 		intptr = &options->max_authtries;
   2350 		goto parse_int;
   2351 
   2352 	case sMaxSessions:
   2353 		intptr = &options->max_sessions;
   2354 		goto parse_int;
   2355 
   2356 	case sBanner:
   2357 		charptr = &options->banner;
   2358 		goto parse_filename;
   2359 
   2360 	/*
   2361 	 * These options can contain %X options expanded at
   2362 	 * connect time, so that you can specify paths like:
   2363 	 *
   2364 	 * AuthorizedKeysFile	/etc/ssh_keys/%u
   2365 	 */
   2366 	case sAuthorizedKeysFile:
   2367 		uintptr = &options->num_authkeys_files;
   2368 		chararrayptr = &options->authorized_keys_files;
   2369  parse_filenames:
   2370 		found = *uintptr == 0;
   2371 		while ((arg = argv_next(&ac, &av)) != NULL) {
   2372 			if (*arg == '\0') {
   2373 				error("%s line %d: keyword %s empty argument",
   2374 				    filename, linenum, keyword);
   2375 				goto out;
   2376 			}
   2377 			/* Allow "none" only in first position */
   2378 			if (strcasecmp(arg, "none") == 0) {
   2379 				if (nstrs > 0 || ac > 0) {
   2380 					error("%s line %d: keyword %s \"none\" "
   2381 					    "argument must appear alone.",
   2382 					    filename, linenum, keyword);
   2383 					goto out;
   2384 				}
   2385 			}
   2386 			arg2 = tilde_expand_filename(arg, getuid());
   2387 			opt_array_append(filename, linenum, keyword,
   2388 			    &strs, &nstrs, arg2);
   2389 			free(arg2);
   2390 		}
   2391 		if (nstrs == 0) {
   2392 			fatal("%s line %d: no %s specified",
   2393 			    filename, linenum, keyword);
   2394 		}
   2395 		if (found && *activep) {
   2396 			*chararrayptr = strs;
   2397 			*uintptr = nstrs;
   2398 			strs = NULL; /* transferred */
   2399 			nstrs = 0;
   2400 		}
   2401 		break;
   2402 
   2403 	case sAuthorizedPrincipalsFile:
   2404 		charptr = &options->authorized_principals_file;
   2405 		arg = argv_next(&ac, &av);
   2406 		if (!arg || *arg == '\0')
   2407 			fatal("%s line %d: %s missing argument.",
   2408 			    filename, linenum, keyword);
   2409 		if (*activep && *charptr == NULL) {
   2410 			*charptr = tilde_expand_filename(arg, getuid());
   2411 			/* increase optional counter */
   2412 			if (intptr != NULL)
   2413 				*intptr = *intptr + 1;
   2414 		}
   2415 		break;
   2416 
   2417 	case sClientAliveInterval:
   2418 		intptr = &options->client_alive_interval;
   2419 		goto parse_time;
   2420 
   2421 	case sClientAliveCountMax:
   2422 		intptr = &options->client_alive_count_max;
   2423 		goto parse_int;
   2424 
   2425 	case sAcceptEnv:
   2426 		/* XXX appends to list; doesn't respect first-match-wins */
   2427 		while ((arg = argv_next(&ac, &av)) != NULL) {
   2428 			if (*arg == '\0' || strchr(arg, '=') != NULL)
   2429 				fatal("%s line %d: Invalid environment name.",
   2430 				    filename, linenum);
   2431 			found = 1;
   2432 			if (!*activep)
   2433 				continue;
   2434 			opt_array_append(filename, linenum, keyword,
   2435 			    &options->accept_env, &options->num_accept_env,
   2436 			    arg);
   2437 		}
   2438 		if (!found) {
   2439 			fatal("%s line %d: no %s specified",
   2440 			    filename, linenum, keyword);
   2441 		}
   2442 		break;
   2443 
   2444 	case sSetEnv:
   2445 		found = options->num_setenv == 0;
   2446 		while ((arg = argv_next(&ac, &av)) != NULL) {
   2447 			if (*arg == '\0' || strchr(arg, '=') == NULL)
   2448 				fatal("%s line %d: Invalid environment.",
   2449 				    filename, linenum);
   2450 			if (lookup_setenv_in_list(arg, strs, nstrs) != NULL) {
   2451 				debug2("%s line %d: ignoring duplicate env "
   2452 				    "name \"%.64s\"", filename, linenum, arg);
   2453 				continue;
   2454 			}
   2455 			opt_array_append(filename, linenum, keyword,
   2456 			    &strs, &nstrs, arg);
   2457 		}
   2458 		if (nstrs == 0) {
   2459 			fatal("%s line %d: no %s specified",
   2460 			    filename, linenum, keyword);
   2461 		}
   2462 		if (found && *activep) {
   2463 			options->setenv = strs;
   2464 			options->num_setenv = nstrs;
   2465 			strs = NULL; /* transferred */
   2466 			nstrs = 0;
   2467 		}
   2468 		break;
   2469 
   2470 	case sPermitTunnel:
   2471 		intptr = &options->permit_tun;
   2472 		arg = argv_next(&ac, &av);
   2473 		if (!arg || *arg == '\0')
   2474 			fatal("%s line %d: %s missing argument.",
   2475 			    filename, linenum, keyword);
   2476 		value = -1;
   2477 		for (i = 0; tunmode_desc[i].val != -1; i++)
   2478 			if (strcmp(tunmode_desc[i].text, arg) == 0) {
   2479 				value = tunmode_desc[i].val;
   2480 				break;
   2481 			}
   2482 		if (value == -1)
   2483 			fatal("%s line %d: bad %s argument %s",
   2484 			    filename, linenum, keyword, arg);
   2485 		if (*activep && *intptr == -1)
   2486 			*intptr = value;
   2487 		break;
   2488 
   2489 	case sInclude:
   2490 		if (cmdline) {
   2491 			fatal("Include directive not supported as a "
   2492 			    "command-line option");
   2493 		}
   2494 		value = 0;
   2495 		while ((arg2 = argv_next(&ac, &av)) != NULL) {
   2496 			if (*arg2 == '\0') {
   2497 				error("%s line %d: keyword %s empty argument",
   2498 				    filename, linenum, keyword);
   2499 				goto out;
   2500 			}
   2501 			value++;
   2502 			found = 0;
   2503 			if (*arg2 != '/' && *arg2 != '~') {
   2504 				xasprintf(&arg, "%s/%s", SSHDIR, arg2);
   2505 			} else
   2506 				arg = xstrdup(arg2);
   2507 
   2508 			/*
   2509 			 * Don't let included files clobber the containing
   2510 			 * file's Match state.
   2511 			 */
   2512 			oactive = *activep;
   2513 
   2514 			/* consult cache of include files */
   2515 			TAILQ_FOREACH(item, includes, entry) {
   2516 				if (strcmp(item->selector, arg) != 0)
   2517 					continue;
   2518 				if (item->filename != NULL) {
   2519 					parse_server_config_depth(options,
   2520 					    item->filename, item->contents,
   2521 					    includes, connectinfo,
   2522 					    (*inc_flags & SSHCFG_MATCH_ONLY
   2523 					        ? SSHCFG_MATCH_ONLY : (oactive
   2524 					            ? 0 : SSHCFG_NEVERMATCH)),
   2525 					    activep, depth + 1);
   2526 				}
   2527 				found = 1;
   2528 				*activep = oactive;
   2529 			}
   2530 			if (found != 0) {
   2531 				free(arg);
   2532 				continue;
   2533 			}
   2534 
   2535 			/* requested glob was not in cache */
   2536 			debug2("%s line %d: new include %s",
   2537 			    filename, linenum, arg);
   2538 			if ((r = glob(arg, 0, NULL, &gbuf)) != 0) {
   2539 				if (r != GLOB_NOMATCH) {
   2540 					fatal("%s line %d: include \"%s\" glob "
   2541 					    "failed", filename, linenum, arg);
   2542 				}
   2543 				/*
   2544 				 * If no entry matched then record a
   2545 				 * placeholder to skip later glob calls.
   2546 				 */
   2547 				debug2("%s line %d: no match for %s",
   2548 				    filename, linenum, arg);
   2549 				item = xcalloc(1, sizeof(*item));
   2550 				item->selector = strdup(arg);
   2551 				TAILQ_INSERT_TAIL(includes,
   2552 				    item, entry);
   2553 			}
   2554 			if (gbuf.gl_pathc > INT_MAX)
   2555 				fatal_f("too many glob results");
   2556 			for (n = 0; n < (int)gbuf.gl_pathc; n++) {
   2557 				debug2("%s line %d: including %s",
   2558 				    filename, linenum, gbuf.gl_pathv[n]);
   2559 				item = xcalloc(1, sizeof(*item));
   2560 				item->selector = strdup(arg);
   2561 				item->filename = strdup(gbuf.gl_pathv[n]);
   2562 				if ((item->contents = sshbuf_new()) == NULL)
   2563 					fatal_f("sshbuf_new failed");
   2564 				load_server_config(item->filename,
   2565 				    item->contents);
   2566 				parse_server_config_depth(options,
   2567 				    item->filename, item->contents,
   2568 				    includes, connectinfo,
   2569 				    (*inc_flags & SSHCFG_MATCH_ONLY
   2570 				        ? SSHCFG_MATCH_ONLY : (oactive
   2571 				            ? 0 : SSHCFG_NEVERMATCH)),
   2572 				    activep, depth + 1);
   2573 				*activep = oactive;
   2574 				TAILQ_INSERT_TAIL(includes, item, entry);
   2575 			}
   2576 			globfree(&gbuf);
   2577 			free(arg);
   2578 		}
   2579 		if (value == 0) {
   2580 			fatal("%s line %d: %s missing filename argument",
   2581 			    filename, linenum, keyword);
   2582 		}
   2583 		break;
   2584 
   2585 	case sMatch:
   2586 		if (cmdline)
   2587 			fatal("Match directive not supported as a command-line "
   2588 			    "option");
   2589 		value = match_cfg_line(str, &ac, &av, linenum,
   2590 		    (*inc_flags & SSHCFG_NEVERMATCH ? NULL : connectinfo));
   2591 		if (value < 0)
   2592 			fatal("%s line %d: Bad Match condition", filename,
   2593 			    linenum);
   2594 		*activep = (*inc_flags & SSHCFG_NEVERMATCH) ? 0 : value;
   2595 		/*
   2596 		 * The MATCH_ONLY flag is applicable only until the first
   2597 		 * match block.
   2598 		 */
   2599 		*inc_flags &= ~SSHCFG_MATCH_ONLY;
   2600 		break;
   2601 
   2602 	case sPermitListen:
   2603 	case sPermitOpen:
   2604 		if (opcode == sPermitListen) {
   2605 			uintptr = &options->num_permitted_listens;
   2606 			chararrayptr = &options->permitted_listens;
   2607 		} else {
   2608 			uintptr = &options->num_permitted_opens;
   2609 			chararrayptr = &options->permitted_opens;
   2610 		}
   2611 		found = *uintptr == 0;
   2612 		while ((arg = argv_next(&ac, &av)) != NULL) {
   2613 			if (strcmp(arg, "any") == 0 ||
   2614 			    strcmp(arg, "none") == 0) {
   2615 				if (nstrs != 0) {
   2616 					fatal("%s line %d: %s must appear "
   2617 					    "alone on a %s line.",
   2618 					    filename, linenum, arg, keyword);
   2619 				}
   2620 				opt_array_append(filename, linenum, keyword,
   2621 				    &strs, &nstrs, arg);
   2622 				continue;
   2623 			}
   2624 
   2625 			if (opcode == sPermitListen &&
   2626 			    strchr(arg, ':') == NULL) {
   2627 				/*
   2628 				 * Allow bare port number for PermitListen
   2629 				 * to indicate a wildcard listen host.
   2630 				 */
   2631 				xasprintf(&arg2, "*:%s", arg);
   2632 			} else {
   2633 				arg2 = xstrdup(arg);
   2634 				p = hpdelim(&arg);
   2635 				if (p == NULL) {
   2636 					fatal("%s line %d: %s missing host",
   2637 					    filename, linenum, keyword);
   2638 				}
   2639 				p = cleanhostname(p);
   2640 			}
   2641 			if (arg == NULL ||
   2642 			    ((port = permitopen_port(arg)) < 0)) {
   2643 				fatal("%s line %d: %s bad port number",
   2644 				    filename, linenum, keyword);
   2645 			}
   2646 			opt_array_append(filename, linenum, keyword,
   2647 			    &strs, &nstrs, arg2);
   2648 			free(arg2);
   2649 		}
   2650 		if (nstrs == 0) {
   2651 			fatal("%s line %d: %s missing argument.",
   2652 			    filename, linenum, keyword);
   2653 		}
   2654 		if (found && *activep) {
   2655 			*chararrayptr = strs;
   2656 			*uintptr = nstrs;
   2657 			strs = NULL; /* transferred */
   2658 			nstrs = 0;
   2659 		}
   2660 		break;
   2661 
   2662 	case sForceCommand:
   2663 		if (str == NULL || *str == '\0')
   2664 			fatal("%s line %d: %s missing argument.",
   2665 			    filename, linenum, keyword);
   2666 		len = strspn(str, WHITESPACE);
   2667 		if (*activep && options->adm_forced_command == NULL)
   2668 			options->adm_forced_command = xstrdup(str + len);
   2669 		argv_consume(&ac);
   2670 		break;
   2671 
   2672 	case sChrootDirectory:
   2673 		charptr = &options->chroot_directory;
   2674 
   2675 		arg = argv_next(&ac, &av);
   2676 		if (!arg || *arg == '\0')
   2677 			fatal("%s line %d: %s missing argument.",
   2678 			    filename, linenum, keyword);
   2679 		if (*activep && *charptr == NULL)
   2680 			*charptr = xstrdup(arg);
   2681 		break;
   2682 
   2683 	case sTrustedUserCAKeys:
   2684 		charptr = &options->trusted_user_ca_keys;
   2685 		goto parse_filename;
   2686 
   2687 	case sRevokedKeys:
   2688 		uintptr = &options->num_revoked_keys_files;
   2689 		chararrayptr = &options->revoked_keys_files;
   2690 		goto parse_filenames;
   2691 
   2692 	case sSecurityKeyProvider:
   2693 		charptr = &options->sk_provider;
   2694 		arg = argv_next(&ac, &av);
   2695 		if (!arg || *arg == '\0')
   2696 			fatal("%s line %d: %s missing argument.",
   2697 			    filename, linenum, keyword);
   2698 		if (*activep && *charptr == NULL) {
   2699 			*charptr = strcasecmp(arg, "internal") == 0 ?
   2700 			    xstrdup(arg) : derelativise_path(arg);
   2701 			/* increase optional counter */
   2702 			if (intptr != NULL)
   2703 				*intptr = *intptr + 1;
   2704 		}
   2705 		break;
   2706 
   2707 	case sIPQoS:
   2708 		arg = argv_next(&ac, &av);
   2709 		if (!arg || *arg == '\0')
   2710 			fatal("%s line %d: %s missing argument.",
   2711 			    filename, linenum, keyword);
   2712 		if ((value = parse_ipqos(arg)) == -1)
   2713 			fatal("%s line %d: Bad %s value: %s",
   2714 			    filename, linenum, keyword, arg);
   2715 		if (value == INT_MIN) {
   2716 			debug("%s line %d: Deprecated IPQoS value \"%s\" "
   2717 			    "ignored - using system default instead. Consider"
   2718 			    " using DSCP values.", filename, linenum, arg);
   2719 			value = INT_MAX;
   2720 		}
   2721 		arg = argv_next(&ac, &av);
   2722 		if (arg == NULL)
   2723 			value2 = value;
   2724 		else if ((value2 = parse_ipqos(arg)) == -1)
   2725 			fatal("%s line %d: Bad %s value: %s",
   2726 			    filename, linenum, keyword, arg);
   2727 		if (value2 == INT_MIN) {
   2728 			debug("%s line %d: Deprecated IPQoS value \"%s\" "
   2729 			    "ignored - using system default instead. Consider"
   2730 			    " using DSCP values.", filename, linenum, arg);
   2731 			value2 = INT_MAX;
   2732 		}
   2733 		if (*activep && options->ip_qos_interactive == -1) {
   2734 			options->ip_qos_interactive = value;
   2735 			options->ip_qos_bulk = value2;
   2736 		}
   2737 		break;
   2738 
   2739 	case sVersionAddendum:
   2740 		if (str == NULL || *str == '\0')
   2741 			fatal("%s line %d: %s missing argument.",
   2742 			    filename, linenum, keyword);
   2743 		len = strspn(str, WHITESPACE);
   2744 		if (strchr(str + len, '\r') != NULL) {
   2745 			fatal("%.200s line %d: Invalid %s argument",
   2746 			    filename, linenum, keyword);
   2747 		}
   2748 		if ((arg = strchr(line, '#')) != NULL) {
   2749 			*arg = '\0';
   2750 			rtrim(line);
   2751 		}
   2752 		if (*activep && options->version_addendum == NULL) {
   2753 			if (strcasecmp(str + len, "none") == 0)
   2754 				options->version_addendum = xstrdup("");
   2755 			else
   2756 				options->version_addendum = xstrdup(str + len);
   2757 		}
   2758 		argv_consume(&ac);
   2759 		break;
   2760 
   2761 	case sAuthorizedKeysCommand:
   2762 		charptr = &options->authorized_keys_command;
   2763  parse_command:
   2764 		len = strspn(str, WHITESPACE);
   2765 		if (str[len] != '/' && strcasecmp(str + len, "none") != 0) {
   2766 			fatal("%.200s line %d: %s must be an absolute path",
   2767 			    filename, linenum, keyword);
   2768 		}
   2769 		if (*activep && *charptr == NULL)
   2770 			*charptr = xstrdup(str + len);
   2771 		argv_consume(&ac);
   2772 		break;
   2773 
   2774 	case sAuthorizedKeysCommandUser:
   2775 		charptr = &options->authorized_keys_command_user;
   2776  parse_localuser:
   2777 		arg = argv_next(&ac, &av);
   2778 		if (!arg || *arg == '\0') {
   2779 			fatal("%s line %d: missing %s argument.",
   2780 			    filename, linenum, keyword);
   2781 		}
   2782 		if (*activep && *charptr == NULL)
   2783 			*charptr = xstrdup(arg);
   2784 		break;
   2785 
   2786 	case sAuthorizedPrincipalsCommand:
   2787 		charptr = &options->authorized_principals_command;
   2788 		goto parse_command;
   2789 
   2790 	case sAuthorizedPrincipalsCommandUser:
   2791 		charptr = &options->authorized_principals_command_user;
   2792 		goto parse_localuser;
   2793 
   2794 	case sAuthenticationMethods:
   2795 		found = options->num_auth_methods == 0;
   2796 		value = 0; /* seen "any" pseudo-method */
   2797 		while ((arg = argv_next(&ac, &av)) != NULL) {
   2798 			if (strcmp(arg, "any") == 0) {
   2799 				if (nstrs > 0) {
   2800 					fatal("%s line %d: \"any\" must "
   2801 					    "appear alone in %s",
   2802 					    filename, linenum, keyword);
   2803 				}
   2804 				value = 1;
   2805 			} else if (value) {
   2806 				fatal("%s line %d: \"any\" must appear "
   2807 				    "alone in %s", filename, linenum, keyword);
   2808 			} else if (auth2_methods_valid(arg, 0) != 0) {
   2809 				fatal("%s line %d: invalid %s method list.",
   2810 				    filename, linenum, keyword);
   2811 			}
   2812 			opt_array_append(filename, linenum, keyword,
   2813 			    &strs, &nstrs, arg);
   2814 		}
   2815 		if (nstrs == 0) {
   2816 			fatal("%s line %d: no %s specified",
   2817 			    filename, linenum, keyword);
   2818 		}
   2819 		if (found && *activep) {
   2820 			options->auth_methods = strs;
   2821 			options->num_auth_methods = nstrs;
   2822 			strs = NULL; /* transferred */
   2823 			nstrs = 0;
   2824 		}
   2825 		break;
   2826 
   2827 	case sStreamLocalBindMask:
   2828 		arg = argv_next(&ac, &av);
   2829 		if (!arg || *arg == '\0')
   2830 			fatal("%s line %d: %s missing argument.",
   2831 			    filename, linenum, keyword);
   2832 		/* Parse mode in octal format */
   2833 		value = strtol(arg, &p, 8);
   2834 		if (arg == p || value < 0 || value > 0777)
   2835 			fatal("%s line %d: Invalid %s.",
   2836 			    filename, linenum, keyword);
   2837 		if (*activep)
   2838 			options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
   2839 		break;
   2840 
   2841 	case sStreamLocalBindUnlink:
   2842 		intptr = &options->fwd_opts.streamlocal_bind_unlink;
   2843 		goto parse_flag;
   2844 
   2845 	case sFingerprintHash:
   2846 		arg = argv_next(&ac, &av);
   2847 		if (!arg || *arg == '\0')
   2848 			fatal("%s line %d: %s missing argument.",
   2849 			    filename, linenum, keyword);
   2850 		if ((value = ssh_digest_alg_by_name(arg)) == -1)
   2851 			fatal("%.200s line %d: Invalid %s algorithm \"%s\".",
   2852 			    filename, linenum, keyword, arg);
   2853 		if (*activep)
   2854 			options->fingerprint_hash = value;
   2855 		break;
   2856 
   2857 	case sExposeAuthInfo:
   2858 		intptr = &options->expose_userauth_info;
   2859 		goto parse_flag;
   2860 
   2861 	case sRDomain:
   2862 #if !defined(__OpenBSD__) && !defined(HAVE_SYS_SET_PROCESS_RDOMAIN)
   2863 		fatal("%s line %d: setting RDomain not supported on this "
   2864 		    "platform.", filename, linenum);
   2865 #endif
   2866 		charptr = &options->routing_domain;
   2867 		arg = argv_next(&ac, &av);
   2868 		if (!arg || *arg == '\0')
   2869 			fatal("%s line %d: %s missing argument.",
   2870 			    filename, linenum, keyword);
   2871 		if (strcasecmp(arg, "none") != 0 && strcmp(arg, "%D") != 0 &&
   2872 		    !valid_rdomain(arg))
   2873 			fatal("%s line %d: invalid routing domain",
   2874 			    filename, linenum);
   2875 		if (*activep && *charptr == NULL)
   2876 			*charptr = xstrdup(arg);
   2877 		break;
   2878 
   2879 	case sRequiredRSASize:
   2880 		intptr = &options->required_rsa_size;
   2881 		goto parse_int;
   2882 
   2883 	case sChannelTimeout:
   2884 		found = options->num_channel_timeouts == 0;
   2885 		while ((arg = argv_next(&ac, &av)) != NULL) {
   2886 			/* Allow "none" only in first position */
   2887 			if (strcasecmp(arg, "none") == 0) {
   2888 				if (nstrs > 0 || ac > 0) {
   2889 					error("%s line %d: keyword %s \"none\" "
   2890 					    "argument must appear alone.",
   2891 					    filename, linenum, keyword);
   2892 					goto out;
   2893 				}
   2894 			} else if (parse_pattern_interval(arg,
   2895 			    NULL, NULL) != 0) {
   2896 				fatal("%s line %d: invalid channel timeout %s",
   2897 				    filename, linenum, arg);
   2898 			}
   2899 			opt_array_append(filename, linenum, keyword,
   2900 			    &strs, &nstrs, arg);
   2901 		}
   2902 		if (nstrs == 0) {
   2903 			fatal("%s line %d: no %s specified",
   2904 			    filename, linenum, keyword);
   2905 		}
   2906 		if (found && *activep) {
   2907 			options->channel_timeouts = strs;
   2908 			options->num_channel_timeouts = nstrs;
   2909 			strs = NULL; /* transferred */
   2910 			nstrs = 0;
   2911 		}
   2912 		break;
   2913 
   2914 	case sUnusedConnectionTimeout:
   2915 		intptr = &options->unused_connection_timeout;
   2916 		/* peek at first arg for "none" so we can reuse parse_time */
   2917 		if (av[0] != NULL && strcasecmp(av[0], "none") == 0) {
   2918 			(void)argv_next(&ac, &av); /* consume arg */
   2919 			if (*activep)
   2920 				*intptr = 0;
   2921 			break;
   2922 		}
   2923 		goto parse_time;
   2924 
   2925 	case sSshdSessionPath:
   2926 		charptr = &options->sshd_session_path;
   2927 		goto parse_filename;
   2928 
   2929 	case sSshdAuthPath:
   2930 		charptr = &options->sshd_auth_path;
   2931 		goto parse_filename;
   2932 
   2933 	case sRefuseConnection:
   2934 		intptr = &options->refuse_connection;
   2935 		multistate_ptr = multistate_flag;
   2936 		goto parse_multistate;
   2937 
   2938 	case sDeprecated:
   2939 	case sIgnore:
   2940 	case sUnsupported:
   2941 		do_log2(opcode == sIgnore ?
   2942 		    SYSLOG_LEVEL_DEBUG2 : SYSLOG_LEVEL_INFO,
   2943 		    "%s line %d: %s option %s", filename, linenum,
   2944 		    opcode == sUnsupported ? "Unsupported" : "Deprecated",
   2945 		    keyword);
   2946 		argv_consume(&ac);
   2947 		break;
   2948 
   2949 #ifdef WITH_LDAP_PUBKEY
   2950 	case sLdapPublickey:
   2951 		intptr = &options->lpk.on;
   2952 		goto parse_flag;
   2953 	case sLdapServers:
   2954 		/* arg = strdelim(&cp); */
   2955 		p = line;
   2956 		while(*p++);
   2957 		arg = p;
   2958 		if (!arg || *arg == '\0')
   2959 		    fatal("%s line %d: missing ldap server",filename,linenum);
   2960 		arg[strlen(arg)] = '\0';
   2961 		if ((options->lpk.servers = ldap_parse_servers(arg)) == NULL)
   2962 		    fatal("%s line %d: error in ldap servers", filename, linenum);
   2963 		memset(arg,0,strlen(arg));
   2964 		break;
   2965 	case sLdapUserDN:
   2966 		arg = argv_next(&ac, &av);
   2967 		if (!arg || *arg == '\0')
   2968 		    fatal("%s line %d: missing ldap server",filename,linenum);
   2969 		arg[strlen(arg)] = '\0';
   2970 		options->lpk.u_basedn = xstrdup(arg);
   2971 		memset(arg,0,strlen(arg));
   2972 		break;
   2973 	case sLdapGroupDN:
   2974 		arg = argv_next(&ac, &av);
   2975 		if (!arg || *arg == '\0')
   2976 		    fatal("%s line %d: missing ldap server",filename,linenum);
   2977 		arg[strlen(arg)] = '\0';
   2978 		options->lpk.g_basedn = xstrdup(arg);
   2979 		memset(arg,0,strlen(arg));
   2980 		break;
   2981 	case sBindDN:
   2982 		arg = argv_next(&ac, &av);
   2983 		if (!arg || *arg == '\0')
   2984 		    fatal("%s line %d: missing binddn",filename,linenum);
   2985 		arg[strlen(arg)] = '\0';
   2986 		options->lpk.binddn = xstrdup(arg);
   2987 		memset(arg,0,strlen(arg));
   2988 		break;
   2989 	case sBindPw:
   2990 		arg = argv_next(&ac, &av);
   2991 		if (!arg || *arg == '\0')
   2992 		    fatal("%s line %d: missing bindpw",filename,linenum);
   2993 		arg[strlen(arg)] = '\0';
   2994 		options->lpk.bindpw = xstrdup(arg);
   2995 		memset(arg,0,strlen(arg));
   2996 		break;
   2997 	case sMyGroup:
   2998 		arg = argv_next(&ac, &av);
   2999 		if (!arg || *arg == '\0')
   3000 		    fatal("%s line %d: missing groupname",filename, linenum);
   3001 		arg[strlen(arg)] = '\0';
   3002 		options->lpk.sgroup = xstrdup(arg);
   3003 		if (options->lpk.sgroup)
   3004 		    options->lpk.fgroup = ldap_parse_groups(options->lpk.sgroup);
   3005 		memset(arg,0,strlen(arg));
   3006 		break;
   3007 	case sLdapFilter:
   3008 		arg = argv_next(&ac, &av);
   3009 		if (!arg || *arg == '\0')
   3010 		    fatal("%s line %d: missing filter",filename, linenum);
   3011 		arg[strlen(arg)] = '\0';
   3012 		options->lpk.filter = xstrdup(arg);
   3013 		memset(arg,0,strlen(arg));
   3014 		break;
   3015 	case sForceTLS:
   3016 		intptr = &options->lpk.tls;
   3017 		arg = argv_next(&ac, &av);
   3018 		if (!arg || *arg == '\0')
   3019 			fatal("%s line %d: missing yes/no argument.",
   3020 			    filename, linenum);
   3021 		value = 0;	/* silence compiler */
   3022 		if (strcmp(arg, "yes") == 0)
   3023 			value = 1;
   3024 		else if (strcmp(arg, "no") == 0)
   3025 			value = 0;
   3026 		else if (strcmp(arg, "try") == 0)
   3027 			value = -1;
   3028 		else
   3029 			fatal("%s line %d: Bad yes/no argument: %s",
   3030 				filename, linenum, arg);
   3031 		if (*intptr == -1)
   3032 			*intptr = value;
   3033 		break;
   3034 	case sBindTimeout:
   3035 		timetptr = &options->lpk.b_timeout.tv_sec;
   3036 parse_ulong:
   3037 		arg = argv_next(&ac, &av);
   3038 		if (!arg || *arg == '\0')
   3039 			fatal("%s line %d: missing integer value.",
   3040 			    filename, linenum);
   3041 		lvalue = atol(arg);
   3042 		if (*activep && *timetptr == -1)
   3043 			*timetptr = lvalue;
   3044 		break;
   3045 
   3046 	case sSearchTimeout:
   3047 		timetptr = &options->lpk.s_timeout.tv_sec;
   3048 		goto parse_ulong;
   3049 		break;
   3050 	case sLdapConf:
   3051 		arg = argv_next(&ac, &av);
   3052 		if (!arg || *arg == '\0')
   3053 		    fatal("%s line %d: missing LpkLdapConf", filename, linenum);
   3054 		arg[strlen(arg)] = '\0';
   3055 		options->lpk.l_conf = xstrdup(arg);
   3056 		memset(arg, 0, strlen(arg));
   3057 		break;
   3058 	case sLpkPubKeyAttr:
   3059 		arg = argv_next(&ac, &av);
   3060                 if (!arg || *arg == '\0')
   3061                     fatal("%s line %d: missing pubkeyattr",filename,linenum);
   3062                 arg[strlen(arg)] = '\0';
   3063                 options->lpk.pub_key_attr = xstrdup(arg);
   3064                 memset(arg,0,strlen(arg));
   3065                 break;
   3066 
   3067 #endif
   3068 
   3069 	default:
   3070 		fatal("%s line %d: Missing handler for opcode %s (%d)",
   3071 		    filename, linenum, keyword, opcode);
   3072 	}
   3073 	/* Check that there is no garbage at end of line. */
   3074 	if (ac > 0) {
   3075 		error("%.200s line %d: keyword %s extra arguments "
   3076 		    "at end of line", filename, linenum, keyword);
   3077 		goto out;
   3078 	}
   3079 
   3080 	/* success */
   3081 	ret = 0;
   3082  out:
   3083 	opt_array_free2(strs, NULL, nstrs);
   3084 	argv_free(oav, oac);
   3085 	return ret;
   3086 }
   3087 
   3088 int
   3089 process_server_config_line(ServerOptions *options, char *line,
   3090     const char *filename, int linenum, int *activep,
   3091     struct connection_info *connectinfo, struct include_list *includes)
   3092 {
   3093 	int inc_flags = 0;
   3094 
   3095 	return process_server_config_line_depth(options, line, filename,
   3096 	    linenum, activep, connectinfo, &inc_flags, 0, includes);
   3097 }
   3098 
   3099 
   3100 /* Reads the server configuration file. */
   3101 
   3102 void
   3103 load_server_config(const char *filename, struct sshbuf *conf)
   3104 {
   3105 	struct stat st;
   3106 	char *line = NULL, *cp;
   3107 	size_t linesize = 0;
   3108 	FILE *f;
   3109 	int r;
   3110 
   3111 	debug2_f("filename %s", filename);
   3112 	if ((f = fopen(filename, "r")) == NULL) {
   3113 		perror(filename);
   3114 		exit(1);
   3115 	}
   3116 	sshbuf_reset(conf);
   3117 	/* grow buffer, so realloc is avoided for large config files */
   3118 	if (fstat(fileno(f), &st) == 0 && st.st_size > 0 &&
   3119 	    (r = sshbuf_allocate(conf, st.st_size)) != 0)
   3120 		fatal_fr(r, "allocate");
   3121 	while (getline(&line, &linesize, f) != -1) {
   3122 		/*
   3123 		 * Strip whitespace
   3124 		 * NB - preserve newlines, they are needed to reproduce
   3125 		 * line numbers later for error messages
   3126 		 */
   3127 		cp = line + strspn(line, " \t\r");
   3128 		if ((r = sshbuf_put(conf, cp, strlen(cp))) != 0)
   3129 			fatal_fr(r, "sshbuf_put");
   3130 	}
   3131 	free(line);
   3132 	if ((r = sshbuf_put_u8(conf, 0)) != 0)
   3133 		fatal_fr(r, "sshbuf_put_u8");
   3134 	fclose(f);
   3135 	debug2_f("done config len = %zu", sshbuf_len(conf));
   3136 }
   3137 
   3138 void
   3139 parse_server_match_config(ServerOptions *options,
   3140    struct include_list *includes, struct connection_info *connectinfo)
   3141 {
   3142 	ServerOptions mo;
   3143 
   3144 	initialize_server_options(&mo);
   3145 	parse_server_config(&mo, "reprocess config", cfg, includes,
   3146 	    connectinfo, 0);
   3147 	copy_set_server_options(options, &mo, 0);
   3148 }
   3149 
   3150 int
   3151 parse_server_match_testspec(struct connection_info *ci, char *spec)
   3152 {
   3153 	char *p;
   3154 	const char *val;
   3155 
   3156 	while ((p = strsep(&spec, ",")) && *p != '\0') {
   3157 		if ((val = strprefix(p, "addr=", 0)) != NULL) {
   3158 			ci->address = xstrdup(val);
   3159 		} else if ((val = strprefix(p, "host=", 0)) != NULL) {
   3160 			ci->host = xstrdup(val);
   3161 		} else if ((val = strprefix(p, "user=", 0)) != NULL) {
   3162 			ci->user = xstrdup(val);
   3163 		} else if ((val = strprefix(p, "laddr=", 0)) != NULL) {
   3164 			ci->laddress = xstrdup(val);
   3165 		} else if ((val = strprefix(p, "rdomain=", 0)) != NULL) {
   3166 			ci->rdomain = xstrdup(val);
   3167 		} else if ((val = strprefix(p, "lport=", 0)) != NULL) {
   3168 			ci->lport = a2port(val);
   3169 			if (ci->lport == -1) {
   3170 				fprintf(stderr, "Invalid port '%s' in test mode"
   3171 				    " specification %s\n", p+6, p);
   3172 				return -1;
   3173 			}
   3174 		} else if (strcmp(p, "invalid-user") == 0) {
   3175 			ci->user_invalid = 1;
   3176 		} else {
   3177 			fprintf(stderr, "Invalid test mode specification %s\n",
   3178 			    p);
   3179 			return -1;
   3180 		}
   3181 	}
   3182 	return 0;
   3183 }
   3184 
   3185 void
   3186 servconf_merge_subsystems(ServerOptions *dst, ServerOptions *src)
   3187 {
   3188 	u_int i, j, found;
   3189 
   3190 	for (i = 0; i < src->num_subsystems; i++) {
   3191 		found = 0;
   3192 		for (j = 0; j < dst->num_subsystems; j++) {
   3193 			if (strcmp(src->subsystem_name[i],
   3194 			    dst->subsystem_name[j]) == 0) {
   3195 				found = 1;
   3196 				break;
   3197 			}
   3198 		}
   3199 		if (found) {
   3200 			debug_f("override \"%s\"", dst->subsystem_name[j]);
   3201 			free(dst->subsystem_command[j]);
   3202 			free(dst->subsystem_args[j]);
   3203 			dst->subsystem_command[j] =
   3204 			    xstrdup(src->subsystem_command[i]);
   3205 			dst->subsystem_args[j] =
   3206 			    xstrdup(src->subsystem_args[i]);
   3207 			continue;
   3208 		}
   3209 		debug_f("add \"%s\"", src->subsystem_name[i]);
   3210 		dst->subsystem_name = xrecallocarray(
   3211 		    dst->subsystem_name, dst->num_subsystems,
   3212 		    dst->num_subsystems + 1, sizeof(*dst->subsystem_name));
   3213 		dst->subsystem_command = xrecallocarray(
   3214 		    dst->subsystem_command, dst->num_subsystems,
   3215 		    dst->num_subsystems + 1, sizeof(*dst->subsystem_command));
   3216 		dst->subsystem_args = xrecallocarray(
   3217 		    dst->subsystem_args, dst->num_subsystems,
   3218 		    dst->num_subsystems + 1, sizeof(*dst->subsystem_args));
   3219 		j = dst->num_subsystems++;
   3220 		dst->subsystem_name[j] = xstrdup(src->subsystem_name[i]);
   3221 		dst->subsystem_command[j] = xstrdup(src->subsystem_command[i]);
   3222 		dst->subsystem_args[j] = xstrdup(src->subsystem_args[i]);
   3223 	}
   3224 }
   3225 
   3226 /*
   3227  * Copy any supported values that are set.
   3228  *
   3229  * If the preauth flag is set, we do not bother copying the string or
   3230  * array values that are not used pre-authentication, because any that we
   3231  * do use must be explicitly sent in mm_getpwnamallow().
   3232  */
   3233 void
   3234 copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
   3235 {
   3236 #define M_CP_INTOPT(n) do {\
   3237 	if (src->n != -1) \
   3238 		dst->n = src->n; \
   3239 } while (0)
   3240 
   3241 	M_CP_INTOPT(password_authentication);
   3242 	M_CP_INTOPT(gss_authentication);
   3243 	M_CP_INTOPT(pubkey_authentication);
   3244 	M_CP_INTOPT(pubkey_auth_options);
   3245 	M_CP_INTOPT(kerberos_authentication);
   3246 	M_CP_INTOPT(hostbased_authentication);
   3247 	M_CP_INTOPT(hostbased_uses_name_from_packet_only);
   3248 	M_CP_INTOPT(kbd_interactive_authentication);
   3249 	M_CP_INTOPT(permit_root_login);
   3250 	M_CP_INTOPT(permit_empty_passwd);
   3251 	M_CP_INTOPT(ignore_rhosts);
   3252 
   3253 	M_CP_INTOPT(allow_tcp_forwarding);
   3254 	M_CP_INTOPT(allow_streamlocal_forwarding);
   3255 	M_CP_INTOPT(allow_agent_forwarding);
   3256 	M_CP_INTOPT(disable_forwarding);
   3257 	M_CP_INTOPT(expose_userauth_info);
   3258 	M_CP_INTOPT(permit_tun);
   3259 	M_CP_INTOPT(fwd_opts.gateway_ports);
   3260 	M_CP_INTOPT(fwd_opts.streamlocal_bind_unlink);
   3261 	M_CP_INTOPT(x11_display_offset);
   3262 	M_CP_INTOPT(x11_forwarding);
   3263 	M_CP_INTOPT(x11_use_localhost);
   3264 	M_CP_INTOPT(permit_tty);
   3265 	M_CP_INTOPT(permit_user_rc);
   3266 	M_CP_INTOPT(max_sessions);
   3267 	M_CP_INTOPT(max_authtries);
   3268 	M_CP_INTOPT(client_alive_count_max);
   3269 	M_CP_INTOPT(client_alive_interval);
   3270 	M_CP_INTOPT(ip_qos_interactive);
   3271 	M_CP_INTOPT(ip_qos_bulk);
   3272 	M_CP_INTOPT(rekey_limit);
   3273 	M_CP_INTOPT(rekey_interval);
   3274 	M_CP_INTOPT(log_level);
   3275 	M_CP_INTOPT(required_rsa_size);
   3276 	M_CP_INTOPT(unused_connection_timeout);
   3277 	M_CP_INTOPT(refuse_connection);
   3278 
   3279 	/*
   3280 	 * The bind_mask is a mode_t that may be unsigned, so we can't use
   3281 	 * M_CP_INTOPT - it does a signed comparison that causes compiler
   3282 	 * warnings.
   3283 	 */
   3284 	if (src->fwd_opts.streamlocal_bind_mask != (mode_t)-1) {
   3285 		dst->fwd_opts.streamlocal_bind_mask =
   3286 		    src->fwd_opts.streamlocal_bind_mask;
   3287 	}
   3288 
   3289 	/* M_CP_STROPT and M_CP_STRARRAYOPT should not appear before here */
   3290 #define M_CP_STROPT(n) do {\
   3291 	if (src->n != NULL && dst->n != src->n) { \
   3292 		free(dst->n); \
   3293 		dst->n = xstrdup(src->n); \
   3294 	} \
   3295 } while(0)
   3296 #define M_CP_STRARRAYOPT(s, num_s, clobber) do {\
   3297 	u_int i; \
   3298 	if (src->num_s != 0) { \
   3299 		for (i = 0; i < dst->num_s; i++) \
   3300 			free(dst->s[i]); \
   3301 		free(dst->s); \
   3302 		dst->s = xcalloc(src->num_s, sizeof(*dst->s)); \
   3303 		for (i = 0; i < src->num_s; i++) \
   3304 			dst->s[i] = xstrdup(src->s[i]); \
   3305 		if (clobber) \
   3306 			dst->num_s = src->num_s; \
   3307 	} \
   3308 } while(0)
   3309 
   3310 	/* See comment in servconf.h */
   3311 	COPY_MATCH_STRING_OPTS();
   3312 
   3313 	/* Arguments that accept '+...' need to be expanded */
   3314 	assemble_algorithms(dst);
   3315 
   3316 	/*
   3317 	 * The only things that should be below this point are string options
   3318 	 * which are only used after authentication.
   3319 	 */
   3320 	if (preauth)
   3321 		return;
   3322 
   3323 	/* These options may be "none" to clear a global setting */
   3324 	M_CP_STROPT(adm_forced_command);
   3325 	if (option_clear_or_none(dst->adm_forced_command)) {
   3326 		free(dst->adm_forced_command);
   3327 		dst->adm_forced_command = NULL;
   3328 	}
   3329 	M_CP_STROPT(chroot_directory);
   3330 	if (option_clear_or_none(dst->chroot_directory)) {
   3331 		free(dst->chroot_directory);
   3332 		dst->chroot_directory = NULL;
   3333 	}
   3334 
   3335 	/* Subsystems require merging. */
   3336 	servconf_merge_subsystems(dst, src);
   3337 }
   3338 
   3339 #undef M_CP_INTOPT
   3340 #undef M_CP_STROPT
   3341 #undef M_CP_STRARRAYOPT
   3342 
   3343 #define SERVCONF_MAX_DEPTH	16
   3344 static void
   3345 parse_server_config_depth(ServerOptions *options, const char *filename,
   3346     struct sshbuf *conf, struct include_list *includes,
   3347     struct connection_info *connectinfo, int flags, int *activep, int depth)
   3348 {
   3349 	int linenum, bad_options = 0;
   3350 	char *cp, *obuf, *cbuf;
   3351 
   3352 	if (depth < 0 || depth > SERVCONF_MAX_DEPTH)
   3353 		fatal("Too many recursive configuration includes");
   3354 
   3355 	debug2_f("config %s len %zu%s", filename, sshbuf_len(conf),
   3356 	    (flags & SSHCFG_NEVERMATCH ? " [checking syntax only]" : ""));
   3357 
   3358 	if ((obuf = cbuf = sshbuf_dup_string(conf)) == NULL)
   3359 		fatal_f("sshbuf_dup_string failed");
   3360 	linenum = 1;
   3361 	while ((cp = strsep(&cbuf, "\n")) != NULL) {
   3362 		if (process_server_config_line_depth(options, cp,
   3363 		    filename, linenum++, activep, connectinfo, &flags,
   3364 		    depth, includes) != 0)
   3365 			bad_options++;
   3366 	}
   3367 	free(obuf);
   3368 	if (bad_options > 0)
   3369 		fatal("%s: terminating, %d bad configuration options",
   3370 		    filename, bad_options);
   3371 }
   3372 
   3373 void
   3374 parse_server_config(ServerOptions *options, const char *filename,
   3375     struct sshbuf *conf, struct include_list *includes,
   3376     struct connection_info *connectinfo, int reexec)
   3377 {
   3378 	int active = connectinfo ? 0 : 1;
   3379 	parse_server_config_depth(options, filename, conf, includes,
   3380 	    connectinfo, (connectinfo ? SSHCFG_MATCH_ONLY : 0), &active, 0);
   3381 	if (!reexec)
   3382 		process_queued_listen_addrs(options);
   3383 }
   3384 
   3385 static const char *
   3386 fmt_multistate_int(int val, const struct multistate *m)
   3387 {
   3388 	u_int i;
   3389 
   3390 	for (i = 0; m[i].key != NULL; i++) {
   3391 		if (m[i].value == val)
   3392 			return m[i].key;
   3393 	}
   3394 	return "UNKNOWN";
   3395 }
   3396 
   3397 static const char *
   3398 fmt_intarg(ServerOpCodes code, int val)
   3399 {
   3400 	if (val == -1)
   3401 		return "unset";
   3402 	switch (code) {
   3403 	case sAddressFamily:
   3404 		return fmt_multistate_int(val, multistate_addressfamily);
   3405 	case sPermitRootLogin:
   3406 		return fmt_multistate_int(val, multistate_permitrootlogin);
   3407 	case sGatewayPorts:
   3408 		return fmt_multistate_int(val, multistate_gatewayports);
   3409 	case sCompression:
   3410 		return fmt_multistate_int(val, multistate_compression);
   3411 	case sAllowTcpForwarding:
   3412 		return fmt_multistate_int(val, multistate_tcpfwd);
   3413 	case sAllowStreamLocalForwarding:
   3414 		return fmt_multistate_int(val, multistate_tcpfwd);
   3415 	case sIgnoreRhosts:
   3416 		return fmt_multistate_int(val, multistate_ignore_rhosts);
   3417 	case sFingerprintHash:
   3418 		return ssh_digest_alg_name(val);
   3419 	default:
   3420 		switch (val) {
   3421 		case 0:
   3422 			return "no";
   3423 		case 1:
   3424 			return "yes";
   3425 		default:
   3426 			return "UNKNOWN";
   3427 		}
   3428 	}
   3429 }
   3430 
   3431 static void
   3432 dump_cfg_int(ServerOpCodes code, int val)
   3433 {
   3434 	if (code == sUnusedConnectionTimeout && val == 0) {
   3435 		printf("%s none\n", lookup_opcode_name(code));
   3436 		return;
   3437 	}
   3438 	printf("%s %d\n", lookup_opcode_name(code), val);
   3439 }
   3440 
   3441 static void
   3442 dump_cfg_oct(ServerOpCodes code, int val)
   3443 {
   3444 	printf("%s 0%o\n", lookup_opcode_name(code), val);
   3445 }
   3446 
   3447 static void
   3448 dump_cfg_fmtint(ServerOpCodes code, int val)
   3449 {
   3450 	printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
   3451 }
   3452 
   3453 static void
   3454 dump_cfg_string(ServerOpCodes code, const char *val)
   3455 {
   3456 	printf("%s %s\n", lookup_opcode_name(code),
   3457 	    val == NULL ? "none" : val);
   3458 }
   3459 
   3460 static void
   3461 dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals)
   3462 {
   3463 	u_int i;
   3464 
   3465 	for (i = 0; i < count; i++)
   3466 		printf("%s %s\n", lookup_opcode_name(code), vals[i]);
   3467 }
   3468 
   3469 static void
   3470 dump_cfg_strarray_oneline(ServerOpCodes code, u_int count, char **vals)
   3471 {
   3472 	u_int i;
   3473 
   3474 	switch (code) {
   3475 	case sAuthenticationMethods:
   3476 	case sChannelTimeout:
   3477 		break;
   3478 	default:
   3479 		if (count <= 0)
   3480 			return;
   3481 		break;
   3482 	}
   3483 
   3484 	printf("%s", lookup_opcode_name(code));
   3485 	for (i = 0; i < count; i++)
   3486 		printf(" %s",  vals[i]);
   3487 	if (code == sAuthenticationMethods && count == 0)
   3488 		printf(" any");
   3489 	else if (code == sChannelTimeout && count == 0)
   3490 		printf(" none");
   3491 	printf("\n");
   3492 }
   3493 
   3494 static char *
   3495 format_listen_addrs(struct listenaddr *la)
   3496 {
   3497 	int r;
   3498 	struct addrinfo *ai;
   3499 	char addr[NI_MAXHOST], port[NI_MAXSERV];
   3500 	char *laddr1 = xstrdup(""), *laddr2 = NULL;
   3501 
   3502 	/*
   3503 	 * ListenAddress must be after Port.  add_one_listen_addr pushes
   3504 	 * addresses onto a stack, so to maintain ordering we need to
   3505 	 * print these in reverse order.
   3506 	 */
   3507 	for (ai = la->addrs; ai; ai = ai->ai_next) {
   3508 		if ((r = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
   3509 		    sizeof(addr), port, sizeof(port),
   3510 		    NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
   3511 			error("getnameinfo: %.100s", ssh_gai_strerror(r));
   3512 			continue;
   3513 		}
   3514 		laddr2 = laddr1;
   3515 		if (ai->ai_family == AF_INET6) {
   3516 			xasprintf(&laddr1, "listenaddress [%s]:%s%s%s\n%s",
   3517 			    addr, port,
   3518 			    la->rdomain == NULL ? "" : " rdomain ",
   3519 			    la->rdomain == NULL ? "" : la->rdomain,
   3520 			    laddr2);
   3521 		} else {
   3522 			xasprintf(&laddr1, "listenaddress %s:%s%s%s\n%s",
   3523 			    addr, port,
   3524 			    la->rdomain == NULL ? "" : " rdomain ",
   3525 			    la->rdomain == NULL ? "" : la->rdomain,
   3526 			    laddr2);
   3527 		}
   3528 		free(laddr2);
   3529 	}
   3530 	return laddr1;
   3531 }
   3532 
   3533 void
   3534 dump_config(ServerOptions *o)
   3535 {
   3536 	const char *s;
   3537 	u_int i;
   3538 
   3539 	/* these are usually at the top of the config */
   3540 	for (i = 0; i < o->num_ports; i++)
   3541 		printf("port %d\n", o->ports[i]);
   3542 	dump_cfg_fmtint(sAddressFamily, o->address_family);
   3543 
   3544 	for (i = 0; i < o->num_listen_addrs; i++) {
   3545 		char *ss = format_listen_addrs(&o->listen_addrs[i]);
   3546 		printf("%s", ss);
   3547 		free(ss);
   3548 	}
   3549 
   3550 	/* integer arguments */
   3551 #ifdef USE_PAM
   3552 	dump_cfg_fmtint(sUsePAM, o->use_pam);
   3553 	dump_cfg_string(sPAMServiceName, o->pam_service_name);
   3554 #endif
   3555 	dump_cfg_int(sLoginGraceTime, o->login_grace_time);
   3556 	dump_cfg_int(sX11DisplayOffset, o->x11_display_offset);
   3557 	dump_cfg_int(sMaxAuthTries, o->max_authtries);
   3558 	dump_cfg_int(sMaxSessions, o->max_sessions);
   3559 	dump_cfg_int(sClientAliveInterval, o->client_alive_interval);
   3560 	dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max);
   3561 	dump_cfg_int(sRequiredRSASize, o->required_rsa_size);
   3562 	dump_cfg_oct(sStreamLocalBindMask, o->fwd_opts.streamlocal_bind_mask);
   3563 	dump_cfg_int(sUnusedConnectionTimeout, o->unused_connection_timeout);
   3564 
   3565 	/* formatted integer arguments */
   3566 	dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login);
   3567 	dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts);
   3568 	dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts);
   3569 	dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication);
   3570 	dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly,
   3571 	    o->hostbased_uses_name_from_packet_only);
   3572 	dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication);
   3573 #ifdef KRB5
   3574 	dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication);
   3575 	dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd);
   3576 	dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup);
   3577 	dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
   3578 #endif
   3579 #ifdef GSSAPI
   3580 	dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
   3581 	dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
   3582 	dump_cfg_fmtint(sGssDelegateCreds, o->gss_deleg_creds);
   3583 	dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor);
   3584 #endif
   3585 	dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
   3586 	dump_cfg_fmtint(sKbdInteractiveAuthentication,
   3587 	    o->kbd_interactive_authentication);
   3588 	dump_cfg_fmtint(sPrintMotd, o->print_motd);
   3589 	dump_cfg_fmtint(sPrintLastLog, o->print_lastlog);
   3590 	dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding);
   3591 	dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost);
   3592 	dump_cfg_fmtint(sPermitTTY, o->permit_tty);
   3593 	dump_cfg_fmtint(sPermitUserRC, o->permit_user_rc);
   3594 	dump_cfg_fmtint(sStrictModes, o->strict_modes);
   3595 	dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive);
   3596 	dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd);
   3597 	dump_cfg_fmtint(sCompression, o->compression);
   3598 	dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports);
   3599 	dump_cfg_fmtint(sUseDNS, o->use_dns);
   3600 	dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
   3601 	dump_cfg_fmtint(sAllowAgentForwarding, o->allow_agent_forwarding);
   3602 	dump_cfg_fmtint(sDisableForwarding, o->disable_forwarding);
   3603 	dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding);
   3604 	dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
   3605 	dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash);
   3606 	dump_cfg_fmtint(sExposeAuthInfo, o->expose_userauth_info);
   3607 	dump_cfg_fmtint(sRefuseConnection, o->refuse_connection);
   3608 
   3609 	/* string arguments */
   3610 	dump_cfg_string(sPidFile, o->pid_file);
   3611 	dump_cfg_string(sModuliFile, o->moduli_file);
   3612 	dump_cfg_string(sXAuthLocation, o->xauth_location);
   3613 	dump_cfg_string(sCiphers, o->ciphers);
   3614 	dump_cfg_string(sMacs, o->macs);
   3615 	dump_cfg_string(sBanner, o->banner);
   3616 	dump_cfg_string(sForceCommand, o->adm_forced_command);
   3617 	dump_cfg_string(sChrootDirectory, o->chroot_directory);
   3618 	dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);
   3619 	dump_cfg_string(sSecurityKeyProvider, o->sk_provider);
   3620 	dump_cfg_string(sAuthorizedPrincipalsFile,
   3621 	    o->authorized_principals_file);
   3622 	dump_cfg_string(sVersionAddendum, *o->version_addendum == '\0'
   3623 	    ? "none" : o->version_addendum);
   3624 	dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command);
   3625 	dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user);
   3626 	dump_cfg_string(sAuthorizedPrincipalsCommand, o->authorized_principals_command);
   3627 	dump_cfg_string(sAuthorizedPrincipalsCommandUser, o->authorized_principals_command_user);
   3628 	dump_cfg_string(sHostKeyAgent, o->host_key_agent);
   3629 	dump_cfg_string(sKexAlgorithms, o->kex_algorithms);
   3630 	dump_cfg_string(sCASignatureAlgorithms, o->ca_sign_algorithms);
   3631 	dump_cfg_string(sHostbasedAcceptedAlgorithms, o->hostbased_accepted_algos);
   3632 	dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms);
   3633 	dump_cfg_string(sPubkeyAcceptedAlgorithms, o->pubkey_accepted_algos);
   3634 #if defined(__OpenBSD__) || defined(HAVE_SYS_SET_PROCESS_RDOMAIN)
   3635 	dump_cfg_string(sRDomain, o->routing_domain);
   3636 #endif
   3637 	dump_cfg_string(sSshdSessionPath, o->sshd_session_path);
   3638 	dump_cfg_string(sSshdAuthPath, o->sshd_auth_path);
   3639 	dump_cfg_string(sPerSourcePenaltyExemptList, o->per_source_penalty_exempt);
   3640 
   3641 	/* string arguments requiring a lookup */
   3642 	dump_cfg_string(sLogLevel, log_level_name(o->log_level));
   3643 	dump_cfg_string(sLogFacility, log_facility_name(o->log_facility));
   3644 
   3645 	/* string array arguments */
   3646 	dump_cfg_strarray_oneline(sAuthorizedKeysFile, o->num_authkeys_files,
   3647 	    o->authorized_keys_files);
   3648 	dump_cfg_strarray_oneline(sRevokedKeys, o->num_revoked_keys_files,
   3649 	    o->revoked_keys_files);
   3650 	dump_cfg_strarray(sHostKeyFile, o->num_host_key_files,
   3651 	    o->host_key_files);
   3652 	dump_cfg_strarray(sHostCertificate, o->num_host_cert_files,
   3653 	    o->host_cert_files);
   3654 	dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users);
   3655 	dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users);
   3656 	dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups);
   3657 	dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups);
   3658 	dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env);
   3659 	dump_cfg_strarray(sSetEnv, o->num_setenv, o->setenv);
   3660 	dump_cfg_strarray_oneline(sAuthenticationMethods,
   3661 	    o->num_auth_methods, o->auth_methods);
   3662 	dump_cfg_strarray_oneline(sLogVerbose,
   3663 	    o->num_log_verbose, o->log_verbose);
   3664 	dump_cfg_strarray_oneline(sChannelTimeout,
   3665 	    o->num_channel_timeouts, o->channel_timeouts);
   3666 
   3667 	/* other arguments */
   3668 	for (i = 0; i < o->num_subsystems; i++)
   3669 		printf("subsystem %s %s\n", o->subsystem_name[i],
   3670 		    o->subsystem_args[i]);
   3671 
   3672 	printf("maxstartups %d:%d:%d\n", o->max_startups_begin,
   3673 	    o->max_startups_rate, o->max_startups);
   3674 	printf("persourcemaxstartups ");
   3675 	if (o->per_source_max_startups == INT_MAX)
   3676 		printf("none\n");
   3677 	else
   3678 		printf("%d\n", o->per_source_max_startups);
   3679 	printf("persourcenetblocksize %d:%d\n", o->per_source_masklen_ipv4,
   3680 	    o->per_source_masklen_ipv6);
   3681 
   3682 	s = NULL;
   3683 	for (i = 0; tunmode_desc[i].val != -1; i++) {
   3684 		if (tunmode_desc[i].val == o->permit_tun) {
   3685 			s = tunmode_desc[i].text;
   3686 			break;
   3687 		}
   3688 	}
   3689 	dump_cfg_string(sPermitTunnel, s);
   3690 
   3691 	printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
   3692 	printf("%s\n", iptos2str(o->ip_qos_bulk));
   3693 
   3694 	printf("rekeylimit %llu %d\n", (unsigned long long)o->rekey_limit,
   3695 	    o->rekey_interval);
   3696 
   3697 	printf("permitopen");
   3698 	if (o->num_permitted_opens == 0)
   3699 		printf(" any");
   3700 	else {
   3701 		for (i = 0; i < o->num_permitted_opens; i++)
   3702 			printf(" %s", o->permitted_opens[i]);
   3703 	}
   3704 	printf("\n");
   3705 	printf("permitlisten");
   3706 	if (o->num_permitted_listens == 0)
   3707 		printf(" any");
   3708 	else {
   3709 		for (i = 0; i < o->num_permitted_listens; i++)
   3710 			printf(" %s", o->permitted_listens[i]);
   3711 	}
   3712 	printf("\n");
   3713 
   3714 	if (o->permit_user_env_allowlist == NULL) {
   3715 		dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env);
   3716 	} else {
   3717 		printf("permituserenvironment %s\n",
   3718 		    o->permit_user_env_allowlist);
   3719 	}
   3720 
   3721 	printf("pubkeyauthoptions");
   3722 	if (o->pubkey_auth_options == 0)
   3723 		printf(" none");
   3724 	if (o->pubkey_auth_options & PUBKEYAUTH_TOUCH_REQUIRED)
   3725 		printf(" touch-required");
   3726 	if (o->pubkey_auth_options & PUBKEYAUTH_VERIFY_REQUIRED)
   3727 		printf(" verify-required");
   3728 	printf("\n");
   3729 
   3730 	if (o->per_source_penalty.enabled) {
   3731 		printf("persourcepenalties crash:%f authfail:%f noauth:%f "
   3732 		    "invaliduser:%f "
   3733 		    "grace-exceeded:%f refuseconnection:%f max:%f min:%f "
   3734 		    "max-sources4:%d max-sources6:%d "
   3735 		    "overflow:%s overflow6:%s\n",
   3736 		    o->per_source_penalty.penalty_crash,
   3737 		    o->per_source_penalty.penalty_authfail,
   3738 		    o->per_source_penalty.penalty_noauth,
   3739 		    o->per_source_penalty.penalty_invaliduser,
   3740 		    o->per_source_penalty.penalty_grace,
   3741 		    o->per_source_penalty.penalty_refuseconnection,
   3742 		    o->per_source_penalty.penalty_max,
   3743 		    o->per_source_penalty.penalty_min,
   3744 		    o->per_source_penalty.max_sources4,
   3745 		    o->per_source_penalty.max_sources6,
   3746 		    o->per_source_penalty.overflow_mode ==
   3747 		    PER_SOURCE_PENALTY_OVERFLOW_DENY_ALL ?
   3748 		    "deny-all" : "permissive",
   3749 		    o->per_source_penalty.overflow_mode6 ==
   3750 		    PER_SOURCE_PENALTY_OVERFLOW_DENY_ALL ?
   3751 		    "deny-all" : "permissive");
   3752 	} else
   3753 		printf("persourcepenalties no\n");
   3754 }
   3755