]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - crypto/openssh/servconf.c
zfs: merge openzfs/zfs@41e55b476
[FreeBSD/FreeBSD.git] / crypto / openssh / servconf.c
1 /* $OpenBSD: servconf.c,v 1.402 2023/09/08 06:34:24 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_ALL },
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                 arg = argv_next(&ac, &av);
1951                 if (!arg || *arg == '\0')
1952                         fatal("%s line %d: %s missing argument.",
1953                             filename, linenum, keyword);
1954                 if (!*activep) {
1955                         argv_consume(&ac);
1956                         break;
1957                 }
1958                 found = 0;
1959                 for (i = 0; i < options->num_subsystems; i++) {
1960                         if (strcmp(arg, options->subsystem_name[i]) == 0) {
1961                                 found = 1;
1962                                 break;
1963                         }
1964                 }
1965                 if (found) {
1966                         debug("%s line %d: Subsystem '%s' already defined.",
1967                             filename, linenum, arg);
1968                         argv_consume(&ac);
1969                         break;
1970                 }
1971                 options->subsystem_name = xrecallocarray(
1972                     options->subsystem_name, options->num_subsystems,
1973                     options->num_subsystems + 1,
1974                     sizeof(*options->subsystem_name));
1975                 options->subsystem_command = xrecallocarray(
1976                     options->subsystem_command, options->num_subsystems,
1977                     options->num_subsystems + 1,
1978                     sizeof(*options->subsystem_command));
1979                 options->subsystem_args = xrecallocarray(
1980                     options->subsystem_args, options->num_subsystems,
1981                     options->num_subsystems + 1,
1982                     sizeof(*options->subsystem_args));
1983                 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1984                 arg = argv_next(&ac, &av);
1985                 if (!arg || *arg == '\0') {
1986                         fatal("%s line %d: Missing subsystem command.",
1987                             filename, linenum);
1988                 }
1989                 options->subsystem_command[options->num_subsystems] =
1990                     xstrdup(arg);
1991                 /* Collect arguments (separate to executable) */
1992                 arg = argv_assemble(1, &arg); /* quote command correctly */
1993                 arg2 = argv_assemble(ac, av); /* rest of command */
1994                 xasprintf(&options->subsystem_args[options->num_subsystems],
1995                     "%s %s", arg, arg2);
1996                 free(arg2);
1997                 argv_consume(&ac);
1998                 options->num_subsystems++;
1999                 break;
2000
2001         case sMaxStartups:
2002                 arg = argv_next(&ac, &av);
2003                 if (!arg || *arg == '\0')
2004                         fatal("%s line %d: %s missing argument.",
2005                             filename, linenum, keyword);
2006                 if ((n = sscanf(arg, "%d:%d:%d",
2007                     &options->max_startups_begin,
2008                     &options->max_startups_rate,
2009                     &options->max_startups)) == 3) {
2010                         if (options->max_startups_begin >
2011                             options->max_startups ||
2012                             options->max_startups_rate > 100 ||
2013                             options->max_startups_rate < 1)
2014                                 fatal("%s line %d: Invalid %s spec.",
2015                                     filename, linenum, keyword);
2016                 } else if (n != 1)
2017                         fatal("%s line %d: Invalid %s spec.",
2018                             filename, linenum, keyword);
2019                 else
2020                         options->max_startups = options->max_startups_begin;
2021                 if (options->max_startups <= 0 ||
2022                     options->max_startups_begin <= 0)
2023                         fatal("%s line %d: Invalid %s spec.",
2024                             filename, linenum, keyword);
2025                 break;
2026
2027         case sPerSourceNetBlockSize:
2028                 arg = argv_next(&ac, &av);
2029                 if (!arg || *arg == '\0')
2030                         fatal("%s line %d: %s missing argument.",
2031                             filename, linenum, keyword);
2032                 switch (n = sscanf(arg, "%d:%d", &value, &value2)) {
2033                 case 2:
2034                         if (value2 < 0 || value2 > 128)
2035                                 n = -1;
2036                         /* FALLTHROUGH */
2037                 case 1:
2038                         if (value < 0 || value > 32)
2039                                 n = -1;
2040                 }
2041                 if (n != 1 && n != 2)
2042                         fatal("%s line %d: Invalid %s spec.",
2043                             filename, linenum, keyword);
2044                 if (*activep) {
2045                         options->per_source_masklen_ipv4 = value;
2046                         options->per_source_masklen_ipv6 = value2;
2047                 }
2048                 break;
2049
2050         case sPerSourceMaxStartups:
2051                 arg = argv_next(&ac, &av);
2052                 if (!arg || *arg == '\0')
2053                         fatal("%s line %d: %s missing argument.",
2054                             filename, linenum, keyword);
2055                 if (strcmp(arg, "none") == 0) { /* no limit */
2056                         value = INT_MAX;
2057                 } else {
2058                         if ((errstr = atoi_err(arg, &value)) != NULL)
2059                                 fatal("%s line %d: %s integer value %s.",
2060                                     filename, linenum, keyword, errstr);
2061                 }
2062                 if (*activep && options->per_source_max_startups == -1)
2063                         options->per_source_max_startups = value;
2064                 break;
2065
2066         case sMaxAuthTries:
2067                 intptr = &options->max_authtries;
2068                 goto parse_int;
2069
2070         case sMaxSessions:
2071                 intptr = &options->max_sessions;
2072                 goto parse_int;
2073
2074         case sBanner:
2075                 charptr = &options->banner;
2076                 goto parse_filename;
2077
2078         /*
2079          * These options can contain %X options expanded at
2080          * connect time, so that you can specify paths like:
2081          *
2082          * AuthorizedKeysFile   /etc/ssh_keys/%u
2083          */
2084         case sAuthorizedKeysFile:
2085                 uvalue = options->num_authkeys_files;
2086                 while ((arg = argv_next(&ac, &av)) != NULL) {
2087                         if (*arg == '\0') {
2088                                 error("%s line %d: keyword %s empty argument",
2089                                     filename, linenum, keyword);
2090                                 goto out;
2091                         }
2092                         arg2 = tilde_expand_filename(arg, getuid());
2093                         if (*activep && uvalue == 0) {
2094                                 opt_array_append(filename, linenum, keyword,
2095                                     &options->authorized_keys_files,
2096                                     &options->num_authkeys_files, arg2);
2097                         }
2098                         free(arg2);
2099                 }
2100                 break;
2101
2102         case sAuthorizedPrincipalsFile:
2103                 charptr = &options->authorized_principals_file;
2104                 arg = argv_next(&ac, &av);
2105                 if (!arg || *arg == '\0')
2106                         fatal("%s line %d: %s missing argument.",
2107                             filename, linenum, keyword);
2108                 if (*activep && *charptr == NULL) {
2109                         *charptr = tilde_expand_filename(arg, getuid());
2110                         /* increase optional counter */
2111                         if (intptr != NULL)
2112                                 *intptr = *intptr + 1;
2113                 }
2114                 break;
2115
2116         case sClientAliveInterval:
2117                 intptr = &options->client_alive_interval;
2118                 goto parse_time;
2119
2120         case sClientAliveCountMax:
2121                 intptr = &options->client_alive_count_max;
2122                 goto parse_int;
2123
2124         case sAcceptEnv:
2125                 while ((arg = argv_next(&ac, &av)) != NULL) {
2126                         if (*arg == '\0' || strchr(arg, '=') != NULL)
2127                                 fatal("%s line %d: Invalid environment name.",
2128                                     filename, linenum);
2129                         if (!*activep)
2130                                 continue;
2131                         opt_array_append(filename, linenum, keyword,
2132                             &options->accept_env, &options->num_accept_env,
2133                             arg);
2134                 }
2135                 break;
2136
2137         case sSetEnv:
2138                 uvalue = options->num_setenv;
2139                 while ((arg = argv_next(&ac, &av)) != NULL) {
2140                         if (*arg == '\0' || strchr(arg, '=') == NULL)
2141                                 fatal("%s line %d: Invalid environment.",
2142                                     filename, linenum);
2143                         if (!*activep || uvalue != 0)
2144                                 continue;
2145                         if (lookup_setenv_in_list(arg, options->setenv,
2146                             options->num_setenv) != NULL) {
2147                                 debug2("%s line %d: ignoring duplicate env "
2148                                     "name \"%.64s\"", filename, linenum, arg);
2149                                 continue;
2150                         }
2151                         opt_array_append(filename, linenum, keyword,
2152                             &options->setenv, &options->num_setenv, arg);
2153                 }
2154                 break;
2155
2156         case sPermitTunnel:
2157                 intptr = &options->permit_tun;
2158                 arg = argv_next(&ac, &av);
2159                 if (!arg || *arg == '\0')
2160                         fatal("%s line %d: %s missing argument.",
2161                             filename, linenum, keyword);
2162                 value = -1;
2163                 for (i = 0; tunmode_desc[i].val != -1; i++)
2164                         if (strcmp(tunmode_desc[i].text, arg) == 0) {
2165                                 value = tunmode_desc[i].val;
2166                                 break;
2167                         }
2168                 if (value == -1)
2169                         fatal("%s line %d: bad %s argument %s",
2170                             filename, linenum, keyword, arg);
2171                 if (*activep && *intptr == -1)
2172                         *intptr = value;
2173                 break;
2174
2175         case sInclude:
2176                 if (cmdline) {
2177                         fatal("Include directive not supported as a "
2178                             "command-line option");
2179                 }
2180                 value = 0;
2181                 while ((arg2 = argv_next(&ac, &av)) != NULL) {
2182                         if (*arg2 == '\0') {
2183                                 error("%s line %d: keyword %s empty argument",
2184                                     filename, linenum, keyword);
2185                                 goto out;
2186                         }
2187                         value++;
2188                         found = 0;
2189                         if (*arg2 != '/' && *arg2 != '~') {
2190                                 xasprintf(&arg, "%s/%s", SSHDIR, arg2);
2191                         } else
2192                                 arg = xstrdup(arg2);
2193
2194                         /*
2195                          * Don't let included files clobber the containing
2196                          * file's Match state.
2197                          */
2198                         oactive = *activep;
2199
2200                         /* consult cache of include files */
2201                         TAILQ_FOREACH(item, includes, entry) {
2202                                 if (strcmp(item->selector, arg) != 0)
2203                                         continue;
2204                                 if (item->filename != NULL) {
2205                                         parse_server_config_depth(options,
2206                                             item->filename, item->contents,
2207                                             includes, connectinfo,
2208                                             (*inc_flags & SSHCFG_MATCH_ONLY
2209                                                 ? SSHCFG_MATCH_ONLY : (oactive
2210                                                     ? 0 : SSHCFG_NEVERMATCH)),
2211                                             activep, depth + 1);
2212                                 }
2213                                 found = 1;
2214                                 *activep = oactive;
2215                         }
2216                         if (found != 0) {
2217                                 free(arg);
2218                                 continue;
2219                         }
2220
2221                         /* requested glob was not in cache */
2222                         debug2("%s line %d: new include %s",
2223                             filename, linenum, arg);
2224                         if ((r = glob(arg, 0, NULL, &gbuf)) != 0) {
2225                                 if (r != GLOB_NOMATCH) {
2226                                         fatal("%s line %d: include \"%s\" glob "
2227                                             "failed", filename, linenum, arg);
2228                                 }
2229                                 /*
2230                                  * If no entry matched then record a
2231                                  * placeholder to skip later glob calls.
2232                                  */
2233                                 debug2("%s line %d: no match for %s",
2234                                     filename, linenum, arg);
2235                                 item = xcalloc(1, sizeof(*item));
2236                                 item->selector = strdup(arg);
2237                                 TAILQ_INSERT_TAIL(includes,
2238                                     item, entry);
2239                         }
2240                         if (gbuf.gl_pathc > INT_MAX)
2241                                 fatal_f("too many glob results");
2242                         for (n = 0; n < (int)gbuf.gl_pathc; n++) {
2243                                 debug2("%s line %d: including %s",
2244                                     filename, linenum, gbuf.gl_pathv[n]);
2245                                 item = xcalloc(1, sizeof(*item));
2246                                 item->selector = strdup(arg);
2247                                 item->filename = strdup(gbuf.gl_pathv[n]);
2248                                 if ((item->contents = sshbuf_new()) == NULL)
2249                                         fatal_f("sshbuf_new failed");
2250                                 load_server_config(item->filename,
2251                                     item->contents);
2252                                 parse_server_config_depth(options,
2253                                     item->filename, item->contents,
2254                                     includes, connectinfo,
2255                                     (*inc_flags & SSHCFG_MATCH_ONLY
2256                                         ? SSHCFG_MATCH_ONLY : (oactive
2257                                             ? 0 : SSHCFG_NEVERMATCH)),
2258                                     activep, depth + 1);
2259                                 *activep = oactive;
2260                                 TAILQ_INSERT_TAIL(includes, item, entry);
2261                         }
2262                         globfree(&gbuf);
2263                         free(arg);
2264                 }
2265                 if (value == 0) {
2266                         fatal("%s line %d: %s missing filename argument",
2267                             filename, linenum, keyword);
2268                 }
2269                 break;
2270
2271         case sMatch:
2272                 if (cmdline)
2273                         fatal("Match directive not supported as a command-line "
2274                             "option");
2275                 value = match_cfg_line(&str, linenum,
2276                     (*inc_flags & SSHCFG_NEVERMATCH ? NULL : connectinfo));
2277                 if (value < 0)
2278                         fatal("%s line %d: Bad Match condition", filename,
2279                             linenum);
2280                 *activep = (*inc_flags & SSHCFG_NEVERMATCH) ? 0 : value;
2281                 /*
2282                  * The MATCH_ONLY flag is applicable only until the first
2283                  * match block.
2284                  */
2285                 *inc_flags &= ~SSHCFG_MATCH_ONLY;
2286                 /*
2287                  * If match_cfg_line() didn't consume all its arguments then
2288                  * arrange for the extra arguments check below to fail.
2289                  */
2290                 if (str == NULL || *str == '\0')
2291                         argv_consume(&ac);
2292                 break;
2293
2294         case sPermitListen:
2295         case sPermitOpen:
2296                 if (opcode == sPermitListen) {
2297                         uintptr = &options->num_permitted_listens;
2298                         chararrayptr = &options->permitted_listens;
2299                 } else {
2300                         uintptr = &options->num_permitted_opens;
2301                         chararrayptr = &options->permitted_opens;
2302                 }
2303                 arg = argv_next(&ac, &av);
2304                 if (!arg || *arg == '\0')
2305                         fatal("%s line %d: %s missing argument.",
2306                             filename, linenum, keyword);
2307                 uvalue = *uintptr;      /* modified later */
2308                 if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) {
2309                         if (*activep && uvalue == 0) {
2310                                 *uintptr = 1;
2311                                 *chararrayptr = xcalloc(1,
2312                                     sizeof(**chararrayptr));
2313                                 (*chararrayptr)[0] = xstrdup(arg);
2314                         }
2315                         break;
2316                 }
2317                 for (; arg != NULL && *arg != '\0'; arg = argv_next(&ac, &av)) {
2318                         if (opcode == sPermitListen &&
2319                             strchr(arg, ':') == NULL) {
2320                                 /*
2321                                  * Allow bare port number for PermitListen
2322                                  * to indicate a wildcard listen host.
2323                                  */
2324                                 xasprintf(&arg2, "*:%s", arg);
2325                         } else {
2326                                 arg2 = xstrdup(arg);
2327                                 p = hpdelim(&arg);
2328                                 if (p == NULL) {
2329                                         fatal("%s line %d: %s missing host",
2330                                             filename, linenum, keyword);
2331                                 }
2332                                 p = cleanhostname(p);
2333                         }
2334                         if (arg == NULL ||
2335                             ((port = permitopen_port(arg)) < 0)) {
2336                                 fatal("%s line %d: %s bad port number",
2337                                     filename, linenum, keyword);
2338                         }
2339                         if (*activep && uvalue == 0) {
2340                                 opt_array_append(filename, linenum, keyword,
2341                                     chararrayptr, uintptr, arg2);
2342                         }
2343                         free(arg2);
2344                 }
2345                 break;
2346
2347         case sForceCommand:
2348                 if (str == NULL || *str == '\0')
2349                         fatal("%s line %d: %s missing argument.",
2350                             filename, linenum, keyword);
2351                 len = strspn(str, WHITESPACE);
2352                 if (*activep && options->adm_forced_command == NULL)
2353                         options->adm_forced_command = xstrdup(str + len);
2354                 argv_consume(&ac);
2355                 break;
2356
2357         case sChrootDirectory:
2358                 charptr = &options->chroot_directory;
2359
2360                 arg = argv_next(&ac, &av);
2361                 if (!arg || *arg == '\0')
2362                         fatal("%s line %d: %s missing argument.",
2363                             filename, linenum, keyword);
2364                 if (*activep && *charptr == NULL)
2365                         *charptr = xstrdup(arg);
2366                 break;
2367
2368         case sTrustedUserCAKeys:
2369                 charptr = &options->trusted_user_ca_keys;
2370                 goto parse_filename;
2371
2372         case sRevokedKeys:
2373                 charptr = &options->revoked_keys_file;
2374                 goto parse_filename;
2375
2376         case sSecurityKeyProvider:
2377                 charptr = &options->sk_provider;
2378                 arg = argv_next(&ac, &av);
2379                 if (!arg || *arg == '\0')
2380                         fatal("%s line %d: %s missing argument.",
2381                             filename, linenum, keyword);
2382                 if (*activep && *charptr == NULL) {
2383                         *charptr = strcasecmp(arg, "internal") == 0 ?
2384                             xstrdup(arg) : derelativise_path(arg);
2385                         /* increase optional counter */
2386                         if (intptr != NULL)
2387                                 *intptr = *intptr + 1;
2388                 }
2389                 break;
2390
2391         case sIPQoS:
2392                 arg = argv_next(&ac, &av);
2393                 if (!arg || *arg == '\0')
2394                         fatal("%s line %d: %s missing argument.",
2395                             filename, linenum, keyword);
2396                 if ((value = parse_ipqos(arg)) == -1)
2397                         fatal("%s line %d: Bad %s value: %s",
2398                             filename, linenum, keyword, arg);
2399                 arg = argv_next(&ac, &av);
2400                 if (arg == NULL)
2401                         value2 = value;
2402                 else if ((value2 = parse_ipqos(arg)) == -1)
2403                         fatal("%s line %d: Bad %s value: %s",
2404                             filename, linenum, keyword, arg);
2405                 if (*activep) {
2406                         options->ip_qos_interactive = value;
2407                         options->ip_qos_bulk = value2;
2408                 }
2409                 break;
2410
2411         case sVersionAddendum:
2412                 if (str == NULL || *str == '\0')
2413                         fatal("%s line %d: %s missing argument.",
2414                             filename, linenum, keyword);
2415                 len = strspn(str, WHITESPACE);
2416                 if (strchr(str + len, '\r') != NULL) {
2417                         fatal("%.200s line %d: Invalid %s argument",
2418                             filename, linenum, keyword);
2419                 }
2420                 if ((arg = strchr(line, '#')) != NULL) {
2421                         *arg = '\0';
2422                         rtrim(line);
2423                 }
2424                 if (*activep && options->version_addendum == NULL) {
2425                         if (strcasecmp(str + len, "none") == 0)
2426                                 options->version_addendum = xstrdup("");
2427                         else
2428                                 options->version_addendum = xstrdup(str + len);
2429                 }
2430                 argv_consume(&ac);
2431                 break;
2432
2433         case sAuthorizedKeysCommand:
2434                 charptr = &options->authorized_keys_command;
2435  parse_command:
2436                 len = strspn(str, WHITESPACE);
2437                 if (str[len] != '/' && strcasecmp(str + len, "none") != 0) {
2438                         fatal("%.200s line %d: %s must be an absolute path",
2439                             filename, linenum, keyword);
2440                 }
2441                 if (*activep && *charptr == NULL)
2442                         *charptr = xstrdup(str + len);
2443                 argv_consume(&ac);
2444                 break;
2445
2446         case sAuthorizedKeysCommandUser:
2447                 charptr = &options->authorized_keys_command_user;
2448  parse_localuser:
2449                 arg = argv_next(&ac, &av);
2450                 if (!arg || *arg == '\0') {
2451                         fatal("%s line %d: missing %s argument.",
2452                             filename, linenum, keyword);
2453                 }
2454                 if (*activep && *charptr == NULL)
2455                         *charptr = xstrdup(arg);
2456                 break;
2457
2458         case sAuthorizedPrincipalsCommand:
2459                 charptr = &options->authorized_principals_command;
2460                 goto parse_command;
2461
2462         case sAuthorizedPrincipalsCommandUser:
2463                 charptr = &options->authorized_principals_command_user;
2464                 goto parse_localuser;
2465
2466         case sAuthenticationMethods:
2467                 found = options->num_auth_methods == 0;
2468                 value = 0; /* seen "any" pseudo-method */
2469                 value2 = 0; /* successfully parsed any method */
2470                 while ((arg = argv_next(&ac, &av)) != NULL) {
2471                         if (strcmp(arg, "any") == 0) {
2472                                 if (options->num_auth_methods > 0) {
2473                                         fatal("%s line %d: \"any\" must "
2474                                             "appear alone in %s",
2475                                             filename, linenum, keyword);
2476                                 }
2477                                 value = 1;
2478                         } else if (value) {
2479                                 fatal("%s line %d: \"any\" must appear "
2480                                     "alone in %s", filename, linenum, keyword);
2481                         } else if (auth2_methods_valid(arg, 0) != 0) {
2482                                 fatal("%s line %d: invalid %s method list.",
2483                                     filename, linenum, keyword);
2484                         }
2485                         value2 = 1;
2486                         if (!found || !*activep)
2487                                 continue;
2488                         opt_array_append(filename, linenum, keyword,
2489                             &options->auth_methods,
2490                             &options->num_auth_methods, arg);
2491                 }
2492                 if (value2 == 0) {
2493                         fatal("%s line %d: no %s specified",
2494                             filename, linenum, keyword);
2495                 }
2496                 break;
2497
2498         case sStreamLocalBindMask:
2499                 arg = argv_next(&ac, &av);
2500                 if (!arg || *arg == '\0')
2501                         fatal("%s line %d: %s missing argument.",
2502                             filename, linenum, keyword);
2503                 /* Parse mode in octal format */
2504                 value = strtol(arg, &p, 8);
2505                 if (arg == p || value < 0 || value > 0777)
2506                         fatal("%s line %d: Invalid %s.",
2507                             filename, linenum, keyword);
2508                 if (*activep)
2509                         options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
2510                 break;
2511
2512         case sStreamLocalBindUnlink:
2513                 intptr = &options->fwd_opts.streamlocal_bind_unlink;
2514                 goto parse_flag;
2515
2516         case sFingerprintHash:
2517                 arg = argv_next(&ac, &av);
2518                 if (!arg || *arg == '\0')
2519                         fatal("%s line %d: %s missing argument.",
2520                             filename, linenum, keyword);
2521                 if ((value = ssh_digest_alg_by_name(arg)) == -1)
2522                         fatal("%.200s line %d: Invalid %s algorithm \"%s\".",
2523                             filename, linenum, keyword, arg);
2524                 if (*activep)
2525                         options->fingerprint_hash = value;
2526                 break;
2527
2528         case sExposeAuthInfo:
2529                 intptr = &options->expose_userauth_info;
2530                 goto parse_flag;
2531
2532         case sRDomain:
2533 #if !defined(__OpenBSD__) && !defined(HAVE_SYS_SET_PROCESS_RDOMAIN)
2534                 fatal("%s line %d: setting RDomain not supported on this "
2535                     "platform.", filename, linenum);
2536 #endif
2537                 charptr = &options->routing_domain;
2538                 arg = argv_next(&ac, &av);
2539                 if (!arg || *arg == '\0')
2540                         fatal("%s line %d: %s missing argument.",
2541                             filename, linenum, keyword);
2542                 if (strcasecmp(arg, "none") != 0 && strcmp(arg, "%D") != 0 &&
2543                     !valid_rdomain(arg))
2544                         fatal("%s line %d: invalid routing domain",
2545                             filename, linenum);
2546                 if (*activep && *charptr == NULL)
2547                         *charptr = xstrdup(arg);
2548                 break;
2549
2550         case sRequiredRSASize:
2551                 intptr = &options->required_rsa_size;
2552                 goto parse_int;
2553
2554         case sChannelTimeout:
2555                 uvalue = options->num_channel_timeouts;
2556                 i = 0;
2557                 while ((arg = argv_next(&ac, &av)) != NULL) {
2558                         /* Allow "none" only in first position */
2559                         if (strcasecmp(arg, "none") == 0) {
2560                                 if (i > 0 || ac > 0) {
2561                                         error("%s line %d: keyword %s \"none\" "
2562                                             "argument must appear alone.",
2563                                             filename, linenum, keyword);
2564                                         goto out;
2565                                 }
2566                         } else if (parse_timeout(arg, NULL, NULL) != 0) {
2567                                 fatal("%s line %d: invalid channel timeout %s",
2568                                     filename, linenum, arg);
2569                         }
2570                         if (!*activep || uvalue != 0)
2571                                 continue;
2572                         opt_array_append(filename, linenum, keyword,
2573                             &options->channel_timeouts,
2574                             &options->num_channel_timeouts, arg);
2575                 }
2576                 break;
2577
2578         case sUnusedConnectionTimeout:
2579                 intptr = &options->unused_connection_timeout;
2580                 /* peek at first arg for "none" so we can reuse parse_time */
2581                 if (av[0] != NULL && strcasecmp(av[0], "none") == 0) {
2582                         (void)argv_next(&ac, &av); /* consume arg */
2583                         if (*activep)
2584                                 *intptr = 0;
2585                         break;
2586                 }
2587                 goto parse_time;
2588
2589         case sUseBlacklist:
2590                 intptr = &options->use_blacklist;
2591                 goto parse_flag;
2592
2593         case sDeprecated:
2594         case sIgnore:
2595         case sUnsupported:
2596                 do_log2(opcode == sIgnore ?
2597                     SYSLOG_LEVEL_DEBUG2 : SYSLOG_LEVEL_INFO,
2598                     "%s line %d: %s option %s", filename, linenum,
2599                     opcode == sUnsupported ? "Unsupported" : "Deprecated",
2600                     keyword);
2601                 argv_consume(&ac);
2602                 break;
2603
2604         default:
2605                 fatal("%s line %d: Missing handler for opcode %s (%d)",
2606                     filename, linenum, keyword, opcode);
2607         }
2608         /* Check that there is no garbage at end of line. */
2609         if (ac > 0) {
2610                 error("%.200s line %d: keyword %s extra arguments "
2611                     "at end of line", filename, linenum, keyword);
2612                 goto out;
2613         }
2614
2615         /* success */
2616         ret = 0;
2617  out:
2618         argv_free(oav, oac);
2619         return ret;
2620 }
2621
2622 int
2623 process_server_config_line(ServerOptions *options, char *line,
2624     const char *filename, int linenum, int *activep,
2625     struct connection_info *connectinfo, struct include_list *includes)
2626 {
2627         int inc_flags = 0;
2628
2629         return process_server_config_line_depth(options, line, filename,
2630             linenum, activep, connectinfo, &inc_flags, 0, includes);
2631 }
2632
2633
2634 /* Reads the server configuration file. */
2635
2636 void
2637 load_server_config(const char *filename, struct sshbuf *conf)
2638 {
2639         struct stat st;
2640         char *line = NULL, *cp;
2641         size_t linesize = 0;
2642         FILE *f;
2643         int r;
2644
2645         debug2_f("filename %s", filename);
2646         if ((f = fopen(filename, "r")) == NULL) {
2647                 perror(filename);
2648                 exit(1);
2649         }
2650         sshbuf_reset(conf);
2651         /* grow buffer, so realloc is avoided for large config files */
2652         if (fstat(fileno(f), &st) == 0 && st.st_size > 0 &&
2653             (r = sshbuf_allocate(conf, st.st_size)) != 0)
2654                 fatal_fr(r, "allocate");
2655         while (getline(&line, &linesize, f) != -1) {
2656                 /*
2657                  * Strip whitespace
2658                  * NB - preserve newlines, they are needed to reproduce
2659                  * line numbers later for error messages
2660                  */
2661                 cp = line + strspn(line, " \t\r");
2662                 if ((r = sshbuf_put(conf, cp, strlen(cp))) != 0)
2663                         fatal_fr(r, "sshbuf_put");
2664         }
2665         free(line);
2666         if ((r = sshbuf_put_u8(conf, 0)) != 0)
2667                 fatal_fr(r, "sshbuf_put_u8");
2668         fclose(f);
2669         debug2_f("done config len = %zu", sshbuf_len(conf));
2670 }
2671
2672 void
2673 parse_server_match_config(ServerOptions *options,
2674    struct include_list *includes, struct connection_info *connectinfo)
2675 {
2676         ServerOptions mo;
2677
2678         initialize_server_options(&mo);
2679         parse_server_config(&mo, "reprocess config", cfg, includes,
2680             connectinfo, 0);
2681         copy_set_server_options(options, &mo, 0);
2682 }
2683
2684 int parse_server_match_testspec(struct connection_info *ci, char *spec)
2685 {
2686         char *p;
2687
2688         while ((p = strsep(&spec, ",")) && *p != '\0') {
2689                 if (strncmp(p, "addr=", 5) == 0) {
2690                         ci->address = xstrdup(p + 5);
2691                 } else if (strncmp(p, "host=", 5) == 0) {
2692                         ci->host = xstrdup(p + 5);
2693                 } else if (strncmp(p, "user=", 5) == 0) {
2694                         ci->user = xstrdup(p + 5);
2695                 } else if (strncmp(p, "laddr=", 6) == 0) {
2696                         ci->laddress = xstrdup(p + 6);
2697                 } else if (strncmp(p, "rdomain=", 8) == 0) {
2698                         ci->rdomain = xstrdup(p + 8);
2699                 } else if (strncmp(p, "lport=", 6) == 0) {
2700                         ci->lport = a2port(p + 6);
2701                         if (ci->lport == -1) {
2702                                 fprintf(stderr, "Invalid port '%s' in test mode"
2703                                     " specification %s\n", p+6, p);
2704                                 return -1;
2705                         }
2706                 } else {
2707                         fprintf(stderr, "Invalid test mode specification %s\n",
2708                             p);
2709                         return -1;
2710                 }
2711         }
2712         return 0;
2713 }
2714
2715 void
2716 servconf_merge_subsystems(ServerOptions *dst, ServerOptions *src)
2717 {
2718         u_int i, j, found;
2719
2720         for (i = 0; i < src->num_subsystems; i++) {
2721                 found = 0;
2722                 for (j = 0; j < dst->num_subsystems; j++) {
2723                         if (strcmp(src->subsystem_name[i],
2724                             dst->subsystem_name[j]) == 0) {
2725                                 found = 1;
2726                                 break;
2727                         }
2728                 }
2729                 if (found) {
2730                         debug_f("override \"%s\"", dst->subsystem_name[j]);
2731                         free(dst->subsystem_command[j]);
2732                         free(dst->subsystem_args[j]);
2733                         dst->subsystem_command[j] =
2734                             xstrdup(src->subsystem_command[i]);
2735                         dst->subsystem_args[j] =
2736                             xstrdup(src->subsystem_args[i]);
2737                         continue;
2738                 }
2739                 debug_f("add \"%s\"", src->subsystem_name[i]);
2740                 dst->subsystem_name = xrecallocarray(
2741                     dst->subsystem_name, dst->num_subsystems,
2742                     dst->num_subsystems + 1, sizeof(*dst->subsystem_name));
2743                 dst->subsystem_command = xrecallocarray(
2744                     dst->subsystem_command, dst->num_subsystems,
2745                     dst->num_subsystems + 1, sizeof(*dst->subsystem_command));
2746                 dst->subsystem_args = xrecallocarray(
2747                     dst->subsystem_args, dst->num_subsystems,
2748                     dst->num_subsystems + 1, sizeof(*dst->subsystem_args));
2749                 j = dst->num_subsystems++;
2750                 dst->subsystem_name[j] = xstrdup(src->subsystem_name[i]);
2751                 dst->subsystem_command[j] = xstrdup(src->subsystem_command[i]);
2752                 dst->subsystem_args[j] = xstrdup(src->subsystem_args[i]);
2753         }
2754 }
2755
2756 /*
2757  * Copy any supported values that are set.
2758  *
2759  * If the preauth flag is set, we do not bother copying the string or
2760  * array values that are not used pre-authentication, because any that we
2761  * do use must be explicitly sent in mm_getpwnamallow().
2762  */
2763 void
2764 copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
2765 {
2766 #define M_CP_INTOPT(n) do {\
2767         if (src->n != -1) \
2768                 dst->n = src->n; \
2769 } while (0)
2770
2771         M_CP_INTOPT(password_authentication);
2772         M_CP_INTOPT(gss_authentication);
2773         M_CP_INTOPT(pubkey_authentication);
2774         M_CP_INTOPT(pubkey_auth_options);
2775         M_CP_INTOPT(kerberos_authentication);
2776         M_CP_INTOPT(hostbased_authentication);
2777         M_CP_INTOPT(hostbased_uses_name_from_packet_only);
2778         M_CP_INTOPT(kbd_interactive_authentication);
2779         M_CP_INTOPT(permit_root_login);
2780         M_CP_INTOPT(permit_empty_passwd);
2781         M_CP_INTOPT(ignore_rhosts);
2782
2783         M_CP_INTOPT(allow_tcp_forwarding);
2784         M_CP_INTOPT(allow_streamlocal_forwarding);
2785         M_CP_INTOPT(allow_agent_forwarding);
2786         M_CP_INTOPT(disable_forwarding);
2787         M_CP_INTOPT(expose_userauth_info);
2788         M_CP_INTOPT(permit_tun);
2789         M_CP_INTOPT(fwd_opts.gateway_ports);
2790         M_CP_INTOPT(fwd_opts.streamlocal_bind_unlink);
2791         M_CP_INTOPT(x11_display_offset);
2792         M_CP_INTOPT(x11_forwarding);
2793         M_CP_INTOPT(x11_use_localhost);
2794         M_CP_INTOPT(permit_tty);
2795         M_CP_INTOPT(permit_user_rc);
2796         M_CP_INTOPT(max_sessions);
2797         M_CP_INTOPT(max_authtries);
2798         M_CP_INTOPT(client_alive_count_max);
2799         M_CP_INTOPT(client_alive_interval);
2800         M_CP_INTOPT(ip_qos_interactive);
2801         M_CP_INTOPT(ip_qos_bulk);
2802         M_CP_INTOPT(rekey_limit);
2803         M_CP_INTOPT(rekey_interval);
2804         M_CP_INTOPT(log_level);
2805         M_CP_INTOPT(required_rsa_size);
2806         M_CP_INTOPT(unused_connection_timeout);
2807
2808         /*
2809          * The bind_mask is a mode_t that may be unsigned, so we can't use
2810          * M_CP_INTOPT - it does a signed comparison that causes compiler
2811          * warnings.
2812          */
2813         if (src->fwd_opts.streamlocal_bind_mask != (mode_t)-1) {
2814                 dst->fwd_opts.streamlocal_bind_mask =
2815                     src->fwd_opts.streamlocal_bind_mask;
2816         }
2817
2818         /* M_CP_STROPT and M_CP_STRARRAYOPT should not appear before here */
2819 #define M_CP_STROPT(n) do {\
2820         if (src->n != NULL && dst->n != src->n) { \
2821                 free(dst->n); \
2822                 dst->n = src->n; \
2823         } \
2824 } while(0)
2825 #define M_CP_STRARRAYOPT(s, num_s) do {\
2826         u_int i; \
2827         if (src->num_s != 0) { \
2828                 for (i = 0; i < dst->num_s; i++) \
2829                         free(dst->s[i]); \
2830                 free(dst->s); \
2831                 dst->s = xcalloc(src->num_s, sizeof(*dst->s)); \
2832                 for (i = 0; i < src->num_s; i++) \
2833                         dst->s[i] = xstrdup(src->s[i]); \
2834                 dst->num_s = src->num_s; \
2835         } \
2836 } while(0)
2837
2838         /* See comment in servconf.h */
2839         COPY_MATCH_STRING_OPTS();
2840
2841         /* Arguments that accept '+...' need to be expanded */
2842         assemble_algorithms(dst);
2843
2844         /*
2845          * The only things that should be below this point are string options
2846          * which are only used after authentication.
2847          */
2848         if (preauth)
2849                 return;
2850
2851         /* These options may be "none" to clear a global setting */
2852         M_CP_STROPT(adm_forced_command);
2853         if (option_clear_or_none(dst->adm_forced_command)) {
2854                 free(dst->adm_forced_command);
2855                 dst->adm_forced_command = NULL;
2856         }
2857         M_CP_STROPT(chroot_directory);
2858         if (option_clear_or_none(dst->chroot_directory)) {
2859                 free(dst->chroot_directory);
2860                 dst->chroot_directory = NULL;
2861         }
2862
2863         /* Subsystems require merging. */
2864         servconf_merge_subsystems(dst, src);
2865 }
2866
2867 #undef M_CP_INTOPT
2868 #undef M_CP_STROPT
2869 #undef M_CP_STRARRAYOPT
2870
2871 #define SERVCONF_MAX_DEPTH      16
2872 static void
2873 parse_server_config_depth(ServerOptions *options, const char *filename,
2874     struct sshbuf *conf, struct include_list *includes,
2875     struct connection_info *connectinfo, int flags, int *activep, int depth)
2876 {
2877         int linenum, bad_options = 0;
2878         char *cp, *obuf, *cbuf;
2879
2880         if (depth < 0 || depth > SERVCONF_MAX_DEPTH)
2881                 fatal("Too many recursive configuration includes");
2882
2883         debug2_f("config %s len %zu%s", filename, sshbuf_len(conf),
2884             (flags & SSHCFG_NEVERMATCH ? " [checking syntax only]" : ""));
2885
2886         if ((obuf = cbuf = sshbuf_dup_string(conf)) == NULL)
2887                 fatal_f("sshbuf_dup_string failed");
2888         linenum = 1;
2889         while ((cp = strsep(&cbuf, "\n")) != NULL) {
2890                 if (process_server_config_line_depth(options, cp,
2891                     filename, linenum++, activep, connectinfo, &flags,
2892                     depth, includes) != 0)
2893                         bad_options++;
2894         }
2895         free(obuf);
2896         if (bad_options > 0)
2897                 fatal("%s: terminating, %d bad configuration options",
2898                     filename, bad_options);
2899 }
2900
2901 void
2902 parse_server_config(ServerOptions *options, const char *filename,
2903     struct sshbuf *conf, struct include_list *includes,
2904     struct connection_info *connectinfo, int reexec)
2905 {
2906         int active = connectinfo ? 0 : 1;
2907         parse_server_config_depth(options, filename, conf, includes,
2908             connectinfo, (connectinfo ? SSHCFG_MATCH_ONLY : 0), &active, 0);
2909         if (!reexec)
2910                 process_queued_listen_addrs(options);
2911 }
2912
2913 static const char *
2914 fmt_multistate_int(int val, const struct multistate *m)
2915 {
2916         u_int i;
2917
2918         for (i = 0; m[i].key != NULL; i++) {
2919                 if (m[i].value == val)
2920                         return m[i].key;
2921         }
2922         return "UNKNOWN";
2923 }
2924
2925 static const char *
2926 fmt_intarg(ServerOpCodes code, int val)
2927 {
2928         if (val == -1)
2929                 return "unset";
2930         switch (code) {
2931         case sAddressFamily:
2932                 return fmt_multistate_int(val, multistate_addressfamily);
2933         case sPermitRootLogin:
2934                 return fmt_multistate_int(val, multistate_permitrootlogin);
2935         case sGatewayPorts:
2936                 return fmt_multistate_int(val, multistate_gatewayports);
2937         case sCompression:
2938                 return fmt_multistate_int(val, multistate_compression);
2939         case sAllowTcpForwarding:
2940                 return fmt_multistate_int(val, multistate_tcpfwd);
2941         case sAllowStreamLocalForwarding:
2942                 return fmt_multistate_int(val, multistate_tcpfwd);
2943         case sIgnoreRhosts:
2944                 return fmt_multistate_int(val, multistate_ignore_rhosts);
2945         case sFingerprintHash:
2946                 return ssh_digest_alg_name(val);
2947         default:
2948                 switch (val) {
2949                 case 0:
2950                         return "no";
2951                 case 1:
2952                         return "yes";
2953                 default:
2954                         return "UNKNOWN";
2955                 }
2956         }
2957 }
2958
2959 static void
2960 dump_cfg_int(ServerOpCodes code, int val)
2961 {
2962         if (code == sUnusedConnectionTimeout && val == 0) {
2963                 printf("%s none\n", lookup_opcode_name(code));
2964                 return;
2965         }
2966         printf("%s %d\n", lookup_opcode_name(code), val);
2967 }
2968
2969 static void
2970 dump_cfg_oct(ServerOpCodes code, int val)
2971 {
2972         printf("%s 0%o\n", lookup_opcode_name(code), val);
2973 }
2974
2975 static void
2976 dump_cfg_fmtint(ServerOpCodes code, int val)
2977 {
2978         printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
2979 }
2980
2981 static void
2982 dump_cfg_string(ServerOpCodes code, const char *val)
2983 {
2984         printf("%s %s\n", lookup_opcode_name(code),
2985             val == NULL ? "none" : val);
2986 }
2987
2988 static void
2989 dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals)
2990 {
2991         u_int i;
2992
2993         for (i = 0; i < count; i++)
2994                 printf("%s %s\n", lookup_opcode_name(code), vals[i]);
2995 }
2996
2997 static void
2998 dump_cfg_strarray_oneline(ServerOpCodes code, u_int count, char **vals)
2999 {
3000         u_int i;
3001
3002         switch (code) {
3003         case sAuthenticationMethods:
3004         case sChannelTimeout:
3005                 break;
3006         default:
3007                 if (count <= 0)
3008                         return;
3009                 break;
3010         }
3011
3012         printf("%s", lookup_opcode_name(code));
3013         for (i = 0; i < count; i++)
3014                 printf(" %s",  vals[i]);
3015         if (code == sAuthenticationMethods && count == 0)
3016                 printf(" any");
3017         else if (code == sChannelTimeout && count == 0)
3018                 printf(" none");
3019         printf("\n");
3020 }
3021
3022 static char *
3023 format_listen_addrs(struct listenaddr *la)
3024 {
3025         int r;
3026         struct addrinfo *ai;
3027         char addr[NI_MAXHOST], port[NI_MAXSERV];
3028         char *laddr1 = xstrdup(""), *laddr2 = NULL;
3029
3030         /*
3031          * ListenAddress must be after Port.  add_one_listen_addr pushes
3032          * addresses onto a stack, so to maintain ordering we need to
3033          * print these in reverse order.
3034          */
3035         for (ai = la->addrs; ai; ai = ai->ai_next) {
3036                 if ((r = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
3037                     sizeof(addr), port, sizeof(port),
3038                     NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
3039                         error("getnameinfo: %.100s", ssh_gai_strerror(r));
3040                         continue;
3041                 }
3042                 laddr2 = laddr1;
3043                 if (ai->ai_family == AF_INET6) {
3044                         xasprintf(&laddr1, "listenaddress [%s]:%s%s%s\n%s",
3045                             addr, port,
3046                             la->rdomain == NULL ? "" : " rdomain ",
3047                             la->rdomain == NULL ? "" : la->rdomain,
3048                             laddr2);
3049                 } else {
3050                         xasprintf(&laddr1, "listenaddress %s:%s%s%s\n%s",
3051                             addr, port,
3052                             la->rdomain == NULL ? "" : " rdomain ",
3053                             la->rdomain == NULL ? "" : la->rdomain,
3054                             laddr2);
3055                 }
3056                 free(laddr2);
3057         }
3058         return laddr1;
3059 }
3060
3061 void
3062 dump_config(ServerOptions *o)
3063 {
3064         char *s;
3065         u_int i;
3066
3067         /* these are usually at the top of the config */
3068         for (i = 0; i < o->num_ports; i++)
3069                 printf("port %d\n", o->ports[i]);
3070         dump_cfg_fmtint(sAddressFamily, o->address_family);
3071
3072         for (i = 0; i < o->num_listen_addrs; i++) {
3073                 s = format_listen_addrs(&o->listen_addrs[i]);
3074                 printf("%s", s);
3075                 free(s);
3076         }
3077
3078         /* integer arguments */
3079 #ifdef USE_PAM
3080         dump_cfg_fmtint(sUsePAM, o->use_pam);
3081 #endif
3082         dump_cfg_int(sLoginGraceTime, o->login_grace_time);
3083         dump_cfg_int(sX11DisplayOffset, o->x11_display_offset);
3084         dump_cfg_int(sMaxAuthTries, o->max_authtries);
3085         dump_cfg_int(sMaxSessions, o->max_sessions);
3086         dump_cfg_int(sClientAliveInterval, o->client_alive_interval);
3087         dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max);
3088         dump_cfg_int(sRequiredRSASize, o->required_rsa_size);
3089         dump_cfg_oct(sStreamLocalBindMask, o->fwd_opts.streamlocal_bind_mask);
3090         dump_cfg_int(sUnusedConnectionTimeout, o->unused_connection_timeout);
3091
3092         /* formatted integer arguments */
3093         dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login);
3094         dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts);
3095         dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts);
3096         dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication);
3097         dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly,
3098             o->hostbased_uses_name_from_packet_only);
3099         dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication);
3100 #ifdef KRB5
3101         dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication);
3102         dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd);
3103         dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup);
3104 # ifdef USE_AFS
3105         dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
3106 # endif
3107 #endif
3108 #ifdef GSSAPI
3109         dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
3110         dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
3111 #endif
3112         dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
3113         dump_cfg_fmtint(sKbdInteractiveAuthentication,
3114             o->kbd_interactive_authentication);
3115         dump_cfg_fmtint(sPrintMotd, o->print_motd);
3116 #ifndef DISABLE_LASTLOG
3117         dump_cfg_fmtint(sPrintLastLog, o->print_lastlog);
3118 #endif
3119         dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding);
3120         dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost);
3121         dump_cfg_fmtint(sPermitTTY, o->permit_tty);
3122         dump_cfg_fmtint(sPermitUserRC, o->permit_user_rc);
3123         dump_cfg_fmtint(sStrictModes, o->strict_modes);
3124         dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive);
3125         dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd);
3126         dump_cfg_fmtint(sCompression, o->compression);
3127         dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports);
3128         dump_cfg_fmtint(sUseDNS, o->use_dns);
3129         dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
3130         dump_cfg_fmtint(sAllowAgentForwarding, o->allow_agent_forwarding);
3131         dump_cfg_fmtint(sDisableForwarding, o->disable_forwarding);
3132         dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding);
3133         dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
3134         dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash);
3135         dump_cfg_fmtint(sExposeAuthInfo, o->expose_userauth_info);
3136         dump_cfg_fmtint(sUseBlacklist, o->use_blacklist);
3137
3138         /* string arguments */
3139         dump_cfg_string(sPidFile, o->pid_file);
3140         dump_cfg_string(sModuliFile, o->moduli_file);
3141         dump_cfg_string(sXAuthLocation, o->xauth_location);
3142         dump_cfg_string(sCiphers, o->ciphers);
3143         dump_cfg_string(sMacs, o->macs);
3144         dump_cfg_string(sBanner, o->banner);
3145         dump_cfg_string(sForceCommand, o->adm_forced_command);
3146         dump_cfg_string(sChrootDirectory, o->chroot_directory);
3147         dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);
3148         dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
3149         dump_cfg_string(sSecurityKeyProvider, o->sk_provider);
3150         dump_cfg_string(sAuthorizedPrincipalsFile,
3151             o->authorized_principals_file);
3152         dump_cfg_string(sVersionAddendum, *o->version_addendum == '\0'
3153             ? "none" : o->version_addendum);
3154         dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command);
3155         dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user);
3156         dump_cfg_string(sAuthorizedPrincipalsCommand, o->authorized_principals_command);
3157         dump_cfg_string(sAuthorizedPrincipalsCommandUser, o->authorized_principals_command_user);
3158         dump_cfg_string(sHostKeyAgent, o->host_key_agent);
3159         dump_cfg_string(sKexAlgorithms, o->kex_algorithms);
3160         dump_cfg_string(sCASignatureAlgorithms, o->ca_sign_algorithms);
3161         dump_cfg_string(sHostbasedAcceptedAlgorithms, o->hostbased_accepted_algos);
3162         dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms);
3163         dump_cfg_string(sPubkeyAcceptedAlgorithms, o->pubkey_accepted_algos);
3164 #if defined(__OpenBSD__) || defined(HAVE_SYS_SET_PROCESS_RDOMAIN)
3165         dump_cfg_string(sRDomain, o->routing_domain);
3166 #endif
3167
3168         /* string arguments requiring a lookup */
3169         dump_cfg_string(sLogLevel, log_level_name(o->log_level));
3170         dump_cfg_string(sLogFacility, log_facility_name(o->log_facility));
3171
3172         /* string array arguments */
3173         dump_cfg_strarray_oneline(sAuthorizedKeysFile, o->num_authkeys_files,
3174             o->authorized_keys_files);
3175         dump_cfg_strarray(sHostKeyFile, o->num_host_key_files,
3176             o->host_key_files);
3177         dump_cfg_strarray(sHostCertificate, o->num_host_cert_files,
3178             o->host_cert_files);
3179         dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users);
3180         dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users);
3181         dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups);
3182         dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups);
3183         dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env);
3184         dump_cfg_strarray(sSetEnv, o->num_setenv, o->setenv);
3185         dump_cfg_strarray_oneline(sAuthenticationMethods,
3186             o->num_auth_methods, o->auth_methods);
3187         dump_cfg_strarray_oneline(sLogVerbose,
3188             o->num_log_verbose, o->log_verbose);
3189         dump_cfg_strarray_oneline(sChannelTimeout,
3190             o->num_channel_timeouts, o->channel_timeouts);
3191
3192         /* other arguments */
3193         for (i = 0; i < o->num_subsystems; i++)
3194                 printf("subsystem %s %s\n", o->subsystem_name[i],
3195                     o->subsystem_args[i]);
3196
3197         printf("maxstartups %d:%d:%d\n", o->max_startups_begin,
3198             o->max_startups_rate, o->max_startups);
3199         printf("persourcemaxstartups ");
3200         if (o->per_source_max_startups == INT_MAX)
3201                 printf("none\n");
3202         else
3203                 printf("%d\n", o->per_source_max_startups);
3204         printf("persourcenetblocksize %d:%d\n", o->per_source_masklen_ipv4,
3205             o->per_source_masklen_ipv6);
3206
3207         s = NULL;
3208         for (i = 0; tunmode_desc[i].val != -1; i++) {
3209                 if (tunmode_desc[i].val == o->permit_tun) {
3210                         s = tunmode_desc[i].text;
3211                         break;
3212                 }
3213         }
3214         dump_cfg_string(sPermitTunnel, s);
3215
3216         printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
3217         printf("%s\n", iptos2str(o->ip_qos_bulk));
3218
3219         printf("rekeylimit %llu %d\n", (unsigned long long)o->rekey_limit,
3220             o->rekey_interval);
3221
3222         printf("permitopen");
3223         if (o->num_permitted_opens == 0)
3224                 printf(" any");
3225         else {
3226                 for (i = 0; i < o->num_permitted_opens; i++)
3227                         printf(" %s", o->permitted_opens[i]);
3228         }
3229         printf("\n");
3230         printf("permitlisten");
3231         if (o->num_permitted_listens == 0)
3232                 printf(" any");
3233         else {
3234                 for (i = 0; i < o->num_permitted_listens; i++)
3235                         printf(" %s", o->permitted_listens[i]);
3236         }
3237         printf("\n");
3238
3239         if (o->permit_user_env_allowlist == NULL) {
3240                 dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env);
3241         } else {
3242                 printf("permituserenvironment %s\n",
3243                     o->permit_user_env_allowlist);
3244         }
3245
3246         printf("pubkeyauthoptions");
3247         if (o->pubkey_auth_options == 0)
3248                 printf(" none");
3249         if (o->pubkey_auth_options & PUBKEYAUTH_TOUCH_REQUIRED)
3250                 printf(" touch-required");
3251         if (o->pubkey_auth_options & PUBKEYAUTH_VERIFY_REQUIRED)
3252                 printf(" verify-required");
3253         printf("\n");
3254 }