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