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