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