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