1462c32cbSDag-Erling Smørgrav 2*e4a9863fSDag-Erling Smørgrav /* $OpenBSD: servconf.c,v 1.240 2013/07/19 07:37:48 markus Exp $ */ 389986192SBrooks Davis /* $FreeBSD$ */ 4511b41d2SMark Murray /* 5511b41d2SMark Murray * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 6511b41d2SMark Murray * All rights reserved 7511b41d2SMark Murray * 8c2d3a559SKris Kennaway * As far as I am concerned, the code I have written for this software 9c2d3a559SKris Kennaway * can be used freely for any purpose. Any derived versions of this 10c2d3a559SKris Kennaway * software must be clearly marked as such, and if the derived work is 11c2d3a559SKris Kennaway * incompatible with the protocol description in the RFC file, it must be 12c2d3a559SKris Kennaway * called by a name other than "ssh" or "Secure Shell". 13511b41d2SMark Murray */ 14511b41d2SMark Murray 15511b41d2SMark Murray #include "includes.h" 16333ee039SDag-Erling Smørgrav __RCSID("$FreeBSD$"); 17511b41d2SMark Murray 18333ee039SDag-Erling Smørgrav #include <sys/types.h> 19333ee039SDag-Erling Smørgrav #include <sys/socket.h> 20333ee039SDag-Erling Smørgrav 214a421b63SDag-Erling Smørgrav #include <netinet/in.h> 224a421b63SDag-Erling Smørgrav #include <netinet/in_systm.h> 234a421b63SDag-Erling Smørgrav #include <netinet/ip.h> 244a421b63SDag-Erling Smørgrav 25*e4a9863fSDag-Erling Smørgrav #include <ctype.h> 26333ee039SDag-Erling Smørgrav #include <netdb.h> 27333ee039SDag-Erling Smørgrav #include <pwd.h> 28333ee039SDag-Erling Smørgrav #include <stdio.h> 29333ee039SDag-Erling Smørgrav #include <stdlib.h> 30333ee039SDag-Erling Smørgrav #include <string.h> 31333ee039SDag-Erling Smørgrav #include <signal.h> 32333ee039SDag-Erling Smørgrav #include <unistd.h> 33333ee039SDag-Erling Smørgrav #include <stdarg.h> 34d4af9e69SDag-Erling Smørgrav #include <errno.h> 35*e4a9863fSDag-Erling Smørgrav #ifdef HAVE_UTIL_H 36*e4a9863fSDag-Erling Smørgrav #include <util.h> 37*e4a9863fSDag-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" 44511b41d2SMark Murray #include "servconf.h" 45e8aafc91SKris Kennaway #include "compat.h" 46ca3176e7SBrian Feldman #include "pathnames.h" 47ca3176e7SBrian Feldman #include "misc.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" 59b15c8340SDag-Erling Smørgrav #include "version.h" 60511b41d2SMark Murray 61cce7d346SDag-Erling Smørgrav static void add_listen_addr(ServerOptions *, char *, int); 62cce7d346SDag-Erling Smørgrav static void add_one_listen_addr(ServerOptions *, char *, int); 63ca3176e7SBrian Feldman 6480628bacSDag-Erling Smørgrav /* Use of privilege separation or not */ 6580628bacSDag-Erling Smørgrav extern int use_privsep; 66333ee039SDag-Erling Smørgrav extern Buffer cfg; 67511b41d2SMark Murray 68511b41d2SMark Murray /* Initializes the server options to their default values. */ 69511b41d2SMark Murray 70511b41d2SMark Murray void 71511b41d2SMark Murray initialize_server_options(ServerOptions *options) 72511b41d2SMark Murray { 73511b41d2SMark Murray memset(options, 0, sizeof(*options)); 74989dd127SDag-Erling Smørgrav 75989dd127SDag-Erling Smørgrav /* Portable-specific options */ 76cf2b5f3bSDag-Erling Smørgrav options->use_pam = -1; 77989dd127SDag-Erling Smørgrav 78989dd127SDag-Erling Smørgrav /* Standard Options */ 79511b41d2SMark Murray options->num_ports = 0; 80511b41d2SMark Murray options->ports_from_cmdline = 0; 81511b41d2SMark Murray options->listen_addrs = NULL; 82aa49c926SDag-Erling Smørgrav options->address_family = -1; 83ca3176e7SBrian Feldman options->num_host_key_files = 0; 84b15c8340SDag-Erling Smørgrav options->num_host_cert_files = 0; 85*e4a9863fSDag-Erling Smørgrav options->host_key_agent = NULL; 86e8aafc91SKris Kennaway options->pid_file = NULL; 87511b41d2SMark Murray options->server_key_bits = -1; 88511b41d2SMark Murray options->login_grace_time = -1; 89511b41d2SMark Murray options->key_regeneration_time = -1; 90ca3176e7SBrian Feldman options->permit_root_login = PERMIT_NOT_SET; 91511b41d2SMark Murray options->ignore_rhosts = -1; 92511b41d2SMark Murray options->ignore_user_known_hosts = -1; 93511b41d2SMark Murray options->print_motd = -1; 94ca3176e7SBrian Feldman options->print_lastlog = -1; 95511b41d2SMark Murray options->x11_forwarding = -1; 96511b41d2SMark Murray options->x11_display_offset = -1; 97af12a3e7SDag-Erling Smørgrav options->x11_use_localhost = -1; 98c2d3a559SKris Kennaway options->xauth_location = NULL; 99511b41d2SMark Murray options->strict_modes = -1; 1001ec0d754SDag-Erling Smørgrav options->tcp_keep_alive = -1; 101af12a3e7SDag-Erling Smørgrav options->log_facility = SYSLOG_FACILITY_NOT_SET; 102af12a3e7SDag-Erling Smørgrav options->log_level = SYSLOG_LEVEL_NOT_SET; 103511b41d2SMark Murray options->rhosts_rsa_authentication = -1; 104ca3176e7SBrian Feldman options->hostbased_authentication = -1; 105ca3176e7SBrian Feldman options->hostbased_uses_name_from_packet_only = -1; 106511b41d2SMark Murray options->rsa_authentication = -1; 107ca3176e7SBrian Feldman options->pubkey_authentication = -1; 108cb96ab36SAssar Westerlund options->kerberos_authentication = -1; 109af12a3e7SDag-Erling Smørgrav options->kerberos_or_local_passwd = -1; 110af12a3e7SDag-Erling Smørgrav options->kerberos_ticket_cleanup = -1; 1111ec0d754SDag-Erling Smørgrav options->kerberos_get_afs_token = -1; 112cf2b5f3bSDag-Erling Smørgrav options->gss_authentication=-1; 113cf2b5f3bSDag-Erling Smørgrav options->gss_cleanup_creds = -1; 114511b41d2SMark Murray options->password_authentication = -1; 11509958426SBrian Feldman options->kbd_interactive_authentication = -1; 116af12a3e7SDag-Erling Smørgrav options->challenge_response_authentication = -1; 117511b41d2SMark Murray options->permit_empty_passwd = -1; 118f388f5efSDag-Erling Smørgrav options->permit_user_env = -1; 119511b41d2SMark Murray options->use_login = -1; 12080628bacSDag-Erling Smørgrav options->compression = -1; 121*e4a9863fSDag-Erling Smørgrav options->rekey_limit = -1; 122*e4a9863fSDag-Erling Smørgrav options->rekey_interval = -1; 12309958426SBrian Feldman options->allow_tcp_forwarding = -1; 124d4af9e69SDag-Erling Smørgrav options->allow_agent_forwarding = -1; 125511b41d2SMark Murray options->num_allow_users = 0; 126511b41d2SMark Murray options->num_deny_users = 0; 127511b41d2SMark Murray options->num_allow_groups = 0; 128511b41d2SMark Murray options->num_deny_groups = 0; 129e8aafc91SKris Kennaway options->ciphers = NULL; 130ca3176e7SBrian Feldman options->macs = NULL; 1314a421b63SDag-Erling Smørgrav options->kex_algorithms = NULL; 132e8aafc91SKris Kennaway options->protocol = SSH_PROTO_UNKNOWN; 133e8aafc91SKris Kennaway options->gateway_ports = -1; 134c2d3a559SKris Kennaway options->num_subsystems = 0; 135c2d3a559SKris Kennaway options->max_startups_begin = -1; 136c2d3a559SKris Kennaway options->max_startups_rate = -1; 137c2d3a559SKris Kennaway options->max_startups = -1; 13821e764dfSDag-Erling Smørgrav options->max_authtries = -1; 139d4af9e69SDag-Erling Smørgrav options->max_sessions = -1; 140ca3176e7SBrian Feldman options->banner = NULL; 141cf2b5f3bSDag-Erling Smørgrav options->use_dns = -1; 142ca3176e7SBrian Feldman options->client_alive_interval = -1; 143ca3176e7SBrian Feldman options->client_alive_count_max = -1; 144e146993eSDag-Erling Smørgrav options->num_authkeys_files = 0; 14521e764dfSDag-Erling Smørgrav options->num_accept_env = 0; 146b74df5b2SDag-Erling Smørgrav options->permit_tun = -1; 147333ee039SDag-Erling Smørgrav options->num_permitted_opens = -1; 148333ee039SDag-Erling Smørgrav options->adm_forced_command = NULL; 149d4af9e69SDag-Erling Smørgrav options->chroot_directory = NULL; 1506888a9beSDag-Erling Smørgrav options->authorized_keys_command = NULL; 1516888a9beSDag-Erling Smørgrav options->authorized_keys_command_user = NULL; 152cce7d346SDag-Erling Smørgrav options->zero_knowledge_password_authentication = -1; 153b15c8340SDag-Erling Smørgrav options->revoked_keys_file = NULL; 154b15c8340SDag-Erling Smørgrav options->trusted_user_ca_keys = NULL; 155e2f6069cSDag-Erling Smørgrav options->authorized_principals_file = NULL; 1564a421b63SDag-Erling Smørgrav options->ip_qos_interactive = -1; 1574a421b63SDag-Erling Smørgrav options->ip_qos_bulk = -1; 158462c32cbSDag-Erling Smørgrav options->version_addendum = NULL; 15989986192SBrooks Davis options->hpn_disabled = -1; 16089986192SBrooks Davis options->hpn_buffer_size = -1; 16189986192SBrooks Davis options->tcp_rcv_buf_poll = -1; 16289986192SBrooks Davis #ifdef NONE_CIPHER_ENABLED 16389986192SBrooks Davis options->none_enabled = -1; 16489986192SBrooks Davis #endif 165511b41d2SMark Murray } 166511b41d2SMark Murray 167511b41d2SMark Murray void 168511b41d2SMark Murray fill_default_server_options(ServerOptions *options) 169511b41d2SMark Murray { 170989dd127SDag-Erling Smørgrav /* Portable-specific options */ 171cf2b5f3bSDag-Erling Smørgrav if (options->use_pam == -1) 172f0477b26SDag-Erling Smørgrav options->use_pam = 1; 173989dd127SDag-Erling Smørgrav 174989dd127SDag-Erling Smørgrav /* Standard Options */ 175ca3176e7SBrian Feldman if (options->protocol == SSH_PROTO_UNKNOWN) 176028c324aSDag-Erling Smørgrav options->protocol = SSH_PROTO_2; 177ca3176e7SBrian Feldman if (options->num_host_key_files == 0) { 178ca3176e7SBrian Feldman /* fill default hostkeys for protocols */ 179ca3176e7SBrian Feldman if (options->protocol & SSH_PROTO_1) 180af12a3e7SDag-Erling Smørgrav options->host_key_files[options->num_host_key_files++] = 181af12a3e7SDag-Erling Smørgrav _PATH_HOST_KEY_FILE; 182af12a3e7SDag-Erling Smørgrav if (options->protocol & SSH_PROTO_2) { 183af12a3e7SDag-Erling Smørgrav options->host_key_files[options->num_host_key_files++] = 184d4af9e69SDag-Erling Smørgrav _PATH_HOST_RSA_KEY_FILE; 185d4af9e69SDag-Erling Smørgrav options->host_key_files[options->num_host_key_files++] = 186af12a3e7SDag-Erling Smørgrav _PATH_HOST_DSA_KEY_FILE; 1874a421b63SDag-Erling Smørgrav #ifdef OPENSSL_HAS_ECC 1884a421b63SDag-Erling Smørgrav options->host_key_files[options->num_host_key_files++] = 1894a421b63SDag-Erling Smørgrav _PATH_HOST_ECDSA_KEY_FILE; 1904a421b63SDag-Erling Smørgrav #endif 191af12a3e7SDag-Erling Smørgrav } 192ca3176e7SBrian Feldman } 193b15c8340SDag-Erling Smørgrav /* No certificates by default */ 194511b41d2SMark Murray if (options->num_ports == 0) 195511b41d2SMark Murray options->ports[options->num_ports++] = SSH_DEFAULT_PORT; 196511b41d2SMark Murray if (options->listen_addrs == NULL) 197ca3176e7SBrian Feldman add_listen_addr(options, NULL, 0); 198e8aafc91SKris Kennaway if (options->pid_file == NULL) 199ca3176e7SBrian Feldman options->pid_file = _PATH_SSH_DAEMON_PID_FILE; 200511b41d2SMark Murray if (options->server_key_bits == -1) 201d4af9e69SDag-Erling Smørgrav options->server_key_bits = 1024; 202511b41d2SMark Murray if (options->login_grace_time == -1) 203975616f0SDag-Erling Smørgrav options->login_grace_time = 120; 204511b41d2SMark Murray if (options->key_regeneration_time == -1) 205511b41d2SMark Murray options->key_regeneration_time = 3600; 206ca3176e7SBrian Feldman if (options->permit_root_login == PERMIT_NOT_SET) 207975616f0SDag-Erling Smørgrav options->permit_root_login = PERMIT_NO; 208511b41d2SMark Murray if (options->ignore_rhosts == -1) 209fe5fd017SMark Murray options->ignore_rhosts = 1; 210511b41d2SMark Murray if (options->ignore_user_known_hosts == -1) 211511b41d2SMark Murray options->ignore_user_known_hosts = 0; 212511b41d2SMark Murray if (options->print_motd == -1) 213511b41d2SMark Murray options->print_motd = 1; 214ca3176e7SBrian Feldman if (options->print_lastlog == -1) 215ca3176e7SBrian Feldman options->print_lastlog = 1; 216511b41d2SMark Murray if (options->x11_forwarding == -1) 217975616f0SDag-Erling Smørgrav options->x11_forwarding = 1; 218511b41d2SMark Murray if (options->x11_display_offset == -1) 219fe5fd017SMark Murray options->x11_display_offset = 10; 220af12a3e7SDag-Erling Smørgrav if (options->x11_use_localhost == -1) 221af12a3e7SDag-Erling Smørgrav options->x11_use_localhost = 1; 222c2d3a559SKris Kennaway if (options->xauth_location == NULL) 223af12a3e7SDag-Erling Smørgrav options->xauth_location = _PATH_XAUTH; 224511b41d2SMark Murray if (options->strict_modes == -1) 225511b41d2SMark Murray options->strict_modes = 1; 2261ec0d754SDag-Erling Smørgrav if (options->tcp_keep_alive == -1) 2271ec0d754SDag-Erling Smørgrav options->tcp_keep_alive = 1; 228af12a3e7SDag-Erling Smørgrav if (options->log_facility == SYSLOG_FACILITY_NOT_SET) 229511b41d2SMark Murray options->log_facility = SYSLOG_FACILITY_AUTH; 230af12a3e7SDag-Erling Smørgrav if (options->log_level == SYSLOG_LEVEL_NOT_SET) 231511b41d2SMark Murray options->log_level = SYSLOG_LEVEL_INFO; 232511b41d2SMark Murray if (options->rhosts_rsa_authentication == -1) 233fe5fd017SMark Murray options->rhosts_rsa_authentication = 0; 234ca3176e7SBrian Feldman if (options->hostbased_authentication == -1) 235ca3176e7SBrian Feldman options->hostbased_authentication = 0; 236ca3176e7SBrian Feldman if (options->hostbased_uses_name_from_packet_only == -1) 237ca3176e7SBrian Feldman options->hostbased_uses_name_from_packet_only = 0; 238511b41d2SMark Murray if (options->rsa_authentication == -1) 239511b41d2SMark Murray options->rsa_authentication = 1; 240ca3176e7SBrian Feldman if (options->pubkey_authentication == -1) 241ca3176e7SBrian Feldman options->pubkey_authentication = 1; 242989dd127SDag-Erling Smørgrav if (options->kerberos_authentication == -1) 243cf2b5f3bSDag-Erling Smørgrav options->kerberos_authentication = 0; 244af12a3e7SDag-Erling Smørgrav if (options->kerberos_or_local_passwd == -1) 245af12a3e7SDag-Erling Smørgrav options->kerberos_or_local_passwd = 1; 246af12a3e7SDag-Erling Smørgrav if (options->kerberos_ticket_cleanup == -1) 247af12a3e7SDag-Erling Smørgrav options->kerberos_ticket_cleanup = 1; 2481ec0d754SDag-Erling Smørgrav if (options->kerberos_get_afs_token == -1) 2491ec0d754SDag-Erling Smørgrav options->kerberos_get_afs_token = 0; 250cf2b5f3bSDag-Erling Smørgrav if (options->gss_authentication == -1) 251cf2b5f3bSDag-Erling Smørgrav options->gss_authentication = 0; 252cf2b5f3bSDag-Erling Smørgrav if (options->gss_cleanup_creds == -1) 253cf2b5f3bSDag-Erling Smørgrav options->gss_cleanup_creds = 1; 254511b41d2SMark Murray if (options->password_authentication == -1) 255b909c84bSDag-Erling Smørgrav options->password_authentication = 0; 25609958426SBrian Feldman if (options->kbd_interactive_authentication == -1) 25709958426SBrian Feldman options->kbd_interactive_authentication = 0; 258af12a3e7SDag-Erling Smørgrav if (options->challenge_response_authentication == -1) 25980241871SDag-Erling Smørgrav options->challenge_response_authentication = 1; 260511b41d2SMark Murray if (options->permit_empty_passwd == -1) 261fe5fd017SMark Murray options->permit_empty_passwd = 0; 262f388f5efSDag-Erling Smørgrav if (options->permit_user_env == -1) 263f388f5efSDag-Erling Smørgrav options->permit_user_env = 0; 264511b41d2SMark Murray if (options->use_login == -1) 265511b41d2SMark Murray options->use_login = 0; 26680628bacSDag-Erling Smørgrav if (options->compression == -1) 267d4ecd108SDag-Erling Smørgrav options->compression = COMP_DELAYED; 268*e4a9863fSDag-Erling Smørgrav if (options->rekey_limit == -1) 269*e4a9863fSDag-Erling Smørgrav options->rekey_limit = 0; 270*e4a9863fSDag-Erling Smørgrav if (options->rekey_interval == -1) 271*e4a9863fSDag-Erling Smørgrav options->rekey_interval = 0; 27209958426SBrian Feldman if (options->allow_tcp_forwarding == -1) 2736888a9beSDag-Erling Smørgrav options->allow_tcp_forwarding = FORWARD_ALLOW; 274d4af9e69SDag-Erling Smørgrav if (options->allow_agent_forwarding == -1) 275d4af9e69SDag-Erling Smørgrav options->allow_agent_forwarding = 1; 276e8aafc91SKris Kennaway if (options->gateway_ports == -1) 277e8aafc91SKris Kennaway options->gateway_ports = 0; 278c2d3a559SKris Kennaway if (options->max_startups == -1) 2796888a9beSDag-Erling Smørgrav options->max_startups = 100; 280c2d3a559SKris Kennaway if (options->max_startups_rate == -1) 2816888a9beSDag-Erling Smørgrav options->max_startups_rate = 30; /* 30% */ 282c2d3a559SKris Kennaway if (options->max_startups_begin == -1) 2836888a9beSDag-Erling Smørgrav options->max_startups_begin = 10; 28421e764dfSDag-Erling Smørgrav if (options->max_authtries == -1) 28521e764dfSDag-Erling Smørgrav options->max_authtries = DEFAULT_AUTH_FAIL_MAX; 286d4af9e69SDag-Erling Smørgrav if (options->max_sessions == -1) 287d4af9e69SDag-Erling Smørgrav options->max_sessions = DEFAULT_SESSIONS_MAX; 288cf2b5f3bSDag-Erling Smørgrav if (options->use_dns == -1) 289cf2b5f3bSDag-Erling Smørgrav options->use_dns = 1; 290ca3176e7SBrian Feldman if (options->client_alive_interval == -1) 291ca3176e7SBrian Feldman options->client_alive_interval = 0; 292ca3176e7SBrian Feldman if (options->client_alive_count_max == -1) 293ca3176e7SBrian Feldman options->client_alive_count_max = 3; 294e146993eSDag-Erling Smørgrav if (options->num_authkeys_files == 0) { 295e146993eSDag-Erling Smørgrav options->authorized_keys_files[options->num_authkeys_files++] = 296e146993eSDag-Erling Smørgrav xstrdup(_PATH_SSH_USER_PERMITTED_KEYS); 297e146993eSDag-Erling Smørgrav options->authorized_keys_files[options->num_authkeys_files++] = 298e146993eSDag-Erling Smørgrav xstrdup(_PATH_SSH_USER_PERMITTED_KEYS2); 299af12a3e7SDag-Erling Smørgrav } 300b74df5b2SDag-Erling Smørgrav if (options->permit_tun == -1) 301b74df5b2SDag-Erling Smørgrav options->permit_tun = SSH_TUNMODE_NO; 302cce7d346SDag-Erling Smørgrav if (options->zero_knowledge_password_authentication == -1) 303cce7d346SDag-Erling Smørgrav options->zero_knowledge_password_authentication = 0; 3044a421b63SDag-Erling Smørgrav if (options->ip_qos_interactive == -1) 3054a421b63SDag-Erling Smørgrav options->ip_qos_interactive = IPTOS_LOWDELAY; 3064a421b63SDag-Erling Smørgrav if (options->ip_qos_bulk == -1) 3074a421b63SDag-Erling Smørgrav options->ip_qos_bulk = IPTOS_THROUGHPUT; 308462c32cbSDag-Erling Smørgrav if (options->version_addendum == NULL) 309462c32cbSDag-Erling Smørgrav options->version_addendum = xstrdup(SSH_VERSION_FREEBSD); 310462c32cbSDag-Erling Smørgrav /* Turn privilege separation on by default */ 311462c32cbSDag-Erling Smørgrav if (use_privsep == -1) 312c89ea4d7SDag-Erling Smørgrav use_privsep = PRIVSEP_NOSANDBOX; 313462c32cbSDag-Erling Smørgrav 314462c32cbSDag-Erling Smørgrav #ifndef HAVE_MMAP 315462c32cbSDag-Erling Smørgrav if (use_privsep && options->compression == 1) { 316462c32cbSDag-Erling Smørgrav error("This platform does not support both privilege " 317462c32cbSDag-Erling Smørgrav "separation and compression"); 318462c32cbSDag-Erling Smørgrav error("Compression disabled"); 319462c32cbSDag-Erling Smørgrav options->compression = 0; 320462c32cbSDag-Erling Smørgrav } 321462c32cbSDag-Erling Smørgrav #endif 322462c32cbSDag-Erling Smørgrav 32389986192SBrooks Davis if (options->hpn_disabled == -1) 32489986192SBrooks Davis options->hpn_disabled = 0; 32589986192SBrooks Davis if (options->hpn_buffer_size == -1) { 32689986192SBrooks Davis /* 32789986192SBrooks Davis * HPN buffer size option not explicitly set. Try to figure 32889986192SBrooks Davis * out what value to use or resort to default. 32989986192SBrooks Davis */ 33089986192SBrooks Davis options->hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT; 33189986192SBrooks Davis if (!options->hpn_disabled) { 33289986192SBrooks Davis sock_get_rcvbuf(&options->hpn_buffer_size, 0); 33389986192SBrooks Davis debug ("HPN Buffer Size: %d", options->hpn_buffer_size); 33489986192SBrooks Davis } 33589986192SBrooks Davis } else { 33689986192SBrooks Davis /* 33789986192SBrooks Davis * In the case that the user sets both values in a 33889986192SBrooks Davis * contradictory manner hpn_disabled overrrides hpn_buffer_size. 33989986192SBrooks Davis */ 34089986192SBrooks Davis if (options->hpn_disabled <= 0) { 34189986192SBrooks Davis u_int maxlen; 34289986192SBrooks Davis 34389986192SBrooks Davis maxlen = buffer_get_max_len(); 34489986192SBrooks Davis if (options->hpn_buffer_size == 0) 34589986192SBrooks Davis options->hpn_buffer_size = 1; 34689986192SBrooks Davis /* Limit the maximum buffer to BUFFER_MAX_LEN. */ 34789986192SBrooks Davis if (options->hpn_buffer_size > maxlen / 1024) 34889986192SBrooks Davis options->hpn_buffer_size = maxlen; 34989986192SBrooks Davis else 35089986192SBrooks Davis options->hpn_buffer_size *= 1024; 351462c32cbSDag-Erling Smørgrav } else { 35289986192SBrooks Davis options->hpn_buffer_size = CHAN_TCP_WINDOW_DEFAULT; 35389986192SBrooks Davis } 354989dd127SDag-Erling Smørgrav } 355511b41d2SMark Murray } 356511b41d2SMark Murray 357511b41d2SMark Murray /* Keyword tokens. */ 358511b41d2SMark Murray typedef enum { 359511b41d2SMark Murray sBadOption, /* == unknown option */ 360989dd127SDag-Erling Smørgrav /* Portable-specific options */ 361cf2b5f3bSDag-Erling Smørgrav sUsePAM, 362989dd127SDag-Erling Smørgrav /* Standard Options */ 363511b41d2SMark Murray sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime, 364511b41d2SMark Murray sPermitRootLogin, sLogFacility, sLogLevel, 365cf2b5f3bSDag-Erling Smørgrav sRhostsRSAAuthentication, sRSAAuthentication, 366af12a3e7SDag-Erling Smørgrav sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, 3671ec0d754SDag-Erling Smørgrav sKerberosGetAFSToken, 368cf2b5f3bSDag-Erling Smørgrav sKerberosTgtPassing, sChallengeResponseAuthentication, 369aa49c926SDag-Erling Smørgrav sPasswordAuthentication, sKbdInteractiveAuthentication, 370aa49c926SDag-Erling Smørgrav sListenAddress, sAddressFamily, 371ca3176e7SBrian Feldman sPrintMotd, sPrintLastLog, sIgnoreRhosts, 372af12a3e7SDag-Erling Smørgrav sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, 3731ec0d754SDag-Erling Smørgrav sStrictModes, sEmptyPasswd, sTCPKeepAlive, 374f388f5efSDag-Erling Smørgrav sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression, 375*e4a9863fSDag-Erling Smørgrav sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, 376ca3176e7SBrian Feldman sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, 37721e764dfSDag-Erling Smørgrav sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, 378d4af9e69SDag-Erling Smørgrav sMaxStartups, sMaxAuthTries, sMaxSessions, 379cf2b5f3bSDag-Erling Smørgrav sBanner, sUseDNS, sHostbasedAuthentication, 380ca3176e7SBrian Feldman sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, 381e146993eSDag-Erling Smørgrav sClientAliveCountMax, sAuthorizedKeysFile, 382b74df5b2SDag-Erling Smørgrav sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, 383d4af9e69SDag-Erling Smørgrav sMatch, sPermitOpen, sForceCommand, sChrootDirectory, 384d4af9e69SDag-Erling Smørgrav sUsePrivilegeSeparation, sAllowAgentForwarding, 385b15c8340SDag-Erling Smørgrav sZeroKnowledgePasswordAuthentication, sHostCertificate, 386e2f6069cSDag-Erling Smørgrav sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, 387462c32cbSDag-Erling Smørgrav sKexAlgorithms, sIPQoS, sVersionAddendum, 3886888a9beSDag-Erling Smørgrav sAuthorizedKeysCommand, sAuthorizedKeysCommandUser, 389*e4a9863fSDag-Erling Smørgrav sAuthenticationMethods, sHostKeyAgent, 39089986192SBrooks Davis sHPNDisabled, sHPNBufferSize, sTcpRcvBufPoll, 39189986192SBrooks Davis #ifdef NONE_CIPHER_ENABLED 39289986192SBrooks Davis sNoneEnabled, 39389986192SBrooks Davis #endif 394cf2b5f3bSDag-Erling Smørgrav sDeprecated, sUnsupported 395511b41d2SMark Murray } ServerOpCodes; 396511b41d2SMark Murray 397333ee039SDag-Erling Smørgrav #define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */ 398333ee039SDag-Erling Smørgrav #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */ 399333ee039SDag-Erling Smørgrav #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH) 400333ee039SDag-Erling Smørgrav 401511b41d2SMark Murray /* Textual representation of the tokens. */ 402511b41d2SMark Murray static struct { 403511b41d2SMark Murray const char *name; 404511b41d2SMark Murray ServerOpCodes opcode; 405333ee039SDag-Erling Smørgrav u_int flags; 406511b41d2SMark Murray } keywords[] = { 407989dd127SDag-Erling Smørgrav /* Portable-specific options */ 408cf2b5f3bSDag-Erling Smørgrav #ifdef USE_PAM 409333ee039SDag-Erling Smørgrav { "usepam", sUsePAM, SSHCFG_GLOBAL }, 410cf2b5f3bSDag-Erling Smørgrav #else 411333ee039SDag-Erling Smørgrav { "usepam", sUnsupported, SSHCFG_GLOBAL }, 412975616f0SDag-Erling Smørgrav #endif 413333ee039SDag-Erling Smørgrav { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, 414989dd127SDag-Erling Smørgrav /* Standard Options */ 415333ee039SDag-Erling Smørgrav { "port", sPort, SSHCFG_GLOBAL }, 416333ee039SDag-Erling Smørgrav { "hostkey", sHostKeyFile, SSHCFG_GLOBAL }, 417333ee039SDag-Erling Smørgrav { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */ 418*e4a9863fSDag-Erling Smørgrav { "hostkeyagent", sHostKeyAgent, SSHCFG_GLOBAL }, 419333ee039SDag-Erling Smørgrav { "pidfile", sPidFile, SSHCFG_GLOBAL }, 420333ee039SDag-Erling Smørgrav { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL }, 421333ee039SDag-Erling Smørgrav { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL }, 422333ee039SDag-Erling Smørgrav { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL }, 423d4af9e69SDag-Erling Smørgrav { "permitrootlogin", sPermitRootLogin, SSHCFG_ALL }, 424333ee039SDag-Erling Smørgrav { "syslogfacility", sLogFacility, SSHCFG_GLOBAL }, 425333ee039SDag-Erling Smørgrav { "loglevel", sLogLevel, SSHCFG_GLOBAL }, 426333ee039SDag-Erling Smørgrav { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL }, 427d4af9e69SDag-Erling Smørgrav { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_ALL }, 428d4af9e69SDag-Erling Smørgrav { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL }, 429e2f6069cSDag-Erling Smørgrav { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_ALL }, 430d4af9e69SDag-Erling Smørgrav { "rsaauthentication", sRSAAuthentication, SSHCFG_ALL }, 431d4af9e69SDag-Erling Smørgrav { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL }, 432333ee039SDag-Erling Smørgrav { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */ 433cf2b5f3bSDag-Erling Smørgrav #ifdef KRB5 434d4af9e69SDag-Erling Smørgrav { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL }, 435333ee039SDag-Erling Smørgrav { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL }, 436333ee039SDag-Erling Smørgrav { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL }, 4371ec0d754SDag-Erling Smørgrav #ifdef USE_AFS 438333ee039SDag-Erling Smørgrav { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL }, 4391ec0d754SDag-Erling Smørgrav #else 440333ee039SDag-Erling Smørgrav { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, 4411ec0d754SDag-Erling Smørgrav #endif 442cf2b5f3bSDag-Erling Smørgrav #else 443d4af9e69SDag-Erling Smørgrav { "kerberosauthentication", sUnsupported, SSHCFG_ALL }, 444333ee039SDag-Erling Smørgrav { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL }, 445333ee039SDag-Erling Smørgrav { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL }, 446333ee039SDag-Erling Smørgrav { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, 447cb96ab36SAssar Westerlund #endif 448333ee039SDag-Erling Smørgrav { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, 449333ee039SDag-Erling Smørgrav { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, 450cf2b5f3bSDag-Erling Smørgrav #ifdef GSSAPI 451d4af9e69SDag-Erling Smørgrav { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, 452333ee039SDag-Erling Smørgrav { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, 453cf2b5f3bSDag-Erling Smørgrav #else 454d4af9e69SDag-Erling Smørgrav { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, 455333ee039SDag-Erling Smørgrav { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, 456511b41d2SMark Murray #endif 457d4af9e69SDag-Erling Smørgrav { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, 458d4af9e69SDag-Erling Smørgrav { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, 459333ee039SDag-Erling Smørgrav { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, 460333ee039SDag-Erling Smørgrav { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */ 461cce7d346SDag-Erling Smørgrav #ifdef JPAKE 462cce7d346SDag-Erling Smørgrav { "zeroknowledgepasswordauthentication", sZeroKnowledgePasswordAuthentication, SSHCFG_ALL }, 463cce7d346SDag-Erling Smørgrav #else 464cce7d346SDag-Erling Smørgrav { "zeroknowledgepasswordauthentication", sUnsupported, SSHCFG_ALL }, 465cce7d346SDag-Erling Smørgrav #endif 466333ee039SDag-Erling Smørgrav { "checkmail", sDeprecated, SSHCFG_GLOBAL }, 467333ee039SDag-Erling Smørgrav { "listenaddress", sListenAddress, SSHCFG_GLOBAL }, 468333ee039SDag-Erling Smørgrav { "addressfamily", sAddressFamily, SSHCFG_GLOBAL }, 469333ee039SDag-Erling Smørgrav { "printmotd", sPrintMotd, SSHCFG_GLOBAL }, 470333ee039SDag-Erling Smørgrav { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL }, 471333ee039SDag-Erling Smørgrav { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL }, 472333ee039SDag-Erling Smørgrav { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL }, 473333ee039SDag-Erling Smørgrav { "x11forwarding", sX11Forwarding, SSHCFG_ALL }, 474333ee039SDag-Erling Smørgrav { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL }, 475333ee039SDag-Erling Smørgrav { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL }, 476333ee039SDag-Erling Smørgrav { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL }, 477333ee039SDag-Erling Smørgrav { "strictmodes", sStrictModes, SSHCFG_GLOBAL }, 478cce7d346SDag-Erling Smørgrav { "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL }, 479333ee039SDag-Erling Smørgrav { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL }, 480333ee039SDag-Erling Smørgrav { "uselogin", sUseLogin, SSHCFG_GLOBAL }, 481333ee039SDag-Erling Smørgrav { "compression", sCompression, SSHCFG_GLOBAL }, 482*e4a9863fSDag-Erling Smørgrav { "rekeylimit", sRekeyLimit, SSHCFG_ALL }, 483333ee039SDag-Erling Smørgrav { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, 484333ee039SDag-Erling Smørgrav { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */ 485333ee039SDag-Erling Smørgrav { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL }, 486d4af9e69SDag-Erling Smørgrav { "allowagentforwarding", sAllowAgentForwarding, SSHCFG_ALL }, 487462c32cbSDag-Erling Smørgrav { "allowusers", sAllowUsers, SSHCFG_ALL }, 488462c32cbSDag-Erling Smørgrav { "denyusers", sDenyUsers, SSHCFG_ALL }, 489462c32cbSDag-Erling Smørgrav { "allowgroups", sAllowGroups, SSHCFG_ALL }, 490462c32cbSDag-Erling Smørgrav { "denygroups", sDenyGroups, SSHCFG_ALL }, 491333ee039SDag-Erling Smørgrav { "ciphers", sCiphers, SSHCFG_GLOBAL }, 492333ee039SDag-Erling Smørgrav { "macs", sMacs, SSHCFG_GLOBAL }, 493333ee039SDag-Erling Smørgrav { "protocol", sProtocol, SSHCFG_GLOBAL }, 494333ee039SDag-Erling Smørgrav { "gatewayports", sGatewayPorts, SSHCFG_ALL }, 495333ee039SDag-Erling Smørgrav { "subsystem", sSubsystem, SSHCFG_GLOBAL }, 496333ee039SDag-Erling Smørgrav { "maxstartups", sMaxStartups, SSHCFG_GLOBAL }, 497d4af9e69SDag-Erling Smørgrav { "maxauthtries", sMaxAuthTries, SSHCFG_ALL }, 498d4af9e69SDag-Erling Smørgrav { "maxsessions", sMaxSessions, SSHCFG_ALL }, 499d4af9e69SDag-Erling Smørgrav { "banner", sBanner, SSHCFG_ALL }, 500333ee039SDag-Erling Smørgrav { "usedns", sUseDNS, SSHCFG_GLOBAL }, 501333ee039SDag-Erling Smørgrav { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL }, 502333ee039SDag-Erling Smørgrav { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL }, 503333ee039SDag-Erling Smørgrav { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL }, 504333ee039SDag-Erling Smørgrav { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL }, 505e2f6069cSDag-Erling Smørgrav { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_ALL }, 506e146993eSDag-Erling Smørgrav { "authorizedkeysfile2", sDeprecated, SSHCFG_ALL }, 507333ee039SDag-Erling Smørgrav { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL}, 508462c32cbSDag-Erling Smørgrav { "acceptenv", sAcceptEnv, SSHCFG_ALL }, 509e2f6069cSDag-Erling Smørgrav { "permittunnel", sPermitTunnel, SSHCFG_ALL }, 510333ee039SDag-Erling Smørgrav { "match", sMatch, SSHCFG_ALL }, 511333ee039SDag-Erling Smørgrav { "permitopen", sPermitOpen, SSHCFG_ALL }, 512333ee039SDag-Erling Smørgrav { "forcecommand", sForceCommand, SSHCFG_ALL }, 513d4af9e69SDag-Erling Smørgrav { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, 514b15c8340SDag-Erling Smørgrav { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, 515b15c8340SDag-Erling Smørgrav { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, 516b15c8340SDag-Erling Smørgrav { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, 517e2f6069cSDag-Erling Smørgrav { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, 5184a421b63SDag-Erling Smørgrav { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, 5194a421b63SDag-Erling Smørgrav { "ipqos", sIPQoS, SSHCFG_ALL }, 5206888a9beSDag-Erling Smørgrav { "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL }, 5216888a9beSDag-Erling Smørgrav { "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL }, 522462c32cbSDag-Erling Smørgrav { "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL }, 5236888a9beSDag-Erling Smørgrav { "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL }, 52489986192SBrooks Davis { "hpndisabled", sHPNDisabled, SSHCFG_ALL }, 52589986192SBrooks Davis { "hpnbuffersize", sHPNBufferSize, SSHCFG_ALL }, 52689986192SBrooks Davis { "tcprcvbufpoll", sTcpRcvBufPoll, SSHCFG_ALL }, 52789986192SBrooks Davis #ifdef NONE_CIPHER_ENABLED 52889986192SBrooks Davis { "noneenabled", sNoneEnabled, SSHCFG_ALL }, 52989986192SBrooks Davis #endif 530333ee039SDag-Erling Smørgrav { NULL, sBadOption, 0 } 531511b41d2SMark Murray }; 532511b41d2SMark Murray 533d4af9e69SDag-Erling Smørgrav static struct { 534d4af9e69SDag-Erling Smørgrav int val; 535d4af9e69SDag-Erling Smørgrav char *text; 536d4af9e69SDag-Erling Smørgrav } tunmode_desc[] = { 537d4af9e69SDag-Erling Smørgrav { SSH_TUNMODE_NO, "no" }, 538d4af9e69SDag-Erling Smørgrav { SSH_TUNMODE_POINTOPOINT, "point-to-point" }, 539d4af9e69SDag-Erling Smørgrav { SSH_TUNMODE_ETHERNET, "ethernet" }, 540d4af9e69SDag-Erling Smørgrav { SSH_TUNMODE_YES, "yes" }, 541d4af9e69SDag-Erling Smørgrav { -1, NULL } 542d4af9e69SDag-Erling Smørgrav }; 543d4af9e69SDag-Erling Smørgrav 544511b41d2SMark Murray /* 545ca3176e7SBrian Feldman * Returns the number of the token pointed to by cp or sBadOption. 546511b41d2SMark Murray */ 547511b41d2SMark Murray 548511b41d2SMark Murray static ServerOpCodes 549511b41d2SMark Murray parse_token(const char *cp, const char *filename, 550333ee039SDag-Erling Smørgrav int linenum, u_int *flags) 551511b41d2SMark Murray { 552ca3176e7SBrian Feldman u_int i; 553511b41d2SMark Murray 554511b41d2SMark Murray for (i = 0; keywords[i].name; i++) 555333ee039SDag-Erling Smørgrav if (strcasecmp(cp, keywords[i].name) == 0) { 556333ee039SDag-Erling Smørgrav *flags = keywords[i].flags; 557511b41d2SMark Murray return keywords[i].opcode; 558333ee039SDag-Erling Smørgrav } 559511b41d2SMark Murray 560ca3176e7SBrian Feldman error("%s: line %d: Bad configuration option: %s", 561511b41d2SMark Murray filename, linenum, cp); 562511b41d2SMark Murray return sBadOption; 563511b41d2SMark Murray } 564511b41d2SMark Murray 565b15c8340SDag-Erling Smørgrav char * 566b15c8340SDag-Erling Smørgrav derelativise_path(const char *path) 567b15c8340SDag-Erling Smørgrav { 5688ad9b54aSDag-Erling Smørgrav char *expanded, *ret, cwd[MAXPATHLEN]; 569b15c8340SDag-Erling Smørgrav 570b15c8340SDag-Erling Smørgrav expanded = tilde_expand_filename(path, getuid()); 571b15c8340SDag-Erling Smørgrav if (*expanded == '/') 572b15c8340SDag-Erling Smørgrav return expanded; 5738ad9b54aSDag-Erling Smørgrav if (getcwd(cwd, sizeof(cwd)) == NULL) 574b15c8340SDag-Erling Smørgrav fatal("%s: getcwd: %s", __func__, strerror(errno)); 575b15c8340SDag-Erling Smørgrav xasprintf(&ret, "%s/%s", cwd, expanded); 576*e4a9863fSDag-Erling Smørgrav free(expanded); 577b15c8340SDag-Erling Smørgrav return ret; 578b15c8340SDag-Erling Smørgrav } 579b15c8340SDag-Erling Smørgrav 580af12a3e7SDag-Erling Smørgrav static void 581cce7d346SDag-Erling Smørgrav add_listen_addr(ServerOptions *options, char *addr, int port) 582511b41d2SMark Murray { 583d4ecd108SDag-Erling Smørgrav u_int i; 584511b41d2SMark Murray 585511b41d2SMark Murray if (options->num_ports == 0) 586511b41d2SMark Murray options->ports[options->num_ports++] = SSH_DEFAULT_PORT; 587aa49c926SDag-Erling Smørgrav if (options->address_family == -1) 588aa49c926SDag-Erling Smørgrav options->address_family = AF_UNSPEC; 589ca3176e7SBrian Feldman if (port == 0) 590ca3176e7SBrian Feldman for (i = 0; i < options->num_ports; i++) 591ca3176e7SBrian Feldman add_one_listen_addr(options, addr, options->ports[i]); 592ca3176e7SBrian Feldman else 593ca3176e7SBrian Feldman add_one_listen_addr(options, addr, port); 594ca3176e7SBrian Feldman } 595ca3176e7SBrian Feldman 596af12a3e7SDag-Erling Smørgrav static void 597cce7d346SDag-Erling Smørgrav add_one_listen_addr(ServerOptions *options, char *addr, int port) 598ca3176e7SBrian Feldman { 599ca3176e7SBrian Feldman struct addrinfo hints, *ai, *aitop; 600ca3176e7SBrian Feldman char strport[NI_MAXSERV]; 601ca3176e7SBrian Feldman int gaierr; 602ca3176e7SBrian Feldman 603511b41d2SMark Murray memset(&hints, 0, sizeof(hints)); 604aa49c926SDag-Erling Smørgrav hints.ai_family = options->address_family; 605511b41d2SMark Murray hints.ai_socktype = SOCK_STREAM; 606511b41d2SMark Murray hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0; 607cce7d346SDag-Erling Smørgrav snprintf(strport, sizeof strport, "%d", port); 608511b41d2SMark Murray if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0) 609ca3176e7SBrian Feldman fatal("bad addr or host: %s (%s)", 610511b41d2SMark Murray addr ? addr : "<NULL>", 611d4af9e69SDag-Erling Smørgrav ssh_gai_strerror(gaierr)); 612511b41d2SMark Murray for (ai = aitop; ai->ai_next; ai = ai->ai_next) 613511b41d2SMark Murray ; 614511b41d2SMark Murray ai->ai_next = options->listen_addrs; 615511b41d2SMark Murray options->listen_addrs = aitop; 616511b41d2SMark Murray } 617511b41d2SMark Murray 618462c32cbSDag-Erling Smørgrav struct connection_info * 619462c32cbSDag-Erling Smørgrav get_connection_info(int populate, int use_dns) 620462c32cbSDag-Erling Smørgrav { 621462c32cbSDag-Erling Smørgrav static struct connection_info ci; 622462c32cbSDag-Erling Smørgrav 623462c32cbSDag-Erling Smørgrav if (!populate) 624462c32cbSDag-Erling Smørgrav return &ci; 625462c32cbSDag-Erling Smørgrav ci.host = get_canonical_hostname(use_dns); 626462c32cbSDag-Erling Smørgrav ci.address = get_remote_ipaddr(); 627462c32cbSDag-Erling Smørgrav ci.laddress = get_local_ipaddr(packet_get_connection_in()); 628462c32cbSDag-Erling Smørgrav ci.lport = get_local_port(); 629462c32cbSDag-Erling Smørgrav return &ci; 630462c32cbSDag-Erling Smørgrav } 631462c32cbSDag-Erling Smørgrav 632333ee039SDag-Erling Smørgrav /* 633333ee039SDag-Erling Smørgrav * The strategy for the Match blocks is that the config file is parsed twice. 634333ee039SDag-Erling Smørgrav * 635333ee039SDag-Erling Smørgrav * The first time is at startup. activep is initialized to 1 and the 636333ee039SDag-Erling Smørgrav * directives in the global context are processed and acted on. Hitting a 637333ee039SDag-Erling Smørgrav * Match directive unsets activep and the directives inside the block are 638333ee039SDag-Erling Smørgrav * checked for syntax only. 639333ee039SDag-Erling Smørgrav * 640333ee039SDag-Erling Smørgrav * The second time is after a connection has been established but before 641333ee039SDag-Erling Smørgrav * authentication. activep is initialized to 2 and global config directives 642333ee039SDag-Erling Smørgrav * are ignored since they have already been processed. If the criteria in a 643333ee039SDag-Erling Smørgrav * Match block is met, activep is set and the subsequent directives 644333ee039SDag-Erling Smørgrav * processed and actioned until EOF or another Match block unsets it. Any 645333ee039SDag-Erling Smørgrav * options set are copied into the main server config. 646333ee039SDag-Erling Smørgrav * 647333ee039SDag-Erling Smørgrav * Potential additions/improvements: 648333ee039SDag-Erling Smørgrav * - Add Match support for pre-kex directives, eg Protocol, Ciphers. 649333ee039SDag-Erling Smørgrav * 650333ee039SDag-Erling Smørgrav * - Add a Tag directive (idea from David Leonard) ala pf, eg: 651333ee039SDag-Erling Smørgrav * Match Address 192.168.0.* 652333ee039SDag-Erling Smørgrav * Tag trusted 653333ee039SDag-Erling Smørgrav * Match Group wheel 654333ee039SDag-Erling Smørgrav * Tag trusted 655333ee039SDag-Erling Smørgrav * Match Tag trusted 656333ee039SDag-Erling Smørgrav * AllowTcpForwarding yes 657333ee039SDag-Erling Smørgrav * GatewayPorts clientspecified 658333ee039SDag-Erling Smørgrav * [...] 659333ee039SDag-Erling Smørgrav * 660333ee039SDag-Erling Smørgrav * - Add a PermittedChannelRequests directive 661333ee039SDag-Erling Smørgrav * Match Group shell 662333ee039SDag-Erling Smørgrav * PermittedChannelRequests session,forwarded-tcpip 663333ee039SDag-Erling Smørgrav */ 664333ee039SDag-Erling Smørgrav 665333ee039SDag-Erling Smørgrav static int 666333ee039SDag-Erling Smørgrav match_cfg_line_group(const char *grps, int line, const char *user) 667333ee039SDag-Erling Smørgrav { 668333ee039SDag-Erling Smørgrav int result = 0; 669333ee039SDag-Erling Smørgrav struct passwd *pw; 670333ee039SDag-Erling Smørgrav 671333ee039SDag-Erling Smørgrav if (user == NULL) 672333ee039SDag-Erling Smørgrav goto out; 673333ee039SDag-Erling Smørgrav 674333ee039SDag-Erling Smørgrav if ((pw = getpwnam(user)) == NULL) { 675333ee039SDag-Erling Smørgrav debug("Can't match group at line %d because user %.100s does " 676333ee039SDag-Erling Smørgrav "not exist", line, user); 677333ee039SDag-Erling Smørgrav } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) { 678333ee039SDag-Erling Smørgrav debug("Can't Match group because user %.100s not in any group " 679333ee039SDag-Erling Smørgrav "at line %d", user, line); 680d4af9e69SDag-Erling Smørgrav } else if (ga_match_pattern_list(grps) != 1) { 681d4af9e69SDag-Erling Smørgrav debug("user %.100s does not match group list %.100s at line %d", 682d4af9e69SDag-Erling Smørgrav user, grps, line); 683333ee039SDag-Erling Smørgrav } else { 684d4af9e69SDag-Erling Smørgrav debug("user %.100s matched group list %.100s at line %d", user, 685d4af9e69SDag-Erling Smørgrav grps, line); 686333ee039SDag-Erling Smørgrav result = 1; 687333ee039SDag-Erling Smørgrav } 688333ee039SDag-Erling Smørgrav out: 689333ee039SDag-Erling Smørgrav ga_free(); 690333ee039SDag-Erling Smørgrav return result; 691333ee039SDag-Erling Smørgrav } 692333ee039SDag-Erling Smørgrav 693462c32cbSDag-Erling Smørgrav /* 6946888a9beSDag-Erling Smørgrav * All of the attributes on a single Match line are ANDed together, so we need 6956888a9beSDag-Erling Smørgrav * to check every * attribute and set the result to zero if any attribute does 6966888a9beSDag-Erling Smørgrav * not match. 697462c32cbSDag-Erling Smørgrav */ 698333ee039SDag-Erling Smørgrav static int 699462c32cbSDag-Erling Smørgrav match_cfg_line(char **condition, int line, struct connection_info *ci) 700333ee039SDag-Erling Smørgrav { 701462c32cbSDag-Erling Smørgrav int result = 1, port; 702333ee039SDag-Erling Smørgrav char *arg, *attrib, *cp = *condition; 703333ee039SDag-Erling Smørgrav size_t len; 704333ee039SDag-Erling Smørgrav 705462c32cbSDag-Erling Smørgrav if (ci == NULL) 706333ee039SDag-Erling Smørgrav debug3("checking syntax for 'Match %s'", cp); 707333ee039SDag-Erling Smørgrav else 708462c32cbSDag-Erling Smørgrav debug3("checking match for '%s' user %s host %s addr %s " 709462c32cbSDag-Erling Smørgrav "laddr %s lport %d", cp, ci->user ? ci->user : "(null)", 710462c32cbSDag-Erling Smørgrav ci->host ? ci->host : "(null)", 711462c32cbSDag-Erling Smørgrav ci->address ? ci->address : "(null)", 712462c32cbSDag-Erling Smørgrav ci->laddress ? ci->laddress : "(null)", ci->lport); 713333ee039SDag-Erling Smørgrav 714333ee039SDag-Erling Smørgrav while ((attrib = strdelim(&cp)) && *attrib != '\0') { 715333ee039SDag-Erling Smørgrav if ((arg = strdelim(&cp)) == NULL || *arg == '\0') { 716333ee039SDag-Erling Smørgrav error("Missing Match criteria for %s", attrib); 717333ee039SDag-Erling Smørgrav return -1; 718333ee039SDag-Erling Smørgrav } 719333ee039SDag-Erling Smørgrav len = strlen(arg); 720333ee039SDag-Erling Smørgrav if (strcasecmp(attrib, "user") == 0) { 721462c32cbSDag-Erling Smørgrav if (ci == NULL || ci->user == NULL) { 722333ee039SDag-Erling Smørgrav result = 0; 723333ee039SDag-Erling Smørgrav continue; 724333ee039SDag-Erling Smørgrav } 725462c32cbSDag-Erling Smørgrav if (match_pattern_list(ci->user, arg, len, 0) != 1) 726333ee039SDag-Erling Smørgrav result = 0; 727333ee039SDag-Erling Smørgrav else 728333ee039SDag-Erling Smørgrav debug("user %.100s matched 'User %.100s' at " 729462c32cbSDag-Erling Smørgrav "line %d", ci->user, arg, line); 730333ee039SDag-Erling Smørgrav } else if (strcasecmp(attrib, "group") == 0) { 731462c32cbSDag-Erling Smørgrav if (ci == NULL || ci->user == NULL) { 732462c32cbSDag-Erling Smørgrav result = 0; 733462c32cbSDag-Erling Smørgrav continue; 734462c32cbSDag-Erling Smørgrav } 735462c32cbSDag-Erling Smørgrav switch (match_cfg_line_group(arg, line, ci->user)) { 736333ee039SDag-Erling Smørgrav case -1: 737333ee039SDag-Erling Smørgrav return -1; 738333ee039SDag-Erling Smørgrav case 0: 739333ee039SDag-Erling Smørgrav result = 0; 740333ee039SDag-Erling Smørgrav } 741333ee039SDag-Erling Smørgrav } else if (strcasecmp(attrib, "host") == 0) { 742462c32cbSDag-Erling Smørgrav if (ci == NULL || ci->host == NULL) { 743333ee039SDag-Erling Smørgrav result = 0; 744333ee039SDag-Erling Smørgrav continue; 745333ee039SDag-Erling Smørgrav } 746462c32cbSDag-Erling Smørgrav if (match_hostname(ci->host, arg, len) != 1) 747333ee039SDag-Erling Smørgrav result = 0; 748333ee039SDag-Erling Smørgrav else 749333ee039SDag-Erling Smørgrav debug("connection from %.100s matched 'Host " 750462c32cbSDag-Erling Smørgrav "%.100s' at line %d", ci->host, arg, line); 751333ee039SDag-Erling Smørgrav } else if (strcasecmp(attrib, "address") == 0) { 752462c32cbSDag-Erling Smørgrav if (ci == NULL || ci->address == NULL) { 753462c32cbSDag-Erling Smørgrav result = 0; 754462c32cbSDag-Erling Smørgrav continue; 755462c32cbSDag-Erling Smørgrav } 756462c32cbSDag-Erling Smørgrav switch (addr_match_list(ci->address, arg)) { 757d4af9e69SDag-Erling Smørgrav case 1: 758333ee039SDag-Erling Smørgrav debug("connection from %.100s matched 'Address " 759462c32cbSDag-Erling Smørgrav "%.100s' at line %d", ci->address, arg, line); 760d4af9e69SDag-Erling Smørgrav break; 761d4af9e69SDag-Erling Smørgrav case 0: 762d4af9e69SDag-Erling Smørgrav case -1: 763d4af9e69SDag-Erling Smørgrav result = 0; 764d4af9e69SDag-Erling Smørgrav break; 765d4af9e69SDag-Erling Smørgrav case -2: 766d4af9e69SDag-Erling Smørgrav return -1; 767d4af9e69SDag-Erling Smørgrav } 768462c32cbSDag-Erling Smørgrav } else if (strcasecmp(attrib, "localaddress") == 0){ 769462c32cbSDag-Erling Smørgrav if (ci == NULL || ci->laddress == NULL) { 770462c32cbSDag-Erling Smørgrav result = 0; 771462c32cbSDag-Erling Smørgrav continue; 772462c32cbSDag-Erling Smørgrav } 773462c32cbSDag-Erling Smørgrav switch (addr_match_list(ci->laddress, arg)) { 774462c32cbSDag-Erling Smørgrav case 1: 775462c32cbSDag-Erling Smørgrav debug("connection from %.100s matched " 776462c32cbSDag-Erling Smørgrav "'LocalAddress %.100s' at line %d", 777462c32cbSDag-Erling Smørgrav ci->laddress, arg, line); 778462c32cbSDag-Erling Smørgrav break; 779462c32cbSDag-Erling Smørgrav case 0: 780462c32cbSDag-Erling Smørgrav case -1: 781462c32cbSDag-Erling Smørgrav result = 0; 782462c32cbSDag-Erling Smørgrav break; 783462c32cbSDag-Erling Smørgrav case -2: 784462c32cbSDag-Erling Smørgrav return -1; 785462c32cbSDag-Erling Smørgrav } 786462c32cbSDag-Erling Smørgrav } else if (strcasecmp(attrib, "localport") == 0) { 787462c32cbSDag-Erling Smørgrav if ((port = a2port(arg)) == -1) { 788462c32cbSDag-Erling Smørgrav error("Invalid LocalPort '%s' on Match line", 789462c32cbSDag-Erling Smørgrav arg); 790462c32cbSDag-Erling Smørgrav return -1; 791462c32cbSDag-Erling Smørgrav } 792462c32cbSDag-Erling Smørgrav if (ci == NULL || ci->lport == 0) { 793462c32cbSDag-Erling Smørgrav result = 0; 794462c32cbSDag-Erling Smørgrav continue; 795462c32cbSDag-Erling Smørgrav } 796462c32cbSDag-Erling Smørgrav /* TODO support port lists */ 797462c32cbSDag-Erling Smørgrav if (port == ci->lport) 798462c32cbSDag-Erling Smørgrav debug("connection from %.100s matched " 799462c32cbSDag-Erling Smørgrav "'LocalPort %d' at line %d", 800462c32cbSDag-Erling Smørgrav ci->laddress, port, line); 801462c32cbSDag-Erling Smørgrav else 802462c32cbSDag-Erling Smørgrav result = 0; 803333ee039SDag-Erling Smørgrav } else { 804333ee039SDag-Erling Smørgrav error("Unsupported Match attribute %s", attrib); 805333ee039SDag-Erling Smørgrav return -1; 806333ee039SDag-Erling Smørgrav } 807333ee039SDag-Erling Smørgrav } 808462c32cbSDag-Erling Smørgrav if (ci != NULL) 809333ee039SDag-Erling Smørgrav debug3("match %sfound", result ? "" : "not "); 810333ee039SDag-Erling Smørgrav *condition = cp; 811333ee039SDag-Erling Smørgrav return result; 812333ee039SDag-Erling Smørgrav } 813333ee039SDag-Erling Smørgrav 814333ee039SDag-Erling Smørgrav #define WHITESPACE " \t\r\n" 815333ee039SDag-Erling Smørgrav 816e146993eSDag-Erling Smørgrav /* Multistate option parsing */ 817e146993eSDag-Erling Smørgrav struct multistate { 818e146993eSDag-Erling Smørgrav char *key; 819e146993eSDag-Erling Smørgrav int value; 820e146993eSDag-Erling Smørgrav }; 821e146993eSDag-Erling Smørgrav static const struct multistate multistate_addressfamily[] = { 822e146993eSDag-Erling Smørgrav { "inet", AF_INET }, 823e146993eSDag-Erling Smørgrav { "inet6", AF_INET6 }, 824e146993eSDag-Erling Smørgrav { "any", AF_UNSPEC }, 825e146993eSDag-Erling Smørgrav { NULL, -1 } 826e146993eSDag-Erling Smørgrav }; 827e146993eSDag-Erling Smørgrav static const struct multistate multistate_permitrootlogin[] = { 828e146993eSDag-Erling Smørgrav { "without-password", PERMIT_NO_PASSWD }, 829e146993eSDag-Erling Smørgrav { "forced-commands-only", PERMIT_FORCED_ONLY }, 830e146993eSDag-Erling Smørgrav { "yes", PERMIT_YES }, 831e146993eSDag-Erling Smørgrav { "no", PERMIT_NO }, 832e146993eSDag-Erling Smørgrav { NULL, -1 } 833e146993eSDag-Erling Smørgrav }; 834e146993eSDag-Erling Smørgrav static const struct multistate multistate_compression[] = { 835e146993eSDag-Erling Smørgrav { "delayed", COMP_DELAYED }, 836e146993eSDag-Erling Smørgrav { "yes", COMP_ZLIB }, 837e146993eSDag-Erling Smørgrav { "no", COMP_NONE }, 838e146993eSDag-Erling Smørgrav { NULL, -1 } 839e146993eSDag-Erling Smørgrav }; 840e146993eSDag-Erling Smørgrav static const struct multistate multistate_gatewayports[] = { 841e146993eSDag-Erling Smørgrav { "clientspecified", 2 }, 842e146993eSDag-Erling Smørgrav { "yes", 1 }, 843e146993eSDag-Erling Smørgrav { "no", 0 }, 844e146993eSDag-Erling Smørgrav { NULL, -1 } 845e146993eSDag-Erling Smørgrav }; 846e146993eSDag-Erling Smørgrav static const struct multistate multistate_privsep[] = { 847462c32cbSDag-Erling Smørgrav { "yes", PRIVSEP_NOSANDBOX }, 848462c32cbSDag-Erling Smørgrav { "sandbox", PRIVSEP_ON }, 849462c32cbSDag-Erling Smørgrav { "nosandbox", PRIVSEP_NOSANDBOX }, 850e146993eSDag-Erling Smørgrav { "no", PRIVSEP_OFF }, 851e146993eSDag-Erling Smørgrav { NULL, -1 } 852e146993eSDag-Erling Smørgrav }; 8536888a9beSDag-Erling Smørgrav static const struct multistate multistate_tcpfwd[] = { 8546888a9beSDag-Erling Smørgrav { "yes", FORWARD_ALLOW }, 8556888a9beSDag-Erling Smørgrav { "all", FORWARD_ALLOW }, 8566888a9beSDag-Erling Smørgrav { "no", FORWARD_DENY }, 8576888a9beSDag-Erling Smørgrav { "remote", FORWARD_REMOTE }, 8586888a9beSDag-Erling Smørgrav { "local", FORWARD_LOCAL }, 8596888a9beSDag-Erling Smørgrav { NULL, -1 } 8606888a9beSDag-Erling Smørgrav }; 861e146993eSDag-Erling Smørgrav 862af12a3e7SDag-Erling Smørgrav int 863af12a3e7SDag-Erling Smørgrav process_server_config_line(ServerOptions *options, char *line, 864462c32cbSDag-Erling Smørgrav const char *filename, int linenum, int *activep, 865462c32cbSDag-Erling Smørgrav struct connection_info *connectinfo) 866511b41d2SMark Murray { 867ca3176e7SBrian Feldman char *cp, **charptr, *arg, *p; 868*e4a9863fSDag-Erling Smørgrav int cmdline = 0, *intptr, value, value2, n, port; 869d4af9e69SDag-Erling Smørgrav SyslogFacility *log_facility_ptr; 870d4af9e69SDag-Erling Smørgrav LogLevel *log_level_ptr; 871511b41d2SMark Murray ServerOpCodes opcode; 872333ee039SDag-Erling Smørgrav u_int i, flags = 0; 873333ee039SDag-Erling Smørgrav size_t len; 874*e4a9863fSDag-Erling Smørgrav long long val64; 875e146993eSDag-Erling Smørgrav const struct multistate *multistate_ptr; 876511b41d2SMark Murray 877c2d3a559SKris Kennaway cp = line; 878333ee039SDag-Erling Smørgrav if ((arg = strdelim(&cp)) == NULL) 879333ee039SDag-Erling Smørgrav return 0; 880c2d3a559SKris Kennaway /* Ignore leading whitespace */ 881c2d3a559SKris Kennaway if (*arg == '\0') 882c2d3a559SKris Kennaway arg = strdelim(&cp); 883ca3176e7SBrian Feldman if (!arg || !*arg || *arg == '#') 884af12a3e7SDag-Erling Smørgrav return 0; 885ca3176e7SBrian Feldman intptr = NULL; 886ca3176e7SBrian Feldman charptr = NULL; 887333ee039SDag-Erling Smørgrav opcode = parse_token(arg, filename, linenum, &flags); 888333ee039SDag-Erling Smørgrav 889333ee039SDag-Erling Smørgrav if (activep == NULL) { /* We are processing a command line directive */ 890333ee039SDag-Erling Smørgrav cmdline = 1; 891333ee039SDag-Erling Smørgrav activep = &cmdline; 892333ee039SDag-Erling Smørgrav } 893333ee039SDag-Erling Smørgrav if (*activep && opcode != sMatch) 894333ee039SDag-Erling Smørgrav debug3("%s:%d setting %s %s", filename, linenum, arg, cp); 895333ee039SDag-Erling Smørgrav if (*activep == 0 && !(flags & SSHCFG_MATCH)) { 896462c32cbSDag-Erling Smørgrav if (connectinfo == NULL) { 897333ee039SDag-Erling Smørgrav fatal("%s line %d: Directive '%s' is not allowed " 898333ee039SDag-Erling Smørgrav "within a Match block", filename, linenum, arg); 899333ee039SDag-Erling Smørgrav } else { /* this is a directive we have already processed */ 900333ee039SDag-Erling Smørgrav while (arg) 901333ee039SDag-Erling Smørgrav arg = strdelim(&cp); 902333ee039SDag-Erling Smørgrav return 0; 903333ee039SDag-Erling Smørgrav } 904333ee039SDag-Erling Smørgrav } 905333ee039SDag-Erling Smørgrav 906511b41d2SMark Murray switch (opcode) { 907989dd127SDag-Erling Smørgrav /* Portable-specific options */ 908cf2b5f3bSDag-Erling Smørgrav case sUsePAM: 909cf2b5f3bSDag-Erling Smørgrav intptr = &options->use_pam; 910989dd127SDag-Erling Smørgrav goto parse_flag; 911989dd127SDag-Erling Smørgrav 912989dd127SDag-Erling Smørgrav /* Standard Options */ 913511b41d2SMark Murray case sBadOption: 914af12a3e7SDag-Erling Smørgrav return -1; 915511b41d2SMark Murray case sPort: 916511b41d2SMark Murray /* ignore ports from configfile if cmdline specifies ports */ 917511b41d2SMark Murray if (options->ports_from_cmdline) 918af12a3e7SDag-Erling Smørgrav return 0; 919511b41d2SMark Murray if (options->listen_addrs != NULL) 920511b41d2SMark Murray fatal("%s line %d: ports must be specified before " 921af12a3e7SDag-Erling Smørgrav "ListenAddress.", filename, linenum); 922511b41d2SMark Murray if (options->num_ports >= MAX_PORTS) 923ca3176e7SBrian Feldman fatal("%s line %d: too many ports.", 924511b41d2SMark Murray filename, linenum); 925c2d3a559SKris Kennaway arg = strdelim(&cp); 926c2d3a559SKris Kennaway if (!arg || *arg == '\0') 927ca3176e7SBrian Feldman fatal("%s line %d: missing port number.", 928511b41d2SMark Murray filename, linenum); 929ca3176e7SBrian Feldman options->ports[options->num_ports++] = a2port(arg); 930cce7d346SDag-Erling Smørgrav if (options->ports[options->num_ports-1] <= 0) 931ca3176e7SBrian Feldman fatal("%s line %d: Badly formatted port number.", 932ca3176e7SBrian Feldman filename, linenum); 933511b41d2SMark Murray break; 934511b41d2SMark Murray 935511b41d2SMark Murray case sServerKeyBits: 936511b41d2SMark Murray intptr = &options->server_key_bits; 937511b41d2SMark Murray parse_int: 938c2d3a559SKris Kennaway arg = strdelim(&cp); 939ca3176e7SBrian Feldman if (!arg || *arg == '\0') 940ca3176e7SBrian Feldman fatal("%s line %d: missing integer value.", 941511b41d2SMark Murray filename, linenum); 942c2d3a559SKris Kennaway value = atoi(arg); 943333ee039SDag-Erling Smørgrav if (*activep && *intptr == -1) 944511b41d2SMark Murray *intptr = value; 945511b41d2SMark Murray break; 946511b41d2SMark Murray 947511b41d2SMark Murray case sLoginGraceTime: 948511b41d2SMark Murray intptr = &options->login_grace_time; 949af12a3e7SDag-Erling Smørgrav parse_time: 950af12a3e7SDag-Erling Smørgrav arg = strdelim(&cp); 951af12a3e7SDag-Erling Smørgrav if (!arg || *arg == '\0') 952af12a3e7SDag-Erling Smørgrav fatal("%s line %d: missing time value.", 953af12a3e7SDag-Erling Smørgrav filename, linenum); 954af12a3e7SDag-Erling Smørgrav if ((value = convtime(arg)) == -1) 955af12a3e7SDag-Erling Smørgrav fatal("%s line %d: invalid time value.", 956af12a3e7SDag-Erling Smørgrav filename, linenum); 957af12a3e7SDag-Erling Smørgrav if (*intptr == -1) 958af12a3e7SDag-Erling Smørgrav *intptr = value; 959af12a3e7SDag-Erling Smørgrav break; 960511b41d2SMark Murray 961511b41d2SMark Murray case sKeyRegenerationTime: 962511b41d2SMark Murray intptr = &options->key_regeneration_time; 963af12a3e7SDag-Erling Smørgrav goto parse_time; 964511b41d2SMark Murray 965511b41d2SMark Murray case sListenAddress: 966c2d3a559SKris Kennaway arg = strdelim(&cp); 967aa49c926SDag-Erling Smørgrav if (arg == NULL || *arg == '\0') 968aa49c926SDag-Erling Smørgrav fatal("%s line %d: missing address", 969511b41d2SMark Murray filename, linenum); 970d4ecd108SDag-Erling Smørgrav /* check for bare IPv6 address: no "[]" and 2 or more ":" */ 971d4ecd108SDag-Erling Smørgrav if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL 972d4ecd108SDag-Erling Smørgrav && strchr(p+1, ':') != NULL) { 973d4ecd108SDag-Erling Smørgrav add_listen_addr(options, arg, 0); 974d4ecd108SDag-Erling Smørgrav break; 975d4ecd108SDag-Erling Smørgrav } 976aa49c926SDag-Erling Smørgrav p = hpdelim(&arg); 977aa49c926SDag-Erling Smørgrav if (p == NULL) 978aa49c926SDag-Erling Smørgrav fatal("%s line %d: bad address:port usage", 979ca3176e7SBrian Feldman filename, linenum); 980aa49c926SDag-Erling Smørgrav p = cleanhostname(p); 981aa49c926SDag-Erling Smørgrav if (arg == NULL) 982aa49c926SDag-Erling Smørgrav port = 0; 983cce7d346SDag-Erling Smørgrav else if ((port = a2port(arg)) <= 0) 984aa49c926SDag-Erling Smørgrav fatal("%s line %d: bad port number", filename, linenum); 985ca3176e7SBrian Feldman 986aa49c926SDag-Erling Smørgrav add_listen_addr(options, p, port); 987aa49c926SDag-Erling Smørgrav 988aa49c926SDag-Erling Smørgrav break; 989aa49c926SDag-Erling Smørgrav 990aa49c926SDag-Erling Smørgrav case sAddressFamily: 991e146993eSDag-Erling Smørgrav intptr = &options->address_family; 992e146993eSDag-Erling Smørgrav multistate_ptr = multistate_addressfamily; 993e146993eSDag-Erling Smørgrav if (options->listen_addrs != NULL) 994e146993eSDag-Erling Smørgrav fatal("%s line %d: address family must be specified " 995e146993eSDag-Erling Smørgrav "before ListenAddress.", filename, linenum); 996e146993eSDag-Erling Smørgrav parse_multistate: 997aa49c926SDag-Erling Smørgrav arg = strdelim(&cp); 998d4ecd108SDag-Erling Smørgrav if (!arg || *arg == '\0') 999e146993eSDag-Erling Smørgrav fatal("%s line %d: missing argument.", 1000d4ecd108SDag-Erling Smørgrav filename, linenum); 1001e146993eSDag-Erling Smørgrav value = -1; 1002e146993eSDag-Erling Smørgrav for (i = 0; multistate_ptr[i].key != NULL; i++) { 1003e146993eSDag-Erling Smørgrav if (strcasecmp(arg, multistate_ptr[i].key) == 0) { 1004e146993eSDag-Erling Smørgrav value = multistate_ptr[i].value; 1005e146993eSDag-Erling Smørgrav break; 1006e146993eSDag-Erling Smørgrav } 1007e146993eSDag-Erling Smørgrav } 1008e146993eSDag-Erling Smørgrav if (value == -1) 1009e146993eSDag-Erling Smørgrav fatal("%s line %d: unsupported option \"%s\".", 1010aa49c926SDag-Erling Smørgrav filename, linenum, arg); 1011e146993eSDag-Erling Smørgrav if (*activep && *intptr == -1) 1012aa49c926SDag-Erling Smørgrav *intptr = value; 1013511b41d2SMark Murray break; 1014511b41d2SMark Murray 1015511b41d2SMark Murray case sHostKeyFile: 1016ca3176e7SBrian Feldman intptr = &options->num_host_key_files; 1017ca3176e7SBrian Feldman if (*intptr >= MAX_HOSTKEYS) 1018ca3176e7SBrian Feldman fatal("%s line %d: too many host keys specified (max %d).", 1019ca3176e7SBrian Feldman filename, linenum, MAX_HOSTKEYS); 1020ca3176e7SBrian Feldman charptr = &options->host_key_files[*intptr]; 1021c2d3a559SKris Kennaway parse_filename: 1022c2d3a559SKris Kennaway arg = strdelim(&cp); 1023ca3176e7SBrian Feldman if (!arg || *arg == '\0') 1024ca3176e7SBrian Feldman fatal("%s line %d: missing file name.", 1025e8aafc91SKris Kennaway filename, linenum); 1026333ee039SDag-Erling Smørgrav if (*activep && *charptr == NULL) { 1027b15c8340SDag-Erling Smørgrav *charptr = derelativise_path(arg); 1028ca3176e7SBrian Feldman /* increase optional counter */ 1029ca3176e7SBrian Feldman if (intptr != NULL) 1030ca3176e7SBrian Feldman *intptr = *intptr + 1; 1031ca3176e7SBrian Feldman } 1032e8aafc91SKris Kennaway break; 1033e8aafc91SKris Kennaway 1034*e4a9863fSDag-Erling Smørgrav case sHostKeyAgent: 1035*e4a9863fSDag-Erling Smørgrav charptr = &options->host_key_agent; 1036*e4a9863fSDag-Erling Smørgrav arg = strdelim(&cp); 1037*e4a9863fSDag-Erling Smørgrav if (!arg || *arg == '\0') 1038*e4a9863fSDag-Erling Smørgrav fatal("%s line %d: missing socket name.", 1039*e4a9863fSDag-Erling Smørgrav filename, linenum); 1040*e4a9863fSDag-Erling Smørgrav if (*activep && *charptr == NULL) 1041*e4a9863fSDag-Erling Smørgrav *charptr = !strcmp(arg, SSH_AUTHSOCKET_ENV_NAME) ? 1042*e4a9863fSDag-Erling Smørgrav xstrdup(arg) : derelativise_path(arg); 1043*e4a9863fSDag-Erling Smørgrav break; 1044*e4a9863fSDag-Erling Smørgrav 1045b15c8340SDag-Erling Smørgrav case sHostCertificate: 1046b15c8340SDag-Erling Smørgrav intptr = &options->num_host_cert_files; 1047b15c8340SDag-Erling Smørgrav if (*intptr >= MAX_HOSTKEYS) 1048b15c8340SDag-Erling Smørgrav fatal("%s line %d: too many host certificates " 1049b15c8340SDag-Erling Smørgrav "specified (max %d).", filename, linenum, 1050b15c8340SDag-Erling Smørgrav MAX_HOSTCERTS); 1051b15c8340SDag-Erling Smørgrav charptr = &options->host_cert_files[*intptr]; 1052b15c8340SDag-Erling Smørgrav goto parse_filename; 1053b15c8340SDag-Erling Smørgrav break; 1054b15c8340SDag-Erling Smørgrav 1055e8aafc91SKris Kennaway case sPidFile: 1056e8aafc91SKris Kennaway charptr = &options->pid_file; 1057c2d3a559SKris Kennaway goto parse_filename; 1058511b41d2SMark Murray 1059511b41d2SMark Murray case sPermitRootLogin: 1060511b41d2SMark Murray intptr = &options->permit_root_login; 1061e146993eSDag-Erling Smørgrav multistate_ptr = multistate_permitrootlogin; 1062e146993eSDag-Erling Smørgrav goto parse_multistate; 1063511b41d2SMark Murray 1064511b41d2SMark Murray case sIgnoreRhosts: 1065511b41d2SMark Murray intptr = &options->ignore_rhosts; 1066511b41d2SMark Murray parse_flag: 1067c2d3a559SKris Kennaway arg = strdelim(&cp); 1068ca3176e7SBrian Feldman if (!arg || *arg == '\0') 1069ca3176e7SBrian Feldman fatal("%s line %d: missing yes/no argument.", 1070511b41d2SMark Murray filename, linenum); 1071ca3176e7SBrian Feldman value = 0; /* silence compiler */ 1072c2d3a559SKris Kennaway if (strcmp(arg, "yes") == 0) 1073511b41d2SMark Murray value = 1; 1074c2d3a559SKris Kennaway else if (strcmp(arg, "no") == 0) 1075511b41d2SMark Murray value = 0; 1076ca3176e7SBrian Feldman else 1077ca3176e7SBrian Feldman fatal("%s line %d: Bad yes/no argument: %s", 1078c2d3a559SKris Kennaway filename, linenum, arg); 1079333ee039SDag-Erling Smørgrav if (*activep && *intptr == -1) 1080511b41d2SMark Murray *intptr = value; 1081511b41d2SMark Murray break; 1082511b41d2SMark Murray 1083511b41d2SMark Murray case sIgnoreUserKnownHosts: 1084511b41d2SMark Murray intptr = &options->ignore_user_known_hosts; 1085962a3f4eSSheldon Hearn goto parse_flag; 1086511b41d2SMark Murray 1087511b41d2SMark Murray case sRhostsRSAAuthentication: 1088511b41d2SMark Murray intptr = &options->rhosts_rsa_authentication; 1089511b41d2SMark Murray goto parse_flag; 1090511b41d2SMark Murray 1091ca3176e7SBrian Feldman case sHostbasedAuthentication: 1092ca3176e7SBrian Feldman intptr = &options->hostbased_authentication; 1093ca3176e7SBrian Feldman goto parse_flag; 1094ca3176e7SBrian Feldman 1095ca3176e7SBrian Feldman case sHostbasedUsesNameFromPacketOnly: 1096ca3176e7SBrian Feldman intptr = &options->hostbased_uses_name_from_packet_only; 1097ca3176e7SBrian Feldman goto parse_flag; 1098ca3176e7SBrian Feldman 1099511b41d2SMark Murray case sRSAAuthentication: 1100511b41d2SMark Murray intptr = &options->rsa_authentication; 1101511b41d2SMark Murray goto parse_flag; 1102511b41d2SMark Murray 1103ca3176e7SBrian Feldman case sPubkeyAuthentication: 1104ca3176e7SBrian Feldman intptr = &options->pubkey_authentication; 1105e8aafc91SKris Kennaway goto parse_flag; 1106cf2b5f3bSDag-Erling Smørgrav 1107cb96ab36SAssar Westerlund case sKerberosAuthentication: 1108cb96ab36SAssar Westerlund intptr = &options->kerberos_authentication; 1109511b41d2SMark Murray goto parse_flag; 1110511b41d2SMark Murray 1111af12a3e7SDag-Erling Smørgrav case sKerberosOrLocalPasswd: 1112af12a3e7SDag-Erling Smørgrav intptr = &options->kerberos_or_local_passwd; 1113511b41d2SMark Murray goto parse_flag; 1114511b41d2SMark Murray 1115af12a3e7SDag-Erling Smørgrav case sKerberosTicketCleanup: 1116af12a3e7SDag-Erling Smørgrav intptr = &options->kerberos_ticket_cleanup; 1117511b41d2SMark Murray goto parse_flag; 1118cf2b5f3bSDag-Erling Smørgrav 11191ec0d754SDag-Erling Smørgrav case sKerberosGetAFSToken: 11201ec0d754SDag-Erling Smørgrav intptr = &options->kerberos_get_afs_token; 11211ec0d754SDag-Erling Smørgrav goto parse_flag; 11221ec0d754SDag-Erling Smørgrav 1123cf2b5f3bSDag-Erling Smørgrav case sGssAuthentication: 1124cf2b5f3bSDag-Erling Smørgrav intptr = &options->gss_authentication; 1125fe5fd017SMark Murray goto parse_flag; 1126cf2b5f3bSDag-Erling Smørgrav 1127cf2b5f3bSDag-Erling Smørgrav case sGssCleanupCreds: 1128cf2b5f3bSDag-Erling Smørgrav intptr = &options->gss_cleanup_creds; 1129511b41d2SMark Murray goto parse_flag; 1130511b41d2SMark Murray 1131511b41d2SMark Murray case sPasswordAuthentication: 1132511b41d2SMark Murray intptr = &options->password_authentication; 1133511b41d2SMark Murray goto parse_flag; 1134511b41d2SMark Murray 1135cce7d346SDag-Erling Smørgrav case sZeroKnowledgePasswordAuthentication: 1136cce7d346SDag-Erling Smørgrav intptr = &options->zero_knowledge_password_authentication; 1137cce7d346SDag-Erling Smørgrav goto parse_flag; 1138cce7d346SDag-Erling Smørgrav 113909958426SBrian Feldman case sKbdInteractiveAuthentication: 114009958426SBrian Feldman intptr = &options->kbd_interactive_authentication; 114109958426SBrian Feldman goto parse_flag; 114209958426SBrian Feldman 1143ca3176e7SBrian Feldman case sChallengeResponseAuthentication: 1144af12a3e7SDag-Erling Smørgrav intptr = &options->challenge_response_authentication; 1145511b41d2SMark Murray goto parse_flag; 1146511b41d2SMark Murray 1147511b41d2SMark Murray case sPrintMotd: 1148511b41d2SMark Murray intptr = &options->print_motd; 1149511b41d2SMark Murray goto parse_flag; 1150511b41d2SMark Murray 1151ca3176e7SBrian Feldman case sPrintLastLog: 1152ca3176e7SBrian Feldman intptr = &options->print_lastlog; 1153ca3176e7SBrian Feldman goto parse_flag; 1154ca3176e7SBrian Feldman 1155511b41d2SMark Murray case sX11Forwarding: 1156511b41d2SMark Murray intptr = &options->x11_forwarding; 1157511b41d2SMark Murray goto parse_flag; 1158511b41d2SMark Murray 1159511b41d2SMark Murray case sX11DisplayOffset: 1160511b41d2SMark Murray intptr = &options->x11_display_offset; 1161511b41d2SMark Murray goto parse_int; 1162511b41d2SMark Murray 1163af12a3e7SDag-Erling Smørgrav case sX11UseLocalhost: 1164af12a3e7SDag-Erling Smørgrav intptr = &options->x11_use_localhost; 1165af12a3e7SDag-Erling Smørgrav goto parse_flag; 1166af12a3e7SDag-Erling Smørgrav 1167c2d3a559SKris Kennaway case sXAuthLocation: 1168c2d3a559SKris Kennaway charptr = &options->xauth_location; 1169c2d3a559SKris Kennaway goto parse_filename; 1170c2d3a559SKris Kennaway 1171511b41d2SMark Murray case sStrictModes: 1172511b41d2SMark Murray intptr = &options->strict_modes; 1173511b41d2SMark Murray goto parse_flag; 1174511b41d2SMark Murray 11751ec0d754SDag-Erling Smørgrav case sTCPKeepAlive: 11761ec0d754SDag-Erling Smørgrav intptr = &options->tcp_keep_alive; 1177511b41d2SMark Murray goto parse_flag; 1178511b41d2SMark Murray 1179511b41d2SMark Murray case sEmptyPasswd: 1180511b41d2SMark Murray intptr = &options->permit_empty_passwd; 1181511b41d2SMark Murray goto parse_flag; 1182511b41d2SMark Murray 1183f388f5efSDag-Erling Smørgrav case sPermitUserEnvironment: 1184f388f5efSDag-Erling Smørgrav intptr = &options->permit_user_env; 1185f388f5efSDag-Erling Smørgrav goto parse_flag; 1186f388f5efSDag-Erling Smørgrav 1187511b41d2SMark Murray case sUseLogin: 1188511b41d2SMark Murray intptr = &options->use_login; 1189511b41d2SMark Murray goto parse_flag; 1190511b41d2SMark Murray 119180628bacSDag-Erling Smørgrav case sCompression: 119280628bacSDag-Erling Smørgrav intptr = &options->compression; 1193e146993eSDag-Erling Smørgrav multistate_ptr = multistate_compression; 1194e146993eSDag-Erling Smørgrav goto parse_multistate; 119580628bacSDag-Erling Smørgrav 1196*e4a9863fSDag-Erling Smørgrav case sRekeyLimit: 1197*e4a9863fSDag-Erling Smørgrav arg = strdelim(&cp); 1198*e4a9863fSDag-Erling Smørgrav if (!arg || *arg == '\0') 1199*e4a9863fSDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", filename, 1200*e4a9863fSDag-Erling Smørgrav linenum); 1201*e4a9863fSDag-Erling Smørgrav if (strcmp(arg, "default") == 0) { 1202*e4a9863fSDag-Erling Smørgrav val64 = 0; 1203*e4a9863fSDag-Erling Smørgrav } else { 1204*e4a9863fSDag-Erling Smørgrav if (scan_scaled(arg, &val64) == -1) 1205*e4a9863fSDag-Erling Smørgrav fatal("%.200s line %d: Bad number '%s': %s", 1206*e4a9863fSDag-Erling Smørgrav filename, linenum, arg, strerror(errno)); 1207*e4a9863fSDag-Erling Smørgrav /* check for too-large or too-small limits */ 1208*e4a9863fSDag-Erling Smørgrav if (val64 > UINT_MAX) 1209*e4a9863fSDag-Erling Smørgrav fatal("%.200s line %d: RekeyLimit too large", 1210*e4a9863fSDag-Erling Smørgrav filename, linenum); 1211*e4a9863fSDag-Erling Smørgrav if (val64 != 0 && val64 < 16) 1212*e4a9863fSDag-Erling Smørgrav fatal("%.200s line %d: RekeyLimit too small", 1213*e4a9863fSDag-Erling Smørgrav filename, linenum); 1214*e4a9863fSDag-Erling Smørgrav } 1215*e4a9863fSDag-Erling Smørgrav if (*activep && options->rekey_limit == -1) 1216*e4a9863fSDag-Erling Smørgrav options->rekey_limit = (u_int32_t)val64; 1217*e4a9863fSDag-Erling Smørgrav if (cp != NULL) { /* optional rekey interval present */ 1218*e4a9863fSDag-Erling Smørgrav if (strcmp(cp, "none") == 0) { 1219*e4a9863fSDag-Erling Smørgrav (void)strdelim(&cp); /* discard */ 1220*e4a9863fSDag-Erling Smørgrav break; 1221*e4a9863fSDag-Erling Smørgrav } 1222*e4a9863fSDag-Erling Smørgrav intptr = &options->rekey_interval; 1223*e4a9863fSDag-Erling Smørgrav goto parse_time; 1224*e4a9863fSDag-Erling Smørgrav } 1225*e4a9863fSDag-Erling Smørgrav break; 1226*e4a9863fSDag-Erling Smørgrav 1227e8aafc91SKris Kennaway case sGatewayPorts: 1228e8aafc91SKris Kennaway intptr = &options->gateway_ports; 1229e146993eSDag-Erling Smørgrav multistate_ptr = multistate_gatewayports; 1230e146993eSDag-Erling Smørgrav goto parse_multistate; 1231e8aafc91SKris Kennaway 1232cf2b5f3bSDag-Erling Smørgrav case sUseDNS: 1233cf2b5f3bSDag-Erling Smørgrav intptr = &options->use_dns; 1234ca3176e7SBrian Feldman goto parse_flag; 1235ca3176e7SBrian Feldman 1236511b41d2SMark Murray case sLogFacility: 1237d4af9e69SDag-Erling Smørgrav log_facility_ptr = &options->log_facility; 1238c2d3a559SKris Kennaway arg = strdelim(&cp); 1239c2d3a559SKris Kennaway value = log_facility_number(arg); 1240af12a3e7SDag-Erling Smørgrav if (value == SYSLOG_FACILITY_NOT_SET) 1241ca3176e7SBrian Feldman fatal("%.200s line %d: unsupported log facility '%s'", 1242c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 1243d4af9e69SDag-Erling Smørgrav if (*log_facility_ptr == -1) 1244d4af9e69SDag-Erling Smørgrav *log_facility_ptr = (SyslogFacility) value; 1245511b41d2SMark Murray break; 1246511b41d2SMark Murray 1247511b41d2SMark Murray case sLogLevel: 1248d4af9e69SDag-Erling Smørgrav log_level_ptr = &options->log_level; 1249c2d3a559SKris Kennaway arg = strdelim(&cp); 1250c2d3a559SKris Kennaway value = log_level_number(arg); 1251af12a3e7SDag-Erling Smørgrav if (value == SYSLOG_LEVEL_NOT_SET) 1252ca3176e7SBrian Feldman fatal("%.200s line %d: unsupported log level '%s'", 1253c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 1254d4af9e69SDag-Erling Smørgrav if (*log_level_ptr == -1) 1255d4af9e69SDag-Erling Smørgrav *log_level_ptr = (LogLevel) value; 1256511b41d2SMark Murray break; 1257511b41d2SMark Murray 125809958426SBrian Feldman case sAllowTcpForwarding: 125909958426SBrian Feldman intptr = &options->allow_tcp_forwarding; 12606888a9beSDag-Erling Smørgrav multistate_ptr = multistate_tcpfwd; 12616888a9beSDag-Erling Smørgrav goto parse_multistate; 126209958426SBrian Feldman 1263d4af9e69SDag-Erling Smørgrav case sAllowAgentForwarding: 1264d4af9e69SDag-Erling Smørgrav intptr = &options->allow_agent_forwarding; 1265d4af9e69SDag-Erling Smørgrav goto parse_flag; 1266d4af9e69SDag-Erling Smørgrav 126780628bacSDag-Erling Smørgrav case sUsePrivilegeSeparation: 126880628bacSDag-Erling Smørgrav intptr = &use_privsep; 1269e146993eSDag-Erling Smørgrav multistate_ptr = multistate_privsep; 1270e146993eSDag-Erling Smørgrav goto parse_multistate; 127180628bacSDag-Erling Smørgrav 1272511b41d2SMark Murray case sAllowUsers: 1273c2d3a559SKris Kennaway while ((arg = strdelim(&cp)) && *arg != '\0') { 127442f71286SMark Murray if (options->num_allow_users >= MAX_ALLOW_USERS) 1275af12a3e7SDag-Erling Smørgrav fatal("%s line %d: too many allow users.", 1276e8aafc91SKris Kennaway filename, linenum); 1277462c32cbSDag-Erling Smørgrav if (!*activep) 1278462c32cbSDag-Erling Smørgrav continue; 1279a82e551fSDag-Erling Smørgrav options->allow_users[options->num_allow_users++] = 1280a82e551fSDag-Erling Smørgrav xstrdup(arg); 1281511b41d2SMark Murray } 1282511b41d2SMark Murray break; 1283511b41d2SMark Murray 1284511b41d2SMark Murray case sDenyUsers: 1285c2d3a559SKris Kennaway while ((arg = strdelim(&cp)) && *arg != '\0') { 12862803b77eSBrian Feldman if (options->num_deny_users >= MAX_DENY_USERS) 1287af12a3e7SDag-Erling Smørgrav fatal("%s line %d: too many deny users.", 1288e8aafc91SKris Kennaway filename, linenum); 1289462c32cbSDag-Erling Smørgrav if (!*activep) 1290462c32cbSDag-Erling Smørgrav continue; 1291a82e551fSDag-Erling Smørgrav options->deny_users[options->num_deny_users++] = 1292a82e551fSDag-Erling Smørgrav xstrdup(arg); 1293511b41d2SMark Murray } 1294511b41d2SMark Murray break; 1295511b41d2SMark Murray 1296511b41d2SMark Murray case sAllowGroups: 1297c2d3a559SKris Kennaway while ((arg = strdelim(&cp)) && *arg != '\0') { 129842f71286SMark Murray if (options->num_allow_groups >= MAX_ALLOW_GROUPS) 1299af12a3e7SDag-Erling Smørgrav fatal("%s line %d: too many allow groups.", 1300e8aafc91SKris Kennaway filename, linenum); 1301462c32cbSDag-Erling Smørgrav if (!*activep) 1302462c32cbSDag-Erling Smørgrav continue; 1303a82e551fSDag-Erling Smørgrav options->allow_groups[options->num_allow_groups++] = 1304a82e551fSDag-Erling Smørgrav xstrdup(arg); 1305511b41d2SMark Murray } 1306511b41d2SMark Murray break; 1307511b41d2SMark Murray 1308511b41d2SMark Murray case sDenyGroups: 1309c2d3a559SKris Kennaway while ((arg = strdelim(&cp)) && *arg != '\0') { 131042f71286SMark Murray if (options->num_deny_groups >= MAX_DENY_GROUPS) 1311af12a3e7SDag-Erling Smørgrav fatal("%s line %d: too many deny groups.", 1312e8aafc91SKris Kennaway filename, linenum); 1313462c32cbSDag-Erling Smørgrav if (!*activep) 1314462c32cbSDag-Erling Smørgrav continue; 1315462c32cbSDag-Erling Smørgrav options->deny_groups[options->num_deny_groups++] = 1316462c32cbSDag-Erling Smørgrav xstrdup(arg); 1317511b41d2SMark Murray } 1318511b41d2SMark Murray break; 1319511b41d2SMark Murray 1320e8aafc91SKris Kennaway case sCiphers: 1321c2d3a559SKris Kennaway arg = strdelim(&cp); 1322c2d3a559SKris Kennaway if (!arg || *arg == '\0') 1323c322fe35SKris Kennaway fatal("%s line %d: Missing argument.", filename, linenum); 1324c2d3a559SKris Kennaway if (!ciphers_valid(arg)) 1325e8aafc91SKris Kennaway fatal("%s line %d: Bad SSH2 cipher spec '%s'.", 1326c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 1327e8aafc91SKris Kennaway if (options->ciphers == NULL) 1328c2d3a559SKris Kennaway options->ciphers = xstrdup(arg); 1329e8aafc91SKris Kennaway break; 1330e8aafc91SKris Kennaway 1331ca3176e7SBrian Feldman case sMacs: 1332ca3176e7SBrian Feldman arg = strdelim(&cp); 1333ca3176e7SBrian Feldman if (!arg || *arg == '\0') 1334ca3176e7SBrian Feldman fatal("%s line %d: Missing argument.", filename, linenum); 1335ca3176e7SBrian Feldman if (!mac_valid(arg)) 1336ca3176e7SBrian Feldman fatal("%s line %d: Bad SSH2 mac spec '%s'.", 1337ca3176e7SBrian Feldman filename, linenum, arg ? arg : "<NONE>"); 1338ca3176e7SBrian Feldman if (options->macs == NULL) 1339ca3176e7SBrian Feldman options->macs = xstrdup(arg); 1340ca3176e7SBrian Feldman break; 1341ca3176e7SBrian Feldman 13424a421b63SDag-Erling Smørgrav case sKexAlgorithms: 13434a421b63SDag-Erling Smørgrav arg = strdelim(&cp); 13444a421b63SDag-Erling Smørgrav if (!arg || *arg == '\0') 13454a421b63SDag-Erling Smørgrav fatal("%s line %d: Missing argument.", 13464a421b63SDag-Erling Smørgrav filename, linenum); 13474a421b63SDag-Erling Smørgrav if (!kex_names_valid(arg)) 13484a421b63SDag-Erling Smørgrav fatal("%s line %d: Bad SSH2 KexAlgorithms '%s'.", 13494a421b63SDag-Erling Smørgrav filename, linenum, arg ? arg : "<NONE>"); 13504a421b63SDag-Erling Smørgrav if (options->kex_algorithms == NULL) 13514a421b63SDag-Erling Smørgrav options->kex_algorithms = xstrdup(arg); 13524a421b63SDag-Erling Smørgrav break; 13534a421b63SDag-Erling Smørgrav 1354e8aafc91SKris Kennaway case sProtocol: 1355e8aafc91SKris Kennaway intptr = &options->protocol; 1356c2d3a559SKris Kennaway arg = strdelim(&cp); 1357c2d3a559SKris Kennaway if (!arg || *arg == '\0') 1358c322fe35SKris Kennaway fatal("%s line %d: Missing argument.", filename, linenum); 1359c2d3a559SKris Kennaway value = proto_spec(arg); 1360e8aafc91SKris Kennaway if (value == SSH_PROTO_UNKNOWN) 1361e8aafc91SKris Kennaway fatal("%s line %d: Bad protocol spec '%s'.", 1362c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 1363e8aafc91SKris Kennaway if (*intptr == SSH_PROTO_UNKNOWN) 1364e8aafc91SKris Kennaway *intptr = value; 1365e8aafc91SKris Kennaway break; 1366e8aafc91SKris Kennaway 1367c2d3a559SKris Kennaway case sSubsystem: 1368c2d3a559SKris Kennaway if (options->num_subsystems >= MAX_SUBSYSTEMS) { 1369c2d3a559SKris Kennaway fatal("%s line %d: too many subsystems defined.", 1370c2d3a559SKris Kennaway filename, linenum); 1371c2d3a559SKris Kennaway } 1372c2d3a559SKris Kennaway arg = strdelim(&cp); 1373c2d3a559SKris Kennaway if (!arg || *arg == '\0') 1374c2d3a559SKris Kennaway fatal("%s line %d: Missing subsystem name.", 1375c2d3a559SKris Kennaway filename, linenum); 1376333ee039SDag-Erling Smørgrav if (!*activep) { 1377333ee039SDag-Erling Smørgrav arg = strdelim(&cp); 1378333ee039SDag-Erling Smørgrav break; 1379333ee039SDag-Erling Smørgrav } 1380c2d3a559SKris Kennaway for (i = 0; i < options->num_subsystems; i++) 1381c2d3a559SKris Kennaway if (strcmp(arg, options->subsystem_name[i]) == 0) 1382c2d3a559SKris Kennaway fatal("%s line %d: Subsystem '%s' already defined.", 1383c2d3a559SKris Kennaway filename, linenum, arg); 1384c2d3a559SKris Kennaway options->subsystem_name[options->num_subsystems] = xstrdup(arg); 1385c2d3a559SKris Kennaway arg = strdelim(&cp); 1386c2d3a559SKris Kennaway if (!arg || *arg == '\0') 1387c2d3a559SKris Kennaway fatal("%s line %d: Missing subsystem command.", 1388c2d3a559SKris Kennaway filename, linenum); 1389c2d3a559SKris Kennaway options->subsystem_command[options->num_subsystems] = xstrdup(arg); 1390333ee039SDag-Erling Smørgrav 1391333ee039SDag-Erling Smørgrav /* Collect arguments (separate to executable) */ 1392333ee039SDag-Erling Smørgrav p = xstrdup(arg); 1393333ee039SDag-Erling Smørgrav len = strlen(p) + 1; 1394333ee039SDag-Erling Smørgrav while ((arg = strdelim(&cp)) != NULL && *arg != '\0') { 1395333ee039SDag-Erling Smørgrav len += 1 + strlen(arg); 1396333ee039SDag-Erling Smørgrav p = xrealloc(p, 1, len); 1397333ee039SDag-Erling Smørgrav strlcat(p, " ", len); 1398333ee039SDag-Erling Smørgrav strlcat(p, arg, len); 1399333ee039SDag-Erling Smørgrav } 1400333ee039SDag-Erling Smørgrav options->subsystem_args[options->num_subsystems] = p; 1401c2d3a559SKris Kennaway options->num_subsystems++; 1402c2d3a559SKris Kennaway break; 1403c2d3a559SKris Kennaway 1404c2d3a559SKris Kennaway case sMaxStartups: 1405c2d3a559SKris Kennaway arg = strdelim(&cp); 1406c2d3a559SKris Kennaway if (!arg || *arg == '\0') 1407c2d3a559SKris Kennaway fatal("%s line %d: Missing MaxStartups spec.", 1408c2d3a559SKris Kennaway filename, linenum); 1409af12a3e7SDag-Erling Smørgrav if ((n = sscanf(arg, "%d:%d:%d", 1410c2d3a559SKris Kennaway &options->max_startups_begin, 1411c2d3a559SKris Kennaway &options->max_startups_rate, 1412af12a3e7SDag-Erling Smørgrav &options->max_startups)) == 3) { 1413c2d3a559SKris Kennaway if (options->max_startups_begin > 1414c2d3a559SKris Kennaway options->max_startups || 1415c2d3a559SKris Kennaway options->max_startups_rate > 100 || 1416c2d3a559SKris Kennaway options->max_startups_rate < 1) 1417c2d3a559SKris Kennaway fatal("%s line %d: Illegal MaxStartups spec.", 1418c2d3a559SKris Kennaway filename, linenum); 1419af12a3e7SDag-Erling Smørgrav } else if (n != 1) 1420af12a3e7SDag-Erling Smørgrav fatal("%s line %d: Illegal MaxStartups spec.", 1421af12a3e7SDag-Erling Smørgrav filename, linenum); 1422af12a3e7SDag-Erling Smørgrav else 1423af12a3e7SDag-Erling Smørgrav options->max_startups = options->max_startups_begin; 1424933ca70fSBrian Feldman break; 1425933ca70fSBrian Feldman 142621e764dfSDag-Erling Smørgrav case sMaxAuthTries: 142721e764dfSDag-Erling Smørgrav intptr = &options->max_authtries; 142821e764dfSDag-Erling Smørgrav goto parse_int; 142921e764dfSDag-Erling Smørgrav 1430d4af9e69SDag-Erling Smørgrav case sMaxSessions: 1431d4af9e69SDag-Erling Smørgrav intptr = &options->max_sessions; 1432d4af9e69SDag-Erling Smørgrav goto parse_int; 1433d4af9e69SDag-Erling Smørgrav 1434ca3176e7SBrian Feldman case sBanner: 1435ca3176e7SBrian Feldman charptr = &options->banner; 1436ca3176e7SBrian Feldman goto parse_filename; 1437d4af9e69SDag-Erling Smørgrav 1438af12a3e7SDag-Erling Smørgrav /* 1439af12a3e7SDag-Erling Smørgrav * These options can contain %X options expanded at 1440af12a3e7SDag-Erling Smørgrav * connect time, so that you can specify paths like: 1441af12a3e7SDag-Erling Smørgrav * 1442af12a3e7SDag-Erling Smørgrav * AuthorizedKeysFile /etc/ssh_keys/%u 1443af12a3e7SDag-Erling Smørgrav */ 1444af12a3e7SDag-Erling Smørgrav case sAuthorizedKeysFile: 1445e146993eSDag-Erling Smørgrav if (*activep && options->num_authkeys_files == 0) { 1446e146993eSDag-Erling Smørgrav while ((arg = strdelim(&cp)) && *arg != '\0') { 1447e146993eSDag-Erling Smørgrav if (options->num_authkeys_files >= 1448e146993eSDag-Erling Smørgrav MAX_AUTHKEYS_FILES) 1449e146993eSDag-Erling Smørgrav fatal("%s line %d: " 1450e146993eSDag-Erling Smørgrav "too many authorized keys files.", 1451e146993eSDag-Erling Smørgrav filename, linenum); 1452e146993eSDag-Erling Smørgrav options->authorized_keys_files[ 1453e146993eSDag-Erling Smørgrav options->num_authkeys_files++] = 1454e146993eSDag-Erling Smørgrav tilde_expand_filename(arg, getuid()); 1455e146993eSDag-Erling Smørgrav } 1456e146993eSDag-Erling Smørgrav } 1457e146993eSDag-Erling Smørgrav return 0; 1458e146993eSDag-Erling Smørgrav 1459e2f6069cSDag-Erling Smørgrav case sAuthorizedPrincipalsFile: 1460e2f6069cSDag-Erling Smørgrav charptr = &options->authorized_principals_file; 14618ad9b54aSDag-Erling Smørgrav arg = strdelim(&cp); 14628ad9b54aSDag-Erling Smørgrav if (!arg || *arg == '\0') 14638ad9b54aSDag-Erling Smørgrav fatal("%s line %d: missing file name.", 14648ad9b54aSDag-Erling Smørgrav filename, linenum); 14658ad9b54aSDag-Erling Smørgrav if (*activep && *charptr == NULL) { 14668ad9b54aSDag-Erling Smørgrav *charptr = tilde_expand_filename(arg, getuid()); 14678ad9b54aSDag-Erling Smørgrav /* increase optional counter */ 14688ad9b54aSDag-Erling Smørgrav if (intptr != NULL) 14698ad9b54aSDag-Erling Smørgrav *intptr = *intptr + 1; 14708ad9b54aSDag-Erling Smørgrav } 14718ad9b54aSDag-Erling Smørgrav break; 1472af12a3e7SDag-Erling Smørgrav 1473ca3176e7SBrian Feldman case sClientAliveInterval: 1474ca3176e7SBrian Feldman intptr = &options->client_alive_interval; 1475af12a3e7SDag-Erling Smørgrav goto parse_time; 1476af12a3e7SDag-Erling Smørgrav 1477ca3176e7SBrian Feldman case sClientAliveCountMax: 1478ca3176e7SBrian Feldman intptr = &options->client_alive_count_max; 1479ca3176e7SBrian Feldman goto parse_int; 1480af12a3e7SDag-Erling Smørgrav 148121e764dfSDag-Erling Smørgrav case sAcceptEnv: 148221e764dfSDag-Erling Smørgrav while ((arg = strdelim(&cp)) && *arg != '\0') { 148321e764dfSDag-Erling Smørgrav if (strchr(arg, '=') != NULL) 148421e764dfSDag-Erling Smørgrav fatal("%s line %d: Invalid environment name.", 148521e764dfSDag-Erling Smørgrav filename, linenum); 148621e764dfSDag-Erling Smørgrav if (options->num_accept_env >= MAX_ACCEPT_ENV) 148721e764dfSDag-Erling Smørgrav fatal("%s line %d: too many allow env.", 148821e764dfSDag-Erling Smørgrav filename, linenum); 1489333ee039SDag-Erling Smørgrav if (!*activep) 1490462c32cbSDag-Erling Smørgrav continue; 149121e764dfSDag-Erling Smørgrav options->accept_env[options->num_accept_env++] = 149221e764dfSDag-Erling Smørgrav xstrdup(arg); 149321e764dfSDag-Erling Smørgrav } 149421e764dfSDag-Erling Smørgrav break; 149521e764dfSDag-Erling Smørgrav 1496b74df5b2SDag-Erling Smørgrav case sPermitTunnel: 1497b74df5b2SDag-Erling Smørgrav intptr = &options->permit_tun; 1498b74df5b2SDag-Erling Smørgrav arg = strdelim(&cp); 1499b74df5b2SDag-Erling Smørgrav if (!arg || *arg == '\0') 1500b74df5b2SDag-Erling Smørgrav fatal("%s line %d: Missing yes/point-to-point/" 1501b74df5b2SDag-Erling Smørgrav "ethernet/no argument.", filename, linenum); 1502d4af9e69SDag-Erling Smørgrav value = -1; 1503d4af9e69SDag-Erling Smørgrav for (i = 0; tunmode_desc[i].val != -1; i++) 1504d4af9e69SDag-Erling Smørgrav if (strcmp(tunmode_desc[i].text, arg) == 0) { 1505d4af9e69SDag-Erling Smørgrav value = tunmode_desc[i].val; 1506d4af9e69SDag-Erling Smørgrav break; 1507d4af9e69SDag-Erling Smørgrav } 1508d4af9e69SDag-Erling Smørgrav if (value == -1) 1509b74df5b2SDag-Erling Smørgrav fatal("%s line %d: Bad yes/point-to-point/ethernet/" 1510b74df5b2SDag-Erling Smørgrav "no argument: %s", filename, linenum, arg); 1511b74df5b2SDag-Erling Smørgrav if (*intptr == -1) 1512b74df5b2SDag-Erling Smørgrav *intptr = value; 1513b74df5b2SDag-Erling Smørgrav break; 1514b74df5b2SDag-Erling Smørgrav 1515333ee039SDag-Erling Smørgrav case sMatch: 1516333ee039SDag-Erling Smørgrav if (cmdline) 1517333ee039SDag-Erling Smørgrav fatal("Match directive not supported as a command-line " 1518333ee039SDag-Erling Smørgrav "option"); 1519462c32cbSDag-Erling Smørgrav value = match_cfg_line(&cp, linenum, connectinfo); 1520333ee039SDag-Erling Smørgrav if (value < 0) 1521333ee039SDag-Erling Smørgrav fatal("%s line %d: Bad Match condition", filename, 1522333ee039SDag-Erling Smørgrav linenum); 1523333ee039SDag-Erling Smørgrav *activep = value; 1524333ee039SDag-Erling Smørgrav break; 1525333ee039SDag-Erling Smørgrav 1526333ee039SDag-Erling Smørgrav case sPermitOpen: 1527333ee039SDag-Erling Smørgrav arg = strdelim(&cp); 1528333ee039SDag-Erling Smørgrav if (!arg || *arg == '\0') 1529333ee039SDag-Erling Smørgrav fatal("%s line %d: missing PermitOpen specification", 1530333ee039SDag-Erling Smørgrav filename, linenum); 1531d4af9e69SDag-Erling Smørgrav n = options->num_permitted_opens; /* modified later */ 1532333ee039SDag-Erling Smørgrav if (strcmp(arg, "any") == 0) { 1533d4af9e69SDag-Erling Smørgrav if (*activep && n == -1) { 1534333ee039SDag-Erling Smørgrav channel_clear_adm_permitted_opens(); 1535333ee039SDag-Erling Smørgrav options->num_permitted_opens = 0; 1536333ee039SDag-Erling Smørgrav } 1537333ee039SDag-Erling Smørgrav break; 1538333ee039SDag-Erling Smørgrav } 1539462c32cbSDag-Erling Smørgrav if (strcmp(arg, "none") == 0) { 1540462c32cbSDag-Erling Smørgrav if (*activep && n == -1) { 1541462c32cbSDag-Erling Smørgrav options->num_permitted_opens = 1; 1542462c32cbSDag-Erling Smørgrav channel_disable_adm_local_opens(); 1543462c32cbSDag-Erling Smørgrav } 1544462c32cbSDag-Erling Smørgrav break; 1545462c32cbSDag-Erling Smørgrav } 1546d4af9e69SDag-Erling Smørgrav if (*activep && n == -1) 1547d4af9e69SDag-Erling Smørgrav channel_clear_adm_permitted_opens(); 1548333ee039SDag-Erling Smørgrav for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) { 1549333ee039SDag-Erling Smørgrav p = hpdelim(&arg); 1550333ee039SDag-Erling Smørgrav if (p == NULL) 1551333ee039SDag-Erling Smørgrav fatal("%s line %d: missing host in PermitOpen", 1552333ee039SDag-Erling Smørgrav filename, linenum); 1553333ee039SDag-Erling Smørgrav p = cleanhostname(p); 1554462c32cbSDag-Erling Smørgrav if (arg == NULL || ((port = permitopen_port(arg)) < 0)) 1555333ee039SDag-Erling Smørgrav fatal("%s line %d: bad port number in " 1556333ee039SDag-Erling Smørgrav "PermitOpen", filename, linenum); 1557d4af9e69SDag-Erling Smørgrav if (*activep && n == -1) 1558333ee039SDag-Erling Smørgrav options->num_permitted_opens = 1559333ee039SDag-Erling Smørgrav channel_add_adm_permitted_opens(p, port); 1560333ee039SDag-Erling Smørgrav } 1561333ee039SDag-Erling Smørgrav break; 1562333ee039SDag-Erling Smørgrav 1563333ee039SDag-Erling Smørgrav case sForceCommand: 1564333ee039SDag-Erling Smørgrav if (cp == NULL) 1565333ee039SDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", filename, 1566333ee039SDag-Erling Smørgrav linenum); 1567333ee039SDag-Erling Smørgrav len = strspn(cp, WHITESPACE); 1568333ee039SDag-Erling Smørgrav if (*activep && options->adm_forced_command == NULL) 1569333ee039SDag-Erling Smørgrav options->adm_forced_command = xstrdup(cp + len); 1570333ee039SDag-Erling Smørgrav return 0; 1571333ee039SDag-Erling Smørgrav 1572d4af9e69SDag-Erling Smørgrav case sChrootDirectory: 1573d4af9e69SDag-Erling Smørgrav charptr = &options->chroot_directory; 1574d4af9e69SDag-Erling Smørgrav 1575d4af9e69SDag-Erling Smørgrav arg = strdelim(&cp); 1576d4af9e69SDag-Erling Smørgrav if (!arg || *arg == '\0') 1577d4af9e69SDag-Erling Smørgrav fatal("%s line %d: missing file name.", 1578d4af9e69SDag-Erling Smørgrav filename, linenum); 1579d4af9e69SDag-Erling Smørgrav if (*activep && *charptr == NULL) 1580d4af9e69SDag-Erling Smørgrav *charptr = xstrdup(arg); 1581d4af9e69SDag-Erling Smørgrav break; 1582d4af9e69SDag-Erling Smørgrav 1583b15c8340SDag-Erling Smørgrav case sTrustedUserCAKeys: 1584b15c8340SDag-Erling Smørgrav charptr = &options->trusted_user_ca_keys; 1585b15c8340SDag-Erling Smørgrav goto parse_filename; 1586b15c8340SDag-Erling Smørgrav 1587b15c8340SDag-Erling Smørgrav case sRevokedKeys: 1588b15c8340SDag-Erling Smørgrav charptr = &options->revoked_keys_file; 1589b15c8340SDag-Erling Smørgrav goto parse_filename; 1590b15c8340SDag-Erling Smørgrav 15914a421b63SDag-Erling Smørgrav case sIPQoS: 15924a421b63SDag-Erling Smørgrav arg = strdelim(&cp); 15934a421b63SDag-Erling Smørgrav if ((value = parse_ipqos(arg)) == -1) 15944a421b63SDag-Erling Smørgrav fatal("%s line %d: Bad IPQoS value: %s", 15954a421b63SDag-Erling Smørgrav filename, linenum, arg); 15964a421b63SDag-Erling Smørgrav arg = strdelim(&cp); 15974a421b63SDag-Erling Smørgrav if (arg == NULL) 15984a421b63SDag-Erling Smørgrav value2 = value; 15994a421b63SDag-Erling Smørgrav else if ((value2 = parse_ipqos(arg)) == -1) 16004a421b63SDag-Erling Smørgrav fatal("%s line %d: Bad IPQoS value: %s", 16014a421b63SDag-Erling Smørgrav filename, linenum, arg); 16024a421b63SDag-Erling Smørgrav if (*activep) { 16034a421b63SDag-Erling Smørgrav options->ip_qos_interactive = value; 16044a421b63SDag-Erling Smørgrav options->ip_qos_bulk = value2; 16054a421b63SDag-Erling Smørgrav } 16064a421b63SDag-Erling Smørgrav break; 16074a421b63SDag-Erling Smørgrav 1608db58a8e4SDag-Erling Smørgrav case sVersionAddendum: 1609462c32cbSDag-Erling Smørgrav if (cp == NULL) 1610462c32cbSDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", filename, 1611462c32cbSDag-Erling Smørgrav linenum); 1612462c32cbSDag-Erling Smørgrav len = strspn(cp, WHITESPACE); 1613462c32cbSDag-Erling Smørgrav if (*activep && options->version_addendum == NULL) { 1614462c32cbSDag-Erling Smørgrav if (strcasecmp(cp + len, "none") == 0) 1615462c32cbSDag-Erling Smørgrav options->version_addendum = xstrdup(""); 1616462c32cbSDag-Erling Smørgrav else if (strchr(cp + len, '\r') != NULL) 1617462c32cbSDag-Erling Smørgrav fatal("%.200s line %d: Invalid argument", 1618462c32cbSDag-Erling Smørgrav filename, linenum); 1619462c32cbSDag-Erling Smørgrav else 1620462c32cbSDag-Erling Smørgrav options->version_addendum = xstrdup(cp + len); 1621462c32cbSDag-Erling Smørgrav } 1622462c32cbSDag-Erling Smørgrav return 0; 1623db58a8e4SDag-Erling Smørgrav 16246888a9beSDag-Erling Smørgrav case sAuthorizedKeysCommand: 16256888a9beSDag-Erling Smørgrav len = strspn(cp, WHITESPACE); 16266888a9beSDag-Erling Smørgrav if (*activep && options->authorized_keys_command == NULL) { 16276888a9beSDag-Erling Smørgrav if (cp[len] != '/' && strcasecmp(cp + len, "none") != 0) 16286888a9beSDag-Erling Smørgrav fatal("%.200s line %d: AuthorizedKeysCommand " 16296888a9beSDag-Erling Smørgrav "must be an absolute path", 16306888a9beSDag-Erling Smørgrav filename, linenum); 16316888a9beSDag-Erling Smørgrav options->authorized_keys_command = xstrdup(cp + len); 16326888a9beSDag-Erling Smørgrav } 16336888a9beSDag-Erling Smørgrav return 0; 16346888a9beSDag-Erling Smørgrav 16356888a9beSDag-Erling Smørgrav case sAuthorizedKeysCommandUser: 16366888a9beSDag-Erling Smørgrav charptr = &options->authorized_keys_command_user; 16376888a9beSDag-Erling Smørgrav 16386888a9beSDag-Erling Smørgrav arg = strdelim(&cp); 16396888a9beSDag-Erling Smørgrav if (*activep && *charptr == NULL) 16406888a9beSDag-Erling Smørgrav *charptr = xstrdup(arg); 16416888a9beSDag-Erling Smørgrav break; 16426888a9beSDag-Erling Smørgrav 16436888a9beSDag-Erling Smørgrav case sAuthenticationMethods: 16446888a9beSDag-Erling Smørgrav if (*activep && options->num_auth_methods == 0) { 16456888a9beSDag-Erling Smørgrav while ((arg = strdelim(&cp)) && *arg != '\0') { 16466888a9beSDag-Erling Smørgrav if (options->num_auth_methods >= 16476888a9beSDag-Erling Smørgrav MAX_AUTH_METHODS) 16486888a9beSDag-Erling Smørgrav fatal("%s line %d: " 16496888a9beSDag-Erling Smørgrav "too many authentication methods.", 16506888a9beSDag-Erling Smørgrav filename, linenum); 16516888a9beSDag-Erling Smørgrav if (auth2_methods_valid(arg, 0) != 0) 16526888a9beSDag-Erling Smørgrav fatal("%s line %d: invalid " 16536888a9beSDag-Erling Smørgrav "authentication method list.", 16546888a9beSDag-Erling Smørgrav filename, linenum); 16556888a9beSDag-Erling Smørgrav options->auth_methods[ 16566888a9beSDag-Erling Smørgrav options->num_auth_methods++] = xstrdup(arg); 16576888a9beSDag-Erling Smørgrav } 16586888a9beSDag-Erling Smørgrav } 16596888a9beSDag-Erling Smørgrav return 0; 16606888a9beSDag-Erling Smørgrav 166189986192SBrooks Davis case sHPNDisabled: 166289986192SBrooks Davis intptr = &options->hpn_disabled; 166389986192SBrooks Davis goto parse_flag; 166489986192SBrooks Davis 166589986192SBrooks Davis case sHPNBufferSize: 166689986192SBrooks Davis intptr = &options->hpn_buffer_size; 166789986192SBrooks Davis goto parse_int; 166889986192SBrooks Davis 166989986192SBrooks Davis case sTcpRcvBufPoll: 167089986192SBrooks Davis intptr = &options->tcp_rcv_buf_poll; 167189986192SBrooks Davis goto parse_flag; 167289986192SBrooks Davis 167389986192SBrooks Davis #ifdef NONE_CIPHER_ENABLED 167489986192SBrooks Davis case sNoneEnabled: 167589986192SBrooks Davis intptr = &options->none_enabled; 167689986192SBrooks Davis goto parse_flag; 167789986192SBrooks Davis #endif 167889986192SBrooks Davis 1679af12a3e7SDag-Erling Smørgrav case sDeprecated: 1680cf2b5f3bSDag-Erling Smørgrav logit("%s line %d: Deprecated option %s", 1681cf2b5f3bSDag-Erling Smørgrav filename, linenum, arg); 1682cf2b5f3bSDag-Erling Smørgrav while (arg) 1683cf2b5f3bSDag-Erling Smørgrav arg = strdelim(&cp); 1684cf2b5f3bSDag-Erling Smørgrav break; 1685cf2b5f3bSDag-Erling Smørgrav 1686cf2b5f3bSDag-Erling Smørgrav case sUnsupported: 1687cf2b5f3bSDag-Erling Smørgrav logit("%s line %d: Unsupported option %s", 1688af12a3e7SDag-Erling Smørgrav filename, linenum, arg); 1689af12a3e7SDag-Erling Smørgrav while (arg) 1690af12a3e7SDag-Erling Smørgrav arg = strdelim(&cp); 1691af12a3e7SDag-Erling Smørgrav break; 1692af12a3e7SDag-Erling Smørgrav 169342f71286SMark Murray default: 1694af12a3e7SDag-Erling Smørgrav fatal("%s line %d: Missing handler for opcode %s (%d)", 1695c2d3a559SKris Kennaway filename, linenum, arg, opcode); 1696511b41d2SMark Murray } 1697ca3176e7SBrian Feldman if ((arg = strdelim(&cp)) != NULL && *arg != '\0') 1698ca3176e7SBrian Feldman fatal("%s line %d: garbage at end of line; \"%.200s\".", 1699c2d3a559SKris Kennaway filename, linenum, arg); 1700af12a3e7SDag-Erling Smørgrav return 0; 1701af12a3e7SDag-Erling Smørgrav } 1702af12a3e7SDag-Erling Smørgrav 1703af12a3e7SDag-Erling Smørgrav /* Reads the server configuration file. */ 1704af12a3e7SDag-Erling Smørgrav 1705af12a3e7SDag-Erling Smørgrav void 170621e764dfSDag-Erling Smørgrav load_server_config(const char *filename, Buffer *conf) 1707af12a3e7SDag-Erling Smørgrav { 1708462c32cbSDag-Erling Smørgrav char line[4096], *cp; 1709a82e551fSDag-Erling Smørgrav FILE *f; 1710462c32cbSDag-Erling Smørgrav int lineno = 0; 1711af12a3e7SDag-Erling Smørgrav 171221e764dfSDag-Erling Smørgrav debug2("%s: filename %s", __func__, filename); 171321e764dfSDag-Erling Smørgrav if ((f = fopen(filename, "r")) == NULL) { 1714af12a3e7SDag-Erling Smørgrav perror(filename); 1715af12a3e7SDag-Erling Smørgrav exit(1); 1716af12a3e7SDag-Erling Smørgrav } 171721e764dfSDag-Erling Smørgrav buffer_clear(conf); 1718af12a3e7SDag-Erling Smørgrav while (fgets(line, sizeof(line), f)) { 1719462c32cbSDag-Erling Smørgrav lineno++; 1720462c32cbSDag-Erling Smørgrav if (strlen(line) == sizeof(line) - 1) 1721462c32cbSDag-Erling Smørgrav fatal("%s line %d too long", filename, lineno); 172221e764dfSDag-Erling Smørgrav /* 172321e764dfSDag-Erling Smørgrav * Trim out comments and strip whitespace 172421e764dfSDag-Erling Smørgrav * NB - preserve newlines, they are needed to reproduce 172521e764dfSDag-Erling Smørgrav * line numbers later for error messages 172621e764dfSDag-Erling Smørgrav */ 172721e764dfSDag-Erling Smørgrav if ((cp = strchr(line, '#')) != NULL) 172821e764dfSDag-Erling Smørgrav memcpy(cp, "\n", 2); 172921e764dfSDag-Erling Smørgrav cp = line + strspn(line, " \t\r"); 173021e764dfSDag-Erling Smørgrav 173121e764dfSDag-Erling Smørgrav buffer_append(conf, cp, strlen(cp)); 173221e764dfSDag-Erling Smørgrav } 173321e764dfSDag-Erling Smørgrav buffer_append(conf, "\0", 1); 173421e764dfSDag-Erling Smørgrav fclose(f); 173521e764dfSDag-Erling Smørgrav debug2("%s: done config len = %d", __func__, buffer_len(conf)); 173621e764dfSDag-Erling Smørgrav } 173721e764dfSDag-Erling Smørgrav 173821e764dfSDag-Erling Smørgrav void 1739462c32cbSDag-Erling Smørgrav parse_server_match_config(ServerOptions *options, 1740462c32cbSDag-Erling Smørgrav struct connection_info *connectinfo) 174121e764dfSDag-Erling Smørgrav { 1742333ee039SDag-Erling Smørgrav ServerOptions mo; 1743333ee039SDag-Erling Smørgrav 1744333ee039SDag-Erling Smørgrav initialize_server_options(&mo); 1745462c32cbSDag-Erling Smørgrav parse_server_config(&mo, "reprocess config", &cfg, connectinfo); 1746d4af9e69SDag-Erling Smørgrav copy_set_server_options(options, &mo, 0); 1747333ee039SDag-Erling Smørgrav } 1748333ee039SDag-Erling Smørgrav 1749462c32cbSDag-Erling Smørgrav int parse_server_match_testspec(struct connection_info *ci, char *spec) 1750462c32cbSDag-Erling Smørgrav { 1751462c32cbSDag-Erling Smørgrav char *p; 1752462c32cbSDag-Erling Smørgrav 1753462c32cbSDag-Erling Smørgrav while ((p = strsep(&spec, ",")) && *p != '\0') { 1754462c32cbSDag-Erling Smørgrav if (strncmp(p, "addr=", 5) == 0) { 1755462c32cbSDag-Erling Smørgrav ci->address = xstrdup(p + 5); 1756462c32cbSDag-Erling Smørgrav } else if (strncmp(p, "host=", 5) == 0) { 1757462c32cbSDag-Erling Smørgrav ci->host = xstrdup(p + 5); 1758462c32cbSDag-Erling Smørgrav } else if (strncmp(p, "user=", 5) == 0) { 1759462c32cbSDag-Erling Smørgrav ci->user = xstrdup(p + 5); 1760462c32cbSDag-Erling Smørgrav } else if (strncmp(p, "laddr=", 6) == 0) { 1761462c32cbSDag-Erling Smørgrav ci->laddress = xstrdup(p + 6); 1762462c32cbSDag-Erling Smørgrav } else if (strncmp(p, "lport=", 6) == 0) { 1763462c32cbSDag-Erling Smørgrav ci->lport = a2port(p + 6); 1764462c32cbSDag-Erling Smørgrav if (ci->lport == -1) { 1765462c32cbSDag-Erling Smørgrav fprintf(stderr, "Invalid port '%s' in test mode" 1766462c32cbSDag-Erling Smørgrav " specification %s\n", p+6, p); 1767462c32cbSDag-Erling Smørgrav return -1; 1768462c32cbSDag-Erling Smørgrav } 1769462c32cbSDag-Erling Smørgrav } else { 1770462c32cbSDag-Erling Smørgrav fprintf(stderr, "Invalid test mode specification %s\n", 1771462c32cbSDag-Erling Smørgrav p); 1772462c32cbSDag-Erling Smørgrav return -1; 1773462c32cbSDag-Erling Smørgrav } 1774462c32cbSDag-Erling Smørgrav } 1775462c32cbSDag-Erling Smørgrav return 0; 1776462c32cbSDag-Erling Smørgrav } 1777462c32cbSDag-Erling Smørgrav 1778462c32cbSDag-Erling Smørgrav /* 1779462c32cbSDag-Erling Smørgrav * returns 1 for a complete spec, 0 for partial spec and -1 for an 1780462c32cbSDag-Erling Smørgrav * empty spec. 1781462c32cbSDag-Erling Smørgrav */ 1782462c32cbSDag-Erling Smørgrav int server_match_spec_complete(struct connection_info *ci) 1783462c32cbSDag-Erling Smørgrav { 1784462c32cbSDag-Erling Smørgrav if (ci->user && ci->host && ci->address) 1785462c32cbSDag-Erling Smørgrav return 1; /* complete */ 1786462c32cbSDag-Erling Smørgrav if (!ci->user && !ci->host && !ci->address) 1787462c32cbSDag-Erling Smørgrav return -1; /* empty */ 1788462c32cbSDag-Erling Smørgrav return 0; /* partial */ 1789462c32cbSDag-Erling Smørgrav } 1790462c32cbSDag-Erling Smørgrav 1791d4af9e69SDag-Erling Smørgrav /* Helper macros */ 1792d4af9e69SDag-Erling Smørgrav #define M_CP_INTOPT(n) do {\ 1793d4af9e69SDag-Erling Smørgrav if (src->n != -1) \ 1794d4af9e69SDag-Erling Smørgrav dst->n = src->n; \ 1795d4af9e69SDag-Erling Smørgrav } while (0) 1796d4af9e69SDag-Erling Smørgrav #define M_CP_STROPT(n) do {\ 1797d4af9e69SDag-Erling Smørgrav if (src->n != NULL) { \ 1798*e4a9863fSDag-Erling Smørgrav free(dst->n); \ 1799d4af9e69SDag-Erling Smørgrav dst->n = src->n; \ 1800d4af9e69SDag-Erling Smørgrav } \ 1801d4af9e69SDag-Erling Smørgrav } while(0) 1802e146993eSDag-Erling Smørgrav #define M_CP_STRARRAYOPT(n, num_n) do {\ 1803e146993eSDag-Erling Smørgrav if (src->num_n != 0) { \ 1804e146993eSDag-Erling Smørgrav for (dst->num_n = 0; dst->num_n < src->num_n; dst->num_n++) \ 1805e146993eSDag-Erling Smørgrav dst->n[dst->num_n] = xstrdup(src->n[dst->num_n]); \ 1806e146993eSDag-Erling Smørgrav } \ 1807e146993eSDag-Erling Smørgrav } while(0) 1808d4af9e69SDag-Erling Smørgrav 1809d4af9e69SDag-Erling Smørgrav /* 1810d4af9e69SDag-Erling Smørgrav * Copy any supported values that are set. 1811d4af9e69SDag-Erling Smørgrav * 18127aee6ffeSDag-Erling Smørgrav * If the preauth flag is set, we do not bother copying the string or 1813d4af9e69SDag-Erling Smørgrav * array values that are not used pre-authentication, because any that we 1814d4af9e69SDag-Erling Smørgrav * do use must be explictly sent in mm_getpwnamallow(). 1815d4af9e69SDag-Erling Smørgrav */ 1816333ee039SDag-Erling Smørgrav void 1817d4af9e69SDag-Erling Smørgrav copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) 1818333ee039SDag-Erling Smørgrav { 1819d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(password_authentication); 1820d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(gss_authentication); 1821d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(rsa_authentication); 1822d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(pubkey_authentication); 1823d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(kerberos_authentication); 1824d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(hostbased_authentication); 1825e2f6069cSDag-Erling Smørgrav M_CP_INTOPT(hostbased_uses_name_from_packet_only); 1826d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(kbd_interactive_authentication); 1827cce7d346SDag-Erling Smørgrav M_CP_INTOPT(zero_knowledge_password_authentication); 18286888a9beSDag-Erling Smørgrav M_CP_STROPT(authorized_keys_command); 18296888a9beSDag-Erling Smørgrav M_CP_STROPT(authorized_keys_command_user); 1830d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(permit_root_login); 1831cce7d346SDag-Erling Smørgrav M_CP_INTOPT(permit_empty_passwd); 1832d4af9e69SDag-Erling Smørgrav 1833d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(allow_tcp_forwarding); 1834d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(allow_agent_forwarding); 1835e2f6069cSDag-Erling Smørgrav M_CP_INTOPT(permit_tun); 1836d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(gateway_ports); 1837d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(x11_display_offset); 1838d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(x11_forwarding); 1839d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(x11_use_localhost); 1840d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(max_sessions); 1841d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(max_authtries); 18424a421b63SDag-Erling Smørgrav M_CP_INTOPT(ip_qos_interactive); 18434a421b63SDag-Erling Smørgrav M_CP_INTOPT(ip_qos_bulk); 1844*e4a9863fSDag-Erling Smørgrav M_CP_INTOPT(rekey_limit); 1845*e4a9863fSDag-Erling Smørgrav M_CP_INTOPT(rekey_interval); 1846d4af9e69SDag-Erling Smørgrav 1847e146993eSDag-Erling Smørgrav /* See comment in servconf.h */ 1848e146993eSDag-Erling Smørgrav COPY_MATCH_STRING_OPTS(); 1849e146993eSDag-Erling Smørgrav 1850e146993eSDag-Erling Smørgrav /* 1851e146993eSDag-Erling Smørgrav * The only things that should be below this point are string options 1852e146993eSDag-Erling Smørgrav * which are only used after authentication. 1853e146993eSDag-Erling Smørgrav */ 1854d4af9e69SDag-Erling Smørgrav if (preauth) 1855d4af9e69SDag-Erling Smørgrav return; 1856e146993eSDag-Erling Smørgrav 1857d4af9e69SDag-Erling Smørgrav M_CP_STROPT(adm_forced_command); 1858d4af9e69SDag-Erling Smørgrav M_CP_STROPT(chroot_directory); 1859333ee039SDag-Erling Smørgrav } 1860d4af9e69SDag-Erling Smørgrav 1861d4af9e69SDag-Erling Smørgrav #undef M_CP_INTOPT 1862d4af9e69SDag-Erling Smørgrav #undef M_CP_STROPT 1863e146993eSDag-Erling Smørgrav #undef M_CP_STRARRAYOPT 1864333ee039SDag-Erling Smørgrav 1865333ee039SDag-Erling Smørgrav void 1866333ee039SDag-Erling Smørgrav parse_server_config(ServerOptions *options, const char *filename, Buffer *conf, 1867462c32cbSDag-Erling Smørgrav struct connection_info *connectinfo) 1868333ee039SDag-Erling Smørgrav { 1869333ee039SDag-Erling Smørgrav int active, linenum, bad_options = 0; 187021e764dfSDag-Erling Smørgrav char *cp, *obuf, *cbuf; 187121e764dfSDag-Erling Smørgrav 187221e764dfSDag-Erling Smørgrav debug2("%s: config %s len %d", __func__, filename, buffer_len(conf)); 187321e764dfSDag-Erling Smørgrav 187421e764dfSDag-Erling Smørgrav obuf = cbuf = xstrdup(buffer_ptr(conf)); 1875462c32cbSDag-Erling Smørgrav active = connectinfo ? 0 : 1; 187621e764dfSDag-Erling Smørgrav linenum = 1; 187721e764dfSDag-Erling Smørgrav while ((cp = strsep(&cbuf, "\n")) != NULL) { 187821e764dfSDag-Erling Smørgrav if (process_server_config_line(options, cp, filename, 1879462c32cbSDag-Erling Smørgrav linenum++, &active, connectinfo) != 0) 1880af12a3e7SDag-Erling Smørgrav bad_options++; 1881511b41d2SMark Murray } 1882*e4a9863fSDag-Erling Smørgrav free(obuf); 1883ca3176e7SBrian Feldman if (bad_options > 0) 1884af12a3e7SDag-Erling Smørgrav fatal("%s: terminating, %d bad configuration options", 1885511b41d2SMark Murray filename, bad_options); 1886511b41d2SMark Murray } 1887d4af9e69SDag-Erling Smørgrav 1888d4af9e69SDag-Erling Smørgrav static const char * 1889e146993eSDag-Erling Smørgrav fmt_multistate_int(int val, const struct multistate *m) 1890d4af9e69SDag-Erling Smørgrav { 1891e146993eSDag-Erling Smørgrav u_int i; 1892e146993eSDag-Erling Smørgrav 1893e146993eSDag-Erling Smørgrav for (i = 0; m[i].key != NULL; i++) { 1894e146993eSDag-Erling Smørgrav if (m[i].value == val) 1895e146993eSDag-Erling Smørgrav return m[i].key; 1896e146993eSDag-Erling Smørgrav } 1897d4af9e69SDag-Erling Smørgrav return "UNKNOWN"; 1898d4af9e69SDag-Erling Smørgrav } 1899e146993eSDag-Erling Smørgrav 1900e146993eSDag-Erling Smørgrav static const char * 1901e146993eSDag-Erling Smørgrav fmt_intarg(ServerOpCodes code, int val) 1902e146993eSDag-Erling Smørgrav { 1903e146993eSDag-Erling Smørgrav if (val == -1) 1904e146993eSDag-Erling Smørgrav return "unset"; 1905e146993eSDag-Erling Smørgrav switch (code) { 1906e146993eSDag-Erling Smørgrav case sAddressFamily: 1907e146993eSDag-Erling Smørgrav return fmt_multistate_int(val, multistate_addressfamily); 1908e146993eSDag-Erling Smørgrav case sPermitRootLogin: 1909e146993eSDag-Erling Smørgrav return fmt_multistate_int(val, multistate_permitrootlogin); 1910e146993eSDag-Erling Smørgrav case sGatewayPorts: 1911e146993eSDag-Erling Smørgrav return fmt_multistate_int(val, multistate_gatewayports); 1912e146993eSDag-Erling Smørgrav case sCompression: 1913e146993eSDag-Erling Smørgrav return fmt_multistate_int(val, multistate_compression); 1914e146993eSDag-Erling Smørgrav case sUsePrivilegeSeparation: 1915e146993eSDag-Erling Smørgrav return fmt_multistate_int(val, multistate_privsep); 19166888a9beSDag-Erling Smørgrav case sAllowTcpForwarding: 19176888a9beSDag-Erling Smørgrav return fmt_multistate_int(val, multistate_tcpfwd); 1918e146993eSDag-Erling Smørgrav case sProtocol: 1919d4af9e69SDag-Erling Smørgrav switch (val) { 1920d4af9e69SDag-Erling Smørgrav case SSH_PROTO_1: 1921d4af9e69SDag-Erling Smørgrav return "1"; 1922d4af9e69SDag-Erling Smørgrav case SSH_PROTO_2: 1923d4af9e69SDag-Erling Smørgrav return "2"; 1924d4af9e69SDag-Erling Smørgrav case (SSH_PROTO_1|SSH_PROTO_2): 1925d4af9e69SDag-Erling Smørgrav return "2,1"; 1926d4af9e69SDag-Erling Smørgrav default: 1927d4af9e69SDag-Erling Smørgrav return "UNKNOWN"; 1928d4af9e69SDag-Erling Smørgrav } 1929e146993eSDag-Erling Smørgrav default: 1930d4af9e69SDag-Erling Smørgrav switch (val) { 1931d4af9e69SDag-Erling Smørgrav case 0: 1932d4af9e69SDag-Erling Smørgrav return "no"; 1933d4af9e69SDag-Erling Smørgrav case 1: 1934d4af9e69SDag-Erling Smørgrav return "yes"; 1935e146993eSDag-Erling Smørgrav default: 1936d4af9e69SDag-Erling Smørgrav return "UNKNOWN"; 1937d4af9e69SDag-Erling Smørgrav } 1938e146993eSDag-Erling Smørgrav } 1939e146993eSDag-Erling Smørgrav } 1940d4af9e69SDag-Erling Smørgrav 1941d4af9e69SDag-Erling Smørgrav static const char * 1942d4af9e69SDag-Erling Smørgrav lookup_opcode_name(ServerOpCodes code) 1943d4af9e69SDag-Erling Smørgrav { 1944d4af9e69SDag-Erling Smørgrav u_int i; 1945d4af9e69SDag-Erling Smørgrav 1946d4af9e69SDag-Erling Smørgrav for (i = 0; keywords[i].name != NULL; i++) 1947d4af9e69SDag-Erling Smørgrav if (keywords[i].opcode == code) 1948d4af9e69SDag-Erling Smørgrav return(keywords[i].name); 1949d4af9e69SDag-Erling Smørgrav return "UNKNOWN"; 1950d4af9e69SDag-Erling Smørgrav } 1951d4af9e69SDag-Erling Smørgrav 1952d4af9e69SDag-Erling Smørgrav static void 1953d4af9e69SDag-Erling Smørgrav dump_cfg_int(ServerOpCodes code, int val) 1954d4af9e69SDag-Erling Smørgrav { 1955d4af9e69SDag-Erling Smørgrav printf("%s %d\n", lookup_opcode_name(code), val); 1956d4af9e69SDag-Erling Smørgrav } 1957d4af9e69SDag-Erling Smørgrav 1958d4af9e69SDag-Erling Smørgrav static void 1959d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(ServerOpCodes code, int val) 1960d4af9e69SDag-Erling Smørgrav { 1961d4af9e69SDag-Erling Smørgrav printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val)); 1962d4af9e69SDag-Erling Smørgrav } 1963d4af9e69SDag-Erling Smørgrav 1964d4af9e69SDag-Erling Smørgrav static void 1965d4af9e69SDag-Erling Smørgrav dump_cfg_string(ServerOpCodes code, const char *val) 1966d4af9e69SDag-Erling Smørgrav { 1967d4af9e69SDag-Erling Smørgrav if (val == NULL) 1968d4af9e69SDag-Erling Smørgrav return; 1969d4af9e69SDag-Erling Smørgrav printf("%s %s\n", lookup_opcode_name(code), val); 1970d4af9e69SDag-Erling Smørgrav } 1971d4af9e69SDag-Erling Smørgrav 1972d4af9e69SDag-Erling Smørgrav static void 1973d4af9e69SDag-Erling Smørgrav dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals) 1974d4af9e69SDag-Erling Smørgrav { 1975d4af9e69SDag-Erling Smørgrav u_int i; 1976d4af9e69SDag-Erling Smørgrav 1977d4af9e69SDag-Erling Smørgrav for (i = 0; i < count; i++) 1978d4af9e69SDag-Erling Smørgrav printf("%s %s\n", lookup_opcode_name(code), vals[i]); 1979d4af9e69SDag-Erling Smørgrav } 1980d4af9e69SDag-Erling Smørgrav 1981e146993eSDag-Erling Smørgrav static void 1982e146993eSDag-Erling Smørgrav dump_cfg_strarray_oneline(ServerOpCodes code, u_int count, char **vals) 1983e146993eSDag-Erling Smørgrav { 1984e146993eSDag-Erling Smørgrav u_int i; 1985e146993eSDag-Erling Smørgrav 1986e146993eSDag-Erling Smørgrav printf("%s", lookup_opcode_name(code)); 1987e146993eSDag-Erling Smørgrav for (i = 0; i < count; i++) 1988e146993eSDag-Erling Smørgrav printf(" %s", vals[i]); 1989e146993eSDag-Erling Smørgrav printf("\n"); 1990e146993eSDag-Erling Smørgrav } 1991e146993eSDag-Erling Smørgrav 1992d4af9e69SDag-Erling Smørgrav void 1993d4af9e69SDag-Erling Smørgrav dump_config(ServerOptions *o) 1994d4af9e69SDag-Erling Smørgrav { 1995d4af9e69SDag-Erling Smørgrav u_int i; 1996d4af9e69SDag-Erling Smørgrav int ret; 1997d4af9e69SDag-Erling Smørgrav struct addrinfo *ai; 1998d4af9e69SDag-Erling Smørgrav char addr[NI_MAXHOST], port[NI_MAXSERV], *s = NULL; 1999d4af9e69SDag-Erling Smørgrav 2000d4af9e69SDag-Erling Smørgrav /* these are usually at the top of the config */ 2001d4af9e69SDag-Erling Smørgrav for (i = 0; i < o->num_ports; i++) 2002d4af9e69SDag-Erling Smørgrav printf("port %d\n", o->ports[i]); 2003d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sProtocol, o->protocol); 2004d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sAddressFamily, o->address_family); 2005d4af9e69SDag-Erling Smørgrav 2006d4af9e69SDag-Erling Smørgrav /* ListenAddress must be after Port */ 2007d4af9e69SDag-Erling Smørgrav for (ai = o->listen_addrs; ai; ai = ai->ai_next) { 2008d4af9e69SDag-Erling Smørgrav if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr, 2009d4af9e69SDag-Erling Smørgrav sizeof(addr), port, sizeof(port), 2010d4af9e69SDag-Erling Smørgrav NI_NUMERICHOST|NI_NUMERICSERV)) != 0) { 2011d4af9e69SDag-Erling Smørgrav error("getnameinfo failed: %.100s", 2012d4af9e69SDag-Erling Smørgrav (ret != EAI_SYSTEM) ? gai_strerror(ret) : 2013d4af9e69SDag-Erling Smørgrav strerror(errno)); 2014d4af9e69SDag-Erling Smørgrav } else { 2015d4af9e69SDag-Erling Smørgrav if (ai->ai_family == AF_INET6) 2016d4af9e69SDag-Erling Smørgrav printf("listenaddress [%s]:%s\n", addr, port); 2017d4af9e69SDag-Erling Smørgrav else 2018d4af9e69SDag-Erling Smørgrav printf("listenaddress %s:%s\n", addr, port); 2019d4af9e69SDag-Erling Smørgrav } 2020d4af9e69SDag-Erling Smørgrav } 2021d4af9e69SDag-Erling Smørgrav 2022d4af9e69SDag-Erling Smørgrav /* integer arguments */ 2023cce7d346SDag-Erling Smørgrav #ifdef USE_PAM 2024cce7d346SDag-Erling Smørgrav dump_cfg_int(sUsePAM, o->use_pam); 2025cce7d346SDag-Erling Smørgrav #endif 2026d4af9e69SDag-Erling Smørgrav dump_cfg_int(sServerKeyBits, o->server_key_bits); 2027d4af9e69SDag-Erling Smørgrav dump_cfg_int(sLoginGraceTime, o->login_grace_time); 2028d4af9e69SDag-Erling Smørgrav dump_cfg_int(sKeyRegenerationTime, o->key_regeneration_time); 2029d4af9e69SDag-Erling Smørgrav dump_cfg_int(sX11DisplayOffset, o->x11_display_offset); 2030d4af9e69SDag-Erling Smørgrav dump_cfg_int(sMaxAuthTries, o->max_authtries); 2031cce7d346SDag-Erling Smørgrav dump_cfg_int(sMaxSessions, o->max_sessions); 2032d4af9e69SDag-Erling Smørgrav dump_cfg_int(sClientAliveInterval, o->client_alive_interval); 2033d4af9e69SDag-Erling Smørgrav dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max); 2034d4af9e69SDag-Erling Smørgrav 2035d4af9e69SDag-Erling Smørgrav /* formatted integer arguments */ 2036d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login); 2037d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts); 2038d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts); 2039d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sRhostsRSAAuthentication, o->rhosts_rsa_authentication); 2040d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication); 2041d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly, 2042d4af9e69SDag-Erling Smørgrav o->hostbased_uses_name_from_packet_only); 2043d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sRSAAuthentication, o->rsa_authentication); 2044d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication); 2045cce7d346SDag-Erling Smørgrav #ifdef KRB5 2046d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication); 2047d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd); 2048d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup); 2049cce7d346SDag-Erling Smørgrav # ifdef USE_AFS 2050d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); 2051cce7d346SDag-Erling Smørgrav # endif 2052cce7d346SDag-Erling Smørgrav #endif 2053cce7d346SDag-Erling Smørgrav #ifdef GSSAPI 2054d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); 2055d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); 2056cce7d346SDag-Erling Smørgrav #endif 2057cce7d346SDag-Erling Smørgrav #ifdef JPAKE 2058cce7d346SDag-Erling Smørgrav dump_cfg_fmtint(sZeroKnowledgePasswordAuthentication, 2059cce7d346SDag-Erling Smørgrav o->zero_knowledge_password_authentication); 2060cce7d346SDag-Erling Smørgrav #endif 2061d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); 2062d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sKbdInteractiveAuthentication, 2063d4af9e69SDag-Erling Smørgrav o->kbd_interactive_authentication); 2064d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sChallengeResponseAuthentication, 2065d4af9e69SDag-Erling Smørgrav o->challenge_response_authentication); 2066d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sPrintMotd, o->print_motd); 2067d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sPrintLastLog, o->print_lastlog); 2068d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding); 2069d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost); 2070d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sStrictModes, o->strict_modes); 2071d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive); 2072d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd); 2073d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env); 2074d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sUseLogin, o->use_login); 2075d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sCompression, o->compression); 2076d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sGatewayPorts, o->gateway_ports); 2077d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sUseDNS, o->use_dns); 2078d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); 2079d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); 2080d4af9e69SDag-Erling Smørgrav 2081d4af9e69SDag-Erling Smørgrav /* string arguments */ 2082d4af9e69SDag-Erling Smørgrav dump_cfg_string(sPidFile, o->pid_file); 2083d4af9e69SDag-Erling Smørgrav dump_cfg_string(sXAuthLocation, o->xauth_location); 2084d4af9e69SDag-Erling Smørgrav dump_cfg_string(sCiphers, o->ciphers); 2085d4af9e69SDag-Erling Smørgrav dump_cfg_string(sMacs, o->macs); 2086d4af9e69SDag-Erling Smørgrav dump_cfg_string(sBanner, o->banner); 2087d4af9e69SDag-Erling Smørgrav dump_cfg_string(sForceCommand, o->adm_forced_command); 2088b15c8340SDag-Erling Smørgrav dump_cfg_string(sChrootDirectory, o->chroot_directory); 2089b15c8340SDag-Erling Smørgrav dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys); 2090b15c8340SDag-Erling Smørgrav dump_cfg_string(sRevokedKeys, o->revoked_keys_file); 2091e2f6069cSDag-Erling Smørgrav dump_cfg_string(sAuthorizedPrincipalsFile, 2092e2f6069cSDag-Erling Smørgrav o->authorized_principals_file); 2093462c32cbSDag-Erling Smørgrav dump_cfg_string(sVersionAddendum, o->version_addendum); 20946888a9beSDag-Erling Smørgrav dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command); 20956888a9beSDag-Erling Smørgrav dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user); 2096*e4a9863fSDag-Erling Smørgrav dump_cfg_string(sHostKeyAgent, o->host_key_agent); 2097d4af9e69SDag-Erling Smørgrav 2098d4af9e69SDag-Erling Smørgrav /* string arguments requiring a lookup */ 2099d4af9e69SDag-Erling Smørgrav dump_cfg_string(sLogLevel, log_level_name(o->log_level)); 2100d4af9e69SDag-Erling Smørgrav dump_cfg_string(sLogFacility, log_facility_name(o->log_facility)); 2101d4af9e69SDag-Erling Smørgrav 2102d4af9e69SDag-Erling Smørgrav /* string array arguments */ 2103e146993eSDag-Erling Smørgrav dump_cfg_strarray_oneline(sAuthorizedKeysFile, o->num_authkeys_files, 2104e146993eSDag-Erling Smørgrav o->authorized_keys_files); 2105d4af9e69SDag-Erling Smørgrav dump_cfg_strarray(sHostKeyFile, o->num_host_key_files, 2106d4af9e69SDag-Erling Smørgrav o->host_key_files); 2107b15c8340SDag-Erling Smørgrav dump_cfg_strarray(sHostKeyFile, o->num_host_cert_files, 2108b15c8340SDag-Erling Smørgrav o->host_cert_files); 2109d4af9e69SDag-Erling Smørgrav dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users); 2110d4af9e69SDag-Erling Smørgrav dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users); 2111d4af9e69SDag-Erling Smørgrav dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups); 2112d4af9e69SDag-Erling Smørgrav dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups); 2113d4af9e69SDag-Erling Smørgrav dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env); 21146888a9beSDag-Erling Smørgrav dump_cfg_strarray_oneline(sAuthenticationMethods, 21156888a9beSDag-Erling Smørgrav o->num_auth_methods, o->auth_methods); 2116d4af9e69SDag-Erling Smørgrav 2117d4af9e69SDag-Erling Smørgrav /* other arguments */ 2118d4af9e69SDag-Erling Smørgrav for (i = 0; i < o->num_subsystems; i++) 2119d4af9e69SDag-Erling Smørgrav printf("subsystem %s %s\n", o->subsystem_name[i], 2120d4af9e69SDag-Erling Smørgrav o->subsystem_args[i]); 2121d4af9e69SDag-Erling Smørgrav 2122d4af9e69SDag-Erling Smørgrav printf("maxstartups %d:%d:%d\n", o->max_startups_begin, 2123d4af9e69SDag-Erling Smørgrav o->max_startups_rate, o->max_startups); 2124d4af9e69SDag-Erling Smørgrav 2125d4af9e69SDag-Erling Smørgrav for (i = 0; tunmode_desc[i].val != -1; i++) 2126d4af9e69SDag-Erling Smørgrav if (tunmode_desc[i].val == o->permit_tun) { 2127d4af9e69SDag-Erling Smørgrav s = tunmode_desc[i].text; 2128d4af9e69SDag-Erling Smørgrav break; 2129d4af9e69SDag-Erling Smørgrav } 2130d4af9e69SDag-Erling Smørgrav dump_cfg_string(sPermitTunnel, s); 2131d4af9e69SDag-Erling Smørgrav 2132e146993eSDag-Erling Smørgrav printf("ipqos %s ", iptos2str(o->ip_qos_interactive)); 2133e146993eSDag-Erling Smørgrav printf("%s\n", iptos2str(o->ip_qos_bulk)); 21344a421b63SDag-Erling Smørgrav 2135*e4a9863fSDag-Erling Smørgrav printf("rekeylimit %lld %d\n", (long long)o->rekey_limit, 2136*e4a9863fSDag-Erling Smørgrav o->rekey_interval); 2137*e4a9863fSDag-Erling Smørgrav 2138d4af9e69SDag-Erling Smørgrav channel_print_adm_permitted_opens(); 2139d4af9e69SDag-Erling Smørgrav } 2140