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