2 /* $OpenBSD: servconf.c,v 1.386 2022/09/17 10:34:29 djm Exp $ */
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
7 * As far as I am concerned, the code I have written for this software
8 * can be used freely for any purpose. Any derived versions of this
9 * software must be clearly marked as such, and if the derived work is
10 * incompatible with the protocol description in the RFC file, it must be
11 * called by a name other than "ssh" or "Secure Shell".
16 #include <sys/types.h>
17 #include <sys/socket.h>
20 #include <sys/sysctl.h>
23 #include <netinet/in.h>
24 #include <netinet/in_systm.h>
25 #include <netinet/ip.h>
26 #ifdef HAVE_NET_ROUTE_H
27 #include <net/route.h>
44 #ifdef USE_SYSTEM_GLOB
47 # include "openbsd-compat/glob.h"
50 #include "openbsd-compat/sys-queue.h"
58 #include "pathnames.h"
65 #include "groupaccess.h"
71 #include "myproposal.h"
75 static void add_listen_addr(ServerOptions *, const char *,
77 static void add_one_listen_addr(ServerOptions *, const char *,
79 static void parse_server_config_depth(ServerOptions *options,
80 const char *filename, struct sshbuf *conf, struct include_list *includes,
81 struct connection_info *connectinfo, int flags, int *activep, int depth);
83 /* Use of privilege separation or not */
84 extern int use_privsep;
85 extern struct sshbuf *cfg;
87 /* Initializes the server options to their default values. */
90 initialize_server_options(ServerOptions *options)
92 memset(options, 0, sizeof(*options));
94 /* Portable-specific options */
95 options->use_pam = -1;
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->max_authtries = -1;
172 options->max_sessions = -1;
173 options->banner = NULL;
174 options->use_dns = -1;
175 options->client_alive_interval = -1;
176 options->client_alive_count_max = -1;
177 options->num_authkeys_files = 0;
178 options->num_accept_env = 0;
179 options->num_setenv = 0;
180 options->permit_tun = -1;
181 options->permitted_opens = NULL;
182 options->permitted_listens = NULL;
183 options->adm_forced_command = NULL;
184 options->chroot_directory = NULL;
185 options->authorized_keys_command = NULL;
186 options->authorized_keys_command_user = NULL;
187 options->revoked_keys_file = NULL;
188 options->sk_provider = NULL;
189 options->trusted_user_ca_keys = NULL;
190 options->authorized_principals_file = NULL;
191 options->authorized_principals_command = NULL;
192 options->authorized_principals_command_user = NULL;
193 options->ip_qos_interactive = -1;
194 options->ip_qos_bulk = -1;
195 options->version_addendum = NULL;
196 options->fingerprint_hash = -1;
197 options->disable_forwarding = -1;
198 options->expose_userauth_info = -1;
199 options->required_rsa_size = -1;
200 options->use_blacklist = -1;
203 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
205 option_clear_or_none(const char *o)
207 return o == NULL || strcasecmp(o, "none") == 0;
211 assemble_algorithms(ServerOptions *o)
213 char *all_cipher, *all_mac, *all_kex, *all_key, *all_sig;
214 char *def_cipher, *def_mac, *def_kex, *def_key, *def_sig;
217 all_cipher = cipher_alg_list(',', 0);
218 all_mac = mac_alg_list(',');
219 all_kex = kex_alg_list(',');
220 all_key = sshkey_alg_list(0, 0, 1, ',');
221 all_sig = sshkey_alg_list(0, 1, 1, ',');
222 /* remove unsupported algos from default lists */
223 def_cipher = match_filter_allowlist(KEX_SERVER_ENCRYPT, all_cipher);
224 def_mac = match_filter_allowlist(KEX_SERVER_MAC, all_mac);
225 def_kex = match_filter_allowlist(KEX_SERVER_KEX, all_kex);
226 def_key = match_filter_allowlist(KEX_DEFAULT_PK_ALG, all_key);
227 def_sig = match_filter_allowlist(SSH_ALLOWED_CA_SIGALGS, all_sig);
228 #define ASSEMBLE(what, defaults, all) \
230 if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \
231 fatal_fr(r, "%s", #what); \
233 ASSEMBLE(ciphers, def_cipher, all_cipher);
234 ASSEMBLE(macs, def_mac, all_mac);
235 ASSEMBLE(kex_algorithms, def_kex, all_kex);
236 ASSEMBLE(hostkeyalgorithms, def_key, all_key);
237 ASSEMBLE(hostbased_accepted_algos, def_key, all_key);
238 ASSEMBLE(pubkey_accepted_algos, def_key, all_key);
239 ASSEMBLE(ca_sign_algorithms, def_sig, all_sig);
253 static const char *defaultkey = "[default]";
256 servconf_add_hostkey(const char *file, const int line,
257 ServerOptions *options, const char *path, int userprovided)
259 char *apath = derelativise_path(path);
261 if (file == defaultkey && access(path, R_OK) != 0)
263 opt_array_append2(file, line, "HostKey",
264 &options->host_key_files, &options->host_key_file_userprovided,
265 &options->num_host_key_files, apath, userprovided);
270 servconf_add_hostcert(const char *file, const int line,
271 ServerOptions *options, const char *path)
273 char *apath = derelativise_path(path);
275 opt_array_append(file, line, "HostCertificate",
276 &options->host_cert_files, &options->num_host_cert_files, apath);
281 fill_default_server_options(ServerOptions *options)
285 /* Portable-specific options */
286 if (options->use_pam == -1)
287 options->use_pam = 1;
289 /* Standard Options */
290 if (options->num_host_key_files == 0) {
291 /* fill default hostkeys for protocols */
292 servconf_add_hostkey(defaultkey, 0, options,
293 _PATH_HOST_RSA_KEY_FILE, 0);
294 #ifdef OPENSSL_HAS_ECC
295 servconf_add_hostkey(defaultkey, 0, options,
296 _PATH_HOST_ECDSA_KEY_FILE, 0);
298 servconf_add_hostkey(defaultkey, 0, options,
299 _PATH_HOST_ED25519_KEY_FILE, 0);
301 servconf_add_hostkey(defaultkey, 0, options,
302 _PATH_HOST_XMSS_KEY_FILE, 0);
303 #endif /* WITH_XMSS */
305 if (options->num_host_key_files == 0)
306 fatal("No host key files found");
307 /* No certificates by default */
308 if (options->num_ports == 0)
309 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
310 if (options->address_family == -1)
311 options->address_family = AF_UNSPEC;
312 if (options->listen_addrs == NULL)
313 add_listen_addr(options, NULL, NULL, 0);
314 if (options->pid_file == NULL)
315 options->pid_file = xstrdup(_PATH_SSH_DAEMON_PID_FILE);
316 if (options->moduli_file == NULL)
317 options->moduli_file = xstrdup(_PATH_DH_MODULI);
318 if (options->login_grace_time == -1)
319 options->login_grace_time = 120;
320 if (options->permit_root_login == PERMIT_NOT_SET)
321 options->permit_root_login = PERMIT_NO;
322 if (options->ignore_rhosts == -1)
323 options->ignore_rhosts = 1;
324 if (options->ignore_user_known_hosts == -1)
325 options->ignore_user_known_hosts = 0;
326 if (options->print_motd == -1)
327 options->print_motd = 1;
328 if (options->print_lastlog == -1)
329 options->print_lastlog = 1;
330 if (options->x11_forwarding == -1)
331 options->x11_forwarding = 1;
332 if (options->x11_display_offset == -1)
333 options->x11_display_offset = 10;
334 if (options->x11_use_localhost == -1)
335 options->x11_use_localhost = 1;
336 if (options->xauth_location == NULL)
337 options->xauth_location = xstrdup(_PATH_XAUTH);
338 if (options->permit_tty == -1)
339 options->permit_tty = 1;
340 if (options->permit_user_rc == -1)
341 options->permit_user_rc = 1;
342 if (options->strict_modes == -1)
343 options->strict_modes = 1;
344 if (options->tcp_keep_alive == -1)
345 options->tcp_keep_alive = 1;
346 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
347 options->log_facility = SYSLOG_FACILITY_AUTH;
348 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
349 options->log_level = SYSLOG_LEVEL_INFO;
350 if (options->hostbased_authentication == -1)
351 options->hostbased_authentication = 0;
352 if (options->hostbased_uses_name_from_packet_only == -1)
353 options->hostbased_uses_name_from_packet_only = 0;
354 if (options->pubkey_authentication == -1)
355 options->pubkey_authentication = 1;
356 if (options->pubkey_auth_options == -1)
357 options->pubkey_auth_options = 0;
358 if (options->kerberos_authentication == -1)
359 options->kerberos_authentication = 0;
360 if (options->kerberos_or_local_passwd == -1)
361 options->kerberos_or_local_passwd = 1;
362 if (options->kerberos_ticket_cleanup == -1)
363 options->kerberos_ticket_cleanup = 1;
364 if (options->kerberos_get_afs_token == -1)
365 options->kerberos_get_afs_token = 0;
366 if (options->gss_authentication == -1)
367 options->gss_authentication = 0;
368 if (options->gss_cleanup_creds == -1)
369 options->gss_cleanup_creds = 1;
370 if (options->gss_strict_acceptor == -1)
371 options->gss_strict_acceptor = 1;
372 if (options->password_authentication == -1)
373 options->password_authentication = 0;
374 if (options->kbd_interactive_authentication == -1)
375 options->kbd_interactive_authentication = 1;
376 if (options->permit_empty_passwd == -1)
377 options->permit_empty_passwd = 0;
378 if (options->permit_user_env == -1) {
379 options->permit_user_env = 0;
380 options->permit_user_env_allowlist = NULL;
382 if (options->compression == -1)
384 options->compression = COMP_DELAYED;
386 options->compression = COMP_NONE;
389 if (options->rekey_limit == -1)
390 options->rekey_limit = 0;
391 if (options->rekey_interval == -1)
392 options->rekey_interval = 0;
393 if (options->allow_tcp_forwarding == -1)
394 options->allow_tcp_forwarding = FORWARD_ALLOW;
395 if (options->allow_streamlocal_forwarding == -1)
396 options->allow_streamlocal_forwarding = FORWARD_ALLOW;
397 if (options->allow_agent_forwarding == -1)
398 options->allow_agent_forwarding = 1;
399 if (options->fwd_opts.gateway_ports == -1)
400 options->fwd_opts.gateway_ports = 0;
401 if (options->max_startups == -1)
402 options->max_startups = 100;
403 if (options->max_startups_rate == -1)
404 options->max_startups_rate = 30; /* 30% */
405 if (options->max_startups_begin == -1)
406 options->max_startups_begin = 10;
407 if (options->per_source_max_startups == -1)
408 options->per_source_max_startups = INT_MAX;
409 if (options->per_source_masklen_ipv4 == -1)
410 options->per_source_masklen_ipv4 = 32;
411 if (options->per_source_masklen_ipv6 == -1)
412 options->per_source_masklen_ipv6 = 128;
413 if (options->max_authtries == -1)
414 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
415 if (options->max_sessions == -1)
416 options->max_sessions = DEFAULT_SESSIONS_MAX;
417 if (options->use_dns == -1)
418 options->use_dns = 1;
419 if (options->client_alive_interval == -1)
420 options->client_alive_interval = 0;
421 if (options->client_alive_count_max == -1)
422 options->client_alive_count_max = 3;
423 if (options->num_authkeys_files == 0) {
424 opt_array_append(defaultkey, 0, "AuthorizedKeysFiles",
425 &options->authorized_keys_files,
426 &options->num_authkeys_files,
427 _PATH_SSH_USER_PERMITTED_KEYS);
428 opt_array_append(defaultkey, 0, "AuthorizedKeysFiles",
429 &options->authorized_keys_files,
430 &options->num_authkeys_files,
431 _PATH_SSH_USER_PERMITTED_KEYS2);
433 if (options->permit_tun == -1)
434 options->permit_tun = SSH_TUNMODE_NO;
435 if (options->ip_qos_interactive == -1)
436 options->ip_qos_interactive = IPTOS_DSCP_AF21;
437 if (options->ip_qos_bulk == -1)
438 options->ip_qos_bulk = IPTOS_DSCP_CS1;
439 if (options->version_addendum == NULL)
440 options->version_addendum = xstrdup(SSH_VERSION_FREEBSD);
441 if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
442 options->fwd_opts.streamlocal_bind_mask = 0177;
443 if (options->fwd_opts.streamlocal_bind_unlink == -1)
444 options->fwd_opts.streamlocal_bind_unlink = 0;
445 if (options->fingerprint_hash == -1)
446 options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
447 if (options->disable_forwarding == -1)
448 options->disable_forwarding = 0;
449 if (options->expose_userauth_info == -1)
450 options->expose_userauth_info = 0;
451 if (options->sk_provider == NULL)
452 options->sk_provider = xstrdup("internal");
453 if (options->required_rsa_size == -1)
454 options->required_rsa_size = SSH_RSA_MINIMUM_MODULUS_SIZE;
455 if (options->use_blacklist == -1)
456 options->use_blacklist = 0;
458 assemble_algorithms(options);
460 /* Turn privilege separation and sandboxing on by default */
461 if (use_privsep == -1)
462 use_privsep = PRIVSEP_ON;
464 #define CLEAR_ON_NONE(v) \
466 if (option_clear_or_none(v)) { \
471 CLEAR_ON_NONE(options->pid_file);
472 CLEAR_ON_NONE(options->xauth_location);
473 CLEAR_ON_NONE(options->banner);
474 CLEAR_ON_NONE(options->trusted_user_ca_keys);
475 CLEAR_ON_NONE(options->revoked_keys_file);
476 CLEAR_ON_NONE(options->sk_provider);
477 CLEAR_ON_NONE(options->authorized_principals_file);
478 CLEAR_ON_NONE(options->adm_forced_command);
479 CLEAR_ON_NONE(options->chroot_directory);
480 CLEAR_ON_NONE(options->routing_domain);
481 CLEAR_ON_NONE(options->host_key_agent);
482 for (i = 0; i < options->num_host_key_files; i++)
483 CLEAR_ON_NONE(options->host_key_files[i]);
484 for (i = 0; i < options->num_host_cert_files; i++)
485 CLEAR_ON_NONE(options->host_cert_files[i]);
488 /* Similar handling for AuthenticationMethods=any */
489 if (options->num_auth_methods == 1 &&
490 strcmp(options->auth_methods[0], "any") == 0) {
491 free(options->auth_methods[0]);
492 options->auth_methods[0] = NULL;
493 options->num_auth_methods = 0;
497 /* Keyword tokens. */
499 sBadOption, /* == unknown option */
500 /* Portable-specific options */
502 /* Standard Options */
503 sPort, sHostKeyFile, sLoginGraceTime,
504 sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose,
505 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
506 sKerberosGetAFSToken, sPasswordAuthentication,
507 sKbdInteractiveAuthentication, sListenAddress, sAddressFamily,
508 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
509 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
510 sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive,
511 sPermitUserEnvironment, sAllowTcpForwarding, sCompression,
512 sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
513 sIgnoreUserKnownHosts, sCiphers, sMacs, sPidFile, sModuliFile,
514 sGatewayPorts, sPubkeyAuthentication, sPubkeyAcceptedAlgorithms,
515 sXAuthLocation, sSubsystem, sMaxStartups, sMaxAuthTries, sMaxSessions,
516 sBanner, sUseDNS, sHostbasedAuthentication,
517 sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedAlgorithms,
518 sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize,
519 sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
520 sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
521 sAcceptEnv, sSetEnv, sPermitTunnel,
522 sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory,
523 sUsePrivilegeSeparation, sAllowAgentForwarding,
524 sHostCertificate, sInclude,
525 sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
526 sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser,
527 sKexAlgorithms, sCASignatureAlgorithms, sIPQoS, sVersionAddendum,
528 sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
529 sAuthenticationMethods, sHostKeyAgent, sPermitUserRC,
530 sStreamLocalBindMask, sStreamLocalBindUnlink,
531 sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding,
532 sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider,
535 sDeprecated, sIgnore, sUnsupported
538 #define SSHCFG_GLOBAL 0x01 /* allowed in main section of config */
539 #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
540 #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
541 #define SSHCFG_NEVERMATCH 0x04 /* Match never matches; internal only */
542 #define SSHCFG_MATCH_ONLY 0x08 /* Match only in conditional blocks; internal only */
544 /* Textual representation of the tokens. */
547 ServerOpCodes opcode;
550 /* Portable-specific options */
552 { "usepam", sUsePAM, SSHCFG_GLOBAL },
554 { "usepam", sUnsupported, SSHCFG_GLOBAL },
556 { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
557 /* Standard Options */
558 { "port", sPort, SSHCFG_GLOBAL },
559 { "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
560 { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */
561 { "hostkeyagent", sHostKeyAgent, SSHCFG_GLOBAL },
562 { "pidfile", sPidFile, SSHCFG_GLOBAL },
563 { "modulifile", sModuliFile, SSHCFG_GLOBAL },
564 { "serverkeybits", sDeprecated, SSHCFG_GLOBAL },
565 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
566 { "keyregenerationinterval", sDeprecated, SSHCFG_GLOBAL },
567 { "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
568 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
569 { "loglevel", sLogLevel, SSHCFG_ALL },
570 { "logverbose", sLogVerbose, SSHCFG_ALL },
571 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
572 { "rhostsrsaauthentication", sDeprecated, SSHCFG_ALL },
573 { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
574 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_ALL },
575 { "hostbasedacceptedalgorithms", sHostbasedAcceptedAlgorithms, SSHCFG_ALL },
576 { "hostbasedacceptedkeytypes", sHostbasedAcceptedAlgorithms, SSHCFG_ALL }, /* obsolete */
577 { "hostkeyalgorithms", sHostKeyAlgorithms, SSHCFG_GLOBAL },
578 { "rsaauthentication", sDeprecated, SSHCFG_ALL },
579 { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
580 { "pubkeyacceptedalgorithms", sPubkeyAcceptedAlgorithms, SSHCFG_ALL },
581 { "pubkeyacceptedkeytypes", sPubkeyAcceptedAlgorithms, SSHCFG_ALL }, /* obsolete */
582 { "pubkeyauthoptions", sPubkeyAuthOptions, SSHCFG_ALL },
583 { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
585 { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
586 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
587 { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
589 { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
591 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
594 { "kerberosauthentication", sUnsupported, SSHCFG_ALL },
595 { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
596 { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
597 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
599 { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
600 { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
602 { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
603 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
604 { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
606 { "gssapiauthentication", sUnsupported, SSHCFG_ALL },
607 { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
608 { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
610 { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
611 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
612 { "challengeresponseauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, /* alias */
613 { "skeyauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, /* alias */
614 { "checkmail", sDeprecated, SSHCFG_GLOBAL },
615 { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
616 { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
617 { "printmotd", sPrintMotd, SSHCFG_GLOBAL },
618 #ifdef DISABLE_LASTLOG
619 { "printlastlog", sUnsupported, SSHCFG_GLOBAL },
621 { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
623 { "ignorerhosts", sIgnoreRhosts, SSHCFG_ALL },
624 { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
625 { "x11forwarding", sX11Forwarding, SSHCFG_ALL },
626 { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
627 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
628 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
629 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
630 { "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL },
631 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
632 { "uselogin", sDeprecated, SSHCFG_GLOBAL },
633 { "compression", sCompression, SSHCFG_GLOBAL },
634 { "rekeylimit", sRekeyLimit, SSHCFG_ALL },
635 { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
636 { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
637 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
638 { "allowagentforwarding", sAllowAgentForwarding, SSHCFG_ALL },
639 { "allowusers", sAllowUsers, SSHCFG_ALL },
640 { "denyusers", sDenyUsers, SSHCFG_ALL },
641 { "allowgroups", sAllowGroups, SSHCFG_ALL },
642 { "denygroups", sDenyGroups, SSHCFG_ALL },
643 { "ciphers", sCiphers, SSHCFG_GLOBAL },
644 { "macs", sMacs, SSHCFG_GLOBAL },
645 { "protocol", sIgnore, SSHCFG_GLOBAL },
646 { "gatewayports", sGatewayPorts, SSHCFG_ALL },
647 { "subsystem", sSubsystem, SSHCFG_GLOBAL },
648 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
649 { "persourcemaxstartups", sPerSourceMaxStartups, SSHCFG_GLOBAL },
650 { "persourcenetblocksize", sPerSourceNetBlockSize, SSHCFG_GLOBAL },
651 { "maxauthtries", sMaxAuthTries, SSHCFG_ALL },
652 { "maxsessions", sMaxSessions, SSHCFG_ALL },
653 { "banner", sBanner, SSHCFG_ALL },
654 { "usedns", sUseDNS, SSHCFG_GLOBAL },
655 { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
656 { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
657 { "clientaliveinterval", sClientAliveInterval, SSHCFG_ALL },
658 { "clientalivecountmax", sClientAliveCountMax, SSHCFG_ALL },
659 { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_ALL },
660 { "authorizedkeysfile2", sDeprecated, SSHCFG_ALL },
661 { "useprivilegeseparation", sDeprecated, SSHCFG_GLOBAL},
662 { "acceptenv", sAcceptEnv, SSHCFG_ALL },
663 { "setenv", sSetEnv, SSHCFG_ALL },
664 { "permittunnel", sPermitTunnel, SSHCFG_ALL },
665 { "permittty", sPermitTTY, SSHCFG_ALL },
666 { "permituserrc", sPermitUserRC, SSHCFG_ALL },
667 { "match", sMatch, SSHCFG_ALL },
668 { "permitopen", sPermitOpen, SSHCFG_ALL },
669 { "permitlisten", sPermitListen, SSHCFG_ALL },
670 { "forcecommand", sForceCommand, SSHCFG_ALL },
671 { "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
672 { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
673 { "revokedkeys", sRevokedKeys, SSHCFG_ALL },
674 { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
675 { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
676 { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
677 { "include", sInclude, SSHCFG_ALL },
678 { "ipqos", sIPQoS, SSHCFG_ALL },
679 { "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL },
680 { "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL },
681 { "authorizedprincipalscommand", sAuthorizedPrincipalsCommand, SSHCFG_ALL },
682 { "authorizedprincipalscommanduser", sAuthorizedPrincipalsCommandUser, SSHCFG_ALL },
683 { "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
684 { "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL },
685 { "streamlocalbindmask", sStreamLocalBindMask, SSHCFG_ALL },
686 { "streamlocalbindunlink", sStreamLocalBindUnlink, SSHCFG_ALL },
687 { "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL },
688 { "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL },
689 { "disableforwarding", sDisableForwarding, SSHCFG_ALL },
690 { "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL },
691 { "rdomain", sRDomain, SSHCFG_ALL },
692 { "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL },
693 { "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL },
694 { "requiredrsasize", sRequiredRSASize, SSHCFG_ALL },
695 { "useblacklist", sUseBlacklist, SSHCFG_GLOBAL },
696 { "useblocklist", sUseBlacklist, SSHCFG_GLOBAL }, /* alias */
697 { "noneenabled", sUnsupported, SSHCFG_ALL },
698 { "hpndisabled", sDeprecated, SSHCFG_ALL },
699 { "hpnbuffersize", sDeprecated, SSHCFG_ALL },
700 { "tcprcvbufpoll", sDeprecated, SSHCFG_ALL },
701 { NULL, sBadOption, 0 }
708 { SSH_TUNMODE_NO, "no" },
709 { SSH_TUNMODE_POINTOPOINT, "point-to-point" },
710 { SSH_TUNMODE_ETHERNET, "ethernet" },
711 { SSH_TUNMODE_YES, "yes" },
715 /* Returns an opcode name from its number */
718 lookup_opcode_name(ServerOpCodes code)
722 for (i = 0; keywords[i].name != NULL; i++)
723 if (keywords[i].opcode == code)
724 return(keywords[i].name);
730 * Returns the number of the token pointed to by cp or sBadOption.
734 parse_token(const char *cp, const char *filename,
735 int linenum, u_int *flags)
739 for (i = 0; keywords[i].name; i++)
740 if (strcasecmp(cp, keywords[i].name) == 0) {
741 *flags = keywords[i].flags;
742 return keywords[i].opcode;
745 error("%s: line %d: Bad configuration option: %s",
746 filename, linenum, cp);
751 derelativise_path(const char *path)
753 char *expanded, *ret, cwd[PATH_MAX];
755 if (strcasecmp(path, "none") == 0)
756 return xstrdup("none");
757 expanded = tilde_expand_filename(path, getuid());
758 if (path_absolute(expanded))
760 if (getcwd(cwd, sizeof(cwd)) == NULL)
761 fatal_f("getcwd: %s", strerror(errno));
762 xasprintf(&ret, "%s/%s", cwd, expanded);
768 add_listen_addr(ServerOptions *options, const char *addr,
769 const char *rdomain, int port)
774 add_one_listen_addr(options, addr, rdomain, port);
776 for (i = 0; i < options->num_ports; i++) {
777 add_one_listen_addr(options, addr, rdomain,
784 add_one_listen_addr(ServerOptions *options, const char *addr,
785 const char *rdomain, int port)
787 struct addrinfo hints, *ai, *aitop;
788 char strport[NI_MAXSERV];
792 /* Find listen_addrs entry for this rdomain */
793 for (i = 0; i < options->num_listen_addrs; i++) {
794 if (rdomain == NULL && options->listen_addrs[i].rdomain == NULL)
796 if (rdomain == NULL || options->listen_addrs[i].rdomain == NULL)
798 if (strcmp(rdomain, options->listen_addrs[i].rdomain) == 0)
801 if (i >= options->num_listen_addrs) {
802 /* No entry for this rdomain; allocate one */
804 fatal_f("too many listen addresses");
805 options->listen_addrs = xrecallocarray(options->listen_addrs,
806 options->num_listen_addrs, options->num_listen_addrs + 1,
807 sizeof(*options->listen_addrs));
808 i = options->num_listen_addrs++;
810 options->listen_addrs[i].rdomain = xstrdup(rdomain);
812 /* options->listen_addrs[i] points to the addresses for this rdomain */
814 memset(&hints, 0, sizeof(hints));
815 hints.ai_family = options->address_family;
816 hints.ai_socktype = SOCK_STREAM;
817 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
818 snprintf(strport, sizeof strport, "%d", port);
819 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
820 fatal("bad addr or host: %s (%s)",
821 addr ? addr : "<NULL>",
822 ssh_gai_strerror(gaierr));
823 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
825 ai->ai_next = options->listen_addrs[i].addrs;
826 options->listen_addrs[i].addrs = aitop;
829 /* Returns nonzero if the routing domain name is valid */
831 valid_rdomain(const char *name)
833 #if defined(HAVE_SYS_VALID_RDOMAIN)
834 return sys_valid_rdomain(name);
835 #elif defined(__OpenBSD__)
838 struct rt_tableinfo info;
840 size_t miblen = sizeof(mib);
845 num = strtonum(name, 0, 255, &errstr);
849 /* Check whether the table actually exists */
850 memset(mib, 0, sizeof(mib));
853 mib[4] = NET_RT_TABLE;
855 if (sysctl(mib, 6, &info, &miblen, NULL, 0) == -1)
859 #else /* defined(__OpenBSD__) */
860 error("Routing domains are not supported on this platform");
866 * Queue a ListenAddress to be processed once we have all of the Ports
867 * and AddressFamily options.
870 queue_listen_addr(ServerOptions *options, const char *addr,
871 const char *rdomain, int port)
873 struct queued_listenaddr *qla;
875 options->queued_listen_addrs = xrecallocarray(
876 options->queued_listen_addrs,
877 options->num_queued_listens, options->num_queued_listens + 1,
878 sizeof(*options->queued_listen_addrs));
879 qla = &options->queued_listen_addrs[options->num_queued_listens++];
880 qla->addr = xstrdup(addr);
882 qla->rdomain = rdomain == NULL ? NULL : xstrdup(rdomain);
886 * Process queued (text) ListenAddress entries.
889 process_queued_listen_addrs(ServerOptions *options)
892 struct queued_listenaddr *qla;
894 if (options->num_ports == 0)
895 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
896 if (options->address_family == -1)
897 options->address_family = AF_UNSPEC;
899 for (i = 0; i < options->num_queued_listens; i++) {
900 qla = &options->queued_listen_addrs[i];
901 add_listen_addr(options, qla->addr, qla->rdomain, qla->port);
905 free(options->queued_listen_addrs);
906 options->queued_listen_addrs = NULL;
907 options->num_queued_listens = 0;
911 * Inform channels layer of permitopen options for a single forwarding
912 * direction (local/remote).
915 process_permitopen_list(struct ssh *ssh, ServerOpCodes opcode,
916 char **opens, u_int num_opens)
920 char *host, *arg, *oarg;
921 int where = opcode == sPermitOpen ? FORWARD_LOCAL : FORWARD_REMOTE;
922 const char *what = lookup_opcode_name(opcode);
924 channel_clear_permission(ssh, FORWARD_ADM, where);
926 return; /* permit any */
928 /* handle keywords: "any" / "none" */
929 if (num_opens == 1 && strcmp(opens[0], "any") == 0)
931 if (num_opens == 1 && strcmp(opens[0], "none") == 0) {
932 channel_disable_admin(ssh, where);
935 /* Otherwise treat it as a list of permitted host:port */
936 for (i = 0; i < num_opens; i++) {
937 oarg = arg = xstrdup(opens[i]);
938 host = hpdelim(&arg);
940 fatal_f("missing host in %s", what);
941 host = cleanhostname(host);
942 if (arg == NULL || ((port = permitopen_port(arg)) < 0))
943 fatal_f("bad port number in %s", what);
944 /* Send it to channels layer */
945 channel_add_permission(ssh, FORWARD_ADM,
952 * Inform channels layer of permitopen options from configuration.
955 process_permitopen(struct ssh *ssh, ServerOptions *options)
957 process_permitopen_list(ssh, sPermitOpen,
958 options->permitted_opens, options->num_permitted_opens);
959 process_permitopen_list(ssh, sPermitListen,
960 options->permitted_listens,
961 options->num_permitted_listens);
964 struct connection_info *
965 get_connection_info(struct ssh *ssh, int populate, int use_dns)
967 static struct connection_info ci;
969 if (ssh == NULL || !populate)
971 ci.host = auth_get_canonical_hostname(ssh, use_dns);
972 ci.address = ssh_remote_ipaddr(ssh);
973 ci.laddress = ssh_local_ipaddr(ssh);
974 ci.lport = ssh_local_port(ssh);
975 ci.rdomain = ssh_packet_rdomain_in(ssh);
980 * The strategy for the Match blocks is that the config file is parsed twice.
982 * The first time is at startup. activep is initialized to 1 and the
983 * directives in the global context are processed and acted on. Hitting a
984 * Match directive unsets activep and the directives inside the block are
985 * checked for syntax only.
987 * The second time is after a connection has been established but before
988 * authentication. activep is initialized to 2 and global config directives
989 * are ignored since they have already been processed. If the criteria in a
990 * Match block is met, activep is set and the subsequent directives
991 * processed and actioned until EOF or another Match block unsets it. Any
992 * options set are copied into the main server config.
994 * Potential additions/improvements:
995 * - Add Match support for pre-kex directives, eg. Ciphers.
997 * - Add a Tag directive (idea from David Leonard) ala pf, eg:
998 * Match Address 192.168.0.*
1003 * AllowTcpForwarding yes
1004 * GatewayPorts clientspecified
1007 * - Add a PermittedChannelRequests directive
1009 * PermittedChannelRequests session,forwarded-tcpip
1013 match_cfg_line_group(const char *grps, int line, const char *user)
1021 if ((pw = getpwnam(user)) == NULL) {
1022 debug("Can't match group at line %d because user %.100s does "
1023 "not exist", line, user);
1024 } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
1025 debug("Can't Match group because user %.100s not in any group "
1026 "at line %d", user, line);
1027 } else if (ga_match_pattern_list(grps) != 1) {
1028 debug("user %.100s does not match group list %.100s at line %d",
1031 debug("user %.100s matched group list %.100s at line %d", user,
1041 match_test_missing_fatal(const char *criteria, const char *attrib)
1043 fatal("'Match %s' in configuration but '%s' not in connection "
1044 "test specification.", criteria, attrib);
1048 * All of the attributes on a single Match line are ANDed together, so we need
1049 * to check every attribute and set the result to zero if any attribute does
1053 match_cfg_line(char **condition, int line, struct connection_info *ci)
1055 int result = 1, attributes = 0, port;
1056 char *arg, *attrib, *cp = *condition;
1059 debug3("checking syntax for 'Match %s'", cp);
1061 debug3("checking match for '%s' user %s host %s addr %s "
1062 "laddr %s lport %d", cp, ci->user ? ci->user : "(null)",
1063 ci->host ? ci->host : "(null)",
1064 ci->address ? ci->address : "(null)",
1065 ci->laddress ? ci->laddress : "(null)", ci->lport);
1067 while ((attrib = strdelim(&cp)) && *attrib != '\0') {
1068 /* Terminate on comment */
1069 if (*attrib == '#') {
1070 cp = NULL; /* mark all arguments consumed */
1075 /* Criterion "all" has no argument and must appear alone */
1076 if (strcasecmp(attrib, "all") == 0) {
1077 if (attributes > 1 || ((arg = strdelim(&cp)) != NULL &&
1078 *arg != '\0' && *arg != '#')) {
1079 error("'all' cannot be combined with other "
1080 "Match attributes");
1083 if (arg != NULL && *arg == '#')
1084 cp = NULL; /* mark all arguments consumed */
1088 /* All other criteria require an argument */
1089 if ((arg = strdelim(&cp)) == NULL ||
1090 *arg == '\0' || *arg == '#') {
1091 error("Missing Match criteria for %s", attrib);
1094 if (strcasecmp(attrib, "user") == 0) {
1095 if (ci == NULL || (ci->test && ci->user == NULL)) {
1099 if (ci->user == NULL)
1100 match_test_missing_fatal("User", "user");
1101 if (match_usergroup_pattern_list(ci->user, arg) != 1)
1104 debug("user %.100s matched 'User %.100s' at "
1105 "line %d", ci->user, arg, line);
1106 } else if (strcasecmp(attrib, "group") == 0) {
1107 if (ci == NULL || (ci->test && ci->user == NULL)) {
1111 if (ci->user == NULL)
1112 match_test_missing_fatal("Group", "user");
1113 switch (match_cfg_line_group(arg, line, ci->user)) {
1119 } else if (strcasecmp(attrib, "host") == 0) {
1120 if (ci == NULL || (ci->test && ci->host == NULL)) {
1124 if (ci->host == NULL)
1125 match_test_missing_fatal("Host", "host");
1126 if (match_hostname(ci->host, arg) != 1)
1129 debug("connection from %.100s matched 'Host "
1130 "%.100s' at line %d", ci->host, arg, line);
1131 } else if (strcasecmp(attrib, "address") == 0) {
1132 if (ci == NULL || (ci->test && ci->address == NULL)) {
1133 if (addr_match_list(NULL, arg) != 0)
1134 fatal("Invalid Match address argument "
1135 "'%s' at line %d", arg, line);
1139 if (ci->address == NULL)
1140 match_test_missing_fatal("Address", "addr");
1141 switch (addr_match_list(ci->address, arg)) {
1143 debug("connection from %.100s matched 'Address "
1144 "%.100s' at line %d", ci->address, arg, line);
1153 } else if (strcasecmp(attrib, "localaddress") == 0){
1154 if (ci == NULL || (ci->test && ci->laddress == NULL)) {
1155 if (addr_match_list(NULL, arg) != 0)
1156 fatal("Invalid Match localaddress "
1157 "argument '%s' at line %d", arg,
1162 if (ci->laddress == NULL)
1163 match_test_missing_fatal("LocalAddress",
1165 switch (addr_match_list(ci->laddress, arg)) {
1167 debug("connection from %.100s matched "
1168 "'LocalAddress %.100s' at line %d",
1169 ci->laddress, arg, line);
1178 } else if (strcasecmp(attrib, "localport") == 0) {
1179 if ((port = a2port(arg)) == -1) {
1180 error("Invalid LocalPort '%s' on Match line",
1184 if (ci == NULL || (ci->test && ci->lport == -1)) {
1189 match_test_missing_fatal("LocalPort", "lport");
1190 /* TODO support port lists */
1191 if (port == ci->lport)
1192 debug("connection from %.100s matched "
1193 "'LocalPort %d' at line %d",
1194 ci->laddress, port, line);
1197 } else if (strcasecmp(attrib, "rdomain") == 0) {
1198 if (ci == NULL || (ci->test && ci->rdomain == NULL)) {
1202 if (ci->rdomain == NULL)
1203 match_test_missing_fatal("RDomain", "rdomain");
1204 if (match_pattern_list(ci->rdomain, arg, 0) != 1)
1207 debug("user %.100s matched 'RDomain %.100s' at "
1208 "line %d", ci->rdomain, arg, line);
1210 error("Unsupported Match attribute %s", attrib);
1214 if (attributes == 0) {
1215 error("One or more attributes required for Match");
1219 debug3("match %sfound", result ? "" : "not ");
1224 #define WHITESPACE " \t\r\n"
1226 /* Multistate option parsing */
1231 static const struct multistate multistate_flag[] = {
1236 static const struct multistate multistate_ignore_rhosts[] = {
1237 { "yes", IGNORE_RHOSTS_YES },
1238 { "no", IGNORE_RHOSTS_NO },
1239 { "shosts-only", IGNORE_RHOSTS_SHOSTS },
1242 static const struct multistate multistate_addressfamily[] = {
1243 { "inet", AF_INET },
1244 { "inet6", AF_INET6 },
1245 { "any", AF_UNSPEC },
1248 static const struct multistate multistate_permitrootlogin[] = {
1249 { "without-password", PERMIT_NO_PASSWD },
1250 { "prohibit-password", PERMIT_NO_PASSWD },
1251 { "forced-commands-only", PERMIT_FORCED_ONLY },
1252 { "yes", PERMIT_YES },
1253 { "no", PERMIT_NO },
1256 static const struct multistate multistate_compression[] = {
1258 { "yes", COMP_DELAYED },
1259 { "delayed", COMP_DELAYED },
1261 { "no", COMP_NONE },
1264 static const struct multistate multistate_gatewayports[] = {
1265 { "clientspecified", 2 },
1270 static const struct multistate multistate_tcpfwd[] = {
1271 { "yes", FORWARD_ALLOW },
1272 { "all", FORWARD_ALLOW },
1273 { "no", FORWARD_DENY },
1274 { "remote", FORWARD_REMOTE },
1275 { "local", FORWARD_LOCAL },
1280 process_server_config_line_depth(ServerOptions *options, char *line,
1281 const char *filename, int linenum, int *activep,
1282 struct connection_info *connectinfo, int *inc_flags, int depth,
1283 struct include_list *includes)
1285 char *str, ***chararrayptr, **charptr, *arg, *arg2, *p, *keyword;
1286 int cmdline = 0, *intptr, value, value2, n, port, oactive, r, found;
1287 SyslogFacility *log_facility_ptr;
1288 LogLevel *log_level_ptr;
1289 ServerOpCodes opcode;
1290 u_int i, *uintptr, uvalue, flags = 0;
1293 const struct multistate *multistate_ptr;
1295 struct include_item *item;
1297 char **oav = NULL, **av;
1301 /* Strip trailing whitespace. Allow \f (form feed) at EOL only */
1302 if ((len = strlen(line)) == 0)
1304 for (len--; len > 0; len--) {
1305 if (strchr(WHITESPACE "\f", line[len]) == NULL)
1311 if ((keyword = strdelim(&str)) == NULL)
1313 /* Ignore leading whitespace */
1314 if (*keyword == '\0')
1315 keyword = strdelim(&str);
1316 if (!keyword || !*keyword || *keyword == '#')
1318 if (str == NULL || *str == '\0') {
1319 error("%s line %d: no argument after keyword \"%s\"",
1320 filename, linenum, keyword);
1325 opcode = parse_token(keyword, filename, linenum, &flags);
1327 if (argv_split(str, &oac, &oav, 1) != 0) {
1328 error("%s line %d: invalid quotes", filename, linenum);
1334 if (activep == NULL) { /* We are processing a command line directive */
1338 if (*activep && opcode != sMatch && opcode != sInclude)
1339 debug3("%s:%d setting %s %s", filename, linenum, keyword, str);
1340 if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
1341 if (connectinfo == NULL) {
1342 fatal("%s line %d: Directive '%s' is not allowed "
1343 "within a Match block", filename, linenum, keyword);
1344 } else { /* this is a directive we have already processed */
1351 /* Portable-specific options */
1353 intptr = &options->use_pam;
1356 /* Standard Options */
1360 /* ignore ports from configfile if cmdline specifies ports */
1361 if (options->ports_from_cmdline) {
1365 if (options->num_ports >= MAX_PORTS)
1366 fatal("%s line %d: too many ports.",
1368 arg = argv_next(&ac, &av);
1369 if (!arg || *arg == '\0')
1370 fatal("%s line %d: missing port number.",
1372 options->ports[options->num_ports++] = a2port(arg);
1373 if (options->ports[options->num_ports-1] <= 0)
1374 fatal("%s line %d: Badly formatted port number.",
1378 case sLoginGraceTime:
1379 intptr = &options->login_grace_time;
1381 arg = argv_next(&ac, &av);
1382 if (!arg || *arg == '\0')
1383 fatal("%s line %d: missing time value.",
1385 if ((value = convtime(arg)) == -1)
1386 fatal("%s line %d: invalid time value.",
1388 if (*activep && *intptr == -1)
1392 case sListenAddress:
1393 arg = argv_next(&ac, &av);
1394 if (arg == NULL || *arg == '\0')
1395 fatal("%s line %d: missing address",
1397 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
1398 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
1399 && strchr(p+1, ':') != NULL) {
1406 fatal("%s line %d: bad address:port usage",
1408 p = cleanhostname(p);
1411 else if ((port = a2port(arg)) <= 0)
1412 fatal("%s line %d: bad port number",
1415 /* Optional routing table */
1417 if ((arg = argv_next(&ac, &av)) != NULL) {
1418 if (strcmp(arg, "rdomain") != 0 ||
1419 (arg2 = argv_next(&ac, &av)) == NULL)
1420 fatal("%s line %d: bad ListenAddress syntax",
1422 if (!valid_rdomain(arg2))
1423 fatal("%s line %d: bad routing domain",
1426 queue_listen_addr(options, p, arg2, port);
1430 case sAddressFamily:
1431 intptr = &options->address_family;
1432 multistate_ptr = multistate_addressfamily;
1434 arg = argv_next(&ac, &av);
1435 if (!arg || *arg == '\0')
1436 fatal("%s line %d: missing argument.",
1439 for (i = 0; multistate_ptr[i].key != NULL; i++) {
1440 if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
1441 value = multistate_ptr[i].value;
1446 fatal("%s line %d: unsupported option \"%s\".",
1447 filename, linenum, arg);
1448 if (*activep && *intptr == -1)
1453 arg = argv_next(&ac, &av);
1454 if (!arg || *arg == '\0')
1455 fatal("%s line %d: missing file name.",
1458 servconf_add_hostkey(filename, linenum,
1464 charptr = &options->host_key_agent;
1465 arg = argv_next(&ac, &av);
1466 if (!arg || *arg == '\0')
1467 fatal("%s line %d: missing socket name.",
1469 if (*activep && *charptr == NULL)
1470 *charptr = !strcmp(arg, SSH_AUTHSOCKET_ENV_NAME) ?
1471 xstrdup(arg) : derelativise_path(arg);
1474 case sHostCertificate:
1475 arg = argv_next(&ac, &av);
1476 if (!arg || *arg == '\0')
1477 fatal("%s line %d: missing file name.",
1480 servconf_add_hostcert(filename, linenum, options, arg);
1484 charptr = &options->pid_file;
1486 arg = argv_next(&ac, &av);
1487 if (!arg || *arg == '\0')
1488 fatal("%s line %d: missing file name.",
1490 if (*activep && *charptr == NULL) {
1491 *charptr = derelativise_path(arg);
1492 /* increase optional counter */
1494 *intptr = *intptr + 1;
1499 charptr = &options->moduli_file;
1500 goto parse_filename;
1502 case sPermitRootLogin:
1503 intptr = &options->permit_root_login;
1504 multistate_ptr = multistate_permitrootlogin;
1505 goto parse_multistate;
1508 intptr = &options->ignore_rhosts;
1509 multistate_ptr = multistate_ignore_rhosts;
1510 goto parse_multistate;
1512 case sIgnoreUserKnownHosts:
1513 intptr = &options->ignore_user_known_hosts;
1515 multistate_ptr = multistate_flag;
1516 goto parse_multistate;
1518 case sHostbasedAuthentication:
1519 intptr = &options->hostbased_authentication;
1522 case sHostbasedUsesNameFromPacketOnly:
1523 intptr = &options->hostbased_uses_name_from_packet_only;
1526 case sHostbasedAcceptedAlgorithms:
1527 charptr = &options->hostbased_accepted_algos;
1529 arg = argv_next(&ac, &av);
1530 if (!arg || *arg == '\0')
1531 fatal("%s line %d: Missing argument.",
1534 !sshkey_names_valid2(*arg == '+' || *arg == '^' ?
1536 fatal("%s line %d: Bad key types '%s'.",
1537 filename, linenum, arg ? arg : "<NONE>");
1538 if (*activep && *charptr == NULL)
1539 *charptr = xstrdup(arg);
1542 case sHostKeyAlgorithms:
1543 charptr = &options->hostkeyalgorithms;
1544 goto parse_pubkey_algos;
1546 case sCASignatureAlgorithms:
1547 charptr = &options->ca_sign_algorithms;
1548 goto parse_pubkey_algos;
1550 case sPubkeyAuthentication:
1551 intptr = &options->pubkey_authentication;
1554 case sPubkeyAcceptedAlgorithms:
1555 charptr = &options->pubkey_accepted_algos;
1556 goto parse_pubkey_algos;
1558 case sPubkeyAuthOptions:
1559 intptr = &options->pubkey_auth_options;
1561 while ((arg = argv_next(&ac, &av)) != NULL) {
1562 if (strcasecmp(arg, "none") == 0)
1564 if (strcasecmp(arg, "touch-required") == 0)
1565 value |= PUBKEYAUTH_TOUCH_REQUIRED;
1566 else if (strcasecmp(arg, "verify-required") == 0)
1567 value |= PUBKEYAUTH_VERIFY_REQUIRED;
1569 error("%s line %d: unsupported %s option %s",
1570 filename, linenum, keyword, arg);
1574 if (*activep && *intptr == -1)
1578 case sKerberosAuthentication:
1579 intptr = &options->kerberos_authentication;
1582 case sKerberosOrLocalPasswd:
1583 intptr = &options->kerberos_or_local_passwd;
1586 case sKerberosTicketCleanup:
1587 intptr = &options->kerberos_ticket_cleanup;
1590 case sKerberosGetAFSToken:
1591 intptr = &options->kerberos_get_afs_token;
1594 case sGssAuthentication:
1595 intptr = &options->gss_authentication;
1598 case sGssCleanupCreds:
1599 intptr = &options->gss_cleanup_creds;
1602 case sGssStrictAcceptor:
1603 intptr = &options->gss_strict_acceptor;
1606 case sPasswordAuthentication:
1607 intptr = &options->password_authentication;
1610 case sKbdInteractiveAuthentication:
1611 intptr = &options->kbd_interactive_authentication;
1615 intptr = &options->print_motd;
1619 intptr = &options->print_lastlog;
1622 case sX11Forwarding:
1623 intptr = &options->x11_forwarding;
1626 case sX11DisplayOffset:
1627 intptr = &options->x11_display_offset;
1629 arg = argv_next(&ac, &av);
1630 if ((errstr = atoi_err(arg, &value)) != NULL)
1631 fatal("%s line %d: %s integer value %s.",
1632 filename, linenum, keyword, errstr);
1633 if (*activep && *intptr == -1)
1637 case sX11UseLocalhost:
1638 intptr = &options->x11_use_localhost;
1641 case sXAuthLocation:
1642 charptr = &options->xauth_location;
1643 goto parse_filename;
1646 intptr = &options->permit_tty;
1650 intptr = &options->permit_user_rc;
1654 intptr = &options->strict_modes;
1658 intptr = &options->tcp_keep_alive;
1662 intptr = &options->permit_empty_passwd;
1665 case sPermitUserEnvironment:
1666 intptr = &options->permit_user_env;
1667 charptr = &options->permit_user_env_allowlist;
1668 arg = argv_next(&ac, &av);
1669 if (!arg || *arg == '\0')
1670 fatal("%s line %d: %s missing argument.",
1671 filename, linenum, keyword);
1674 if (strcmp(arg, "yes") == 0)
1676 else if (strcmp(arg, "no") == 0)
1679 /* Pattern-list specified */
1683 if (*activep && *intptr == -1) {
1692 intptr = &options->compression;
1693 multistate_ptr = multistate_compression;
1694 goto parse_multistate;
1697 arg = argv_next(&ac, &av);
1698 if (!arg || *arg == '\0')
1699 fatal("%s line %d: %s missing argument.",
1700 filename, linenum, keyword);
1701 if (strcmp(arg, "default") == 0) {
1704 if (scan_scaled(arg, &val64) == -1)
1705 fatal("%.200s line %d: Bad %s number '%s': %s",
1706 filename, linenum, keyword,
1707 arg, strerror(errno));
1708 if (val64 != 0 && val64 < 16)
1709 fatal("%.200s line %d: %s too small",
1710 filename, linenum, keyword);
1712 if (*activep && options->rekey_limit == -1)
1713 options->rekey_limit = val64;
1714 if (ac != 0) { /* optional rekey interval present */
1715 if (strcmp(av[0], "none") == 0) {
1716 (void)argv_next(&ac, &av); /* discard */
1719 intptr = &options->rekey_interval;
1725 intptr = &options->fwd_opts.gateway_ports;
1726 multistate_ptr = multistate_gatewayports;
1727 goto parse_multistate;
1730 intptr = &options->use_dns;
1734 log_facility_ptr = &options->log_facility;
1735 arg = argv_next(&ac, &av);
1736 value = log_facility_number(arg);
1737 if (value == SYSLOG_FACILITY_NOT_SET)
1738 fatal("%.200s line %d: unsupported log facility '%s'",
1739 filename, linenum, arg ? arg : "<NONE>");
1740 if (*log_facility_ptr == -1)
1741 *log_facility_ptr = (SyslogFacility) value;
1745 log_level_ptr = &options->log_level;
1746 arg = argv_next(&ac, &av);
1747 value = log_level_number(arg);
1748 if (value == SYSLOG_LEVEL_NOT_SET)
1749 fatal("%.200s line %d: unsupported log level '%s'",
1750 filename, linenum, arg ? arg : "<NONE>");
1751 if (*activep && *log_level_ptr == -1)
1752 *log_level_ptr = (LogLevel) value;
1756 found = options->num_log_verbose == 0;
1758 while ((arg = argv_next(&ac, &av)) != NULL) {
1760 error("%s line %d: keyword %s empty argument",
1761 filename, linenum, keyword);
1764 /* Allow "none" only in first position */
1765 if (strcasecmp(arg, "none") == 0) {
1766 if (i > 0 || ac > 0) {
1767 error("%s line %d: keyword %s \"none\" "
1768 "argument must appear alone.",
1769 filename, linenum, keyword);
1774 if (!found || !*activep)
1776 opt_array_append(filename, linenum, keyword,
1777 &options->log_verbose, &options->num_log_verbose,
1782 case sAllowTcpForwarding:
1783 intptr = &options->allow_tcp_forwarding;
1784 multistate_ptr = multistate_tcpfwd;
1785 goto parse_multistate;
1787 case sAllowStreamLocalForwarding:
1788 intptr = &options->allow_streamlocal_forwarding;
1789 multistate_ptr = multistate_tcpfwd;
1790 goto parse_multistate;
1792 case sAllowAgentForwarding:
1793 intptr = &options->allow_agent_forwarding;
1796 case sDisableForwarding:
1797 intptr = &options->disable_forwarding;
1801 chararrayptr = &options->allow_users;
1802 uintptr = &options->num_allow_users;
1803 parse_allowdenyusers:
1804 while ((arg = argv_next(&ac, &av)) != NULL) {
1806 match_user(NULL, NULL, NULL, arg) == -1)
1807 fatal("%s line %d: invalid %s pattern: \"%s\"",
1808 filename, linenum, keyword, arg);
1811 opt_array_append(filename, linenum, keyword,
1812 chararrayptr, uintptr, arg);
1817 chararrayptr = &options->deny_users;
1818 uintptr = &options->num_deny_users;
1819 goto parse_allowdenyusers;
1822 chararrayptr = &options->allow_groups;
1823 uintptr = &options->num_allow_groups;
1824 parse_allowdenygroups:
1825 while ((arg = argv_next(&ac, &av)) != NULL) {
1827 fatal("%s line %d: empty %s pattern",
1828 filename, linenum, keyword);
1831 opt_array_append(filename, linenum, keyword,
1832 chararrayptr, uintptr, arg);
1837 chararrayptr = &options->deny_groups;
1838 uintptr = &options->num_deny_groups;
1839 goto parse_allowdenygroups;
1842 arg = argv_next(&ac, &av);
1843 if (!arg || *arg == '\0')
1844 fatal("%s line %d: %s missing argument.",
1845 filename, linenum, keyword);
1847 !ciphers_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg))
1848 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1849 filename, linenum, arg ? arg : "<NONE>");
1850 if (options->ciphers == NULL)
1851 options->ciphers = xstrdup(arg);
1855 arg = argv_next(&ac, &av);
1856 if (!arg || *arg == '\0')
1857 fatal("%s line %d: %s missing argument.",
1858 filename, linenum, keyword);
1860 !mac_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg))
1861 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1862 filename, linenum, arg ? arg : "<NONE>");
1863 if (options->macs == NULL)
1864 options->macs = xstrdup(arg);
1867 case sKexAlgorithms:
1868 arg = argv_next(&ac, &av);
1869 if (!arg || *arg == '\0')
1870 fatal("%s line %d: %s missing argument.",
1871 filename, linenum, keyword);
1873 !kex_names_valid(*arg == '+' || *arg == '^' ?
1875 fatal("%s line %d: Bad SSH2 KexAlgorithms '%s'.",
1876 filename, linenum, arg ? arg : "<NONE>");
1877 if (options->kex_algorithms == NULL)
1878 options->kex_algorithms = xstrdup(arg);
1882 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1883 fatal("%s line %d: too many subsystems defined.",
1886 arg = argv_next(&ac, &av);
1887 if (!arg || *arg == '\0')
1888 fatal("%s line %d: %s missing argument.",
1889 filename, linenum, keyword);
1891 arg = argv_next(&ac, &av);
1894 for (i = 0; i < options->num_subsystems; i++)
1895 if (strcmp(arg, options->subsystem_name[i]) == 0)
1896 fatal("%s line %d: Subsystem '%s' "
1897 "already defined.", filename, linenum, arg);
1898 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1899 arg = argv_next(&ac, &av);
1900 if (!arg || *arg == '\0')
1901 fatal("%s line %d: Missing subsystem command.",
1903 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1905 /* Collect arguments (separate to executable) */
1907 len = strlen(p) + 1;
1908 while ((arg = argv_next(&ac, &av)) != NULL) {
1909 len += 1 + strlen(arg);
1910 p = xreallocarray(p, 1, len);
1911 strlcat(p, " ", len);
1912 strlcat(p, arg, len);
1914 options->subsystem_args[options->num_subsystems] = p;
1915 options->num_subsystems++;
1919 arg = argv_next(&ac, &av);
1920 if (!arg || *arg == '\0')
1921 fatal("%s line %d: %s missing argument.",
1922 filename, linenum, keyword);
1923 if ((n = sscanf(arg, "%d:%d:%d",
1924 &options->max_startups_begin,
1925 &options->max_startups_rate,
1926 &options->max_startups)) == 3) {
1927 if (options->max_startups_begin >
1928 options->max_startups ||
1929 options->max_startups_rate > 100 ||
1930 options->max_startups_rate < 1)
1931 fatal("%s line %d: Invalid %s spec.",
1932 filename, linenum, keyword);
1934 fatal("%s line %d: Invalid %s spec.",
1935 filename, linenum, keyword);
1937 options->max_startups = options->max_startups_begin;
1940 case sPerSourceNetBlockSize:
1941 arg = argv_next(&ac, &av);
1942 if (!arg || *arg == '\0')
1943 fatal("%s line %d: %s missing argument.",
1944 filename, linenum, keyword);
1945 switch (n = sscanf(arg, "%d:%d", &value, &value2)) {
1947 if (value2 < 0 || value2 > 128)
1951 if (value < 0 || value > 32)
1954 if (n != 1 && n != 2)
1955 fatal("%s line %d: Invalid %s spec.",
1956 filename, linenum, keyword);
1958 options->per_source_masklen_ipv4 = value;
1959 options->per_source_masklen_ipv6 = value2;
1963 case sPerSourceMaxStartups:
1964 arg = argv_next(&ac, &av);
1965 if (!arg || *arg == '\0')
1966 fatal("%s line %d: %s missing argument.",
1967 filename, linenum, keyword);
1968 if (strcmp(arg, "none") == 0) { /* no limit */
1971 if ((errstr = atoi_err(arg, &value)) != NULL)
1972 fatal("%s line %d: %s integer value %s.",
1973 filename, linenum, keyword, errstr);
1976 options->per_source_max_startups = value;
1980 intptr = &options->max_authtries;
1984 intptr = &options->max_sessions;
1988 charptr = &options->banner;
1989 goto parse_filename;
1992 * These options can contain %X options expanded at
1993 * connect time, so that you can specify paths like:
1995 * AuthorizedKeysFile /etc/ssh_keys/%u
1997 case sAuthorizedKeysFile:
1998 uvalue = options->num_authkeys_files;
1999 while ((arg = argv_next(&ac, &av)) != NULL) {
2001 error("%s line %d: keyword %s empty argument",
2002 filename, linenum, keyword);
2005 arg2 = tilde_expand_filename(arg, getuid());
2006 if (*activep && uvalue == 0) {
2007 opt_array_append(filename, linenum, keyword,
2008 &options->authorized_keys_files,
2009 &options->num_authkeys_files, arg2);
2015 case sAuthorizedPrincipalsFile:
2016 charptr = &options->authorized_principals_file;
2017 arg = argv_next(&ac, &av);
2018 if (!arg || *arg == '\0')
2019 fatal("%s line %d: %s missing argument.",
2020 filename, linenum, keyword);
2021 if (*activep && *charptr == NULL) {
2022 *charptr = tilde_expand_filename(arg, getuid());
2023 /* increase optional counter */
2025 *intptr = *intptr + 1;
2029 case sClientAliveInterval:
2030 intptr = &options->client_alive_interval;
2033 case sClientAliveCountMax:
2034 intptr = &options->client_alive_count_max;
2038 while ((arg = argv_next(&ac, &av)) != NULL) {
2039 if (*arg == '\0' || strchr(arg, '=') != NULL)
2040 fatal("%s line %d: Invalid environment name.",
2044 opt_array_append(filename, linenum, keyword,
2045 &options->accept_env, &options->num_accept_env,
2051 uvalue = options->num_setenv;
2052 while ((arg = argv_next(&ac, &av)) != NULL) {
2053 if (*arg == '\0' || strchr(arg, '=') == NULL)
2054 fatal("%s line %d: Invalid environment.",
2056 if (!*activep || uvalue != 0)
2058 if (lookup_setenv_in_list(arg, options->setenv,
2059 options->num_setenv) != NULL) {
2060 debug2("%s line %d: ignoring duplicate env "
2061 "name \"%.64s\"", filename, linenum, arg);
2064 opt_array_append(filename, linenum, keyword,
2065 &options->setenv, &options->num_setenv, arg);
2070 intptr = &options->permit_tun;
2071 arg = argv_next(&ac, &av);
2072 if (!arg || *arg == '\0')
2073 fatal("%s line %d: %s missing argument.",
2074 filename, linenum, keyword);
2076 for (i = 0; tunmode_desc[i].val != -1; i++)
2077 if (strcmp(tunmode_desc[i].text, arg) == 0) {
2078 value = tunmode_desc[i].val;
2082 fatal("%s line %d: bad %s argument %s",
2083 filename, linenum, keyword, arg);
2084 if (*activep && *intptr == -1)
2090 fatal("Include directive not supported as a "
2091 "command-line option");
2094 while ((arg2 = argv_next(&ac, &av)) != NULL) {
2095 if (*arg2 == '\0') {
2096 error("%s line %d: keyword %s empty argument",
2097 filename, linenum, keyword);
2102 if (*arg2 != '/' && *arg2 != '~') {
2103 xasprintf(&arg, "%s/%s", SSHDIR, arg2);
2105 arg = xstrdup(arg2);
2108 * Don't let included files clobber the containing
2109 * file's Match state.
2113 /* consult cache of include files */
2114 TAILQ_FOREACH(item, includes, entry) {
2115 if (strcmp(item->selector, arg) != 0)
2117 if (item->filename != NULL) {
2118 parse_server_config_depth(options,
2119 item->filename, item->contents,
2120 includes, connectinfo,
2121 (*inc_flags & SSHCFG_MATCH_ONLY
2122 ? SSHCFG_MATCH_ONLY : (oactive
2123 ? 0 : SSHCFG_NEVERMATCH)),
2124 activep, depth + 1);
2134 /* requested glob was not in cache */
2135 debug2("%s line %d: new include %s",
2136 filename, linenum, arg);
2137 if ((r = glob(arg, 0, NULL, &gbuf)) != 0) {
2138 if (r != GLOB_NOMATCH) {
2139 fatal("%s line %d: include \"%s\" glob "
2140 "failed", filename, linenum, arg);
2143 * If no entry matched then record a
2144 * placeholder to skip later glob calls.
2146 debug2("%s line %d: no match for %s",
2147 filename, linenum, arg);
2148 item = xcalloc(1, sizeof(*item));
2149 item->selector = strdup(arg);
2150 TAILQ_INSERT_TAIL(includes,
2153 if (gbuf.gl_pathc > INT_MAX)
2154 fatal_f("too many glob results");
2155 for (n = 0; n < (int)gbuf.gl_pathc; n++) {
2156 debug2("%s line %d: including %s",
2157 filename, linenum, gbuf.gl_pathv[n]);
2158 item = xcalloc(1, sizeof(*item));
2159 item->selector = strdup(arg);
2160 item->filename = strdup(gbuf.gl_pathv[n]);
2161 if ((item->contents = sshbuf_new()) == NULL)
2162 fatal_f("sshbuf_new failed");
2163 load_server_config(item->filename,
2165 parse_server_config_depth(options,
2166 item->filename, item->contents,
2167 includes, connectinfo,
2168 (*inc_flags & SSHCFG_MATCH_ONLY
2169 ? SSHCFG_MATCH_ONLY : (oactive
2170 ? 0 : SSHCFG_NEVERMATCH)),
2171 activep, depth + 1);
2173 TAILQ_INSERT_TAIL(includes, item, entry);
2179 fatal("%s line %d: %s missing filename argument",
2180 filename, linenum, keyword);
2186 fatal("Match directive not supported as a command-line "
2188 value = match_cfg_line(&str, linenum,
2189 (*inc_flags & SSHCFG_NEVERMATCH ? NULL : connectinfo));
2191 fatal("%s line %d: Bad Match condition", filename,
2193 *activep = (*inc_flags & SSHCFG_NEVERMATCH) ? 0 : value;
2195 * The MATCH_ONLY flag is applicable only until the first
2198 *inc_flags &= ~SSHCFG_MATCH_ONLY;
2200 * If match_cfg_line() didn't consume all its arguments then
2201 * arrange for the extra arguments check below to fail.
2203 if (str == NULL || *str == '\0')
2209 if (opcode == sPermitListen) {
2210 uintptr = &options->num_permitted_listens;
2211 chararrayptr = &options->permitted_listens;
2213 uintptr = &options->num_permitted_opens;
2214 chararrayptr = &options->permitted_opens;
2216 arg = argv_next(&ac, &av);
2217 if (!arg || *arg == '\0')
2218 fatal("%s line %d: %s missing argument.",
2219 filename, linenum, keyword);
2220 uvalue = *uintptr; /* modified later */
2221 if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) {
2222 if (*activep && uvalue == 0) {
2224 *chararrayptr = xcalloc(1,
2225 sizeof(**chararrayptr));
2226 (*chararrayptr)[0] = xstrdup(arg);
2230 for (; arg != NULL && *arg != '\0'; arg = argv_next(&ac, &av)) {
2231 if (opcode == sPermitListen &&
2232 strchr(arg, ':') == NULL) {
2234 * Allow bare port number for PermitListen
2235 * to indicate a wildcard listen host.
2237 xasprintf(&arg2, "*:%s", arg);
2239 arg2 = xstrdup(arg);
2242 fatal("%s line %d: %s missing host",
2243 filename, linenum, keyword);
2245 p = cleanhostname(p);
2248 ((port = permitopen_port(arg)) < 0)) {
2249 fatal("%s line %d: %s bad port number",
2250 filename, linenum, keyword);
2252 if (*activep && uvalue == 0) {
2253 opt_array_append(filename, linenum, keyword,
2254 chararrayptr, uintptr, arg2);
2261 if (str == NULL || *str == '\0')
2262 fatal("%s line %d: %s missing argument.",
2263 filename, linenum, keyword);
2264 len = strspn(str, WHITESPACE);
2265 if (*activep && options->adm_forced_command == NULL)
2266 options->adm_forced_command = xstrdup(str + len);
2270 case sChrootDirectory:
2271 charptr = &options->chroot_directory;
2273 arg = argv_next(&ac, &av);
2274 if (!arg || *arg == '\0')
2275 fatal("%s line %d: %s missing argument.",
2276 filename, linenum, keyword);
2277 if (*activep && *charptr == NULL)
2278 *charptr = xstrdup(arg);
2281 case sTrustedUserCAKeys:
2282 charptr = &options->trusted_user_ca_keys;
2283 goto parse_filename;
2286 charptr = &options->revoked_keys_file;
2287 goto parse_filename;
2289 case sSecurityKeyProvider:
2290 charptr = &options->sk_provider;
2291 arg = argv_next(&ac, &av);
2292 if (!arg || *arg == '\0')
2293 fatal("%s line %d: %s missing argument.",
2294 filename, linenum, keyword);
2295 if (*activep && *charptr == NULL) {
2296 *charptr = strcasecmp(arg, "internal") == 0 ?
2297 xstrdup(arg) : derelativise_path(arg);
2298 /* increase optional counter */
2300 *intptr = *intptr + 1;
2305 arg = argv_next(&ac, &av);
2306 if (!arg || *arg == '\0')
2307 fatal("%s line %d: %s missing argument.",
2308 filename, linenum, keyword);
2309 if ((value = parse_ipqos(arg)) == -1)
2310 fatal("%s line %d: Bad %s value: %s",
2311 filename, linenum, keyword, arg);
2312 arg = argv_next(&ac, &av);
2315 else if ((value2 = parse_ipqos(arg)) == -1)
2316 fatal("%s line %d: Bad %s value: %s",
2317 filename, linenum, keyword, arg);
2319 options->ip_qos_interactive = value;
2320 options->ip_qos_bulk = value2;
2324 case sVersionAddendum:
2325 if (str == NULL || *str == '\0')
2326 fatal("%s line %d: %s missing argument.",
2327 filename, linenum, keyword);
2328 len = strspn(str, WHITESPACE);
2329 if (strchr(str + len, '\r') != NULL) {
2330 fatal("%.200s line %d: Invalid %s argument",
2331 filename, linenum, keyword);
2333 if ((arg = strchr(line, '#')) != NULL) {
2337 if (*activep && options->version_addendum == NULL) {
2338 if (strcasecmp(str + len, "none") == 0)
2339 options->version_addendum = xstrdup("");
2341 options->version_addendum = xstrdup(str + len);
2346 case sAuthorizedKeysCommand:
2347 charptr = &options->authorized_keys_command;
2349 len = strspn(str, WHITESPACE);
2350 if (str[len] != '/' && strcasecmp(str + len, "none") != 0) {
2351 fatal("%.200s line %d: %s must be an absolute path",
2352 filename, linenum, keyword);
2354 if (*activep && options->authorized_keys_command == NULL)
2355 *charptr = xstrdup(str + len);
2359 case sAuthorizedKeysCommandUser:
2360 charptr = &options->authorized_keys_command_user;
2362 arg = argv_next(&ac, &av);
2363 if (!arg || *arg == '\0') {
2364 fatal("%s line %d: missing %s argument.",
2365 filename, linenum, keyword);
2367 if (*activep && *charptr == NULL)
2368 *charptr = xstrdup(arg);
2371 case sAuthorizedPrincipalsCommand:
2372 charptr = &options->authorized_principals_command;
2375 case sAuthorizedPrincipalsCommandUser:
2376 charptr = &options->authorized_principals_command_user;
2377 goto parse_localuser;
2379 case sAuthenticationMethods:
2380 found = options->num_auth_methods == 0;
2381 value = 0; /* seen "any" pseudo-method */
2382 value2 = 0; /* successfully parsed any method */
2383 while ((arg = argv_next(&ac, &av)) != NULL) {
2384 if (strcmp(arg, "any") == 0) {
2385 if (options->num_auth_methods > 0) {
2386 fatal("%s line %d: \"any\" must "
2387 "appear alone in %s",
2388 filename, linenum, keyword);
2392 fatal("%s line %d: \"any\" must appear "
2393 "alone in %s", filename, linenum, keyword);
2394 } else if (auth2_methods_valid(arg, 0) != 0) {
2395 fatal("%s line %d: invalid %s method list.",
2396 filename, linenum, keyword);
2399 if (!found || !*activep)
2401 opt_array_append(filename, linenum, keyword,
2402 &options->auth_methods,
2403 &options->num_auth_methods, arg);
2406 fatal("%s line %d: no %s specified",
2407 filename, linenum, keyword);
2411 case sStreamLocalBindMask:
2412 arg = argv_next(&ac, &av);
2413 if (!arg || *arg == '\0')
2414 fatal("%s line %d: %s missing argument.",
2415 filename, linenum, keyword);
2416 /* Parse mode in octal format */
2417 value = strtol(arg, &p, 8);
2418 if (arg == p || value < 0 || value > 0777)
2419 fatal("%s line %d: Invalid %s.",
2420 filename, linenum, keyword);
2422 options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
2425 case sStreamLocalBindUnlink:
2426 intptr = &options->fwd_opts.streamlocal_bind_unlink;
2429 case sFingerprintHash:
2430 arg = argv_next(&ac, &av);
2431 if (!arg || *arg == '\0')
2432 fatal("%s line %d: %s missing argument.",
2433 filename, linenum, keyword);
2434 if ((value = ssh_digest_alg_by_name(arg)) == -1)
2435 fatal("%.200s line %d: Invalid %s algorithm \"%s\".",
2436 filename, linenum, keyword, arg);
2438 options->fingerprint_hash = value;
2441 case sExposeAuthInfo:
2442 intptr = &options->expose_userauth_info;
2446 #if !defined(__OpenBSD__) && !defined(HAVE_SYS_SET_PROCESS_RDOMAIN)
2447 fatal("%s line %d: setting RDomain not supported on this "
2448 "platform.", filename, linenum);
2450 charptr = &options->routing_domain;
2451 arg = argv_next(&ac, &av);
2452 if (!arg || *arg == '\0')
2453 fatal("%s line %d: %s missing argument.",
2454 filename, linenum, keyword);
2455 if (strcasecmp(arg, "none") != 0 && strcmp(arg, "%D") != 0 &&
2456 !valid_rdomain(arg))
2457 fatal("%s line %d: invalid routing domain",
2459 if (*activep && *charptr == NULL)
2460 *charptr = xstrdup(arg);
2463 case sRequiredRSASize:
2464 intptr = &options->required_rsa_size;
2468 intptr = &options->use_blacklist;
2474 do_log2(opcode == sIgnore ?
2475 SYSLOG_LEVEL_DEBUG2 : SYSLOG_LEVEL_INFO,
2476 "%s line %d: %s option %s", filename, linenum,
2477 opcode == sUnsupported ? "Unsupported" : "Deprecated",
2483 fatal("%s line %d: Missing handler for opcode %s (%d)",
2484 filename, linenum, keyword, opcode);
2486 /* Check that there is no garbage at end of line. */
2488 error("%.200s line %d: keyword %s extra arguments "
2489 "at end of line", filename, linenum, keyword);
2496 argv_free(oav, oac);
2501 process_server_config_line(ServerOptions *options, char *line,
2502 const char *filename, int linenum, int *activep,
2503 struct connection_info *connectinfo, struct include_list *includes)
2507 return process_server_config_line_depth(options, line, filename,
2508 linenum, activep, connectinfo, &inc_flags, 0, includes);
2512 /* Reads the server configuration file. */
2515 load_server_config(const char *filename, struct sshbuf *conf)
2518 char *line = NULL, *cp;
2519 size_t linesize = 0;
2523 debug2_f("filename %s", filename);
2524 if ((f = fopen(filename, "r")) == NULL) {
2529 /* grow buffer, so realloc is avoided for large config files */
2530 if (fstat(fileno(f), &st) == 0 && st.st_size > 0 &&
2531 (r = sshbuf_allocate(conf, st.st_size)) != 0)
2532 fatal_fr(r, "allocate");
2533 while (getline(&line, &linesize, f) != -1) {
2537 * NB - preserve newlines, they are needed to reproduce
2538 * line numbers later for error messages
2540 cp = line + strspn(line, " \t\r");
2541 if ((r = sshbuf_put(conf, cp, strlen(cp))) != 0)
2542 fatal_fr(r, "sshbuf_put");
2545 if ((r = sshbuf_put_u8(conf, 0)) != 0)
2546 fatal_fr(r, "sshbuf_put_u8");
2548 debug2_f("done config len = %zu", sshbuf_len(conf));
2552 parse_server_match_config(ServerOptions *options,
2553 struct include_list *includes, struct connection_info *connectinfo)
2557 initialize_server_options(&mo);
2558 parse_server_config(&mo, "reprocess config", cfg, includes,
2560 copy_set_server_options(options, &mo, 0);
2563 int parse_server_match_testspec(struct connection_info *ci, char *spec)
2567 while ((p = strsep(&spec, ",")) && *p != '\0') {
2568 if (strncmp(p, "addr=", 5) == 0) {
2569 ci->address = xstrdup(p + 5);
2570 } else if (strncmp(p, "host=", 5) == 0) {
2571 ci->host = xstrdup(p + 5);
2572 } else if (strncmp(p, "user=", 5) == 0) {
2573 ci->user = xstrdup(p + 5);
2574 } else if (strncmp(p, "laddr=", 6) == 0) {
2575 ci->laddress = xstrdup(p + 6);
2576 } else if (strncmp(p, "rdomain=", 8) == 0) {
2577 ci->rdomain = xstrdup(p + 8);
2578 } else if (strncmp(p, "lport=", 6) == 0) {
2579 ci->lport = a2port(p + 6);
2580 if (ci->lport == -1) {
2581 fprintf(stderr, "Invalid port '%s' in test mode"
2582 " specification %s\n", p+6, p);
2586 fprintf(stderr, "Invalid test mode specification %s\n",
2595 * Copy any supported values that are set.
2597 * If the preauth flag is set, we do not bother copying the string or
2598 * array values that are not used pre-authentication, because any that we
2599 * do use must be explicitly sent in mm_getpwnamallow().
2602 copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
2604 #define M_CP_INTOPT(n) do {\
2609 M_CP_INTOPT(password_authentication);
2610 M_CP_INTOPT(gss_authentication);
2611 M_CP_INTOPT(pubkey_authentication);
2612 M_CP_INTOPT(pubkey_auth_options);
2613 M_CP_INTOPT(kerberos_authentication);
2614 M_CP_INTOPT(hostbased_authentication);
2615 M_CP_INTOPT(hostbased_uses_name_from_packet_only);
2616 M_CP_INTOPT(kbd_interactive_authentication);
2617 M_CP_INTOPT(permit_root_login);
2618 M_CP_INTOPT(permit_empty_passwd);
2619 M_CP_INTOPT(ignore_rhosts);
2621 M_CP_INTOPT(allow_tcp_forwarding);
2622 M_CP_INTOPT(allow_streamlocal_forwarding);
2623 M_CP_INTOPT(allow_agent_forwarding);
2624 M_CP_INTOPT(disable_forwarding);
2625 M_CP_INTOPT(expose_userauth_info);
2626 M_CP_INTOPT(permit_tun);
2627 M_CP_INTOPT(fwd_opts.gateway_ports);
2628 M_CP_INTOPT(fwd_opts.streamlocal_bind_unlink);
2629 M_CP_INTOPT(x11_display_offset);
2630 M_CP_INTOPT(x11_forwarding);
2631 M_CP_INTOPT(x11_use_localhost);
2632 M_CP_INTOPT(permit_tty);
2633 M_CP_INTOPT(permit_user_rc);
2634 M_CP_INTOPT(max_sessions);
2635 M_CP_INTOPT(max_authtries);
2636 M_CP_INTOPT(client_alive_count_max);
2637 M_CP_INTOPT(client_alive_interval);
2638 M_CP_INTOPT(ip_qos_interactive);
2639 M_CP_INTOPT(ip_qos_bulk);
2640 M_CP_INTOPT(rekey_limit);
2641 M_CP_INTOPT(rekey_interval);
2642 M_CP_INTOPT(log_level);
2643 M_CP_INTOPT(required_rsa_size);
2646 * The bind_mask is a mode_t that may be unsigned, so we can't use
2647 * M_CP_INTOPT - it does a signed comparison that causes compiler
2650 if (src->fwd_opts.streamlocal_bind_mask != (mode_t)-1) {
2651 dst->fwd_opts.streamlocal_bind_mask =
2652 src->fwd_opts.streamlocal_bind_mask;
2655 /* M_CP_STROPT and M_CP_STRARRAYOPT should not appear before here */
2656 #define M_CP_STROPT(n) do {\
2657 if (src->n != NULL && dst->n != src->n) { \
2662 #define M_CP_STRARRAYOPT(s, num_s) do {\
2664 if (src->num_s != 0) { \
2665 for (i = 0; i < dst->num_s; i++) \
2668 dst->s = xcalloc(src->num_s, sizeof(*dst->s)); \
2669 for (i = 0; i < src->num_s; i++) \
2670 dst->s[i] = xstrdup(src->s[i]); \
2671 dst->num_s = src->num_s; \
2675 /* See comment in servconf.h */
2676 COPY_MATCH_STRING_OPTS();
2678 /* Arguments that accept '+...' need to be expanded */
2679 assemble_algorithms(dst);
2682 * The only things that should be below this point are string options
2683 * which are only used after authentication.
2688 /* These options may be "none" to clear a global setting */
2689 M_CP_STROPT(adm_forced_command);
2690 if (option_clear_or_none(dst->adm_forced_command)) {
2691 free(dst->adm_forced_command);
2692 dst->adm_forced_command = NULL;
2694 M_CP_STROPT(chroot_directory);
2695 if (option_clear_or_none(dst->chroot_directory)) {
2696 free(dst->chroot_directory);
2697 dst->chroot_directory = NULL;
2703 #undef M_CP_STRARRAYOPT
2705 #define SERVCONF_MAX_DEPTH 16
2707 parse_server_config_depth(ServerOptions *options, const char *filename,
2708 struct sshbuf *conf, struct include_list *includes,
2709 struct connection_info *connectinfo, int flags, int *activep, int depth)
2711 int linenum, bad_options = 0;
2712 char *cp, *obuf, *cbuf;
2714 if (depth < 0 || depth > SERVCONF_MAX_DEPTH)
2715 fatal("Too many recursive configuration includes");
2717 debug2_f("config %s len %zu%s", filename, sshbuf_len(conf),
2718 (flags & SSHCFG_NEVERMATCH ? " [checking syntax only]" : ""));
2720 if ((obuf = cbuf = sshbuf_dup_string(conf)) == NULL)
2721 fatal_f("sshbuf_dup_string failed");
2723 while ((cp = strsep(&cbuf, "\n")) != NULL) {
2724 if (process_server_config_line_depth(options, cp,
2725 filename, linenum++, activep, connectinfo, &flags,
2726 depth, includes) != 0)
2730 if (bad_options > 0)
2731 fatal("%s: terminating, %d bad configuration options",
2732 filename, bad_options);
2736 parse_server_config(ServerOptions *options, const char *filename,
2737 struct sshbuf *conf, struct include_list *includes,
2738 struct connection_info *connectinfo, int reexec)
2740 int active = connectinfo ? 0 : 1;
2741 parse_server_config_depth(options, filename, conf, includes,
2742 connectinfo, (connectinfo ? SSHCFG_MATCH_ONLY : 0), &active, 0);
2744 process_queued_listen_addrs(options);
2748 fmt_multistate_int(int val, const struct multistate *m)
2752 for (i = 0; m[i].key != NULL; i++) {
2753 if (m[i].value == val)
2760 fmt_intarg(ServerOpCodes code, int val)
2765 case sAddressFamily:
2766 return fmt_multistate_int(val, multistate_addressfamily);
2767 case sPermitRootLogin:
2768 return fmt_multistate_int(val, multistate_permitrootlogin);
2770 return fmt_multistate_int(val, multistate_gatewayports);
2772 return fmt_multistate_int(val, multistate_compression);
2773 case sAllowTcpForwarding:
2774 return fmt_multistate_int(val, multistate_tcpfwd);
2775 case sAllowStreamLocalForwarding:
2776 return fmt_multistate_int(val, multistate_tcpfwd);
2778 return fmt_multistate_int(val, multistate_ignore_rhosts);
2779 case sFingerprintHash:
2780 return ssh_digest_alg_name(val);
2794 dump_cfg_int(ServerOpCodes code, int val)
2796 printf("%s %d\n", lookup_opcode_name(code), val);
2800 dump_cfg_oct(ServerOpCodes code, int val)
2802 printf("%s 0%o\n", lookup_opcode_name(code), val);
2806 dump_cfg_fmtint(ServerOpCodes code, int val)
2808 printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
2812 dump_cfg_string(ServerOpCodes code, const char *val)
2814 printf("%s %s\n", lookup_opcode_name(code),
2815 val == NULL ? "none" : val);
2819 dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals)
2823 for (i = 0; i < count; i++)
2824 printf("%s %s\n", lookup_opcode_name(code), vals[i]);
2828 dump_cfg_strarray_oneline(ServerOpCodes code, u_int count, char **vals)
2832 if (count <= 0 && code != sAuthenticationMethods)
2834 printf("%s", lookup_opcode_name(code));
2835 for (i = 0; i < count; i++)
2836 printf(" %s", vals[i]);
2837 if (code == sAuthenticationMethods && count == 0)
2843 format_listen_addrs(struct listenaddr *la)
2846 struct addrinfo *ai;
2847 char addr[NI_MAXHOST], port[NI_MAXSERV];
2848 char *laddr1 = xstrdup(""), *laddr2 = NULL;
2851 * ListenAddress must be after Port. add_one_listen_addr pushes
2852 * addresses onto a stack, so to maintain ordering we need to
2853 * print these in reverse order.
2855 for (ai = la->addrs; ai; ai = ai->ai_next) {
2856 if ((r = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
2857 sizeof(addr), port, sizeof(port),
2858 NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
2859 error("getnameinfo: %.100s", ssh_gai_strerror(r));
2863 if (ai->ai_family == AF_INET6) {
2864 xasprintf(&laddr1, "listenaddress [%s]:%s%s%s\n%s",
2866 la->rdomain == NULL ? "" : " rdomain ",
2867 la->rdomain == NULL ? "" : la->rdomain,
2870 xasprintf(&laddr1, "listenaddress %s:%s%s%s\n%s",
2872 la->rdomain == NULL ? "" : " rdomain ",
2873 la->rdomain == NULL ? "" : la->rdomain,
2882 dump_config(ServerOptions *o)
2887 /* these are usually at the top of the config */
2888 for (i = 0; i < o->num_ports; i++)
2889 printf("port %d\n", o->ports[i]);
2890 dump_cfg_fmtint(sAddressFamily, o->address_family);
2892 for (i = 0; i < o->num_listen_addrs; i++) {
2893 s = format_listen_addrs(&o->listen_addrs[i]);
2898 /* integer arguments */
2900 dump_cfg_fmtint(sUsePAM, o->use_pam);
2902 dump_cfg_int(sLoginGraceTime, o->login_grace_time);
2903 dump_cfg_int(sX11DisplayOffset, o->x11_display_offset);
2904 dump_cfg_int(sMaxAuthTries, o->max_authtries);
2905 dump_cfg_int(sMaxSessions, o->max_sessions);
2906 dump_cfg_int(sClientAliveInterval, o->client_alive_interval);
2907 dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max);
2908 dump_cfg_int(sRequiredRSASize, o->required_rsa_size);
2909 dump_cfg_oct(sStreamLocalBindMask, o->fwd_opts.streamlocal_bind_mask);
2911 /* formatted integer arguments */
2912 dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login);
2913 dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts);
2914 dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts);
2915 dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication);
2916 dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly,
2917 o->hostbased_uses_name_from_packet_only);
2918 dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication);
2920 dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication);
2921 dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd);
2922 dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup);
2924 dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
2928 dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
2929 dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
2931 dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
2932 dump_cfg_fmtint(sKbdInteractiveAuthentication,
2933 o->kbd_interactive_authentication);
2934 dump_cfg_fmtint(sPrintMotd, o->print_motd);
2935 #ifndef DISABLE_LASTLOG
2936 dump_cfg_fmtint(sPrintLastLog, o->print_lastlog);
2938 dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding);
2939 dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost);
2940 dump_cfg_fmtint(sPermitTTY, o->permit_tty);
2941 dump_cfg_fmtint(sPermitUserRC, o->permit_user_rc);
2942 dump_cfg_fmtint(sStrictModes, o->strict_modes);
2943 dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive);
2944 dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd);
2945 dump_cfg_fmtint(sCompression, o->compression);
2946 dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports);
2947 dump_cfg_fmtint(sUseDNS, o->use_dns);
2948 dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
2949 dump_cfg_fmtint(sAllowAgentForwarding, o->allow_agent_forwarding);
2950 dump_cfg_fmtint(sDisableForwarding, o->disable_forwarding);
2951 dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding);
2952 dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2953 dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash);
2954 dump_cfg_fmtint(sExposeAuthInfo, o->expose_userauth_info);
2955 dump_cfg_fmtint(sUseBlacklist, o->use_blacklist);
2957 /* string arguments */
2958 dump_cfg_string(sPidFile, o->pid_file);
2959 dump_cfg_string(sModuliFile, o->moduli_file);
2960 dump_cfg_string(sXAuthLocation, o->xauth_location);
2961 dump_cfg_string(sCiphers, o->ciphers);
2962 dump_cfg_string(sMacs, o->macs);
2963 dump_cfg_string(sBanner, o->banner);
2964 dump_cfg_string(sForceCommand, o->adm_forced_command);
2965 dump_cfg_string(sChrootDirectory, o->chroot_directory);
2966 dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);
2967 dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
2968 dump_cfg_string(sSecurityKeyProvider, o->sk_provider);
2969 dump_cfg_string(sAuthorizedPrincipalsFile,
2970 o->authorized_principals_file);
2971 dump_cfg_string(sVersionAddendum, *o->version_addendum == '\0'
2972 ? "none" : o->version_addendum);
2973 dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command);
2974 dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user);
2975 dump_cfg_string(sAuthorizedPrincipalsCommand, o->authorized_principals_command);
2976 dump_cfg_string(sAuthorizedPrincipalsCommandUser, o->authorized_principals_command_user);
2977 dump_cfg_string(sHostKeyAgent, o->host_key_agent);
2978 dump_cfg_string(sKexAlgorithms, o->kex_algorithms);
2979 dump_cfg_string(sCASignatureAlgorithms, o->ca_sign_algorithms);
2980 dump_cfg_string(sHostbasedAcceptedAlgorithms, o->hostbased_accepted_algos);
2981 dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms);
2982 dump_cfg_string(sPubkeyAcceptedAlgorithms, o->pubkey_accepted_algos);
2983 #if defined(__OpenBSD__) || defined(HAVE_SYS_SET_PROCESS_RDOMAIN)
2984 dump_cfg_string(sRDomain, o->routing_domain);
2987 /* string arguments requiring a lookup */
2988 dump_cfg_string(sLogLevel, log_level_name(o->log_level));
2989 dump_cfg_string(sLogFacility, log_facility_name(o->log_facility));
2991 /* string array arguments */
2992 dump_cfg_strarray_oneline(sAuthorizedKeysFile, o->num_authkeys_files,
2993 o->authorized_keys_files);
2994 dump_cfg_strarray(sHostKeyFile, o->num_host_key_files,
2996 dump_cfg_strarray(sHostCertificate, o->num_host_cert_files,
2997 o->host_cert_files);
2998 dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users);
2999 dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users);
3000 dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups);
3001 dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups);
3002 dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env);
3003 dump_cfg_strarray(sSetEnv, o->num_setenv, o->setenv);
3004 dump_cfg_strarray_oneline(sAuthenticationMethods,
3005 o->num_auth_methods, o->auth_methods);
3006 dump_cfg_strarray_oneline(sLogVerbose,
3007 o->num_log_verbose, o->log_verbose);
3009 /* other arguments */
3010 for (i = 0; i < o->num_subsystems; i++)
3011 printf("subsystem %s %s\n", o->subsystem_name[i],
3012 o->subsystem_args[i]);
3014 printf("maxstartups %d:%d:%d\n", o->max_startups_begin,
3015 o->max_startups_rate, o->max_startups);
3016 printf("persourcemaxstartups ");
3017 if (o->per_source_max_startups == INT_MAX)
3020 printf("%d\n", o->per_source_max_startups);
3021 printf("persourcenetblocksize %d:%d\n", o->per_source_masklen_ipv4,
3022 o->per_source_masklen_ipv6);
3025 for (i = 0; tunmode_desc[i].val != -1; i++) {
3026 if (tunmode_desc[i].val == o->permit_tun) {
3027 s = tunmode_desc[i].text;
3031 dump_cfg_string(sPermitTunnel, s);
3033 printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
3034 printf("%s\n", iptos2str(o->ip_qos_bulk));
3036 printf("rekeylimit %llu %d\n", (unsigned long long)o->rekey_limit,
3039 printf("permitopen");
3040 if (o->num_permitted_opens == 0)
3043 for (i = 0; i < o->num_permitted_opens; i++)
3044 printf(" %s", o->permitted_opens[i]);
3047 printf("permitlisten");
3048 if (o->num_permitted_listens == 0)
3051 for (i = 0; i < o->num_permitted_listens; i++)
3052 printf(" %s", o->permitted_listens[i]);
3056 if (o->permit_user_env_allowlist == NULL) {
3057 dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env);
3059 printf("permituserenvironment %s\n",
3060 o->permit_user_env_allowlist);
3063 printf("pubkeyauthoptions");
3064 if (o->pubkey_auth_options == 0)
3066 if (o->pubkey_auth_options & PUBKEYAUTH_TOUCH_REQUIRED)
3067 printf(" touch-required");
3068 if (o->pubkey_auth_options & PUBKEYAUTH_VERIFY_REQUIRED)
3069 printf(" verify-required");