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