1 /* $OpenBSD: servconf.c,v 1.402 2023/09/08 06:34:24 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 /* Parse a ChannelTimeout clause "pattern=interval" */ 909 static int 910 parse_timeout(const char *s, char **typep, int *secsp) 911 { 912 char *cp, *sdup; 913 int secs; 914 915 if (typep != NULL) 916 *typep = NULL; 917 if (secsp != NULL) 918 *secsp = 0; 919 if (s == NULL) 920 return -1; 921 sdup = xstrdup(s); 922 923 if ((cp = strchr(sdup, '=')) == NULL || cp == sdup) { 924 free(sdup); 925 return -1; 926 } 927 *cp++ = '\0'; 928 if ((secs = convtime(cp)) < 0) { 929 free(sdup); 930 return -1; 931 } 932 /* success */ 933 if (typep != NULL) 934 *typep = xstrdup(sdup); 935 if (secsp != NULL) 936 *secsp = secs; 937 free(sdup); 938 return 0; 939 } 940 941 void 942 process_channel_timeouts(struct ssh *ssh, ServerOptions *options) 943 { 944 int secs; 945 u_int i; 946 char *type; 947 948 debug3_f("setting %u timeouts", options->num_channel_timeouts); 949 channel_clear_timeouts(ssh); 950 for (i = 0; i < options->num_channel_timeouts; i++) { 951 if (parse_timeout(options->channel_timeouts[i], 952 &type, &secs) != 0) { 953 fatal_f("internal error: bad timeout %s", 954 options->channel_timeouts[i]); 955 } 956 channel_add_timeout(ssh, type, secs); 957 free(type); 958 } 959 } 960 961 struct connection_info * 962 get_connection_info(struct ssh *ssh, int populate, int use_dns) 963 { 964 static struct connection_info ci; 965 966 if (ssh == NULL || !populate) 967 return &ci; 968 ci.host = auth_get_canonical_hostname(ssh, use_dns); 969 ci.address = ssh_remote_ipaddr(ssh); 970 ci.laddress = ssh_local_ipaddr(ssh); 971 ci.lport = ssh_local_port(ssh); 972 ci.rdomain = ssh_packet_rdomain_in(ssh); 973 return &ci; 974 } 975 976 /* 977 * The strategy for the Match blocks is that the config file is parsed twice. 978 * 979 * The first time is at startup. activep is initialized to 1 and the 980 * directives in the global context are processed and acted on. Hitting a 981 * Match directive unsets activep and the directives inside the block are 982 * checked for syntax only. 983 * 984 * The second time is after a connection has been established but before 985 * authentication. activep is initialized to 2 and global config directives 986 * are ignored since they have already been processed. If the criteria in a 987 * Match block is met, activep is set and the subsequent directives 988 * processed and actioned until EOF or another Match block unsets it. Any 989 * options set are copied into the main server config. 990 * 991 * Potential additions/improvements: 992 * - Add Match support for pre-kex directives, eg. Ciphers. 993 * 994 * - Add a Tag directive (idea from David Leonard) ala pf, eg: 995 * Match Address 192.168.0.* 996 * Tag trusted 997 * Match Group wheel 998 * Tag trusted 999 * Match Tag trusted 1000 * AllowTcpForwarding yes 1001 * GatewayPorts clientspecified 1002 * [...] 1003 * 1004 * - Add a PermittedChannelRequests directive 1005 * Match Group shell 1006 * PermittedChannelRequests session,forwarded-tcpip 1007 */ 1008 1009 static int 1010 match_cfg_line_group(const char *grps, int line, const char *user) 1011 { 1012 int result = 0; 1013 struct passwd *pw; 1014 1015 if (user == NULL) 1016 goto out; 1017 1018 if ((pw = getpwnam(user)) == NULL) { 1019 debug("Can't match group at line %d because user %.100s does " 1020 "not exist", line, user); 1021 } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) { 1022 debug("Can't Match group because user %.100s not in any group " 1023 "at line %d", user, line); 1024 } else if (ga_match_pattern_list(grps) != 1) { 1025 debug("user %.100s does not match group list %.100s at line %d", 1026 user, grps, line); 1027 } else { 1028 debug("user %.100s matched group list %.100s at line %d", user, 1029 grps, line); 1030 result = 1; 1031 } 1032 out: 1033 ga_free(); 1034 return result; 1035 } 1036 1037 static void 1038 match_test_missing_fatal(const char *criteria, const char *attrib) 1039 { 1040 fatal("'Match %s' in configuration but '%s' not in connection " 1041 "test specification.", criteria, attrib); 1042 } 1043 1044 /* 1045 * All of the attributes on a single Match line are ANDed together, so we need 1046 * to check every attribute and set the result to zero if any attribute does 1047 * not match. 1048 */ 1049 static int 1050 match_cfg_line(char **condition, int line, struct connection_info *ci) 1051 { 1052 int result = 1, attributes = 0, port; 1053 char *arg, *attrib, *cp = *condition; 1054 1055 if (ci == NULL) 1056 debug3("checking syntax for 'Match %s'", cp); 1057 else 1058 debug3("checking match for '%s' user %s host %s addr %s " 1059 "laddr %s lport %d", cp, ci->user ? ci->user : "(null)", 1060 ci->host ? ci->host : "(null)", 1061 ci->address ? ci->address : "(null)", 1062 ci->laddress ? ci->laddress : "(null)", ci->lport); 1063 1064 while ((attrib = strdelim(&cp)) && *attrib != '\0') { 1065 /* Terminate on comment */ 1066 if (*attrib == '#') { 1067 cp = NULL; /* mark all arguments consumed */ 1068 break; 1069 } 1070 arg = NULL; 1071 attributes++; 1072 /* Criterion "all" has no argument and must appear alone */ 1073 if (strcasecmp(attrib, "all") == 0) { 1074 if (attributes > 1 || ((arg = strdelim(&cp)) != NULL && 1075 *arg != '\0' && *arg != '#')) { 1076 error("'all' cannot be combined with other " 1077 "Match attributes"); 1078 return -1; 1079 } 1080 if (arg != NULL && *arg == '#') 1081 cp = NULL; /* mark all arguments consumed */ 1082 *condition = cp; 1083 return 1; 1084 } 1085 /* All other criteria require an argument */ 1086 if ((arg = strdelim(&cp)) == NULL || 1087 *arg == '\0' || *arg == '#') { 1088 error("Missing Match criteria for %s", attrib); 1089 return -1; 1090 } 1091 if (strcasecmp(attrib, "user") == 0) { 1092 if (ci == NULL || (ci->test && ci->user == NULL)) { 1093 result = 0; 1094 continue; 1095 } 1096 if (ci->user == NULL) 1097 match_test_missing_fatal("User", "user"); 1098 if (match_usergroup_pattern_list(ci->user, arg) != 1) 1099 result = 0; 1100 else 1101 debug("user %.100s matched 'User %.100s' at " 1102 "line %d", ci->user, arg, line); 1103 } else if (strcasecmp(attrib, "group") == 0) { 1104 if (ci == NULL || (ci->test && ci->user == NULL)) { 1105 result = 0; 1106 continue; 1107 } 1108 if (ci->user == NULL) 1109 match_test_missing_fatal("Group", "user"); 1110 switch (match_cfg_line_group(arg, line, ci->user)) { 1111 case -1: 1112 return -1; 1113 case 0: 1114 result = 0; 1115 } 1116 } else if (strcasecmp(attrib, "host") == 0) { 1117 if (ci == NULL || (ci->test && ci->host == NULL)) { 1118 result = 0; 1119 continue; 1120 } 1121 if (ci->host == NULL) 1122 match_test_missing_fatal("Host", "host"); 1123 if (match_hostname(ci->host, arg) != 1) 1124 result = 0; 1125 else 1126 debug("connection from %.100s matched 'Host " 1127 "%.100s' at line %d", ci->host, arg, line); 1128 } else if (strcasecmp(attrib, "address") == 0) { 1129 if (ci == NULL || (ci->test && ci->address == NULL)) { 1130 if (addr_match_list(NULL, arg) != 0) 1131 fatal("Invalid Match address argument " 1132 "'%s' at line %d", arg, line); 1133 result = 0; 1134 continue; 1135 } 1136 if (ci->address == NULL) 1137 match_test_missing_fatal("Address", "addr"); 1138 switch (addr_match_list(ci->address, arg)) { 1139 case 1: 1140 debug("connection from %.100s matched 'Address " 1141 "%.100s' at line %d", ci->address, arg, line); 1142 break; 1143 case 0: 1144 case -1: 1145 result = 0; 1146 break; 1147 case -2: 1148 return -1; 1149 } 1150 } else if (strcasecmp(attrib, "localaddress") == 0){ 1151 if (ci == NULL || (ci->test && ci->laddress == NULL)) { 1152 if (addr_match_list(NULL, arg) != 0) 1153 fatal("Invalid Match localaddress " 1154 "argument '%s' at line %d", arg, 1155 line); 1156 result = 0; 1157 continue; 1158 } 1159 if (ci->laddress == NULL) 1160 match_test_missing_fatal("LocalAddress", 1161 "laddr"); 1162 switch (addr_match_list(ci->laddress, arg)) { 1163 case 1: 1164 debug("connection from %.100s matched " 1165 "'LocalAddress %.100s' at line %d", 1166 ci->laddress, arg, line); 1167 break; 1168 case 0: 1169 case -1: 1170 result = 0; 1171 break; 1172 case -2: 1173 return -1; 1174 } 1175 } else if (strcasecmp(attrib, "localport") == 0) { 1176 if ((port = a2port(arg)) == -1) { 1177 error("Invalid LocalPort '%s' on Match line", 1178 arg); 1179 return -1; 1180 } 1181 if (ci == NULL || (ci->test && ci->lport == -1)) { 1182 result = 0; 1183 continue; 1184 } 1185 if (ci->lport == 0) 1186 match_test_missing_fatal("LocalPort", "lport"); 1187 /* TODO support port lists */ 1188 if (port == ci->lport) 1189 debug("connection from %.100s matched " 1190 "'LocalPort %d' at line %d", 1191 ci->laddress, port, line); 1192 else 1193 result = 0; 1194 } else if (strcasecmp(attrib, "rdomain") == 0) { 1195 if (ci == NULL || (ci->test && ci->rdomain == NULL)) { 1196 result = 0; 1197 continue; 1198 } 1199 if (ci->rdomain == NULL) 1200 match_test_missing_fatal("RDomain", "rdomain"); 1201 if (match_pattern_list(ci->rdomain, arg, 0) != 1) 1202 result = 0; 1203 else 1204 debug("user %.100s matched 'RDomain %.100s' at " 1205 "line %d", ci->rdomain, arg, line); 1206 } else { 1207 error("Unsupported Match attribute %s", attrib); 1208 return -1; 1209 } 1210 } 1211 if (attributes == 0) { 1212 error("One or more attributes required for Match"); 1213 return -1; 1214 } 1215 if (ci != NULL) 1216 debug3("match %sfound", result ? "" : "not "); 1217 *condition = cp; 1218 return result; 1219 } 1220 1221 #define WHITESPACE " \t\r\n" 1222 1223 /* Multistate option parsing */ 1224 struct multistate { 1225 char *key; 1226 int value; 1227 }; 1228 static const struct multistate multistate_flag[] = { 1229 { "yes", 1 }, 1230 { "no", 0 }, 1231 { NULL, -1 } 1232 }; 1233 static const struct multistate multistate_ignore_rhosts[] = { 1234 { "yes", IGNORE_RHOSTS_YES }, 1235 { "no", IGNORE_RHOSTS_NO }, 1236 { "shosts-only", IGNORE_RHOSTS_SHOSTS }, 1237 { NULL, -1 } 1238 }; 1239 static const struct multistate multistate_addressfamily[] = { 1240 { "inet", AF_INET }, 1241 { "inet6", AF_INET6 }, 1242 { "any", AF_UNSPEC }, 1243 { NULL, -1 } 1244 }; 1245 static const struct multistate multistate_permitrootlogin[] = { 1246 { "without-password", PERMIT_NO_PASSWD }, 1247 { "prohibit-password", PERMIT_NO_PASSWD }, 1248 { "forced-commands-only", PERMIT_FORCED_ONLY }, 1249 { "yes", PERMIT_YES }, 1250 { "no", PERMIT_NO }, 1251 { NULL, -1 } 1252 }; 1253 static const struct multistate multistate_compression[] = { 1254 #ifdef WITH_ZLIB 1255 { "yes", COMP_DELAYED }, 1256 { "delayed", COMP_DELAYED }, 1257 #endif 1258 { "no", COMP_NONE }, 1259 { NULL, -1 } 1260 }; 1261 static const struct multistate multistate_gatewayports[] = { 1262 { "clientspecified", 2 }, 1263 { "yes", 1 }, 1264 { "no", 0 }, 1265 { NULL, -1 } 1266 }; 1267 static const struct multistate multistate_tcpfwd[] = { 1268 { "yes", FORWARD_ALLOW }, 1269 { "all", FORWARD_ALLOW }, 1270 { "no", FORWARD_DENY }, 1271 { "remote", FORWARD_REMOTE }, 1272 { "local", FORWARD_LOCAL }, 1273 { NULL, -1 } 1274 }; 1275 1276 static int 1277 process_server_config_line_depth(ServerOptions *options, char *line, 1278 const char *filename, int linenum, int *activep, 1279 struct connection_info *connectinfo, int *inc_flags, int depth, 1280 struct include_list *includes) 1281 { 1282 char *str, ***chararrayptr, **charptr, *arg, *arg2, *p, *keyword; 1283 int cmdline = 0, *intptr, value, value2, n, port, oactive, r, found; 1284 int ca_only = 0; 1285 SyslogFacility *log_facility_ptr; 1286 LogLevel *log_level_ptr; 1287 ServerOpCodes opcode; 1288 u_int i, *uintptr, uvalue, flags = 0; 1289 size_t len; 1290 long long val64; 1291 const struct multistate *multistate_ptr; 1292 const char *errstr; 1293 struct include_item *item; 1294 glob_t gbuf; 1295 char **oav = NULL, **av; 1296 int oac = 0, ac; 1297 int ret = -1; 1298 1299 /* Strip trailing whitespace. Allow \f (form feed) at EOL only */ 1300 if ((len = strlen(line)) == 0) 1301 return 0; 1302 for (len--; len > 0; len--) { 1303 if (strchr(WHITESPACE "\f", line[len]) == NULL) 1304 break; 1305 line[len] = '\0'; 1306 } 1307 1308 str = line; 1309 if ((keyword = strdelim(&str)) == NULL) 1310 return 0; 1311 /* Ignore leading whitespace */ 1312 if (*keyword == '\0') 1313 keyword = strdelim(&str); 1314 if (!keyword || !*keyword || *keyword == '#') 1315 return 0; 1316 if (str == NULL || *str == '\0') { 1317 error("%s line %d: no argument after keyword \"%s\"", 1318 filename, linenum, keyword); 1319 return -1; 1320 } 1321 intptr = NULL; 1322 charptr = NULL; 1323 opcode = parse_token(keyword, filename, linenum, &flags); 1324 1325 if (argv_split(str, &oac, &oav, 1) != 0) { 1326 error("%s line %d: invalid quotes", filename, linenum); 1327 return -1; 1328 } 1329 ac = oac; 1330 av = oav; 1331 1332 if (activep == NULL) { /* We are processing a command line directive */ 1333 cmdline = 1; 1334 activep = &cmdline; 1335 } 1336 if (*activep && opcode != sMatch && opcode != sInclude) 1337 debug3("%s:%d setting %s %s", filename, linenum, keyword, str); 1338 if (*activep == 0 && !(flags & SSHCFG_MATCH)) { 1339 if (connectinfo == NULL) { 1340 fatal("%s line %d: Directive '%s' is not allowed " 1341 "within a Match block", filename, linenum, keyword); 1342 } else { /* this is a directive we have already processed */ 1343 ret = 0; 1344 goto out; 1345 } 1346 } 1347 1348 switch (opcode) { 1349 case sBadOption: 1350 goto out; 1351 case sPort: 1352 /* ignore ports from configfile if cmdline specifies ports */ 1353 if (options->ports_from_cmdline) { 1354 argv_consume(&ac); 1355 break; 1356 } 1357 if (options->num_ports >= MAX_PORTS) 1358 fatal("%s line %d: too many ports.", 1359 filename, linenum); 1360 arg = argv_next(&ac, &av); 1361 if (!arg || *arg == '\0') 1362 fatal("%s line %d: missing port number.", 1363 filename, linenum); 1364 options->ports[options->num_ports++] = a2port(arg); 1365 if (options->ports[options->num_ports-1] <= 0) 1366 fatal("%s line %d: Badly formatted port number.", 1367 filename, linenum); 1368 break; 1369 1370 case sLoginGraceTime: 1371 intptr = &options->login_grace_time; 1372 parse_time: 1373 arg = argv_next(&ac, &av); 1374 if (!arg || *arg == '\0') 1375 fatal("%s line %d: missing time value.", 1376 filename, linenum); 1377 if ((value = convtime(arg)) == -1) 1378 fatal("%s line %d: invalid time value.", 1379 filename, linenum); 1380 if (*activep && *intptr == -1) 1381 *intptr = value; 1382 break; 1383 1384 case sListenAddress: 1385 arg = argv_next(&ac, &av); 1386 if (arg == NULL || *arg == '\0') 1387 fatal("%s line %d: missing address", 1388 filename, linenum); 1389 /* check for bare IPv6 address: no "[]" and 2 or more ":" */ 1390 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL 1391 && strchr(p+1, ':') != NULL) { 1392 port = 0; 1393 p = arg; 1394 } else { 1395 arg2 = NULL; 1396 p = hpdelim(&arg); 1397 if (p == NULL) 1398 fatal("%s line %d: bad address:port usage", 1399 filename, linenum); 1400 p = cleanhostname(p); 1401 if (arg == NULL) 1402 port = 0; 1403 else if ((port = a2port(arg)) <= 0) 1404 fatal("%s line %d: bad port number", 1405 filename, linenum); 1406 } 1407 /* Optional routing table */ 1408 arg2 = NULL; 1409 if ((arg = argv_next(&ac, &av)) != NULL) { 1410 if (strcmp(arg, "rdomain") != 0 || 1411 (arg2 = argv_next(&ac, &av)) == NULL) 1412 fatal("%s line %d: bad ListenAddress syntax", 1413 filename, linenum); 1414 if (!valid_rdomain(arg2)) 1415 fatal("%s line %d: bad routing domain", 1416 filename, linenum); 1417 } 1418 queue_listen_addr(options, p, arg2, port); 1419 1420 break; 1421 1422 case sAddressFamily: 1423 intptr = &options->address_family; 1424 multistate_ptr = multistate_addressfamily; 1425 parse_multistate: 1426 arg = argv_next(&ac, &av); 1427 if (!arg || *arg == '\0') 1428 fatal("%s line %d: missing argument.", 1429 filename, linenum); 1430 value = -1; 1431 for (i = 0; multistate_ptr[i].key != NULL; i++) { 1432 if (strcasecmp(arg, multistate_ptr[i].key) == 0) { 1433 value = multistate_ptr[i].value; 1434 break; 1435 } 1436 } 1437 if (value == -1) 1438 fatal("%s line %d: unsupported option \"%s\".", 1439 filename, linenum, arg); 1440 if (*activep && *intptr == -1) 1441 *intptr = value; 1442 break; 1443 1444 case sHostKeyFile: 1445 arg = argv_next(&ac, &av); 1446 if (!arg || *arg == '\0') 1447 fatal("%s line %d: missing file name.", 1448 filename, linenum); 1449 if (*activep) { 1450 servconf_add_hostkey(filename, linenum, 1451 options, arg, 1); 1452 } 1453 break; 1454 1455 case sHostKeyAgent: 1456 charptr = &options->host_key_agent; 1457 arg = argv_next(&ac, &av); 1458 if (!arg || *arg == '\0') 1459 fatal("%s line %d: missing socket name.", 1460 filename, linenum); 1461 if (*activep && *charptr == NULL) 1462 *charptr = !strcmp(arg, SSH_AUTHSOCKET_ENV_NAME) ? 1463 xstrdup(arg) : derelativise_path(arg); 1464 break; 1465 1466 case sHostCertificate: 1467 arg = argv_next(&ac, &av); 1468 if (!arg || *arg == '\0') 1469 fatal("%s line %d: missing file name.", 1470 filename, linenum); 1471 if (*activep) 1472 servconf_add_hostcert(filename, linenum, options, arg); 1473 break; 1474 1475 case sPidFile: 1476 charptr = &options->pid_file; 1477 parse_filename: 1478 arg = argv_next(&ac, &av); 1479 if (!arg || *arg == '\0') 1480 fatal("%s line %d: missing file name.", 1481 filename, linenum); 1482 if (*activep && *charptr == NULL) { 1483 *charptr = derelativise_path(arg); 1484 /* increase optional counter */ 1485 if (intptr != NULL) 1486 *intptr = *intptr + 1; 1487 } 1488 break; 1489 1490 case sModuliFile: 1491 charptr = &options->moduli_file; 1492 goto parse_filename; 1493 1494 case sPermitRootLogin: 1495 intptr = &options->permit_root_login; 1496 multistate_ptr = multistate_permitrootlogin; 1497 goto parse_multistate; 1498 1499 case sIgnoreRhosts: 1500 intptr = &options->ignore_rhosts; 1501 multistate_ptr = multistate_ignore_rhosts; 1502 goto parse_multistate; 1503 1504 case sIgnoreUserKnownHosts: 1505 intptr = &options->ignore_user_known_hosts; 1506 parse_flag: 1507 multistate_ptr = multistate_flag; 1508 goto parse_multistate; 1509 1510 case sHostbasedAuthentication: 1511 intptr = &options->hostbased_authentication; 1512 goto parse_flag; 1513 1514 case sHostbasedUsesNameFromPacketOnly: 1515 intptr = &options->hostbased_uses_name_from_packet_only; 1516 goto parse_flag; 1517 1518 case sHostbasedAcceptedAlgorithms: 1519 charptr = &options->hostbased_accepted_algos; 1520 ca_only = 0; 1521 parse_pubkey_algos: 1522 arg = argv_next(&ac, &av); 1523 if (!arg || *arg == '\0') 1524 fatal("%s line %d: Missing argument.", 1525 filename, linenum); 1526 if (*arg != '-' && 1527 !sshkey_names_valid2(*arg == '+' || *arg == '^' ? 1528 arg + 1 : arg, 1, ca_only)) 1529 fatal("%s line %d: Bad key types '%s'.", 1530 filename, linenum, arg ? arg : "<NONE>"); 1531 if (*activep && *charptr == NULL) 1532 *charptr = xstrdup(arg); 1533 break; 1534 1535 case sHostKeyAlgorithms: 1536 charptr = &options->hostkeyalgorithms; 1537 ca_only = 0; 1538 goto parse_pubkey_algos; 1539 1540 case sCASignatureAlgorithms: 1541 charptr = &options->ca_sign_algorithms; 1542 ca_only = 1; 1543 goto parse_pubkey_algos; 1544 1545 case sPubkeyAuthentication: 1546 intptr = &options->pubkey_authentication; 1547 ca_only = 0; 1548 goto parse_flag; 1549 1550 case sPubkeyAcceptedAlgorithms: 1551 charptr = &options->pubkey_accepted_algos; 1552 ca_only = 0; 1553 goto parse_pubkey_algos; 1554 1555 case sPubkeyAuthOptions: 1556 intptr = &options->pubkey_auth_options; 1557 value = 0; 1558 while ((arg = argv_next(&ac, &av)) != NULL) { 1559 if (strcasecmp(arg, "none") == 0) 1560 continue; 1561 if (strcasecmp(arg, "touch-required") == 0) 1562 value |= PUBKEYAUTH_TOUCH_REQUIRED; 1563 else if (strcasecmp(arg, "verify-required") == 0) 1564 value |= PUBKEYAUTH_VERIFY_REQUIRED; 1565 else { 1566 error("%s line %d: unsupported %s option %s", 1567 filename, linenum, keyword, arg); 1568 goto out; 1569 } 1570 } 1571 if (*activep && *intptr == -1) 1572 *intptr = value; 1573 break; 1574 1575 case sKerberosAuthentication: 1576 intptr = &options->kerberos_authentication; 1577 goto parse_flag; 1578 1579 case sKerberosOrLocalPasswd: 1580 intptr = &options->kerberos_or_local_passwd; 1581 goto parse_flag; 1582 1583 case sKerberosTicketCleanup: 1584 intptr = &options->kerberos_ticket_cleanup; 1585 goto parse_flag; 1586 1587 case sKerberosGetAFSToken: 1588 intptr = &options->kerberos_get_afs_token; 1589 goto parse_flag; 1590 1591 case sGssAuthentication: 1592 intptr = &options->gss_authentication; 1593 goto parse_flag; 1594 1595 case sGssCleanupCreds: 1596 intptr = &options->gss_cleanup_creds; 1597 goto parse_flag; 1598 1599 case sGssStrictAcceptor: 1600 intptr = &options->gss_strict_acceptor; 1601 goto parse_flag; 1602 1603 case sPasswordAuthentication: 1604 intptr = &options->password_authentication; 1605 goto parse_flag; 1606 1607 case sKbdInteractiveAuthentication: 1608 intptr = &options->kbd_interactive_authentication; 1609 goto parse_flag; 1610 1611 case sPrintMotd: 1612 intptr = &options->print_motd; 1613 goto parse_flag; 1614 1615 case sPrintLastLog: 1616 intptr = &options->print_lastlog; 1617 goto parse_flag; 1618 1619 case sX11Forwarding: 1620 intptr = &options->x11_forwarding; 1621 goto parse_flag; 1622 1623 case sX11DisplayOffset: 1624 intptr = &options->x11_display_offset; 1625 parse_int: 1626 arg = argv_next(&ac, &av); 1627 if ((errstr = atoi_err(arg, &value)) != NULL) 1628 fatal("%s line %d: %s integer value %s.", 1629 filename, linenum, keyword, errstr); 1630 if (*activep && *intptr == -1) 1631 *intptr = value; 1632 break; 1633 1634 case sX11UseLocalhost: 1635 intptr = &options->x11_use_localhost; 1636 goto parse_flag; 1637 1638 case sXAuthLocation: 1639 charptr = &options->xauth_location; 1640 goto parse_filename; 1641 1642 case sPermitTTY: 1643 intptr = &options->permit_tty; 1644 goto parse_flag; 1645 1646 case sPermitUserRC: 1647 intptr = &options->permit_user_rc; 1648 goto parse_flag; 1649 1650 case sStrictModes: 1651 intptr = &options->strict_modes; 1652 goto parse_flag; 1653 1654 case sTCPKeepAlive: 1655 intptr = &options->tcp_keep_alive; 1656 goto parse_flag; 1657 1658 case sEmptyPasswd: 1659 intptr = &options->permit_empty_passwd; 1660 goto parse_flag; 1661 1662 case sPermitUserEnvironment: 1663 intptr = &options->permit_user_env; 1664 charptr = &options->permit_user_env_allowlist; 1665 arg = argv_next(&ac, &av); 1666 if (!arg || *arg == '\0') 1667 fatal("%s line %d: %s missing argument.", 1668 filename, linenum, keyword); 1669 value = 0; 1670 p = NULL; 1671 if (strcmp(arg, "yes") == 0) 1672 value = 1; 1673 else if (strcmp(arg, "no") == 0) 1674 value = 0; 1675 else { 1676 /* Pattern-list specified */ 1677 value = 1; 1678 p = xstrdup(arg); 1679 } 1680 if (*activep && *intptr == -1) { 1681 *intptr = value; 1682 *charptr = p; 1683 p = NULL; 1684 } 1685 free(p); 1686 break; 1687 1688 case sCompression: 1689 intptr = &options->compression; 1690 multistate_ptr = multistate_compression; 1691 goto parse_multistate; 1692 1693 case sRekeyLimit: 1694 arg = argv_next(&ac, &av); 1695 if (!arg || *arg == '\0') 1696 fatal("%s line %d: %s missing argument.", 1697 filename, linenum, keyword); 1698 if (strcmp(arg, "default") == 0) { 1699 val64 = 0; 1700 } else { 1701 if (scan_scaled(arg, &val64) == -1) 1702 fatal("%.200s line %d: Bad %s number '%s': %s", 1703 filename, linenum, keyword, 1704 arg, strerror(errno)); 1705 if (val64 != 0 && val64 < 16) 1706 fatal("%.200s line %d: %s too small", 1707 filename, linenum, keyword); 1708 } 1709 if (*activep && options->rekey_limit == -1) 1710 options->rekey_limit = val64; 1711 if (ac != 0) { /* optional rekey interval present */ 1712 if (strcmp(av[0], "none") == 0) { 1713 (void)argv_next(&ac, &av); /* discard */ 1714 break; 1715 } 1716 intptr = &options->rekey_interval; 1717 goto parse_time; 1718 } 1719 break; 1720 1721 case sGatewayPorts: 1722 intptr = &options->fwd_opts.gateway_ports; 1723 multistate_ptr = multistate_gatewayports; 1724 goto parse_multistate; 1725 1726 case sUseDNS: 1727 intptr = &options->use_dns; 1728 goto parse_flag; 1729 1730 case sLogFacility: 1731 log_facility_ptr = &options->log_facility; 1732 arg = argv_next(&ac, &av); 1733 value = log_facility_number(arg); 1734 if (value == SYSLOG_FACILITY_NOT_SET) 1735 fatal("%.200s line %d: unsupported log facility '%s'", 1736 filename, linenum, arg ? arg : "<NONE>"); 1737 if (*log_facility_ptr == -1) 1738 *log_facility_ptr = (SyslogFacility) value; 1739 break; 1740 1741 case sLogLevel: 1742 log_level_ptr = &options->log_level; 1743 arg = argv_next(&ac, &av); 1744 value = log_level_number(arg); 1745 if (value == SYSLOG_LEVEL_NOT_SET) 1746 fatal("%.200s line %d: unsupported log level '%s'", 1747 filename, linenum, arg ? arg : "<NONE>"); 1748 if (*activep && *log_level_ptr == -1) 1749 *log_level_ptr = (LogLevel) value; 1750 break; 1751 1752 case sLogVerbose: 1753 found = options->num_log_verbose == 0; 1754 i = 0; 1755 while ((arg = argv_next(&ac, &av)) != NULL) { 1756 if (*arg == '\0') { 1757 error("%s line %d: keyword %s empty argument", 1758 filename, linenum, keyword); 1759 goto out; 1760 } 1761 /* Allow "none" only in first position */ 1762 if (strcasecmp(arg, "none") == 0) { 1763 if (i > 0 || ac > 0) { 1764 error("%s line %d: keyword %s \"none\" " 1765 "argument must appear alone.", 1766 filename, linenum, keyword); 1767 goto out; 1768 } 1769 } 1770 i++; 1771 if (!found || !*activep) 1772 continue; 1773 opt_array_append(filename, linenum, keyword, 1774 &options->log_verbose, &options->num_log_verbose, 1775 arg); 1776 } 1777 break; 1778 1779 case sAllowTcpForwarding: 1780 intptr = &options->allow_tcp_forwarding; 1781 multistate_ptr = multistate_tcpfwd; 1782 goto parse_multistate; 1783 1784 case sAllowStreamLocalForwarding: 1785 intptr = &options->allow_streamlocal_forwarding; 1786 multistate_ptr = multistate_tcpfwd; 1787 goto parse_multistate; 1788 1789 case sAllowAgentForwarding: 1790 intptr = &options->allow_agent_forwarding; 1791 goto parse_flag; 1792 1793 case sDisableForwarding: 1794 intptr = &options->disable_forwarding; 1795 goto parse_flag; 1796 1797 case sAllowUsers: 1798 chararrayptr = &options->allow_users; 1799 uintptr = &options->num_allow_users; 1800 parse_allowdenyusers: 1801 while ((arg = argv_next(&ac, &av)) != NULL) { 1802 if (*arg == '\0' || 1803 match_user(NULL, NULL, NULL, arg) == -1) 1804 fatal("%s line %d: invalid %s pattern: \"%s\"", 1805 filename, linenum, keyword, arg); 1806 if (!*activep) 1807 continue; 1808 opt_array_append(filename, linenum, keyword, 1809 chararrayptr, uintptr, arg); 1810 } 1811 break; 1812 1813 case sDenyUsers: 1814 chararrayptr = &options->deny_users; 1815 uintptr = &options->num_deny_users; 1816 goto parse_allowdenyusers; 1817 1818 case sAllowGroups: 1819 chararrayptr = &options->allow_groups; 1820 uintptr = &options->num_allow_groups; 1821 parse_allowdenygroups: 1822 while ((arg = argv_next(&ac, &av)) != NULL) { 1823 if (*arg == '\0') 1824 fatal("%s line %d: empty %s pattern", 1825 filename, linenum, keyword); 1826 if (!*activep) 1827 continue; 1828 opt_array_append(filename, linenum, keyword, 1829 chararrayptr, uintptr, arg); 1830 } 1831 break; 1832 1833 case sDenyGroups: 1834 chararrayptr = &options->deny_groups; 1835 uintptr = &options->num_deny_groups; 1836 goto parse_allowdenygroups; 1837 1838 case sCiphers: 1839 arg = argv_next(&ac, &av); 1840 if (!arg || *arg == '\0') 1841 fatal("%s line %d: %s missing argument.", 1842 filename, linenum, keyword); 1843 if (*arg != '-' && 1844 !ciphers_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg)) 1845 fatal("%s line %d: Bad SSH2 cipher spec '%s'.", 1846 filename, linenum, arg ? arg : "<NONE>"); 1847 if (options->ciphers == NULL) 1848 options->ciphers = xstrdup(arg); 1849 break; 1850 1851 case sMacs: 1852 arg = argv_next(&ac, &av); 1853 if (!arg || *arg == '\0') 1854 fatal("%s line %d: %s missing argument.", 1855 filename, linenum, keyword); 1856 if (*arg != '-' && 1857 !mac_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg)) 1858 fatal("%s line %d: Bad SSH2 mac spec '%s'.", 1859 filename, linenum, arg ? arg : "<NONE>"); 1860 if (options->macs == NULL) 1861 options->macs = xstrdup(arg); 1862 break; 1863 1864 case sKexAlgorithms: 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 (*arg != '-' && 1870 !kex_names_valid(*arg == '+' || *arg == '^' ? 1871 arg + 1 : arg)) 1872 fatal("%s line %d: Bad SSH2 KexAlgorithms '%s'.", 1873 filename, linenum, arg ? arg : "<NONE>"); 1874 if (options->kex_algorithms == NULL) 1875 options->kex_algorithms = xstrdup(arg); 1876 break; 1877 1878 case sSubsystem: 1879 arg = argv_next(&ac, &av); 1880 if (!arg || *arg == '\0') 1881 fatal("%s line %d: %s missing argument.", 1882 filename, linenum, keyword); 1883 if (!*activep) { 1884 argv_consume(&ac); 1885 break; 1886 } 1887 found = 0; 1888 for (i = 0; i < options->num_subsystems; i++) { 1889 if (strcmp(arg, options->subsystem_name[i]) == 0) { 1890 found = 1; 1891 break; 1892 } 1893 } 1894 if (found) { 1895 debug("%s line %d: Subsystem '%s' already defined.", 1896 filename, linenum, arg); 1897 argv_consume(&ac); 1898 break; 1899 } 1900 options->subsystem_name = xrecallocarray( 1901 options->subsystem_name, options->num_subsystems, 1902 options->num_subsystems + 1, 1903 sizeof(*options->subsystem_name)); 1904 options->subsystem_command = xrecallocarray( 1905 options->subsystem_command, options->num_subsystems, 1906 options->num_subsystems + 1, 1907 sizeof(*options->subsystem_command)); 1908 options->subsystem_args = xrecallocarray( 1909 options->subsystem_args, options->num_subsystems, 1910 options->num_subsystems + 1, 1911 sizeof(*options->subsystem_args)); 1912 options->subsystem_name[options->num_subsystems] = xstrdup(arg); 1913 arg = argv_next(&ac, &av); 1914 if (!arg || *arg == '\0') { 1915 fatal("%s line %d: Missing subsystem command.", 1916 filename, linenum); 1917 } 1918 options->subsystem_command[options->num_subsystems] = 1919 xstrdup(arg); 1920 /* Collect arguments (separate to executable) */ 1921 arg = argv_assemble(1, &arg); /* quote command correctly */ 1922 arg2 = argv_assemble(ac, av); /* rest of command */ 1923 xasprintf(&options->subsystem_args[options->num_subsystems], 1924 "%s %s", arg, arg2); 1925 free(arg2); 1926 argv_consume(&ac); 1927 options->num_subsystems++; 1928 break; 1929 1930 case sMaxStartups: 1931 arg = argv_next(&ac, &av); 1932 if (!arg || *arg == '\0') 1933 fatal("%s line %d: %s missing argument.", 1934 filename, linenum, keyword); 1935 if ((n = sscanf(arg, "%d:%d:%d", 1936 &options->max_startups_begin, 1937 &options->max_startups_rate, 1938 &options->max_startups)) == 3) { 1939 if (options->max_startups_begin > 1940 options->max_startups || 1941 options->max_startups_rate > 100 || 1942 options->max_startups_rate < 1) 1943 fatal("%s line %d: Invalid %s spec.", 1944 filename, linenum, keyword); 1945 } else if (n != 1) 1946 fatal("%s line %d: Invalid %s spec.", 1947 filename, linenum, keyword); 1948 else 1949 options->max_startups = options->max_startups_begin; 1950 if (options->max_startups <= 0 || 1951 options->max_startups_begin <= 0) 1952 fatal("%s line %d: Invalid %s spec.", 1953 filename, linenum, keyword); 1954 break; 1955 1956 case sPerSourceNetBlockSize: 1957 arg = argv_next(&ac, &av); 1958 if (!arg || *arg == '\0') 1959 fatal("%s line %d: %s missing argument.", 1960 filename, linenum, keyword); 1961 switch (n = sscanf(arg, "%d:%d", &value, &value2)) { 1962 case 2: 1963 if (value2 < 0 || value2 > 128) 1964 n = -1; 1965 /* FALLTHROUGH */ 1966 case 1: 1967 if (value < 0 || value > 32) 1968 n = -1; 1969 } 1970 if (n != 1 && n != 2) 1971 fatal("%s line %d: Invalid %s spec.", 1972 filename, linenum, keyword); 1973 if (*activep) { 1974 options->per_source_masklen_ipv4 = value; 1975 options->per_source_masklen_ipv6 = value2; 1976 } 1977 break; 1978 1979 case sPerSourceMaxStartups: 1980 arg = argv_next(&ac, &av); 1981 if (!arg || *arg == '\0') 1982 fatal("%s line %d: %s missing argument.", 1983 filename, linenum, keyword); 1984 if (strcmp(arg, "none") == 0) { /* no limit */ 1985 value = INT_MAX; 1986 } else { 1987 if ((errstr = atoi_err(arg, &value)) != NULL) 1988 fatal("%s line %d: %s integer value %s.", 1989 filename, linenum, keyword, errstr); 1990 } 1991 if (*activep && options->per_source_max_startups == -1) 1992 options->per_source_max_startups = value; 1993 break; 1994 1995 case sMaxAuthTries: 1996 intptr = &options->max_authtries; 1997 goto parse_int; 1998 1999 case sMaxSessions: 2000 intptr = &options->max_sessions; 2001 goto parse_int; 2002 2003 case sBanner: 2004 charptr = &options->banner; 2005 goto parse_filename; 2006 2007 /* 2008 * These options can contain %X options expanded at 2009 * connect time, so that you can specify paths like: 2010 * 2011 * AuthorizedKeysFile /etc/ssh_keys/%u 2012 */ 2013 case sAuthorizedKeysFile: 2014 uvalue = options->num_authkeys_files; 2015 while ((arg = argv_next(&ac, &av)) != NULL) { 2016 if (*arg == '\0') { 2017 error("%s line %d: keyword %s empty argument", 2018 filename, linenum, keyword); 2019 goto out; 2020 } 2021 arg2 = tilde_expand_filename(arg, getuid()); 2022 if (*activep && uvalue == 0) { 2023 opt_array_append(filename, linenum, keyword, 2024 &options->authorized_keys_files, 2025 &options->num_authkeys_files, arg2); 2026 } 2027 free(arg2); 2028 } 2029 break; 2030 2031 case sAuthorizedPrincipalsFile: 2032 charptr = &options->authorized_principals_file; 2033 arg = argv_next(&ac, &av); 2034 if (!arg || *arg == '\0') 2035 fatal("%s line %d: %s missing argument.", 2036 filename, linenum, keyword); 2037 if (*activep && *charptr == NULL) { 2038 *charptr = tilde_expand_filename(arg, getuid()); 2039 /* increase optional counter */ 2040 if (intptr != NULL) 2041 *intptr = *intptr + 1; 2042 } 2043 break; 2044 2045 case sClientAliveInterval: 2046 intptr = &options->client_alive_interval; 2047 goto parse_time; 2048 2049 case sClientAliveCountMax: 2050 intptr = &options->client_alive_count_max; 2051 goto parse_int; 2052 2053 case sAcceptEnv: 2054 while ((arg = argv_next(&ac, &av)) != NULL) { 2055 if (*arg == '\0' || strchr(arg, '=') != NULL) 2056 fatal("%s line %d: Invalid environment name.", 2057 filename, linenum); 2058 if (!*activep) 2059 continue; 2060 opt_array_append(filename, linenum, keyword, 2061 &options->accept_env, &options->num_accept_env, 2062 arg); 2063 } 2064 break; 2065 2066 case sSetEnv: 2067 uvalue = options->num_setenv; 2068 while ((arg = argv_next(&ac, &av)) != NULL) { 2069 if (*arg == '\0' || strchr(arg, '=') == NULL) 2070 fatal("%s line %d: Invalid environment.", 2071 filename, linenum); 2072 if (!*activep || uvalue != 0) 2073 continue; 2074 if (lookup_setenv_in_list(arg, options->setenv, 2075 options->num_setenv) != NULL) { 2076 debug2("%s line %d: ignoring duplicate env " 2077 "name \"%.64s\"", filename, linenum, arg); 2078 continue; 2079 } 2080 opt_array_append(filename, linenum, keyword, 2081 &options->setenv, &options->num_setenv, arg); 2082 } 2083 break; 2084 2085 case sPermitTunnel: 2086 intptr = &options->permit_tun; 2087 arg = argv_next(&ac, &av); 2088 if (!arg || *arg == '\0') 2089 fatal("%s line %d: %s missing argument.", 2090 filename, linenum, keyword); 2091 value = -1; 2092 for (i = 0; tunmode_desc[i].val != -1; i++) 2093 if (strcmp(tunmode_desc[i].text, arg) == 0) { 2094 value = tunmode_desc[i].val; 2095 break; 2096 } 2097 if (value == -1) 2098 fatal("%s line %d: bad %s argument %s", 2099 filename, linenum, keyword, arg); 2100 if (*activep && *intptr == -1) 2101 *intptr = value; 2102 break; 2103 2104 case sInclude: 2105 if (cmdline) { 2106 fatal("Include directive not supported as a " 2107 "command-line option"); 2108 } 2109 value = 0; 2110 while ((arg2 = argv_next(&ac, &av)) != NULL) { 2111 if (*arg2 == '\0') { 2112 error("%s line %d: keyword %s empty argument", 2113 filename, linenum, keyword); 2114 goto out; 2115 } 2116 value++; 2117 found = 0; 2118 if (*arg2 != '/' && *arg2 != '~') { 2119 xasprintf(&arg, "%s/%s", SSHDIR, arg2); 2120 } else 2121 arg = xstrdup(arg2); 2122 2123 /* 2124 * Don't let included files clobber the containing 2125 * file's Match state. 2126 */ 2127 oactive = *activep; 2128 2129 /* consult cache of include files */ 2130 TAILQ_FOREACH(item, includes, entry) { 2131 if (strcmp(item->selector, arg) != 0) 2132 continue; 2133 if (item->filename != NULL) { 2134 parse_server_config_depth(options, 2135 item->filename, item->contents, 2136 includes, connectinfo, 2137 (*inc_flags & SSHCFG_MATCH_ONLY 2138 ? SSHCFG_MATCH_ONLY : (oactive 2139 ? 0 : SSHCFG_NEVERMATCH)), 2140 activep, depth + 1); 2141 } 2142 found = 1; 2143 *activep = oactive; 2144 } 2145 if (found != 0) { 2146 free(arg); 2147 continue; 2148 } 2149 2150 /* requested glob was not in cache */ 2151 debug2("%s line %d: new include %s", 2152 filename, linenum, arg); 2153 if ((r = glob(arg, 0, NULL, &gbuf)) != 0) { 2154 if (r != GLOB_NOMATCH) { 2155 fatal("%s line %d: include \"%s\" glob " 2156 "failed", filename, linenum, arg); 2157 } 2158 /* 2159 * If no entry matched then record a 2160 * placeholder to skip later glob calls. 2161 */ 2162 debug2("%s line %d: no match for %s", 2163 filename, linenum, arg); 2164 item = xcalloc(1, sizeof(*item)); 2165 item->selector = strdup(arg); 2166 TAILQ_INSERT_TAIL(includes, 2167 item, entry); 2168 } 2169 if (gbuf.gl_pathc > INT_MAX) 2170 fatal_f("too many glob results"); 2171 for (n = 0; n < (int)gbuf.gl_pathc; n++) { 2172 debug2("%s line %d: including %s", 2173 filename, linenum, gbuf.gl_pathv[n]); 2174 item = xcalloc(1, sizeof(*item)); 2175 item->selector = strdup(arg); 2176 item->filename = strdup(gbuf.gl_pathv[n]); 2177 if ((item->contents = sshbuf_new()) == NULL) 2178 fatal_f("sshbuf_new failed"); 2179 load_server_config(item->filename, 2180 item->contents); 2181 parse_server_config_depth(options, 2182 item->filename, item->contents, 2183 includes, connectinfo, 2184 (*inc_flags & SSHCFG_MATCH_ONLY 2185 ? SSHCFG_MATCH_ONLY : (oactive 2186 ? 0 : SSHCFG_NEVERMATCH)), 2187 activep, depth + 1); 2188 *activep = oactive; 2189 TAILQ_INSERT_TAIL(includes, item, entry); 2190 } 2191 globfree(&gbuf); 2192 free(arg); 2193 } 2194 if (value == 0) { 2195 fatal("%s line %d: %s missing filename argument", 2196 filename, linenum, keyword); 2197 } 2198 break; 2199 2200 case sMatch: 2201 if (cmdline) 2202 fatal("Match directive not supported as a command-line " 2203 "option"); 2204 value = match_cfg_line(&str, linenum, 2205 (*inc_flags & SSHCFG_NEVERMATCH ? NULL : connectinfo)); 2206 if (value < 0) 2207 fatal("%s line %d: Bad Match condition", filename, 2208 linenum); 2209 *activep = (*inc_flags & SSHCFG_NEVERMATCH) ? 0 : value; 2210 /* 2211 * The MATCH_ONLY flag is applicable only until the first 2212 * match block. 2213 */ 2214 *inc_flags &= ~SSHCFG_MATCH_ONLY; 2215 /* 2216 * If match_cfg_line() didn't consume all its arguments then 2217 * arrange for the extra arguments check below to fail. 2218 */ 2219 if (str == NULL || *str == '\0') 2220 argv_consume(&ac); 2221 break; 2222 2223 case sPermitListen: 2224 case sPermitOpen: 2225 if (opcode == sPermitListen) { 2226 uintptr = &options->num_permitted_listens; 2227 chararrayptr = &options->permitted_listens; 2228 } else { 2229 uintptr = &options->num_permitted_opens; 2230 chararrayptr = &options->permitted_opens; 2231 } 2232 arg = argv_next(&ac, &av); 2233 if (!arg || *arg == '\0') 2234 fatal("%s line %d: %s missing argument.", 2235 filename, linenum, keyword); 2236 uvalue = *uintptr; /* modified later */ 2237 if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) { 2238 if (*activep && uvalue == 0) { 2239 *uintptr = 1; 2240 *chararrayptr = xcalloc(1, 2241 sizeof(**chararrayptr)); 2242 (*chararrayptr)[0] = xstrdup(arg); 2243 } 2244 break; 2245 } 2246 for (; arg != NULL && *arg != '\0'; arg = argv_next(&ac, &av)) { 2247 if (opcode == sPermitListen && 2248 strchr(arg, ':') == NULL) { 2249 /* 2250 * Allow bare port number for PermitListen 2251 * to indicate a wildcard listen host. 2252 */ 2253 xasprintf(&arg2, "*:%s", arg); 2254 } else { 2255 arg2 = xstrdup(arg); 2256 p = hpdelim(&arg); 2257 if (p == NULL) { 2258 fatal("%s line %d: %s missing host", 2259 filename, linenum, keyword); 2260 } 2261 p = cleanhostname(p); 2262 } 2263 if (arg == NULL || 2264 ((port = permitopen_port(arg)) < 0)) { 2265 fatal("%s line %d: %s bad port number", 2266 filename, linenum, keyword); 2267 } 2268 if (*activep && uvalue == 0) { 2269 opt_array_append(filename, linenum, keyword, 2270 chararrayptr, uintptr, arg2); 2271 } 2272 free(arg2); 2273 } 2274 break; 2275 2276 case sForceCommand: 2277 if (str == NULL || *str == '\0') 2278 fatal("%s line %d: %s missing argument.", 2279 filename, linenum, keyword); 2280 len = strspn(str, WHITESPACE); 2281 if (*activep && options->adm_forced_command == NULL) 2282 options->adm_forced_command = xstrdup(str + len); 2283 argv_consume(&ac); 2284 break; 2285 2286 case sChrootDirectory: 2287 charptr = &options->chroot_directory; 2288 2289 arg = argv_next(&ac, &av); 2290 if (!arg || *arg == '\0') 2291 fatal("%s line %d: %s missing argument.", 2292 filename, linenum, keyword); 2293 if (*activep && *charptr == NULL) 2294 *charptr = xstrdup(arg); 2295 break; 2296 2297 case sTrustedUserCAKeys: 2298 charptr = &options->trusted_user_ca_keys; 2299 goto parse_filename; 2300 2301 case sRevokedKeys: 2302 charptr = &options->revoked_keys_file; 2303 goto parse_filename; 2304 2305 case sSecurityKeyProvider: 2306 charptr = &options->sk_provider; 2307 arg = argv_next(&ac, &av); 2308 if (!arg || *arg == '\0') 2309 fatal("%s line %d: %s missing argument.", 2310 filename, linenum, keyword); 2311 if (*activep && *charptr == NULL) { 2312 *charptr = strcasecmp(arg, "internal") == 0 ? 2313 xstrdup(arg) : derelativise_path(arg); 2314 /* increase optional counter */ 2315 if (intptr != NULL) 2316 *intptr = *intptr + 1; 2317 } 2318 break; 2319 2320 case sIPQoS: 2321 arg = argv_next(&ac, &av); 2322 if (!arg || *arg == '\0') 2323 fatal("%s line %d: %s missing argument.", 2324 filename, linenum, keyword); 2325 if ((value = parse_ipqos(arg)) == -1) 2326 fatal("%s line %d: Bad %s value: %s", 2327 filename, linenum, keyword, arg); 2328 arg = argv_next(&ac, &av); 2329 if (arg == NULL) 2330 value2 = value; 2331 else if ((value2 = parse_ipqos(arg)) == -1) 2332 fatal("%s line %d: Bad %s value: %s", 2333 filename, linenum, keyword, arg); 2334 if (*activep) { 2335 options->ip_qos_interactive = value; 2336 options->ip_qos_bulk = value2; 2337 } 2338 break; 2339 2340 case sVersionAddendum: 2341 if (str == NULL || *str == '\0') 2342 fatal("%s line %d: %s missing argument.", 2343 filename, linenum, keyword); 2344 len = strspn(str, WHITESPACE); 2345 if (strchr(str + len, '\r') != NULL) { 2346 fatal("%.200s line %d: Invalid %s argument", 2347 filename, linenum, keyword); 2348 } 2349 if ((arg = strchr(line, '#')) != NULL) { 2350 *arg = '\0'; 2351 rtrim(line); 2352 } 2353 if (*activep && options->version_addendum == NULL) { 2354 if (strcasecmp(str + len, "none") == 0) 2355 options->version_addendum = xstrdup(""); 2356 else 2357 options->version_addendum = xstrdup(str + len); 2358 } 2359 argv_consume(&ac); 2360 break; 2361 2362 case sAuthorizedKeysCommand: 2363 charptr = &options->authorized_keys_command; 2364 parse_command: 2365 len = strspn(str, WHITESPACE); 2366 if (str[len] != '/' && strcasecmp(str + len, "none") != 0) { 2367 fatal("%.200s line %d: %s must be an absolute path", 2368 filename, linenum, keyword); 2369 } 2370 if (*activep && *charptr == NULL) 2371 *charptr = xstrdup(str + len); 2372 argv_consume(&ac); 2373 break; 2374 2375 case sAuthorizedKeysCommandUser: 2376 charptr = &options->authorized_keys_command_user; 2377 parse_localuser: 2378 arg = argv_next(&ac, &av); 2379 if (!arg || *arg == '\0') { 2380 fatal("%s line %d: missing %s argument.", 2381 filename, linenum, keyword); 2382 } 2383 if (*activep && *charptr == NULL) 2384 *charptr = xstrdup(arg); 2385 break; 2386 2387 case sAuthorizedPrincipalsCommand: 2388 charptr = &options->authorized_principals_command; 2389 goto parse_command; 2390 2391 case sAuthorizedPrincipalsCommandUser: 2392 charptr = &options->authorized_principals_command_user; 2393 goto parse_localuser; 2394 2395 case sAuthenticationMethods: 2396 found = options->num_auth_methods == 0; 2397 value = 0; /* seen "any" pseudo-method */ 2398 value2 = 0; /* successfully parsed any method */ 2399 while ((arg = argv_next(&ac, &av)) != NULL) { 2400 if (strcmp(arg, "any") == 0) { 2401 if (options->num_auth_methods > 0) { 2402 fatal("%s line %d: \"any\" must " 2403 "appear alone in %s", 2404 filename, linenum, keyword); 2405 } 2406 value = 1; 2407 } else if (value) { 2408 fatal("%s line %d: \"any\" must appear " 2409 "alone in %s", filename, linenum, keyword); 2410 } else if (auth2_methods_valid(arg, 0) != 0) { 2411 fatal("%s line %d: invalid %s method list.", 2412 filename, linenum, keyword); 2413 } 2414 value2 = 1; 2415 if (!found || !*activep) 2416 continue; 2417 opt_array_append(filename, linenum, keyword, 2418 &options->auth_methods, 2419 &options->num_auth_methods, arg); 2420 } 2421 if (value2 == 0) { 2422 fatal("%s line %d: no %s specified", 2423 filename, linenum, keyword); 2424 } 2425 break; 2426 2427 case sStreamLocalBindMask: 2428 arg = argv_next(&ac, &av); 2429 if (!arg || *arg == '\0') 2430 fatal("%s line %d: %s missing argument.", 2431 filename, linenum, keyword); 2432 /* Parse mode in octal format */ 2433 value = strtol(arg, &p, 8); 2434 if (arg == p || value < 0 || value > 0777) 2435 fatal("%s line %d: Invalid %s.", 2436 filename, linenum, keyword); 2437 if (*activep) 2438 options->fwd_opts.streamlocal_bind_mask = (mode_t)value; 2439 break; 2440 2441 case sStreamLocalBindUnlink: 2442 intptr = &options->fwd_opts.streamlocal_bind_unlink; 2443 goto parse_flag; 2444 2445 case sFingerprintHash: 2446 arg = argv_next(&ac, &av); 2447 if (!arg || *arg == '\0') 2448 fatal("%s line %d: %s missing argument.", 2449 filename, linenum, keyword); 2450 if ((value = ssh_digest_alg_by_name(arg)) == -1) 2451 fatal("%.200s line %d: Invalid %s algorithm \"%s\".", 2452 filename, linenum, keyword, arg); 2453 if (*activep) 2454 options->fingerprint_hash = value; 2455 break; 2456 2457 case sExposeAuthInfo: 2458 intptr = &options->expose_userauth_info; 2459 goto parse_flag; 2460 2461 case sRDomain: 2462 charptr = &options->routing_domain; 2463 arg = argv_next(&ac, &av); 2464 if (!arg || *arg == '\0') 2465 fatal("%s line %d: %s missing argument.", 2466 filename, linenum, keyword); 2467 if (strcasecmp(arg, "none") != 0 && strcmp(arg, "%D") != 0 && 2468 !valid_rdomain(arg)) 2469 fatal("%s line %d: invalid routing domain", 2470 filename, linenum); 2471 if (*activep && *charptr == NULL) 2472 *charptr = xstrdup(arg); 2473 break; 2474 2475 case sRequiredRSASize: 2476 intptr = &options->required_rsa_size; 2477 goto parse_int; 2478 2479 case sChannelTimeout: 2480 uvalue = options->num_channel_timeouts; 2481 i = 0; 2482 while ((arg = argv_next(&ac, &av)) != NULL) { 2483 /* Allow "none" only in first position */ 2484 if (strcasecmp(arg, "none") == 0) { 2485 if (i > 0 || ac > 0) { 2486 error("%s line %d: keyword %s \"none\" " 2487 "argument must appear alone.", 2488 filename, linenum, keyword); 2489 goto out; 2490 } 2491 } else if (parse_timeout(arg, NULL, NULL) != 0) { 2492 fatal("%s line %d: invalid channel timeout %s", 2493 filename, linenum, arg); 2494 } 2495 if (!*activep || uvalue != 0) 2496 continue; 2497 opt_array_append(filename, linenum, keyword, 2498 &options->channel_timeouts, 2499 &options->num_channel_timeouts, arg); 2500 } 2501 break; 2502 2503 case sUnusedConnectionTimeout: 2504 intptr = &options->unused_connection_timeout; 2505 /* peek at first arg for "none" so we can reuse parse_time */ 2506 if (av[0] != NULL && strcasecmp(av[0], "none") == 0) { 2507 (void)argv_next(&ac, &av); /* consume arg */ 2508 if (*activep) 2509 *intptr = 0; 2510 break; 2511 } 2512 goto parse_time; 2513 2514 case sDeprecated: 2515 case sIgnore: 2516 case sUnsupported: 2517 do_log2(opcode == sIgnore ? 2518 SYSLOG_LEVEL_DEBUG2 : SYSLOG_LEVEL_INFO, 2519 "%s line %d: %s option %s", filename, linenum, 2520 opcode == sUnsupported ? "Unsupported" : "Deprecated", 2521 keyword); 2522 argv_consume(&ac); 2523 break; 2524 2525 default: 2526 fatal("%s line %d: Missing handler for opcode %s (%d)", 2527 filename, linenum, keyword, opcode); 2528 } 2529 /* Check that there is no garbage at end of line. */ 2530 if (ac > 0) { 2531 error("%.200s line %d: keyword %s extra arguments " 2532 "at end of line", filename, linenum, keyword); 2533 goto out; 2534 } 2535 2536 /* success */ 2537 ret = 0; 2538 out: 2539 argv_free(oav, oac); 2540 return ret; 2541 } 2542 2543 int 2544 process_server_config_line(ServerOptions *options, char *line, 2545 const char *filename, int linenum, int *activep, 2546 struct connection_info *connectinfo, struct include_list *includes) 2547 { 2548 int inc_flags = 0; 2549 2550 return process_server_config_line_depth(options, line, filename, 2551 linenum, activep, connectinfo, &inc_flags, 0, includes); 2552 } 2553 2554 2555 /* Reads the server configuration file. */ 2556 2557 void 2558 load_server_config(const char *filename, struct sshbuf *conf) 2559 { 2560 struct stat st; 2561 char *line = NULL, *cp; 2562 size_t linesize = 0; 2563 FILE *f; 2564 int r; 2565 2566 debug2_f("filename %s", filename); 2567 if ((f = fopen(filename, "r")) == NULL) { 2568 perror(filename); 2569 exit(1); 2570 } 2571 sshbuf_reset(conf); 2572 /* grow buffer, so realloc is avoided for large config files */ 2573 if (fstat(fileno(f), &st) == 0 && st.st_size > 0 && 2574 (r = sshbuf_allocate(conf, st.st_size)) != 0) 2575 fatal_fr(r, "allocate"); 2576 while (getline(&line, &linesize, f) != -1) { 2577 /* 2578 * Strip whitespace 2579 * NB - preserve newlines, they are needed to reproduce 2580 * line numbers later for error messages 2581 */ 2582 cp = line + strspn(line, " \t\r"); 2583 if ((r = sshbuf_put(conf, cp, strlen(cp))) != 0) 2584 fatal_fr(r, "sshbuf_put"); 2585 } 2586 free(line); 2587 if ((r = sshbuf_put_u8(conf, 0)) != 0) 2588 fatal_fr(r, "sshbuf_put_u8"); 2589 fclose(f); 2590 debug2_f("done config len = %zu", sshbuf_len(conf)); 2591 } 2592 2593 void 2594 parse_server_match_config(ServerOptions *options, 2595 struct include_list *includes, struct connection_info *connectinfo) 2596 { 2597 ServerOptions mo; 2598 2599 initialize_server_options(&mo); 2600 parse_server_config(&mo, "reprocess config", cfg, includes, 2601 connectinfo, 0); 2602 copy_set_server_options(options, &mo, 0); 2603 } 2604 2605 int parse_server_match_testspec(struct connection_info *ci, char *spec) 2606 { 2607 char *p; 2608 2609 while ((p = strsep(&spec, ",")) && *p != '\0') { 2610 if (strncmp(p, "addr=", 5) == 0) { 2611 ci->address = xstrdup(p + 5); 2612 } else if (strncmp(p, "host=", 5) == 0) { 2613 ci->host = xstrdup(p + 5); 2614 } else if (strncmp(p, "user=", 5) == 0) { 2615 ci->user = xstrdup(p + 5); 2616 } else if (strncmp(p, "laddr=", 6) == 0) { 2617 ci->laddress = xstrdup(p + 6); 2618 } else if (strncmp(p, "rdomain=", 8) == 0) { 2619 ci->rdomain = xstrdup(p + 8); 2620 } else if (strncmp(p, "lport=", 6) == 0) { 2621 ci->lport = a2port(p + 6); 2622 if (ci->lport == -1) { 2623 fprintf(stderr, "Invalid port '%s' in test mode" 2624 " specification %s\n", p+6, p); 2625 return -1; 2626 } 2627 } else { 2628 fprintf(stderr, "Invalid test mode specification %s\n", 2629 p); 2630 return -1; 2631 } 2632 } 2633 return 0; 2634 } 2635 2636 void 2637 servconf_merge_subsystems(ServerOptions *dst, ServerOptions *src) 2638 { 2639 u_int i, j, found; 2640 2641 for (i = 0; i < src->num_subsystems; i++) { 2642 found = 0; 2643 for (j = 0; j < dst->num_subsystems; j++) { 2644 if (strcmp(src->subsystem_name[i], 2645 dst->subsystem_name[j]) == 0) { 2646 found = 1; 2647 break; 2648 } 2649 } 2650 if (found) { 2651 debug_f("override \"%s\"", dst->subsystem_name[j]); 2652 free(dst->subsystem_command[j]); 2653 free(dst->subsystem_args[j]); 2654 dst->subsystem_command[j] = 2655 xstrdup(src->subsystem_command[i]); 2656 dst->subsystem_args[j] = 2657 xstrdup(src->subsystem_args[i]); 2658 continue; 2659 } 2660 debug_f("add \"%s\"", src->subsystem_name[i]); 2661 dst->subsystem_name = xrecallocarray( 2662 dst->subsystem_name, dst->num_subsystems, 2663 dst->num_subsystems + 1, sizeof(*dst->subsystem_name)); 2664 dst->subsystem_command = xrecallocarray( 2665 dst->subsystem_command, dst->num_subsystems, 2666 dst->num_subsystems + 1, sizeof(*dst->subsystem_command)); 2667 dst->subsystem_args = xrecallocarray( 2668 dst->subsystem_args, dst->num_subsystems, 2669 dst->num_subsystems + 1, sizeof(*dst->subsystem_args)); 2670 j = dst->num_subsystems++; 2671 dst->subsystem_name[j] = xstrdup(src->subsystem_name[i]); 2672 dst->subsystem_command[j] = xstrdup(src->subsystem_command[i]); 2673 dst->subsystem_args[j] = xstrdup(src->subsystem_args[i]); 2674 } 2675 } 2676 2677 /* 2678 * Copy any supported values that are set. 2679 * 2680 * If the preauth flag is set, we do not bother copying the string or 2681 * array values that are not used pre-authentication, because any that we 2682 * do use must be explicitly sent in mm_getpwnamallow(). 2683 */ 2684 void 2685 copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) 2686 { 2687 #define M_CP_INTOPT(n) do {\ 2688 if (src->n != -1) \ 2689 dst->n = src->n; \ 2690 } while (0) 2691 2692 M_CP_INTOPT(password_authentication); 2693 M_CP_INTOPT(gss_authentication); 2694 M_CP_INTOPT(pubkey_authentication); 2695 M_CP_INTOPT(pubkey_auth_options); 2696 M_CP_INTOPT(kerberos_authentication); 2697 M_CP_INTOPT(hostbased_authentication); 2698 M_CP_INTOPT(hostbased_uses_name_from_packet_only); 2699 M_CP_INTOPT(kbd_interactive_authentication); 2700 M_CP_INTOPT(permit_root_login); 2701 M_CP_INTOPT(permit_empty_passwd); 2702 M_CP_INTOPT(ignore_rhosts); 2703 2704 M_CP_INTOPT(allow_tcp_forwarding); 2705 M_CP_INTOPT(allow_streamlocal_forwarding); 2706 M_CP_INTOPT(allow_agent_forwarding); 2707 M_CP_INTOPT(disable_forwarding); 2708 M_CP_INTOPT(expose_userauth_info); 2709 M_CP_INTOPT(permit_tun); 2710 M_CP_INTOPT(fwd_opts.gateway_ports); 2711 M_CP_INTOPT(fwd_opts.streamlocal_bind_unlink); 2712 M_CP_INTOPT(x11_display_offset); 2713 M_CP_INTOPT(x11_forwarding); 2714 M_CP_INTOPT(x11_use_localhost); 2715 M_CP_INTOPT(permit_tty); 2716 M_CP_INTOPT(permit_user_rc); 2717 M_CP_INTOPT(max_sessions); 2718 M_CP_INTOPT(max_authtries); 2719 M_CP_INTOPT(client_alive_count_max); 2720 M_CP_INTOPT(client_alive_interval); 2721 M_CP_INTOPT(ip_qos_interactive); 2722 M_CP_INTOPT(ip_qos_bulk); 2723 M_CP_INTOPT(rekey_limit); 2724 M_CP_INTOPT(rekey_interval); 2725 M_CP_INTOPT(log_level); 2726 M_CP_INTOPT(required_rsa_size); 2727 M_CP_INTOPT(unused_connection_timeout); 2728 2729 /* 2730 * The bind_mask is a mode_t that may be unsigned, so we can't use 2731 * M_CP_INTOPT - it does a signed comparison that causes compiler 2732 * warnings. 2733 */ 2734 if (src->fwd_opts.streamlocal_bind_mask != (mode_t)-1) { 2735 dst->fwd_opts.streamlocal_bind_mask = 2736 src->fwd_opts.streamlocal_bind_mask; 2737 } 2738 2739 /* M_CP_STROPT and M_CP_STRARRAYOPT should not appear before here */ 2740 #define M_CP_STROPT(n) do {\ 2741 if (src->n != NULL && dst->n != src->n) { \ 2742 free(dst->n); \ 2743 dst->n = src->n; \ 2744 } \ 2745 } while(0) 2746 #define M_CP_STRARRAYOPT(s, num_s) do {\ 2747 u_int i; \ 2748 if (src->num_s != 0) { \ 2749 for (i = 0; i < dst->num_s; i++) \ 2750 free(dst->s[i]); \ 2751 free(dst->s); \ 2752 dst->s = xcalloc(src->num_s, sizeof(*dst->s)); \ 2753 for (i = 0; i < src->num_s; i++) \ 2754 dst->s[i] = xstrdup(src->s[i]); \ 2755 dst->num_s = src->num_s; \ 2756 } \ 2757 } while(0) 2758 2759 /* See comment in servconf.h */ 2760 COPY_MATCH_STRING_OPTS(); 2761 2762 /* Arguments that accept '+...' need to be expanded */ 2763 assemble_algorithms(dst); 2764 2765 /* 2766 * The only things that should be below this point are string options 2767 * which are only used after authentication. 2768 */ 2769 if (preauth) 2770 return; 2771 2772 /* These options may be "none" to clear a global setting */ 2773 M_CP_STROPT(adm_forced_command); 2774 if (option_clear_or_none(dst->adm_forced_command)) { 2775 free(dst->adm_forced_command); 2776 dst->adm_forced_command = NULL; 2777 } 2778 M_CP_STROPT(chroot_directory); 2779 if (option_clear_or_none(dst->chroot_directory)) { 2780 free(dst->chroot_directory); 2781 dst->chroot_directory = NULL; 2782 } 2783 2784 /* Subsystems require merging. */ 2785 servconf_merge_subsystems(dst, src); 2786 } 2787 2788 #undef M_CP_INTOPT 2789 #undef M_CP_STROPT 2790 #undef M_CP_STRARRAYOPT 2791 2792 #define SERVCONF_MAX_DEPTH 16 2793 static void 2794 parse_server_config_depth(ServerOptions *options, const char *filename, 2795 struct sshbuf *conf, struct include_list *includes, 2796 struct connection_info *connectinfo, int flags, int *activep, int depth) 2797 { 2798 int linenum, bad_options = 0; 2799 char *cp, *obuf, *cbuf; 2800 2801 if (depth < 0 || depth > SERVCONF_MAX_DEPTH) 2802 fatal("Too many recursive configuration includes"); 2803 2804 debug2_f("config %s len %zu%s", filename, sshbuf_len(conf), 2805 (flags & SSHCFG_NEVERMATCH ? " [checking syntax only]" : "")); 2806 2807 if ((obuf = cbuf = sshbuf_dup_string(conf)) == NULL) 2808 fatal_f("sshbuf_dup_string failed"); 2809 linenum = 1; 2810 while ((cp = strsep(&cbuf, "\n")) != NULL) { 2811 if (process_server_config_line_depth(options, cp, 2812 filename, linenum++, activep, connectinfo, &flags, 2813 depth, includes) != 0) 2814 bad_options++; 2815 } 2816 free(obuf); 2817 if (bad_options > 0) 2818 fatal("%s: terminating, %d bad configuration options", 2819 filename, bad_options); 2820 } 2821 2822 void 2823 parse_server_config(ServerOptions *options, const char *filename, 2824 struct sshbuf *conf, struct include_list *includes, 2825 struct connection_info *connectinfo, int reexec) 2826 { 2827 int active = connectinfo ? 0 : 1; 2828 parse_server_config_depth(options, filename, conf, includes, 2829 connectinfo, (connectinfo ? SSHCFG_MATCH_ONLY : 0), &active, 0); 2830 if (!reexec) 2831 process_queued_listen_addrs(options); 2832 } 2833 2834 static const char * 2835 fmt_multistate_int(int val, const struct multistate *m) 2836 { 2837 u_int i; 2838 2839 for (i = 0; m[i].key != NULL; i++) { 2840 if (m[i].value == val) 2841 return m[i].key; 2842 } 2843 return "UNKNOWN"; 2844 } 2845 2846 static const char * 2847 fmt_intarg(ServerOpCodes code, int val) 2848 { 2849 if (val == -1) 2850 return "unset"; 2851 switch (code) { 2852 case sAddressFamily: 2853 return fmt_multistate_int(val, multistate_addressfamily); 2854 case sPermitRootLogin: 2855 return fmt_multistate_int(val, multistate_permitrootlogin); 2856 case sGatewayPorts: 2857 return fmt_multistate_int(val, multistate_gatewayports); 2858 case sCompression: 2859 return fmt_multistate_int(val, multistate_compression); 2860 case sAllowTcpForwarding: 2861 return fmt_multistate_int(val, multistate_tcpfwd); 2862 case sAllowStreamLocalForwarding: 2863 return fmt_multistate_int(val, multistate_tcpfwd); 2864 case sIgnoreRhosts: 2865 return fmt_multistate_int(val, multistate_ignore_rhosts); 2866 case sFingerprintHash: 2867 return ssh_digest_alg_name(val); 2868 default: 2869 switch (val) { 2870 case 0: 2871 return "no"; 2872 case 1: 2873 return "yes"; 2874 default: 2875 return "UNKNOWN"; 2876 } 2877 } 2878 } 2879 2880 static void 2881 dump_cfg_int(ServerOpCodes code, int val) 2882 { 2883 if (code == sUnusedConnectionTimeout && val == 0) { 2884 printf("%s none\n", lookup_opcode_name(code)); 2885 return; 2886 } 2887 printf("%s %d\n", lookup_opcode_name(code), val); 2888 } 2889 2890 static void 2891 dump_cfg_oct(ServerOpCodes code, int val) 2892 { 2893 printf("%s 0%o\n", lookup_opcode_name(code), val); 2894 } 2895 2896 static void 2897 dump_cfg_fmtint(ServerOpCodes code, int val) 2898 { 2899 printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val)); 2900 } 2901 2902 static void 2903 dump_cfg_string(ServerOpCodes code, const char *val) 2904 { 2905 printf("%s %s\n", lookup_opcode_name(code), 2906 val == NULL ? "none" : val); 2907 } 2908 2909 static void 2910 dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals) 2911 { 2912 u_int i; 2913 2914 for (i = 0; i < count; i++) 2915 printf("%s %s\n", lookup_opcode_name(code), vals[i]); 2916 } 2917 2918 static void 2919 dump_cfg_strarray_oneline(ServerOpCodes code, u_int count, char **vals) 2920 { 2921 u_int i; 2922 2923 switch (code) { 2924 case sAuthenticationMethods: 2925 case sChannelTimeout: 2926 break; 2927 default: 2928 if (count <= 0) 2929 return; 2930 break; 2931 } 2932 2933 printf("%s", lookup_opcode_name(code)); 2934 for (i = 0; i < count; i++) 2935 printf(" %s", vals[i]); 2936 if (code == sAuthenticationMethods && count == 0) 2937 printf(" any"); 2938 else if (code == sChannelTimeout && count == 0) 2939 printf(" none"); 2940 printf("\n"); 2941 } 2942 2943 static char * 2944 format_listen_addrs(struct listenaddr *la) 2945 { 2946 int r; 2947 struct addrinfo *ai; 2948 char addr[NI_MAXHOST], port[NI_MAXSERV]; 2949 char *laddr1 = xstrdup(""), *laddr2 = NULL; 2950 2951 /* 2952 * ListenAddress must be after Port. add_one_listen_addr pushes 2953 * addresses onto a stack, so to maintain ordering we need to 2954 * print these in reverse order. 2955 */ 2956 for (ai = la->addrs; ai; ai = ai->ai_next) { 2957 if ((r = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr, 2958 sizeof(addr), port, sizeof(port), 2959 NI_NUMERICHOST|NI_NUMERICSERV)) != 0) { 2960 error("getnameinfo: %.100s", ssh_gai_strerror(r)); 2961 continue; 2962 } 2963 laddr2 = laddr1; 2964 if (ai->ai_family == AF_INET6) { 2965 xasprintf(&laddr1, "listenaddress [%s]:%s%s%s\n%s", 2966 addr, port, 2967 la->rdomain == NULL ? "" : " rdomain ", 2968 la->rdomain == NULL ? "" : la->rdomain, 2969 laddr2); 2970 } else { 2971 xasprintf(&laddr1, "listenaddress %s:%s%s%s\n%s", 2972 addr, port, 2973 la->rdomain == NULL ? "" : " rdomain ", 2974 la->rdomain == NULL ? "" : la->rdomain, 2975 laddr2); 2976 } 2977 free(laddr2); 2978 } 2979 return laddr1; 2980 } 2981 2982 void 2983 dump_config(ServerOptions *o) 2984 { 2985 char *s; 2986 u_int i; 2987 2988 /* these are usually at the top of the config */ 2989 for (i = 0; i < o->num_ports; i++) 2990 printf("port %d\n", o->ports[i]); 2991 dump_cfg_fmtint(sAddressFamily, o->address_family); 2992 2993 for (i = 0; i < o->num_listen_addrs; i++) { 2994 s = format_listen_addrs(&o->listen_addrs[i]); 2995 printf("%s", s); 2996 free(s); 2997 } 2998 2999 /* integer arguments */ 3000 dump_cfg_int(sLoginGraceTime, o->login_grace_time); 3001 dump_cfg_int(sX11DisplayOffset, o->x11_display_offset); 3002 dump_cfg_int(sMaxAuthTries, o->max_authtries); 3003 dump_cfg_int(sMaxSessions, o->max_sessions); 3004 dump_cfg_int(sClientAliveInterval, o->client_alive_interval); 3005 dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max); 3006 dump_cfg_int(sRequiredRSASize, o->required_rsa_size); 3007 dump_cfg_oct(sStreamLocalBindMask, o->fwd_opts.streamlocal_bind_mask); 3008 dump_cfg_int(sUnusedConnectionTimeout, o->unused_connection_timeout); 3009 3010 /* formatted integer arguments */ 3011 dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login); 3012 dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts); 3013 dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts); 3014 dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication); 3015 dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly, 3016 o->hostbased_uses_name_from_packet_only); 3017 dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication); 3018 #ifdef KRB5 3019 dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication); 3020 dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd); 3021 dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup); 3022 dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); 3023 #endif 3024 #ifdef GSSAPI 3025 dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); 3026 dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); 3027 #endif 3028 dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); 3029 dump_cfg_fmtint(sKbdInteractiveAuthentication, 3030 o->kbd_interactive_authentication); 3031 dump_cfg_fmtint(sPrintMotd, o->print_motd); 3032 dump_cfg_fmtint(sPrintLastLog, o->print_lastlog); 3033 dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding); 3034 dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost); 3035 dump_cfg_fmtint(sPermitTTY, o->permit_tty); 3036 dump_cfg_fmtint(sPermitUserRC, o->permit_user_rc); 3037 dump_cfg_fmtint(sStrictModes, o->strict_modes); 3038 dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive); 3039 dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd); 3040 dump_cfg_fmtint(sCompression, o->compression); 3041 dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports); 3042 dump_cfg_fmtint(sUseDNS, o->use_dns); 3043 dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); 3044 dump_cfg_fmtint(sAllowAgentForwarding, o->allow_agent_forwarding); 3045 dump_cfg_fmtint(sDisableForwarding, o->disable_forwarding); 3046 dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding); 3047 dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink); 3048 dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); 3049 dump_cfg_fmtint(sExposeAuthInfo, o->expose_userauth_info); 3050 3051 /* string arguments */ 3052 dump_cfg_string(sPidFile, o->pid_file); 3053 dump_cfg_string(sModuliFile, o->moduli_file); 3054 dump_cfg_string(sXAuthLocation, o->xauth_location); 3055 dump_cfg_string(sCiphers, o->ciphers); 3056 dump_cfg_string(sMacs, o->macs); 3057 dump_cfg_string(sBanner, o->banner); 3058 dump_cfg_string(sForceCommand, o->adm_forced_command); 3059 dump_cfg_string(sChrootDirectory, o->chroot_directory); 3060 dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys); 3061 dump_cfg_string(sRevokedKeys, o->revoked_keys_file); 3062 dump_cfg_string(sSecurityKeyProvider, o->sk_provider); 3063 dump_cfg_string(sAuthorizedPrincipalsFile, 3064 o->authorized_principals_file); 3065 dump_cfg_string(sVersionAddendum, *o->version_addendum == '\0' 3066 ? "none" : o->version_addendum); 3067 dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command); 3068 dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user); 3069 dump_cfg_string(sAuthorizedPrincipalsCommand, o->authorized_principals_command); 3070 dump_cfg_string(sAuthorizedPrincipalsCommandUser, o->authorized_principals_command_user); 3071 dump_cfg_string(sHostKeyAgent, o->host_key_agent); 3072 dump_cfg_string(sKexAlgorithms, o->kex_algorithms); 3073 dump_cfg_string(sCASignatureAlgorithms, o->ca_sign_algorithms); 3074 dump_cfg_string(sHostbasedAcceptedAlgorithms, o->hostbased_accepted_algos); 3075 dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms); 3076 dump_cfg_string(sPubkeyAcceptedAlgorithms, o->pubkey_accepted_algos); 3077 dump_cfg_string(sRDomain, o->routing_domain); 3078 3079 /* string arguments requiring a lookup */ 3080 dump_cfg_string(sLogLevel, log_level_name(o->log_level)); 3081 dump_cfg_string(sLogFacility, log_facility_name(o->log_facility)); 3082 3083 /* string array arguments */ 3084 dump_cfg_strarray_oneline(sAuthorizedKeysFile, o->num_authkeys_files, 3085 o->authorized_keys_files); 3086 dump_cfg_strarray(sHostKeyFile, o->num_host_key_files, 3087 o->host_key_files); 3088 dump_cfg_strarray(sHostCertificate, o->num_host_cert_files, 3089 o->host_cert_files); 3090 dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users); 3091 dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users); 3092 dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups); 3093 dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups); 3094 dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env); 3095 dump_cfg_strarray(sSetEnv, o->num_setenv, o->setenv); 3096 dump_cfg_strarray_oneline(sAuthenticationMethods, 3097 o->num_auth_methods, o->auth_methods); 3098 dump_cfg_strarray_oneline(sLogVerbose, 3099 o->num_log_verbose, o->log_verbose); 3100 dump_cfg_strarray_oneline(sChannelTimeout, 3101 o->num_channel_timeouts, o->channel_timeouts); 3102 3103 /* other arguments */ 3104 for (i = 0; i < o->num_subsystems; i++) 3105 printf("subsystem %s %s\n", o->subsystem_name[i], 3106 o->subsystem_args[i]); 3107 3108 printf("maxstartups %d:%d:%d\n", o->max_startups_begin, 3109 o->max_startups_rate, o->max_startups); 3110 printf("persourcemaxstartups "); 3111 if (o->per_source_max_startups == INT_MAX) 3112 printf("none\n"); 3113 else 3114 printf("%d\n", o->per_source_max_startups); 3115 printf("persourcenetblocksize %d:%d\n", o->per_source_masklen_ipv4, 3116 o->per_source_masklen_ipv6); 3117 3118 s = NULL; 3119 for (i = 0; tunmode_desc[i].val != -1; i++) { 3120 if (tunmode_desc[i].val == o->permit_tun) { 3121 s = tunmode_desc[i].text; 3122 break; 3123 } 3124 } 3125 dump_cfg_string(sPermitTunnel, s); 3126 3127 printf("ipqos %s ", iptos2str(o->ip_qos_interactive)); 3128 printf("%s\n", iptos2str(o->ip_qos_bulk)); 3129 3130 printf("rekeylimit %llu %d\n", (unsigned long long)o->rekey_limit, 3131 o->rekey_interval); 3132 3133 printf("permitopen"); 3134 if (o->num_permitted_opens == 0) 3135 printf(" any"); 3136 else { 3137 for (i = 0; i < o->num_permitted_opens; i++) 3138 printf(" %s", o->permitted_opens[i]); 3139 } 3140 printf("\n"); 3141 printf("permitlisten"); 3142 if (o->num_permitted_listens == 0) 3143 printf(" any"); 3144 else { 3145 for (i = 0; i < o->num_permitted_listens; i++) 3146 printf(" %s", o->permitted_listens[i]); 3147 } 3148 printf("\n"); 3149 3150 if (o->permit_user_env_allowlist == NULL) { 3151 dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env); 3152 } else { 3153 printf("permituserenvironment %s\n", 3154 o->permit_user_env_allowlist); 3155 } 3156 3157 printf("pubkeyauthoptions"); 3158 if (o->pubkey_auth_options == 0) 3159 printf(" none"); 3160 if (o->pubkey_auth_options & PUBKEYAUTH_TOUCH_REQUIRED) 3161 printf(" touch-required"); 3162 if (o->pubkey_auth_options & PUBKEYAUTH_VERIFY_REQUIRED) 3163 printf(" verify-required"); 3164 printf("\n"); 3165 } 3166