17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 37c478bd9Sstevel@tonic-gate * All rights reserved 47c478bd9Sstevel@tonic-gate * 57c478bd9Sstevel@tonic-gate * As far as I am concerned, the code I have written for this software 67c478bd9Sstevel@tonic-gate * can be used freely for any purpose. Any derived versions of this 77c478bd9Sstevel@tonic-gate * software must be clearly marked as such, and if the derived work is 87c478bd9Sstevel@tonic-gate * incompatible with the protocol description in the RFC file, it must be 97c478bd9Sstevel@tonic-gate * called by a name other than "ssh" or "Secure Shell". 107c478bd9Sstevel@tonic-gate */ 117c478bd9Sstevel@tonic-gate /* 126f8d59d8SJan Pechanec * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 137c478bd9Sstevel@tonic-gate * Use is subject to license terms. 147c478bd9Sstevel@tonic-gate */ 157c478bd9Sstevel@tonic-gate 167c478bd9Sstevel@tonic-gate #include "includes.h" 177c478bd9Sstevel@tonic-gate RCSID("$OpenBSD: servconf.c,v 1.115 2002/09/04 18:52:42 stevesk Exp $"); 187c478bd9Sstevel@tonic-gate 197c478bd9Sstevel@tonic-gate #ifdef HAVE_DEFOPEN 207c478bd9Sstevel@tonic-gate #include <deflt.h> 217c478bd9Sstevel@tonic-gate #endif /* HAVE_DEFOPEN */ 227c478bd9Sstevel@tonic-gate 237c478bd9Sstevel@tonic-gate #if defined(KRB4) 247c478bd9Sstevel@tonic-gate #include <krb.h> 257c478bd9Sstevel@tonic-gate #endif 267c478bd9Sstevel@tonic-gate #if defined(KRB5) 277c478bd9Sstevel@tonic-gate #ifdef HEIMDAL 287c478bd9Sstevel@tonic-gate #include <krb.h> 297c478bd9Sstevel@tonic-gate #else 307c478bd9Sstevel@tonic-gate /* Bodge - but then, so is using the kerberos IV KEYFILE to get a Kerberos V 317c478bd9Sstevel@tonic-gate * keytab */ 327c478bd9Sstevel@tonic-gate #define KEYFILE "/etc/krb5.keytab" 337c478bd9Sstevel@tonic-gate #endif 347c478bd9Sstevel@tonic-gate #endif 357c478bd9Sstevel@tonic-gate #ifdef AFS 367c478bd9Sstevel@tonic-gate #include <kafs.h> 377c478bd9Sstevel@tonic-gate #endif 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gate #include "ssh.h" 407c478bd9Sstevel@tonic-gate #include "log.h" 417c478bd9Sstevel@tonic-gate #include "servconf.h" 427c478bd9Sstevel@tonic-gate #include "xmalloc.h" 437c478bd9Sstevel@tonic-gate #include "compat.h" 447c478bd9Sstevel@tonic-gate #include "pathnames.h" 457c478bd9Sstevel@tonic-gate #include "tildexpand.h" 467c478bd9Sstevel@tonic-gate #include "misc.h" 477c478bd9Sstevel@tonic-gate #include "cipher.h" 487c478bd9Sstevel@tonic-gate #include "kex.h" 497c478bd9Sstevel@tonic-gate #include "mac.h" 507c478bd9Sstevel@tonic-gate #include "auth.h" 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gate static void add_listen_addr(ServerOptions *, char *, u_short); 537c478bd9Sstevel@tonic-gate static void add_one_listen_addr(ServerOptions *, char *, u_short); 547c478bd9Sstevel@tonic-gate 557c478bd9Sstevel@tonic-gate /* AF_UNSPEC or AF_INET or AF_INET6 */ 567c478bd9Sstevel@tonic-gate extern int IPv4or6; 577c478bd9Sstevel@tonic-gate 586f8d59d8SJan Pechanec /* 596f8d59d8SJan Pechanec * Initializes the server options to their initial (unset) values. Some of those 606f8d59d8SJan Pechanec * that stay unset after the command line options and configuration files are 616f8d59d8SJan Pechanec * read are set to their default values in fill_default_server_options(). 626f8d59d8SJan Pechanec */ 637c478bd9Sstevel@tonic-gate void 647c478bd9Sstevel@tonic-gate initialize_server_options(ServerOptions *options) 657c478bd9Sstevel@tonic-gate { 667c478bd9Sstevel@tonic-gate (void) memset(options, 0, sizeof(*options)); 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate /* Portable-specific options */ 697c478bd9Sstevel@tonic-gate options->pam_authentication_via_kbd_int = -1; 707c478bd9Sstevel@tonic-gate 717c478bd9Sstevel@tonic-gate /* Standard Options */ 727c478bd9Sstevel@tonic-gate options->num_ports = 0; 737c478bd9Sstevel@tonic-gate options->ports_from_cmdline = 0; 747c478bd9Sstevel@tonic-gate options->listen_addrs = NULL; 757c478bd9Sstevel@tonic-gate options->num_host_key_files = 0; 767c478bd9Sstevel@tonic-gate options->pid_file = NULL; 777c478bd9Sstevel@tonic-gate options->server_key_bits = -1; 787c478bd9Sstevel@tonic-gate options->login_grace_time = -1; 797c478bd9Sstevel@tonic-gate options->key_regeneration_time = -1; 807c478bd9Sstevel@tonic-gate options->permit_root_login = PERMIT_NOT_SET; 817c478bd9Sstevel@tonic-gate options->ignore_rhosts = -1; 827c478bd9Sstevel@tonic-gate options->ignore_user_known_hosts = -1; 837c478bd9Sstevel@tonic-gate options->print_motd = -1; 847c478bd9Sstevel@tonic-gate options->print_lastlog = -1; 857c478bd9Sstevel@tonic-gate options->x11_forwarding = -1; 867c478bd9Sstevel@tonic-gate options->x11_display_offset = -1; 877c478bd9Sstevel@tonic-gate options->x11_use_localhost = -1; 887c478bd9Sstevel@tonic-gate options->xauth_location = NULL; 897c478bd9Sstevel@tonic-gate options->strict_modes = -1; 907c478bd9Sstevel@tonic-gate options->keepalives = -1; 917c478bd9Sstevel@tonic-gate options->log_facility = SYSLOG_FACILITY_NOT_SET; 927c478bd9Sstevel@tonic-gate options->log_level = SYSLOG_LEVEL_NOT_SET; 937c478bd9Sstevel@tonic-gate options->rhosts_authentication = -1; 947c478bd9Sstevel@tonic-gate options->rhosts_rsa_authentication = -1; 957c478bd9Sstevel@tonic-gate options->hostbased_authentication = -1; 967c478bd9Sstevel@tonic-gate options->hostbased_uses_name_from_packet_only = -1; 977c478bd9Sstevel@tonic-gate options->rsa_authentication = -1; 987c478bd9Sstevel@tonic-gate options->pubkey_authentication = -1; 997c478bd9Sstevel@tonic-gate #ifdef GSSAPI 1007c478bd9Sstevel@tonic-gate options->gss_authentication = -1; 1017c478bd9Sstevel@tonic-gate options->gss_keyex = -1; 1027c478bd9Sstevel@tonic-gate options->gss_store_creds = -1; 1037c478bd9Sstevel@tonic-gate options->gss_use_session_ccache = -1; 1047c478bd9Sstevel@tonic-gate options->gss_cleanup_creds = -1; 1057c478bd9Sstevel@tonic-gate #endif 1067c478bd9Sstevel@tonic-gate #if defined(KRB4) || defined(KRB5) 1077c478bd9Sstevel@tonic-gate options->kerberos_authentication = -1; 1087c478bd9Sstevel@tonic-gate options->kerberos_or_local_passwd = -1; 1097c478bd9Sstevel@tonic-gate options->kerberos_ticket_cleanup = -1; 1107c478bd9Sstevel@tonic-gate #endif 1117c478bd9Sstevel@tonic-gate #if defined(AFS) || defined(KRB5) 1127c478bd9Sstevel@tonic-gate options->kerberos_tgt_passing = -1; 1137c478bd9Sstevel@tonic-gate #endif 1147c478bd9Sstevel@tonic-gate #ifdef AFS 1157c478bd9Sstevel@tonic-gate options->afs_token_passing = -1; 1167c478bd9Sstevel@tonic-gate #endif 1177c478bd9Sstevel@tonic-gate options->password_authentication = -1; 1187c478bd9Sstevel@tonic-gate options->kbd_interactive_authentication = -1; 1197c478bd9Sstevel@tonic-gate options->challenge_response_authentication = -1; 1207c478bd9Sstevel@tonic-gate options->permit_empty_passwd = -1; 1217c478bd9Sstevel@tonic-gate options->permit_user_env = -1; 1227c478bd9Sstevel@tonic-gate options->compression = -1; 1237c478bd9Sstevel@tonic-gate options->allow_tcp_forwarding = -1; 1247c478bd9Sstevel@tonic-gate options->num_allow_users = 0; 1257c478bd9Sstevel@tonic-gate options->num_deny_users = 0; 1267c478bd9Sstevel@tonic-gate options->num_allow_groups = 0; 1277c478bd9Sstevel@tonic-gate options->num_deny_groups = 0; 1287c478bd9Sstevel@tonic-gate options->ciphers = NULL; 1297c478bd9Sstevel@tonic-gate options->macs = NULL; 1307c478bd9Sstevel@tonic-gate options->protocol = SSH_PROTO_UNKNOWN; 1317c478bd9Sstevel@tonic-gate options->gateway_ports = -1; 1327c478bd9Sstevel@tonic-gate options->num_subsystems = 0; 1337c478bd9Sstevel@tonic-gate options->max_startups_begin = -1; 1347c478bd9Sstevel@tonic-gate options->max_startups_rate = -1; 1357c478bd9Sstevel@tonic-gate options->max_startups = -1; 1367c478bd9Sstevel@tonic-gate options->banner = NULL; 1377c478bd9Sstevel@tonic-gate options->verify_reverse_mapping = -1; 1387c478bd9Sstevel@tonic-gate options->client_alive_interval = -1; 1397c478bd9Sstevel@tonic-gate options->client_alive_count_max = -1; 1407c478bd9Sstevel@tonic-gate options->authorized_keys_file = NULL; 1417c478bd9Sstevel@tonic-gate options->authorized_keys_file2 = NULL; 1427c478bd9Sstevel@tonic-gate 1437c478bd9Sstevel@tonic-gate options->max_auth_tries = -1; 1447c478bd9Sstevel@tonic-gate options->max_auth_tries_log = -1; 1457c478bd9Sstevel@tonic-gate 1467c478bd9Sstevel@tonic-gate options->max_init_auth_tries = -1; 1477c478bd9Sstevel@tonic-gate options->max_init_auth_tries_log = -1; 1487c478bd9Sstevel@tonic-gate 1497c478bd9Sstevel@tonic-gate options->lookup_client_hostnames = -1; 150cd7d5fafSJan Pechanec options->use_openssl_engine = -1; 1516f8d59d8SJan Pechanec options->chroot_directory = NULL; 1527c478bd9Sstevel@tonic-gate } 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate #ifdef HAVE_DEFOPEN 1557c478bd9Sstevel@tonic-gate /* 1567c478bd9Sstevel@tonic-gate * Reads /etc/default/login and defaults several ServerOptions: 1577c478bd9Sstevel@tonic-gate * 1587c478bd9Sstevel@tonic-gate * PermitRootLogin 1597c478bd9Sstevel@tonic-gate * PermitEmptyPasswords 1607c478bd9Sstevel@tonic-gate * LoginGraceTime 1617c478bd9Sstevel@tonic-gate * 1627c478bd9Sstevel@tonic-gate * CONSOLE=* -> PermitRootLogin=without-password 1637c478bd9Sstevel@tonic-gate * #CONSOLE=* -> PermitRootLogin=yes 1647c478bd9Sstevel@tonic-gate * 1657c478bd9Sstevel@tonic-gate * PASSREQ=YES -> PermitEmptyPasswords=no 1667c478bd9Sstevel@tonic-gate * PASSREQ=NO -> PermitEmptyPasswords=yes 1677c478bd9Sstevel@tonic-gate * #PASSREQ=* -> PermitEmptyPasswords=no 1687c478bd9Sstevel@tonic-gate * 1697c478bd9Sstevel@tonic-gate * TIMEOUT=<secs> -> LoginGraceTime=<secs> 1707c478bd9Sstevel@tonic-gate * #TIMEOUT=<secs> -> LoginGraceTime=300 1717c478bd9Sstevel@tonic-gate */ 1727c478bd9Sstevel@tonic-gate static 1737c478bd9Sstevel@tonic-gate void 1747c478bd9Sstevel@tonic-gate deflt_fill_default_server_options(ServerOptions *options) 1757c478bd9Sstevel@tonic-gate { 1767c478bd9Sstevel@tonic-gate int flags; 1777c478bd9Sstevel@tonic-gate char *ptr; 1787c478bd9Sstevel@tonic-gate 1797c478bd9Sstevel@tonic-gate if (defopen(_PATH_DEFAULT_LOGIN)) 1807c478bd9Sstevel@tonic-gate return; 1817c478bd9Sstevel@tonic-gate 1827c478bd9Sstevel@tonic-gate /* Ignore case */ 1837c478bd9Sstevel@tonic-gate flags = defcntl(DC_GETFLAGS, 0); 1847c478bd9Sstevel@tonic-gate TURNOFF(flags, DC_CASE); 1857c478bd9Sstevel@tonic-gate (void) defcntl(DC_SETFLAGS, flags); 1867c478bd9Sstevel@tonic-gate 1877c478bd9Sstevel@tonic-gate if (options->permit_root_login == PERMIT_NOT_SET && 1887c478bd9Sstevel@tonic-gate (ptr = defread("CONSOLE=")) != NULL) 1897c478bd9Sstevel@tonic-gate options->permit_root_login = PERMIT_NO_PASSWD; 1907c478bd9Sstevel@tonic-gate 1917c478bd9Sstevel@tonic-gate if (options->permit_empty_passwd == -1 && 1927c478bd9Sstevel@tonic-gate (ptr = defread("PASSREQ=")) != NULL) { 1937c478bd9Sstevel@tonic-gate if (strcasecmp("YES", ptr) == 0) 1947c478bd9Sstevel@tonic-gate options->permit_empty_passwd = 0; 1957c478bd9Sstevel@tonic-gate else if (strcasecmp("NO", ptr) == 0) 1967c478bd9Sstevel@tonic-gate options->permit_empty_passwd = 1; 1977c478bd9Sstevel@tonic-gate } 1987c478bd9Sstevel@tonic-gate 1997c478bd9Sstevel@tonic-gate if (options->max_init_auth_tries == -1 && 2007c478bd9Sstevel@tonic-gate (ptr = defread("RETRIES=")) != NULL) { 2017c478bd9Sstevel@tonic-gate options->max_init_auth_tries = atoi(ptr); 2027c478bd9Sstevel@tonic-gate } 2037c478bd9Sstevel@tonic-gate 2047c478bd9Sstevel@tonic-gate if (options->max_init_auth_tries_log == -1 && 2057c478bd9Sstevel@tonic-gate (ptr = defread("SYSLOG_FAILED_LOGINS=")) != NULL) { 2067c478bd9Sstevel@tonic-gate options->max_init_auth_tries_log = atoi(ptr); 2077c478bd9Sstevel@tonic-gate } 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate if (options->login_grace_time == -1) { 2107c478bd9Sstevel@tonic-gate if ((ptr = defread("TIMEOUT=")) != NULL) 2117c478bd9Sstevel@tonic-gate options->login_grace_time = (unsigned)atoi(ptr); 2127c478bd9Sstevel@tonic-gate else 2137c478bd9Sstevel@tonic-gate options->login_grace_time = 300; 2147c478bd9Sstevel@tonic-gate } 2157c478bd9Sstevel@tonic-gate 2167c478bd9Sstevel@tonic-gate (void) defopen((char *)NULL); 2177c478bd9Sstevel@tonic-gate } 2187c478bd9Sstevel@tonic-gate #endif /* HAVE_DEFOPEN */ 2197c478bd9Sstevel@tonic-gate 2207c478bd9Sstevel@tonic-gate void 2217c478bd9Sstevel@tonic-gate fill_default_server_options(ServerOptions *options) 2227c478bd9Sstevel@tonic-gate { 2237c478bd9Sstevel@tonic-gate 2247c478bd9Sstevel@tonic-gate #ifdef HAVE_DEFOPEN 2257c478bd9Sstevel@tonic-gate deflt_fill_default_server_options(options); 2267c478bd9Sstevel@tonic-gate #endif /* HAVE_DEFOPEN */ 2277c478bd9Sstevel@tonic-gate 2287c478bd9Sstevel@tonic-gate /* Portable-specific options */ 2297c478bd9Sstevel@tonic-gate if (options->pam_authentication_via_kbd_int == -1) 2307c478bd9Sstevel@tonic-gate options->pam_authentication_via_kbd_int = 0; 2317c478bd9Sstevel@tonic-gate 2327c478bd9Sstevel@tonic-gate /* Standard Options */ 2337c478bd9Sstevel@tonic-gate if (options->protocol == SSH_PROTO_UNKNOWN) 2347c478bd9Sstevel@tonic-gate options->protocol = SSH_PROTO_1|SSH_PROTO_2; 2357c478bd9Sstevel@tonic-gate if (options->num_host_key_files == 0) { 2367c478bd9Sstevel@tonic-gate /* fill default hostkeys for protocols */ 2377c478bd9Sstevel@tonic-gate if (options->protocol & SSH_PROTO_1) 2387c478bd9Sstevel@tonic-gate options->host_key_files[options->num_host_key_files++] = 2397c478bd9Sstevel@tonic-gate _PATH_HOST_KEY_FILE; 2407c478bd9Sstevel@tonic-gate #ifndef GSSAPI 2417c478bd9Sstevel@tonic-gate /* With GSS keyex we can run v2 w/ no host keys */ 2427c478bd9Sstevel@tonic-gate if (options->protocol & SSH_PROTO_2) { 2437c478bd9Sstevel@tonic-gate options->host_key_files[options->num_host_key_files++] = 2447c478bd9Sstevel@tonic-gate _PATH_HOST_RSA_KEY_FILE; 2457c478bd9Sstevel@tonic-gate options->host_key_files[options->num_host_key_files++] = 2467c478bd9Sstevel@tonic-gate _PATH_HOST_DSA_KEY_FILE; 2477c478bd9Sstevel@tonic-gate } 2487c478bd9Sstevel@tonic-gate #endif /* GSSAPI */ 2497c478bd9Sstevel@tonic-gate } 2507c478bd9Sstevel@tonic-gate if (options->num_ports == 0) 2517c478bd9Sstevel@tonic-gate options->ports[options->num_ports++] = SSH_DEFAULT_PORT; 2527c478bd9Sstevel@tonic-gate if (options->listen_addrs == NULL) 2537c478bd9Sstevel@tonic-gate add_listen_addr(options, NULL, 0); 2547c478bd9Sstevel@tonic-gate if (options->pid_file == NULL) 2557c478bd9Sstevel@tonic-gate options->pid_file = _PATH_SSH_DAEMON_PID_FILE; 2567c478bd9Sstevel@tonic-gate if (options->server_key_bits == -1) 2577c478bd9Sstevel@tonic-gate options->server_key_bits = 768; 2587c478bd9Sstevel@tonic-gate if (options->login_grace_time == -1) 2597c478bd9Sstevel@tonic-gate options->login_grace_time = 120; 2607c478bd9Sstevel@tonic-gate if (options->key_regeneration_time == -1) 2617c478bd9Sstevel@tonic-gate options->key_regeneration_time = 3600; 2627c478bd9Sstevel@tonic-gate if (options->permit_root_login == PERMIT_NOT_SET) 2637c478bd9Sstevel@tonic-gate options->permit_root_login = PERMIT_YES; 2647c478bd9Sstevel@tonic-gate if (options->ignore_rhosts == -1) 2657c478bd9Sstevel@tonic-gate options->ignore_rhosts = 1; 2667c478bd9Sstevel@tonic-gate if (options->ignore_user_known_hosts == -1) 2677c478bd9Sstevel@tonic-gate options->ignore_user_known_hosts = 0; 2687c478bd9Sstevel@tonic-gate if (options->print_motd == -1) 2697c478bd9Sstevel@tonic-gate options->print_motd = 1; 2707c478bd9Sstevel@tonic-gate if (options->print_lastlog == -1) 2717c478bd9Sstevel@tonic-gate options->print_lastlog = 1; 2727c478bd9Sstevel@tonic-gate if (options->x11_forwarding == -1) 2737c478bd9Sstevel@tonic-gate options->x11_forwarding = 1; 2747c478bd9Sstevel@tonic-gate if (options->x11_display_offset == -1) 2757c478bd9Sstevel@tonic-gate options->x11_display_offset = 10; 2767c478bd9Sstevel@tonic-gate if (options->x11_use_localhost == -1) 2777c478bd9Sstevel@tonic-gate options->x11_use_localhost = 1; 2787c478bd9Sstevel@tonic-gate if (options->xauth_location == NULL) 2797c478bd9Sstevel@tonic-gate options->xauth_location = _PATH_XAUTH; 2807c478bd9Sstevel@tonic-gate if (options->strict_modes == -1) 2817c478bd9Sstevel@tonic-gate options->strict_modes = 1; 2827c478bd9Sstevel@tonic-gate if (options->keepalives == -1) 2837c478bd9Sstevel@tonic-gate options->keepalives = 1; 2847c478bd9Sstevel@tonic-gate if (options->log_facility == SYSLOG_FACILITY_NOT_SET) 2857c478bd9Sstevel@tonic-gate options->log_facility = SYSLOG_FACILITY_AUTH; 2867c478bd9Sstevel@tonic-gate if (options->log_level == SYSLOG_LEVEL_NOT_SET) 2877c478bd9Sstevel@tonic-gate options->log_level = SYSLOG_LEVEL_INFO; 2887c478bd9Sstevel@tonic-gate if (options->rhosts_authentication == -1) 2897c478bd9Sstevel@tonic-gate options->rhosts_authentication = 0; 2907c478bd9Sstevel@tonic-gate if (options->rhosts_rsa_authentication == -1) 2917c478bd9Sstevel@tonic-gate options->rhosts_rsa_authentication = 0; 2927c478bd9Sstevel@tonic-gate if (options->hostbased_authentication == -1) 2937c478bd9Sstevel@tonic-gate options->hostbased_authentication = 0; 2947c478bd9Sstevel@tonic-gate if (options->hostbased_uses_name_from_packet_only == -1) 2957c478bd9Sstevel@tonic-gate options->hostbased_uses_name_from_packet_only = 0; 2967c478bd9Sstevel@tonic-gate if (options->rsa_authentication == -1) 2977c478bd9Sstevel@tonic-gate options->rsa_authentication = 1; 2987c478bd9Sstevel@tonic-gate if (options->pubkey_authentication == -1) 2997c478bd9Sstevel@tonic-gate options->pubkey_authentication = 1; 3007c478bd9Sstevel@tonic-gate #ifdef GSSAPI 3017c478bd9Sstevel@tonic-gate if (options->gss_authentication == -1) 3027c478bd9Sstevel@tonic-gate options->gss_authentication = 1; 3037c478bd9Sstevel@tonic-gate if (options->gss_keyex == -1) 3047c478bd9Sstevel@tonic-gate options->gss_keyex = 1; 3057c478bd9Sstevel@tonic-gate if (options->gss_store_creds == -1) 3067c478bd9Sstevel@tonic-gate options->gss_store_creds = 1; 3077c478bd9Sstevel@tonic-gate if (options->gss_use_session_ccache == -1) 3087c478bd9Sstevel@tonic-gate options->gss_use_session_ccache = 1; 3097c478bd9Sstevel@tonic-gate if (options->gss_cleanup_creds == -1) 3107c478bd9Sstevel@tonic-gate options->gss_cleanup_creds = 1; 3117c478bd9Sstevel@tonic-gate #endif 3127c478bd9Sstevel@tonic-gate #if defined(KRB4) || defined(KRB5) 3137c478bd9Sstevel@tonic-gate if (options->kerberos_authentication == -1) 3147c478bd9Sstevel@tonic-gate options->kerberos_authentication = 0; 3157c478bd9Sstevel@tonic-gate if (options->kerberos_or_local_passwd == -1) 3167c478bd9Sstevel@tonic-gate options->kerberos_or_local_passwd = 1; 3177c478bd9Sstevel@tonic-gate if (options->kerberos_ticket_cleanup == -1) 3187c478bd9Sstevel@tonic-gate options->kerberos_ticket_cleanup = 1; 3197c478bd9Sstevel@tonic-gate #endif 3207c478bd9Sstevel@tonic-gate #if defined(AFS) || defined(KRB5) 3217c478bd9Sstevel@tonic-gate if (options->kerberos_tgt_passing == -1) 3227c478bd9Sstevel@tonic-gate options->kerberos_tgt_passing = 0; 3237c478bd9Sstevel@tonic-gate #endif 3247c478bd9Sstevel@tonic-gate #ifdef AFS 3257c478bd9Sstevel@tonic-gate if (options->afs_token_passing == -1) 3267c478bd9Sstevel@tonic-gate options->afs_token_passing = 0; 3277c478bd9Sstevel@tonic-gate #endif 3287c478bd9Sstevel@tonic-gate if (options->password_authentication == -1) 3297c478bd9Sstevel@tonic-gate options->password_authentication = 1; 3307c478bd9Sstevel@tonic-gate if (options->kbd_interactive_authentication == -1) 3317c478bd9Sstevel@tonic-gate options->kbd_interactive_authentication = 0; 3327c478bd9Sstevel@tonic-gate if (options->challenge_response_authentication == -1) 3337c478bd9Sstevel@tonic-gate options->challenge_response_authentication = 1; 3347c478bd9Sstevel@tonic-gate if (options->permit_empty_passwd == -1) 3357c478bd9Sstevel@tonic-gate options->permit_empty_passwd = 0; 3367c478bd9Sstevel@tonic-gate if (options->permit_user_env == -1) 3377c478bd9Sstevel@tonic-gate options->permit_user_env = 0; 3387c478bd9Sstevel@tonic-gate if (options->compression == -1) 3397c478bd9Sstevel@tonic-gate options->compression = 1; 3407c478bd9Sstevel@tonic-gate if (options->allow_tcp_forwarding == -1) 3417c478bd9Sstevel@tonic-gate options->allow_tcp_forwarding = 1; 3427c478bd9Sstevel@tonic-gate if (options->gateway_ports == -1) 3437c478bd9Sstevel@tonic-gate options->gateway_ports = 0; 3447c478bd9Sstevel@tonic-gate if (options->max_startups == -1) 3457c478bd9Sstevel@tonic-gate options->max_startups = 10; 3467c478bd9Sstevel@tonic-gate if (options->max_startups_rate == -1) 3477c478bd9Sstevel@tonic-gate options->max_startups_rate = 100; /* 100% */ 3487c478bd9Sstevel@tonic-gate if (options->max_startups_begin == -1) 3497c478bd9Sstevel@tonic-gate options->max_startups_begin = options->max_startups; 3507c478bd9Sstevel@tonic-gate if (options->verify_reverse_mapping == -1) 3517c478bd9Sstevel@tonic-gate options->verify_reverse_mapping = 0; 3527c478bd9Sstevel@tonic-gate if (options->client_alive_interval == -1) 3537c478bd9Sstevel@tonic-gate options->client_alive_interval = 0; 3547c478bd9Sstevel@tonic-gate if (options->client_alive_count_max == -1) 3557c478bd9Sstevel@tonic-gate options->client_alive_count_max = 3; 3567c478bd9Sstevel@tonic-gate if (options->authorized_keys_file2 == NULL) { 3577c478bd9Sstevel@tonic-gate /* authorized_keys_file2 falls back to authorized_keys_file */ 3587c478bd9Sstevel@tonic-gate if (options->authorized_keys_file != NULL) 3597c478bd9Sstevel@tonic-gate options->authorized_keys_file2 = options->authorized_keys_file; 3607c478bd9Sstevel@tonic-gate else 3617c478bd9Sstevel@tonic-gate options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2; 3627c478bd9Sstevel@tonic-gate } 3637c478bd9Sstevel@tonic-gate if (options->authorized_keys_file == NULL) 3647c478bd9Sstevel@tonic-gate options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS; 3657c478bd9Sstevel@tonic-gate 3667c478bd9Sstevel@tonic-gate if (options->max_auth_tries == -1) 3677c478bd9Sstevel@tonic-gate options->max_auth_tries = AUTH_FAIL_MAX; 3687c478bd9Sstevel@tonic-gate if (options->max_auth_tries_log == -1) 3697c478bd9Sstevel@tonic-gate options->max_auth_tries_log = options->max_auth_tries / 2; 3707c478bd9Sstevel@tonic-gate 3717c478bd9Sstevel@tonic-gate if (options->max_init_auth_tries == -1) 3727c478bd9Sstevel@tonic-gate options->max_init_auth_tries = AUTH_FAIL_MAX; 3737c478bd9Sstevel@tonic-gate if (options->max_init_auth_tries_log == -1) 3747c478bd9Sstevel@tonic-gate options->max_init_auth_tries_log = options->max_init_auth_tries / 2; 3757c478bd9Sstevel@tonic-gate 3767c478bd9Sstevel@tonic-gate if (options->lookup_client_hostnames == -1) 3777c478bd9Sstevel@tonic-gate options->lookup_client_hostnames = 1; 378cd7d5fafSJan Pechanec if (options->use_openssl_engine == -1) 379cd7d5fafSJan Pechanec options->use_openssl_engine = 1; 3807c478bd9Sstevel@tonic-gate } 3817c478bd9Sstevel@tonic-gate 3827c478bd9Sstevel@tonic-gate /* Keyword tokens. */ 3837c478bd9Sstevel@tonic-gate typedef enum { 3847c478bd9Sstevel@tonic-gate sBadOption, /* == unknown option */ 3857c478bd9Sstevel@tonic-gate /* Portable-specific options */ 3867c478bd9Sstevel@tonic-gate sPAMAuthenticationViaKbdInt, 3877c478bd9Sstevel@tonic-gate /* Standard Options */ 3887c478bd9Sstevel@tonic-gate sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime, 3897c478bd9Sstevel@tonic-gate sPermitRootLogin, sLogFacility, sLogLevel, 3907c478bd9Sstevel@tonic-gate sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication, 3917c478bd9Sstevel@tonic-gate #ifdef GSSAPI 3927c478bd9Sstevel@tonic-gate sGssAuthentication, sGssKeyEx, sGssStoreDelegCreds, 3937c478bd9Sstevel@tonic-gate sGssUseSessionCredCache, sGssCleanupCreds, 3947c478bd9Sstevel@tonic-gate #endif /* GSSAPI */ 3957c478bd9Sstevel@tonic-gate #if defined(KRB4) || defined(KRB5) 3967c478bd9Sstevel@tonic-gate sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, 3977c478bd9Sstevel@tonic-gate #endif 3987c478bd9Sstevel@tonic-gate #if defined(AFS) || defined(KRB5) 3997c478bd9Sstevel@tonic-gate sKerberosTgtPassing, 4007c478bd9Sstevel@tonic-gate #endif 4017c478bd9Sstevel@tonic-gate #ifdef AFS 4027c478bd9Sstevel@tonic-gate sAFSTokenPassing, 4037c478bd9Sstevel@tonic-gate #endif 4047c478bd9Sstevel@tonic-gate sChallengeResponseAuthentication, 4057c478bd9Sstevel@tonic-gate sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress, 4067c478bd9Sstevel@tonic-gate sPrintMotd, sPrintLastLog, sIgnoreRhosts, 4077c478bd9Sstevel@tonic-gate sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, 4087c478bd9Sstevel@tonic-gate sStrictModes, sEmptyPasswd, sKeepAlives, 4097c478bd9Sstevel@tonic-gate sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression, 4107c478bd9Sstevel@tonic-gate sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, 4117c478bd9Sstevel@tonic-gate sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, 4127c478bd9Sstevel@tonic-gate sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups, 4137c478bd9Sstevel@tonic-gate sBanner, sVerifyReverseMapping, sHostbasedAuthentication, 4147c478bd9Sstevel@tonic-gate sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, 4157c478bd9Sstevel@tonic-gate sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, 4167c478bd9Sstevel@tonic-gate sMaxAuthTries, sMaxAuthTriesLog, sUsePrivilegeSeparation, 4176f8d59d8SJan Pechanec sLookupClientHostnames, sUseOpenSSLEngine, sChrootDirectory, 4187c478bd9Sstevel@tonic-gate sDeprecated 4197c478bd9Sstevel@tonic-gate } ServerOpCodes; 4207c478bd9Sstevel@tonic-gate 4217c478bd9Sstevel@tonic-gate /* Textual representation of the tokens. */ 4227c478bd9Sstevel@tonic-gate static struct { 4237c478bd9Sstevel@tonic-gate const char *name; 4247c478bd9Sstevel@tonic-gate ServerOpCodes opcode; 4257c478bd9Sstevel@tonic-gate } keywords[] = { 4267c478bd9Sstevel@tonic-gate /* Portable-specific options */ 4277c478bd9Sstevel@tonic-gate { "PAMAuthenticationViaKbdInt", sPAMAuthenticationViaKbdInt }, 4287c478bd9Sstevel@tonic-gate /* Standard Options */ 4297c478bd9Sstevel@tonic-gate { "port", sPort }, 4307c478bd9Sstevel@tonic-gate { "hostkey", sHostKeyFile }, 4317c478bd9Sstevel@tonic-gate { "hostdsakey", sHostKeyFile }, /* alias */ 4327c478bd9Sstevel@tonic-gate { "pidfile", sPidFile }, 4337c478bd9Sstevel@tonic-gate { "serverkeybits", sServerKeyBits }, 4347c478bd9Sstevel@tonic-gate { "logingracetime", sLoginGraceTime }, 4357c478bd9Sstevel@tonic-gate { "keyregenerationinterval", sKeyRegenerationTime }, 4367c478bd9Sstevel@tonic-gate { "permitrootlogin", sPermitRootLogin }, 4377c478bd9Sstevel@tonic-gate { "syslogfacility", sLogFacility }, 4387c478bd9Sstevel@tonic-gate { "loglevel", sLogLevel }, 4397c478bd9Sstevel@tonic-gate { "rhostsauthentication", sRhostsAuthentication }, 4407c478bd9Sstevel@tonic-gate { "rhostsrsaauthentication", sRhostsRSAAuthentication }, 4417c478bd9Sstevel@tonic-gate { "hostbasedauthentication", sHostbasedAuthentication }, 4427c478bd9Sstevel@tonic-gate { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly }, 4437c478bd9Sstevel@tonic-gate { "rsaauthentication", sRSAAuthentication }, 4447c478bd9Sstevel@tonic-gate { "pubkeyauthentication", sPubkeyAuthentication }, 4457c478bd9Sstevel@tonic-gate { "dsaauthentication", sPubkeyAuthentication }, /* alias */ 4467c478bd9Sstevel@tonic-gate #ifdef GSSAPI 4477c478bd9Sstevel@tonic-gate { "gssapiauthentication", sGssAuthentication }, 4487c478bd9Sstevel@tonic-gate { "gssapikeyexchange", sGssKeyEx }, 4497c478bd9Sstevel@tonic-gate { "gssapistoredelegatedcredentials", sGssStoreDelegCreds }, 4507c478bd9Sstevel@tonic-gate { "gssauthentication", sGssAuthentication }, /* alias */ 4517c478bd9Sstevel@tonic-gate { "gsskeyex", sGssKeyEx }, /* alias */ 4527c478bd9Sstevel@tonic-gate { "gssstoredelegcreds", sGssStoreDelegCreds }, /* alias */ 4537c478bd9Sstevel@tonic-gate #ifndef SUNW_GSSAPI 4547c478bd9Sstevel@tonic-gate { "gssusesessionccache", sGssUseSessionCredCache }, 4557c478bd9Sstevel@tonic-gate { "gssusesessioncredcache", sGssUseSessionCredCache }, 4567c478bd9Sstevel@tonic-gate { "gsscleanupcreds", sGssCleanupCreds }, 4577c478bd9Sstevel@tonic-gate #endif /* SUNW_GSSAPI */ 4587c478bd9Sstevel@tonic-gate #endif 4597c478bd9Sstevel@tonic-gate #if defined(KRB4) || defined(KRB5) 4607c478bd9Sstevel@tonic-gate { "kerberosauthentication", sKerberosAuthentication }, 4617c478bd9Sstevel@tonic-gate { "kerberosorlocalpasswd", sKerberosOrLocalPasswd }, 4627c478bd9Sstevel@tonic-gate { "kerberosticketcleanup", sKerberosTicketCleanup }, 4637c478bd9Sstevel@tonic-gate #endif 4647c478bd9Sstevel@tonic-gate #if defined(AFS) || defined(KRB5) 4657c478bd9Sstevel@tonic-gate { "kerberostgtpassing", sKerberosTgtPassing }, 4667c478bd9Sstevel@tonic-gate #endif 4677c478bd9Sstevel@tonic-gate #ifdef AFS 4687c478bd9Sstevel@tonic-gate { "afstokenpassing", sAFSTokenPassing }, 4697c478bd9Sstevel@tonic-gate #endif 4707c478bd9Sstevel@tonic-gate { "passwordauthentication", sPasswordAuthentication }, 4717c478bd9Sstevel@tonic-gate { "kbdinteractiveauthentication", sKbdInteractiveAuthentication }, 4727c478bd9Sstevel@tonic-gate { "challengeresponseauthentication", sChallengeResponseAuthentication }, 4737c478bd9Sstevel@tonic-gate { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */ 4747c478bd9Sstevel@tonic-gate { "checkmail", sDeprecated }, 4757c478bd9Sstevel@tonic-gate { "listenaddress", sListenAddress }, 4767c478bd9Sstevel@tonic-gate { "printmotd", sPrintMotd }, 4777c478bd9Sstevel@tonic-gate { "printlastlog", sPrintLastLog }, 4787c478bd9Sstevel@tonic-gate { "ignorerhosts", sIgnoreRhosts }, 4797c478bd9Sstevel@tonic-gate { "ignoreuserknownhosts", sIgnoreUserKnownHosts }, 4807c478bd9Sstevel@tonic-gate { "x11forwarding", sX11Forwarding }, 4817c478bd9Sstevel@tonic-gate { "x11displayoffset", sX11DisplayOffset }, 4827c478bd9Sstevel@tonic-gate { "x11uselocalhost", sX11UseLocalhost }, 4837c478bd9Sstevel@tonic-gate { "xauthlocation", sXAuthLocation }, 4847c478bd9Sstevel@tonic-gate { "strictmodes", sStrictModes }, 4857c478bd9Sstevel@tonic-gate { "permitemptypasswords", sEmptyPasswd }, 4867c478bd9Sstevel@tonic-gate { "permituserenvironment", sPermitUserEnvironment }, 4877c478bd9Sstevel@tonic-gate { "uselogin", sUseLogin }, 4887c478bd9Sstevel@tonic-gate { "compression", sCompression }, 4897c478bd9Sstevel@tonic-gate { "keepalive", sKeepAlives }, 4907c478bd9Sstevel@tonic-gate { "allowtcpforwarding", sAllowTcpForwarding }, 4917c478bd9Sstevel@tonic-gate { "allowusers", sAllowUsers }, 4927c478bd9Sstevel@tonic-gate { "denyusers", sDenyUsers }, 4937c478bd9Sstevel@tonic-gate { "allowgroups", sAllowGroups }, 4947c478bd9Sstevel@tonic-gate { "denygroups", sDenyGroups }, 4957c478bd9Sstevel@tonic-gate { "ciphers", sCiphers }, 4967c478bd9Sstevel@tonic-gate { "macs", sMacs }, 4977c478bd9Sstevel@tonic-gate { "protocol", sProtocol }, 4987c478bd9Sstevel@tonic-gate { "gatewayports", sGatewayPorts }, 4997c478bd9Sstevel@tonic-gate { "subsystem", sSubsystem }, 5007c478bd9Sstevel@tonic-gate { "maxstartups", sMaxStartups }, 5017c478bd9Sstevel@tonic-gate { "banner", sBanner }, 5027c478bd9Sstevel@tonic-gate { "verifyreversemapping", sVerifyReverseMapping }, 5037c478bd9Sstevel@tonic-gate { "reversemappingcheck", sVerifyReverseMapping }, 5047c478bd9Sstevel@tonic-gate { "clientaliveinterval", sClientAliveInterval }, 5057c478bd9Sstevel@tonic-gate { "clientalivecountmax", sClientAliveCountMax }, 5067c478bd9Sstevel@tonic-gate { "authorizedkeysfile", sAuthorizedKeysFile }, 5077c478bd9Sstevel@tonic-gate { "authorizedkeysfile2", sAuthorizedKeysFile2 }, 5087c478bd9Sstevel@tonic-gate { "maxauthtries", sMaxAuthTries }, 5097c478bd9Sstevel@tonic-gate { "maxauthtrieslog", sMaxAuthTriesLog }, 5107c478bd9Sstevel@tonic-gate { "useprivilegeseparation", sUsePrivilegeSeparation}, 5117c478bd9Sstevel@tonic-gate { "lookupclienthostnames", sLookupClientHostnames}, 512cd7d5fafSJan Pechanec { "useopensslengine", sUseOpenSSLEngine}, 5136f8d59d8SJan Pechanec { "chrootdirectory", sChrootDirectory}, 5147c478bd9Sstevel@tonic-gate { NULL, sBadOption } 5157c478bd9Sstevel@tonic-gate }; 5167c478bd9Sstevel@tonic-gate 5177c478bd9Sstevel@tonic-gate /* 5187c478bd9Sstevel@tonic-gate * Returns the number of the token pointed to by cp or sBadOption. 5197c478bd9Sstevel@tonic-gate */ 5207c478bd9Sstevel@tonic-gate 5217c478bd9Sstevel@tonic-gate static ServerOpCodes 5227c478bd9Sstevel@tonic-gate parse_token(const char *cp, const char *filename, 5237c478bd9Sstevel@tonic-gate int linenum) 5247c478bd9Sstevel@tonic-gate { 5257c478bd9Sstevel@tonic-gate u_int i; 5267c478bd9Sstevel@tonic-gate 5277c478bd9Sstevel@tonic-gate for (i = 0; keywords[i].name; i++) 5287c478bd9Sstevel@tonic-gate if (strcasecmp(cp, keywords[i].name) == 0) 5297c478bd9Sstevel@tonic-gate return keywords[i].opcode; 5307c478bd9Sstevel@tonic-gate 5317c478bd9Sstevel@tonic-gate error("%s: line %d: Bad configuration option: %s", 5327c478bd9Sstevel@tonic-gate filename, linenum, cp); 5337c478bd9Sstevel@tonic-gate return sBadOption; 5347c478bd9Sstevel@tonic-gate } 5357c478bd9Sstevel@tonic-gate 5367c478bd9Sstevel@tonic-gate static void 5377c478bd9Sstevel@tonic-gate add_listen_addr(ServerOptions *options, char *addr, u_short port) 5387c478bd9Sstevel@tonic-gate { 5397c478bd9Sstevel@tonic-gate int i; 5407c478bd9Sstevel@tonic-gate 5417c478bd9Sstevel@tonic-gate if (options->num_ports == 0) 5427c478bd9Sstevel@tonic-gate options->ports[options->num_ports++] = SSH_DEFAULT_PORT; 5437c478bd9Sstevel@tonic-gate if (port == 0) 5447c478bd9Sstevel@tonic-gate for (i = 0; i < options->num_ports; i++) 5457c478bd9Sstevel@tonic-gate add_one_listen_addr(options, addr, options->ports[i]); 5467c478bd9Sstevel@tonic-gate else 5477c478bd9Sstevel@tonic-gate add_one_listen_addr(options, addr, port); 5487c478bd9Sstevel@tonic-gate } 5497c478bd9Sstevel@tonic-gate 5507c478bd9Sstevel@tonic-gate static void 5517c478bd9Sstevel@tonic-gate add_one_listen_addr(ServerOptions *options, char *addr, u_short port) 5527c478bd9Sstevel@tonic-gate { 5537c478bd9Sstevel@tonic-gate struct addrinfo hints, *ai, *aitop; 5547c478bd9Sstevel@tonic-gate char strport[NI_MAXSERV]; 5557c478bd9Sstevel@tonic-gate int gaierr; 5567c478bd9Sstevel@tonic-gate 5577c478bd9Sstevel@tonic-gate (void) memset(&hints, 0, sizeof(hints)); 5587c478bd9Sstevel@tonic-gate hints.ai_family = IPv4or6; 5597c478bd9Sstevel@tonic-gate hints.ai_socktype = SOCK_STREAM; 5607c478bd9Sstevel@tonic-gate hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0; 5617c478bd9Sstevel@tonic-gate (void) snprintf(strport, sizeof strport, "%u", port); 5627c478bd9Sstevel@tonic-gate if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0) 5637c478bd9Sstevel@tonic-gate fatal("bad addr or host: %s (%s)", 5647c478bd9Sstevel@tonic-gate addr ? addr : "<NULL>", 5657c478bd9Sstevel@tonic-gate gai_strerror(gaierr)); 5667c478bd9Sstevel@tonic-gate for (ai = aitop; ai->ai_next; ai = ai->ai_next) 5677c478bd9Sstevel@tonic-gate ; 5687c478bd9Sstevel@tonic-gate ai->ai_next = options->listen_addrs; 5697c478bd9Sstevel@tonic-gate options->listen_addrs = aitop; 5707c478bd9Sstevel@tonic-gate } 5717c478bd9Sstevel@tonic-gate 5727c478bd9Sstevel@tonic-gate int 5737c478bd9Sstevel@tonic-gate process_server_config_line(ServerOptions *options, char *line, 5747c478bd9Sstevel@tonic-gate const char *filename, int linenum) 5757c478bd9Sstevel@tonic-gate { 5767c478bd9Sstevel@tonic-gate char *cp, **charptr, *arg, *p; 5777c478bd9Sstevel@tonic-gate int *intptr, value, i, n; 5787c478bd9Sstevel@tonic-gate ServerOpCodes opcode; 5796f8d59d8SJan Pechanec size_t len; 5807c478bd9Sstevel@tonic-gate 5817c478bd9Sstevel@tonic-gate cp = line; 5827c478bd9Sstevel@tonic-gate arg = strdelim(&cp); 5837c478bd9Sstevel@tonic-gate /* Ignore leading whitespace */ 5847c478bd9Sstevel@tonic-gate if (*arg == '\0') 5857c478bd9Sstevel@tonic-gate arg = strdelim(&cp); 5867c478bd9Sstevel@tonic-gate if (!arg || !*arg || *arg == '#') 5877c478bd9Sstevel@tonic-gate return 0; 5887c478bd9Sstevel@tonic-gate intptr = NULL; 5897c478bd9Sstevel@tonic-gate charptr = NULL; 5907c478bd9Sstevel@tonic-gate opcode = parse_token(arg, filename, linenum); 5917c478bd9Sstevel@tonic-gate switch (opcode) { 5927c478bd9Sstevel@tonic-gate /* Portable-specific options */ 5937c478bd9Sstevel@tonic-gate case sPAMAuthenticationViaKbdInt: 5947c478bd9Sstevel@tonic-gate intptr = &options->pam_authentication_via_kbd_int; 5957c478bd9Sstevel@tonic-gate goto parse_flag; 5967c478bd9Sstevel@tonic-gate 5977c478bd9Sstevel@tonic-gate /* Standard Options */ 5987c478bd9Sstevel@tonic-gate case sBadOption: 5997c478bd9Sstevel@tonic-gate return -1; 6007c478bd9Sstevel@tonic-gate case sPort: 6017c478bd9Sstevel@tonic-gate /* ignore ports from configfile if cmdline specifies ports */ 6027c478bd9Sstevel@tonic-gate if (options->ports_from_cmdline) 6037c478bd9Sstevel@tonic-gate return 0; 6047c478bd9Sstevel@tonic-gate if (options->listen_addrs != NULL) 6057c478bd9Sstevel@tonic-gate fatal("%s line %d: ports must be specified before " 6067c478bd9Sstevel@tonic-gate "ListenAddress.", filename, linenum); 6077c478bd9Sstevel@tonic-gate if (options->num_ports >= MAX_PORTS) 6087c478bd9Sstevel@tonic-gate fatal("%s line %d: too many ports.", 6097c478bd9Sstevel@tonic-gate filename, linenum); 6107c478bd9Sstevel@tonic-gate arg = strdelim(&cp); 6117c478bd9Sstevel@tonic-gate if (!arg || *arg == '\0') 6127c478bd9Sstevel@tonic-gate fatal("%s line %d: missing port number.", 6137c478bd9Sstevel@tonic-gate filename, linenum); 6147c478bd9Sstevel@tonic-gate options->ports[options->num_ports++] = a2port(arg); 6157c478bd9Sstevel@tonic-gate if (options->ports[options->num_ports-1] == 0) 6167c478bd9Sstevel@tonic-gate fatal("%s line %d: Badly formatted port number.", 6177c478bd9Sstevel@tonic-gate filename, linenum); 6187c478bd9Sstevel@tonic-gate break; 6197c478bd9Sstevel@tonic-gate 6207c478bd9Sstevel@tonic-gate case sServerKeyBits: 6217c478bd9Sstevel@tonic-gate intptr = &options->server_key_bits; 6227c478bd9Sstevel@tonic-gate parse_int: 6237c478bd9Sstevel@tonic-gate arg = strdelim(&cp); 6247c478bd9Sstevel@tonic-gate if (!arg || *arg == '\0') 6257c478bd9Sstevel@tonic-gate fatal("%s line %d: missing integer value.", 6267c478bd9Sstevel@tonic-gate filename, linenum); 6277c478bd9Sstevel@tonic-gate value = atoi(arg); 6287c478bd9Sstevel@tonic-gate if (*intptr == -1) 6297c478bd9Sstevel@tonic-gate *intptr = value; 6307c478bd9Sstevel@tonic-gate break; 6317c478bd9Sstevel@tonic-gate 6327c478bd9Sstevel@tonic-gate case sLoginGraceTime: 6337c478bd9Sstevel@tonic-gate intptr = &options->login_grace_time; 6347c478bd9Sstevel@tonic-gate parse_time: 6357c478bd9Sstevel@tonic-gate arg = strdelim(&cp); 6367c478bd9Sstevel@tonic-gate if (!arg || *arg == '\0') 6377c478bd9Sstevel@tonic-gate fatal("%s line %d: missing time value.", 6387c478bd9Sstevel@tonic-gate filename, linenum); 6397c478bd9Sstevel@tonic-gate if ((value = convtime(arg)) == -1) 6407c478bd9Sstevel@tonic-gate fatal("%s line %d: invalid time value.", 6417c478bd9Sstevel@tonic-gate filename, linenum); 6427c478bd9Sstevel@tonic-gate if (*intptr == -1) 6437c478bd9Sstevel@tonic-gate *intptr = value; 6447c478bd9Sstevel@tonic-gate break; 6457c478bd9Sstevel@tonic-gate 6467c478bd9Sstevel@tonic-gate case sKeyRegenerationTime: 6477c478bd9Sstevel@tonic-gate intptr = &options->key_regeneration_time; 6487c478bd9Sstevel@tonic-gate goto parse_time; 6497c478bd9Sstevel@tonic-gate 6507c478bd9Sstevel@tonic-gate case sListenAddress: 6517c478bd9Sstevel@tonic-gate arg = strdelim(&cp); 6527c478bd9Sstevel@tonic-gate if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0) 6537c478bd9Sstevel@tonic-gate fatal("%s line %d: missing inet addr.", 6547c478bd9Sstevel@tonic-gate filename, linenum); 6557c478bd9Sstevel@tonic-gate if (*arg == '[') { 6567c478bd9Sstevel@tonic-gate if ((p = strchr(arg, ']')) == NULL) 6577c478bd9Sstevel@tonic-gate fatal("%s line %d: bad ipv6 inet addr usage.", 6587c478bd9Sstevel@tonic-gate filename, linenum); 6597c478bd9Sstevel@tonic-gate arg++; 6607c478bd9Sstevel@tonic-gate (void) memmove(p, p+1, strlen(p+1)+1); 6617c478bd9Sstevel@tonic-gate } else if (((p = strchr(arg, ':')) == NULL) || 6627c478bd9Sstevel@tonic-gate (strchr(p+1, ':') != NULL)) { 6637c478bd9Sstevel@tonic-gate add_listen_addr(options, arg, 0); 6647c478bd9Sstevel@tonic-gate break; 6657c478bd9Sstevel@tonic-gate } 6667c478bd9Sstevel@tonic-gate if (*p == ':') { 6677c478bd9Sstevel@tonic-gate u_short port; 6687c478bd9Sstevel@tonic-gate 6697c478bd9Sstevel@tonic-gate p++; 6707c478bd9Sstevel@tonic-gate if (*p == '\0') 6717c478bd9Sstevel@tonic-gate fatal("%s line %d: bad inet addr:port usage.", 6727c478bd9Sstevel@tonic-gate filename, linenum); 6737c478bd9Sstevel@tonic-gate else { 6747c478bd9Sstevel@tonic-gate *(p-1) = '\0'; 6757c478bd9Sstevel@tonic-gate if ((port = a2port(p)) == 0) 6767c478bd9Sstevel@tonic-gate fatal("%s line %d: bad port number.", 6777c478bd9Sstevel@tonic-gate filename, linenum); 6787c478bd9Sstevel@tonic-gate add_listen_addr(options, arg, port); 6797c478bd9Sstevel@tonic-gate } 6807c478bd9Sstevel@tonic-gate } else if (*p == '\0') 6817c478bd9Sstevel@tonic-gate add_listen_addr(options, arg, 0); 6827c478bd9Sstevel@tonic-gate else 6837c478bd9Sstevel@tonic-gate fatal("%s line %d: bad inet addr usage.", 6847c478bd9Sstevel@tonic-gate filename, linenum); 6857c478bd9Sstevel@tonic-gate break; 6867c478bd9Sstevel@tonic-gate 6877c478bd9Sstevel@tonic-gate case sHostKeyFile: 6887c478bd9Sstevel@tonic-gate intptr = &options->num_host_key_files; 6897c478bd9Sstevel@tonic-gate if (*intptr >= MAX_HOSTKEYS) 6907c478bd9Sstevel@tonic-gate fatal("%s line %d: too many host keys specified (max %d).", 6917c478bd9Sstevel@tonic-gate filename, linenum, MAX_HOSTKEYS); 6927c478bd9Sstevel@tonic-gate charptr = &options->host_key_files[*intptr]; 6937c478bd9Sstevel@tonic-gate parse_filename: 6947c478bd9Sstevel@tonic-gate arg = strdelim(&cp); 6957c478bd9Sstevel@tonic-gate if (!arg || *arg == '\0') 6967c478bd9Sstevel@tonic-gate fatal("%s line %d: missing file name.", 6977c478bd9Sstevel@tonic-gate filename, linenum); 6987c478bd9Sstevel@tonic-gate if (*charptr == NULL) { 6997c478bd9Sstevel@tonic-gate *charptr = tilde_expand_filename(arg, getuid()); 7007c478bd9Sstevel@tonic-gate /* increase optional counter */ 7017c478bd9Sstevel@tonic-gate if (intptr != NULL) 7027c478bd9Sstevel@tonic-gate *intptr = *intptr + 1; 7037c478bd9Sstevel@tonic-gate } 7047c478bd9Sstevel@tonic-gate break; 7057c478bd9Sstevel@tonic-gate 7067c478bd9Sstevel@tonic-gate case sPidFile: 7077c478bd9Sstevel@tonic-gate charptr = &options->pid_file; 7087c478bd9Sstevel@tonic-gate goto parse_filename; 7097c478bd9Sstevel@tonic-gate 7107c478bd9Sstevel@tonic-gate case sPermitRootLogin: 7117c478bd9Sstevel@tonic-gate intptr = &options->permit_root_login; 7127c478bd9Sstevel@tonic-gate arg = strdelim(&cp); 7137c478bd9Sstevel@tonic-gate if (!arg || *arg == '\0') 7147c478bd9Sstevel@tonic-gate fatal("%s line %d: missing yes/" 7157c478bd9Sstevel@tonic-gate "without-password/forced-commands-only/no " 7167c478bd9Sstevel@tonic-gate "argument.", filename, linenum); 7177c478bd9Sstevel@tonic-gate value = 0; /* silence compiler */ 7187c478bd9Sstevel@tonic-gate if (strcmp(arg, "without-password") == 0) 7197c478bd9Sstevel@tonic-gate value = PERMIT_NO_PASSWD; 7207c478bd9Sstevel@tonic-gate else if (strcmp(arg, "forced-commands-only") == 0) 7217c478bd9Sstevel@tonic-gate value = PERMIT_FORCED_ONLY; 7227c478bd9Sstevel@tonic-gate else if (strcmp(arg, "yes") == 0) 7237c478bd9Sstevel@tonic-gate value = PERMIT_YES; 7247c478bd9Sstevel@tonic-gate else if (strcmp(arg, "no") == 0) 7257c478bd9Sstevel@tonic-gate value = PERMIT_NO; 7267c478bd9Sstevel@tonic-gate else 7277c478bd9Sstevel@tonic-gate fatal("%s line %d: Bad yes/" 7287c478bd9Sstevel@tonic-gate "without-password/forced-commands-only/no " 7297c478bd9Sstevel@tonic-gate "argument: %s", filename, linenum, arg); 7307c478bd9Sstevel@tonic-gate if (*intptr == -1) 7317c478bd9Sstevel@tonic-gate *intptr = value; 7327c478bd9Sstevel@tonic-gate break; 7337c478bd9Sstevel@tonic-gate 7347c478bd9Sstevel@tonic-gate case sIgnoreRhosts: 7357c478bd9Sstevel@tonic-gate intptr = &options->ignore_rhosts; 7367c478bd9Sstevel@tonic-gate parse_flag: 7377c478bd9Sstevel@tonic-gate arg = strdelim(&cp); 7387c478bd9Sstevel@tonic-gate if (!arg || *arg == '\0') 7397c478bd9Sstevel@tonic-gate fatal("%s line %d: missing yes/no argument.", 7407c478bd9Sstevel@tonic-gate filename, linenum); 7417c478bd9Sstevel@tonic-gate value = 0; /* silence compiler */ 7427c478bd9Sstevel@tonic-gate if (strcmp(arg, "yes") == 0) 7437c478bd9Sstevel@tonic-gate value = 1; 7447c478bd9Sstevel@tonic-gate else if (strcmp(arg, "no") == 0) 7457c478bd9Sstevel@tonic-gate value = 0; 7467c478bd9Sstevel@tonic-gate else 7477c478bd9Sstevel@tonic-gate fatal("%s line %d: Bad yes/no argument: %s", 7487c478bd9Sstevel@tonic-gate filename, linenum, arg); 7497c478bd9Sstevel@tonic-gate if (*intptr == -1) 7507c478bd9Sstevel@tonic-gate *intptr = value; 7517c478bd9Sstevel@tonic-gate break; 7527c478bd9Sstevel@tonic-gate 7537c478bd9Sstevel@tonic-gate case sIgnoreUserKnownHosts: 7547c478bd9Sstevel@tonic-gate intptr = &options->ignore_user_known_hosts; 7557c478bd9Sstevel@tonic-gate goto parse_flag; 7567c478bd9Sstevel@tonic-gate 7577c478bd9Sstevel@tonic-gate case sRhostsAuthentication: 7587c478bd9Sstevel@tonic-gate intptr = &options->rhosts_authentication; 7597c478bd9Sstevel@tonic-gate goto parse_flag; 7607c478bd9Sstevel@tonic-gate 7617c478bd9Sstevel@tonic-gate case sRhostsRSAAuthentication: 7627c478bd9Sstevel@tonic-gate intptr = &options->rhosts_rsa_authentication; 7637c478bd9Sstevel@tonic-gate goto parse_flag; 7647c478bd9Sstevel@tonic-gate 7657c478bd9Sstevel@tonic-gate case sHostbasedAuthentication: 7667c478bd9Sstevel@tonic-gate intptr = &options->hostbased_authentication; 7677c478bd9Sstevel@tonic-gate goto parse_flag; 7687c478bd9Sstevel@tonic-gate 7697c478bd9Sstevel@tonic-gate case sHostbasedUsesNameFromPacketOnly: 7707c478bd9Sstevel@tonic-gate intptr = &options->hostbased_uses_name_from_packet_only; 7717c478bd9Sstevel@tonic-gate goto parse_flag; 7727c478bd9Sstevel@tonic-gate 7737c478bd9Sstevel@tonic-gate case sRSAAuthentication: 7747c478bd9Sstevel@tonic-gate intptr = &options->rsa_authentication; 7757c478bd9Sstevel@tonic-gate goto parse_flag; 7767c478bd9Sstevel@tonic-gate 7777c478bd9Sstevel@tonic-gate case sPubkeyAuthentication: 7787c478bd9Sstevel@tonic-gate intptr = &options->pubkey_authentication; 7797c478bd9Sstevel@tonic-gate goto parse_flag; 7807c478bd9Sstevel@tonic-gate #ifdef GSSAPI 7817c478bd9Sstevel@tonic-gate case sGssAuthentication: 7827c478bd9Sstevel@tonic-gate intptr = &options->gss_authentication; 7837c478bd9Sstevel@tonic-gate goto parse_flag; 7847c478bd9Sstevel@tonic-gate case sGssKeyEx: 7857c478bd9Sstevel@tonic-gate intptr = &options->gss_keyex; 7867c478bd9Sstevel@tonic-gate goto parse_flag; 7877c478bd9Sstevel@tonic-gate case sGssStoreDelegCreds: 7887c478bd9Sstevel@tonic-gate intptr = &options->gss_keyex; 7897c478bd9Sstevel@tonic-gate goto parse_flag; 7907c478bd9Sstevel@tonic-gate #ifndef SUNW_GSSAPI 7917c478bd9Sstevel@tonic-gate case sGssUseSessionCredCache: 7927c478bd9Sstevel@tonic-gate intptr = &options->gss_use_session_ccache; 7937c478bd9Sstevel@tonic-gate goto parse_flag; 7947c478bd9Sstevel@tonic-gate case sGssCleanupCreds: 7957c478bd9Sstevel@tonic-gate intptr = &options->gss_cleanup_creds; 7967c478bd9Sstevel@tonic-gate goto parse_flag; 7977c478bd9Sstevel@tonic-gate #endif /* SUNW_GSSAPI */ 7987c478bd9Sstevel@tonic-gate #endif /* GSSAPI */ 7997c478bd9Sstevel@tonic-gate #if defined(KRB4) || defined(KRB5) 8007c478bd9Sstevel@tonic-gate case sKerberosAuthentication: 8017c478bd9Sstevel@tonic-gate intptr = &options->kerberos_authentication; 8027c478bd9Sstevel@tonic-gate goto parse_flag; 8037c478bd9Sstevel@tonic-gate 8047c478bd9Sstevel@tonic-gate case sKerberosOrLocalPasswd: 8057c478bd9Sstevel@tonic-gate intptr = &options->kerberos_or_local_passwd; 8067c478bd9Sstevel@tonic-gate goto parse_flag; 8077c478bd9Sstevel@tonic-gate 8087c478bd9Sstevel@tonic-gate case sKerberosTicketCleanup: 8097c478bd9Sstevel@tonic-gate intptr = &options->kerberos_ticket_cleanup; 8107c478bd9Sstevel@tonic-gate goto parse_flag; 8117c478bd9Sstevel@tonic-gate #endif 8127c478bd9Sstevel@tonic-gate #if defined(AFS) || defined(KRB5) 8137c478bd9Sstevel@tonic-gate case sKerberosTgtPassing: 8147c478bd9Sstevel@tonic-gate intptr = &options->kerberos_tgt_passing; 8157c478bd9Sstevel@tonic-gate goto parse_flag; 8167c478bd9Sstevel@tonic-gate #endif 8177c478bd9Sstevel@tonic-gate #ifdef AFS 8187c478bd9Sstevel@tonic-gate case sAFSTokenPassing: 8197c478bd9Sstevel@tonic-gate intptr = &options->afs_token_passing; 8207c478bd9Sstevel@tonic-gate goto parse_flag; 8217c478bd9Sstevel@tonic-gate #endif 8227c478bd9Sstevel@tonic-gate 8237c478bd9Sstevel@tonic-gate case sPasswordAuthentication: 8247c478bd9Sstevel@tonic-gate intptr = &options->password_authentication; 8257c478bd9Sstevel@tonic-gate goto parse_flag; 8267c478bd9Sstevel@tonic-gate 8277c478bd9Sstevel@tonic-gate case sKbdInteractiveAuthentication: 8287c478bd9Sstevel@tonic-gate intptr = &options->kbd_interactive_authentication; 8297c478bd9Sstevel@tonic-gate goto parse_flag; 8307c478bd9Sstevel@tonic-gate 8317c478bd9Sstevel@tonic-gate case sChallengeResponseAuthentication: 8327c478bd9Sstevel@tonic-gate intptr = &options->challenge_response_authentication; 8337c478bd9Sstevel@tonic-gate goto parse_flag; 8347c478bd9Sstevel@tonic-gate 8357c478bd9Sstevel@tonic-gate case sPrintMotd: 8367c478bd9Sstevel@tonic-gate intptr = &options->print_motd; 8377c478bd9Sstevel@tonic-gate goto parse_flag; 8387c478bd9Sstevel@tonic-gate 8397c478bd9Sstevel@tonic-gate case sPrintLastLog: 8407c478bd9Sstevel@tonic-gate intptr = &options->print_lastlog; 8417c478bd9Sstevel@tonic-gate goto parse_flag; 8427c478bd9Sstevel@tonic-gate 8437c478bd9Sstevel@tonic-gate case sX11Forwarding: 8447c478bd9Sstevel@tonic-gate intptr = &options->x11_forwarding; 8457c478bd9Sstevel@tonic-gate goto parse_flag; 8467c478bd9Sstevel@tonic-gate 8477c478bd9Sstevel@tonic-gate case sX11DisplayOffset: 8487c478bd9Sstevel@tonic-gate intptr = &options->x11_display_offset; 8497c478bd9Sstevel@tonic-gate goto parse_int; 8507c478bd9Sstevel@tonic-gate 8517c478bd9Sstevel@tonic-gate case sX11UseLocalhost: 8527c478bd9Sstevel@tonic-gate intptr = &options->x11_use_localhost; 8537c478bd9Sstevel@tonic-gate goto parse_flag; 8547c478bd9Sstevel@tonic-gate 8557c478bd9Sstevel@tonic-gate case sXAuthLocation: 8567c478bd9Sstevel@tonic-gate charptr = &options->xauth_location; 8577c478bd9Sstevel@tonic-gate goto parse_filename; 8587c478bd9Sstevel@tonic-gate 8597c478bd9Sstevel@tonic-gate case sStrictModes: 8607c478bd9Sstevel@tonic-gate intptr = &options->strict_modes; 8617c478bd9Sstevel@tonic-gate goto parse_flag; 8627c478bd9Sstevel@tonic-gate 8637c478bd9Sstevel@tonic-gate case sKeepAlives: 8647c478bd9Sstevel@tonic-gate intptr = &options->keepalives; 8657c478bd9Sstevel@tonic-gate goto parse_flag; 8667c478bd9Sstevel@tonic-gate 8677c478bd9Sstevel@tonic-gate case sEmptyPasswd: 8687c478bd9Sstevel@tonic-gate intptr = &options->permit_empty_passwd; 8697c478bd9Sstevel@tonic-gate goto parse_flag; 8707c478bd9Sstevel@tonic-gate 8717c478bd9Sstevel@tonic-gate case sPermitUserEnvironment: 8727c478bd9Sstevel@tonic-gate intptr = &options->permit_user_env; 8737c478bd9Sstevel@tonic-gate goto parse_flag; 8747c478bd9Sstevel@tonic-gate 8757c478bd9Sstevel@tonic-gate case sUseLogin: 876*b9aa66a7SJan Pechanec log("%s line %d: ignoring UseLogin option value." 877*b9aa66a7SJan Pechanec " This option is always off.", filename, linenum); 878*b9aa66a7SJan Pechanec while (arg) 879*b9aa66a7SJan Pechanec arg = strdelim(&cp); 880*b9aa66a7SJan Pechanec break; 8817c478bd9Sstevel@tonic-gate 8827c478bd9Sstevel@tonic-gate case sCompression: 8837c478bd9Sstevel@tonic-gate intptr = &options->compression; 8847c478bd9Sstevel@tonic-gate goto parse_flag; 8857c478bd9Sstevel@tonic-gate 8867c478bd9Sstevel@tonic-gate case sGatewayPorts: 8879b03ea0fSjp161948 arg = strdelim(&cp); 8889b03ea0fSjp161948 if (get_yes_no_flag(&options->gateway_ports, arg, filename, 8899b03ea0fSjp161948 linenum, 1) == 1) 8909b03ea0fSjp161948 break; 8919b03ea0fSjp161948 8929b03ea0fSjp161948 if (strcmp(arg, "clientspecified") == 0) 8939b03ea0fSjp161948 options->gateway_ports = 2; 8949b03ea0fSjp161948 else 8959b03ea0fSjp161948 fatal("%.200s line %d: Bad yes/no/clientspecified " 8969b03ea0fSjp161948 "argument.", filename, linenum); 8979b03ea0fSjp161948 break; 8987c478bd9Sstevel@tonic-gate 8997c478bd9Sstevel@tonic-gate case sVerifyReverseMapping: 9007c478bd9Sstevel@tonic-gate intptr = &options->verify_reverse_mapping; 9017c478bd9Sstevel@tonic-gate goto parse_flag; 9027c478bd9Sstevel@tonic-gate 9037c478bd9Sstevel@tonic-gate case sLogFacility: 9047c478bd9Sstevel@tonic-gate intptr = (int *) &options->log_facility; 9057c478bd9Sstevel@tonic-gate arg = strdelim(&cp); 9067c478bd9Sstevel@tonic-gate value = log_facility_number(arg); 9077c478bd9Sstevel@tonic-gate if (value == SYSLOG_FACILITY_NOT_SET) 9087c478bd9Sstevel@tonic-gate fatal("%.200s line %d: unsupported log facility '%s'", 9097c478bd9Sstevel@tonic-gate filename, linenum, arg ? arg : "<NONE>"); 9107c478bd9Sstevel@tonic-gate if (*intptr == -1) 9117c478bd9Sstevel@tonic-gate *intptr = (SyslogFacility) value; 9127c478bd9Sstevel@tonic-gate break; 9137c478bd9Sstevel@tonic-gate 9147c478bd9Sstevel@tonic-gate case sLogLevel: 9157c478bd9Sstevel@tonic-gate intptr = (int *) &options->log_level; 9167c478bd9Sstevel@tonic-gate arg = strdelim(&cp); 9177c478bd9Sstevel@tonic-gate value = log_level_number(arg); 9187c478bd9Sstevel@tonic-gate if (value == SYSLOG_LEVEL_NOT_SET) 9197c478bd9Sstevel@tonic-gate fatal("%.200s line %d: unsupported log level '%s'", 9207c478bd9Sstevel@tonic-gate filename, linenum, arg ? arg : "<NONE>"); 9217c478bd9Sstevel@tonic-gate if (*intptr == -1) 9227c478bd9Sstevel@tonic-gate *intptr = (LogLevel) value; 9237c478bd9Sstevel@tonic-gate break; 9247c478bd9Sstevel@tonic-gate 9257c478bd9Sstevel@tonic-gate case sAllowTcpForwarding: 9267c478bd9Sstevel@tonic-gate intptr = &options->allow_tcp_forwarding; 9277c478bd9Sstevel@tonic-gate goto parse_flag; 9287c478bd9Sstevel@tonic-gate 9297c478bd9Sstevel@tonic-gate case sUsePrivilegeSeparation: 9309a8058b5Sjp161948 log("%s line %d: ignoring UsePrivilegeSeparation option value." 9319a8058b5Sjp161948 " This option is always on.", filename, linenum); 9329a8058b5Sjp161948 while (arg) 9339a8058b5Sjp161948 arg = strdelim(&cp); 9349a8058b5Sjp161948 break; 9357c478bd9Sstevel@tonic-gate 9367c478bd9Sstevel@tonic-gate case sAllowUsers: 9377c478bd9Sstevel@tonic-gate while (((arg = strdelim(&cp)) != NULL) && *arg != '\0') { 9387c478bd9Sstevel@tonic-gate if (options->num_allow_users >= MAX_ALLOW_USERS) 9397c478bd9Sstevel@tonic-gate fatal("%s line %d: too many allow users.", 9407c478bd9Sstevel@tonic-gate filename, linenum); 9417c478bd9Sstevel@tonic-gate options->allow_users[options->num_allow_users++] = 9427c478bd9Sstevel@tonic-gate xstrdup(arg); 9437c478bd9Sstevel@tonic-gate } 9447c478bd9Sstevel@tonic-gate break; 9457c478bd9Sstevel@tonic-gate 9467c478bd9Sstevel@tonic-gate case sDenyUsers: 9477c478bd9Sstevel@tonic-gate while (((arg = strdelim(&cp)) != NULL) && *arg != '\0') { 9487c478bd9Sstevel@tonic-gate if (options->num_deny_users >= MAX_DENY_USERS) 9497c478bd9Sstevel@tonic-gate fatal( "%s line %d: too many deny users.", 9507c478bd9Sstevel@tonic-gate filename, linenum); 9517c478bd9Sstevel@tonic-gate options->deny_users[options->num_deny_users++] = 9527c478bd9Sstevel@tonic-gate xstrdup(arg); 9537c478bd9Sstevel@tonic-gate } 9547c478bd9Sstevel@tonic-gate break; 9557c478bd9Sstevel@tonic-gate 9567c478bd9Sstevel@tonic-gate case sAllowGroups: 9577c478bd9Sstevel@tonic-gate while (((arg = strdelim(&cp)) != NULL) && *arg != '\0') { 9587c478bd9Sstevel@tonic-gate if (options->num_allow_groups >= MAX_ALLOW_GROUPS) 9597c478bd9Sstevel@tonic-gate fatal("%s line %d: too many allow groups.", 9607c478bd9Sstevel@tonic-gate filename, linenum); 9617c478bd9Sstevel@tonic-gate options->allow_groups[options->num_allow_groups++] = 9627c478bd9Sstevel@tonic-gate xstrdup(arg); 9637c478bd9Sstevel@tonic-gate } 9647c478bd9Sstevel@tonic-gate break; 9657c478bd9Sstevel@tonic-gate 9667c478bd9Sstevel@tonic-gate case sDenyGroups: 9677c478bd9Sstevel@tonic-gate while (((arg = strdelim(&cp)) != NULL) && *arg != '\0') { 9687c478bd9Sstevel@tonic-gate if (options->num_deny_groups >= MAX_DENY_GROUPS) 9697c478bd9Sstevel@tonic-gate fatal("%s line %d: too many deny groups.", 9707c478bd9Sstevel@tonic-gate filename, linenum); 9717c478bd9Sstevel@tonic-gate options->deny_groups[options->num_deny_groups++] = xstrdup(arg); 9727c478bd9Sstevel@tonic-gate } 9737c478bd9Sstevel@tonic-gate break; 9747c478bd9Sstevel@tonic-gate 9757c478bd9Sstevel@tonic-gate case sCiphers: 9767c478bd9Sstevel@tonic-gate arg = strdelim(&cp); 9777c478bd9Sstevel@tonic-gate if (!arg || *arg == '\0') 9787c478bd9Sstevel@tonic-gate fatal("%s line %d: Missing argument.", filename, linenum); 9797c478bd9Sstevel@tonic-gate if (!ciphers_valid(arg)) 9807c478bd9Sstevel@tonic-gate fatal("%s line %d: Bad SSH2 cipher spec '%s'.", 9817c478bd9Sstevel@tonic-gate filename, linenum, arg ? arg : "<NONE>"); 9827c478bd9Sstevel@tonic-gate if (options->ciphers == NULL) 9837c478bd9Sstevel@tonic-gate options->ciphers = xstrdup(arg); 9847c478bd9Sstevel@tonic-gate break; 9857c478bd9Sstevel@tonic-gate 9867c478bd9Sstevel@tonic-gate case sMacs: 9877c478bd9Sstevel@tonic-gate arg = strdelim(&cp); 9887c478bd9Sstevel@tonic-gate if (!arg || *arg == '\0') 9897c478bd9Sstevel@tonic-gate fatal("%s line %d: Missing argument.", filename, linenum); 9907c478bd9Sstevel@tonic-gate if (!mac_valid(arg)) 9917c478bd9Sstevel@tonic-gate fatal("%s line %d: Bad SSH2 mac spec '%s'.", 9927c478bd9Sstevel@tonic-gate filename, linenum, arg ? arg : "<NONE>"); 9937c478bd9Sstevel@tonic-gate if (options->macs == NULL) 9947c478bd9Sstevel@tonic-gate options->macs = xstrdup(arg); 9957c478bd9Sstevel@tonic-gate break; 9967c478bd9Sstevel@tonic-gate 9977c478bd9Sstevel@tonic-gate case sProtocol: 9987c478bd9Sstevel@tonic-gate intptr = &options->protocol; 9997c478bd9Sstevel@tonic-gate arg = strdelim(&cp); 10007c478bd9Sstevel@tonic-gate if (!arg || *arg == '\0') 10017c478bd9Sstevel@tonic-gate fatal("%s line %d: Missing argument.", filename, linenum); 10027c478bd9Sstevel@tonic-gate value = proto_spec(arg); 10037c478bd9Sstevel@tonic-gate if (value == SSH_PROTO_UNKNOWN) 10047c478bd9Sstevel@tonic-gate fatal("%s line %d: Bad protocol spec '%s'.", 10057c478bd9Sstevel@tonic-gate filename, linenum, arg ? arg : "<NONE>"); 10067c478bd9Sstevel@tonic-gate if (*intptr == SSH_PROTO_UNKNOWN) 10077c478bd9Sstevel@tonic-gate *intptr = value; 10087c478bd9Sstevel@tonic-gate break; 10097c478bd9Sstevel@tonic-gate 10107c478bd9Sstevel@tonic-gate case sSubsystem: 10117c478bd9Sstevel@tonic-gate if (options->num_subsystems >= MAX_SUBSYSTEMS) { 10127c478bd9Sstevel@tonic-gate fatal("%s line %d: too many subsystems defined.", 10137c478bd9Sstevel@tonic-gate filename, linenum); 10147c478bd9Sstevel@tonic-gate } 10157c478bd9Sstevel@tonic-gate arg = strdelim(&cp); 10167c478bd9Sstevel@tonic-gate if (!arg || *arg == '\0') 10177c478bd9Sstevel@tonic-gate fatal("%s line %d: Missing subsystem name.", 10187c478bd9Sstevel@tonic-gate filename, linenum); 10197c478bd9Sstevel@tonic-gate for (i = 0; i < options->num_subsystems; i++) 10207c478bd9Sstevel@tonic-gate if (strcmp(arg, options->subsystem_name[i]) == 0) 10217c478bd9Sstevel@tonic-gate fatal("%s line %d: Subsystem '%s' already defined.", 10227c478bd9Sstevel@tonic-gate filename, linenum, arg); 10237c478bd9Sstevel@tonic-gate options->subsystem_name[options->num_subsystems] = xstrdup(arg); 10247c478bd9Sstevel@tonic-gate arg = strdelim(&cp); 10257c478bd9Sstevel@tonic-gate if (!arg || *arg == '\0') 10267c478bd9Sstevel@tonic-gate fatal("%s line %d: Missing subsystem command.", 10277c478bd9Sstevel@tonic-gate filename, linenum); 10287c478bd9Sstevel@tonic-gate options->subsystem_command[options->num_subsystems] = xstrdup(arg); 10296f8d59d8SJan Pechanec 10306f8d59d8SJan Pechanec /* 10316f8d59d8SJan Pechanec * Collect arguments (separate to executable), including the 10326f8d59d8SJan Pechanec * name of the executable, in a way that is easier to parse 10336f8d59d8SJan Pechanec * later. 10346f8d59d8SJan Pechanec */ 10356f8d59d8SJan Pechanec p = xstrdup(arg); 10366f8d59d8SJan Pechanec len = strlen(p) + 1; 10376f8d59d8SJan Pechanec while ((arg = strdelim(&cp)) != NULL && *arg != '\0') { 10386f8d59d8SJan Pechanec len += 1 + strlen(arg); 10396f8d59d8SJan Pechanec p = xrealloc(p, len); 10406f8d59d8SJan Pechanec strlcat(p, " ", len); 10416f8d59d8SJan Pechanec strlcat(p, arg, len); 10426f8d59d8SJan Pechanec } 10436f8d59d8SJan Pechanec options->subsystem_args[options->num_subsystems] = p; 10447c478bd9Sstevel@tonic-gate options->num_subsystems++; 10457c478bd9Sstevel@tonic-gate break; 10467c478bd9Sstevel@tonic-gate 10477c478bd9Sstevel@tonic-gate case sMaxStartups: 10487c478bd9Sstevel@tonic-gate arg = strdelim(&cp); 10497c478bd9Sstevel@tonic-gate if (!arg || *arg == '\0') 10507c478bd9Sstevel@tonic-gate fatal("%s line %d: Missing MaxStartups spec.", 10517c478bd9Sstevel@tonic-gate filename, linenum); 10527c478bd9Sstevel@tonic-gate if ((n = sscanf(arg, "%d:%d:%d", 10537c478bd9Sstevel@tonic-gate &options->max_startups_begin, 10547c478bd9Sstevel@tonic-gate &options->max_startups_rate, 10557c478bd9Sstevel@tonic-gate &options->max_startups)) == 3) { 10567c478bd9Sstevel@tonic-gate if (options->max_startups_begin > 10577c478bd9Sstevel@tonic-gate options->max_startups || 10587c478bd9Sstevel@tonic-gate options->max_startups_rate > 100 || 10597c478bd9Sstevel@tonic-gate options->max_startups_rate < 1) 10607c478bd9Sstevel@tonic-gate fatal("%s line %d: Illegal MaxStartups spec.", 10617c478bd9Sstevel@tonic-gate filename, linenum); 10627c478bd9Sstevel@tonic-gate } else if (n != 1) 10637c478bd9Sstevel@tonic-gate fatal("%s line %d: Illegal MaxStartups spec.", 10647c478bd9Sstevel@tonic-gate filename, linenum); 10657c478bd9Sstevel@tonic-gate else 10667c478bd9Sstevel@tonic-gate options->max_startups = options->max_startups_begin; 10677c478bd9Sstevel@tonic-gate break; 10687c478bd9Sstevel@tonic-gate 10697c478bd9Sstevel@tonic-gate case sBanner: 10707c478bd9Sstevel@tonic-gate charptr = &options->banner; 10717c478bd9Sstevel@tonic-gate goto parse_filename; 10727c478bd9Sstevel@tonic-gate /* 10737c478bd9Sstevel@tonic-gate * These options can contain %X options expanded at 10747c478bd9Sstevel@tonic-gate * connect time, so that you can specify paths like: 10757c478bd9Sstevel@tonic-gate * 10767c478bd9Sstevel@tonic-gate * AuthorizedKeysFile /etc/ssh_keys/%u 10777c478bd9Sstevel@tonic-gate */ 10787c478bd9Sstevel@tonic-gate case sAuthorizedKeysFile: 10797c478bd9Sstevel@tonic-gate case sAuthorizedKeysFile2: 10807c478bd9Sstevel@tonic-gate charptr = (opcode == sAuthorizedKeysFile) ? 10817c478bd9Sstevel@tonic-gate &options->authorized_keys_file : 10827c478bd9Sstevel@tonic-gate &options->authorized_keys_file2; 10837c478bd9Sstevel@tonic-gate goto parse_filename; 10847c478bd9Sstevel@tonic-gate 10857c478bd9Sstevel@tonic-gate case sClientAliveInterval: 10867c478bd9Sstevel@tonic-gate intptr = &options->client_alive_interval; 10877c478bd9Sstevel@tonic-gate goto parse_time; 10887c478bd9Sstevel@tonic-gate 10897c478bd9Sstevel@tonic-gate case sClientAliveCountMax: 10907c478bd9Sstevel@tonic-gate intptr = &options->client_alive_count_max; 10917c478bd9Sstevel@tonic-gate goto parse_int; 10927c478bd9Sstevel@tonic-gate 10937c478bd9Sstevel@tonic-gate case sMaxAuthTries: 10947c478bd9Sstevel@tonic-gate intptr = &options->max_auth_tries; 10957c478bd9Sstevel@tonic-gate goto parse_int; 10967c478bd9Sstevel@tonic-gate 10977c478bd9Sstevel@tonic-gate case sMaxAuthTriesLog: 10987c478bd9Sstevel@tonic-gate intptr = &options->max_auth_tries_log; 10997c478bd9Sstevel@tonic-gate goto parse_int; 11007c478bd9Sstevel@tonic-gate 11017c478bd9Sstevel@tonic-gate case sLookupClientHostnames: 11027c478bd9Sstevel@tonic-gate intptr = &options->lookup_client_hostnames; 11037c478bd9Sstevel@tonic-gate goto parse_flag; 11046f8d59d8SJan Pechanec 1105cd7d5fafSJan Pechanec case sUseOpenSSLEngine: 1106cd7d5fafSJan Pechanec intptr = &options->use_openssl_engine; 1107cd7d5fafSJan Pechanec goto parse_flag; 11087c478bd9Sstevel@tonic-gate 11096f8d59d8SJan Pechanec case sChrootDirectory: 11106f8d59d8SJan Pechanec charptr = &options->chroot_directory; 11116f8d59d8SJan Pechanec 11126f8d59d8SJan Pechanec arg = strdelim(&cp); 11136f8d59d8SJan Pechanec if (arg == NULL || *arg == '\0') 11146f8d59d8SJan Pechanec fatal("%s line %d: missing directory name for " 11156f8d59d8SJan Pechanec "ChrootDirectory.", filename, linenum); 11166f8d59d8SJan Pechanec if (*charptr == NULL) 11176f8d59d8SJan Pechanec *charptr = xstrdup(arg); 11186f8d59d8SJan Pechanec break; 11196f8d59d8SJan Pechanec 11207c478bd9Sstevel@tonic-gate case sDeprecated: 11217c478bd9Sstevel@tonic-gate log("%s line %d: Deprecated option %s", 11227c478bd9Sstevel@tonic-gate filename, linenum, arg); 11237c478bd9Sstevel@tonic-gate while (arg) 11247c478bd9Sstevel@tonic-gate arg = strdelim(&cp); 11257c478bd9Sstevel@tonic-gate break; 11267c478bd9Sstevel@tonic-gate 11277c478bd9Sstevel@tonic-gate default: 11287c478bd9Sstevel@tonic-gate fatal("%s line %d: Missing handler for opcode %s (%d)", 11297c478bd9Sstevel@tonic-gate filename, linenum, arg, opcode); 11307c478bd9Sstevel@tonic-gate } 11317c478bd9Sstevel@tonic-gate if ((arg = strdelim(&cp)) != NULL && *arg != '\0') 11327c478bd9Sstevel@tonic-gate fatal("%s line %d: garbage at end of line; \"%.200s\".", 11337c478bd9Sstevel@tonic-gate filename, linenum, arg); 11347c478bd9Sstevel@tonic-gate return 0; 11357c478bd9Sstevel@tonic-gate } 11367c478bd9Sstevel@tonic-gate 11377c478bd9Sstevel@tonic-gate /* Reads the server configuration file. */ 11387c478bd9Sstevel@tonic-gate 11397c478bd9Sstevel@tonic-gate void 11407c478bd9Sstevel@tonic-gate read_server_config(ServerOptions *options, const char *filename) 11417c478bd9Sstevel@tonic-gate { 11427c478bd9Sstevel@tonic-gate int linenum, bad_options = 0; 11437c478bd9Sstevel@tonic-gate char line[1024]; 11447c478bd9Sstevel@tonic-gate FILE *f; 11457c478bd9Sstevel@tonic-gate 11467c478bd9Sstevel@tonic-gate f = fopen(filename, "r"); 11477c478bd9Sstevel@tonic-gate if (!f) { 11487c478bd9Sstevel@tonic-gate perror(filename); 11497c478bd9Sstevel@tonic-gate exit(1); 11507c478bd9Sstevel@tonic-gate } 11517c478bd9Sstevel@tonic-gate linenum = 0; 11527c478bd9Sstevel@tonic-gate while (fgets(line, sizeof(line), f)) { 11537c478bd9Sstevel@tonic-gate /* Update line number counter. */ 11547c478bd9Sstevel@tonic-gate linenum++; 11557c478bd9Sstevel@tonic-gate if (process_server_config_line(options, line, filename, linenum) != 0) 11567c478bd9Sstevel@tonic-gate bad_options++; 11577c478bd9Sstevel@tonic-gate } 11587c478bd9Sstevel@tonic-gate (void) fclose(f); 11597c478bd9Sstevel@tonic-gate if (bad_options > 0) 11607c478bd9Sstevel@tonic-gate fatal("%s: terminating, %d bad configuration options", 11617c478bd9Sstevel@tonic-gate filename, bad_options); 11627c478bd9Sstevel@tonic-gate } 11636f8d59d8SJan Pechanec 11646f8d59d8SJan Pechanec /* 11656f8d59d8SJan Pechanec * Note that "none" is a special path having the same affect on sshd 11666f8d59d8SJan Pechanec * configuration as not specifying ChrootDirectory at all. 11676f8d59d8SJan Pechanec */ 11686f8d59d8SJan Pechanec int 11696f8d59d8SJan Pechanec chroot_requested(char *chroot_directory) 11706f8d59d8SJan Pechanec { 11716f8d59d8SJan Pechanec return (chroot_directory != NULL && 11726f8d59d8SJan Pechanec strcasecmp(chroot_directory, "none") != 0); 11736f8d59d8SJan Pechanec } 1174