1eccfee6eSDag-Erling Smørgrav 2*acc1a9efSDag-Erling Smørgrav /* $OpenBSD: servconf.c,v 1.285 2016/02/17 05:29:04 djm Exp $ */ 3511b41d2SMark Murray /* 4511b41d2SMark Murray * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 5511b41d2SMark Murray * All rights reserved 6511b41d2SMark Murray * 7c2d3a559SKris Kennaway * As far as I am concerned, the code I have written for this software 8c2d3a559SKris Kennaway * can be used freely for any purpose. Any derived versions of this 9c2d3a559SKris Kennaway * software must be clearly marked as such, and if the derived work is 10c2d3a559SKris Kennaway * incompatible with the protocol description in the RFC file, it must be 11c2d3a559SKris Kennaway * called by a name other than "ssh" or "Secure Shell". 12511b41d2SMark Murray */ 13511b41d2SMark Murray 14511b41d2SMark Murray #include "includes.h" 15333ee039SDag-Erling Smørgrav __RCSID("$FreeBSD$"); 16511b41d2SMark Murray 17333ee039SDag-Erling Smørgrav #include <sys/types.h> 18333ee039SDag-Erling Smørgrav #include <sys/socket.h> 19333ee039SDag-Erling Smørgrav 204a421b63SDag-Erling Smørgrav #include <netinet/in.h> 214a421b63SDag-Erling Smørgrav #include <netinet/in_systm.h> 224a421b63SDag-Erling Smørgrav #include <netinet/ip.h> 234a421b63SDag-Erling Smørgrav 24e4a9863fSDag-Erling Smørgrav #include <ctype.h> 25333ee039SDag-Erling Smørgrav #include <netdb.h> 26333ee039SDag-Erling Smørgrav #include <pwd.h> 27333ee039SDag-Erling Smørgrav #include <stdio.h> 28333ee039SDag-Erling Smørgrav #include <stdlib.h> 29333ee039SDag-Erling Smørgrav #include <string.h> 30333ee039SDag-Erling Smørgrav #include <signal.h> 31333ee039SDag-Erling Smørgrav #include <unistd.h> 32bc5531deSDag-Erling Smørgrav #include <limits.h> 33333ee039SDag-Erling Smørgrav #include <stdarg.h> 34d4af9e69SDag-Erling Smørgrav #include <errno.h> 35e4a9863fSDag-Erling Smørgrav #ifdef HAVE_UTIL_H 36e4a9863fSDag-Erling Smørgrav #include <util.h> 37e4a9863fSDag-Erling Smørgrav #endif 38333ee039SDag-Erling Smørgrav 39d4af9e69SDag-Erling Smørgrav #include "openbsd-compat/sys-queue.h" 40333ee039SDag-Erling Smørgrav #include "xmalloc.h" 41511b41d2SMark Murray #include "ssh.h" 42ca3176e7SBrian Feldman #include "log.h" 43333ee039SDag-Erling Smørgrav #include "buffer.h" 44a0ee8cc6SDag-Erling Smørgrav #include "misc.h" 45511b41d2SMark Murray #include "servconf.h" 46e8aafc91SKris Kennaway #include "compat.h" 47ca3176e7SBrian Feldman #include "pathnames.h" 48ca3176e7SBrian Feldman #include "cipher.h" 49333ee039SDag-Erling Smørgrav #include "key.h" 50ca3176e7SBrian Feldman #include "kex.h" 51ca3176e7SBrian Feldman #include "mac.h" 52333ee039SDag-Erling Smørgrav #include "match.h" 53333ee039SDag-Erling Smørgrav #include "channels.h" 54333ee039SDag-Erling Smørgrav #include "groupaccess.h" 55462c32cbSDag-Erling Smørgrav #include "canohost.h" 56462c32cbSDag-Erling Smørgrav #include "packet.h" 576888a9beSDag-Erling Smørgrav #include "hostfile.h" 586888a9beSDag-Erling Smørgrav #include "auth.h" 59bc5531deSDag-Erling Smørgrav #include "myproposal.h" 60bc5531deSDag-Erling Smørgrav #include "digest.h" 61b15c8340SDag-Erling Smørgrav #include "version.h" 62511b41d2SMark Murray 63cce7d346SDag-Erling Smørgrav static void add_listen_addr(ServerOptions *, char *, int); 64cce7d346SDag-Erling Smørgrav static void add_one_listen_addr(ServerOptions *, char *, int); 65ca3176e7SBrian Feldman 6680628bacSDag-Erling Smørgrav /* Use of privilege separation or not */ 6780628bacSDag-Erling Smørgrav extern int use_privsep; 68333ee039SDag-Erling Smørgrav extern Buffer cfg; 69511b41d2SMark Murray 70511b41d2SMark Murray /* Initializes the server options to their default values. */ 71511b41d2SMark Murray 72511b41d2SMark Murray void 73511b41d2SMark Murray initialize_server_options(ServerOptions *options) 74511b41d2SMark Murray { 75511b41d2SMark Murray memset(options, 0, sizeof(*options)); 76989dd127SDag-Erling Smørgrav 77989dd127SDag-Erling Smørgrav /* Portable-specific options */ 78cf2b5f3bSDag-Erling Smørgrav options->use_pam = -1; 79989dd127SDag-Erling Smørgrav 80989dd127SDag-Erling Smørgrav /* Standard Options */ 81511b41d2SMark Murray options->num_ports = 0; 82511b41d2SMark Murray options->ports_from_cmdline = 0; 83557f75e5SDag-Erling Smørgrav options->queued_listen_addrs = NULL; 84557f75e5SDag-Erling Smørgrav options->num_queued_listens = 0; 85511b41d2SMark Murray options->listen_addrs = NULL; 86aa49c926SDag-Erling Smørgrav options->address_family = -1; 87ca3176e7SBrian Feldman options->num_host_key_files = 0; 88b15c8340SDag-Erling Smørgrav options->num_host_cert_files = 0; 89e4a9863fSDag-Erling Smørgrav options->host_key_agent = NULL; 90e8aafc91SKris Kennaway options->pid_file = NULL; 91511b41d2SMark Murray options->server_key_bits = -1; 92511b41d2SMark Murray options->login_grace_time = -1; 93511b41d2SMark Murray options->key_regeneration_time = -1; 94ca3176e7SBrian Feldman options->permit_root_login = PERMIT_NOT_SET; 95511b41d2SMark Murray options->ignore_rhosts = -1; 96511b41d2SMark Murray options->ignore_user_known_hosts = -1; 97511b41d2SMark Murray options->print_motd = -1; 98ca3176e7SBrian Feldman options->print_lastlog = -1; 99511b41d2SMark Murray options->x11_forwarding = -1; 100511b41d2SMark Murray options->x11_display_offset = -1; 101af12a3e7SDag-Erling Smørgrav options->x11_use_localhost = -1; 102f7167e0eSDag-Erling Smørgrav options->permit_tty = -1; 103a0ee8cc6SDag-Erling Smørgrav options->permit_user_rc = -1; 104c2d3a559SKris Kennaway options->xauth_location = NULL; 105511b41d2SMark Murray options->strict_modes = -1; 1061ec0d754SDag-Erling Smørgrav options->tcp_keep_alive = -1; 107af12a3e7SDag-Erling Smørgrav options->log_facility = SYSLOG_FACILITY_NOT_SET; 108af12a3e7SDag-Erling Smørgrav options->log_level = SYSLOG_LEVEL_NOT_SET; 109511b41d2SMark Murray options->rhosts_rsa_authentication = -1; 110ca3176e7SBrian Feldman options->hostbased_authentication = -1; 111ca3176e7SBrian Feldman options->hostbased_uses_name_from_packet_only = -1; 112bc5531deSDag-Erling Smørgrav options->hostbased_key_types = NULL; 113eccfee6eSDag-Erling Smørgrav options->hostkeyalgorithms = NULL; 114511b41d2SMark Murray options->rsa_authentication = -1; 115ca3176e7SBrian Feldman options->pubkey_authentication = -1; 116bc5531deSDag-Erling Smørgrav options->pubkey_key_types = NULL; 117cb96ab36SAssar Westerlund options->kerberos_authentication = -1; 118af12a3e7SDag-Erling Smørgrav options->kerberos_or_local_passwd = -1; 119af12a3e7SDag-Erling Smørgrav options->kerberos_ticket_cleanup = -1; 1201ec0d754SDag-Erling Smørgrav options->kerberos_get_afs_token = -1; 121cf2b5f3bSDag-Erling Smørgrav options->gss_authentication=-1; 122cf2b5f3bSDag-Erling Smørgrav options->gss_cleanup_creds = -1; 123557f75e5SDag-Erling Smørgrav options->gss_strict_acceptor = -1; 124511b41d2SMark Murray options->password_authentication = -1; 12509958426SBrian Feldman options->kbd_interactive_authentication = -1; 126af12a3e7SDag-Erling Smørgrav options->challenge_response_authentication = -1; 127511b41d2SMark Murray options->permit_empty_passwd = -1; 128f388f5efSDag-Erling Smørgrav options->permit_user_env = -1; 129511b41d2SMark Murray options->use_login = -1; 13080628bacSDag-Erling Smørgrav options->compression = -1; 131e4a9863fSDag-Erling Smørgrav options->rekey_limit = -1; 132e4a9863fSDag-Erling Smørgrav options->rekey_interval = -1; 13309958426SBrian Feldman options->allow_tcp_forwarding = -1; 134a0ee8cc6SDag-Erling Smørgrav options->allow_streamlocal_forwarding = -1; 135d4af9e69SDag-Erling Smørgrav options->allow_agent_forwarding = -1; 136511b41d2SMark Murray options->num_allow_users = 0; 137511b41d2SMark Murray options->num_deny_users = 0; 138511b41d2SMark Murray options->num_allow_groups = 0; 139511b41d2SMark Murray options->num_deny_groups = 0; 140e8aafc91SKris Kennaway options->ciphers = NULL; 141ca3176e7SBrian Feldman options->macs = NULL; 1424a421b63SDag-Erling Smørgrav options->kex_algorithms = NULL; 143e8aafc91SKris Kennaway options->protocol = SSH_PROTO_UNKNOWN; 144a0ee8cc6SDag-Erling Smørgrav options->fwd_opts.gateway_ports = -1; 145a0ee8cc6SDag-Erling Smørgrav options->fwd_opts.streamlocal_bind_mask = (mode_t)-1; 146a0ee8cc6SDag-Erling Smørgrav options->fwd_opts.streamlocal_bind_unlink = -1; 147c2d3a559SKris Kennaway options->num_subsystems = 0; 148c2d3a559SKris Kennaway options->max_startups_begin = -1; 149c2d3a559SKris Kennaway options->max_startups_rate = -1; 150c2d3a559SKris Kennaway options->max_startups = -1; 15121e764dfSDag-Erling Smørgrav options->max_authtries = -1; 152d4af9e69SDag-Erling Smørgrav options->max_sessions = -1; 153ca3176e7SBrian Feldman options->banner = NULL; 154cf2b5f3bSDag-Erling Smørgrav options->use_dns = -1; 155ca3176e7SBrian Feldman options->client_alive_interval = -1; 156ca3176e7SBrian Feldman options->client_alive_count_max = -1; 157e146993eSDag-Erling Smørgrav options->num_authkeys_files = 0; 15821e764dfSDag-Erling Smørgrav options->num_accept_env = 0; 159b74df5b2SDag-Erling Smørgrav options->permit_tun = -1; 160333ee039SDag-Erling Smørgrav options->num_permitted_opens = -1; 161333ee039SDag-Erling Smørgrav options->adm_forced_command = NULL; 162d4af9e69SDag-Erling Smørgrav options->chroot_directory = NULL; 1636888a9beSDag-Erling Smørgrav options->authorized_keys_command = NULL; 1646888a9beSDag-Erling Smørgrav options->authorized_keys_command_user = NULL; 165b15c8340SDag-Erling Smørgrav options->revoked_keys_file = NULL; 166b15c8340SDag-Erling Smørgrav options->trusted_user_ca_keys = NULL; 167e2f6069cSDag-Erling Smørgrav options->authorized_principals_file = NULL; 168557f75e5SDag-Erling Smørgrav options->authorized_principals_command = NULL; 169557f75e5SDag-Erling Smørgrav options->authorized_principals_command_user = NULL; 1704a421b63SDag-Erling Smørgrav options->ip_qos_interactive = -1; 1714a421b63SDag-Erling Smørgrav options->ip_qos_bulk = -1; 172462c32cbSDag-Erling Smørgrav options->version_addendum = NULL; 173bc5531deSDag-Erling Smørgrav options->fingerprint_hash = -1; 174bc5531deSDag-Erling Smørgrav } 175bc5531deSDag-Erling Smørgrav 176bc5531deSDag-Erling Smørgrav /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ 177bc5531deSDag-Erling Smørgrav static int 178bc5531deSDag-Erling Smørgrav option_clear_or_none(const char *o) 179bc5531deSDag-Erling Smørgrav { 180bc5531deSDag-Erling Smørgrav return o == NULL || strcasecmp(o, "none") == 0; 181511b41d2SMark Murray } 182511b41d2SMark Murray 183*acc1a9efSDag-Erling Smørgrav static void 184*acc1a9efSDag-Erling Smørgrav assemble_algorithms(ServerOptions *o) 185*acc1a9efSDag-Erling Smørgrav { 186*acc1a9efSDag-Erling Smørgrav if (kex_assemble_names(KEX_SERVER_ENCRYPT, &o->ciphers) != 0 || 187*acc1a9efSDag-Erling Smørgrav kex_assemble_names(KEX_SERVER_MAC, &o->macs) != 0 || 188*acc1a9efSDag-Erling Smørgrav kex_assemble_names(KEX_SERVER_KEX, &o->kex_algorithms) != 0 || 189*acc1a9efSDag-Erling Smørgrav kex_assemble_names(KEX_DEFAULT_PK_ALG, 190*acc1a9efSDag-Erling Smørgrav &o->hostkeyalgorithms) != 0 || 191*acc1a9efSDag-Erling Smørgrav kex_assemble_names(KEX_DEFAULT_PK_ALG, 192*acc1a9efSDag-Erling Smørgrav &o->hostbased_key_types) != 0 || 193*acc1a9efSDag-Erling Smørgrav kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->pubkey_key_types) != 0) 194*acc1a9efSDag-Erling Smørgrav fatal("kex_assemble_names failed"); 195*acc1a9efSDag-Erling Smørgrav } 196*acc1a9efSDag-Erling Smørgrav 197511b41d2SMark Murray void 198511b41d2SMark Murray fill_default_server_options(ServerOptions *options) 199511b41d2SMark Murray { 200bc5531deSDag-Erling Smørgrav int i; 201bc5531deSDag-Erling Smørgrav 202989dd127SDag-Erling Smørgrav /* Portable-specific options */ 203cf2b5f3bSDag-Erling Smørgrav if (options->use_pam == -1) 204f0477b26SDag-Erling Smørgrav options->use_pam = 1; 205989dd127SDag-Erling Smørgrav 206989dd127SDag-Erling Smørgrav /* Standard Options */ 207ca3176e7SBrian Feldman if (options->protocol == SSH_PROTO_UNKNOWN) 208028c324aSDag-Erling Smørgrav options->protocol = SSH_PROTO_2; 209eccfee6eSDag-Erling Smørgrav if (options->protocol & SSH_PROTO_1) 210eccfee6eSDag-Erling Smørgrav error("WARNING: SSH protocol version 1 enabled"); 211ca3176e7SBrian Feldman if (options->num_host_key_files == 0) { 212ca3176e7SBrian Feldman /* fill default hostkeys for protocols */ 213ca3176e7SBrian Feldman if (options->protocol & SSH_PROTO_1) 214af12a3e7SDag-Erling Smørgrav options->host_key_files[options->num_host_key_files++] = 215af12a3e7SDag-Erling Smørgrav _PATH_HOST_KEY_FILE; 216af12a3e7SDag-Erling Smørgrav if (options->protocol & SSH_PROTO_2) { 217af12a3e7SDag-Erling Smørgrav options->host_key_files[options->num_host_key_files++] = 218d4af9e69SDag-Erling Smørgrav _PATH_HOST_RSA_KEY_FILE; 219d4af9e69SDag-Erling Smørgrav options->host_key_files[options->num_host_key_files++] = 220af12a3e7SDag-Erling Smørgrav _PATH_HOST_DSA_KEY_FILE; 2214a421b63SDag-Erling Smørgrav #ifdef OPENSSL_HAS_ECC 2224a421b63SDag-Erling Smørgrav options->host_key_files[options->num_host_key_files++] = 2234a421b63SDag-Erling Smørgrav _PATH_HOST_ECDSA_KEY_FILE; 2244a421b63SDag-Erling Smørgrav #endif 225f7167e0eSDag-Erling Smørgrav options->host_key_files[options->num_host_key_files++] = 226f7167e0eSDag-Erling Smørgrav _PATH_HOST_ED25519_KEY_FILE; 227af12a3e7SDag-Erling Smørgrav } 228ca3176e7SBrian Feldman } 229b15c8340SDag-Erling Smørgrav /* No certificates by default */ 230511b41d2SMark Murray if (options->num_ports == 0) 231511b41d2SMark Murray options->ports[options->num_ports++] = SSH_DEFAULT_PORT; 232557f75e5SDag-Erling Smørgrav if (options->address_family == -1) 233557f75e5SDag-Erling Smørgrav options->address_family = AF_UNSPEC; 234511b41d2SMark Murray if (options->listen_addrs == NULL) 235ca3176e7SBrian Feldman add_listen_addr(options, NULL, 0); 236e8aafc91SKris Kennaway if (options->pid_file == NULL) 237bc5531deSDag-Erling Smørgrav options->pid_file = xstrdup(_PATH_SSH_DAEMON_PID_FILE); 238511b41d2SMark Murray if (options->server_key_bits == -1) 239d4af9e69SDag-Erling Smørgrav options->server_key_bits = 1024; 240511b41d2SMark Murray if (options->login_grace_time == -1) 241975616f0SDag-Erling Smørgrav options->login_grace_time = 120; 242511b41d2SMark Murray if (options->key_regeneration_time == -1) 243511b41d2SMark Murray options->key_regeneration_time = 3600; 244ca3176e7SBrian Feldman if (options->permit_root_login == PERMIT_NOT_SET) 245975616f0SDag-Erling Smørgrav options->permit_root_login = PERMIT_NO; 246511b41d2SMark Murray if (options->ignore_rhosts == -1) 247fe5fd017SMark Murray options->ignore_rhosts = 1; 248511b41d2SMark Murray if (options->ignore_user_known_hosts == -1) 249511b41d2SMark Murray options->ignore_user_known_hosts = 0; 250511b41d2SMark Murray if (options->print_motd == -1) 251511b41d2SMark Murray options->print_motd = 1; 252ca3176e7SBrian Feldman if (options->print_lastlog == -1) 253ca3176e7SBrian Feldman options->print_lastlog = 1; 254511b41d2SMark Murray if (options->x11_forwarding == -1) 255975616f0SDag-Erling Smørgrav options->x11_forwarding = 1; 256511b41d2SMark Murray if (options->x11_display_offset == -1) 257fe5fd017SMark Murray options->x11_display_offset = 10; 258af12a3e7SDag-Erling Smørgrav if (options->x11_use_localhost == -1) 259af12a3e7SDag-Erling Smørgrav options->x11_use_localhost = 1; 260c2d3a559SKris Kennaway if (options->xauth_location == NULL) 261bc5531deSDag-Erling Smørgrav options->xauth_location = xstrdup(_PATH_XAUTH); 262f7167e0eSDag-Erling Smørgrav if (options->permit_tty == -1) 263f7167e0eSDag-Erling Smørgrav options->permit_tty = 1; 264a0ee8cc6SDag-Erling Smørgrav if (options->permit_user_rc == -1) 265a0ee8cc6SDag-Erling Smørgrav options->permit_user_rc = 1; 266511b41d2SMark Murray if (options->strict_modes == -1) 267511b41d2SMark Murray options->strict_modes = 1; 2681ec0d754SDag-Erling Smørgrav if (options->tcp_keep_alive == -1) 2691ec0d754SDag-Erling Smørgrav options->tcp_keep_alive = 1; 270af12a3e7SDag-Erling Smørgrav if (options->log_facility == SYSLOG_FACILITY_NOT_SET) 271511b41d2SMark Murray options->log_facility = SYSLOG_FACILITY_AUTH; 272af12a3e7SDag-Erling Smørgrav if (options->log_level == SYSLOG_LEVEL_NOT_SET) 273511b41d2SMark Murray options->log_level = SYSLOG_LEVEL_INFO; 274511b41d2SMark Murray if (options->rhosts_rsa_authentication == -1) 275fe5fd017SMark Murray options->rhosts_rsa_authentication = 0; 276ca3176e7SBrian Feldman if (options->hostbased_authentication == -1) 277ca3176e7SBrian Feldman options->hostbased_authentication = 0; 278ca3176e7SBrian Feldman if (options->hostbased_uses_name_from_packet_only == -1) 279ca3176e7SBrian Feldman options->hostbased_uses_name_from_packet_only = 0; 280511b41d2SMark Murray if (options->rsa_authentication == -1) 281511b41d2SMark Murray options->rsa_authentication = 1; 282ca3176e7SBrian Feldman if (options->pubkey_authentication == -1) 283ca3176e7SBrian Feldman options->pubkey_authentication = 1; 284989dd127SDag-Erling Smørgrav if (options->kerberos_authentication == -1) 285cf2b5f3bSDag-Erling Smørgrav options->kerberos_authentication = 0; 286af12a3e7SDag-Erling Smørgrav if (options->kerberos_or_local_passwd == -1) 287af12a3e7SDag-Erling Smørgrav options->kerberos_or_local_passwd = 1; 288af12a3e7SDag-Erling Smørgrav if (options->kerberos_ticket_cleanup == -1) 289af12a3e7SDag-Erling Smørgrav options->kerberos_ticket_cleanup = 1; 2901ec0d754SDag-Erling Smørgrav if (options->kerberos_get_afs_token == -1) 2911ec0d754SDag-Erling Smørgrav options->kerberos_get_afs_token = 0; 292cf2b5f3bSDag-Erling Smørgrav if (options->gss_authentication == -1) 293cf2b5f3bSDag-Erling Smørgrav options->gss_authentication = 0; 294cf2b5f3bSDag-Erling Smørgrav if (options->gss_cleanup_creds == -1) 295cf2b5f3bSDag-Erling Smørgrav options->gss_cleanup_creds = 1; 296557f75e5SDag-Erling Smørgrav if (options->gss_strict_acceptor == -1) 297557f75e5SDag-Erling Smørgrav options->gss_strict_acceptor = 0; 298511b41d2SMark Murray if (options->password_authentication == -1) 299b909c84bSDag-Erling Smørgrav options->password_authentication = 0; 30009958426SBrian Feldman if (options->kbd_interactive_authentication == -1) 30109958426SBrian Feldman options->kbd_interactive_authentication = 0; 302af12a3e7SDag-Erling Smørgrav if (options->challenge_response_authentication == -1) 30380241871SDag-Erling Smørgrav options->challenge_response_authentication = 1; 304511b41d2SMark Murray if (options->permit_empty_passwd == -1) 305fe5fd017SMark Murray options->permit_empty_passwd = 0; 306f388f5efSDag-Erling Smørgrav if (options->permit_user_env == -1) 307f388f5efSDag-Erling Smørgrav options->permit_user_env = 0; 308511b41d2SMark Murray if (options->use_login == -1) 309511b41d2SMark Murray options->use_login = 0; 31080628bacSDag-Erling Smørgrav if (options->compression == -1) 311d4ecd108SDag-Erling Smørgrav options->compression = COMP_DELAYED; 312e4a9863fSDag-Erling Smørgrav if (options->rekey_limit == -1) 313e4a9863fSDag-Erling Smørgrav options->rekey_limit = 0; 314e4a9863fSDag-Erling Smørgrav if (options->rekey_interval == -1) 315e4a9863fSDag-Erling Smørgrav options->rekey_interval = 0; 31609958426SBrian Feldman if (options->allow_tcp_forwarding == -1) 3176888a9beSDag-Erling Smørgrav options->allow_tcp_forwarding = FORWARD_ALLOW; 318a0ee8cc6SDag-Erling Smørgrav if (options->allow_streamlocal_forwarding == -1) 319a0ee8cc6SDag-Erling Smørgrav options->allow_streamlocal_forwarding = FORWARD_ALLOW; 320d4af9e69SDag-Erling Smørgrav if (options->allow_agent_forwarding == -1) 321d4af9e69SDag-Erling Smørgrav options->allow_agent_forwarding = 1; 322a0ee8cc6SDag-Erling Smørgrav if (options->fwd_opts.gateway_ports == -1) 323a0ee8cc6SDag-Erling Smørgrav options->fwd_opts.gateway_ports = 0; 324c2d3a559SKris Kennaway if (options->max_startups == -1) 3256888a9beSDag-Erling Smørgrav options->max_startups = 100; 326c2d3a559SKris Kennaway if (options->max_startups_rate == -1) 3276888a9beSDag-Erling Smørgrav options->max_startups_rate = 30; /* 30% */ 328c2d3a559SKris Kennaway if (options->max_startups_begin == -1) 3296888a9beSDag-Erling Smørgrav options->max_startups_begin = 10; 33021e764dfSDag-Erling Smørgrav if (options->max_authtries == -1) 33121e764dfSDag-Erling Smørgrav options->max_authtries = DEFAULT_AUTH_FAIL_MAX; 332d4af9e69SDag-Erling Smørgrav if (options->max_sessions == -1) 333d4af9e69SDag-Erling Smørgrav options->max_sessions = DEFAULT_SESSIONS_MAX; 334cf2b5f3bSDag-Erling Smørgrav if (options->use_dns == -1) 335c4cd1fa4SDag-Erling Smørgrav options->use_dns = 1; 336ca3176e7SBrian Feldman if (options->client_alive_interval == -1) 337ca3176e7SBrian Feldman options->client_alive_interval = 0; 338ca3176e7SBrian Feldman if (options->client_alive_count_max == -1) 339ca3176e7SBrian Feldman options->client_alive_count_max = 3; 340e146993eSDag-Erling Smørgrav if (options->num_authkeys_files == 0) { 341e146993eSDag-Erling Smørgrav options->authorized_keys_files[options->num_authkeys_files++] = 342e146993eSDag-Erling Smørgrav xstrdup(_PATH_SSH_USER_PERMITTED_KEYS); 343e146993eSDag-Erling Smørgrav options->authorized_keys_files[options->num_authkeys_files++] = 344e146993eSDag-Erling Smørgrav xstrdup(_PATH_SSH_USER_PERMITTED_KEYS2); 345af12a3e7SDag-Erling Smørgrav } 346b74df5b2SDag-Erling Smørgrav if (options->permit_tun == -1) 347b74df5b2SDag-Erling Smørgrav options->permit_tun = SSH_TUNMODE_NO; 3484a421b63SDag-Erling Smørgrav if (options->ip_qos_interactive == -1) 3494a421b63SDag-Erling Smørgrav options->ip_qos_interactive = IPTOS_LOWDELAY; 3504a421b63SDag-Erling Smørgrav if (options->ip_qos_bulk == -1) 3514a421b63SDag-Erling Smørgrav options->ip_qos_bulk = IPTOS_THROUGHPUT; 352462c32cbSDag-Erling Smørgrav if (options->version_addendum == NULL) 353462c32cbSDag-Erling Smørgrav options->version_addendum = xstrdup(SSH_VERSION_FREEBSD); 354a0ee8cc6SDag-Erling Smørgrav if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1) 355a0ee8cc6SDag-Erling Smørgrav options->fwd_opts.streamlocal_bind_mask = 0177; 356a0ee8cc6SDag-Erling Smørgrav if (options->fwd_opts.streamlocal_bind_unlink == -1) 357a0ee8cc6SDag-Erling Smørgrav options->fwd_opts.streamlocal_bind_unlink = 0; 358bc5531deSDag-Erling Smørgrav if (options->fingerprint_hash == -1) 359bc5531deSDag-Erling Smørgrav options->fingerprint_hash = SSH_FP_HASH_DEFAULT; 360eccfee6eSDag-Erling Smørgrav 361*acc1a9efSDag-Erling Smørgrav assemble_algorithms(options); 362eccfee6eSDag-Erling Smørgrav 363*acc1a9efSDag-Erling Smørgrav /* Turn privilege separation and sandboxing on by default */ 364462c32cbSDag-Erling Smørgrav if (use_privsep == -1) 3652b1970f3SDag-Erling Smørgrav use_privsep = PRIVSEP_ON; 366462c32cbSDag-Erling Smørgrav 367bc5531deSDag-Erling Smørgrav #define CLEAR_ON_NONE(v) \ 368bc5531deSDag-Erling Smørgrav do { \ 369bc5531deSDag-Erling Smørgrav if (option_clear_or_none(v)) { \ 370bc5531deSDag-Erling Smørgrav free(v); \ 371bc5531deSDag-Erling Smørgrav v = NULL; \ 372bc5531deSDag-Erling Smørgrav } \ 373bc5531deSDag-Erling Smørgrav } while(0) 374bc5531deSDag-Erling Smørgrav CLEAR_ON_NONE(options->pid_file); 375bc5531deSDag-Erling Smørgrav CLEAR_ON_NONE(options->xauth_location); 376bc5531deSDag-Erling Smørgrav CLEAR_ON_NONE(options->banner); 377bc5531deSDag-Erling Smørgrav CLEAR_ON_NONE(options->trusted_user_ca_keys); 378bc5531deSDag-Erling Smørgrav CLEAR_ON_NONE(options->revoked_keys_file); 379557f75e5SDag-Erling Smørgrav CLEAR_ON_NONE(options->authorized_principals_file); 380*acc1a9efSDag-Erling Smørgrav CLEAR_ON_NONE(options->adm_forced_command); 381*acc1a9efSDag-Erling Smørgrav CLEAR_ON_NONE(options->chroot_directory); 382bc5531deSDag-Erling Smørgrav for (i = 0; i < options->num_host_key_files; i++) 383bc5531deSDag-Erling Smørgrav CLEAR_ON_NONE(options->host_key_files[i]); 384bc5531deSDag-Erling Smørgrav for (i = 0; i < options->num_host_cert_files; i++) 385bc5531deSDag-Erling Smørgrav CLEAR_ON_NONE(options->host_cert_files[i]); 386bc5531deSDag-Erling Smørgrav #undef CLEAR_ON_NONE 387bc5531deSDag-Erling Smørgrav 388462c32cbSDag-Erling Smørgrav #ifndef HAVE_MMAP 389462c32cbSDag-Erling Smørgrav if (use_privsep && options->compression == 1) { 390462c32cbSDag-Erling Smørgrav error("This platform does not support both privilege " 391462c32cbSDag-Erling Smørgrav "separation and compression"); 392462c32cbSDag-Erling Smørgrav error("Compression disabled"); 393462c32cbSDag-Erling Smørgrav options->compression = 0; 394462c32cbSDag-Erling Smørgrav } 395462c32cbSDag-Erling Smørgrav #endif 396462c32cbSDag-Erling Smørgrav 397511b41d2SMark Murray } 398511b41d2SMark Murray 399511b41d2SMark Murray /* Keyword tokens. */ 400511b41d2SMark Murray typedef enum { 401511b41d2SMark Murray sBadOption, /* == unknown option */ 402989dd127SDag-Erling Smørgrav /* Portable-specific options */ 403cf2b5f3bSDag-Erling Smørgrav sUsePAM, 404989dd127SDag-Erling Smørgrav /* Standard Options */ 405bc5531deSDag-Erling Smørgrav sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, 406bc5531deSDag-Erling Smørgrav sKeyRegenerationTime, sPermitRootLogin, sLogFacility, sLogLevel, 407cf2b5f3bSDag-Erling Smørgrav sRhostsRSAAuthentication, sRSAAuthentication, 408af12a3e7SDag-Erling Smørgrav sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, 4091ec0d754SDag-Erling Smørgrav sKerberosGetAFSToken, 410cf2b5f3bSDag-Erling Smørgrav sKerberosTgtPassing, sChallengeResponseAuthentication, 411aa49c926SDag-Erling Smørgrav sPasswordAuthentication, sKbdInteractiveAuthentication, 412aa49c926SDag-Erling Smørgrav sListenAddress, sAddressFamily, 413ca3176e7SBrian Feldman sPrintMotd, sPrintLastLog, sIgnoreRhosts, 414af12a3e7SDag-Erling Smørgrav sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, 415f7167e0eSDag-Erling Smørgrav sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive, 416f388f5efSDag-Erling Smørgrav sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression, 417e4a9863fSDag-Erling Smørgrav sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, 418ca3176e7SBrian Feldman sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, 419bc5531deSDag-Erling Smørgrav sGatewayPorts, sPubkeyAuthentication, sPubkeyAcceptedKeyTypes, 420bc5531deSDag-Erling Smørgrav sXAuthLocation, sSubsystem, sMaxStartups, sMaxAuthTries, sMaxSessions, 421cf2b5f3bSDag-Erling Smørgrav sBanner, sUseDNS, sHostbasedAuthentication, 422bc5531deSDag-Erling Smørgrav sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, 423eccfee6eSDag-Erling Smørgrav sHostKeyAlgorithms, 424bc5531deSDag-Erling Smørgrav sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, 425557f75e5SDag-Erling Smørgrav sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, 426557f75e5SDag-Erling Smørgrav sAcceptEnv, sPermitTunnel, 427d4af9e69SDag-Erling Smørgrav sMatch, sPermitOpen, sForceCommand, sChrootDirectory, 428d4af9e69SDag-Erling Smørgrav sUsePrivilegeSeparation, sAllowAgentForwarding, 429b83788ffSDag-Erling Smørgrav sHostCertificate, 430e2f6069cSDag-Erling Smørgrav sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, 431557f75e5SDag-Erling Smørgrav sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser, 432462c32cbSDag-Erling Smørgrav sKexAlgorithms, sIPQoS, sVersionAddendum, 4336888a9beSDag-Erling Smørgrav sAuthorizedKeysCommand, sAuthorizedKeysCommandUser, 434a0ee8cc6SDag-Erling Smørgrav sAuthenticationMethods, sHostKeyAgent, sPermitUserRC, 435a0ee8cc6SDag-Erling Smørgrav sStreamLocalBindMask, sStreamLocalBindUnlink, 436bc5531deSDag-Erling Smørgrav sAllowStreamLocalForwarding, sFingerprintHash, 437cf2b5f3bSDag-Erling Smørgrav sDeprecated, sUnsupported 438511b41d2SMark Murray } ServerOpCodes; 439511b41d2SMark Murray 440333ee039SDag-Erling Smørgrav #define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */ 441333ee039SDag-Erling Smørgrav #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */ 442333ee039SDag-Erling Smørgrav #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH) 443333ee039SDag-Erling Smørgrav 444511b41d2SMark Murray /* Textual representation of the tokens. */ 445511b41d2SMark Murray static struct { 446511b41d2SMark Murray const char *name; 447511b41d2SMark Murray ServerOpCodes opcode; 448333ee039SDag-Erling Smørgrav u_int flags; 449511b41d2SMark Murray } keywords[] = { 450989dd127SDag-Erling Smørgrav /* Portable-specific options */ 451cf2b5f3bSDag-Erling Smørgrav #ifdef USE_PAM 452333ee039SDag-Erling Smørgrav { "usepam", sUsePAM, SSHCFG_GLOBAL }, 453cf2b5f3bSDag-Erling Smørgrav #else 454333ee039SDag-Erling Smørgrav { "usepam", sUnsupported, SSHCFG_GLOBAL }, 455975616f0SDag-Erling Smørgrav #endif 456333ee039SDag-Erling Smørgrav { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, 457989dd127SDag-Erling Smørgrav /* Standard Options */ 458333ee039SDag-Erling Smørgrav { "port", sPort, SSHCFG_GLOBAL }, 459333ee039SDag-Erling Smørgrav { "hostkey", sHostKeyFile, SSHCFG_GLOBAL }, 460333ee039SDag-Erling Smørgrav { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */ 461e4a9863fSDag-Erling Smørgrav { "hostkeyagent", sHostKeyAgent, SSHCFG_GLOBAL }, 462333ee039SDag-Erling Smørgrav { "pidfile", sPidFile, SSHCFG_GLOBAL }, 463333ee039SDag-Erling Smørgrav { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL }, 464333ee039SDag-Erling Smørgrav { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL }, 465333ee039SDag-Erling Smørgrav { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL }, 466d4af9e69SDag-Erling Smørgrav { "permitrootlogin", sPermitRootLogin, SSHCFG_ALL }, 467333ee039SDag-Erling Smørgrav { "syslogfacility", sLogFacility, SSHCFG_GLOBAL }, 468333ee039SDag-Erling Smørgrav { "loglevel", sLogLevel, SSHCFG_GLOBAL }, 469333ee039SDag-Erling Smørgrav { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL }, 470d4af9e69SDag-Erling Smørgrav { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_ALL }, 471d4af9e69SDag-Erling Smørgrav { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL }, 472e2f6069cSDag-Erling Smørgrav { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_ALL }, 473bc5531deSDag-Erling Smørgrav { "hostbasedacceptedkeytypes", sHostbasedAcceptedKeyTypes, SSHCFG_ALL }, 474eccfee6eSDag-Erling Smørgrav { "hostkeyalgorithms", sHostKeyAlgorithms, SSHCFG_GLOBAL }, 475d4af9e69SDag-Erling Smørgrav { "rsaauthentication", sRSAAuthentication, SSHCFG_ALL }, 476d4af9e69SDag-Erling Smørgrav { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL }, 477bc5531deSDag-Erling Smørgrav { "pubkeyacceptedkeytypes", sPubkeyAcceptedKeyTypes, SSHCFG_ALL }, 478333ee039SDag-Erling Smørgrav { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */ 479cf2b5f3bSDag-Erling Smørgrav #ifdef KRB5 480d4af9e69SDag-Erling Smørgrav { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL }, 481333ee039SDag-Erling Smørgrav { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL }, 482333ee039SDag-Erling Smørgrav { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL }, 4831ec0d754SDag-Erling Smørgrav #ifdef USE_AFS 484333ee039SDag-Erling Smørgrav { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL }, 4851ec0d754SDag-Erling Smørgrav #else 486333ee039SDag-Erling Smørgrav { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, 4871ec0d754SDag-Erling Smørgrav #endif 488cf2b5f3bSDag-Erling Smørgrav #else 489d4af9e69SDag-Erling Smørgrav { "kerberosauthentication", sUnsupported, SSHCFG_ALL }, 490333ee039SDag-Erling Smørgrav { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL }, 491333ee039SDag-Erling Smørgrav { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL }, 492333ee039SDag-Erling Smørgrav { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, 493cb96ab36SAssar Westerlund #endif 494333ee039SDag-Erling Smørgrav { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, 495333ee039SDag-Erling Smørgrav { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, 496cf2b5f3bSDag-Erling Smørgrav #ifdef GSSAPI 497d4af9e69SDag-Erling Smørgrav { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, 498333ee039SDag-Erling Smørgrav { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, 499557f75e5SDag-Erling Smørgrav { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, 500cf2b5f3bSDag-Erling Smørgrav #else 501d4af9e69SDag-Erling Smørgrav { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, 502333ee039SDag-Erling Smørgrav { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, 503557f75e5SDag-Erling Smørgrav { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, 504511b41d2SMark Murray #endif 505d4af9e69SDag-Erling Smørgrav { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, 506d4af9e69SDag-Erling Smørgrav { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, 507333ee039SDag-Erling Smørgrav { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, 508333ee039SDag-Erling Smørgrav { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */ 509333ee039SDag-Erling Smørgrav { "checkmail", sDeprecated, SSHCFG_GLOBAL }, 510333ee039SDag-Erling Smørgrav { "listenaddress", sListenAddress, SSHCFG_GLOBAL }, 511333ee039SDag-Erling Smørgrav { "addressfamily", sAddressFamily, SSHCFG_GLOBAL }, 512333ee039SDag-Erling Smørgrav { "printmotd", sPrintMotd, SSHCFG_GLOBAL }, 513*acc1a9efSDag-Erling Smørgrav #ifdef DISABLE_LASTLOG 514*acc1a9efSDag-Erling Smørgrav { "printlastlog", sUnsupported, SSHCFG_GLOBAL }, 515*acc1a9efSDag-Erling Smørgrav #else 516333ee039SDag-Erling Smørgrav { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL }, 517*acc1a9efSDag-Erling Smørgrav #endif 518333ee039SDag-Erling Smørgrav { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL }, 519333ee039SDag-Erling Smørgrav { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL }, 520333ee039SDag-Erling Smørgrav { "x11forwarding", sX11Forwarding, SSHCFG_ALL }, 521333ee039SDag-Erling Smørgrav { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL }, 522333ee039SDag-Erling Smørgrav { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL }, 523333ee039SDag-Erling Smørgrav { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL }, 524333ee039SDag-Erling Smørgrav { "strictmodes", sStrictModes, SSHCFG_GLOBAL }, 525cce7d346SDag-Erling Smørgrav { "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL }, 526333ee039SDag-Erling Smørgrav { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL }, 527333ee039SDag-Erling Smørgrav { "uselogin", sUseLogin, SSHCFG_GLOBAL }, 528333ee039SDag-Erling Smørgrav { "compression", sCompression, SSHCFG_GLOBAL }, 529e4a9863fSDag-Erling Smørgrav { "rekeylimit", sRekeyLimit, SSHCFG_ALL }, 530333ee039SDag-Erling Smørgrav { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, 531333ee039SDag-Erling Smørgrav { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */ 532333ee039SDag-Erling Smørgrav { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL }, 533d4af9e69SDag-Erling Smørgrav { "allowagentforwarding", sAllowAgentForwarding, SSHCFG_ALL }, 534462c32cbSDag-Erling Smørgrav { "allowusers", sAllowUsers, SSHCFG_ALL }, 535462c32cbSDag-Erling Smørgrav { "denyusers", sDenyUsers, SSHCFG_ALL }, 536462c32cbSDag-Erling Smørgrav { "allowgroups", sAllowGroups, SSHCFG_ALL }, 537462c32cbSDag-Erling Smørgrav { "denygroups", sDenyGroups, SSHCFG_ALL }, 538333ee039SDag-Erling Smørgrav { "ciphers", sCiphers, SSHCFG_GLOBAL }, 539333ee039SDag-Erling Smørgrav { "macs", sMacs, SSHCFG_GLOBAL }, 540333ee039SDag-Erling Smørgrav { "protocol", sProtocol, SSHCFG_GLOBAL }, 541333ee039SDag-Erling Smørgrav { "gatewayports", sGatewayPorts, SSHCFG_ALL }, 542333ee039SDag-Erling Smørgrav { "subsystem", sSubsystem, SSHCFG_GLOBAL }, 543333ee039SDag-Erling Smørgrav { "maxstartups", sMaxStartups, SSHCFG_GLOBAL }, 544d4af9e69SDag-Erling Smørgrav { "maxauthtries", sMaxAuthTries, SSHCFG_ALL }, 545d4af9e69SDag-Erling Smørgrav { "maxsessions", sMaxSessions, SSHCFG_ALL }, 546d4af9e69SDag-Erling Smørgrav { "banner", sBanner, SSHCFG_ALL }, 547333ee039SDag-Erling Smørgrav { "usedns", sUseDNS, SSHCFG_GLOBAL }, 548333ee039SDag-Erling Smørgrav { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL }, 549333ee039SDag-Erling Smørgrav { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL }, 550333ee039SDag-Erling Smørgrav { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL }, 551333ee039SDag-Erling Smørgrav { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL }, 552e2f6069cSDag-Erling Smørgrav { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_ALL }, 553e146993eSDag-Erling Smørgrav { "authorizedkeysfile2", sDeprecated, SSHCFG_ALL }, 554333ee039SDag-Erling Smørgrav { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL}, 555462c32cbSDag-Erling Smørgrav { "acceptenv", sAcceptEnv, SSHCFG_ALL }, 556e2f6069cSDag-Erling Smørgrav { "permittunnel", sPermitTunnel, SSHCFG_ALL }, 557f7167e0eSDag-Erling Smørgrav { "permittty", sPermitTTY, SSHCFG_ALL }, 558a0ee8cc6SDag-Erling Smørgrav { "permituserrc", sPermitUserRC, SSHCFG_ALL }, 559333ee039SDag-Erling Smørgrav { "match", sMatch, SSHCFG_ALL }, 560333ee039SDag-Erling Smørgrav { "permitopen", sPermitOpen, SSHCFG_ALL }, 561333ee039SDag-Erling Smørgrav { "forcecommand", sForceCommand, SSHCFG_ALL }, 562d4af9e69SDag-Erling Smørgrav { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, 563b15c8340SDag-Erling Smørgrav { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, 564b15c8340SDag-Erling Smørgrav { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, 565b15c8340SDag-Erling Smørgrav { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, 566e2f6069cSDag-Erling Smørgrav { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, 5674a421b63SDag-Erling Smørgrav { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, 5684a421b63SDag-Erling Smørgrav { "ipqos", sIPQoS, SSHCFG_ALL }, 5696888a9beSDag-Erling Smørgrav { "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL }, 5706888a9beSDag-Erling Smørgrav { "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL }, 571557f75e5SDag-Erling Smørgrav { "authorizedprincipalscommand", sAuthorizedPrincipalsCommand, SSHCFG_ALL }, 572557f75e5SDag-Erling Smørgrav { "authorizedprincipalscommanduser", sAuthorizedPrincipalsCommandUser, SSHCFG_ALL }, 573462c32cbSDag-Erling Smørgrav { "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL }, 5746888a9beSDag-Erling Smørgrav { "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL }, 575a0ee8cc6SDag-Erling Smørgrav { "streamlocalbindmask", sStreamLocalBindMask, SSHCFG_ALL }, 576a0ee8cc6SDag-Erling Smørgrav { "streamlocalbindunlink", sStreamLocalBindUnlink, SSHCFG_ALL }, 577a0ee8cc6SDag-Erling Smørgrav { "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL }, 578bc5531deSDag-Erling Smørgrav { "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL }, 5796f351346SDag-Erling Smørgrav { "noneenabled", sUnsupported, SSHCFG_ALL }, 5809860d96eSDag-Erling Smørgrav { "hpndisabled", sDeprecated, SSHCFG_ALL }, 5819860d96eSDag-Erling Smørgrav { "hpnbuffersize", sDeprecated, SSHCFG_ALL }, 5829860d96eSDag-Erling Smørgrav { "tcprcvbufpoll", sDeprecated, SSHCFG_ALL }, 583333ee039SDag-Erling Smørgrav { NULL, sBadOption, 0 } 584511b41d2SMark Murray }; 585511b41d2SMark Murray 586d4af9e69SDag-Erling Smørgrav static struct { 587d4af9e69SDag-Erling Smørgrav int val; 588d4af9e69SDag-Erling Smørgrav char *text; 589d4af9e69SDag-Erling Smørgrav } tunmode_desc[] = { 590d4af9e69SDag-Erling Smørgrav { SSH_TUNMODE_NO, "no" }, 591d4af9e69SDag-Erling Smørgrav { SSH_TUNMODE_POINTOPOINT, "point-to-point" }, 592d4af9e69SDag-Erling Smørgrav { SSH_TUNMODE_ETHERNET, "ethernet" }, 593d4af9e69SDag-Erling Smørgrav { SSH_TUNMODE_YES, "yes" }, 594d4af9e69SDag-Erling Smørgrav { -1, NULL } 595d4af9e69SDag-Erling Smørgrav }; 596d4af9e69SDag-Erling Smørgrav 597511b41d2SMark Murray /* 598ca3176e7SBrian Feldman * Returns the number of the token pointed to by cp or sBadOption. 599511b41d2SMark Murray */ 600511b41d2SMark Murray 601511b41d2SMark Murray static ServerOpCodes 602511b41d2SMark Murray parse_token(const char *cp, const char *filename, 603333ee039SDag-Erling Smørgrav int linenum, u_int *flags) 604511b41d2SMark Murray { 605ca3176e7SBrian Feldman u_int i; 606511b41d2SMark Murray 607511b41d2SMark Murray for (i = 0; keywords[i].name; i++) 608333ee039SDag-Erling Smørgrav if (strcasecmp(cp, keywords[i].name) == 0) { 609333ee039SDag-Erling Smørgrav *flags = keywords[i].flags; 610511b41d2SMark Murray return keywords[i].opcode; 611333ee039SDag-Erling Smørgrav } 612511b41d2SMark Murray 613ca3176e7SBrian Feldman error("%s: line %d: Bad configuration option: %s", 614511b41d2SMark Murray filename, linenum, cp); 615511b41d2SMark Murray return sBadOption; 616511b41d2SMark Murray } 617511b41d2SMark Murray 618b15c8340SDag-Erling Smørgrav char * 619b15c8340SDag-Erling Smørgrav derelativise_path(const char *path) 620b15c8340SDag-Erling Smørgrav { 621bc5531deSDag-Erling Smørgrav char *expanded, *ret, cwd[PATH_MAX]; 622b15c8340SDag-Erling Smørgrav 623bc5531deSDag-Erling Smørgrav if (strcasecmp(path, "none") == 0) 624bc5531deSDag-Erling Smørgrav return xstrdup("none"); 625b15c8340SDag-Erling Smørgrav expanded = tilde_expand_filename(path, getuid()); 626b15c8340SDag-Erling Smørgrav if (*expanded == '/') 627b15c8340SDag-Erling Smørgrav return expanded; 6288ad9b54aSDag-Erling Smørgrav if (getcwd(cwd, sizeof(cwd)) == NULL) 629b15c8340SDag-Erling Smørgrav fatal("%s: getcwd: %s", __func__, strerror(errno)); 630b15c8340SDag-Erling Smørgrav xasprintf(&ret, "%s/%s", cwd, expanded); 631e4a9863fSDag-Erling Smørgrav free(expanded); 632b15c8340SDag-Erling Smørgrav return ret; 633b15c8340SDag-Erling Smørgrav } 634b15c8340SDag-Erling Smørgrav 635af12a3e7SDag-Erling Smørgrav static void 636cce7d346SDag-Erling Smørgrav add_listen_addr(ServerOptions *options, char *addr, int port) 637511b41d2SMark Murray { 638d4ecd108SDag-Erling Smørgrav u_int i; 639511b41d2SMark Murray 640ca3176e7SBrian Feldman if (port == 0) 641ca3176e7SBrian Feldman for (i = 0; i < options->num_ports; i++) 642ca3176e7SBrian Feldman add_one_listen_addr(options, addr, options->ports[i]); 643ca3176e7SBrian Feldman else 644ca3176e7SBrian Feldman add_one_listen_addr(options, addr, port); 645ca3176e7SBrian Feldman } 646ca3176e7SBrian Feldman 647af12a3e7SDag-Erling Smørgrav static void 648cce7d346SDag-Erling Smørgrav add_one_listen_addr(ServerOptions *options, char *addr, int port) 649ca3176e7SBrian Feldman { 650ca3176e7SBrian Feldman struct addrinfo hints, *ai, *aitop; 651ca3176e7SBrian Feldman char strport[NI_MAXSERV]; 652ca3176e7SBrian Feldman int gaierr; 653ca3176e7SBrian Feldman 654511b41d2SMark Murray memset(&hints, 0, sizeof(hints)); 655aa49c926SDag-Erling Smørgrav hints.ai_family = options->address_family; 656511b41d2SMark Murray hints.ai_socktype = SOCK_STREAM; 657511b41d2SMark Murray hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0; 658cce7d346SDag-Erling Smørgrav snprintf(strport, sizeof strport, "%d", port); 659511b41d2SMark Murray if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0) 660ca3176e7SBrian Feldman fatal("bad addr or host: %s (%s)", 661511b41d2SMark Murray addr ? addr : "<NULL>", 662d4af9e69SDag-Erling Smørgrav ssh_gai_strerror(gaierr)); 663511b41d2SMark Murray for (ai = aitop; ai->ai_next; ai = ai->ai_next) 664511b41d2SMark Murray ; 665511b41d2SMark Murray ai->ai_next = options->listen_addrs; 666511b41d2SMark Murray options->listen_addrs = aitop; 667511b41d2SMark Murray } 668511b41d2SMark Murray 669557f75e5SDag-Erling Smørgrav /* 670557f75e5SDag-Erling Smørgrav * Queue a ListenAddress to be processed once we have all of the Ports 671557f75e5SDag-Erling Smørgrav * and AddressFamily options. 672557f75e5SDag-Erling Smørgrav */ 673557f75e5SDag-Erling Smørgrav static void 674557f75e5SDag-Erling Smørgrav queue_listen_addr(ServerOptions *options, char *addr, int port) 675557f75e5SDag-Erling Smørgrav { 676557f75e5SDag-Erling Smørgrav options->queued_listen_addrs = xreallocarray( 677557f75e5SDag-Erling Smørgrav options->queued_listen_addrs, options->num_queued_listens + 1, 678557f75e5SDag-Erling Smørgrav sizeof(addr)); 679557f75e5SDag-Erling Smørgrav options->queued_listen_ports = xreallocarray( 680557f75e5SDag-Erling Smørgrav options->queued_listen_ports, options->num_queued_listens + 1, 681557f75e5SDag-Erling Smørgrav sizeof(port)); 682557f75e5SDag-Erling Smørgrav options->queued_listen_addrs[options->num_queued_listens] = 683557f75e5SDag-Erling Smørgrav xstrdup(addr); 684557f75e5SDag-Erling Smørgrav options->queued_listen_ports[options->num_queued_listens] = port; 685557f75e5SDag-Erling Smørgrav options->num_queued_listens++; 686557f75e5SDag-Erling Smørgrav } 687557f75e5SDag-Erling Smørgrav 688557f75e5SDag-Erling Smørgrav /* 689557f75e5SDag-Erling Smørgrav * Process queued (text) ListenAddress entries. 690557f75e5SDag-Erling Smørgrav */ 691557f75e5SDag-Erling Smørgrav static void 692557f75e5SDag-Erling Smørgrav process_queued_listen_addrs(ServerOptions *options) 693557f75e5SDag-Erling Smørgrav { 694557f75e5SDag-Erling Smørgrav u_int i; 695557f75e5SDag-Erling Smørgrav 696557f75e5SDag-Erling Smørgrav if (options->num_ports == 0) 697557f75e5SDag-Erling Smørgrav options->ports[options->num_ports++] = SSH_DEFAULT_PORT; 698557f75e5SDag-Erling Smørgrav if (options->address_family == -1) 699557f75e5SDag-Erling Smørgrav options->address_family = AF_UNSPEC; 700557f75e5SDag-Erling Smørgrav 701557f75e5SDag-Erling Smørgrav for (i = 0; i < options->num_queued_listens; i++) { 702557f75e5SDag-Erling Smørgrav add_listen_addr(options, options->queued_listen_addrs[i], 703557f75e5SDag-Erling Smørgrav options->queued_listen_ports[i]); 704557f75e5SDag-Erling Smørgrav free(options->queued_listen_addrs[i]); 705557f75e5SDag-Erling Smørgrav options->queued_listen_addrs[i] = NULL; 706557f75e5SDag-Erling Smørgrav } 707557f75e5SDag-Erling Smørgrav free(options->queued_listen_addrs); 708557f75e5SDag-Erling Smørgrav options->queued_listen_addrs = NULL; 709557f75e5SDag-Erling Smørgrav free(options->queued_listen_ports); 710557f75e5SDag-Erling Smørgrav options->queued_listen_ports = NULL; 711557f75e5SDag-Erling Smørgrav options->num_queued_listens = 0; 712557f75e5SDag-Erling Smørgrav } 713557f75e5SDag-Erling Smørgrav 714462c32cbSDag-Erling Smørgrav struct connection_info * 715462c32cbSDag-Erling Smørgrav get_connection_info(int populate, int use_dns) 716462c32cbSDag-Erling Smørgrav { 717462c32cbSDag-Erling Smørgrav static struct connection_info ci; 718462c32cbSDag-Erling Smørgrav 719462c32cbSDag-Erling Smørgrav if (!populate) 720462c32cbSDag-Erling Smørgrav return &ci; 721462c32cbSDag-Erling Smørgrav ci.host = get_canonical_hostname(use_dns); 722462c32cbSDag-Erling Smørgrav ci.address = get_remote_ipaddr(); 723462c32cbSDag-Erling Smørgrav ci.laddress = get_local_ipaddr(packet_get_connection_in()); 724462c32cbSDag-Erling Smørgrav ci.lport = get_local_port(); 725462c32cbSDag-Erling Smørgrav return &ci; 726462c32cbSDag-Erling Smørgrav } 727462c32cbSDag-Erling Smørgrav 728333ee039SDag-Erling Smørgrav /* 729333ee039SDag-Erling Smørgrav * The strategy for the Match blocks is that the config file is parsed twice. 730333ee039SDag-Erling Smørgrav * 731333ee039SDag-Erling Smørgrav * The first time is at startup. activep is initialized to 1 and the 732333ee039SDag-Erling Smørgrav * directives in the global context are processed and acted on. Hitting a 733333ee039SDag-Erling Smørgrav * Match directive unsets activep and the directives inside the block are 734333ee039SDag-Erling Smørgrav * checked for syntax only. 735333ee039SDag-Erling Smørgrav * 736333ee039SDag-Erling Smørgrav * The second time is after a connection has been established but before 737333ee039SDag-Erling Smørgrav * authentication. activep is initialized to 2 and global config directives 738333ee039SDag-Erling Smørgrav * are ignored since they have already been processed. If the criteria in a 739333ee039SDag-Erling Smørgrav * Match block is met, activep is set and the subsequent directives 740333ee039SDag-Erling Smørgrav * processed and actioned until EOF or another Match block unsets it. Any 741333ee039SDag-Erling Smørgrav * options set are copied into the main server config. 742333ee039SDag-Erling Smørgrav * 743333ee039SDag-Erling Smørgrav * Potential additions/improvements: 744333ee039SDag-Erling Smørgrav * - Add Match support for pre-kex directives, eg Protocol, Ciphers. 745333ee039SDag-Erling Smørgrav * 746333ee039SDag-Erling Smørgrav * - Add a Tag directive (idea from David Leonard) ala pf, eg: 747333ee039SDag-Erling Smørgrav * Match Address 192.168.0.* 748333ee039SDag-Erling Smørgrav * Tag trusted 749333ee039SDag-Erling Smørgrav * Match Group wheel 750333ee039SDag-Erling Smørgrav * Tag trusted 751333ee039SDag-Erling Smørgrav * Match Tag trusted 752333ee039SDag-Erling Smørgrav * AllowTcpForwarding yes 753333ee039SDag-Erling Smørgrav * GatewayPorts clientspecified 754333ee039SDag-Erling Smørgrav * [...] 755333ee039SDag-Erling Smørgrav * 756333ee039SDag-Erling Smørgrav * - Add a PermittedChannelRequests directive 757333ee039SDag-Erling Smørgrav * Match Group shell 758333ee039SDag-Erling Smørgrav * PermittedChannelRequests session,forwarded-tcpip 759333ee039SDag-Erling Smørgrav */ 760333ee039SDag-Erling Smørgrav 761333ee039SDag-Erling Smørgrav static int 762333ee039SDag-Erling Smørgrav match_cfg_line_group(const char *grps, int line, const char *user) 763333ee039SDag-Erling Smørgrav { 764333ee039SDag-Erling Smørgrav int result = 0; 765333ee039SDag-Erling Smørgrav struct passwd *pw; 766333ee039SDag-Erling Smørgrav 767333ee039SDag-Erling Smørgrav if (user == NULL) 768333ee039SDag-Erling Smørgrav goto out; 769333ee039SDag-Erling Smørgrav 770333ee039SDag-Erling Smørgrav if ((pw = getpwnam(user)) == NULL) { 771333ee039SDag-Erling Smørgrav debug("Can't match group at line %d because user %.100s does " 772333ee039SDag-Erling Smørgrav "not exist", line, user); 773333ee039SDag-Erling Smørgrav } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) { 774333ee039SDag-Erling Smørgrav debug("Can't Match group because user %.100s not in any group " 775333ee039SDag-Erling Smørgrav "at line %d", user, line); 776d4af9e69SDag-Erling Smørgrav } else if (ga_match_pattern_list(grps) != 1) { 777d4af9e69SDag-Erling Smørgrav debug("user %.100s does not match group list %.100s at line %d", 778d4af9e69SDag-Erling Smørgrav user, grps, line); 779333ee039SDag-Erling Smørgrav } else { 780d4af9e69SDag-Erling Smørgrav debug("user %.100s matched group list %.100s at line %d", user, 781d4af9e69SDag-Erling Smørgrav grps, line); 782333ee039SDag-Erling Smørgrav result = 1; 783333ee039SDag-Erling Smørgrav } 784333ee039SDag-Erling Smørgrav out: 785333ee039SDag-Erling Smørgrav ga_free(); 786333ee039SDag-Erling Smørgrav return result; 787333ee039SDag-Erling Smørgrav } 788333ee039SDag-Erling Smørgrav 789462c32cbSDag-Erling Smørgrav /* 7906888a9beSDag-Erling Smørgrav * All of the attributes on a single Match line are ANDed together, so we need 791f7167e0eSDag-Erling Smørgrav * to check every attribute and set the result to zero if any attribute does 7926888a9beSDag-Erling Smørgrav * not match. 793462c32cbSDag-Erling Smørgrav */ 794333ee039SDag-Erling Smørgrav static int 795462c32cbSDag-Erling Smørgrav match_cfg_line(char **condition, int line, struct connection_info *ci) 796333ee039SDag-Erling Smørgrav { 797f7167e0eSDag-Erling Smørgrav int result = 1, attributes = 0, port; 798333ee039SDag-Erling Smørgrav char *arg, *attrib, *cp = *condition; 799333ee039SDag-Erling Smørgrav 800462c32cbSDag-Erling Smørgrav if (ci == NULL) 801333ee039SDag-Erling Smørgrav debug3("checking syntax for 'Match %s'", cp); 802333ee039SDag-Erling Smørgrav else 803462c32cbSDag-Erling Smørgrav debug3("checking match for '%s' user %s host %s addr %s " 804462c32cbSDag-Erling Smørgrav "laddr %s lport %d", cp, ci->user ? ci->user : "(null)", 805462c32cbSDag-Erling Smørgrav ci->host ? ci->host : "(null)", 806462c32cbSDag-Erling Smørgrav ci->address ? ci->address : "(null)", 807462c32cbSDag-Erling Smørgrav ci->laddress ? ci->laddress : "(null)", ci->lport); 808333ee039SDag-Erling Smørgrav 809333ee039SDag-Erling Smørgrav while ((attrib = strdelim(&cp)) && *attrib != '\0') { 810f7167e0eSDag-Erling Smørgrav attributes++; 811f7167e0eSDag-Erling Smørgrav if (strcasecmp(attrib, "all") == 0) { 812f7167e0eSDag-Erling Smørgrav if (attributes != 1 || 813f7167e0eSDag-Erling Smørgrav ((arg = strdelim(&cp)) != NULL && *arg != '\0')) { 814f7167e0eSDag-Erling Smørgrav error("'all' cannot be combined with other " 815f7167e0eSDag-Erling Smørgrav "Match attributes"); 816f7167e0eSDag-Erling Smørgrav return -1; 817f7167e0eSDag-Erling Smørgrav } 818f7167e0eSDag-Erling Smørgrav *condition = cp; 819f7167e0eSDag-Erling Smørgrav return 1; 820f7167e0eSDag-Erling Smørgrav } 821333ee039SDag-Erling Smørgrav if ((arg = strdelim(&cp)) == NULL || *arg == '\0') { 822333ee039SDag-Erling Smørgrav error("Missing Match criteria for %s", attrib); 823333ee039SDag-Erling Smørgrav return -1; 824333ee039SDag-Erling Smørgrav } 825333ee039SDag-Erling Smørgrav if (strcasecmp(attrib, "user") == 0) { 826462c32cbSDag-Erling Smørgrav if (ci == NULL || ci->user == NULL) { 827333ee039SDag-Erling Smørgrav result = 0; 828333ee039SDag-Erling Smørgrav continue; 829333ee039SDag-Erling Smørgrav } 830557f75e5SDag-Erling Smørgrav if (match_pattern_list(ci->user, arg, 0) != 1) 831333ee039SDag-Erling Smørgrav result = 0; 832333ee039SDag-Erling Smørgrav else 833333ee039SDag-Erling Smørgrav debug("user %.100s matched 'User %.100s' at " 834462c32cbSDag-Erling Smørgrav "line %d", ci->user, arg, line); 835333ee039SDag-Erling Smørgrav } else if (strcasecmp(attrib, "group") == 0) { 836462c32cbSDag-Erling Smørgrav if (ci == NULL || ci->user == NULL) { 837462c32cbSDag-Erling Smørgrav result = 0; 838462c32cbSDag-Erling Smørgrav continue; 839462c32cbSDag-Erling Smørgrav } 840462c32cbSDag-Erling Smørgrav switch (match_cfg_line_group(arg, line, ci->user)) { 841333ee039SDag-Erling Smørgrav case -1: 842333ee039SDag-Erling Smørgrav return -1; 843333ee039SDag-Erling Smørgrav case 0: 844333ee039SDag-Erling Smørgrav result = 0; 845333ee039SDag-Erling Smørgrav } 846333ee039SDag-Erling Smørgrav } else if (strcasecmp(attrib, "host") == 0) { 847462c32cbSDag-Erling Smørgrav if (ci == NULL || ci->host == NULL) { 848333ee039SDag-Erling Smørgrav result = 0; 849333ee039SDag-Erling Smørgrav continue; 850333ee039SDag-Erling Smørgrav } 851557f75e5SDag-Erling Smørgrav if (match_hostname(ci->host, arg) != 1) 852333ee039SDag-Erling Smørgrav result = 0; 853333ee039SDag-Erling Smørgrav else 854333ee039SDag-Erling Smørgrav debug("connection from %.100s matched 'Host " 855462c32cbSDag-Erling Smørgrav "%.100s' at line %d", ci->host, arg, line); 856333ee039SDag-Erling Smørgrav } else if (strcasecmp(attrib, "address") == 0) { 857462c32cbSDag-Erling Smørgrav if (ci == NULL || ci->address == NULL) { 858462c32cbSDag-Erling Smørgrav result = 0; 859462c32cbSDag-Erling Smørgrav continue; 860462c32cbSDag-Erling Smørgrav } 861462c32cbSDag-Erling Smørgrav switch (addr_match_list(ci->address, arg)) { 862d4af9e69SDag-Erling Smørgrav case 1: 863333ee039SDag-Erling Smørgrav debug("connection from %.100s matched 'Address " 864462c32cbSDag-Erling Smørgrav "%.100s' at line %d", ci->address, arg, line); 865d4af9e69SDag-Erling Smørgrav break; 866d4af9e69SDag-Erling Smørgrav case 0: 867d4af9e69SDag-Erling Smørgrav case -1: 868d4af9e69SDag-Erling Smørgrav result = 0; 869d4af9e69SDag-Erling Smørgrav break; 870d4af9e69SDag-Erling Smørgrav case -2: 871d4af9e69SDag-Erling Smørgrav return -1; 872d4af9e69SDag-Erling Smørgrav } 873462c32cbSDag-Erling Smørgrav } else if (strcasecmp(attrib, "localaddress") == 0){ 874462c32cbSDag-Erling Smørgrav if (ci == NULL || ci->laddress == NULL) { 875462c32cbSDag-Erling Smørgrav result = 0; 876462c32cbSDag-Erling Smørgrav continue; 877462c32cbSDag-Erling Smørgrav } 878462c32cbSDag-Erling Smørgrav switch (addr_match_list(ci->laddress, arg)) { 879462c32cbSDag-Erling Smørgrav case 1: 880462c32cbSDag-Erling Smørgrav debug("connection from %.100s matched " 881462c32cbSDag-Erling Smørgrav "'LocalAddress %.100s' at line %d", 882462c32cbSDag-Erling Smørgrav ci->laddress, arg, line); 883462c32cbSDag-Erling Smørgrav break; 884462c32cbSDag-Erling Smørgrav case 0: 885462c32cbSDag-Erling Smørgrav case -1: 886462c32cbSDag-Erling Smørgrav result = 0; 887462c32cbSDag-Erling Smørgrav break; 888462c32cbSDag-Erling Smørgrav case -2: 889462c32cbSDag-Erling Smørgrav return -1; 890462c32cbSDag-Erling Smørgrav } 891462c32cbSDag-Erling Smørgrav } else if (strcasecmp(attrib, "localport") == 0) { 892462c32cbSDag-Erling Smørgrav if ((port = a2port(arg)) == -1) { 893462c32cbSDag-Erling Smørgrav error("Invalid LocalPort '%s' on Match line", 894462c32cbSDag-Erling Smørgrav arg); 895462c32cbSDag-Erling Smørgrav return -1; 896462c32cbSDag-Erling Smørgrav } 897462c32cbSDag-Erling Smørgrav if (ci == NULL || ci->lport == 0) { 898462c32cbSDag-Erling Smørgrav result = 0; 899462c32cbSDag-Erling Smørgrav continue; 900462c32cbSDag-Erling Smørgrav } 901462c32cbSDag-Erling Smørgrav /* TODO support port lists */ 902462c32cbSDag-Erling Smørgrav if (port == ci->lport) 903462c32cbSDag-Erling Smørgrav debug("connection from %.100s matched " 904462c32cbSDag-Erling Smørgrav "'LocalPort %d' at line %d", 905462c32cbSDag-Erling Smørgrav ci->laddress, port, line); 906462c32cbSDag-Erling Smørgrav else 907462c32cbSDag-Erling Smørgrav result = 0; 908333ee039SDag-Erling Smørgrav } else { 909333ee039SDag-Erling Smørgrav error("Unsupported Match attribute %s", attrib); 910333ee039SDag-Erling Smørgrav return -1; 911333ee039SDag-Erling Smørgrav } 912333ee039SDag-Erling Smørgrav } 913f7167e0eSDag-Erling Smørgrav if (attributes == 0) { 914f7167e0eSDag-Erling Smørgrav error("One or more attributes required for Match"); 915f7167e0eSDag-Erling Smørgrav return -1; 916f7167e0eSDag-Erling Smørgrav } 917462c32cbSDag-Erling Smørgrav if (ci != NULL) 918333ee039SDag-Erling Smørgrav debug3("match %sfound", result ? "" : "not "); 919333ee039SDag-Erling Smørgrav *condition = cp; 920333ee039SDag-Erling Smørgrav return result; 921333ee039SDag-Erling Smørgrav } 922333ee039SDag-Erling Smørgrav 923333ee039SDag-Erling Smørgrav #define WHITESPACE " \t\r\n" 924333ee039SDag-Erling Smørgrav 925e146993eSDag-Erling Smørgrav /* Multistate option parsing */ 926e146993eSDag-Erling Smørgrav struct multistate { 927e146993eSDag-Erling Smørgrav char *key; 928e146993eSDag-Erling Smørgrav int value; 929e146993eSDag-Erling Smørgrav }; 930e146993eSDag-Erling Smørgrav static const struct multistate multistate_addressfamily[] = { 931e146993eSDag-Erling Smørgrav { "inet", AF_INET }, 932e146993eSDag-Erling Smørgrav { "inet6", AF_INET6 }, 933e146993eSDag-Erling Smørgrav { "any", AF_UNSPEC }, 934e146993eSDag-Erling Smørgrav { NULL, -1 } 935e146993eSDag-Erling Smørgrav }; 936e146993eSDag-Erling Smørgrav static const struct multistate multistate_permitrootlogin[] = { 937e146993eSDag-Erling Smørgrav { "without-password", PERMIT_NO_PASSWD }, 938eccfee6eSDag-Erling Smørgrav { "prohibit-password", PERMIT_NO_PASSWD }, 939e146993eSDag-Erling Smørgrav { "forced-commands-only", PERMIT_FORCED_ONLY }, 940e146993eSDag-Erling Smørgrav { "yes", PERMIT_YES }, 941e146993eSDag-Erling Smørgrav { "no", PERMIT_NO }, 942e146993eSDag-Erling Smørgrav { NULL, -1 } 943e146993eSDag-Erling Smørgrav }; 944e146993eSDag-Erling Smørgrav static const struct multistate multistate_compression[] = { 945e146993eSDag-Erling Smørgrav { "delayed", COMP_DELAYED }, 946e146993eSDag-Erling Smørgrav { "yes", COMP_ZLIB }, 947e146993eSDag-Erling Smørgrav { "no", COMP_NONE }, 948e146993eSDag-Erling Smørgrav { NULL, -1 } 949e146993eSDag-Erling Smørgrav }; 950e146993eSDag-Erling Smørgrav static const struct multistate multistate_gatewayports[] = { 951e146993eSDag-Erling Smørgrav { "clientspecified", 2 }, 952e146993eSDag-Erling Smørgrav { "yes", 1 }, 953e146993eSDag-Erling Smørgrav { "no", 0 }, 954e146993eSDag-Erling Smørgrav { NULL, -1 } 955e146993eSDag-Erling Smørgrav }; 956e146993eSDag-Erling Smørgrav static const struct multistate multistate_privsep[] = { 957462c32cbSDag-Erling Smørgrav { "yes", PRIVSEP_NOSANDBOX }, 958462c32cbSDag-Erling Smørgrav { "sandbox", PRIVSEP_ON }, 959462c32cbSDag-Erling Smørgrav { "nosandbox", PRIVSEP_NOSANDBOX }, 960e146993eSDag-Erling Smørgrav { "no", PRIVSEP_OFF }, 961e146993eSDag-Erling Smørgrav { NULL, -1 } 962e146993eSDag-Erling Smørgrav }; 9636888a9beSDag-Erling Smørgrav static const struct multistate multistate_tcpfwd[] = { 9646888a9beSDag-Erling Smørgrav { "yes", FORWARD_ALLOW }, 9656888a9beSDag-Erling Smørgrav { "all", FORWARD_ALLOW }, 9666888a9beSDag-Erling Smørgrav { "no", FORWARD_DENY }, 9676888a9beSDag-Erling Smørgrav { "remote", FORWARD_REMOTE }, 9686888a9beSDag-Erling Smørgrav { "local", FORWARD_LOCAL }, 9696888a9beSDag-Erling Smørgrav { NULL, -1 } 9706888a9beSDag-Erling Smørgrav }; 971e146993eSDag-Erling Smørgrav 972af12a3e7SDag-Erling Smørgrav int 973af12a3e7SDag-Erling Smørgrav process_server_config_line(ServerOptions *options, char *line, 974462c32cbSDag-Erling Smørgrav const char *filename, int linenum, int *activep, 975462c32cbSDag-Erling Smørgrav struct connection_info *connectinfo) 976511b41d2SMark Murray { 977ca3176e7SBrian Feldman char *cp, **charptr, *arg, *p; 978e4a9863fSDag-Erling Smørgrav int cmdline = 0, *intptr, value, value2, n, port; 979d4af9e69SDag-Erling Smørgrav SyslogFacility *log_facility_ptr; 980d4af9e69SDag-Erling Smørgrav LogLevel *log_level_ptr; 981511b41d2SMark Murray ServerOpCodes opcode; 982333ee039SDag-Erling Smørgrav u_int i, flags = 0; 983333ee039SDag-Erling Smørgrav size_t len; 984e4a9863fSDag-Erling Smørgrav long long val64; 985e146993eSDag-Erling Smørgrav const struct multistate *multistate_ptr; 986511b41d2SMark Murray 987c2d3a559SKris Kennaway cp = line; 988333ee039SDag-Erling Smørgrav if ((arg = strdelim(&cp)) == NULL) 989333ee039SDag-Erling Smørgrav return 0; 990c2d3a559SKris Kennaway /* Ignore leading whitespace */ 991c2d3a559SKris Kennaway if (*arg == '\0') 992c2d3a559SKris Kennaway arg = strdelim(&cp); 993ca3176e7SBrian Feldman if (!arg || !*arg || *arg == '#') 994af12a3e7SDag-Erling Smørgrav return 0; 995ca3176e7SBrian Feldman intptr = NULL; 996ca3176e7SBrian Feldman charptr = NULL; 997333ee039SDag-Erling Smørgrav opcode = parse_token(arg, filename, linenum, &flags); 998333ee039SDag-Erling Smørgrav 999333ee039SDag-Erling Smørgrav if (activep == NULL) { /* We are processing a command line directive */ 1000333ee039SDag-Erling Smørgrav cmdline = 1; 1001333ee039SDag-Erling Smørgrav activep = &cmdline; 1002333ee039SDag-Erling Smørgrav } 1003333ee039SDag-Erling Smørgrav if (*activep && opcode != sMatch) 1004333ee039SDag-Erling Smørgrav debug3("%s:%d setting %s %s", filename, linenum, arg, cp); 1005333ee039SDag-Erling Smørgrav if (*activep == 0 && !(flags & SSHCFG_MATCH)) { 1006462c32cbSDag-Erling Smørgrav if (connectinfo == NULL) { 1007333ee039SDag-Erling Smørgrav fatal("%s line %d: Directive '%s' is not allowed " 1008333ee039SDag-Erling Smørgrav "within a Match block", filename, linenum, arg); 1009333ee039SDag-Erling Smørgrav } else { /* this is a directive we have already processed */ 1010333ee039SDag-Erling Smørgrav while (arg) 1011333ee039SDag-Erling Smørgrav arg = strdelim(&cp); 1012333ee039SDag-Erling Smørgrav return 0; 1013333ee039SDag-Erling Smørgrav } 1014333ee039SDag-Erling Smørgrav } 1015333ee039SDag-Erling Smørgrav 1016511b41d2SMark Murray switch (opcode) { 1017989dd127SDag-Erling Smørgrav /* Portable-specific options */ 1018cf2b5f3bSDag-Erling Smørgrav case sUsePAM: 1019cf2b5f3bSDag-Erling Smørgrav intptr = &options->use_pam; 1020989dd127SDag-Erling Smørgrav goto parse_flag; 1021989dd127SDag-Erling Smørgrav 1022989dd127SDag-Erling Smørgrav /* Standard Options */ 1023511b41d2SMark Murray case sBadOption: 1024af12a3e7SDag-Erling Smørgrav return -1; 1025511b41d2SMark Murray case sPort: 1026511b41d2SMark Murray /* ignore ports from configfile if cmdline specifies ports */ 1027511b41d2SMark Murray if (options->ports_from_cmdline) 1028af12a3e7SDag-Erling Smørgrav return 0; 1029511b41d2SMark Murray if (options->num_ports >= MAX_PORTS) 1030ca3176e7SBrian Feldman fatal("%s line %d: too many ports.", 1031511b41d2SMark Murray filename, linenum); 1032c2d3a559SKris Kennaway arg = strdelim(&cp); 1033c2d3a559SKris Kennaway if (!arg || *arg == '\0') 1034ca3176e7SBrian Feldman fatal("%s line %d: missing port number.", 1035511b41d2SMark Murray filename, linenum); 1036ca3176e7SBrian Feldman options->ports[options->num_ports++] = a2port(arg); 1037cce7d346SDag-Erling Smørgrav if (options->ports[options->num_ports-1] <= 0) 1038ca3176e7SBrian Feldman fatal("%s line %d: Badly formatted port number.", 1039ca3176e7SBrian Feldman filename, linenum); 1040511b41d2SMark Murray break; 1041511b41d2SMark Murray 1042511b41d2SMark Murray case sServerKeyBits: 1043511b41d2SMark Murray intptr = &options->server_key_bits; 1044511b41d2SMark Murray parse_int: 1045c2d3a559SKris Kennaway arg = strdelim(&cp); 1046ca3176e7SBrian Feldman if (!arg || *arg == '\0') 1047ca3176e7SBrian Feldman fatal("%s line %d: missing integer value.", 1048511b41d2SMark Murray filename, linenum); 1049c2d3a559SKris Kennaway value = atoi(arg); 1050333ee039SDag-Erling Smørgrav if (*activep && *intptr == -1) 1051511b41d2SMark Murray *intptr = value; 1052511b41d2SMark Murray break; 1053511b41d2SMark Murray 1054511b41d2SMark Murray case sLoginGraceTime: 1055511b41d2SMark Murray intptr = &options->login_grace_time; 1056af12a3e7SDag-Erling Smørgrav parse_time: 1057af12a3e7SDag-Erling Smørgrav arg = strdelim(&cp); 1058af12a3e7SDag-Erling Smørgrav if (!arg || *arg == '\0') 1059af12a3e7SDag-Erling Smørgrav fatal("%s line %d: missing time value.", 1060af12a3e7SDag-Erling Smørgrav filename, linenum); 1061af12a3e7SDag-Erling Smørgrav if ((value = convtime(arg)) == -1) 1062af12a3e7SDag-Erling Smørgrav fatal("%s line %d: invalid time value.", 1063af12a3e7SDag-Erling Smørgrav filename, linenum); 1064557f75e5SDag-Erling Smørgrav if (*activep && *intptr == -1) 1065af12a3e7SDag-Erling Smørgrav *intptr = value; 1066af12a3e7SDag-Erling Smørgrav break; 1067511b41d2SMark Murray 1068511b41d2SMark Murray case sKeyRegenerationTime: 1069511b41d2SMark Murray intptr = &options->key_regeneration_time; 1070af12a3e7SDag-Erling Smørgrav goto parse_time; 1071511b41d2SMark Murray 1072511b41d2SMark Murray case sListenAddress: 1073c2d3a559SKris Kennaway arg = strdelim(&cp); 1074aa49c926SDag-Erling Smørgrav if (arg == NULL || *arg == '\0') 1075aa49c926SDag-Erling Smørgrav fatal("%s line %d: missing address", 1076511b41d2SMark Murray filename, linenum); 1077d4ecd108SDag-Erling Smørgrav /* check for bare IPv6 address: no "[]" and 2 or more ":" */ 1078d4ecd108SDag-Erling Smørgrav if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL 1079d4ecd108SDag-Erling Smørgrav && strchr(p+1, ':') != NULL) { 1080557f75e5SDag-Erling Smørgrav queue_listen_addr(options, arg, 0); 1081d4ecd108SDag-Erling Smørgrav break; 1082d4ecd108SDag-Erling Smørgrav } 1083aa49c926SDag-Erling Smørgrav p = hpdelim(&arg); 1084aa49c926SDag-Erling Smørgrav if (p == NULL) 1085aa49c926SDag-Erling Smørgrav fatal("%s line %d: bad address:port usage", 1086ca3176e7SBrian Feldman filename, linenum); 1087aa49c926SDag-Erling Smørgrav p = cleanhostname(p); 1088aa49c926SDag-Erling Smørgrav if (arg == NULL) 1089aa49c926SDag-Erling Smørgrav port = 0; 1090cce7d346SDag-Erling Smørgrav else if ((port = a2port(arg)) <= 0) 1091aa49c926SDag-Erling Smørgrav fatal("%s line %d: bad port number", filename, linenum); 1092ca3176e7SBrian Feldman 1093557f75e5SDag-Erling Smørgrav queue_listen_addr(options, p, port); 1094aa49c926SDag-Erling Smørgrav 1095aa49c926SDag-Erling Smørgrav break; 1096aa49c926SDag-Erling Smørgrav 1097aa49c926SDag-Erling Smørgrav case sAddressFamily: 1098e146993eSDag-Erling Smørgrav intptr = &options->address_family; 1099e146993eSDag-Erling Smørgrav multistate_ptr = multistate_addressfamily; 1100e146993eSDag-Erling Smørgrav parse_multistate: 1101aa49c926SDag-Erling Smørgrav arg = strdelim(&cp); 1102d4ecd108SDag-Erling Smørgrav if (!arg || *arg == '\0') 1103e146993eSDag-Erling Smørgrav fatal("%s line %d: missing argument.", 1104d4ecd108SDag-Erling Smørgrav filename, linenum); 1105e146993eSDag-Erling Smørgrav value = -1; 1106e146993eSDag-Erling Smørgrav for (i = 0; multistate_ptr[i].key != NULL; i++) { 1107e146993eSDag-Erling Smørgrav if (strcasecmp(arg, multistate_ptr[i].key) == 0) { 1108e146993eSDag-Erling Smørgrav value = multistate_ptr[i].value; 1109e146993eSDag-Erling Smørgrav break; 1110e146993eSDag-Erling Smørgrav } 1111e146993eSDag-Erling Smørgrav } 1112e146993eSDag-Erling Smørgrav if (value == -1) 1113e146993eSDag-Erling Smørgrav fatal("%s line %d: unsupported option \"%s\".", 1114aa49c926SDag-Erling Smørgrav filename, linenum, arg); 1115e146993eSDag-Erling Smørgrav if (*activep && *intptr == -1) 1116aa49c926SDag-Erling Smørgrav *intptr = value; 1117511b41d2SMark Murray break; 1118511b41d2SMark Murray 1119511b41d2SMark Murray case sHostKeyFile: 1120ca3176e7SBrian Feldman intptr = &options->num_host_key_files; 1121ca3176e7SBrian Feldman if (*intptr >= MAX_HOSTKEYS) 1122ca3176e7SBrian Feldman fatal("%s line %d: too many host keys specified (max %d).", 1123ca3176e7SBrian Feldman filename, linenum, MAX_HOSTKEYS); 1124ca3176e7SBrian Feldman charptr = &options->host_key_files[*intptr]; 1125c2d3a559SKris Kennaway parse_filename: 1126c2d3a559SKris Kennaway arg = strdelim(&cp); 1127ca3176e7SBrian Feldman if (!arg || *arg == '\0') 1128ca3176e7SBrian Feldman fatal("%s line %d: missing file name.", 1129e8aafc91SKris Kennaway filename, linenum); 1130333ee039SDag-Erling Smørgrav if (*activep && *charptr == NULL) { 1131b15c8340SDag-Erling Smørgrav *charptr = derelativise_path(arg); 1132ca3176e7SBrian Feldman /* increase optional counter */ 1133ca3176e7SBrian Feldman if (intptr != NULL) 1134ca3176e7SBrian Feldman *intptr = *intptr + 1; 1135ca3176e7SBrian Feldman } 1136e8aafc91SKris Kennaway break; 1137e8aafc91SKris Kennaway 1138e4a9863fSDag-Erling Smørgrav case sHostKeyAgent: 1139e4a9863fSDag-Erling Smørgrav charptr = &options->host_key_agent; 1140e4a9863fSDag-Erling Smørgrav arg = strdelim(&cp); 1141e4a9863fSDag-Erling Smørgrav if (!arg || *arg == '\0') 1142e4a9863fSDag-Erling Smørgrav fatal("%s line %d: missing socket name.", 1143e4a9863fSDag-Erling Smørgrav filename, linenum); 1144e4a9863fSDag-Erling Smørgrav if (*activep && *charptr == NULL) 1145e4a9863fSDag-Erling Smørgrav *charptr = !strcmp(arg, SSH_AUTHSOCKET_ENV_NAME) ? 1146e4a9863fSDag-Erling Smørgrav xstrdup(arg) : derelativise_path(arg); 1147e4a9863fSDag-Erling Smørgrav break; 1148e4a9863fSDag-Erling Smørgrav 1149b15c8340SDag-Erling Smørgrav case sHostCertificate: 1150b15c8340SDag-Erling Smørgrav intptr = &options->num_host_cert_files; 1151b15c8340SDag-Erling Smørgrav if (*intptr >= MAX_HOSTKEYS) 1152b15c8340SDag-Erling Smørgrav fatal("%s line %d: too many host certificates " 1153b15c8340SDag-Erling Smørgrav "specified (max %d).", filename, linenum, 1154b15c8340SDag-Erling Smørgrav MAX_HOSTCERTS); 1155b15c8340SDag-Erling Smørgrav charptr = &options->host_cert_files[*intptr]; 1156b15c8340SDag-Erling Smørgrav goto parse_filename; 1157b15c8340SDag-Erling Smørgrav break; 1158b15c8340SDag-Erling Smørgrav 1159e8aafc91SKris Kennaway case sPidFile: 1160e8aafc91SKris Kennaway charptr = &options->pid_file; 1161c2d3a559SKris Kennaway goto parse_filename; 1162511b41d2SMark Murray 1163511b41d2SMark Murray case sPermitRootLogin: 1164511b41d2SMark Murray intptr = &options->permit_root_login; 1165e146993eSDag-Erling Smørgrav multistate_ptr = multistate_permitrootlogin; 1166e146993eSDag-Erling Smørgrav goto parse_multistate; 1167511b41d2SMark Murray 1168511b41d2SMark Murray case sIgnoreRhosts: 1169511b41d2SMark Murray intptr = &options->ignore_rhosts; 1170511b41d2SMark Murray parse_flag: 1171c2d3a559SKris Kennaway arg = strdelim(&cp); 1172ca3176e7SBrian Feldman if (!arg || *arg == '\0') 1173ca3176e7SBrian Feldman fatal("%s line %d: missing yes/no argument.", 1174511b41d2SMark Murray filename, linenum); 1175ca3176e7SBrian Feldman value = 0; /* silence compiler */ 1176c2d3a559SKris Kennaway if (strcmp(arg, "yes") == 0) 1177511b41d2SMark Murray value = 1; 1178c2d3a559SKris Kennaway else if (strcmp(arg, "no") == 0) 1179511b41d2SMark Murray value = 0; 1180ca3176e7SBrian Feldman else 1181ca3176e7SBrian Feldman fatal("%s line %d: Bad yes/no argument: %s", 1182c2d3a559SKris Kennaway filename, linenum, arg); 1183333ee039SDag-Erling Smørgrav if (*activep && *intptr == -1) 1184511b41d2SMark Murray *intptr = value; 1185511b41d2SMark Murray break; 1186511b41d2SMark Murray 1187511b41d2SMark Murray case sIgnoreUserKnownHosts: 1188511b41d2SMark Murray intptr = &options->ignore_user_known_hosts; 1189962a3f4eSSheldon Hearn goto parse_flag; 1190511b41d2SMark Murray 1191511b41d2SMark Murray case sRhostsRSAAuthentication: 1192511b41d2SMark Murray intptr = &options->rhosts_rsa_authentication; 1193511b41d2SMark Murray goto parse_flag; 1194511b41d2SMark Murray 1195ca3176e7SBrian Feldman case sHostbasedAuthentication: 1196ca3176e7SBrian Feldman intptr = &options->hostbased_authentication; 1197ca3176e7SBrian Feldman goto parse_flag; 1198ca3176e7SBrian Feldman 1199ca3176e7SBrian Feldman case sHostbasedUsesNameFromPacketOnly: 1200ca3176e7SBrian Feldman intptr = &options->hostbased_uses_name_from_packet_only; 1201ca3176e7SBrian Feldman goto parse_flag; 1202ca3176e7SBrian Feldman 1203bc5531deSDag-Erling Smørgrav case sHostbasedAcceptedKeyTypes: 1204bc5531deSDag-Erling Smørgrav charptr = &options->hostbased_key_types; 1205bc5531deSDag-Erling Smørgrav parse_keytypes: 1206bc5531deSDag-Erling Smørgrav arg = strdelim(&cp); 1207bc5531deSDag-Erling Smørgrav if (!arg || *arg == '\0') 1208bc5531deSDag-Erling Smørgrav fatal("%s line %d: Missing argument.", 1209bc5531deSDag-Erling Smørgrav filename, linenum); 1210eccfee6eSDag-Erling Smørgrav if (!sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1)) 1211bc5531deSDag-Erling Smørgrav fatal("%s line %d: Bad key types '%s'.", 1212bc5531deSDag-Erling Smørgrav filename, linenum, arg ? arg : "<NONE>"); 1213bc5531deSDag-Erling Smørgrav if (*activep && *charptr == NULL) 1214bc5531deSDag-Erling Smørgrav *charptr = xstrdup(arg); 1215bc5531deSDag-Erling Smørgrav break; 1216bc5531deSDag-Erling Smørgrav 1217eccfee6eSDag-Erling Smørgrav case sHostKeyAlgorithms: 1218eccfee6eSDag-Erling Smørgrav charptr = &options->hostkeyalgorithms; 1219eccfee6eSDag-Erling Smørgrav goto parse_keytypes; 1220eccfee6eSDag-Erling Smørgrav 1221511b41d2SMark Murray case sRSAAuthentication: 1222511b41d2SMark Murray intptr = &options->rsa_authentication; 1223511b41d2SMark Murray goto parse_flag; 1224511b41d2SMark Murray 1225ca3176e7SBrian Feldman case sPubkeyAuthentication: 1226ca3176e7SBrian Feldman intptr = &options->pubkey_authentication; 1227e8aafc91SKris Kennaway goto parse_flag; 1228cf2b5f3bSDag-Erling Smørgrav 1229bc5531deSDag-Erling Smørgrav case sPubkeyAcceptedKeyTypes: 1230bc5531deSDag-Erling Smørgrav charptr = &options->pubkey_key_types; 1231bc5531deSDag-Erling Smørgrav goto parse_keytypes; 1232bc5531deSDag-Erling Smørgrav 1233cb96ab36SAssar Westerlund case sKerberosAuthentication: 1234cb96ab36SAssar Westerlund intptr = &options->kerberos_authentication; 1235511b41d2SMark Murray goto parse_flag; 1236511b41d2SMark Murray 1237af12a3e7SDag-Erling Smørgrav case sKerberosOrLocalPasswd: 1238af12a3e7SDag-Erling Smørgrav intptr = &options->kerberos_or_local_passwd; 1239511b41d2SMark Murray goto parse_flag; 1240511b41d2SMark Murray 1241af12a3e7SDag-Erling Smørgrav case sKerberosTicketCleanup: 1242af12a3e7SDag-Erling Smørgrav intptr = &options->kerberos_ticket_cleanup; 1243511b41d2SMark Murray goto parse_flag; 1244cf2b5f3bSDag-Erling Smørgrav 12451ec0d754SDag-Erling Smørgrav case sKerberosGetAFSToken: 12461ec0d754SDag-Erling Smørgrav intptr = &options->kerberos_get_afs_token; 12471ec0d754SDag-Erling Smørgrav goto parse_flag; 12481ec0d754SDag-Erling Smørgrav 1249cf2b5f3bSDag-Erling Smørgrav case sGssAuthentication: 1250cf2b5f3bSDag-Erling Smørgrav intptr = &options->gss_authentication; 1251fe5fd017SMark Murray goto parse_flag; 1252cf2b5f3bSDag-Erling Smørgrav 1253cf2b5f3bSDag-Erling Smørgrav case sGssCleanupCreds: 1254cf2b5f3bSDag-Erling Smørgrav intptr = &options->gss_cleanup_creds; 1255511b41d2SMark Murray goto parse_flag; 1256511b41d2SMark Murray 1257557f75e5SDag-Erling Smørgrav case sGssStrictAcceptor: 1258557f75e5SDag-Erling Smørgrav intptr = &options->gss_strict_acceptor; 1259557f75e5SDag-Erling Smørgrav goto parse_flag; 1260557f75e5SDag-Erling Smørgrav 1261511b41d2SMark Murray case sPasswordAuthentication: 1262511b41d2SMark Murray intptr = &options->password_authentication; 1263511b41d2SMark Murray goto parse_flag; 1264511b41d2SMark Murray 126509958426SBrian Feldman case sKbdInteractiveAuthentication: 126609958426SBrian Feldman intptr = &options->kbd_interactive_authentication; 126709958426SBrian Feldman goto parse_flag; 126809958426SBrian Feldman 1269ca3176e7SBrian Feldman case sChallengeResponseAuthentication: 1270af12a3e7SDag-Erling Smørgrav intptr = &options->challenge_response_authentication; 1271511b41d2SMark Murray goto parse_flag; 1272511b41d2SMark Murray 1273511b41d2SMark Murray case sPrintMotd: 1274511b41d2SMark Murray intptr = &options->print_motd; 1275511b41d2SMark Murray goto parse_flag; 1276511b41d2SMark Murray 1277ca3176e7SBrian Feldman case sPrintLastLog: 1278ca3176e7SBrian Feldman intptr = &options->print_lastlog; 1279ca3176e7SBrian Feldman goto parse_flag; 1280ca3176e7SBrian Feldman 1281511b41d2SMark Murray case sX11Forwarding: 1282511b41d2SMark Murray intptr = &options->x11_forwarding; 1283511b41d2SMark Murray goto parse_flag; 1284511b41d2SMark Murray 1285511b41d2SMark Murray case sX11DisplayOffset: 1286511b41d2SMark Murray intptr = &options->x11_display_offset; 1287511b41d2SMark Murray goto parse_int; 1288511b41d2SMark Murray 1289af12a3e7SDag-Erling Smørgrav case sX11UseLocalhost: 1290af12a3e7SDag-Erling Smørgrav intptr = &options->x11_use_localhost; 1291af12a3e7SDag-Erling Smørgrav goto parse_flag; 1292af12a3e7SDag-Erling Smørgrav 1293c2d3a559SKris Kennaway case sXAuthLocation: 1294c2d3a559SKris Kennaway charptr = &options->xauth_location; 1295c2d3a559SKris Kennaway goto parse_filename; 1296c2d3a559SKris Kennaway 1297f7167e0eSDag-Erling Smørgrav case sPermitTTY: 1298f7167e0eSDag-Erling Smørgrav intptr = &options->permit_tty; 1299f7167e0eSDag-Erling Smørgrav goto parse_flag; 1300f7167e0eSDag-Erling Smørgrav 1301a0ee8cc6SDag-Erling Smørgrav case sPermitUserRC: 1302a0ee8cc6SDag-Erling Smørgrav intptr = &options->permit_user_rc; 1303a0ee8cc6SDag-Erling Smørgrav goto parse_flag; 1304a0ee8cc6SDag-Erling Smørgrav 1305511b41d2SMark Murray case sStrictModes: 1306511b41d2SMark Murray intptr = &options->strict_modes; 1307511b41d2SMark Murray goto parse_flag; 1308511b41d2SMark Murray 13091ec0d754SDag-Erling Smørgrav case sTCPKeepAlive: 13101ec0d754SDag-Erling Smørgrav intptr = &options->tcp_keep_alive; 1311511b41d2SMark Murray goto parse_flag; 1312511b41d2SMark Murray 1313511b41d2SMark Murray case sEmptyPasswd: 1314511b41d2SMark Murray intptr = &options->permit_empty_passwd; 1315511b41d2SMark Murray goto parse_flag; 1316511b41d2SMark Murray 1317f388f5efSDag-Erling Smørgrav case sPermitUserEnvironment: 1318f388f5efSDag-Erling Smørgrav intptr = &options->permit_user_env; 1319f388f5efSDag-Erling Smørgrav goto parse_flag; 1320f388f5efSDag-Erling Smørgrav 1321511b41d2SMark Murray case sUseLogin: 1322511b41d2SMark Murray intptr = &options->use_login; 1323511b41d2SMark Murray goto parse_flag; 1324511b41d2SMark Murray 132580628bacSDag-Erling Smørgrav case sCompression: 132680628bacSDag-Erling Smørgrav intptr = &options->compression; 1327e146993eSDag-Erling Smørgrav multistate_ptr = multistate_compression; 1328e146993eSDag-Erling Smørgrav goto parse_multistate; 132980628bacSDag-Erling Smørgrav 1330e4a9863fSDag-Erling Smørgrav case sRekeyLimit: 1331e4a9863fSDag-Erling Smørgrav arg = strdelim(&cp); 1332e4a9863fSDag-Erling Smørgrav if (!arg || *arg == '\0') 1333e4a9863fSDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", filename, 1334e4a9863fSDag-Erling Smørgrav linenum); 1335e4a9863fSDag-Erling Smørgrav if (strcmp(arg, "default") == 0) { 1336e4a9863fSDag-Erling Smørgrav val64 = 0; 1337e4a9863fSDag-Erling Smørgrav } else { 1338e4a9863fSDag-Erling Smørgrav if (scan_scaled(arg, &val64) == -1) 1339e4a9863fSDag-Erling Smørgrav fatal("%.200s line %d: Bad number '%s': %s", 1340e4a9863fSDag-Erling Smørgrav filename, linenum, arg, strerror(errno)); 1341e4a9863fSDag-Erling Smørgrav if (val64 != 0 && val64 < 16) 1342e4a9863fSDag-Erling Smørgrav fatal("%.200s line %d: RekeyLimit too small", 1343e4a9863fSDag-Erling Smørgrav filename, linenum); 1344e4a9863fSDag-Erling Smørgrav } 1345e4a9863fSDag-Erling Smørgrav if (*activep && options->rekey_limit == -1) 1346*acc1a9efSDag-Erling Smørgrav options->rekey_limit = val64; 1347e4a9863fSDag-Erling Smørgrav if (cp != NULL) { /* optional rekey interval present */ 1348e4a9863fSDag-Erling Smørgrav if (strcmp(cp, "none") == 0) { 1349e4a9863fSDag-Erling Smørgrav (void)strdelim(&cp); /* discard */ 1350e4a9863fSDag-Erling Smørgrav break; 1351e4a9863fSDag-Erling Smørgrav } 1352e4a9863fSDag-Erling Smørgrav intptr = &options->rekey_interval; 1353e4a9863fSDag-Erling Smørgrav goto parse_time; 1354e4a9863fSDag-Erling Smørgrav } 1355e4a9863fSDag-Erling Smørgrav break; 1356e4a9863fSDag-Erling Smørgrav 1357e8aafc91SKris Kennaway case sGatewayPorts: 1358a0ee8cc6SDag-Erling Smørgrav intptr = &options->fwd_opts.gateway_ports; 1359e146993eSDag-Erling Smørgrav multistate_ptr = multistate_gatewayports; 1360e146993eSDag-Erling Smørgrav goto parse_multistate; 1361e8aafc91SKris Kennaway 1362cf2b5f3bSDag-Erling Smørgrav case sUseDNS: 1363cf2b5f3bSDag-Erling Smørgrav intptr = &options->use_dns; 1364ca3176e7SBrian Feldman goto parse_flag; 1365ca3176e7SBrian Feldman 1366511b41d2SMark Murray case sLogFacility: 1367d4af9e69SDag-Erling Smørgrav log_facility_ptr = &options->log_facility; 1368c2d3a559SKris Kennaway arg = strdelim(&cp); 1369c2d3a559SKris Kennaway value = log_facility_number(arg); 1370af12a3e7SDag-Erling Smørgrav if (value == SYSLOG_FACILITY_NOT_SET) 1371ca3176e7SBrian Feldman fatal("%.200s line %d: unsupported log facility '%s'", 1372c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 1373d4af9e69SDag-Erling Smørgrav if (*log_facility_ptr == -1) 1374d4af9e69SDag-Erling Smørgrav *log_facility_ptr = (SyslogFacility) value; 1375511b41d2SMark Murray break; 1376511b41d2SMark Murray 1377511b41d2SMark Murray case sLogLevel: 1378d4af9e69SDag-Erling Smørgrav log_level_ptr = &options->log_level; 1379c2d3a559SKris Kennaway arg = strdelim(&cp); 1380c2d3a559SKris Kennaway value = log_level_number(arg); 1381af12a3e7SDag-Erling Smørgrav if (value == SYSLOG_LEVEL_NOT_SET) 1382ca3176e7SBrian Feldman fatal("%.200s line %d: unsupported log level '%s'", 1383c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 1384d4af9e69SDag-Erling Smørgrav if (*log_level_ptr == -1) 1385d4af9e69SDag-Erling Smørgrav *log_level_ptr = (LogLevel) value; 1386511b41d2SMark Murray break; 1387511b41d2SMark Murray 138809958426SBrian Feldman case sAllowTcpForwarding: 138909958426SBrian Feldman intptr = &options->allow_tcp_forwarding; 13906888a9beSDag-Erling Smørgrav multistate_ptr = multistate_tcpfwd; 13916888a9beSDag-Erling Smørgrav goto parse_multistate; 139209958426SBrian Feldman 1393a0ee8cc6SDag-Erling Smørgrav case sAllowStreamLocalForwarding: 1394a0ee8cc6SDag-Erling Smørgrav intptr = &options->allow_streamlocal_forwarding; 1395a0ee8cc6SDag-Erling Smørgrav multistate_ptr = multistate_tcpfwd; 1396a0ee8cc6SDag-Erling Smørgrav goto parse_multistate; 1397a0ee8cc6SDag-Erling Smørgrav 1398d4af9e69SDag-Erling Smørgrav case sAllowAgentForwarding: 1399d4af9e69SDag-Erling Smørgrav intptr = &options->allow_agent_forwarding; 1400d4af9e69SDag-Erling Smørgrav goto parse_flag; 1401d4af9e69SDag-Erling Smørgrav 140280628bacSDag-Erling Smørgrav case sUsePrivilegeSeparation: 140380628bacSDag-Erling Smørgrav intptr = &use_privsep; 1404e146993eSDag-Erling Smørgrav multistate_ptr = multistate_privsep; 1405e146993eSDag-Erling Smørgrav goto parse_multistate; 140680628bacSDag-Erling Smørgrav 1407511b41d2SMark Murray case sAllowUsers: 1408c2d3a559SKris Kennaway while ((arg = strdelim(&cp)) && *arg != '\0') { 140942f71286SMark Murray if (options->num_allow_users >= MAX_ALLOW_USERS) 1410af12a3e7SDag-Erling Smørgrav fatal("%s line %d: too many allow users.", 1411e8aafc91SKris Kennaway filename, linenum); 1412462c32cbSDag-Erling Smørgrav if (!*activep) 1413462c32cbSDag-Erling Smørgrav continue; 1414a82e551fSDag-Erling Smørgrav options->allow_users[options->num_allow_users++] = 1415a82e551fSDag-Erling Smørgrav xstrdup(arg); 1416511b41d2SMark Murray } 1417511b41d2SMark Murray break; 1418511b41d2SMark Murray 1419511b41d2SMark Murray case sDenyUsers: 1420c2d3a559SKris Kennaway while ((arg = strdelim(&cp)) && *arg != '\0') { 14212803b77eSBrian Feldman if (options->num_deny_users >= MAX_DENY_USERS) 1422af12a3e7SDag-Erling Smørgrav fatal("%s line %d: too many deny users.", 1423e8aafc91SKris Kennaway filename, linenum); 1424462c32cbSDag-Erling Smørgrav if (!*activep) 1425462c32cbSDag-Erling Smørgrav continue; 1426a82e551fSDag-Erling Smørgrav options->deny_users[options->num_deny_users++] = 1427a82e551fSDag-Erling Smørgrav xstrdup(arg); 1428511b41d2SMark Murray } 1429511b41d2SMark Murray break; 1430511b41d2SMark Murray 1431511b41d2SMark Murray case sAllowGroups: 1432c2d3a559SKris Kennaway while ((arg = strdelim(&cp)) && *arg != '\0') { 143342f71286SMark Murray if (options->num_allow_groups >= MAX_ALLOW_GROUPS) 1434af12a3e7SDag-Erling Smørgrav fatal("%s line %d: too many allow groups.", 1435e8aafc91SKris Kennaway filename, linenum); 1436462c32cbSDag-Erling Smørgrav if (!*activep) 1437462c32cbSDag-Erling Smørgrav continue; 1438a82e551fSDag-Erling Smørgrav options->allow_groups[options->num_allow_groups++] = 1439a82e551fSDag-Erling Smørgrav xstrdup(arg); 1440511b41d2SMark Murray } 1441511b41d2SMark Murray break; 1442511b41d2SMark Murray 1443511b41d2SMark Murray case sDenyGroups: 1444c2d3a559SKris Kennaway while ((arg = strdelim(&cp)) && *arg != '\0') { 144542f71286SMark Murray if (options->num_deny_groups >= MAX_DENY_GROUPS) 1446af12a3e7SDag-Erling Smørgrav fatal("%s line %d: too many deny groups.", 1447e8aafc91SKris Kennaway filename, linenum); 1448462c32cbSDag-Erling Smørgrav if (!*activep) 1449462c32cbSDag-Erling Smørgrav continue; 1450462c32cbSDag-Erling Smørgrav options->deny_groups[options->num_deny_groups++] = 1451462c32cbSDag-Erling Smørgrav xstrdup(arg); 1452511b41d2SMark Murray } 1453511b41d2SMark Murray break; 1454511b41d2SMark Murray 1455e8aafc91SKris Kennaway case sCiphers: 1456c2d3a559SKris Kennaway arg = strdelim(&cp); 1457c2d3a559SKris Kennaway if (!arg || *arg == '\0') 1458c322fe35SKris Kennaway fatal("%s line %d: Missing argument.", filename, linenum); 1459eccfee6eSDag-Erling Smørgrav if (!ciphers_valid(*arg == '+' ? arg + 1 : arg)) 1460e8aafc91SKris Kennaway fatal("%s line %d: Bad SSH2 cipher spec '%s'.", 1461c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 1462e8aafc91SKris Kennaway if (options->ciphers == NULL) 1463c2d3a559SKris Kennaway options->ciphers = xstrdup(arg); 1464e8aafc91SKris Kennaway break; 1465e8aafc91SKris Kennaway 1466ca3176e7SBrian Feldman case sMacs: 1467ca3176e7SBrian Feldman arg = strdelim(&cp); 1468ca3176e7SBrian Feldman if (!arg || *arg == '\0') 1469ca3176e7SBrian Feldman fatal("%s line %d: Missing argument.", filename, linenum); 1470eccfee6eSDag-Erling Smørgrav if (!mac_valid(*arg == '+' ? arg + 1 : arg)) 1471ca3176e7SBrian Feldman fatal("%s line %d: Bad SSH2 mac spec '%s'.", 1472ca3176e7SBrian Feldman filename, linenum, arg ? arg : "<NONE>"); 1473ca3176e7SBrian Feldman if (options->macs == NULL) 1474ca3176e7SBrian Feldman options->macs = xstrdup(arg); 1475ca3176e7SBrian Feldman break; 1476ca3176e7SBrian Feldman 14774a421b63SDag-Erling Smørgrav case sKexAlgorithms: 14784a421b63SDag-Erling Smørgrav arg = strdelim(&cp); 14794a421b63SDag-Erling Smørgrav if (!arg || *arg == '\0') 14804a421b63SDag-Erling Smørgrav fatal("%s line %d: Missing argument.", 14814a421b63SDag-Erling Smørgrav filename, linenum); 1482eccfee6eSDag-Erling Smørgrav if (!kex_names_valid(*arg == '+' ? arg + 1 : arg)) 14834a421b63SDag-Erling Smørgrav fatal("%s line %d: Bad SSH2 KexAlgorithms '%s'.", 14844a421b63SDag-Erling Smørgrav filename, linenum, arg ? arg : "<NONE>"); 14854a421b63SDag-Erling Smørgrav if (options->kex_algorithms == NULL) 14864a421b63SDag-Erling Smørgrav options->kex_algorithms = xstrdup(arg); 14874a421b63SDag-Erling Smørgrav break; 14884a421b63SDag-Erling Smørgrav 1489e8aafc91SKris Kennaway case sProtocol: 1490e8aafc91SKris Kennaway intptr = &options->protocol; 1491c2d3a559SKris Kennaway arg = strdelim(&cp); 1492c2d3a559SKris Kennaway if (!arg || *arg == '\0') 1493c322fe35SKris Kennaway fatal("%s line %d: Missing argument.", filename, linenum); 1494c2d3a559SKris Kennaway value = proto_spec(arg); 1495e8aafc91SKris Kennaway if (value == SSH_PROTO_UNKNOWN) 1496e8aafc91SKris Kennaway fatal("%s line %d: Bad protocol spec '%s'.", 1497c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 1498e8aafc91SKris Kennaway if (*intptr == SSH_PROTO_UNKNOWN) 1499e8aafc91SKris Kennaway *intptr = value; 1500e8aafc91SKris Kennaway break; 1501e8aafc91SKris Kennaway 1502c2d3a559SKris Kennaway case sSubsystem: 1503c2d3a559SKris Kennaway if (options->num_subsystems >= MAX_SUBSYSTEMS) { 1504c2d3a559SKris Kennaway fatal("%s line %d: too many subsystems defined.", 1505c2d3a559SKris Kennaway filename, linenum); 1506c2d3a559SKris Kennaway } 1507c2d3a559SKris Kennaway arg = strdelim(&cp); 1508c2d3a559SKris Kennaway if (!arg || *arg == '\0') 1509c2d3a559SKris Kennaway fatal("%s line %d: Missing subsystem name.", 1510c2d3a559SKris Kennaway filename, linenum); 1511333ee039SDag-Erling Smørgrav if (!*activep) { 1512333ee039SDag-Erling Smørgrav arg = strdelim(&cp); 1513333ee039SDag-Erling Smørgrav break; 1514333ee039SDag-Erling Smørgrav } 1515c2d3a559SKris Kennaway for (i = 0; i < options->num_subsystems; i++) 1516c2d3a559SKris Kennaway if (strcmp(arg, options->subsystem_name[i]) == 0) 1517c2d3a559SKris Kennaway fatal("%s line %d: Subsystem '%s' already defined.", 1518c2d3a559SKris Kennaway filename, linenum, arg); 1519c2d3a559SKris Kennaway options->subsystem_name[options->num_subsystems] = xstrdup(arg); 1520c2d3a559SKris Kennaway arg = strdelim(&cp); 1521c2d3a559SKris Kennaway if (!arg || *arg == '\0') 1522c2d3a559SKris Kennaway fatal("%s line %d: Missing subsystem command.", 1523c2d3a559SKris Kennaway filename, linenum); 1524c2d3a559SKris Kennaway options->subsystem_command[options->num_subsystems] = xstrdup(arg); 1525333ee039SDag-Erling Smørgrav 1526333ee039SDag-Erling Smørgrav /* Collect arguments (separate to executable) */ 1527333ee039SDag-Erling Smørgrav p = xstrdup(arg); 1528333ee039SDag-Erling Smørgrav len = strlen(p) + 1; 1529333ee039SDag-Erling Smørgrav while ((arg = strdelim(&cp)) != NULL && *arg != '\0') { 1530333ee039SDag-Erling Smørgrav len += 1 + strlen(arg); 1531557f75e5SDag-Erling Smørgrav p = xreallocarray(p, 1, len); 1532333ee039SDag-Erling Smørgrav strlcat(p, " ", len); 1533333ee039SDag-Erling Smørgrav strlcat(p, arg, len); 1534333ee039SDag-Erling Smørgrav } 1535333ee039SDag-Erling Smørgrav options->subsystem_args[options->num_subsystems] = p; 1536c2d3a559SKris Kennaway options->num_subsystems++; 1537c2d3a559SKris Kennaway break; 1538c2d3a559SKris Kennaway 1539c2d3a559SKris Kennaway case sMaxStartups: 1540c2d3a559SKris Kennaway arg = strdelim(&cp); 1541c2d3a559SKris Kennaway if (!arg || *arg == '\0') 1542c2d3a559SKris Kennaway fatal("%s line %d: Missing MaxStartups spec.", 1543c2d3a559SKris Kennaway filename, linenum); 1544af12a3e7SDag-Erling Smørgrav if ((n = sscanf(arg, "%d:%d:%d", 1545c2d3a559SKris Kennaway &options->max_startups_begin, 1546c2d3a559SKris Kennaway &options->max_startups_rate, 1547af12a3e7SDag-Erling Smørgrav &options->max_startups)) == 3) { 1548c2d3a559SKris Kennaway if (options->max_startups_begin > 1549c2d3a559SKris Kennaway options->max_startups || 1550c2d3a559SKris Kennaway options->max_startups_rate > 100 || 1551c2d3a559SKris Kennaway options->max_startups_rate < 1) 1552c2d3a559SKris Kennaway fatal("%s line %d: Illegal MaxStartups spec.", 1553c2d3a559SKris Kennaway filename, linenum); 1554af12a3e7SDag-Erling Smørgrav } else if (n != 1) 1555af12a3e7SDag-Erling Smørgrav fatal("%s line %d: Illegal MaxStartups spec.", 1556af12a3e7SDag-Erling Smørgrav filename, linenum); 1557af12a3e7SDag-Erling Smørgrav else 1558af12a3e7SDag-Erling Smørgrav options->max_startups = options->max_startups_begin; 1559933ca70fSBrian Feldman break; 1560933ca70fSBrian Feldman 156121e764dfSDag-Erling Smørgrav case sMaxAuthTries: 156221e764dfSDag-Erling Smørgrav intptr = &options->max_authtries; 156321e764dfSDag-Erling Smørgrav goto parse_int; 156421e764dfSDag-Erling Smørgrav 1565d4af9e69SDag-Erling Smørgrav case sMaxSessions: 1566d4af9e69SDag-Erling Smørgrav intptr = &options->max_sessions; 1567d4af9e69SDag-Erling Smørgrav goto parse_int; 1568d4af9e69SDag-Erling Smørgrav 1569ca3176e7SBrian Feldman case sBanner: 1570ca3176e7SBrian Feldman charptr = &options->banner; 1571ca3176e7SBrian Feldman goto parse_filename; 1572d4af9e69SDag-Erling Smørgrav 1573af12a3e7SDag-Erling Smørgrav /* 1574af12a3e7SDag-Erling Smørgrav * These options can contain %X options expanded at 1575af12a3e7SDag-Erling Smørgrav * connect time, so that you can specify paths like: 1576af12a3e7SDag-Erling Smørgrav * 1577af12a3e7SDag-Erling Smørgrav * AuthorizedKeysFile /etc/ssh_keys/%u 1578af12a3e7SDag-Erling Smørgrav */ 1579af12a3e7SDag-Erling Smørgrav case sAuthorizedKeysFile: 1580e146993eSDag-Erling Smørgrav if (*activep && options->num_authkeys_files == 0) { 1581e146993eSDag-Erling Smørgrav while ((arg = strdelim(&cp)) && *arg != '\0') { 1582e146993eSDag-Erling Smørgrav if (options->num_authkeys_files >= 1583e146993eSDag-Erling Smørgrav MAX_AUTHKEYS_FILES) 1584e146993eSDag-Erling Smørgrav fatal("%s line %d: " 1585e146993eSDag-Erling Smørgrav "too many authorized keys files.", 1586e146993eSDag-Erling Smørgrav filename, linenum); 1587e146993eSDag-Erling Smørgrav options->authorized_keys_files[ 1588e146993eSDag-Erling Smørgrav options->num_authkeys_files++] = 1589e146993eSDag-Erling Smørgrav tilde_expand_filename(arg, getuid()); 1590e146993eSDag-Erling Smørgrav } 1591e146993eSDag-Erling Smørgrav } 1592e146993eSDag-Erling Smørgrav return 0; 1593e146993eSDag-Erling Smørgrav 1594e2f6069cSDag-Erling Smørgrav case sAuthorizedPrincipalsFile: 1595e2f6069cSDag-Erling Smørgrav charptr = &options->authorized_principals_file; 15968ad9b54aSDag-Erling Smørgrav arg = strdelim(&cp); 15978ad9b54aSDag-Erling Smørgrav if (!arg || *arg == '\0') 15988ad9b54aSDag-Erling Smørgrav fatal("%s line %d: missing file name.", 15998ad9b54aSDag-Erling Smørgrav filename, linenum); 16008ad9b54aSDag-Erling Smørgrav if (*activep && *charptr == NULL) { 16018ad9b54aSDag-Erling Smørgrav *charptr = tilde_expand_filename(arg, getuid()); 16028ad9b54aSDag-Erling Smørgrav /* increase optional counter */ 16038ad9b54aSDag-Erling Smørgrav if (intptr != NULL) 16048ad9b54aSDag-Erling Smørgrav *intptr = *intptr + 1; 16058ad9b54aSDag-Erling Smørgrav } 16068ad9b54aSDag-Erling Smørgrav break; 1607af12a3e7SDag-Erling Smørgrav 1608ca3176e7SBrian Feldman case sClientAliveInterval: 1609ca3176e7SBrian Feldman intptr = &options->client_alive_interval; 1610af12a3e7SDag-Erling Smørgrav goto parse_time; 1611af12a3e7SDag-Erling Smørgrav 1612ca3176e7SBrian Feldman case sClientAliveCountMax: 1613ca3176e7SBrian Feldman intptr = &options->client_alive_count_max; 1614ca3176e7SBrian Feldman goto parse_int; 1615af12a3e7SDag-Erling Smørgrav 161621e764dfSDag-Erling Smørgrav case sAcceptEnv: 161721e764dfSDag-Erling Smørgrav while ((arg = strdelim(&cp)) && *arg != '\0') { 161821e764dfSDag-Erling Smørgrav if (strchr(arg, '=') != NULL) 161921e764dfSDag-Erling Smørgrav fatal("%s line %d: Invalid environment name.", 162021e764dfSDag-Erling Smørgrav filename, linenum); 162121e764dfSDag-Erling Smørgrav if (options->num_accept_env >= MAX_ACCEPT_ENV) 162221e764dfSDag-Erling Smørgrav fatal("%s line %d: too many allow env.", 162321e764dfSDag-Erling Smørgrav filename, linenum); 1624333ee039SDag-Erling Smørgrav if (!*activep) 1625462c32cbSDag-Erling Smørgrav continue; 162621e764dfSDag-Erling Smørgrav options->accept_env[options->num_accept_env++] = 162721e764dfSDag-Erling Smørgrav xstrdup(arg); 162821e764dfSDag-Erling Smørgrav } 162921e764dfSDag-Erling Smørgrav break; 163021e764dfSDag-Erling Smørgrav 1631b74df5b2SDag-Erling Smørgrav case sPermitTunnel: 1632b74df5b2SDag-Erling Smørgrav intptr = &options->permit_tun; 1633b74df5b2SDag-Erling Smørgrav arg = strdelim(&cp); 1634b74df5b2SDag-Erling Smørgrav if (!arg || *arg == '\0') 1635b74df5b2SDag-Erling Smørgrav fatal("%s line %d: Missing yes/point-to-point/" 1636b74df5b2SDag-Erling Smørgrav "ethernet/no argument.", filename, linenum); 1637d4af9e69SDag-Erling Smørgrav value = -1; 1638d4af9e69SDag-Erling Smørgrav for (i = 0; tunmode_desc[i].val != -1; i++) 1639d4af9e69SDag-Erling Smørgrav if (strcmp(tunmode_desc[i].text, arg) == 0) { 1640d4af9e69SDag-Erling Smørgrav value = tunmode_desc[i].val; 1641d4af9e69SDag-Erling Smørgrav break; 1642d4af9e69SDag-Erling Smørgrav } 1643d4af9e69SDag-Erling Smørgrav if (value == -1) 1644b74df5b2SDag-Erling Smørgrav fatal("%s line %d: Bad yes/point-to-point/ethernet/" 1645b74df5b2SDag-Erling Smørgrav "no argument: %s", filename, linenum, arg); 1646557f75e5SDag-Erling Smørgrav if (*activep && *intptr == -1) 1647b74df5b2SDag-Erling Smørgrav *intptr = value; 1648b74df5b2SDag-Erling Smørgrav break; 1649b74df5b2SDag-Erling Smørgrav 1650333ee039SDag-Erling Smørgrav case sMatch: 1651333ee039SDag-Erling Smørgrav if (cmdline) 1652333ee039SDag-Erling Smørgrav fatal("Match directive not supported as a command-line " 1653333ee039SDag-Erling Smørgrav "option"); 1654462c32cbSDag-Erling Smørgrav value = match_cfg_line(&cp, linenum, connectinfo); 1655333ee039SDag-Erling Smørgrav if (value < 0) 1656333ee039SDag-Erling Smørgrav fatal("%s line %d: Bad Match condition", filename, 1657333ee039SDag-Erling Smørgrav linenum); 1658333ee039SDag-Erling Smørgrav *activep = value; 1659333ee039SDag-Erling Smørgrav break; 1660333ee039SDag-Erling Smørgrav 1661333ee039SDag-Erling Smørgrav case sPermitOpen: 1662333ee039SDag-Erling Smørgrav arg = strdelim(&cp); 1663333ee039SDag-Erling Smørgrav if (!arg || *arg == '\0') 1664333ee039SDag-Erling Smørgrav fatal("%s line %d: missing PermitOpen specification", 1665333ee039SDag-Erling Smørgrav filename, linenum); 1666d4af9e69SDag-Erling Smørgrav n = options->num_permitted_opens; /* modified later */ 1667333ee039SDag-Erling Smørgrav if (strcmp(arg, "any") == 0) { 1668d4af9e69SDag-Erling Smørgrav if (*activep && n == -1) { 1669333ee039SDag-Erling Smørgrav channel_clear_adm_permitted_opens(); 1670333ee039SDag-Erling Smørgrav options->num_permitted_opens = 0; 1671333ee039SDag-Erling Smørgrav } 1672333ee039SDag-Erling Smørgrav break; 1673333ee039SDag-Erling Smørgrav } 1674462c32cbSDag-Erling Smørgrav if (strcmp(arg, "none") == 0) { 1675462c32cbSDag-Erling Smørgrav if (*activep && n == -1) { 1676462c32cbSDag-Erling Smørgrav options->num_permitted_opens = 1; 1677462c32cbSDag-Erling Smørgrav channel_disable_adm_local_opens(); 1678462c32cbSDag-Erling Smørgrav } 1679462c32cbSDag-Erling Smørgrav break; 1680462c32cbSDag-Erling Smørgrav } 1681d4af9e69SDag-Erling Smørgrav if (*activep && n == -1) 1682d4af9e69SDag-Erling Smørgrav channel_clear_adm_permitted_opens(); 1683333ee039SDag-Erling Smørgrav for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) { 1684333ee039SDag-Erling Smørgrav p = hpdelim(&arg); 1685333ee039SDag-Erling Smørgrav if (p == NULL) 1686333ee039SDag-Erling Smørgrav fatal("%s line %d: missing host in PermitOpen", 1687333ee039SDag-Erling Smørgrav filename, linenum); 1688333ee039SDag-Erling Smørgrav p = cleanhostname(p); 1689462c32cbSDag-Erling Smørgrav if (arg == NULL || ((port = permitopen_port(arg)) < 0)) 1690333ee039SDag-Erling Smørgrav fatal("%s line %d: bad port number in " 1691333ee039SDag-Erling Smørgrav "PermitOpen", filename, linenum); 1692d4af9e69SDag-Erling Smørgrav if (*activep && n == -1) 1693333ee039SDag-Erling Smørgrav options->num_permitted_opens = 1694333ee039SDag-Erling Smørgrav channel_add_adm_permitted_opens(p, port); 1695333ee039SDag-Erling Smørgrav } 1696333ee039SDag-Erling Smørgrav break; 1697333ee039SDag-Erling Smørgrav 1698333ee039SDag-Erling Smørgrav case sForceCommand: 1699557f75e5SDag-Erling Smørgrav if (cp == NULL || *cp == '\0') 1700333ee039SDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", filename, 1701333ee039SDag-Erling Smørgrav linenum); 1702333ee039SDag-Erling Smørgrav len = strspn(cp, WHITESPACE); 1703333ee039SDag-Erling Smørgrav if (*activep && options->adm_forced_command == NULL) 1704333ee039SDag-Erling Smørgrav options->adm_forced_command = xstrdup(cp + len); 1705333ee039SDag-Erling Smørgrav return 0; 1706333ee039SDag-Erling Smørgrav 1707d4af9e69SDag-Erling Smørgrav case sChrootDirectory: 1708d4af9e69SDag-Erling Smørgrav charptr = &options->chroot_directory; 1709d4af9e69SDag-Erling Smørgrav 1710d4af9e69SDag-Erling Smørgrav arg = strdelim(&cp); 1711d4af9e69SDag-Erling Smørgrav if (!arg || *arg == '\0') 1712d4af9e69SDag-Erling Smørgrav fatal("%s line %d: missing file name.", 1713d4af9e69SDag-Erling Smørgrav filename, linenum); 1714d4af9e69SDag-Erling Smørgrav if (*activep && *charptr == NULL) 1715d4af9e69SDag-Erling Smørgrav *charptr = xstrdup(arg); 1716d4af9e69SDag-Erling Smørgrav break; 1717d4af9e69SDag-Erling Smørgrav 1718b15c8340SDag-Erling Smørgrav case sTrustedUserCAKeys: 1719b15c8340SDag-Erling Smørgrav charptr = &options->trusted_user_ca_keys; 1720b15c8340SDag-Erling Smørgrav goto parse_filename; 1721b15c8340SDag-Erling Smørgrav 1722b15c8340SDag-Erling Smørgrav case sRevokedKeys: 1723b15c8340SDag-Erling Smørgrav charptr = &options->revoked_keys_file; 1724b15c8340SDag-Erling Smørgrav goto parse_filename; 1725b15c8340SDag-Erling Smørgrav 17264a421b63SDag-Erling Smørgrav case sIPQoS: 17274a421b63SDag-Erling Smørgrav arg = strdelim(&cp); 17284a421b63SDag-Erling Smørgrav if ((value = parse_ipqos(arg)) == -1) 17294a421b63SDag-Erling Smørgrav fatal("%s line %d: Bad IPQoS value: %s", 17304a421b63SDag-Erling Smørgrav filename, linenum, arg); 17314a421b63SDag-Erling Smørgrav arg = strdelim(&cp); 17324a421b63SDag-Erling Smørgrav if (arg == NULL) 17334a421b63SDag-Erling Smørgrav value2 = value; 17344a421b63SDag-Erling Smørgrav else if ((value2 = parse_ipqos(arg)) == -1) 17354a421b63SDag-Erling Smørgrav fatal("%s line %d: Bad IPQoS value: %s", 17364a421b63SDag-Erling Smørgrav filename, linenum, arg); 17374a421b63SDag-Erling Smørgrav if (*activep) { 17384a421b63SDag-Erling Smørgrav options->ip_qos_interactive = value; 17394a421b63SDag-Erling Smørgrav options->ip_qos_bulk = value2; 17404a421b63SDag-Erling Smørgrav } 17414a421b63SDag-Erling Smørgrav break; 17424a421b63SDag-Erling Smørgrav 1743db58a8e4SDag-Erling Smørgrav case sVersionAddendum: 1744557f75e5SDag-Erling Smørgrav if (cp == NULL || *cp == '\0') 1745462c32cbSDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", filename, 1746462c32cbSDag-Erling Smørgrav linenum); 1747462c32cbSDag-Erling Smørgrav len = strspn(cp, WHITESPACE); 1748462c32cbSDag-Erling Smørgrav if (*activep && options->version_addendum == NULL) { 1749462c32cbSDag-Erling Smørgrav if (strcasecmp(cp + len, "none") == 0) 1750462c32cbSDag-Erling Smørgrav options->version_addendum = xstrdup(""); 1751462c32cbSDag-Erling Smørgrav else if (strchr(cp + len, '\r') != NULL) 1752462c32cbSDag-Erling Smørgrav fatal("%.200s line %d: Invalid argument", 1753462c32cbSDag-Erling Smørgrav filename, linenum); 1754462c32cbSDag-Erling Smørgrav else 1755462c32cbSDag-Erling Smørgrav options->version_addendum = xstrdup(cp + len); 1756462c32cbSDag-Erling Smørgrav } 1757462c32cbSDag-Erling Smørgrav return 0; 1758db58a8e4SDag-Erling Smørgrav 17596888a9beSDag-Erling Smørgrav case sAuthorizedKeysCommand: 1760bc5531deSDag-Erling Smørgrav if (cp == NULL) 1761bc5531deSDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", filename, 1762bc5531deSDag-Erling Smørgrav linenum); 17636888a9beSDag-Erling Smørgrav len = strspn(cp, WHITESPACE); 17646888a9beSDag-Erling Smørgrav if (*activep && options->authorized_keys_command == NULL) { 17656888a9beSDag-Erling Smørgrav if (cp[len] != '/' && strcasecmp(cp + len, "none") != 0) 17666888a9beSDag-Erling Smørgrav fatal("%.200s line %d: AuthorizedKeysCommand " 17676888a9beSDag-Erling Smørgrav "must be an absolute path", 17686888a9beSDag-Erling Smørgrav filename, linenum); 17696888a9beSDag-Erling Smørgrav options->authorized_keys_command = xstrdup(cp + len); 17706888a9beSDag-Erling Smørgrav } 17716888a9beSDag-Erling Smørgrav return 0; 17726888a9beSDag-Erling Smørgrav 17736888a9beSDag-Erling Smørgrav case sAuthorizedKeysCommandUser: 17746888a9beSDag-Erling Smørgrav charptr = &options->authorized_keys_command_user; 17756888a9beSDag-Erling Smørgrav 17766888a9beSDag-Erling Smørgrav arg = strdelim(&cp); 1777bc5531deSDag-Erling Smørgrav if (!arg || *arg == '\0') 1778bc5531deSDag-Erling Smørgrav fatal("%s line %d: missing AuthorizedKeysCommandUser " 1779bc5531deSDag-Erling Smørgrav "argument.", filename, linenum); 17806888a9beSDag-Erling Smørgrav if (*activep && *charptr == NULL) 17816888a9beSDag-Erling Smørgrav *charptr = xstrdup(arg); 17826888a9beSDag-Erling Smørgrav break; 17836888a9beSDag-Erling Smørgrav 1784557f75e5SDag-Erling Smørgrav case sAuthorizedPrincipalsCommand: 1785557f75e5SDag-Erling Smørgrav if (cp == NULL) 1786557f75e5SDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", filename, 1787557f75e5SDag-Erling Smørgrav linenum); 1788557f75e5SDag-Erling Smørgrav len = strspn(cp, WHITESPACE); 1789557f75e5SDag-Erling Smørgrav if (*activep && 1790557f75e5SDag-Erling Smørgrav options->authorized_principals_command == NULL) { 1791557f75e5SDag-Erling Smørgrav if (cp[len] != '/' && strcasecmp(cp + len, "none") != 0) 1792557f75e5SDag-Erling Smørgrav fatal("%.200s line %d: " 1793557f75e5SDag-Erling Smørgrav "AuthorizedPrincipalsCommand must be " 1794557f75e5SDag-Erling Smørgrav "an absolute path", filename, linenum); 1795557f75e5SDag-Erling Smørgrav options->authorized_principals_command = 1796557f75e5SDag-Erling Smørgrav xstrdup(cp + len); 1797557f75e5SDag-Erling Smørgrav } 1798557f75e5SDag-Erling Smørgrav return 0; 1799557f75e5SDag-Erling Smørgrav 1800557f75e5SDag-Erling Smørgrav case sAuthorizedPrincipalsCommandUser: 1801557f75e5SDag-Erling Smørgrav charptr = &options->authorized_principals_command_user; 1802557f75e5SDag-Erling Smørgrav 1803557f75e5SDag-Erling Smørgrav arg = strdelim(&cp); 1804557f75e5SDag-Erling Smørgrav if (!arg || *arg == '\0') 1805557f75e5SDag-Erling Smørgrav fatal("%s line %d: missing " 1806557f75e5SDag-Erling Smørgrav "AuthorizedPrincipalsCommandUser argument.", 1807557f75e5SDag-Erling Smørgrav filename, linenum); 1808557f75e5SDag-Erling Smørgrav if (*activep && *charptr == NULL) 1809557f75e5SDag-Erling Smørgrav *charptr = xstrdup(arg); 1810557f75e5SDag-Erling Smørgrav break; 1811557f75e5SDag-Erling Smørgrav 18126888a9beSDag-Erling Smørgrav case sAuthenticationMethods: 1813557f75e5SDag-Erling Smørgrav if (options->num_auth_methods == 0) { 18146888a9beSDag-Erling Smørgrav while ((arg = strdelim(&cp)) && *arg != '\0') { 18156888a9beSDag-Erling Smørgrav if (options->num_auth_methods >= 18166888a9beSDag-Erling Smørgrav MAX_AUTH_METHODS) 18176888a9beSDag-Erling Smørgrav fatal("%s line %d: " 18186888a9beSDag-Erling Smørgrav "too many authentication methods.", 18196888a9beSDag-Erling Smørgrav filename, linenum); 18206888a9beSDag-Erling Smørgrav if (auth2_methods_valid(arg, 0) != 0) 18216888a9beSDag-Erling Smørgrav fatal("%s line %d: invalid " 18226888a9beSDag-Erling Smørgrav "authentication method list.", 18236888a9beSDag-Erling Smørgrav filename, linenum); 1824557f75e5SDag-Erling Smørgrav if (!*activep) 1825557f75e5SDag-Erling Smørgrav continue; 18266888a9beSDag-Erling Smørgrav options->auth_methods[ 18276888a9beSDag-Erling Smørgrav options->num_auth_methods++] = xstrdup(arg); 18286888a9beSDag-Erling Smørgrav } 18296888a9beSDag-Erling Smørgrav } 18306888a9beSDag-Erling Smørgrav return 0; 18316888a9beSDag-Erling Smørgrav 1832a0ee8cc6SDag-Erling Smørgrav case sStreamLocalBindMask: 1833a0ee8cc6SDag-Erling Smørgrav arg = strdelim(&cp); 1834a0ee8cc6SDag-Erling Smørgrav if (!arg || *arg == '\0') 1835557f75e5SDag-Erling Smørgrav fatal("%s line %d: missing StreamLocalBindMask " 1836557f75e5SDag-Erling Smørgrav "argument.", filename, linenum); 1837a0ee8cc6SDag-Erling Smørgrav /* Parse mode in octal format */ 1838a0ee8cc6SDag-Erling Smørgrav value = strtol(arg, &p, 8); 1839a0ee8cc6SDag-Erling Smørgrav if (arg == p || value < 0 || value > 0777) 1840a0ee8cc6SDag-Erling Smørgrav fatal("%s line %d: Bad mask.", filename, linenum); 1841557f75e5SDag-Erling Smørgrav if (*activep) 1842a0ee8cc6SDag-Erling Smørgrav options->fwd_opts.streamlocal_bind_mask = (mode_t)value; 1843a0ee8cc6SDag-Erling Smørgrav break; 1844a0ee8cc6SDag-Erling Smørgrav 1845a0ee8cc6SDag-Erling Smørgrav case sStreamLocalBindUnlink: 1846a0ee8cc6SDag-Erling Smørgrav intptr = &options->fwd_opts.streamlocal_bind_unlink; 1847a0ee8cc6SDag-Erling Smørgrav goto parse_flag; 1848a0ee8cc6SDag-Erling Smørgrav 1849bc5531deSDag-Erling Smørgrav case sFingerprintHash: 1850bc5531deSDag-Erling Smørgrav arg = strdelim(&cp); 1851bc5531deSDag-Erling Smørgrav if (!arg || *arg == '\0') 1852bc5531deSDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", 1853bc5531deSDag-Erling Smørgrav filename, linenum); 1854bc5531deSDag-Erling Smørgrav if ((value = ssh_digest_alg_by_name(arg)) == -1) 1855bc5531deSDag-Erling Smørgrav fatal("%.200s line %d: Invalid hash algorithm \"%s\".", 1856bc5531deSDag-Erling Smørgrav filename, linenum, arg); 1857bc5531deSDag-Erling Smørgrav if (*activep) 1858bc5531deSDag-Erling Smørgrav options->fingerprint_hash = value; 1859bc5531deSDag-Erling Smørgrav break; 1860bc5531deSDag-Erling Smørgrav 1861af12a3e7SDag-Erling Smørgrav case sDeprecated: 1862cf2b5f3bSDag-Erling Smørgrav logit("%s line %d: Deprecated option %s", 1863cf2b5f3bSDag-Erling Smørgrav filename, linenum, arg); 1864cf2b5f3bSDag-Erling Smørgrav while (arg) 1865cf2b5f3bSDag-Erling Smørgrav arg = strdelim(&cp); 1866cf2b5f3bSDag-Erling Smørgrav break; 1867cf2b5f3bSDag-Erling Smørgrav 1868cf2b5f3bSDag-Erling Smørgrav case sUnsupported: 1869cf2b5f3bSDag-Erling Smørgrav logit("%s line %d: Unsupported option %s", 1870af12a3e7SDag-Erling Smørgrav filename, linenum, arg); 1871af12a3e7SDag-Erling Smørgrav while (arg) 1872af12a3e7SDag-Erling Smørgrav arg = strdelim(&cp); 1873af12a3e7SDag-Erling Smørgrav break; 1874af12a3e7SDag-Erling Smørgrav 187542f71286SMark Murray default: 1876af12a3e7SDag-Erling Smørgrav fatal("%s line %d: Missing handler for opcode %s (%d)", 1877c2d3a559SKris Kennaway filename, linenum, arg, opcode); 1878511b41d2SMark Murray } 1879ca3176e7SBrian Feldman if ((arg = strdelim(&cp)) != NULL && *arg != '\0') 1880ca3176e7SBrian Feldman fatal("%s line %d: garbage at end of line; \"%.200s\".", 1881c2d3a559SKris Kennaway filename, linenum, arg); 1882af12a3e7SDag-Erling Smørgrav return 0; 1883af12a3e7SDag-Erling Smørgrav } 1884af12a3e7SDag-Erling Smørgrav 1885af12a3e7SDag-Erling Smørgrav /* Reads the server configuration file. */ 1886af12a3e7SDag-Erling Smørgrav 1887af12a3e7SDag-Erling Smørgrav void 188821e764dfSDag-Erling Smørgrav load_server_config(const char *filename, Buffer *conf) 1889af12a3e7SDag-Erling Smørgrav { 1890462c32cbSDag-Erling Smørgrav char line[4096], *cp; 1891a82e551fSDag-Erling Smørgrav FILE *f; 1892462c32cbSDag-Erling Smørgrav int lineno = 0; 1893af12a3e7SDag-Erling Smørgrav 189421e764dfSDag-Erling Smørgrav debug2("%s: filename %s", __func__, filename); 189521e764dfSDag-Erling Smørgrav if ((f = fopen(filename, "r")) == NULL) { 1896af12a3e7SDag-Erling Smørgrav perror(filename); 1897af12a3e7SDag-Erling Smørgrav exit(1); 1898af12a3e7SDag-Erling Smørgrav } 189921e764dfSDag-Erling Smørgrav buffer_clear(conf); 1900af12a3e7SDag-Erling Smørgrav while (fgets(line, sizeof(line), f)) { 1901462c32cbSDag-Erling Smørgrav lineno++; 1902462c32cbSDag-Erling Smørgrav if (strlen(line) == sizeof(line) - 1) 1903462c32cbSDag-Erling Smørgrav fatal("%s line %d too long", filename, lineno); 190421e764dfSDag-Erling Smørgrav /* 190521e764dfSDag-Erling Smørgrav * Trim out comments and strip whitespace 190621e764dfSDag-Erling Smørgrav * NB - preserve newlines, they are needed to reproduce 190721e764dfSDag-Erling Smørgrav * line numbers later for error messages 190821e764dfSDag-Erling Smørgrav */ 190921e764dfSDag-Erling Smørgrav if ((cp = strchr(line, '#')) != NULL) 191021e764dfSDag-Erling Smørgrav memcpy(cp, "\n", 2); 191121e764dfSDag-Erling Smørgrav cp = line + strspn(line, " \t\r"); 191221e764dfSDag-Erling Smørgrav 191321e764dfSDag-Erling Smørgrav buffer_append(conf, cp, strlen(cp)); 191421e764dfSDag-Erling Smørgrav } 191521e764dfSDag-Erling Smørgrav buffer_append(conf, "\0", 1); 191621e764dfSDag-Erling Smørgrav fclose(f); 191721e764dfSDag-Erling Smørgrav debug2("%s: done config len = %d", __func__, buffer_len(conf)); 191821e764dfSDag-Erling Smørgrav } 191921e764dfSDag-Erling Smørgrav 192021e764dfSDag-Erling Smørgrav void 1921462c32cbSDag-Erling Smørgrav parse_server_match_config(ServerOptions *options, 1922462c32cbSDag-Erling Smørgrav struct connection_info *connectinfo) 192321e764dfSDag-Erling Smørgrav { 1924333ee039SDag-Erling Smørgrav ServerOptions mo; 1925333ee039SDag-Erling Smørgrav 1926333ee039SDag-Erling Smørgrav initialize_server_options(&mo); 1927462c32cbSDag-Erling Smørgrav parse_server_config(&mo, "reprocess config", &cfg, connectinfo); 1928d4af9e69SDag-Erling Smørgrav copy_set_server_options(options, &mo, 0); 1929333ee039SDag-Erling Smørgrav } 1930333ee039SDag-Erling Smørgrav 1931462c32cbSDag-Erling Smørgrav int parse_server_match_testspec(struct connection_info *ci, char *spec) 1932462c32cbSDag-Erling Smørgrav { 1933462c32cbSDag-Erling Smørgrav char *p; 1934462c32cbSDag-Erling Smørgrav 1935462c32cbSDag-Erling Smørgrav while ((p = strsep(&spec, ",")) && *p != '\0') { 1936462c32cbSDag-Erling Smørgrav if (strncmp(p, "addr=", 5) == 0) { 1937462c32cbSDag-Erling Smørgrav ci->address = xstrdup(p + 5); 1938462c32cbSDag-Erling Smørgrav } else if (strncmp(p, "host=", 5) == 0) { 1939462c32cbSDag-Erling Smørgrav ci->host = xstrdup(p + 5); 1940462c32cbSDag-Erling Smørgrav } else if (strncmp(p, "user=", 5) == 0) { 1941462c32cbSDag-Erling Smørgrav ci->user = xstrdup(p + 5); 1942462c32cbSDag-Erling Smørgrav } else if (strncmp(p, "laddr=", 6) == 0) { 1943462c32cbSDag-Erling Smørgrav ci->laddress = xstrdup(p + 6); 1944462c32cbSDag-Erling Smørgrav } else if (strncmp(p, "lport=", 6) == 0) { 1945462c32cbSDag-Erling Smørgrav ci->lport = a2port(p + 6); 1946462c32cbSDag-Erling Smørgrav if (ci->lport == -1) { 1947462c32cbSDag-Erling Smørgrav fprintf(stderr, "Invalid port '%s' in test mode" 1948462c32cbSDag-Erling Smørgrav " specification %s\n", p+6, p); 1949462c32cbSDag-Erling Smørgrav return -1; 1950462c32cbSDag-Erling Smørgrav } 1951462c32cbSDag-Erling Smørgrav } else { 1952462c32cbSDag-Erling Smørgrav fprintf(stderr, "Invalid test mode specification %s\n", 1953462c32cbSDag-Erling Smørgrav p); 1954462c32cbSDag-Erling Smørgrav return -1; 1955462c32cbSDag-Erling Smørgrav } 1956462c32cbSDag-Erling Smørgrav } 1957462c32cbSDag-Erling Smørgrav return 0; 1958462c32cbSDag-Erling Smørgrav } 1959462c32cbSDag-Erling Smørgrav 1960462c32cbSDag-Erling Smørgrav /* 1961462c32cbSDag-Erling Smørgrav * returns 1 for a complete spec, 0 for partial spec and -1 for an 1962462c32cbSDag-Erling Smørgrav * empty spec. 1963462c32cbSDag-Erling Smørgrav */ 1964462c32cbSDag-Erling Smørgrav int server_match_spec_complete(struct connection_info *ci) 1965462c32cbSDag-Erling Smørgrav { 1966462c32cbSDag-Erling Smørgrav if (ci->user && ci->host && ci->address) 1967462c32cbSDag-Erling Smørgrav return 1; /* complete */ 1968462c32cbSDag-Erling Smørgrav if (!ci->user && !ci->host && !ci->address) 1969462c32cbSDag-Erling Smørgrav return -1; /* empty */ 1970462c32cbSDag-Erling Smørgrav return 0; /* partial */ 1971462c32cbSDag-Erling Smørgrav } 1972462c32cbSDag-Erling Smørgrav 1973d4af9e69SDag-Erling Smørgrav /* 1974d4af9e69SDag-Erling Smørgrav * Copy any supported values that are set. 1975d4af9e69SDag-Erling Smørgrav * 19767aee6ffeSDag-Erling Smørgrav * If the preauth flag is set, we do not bother copying the string or 1977d4af9e69SDag-Erling Smørgrav * array values that are not used pre-authentication, because any that we 1978d4af9e69SDag-Erling Smørgrav * do use must be explictly sent in mm_getpwnamallow(). 1979d4af9e69SDag-Erling Smørgrav */ 1980333ee039SDag-Erling Smørgrav void 1981d4af9e69SDag-Erling Smørgrav copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) 1982333ee039SDag-Erling Smørgrav { 1983f7167e0eSDag-Erling Smørgrav #define M_CP_INTOPT(n) do {\ 1984f7167e0eSDag-Erling Smørgrav if (src->n != -1) \ 1985f7167e0eSDag-Erling Smørgrav dst->n = src->n; \ 1986f7167e0eSDag-Erling Smørgrav } while (0) 1987f7167e0eSDag-Erling Smørgrav 1988d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(password_authentication); 1989d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(gss_authentication); 1990d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(rsa_authentication); 1991d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(pubkey_authentication); 1992d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(kerberos_authentication); 1993d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(hostbased_authentication); 1994e2f6069cSDag-Erling Smørgrav M_CP_INTOPT(hostbased_uses_name_from_packet_only); 1995d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(kbd_interactive_authentication); 1996d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(permit_root_login); 1997cce7d346SDag-Erling Smørgrav M_CP_INTOPT(permit_empty_passwd); 1998d4af9e69SDag-Erling Smørgrav 1999d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(allow_tcp_forwarding); 2000a0ee8cc6SDag-Erling Smørgrav M_CP_INTOPT(allow_streamlocal_forwarding); 2001d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(allow_agent_forwarding); 2002e2f6069cSDag-Erling Smørgrav M_CP_INTOPT(permit_tun); 2003a0ee8cc6SDag-Erling Smørgrav M_CP_INTOPT(fwd_opts.gateway_ports); 2004d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(x11_display_offset); 2005d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(x11_forwarding); 2006d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(x11_use_localhost); 2007f7167e0eSDag-Erling Smørgrav M_CP_INTOPT(permit_tty); 2008a0ee8cc6SDag-Erling Smørgrav M_CP_INTOPT(permit_user_rc); 2009d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(max_sessions); 2010d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(max_authtries); 20114a421b63SDag-Erling Smørgrav M_CP_INTOPT(ip_qos_interactive); 20124a421b63SDag-Erling Smørgrav M_CP_INTOPT(ip_qos_bulk); 2013e4a9863fSDag-Erling Smørgrav M_CP_INTOPT(rekey_limit); 2014e4a9863fSDag-Erling Smørgrav M_CP_INTOPT(rekey_interval); 2015d4af9e69SDag-Erling Smørgrav 2016f7167e0eSDag-Erling Smørgrav /* M_CP_STROPT and M_CP_STRARRAYOPT should not appear before here */ 2017f7167e0eSDag-Erling Smørgrav #define M_CP_STROPT(n) do {\ 2018f7167e0eSDag-Erling Smørgrav if (src->n != NULL && dst->n != src->n) { \ 2019f7167e0eSDag-Erling Smørgrav free(dst->n); \ 2020f7167e0eSDag-Erling Smørgrav dst->n = src->n; \ 2021f7167e0eSDag-Erling Smørgrav } \ 2022f7167e0eSDag-Erling Smørgrav } while(0) 2023f7167e0eSDag-Erling Smørgrav #define M_CP_STRARRAYOPT(n, num_n) do {\ 2024f7167e0eSDag-Erling Smørgrav if (src->num_n != 0) { \ 2025f7167e0eSDag-Erling Smørgrav for (dst->num_n = 0; dst->num_n < src->num_n; dst->num_n++) \ 2026f7167e0eSDag-Erling Smørgrav dst->n[dst->num_n] = xstrdup(src->n[dst->num_n]); \ 2027f7167e0eSDag-Erling Smørgrav } \ 2028f7167e0eSDag-Erling Smørgrav } while(0) 2029f7167e0eSDag-Erling Smørgrav 2030e146993eSDag-Erling Smørgrav /* See comment in servconf.h */ 2031e146993eSDag-Erling Smørgrav COPY_MATCH_STRING_OPTS(); 2032e146993eSDag-Erling Smørgrav 2033*acc1a9efSDag-Erling Smørgrav /* Arguments that accept '+...' need to be expanded */ 2034*acc1a9efSDag-Erling Smørgrav assemble_algorithms(dst); 2035*acc1a9efSDag-Erling Smørgrav 2036e146993eSDag-Erling Smørgrav /* 2037e146993eSDag-Erling Smørgrav * The only things that should be below this point are string options 2038e146993eSDag-Erling Smørgrav * which are only used after authentication. 2039e146993eSDag-Erling Smørgrav */ 2040d4af9e69SDag-Erling Smørgrav if (preauth) 2041d4af9e69SDag-Erling Smørgrav return; 2042e146993eSDag-Erling Smørgrav 2043*acc1a9efSDag-Erling Smørgrav /* These options may be "none" to clear a global setting */ 2044d4af9e69SDag-Erling Smørgrav M_CP_STROPT(adm_forced_command); 2045*acc1a9efSDag-Erling Smørgrav if (option_clear_or_none(dst->adm_forced_command)) { 2046*acc1a9efSDag-Erling Smørgrav free(dst->adm_forced_command); 2047*acc1a9efSDag-Erling Smørgrav dst->adm_forced_command = NULL; 2048*acc1a9efSDag-Erling Smørgrav } 2049d4af9e69SDag-Erling Smørgrav M_CP_STROPT(chroot_directory); 2050*acc1a9efSDag-Erling Smørgrav if (option_clear_or_none(dst->chroot_directory)) { 2051*acc1a9efSDag-Erling Smørgrav free(dst->chroot_directory); 2052*acc1a9efSDag-Erling Smørgrav dst->chroot_directory = NULL; 2053*acc1a9efSDag-Erling Smørgrav } 2054333ee039SDag-Erling Smørgrav } 2055d4af9e69SDag-Erling Smørgrav 2056d4af9e69SDag-Erling Smørgrav #undef M_CP_INTOPT 2057d4af9e69SDag-Erling Smørgrav #undef M_CP_STROPT 2058e146993eSDag-Erling Smørgrav #undef M_CP_STRARRAYOPT 2059333ee039SDag-Erling Smørgrav 2060333ee039SDag-Erling Smørgrav void 2061333ee039SDag-Erling Smørgrav parse_server_config(ServerOptions *options, const char *filename, Buffer *conf, 2062462c32cbSDag-Erling Smørgrav struct connection_info *connectinfo) 2063333ee039SDag-Erling Smørgrav { 2064333ee039SDag-Erling Smørgrav int active, linenum, bad_options = 0; 206521e764dfSDag-Erling Smørgrav char *cp, *obuf, *cbuf; 206621e764dfSDag-Erling Smørgrav 206721e764dfSDag-Erling Smørgrav debug2("%s: config %s len %d", __func__, filename, buffer_len(conf)); 206821e764dfSDag-Erling Smørgrav 206921e764dfSDag-Erling Smørgrav obuf = cbuf = xstrdup(buffer_ptr(conf)); 2070462c32cbSDag-Erling Smørgrav active = connectinfo ? 0 : 1; 207121e764dfSDag-Erling Smørgrav linenum = 1; 207221e764dfSDag-Erling Smørgrav while ((cp = strsep(&cbuf, "\n")) != NULL) { 207321e764dfSDag-Erling Smørgrav if (process_server_config_line(options, cp, filename, 2074462c32cbSDag-Erling Smørgrav linenum++, &active, connectinfo) != 0) 2075af12a3e7SDag-Erling Smørgrav bad_options++; 2076511b41d2SMark Murray } 2077e4a9863fSDag-Erling Smørgrav free(obuf); 2078ca3176e7SBrian Feldman if (bad_options > 0) 2079af12a3e7SDag-Erling Smørgrav fatal("%s: terminating, %d bad configuration options", 2080511b41d2SMark Murray filename, bad_options); 2081557f75e5SDag-Erling Smørgrav process_queued_listen_addrs(options); 2082511b41d2SMark Murray } 2083d4af9e69SDag-Erling Smørgrav 2084d4af9e69SDag-Erling Smørgrav static const char * 2085e146993eSDag-Erling Smørgrav fmt_multistate_int(int val, const struct multistate *m) 2086d4af9e69SDag-Erling Smørgrav { 2087e146993eSDag-Erling Smørgrav u_int i; 2088e146993eSDag-Erling Smørgrav 2089e146993eSDag-Erling Smørgrav for (i = 0; m[i].key != NULL; i++) { 2090e146993eSDag-Erling Smørgrav if (m[i].value == val) 2091e146993eSDag-Erling Smørgrav return m[i].key; 2092e146993eSDag-Erling Smørgrav } 2093d4af9e69SDag-Erling Smørgrav return "UNKNOWN"; 2094d4af9e69SDag-Erling Smørgrav } 2095e146993eSDag-Erling Smørgrav 2096e146993eSDag-Erling Smørgrav static const char * 2097e146993eSDag-Erling Smørgrav fmt_intarg(ServerOpCodes code, int val) 2098e146993eSDag-Erling Smørgrav { 2099e146993eSDag-Erling Smørgrav if (val == -1) 2100e146993eSDag-Erling Smørgrav return "unset"; 2101e146993eSDag-Erling Smørgrav switch (code) { 2102e146993eSDag-Erling Smørgrav case sAddressFamily: 2103e146993eSDag-Erling Smørgrav return fmt_multistate_int(val, multistate_addressfamily); 2104e146993eSDag-Erling Smørgrav case sPermitRootLogin: 2105e146993eSDag-Erling Smørgrav return fmt_multistate_int(val, multistate_permitrootlogin); 2106e146993eSDag-Erling Smørgrav case sGatewayPorts: 2107e146993eSDag-Erling Smørgrav return fmt_multistate_int(val, multistate_gatewayports); 2108e146993eSDag-Erling Smørgrav case sCompression: 2109e146993eSDag-Erling Smørgrav return fmt_multistate_int(val, multistate_compression); 2110e146993eSDag-Erling Smørgrav case sUsePrivilegeSeparation: 2111e146993eSDag-Erling Smørgrav return fmt_multistate_int(val, multistate_privsep); 21126888a9beSDag-Erling Smørgrav case sAllowTcpForwarding: 21136888a9beSDag-Erling Smørgrav return fmt_multistate_int(val, multistate_tcpfwd); 2114a0ee8cc6SDag-Erling Smørgrav case sAllowStreamLocalForwarding: 2115a0ee8cc6SDag-Erling Smørgrav return fmt_multistate_int(val, multistate_tcpfwd); 2116bc5531deSDag-Erling Smørgrav case sFingerprintHash: 2117bc5531deSDag-Erling Smørgrav return ssh_digest_alg_name(val); 2118e146993eSDag-Erling Smørgrav case sProtocol: 2119d4af9e69SDag-Erling Smørgrav switch (val) { 2120d4af9e69SDag-Erling Smørgrav case SSH_PROTO_1: 2121d4af9e69SDag-Erling Smørgrav return "1"; 2122d4af9e69SDag-Erling Smørgrav case SSH_PROTO_2: 2123d4af9e69SDag-Erling Smørgrav return "2"; 2124d4af9e69SDag-Erling Smørgrav case (SSH_PROTO_1|SSH_PROTO_2): 2125d4af9e69SDag-Erling Smørgrav return "2,1"; 2126d4af9e69SDag-Erling Smørgrav default: 2127d4af9e69SDag-Erling Smørgrav return "UNKNOWN"; 2128d4af9e69SDag-Erling Smørgrav } 2129e146993eSDag-Erling Smørgrav default: 2130d4af9e69SDag-Erling Smørgrav switch (val) { 2131d4af9e69SDag-Erling Smørgrav case 0: 2132d4af9e69SDag-Erling Smørgrav return "no"; 2133d4af9e69SDag-Erling Smørgrav case 1: 2134d4af9e69SDag-Erling Smørgrav return "yes"; 2135e146993eSDag-Erling Smørgrav default: 2136d4af9e69SDag-Erling Smørgrav return "UNKNOWN"; 2137d4af9e69SDag-Erling Smørgrav } 2138e146993eSDag-Erling Smørgrav } 2139e146993eSDag-Erling Smørgrav } 2140d4af9e69SDag-Erling Smørgrav 2141d4af9e69SDag-Erling Smørgrav static const char * 2142d4af9e69SDag-Erling Smørgrav lookup_opcode_name(ServerOpCodes code) 2143d4af9e69SDag-Erling Smørgrav { 2144d4af9e69SDag-Erling Smørgrav u_int i; 2145d4af9e69SDag-Erling Smørgrav 2146d4af9e69SDag-Erling Smørgrav for (i = 0; keywords[i].name != NULL; i++) 2147d4af9e69SDag-Erling Smørgrav if (keywords[i].opcode == code) 2148d4af9e69SDag-Erling Smørgrav return(keywords[i].name); 2149d4af9e69SDag-Erling Smørgrav return "UNKNOWN"; 2150d4af9e69SDag-Erling Smørgrav } 2151d4af9e69SDag-Erling Smørgrav 2152d4af9e69SDag-Erling Smørgrav static void 2153d4af9e69SDag-Erling Smørgrav dump_cfg_int(ServerOpCodes code, int val) 2154d4af9e69SDag-Erling Smørgrav { 2155d4af9e69SDag-Erling Smørgrav printf("%s %d\n", lookup_opcode_name(code), val); 2156d4af9e69SDag-Erling Smørgrav } 2157d4af9e69SDag-Erling Smørgrav 2158d4af9e69SDag-Erling Smørgrav static void 2159557f75e5SDag-Erling Smørgrav dump_cfg_oct(ServerOpCodes code, int val) 2160557f75e5SDag-Erling Smørgrav { 2161557f75e5SDag-Erling Smørgrav printf("%s 0%o\n", lookup_opcode_name(code), val); 2162557f75e5SDag-Erling Smørgrav } 2163557f75e5SDag-Erling Smørgrav 2164557f75e5SDag-Erling Smørgrav static void 2165d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(ServerOpCodes code, int val) 2166d4af9e69SDag-Erling Smørgrav { 2167d4af9e69SDag-Erling Smørgrav printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val)); 2168d4af9e69SDag-Erling Smørgrav } 2169d4af9e69SDag-Erling Smørgrav 2170d4af9e69SDag-Erling Smørgrav static void 2171d4af9e69SDag-Erling Smørgrav dump_cfg_string(ServerOpCodes code, const char *val) 2172d4af9e69SDag-Erling Smørgrav { 2173d4af9e69SDag-Erling Smørgrav if (val == NULL) 2174d4af9e69SDag-Erling Smørgrav return; 2175bc5531deSDag-Erling Smørgrav printf("%s %s\n", lookup_opcode_name(code), 2176bc5531deSDag-Erling Smørgrav val == NULL ? "none" : val); 2177d4af9e69SDag-Erling Smørgrav } 2178d4af9e69SDag-Erling Smørgrav 2179d4af9e69SDag-Erling Smørgrav static void 2180d4af9e69SDag-Erling Smørgrav dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals) 2181d4af9e69SDag-Erling Smørgrav { 2182d4af9e69SDag-Erling Smørgrav u_int i; 2183d4af9e69SDag-Erling Smørgrav 2184d4af9e69SDag-Erling Smørgrav for (i = 0; i < count; i++) 2185d4af9e69SDag-Erling Smørgrav printf("%s %s\n", lookup_opcode_name(code), vals[i]); 2186d4af9e69SDag-Erling Smørgrav } 2187d4af9e69SDag-Erling Smørgrav 2188e146993eSDag-Erling Smørgrav static void 2189e146993eSDag-Erling Smørgrav dump_cfg_strarray_oneline(ServerOpCodes code, u_int count, char **vals) 2190e146993eSDag-Erling Smørgrav { 2191e146993eSDag-Erling Smørgrav u_int i; 2192e146993eSDag-Erling Smørgrav 2193557f75e5SDag-Erling Smørgrav if (count <= 0) 2194557f75e5SDag-Erling Smørgrav return; 2195e146993eSDag-Erling Smørgrav printf("%s", lookup_opcode_name(code)); 2196e146993eSDag-Erling Smørgrav for (i = 0; i < count; i++) 2197e146993eSDag-Erling Smørgrav printf(" %s", vals[i]); 2198e146993eSDag-Erling Smørgrav printf("\n"); 2199e146993eSDag-Erling Smørgrav } 2200e146993eSDag-Erling Smørgrav 2201d4af9e69SDag-Erling Smørgrav void 2202d4af9e69SDag-Erling Smørgrav dump_config(ServerOptions *o) 2203d4af9e69SDag-Erling Smørgrav { 2204d4af9e69SDag-Erling Smørgrav u_int i; 2205d4af9e69SDag-Erling Smørgrav int ret; 2206d4af9e69SDag-Erling Smørgrav struct addrinfo *ai; 2207d4af9e69SDag-Erling Smørgrav char addr[NI_MAXHOST], port[NI_MAXSERV], *s = NULL; 2208557f75e5SDag-Erling Smørgrav char *laddr1 = xstrdup(""), *laddr2 = NULL; 2209d4af9e69SDag-Erling Smørgrav 2210d4af9e69SDag-Erling Smørgrav /* these are usually at the top of the config */ 2211d4af9e69SDag-Erling Smørgrav for (i = 0; i < o->num_ports; i++) 2212d4af9e69SDag-Erling Smørgrav printf("port %d\n", o->ports[i]); 2213d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sProtocol, o->protocol); 2214d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sAddressFamily, o->address_family); 2215d4af9e69SDag-Erling Smørgrav 2216557f75e5SDag-Erling Smørgrav /* 2217557f75e5SDag-Erling Smørgrav * ListenAddress must be after Port. add_one_listen_addr pushes 2218557f75e5SDag-Erling Smørgrav * addresses onto a stack, so to maintain ordering we need to 2219557f75e5SDag-Erling Smørgrav * print these in reverse order. 2220557f75e5SDag-Erling Smørgrav */ 2221d4af9e69SDag-Erling Smørgrav for (ai = o->listen_addrs; ai; ai = ai->ai_next) { 2222d4af9e69SDag-Erling Smørgrav if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr, 2223d4af9e69SDag-Erling Smørgrav sizeof(addr), port, sizeof(port), 2224d4af9e69SDag-Erling Smørgrav NI_NUMERICHOST|NI_NUMERICSERV)) != 0) { 2225d4af9e69SDag-Erling Smørgrav error("getnameinfo failed: %.100s", 2226d4af9e69SDag-Erling Smørgrav (ret != EAI_SYSTEM) ? gai_strerror(ret) : 2227d4af9e69SDag-Erling Smørgrav strerror(errno)); 2228d4af9e69SDag-Erling Smørgrav } else { 2229557f75e5SDag-Erling Smørgrav laddr2 = laddr1; 2230d4af9e69SDag-Erling Smørgrav if (ai->ai_family == AF_INET6) 2231557f75e5SDag-Erling Smørgrav xasprintf(&laddr1, "listenaddress [%s]:%s\n%s", 2232557f75e5SDag-Erling Smørgrav addr, port, laddr2); 2233d4af9e69SDag-Erling Smørgrav else 2234557f75e5SDag-Erling Smørgrav xasprintf(&laddr1, "listenaddress %s:%s\n%s", 2235557f75e5SDag-Erling Smørgrav addr, port, laddr2); 2236557f75e5SDag-Erling Smørgrav free(laddr2); 2237d4af9e69SDag-Erling Smørgrav } 2238d4af9e69SDag-Erling Smørgrav } 2239557f75e5SDag-Erling Smørgrav printf("%s", laddr1); 2240557f75e5SDag-Erling Smørgrav free(laddr1); 2241d4af9e69SDag-Erling Smørgrav 2242d4af9e69SDag-Erling Smørgrav /* integer arguments */ 2243cce7d346SDag-Erling Smørgrav #ifdef USE_PAM 2244557f75e5SDag-Erling Smørgrav dump_cfg_fmtint(sUsePAM, o->use_pam); 2245cce7d346SDag-Erling Smørgrav #endif 2246d4af9e69SDag-Erling Smørgrav dump_cfg_int(sServerKeyBits, o->server_key_bits); 2247d4af9e69SDag-Erling Smørgrav dump_cfg_int(sLoginGraceTime, o->login_grace_time); 2248d4af9e69SDag-Erling Smørgrav dump_cfg_int(sKeyRegenerationTime, o->key_regeneration_time); 2249d4af9e69SDag-Erling Smørgrav dump_cfg_int(sX11DisplayOffset, o->x11_display_offset); 2250d4af9e69SDag-Erling Smørgrav dump_cfg_int(sMaxAuthTries, o->max_authtries); 2251cce7d346SDag-Erling Smørgrav dump_cfg_int(sMaxSessions, o->max_sessions); 2252d4af9e69SDag-Erling Smørgrav dump_cfg_int(sClientAliveInterval, o->client_alive_interval); 2253d4af9e69SDag-Erling Smørgrav dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max); 2254557f75e5SDag-Erling Smørgrav dump_cfg_oct(sStreamLocalBindMask, o->fwd_opts.streamlocal_bind_mask); 2255d4af9e69SDag-Erling Smørgrav 2256d4af9e69SDag-Erling Smørgrav /* formatted integer arguments */ 2257d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login); 2258d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts); 2259d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts); 2260d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sRhostsRSAAuthentication, o->rhosts_rsa_authentication); 2261d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication); 2262d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly, 2263d4af9e69SDag-Erling Smørgrav o->hostbased_uses_name_from_packet_only); 2264d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sRSAAuthentication, o->rsa_authentication); 2265d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication); 2266cce7d346SDag-Erling Smørgrav #ifdef KRB5 2267d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication); 2268d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd); 2269d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup); 2270cce7d346SDag-Erling Smørgrav # ifdef USE_AFS 2271d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); 2272cce7d346SDag-Erling Smørgrav # endif 2273cce7d346SDag-Erling Smørgrav #endif 2274cce7d346SDag-Erling Smørgrav #ifdef GSSAPI 2275d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); 2276d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); 2277cce7d346SDag-Erling Smørgrav #endif 2278d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); 2279d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sKbdInteractiveAuthentication, 2280d4af9e69SDag-Erling Smørgrav o->kbd_interactive_authentication); 2281d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sChallengeResponseAuthentication, 2282d4af9e69SDag-Erling Smørgrav o->challenge_response_authentication); 2283d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sPrintMotd, o->print_motd); 2284*acc1a9efSDag-Erling Smørgrav #ifndef DISABLE_LASTLOG 2285d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sPrintLastLog, o->print_lastlog); 2286*acc1a9efSDag-Erling Smørgrav #endif 2287d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding); 2288d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost); 2289f7167e0eSDag-Erling Smørgrav dump_cfg_fmtint(sPermitTTY, o->permit_tty); 2290a0ee8cc6SDag-Erling Smørgrav dump_cfg_fmtint(sPermitUserRC, o->permit_user_rc); 2291d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sStrictModes, o->strict_modes); 2292d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive); 2293d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd); 2294d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env); 2295d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sUseLogin, o->use_login); 2296d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sCompression, o->compression); 2297a0ee8cc6SDag-Erling Smørgrav dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports); 2298d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sUseDNS, o->use_dns); 2299d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); 2300557f75e5SDag-Erling Smørgrav dump_cfg_fmtint(sAllowAgentForwarding, o->allow_agent_forwarding); 2301a0ee8cc6SDag-Erling Smørgrav dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding); 2302d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); 2303bc5531deSDag-Erling Smørgrav dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); 2304d4af9e69SDag-Erling Smørgrav 2305d4af9e69SDag-Erling Smørgrav /* string arguments */ 2306d4af9e69SDag-Erling Smørgrav dump_cfg_string(sPidFile, o->pid_file); 2307d4af9e69SDag-Erling Smørgrav dump_cfg_string(sXAuthLocation, o->xauth_location); 2308bc5531deSDag-Erling Smørgrav dump_cfg_string(sCiphers, o->ciphers ? o->ciphers : KEX_SERVER_ENCRYPT); 2309bc5531deSDag-Erling Smørgrav dump_cfg_string(sMacs, o->macs ? o->macs : KEX_SERVER_MAC); 2310d4af9e69SDag-Erling Smørgrav dump_cfg_string(sBanner, o->banner); 2311d4af9e69SDag-Erling Smørgrav dump_cfg_string(sForceCommand, o->adm_forced_command); 2312b15c8340SDag-Erling Smørgrav dump_cfg_string(sChrootDirectory, o->chroot_directory); 2313b15c8340SDag-Erling Smørgrav dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys); 2314b15c8340SDag-Erling Smørgrav dump_cfg_string(sRevokedKeys, o->revoked_keys_file); 2315e2f6069cSDag-Erling Smørgrav dump_cfg_string(sAuthorizedPrincipalsFile, 2316e2f6069cSDag-Erling Smørgrav o->authorized_principals_file); 2317557f75e5SDag-Erling Smørgrav dump_cfg_string(sVersionAddendum, *o->version_addendum == '\0' 2318557f75e5SDag-Erling Smørgrav ? "none" : o->version_addendum); 23196888a9beSDag-Erling Smørgrav dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command); 23206888a9beSDag-Erling Smørgrav dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user); 2321557f75e5SDag-Erling Smørgrav dump_cfg_string(sAuthorizedPrincipalsCommand, o->authorized_principals_command); 2322557f75e5SDag-Erling Smørgrav dump_cfg_string(sAuthorizedPrincipalsCommandUser, o->authorized_principals_command_user); 2323e4a9863fSDag-Erling Smørgrav dump_cfg_string(sHostKeyAgent, o->host_key_agent); 2324bc5531deSDag-Erling Smørgrav dump_cfg_string(sKexAlgorithms, 2325bc5531deSDag-Erling Smørgrav o->kex_algorithms ? o->kex_algorithms : KEX_SERVER_KEX); 2326bc5531deSDag-Erling Smørgrav dump_cfg_string(sHostbasedAcceptedKeyTypes, o->hostbased_key_types ? 2327bc5531deSDag-Erling Smørgrav o->hostbased_key_types : KEX_DEFAULT_PK_ALG); 2328eccfee6eSDag-Erling Smørgrav dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms ? 2329eccfee6eSDag-Erling Smørgrav o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG); 2330bc5531deSDag-Erling Smørgrav dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ? 2331bc5531deSDag-Erling Smørgrav o->pubkey_key_types : KEX_DEFAULT_PK_ALG); 2332d4af9e69SDag-Erling Smørgrav 2333d4af9e69SDag-Erling Smørgrav /* string arguments requiring a lookup */ 2334d4af9e69SDag-Erling Smørgrav dump_cfg_string(sLogLevel, log_level_name(o->log_level)); 2335d4af9e69SDag-Erling Smørgrav dump_cfg_string(sLogFacility, log_facility_name(o->log_facility)); 2336d4af9e69SDag-Erling Smørgrav 2337d4af9e69SDag-Erling Smørgrav /* string array arguments */ 2338e146993eSDag-Erling Smørgrav dump_cfg_strarray_oneline(sAuthorizedKeysFile, o->num_authkeys_files, 2339e146993eSDag-Erling Smørgrav o->authorized_keys_files); 2340d4af9e69SDag-Erling Smørgrav dump_cfg_strarray(sHostKeyFile, o->num_host_key_files, 2341d4af9e69SDag-Erling Smørgrav o->host_key_files); 2342557f75e5SDag-Erling Smørgrav dump_cfg_strarray(sHostCertificate, o->num_host_cert_files, 2343b15c8340SDag-Erling Smørgrav o->host_cert_files); 2344d4af9e69SDag-Erling Smørgrav dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users); 2345d4af9e69SDag-Erling Smørgrav dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users); 2346d4af9e69SDag-Erling Smørgrav dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups); 2347d4af9e69SDag-Erling Smørgrav dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups); 2348d4af9e69SDag-Erling Smørgrav dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env); 23496888a9beSDag-Erling Smørgrav dump_cfg_strarray_oneline(sAuthenticationMethods, 23506888a9beSDag-Erling Smørgrav o->num_auth_methods, o->auth_methods); 2351d4af9e69SDag-Erling Smørgrav 2352d4af9e69SDag-Erling Smørgrav /* other arguments */ 2353d4af9e69SDag-Erling Smørgrav for (i = 0; i < o->num_subsystems; i++) 2354d4af9e69SDag-Erling Smørgrav printf("subsystem %s %s\n", o->subsystem_name[i], 2355d4af9e69SDag-Erling Smørgrav o->subsystem_args[i]); 2356d4af9e69SDag-Erling Smørgrav 2357d4af9e69SDag-Erling Smørgrav printf("maxstartups %d:%d:%d\n", o->max_startups_begin, 2358d4af9e69SDag-Erling Smørgrav o->max_startups_rate, o->max_startups); 2359d4af9e69SDag-Erling Smørgrav 2360d4af9e69SDag-Erling Smørgrav for (i = 0; tunmode_desc[i].val != -1; i++) 2361d4af9e69SDag-Erling Smørgrav if (tunmode_desc[i].val == o->permit_tun) { 2362d4af9e69SDag-Erling Smørgrav s = tunmode_desc[i].text; 2363d4af9e69SDag-Erling Smørgrav break; 2364d4af9e69SDag-Erling Smørgrav } 2365d4af9e69SDag-Erling Smørgrav dump_cfg_string(sPermitTunnel, s); 2366d4af9e69SDag-Erling Smørgrav 2367e146993eSDag-Erling Smørgrav printf("ipqos %s ", iptos2str(o->ip_qos_interactive)); 2368e146993eSDag-Erling Smørgrav printf("%s\n", iptos2str(o->ip_qos_bulk)); 23694a421b63SDag-Erling Smørgrav 2370*acc1a9efSDag-Erling Smørgrav printf("rekeylimit %llu %d\n", (unsigned long long)o->rekey_limit, 2371e4a9863fSDag-Erling Smørgrav o->rekey_interval); 2372e4a9863fSDag-Erling Smørgrav 2373d4af9e69SDag-Erling Smørgrav channel_print_adm_permitted_opens(); 2374d4af9e69SDag-Erling Smørgrav } 2375