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