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