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