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