2 /* $OpenBSD: servconf.c,v 1.381 2021/07/02 05:11:21 dtucker 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".
17 #include <sys/types.h>
18 #include <sys/socket.h>
21 #include <sys/sysctl.h>
24 #include <netinet/in.h>
25 #include <netinet/in_systm.h>
26 #include <netinet/ip.h>
27 #ifdef HAVE_NET_ROUTE_H
28 #include <net/route.h>
45 #ifdef USE_SYSTEM_GLOB
48 # include "openbsd-compat/glob.h"
51 #include "openbsd-compat/sys-queue.h"
59 #include "pathnames.h"
66 #include "groupaccess.h"
72 #include "myproposal.h"
76 static void add_listen_addr(ServerOptions *, const char *,
78 static void add_one_listen_addr(ServerOptions *, const char *,
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);
84 /* Use of privilege separation or not */
85 extern int use_privsep;
86 extern struct sshbuf *cfg;
88 /* Initializes the server options to their default values. */
91 initialize_server_options(ServerOptions *options)
93 memset(options, 0, sizeof(*options));
95 /* Portable-specific options */
96 options->use_pam = -1;
98 /* Standard Options */
99 options->num_ports = 0;
100 options->ports_from_cmdline = 0;
101 options->queued_listen_addrs = NULL;
102 options->num_queued_listens = 0;
103 options->listen_addrs = NULL;
104 options->num_listen_addrs = 0;
105 options->address_family = -1;
106 options->routing_domain = NULL;
107 options->num_host_key_files = 0;
108 options->num_host_cert_files = 0;
109 options->host_key_agent = NULL;
110 options->pid_file = NULL;
111 options->login_grace_time = -1;
112 options->permit_root_login = PERMIT_NOT_SET;
113 options->ignore_rhosts = -1;
114 options->ignore_user_known_hosts = -1;
115 options->print_motd = -1;
116 options->print_lastlog = -1;
117 options->x11_forwarding = -1;
118 options->x11_display_offset = -1;
119 options->x11_use_localhost = -1;
120 options->permit_tty = -1;
121 options->permit_user_rc = -1;
122 options->xauth_location = NULL;
123 options->strict_modes = -1;
124 options->tcp_keep_alive = -1;
125 options->log_facility = SYSLOG_FACILITY_NOT_SET;
126 options->log_level = SYSLOG_LEVEL_NOT_SET;
127 options->num_log_verbose = 0;
128 options->log_verbose = NULL;
129 options->hostbased_authentication = -1;
130 options->hostbased_uses_name_from_packet_only = -1;
131 options->hostbased_accepted_algos = NULL;
132 options->hostkeyalgorithms = NULL;
133 options->pubkey_authentication = -1;
134 options->pubkey_auth_options = -1;
135 options->pubkey_accepted_algos = NULL;
136 options->kerberos_authentication = -1;
137 options->kerberos_or_local_passwd = -1;
138 options->kerberos_ticket_cleanup = -1;
139 options->kerberos_get_afs_token = -1;
140 options->gss_authentication=-1;
141 options->gss_cleanup_creds = -1;
142 options->gss_strict_acceptor = -1;
143 options->password_authentication = -1;
144 options->kbd_interactive_authentication = -1;
145 options->permit_empty_passwd = -1;
146 options->permit_user_env = -1;
147 options->permit_user_env_allowlist = NULL;
148 options->compression = -1;
149 options->rekey_limit = -1;
150 options->rekey_interval = -1;
151 options->allow_tcp_forwarding = -1;
152 options->allow_streamlocal_forwarding = -1;
153 options->allow_agent_forwarding = -1;
154 options->num_allow_users = 0;
155 options->num_deny_users = 0;
156 options->num_allow_groups = 0;
157 options->num_deny_groups = 0;
158 options->ciphers = NULL;
159 options->macs = NULL;
160 options->kex_algorithms = NULL;
161 options->ca_sign_algorithms = NULL;
162 options->fwd_opts.gateway_ports = -1;
163 options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
164 options->fwd_opts.streamlocal_bind_unlink = -1;
165 options->num_subsystems = 0;
166 options->max_startups_begin = -1;
167 options->max_startups_rate = -1;
168 options->max_startups = -1;
169 options->per_source_max_startups = -1;
170 options->per_source_masklen_ipv4 = -1;
171 options->per_source_masklen_ipv6 = -1;
172 options->max_authtries = -1;
173 options->max_sessions = -1;
174 options->banner = NULL;
175 options->use_dns = -1;
176 options->client_alive_interval = -1;
177 options->client_alive_count_max = -1;
178 options->num_authkeys_files = 0;
179 options->num_accept_env = 0;
180 options->num_setenv = 0;
181 options->permit_tun = -1;
182 options->permitted_opens = NULL;
183 options->permitted_listens = NULL;
184 options->adm_forced_command = NULL;
185 options->chroot_directory = NULL;
186 options->authorized_keys_command = NULL;
187 options->authorized_keys_command_user = NULL;
188 options->revoked_keys_file = NULL;
189 options->sk_provider = NULL;
190 options->trusted_user_ca_keys = NULL;
191 options->authorized_principals_file = NULL;
192 options->authorized_principals_command = NULL;
193 options->authorized_principals_command_user = NULL;
194 options->ip_qos_interactive = -1;
195 options->ip_qos_bulk = -1;
196 options->version_addendum = NULL;
197 options->fingerprint_hash = -1;
198 options->disable_forwarding = -1;
199 options->expose_userauth_info = -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->use_blacklist == -1)
454 options->use_blacklist = 0;
456 assemble_algorithms(options);
458 /* Turn privilege separation and sandboxing on by default */
459 if (use_privsep == -1)
460 use_privsep = PRIVSEP_ON;
462 #define CLEAR_ON_NONE(v) \
464 if (option_clear_or_none(v)) { \
469 CLEAR_ON_NONE(options->pid_file);
470 CLEAR_ON_NONE(options->xauth_location);
471 CLEAR_ON_NONE(options->banner);
472 CLEAR_ON_NONE(options->trusted_user_ca_keys);
473 CLEAR_ON_NONE(options->revoked_keys_file);
474 CLEAR_ON_NONE(options->sk_provider);
475 CLEAR_ON_NONE(options->authorized_principals_file);
476 CLEAR_ON_NONE(options->adm_forced_command);
477 CLEAR_ON_NONE(options->chroot_directory);
478 CLEAR_ON_NONE(options->routing_domain);
479 CLEAR_ON_NONE(options->host_key_agent);
480 for (i = 0; i < options->num_host_key_files; i++)
481 CLEAR_ON_NONE(options->host_key_files[i]);
482 for (i = 0; i < options->num_host_cert_files; i++)
483 CLEAR_ON_NONE(options->host_cert_files[i]);
486 /* Similar handling for AuthenticationMethods=any */
487 if (options->num_auth_methods == 1 &&
488 strcmp(options->auth_methods[0], "any") == 0) {
489 free(options->auth_methods[0]);
490 options->auth_methods[0] = NULL;
491 options->num_auth_methods = 0;
495 /* Keyword tokens. */
497 sBadOption, /* == unknown option */
498 /* Portable-specific options */
500 /* Standard Options */
501 sPort, sHostKeyFile, sLoginGraceTime,
502 sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose,
503 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
504 sKerberosGetAFSToken, sChallengeResponseAuthentication,
505 sPasswordAuthentication, sKbdInteractiveAuthentication,
506 sListenAddress, sAddressFamily,
507 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
508 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
509 sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive,
510 sPermitUserEnvironment, sAllowTcpForwarding, sCompression,
511 sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
512 sIgnoreUserKnownHosts, sCiphers, sMacs, sPidFile, sModuliFile,
513 sGatewayPorts, sPubkeyAuthentication, sPubkeyAcceptedAlgorithms,
514 sXAuthLocation, sSubsystem, sMaxStartups, sMaxAuthTries, sMaxSessions,
515 sBanner, sUseDNS, sHostbasedAuthentication,
516 sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedAlgorithms,
517 sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize,
518 sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
519 sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
520 sAcceptEnv, sSetEnv, sPermitTunnel,
521 sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory,
522 sUsePrivilegeSeparation, sAllowAgentForwarding,
523 sHostCertificate, sInclude,
524 sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
525 sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser,
526 sKexAlgorithms, sCASignatureAlgorithms, sIPQoS, sVersionAddendum,
527 sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
528 sAuthenticationMethods, sHostKeyAgent, sPermitUserRC,
529 sStreamLocalBindMask, sStreamLocalBindUnlink,
530 sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding,
531 sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider,
533 sDeprecated, sIgnore, sUnsupported
536 #define SSHCFG_GLOBAL 0x01 /* allowed in main section of config */
537 #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
538 #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
539 #define SSHCFG_NEVERMATCH 0x04 /* Match never matches; internal only */
540 #define SSHCFG_MATCH_ONLY 0x08 /* Match only in conditional blocks; internal only */
542 /* Textual representation of the tokens. */
545 ServerOpCodes opcode;
548 /* Portable-specific options */
550 { "usepam", sUsePAM, SSHCFG_GLOBAL },
552 { "usepam", sUnsupported, SSHCFG_GLOBAL },
554 { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
555 /* Standard Options */
556 { "port", sPort, SSHCFG_GLOBAL },
557 { "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
558 { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */
559 { "hostkeyagent", sHostKeyAgent, SSHCFG_GLOBAL },
560 { "pidfile", sPidFile, SSHCFG_GLOBAL },
561 { "modulifile", sModuliFile, SSHCFG_GLOBAL },
562 { "serverkeybits", sDeprecated, SSHCFG_GLOBAL },
563 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
564 { "keyregenerationinterval", sDeprecated, SSHCFG_GLOBAL },
565 { "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
566 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
567 { "loglevel", sLogLevel, SSHCFG_ALL },
568 { "logverbose", sLogVerbose, SSHCFG_ALL },
569 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
570 { "rhostsrsaauthentication", sDeprecated, SSHCFG_ALL },
571 { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
572 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_ALL },
573 { "hostbasedacceptedalgorithms", sHostbasedAcceptedAlgorithms, SSHCFG_ALL },
574 { "hostbasedacceptedkeytypes", sHostbasedAcceptedAlgorithms, SSHCFG_ALL }, /* obsolete */
575 { "hostkeyalgorithms", sHostKeyAlgorithms, SSHCFG_GLOBAL },
576 { "rsaauthentication", sDeprecated, SSHCFG_ALL },
577 { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
578 { "pubkeyacceptedalgorithms", sPubkeyAcceptedAlgorithms, SSHCFG_ALL },
579 { "pubkeyacceptedkeytypes", sPubkeyAcceptedAlgorithms, SSHCFG_ALL }, /* obsolete */
580 { "pubkeyauthoptions", sPubkeyAuthOptions, SSHCFG_ALL },
581 { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
583 { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
584 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
585 { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
587 { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
589 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
592 { "kerberosauthentication", sUnsupported, SSHCFG_ALL },
593 { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
594 { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
595 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
597 { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
598 { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
600 { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
601 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
602 { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
604 { "gssapiauthentication", sUnsupported, SSHCFG_ALL },
605 { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
606 { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
608 { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
609 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
610 { "challengeresponseauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, /* alias */
611 { "skeyauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, /* alias */
612 { "checkmail", sDeprecated, SSHCFG_GLOBAL },
613 { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
614 { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
615 { "printmotd", sPrintMotd, SSHCFG_GLOBAL },
616 #ifdef DISABLE_LASTLOG
617 { "printlastlog", sUnsupported, SSHCFG_GLOBAL },
619 { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
621 { "ignorerhosts", sIgnoreRhosts, SSHCFG_ALL },
622 { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
623 { "x11forwarding", sX11Forwarding, SSHCFG_ALL },
624 { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
625 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
626 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
627 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
628 { "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL },
629 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
630 { "uselogin", sDeprecated, SSHCFG_GLOBAL },
631 { "compression", sCompression, SSHCFG_GLOBAL },
632 { "rekeylimit", sRekeyLimit, SSHCFG_ALL },
633 { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
634 { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
635 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
636 { "allowagentforwarding", sAllowAgentForwarding, SSHCFG_ALL },
637 { "allowusers", sAllowUsers, SSHCFG_ALL },
638 { "denyusers", sDenyUsers, SSHCFG_ALL },
639 { "allowgroups", sAllowGroups, SSHCFG_ALL },
640 { "denygroups", sDenyGroups, SSHCFG_ALL },
641 { "ciphers", sCiphers, SSHCFG_GLOBAL },
642 { "macs", sMacs, SSHCFG_GLOBAL },
643 { "protocol", sIgnore, SSHCFG_GLOBAL },
644 { "gatewayports", sGatewayPorts, SSHCFG_ALL },
645 { "subsystem", sSubsystem, SSHCFG_GLOBAL },
646 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
647 { "persourcemaxstartups", sPerSourceMaxStartups, SSHCFG_GLOBAL },
648 { "persourcenetblocksize", sPerSourceNetBlockSize, SSHCFG_GLOBAL },
649 { "maxauthtries", sMaxAuthTries, SSHCFG_ALL },
650 { "maxsessions", sMaxSessions, SSHCFG_ALL },
651 { "banner", sBanner, SSHCFG_ALL },
652 { "usedns", sUseDNS, SSHCFG_GLOBAL },
653 { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
654 { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
655 { "clientaliveinterval", sClientAliveInterval, SSHCFG_ALL },
656 { "clientalivecountmax", sClientAliveCountMax, SSHCFG_ALL },
657 { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_ALL },
658 { "authorizedkeysfile2", sDeprecated, SSHCFG_ALL },
659 { "useprivilegeseparation", sDeprecated, SSHCFG_GLOBAL},
660 { "acceptenv", sAcceptEnv, SSHCFG_ALL },
661 { "setenv", sSetEnv, SSHCFG_ALL },
662 { "permittunnel", sPermitTunnel, SSHCFG_ALL },
663 { "permittty", sPermitTTY, SSHCFG_ALL },
664 { "permituserrc", sPermitUserRC, SSHCFG_ALL },
665 { "match", sMatch, SSHCFG_ALL },
666 { "permitopen", sPermitOpen, SSHCFG_ALL },
667 { "permitlisten", sPermitListen, SSHCFG_ALL },
668 { "forcecommand", sForceCommand, SSHCFG_ALL },
669 { "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
670 { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
671 { "revokedkeys", sRevokedKeys, SSHCFG_ALL },
672 { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
673 { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
674 { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
675 { "include", sInclude, SSHCFG_ALL },
676 { "ipqos", sIPQoS, SSHCFG_ALL },
677 { "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL },
678 { "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL },
679 { "authorizedprincipalscommand", sAuthorizedPrincipalsCommand, SSHCFG_ALL },
680 { "authorizedprincipalscommanduser", sAuthorizedPrincipalsCommandUser, SSHCFG_ALL },
681 { "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
682 { "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL },
683 { "streamlocalbindmask", sStreamLocalBindMask, SSHCFG_ALL },
684 { "streamlocalbindunlink", sStreamLocalBindUnlink, SSHCFG_ALL },
685 { "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL },
686 { "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL },
687 { "disableforwarding", sDisableForwarding, SSHCFG_ALL },
688 { "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL },
689 { "rdomain", sRDomain, SSHCFG_ALL },
690 { "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL },
691 { "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL },
692 { "useblacklist", sUseBlacklist, SSHCFG_GLOBAL },
693 { "useblocklist", sUseBlacklist, SSHCFG_GLOBAL }, /* alias */
694 { "noneenabled", sUnsupported, SSHCFG_ALL },
695 { "hpndisabled", sDeprecated, SSHCFG_ALL },
696 { "hpnbuffersize", sDeprecated, SSHCFG_ALL },
697 { "tcprcvbufpoll", sDeprecated, SSHCFG_ALL },
698 { NULL, sBadOption, 0 }
705 { SSH_TUNMODE_NO, "no" },
706 { SSH_TUNMODE_POINTOPOINT, "point-to-point" },
707 { SSH_TUNMODE_ETHERNET, "ethernet" },
708 { SSH_TUNMODE_YES, "yes" },
712 /* Returns an opcode name from its number */
715 lookup_opcode_name(ServerOpCodes code)
719 for (i = 0; keywords[i].name != NULL; i++)
720 if (keywords[i].opcode == code)
721 return(keywords[i].name);
727 * Returns the number of the token pointed to by cp or sBadOption.
731 parse_token(const char *cp, const char *filename,
732 int linenum, u_int *flags)
736 for (i = 0; keywords[i].name; i++)
737 if (strcasecmp(cp, keywords[i].name) == 0) {
738 *flags = keywords[i].flags;
739 return keywords[i].opcode;
742 error("%s: line %d: Bad configuration option: %s",
743 filename, linenum, cp);
748 derelativise_path(const char *path)
750 char *expanded, *ret, cwd[PATH_MAX];
752 if (strcasecmp(path, "none") == 0)
753 return xstrdup("none");
754 expanded = tilde_expand_filename(path, getuid());
755 if (path_absolute(expanded))
757 if (getcwd(cwd, sizeof(cwd)) == NULL)
758 fatal_f("getcwd: %s", strerror(errno));
759 xasprintf(&ret, "%s/%s", cwd, expanded);
765 add_listen_addr(ServerOptions *options, const char *addr,
766 const char *rdomain, int port)
771 add_one_listen_addr(options, addr, rdomain, port);
773 for (i = 0; i < options->num_ports; i++) {
774 add_one_listen_addr(options, addr, rdomain,
781 add_one_listen_addr(ServerOptions *options, const char *addr,
782 const char *rdomain, int port)
784 struct addrinfo hints, *ai, *aitop;
785 char strport[NI_MAXSERV];
789 /* Find listen_addrs entry for this rdomain */
790 for (i = 0; i < options->num_listen_addrs; i++) {
791 if (rdomain == NULL && options->listen_addrs[i].rdomain == NULL)
793 if (rdomain == NULL || options->listen_addrs[i].rdomain == NULL)
795 if (strcmp(rdomain, options->listen_addrs[i].rdomain) == 0)
798 if (i >= options->num_listen_addrs) {
799 /* No entry for this rdomain; allocate one */
801 fatal_f("too many listen addresses");
802 options->listen_addrs = xrecallocarray(options->listen_addrs,
803 options->num_listen_addrs, options->num_listen_addrs + 1,
804 sizeof(*options->listen_addrs));
805 i = options->num_listen_addrs++;
807 options->listen_addrs[i].rdomain = xstrdup(rdomain);
809 /* options->listen_addrs[i] points to the addresses for this rdomain */
811 memset(&hints, 0, sizeof(hints));
812 hints.ai_family = options->address_family;
813 hints.ai_socktype = SOCK_STREAM;
814 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
815 snprintf(strport, sizeof strport, "%d", port);
816 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
817 fatal("bad addr or host: %s (%s)",
818 addr ? addr : "<NULL>",
819 ssh_gai_strerror(gaierr));
820 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
822 ai->ai_next = options->listen_addrs[i].addrs;
823 options->listen_addrs[i].addrs = aitop;
826 /* Returns nonzero if the routing domain name is valid */
828 valid_rdomain(const char *name)
830 #if defined(HAVE_SYS_VALID_RDOMAIN)
831 return sys_valid_rdomain(name);
832 #elif defined(__OpenBSD__)
835 struct rt_tableinfo info;
837 size_t miblen = sizeof(mib);
842 num = strtonum(name, 0, 255, &errstr);
846 /* Check whether the table actually exists */
847 memset(mib, 0, sizeof(mib));
850 mib[4] = NET_RT_TABLE;
852 if (sysctl(mib, 6, &info, &miblen, NULL, 0) == -1)
856 #else /* defined(__OpenBSD__) */
857 error("Routing domains are not supported on this platform");
863 * Queue a ListenAddress to be processed once we have all of the Ports
864 * and AddressFamily options.
867 queue_listen_addr(ServerOptions *options, const char *addr,
868 const char *rdomain, int port)
870 struct queued_listenaddr *qla;
872 options->queued_listen_addrs = xrecallocarray(
873 options->queued_listen_addrs,
874 options->num_queued_listens, options->num_queued_listens + 1,
875 sizeof(*options->queued_listen_addrs));
876 qla = &options->queued_listen_addrs[options->num_queued_listens++];
877 qla->addr = xstrdup(addr);
879 qla->rdomain = rdomain == NULL ? NULL : xstrdup(rdomain);
883 * Process queued (text) ListenAddress entries.
886 process_queued_listen_addrs(ServerOptions *options)
889 struct queued_listenaddr *qla;
891 if (options->num_ports == 0)
892 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
893 if (options->address_family == -1)
894 options->address_family = AF_UNSPEC;
896 for (i = 0; i < options->num_queued_listens; i++) {
897 qla = &options->queued_listen_addrs[i];
898 add_listen_addr(options, qla->addr, qla->rdomain, qla->port);
902 free(options->queued_listen_addrs);
903 options->queued_listen_addrs = NULL;
904 options->num_queued_listens = 0;
908 * Inform channels layer of permitopen options for a single forwarding
909 * direction (local/remote).
912 process_permitopen_list(struct ssh *ssh, ServerOpCodes opcode,
913 char **opens, u_int num_opens)
917 char *host, *arg, *oarg, ch;
918 int where = opcode == sPermitOpen ? FORWARD_LOCAL : FORWARD_REMOTE;
919 const char *what = lookup_opcode_name(opcode);
921 channel_clear_permission(ssh, FORWARD_ADM, where);
923 return; /* permit any */
925 /* handle keywords: "any" / "none" */
926 if (num_opens == 1 && strcmp(opens[0], "any") == 0)
928 if (num_opens == 1 && strcmp(opens[0], "none") == 0) {
929 channel_disable_admin(ssh, where);
932 /* Otherwise treat it as a list of permitted host:port */
933 for (i = 0; i < num_opens; i++) {
934 oarg = arg = xstrdup(opens[i]);
936 host = hpdelim2(&arg, &ch);
937 if (host == NULL || ch == '/')
938 fatal_f("missing host in %s", what);
939 host = cleanhostname(host);
940 if (arg == NULL || ((port = permitopen_port(arg)) < 0))
941 fatal_f("bad port number in %s", what);
942 /* Send it to channels layer */
943 channel_add_permission(ssh, FORWARD_ADM,
950 * Inform channels layer of permitopen options from configuration.
953 process_permitopen(struct ssh *ssh, ServerOptions *options)
955 process_permitopen_list(ssh, sPermitOpen,
956 options->permitted_opens, options->num_permitted_opens);
957 process_permitopen_list(ssh, sPermitListen,
958 options->permitted_listens,
959 options->num_permitted_listens);
962 struct connection_info *
963 get_connection_info(struct ssh *ssh, int populate, int use_dns)
965 static struct connection_info ci;
967 if (ssh == NULL || !populate)
969 ci.host = auth_get_canonical_hostname(ssh, use_dns);
970 ci.address = ssh_remote_ipaddr(ssh);
971 ci.laddress = ssh_local_ipaddr(ssh);
972 ci.lport = ssh_local_port(ssh);
973 ci.rdomain = ssh_packet_rdomain_in(ssh);
978 * The strategy for the Match blocks is that the config file is parsed twice.
980 * The first time is at startup. activep is initialized to 1 and the
981 * directives in the global context are processed and acted on. Hitting a
982 * Match directive unsets activep and the directives inside the block are
983 * checked for syntax only.
985 * The second time is after a connection has been established but before
986 * authentication. activep is initialized to 2 and global config directives
987 * are ignored since they have already been processed. If the criteria in a
988 * Match block is met, activep is set and the subsequent directives
989 * processed and actioned until EOF or another Match block unsets it. Any
990 * options set are copied into the main server config.
992 * Potential additions/improvements:
993 * - Add Match support for pre-kex directives, eg. Ciphers.
995 * - Add a Tag directive (idea from David Leonard) ala pf, eg:
996 * Match Address 192.168.0.*
1001 * AllowTcpForwarding yes
1002 * GatewayPorts clientspecified
1005 * - Add a PermittedChannelRequests directive
1007 * PermittedChannelRequests session,forwarded-tcpip
1011 match_cfg_line_group(const char *grps, int line, const char *user)
1019 if ((pw = getpwnam(user)) == NULL) {
1020 debug("Can't match group at line %d because user %.100s does "
1021 "not exist", line, user);
1022 } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
1023 debug("Can't Match group because user %.100s not in any group "
1024 "at line %d", user, line);
1025 } else if (ga_match_pattern_list(grps) != 1) {
1026 debug("user %.100s does not match group list %.100s at line %d",
1029 debug("user %.100s matched group list %.100s at line %d", user,
1039 match_test_missing_fatal(const char *criteria, const char *attrib)
1041 fatal("'Match %s' in configuration but '%s' not in connection "
1042 "test specification.", criteria, attrib);
1046 * All of the attributes on a single Match line are ANDed together, so we need
1047 * to check every attribute and set the result to zero if any attribute does
1051 match_cfg_line(char **condition, int line, struct connection_info *ci)
1053 int result = 1, attributes = 0, port;
1054 char *arg, *attrib, *cp = *condition;
1057 debug3("checking syntax for 'Match %s'", cp);
1059 debug3("checking match for '%s' user %s host %s addr %s "
1060 "laddr %s lport %d", cp, ci->user ? ci->user : "(null)",
1061 ci->host ? ci->host : "(null)",
1062 ci->address ? ci->address : "(null)",
1063 ci->laddress ? ci->laddress : "(null)", ci->lport);
1065 while ((attrib = strdelim(&cp)) && *attrib != '\0') {
1066 /* Terminate on comment */
1067 if (*attrib == '#') {
1068 cp = NULL; /* mark all arguments consumed */
1073 /* Criterion "all" has no argument and must appear alone */
1074 if (strcasecmp(attrib, "all") == 0) {
1075 if (attributes > 1 || ((arg = strdelim(&cp)) != NULL &&
1076 *arg != '\0' && *arg != '#')) {
1077 error("'all' cannot be combined with other "
1078 "Match attributes");
1081 if (arg != NULL && *arg == '#')
1082 cp = NULL; /* mark all arguments consumed */
1086 /* All other criteria require an argument */
1087 if ((arg = strdelim(&cp)) == NULL ||
1088 *arg == '\0' || *arg == '#') {
1089 error("Missing Match criteria for %s", attrib);
1092 if (strcasecmp(attrib, "user") == 0) {
1093 if (ci == NULL || (ci->test && ci->user == NULL)) {
1097 if (ci->user == NULL)
1098 match_test_missing_fatal("User", "user");
1099 if (match_usergroup_pattern_list(ci->user, arg) != 1)
1102 debug("user %.100s matched 'User %.100s' at "
1103 "line %d", ci->user, arg, line);
1104 } else if (strcasecmp(attrib, "group") == 0) {
1105 if (ci == NULL || (ci->test && ci->user == NULL)) {
1109 if (ci->user == NULL)
1110 match_test_missing_fatal("Group", "user");
1111 switch (match_cfg_line_group(arg, line, ci->user)) {
1117 } else if (strcasecmp(attrib, "host") == 0) {
1118 if (ci == NULL || (ci->test && ci->host == NULL)) {
1122 if (ci->host == NULL)
1123 match_test_missing_fatal("Host", "host");
1124 if (match_hostname(ci->host, arg) != 1)
1127 debug("connection from %.100s matched 'Host "
1128 "%.100s' at line %d", ci->host, arg, line);
1129 } else if (strcasecmp(attrib, "address") == 0) {
1130 if (ci == NULL || (ci->test && ci->address == NULL)) {
1131 if (addr_match_list(NULL, arg) != 0)
1132 fatal("Invalid Match address argument "
1133 "'%s' at line %d", arg, line);
1137 if (ci->address == NULL)
1138 match_test_missing_fatal("Address", "addr");
1139 switch (addr_match_list(ci->address, arg)) {
1141 debug("connection from %.100s matched 'Address "
1142 "%.100s' at line %d", ci->address, arg, line);
1151 } else if (strcasecmp(attrib, "localaddress") == 0){
1152 if (ci == NULL || (ci->test && ci->laddress == NULL)) {
1153 if (addr_match_list(NULL, arg) != 0)
1154 fatal("Invalid Match localaddress "
1155 "argument '%s' at line %d", arg,
1160 if (ci->laddress == NULL)
1161 match_test_missing_fatal("LocalAddress",
1163 switch (addr_match_list(ci->laddress, arg)) {
1165 debug("connection from %.100s matched "
1166 "'LocalAddress %.100s' at line %d",
1167 ci->laddress, arg, line);
1176 } else if (strcasecmp(attrib, "localport") == 0) {
1177 if ((port = a2port(arg)) == -1) {
1178 error("Invalid LocalPort '%s' on Match line",
1182 if (ci == NULL || (ci->test && ci->lport == -1)) {
1187 match_test_missing_fatal("LocalPort", "lport");
1188 /* TODO support port lists */
1189 if (port == ci->lport)
1190 debug("connection from %.100s matched "
1191 "'LocalPort %d' at line %d",
1192 ci->laddress, port, line);
1195 } else if (strcasecmp(attrib, "rdomain") == 0) {
1196 if (ci == NULL || (ci->test && ci->rdomain == NULL)) {
1200 if (ci->rdomain == NULL)
1201 match_test_missing_fatal("RDomain", "rdomain");
1202 if (match_pattern_list(ci->rdomain, arg, 0) != 1)
1205 debug("user %.100s matched 'RDomain %.100s' at "
1206 "line %d", ci->rdomain, arg, line);
1208 error("Unsupported Match attribute %s", attrib);
1212 if (attributes == 0) {
1213 error("One or more attributes required for Match");
1217 debug3("match %sfound", result ? "" : "not ");
1222 #define WHITESPACE " \t\r\n"
1224 /* Multistate option parsing */
1229 static const struct multistate multistate_flag[] = {
1234 static const struct multistate multistate_ignore_rhosts[] = {
1235 { "yes", IGNORE_RHOSTS_YES },
1236 { "no", IGNORE_RHOSTS_NO },
1237 { "shosts-only", IGNORE_RHOSTS_SHOSTS },
1240 static const struct multistate multistate_addressfamily[] = {
1241 { "inet", AF_INET },
1242 { "inet6", AF_INET6 },
1243 { "any", AF_UNSPEC },
1246 static const struct multistate multistate_permitrootlogin[] = {
1247 { "without-password", PERMIT_NO_PASSWD },
1248 { "prohibit-password", PERMIT_NO_PASSWD },
1249 { "forced-commands-only", PERMIT_FORCED_ONLY },
1250 { "yes", PERMIT_YES },
1251 { "no", PERMIT_NO },
1254 static const struct multistate multistate_compression[] = {
1256 { "yes", COMP_DELAYED },
1257 { "delayed", COMP_DELAYED },
1259 { "no", COMP_NONE },
1262 static const struct multistate multistate_gatewayports[] = {
1263 { "clientspecified", 2 },
1268 static const struct multistate multistate_tcpfwd[] = {
1269 { "yes", FORWARD_ALLOW },
1270 { "all", FORWARD_ALLOW },
1271 { "no", FORWARD_DENY },
1272 { "remote", FORWARD_REMOTE },
1273 { "local", FORWARD_LOCAL },
1278 process_server_config_line_depth(ServerOptions *options, char *line,
1279 const char *filename, int linenum, int *activep,
1280 struct connection_info *connectinfo, int *inc_flags, int depth,
1281 struct include_list *includes)
1283 char ch, *str, ***chararrayptr, **charptr, *arg, *arg2, *p, *keyword;
1284 int cmdline = 0, *intptr, value, value2, n, port, oactive, r, found;
1285 SyslogFacility *log_facility_ptr;
1286 LogLevel *log_level_ptr;
1287 ServerOpCodes opcode;
1288 u_int i, *uintptr, uvalue, flags = 0;
1291 const struct multistate *multistate_ptr;
1293 struct include_item *item;
1295 char **oav = NULL, **av;
1299 /* Strip trailing whitespace. Allow \f (form feed) at EOL only */
1300 if ((len = strlen(line)) == 0)
1302 for (len--; len > 0; len--) {
1303 if (strchr(WHITESPACE "\f", line[len]) == NULL)
1309 if ((keyword = strdelim(&str)) == NULL)
1311 /* Ignore leading whitespace */
1312 if (*keyword == '\0')
1313 keyword = strdelim(&str);
1314 if (!keyword || !*keyword || *keyword == '#')
1316 if (str == NULL || *str == '\0') {
1317 error("%s line %d: no argument after keyword \"%s\"",
1318 filename, linenum, keyword);
1323 opcode = parse_token(keyword, filename, linenum, &flags);
1325 if (argv_split(str, &oac, &oav, 1) != 0) {
1326 error("%s line %d: invalid quotes", filename, linenum);
1332 if (activep == NULL) { /* We are processing a command line directive */
1336 if (*activep && opcode != sMatch && opcode != sInclude)
1337 debug3("%s:%d setting %s %s", filename, linenum, keyword, str);
1338 if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
1339 if (connectinfo == NULL) {
1340 fatal("%s line %d: Directive '%s' is not allowed "
1341 "within a Match block", filename, linenum, keyword);
1342 } else { /* this is a directive we have already processed */
1349 /* Portable-specific options */
1351 intptr = &options->use_pam;
1354 /* Standard Options */
1358 /* ignore ports from configfile if cmdline specifies ports */
1359 if (options->ports_from_cmdline) {
1363 if (options->num_ports >= MAX_PORTS)
1364 fatal("%s line %d: too many ports.",
1366 arg = argv_next(&ac, &av);
1367 if (!arg || *arg == '\0')
1368 fatal("%s line %d: missing port number.",
1370 options->ports[options->num_ports++] = a2port(arg);
1371 if (options->ports[options->num_ports-1] <= 0)
1372 fatal("%s line %d: Badly formatted port number.",
1376 case sLoginGraceTime:
1377 intptr = &options->login_grace_time;
1379 arg = argv_next(&ac, &av);
1380 if (!arg || *arg == '\0')
1381 fatal("%s line %d: missing time value.",
1383 if ((value = convtime(arg)) == -1)
1384 fatal("%s line %d: invalid time value.",
1386 if (*activep && *intptr == -1)
1390 case sListenAddress:
1391 arg = argv_next(&ac, &av);
1392 if (arg == NULL || *arg == '\0')
1393 fatal("%s line %d: missing address",
1395 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
1396 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
1397 && strchr(p+1, ':') != NULL) {
1403 p = hpdelim2(&arg, &ch);
1404 if (p == NULL || ch == '/')
1405 fatal("%s line %d: bad address:port usage",
1407 p = cleanhostname(p);
1410 else if ((port = a2port(arg)) <= 0)
1411 fatal("%s line %d: bad port number",
1414 /* Optional routing table */
1416 if ((arg = argv_next(&ac, &av)) != NULL) {
1417 if (strcmp(arg, "rdomain") != 0 ||
1418 (arg2 = argv_next(&ac, &av)) == NULL)
1419 fatal("%s line %d: bad ListenAddress syntax",
1421 if (!valid_rdomain(arg2))
1422 fatal("%s line %d: bad routing domain",
1425 queue_listen_addr(options, p, arg2, port);
1429 case sAddressFamily:
1430 intptr = &options->address_family;
1431 multistate_ptr = multistate_addressfamily;
1433 arg = argv_next(&ac, &av);
1434 if (!arg || *arg == '\0')
1435 fatal("%s line %d: missing argument.",
1438 for (i = 0; multistate_ptr[i].key != NULL; i++) {
1439 if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
1440 value = multistate_ptr[i].value;
1445 fatal("%s line %d: unsupported option \"%s\".",
1446 filename, linenum, arg);
1447 if (*activep && *intptr == -1)
1452 arg = argv_next(&ac, &av);
1453 if (!arg || *arg == '\0')
1454 fatal("%s line %d: missing file name.",
1457 servconf_add_hostkey(filename, linenum,
1463 charptr = &options->host_key_agent;
1464 arg = argv_next(&ac, &av);
1465 if (!arg || *arg == '\0')
1466 fatal("%s line %d: missing socket name.",
1468 if (*activep && *charptr == NULL)
1469 *charptr = !strcmp(arg, SSH_AUTHSOCKET_ENV_NAME) ?
1470 xstrdup(arg) : derelativise_path(arg);
1473 case sHostCertificate:
1474 arg = argv_next(&ac, &av);
1475 if (!arg || *arg == '\0')
1476 fatal("%s line %d: missing file name.",
1479 servconf_add_hostcert(filename, linenum, options, arg);
1483 charptr = &options->pid_file;
1485 arg = argv_next(&ac, &av);
1486 if (!arg || *arg == '\0')
1487 fatal("%s line %d: missing file name.",
1489 if (*activep && *charptr == NULL) {
1490 *charptr = derelativise_path(arg);
1491 /* increase optional counter */
1493 *intptr = *intptr + 1;
1498 charptr = &options->moduli_file;
1499 goto parse_filename;
1501 case sPermitRootLogin:
1502 intptr = &options->permit_root_login;
1503 multistate_ptr = multistate_permitrootlogin;
1504 goto parse_multistate;
1507 intptr = &options->ignore_rhosts;
1508 multistate_ptr = multistate_ignore_rhosts;
1509 goto parse_multistate;
1511 case sIgnoreUserKnownHosts:
1512 intptr = &options->ignore_user_known_hosts;
1514 multistate_ptr = multistate_flag;
1515 goto parse_multistate;
1517 case sHostbasedAuthentication:
1518 intptr = &options->hostbased_authentication;
1521 case sHostbasedUsesNameFromPacketOnly:
1522 intptr = &options->hostbased_uses_name_from_packet_only;
1525 case sHostbasedAcceptedAlgorithms:
1526 charptr = &options->hostbased_accepted_algos;
1528 arg = argv_next(&ac, &av);
1529 if (!arg || *arg == '\0')
1530 fatal("%s line %d: Missing argument.",
1533 !sshkey_names_valid2(*arg == '+' || *arg == '^' ?
1535 fatal("%s line %d: Bad key types '%s'.",
1536 filename, linenum, arg ? arg : "<NONE>");
1537 if (*activep && *charptr == NULL)
1538 *charptr = xstrdup(arg);
1541 case sHostKeyAlgorithms:
1542 charptr = &options->hostkeyalgorithms;
1543 goto parse_pubkey_algos;
1545 case sCASignatureAlgorithms:
1546 charptr = &options->ca_sign_algorithms;
1547 goto parse_pubkey_algos;
1549 case sPubkeyAuthentication:
1550 intptr = &options->pubkey_authentication;
1553 case sPubkeyAcceptedAlgorithms:
1554 charptr = &options->pubkey_accepted_algos;
1555 goto parse_pubkey_algos;
1557 case sPubkeyAuthOptions:
1558 intptr = &options->pubkey_auth_options;
1560 while ((arg = argv_next(&ac, &av)) != NULL) {
1561 if (strcasecmp(arg, "none") == 0)
1563 if (strcasecmp(arg, "touch-required") == 0)
1564 value |= PUBKEYAUTH_TOUCH_REQUIRED;
1565 else if (strcasecmp(arg, "verify-required") == 0)
1566 value |= PUBKEYAUTH_VERIFY_REQUIRED;
1568 error("%s line %d: unsupported %s option %s",
1569 filename, linenum, keyword, arg);
1573 if (*activep && *intptr == -1)
1577 case sKerberosAuthentication:
1578 intptr = &options->kerberos_authentication;
1581 case sKerberosOrLocalPasswd:
1582 intptr = &options->kerberos_or_local_passwd;
1585 case sKerberosTicketCleanup:
1586 intptr = &options->kerberos_ticket_cleanup;
1589 case sKerberosGetAFSToken:
1590 intptr = &options->kerberos_get_afs_token;
1593 case sGssAuthentication:
1594 intptr = &options->gss_authentication;
1597 case sGssCleanupCreds:
1598 intptr = &options->gss_cleanup_creds;
1601 case sGssStrictAcceptor:
1602 intptr = &options->gss_strict_acceptor;
1605 case sPasswordAuthentication:
1606 intptr = &options->password_authentication;
1609 case sKbdInteractiveAuthentication:
1610 intptr = &options->kbd_interactive_authentication;
1614 intptr = &options->print_motd;
1618 intptr = &options->print_lastlog;
1621 case sX11Forwarding:
1622 intptr = &options->x11_forwarding;
1625 case sX11DisplayOffset:
1626 intptr = &options->x11_display_offset;
1628 arg = argv_next(&ac, &av);
1629 if ((errstr = atoi_err(arg, &value)) != NULL)
1630 fatal("%s line %d: %s integer value %s.",
1631 filename, linenum, keyword, errstr);
1632 if (*activep && *intptr == -1)
1636 case sX11UseLocalhost:
1637 intptr = &options->x11_use_localhost;
1640 case sXAuthLocation:
1641 charptr = &options->xauth_location;
1642 goto parse_filename;
1645 intptr = &options->permit_tty;
1649 intptr = &options->permit_user_rc;
1653 intptr = &options->strict_modes;
1657 intptr = &options->tcp_keep_alive;
1661 intptr = &options->permit_empty_passwd;
1664 case sPermitUserEnvironment:
1665 intptr = &options->permit_user_env;
1666 charptr = &options->permit_user_env_allowlist;
1667 arg = argv_next(&ac, &av);
1668 if (!arg || *arg == '\0')
1669 fatal("%s line %d: %s missing argument.",
1670 filename, linenum, keyword);
1673 if (strcmp(arg, "yes") == 0)
1675 else if (strcmp(arg, "no") == 0)
1678 /* Pattern-list specified */
1682 if (*activep && *intptr == -1) {
1691 intptr = &options->compression;
1692 multistate_ptr = multistate_compression;
1693 goto parse_multistate;
1696 arg = argv_next(&ac, &av);
1697 if (!arg || *arg == '\0')
1698 fatal("%s line %d: %s missing argument.",
1699 filename, linenum, keyword);
1700 if (strcmp(arg, "default") == 0) {
1703 if (scan_scaled(arg, &val64) == -1)
1704 fatal("%.200s line %d: Bad %s number '%s': %s",
1705 filename, linenum, keyword,
1706 arg, strerror(errno));
1707 if (val64 != 0 && val64 < 16)
1708 fatal("%.200s line %d: %s too small",
1709 filename, linenum, keyword);
1711 if (*activep && options->rekey_limit == -1)
1712 options->rekey_limit = val64;
1713 if (ac != 0) { /* optional rekey interval present */
1714 if (strcmp(av[0], "none") == 0) {
1715 (void)argv_next(&ac, &av); /* discard */
1718 intptr = &options->rekey_interval;
1724 intptr = &options->fwd_opts.gateway_ports;
1725 multistate_ptr = multistate_gatewayports;
1726 goto parse_multistate;
1729 intptr = &options->use_dns;
1733 log_facility_ptr = &options->log_facility;
1734 arg = argv_next(&ac, &av);
1735 value = log_facility_number(arg);
1736 if (value == SYSLOG_FACILITY_NOT_SET)
1737 fatal("%.200s line %d: unsupported log facility '%s'",
1738 filename, linenum, arg ? arg : "<NONE>");
1739 if (*log_facility_ptr == -1)
1740 *log_facility_ptr = (SyslogFacility) value;
1744 log_level_ptr = &options->log_level;
1745 arg = argv_next(&ac, &av);
1746 value = log_level_number(arg);
1747 if (value == SYSLOG_LEVEL_NOT_SET)
1748 fatal("%.200s line %d: unsupported log level '%s'",
1749 filename, linenum, arg ? arg : "<NONE>");
1750 if (*activep && *log_level_ptr == -1)
1751 *log_level_ptr = (LogLevel) value;
1755 found = options->num_log_verbose == 0;
1757 while ((arg = argv_next(&ac, &av)) != NULL) {
1759 error("%s line %d: keyword %s empty argument",
1760 filename, linenum, keyword);
1763 /* Allow "none" only in first position */
1764 if (strcasecmp(arg, "none") == 0) {
1765 if (i > 0 || ac > 0) {
1766 error("%s line %d: keyword %s \"none\" "
1767 "argument must appear alone.",
1768 filename, linenum, keyword);
1773 if (!found || !*activep)
1775 opt_array_append(filename, linenum, keyword,
1776 &options->log_verbose, &options->num_log_verbose,
1781 case sAllowTcpForwarding:
1782 intptr = &options->allow_tcp_forwarding;
1783 multistate_ptr = multistate_tcpfwd;
1784 goto parse_multistate;
1786 case sAllowStreamLocalForwarding:
1787 intptr = &options->allow_streamlocal_forwarding;
1788 multistate_ptr = multistate_tcpfwd;
1789 goto parse_multistate;
1791 case sAllowAgentForwarding:
1792 intptr = &options->allow_agent_forwarding;
1795 case sDisableForwarding:
1796 intptr = &options->disable_forwarding;
1800 chararrayptr = &options->allow_users;
1801 uintptr = &options->num_allow_users;
1802 parse_allowdenyusers:
1803 while ((arg = argv_next(&ac, &av)) != NULL) {
1805 match_user(NULL, NULL, NULL, arg) == -1)
1806 fatal("%s line %d: invalid %s pattern: \"%s\"",
1807 filename, linenum, keyword, arg);
1810 opt_array_append(filename, linenum, keyword,
1811 chararrayptr, uintptr, arg);
1816 chararrayptr = &options->deny_users;
1817 uintptr = &options->num_deny_users;
1818 goto parse_allowdenyusers;
1821 chararrayptr = &options->allow_groups;
1822 uintptr = &options->num_allow_groups;
1823 parse_allowdenygroups:
1824 while ((arg = argv_next(&ac, &av)) != NULL) {
1826 fatal("%s line %d: empty %s pattern",
1827 filename, linenum, keyword);
1830 opt_array_append(filename, linenum, keyword,
1831 chararrayptr, uintptr, arg);
1836 chararrayptr = &options->deny_groups;
1837 uintptr = &options->num_deny_groups;
1838 goto parse_allowdenygroups;
1841 arg = argv_next(&ac, &av);
1842 if (!arg || *arg == '\0')
1843 fatal("%s line %d: %s missing argument.",
1844 filename, linenum, keyword);
1846 !ciphers_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg))
1847 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1848 filename, linenum, arg ? arg : "<NONE>");
1849 if (options->ciphers == NULL)
1850 options->ciphers = xstrdup(arg);
1854 arg = argv_next(&ac, &av);
1855 if (!arg || *arg == '\0')
1856 fatal("%s line %d: %s missing argument.",
1857 filename, linenum, keyword);
1859 !mac_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg))
1860 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1861 filename, linenum, arg ? arg : "<NONE>");
1862 if (options->macs == NULL)
1863 options->macs = xstrdup(arg);
1866 case sKexAlgorithms:
1867 arg = argv_next(&ac, &av);
1868 if (!arg || *arg == '\0')
1869 fatal("%s line %d: %s missing argument.",
1870 filename, linenum, keyword);
1872 !kex_names_valid(*arg == '+' || *arg == '^' ?
1874 fatal("%s line %d: Bad SSH2 KexAlgorithms '%s'.",
1875 filename, linenum, arg ? arg : "<NONE>");
1876 if (options->kex_algorithms == NULL)
1877 options->kex_algorithms = xstrdup(arg);
1881 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1882 fatal("%s line %d: too many subsystems defined.",
1885 arg = argv_next(&ac, &av);
1886 if (!arg || *arg == '\0')
1887 fatal("%s line %d: %s missing argument.",
1888 filename, linenum, keyword);
1890 arg = argv_next(&ac, &av);
1893 for (i = 0; i < options->num_subsystems; i++)
1894 if (strcmp(arg, options->subsystem_name[i]) == 0)
1895 fatal("%s line %d: Subsystem '%s' "
1896 "already defined.", filename, linenum, arg);
1897 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1898 arg = argv_next(&ac, &av);
1899 if (!arg || *arg == '\0')
1900 fatal("%s line %d: Missing subsystem command.",
1902 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1904 /* Collect arguments (separate to executable) */
1906 len = strlen(p) + 1;
1907 while ((arg = argv_next(&ac, &av)) != NULL) {
1908 len += 1 + strlen(arg);
1909 p = xreallocarray(p, 1, len);
1910 strlcat(p, " ", len);
1911 strlcat(p, arg, len);
1913 options->subsystem_args[options->num_subsystems] = p;
1914 options->num_subsystems++;
1918 arg = argv_next(&ac, &av);
1919 if (!arg || *arg == '\0')
1920 fatal("%s line %d: %s missing argument.",
1921 filename, linenum, keyword);
1922 if ((n = sscanf(arg, "%d:%d:%d",
1923 &options->max_startups_begin,
1924 &options->max_startups_rate,
1925 &options->max_startups)) == 3) {
1926 if (options->max_startups_begin >
1927 options->max_startups ||
1928 options->max_startups_rate > 100 ||
1929 options->max_startups_rate < 1)
1930 fatal("%s line %d: Invalid %s spec.",
1931 filename, linenum, keyword);
1933 fatal("%s line %d: Invalid %s spec.",
1934 filename, linenum, keyword);
1936 options->max_startups = options->max_startups_begin;
1939 case sPerSourceNetBlockSize:
1940 arg = argv_next(&ac, &av);
1941 if (!arg || *arg == '\0')
1942 fatal("%s line %d: %s missing argument.",
1943 filename, linenum, keyword);
1944 switch (n = sscanf(arg, "%d:%d", &value, &value2)) {
1946 if (value2 < 0 || value2 > 128)
1950 if (value < 0 || value > 32)
1953 if (n != 1 && n != 2)
1954 fatal("%s line %d: Invalid %s spec.",
1955 filename, linenum, keyword);
1957 options->per_source_masklen_ipv4 = value;
1958 options->per_source_masklen_ipv6 = value2;
1962 case sPerSourceMaxStartups:
1963 arg = argv_next(&ac, &av);
1964 if (!arg || *arg == '\0')
1965 fatal("%s line %d: %s missing argument.",
1966 filename, linenum, keyword);
1967 if (strcmp(arg, "none") == 0) { /* no limit */
1970 if ((errstr = atoi_err(arg, &value)) != NULL)
1971 fatal("%s line %d: %s integer value %s.",
1972 filename, linenum, keyword, errstr);
1975 options->per_source_max_startups = value;
1979 intptr = &options->max_authtries;
1983 intptr = &options->max_sessions;
1987 charptr = &options->banner;
1988 goto parse_filename;
1991 * These options can contain %X options expanded at
1992 * connect time, so that you can specify paths like:
1994 * AuthorizedKeysFile /etc/ssh_keys/%u
1996 case sAuthorizedKeysFile:
1997 uvalue = options->num_authkeys_files;
1998 while ((arg = argv_next(&ac, &av)) != NULL) {
2000 error("%s line %d: keyword %s empty argument",
2001 filename, linenum, keyword);
2004 arg2 = tilde_expand_filename(arg, getuid());
2005 if (*activep && uvalue == 0) {
2006 opt_array_append(filename, linenum, keyword,
2007 &options->authorized_keys_files,
2008 &options->num_authkeys_files, arg2);
2014 case sAuthorizedPrincipalsFile:
2015 charptr = &options->authorized_principals_file;
2016 arg = argv_next(&ac, &av);
2017 if (!arg || *arg == '\0')
2018 fatal("%s line %d: %s missing argument.",
2019 filename, linenum, keyword);
2020 if (*activep && *charptr == NULL) {
2021 *charptr = tilde_expand_filename(arg, getuid());
2022 /* increase optional counter */
2024 *intptr = *intptr + 1;
2028 case sClientAliveInterval:
2029 intptr = &options->client_alive_interval;
2032 case sClientAliveCountMax:
2033 intptr = &options->client_alive_count_max;
2037 while ((arg = argv_next(&ac, &av)) != NULL) {
2038 if (*arg == '\0' || strchr(arg, '=') != NULL)
2039 fatal("%s line %d: Invalid environment name.",
2043 opt_array_append(filename, linenum, keyword,
2044 &options->accept_env, &options->num_accept_env,
2050 uvalue = options->num_setenv;
2051 while ((arg = argv_next(&ac, &av)) != NULL) {
2052 if (*arg == '\0' || strchr(arg, '=') == NULL)
2053 fatal("%s line %d: Invalid environment.",
2055 if (!*activep || uvalue != 0)
2057 opt_array_append(filename, linenum, keyword,
2058 &options->setenv, &options->num_setenv, arg);
2063 intptr = &options->permit_tun;
2064 arg = argv_next(&ac, &av);
2065 if (!arg || *arg == '\0')
2066 fatal("%s line %d: %s missing argument.",
2067 filename, linenum, keyword);
2069 for (i = 0; tunmode_desc[i].val != -1; i++)
2070 if (strcmp(tunmode_desc[i].text, arg) == 0) {
2071 value = tunmode_desc[i].val;
2075 fatal("%s line %d: bad %s argument %s",
2076 filename, linenum, keyword, arg);
2077 if (*activep && *intptr == -1)
2083 fatal("Include directive not supported as a "
2084 "command-line option");
2087 while ((arg2 = argv_next(&ac, &av)) != NULL) {
2088 if (*arg2 == '\0') {
2089 error("%s line %d: keyword %s empty argument",
2090 filename, linenum, keyword);
2095 if (*arg2 != '/' && *arg2 != '~') {
2096 xasprintf(&arg, "%s/%s", SSHDIR, arg2);
2098 arg = xstrdup(arg2);
2101 * Don't let included files clobber the containing
2102 * file's Match state.
2106 /* consult cache of include files */
2107 TAILQ_FOREACH(item, includes, entry) {
2108 if (strcmp(item->selector, arg) != 0)
2110 if (item->filename != NULL) {
2111 parse_server_config_depth(options,
2112 item->filename, item->contents,
2113 includes, connectinfo,
2114 (*inc_flags & SSHCFG_MATCH_ONLY
2115 ? SSHCFG_MATCH_ONLY : (oactive
2116 ? 0 : SSHCFG_NEVERMATCH)),
2117 activep, depth + 1);
2127 /* requested glob was not in cache */
2128 debug2("%s line %d: new include %s",
2129 filename, linenum, arg);
2130 if ((r = glob(arg, 0, NULL, &gbuf)) != 0) {
2131 if (r != GLOB_NOMATCH) {
2132 fatal("%s line %d: include \"%s\" glob "
2133 "failed", filename, linenum, arg);
2136 * If no entry matched then record a
2137 * placeholder to skip later glob calls.
2139 debug2("%s line %d: no match for %s",
2140 filename, linenum, arg);
2141 item = xcalloc(1, sizeof(*item));
2142 item->selector = strdup(arg);
2143 TAILQ_INSERT_TAIL(includes,
2146 if (gbuf.gl_pathc > INT_MAX)
2147 fatal_f("too many glob results");
2148 for (n = 0; n < (int)gbuf.gl_pathc; n++) {
2149 debug2("%s line %d: including %s",
2150 filename, linenum, gbuf.gl_pathv[n]);
2151 item = xcalloc(1, sizeof(*item));
2152 item->selector = strdup(arg);
2153 item->filename = strdup(gbuf.gl_pathv[n]);
2154 if ((item->contents = sshbuf_new()) == NULL)
2155 fatal_f("sshbuf_new failed");
2156 load_server_config(item->filename,
2158 parse_server_config_depth(options,
2159 item->filename, item->contents,
2160 includes, connectinfo,
2161 (*inc_flags & SSHCFG_MATCH_ONLY
2162 ? SSHCFG_MATCH_ONLY : (oactive
2163 ? 0 : SSHCFG_NEVERMATCH)),
2164 activep, depth + 1);
2166 TAILQ_INSERT_TAIL(includes, item, entry);
2172 fatal("%s line %d: %s missing filename argument",
2173 filename, linenum, keyword);
2179 fatal("Match directive not supported as a command-line "
2181 value = match_cfg_line(&str, linenum,
2182 (*inc_flags & SSHCFG_NEVERMATCH ? NULL : connectinfo));
2184 fatal("%s line %d: Bad Match condition", filename,
2186 *activep = (*inc_flags & SSHCFG_NEVERMATCH) ? 0 : value;
2188 * The MATCH_ONLY flag is applicable only until the first
2191 *inc_flags &= ~SSHCFG_MATCH_ONLY;
2193 * If match_cfg_line() didn't consume all its arguments then
2194 * arrange for the extra arguments check below to fail.
2196 if (str == NULL || *str == '\0')
2202 if (opcode == sPermitListen) {
2203 uintptr = &options->num_permitted_listens;
2204 chararrayptr = &options->permitted_listens;
2206 uintptr = &options->num_permitted_opens;
2207 chararrayptr = &options->permitted_opens;
2209 arg = argv_next(&ac, &av);
2210 if (!arg || *arg == '\0')
2211 fatal("%s line %d: %s missing argument.",
2212 filename, linenum, keyword);
2213 uvalue = *uintptr; /* modified later */
2214 if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) {
2215 if (*activep && uvalue == 0) {
2217 *chararrayptr = xcalloc(1,
2218 sizeof(**chararrayptr));
2219 (*chararrayptr)[0] = xstrdup(arg);
2223 for (; arg != NULL && *arg != '\0'; arg = argv_next(&ac, &av)) {
2224 if (opcode == sPermitListen &&
2225 strchr(arg, ':') == NULL) {
2227 * Allow bare port number for PermitListen
2228 * to indicate a wildcard listen host.
2230 xasprintf(&arg2, "*:%s", arg);
2232 arg2 = xstrdup(arg);
2234 p = hpdelim2(&arg, &ch);
2235 if (p == NULL || ch == '/') {
2236 fatal("%s line %d: %s missing host",
2237 filename, linenum, keyword);
2239 p = cleanhostname(p);
2242 ((port = permitopen_port(arg)) < 0)) {
2243 fatal("%s line %d: %s bad port number",
2244 filename, linenum, keyword);
2246 if (*activep && uvalue == 0) {
2247 opt_array_append(filename, linenum, keyword,
2248 chararrayptr, uintptr, arg2);
2255 if (str == NULL || *str == '\0')
2256 fatal("%s line %d: %s missing argument.",
2257 filename, linenum, keyword);
2258 len = strspn(str, WHITESPACE);
2259 if (*activep && options->adm_forced_command == NULL)
2260 options->adm_forced_command = xstrdup(str + len);
2264 case sChrootDirectory:
2265 charptr = &options->chroot_directory;
2267 arg = argv_next(&ac, &av);
2268 if (!arg || *arg == '\0')
2269 fatal("%s line %d: %s missing argument.",
2270 filename, linenum, keyword);
2271 if (*activep && *charptr == NULL)
2272 *charptr = xstrdup(arg);
2275 case sTrustedUserCAKeys:
2276 charptr = &options->trusted_user_ca_keys;
2277 goto parse_filename;
2280 charptr = &options->revoked_keys_file;
2281 goto parse_filename;
2283 case sSecurityKeyProvider:
2284 charptr = &options->sk_provider;
2285 arg = argv_next(&ac, &av);
2286 if (!arg || *arg == '\0')
2287 fatal("%s line %d: %s missing argument.",
2288 filename, linenum, keyword);
2289 if (*activep && *charptr == NULL) {
2290 *charptr = strcasecmp(arg, "internal") == 0 ?
2291 xstrdup(arg) : derelativise_path(arg);
2292 /* increase optional counter */
2294 *intptr = *intptr + 1;
2299 arg = argv_next(&ac, &av);
2300 if (!arg || *arg == '\0')
2301 fatal("%s line %d: %s missing argument.",
2302 filename, linenum, keyword);
2303 if ((value = parse_ipqos(arg)) == -1)
2304 fatal("%s line %d: Bad %s value: %s",
2305 filename, linenum, keyword, arg);
2306 arg = argv_next(&ac, &av);
2309 else if ((value2 = parse_ipqos(arg)) == -1)
2310 fatal("%s line %d: Bad %s value: %s",
2311 filename, linenum, keyword, arg);
2313 options->ip_qos_interactive = value;
2314 options->ip_qos_bulk = value2;
2318 case sVersionAddendum:
2319 if (str == NULL || *str == '\0')
2320 fatal("%s line %d: %s missing argument.",
2321 filename, linenum, keyword);
2322 len = strspn(str, WHITESPACE);
2323 if (strchr(str + len, '\r') != NULL) {
2324 fatal("%.200s line %d: Invalid %s argument",
2325 filename, linenum, keyword);
2327 if ((arg = strchr(line, '#')) != NULL) {
2331 if (*activep && options->version_addendum == NULL) {
2332 if (strcasecmp(str + len, "none") == 0)
2333 options->version_addendum = xstrdup("");
2335 options->version_addendum = xstrdup(str + len);
2340 case sAuthorizedKeysCommand:
2341 charptr = &options->authorized_keys_command;
2343 len = strspn(str, WHITESPACE);
2344 if (str[len] != '/' && strcasecmp(str + len, "none") != 0) {
2345 fatal("%.200s line %d: %s must be an absolute path",
2346 filename, linenum, keyword);
2348 if (*activep && options->authorized_keys_command == NULL)
2349 *charptr = xstrdup(str + len);
2353 case sAuthorizedKeysCommandUser:
2354 charptr = &options->authorized_keys_command_user;
2356 arg = argv_next(&ac, &av);
2357 if (!arg || *arg == '\0') {
2358 fatal("%s line %d: missing %s argument.",
2359 filename, linenum, keyword);
2361 if (*activep && *charptr == NULL)
2362 *charptr = xstrdup(arg);
2365 case sAuthorizedPrincipalsCommand:
2366 charptr = &options->authorized_principals_command;
2369 case sAuthorizedPrincipalsCommandUser:
2370 charptr = &options->authorized_principals_command_user;
2371 goto parse_localuser;
2373 case sAuthenticationMethods:
2374 found = options->num_auth_methods == 0;
2375 value = 0; /* seen "any" pseudo-method */
2376 value2 = 0; /* successfully parsed any method */
2377 while ((arg = argv_next(&ac, &av)) != NULL) {
2378 if (strcmp(arg, "any") == 0) {
2379 if (options->num_auth_methods > 0) {
2380 fatal("%s line %d: \"any\" must "
2381 "appear alone in %s",
2382 filename, linenum, keyword);
2386 fatal("%s line %d: \"any\" must appear "
2387 "alone in %s", filename, linenum, keyword);
2388 } else if (auth2_methods_valid(arg, 0) != 0) {
2389 fatal("%s line %d: invalid %s method list.",
2390 filename, linenum, keyword);
2393 if (!found || !*activep)
2395 opt_array_append(filename, linenum, keyword,
2396 &options->auth_methods,
2397 &options->num_auth_methods, arg);
2400 fatal("%s line %d: no %s specified",
2401 filename, linenum, keyword);
2405 case sStreamLocalBindMask:
2406 arg = argv_next(&ac, &av);
2407 if (!arg || *arg == '\0')
2408 fatal("%s line %d: %s missing argument.",
2409 filename, linenum, keyword);
2410 /* Parse mode in octal format */
2411 value = strtol(arg, &p, 8);
2412 if (arg == p || value < 0 || value > 0777)
2413 fatal("%s line %d: Invalid %s.",
2414 filename, linenum, keyword);
2416 options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
2419 case sStreamLocalBindUnlink:
2420 intptr = &options->fwd_opts.streamlocal_bind_unlink;
2423 case sFingerprintHash:
2424 arg = argv_next(&ac, &av);
2425 if (!arg || *arg == '\0')
2426 fatal("%s line %d: %s missing argument.",
2427 filename, linenum, keyword);
2428 if ((value = ssh_digest_alg_by_name(arg)) == -1)
2429 fatal("%.200s line %d: Invalid %s algorithm \"%s\".",
2430 filename, linenum, keyword, arg);
2432 options->fingerprint_hash = value;
2435 case sExposeAuthInfo:
2436 intptr = &options->expose_userauth_info;
2440 #if !defined(__OpenBSD__) && !defined(HAVE_SYS_SET_PROCESS_RDOMAIN)
2441 fatal("%s line %d: setting RDomain not supported on this "
2442 "platform.", filename, linenum);
2444 charptr = &options->routing_domain;
2445 arg = argv_next(&ac, &av);
2446 if (!arg || *arg == '\0')
2447 fatal("%s line %d: %s missing argument.",
2448 filename, linenum, keyword);
2449 if (strcasecmp(arg, "none") != 0 && strcmp(arg, "%D") != 0 &&
2450 !valid_rdomain(arg))
2451 fatal("%s line %d: invalid routing domain",
2453 if (*activep && *charptr == NULL)
2454 *charptr = xstrdup(arg);
2458 intptr = &options->use_blacklist;
2464 do_log2(opcode == sIgnore ?
2465 SYSLOG_LEVEL_DEBUG2 : SYSLOG_LEVEL_INFO,
2466 "%s line %d: %s option %s", filename, linenum,
2467 opcode == sUnsupported ? "Unsupported" : "Deprecated",
2473 fatal("%s line %d: Missing handler for opcode %s (%d)",
2474 filename, linenum, keyword, opcode);
2476 /* Check that there is no garbage at end of line. */
2478 error("%.200s line %d: keyword %s extra arguments "
2479 "at end of line", filename, linenum, keyword);
2486 argv_free(oav, oac);
2491 process_server_config_line(ServerOptions *options, char *line,
2492 const char *filename, int linenum, int *activep,
2493 struct connection_info *connectinfo, struct include_list *includes)
2497 return process_server_config_line_depth(options, line, filename,
2498 linenum, activep, connectinfo, &inc_flags, 0, includes);
2502 /* Reads the server configuration file. */
2505 load_server_config(const char *filename, struct sshbuf *conf)
2508 char *line = NULL, *cp;
2509 size_t linesize = 0;
2513 debug2_f("filename %s", filename);
2514 if ((f = fopen(filename, "r")) == NULL) {
2519 /* grow buffer, so realloc is avoided for large config files */
2520 if (fstat(fileno(f), &st) == 0 && st.st_size > 0 &&
2521 (r = sshbuf_allocate(conf, st.st_size)) != 0)
2522 fatal_fr(r, "allocate");
2523 while (getline(&line, &linesize, f) != -1) {
2527 * NB - preserve newlines, they are needed to reproduce
2528 * line numbers later for error messages
2530 cp = line + strspn(line, " \t\r");
2531 if ((r = sshbuf_put(conf, cp, strlen(cp))) != 0)
2532 fatal_fr(r, "sshbuf_put");
2535 if ((r = sshbuf_put_u8(conf, 0)) != 0)
2536 fatal_fr(r, "sshbuf_put_u8");
2538 debug2_f("done config len = %zu", sshbuf_len(conf));
2542 parse_server_match_config(ServerOptions *options,
2543 struct include_list *includes, struct connection_info *connectinfo)
2547 initialize_server_options(&mo);
2548 parse_server_config(&mo, "reprocess config", cfg, includes,
2550 copy_set_server_options(options, &mo, 0);
2553 int parse_server_match_testspec(struct connection_info *ci, char *spec)
2557 while ((p = strsep(&spec, ",")) && *p != '\0') {
2558 if (strncmp(p, "addr=", 5) == 0) {
2559 ci->address = xstrdup(p + 5);
2560 } else if (strncmp(p, "host=", 5) == 0) {
2561 ci->host = xstrdup(p + 5);
2562 } else if (strncmp(p, "user=", 5) == 0) {
2563 ci->user = xstrdup(p + 5);
2564 } else if (strncmp(p, "laddr=", 6) == 0) {
2565 ci->laddress = xstrdup(p + 6);
2566 } else if (strncmp(p, "rdomain=", 8) == 0) {
2567 ci->rdomain = xstrdup(p + 8);
2568 } else if (strncmp(p, "lport=", 6) == 0) {
2569 ci->lport = a2port(p + 6);
2570 if (ci->lport == -1) {
2571 fprintf(stderr, "Invalid port '%s' in test mode"
2572 " specification %s\n", p+6, p);
2576 fprintf(stderr, "Invalid test mode specification %s\n",
2585 * Copy any supported values that are set.
2587 * If the preauth flag is set, we do not bother copying the string or
2588 * array values that are not used pre-authentication, because any that we
2589 * do use must be explicitly sent in mm_getpwnamallow().
2592 copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
2594 #define M_CP_INTOPT(n) do {\
2599 M_CP_INTOPT(password_authentication);
2600 M_CP_INTOPT(gss_authentication);
2601 M_CP_INTOPT(pubkey_authentication);
2602 M_CP_INTOPT(pubkey_auth_options);
2603 M_CP_INTOPT(kerberos_authentication);
2604 M_CP_INTOPT(hostbased_authentication);
2605 M_CP_INTOPT(hostbased_uses_name_from_packet_only);
2606 M_CP_INTOPT(kbd_interactive_authentication);
2607 M_CP_INTOPT(permit_root_login);
2608 M_CP_INTOPT(permit_empty_passwd);
2609 M_CP_INTOPT(ignore_rhosts);
2611 M_CP_INTOPT(allow_tcp_forwarding);
2612 M_CP_INTOPT(allow_streamlocal_forwarding);
2613 M_CP_INTOPT(allow_agent_forwarding);
2614 M_CP_INTOPT(disable_forwarding);
2615 M_CP_INTOPT(expose_userauth_info);
2616 M_CP_INTOPT(permit_tun);
2617 M_CP_INTOPT(fwd_opts.gateway_ports);
2618 M_CP_INTOPT(fwd_opts.streamlocal_bind_unlink);
2619 M_CP_INTOPT(x11_display_offset);
2620 M_CP_INTOPT(x11_forwarding);
2621 M_CP_INTOPT(x11_use_localhost);
2622 M_CP_INTOPT(permit_tty);
2623 M_CP_INTOPT(permit_user_rc);
2624 M_CP_INTOPT(max_sessions);
2625 M_CP_INTOPT(max_authtries);
2626 M_CP_INTOPT(client_alive_count_max);
2627 M_CP_INTOPT(client_alive_interval);
2628 M_CP_INTOPT(ip_qos_interactive);
2629 M_CP_INTOPT(ip_qos_bulk);
2630 M_CP_INTOPT(rekey_limit);
2631 M_CP_INTOPT(rekey_interval);
2632 M_CP_INTOPT(log_level);
2635 * The bind_mask is a mode_t that may be unsigned, so we can't use
2636 * M_CP_INTOPT - it does a signed comparison that causes compiler
2639 if (src->fwd_opts.streamlocal_bind_mask != (mode_t)-1) {
2640 dst->fwd_opts.streamlocal_bind_mask =
2641 src->fwd_opts.streamlocal_bind_mask;
2644 /* M_CP_STROPT and M_CP_STRARRAYOPT should not appear before here */
2645 #define M_CP_STROPT(n) do {\
2646 if (src->n != NULL && dst->n != src->n) { \
2651 #define M_CP_STRARRAYOPT(s, num_s) do {\
2653 if (src->num_s != 0) { \
2654 for (i = 0; i < dst->num_s; i++) \
2657 dst->s = xcalloc(src->num_s, sizeof(*dst->s)); \
2658 for (i = 0; i < src->num_s; i++) \
2659 dst->s[i] = xstrdup(src->s[i]); \
2660 dst->num_s = src->num_s; \
2664 /* See comment in servconf.h */
2665 COPY_MATCH_STRING_OPTS();
2667 /* Arguments that accept '+...' need to be expanded */
2668 assemble_algorithms(dst);
2671 * The only things that should be below this point are string options
2672 * which are only used after authentication.
2677 /* These options may be "none" to clear a global setting */
2678 M_CP_STROPT(adm_forced_command);
2679 if (option_clear_or_none(dst->adm_forced_command)) {
2680 free(dst->adm_forced_command);
2681 dst->adm_forced_command = NULL;
2683 M_CP_STROPT(chroot_directory);
2684 if (option_clear_or_none(dst->chroot_directory)) {
2685 free(dst->chroot_directory);
2686 dst->chroot_directory = NULL;
2692 #undef M_CP_STRARRAYOPT
2694 #define SERVCONF_MAX_DEPTH 16
2696 parse_server_config_depth(ServerOptions *options, const char *filename,
2697 struct sshbuf *conf, struct include_list *includes,
2698 struct connection_info *connectinfo, int flags, int *activep, int depth)
2700 int linenum, bad_options = 0;
2701 char *cp, *obuf, *cbuf;
2703 if (depth < 0 || depth > SERVCONF_MAX_DEPTH)
2704 fatal("Too many recursive configuration includes");
2706 debug2_f("config %s len %zu%s", filename, sshbuf_len(conf),
2707 (flags & SSHCFG_NEVERMATCH ? " [checking syntax only]" : ""));
2709 if ((obuf = cbuf = sshbuf_dup_string(conf)) == NULL)
2710 fatal_f("sshbuf_dup_string failed");
2712 while ((cp = strsep(&cbuf, "\n")) != NULL) {
2713 if (process_server_config_line_depth(options, cp,
2714 filename, linenum++, activep, connectinfo, &flags,
2715 depth, includes) != 0)
2719 if (bad_options > 0)
2720 fatal("%s: terminating, %d bad configuration options",
2721 filename, bad_options);
2725 parse_server_config(ServerOptions *options, const char *filename,
2726 struct sshbuf *conf, struct include_list *includes,
2727 struct connection_info *connectinfo)
2729 int active = connectinfo ? 0 : 1;
2730 parse_server_config_depth(options, filename, conf, includes,
2731 connectinfo, (connectinfo ? SSHCFG_MATCH_ONLY : 0), &active, 0);
2732 process_queued_listen_addrs(options);
2736 fmt_multistate_int(int val, const struct multistate *m)
2740 for (i = 0; m[i].key != NULL; i++) {
2741 if (m[i].value == val)
2748 fmt_intarg(ServerOpCodes code, int val)
2753 case sAddressFamily:
2754 return fmt_multistate_int(val, multistate_addressfamily);
2755 case sPermitRootLogin:
2756 return fmt_multistate_int(val, multistate_permitrootlogin);
2758 return fmt_multistate_int(val, multistate_gatewayports);
2760 return fmt_multistate_int(val, multistate_compression);
2761 case sAllowTcpForwarding:
2762 return fmt_multistate_int(val, multistate_tcpfwd);
2763 case sAllowStreamLocalForwarding:
2764 return fmt_multistate_int(val, multistate_tcpfwd);
2766 return fmt_multistate_int(val, multistate_ignore_rhosts);
2767 case sFingerprintHash:
2768 return ssh_digest_alg_name(val);
2782 dump_cfg_int(ServerOpCodes code, int val)
2784 printf("%s %d\n", lookup_opcode_name(code), val);
2788 dump_cfg_oct(ServerOpCodes code, int val)
2790 printf("%s 0%o\n", lookup_opcode_name(code), val);
2794 dump_cfg_fmtint(ServerOpCodes code, int val)
2796 printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
2800 dump_cfg_string(ServerOpCodes code, const char *val)
2802 printf("%s %s\n", lookup_opcode_name(code),
2803 val == NULL ? "none" : val);
2807 dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals)
2811 for (i = 0; i < count; i++)
2812 printf("%s %s\n", lookup_opcode_name(code), vals[i]);
2816 dump_cfg_strarray_oneline(ServerOpCodes code, u_int count, char **vals)
2820 if (count <= 0 && code != sAuthenticationMethods)
2822 printf("%s", lookup_opcode_name(code));
2823 for (i = 0; i < count; i++)
2824 printf(" %s", vals[i]);
2825 if (code == sAuthenticationMethods && count == 0)
2831 format_listen_addrs(struct listenaddr *la)
2834 struct addrinfo *ai;
2835 char addr[NI_MAXHOST], port[NI_MAXSERV];
2836 char *laddr1 = xstrdup(""), *laddr2 = NULL;
2839 * ListenAddress must be after Port. add_one_listen_addr pushes
2840 * addresses onto a stack, so to maintain ordering we need to
2841 * print these in reverse order.
2843 for (ai = la->addrs; ai; ai = ai->ai_next) {
2844 if ((r = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
2845 sizeof(addr), port, sizeof(port),
2846 NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
2847 error("getnameinfo: %.100s", ssh_gai_strerror(r));
2851 if (ai->ai_family == AF_INET6) {
2852 xasprintf(&laddr1, "listenaddress [%s]:%s%s%s\n%s",
2854 la->rdomain == NULL ? "" : " rdomain ",
2855 la->rdomain == NULL ? "" : la->rdomain,
2858 xasprintf(&laddr1, "listenaddress %s:%s%s%s\n%s",
2860 la->rdomain == NULL ? "" : " rdomain ",
2861 la->rdomain == NULL ? "" : la->rdomain,
2870 dump_config(ServerOptions *o)
2875 /* these are usually at the top of the config */
2876 for (i = 0; i < o->num_ports; i++)
2877 printf("port %d\n", o->ports[i]);
2878 dump_cfg_fmtint(sAddressFamily, o->address_family);
2880 for (i = 0; i < o->num_listen_addrs; i++) {
2881 s = format_listen_addrs(&o->listen_addrs[i]);
2886 /* integer arguments */
2888 dump_cfg_fmtint(sUsePAM, o->use_pam);
2890 dump_cfg_int(sLoginGraceTime, o->login_grace_time);
2891 dump_cfg_int(sX11DisplayOffset, o->x11_display_offset);
2892 dump_cfg_int(sMaxAuthTries, o->max_authtries);
2893 dump_cfg_int(sMaxSessions, o->max_sessions);
2894 dump_cfg_int(sClientAliveInterval, o->client_alive_interval);
2895 dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max);
2896 dump_cfg_oct(sStreamLocalBindMask, o->fwd_opts.streamlocal_bind_mask);
2898 /* formatted integer arguments */
2899 dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login);
2900 dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts);
2901 dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts);
2902 dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication);
2903 dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly,
2904 o->hostbased_uses_name_from_packet_only);
2905 dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication);
2907 dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication);
2908 dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd);
2909 dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup);
2911 dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
2915 dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
2916 dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
2918 dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
2919 dump_cfg_fmtint(sKbdInteractiveAuthentication,
2920 o->kbd_interactive_authentication);
2921 dump_cfg_fmtint(sPrintMotd, o->print_motd);
2922 #ifndef DISABLE_LASTLOG
2923 dump_cfg_fmtint(sPrintLastLog, o->print_lastlog);
2925 dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding);
2926 dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost);
2927 dump_cfg_fmtint(sPermitTTY, o->permit_tty);
2928 dump_cfg_fmtint(sPermitUserRC, o->permit_user_rc);
2929 dump_cfg_fmtint(sStrictModes, o->strict_modes);
2930 dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive);
2931 dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd);
2932 dump_cfg_fmtint(sCompression, o->compression);
2933 dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports);
2934 dump_cfg_fmtint(sUseDNS, o->use_dns);
2935 dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
2936 dump_cfg_fmtint(sAllowAgentForwarding, o->allow_agent_forwarding);
2937 dump_cfg_fmtint(sDisableForwarding, o->disable_forwarding);
2938 dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding);
2939 dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2940 dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash);
2941 dump_cfg_fmtint(sExposeAuthInfo, o->expose_userauth_info);
2942 dump_cfg_fmtint(sUseBlacklist, o->use_blacklist);
2944 /* string arguments */
2945 dump_cfg_string(sPidFile, o->pid_file);
2946 dump_cfg_string(sModuliFile, o->moduli_file);
2947 dump_cfg_string(sXAuthLocation, o->xauth_location);
2948 dump_cfg_string(sCiphers, o->ciphers);
2949 dump_cfg_string(sMacs, o->macs);
2950 dump_cfg_string(sBanner, o->banner);
2951 dump_cfg_string(sForceCommand, o->adm_forced_command);
2952 dump_cfg_string(sChrootDirectory, o->chroot_directory);
2953 dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);
2954 dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
2955 dump_cfg_string(sSecurityKeyProvider, o->sk_provider);
2956 dump_cfg_string(sAuthorizedPrincipalsFile,
2957 o->authorized_principals_file);
2958 dump_cfg_string(sVersionAddendum, *o->version_addendum == '\0'
2959 ? "none" : o->version_addendum);
2960 dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command);
2961 dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user);
2962 dump_cfg_string(sAuthorizedPrincipalsCommand, o->authorized_principals_command);
2963 dump_cfg_string(sAuthorizedPrincipalsCommandUser, o->authorized_principals_command_user);
2964 dump_cfg_string(sHostKeyAgent, o->host_key_agent);
2965 dump_cfg_string(sKexAlgorithms, o->kex_algorithms);
2966 dump_cfg_string(sCASignatureAlgorithms, o->ca_sign_algorithms);
2967 dump_cfg_string(sHostbasedAcceptedAlgorithms, o->hostbased_accepted_algos);
2968 dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms);
2969 dump_cfg_string(sPubkeyAcceptedAlgorithms, o->pubkey_accepted_algos);
2970 #if defined(__OpenBSD__) || defined(HAVE_SYS_SET_PROCESS_RDOMAIN)
2971 dump_cfg_string(sRDomain, o->routing_domain);
2974 /* string arguments requiring a lookup */
2975 dump_cfg_string(sLogLevel, log_level_name(o->log_level));
2976 dump_cfg_string(sLogFacility, log_facility_name(o->log_facility));
2978 /* string array arguments */
2979 dump_cfg_strarray_oneline(sAuthorizedKeysFile, o->num_authkeys_files,
2980 o->authorized_keys_files);
2981 dump_cfg_strarray(sHostKeyFile, o->num_host_key_files,
2983 dump_cfg_strarray(sHostCertificate, o->num_host_cert_files,
2984 o->host_cert_files);
2985 dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users);
2986 dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users);
2987 dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups);
2988 dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups);
2989 dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env);
2990 dump_cfg_strarray(sSetEnv, o->num_setenv, o->setenv);
2991 dump_cfg_strarray_oneline(sAuthenticationMethods,
2992 o->num_auth_methods, o->auth_methods);
2993 dump_cfg_strarray_oneline(sLogVerbose,
2994 o->num_log_verbose, o->log_verbose);
2996 /* other arguments */
2997 for (i = 0; i < o->num_subsystems; i++)
2998 printf("subsystem %s %s\n", o->subsystem_name[i],
2999 o->subsystem_args[i]);
3001 printf("maxstartups %d:%d:%d\n", o->max_startups_begin,
3002 o->max_startups_rate, o->max_startups);
3003 printf("persourcemaxstartups ");
3004 if (o->per_source_max_startups == INT_MAX)
3007 printf("%d\n", o->per_source_max_startups);
3008 printf("persourcenetblocksize %d:%d\n", o->per_source_masklen_ipv4,
3009 o->per_source_masklen_ipv6);
3012 for (i = 0; tunmode_desc[i].val != -1; i++) {
3013 if (tunmode_desc[i].val == o->permit_tun) {
3014 s = tunmode_desc[i].text;
3018 dump_cfg_string(sPermitTunnel, s);
3020 printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
3021 printf("%s\n", iptos2str(o->ip_qos_bulk));
3023 printf("rekeylimit %llu %d\n", (unsigned long long)o->rekey_limit,
3026 printf("permitopen");
3027 if (o->num_permitted_opens == 0)
3030 for (i = 0; i < o->num_permitted_opens; i++)
3031 printf(" %s", o->permitted_opens[i]);
3034 printf("permitlisten");
3035 if (o->num_permitted_listens == 0)
3038 for (i = 0; i < o->num_permitted_listens; i++)
3039 printf(" %s", o->permitted_listens[i]);
3043 if (o->permit_user_env_allowlist == NULL) {
3044 dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env);
3046 printf("permituserenvironment %s\n",
3047 o->permit_user_env_allowlist);
3050 printf("pubkeyauthoptions");
3051 if (o->pubkey_auth_options == 0)
3053 if (o->pubkey_auth_options & PUBKEYAUTH_TOUCH_REQUIRED)
3054 printf(" touch-required");
3055 if (o->pubkey_auth_options & PUBKEYAUTH_VERIFY_REQUIRED)
3056 printf(" verify-required");