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