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