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