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