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