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