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