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