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