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