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