1eccfee6eSDag-Erling Smørgrav 2*076ad2f8SDag-Erling Smørgrav /* $OpenBSD: servconf.c,v 1.292 2016/06/23 05:17:51 djm Exp $ */ 3511b41d2SMark Murray /* 4511b41d2SMark Murray * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 5511b41d2SMark Murray * All rights reserved 6511b41d2SMark Murray * 7c2d3a559SKris Kennaway * As far as I am concerned, the code I have written for this software 8c2d3a559SKris Kennaway * can be used freely for any purpose. Any derived versions of this 9c2d3a559SKris Kennaway * software must be clearly marked as such, and if the derived work is 10c2d3a559SKris Kennaway * incompatible with the protocol description in the RFC file, it must be 11c2d3a559SKris Kennaway * called by a name other than "ssh" or "Secure Shell". 12511b41d2SMark Murray */ 13511b41d2SMark Murray 14511b41d2SMark Murray #include "includes.h" 15333ee039SDag-Erling Smørgrav __RCSID("$FreeBSD$"); 16511b41d2SMark Murray 17333ee039SDag-Erling Smørgrav #include <sys/types.h> 18333ee039SDag-Erling Smørgrav #include <sys/socket.h> 19333ee039SDag-Erling Smørgrav 204a421b63SDag-Erling Smørgrav #include <netinet/in.h> 214a421b63SDag-Erling Smørgrav #include <netinet/in_systm.h> 224a421b63SDag-Erling Smørgrav #include <netinet/ip.h> 234a421b63SDag-Erling Smørgrav 24e4a9863fSDag-Erling Smørgrav #include <ctype.h> 25144a80bdSDag-Erling Smørgrav #include <fcntl.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> 33bc5531deSDag-Erling Smørgrav #include <limits.h> 34333ee039SDag-Erling Smørgrav #include <stdarg.h> 35d4af9e69SDag-Erling Smørgrav #include <errno.h> 36e4a9863fSDag-Erling Smørgrav #ifdef HAVE_UTIL_H 37e4a9863fSDag-Erling Smørgrav #include <util.h> 38e4a9863fSDag-Erling Smørgrav #endif 39333ee039SDag-Erling Smørgrav 40d4af9e69SDag-Erling Smørgrav #include "openbsd-compat/sys-queue.h" 41333ee039SDag-Erling Smørgrav #include "xmalloc.h" 42511b41d2SMark Murray #include "ssh.h" 43ca3176e7SBrian Feldman #include "log.h" 44333ee039SDag-Erling Smørgrav #include "buffer.h" 45a0ee8cc6SDag-Erling Smørgrav #include "misc.h" 46511b41d2SMark Murray #include "servconf.h" 47e8aafc91SKris Kennaway #include "compat.h" 48ca3176e7SBrian Feldman #include "pathnames.h" 49ca3176e7SBrian Feldman #include "cipher.h" 50333ee039SDag-Erling Smørgrav #include "key.h" 51ca3176e7SBrian Feldman #include "kex.h" 52ca3176e7SBrian Feldman #include "mac.h" 53333ee039SDag-Erling Smørgrav #include "match.h" 54333ee039SDag-Erling Smørgrav #include "channels.h" 55333ee039SDag-Erling Smørgrav #include "groupaccess.h" 56462c32cbSDag-Erling Smørgrav #include "canohost.h" 57462c32cbSDag-Erling Smørgrav #include "packet.h" 586888a9beSDag-Erling Smørgrav #include "hostfile.h" 596888a9beSDag-Erling Smørgrav #include "auth.h" 60bc5531deSDag-Erling Smørgrav #include "myproposal.h" 61bc5531deSDag-Erling Smørgrav #include "digest.h" 62b15c8340SDag-Erling Smørgrav #include "version.h" 63511b41d2SMark Murray 64cce7d346SDag-Erling Smørgrav static void add_listen_addr(ServerOptions *, char *, int); 65cce7d346SDag-Erling Smørgrav static void add_one_listen_addr(ServerOptions *, char *, int); 66ca3176e7SBrian Feldman 6780628bacSDag-Erling Smørgrav /* Use of privilege separation or not */ 6880628bacSDag-Erling Smørgrav extern int use_privsep; 69333ee039SDag-Erling Smørgrav extern Buffer cfg; 70511b41d2SMark Murray 71511b41d2SMark Murray /* Initializes the server options to their default values. */ 72511b41d2SMark Murray 73511b41d2SMark Murray void 74511b41d2SMark Murray initialize_server_options(ServerOptions *options) 75511b41d2SMark Murray { 76511b41d2SMark Murray memset(options, 0, sizeof(*options)); 77989dd127SDag-Erling Smørgrav 78989dd127SDag-Erling Smørgrav /* Portable-specific options */ 79cf2b5f3bSDag-Erling Smørgrav options->use_pam = -1; 80989dd127SDag-Erling Smørgrav 81989dd127SDag-Erling Smørgrav /* Standard Options */ 82511b41d2SMark Murray options->num_ports = 0; 83511b41d2SMark Murray options->ports_from_cmdline = 0; 84557f75e5SDag-Erling Smørgrav options->queued_listen_addrs = NULL; 85557f75e5SDag-Erling Smørgrav options->num_queued_listens = 0; 86511b41d2SMark Murray options->listen_addrs = NULL; 87aa49c926SDag-Erling Smørgrav options->address_family = -1; 88ca3176e7SBrian Feldman options->num_host_key_files = 0; 89b15c8340SDag-Erling Smørgrav options->num_host_cert_files = 0; 90e4a9863fSDag-Erling Smørgrav options->host_key_agent = NULL; 91e8aafc91SKris Kennaway options->pid_file = NULL; 92511b41d2SMark Murray options->server_key_bits = -1; 93511b41d2SMark Murray options->login_grace_time = -1; 94511b41d2SMark Murray options->key_regeneration_time = -1; 95ca3176e7SBrian Feldman options->permit_root_login = PERMIT_NOT_SET; 96511b41d2SMark Murray options->ignore_rhosts = -1; 97511b41d2SMark Murray options->ignore_user_known_hosts = -1; 98511b41d2SMark Murray options->print_motd = -1; 99ca3176e7SBrian Feldman options->print_lastlog = -1; 100511b41d2SMark Murray options->x11_forwarding = -1; 101511b41d2SMark Murray options->x11_display_offset = -1; 102af12a3e7SDag-Erling Smørgrav options->x11_use_localhost = -1; 103f7167e0eSDag-Erling Smørgrav options->permit_tty = -1; 104a0ee8cc6SDag-Erling Smørgrav options->permit_user_rc = -1; 105c2d3a559SKris Kennaway options->xauth_location = NULL; 106511b41d2SMark Murray options->strict_modes = -1; 1071ec0d754SDag-Erling Smørgrav options->tcp_keep_alive = -1; 108af12a3e7SDag-Erling Smørgrav options->log_facility = SYSLOG_FACILITY_NOT_SET; 109af12a3e7SDag-Erling Smørgrav options->log_level = SYSLOG_LEVEL_NOT_SET; 110511b41d2SMark Murray options->rhosts_rsa_authentication = -1; 111ca3176e7SBrian Feldman options->hostbased_authentication = -1; 112ca3176e7SBrian Feldman options->hostbased_uses_name_from_packet_only = -1; 113bc5531deSDag-Erling Smørgrav options->hostbased_key_types = NULL; 114eccfee6eSDag-Erling Smørgrav options->hostkeyalgorithms = NULL; 115511b41d2SMark Murray options->rsa_authentication = -1; 116ca3176e7SBrian Feldman options->pubkey_authentication = -1; 117bc5531deSDag-Erling Smørgrav options->pubkey_key_types = NULL; 118cb96ab36SAssar Westerlund options->kerberos_authentication = -1; 119af12a3e7SDag-Erling Smørgrav options->kerberos_or_local_passwd = -1; 120af12a3e7SDag-Erling Smørgrav options->kerberos_ticket_cleanup = -1; 1211ec0d754SDag-Erling Smørgrav options->kerberos_get_afs_token = -1; 122cf2b5f3bSDag-Erling Smørgrav options->gss_authentication=-1; 123cf2b5f3bSDag-Erling Smørgrav options->gss_cleanup_creds = -1; 124557f75e5SDag-Erling Smørgrav options->gss_strict_acceptor = -1; 125511b41d2SMark Murray options->password_authentication = -1; 12609958426SBrian Feldman options->kbd_interactive_authentication = -1; 127af12a3e7SDag-Erling Smørgrav options->challenge_response_authentication = -1; 128511b41d2SMark Murray options->permit_empty_passwd = -1; 129f388f5efSDag-Erling Smørgrav options->permit_user_env = -1; 130511b41d2SMark Murray options->use_login = -1; 13180628bacSDag-Erling Smørgrav options->compression = -1; 132e4a9863fSDag-Erling Smørgrav options->rekey_limit = -1; 133e4a9863fSDag-Erling Smørgrav options->rekey_interval = -1; 13409958426SBrian Feldman options->allow_tcp_forwarding = -1; 135a0ee8cc6SDag-Erling Smørgrav options->allow_streamlocal_forwarding = -1; 136d4af9e69SDag-Erling Smørgrav options->allow_agent_forwarding = -1; 137511b41d2SMark Murray options->num_allow_users = 0; 138511b41d2SMark Murray options->num_deny_users = 0; 139511b41d2SMark Murray options->num_allow_groups = 0; 140511b41d2SMark Murray options->num_deny_groups = 0; 141e8aafc91SKris Kennaway options->ciphers = NULL; 142ca3176e7SBrian Feldman options->macs = NULL; 1434a421b63SDag-Erling Smørgrav options->kex_algorithms = NULL; 144e8aafc91SKris Kennaway options->protocol = SSH_PROTO_UNKNOWN; 145a0ee8cc6SDag-Erling Smørgrav options->fwd_opts.gateway_ports = -1; 146a0ee8cc6SDag-Erling Smørgrav options->fwd_opts.streamlocal_bind_mask = (mode_t)-1; 147a0ee8cc6SDag-Erling Smørgrav options->fwd_opts.streamlocal_bind_unlink = -1; 148c2d3a559SKris Kennaway options->num_subsystems = 0; 149c2d3a559SKris Kennaway options->max_startups_begin = -1; 150c2d3a559SKris Kennaway options->max_startups_rate = -1; 151c2d3a559SKris Kennaway options->max_startups = -1; 15221e764dfSDag-Erling Smørgrav options->max_authtries = -1; 153d4af9e69SDag-Erling Smørgrav options->max_sessions = -1; 154ca3176e7SBrian Feldman options->banner = NULL; 155cf2b5f3bSDag-Erling Smørgrav options->use_dns = -1; 156ca3176e7SBrian Feldman options->client_alive_interval = -1; 157ca3176e7SBrian Feldman options->client_alive_count_max = -1; 158e146993eSDag-Erling Smørgrav options->num_authkeys_files = 0; 15921e764dfSDag-Erling Smørgrav options->num_accept_env = 0; 160b74df5b2SDag-Erling Smørgrav options->permit_tun = -1; 161333ee039SDag-Erling Smørgrav options->num_permitted_opens = -1; 162333ee039SDag-Erling Smørgrav options->adm_forced_command = NULL; 163d4af9e69SDag-Erling Smørgrav options->chroot_directory = NULL; 1646888a9beSDag-Erling Smørgrav options->authorized_keys_command = NULL; 1656888a9beSDag-Erling Smørgrav options->authorized_keys_command_user = NULL; 166b15c8340SDag-Erling Smørgrav options->revoked_keys_file = NULL; 167b15c8340SDag-Erling Smørgrav options->trusted_user_ca_keys = NULL; 168e2f6069cSDag-Erling Smørgrav options->authorized_principals_file = NULL; 169557f75e5SDag-Erling Smørgrav options->authorized_principals_command = NULL; 170557f75e5SDag-Erling Smørgrav options->authorized_principals_command_user = NULL; 1714a421b63SDag-Erling Smørgrav options->ip_qos_interactive = -1; 1724a421b63SDag-Erling Smørgrav options->ip_qos_bulk = -1; 173462c32cbSDag-Erling Smørgrav options->version_addendum = NULL; 174bc5531deSDag-Erling Smørgrav options->fingerprint_hash = -1; 175b2af61ecSKurt Lidl options->use_blacklist = -1; 176bc5531deSDag-Erling Smørgrav } 177bc5531deSDag-Erling Smørgrav 178bc5531deSDag-Erling Smørgrav /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ 179bc5531deSDag-Erling Smørgrav static int 180bc5531deSDag-Erling Smørgrav option_clear_or_none(const char *o) 181bc5531deSDag-Erling Smørgrav { 182bc5531deSDag-Erling Smørgrav return o == NULL || strcasecmp(o, "none") == 0; 183511b41d2SMark Murray } 184511b41d2SMark Murray 185acc1a9efSDag-Erling Smørgrav static void 186acc1a9efSDag-Erling Smørgrav assemble_algorithms(ServerOptions *o) 187acc1a9efSDag-Erling Smørgrav { 188acc1a9efSDag-Erling Smørgrav if (kex_assemble_names(KEX_SERVER_ENCRYPT, &o->ciphers) != 0 || 189acc1a9efSDag-Erling Smørgrav kex_assemble_names(KEX_SERVER_MAC, &o->macs) != 0 || 190acc1a9efSDag-Erling Smørgrav kex_assemble_names(KEX_SERVER_KEX, &o->kex_algorithms) != 0 || 191acc1a9efSDag-Erling Smørgrav kex_assemble_names(KEX_DEFAULT_PK_ALG, 192acc1a9efSDag-Erling Smørgrav &o->hostkeyalgorithms) != 0 || 193acc1a9efSDag-Erling Smørgrav kex_assemble_names(KEX_DEFAULT_PK_ALG, 194acc1a9efSDag-Erling Smørgrav &o->hostbased_key_types) != 0 || 195acc1a9efSDag-Erling Smørgrav kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->pubkey_key_types) != 0) 196acc1a9efSDag-Erling Smørgrav fatal("kex_assemble_names failed"); 197acc1a9efSDag-Erling Smørgrav } 198acc1a9efSDag-Erling Smørgrav 199511b41d2SMark Murray void 200511b41d2SMark Murray fill_default_server_options(ServerOptions *options) 201511b41d2SMark Murray { 202bc5531deSDag-Erling Smørgrav int i; 203bc5531deSDag-Erling Smørgrav 204989dd127SDag-Erling Smørgrav /* Portable-specific options */ 205cf2b5f3bSDag-Erling Smørgrav if (options->use_pam == -1) 206f0477b26SDag-Erling Smørgrav options->use_pam = 1; 207989dd127SDag-Erling Smørgrav 208989dd127SDag-Erling Smørgrav /* Standard Options */ 209ca3176e7SBrian Feldman if (options->protocol == SSH_PROTO_UNKNOWN) 210028c324aSDag-Erling Smørgrav options->protocol = SSH_PROTO_2; 211144a80bdSDag-Erling Smørgrav #define add_host_key_file(path) \ 212144a80bdSDag-Erling Smørgrav do { \ 213144a80bdSDag-Erling Smørgrav if (access((path), O_RDONLY) == 0) \ 214144a80bdSDag-Erling Smørgrav options->host_key_files \ 215144a80bdSDag-Erling Smørgrav [options->num_host_key_files++] = (path); \ 216144a80bdSDag-Erling Smørgrav } while (0) 217ca3176e7SBrian Feldman if (options->num_host_key_files == 0) { 218ca3176e7SBrian Feldman /* fill default hostkeys for protocols */ 219ca3176e7SBrian Feldman if (options->protocol & SSH_PROTO_1) 220144a80bdSDag-Erling Smørgrav add_host_key_file(_PATH_HOST_KEY_FILE); 221af12a3e7SDag-Erling Smørgrav if (options->protocol & SSH_PROTO_2) { 222144a80bdSDag-Erling Smørgrav add_host_key_file(_PATH_HOST_RSA_KEY_FILE); 223144a80bdSDag-Erling Smørgrav add_host_key_file(_PATH_HOST_DSA_KEY_FILE); 2244a421b63SDag-Erling Smørgrav #ifdef OPENSSL_HAS_ECC 225144a80bdSDag-Erling Smørgrav add_host_key_file(_PATH_HOST_ECDSA_KEY_FILE); 2264a421b63SDag-Erling Smørgrav #endif 227144a80bdSDag-Erling Smørgrav add_host_key_file(_PATH_HOST_ED25519_KEY_FILE); 228af12a3e7SDag-Erling Smørgrav } 229ca3176e7SBrian Feldman } 230144a80bdSDag-Erling Smørgrav #undef add_host_key_file 231144a80bdSDag-Erling Smørgrav if (options->num_host_key_files == 0) 232144a80bdSDag-Erling Smørgrav fatal("No host key files found"); 233b15c8340SDag-Erling Smørgrav /* No certificates by default */ 234511b41d2SMark Murray if (options->num_ports == 0) 235511b41d2SMark Murray options->ports[options->num_ports++] = SSH_DEFAULT_PORT; 236557f75e5SDag-Erling Smørgrav if (options->address_family == -1) 237557f75e5SDag-Erling Smørgrav options->address_family = AF_UNSPEC; 238511b41d2SMark Murray if (options->listen_addrs == NULL) 239ca3176e7SBrian Feldman add_listen_addr(options, NULL, 0); 240e8aafc91SKris Kennaway if (options->pid_file == NULL) 241bc5531deSDag-Erling Smørgrav options->pid_file = xstrdup(_PATH_SSH_DAEMON_PID_FILE); 242511b41d2SMark Murray if (options->server_key_bits == -1) 243d4af9e69SDag-Erling Smørgrav options->server_key_bits = 1024; 244511b41d2SMark Murray if (options->login_grace_time == -1) 245975616f0SDag-Erling Smørgrav options->login_grace_time = 120; 246511b41d2SMark Murray if (options->key_regeneration_time == -1) 247511b41d2SMark Murray options->key_regeneration_time = 3600; 248ca3176e7SBrian Feldman if (options->permit_root_login == PERMIT_NOT_SET) 249975616f0SDag-Erling Smørgrav options->permit_root_login = PERMIT_NO; 250511b41d2SMark Murray if (options->ignore_rhosts == -1) 251fe5fd017SMark Murray options->ignore_rhosts = 1; 252511b41d2SMark Murray if (options->ignore_user_known_hosts == -1) 253511b41d2SMark Murray options->ignore_user_known_hosts = 0; 254511b41d2SMark Murray if (options->print_motd == -1) 255511b41d2SMark Murray options->print_motd = 1; 256ca3176e7SBrian Feldman if (options->print_lastlog == -1) 257ca3176e7SBrian Feldman options->print_lastlog = 1; 258511b41d2SMark Murray if (options->x11_forwarding == -1) 259975616f0SDag-Erling Smørgrav options->x11_forwarding = 1; 260511b41d2SMark Murray if (options->x11_display_offset == -1) 261fe5fd017SMark Murray options->x11_display_offset = 10; 262af12a3e7SDag-Erling Smørgrav if (options->x11_use_localhost == -1) 263af12a3e7SDag-Erling Smørgrav options->x11_use_localhost = 1; 264c2d3a559SKris Kennaway if (options->xauth_location == NULL) 265bc5531deSDag-Erling Smørgrav options->xauth_location = xstrdup(_PATH_XAUTH); 266f7167e0eSDag-Erling Smørgrav if (options->permit_tty == -1) 267f7167e0eSDag-Erling Smørgrav options->permit_tty = 1; 268a0ee8cc6SDag-Erling Smørgrav if (options->permit_user_rc == -1) 269a0ee8cc6SDag-Erling Smørgrav options->permit_user_rc = 1; 270511b41d2SMark Murray if (options->strict_modes == -1) 271511b41d2SMark Murray options->strict_modes = 1; 2721ec0d754SDag-Erling Smørgrav if (options->tcp_keep_alive == -1) 2731ec0d754SDag-Erling Smørgrav options->tcp_keep_alive = 1; 274af12a3e7SDag-Erling Smørgrav if (options->log_facility == SYSLOG_FACILITY_NOT_SET) 275511b41d2SMark Murray options->log_facility = SYSLOG_FACILITY_AUTH; 276af12a3e7SDag-Erling Smørgrav if (options->log_level == SYSLOG_LEVEL_NOT_SET) 277511b41d2SMark Murray options->log_level = SYSLOG_LEVEL_INFO; 278511b41d2SMark Murray if (options->rhosts_rsa_authentication == -1) 279fe5fd017SMark Murray options->rhosts_rsa_authentication = 0; 280ca3176e7SBrian Feldman if (options->hostbased_authentication == -1) 281ca3176e7SBrian Feldman options->hostbased_authentication = 0; 282ca3176e7SBrian Feldman if (options->hostbased_uses_name_from_packet_only == -1) 283ca3176e7SBrian Feldman options->hostbased_uses_name_from_packet_only = 0; 284511b41d2SMark Murray if (options->rsa_authentication == -1) 285511b41d2SMark Murray options->rsa_authentication = 1; 286ca3176e7SBrian Feldman if (options->pubkey_authentication == -1) 287ca3176e7SBrian Feldman options->pubkey_authentication = 1; 288989dd127SDag-Erling Smørgrav if (options->kerberos_authentication == -1) 289cf2b5f3bSDag-Erling Smørgrav options->kerberos_authentication = 0; 290af12a3e7SDag-Erling Smørgrav if (options->kerberos_or_local_passwd == -1) 291af12a3e7SDag-Erling Smørgrav options->kerberos_or_local_passwd = 1; 292af12a3e7SDag-Erling Smørgrav if (options->kerberos_ticket_cleanup == -1) 293af12a3e7SDag-Erling Smørgrav options->kerberos_ticket_cleanup = 1; 2941ec0d754SDag-Erling Smørgrav if (options->kerberos_get_afs_token == -1) 2951ec0d754SDag-Erling Smørgrav options->kerberos_get_afs_token = 0; 296cf2b5f3bSDag-Erling Smørgrav if (options->gss_authentication == -1) 297cf2b5f3bSDag-Erling Smørgrav options->gss_authentication = 0; 298cf2b5f3bSDag-Erling Smørgrav if (options->gss_cleanup_creds == -1) 299cf2b5f3bSDag-Erling Smørgrav options->gss_cleanup_creds = 1; 300557f75e5SDag-Erling Smørgrav if (options->gss_strict_acceptor == -1) 301557f75e5SDag-Erling Smørgrav options->gss_strict_acceptor = 0; 302511b41d2SMark Murray if (options->password_authentication == -1) 303b909c84bSDag-Erling Smørgrav options->password_authentication = 0; 30409958426SBrian Feldman if (options->kbd_interactive_authentication == -1) 30509958426SBrian Feldman options->kbd_interactive_authentication = 0; 306af12a3e7SDag-Erling Smørgrav if (options->challenge_response_authentication == -1) 30780241871SDag-Erling Smørgrav options->challenge_response_authentication = 1; 308511b41d2SMark Murray if (options->permit_empty_passwd == -1) 309fe5fd017SMark Murray options->permit_empty_passwd = 0; 310f388f5efSDag-Erling Smørgrav if (options->permit_user_env == -1) 311f388f5efSDag-Erling Smørgrav options->permit_user_env = 0; 312511b41d2SMark Murray if (options->use_login == -1) 313511b41d2SMark Murray options->use_login = 0; 31480628bacSDag-Erling Smørgrav if (options->compression == -1) 315d4ecd108SDag-Erling Smørgrav options->compression = COMP_DELAYED; 316e4a9863fSDag-Erling Smørgrav if (options->rekey_limit == -1) 317e4a9863fSDag-Erling Smørgrav options->rekey_limit = 0; 318e4a9863fSDag-Erling Smørgrav if (options->rekey_interval == -1) 319e4a9863fSDag-Erling Smørgrav options->rekey_interval = 0; 32009958426SBrian Feldman if (options->allow_tcp_forwarding == -1) 3216888a9beSDag-Erling Smørgrav options->allow_tcp_forwarding = FORWARD_ALLOW; 322a0ee8cc6SDag-Erling Smørgrav if (options->allow_streamlocal_forwarding == -1) 323a0ee8cc6SDag-Erling Smørgrav options->allow_streamlocal_forwarding = FORWARD_ALLOW; 324d4af9e69SDag-Erling Smørgrav if (options->allow_agent_forwarding == -1) 325d4af9e69SDag-Erling Smørgrav options->allow_agent_forwarding = 1; 326a0ee8cc6SDag-Erling Smørgrav if (options->fwd_opts.gateway_ports == -1) 327a0ee8cc6SDag-Erling Smørgrav options->fwd_opts.gateway_ports = 0; 328c2d3a559SKris Kennaway if (options->max_startups == -1) 3296888a9beSDag-Erling Smørgrav options->max_startups = 100; 330c2d3a559SKris Kennaway if (options->max_startups_rate == -1) 3316888a9beSDag-Erling Smørgrav options->max_startups_rate = 30; /* 30% */ 332c2d3a559SKris Kennaway if (options->max_startups_begin == -1) 3336888a9beSDag-Erling Smørgrav options->max_startups_begin = 10; 33421e764dfSDag-Erling Smørgrav if (options->max_authtries == -1) 33521e764dfSDag-Erling Smørgrav options->max_authtries = DEFAULT_AUTH_FAIL_MAX; 336d4af9e69SDag-Erling Smørgrav if (options->max_sessions == -1) 337d4af9e69SDag-Erling Smørgrav options->max_sessions = DEFAULT_SESSIONS_MAX; 338cf2b5f3bSDag-Erling Smørgrav if (options->use_dns == -1) 339c4cd1fa4SDag-Erling Smørgrav options->use_dns = 1; 340ca3176e7SBrian Feldman if (options->client_alive_interval == -1) 341ca3176e7SBrian Feldman options->client_alive_interval = 0; 342ca3176e7SBrian Feldman if (options->client_alive_count_max == -1) 343ca3176e7SBrian Feldman options->client_alive_count_max = 3; 344e146993eSDag-Erling Smørgrav if (options->num_authkeys_files == 0) { 345e146993eSDag-Erling Smørgrav options->authorized_keys_files[options->num_authkeys_files++] = 346e146993eSDag-Erling Smørgrav xstrdup(_PATH_SSH_USER_PERMITTED_KEYS); 347e146993eSDag-Erling Smørgrav options->authorized_keys_files[options->num_authkeys_files++] = 348e146993eSDag-Erling Smørgrav xstrdup(_PATH_SSH_USER_PERMITTED_KEYS2); 349af12a3e7SDag-Erling Smørgrav } 350b74df5b2SDag-Erling Smørgrav if (options->permit_tun == -1) 351b74df5b2SDag-Erling Smørgrav options->permit_tun = SSH_TUNMODE_NO; 3524a421b63SDag-Erling Smørgrav if (options->ip_qos_interactive == -1) 3534a421b63SDag-Erling Smørgrav options->ip_qos_interactive = IPTOS_LOWDELAY; 3544a421b63SDag-Erling Smørgrav if (options->ip_qos_bulk == -1) 3554a421b63SDag-Erling Smørgrav options->ip_qos_bulk = IPTOS_THROUGHPUT; 356462c32cbSDag-Erling Smørgrav if (options->version_addendum == NULL) 357462c32cbSDag-Erling Smørgrav options->version_addendum = xstrdup(SSH_VERSION_FREEBSD); 358a0ee8cc6SDag-Erling Smørgrav if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1) 359a0ee8cc6SDag-Erling Smørgrav options->fwd_opts.streamlocal_bind_mask = 0177; 360a0ee8cc6SDag-Erling Smørgrav if (options->fwd_opts.streamlocal_bind_unlink == -1) 361a0ee8cc6SDag-Erling Smørgrav options->fwd_opts.streamlocal_bind_unlink = 0; 362bc5531deSDag-Erling Smørgrav if (options->fingerprint_hash == -1) 363bc5531deSDag-Erling Smørgrav options->fingerprint_hash = SSH_FP_HASH_DEFAULT; 364b2af61ecSKurt Lidl if (options->use_blacklist == -1) 365b2af61ecSKurt Lidl options->use_blacklist = 0; 366eccfee6eSDag-Erling Smørgrav 367acc1a9efSDag-Erling Smørgrav assemble_algorithms(options); 368eccfee6eSDag-Erling Smørgrav 369acc1a9efSDag-Erling Smørgrav /* Turn privilege separation and sandboxing on by default */ 370462c32cbSDag-Erling Smørgrav if (use_privsep == -1) 3712b1970f3SDag-Erling Smørgrav use_privsep = PRIVSEP_ON; 372462c32cbSDag-Erling Smørgrav 373bc5531deSDag-Erling Smørgrav #define CLEAR_ON_NONE(v) \ 374bc5531deSDag-Erling Smørgrav do { \ 375bc5531deSDag-Erling Smørgrav if (option_clear_or_none(v)) { \ 376bc5531deSDag-Erling Smørgrav free(v); \ 377bc5531deSDag-Erling Smørgrav v = NULL; \ 378bc5531deSDag-Erling Smørgrav } \ 379bc5531deSDag-Erling Smørgrav } while(0) 380bc5531deSDag-Erling Smørgrav CLEAR_ON_NONE(options->pid_file); 381bc5531deSDag-Erling Smørgrav CLEAR_ON_NONE(options->xauth_location); 382bc5531deSDag-Erling Smørgrav CLEAR_ON_NONE(options->banner); 383bc5531deSDag-Erling Smørgrav CLEAR_ON_NONE(options->trusted_user_ca_keys); 384bc5531deSDag-Erling Smørgrav CLEAR_ON_NONE(options->revoked_keys_file); 385557f75e5SDag-Erling Smørgrav CLEAR_ON_NONE(options->authorized_principals_file); 386acc1a9efSDag-Erling Smørgrav CLEAR_ON_NONE(options->adm_forced_command); 387acc1a9efSDag-Erling Smørgrav CLEAR_ON_NONE(options->chroot_directory); 388bc5531deSDag-Erling Smørgrav for (i = 0; i < options->num_host_key_files; i++) 389bc5531deSDag-Erling Smørgrav CLEAR_ON_NONE(options->host_key_files[i]); 390bc5531deSDag-Erling Smørgrav for (i = 0; i < options->num_host_cert_files; i++) 391bc5531deSDag-Erling Smørgrav CLEAR_ON_NONE(options->host_cert_files[i]); 392bc5531deSDag-Erling Smørgrav #undef CLEAR_ON_NONE 393bc5531deSDag-Erling Smørgrav 394*076ad2f8SDag-Erling Smørgrav /* Similar handling for AuthenticationMethods=any */ 395*076ad2f8SDag-Erling Smørgrav if (options->num_auth_methods == 1 && 396*076ad2f8SDag-Erling Smørgrav strcmp(options->auth_methods[0], "any") == 0) { 397*076ad2f8SDag-Erling Smørgrav free(options->auth_methods[0]); 398*076ad2f8SDag-Erling Smørgrav options->auth_methods[0] = NULL; 399*076ad2f8SDag-Erling Smørgrav options->num_auth_methods = 0; 400*076ad2f8SDag-Erling Smørgrav } 401*076ad2f8SDag-Erling Smørgrav 402462c32cbSDag-Erling Smørgrav #ifndef HAVE_MMAP 403462c32cbSDag-Erling Smørgrav if (use_privsep && options->compression == 1) { 404462c32cbSDag-Erling Smørgrav error("This platform does not support both privilege " 405462c32cbSDag-Erling Smørgrav "separation and compression"); 406462c32cbSDag-Erling Smørgrav error("Compression disabled"); 407462c32cbSDag-Erling Smørgrav options->compression = 0; 408462c32cbSDag-Erling Smørgrav } 409462c32cbSDag-Erling Smørgrav #endif 410462c32cbSDag-Erling Smørgrav 411511b41d2SMark Murray } 412511b41d2SMark Murray 413511b41d2SMark Murray /* Keyword tokens. */ 414511b41d2SMark Murray typedef enum { 415511b41d2SMark Murray sBadOption, /* == unknown option */ 416989dd127SDag-Erling Smørgrav /* Portable-specific options */ 417cf2b5f3bSDag-Erling Smørgrav sUsePAM, 418989dd127SDag-Erling Smørgrav /* Standard Options */ 419bc5531deSDag-Erling Smørgrav sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, 420bc5531deSDag-Erling Smørgrav sKeyRegenerationTime, sPermitRootLogin, sLogFacility, sLogLevel, 421cf2b5f3bSDag-Erling Smørgrav sRhostsRSAAuthentication, sRSAAuthentication, 422af12a3e7SDag-Erling Smørgrav sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, 4231ec0d754SDag-Erling Smørgrav sKerberosGetAFSToken, 424cf2b5f3bSDag-Erling Smørgrav sKerberosTgtPassing, sChallengeResponseAuthentication, 425aa49c926SDag-Erling Smørgrav sPasswordAuthentication, sKbdInteractiveAuthentication, 426aa49c926SDag-Erling Smørgrav sListenAddress, sAddressFamily, 427ca3176e7SBrian Feldman sPrintMotd, sPrintLastLog, sIgnoreRhosts, 428af12a3e7SDag-Erling Smørgrav sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, 429f7167e0eSDag-Erling Smørgrav sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive, 430f388f5efSDag-Erling Smørgrav sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression, 431e4a9863fSDag-Erling Smørgrav sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, 432ca3176e7SBrian Feldman sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, 433bc5531deSDag-Erling Smørgrav sGatewayPorts, sPubkeyAuthentication, sPubkeyAcceptedKeyTypes, 434bc5531deSDag-Erling Smørgrav sXAuthLocation, sSubsystem, sMaxStartups, sMaxAuthTries, sMaxSessions, 435cf2b5f3bSDag-Erling Smørgrav sBanner, sUseDNS, sHostbasedAuthentication, 436bc5531deSDag-Erling Smørgrav sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, 437eccfee6eSDag-Erling Smørgrav sHostKeyAlgorithms, 438bc5531deSDag-Erling Smørgrav sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, 439557f75e5SDag-Erling Smørgrav sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, 440557f75e5SDag-Erling Smørgrav sAcceptEnv, sPermitTunnel, 441d4af9e69SDag-Erling Smørgrav sMatch, sPermitOpen, sForceCommand, sChrootDirectory, 442d4af9e69SDag-Erling Smørgrav sUsePrivilegeSeparation, sAllowAgentForwarding, 443b83788ffSDag-Erling Smørgrav sHostCertificate, 444e2f6069cSDag-Erling Smørgrav sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, 445557f75e5SDag-Erling Smørgrav sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser, 446462c32cbSDag-Erling Smørgrav sKexAlgorithms, sIPQoS, sVersionAddendum, 4476888a9beSDag-Erling Smørgrav sAuthorizedKeysCommand, sAuthorizedKeysCommandUser, 448a0ee8cc6SDag-Erling Smørgrav sAuthenticationMethods, sHostKeyAgent, sPermitUserRC, 449a0ee8cc6SDag-Erling Smørgrav sStreamLocalBindMask, sStreamLocalBindUnlink, 450bc5531deSDag-Erling Smørgrav sAllowStreamLocalForwarding, sFingerprintHash, 451b2af61ecSKurt Lidl sUseBlacklist, 452cf2b5f3bSDag-Erling Smørgrav sDeprecated, sUnsupported 453511b41d2SMark Murray } ServerOpCodes; 454511b41d2SMark Murray 455333ee039SDag-Erling Smørgrav #define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */ 456333ee039SDag-Erling Smørgrav #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */ 457333ee039SDag-Erling Smørgrav #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH) 458333ee039SDag-Erling Smørgrav 459511b41d2SMark Murray /* Textual representation of the tokens. */ 460511b41d2SMark Murray static struct { 461511b41d2SMark Murray const char *name; 462511b41d2SMark Murray ServerOpCodes opcode; 463333ee039SDag-Erling Smørgrav u_int flags; 464511b41d2SMark Murray } keywords[] = { 465989dd127SDag-Erling Smørgrav /* Portable-specific options */ 466cf2b5f3bSDag-Erling Smørgrav #ifdef USE_PAM 467333ee039SDag-Erling Smørgrav { "usepam", sUsePAM, SSHCFG_GLOBAL }, 468cf2b5f3bSDag-Erling Smørgrav #else 469333ee039SDag-Erling Smørgrav { "usepam", sUnsupported, SSHCFG_GLOBAL }, 470975616f0SDag-Erling Smørgrav #endif 471333ee039SDag-Erling Smørgrav { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, 472989dd127SDag-Erling Smørgrav /* Standard Options */ 473333ee039SDag-Erling Smørgrav { "port", sPort, SSHCFG_GLOBAL }, 474333ee039SDag-Erling Smørgrav { "hostkey", sHostKeyFile, SSHCFG_GLOBAL }, 475333ee039SDag-Erling Smørgrav { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */ 476e4a9863fSDag-Erling Smørgrav { "hostkeyagent", sHostKeyAgent, SSHCFG_GLOBAL }, 477333ee039SDag-Erling Smørgrav { "pidfile", sPidFile, SSHCFG_GLOBAL }, 478333ee039SDag-Erling Smørgrav { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL }, 479333ee039SDag-Erling Smørgrav { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL }, 480333ee039SDag-Erling Smørgrav { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL }, 481d4af9e69SDag-Erling Smørgrav { "permitrootlogin", sPermitRootLogin, SSHCFG_ALL }, 482333ee039SDag-Erling Smørgrav { "syslogfacility", sLogFacility, SSHCFG_GLOBAL }, 483333ee039SDag-Erling Smørgrav { "loglevel", sLogLevel, SSHCFG_GLOBAL }, 484333ee039SDag-Erling Smørgrav { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL }, 485d4af9e69SDag-Erling Smørgrav { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_ALL }, 486d4af9e69SDag-Erling Smørgrav { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL }, 487e2f6069cSDag-Erling Smørgrav { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_ALL }, 488bc5531deSDag-Erling Smørgrav { "hostbasedacceptedkeytypes", sHostbasedAcceptedKeyTypes, SSHCFG_ALL }, 489eccfee6eSDag-Erling Smørgrav { "hostkeyalgorithms", sHostKeyAlgorithms, SSHCFG_GLOBAL }, 490d4af9e69SDag-Erling Smørgrav { "rsaauthentication", sRSAAuthentication, SSHCFG_ALL }, 491d4af9e69SDag-Erling Smørgrav { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL }, 492bc5531deSDag-Erling Smørgrav { "pubkeyacceptedkeytypes", sPubkeyAcceptedKeyTypes, SSHCFG_ALL }, 493333ee039SDag-Erling Smørgrav { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */ 494cf2b5f3bSDag-Erling Smørgrav #ifdef KRB5 495d4af9e69SDag-Erling Smørgrav { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL }, 496333ee039SDag-Erling Smørgrav { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL }, 497333ee039SDag-Erling Smørgrav { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL }, 4981ec0d754SDag-Erling Smørgrav #ifdef USE_AFS 499333ee039SDag-Erling Smørgrav { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL }, 5001ec0d754SDag-Erling Smørgrav #else 501333ee039SDag-Erling Smørgrav { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, 5021ec0d754SDag-Erling Smørgrav #endif 503cf2b5f3bSDag-Erling Smørgrav #else 504d4af9e69SDag-Erling Smørgrav { "kerberosauthentication", sUnsupported, SSHCFG_ALL }, 505333ee039SDag-Erling Smørgrav { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL }, 506333ee039SDag-Erling Smørgrav { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL }, 507333ee039SDag-Erling Smørgrav { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, 508cb96ab36SAssar Westerlund #endif 509333ee039SDag-Erling Smørgrav { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, 510333ee039SDag-Erling Smørgrav { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, 511cf2b5f3bSDag-Erling Smørgrav #ifdef GSSAPI 512d4af9e69SDag-Erling Smørgrav { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, 513333ee039SDag-Erling Smørgrav { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, 514557f75e5SDag-Erling Smørgrav { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, 515cf2b5f3bSDag-Erling Smørgrav #else 516d4af9e69SDag-Erling Smørgrav { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, 517333ee039SDag-Erling Smørgrav { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, 518557f75e5SDag-Erling Smørgrav { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, 519511b41d2SMark Murray #endif 520d4af9e69SDag-Erling Smørgrav { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, 521d4af9e69SDag-Erling Smørgrav { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, 522333ee039SDag-Erling Smørgrav { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, 523333ee039SDag-Erling Smørgrav { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */ 524333ee039SDag-Erling Smørgrav { "checkmail", sDeprecated, SSHCFG_GLOBAL }, 525333ee039SDag-Erling Smørgrav { "listenaddress", sListenAddress, SSHCFG_GLOBAL }, 526333ee039SDag-Erling Smørgrav { "addressfamily", sAddressFamily, SSHCFG_GLOBAL }, 527333ee039SDag-Erling Smørgrav { "printmotd", sPrintMotd, SSHCFG_GLOBAL }, 528acc1a9efSDag-Erling Smørgrav #ifdef DISABLE_LASTLOG 529acc1a9efSDag-Erling Smørgrav { "printlastlog", sUnsupported, SSHCFG_GLOBAL }, 530acc1a9efSDag-Erling Smørgrav #else 531333ee039SDag-Erling Smørgrav { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL }, 532acc1a9efSDag-Erling Smørgrav #endif 533333ee039SDag-Erling Smørgrav { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL }, 534333ee039SDag-Erling Smørgrav { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL }, 535333ee039SDag-Erling Smørgrav { "x11forwarding", sX11Forwarding, SSHCFG_ALL }, 536333ee039SDag-Erling Smørgrav { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL }, 537333ee039SDag-Erling Smørgrav { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL }, 538333ee039SDag-Erling Smørgrav { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL }, 539333ee039SDag-Erling Smørgrav { "strictmodes", sStrictModes, SSHCFG_GLOBAL }, 540cce7d346SDag-Erling Smørgrav { "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL }, 541333ee039SDag-Erling Smørgrav { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL }, 542333ee039SDag-Erling Smørgrav { "uselogin", sUseLogin, SSHCFG_GLOBAL }, 543333ee039SDag-Erling Smørgrav { "compression", sCompression, SSHCFG_GLOBAL }, 544e4a9863fSDag-Erling Smørgrav { "rekeylimit", sRekeyLimit, SSHCFG_ALL }, 545333ee039SDag-Erling Smørgrav { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, 546333ee039SDag-Erling Smørgrav { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */ 547333ee039SDag-Erling Smørgrav { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL }, 548d4af9e69SDag-Erling Smørgrav { "allowagentforwarding", sAllowAgentForwarding, SSHCFG_ALL }, 549462c32cbSDag-Erling Smørgrav { "allowusers", sAllowUsers, SSHCFG_ALL }, 550462c32cbSDag-Erling Smørgrav { "denyusers", sDenyUsers, SSHCFG_ALL }, 551462c32cbSDag-Erling Smørgrav { "allowgroups", sAllowGroups, SSHCFG_ALL }, 552462c32cbSDag-Erling Smørgrav { "denygroups", sDenyGroups, SSHCFG_ALL }, 553333ee039SDag-Erling Smørgrav { "ciphers", sCiphers, SSHCFG_GLOBAL }, 554333ee039SDag-Erling Smørgrav { "macs", sMacs, SSHCFG_GLOBAL }, 555333ee039SDag-Erling Smørgrav { "protocol", sProtocol, SSHCFG_GLOBAL }, 556333ee039SDag-Erling Smørgrav { "gatewayports", sGatewayPorts, SSHCFG_ALL }, 557333ee039SDag-Erling Smørgrav { "subsystem", sSubsystem, SSHCFG_GLOBAL }, 558333ee039SDag-Erling Smørgrav { "maxstartups", sMaxStartups, SSHCFG_GLOBAL }, 559d4af9e69SDag-Erling Smørgrav { "maxauthtries", sMaxAuthTries, SSHCFG_ALL }, 560d4af9e69SDag-Erling Smørgrav { "maxsessions", sMaxSessions, SSHCFG_ALL }, 561d4af9e69SDag-Erling Smørgrav { "banner", sBanner, SSHCFG_ALL }, 562333ee039SDag-Erling Smørgrav { "usedns", sUseDNS, SSHCFG_GLOBAL }, 563333ee039SDag-Erling Smørgrav { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL }, 564333ee039SDag-Erling Smørgrav { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL }, 565333ee039SDag-Erling Smørgrav { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL }, 566333ee039SDag-Erling Smørgrav { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL }, 567e2f6069cSDag-Erling Smørgrav { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_ALL }, 568e146993eSDag-Erling Smørgrav { "authorizedkeysfile2", sDeprecated, SSHCFG_ALL }, 569333ee039SDag-Erling Smørgrav { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL}, 570462c32cbSDag-Erling Smørgrav { "acceptenv", sAcceptEnv, SSHCFG_ALL }, 571e2f6069cSDag-Erling Smørgrav { "permittunnel", sPermitTunnel, SSHCFG_ALL }, 572f7167e0eSDag-Erling Smørgrav { "permittty", sPermitTTY, SSHCFG_ALL }, 573a0ee8cc6SDag-Erling Smørgrav { "permituserrc", sPermitUserRC, SSHCFG_ALL }, 574333ee039SDag-Erling Smørgrav { "match", sMatch, SSHCFG_ALL }, 575333ee039SDag-Erling Smørgrav { "permitopen", sPermitOpen, SSHCFG_ALL }, 576333ee039SDag-Erling Smørgrav { "forcecommand", sForceCommand, SSHCFG_ALL }, 577d4af9e69SDag-Erling Smørgrav { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, 578b15c8340SDag-Erling Smørgrav { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, 579b15c8340SDag-Erling Smørgrav { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, 580b15c8340SDag-Erling Smørgrav { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, 581e2f6069cSDag-Erling Smørgrav { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, 5824a421b63SDag-Erling Smørgrav { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, 5834a421b63SDag-Erling Smørgrav { "ipqos", sIPQoS, SSHCFG_ALL }, 5846888a9beSDag-Erling Smørgrav { "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL }, 5856888a9beSDag-Erling Smørgrav { "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL }, 586557f75e5SDag-Erling Smørgrav { "authorizedprincipalscommand", sAuthorizedPrincipalsCommand, SSHCFG_ALL }, 587557f75e5SDag-Erling Smørgrav { "authorizedprincipalscommanduser", sAuthorizedPrincipalsCommandUser, SSHCFG_ALL }, 588462c32cbSDag-Erling Smørgrav { "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL }, 5896888a9beSDag-Erling Smørgrav { "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL }, 590a0ee8cc6SDag-Erling Smørgrav { "streamlocalbindmask", sStreamLocalBindMask, SSHCFG_ALL }, 591a0ee8cc6SDag-Erling Smørgrav { "streamlocalbindunlink", sStreamLocalBindUnlink, SSHCFG_ALL }, 592a0ee8cc6SDag-Erling Smørgrav { "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL }, 593bc5531deSDag-Erling Smørgrav { "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL }, 594b2af61ecSKurt Lidl { "useblacklist", sUseBlacklist, SSHCFG_GLOBAL }, 5956f351346SDag-Erling Smørgrav { "noneenabled", sUnsupported, SSHCFG_ALL }, 5969860d96eSDag-Erling Smørgrav { "hpndisabled", sDeprecated, SSHCFG_ALL }, 5979860d96eSDag-Erling Smørgrav { "hpnbuffersize", sDeprecated, SSHCFG_ALL }, 5989860d96eSDag-Erling Smørgrav { "tcprcvbufpoll", sDeprecated, SSHCFG_ALL }, 599333ee039SDag-Erling Smørgrav { NULL, sBadOption, 0 } 600511b41d2SMark Murray }; 601511b41d2SMark Murray 602d4af9e69SDag-Erling Smørgrav static struct { 603d4af9e69SDag-Erling Smørgrav int val; 604d4af9e69SDag-Erling Smørgrav char *text; 605d4af9e69SDag-Erling Smørgrav } tunmode_desc[] = { 606d4af9e69SDag-Erling Smørgrav { SSH_TUNMODE_NO, "no" }, 607d4af9e69SDag-Erling Smørgrav { SSH_TUNMODE_POINTOPOINT, "point-to-point" }, 608d4af9e69SDag-Erling Smørgrav { SSH_TUNMODE_ETHERNET, "ethernet" }, 609d4af9e69SDag-Erling Smørgrav { SSH_TUNMODE_YES, "yes" }, 610d4af9e69SDag-Erling Smørgrav { -1, NULL } 611d4af9e69SDag-Erling Smørgrav }; 612d4af9e69SDag-Erling Smørgrav 613511b41d2SMark Murray /* 614ca3176e7SBrian Feldman * Returns the number of the token pointed to by cp or sBadOption. 615511b41d2SMark Murray */ 616511b41d2SMark Murray 617511b41d2SMark Murray static ServerOpCodes 618511b41d2SMark Murray parse_token(const char *cp, const char *filename, 619333ee039SDag-Erling Smørgrav int linenum, u_int *flags) 620511b41d2SMark Murray { 621ca3176e7SBrian Feldman u_int i; 622511b41d2SMark Murray 623511b41d2SMark Murray for (i = 0; keywords[i].name; i++) 624333ee039SDag-Erling Smørgrav if (strcasecmp(cp, keywords[i].name) == 0) { 625333ee039SDag-Erling Smørgrav *flags = keywords[i].flags; 626511b41d2SMark Murray return keywords[i].opcode; 627333ee039SDag-Erling Smørgrav } 628511b41d2SMark Murray 629ca3176e7SBrian Feldman error("%s: line %d: Bad configuration option: %s", 630511b41d2SMark Murray filename, linenum, cp); 631511b41d2SMark Murray return sBadOption; 632511b41d2SMark Murray } 633511b41d2SMark Murray 634b15c8340SDag-Erling Smørgrav char * 635b15c8340SDag-Erling Smørgrav derelativise_path(const char *path) 636b15c8340SDag-Erling Smørgrav { 637bc5531deSDag-Erling Smørgrav char *expanded, *ret, cwd[PATH_MAX]; 638b15c8340SDag-Erling Smørgrav 639bc5531deSDag-Erling Smørgrav if (strcasecmp(path, "none") == 0) 640bc5531deSDag-Erling Smørgrav return xstrdup("none"); 641b15c8340SDag-Erling Smørgrav expanded = tilde_expand_filename(path, getuid()); 642b15c8340SDag-Erling Smørgrav if (*expanded == '/') 643b15c8340SDag-Erling Smørgrav return expanded; 6448ad9b54aSDag-Erling Smørgrav if (getcwd(cwd, sizeof(cwd)) == NULL) 645b15c8340SDag-Erling Smørgrav fatal("%s: getcwd: %s", __func__, strerror(errno)); 646b15c8340SDag-Erling Smørgrav xasprintf(&ret, "%s/%s", cwd, expanded); 647e4a9863fSDag-Erling Smørgrav free(expanded); 648b15c8340SDag-Erling Smørgrav return ret; 649b15c8340SDag-Erling Smørgrav } 650b15c8340SDag-Erling Smørgrav 651af12a3e7SDag-Erling Smørgrav static void 652cce7d346SDag-Erling Smørgrav add_listen_addr(ServerOptions *options, char *addr, int port) 653511b41d2SMark Murray { 654d4ecd108SDag-Erling Smørgrav u_int i; 655511b41d2SMark Murray 656ca3176e7SBrian Feldman if (port == 0) 657ca3176e7SBrian Feldman for (i = 0; i < options->num_ports; i++) 658ca3176e7SBrian Feldman add_one_listen_addr(options, addr, options->ports[i]); 659ca3176e7SBrian Feldman else 660ca3176e7SBrian Feldman add_one_listen_addr(options, addr, port); 661ca3176e7SBrian Feldman } 662ca3176e7SBrian Feldman 663af12a3e7SDag-Erling Smørgrav static void 664cce7d346SDag-Erling Smørgrav add_one_listen_addr(ServerOptions *options, char *addr, int port) 665ca3176e7SBrian Feldman { 666ca3176e7SBrian Feldman struct addrinfo hints, *ai, *aitop; 667ca3176e7SBrian Feldman char strport[NI_MAXSERV]; 668ca3176e7SBrian Feldman int gaierr; 669ca3176e7SBrian Feldman 670511b41d2SMark Murray memset(&hints, 0, sizeof(hints)); 671aa49c926SDag-Erling Smørgrav hints.ai_family = options->address_family; 672511b41d2SMark Murray hints.ai_socktype = SOCK_STREAM; 673511b41d2SMark Murray hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0; 674cce7d346SDag-Erling Smørgrav snprintf(strport, sizeof strport, "%d", port); 675511b41d2SMark Murray if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0) 676ca3176e7SBrian Feldman fatal("bad addr or host: %s (%s)", 677511b41d2SMark Murray addr ? addr : "<NULL>", 678d4af9e69SDag-Erling Smørgrav ssh_gai_strerror(gaierr)); 679511b41d2SMark Murray for (ai = aitop; ai->ai_next; ai = ai->ai_next) 680511b41d2SMark Murray ; 681511b41d2SMark Murray ai->ai_next = options->listen_addrs; 682511b41d2SMark Murray options->listen_addrs = aitop; 683511b41d2SMark Murray } 684511b41d2SMark Murray 685557f75e5SDag-Erling Smørgrav /* 686557f75e5SDag-Erling Smørgrav * Queue a ListenAddress to be processed once we have all of the Ports 687557f75e5SDag-Erling Smørgrav * and AddressFamily options. 688557f75e5SDag-Erling Smørgrav */ 689557f75e5SDag-Erling Smørgrav static void 690557f75e5SDag-Erling Smørgrav queue_listen_addr(ServerOptions *options, char *addr, int port) 691557f75e5SDag-Erling Smørgrav { 692557f75e5SDag-Erling Smørgrav options->queued_listen_addrs = xreallocarray( 693557f75e5SDag-Erling Smørgrav options->queued_listen_addrs, options->num_queued_listens + 1, 694557f75e5SDag-Erling Smørgrav sizeof(addr)); 695557f75e5SDag-Erling Smørgrav options->queued_listen_ports = xreallocarray( 696557f75e5SDag-Erling Smørgrav options->queued_listen_ports, options->num_queued_listens + 1, 697557f75e5SDag-Erling Smørgrav sizeof(port)); 698557f75e5SDag-Erling Smørgrav options->queued_listen_addrs[options->num_queued_listens] = 699557f75e5SDag-Erling Smørgrav xstrdup(addr); 700557f75e5SDag-Erling Smørgrav options->queued_listen_ports[options->num_queued_listens] = port; 701557f75e5SDag-Erling Smørgrav options->num_queued_listens++; 702557f75e5SDag-Erling Smørgrav } 703557f75e5SDag-Erling Smørgrav 704557f75e5SDag-Erling Smørgrav /* 705557f75e5SDag-Erling Smørgrav * Process queued (text) ListenAddress entries. 706557f75e5SDag-Erling Smørgrav */ 707557f75e5SDag-Erling Smørgrav static void 708557f75e5SDag-Erling Smørgrav process_queued_listen_addrs(ServerOptions *options) 709557f75e5SDag-Erling Smørgrav { 710557f75e5SDag-Erling Smørgrav u_int i; 711557f75e5SDag-Erling Smørgrav 712557f75e5SDag-Erling Smørgrav if (options->num_ports == 0) 713557f75e5SDag-Erling Smørgrav options->ports[options->num_ports++] = SSH_DEFAULT_PORT; 714557f75e5SDag-Erling Smørgrav if (options->address_family == -1) 715557f75e5SDag-Erling Smørgrav options->address_family = AF_UNSPEC; 716557f75e5SDag-Erling Smørgrav 717557f75e5SDag-Erling Smørgrav for (i = 0; i < options->num_queued_listens; i++) { 718557f75e5SDag-Erling Smørgrav add_listen_addr(options, options->queued_listen_addrs[i], 719557f75e5SDag-Erling Smørgrav options->queued_listen_ports[i]); 720557f75e5SDag-Erling Smørgrav free(options->queued_listen_addrs[i]); 721557f75e5SDag-Erling Smørgrav options->queued_listen_addrs[i] = NULL; 722557f75e5SDag-Erling Smørgrav } 723557f75e5SDag-Erling Smørgrav free(options->queued_listen_addrs); 724557f75e5SDag-Erling Smørgrav options->queued_listen_addrs = NULL; 725557f75e5SDag-Erling Smørgrav free(options->queued_listen_ports); 726557f75e5SDag-Erling Smørgrav options->queued_listen_ports = NULL; 727557f75e5SDag-Erling Smørgrav options->num_queued_listens = 0; 728557f75e5SDag-Erling Smørgrav } 729557f75e5SDag-Erling Smørgrav 730462c32cbSDag-Erling Smørgrav struct connection_info * 731462c32cbSDag-Erling Smørgrav get_connection_info(int populate, int use_dns) 732462c32cbSDag-Erling Smørgrav { 733*076ad2f8SDag-Erling Smørgrav struct ssh *ssh = active_state; /* XXX */ 734462c32cbSDag-Erling Smørgrav static struct connection_info ci; 735462c32cbSDag-Erling Smørgrav 736462c32cbSDag-Erling Smørgrav if (!populate) 737462c32cbSDag-Erling Smørgrav return &ci; 738*076ad2f8SDag-Erling Smørgrav ci.host = auth_get_canonical_hostname(ssh, use_dns); 739*076ad2f8SDag-Erling Smørgrav ci.address = ssh_remote_ipaddr(ssh); 740*076ad2f8SDag-Erling Smørgrav ci.laddress = ssh_local_ipaddr(ssh); 741*076ad2f8SDag-Erling Smørgrav ci.lport = ssh_local_port(ssh); 742462c32cbSDag-Erling Smørgrav return &ci; 743462c32cbSDag-Erling Smørgrav } 744462c32cbSDag-Erling Smørgrav 745333ee039SDag-Erling Smørgrav /* 746333ee039SDag-Erling Smørgrav * The strategy for the Match blocks is that the config file is parsed twice. 747333ee039SDag-Erling Smørgrav * 748333ee039SDag-Erling Smørgrav * The first time is at startup. activep is initialized to 1 and the 749333ee039SDag-Erling Smørgrav * directives in the global context are processed and acted on. Hitting a 750333ee039SDag-Erling Smørgrav * Match directive unsets activep and the directives inside the block are 751333ee039SDag-Erling Smørgrav * checked for syntax only. 752333ee039SDag-Erling Smørgrav * 753333ee039SDag-Erling Smørgrav * The second time is after a connection has been established but before 754333ee039SDag-Erling Smørgrav * authentication. activep is initialized to 2 and global config directives 755333ee039SDag-Erling Smørgrav * are ignored since they have already been processed. If the criteria in a 756333ee039SDag-Erling Smørgrav * Match block is met, activep is set and the subsequent directives 757333ee039SDag-Erling Smørgrav * processed and actioned until EOF or another Match block unsets it. Any 758333ee039SDag-Erling Smørgrav * options set are copied into the main server config. 759333ee039SDag-Erling Smørgrav * 760333ee039SDag-Erling Smørgrav * Potential additions/improvements: 761333ee039SDag-Erling Smørgrav * - Add Match support for pre-kex directives, eg Protocol, Ciphers. 762333ee039SDag-Erling Smørgrav * 763333ee039SDag-Erling Smørgrav * - Add a Tag directive (idea from David Leonard) ala pf, eg: 764333ee039SDag-Erling Smørgrav * Match Address 192.168.0.* 765333ee039SDag-Erling Smørgrav * Tag trusted 766333ee039SDag-Erling Smørgrav * Match Group wheel 767333ee039SDag-Erling Smørgrav * Tag trusted 768333ee039SDag-Erling Smørgrav * Match Tag trusted 769333ee039SDag-Erling Smørgrav * AllowTcpForwarding yes 770333ee039SDag-Erling Smørgrav * GatewayPorts clientspecified 771333ee039SDag-Erling Smørgrav * [...] 772333ee039SDag-Erling Smørgrav * 773333ee039SDag-Erling Smørgrav * - Add a PermittedChannelRequests directive 774333ee039SDag-Erling Smørgrav * Match Group shell 775333ee039SDag-Erling Smørgrav * PermittedChannelRequests session,forwarded-tcpip 776333ee039SDag-Erling Smørgrav */ 777333ee039SDag-Erling Smørgrav 778333ee039SDag-Erling Smørgrav static int 779333ee039SDag-Erling Smørgrav match_cfg_line_group(const char *grps, int line, const char *user) 780333ee039SDag-Erling Smørgrav { 781333ee039SDag-Erling Smørgrav int result = 0; 782333ee039SDag-Erling Smørgrav struct passwd *pw; 783333ee039SDag-Erling Smørgrav 784333ee039SDag-Erling Smørgrav if (user == NULL) 785333ee039SDag-Erling Smørgrav goto out; 786333ee039SDag-Erling Smørgrav 787333ee039SDag-Erling Smørgrav if ((pw = getpwnam(user)) == NULL) { 788333ee039SDag-Erling Smørgrav debug("Can't match group at line %d because user %.100s does " 789333ee039SDag-Erling Smørgrav "not exist", line, user); 790333ee039SDag-Erling Smørgrav } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) { 791333ee039SDag-Erling Smørgrav debug("Can't Match group because user %.100s not in any group " 792333ee039SDag-Erling Smørgrav "at line %d", user, line); 793d4af9e69SDag-Erling Smørgrav } else if (ga_match_pattern_list(grps) != 1) { 794d4af9e69SDag-Erling Smørgrav debug("user %.100s does not match group list %.100s at line %d", 795d4af9e69SDag-Erling Smørgrav user, grps, line); 796333ee039SDag-Erling Smørgrav } else { 797d4af9e69SDag-Erling Smørgrav debug("user %.100s matched group list %.100s at line %d", user, 798d4af9e69SDag-Erling Smørgrav grps, line); 799333ee039SDag-Erling Smørgrav result = 1; 800333ee039SDag-Erling Smørgrav } 801333ee039SDag-Erling Smørgrav out: 802333ee039SDag-Erling Smørgrav ga_free(); 803333ee039SDag-Erling Smørgrav return result; 804333ee039SDag-Erling Smørgrav } 805333ee039SDag-Erling Smørgrav 806462c32cbSDag-Erling Smørgrav /* 8076888a9beSDag-Erling Smørgrav * All of the attributes on a single Match line are ANDed together, so we need 808f7167e0eSDag-Erling Smørgrav * to check every attribute and set the result to zero if any attribute does 8096888a9beSDag-Erling Smørgrav * not match. 810462c32cbSDag-Erling Smørgrav */ 811333ee039SDag-Erling Smørgrav static int 812462c32cbSDag-Erling Smørgrav match_cfg_line(char **condition, int line, struct connection_info *ci) 813333ee039SDag-Erling Smørgrav { 814f7167e0eSDag-Erling Smørgrav int result = 1, attributes = 0, port; 815333ee039SDag-Erling Smørgrav char *arg, *attrib, *cp = *condition; 816333ee039SDag-Erling Smørgrav 817462c32cbSDag-Erling Smørgrav if (ci == NULL) 818333ee039SDag-Erling Smørgrav debug3("checking syntax for 'Match %s'", cp); 819333ee039SDag-Erling Smørgrav else 820462c32cbSDag-Erling Smørgrav debug3("checking match for '%s' user %s host %s addr %s " 821462c32cbSDag-Erling Smørgrav "laddr %s lport %d", cp, ci->user ? ci->user : "(null)", 822462c32cbSDag-Erling Smørgrav ci->host ? ci->host : "(null)", 823462c32cbSDag-Erling Smørgrav ci->address ? ci->address : "(null)", 824462c32cbSDag-Erling Smørgrav ci->laddress ? ci->laddress : "(null)", ci->lport); 825333ee039SDag-Erling Smørgrav 826333ee039SDag-Erling Smørgrav while ((attrib = strdelim(&cp)) && *attrib != '\0') { 827f7167e0eSDag-Erling Smørgrav attributes++; 828f7167e0eSDag-Erling Smørgrav if (strcasecmp(attrib, "all") == 0) { 829f7167e0eSDag-Erling Smørgrav if (attributes != 1 || 830f7167e0eSDag-Erling Smørgrav ((arg = strdelim(&cp)) != NULL && *arg != '\0')) { 831f7167e0eSDag-Erling Smørgrav error("'all' cannot be combined with other " 832f7167e0eSDag-Erling Smørgrav "Match attributes"); 833f7167e0eSDag-Erling Smørgrav return -1; 834f7167e0eSDag-Erling Smørgrav } 835f7167e0eSDag-Erling Smørgrav *condition = cp; 836f7167e0eSDag-Erling Smørgrav return 1; 837f7167e0eSDag-Erling Smørgrav } 838333ee039SDag-Erling Smørgrav if ((arg = strdelim(&cp)) == NULL || *arg == '\0') { 839333ee039SDag-Erling Smørgrav error("Missing Match criteria for %s", attrib); 840333ee039SDag-Erling Smørgrav return -1; 841333ee039SDag-Erling Smørgrav } 842333ee039SDag-Erling Smørgrav if (strcasecmp(attrib, "user") == 0) { 843462c32cbSDag-Erling Smørgrav if (ci == NULL || ci->user == NULL) { 844333ee039SDag-Erling Smørgrav result = 0; 845333ee039SDag-Erling Smørgrav continue; 846333ee039SDag-Erling Smørgrav } 847557f75e5SDag-Erling Smørgrav if (match_pattern_list(ci->user, arg, 0) != 1) 848333ee039SDag-Erling Smørgrav result = 0; 849333ee039SDag-Erling Smørgrav else 850333ee039SDag-Erling Smørgrav debug("user %.100s matched 'User %.100s' at " 851462c32cbSDag-Erling Smørgrav "line %d", ci->user, arg, line); 852333ee039SDag-Erling Smørgrav } else if (strcasecmp(attrib, "group") == 0) { 853462c32cbSDag-Erling Smørgrav if (ci == NULL || ci->user == NULL) { 854462c32cbSDag-Erling Smørgrav result = 0; 855462c32cbSDag-Erling Smørgrav continue; 856462c32cbSDag-Erling Smørgrav } 857462c32cbSDag-Erling Smørgrav switch (match_cfg_line_group(arg, line, ci->user)) { 858333ee039SDag-Erling Smørgrav case -1: 859333ee039SDag-Erling Smørgrav return -1; 860333ee039SDag-Erling Smørgrav case 0: 861333ee039SDag-Erling Smørgrav result = 0; 862333ee039SDag-Erling Smørgrav } 863333ee039SDag-Erling Smørgrav } else if (strcasecmp(attrib, "host") == 0) { 864462c32cbSDag-Erling Smørgrav if (ci == NULL || ci->host == NULL) { 865333ee039SDag-Erling Smørgrav result = 0; 866333ee039SDag-Erling Smørgrav continue; 867333ee039SDag-Erling Smørgrav } 868557f75e5SDag-Erling Smørgrav if (match_hostname(ci->host, arg) != 1) 869333ee039SDag-Erling Smørgrav result = 0; 870333ee039SDag-Erling Smørgrav else 871333ee039SDag-Erling Smørgrav debug("connection from %.100s matched 'Host " 872462c32cbSDag-Erling Smørgrav "%.100s' at line %d", ci->host, arg, line); 873333ee039SDag-Erling Smørgrav } else if (strcasecmp(attrib, "address") == 0) { 874462c32cbSDag-Erling Smørgrav if (ci == NULL || ci->address == NULL) { 875462c32cbSDag-Erling Smørgrav result = 0; 876462c32cbSDag-Erling Smørgrav continue; 877462c32cbSDag-Erling Smørgrav } 878462c32cbSDag-Erling Smørgrav switch (addr_match_list(ci->address, arg)) { 879d4af9e69SDag-Erling Smørgrav case 1: 880333ee039SDag-Erling Smørgrav debug("connection from %.100s matched 'Address " 881462c32cbSDag-Erling Smørgrav "%.100s' at line %d", ci->address, arg, line); 882d4af9e69SDag-Erling Smørgrav break; 883d4af9e69SDag-Erling Smørgrav case 0: 884d4af9e69SDag-Erling Smørgrav case -1: 885d4af9e69SDag-Erling Smørgrav result = 0; 886d4af9e69SDag-Erling Smørgrav break; 887d4af9e69SDag-Erling Smørgrav case -2: 888d4af9e69SDag-Erling Smørgrav return -1; 889d4af9e69SDag-Erling Smørgrav } 890462c32cbSDag-Erling Smørgrav } else if (strcasecmp(attrib, "localaddress") == 0){ 891462c32cbSDag-Erling Smørgrav if (ci == NULL || ci->laddress == NULL) { 892462c32cbSDag-Erling Smørgrav result = 0; 893462c32cbSDag-Erling Smørgrav continue; 894462c32cbSDag-Erling Smørgrav } 895462c32cbSDag-Erling Smørgrav switch (addr_match_list(ci->laddress, arg)) { 896462c32cbSDag-Erling Smørgrav case 1: 897462c32cbSDag-Erling Smørgrav debug("connection from %.100s matched " 898462c32cbSDag-Erling Smørgrav "'LocalAddress %.100s' at line %d", 899462c32cbSDag-Erling Smørgrav ci->laddress, arg, line); 900462c32cbSDag-Erling Smørgrav break; 901462c32cbSDag-Erling Smørgrav case 0: 902462c32cbSDag-Erling Smørgrav case -1: 903462c32cbSDag-Erling Smørgrav result = 0; 904462c32cbSDag-Erling Smørgrav break; 905462c32cbSDag-Erling Smørgrav case -2: 906462c32cbSDag-Erling Smørgrav return -1; 907462c32cbSDag-Erling Smørgrav } 908462c32cbSDag-Erling Smørgrav } else if (strcasecmp(attrib, "localport") == 0) { 909462c32cbSDag-Erling Smørgrav if ((port = a2port(arg)) == -1) { 910462c32cbSDag-Erling Smørgrav error("Invalid LocalPort '%s' on Match line", 911462c32cbSDag-Erling Smørgrav arg); 912462c32cbSDag-Erling Smørgrav return -1; 913462c32cbSDag-Erling Smørgrav } 914462c32cbSDag-Erling Smørgrav if (ci == NULL || ci->lport == 0) { 915462c32cbSDag-Erling Smørgrav result = 0; 916462c32cbSDag-Erling Smørgrav continue; 917462c32cbSDag-Erling Smørgrav } 918462c32cbSDag-Erling Smørgrav /* TODO support port lists */ 919462c32cbSDag-Erling Smørgrav if (port == ci->lport) 920462c32cbSDag-Erling Smørgrav debug("connection from %.100s matched " 921462c32cbSDag-Erling Smørgrav "'LocalPort %d' at line %d", 922462c32cbSDag-Erling Smørgrav ci->laddress, port, line); 923462c32cbSDag-Erling Smørgrav else 924462c32cbSDag-Erling Smørgrav result = 0; 925333ee039SDag-Erling Smørgrav } else { 926333ee039SDag-Erling Smørgrav error("Unsupported Match attribute %s", attrib); 927333ee039SDag-Erling Smørgrav return -1; 928333ee039SDag-Erling Smørgrav } 929333ee039SDag-Erling Smørgrav } 930f7167e0eSDag-Erling Smørgrav if (attributes == 0) { 931f7167e0eSDag-Erling Smørgrav error("One or more attributes required for Match"); 932f7167e0eSDag-Erling Smørgrav return -1; 933f7167e0eSDag-Erling Smørgrav } 934462c32cbSDag-Erling Smørgrav if (ci != NULL) 935333ee039SDag-Erling Smørgrav debug3("match %sfound", result ? "" : "not "); 936333ee039SDag-Erling Smørgrav *condition = cp; 937333ee039SDag-Erling Smørgrav return result; 938333ee039SDag-Erling Smørgrav } 939333ee039SDag-Erling Smørgrav 940333ee039SDag-Erling Smørgrav #define WHITESPACE " \t\r\n" 941333ee039SDag-Erling Smørgrav 942e146993eSDag-Erling Smørgrav /* Multistate option parsing */ 943e146993eSDag-Erling Smørgrav struct multistate { 944e146993eSDag-Erling Smørgrav char *key; 945e146993eSDag-Erling Smørgrav int value; 946e146993eSDag-Erling Smørgrav }; 947e146993eSDag-Erling Smørgrav static const struct multistate multistate_addressfamily[] = { 948e146993eSDag-Erling Smørgrav { "inet", AF_INET }, 949e146993eSDag-Erling Smørgrav { "inet6", AF_INET6 }, 950e146993eSDag-Erling Smørgrav { "any", AF_UNSPEC }, 951e146993eSDag-Erling Smørgrav { NULL, -1 } 952e146993eSDag-Erling Smørgrav }; 953e146993eSDag-Erling Smørgrav static const struct multistate multistate_permitrootlogin[] = { 954e146993eSDag-Erling Smørgrav { "without-password", PERMIT_NO_PASSWD }, 955eccfee6eSDag-Erling Smørgrav { "prohibit-password", PERMIT_NO_PASSWD }, 956e146993eSDag-Erling Smørgrav { "forced-commands-only", PERMIT_FORCED_ONLY }, 957e146993eSDag-Erling Smørgrav { "yes", PERMIT_YES }, 958e146993eSDag-Erling Smørgrav { "no", PERMIT_NO }, 959e146993eSDag-Erling Smørgrav { NULL, -1 } 960e146993eSDag-Erling Smørgrav }; 961e146993eSDag-Erling Smørgrav static const struct multistate multistate_compression[] = { 962e146993eSDag-Erling Smørgrav { "delayed", COMP_DELAYED }, 963e146993eSDag-Erling Smørgrav { "yes", COMP_ZLIB }, 964e146993eSDag-Erling Smørgrav { "no", COMP_NONE }, 965e146993eSDag-Erling Smørgrav { NULL, -1 } 966e146993eSDag-Erling Smørgrav }; 967e146993eSDag-Erling Smørgrav static const struct multistate multistate_gatewayports[] = { 968e146993eSDag-Erling Smørgrav { "clientspecified", 2 }, 969e146993eSDag-Erling Smørgrav { "yes", 1 }, 970e146993eSDag-Erling Smørgrav { "no", 0 }, 971e146993eSDag-Erling Smørgrav { NULL, -1 } 972e146993eSDag-Erling Smørgrav }; 973e146993eSDag-Erling Smørgrav static const struct multistate multistate_privsep[] = { 974462c32cbSDag-Erling Smørgrav { "yes", PRIVSEP_NOSANDBOX }, 975462c32cbSDag-Erling Smørgrav { "sandbox", PRIVSEP_ON }, 976462c32cbSDag-Erling Smørgrav { "nosandbox", PRIVSEP_NOSANDBOX }, 977e146993eSDag-Erling Smørgrav { "no", PRIVSEP_OFF }, 978e146993eSDag-Erling Smørgrav { NULL, -1 } 979e146993eSDag-Erling Smørgrav }; 9806888a9beSDag-Erling Smørgrav static const struct multistate multistate_tcpfwd[] = { 9816888a9beSDag-Erling Smørgrav { "yes", FORWARD_ALLOW }, 9826888a9beSDag-Erling Smørgrav { "all", FORWARD_ALLOW }, 9836888a9beSDag-Erling Smørgrav { "no", FORWARD_DENY }, 9846888a9beSDag-Erling Smørgrav { "remote", FORWARD_REMOTE }, 9856888a9beSDag-Erling Smørgrav { "local", FORWARD_LOCAL }, 9866888a9beSDag-Erling Smørgrav { NULL, -1 } 9876888a9beSDag-Erling Smørgrav }; 988e146993eSDag-Erling Smørgrav 989af12a3e7SDag-Erling Smørgrav int 990af12a3e7SDag-Erling Smørgrav process_server_config_line(ServerOptions *options, char *line, 991462c32cbSDag-Erling Smørgrav const char *filename, int linenum, int *activep, 992462c32cbSDag-Erling Smørgrav struct connection_info *connectinfo) 993511b41d2SMark Murray { 994ca3176e7SBrian Feldman char *cp, **charptr, *arg, *p; 995e4a9863fSDag-Erling Smørgrav int cmdline = 0, *intptr, value, value2, n, port; 996d4af9e69SDag-Erling Smørgrav SyslogFacility *log_facility_ptr; 997d4af9e69SDag-Erling Smørgrav LogLevel *log_level_ptr; 998511b41d2SMark Murray ServerOpCodes opcode; 999333ee039SDag-Erling Smørgrav u_int i, flags = 0; 1000333ee039SDag-Erling Smørgrav size_t len; 1001e4a9863fSDag-Erling Smørgrav long long val64; 1002e146993eSDag-Erling Smørgrav const struct multistate *multistate_ptr; 1003511b41d2SMark Murray 1004c2d3a559SKris Kennaway cp = line; 1005333ee039SDag-Erling Smørgrav if ((arg = strdelim(&cp)) == NULL) 1006333ee039SDag-Erling Smørgrav return 0; 1007c2d3a559SKris Kennaway /* Ignore leading whitespace */ 1008c2d3a559SKris Kennaway if (*arg == '\0') 1009c2d3a559SKris Kennaway arg = strdelim(&cp); 1010ca3176e7SBrian Feldman if (!arg || !*arg || *arg == '#') 1011af12a3e7SDag-Erling Smørgrav return 0; 1012ca3176e7SBrian Feldman intptr = NULL; 1013ca3176e7SBrian Feldman charptr = NULL; 1014333ee039SDag-Erling Smørgrav opcode = parse_token(arg, filename, linenum, &flags); 1015333ee039SDag-Erling Smørgrav 1016333ee039SDag-Erling Smørgrav if (activep == NULL) { /* We are processing a command line directive */ 1017333ee039SDag-Erling Smørgrav cmdline = 1; 1018333ee039SDag-Erling Smørgrav activep = &cmdline; 1019333ee039SDag-Erling Smørgrav } 1020333ee039SDag-Erling Smørgrav if (*activep && opcode != sMatch) 1021333ee039SDag-Erling Smørgrav debug3("%s:%d setting %s %s", filename, linenum, arg, cp); 1022333ee039SDag-Erling Smørgrav if (*activep == 0 && !(flags & SSHCFG_MATCH)) { 1023462c32cbSDag-Erling Smørgrav if (connectinfo == NULL) { 1024333ee039SDag-Erling Smørgrav fatal("%s line %d: Directive '%s' is not allowed " 1025333ee039SDag-Erling Smørgrav "within a Match block", filename, linenum, arg); 1026333ee039SDag-Erling Smørgrav } else { /* this is a directive we have already processed */ 1027333ee039SDag-Erling Smørgrav while (arg) 1028333ee039SDag-Erling Smørgrav arg = strdelim(&cp); 1029333ee039SDag-Erling Smørgrav return 0; 1030333ee039SDag-Erling Smørgrav } 1031333ee039SDag-Erling Smørgrav } 1032333ee039SDag-Erling Smørgrav 1033511b41d2SMark Murray switch (opcode) { 1034989dd127SDag-Erling Smørgrav /* Portable-specific options */ 1035cf2b5f3bSDag-Erling Smørgrav case sUsePAM: 1036cf2b5f3bSDag-Erling Smørgrav intptr = &options->use_pam; 1037989dd127SDag-Erling Smørgrav goto parse_flag; 1038989dd127SDag-Erling Smørgrav 1039989dd127SDag-Erling Smørgrav /* Standard Options */ 1040511b41d2SMark Murray case sBadOption: 1041af12a3e7SDag-Erling Smørgrav return -1; 1042511b41d2SMark Murray case sPort: 1043511b41d2SMark Murray /* ignore ports from configfile if cmdline specifies ports */ 1044511b41d2SMark Murray if (options->ports_from_cmdline) 1045af12a3e7SDag-Erling Smørgrav return 0; 1046511b41d2SMark Murray if (options->num_ports >= MAX_PORTS) 1047ca3176e7SBrian Feldman fatal("%s line %d: too many ports.", 1048511b41d2SMark Murray filename, linenum); 1049c2d3a559SKris Kennaway arg = strdelim(&cp); 1050c2d3a559SKris Kennaway if (!arg || *arg == '\0') 1051ca3176e7SBrian Feldman fatal("%s line %d: missing port number.", 1052511b41d2SMark Murray filename, linenum); 1053ca3176e7SBrian Feldman options->ports[options->num_ports++] = a2port(arg); 1054cce7d346SDag-Erling Smørgrav if (options->ports[options->num_ports-1] <= 0) 1055ca3176e7SBrian Feldman fatal("%s line %d: Badly formatted port number.", 1056ca3176e7SBrian Feldman filename, linenum); 1057511b41d2SMark Murray break; 1058511b41d2SMark Murray 1059511b41d2SMark Murray case sServerKeyBits: 1060511b41d2SMark Murray intptr = &options->server_key_bits; 1061511b41d2SMark Murray parse_int: 1062c2d3a559SKris Kennaway arg = strdelim(&cp); 1063ca3176e7SBrian Feldman if (!arg || *arg == '\0') 1064ca3176e7SBrian Feldman fatal("%s line %d: missing integer value.", 1065511b41d2SMark Murray filename, linenum); 1066c2d3a559SKris Kennaway value = atoi(arg); 1067333ee039SDag-Erling Smørgrav if (*activep && *intptr == -1) 1068511b41d2SMark Murray *intptr = value; 1069511b41d2SMark Murray break; 1070511b41d2SMark Murray 1071511b41d2SMark Murray case sLoginGraceTime: 1072511b41d2SMark Murray intptr = &options->login_grace_time; 1073af12a3e7SDag-Erling Smørgrav parse_time: 1074af12a3e7SDag-Erling Smørgrav arg = strdelim(&cp); 1075af12a3e7SDag-Erling Smørgrav if (!arg || *arg == '\0') 1076af12a3e7SDag-Erling Smørgrav fatal("%s line %d: missing time value.", 1077af12a3e7SDag-Erling Smørgrav filename, linenum); 1078af12a3e7SDag-Erling Smørgrav if ((value = convtime(arg)) == -1) 1079af12a3e7SDag-Erling Smørgrav fatal("%s line %d: invalid time value.", 1080af12a3e7SDag-Erling Smørgrav filename, linenum); 1081557f75e5SDag-Erling Smørgrav if (*activep && *intptr == -1) 1082af12a3e7SDag-Erling Smørgrav *intptr = value; 1083af12a3e7SDag-Erling Smørgrav break; 1084511b41d2SMark Murray 1085511b41d2SMark Murray case sKeyRegenerationTime: 1086511b41d2SMark Murray intptr = &options->key_regeneration_time; 1087af12a3e7SDag-Erling Smørgrav goto parse_time; 1088511b41d2SMark Murray 1089511b41d2SMark Murray case sListenAddress: 1090c2d3a559SKris Kennaway arg = strdelim(&cp); 1091aa49c926SDag-Erling Smørgrav if (arg == NULL || *arg == '\0') 1092aa49c926SDag-Erling Smørgrav fatal("%s line %d: missing address", 1093511b41d2SMark Murray filename, linenum); 1094d4ecd108SDag-Erling Smørgrav /* check for bare IPv6 address: no "[]" and 2 or more ":" */ 1095d4ecd108SDag-Erling Smørgrav if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL 1096d4ecd108SDag-Erling Smørgrav && strchr(p+1, ':') != NULL) { 1097557f75e5SDag-Erling Smørgrav queue_listen_addr(options, arg, 0); 1098d4ecd108SDag-Erling Smørgrav break; 1099d4ecd108SDag-Erling Smørgrav } 1100aa49c926SDag-Erling Smørgrav p = hpdelim(&arg); 1101aa49c926SDag-Erling Smørgrav if (p == NULL) 1102aa49c926SDag-Erling Smørgrav fatal("%s line %d: bad address:port usage", 1103ca3176e7SBrian Feldman filename, linenum); 1104aa49c926SDag-Erling Smørgrav p = cleanhostname(p); 1105aa49c926SDag-Erling Smørgrav if (arg == NULL) 1106aa49c926SDag-Erling Smørgrav port = 0; 1107cce7d346SDag-Erling Smørgrav else if ((port = a2port(arg)) <= 0) 1108aa49c926SDag-Erling Smørgrav fatal("%s line %d: bad port number", filename, linenum); 1109ca3176e7SBrian Feldman 1110557f75e5SDag-Erling Smørgrav queue_listen_addr(options, p, port); 1111aa49c926SDag-Erling Smørgrav 1112aa49c926SDag-Erling Smørgrav break; 1113aa49c926SDag-Erling Smørgrav 1114aa49c926SDag-Erling Smørgrav case sAddressFamily: 1115e146993eSDag-Erling Smørgrav intptr = &options->address_family; 1116e146993eSDag-Erling Smørgrav multistate_ptr = multistate_addressfamily; 1117e146993eSDag-Erling Smørgrav parse_multistate: 1118aa49c926SDag-Erling Smørgrav arg = strdelim(&cp); 1119d4ecd108SDag-Erling Smørgrav if (!arg || *arg == '\0') 1120e146993eSDag-Erling Smørgrav fatal("%s line %d: missing argument.", 1121d4ecd108SDag-Erling Smørgrav filename, linenum); 1122e146993eSDag-Erling Smørgrav value = -1; 1123e146993eSDag-Erling Smørgrav for (i = 0; multistate_ptr[i].key != NULL; i++) { 1124e146993eSDag-Erling Smørgrav if (strcasecmp(arg, multistate_ptr[i].key) == 0) { 1125e146993eSDag-Erling Smørgrav value = multistate_ptr[i].value; 1126e146993eSDag-Erling Smørgrav break; 1127e146993eSDag-Erling Smørgrav } 1128e146993eSDag-Erling Smørgrav } 1129e146993eSDag-Erling Smørgrav if (value == -1) 1130e146993eSDag-Erling Smørgrav fatal("%s line %d: unsupported option \"%s\".", 1131aa49c926SDag-Erling Smørgrav filename, linenum, arg); 1132e146993eSDag-Erling Smørgrav if (*activep && *intptr == -1) 1133aa49c926SDag-Erling Smørgrav *intptr = value; 1134511b41d2SMark Murray break; 1135511b41d2SMark Murray 1136511b41d2SMark Murray case sHostKeyFile: 1137ca3176e7SBrian Feldman intptr = &options->num_host_key_files; 1138ca3176e7SBrian Feldman if (*intptr >= MAX_HOSTKEYS) 1139ca3176e7SBrian Feldman fatal("%s line %d: too many host keys specified (max %d).", 1140ca3176e7SBrian Feldman filename, linenum, MAX_HOSTKEYS); 1141ca3176e7SBrian Feldman charptr = &options->host_key_files[*intptr]; 1142c2d3a559SKris Kennaway parse_filename: 1143c2d3a559SKris Kennaway arg = strdelim(&cp); 1144ca3176e7SBrian Feldman if (!arg || *arg == '\0') 1145ca3176e7SBrian Feldman fatal("%s line %d: missing file name.", 1146e8aafc91SKris Kennaway filename, linenum); 1147333ee039SDag-Erling Smørgrav if (*activep && *charptr == NULL) { 1148b15c8340SDag-Erling Smørgrav *charptr = derelativise_path(arg); 1149ca3176e7SBrian Feldman /* increase optional counter */ 1150ca3176e7SBrian Feldman if (intptr != NULL) 1151ca3176e7SBrian Feldman *intptr = *intptr + 1; 1152ca3176e7SBrian Feldman } 1153e8aafc91SKris Kennaway break; 1154e8aafc91SKris Kennaway 1155e4a9863fSDag-Erling Smørgrav case sHostKeyAgent: 1156e4a9863fSDag-Erling Smørgrav charptr = &options->host_key_agent; 1157e4a9863fSDag-Erling Smørgrav arg = strdelim(&cp); 1158e4a9863fSDag-Erling Smørgrav if (!arg || *arg == '\0') 1159e4a9863fSDag-Erling Smørgrav fatal("%s line %d: missing socket name.", 1160e4a9863fSDag-Erling Smørgrav filename, linenum); 1161e4a9863fSDag-Erling Smørgrav if (*activep && *charptr == NULL) 1162e4a9863fSDag-Erling Smørgrav *charptr = !strcmp(arg, SSH_AUTHSOCKET_ENV_NAME) ? 1163e4a9863fSDag-Erling Smørgrav xstrdup(arg) : derelativise_path(arg); 1164e4a9863fSDag-Erling Smørgrav break; 1165e4a9863fSDag-Erling Smørgrav 1166b15c8340SDag-Erling Smørgrav case sHostCertificate: 1167b15c8340SDag-Erling Smørgrav intptr = &options->num_host_cert_files; 1168b15c8340SDag-Erling Smørgrav if (*intptr >= MAX_HOSTKEYS) 1169b15c8340SDag-Erling Smørgrav fatal("%s line %d: too many host certificates " 1170b15c8340SDag-Erling Smørgrav "specified (max %d).", filename, linenum, 1171b15c8340SDag-Erling Smørgrav MAX_HOSTCERTS); 1172b15c8340SDag-Erling Smørgrav charptr = &options->host_cert_files[*intptr]; 1173b15c8340SDag-Erling Smørgrav goto parse_filename; 1174b15c8340SDag-Erling Smørgrav break; 1175b15c8340SDag-Erling Smørgrav 1176e8aafc91SKris Kennaway case sPidFile: 1177e8aafc91SKris Kennaway charptr = &options->pid_file; 1178c2d3a559SKris Kennaway goto parse_filename; 1179511b41d2SMark Murray 1180511b41d2SMark Murray case sPermitRootLogin: 1181511b41d2SMark Murray intptr = &options->permit_root_login; 1182e146993eSDag-Erling Smørgrav multistate_ptr = multistate_permitrootlogin; 1183e146993eSDag-Erling Smørgrav goto parse_multistate; 1184511b41d2SMark Murray 1185511b41d2SMark Murray case sIgnoreRhosts: 1186511b41d2SMark Murray intptr = &options->ignore_rhosts; 1187511b41d2SMark Murray parse_flag: 1188c2d3a559SKris Kennaway arg = strdelim(&cp); 1189ca3176e7SBrian Feldman if (!arg || *arg == '\0') 1190ca3176e7SBrian Feldman fatal("%s line %d: missing yes/no argument.", 1191511b41d2SMark Murray filename, linenum); 1192ca3176e7SBrian Feldman value = 0; /* silence compiler */ 1193c2d3a559SKris Kennaway if (strcmp(arg, "yes") == 0) 1194511b41d2SMark Murray value = 1; 1195c2d3a559SKris Kennaway else if (strcmp(arg, "no") == 0) 1196511b41d2SMark Murray value = 0; 1197ca3176e7SBrian Feldman else 1198ca3176e7SBrian Feldman fatal("%s line %d: Bad yes/no argument: %s", 1199c2d3a559SKris Kennaway filename, linenum, arg); 1200333ee039SDag-Erling Smørgrav if (*activep && *intptr == -1) 1201511b41d2SMark Murray *intptr = value; 1202511b41d2SMark Murray break; 1203511b41d2SMark Murray 1204511b41d2SMark Murray case sIgnoreUserKnownHosts: 1205511b41d2SMark Murray intptr = &options->ignore_user_known_hosts; 1206962a3f4eSSheldon Hearn goto parse_flag; 1207511b41d2SMark Murray 1208511b41d2SMark Murray case sRhostsRSAAuthentication: 1209511b41d2SMark Murray intptr = &options->rhosts_rsa_authentication; 1210511b41d2SMark Murray goto parse_flag; 1211511b41d2SMark Murray 1212ca3176e7SBrian Feldman case sHostbasedAuthentication: 1213ca3176e7SBrian Feldman intptr = &options->hostbased_authentication; 1214ca3176e7SBrian Feldman goto parse_flag; 1215ca3176e7SBrian Feldman 1216ca3176e7SBrian Feldman case sHostbasedUsesNameFromPacketOnly: 1217ca3176e7SBrian Feldman intptr = &options->hostbased_uses_name_from_packet_only; 1218ca3176e7SBrian Feldman goto parse_flag; 1219ca3176e7SBrian Feldman 1220bc5531deSDag-Erling Smørgrav case sHostbasedAcceptedKeyTypes: 1221bc5531deSDag-Erling Smørgrav charptr = &options->hostbased_key_types; 1222bc5531deSDag-Erling Smørgrav parse_keytypes: 1223bc5531deSDag-Erling Smørgrav arg = strdelim(&cp); 1224bc5531deSDag-Erling Smørgrav if (!arg || *arg == '\0') 1225bc5531deSDag-Erling Smørgrav fatal("%s line %d: Missing argument.", 1226bc5531deSDag-Erling Smørgrav filename, linenum); 1227eccfee6eSDag-Erling Smørgrav if (!sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1)) 1228bc5531deSDag-Erling Smørgrav fatal("%s line %d: Bad key types '%s'.", 1229bc5531deSDag-Erling Smørgrav filename, linenum, arg ? arg : "<NONE>"); 1230bc5531deSDag-Erling Smørgrav if (*activep && *charptr == NULL) 1231bc5531deSDag-Erling Smørgrav *charptr = xstrdup(arg); 1232bc5531deSDag-Erling Smørgrav break; 1233bc5531deSDag-Erling Smørgrav 1234eccfee6eSDag-Erling Smørgrav case sHostKeyAlgorithms: 1235eccfee6eSDag-Erling Smørgrav charptr = &options->hostkeyalgorithms; 1236eccfee6eSDag-Erling Smørgrav goto parse_keytypes; 1237eccfee6eSDag-Erling Smørgrav 1238511b41d2SMark Murray case sRSAAuthentication: 1239511b41d2SMark Murray intptr = &options->rsa_authentication; 1240511b41d2SMark Murray goto parse_flag; 1241511b41d2SMark Murray 1242ca3176e7SBrian Feldman case sPubkeyAuthentication: 1243ca3176e7SBrian Feldman intptr = &options->pubkey_authentication; 1244e8aafc91SKris Kennaway goto parse_flag; 1245cf2b5f3bSDag-Erling Smørgrav 1246bc5531deSDag-Erling Smørgrav case sPubkeyAcceptedKeyTypes: 1247bc5531deSDag-Erling Smørgrav charptr = &options->pubkey_key_types; 1248bc5531deSDag-Erling Smørgrav goto parse_keytypes; 1249bc5531deSDag-Erling Smørgrav 1250cb96ab36SAssar Westerlund case sKerberosAuthentication: 1251cb96ab36SAssar Westerlund intptr = &options->kerberos_authentication; 1252511b41d2SMark Murray goto parse_flag; 1253511b41d2SMark Murray 1254af12a3e7SDag-Erling Smørgrav case sKerberosOrLocalPasswd: 1255af12a3e7SDag-Erling Smørgrav intptr = &options->kerberos_or_local_passwd; 1256511b41d2SMark Murray goto parse_flag; 1257511b41d2SMark Murray 1258af12a3e7SDag-Erling Smørgrav case sKerberosTicketCleanup: 1259af12a3e7SDag-Erling Smørgrav intptr = &options->kerberos_ticket_cleanup; 1260511b41d2SMark Murray goto parse_flag; 1261cf2b5f3bSDag-Erling Smørgrav 12621ec0d754SDag-Erling Smørgrav case sKerberosGetAFSToken: 12631ec0d754SDag-Erling Smørgrav intptr = &options->kerberos_get_afs_token; 12641ec0d754SDag-Erling Smørgrav goto parse_flag; 12651ec0d754SDag-Erling Smørgrav 1266cf2b5f3bSDag-Erling Smørgrav case sGssAuthentication: 1267cf2b5f3bSDag-Erling Smørgrav intptr = &options->gss_authentication; 1268fe5fd017SMark Murray goto parse_flag; 1269cf2b5f3bSDag-Erling Smørgrav 1270cf2b5f3bSDag-Erling Smørgrav case sGssCleanupCreds: 1271cf2b5f3bSDag-Erling Smørgrav intptr = &options->gss_cleanup_creds; 1272511b41d2SMark Murray goto parse_flag; 1273511b41d2SMark Murray 1274557f75e5SDag-Erling Smørgrav case sGssStrictAcceptor: 1275557f75e5SDag-Erling Smørgrav intptr = &options->gss_strict_acceptor; 1276557f75e5SDag-Erling Smørgrav goto parse_flag; 1277557f75e5SDag-Erling Smørgrav 1278511b41d2SMark Murray case sPasswordAuthentication: 1279511b41d2SMark Murray intptr = &options->password_authentication; 1280511b41d2SMark Murray goto parse_flag; 1281511b41d2SMark Murray 128209958426SBrian Feldman case sKbdInteractiveAuthentication: 128309958426SBrian Feldman intptr = &options->kbd_interactive_authentication; 128409958426SBrian Feldman goto parse_flag; 128509958426SBrian Feldman 1286ca3176e7SBrian Feldman case sChallengeResponseAuthentication: 1287af12a3e7SDag-Erling Smørgrav intptr = &options->challenge_response_authentication; 1288511b41d2SMark Murray goto parse_flag; 1289511b41d2SMark Murray 1290511b41d2SMark Murray case sPrintMotd: 1291511b41d2SMark Murray intptr = &options->print_motd; 1292511b41d2SMark Murray goto parse_flag; 1293511b41d2SMark Murray 1294ca3176e7SBrian Feldman case sPrintLastLog: 1295ca3176e7SBrian Feldman intptr = &options->print_lastlog; 1296ca3176e7SBrian Feldman goto parse_flag; 1297ca3176e7SBrian Feldman 1298511b41d2SMark Murray case sX11Forwarding: 1299511b41d2SMark Murray intptr = &options->x11_forwarding; 1300511b41d2SMark Murray goto parse_flag; 1301511b41d2SMark Murray 1302511b41d2SMark Murray case sX11DisplayOffset: 1303511b41d2SMark Murray intptr = &options->x11_display_offset; 1304511b41d2SMark Murray goto parse_int; 1305511b41d2SMark Murray 1306af12a3e7SDag-Erling Smørgrav case sX11UseLocalhost: 1307af12a3e7SDag-Erling Smørgrav intptr = &options->x11_use_localhost; 1308af12a3e7SDag-Erling Smørgrav goto parse_flag; 1309af12a3e7SDag-Erling Smørgrav 1310c2d3a559SKris Kennaway case sXAuthLocation: 1311c2d3a559SKris Kennaway charptr = &options->xauth_location; 1312c2d3a559SKris Kennaway goto parse_filename; 1313c2d3a559SKris Kennaway 1314f7167e0eSDag-Erling Smørgrav case sPermitTTY: 1315f7167e0eSDag-Erling Smørgrav intptr = &options->permit_tty; 1316f7167e0eSDag-Erling Smørgrav goto parse_flag; 1317f7167e0eSDag-Erling Smørgrav 1318a0ee8cc6SDag-Erling Smørgrav case sPermitUserRC: 1319a0ee8cc6SDag-Erling Smørgrav intptr = &options->permit_user_rc; 1320a0ee8cc6SDag-Erling Smørgrav goto parse_flag; 1321a0ee8cc6SDag-Erling Smørgrav 1322511b41d2SMark Murray case sStrictModes: 1323511b41d2SMark Murray intptr = &options->strict_modes; 1324511b41d2SMark Murray goto parse_flag; 1325511b41d2SMark Murray 13261ec0d754SDag-Erling Smørgrav case sTCPKeepAlive: 13271ec0d754SDag-Erling Smørgrav intptr = &options->tcp_keep_alive; 1328511b41d2SMark Murray goto parse_flag; 1329511b41d2SMark Murray 1330511b41d2SMark Murray case sEmptyPasswd: 1331511b41d2SMark Murray intptr = &options->permit_empty_passwd; 1332511b41d2SMark Murray goto parse_flag; 1333511b41d2SMark Murray 1334f388f5efSDag-Erling Smørgrav case sPermitUserEnvironment: 1335f388f5efSDag-Erling Smørgrav intptr = &options->permit_user_env; 1336f388f5efSDag-Erling Smørgrav goto parse_flag; 1337f388f5efSDag-Erling Smørgrav 1338511b41d2SMark Murray case sUseLogin: 1339511b41d2SMark Murray intptr = &options->use_login; 1340511b41d2SMark Murray goto parse_flag; 1341511b41d2SMark Murray 134280628bacSDag-Erling Smørgrav case sCompression: 134380628bacSDag-Erling Smørgrav intptr = &options->compression; 1344e146993eSDag-Erling Smørgrav multistate_ptr = multistate_compression; 1345e146993eSDag-Erling Smørgrav goto parse_multistate; 134680628bacSDag-Erling Smørgrav 1347e4a9863fSDag-Erling Smørgrav case sRekeyLimit: 1348e4a9863fSDag-Erling Smørgrav arg = strdelim(&cp); 1349e4a9863fSDag-Erling Smørgrav if (!arg || *arg == '\0') 1350e4a9863fSDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", filename, 1351e4a9863fSDag-Erling Smørgrav linenum); 1352e4a9863fSDag-Erling Smørgrav if (strcmp(arg, "default") == 0) { 1353e4a9863fSDag-Erling Smørgrav val64 = 0; 1354e4a9863fSDag-Erling Smørgrav } else { 1355e4a9863fSDag-Erling Smørgrav if (scan_scaled(arg, &val64) == -1) 1356e4a9863fSDag-Erling Smørgrav fatal("%.200s line %d: Bad number '%s': %s", 1357e4a9863fSDag-Erling Smørgrav filename, linenum, arg, strerror(errno)); 1358e4a9863fSDag-Erling Smørgrav if (val64 != 0 && val64 < 16) 1359e4a9863fSDag-Erling Smørgrav fatal("%.200s line %d: RekeyLimit too small", 1360e4a9863fSDag-Erling Smørgrav filename, linenum); 1361e4a9863fSDag-Erling Smørgrav } 1362e4a9863fSDag-Erling Smørgrav if (*activep && options->rekey_limit == -1) 1363acc1a9efSDag-Erling Smørgrav options->rekey_limit = val64; 1364e4a9863fSDag-Erling Smørgrav if (cp != NULL) { /* optional rekey interval present */ 1365e4a9863fSDag-Erling Smørgrav if (strcmp(cp, "none") == 0) { 1366e4a9863fSDag-Erling Smørgrav (void)strdelim(&cp); /* discard */ 1367e4a9863fSDag-Erling Smørgrav break; 1368e4a9863fSDag-Erling Smørgrav } 1369e4a9863fSDag-Erling Smørgrav intptr = &options->rekey_interval; 1370e4a9863fSDag-Erling Smørgrav goto parse_time; 1371e4a9863fSDag-Erling Smørgrav } 1372e4a9863fSDag-Erling Smørgrav break; 1373e4a9863fSDag-Erling Smørgrav 1374e8aafc91SKris Kennaway case sGatewayPorts: 1375a0ee8cc6SDag-Erling Smørgrav intptr = &options->fwd_opts.gateway_ports; 1376e146993eSDag-Erling Smørgrav multistate_ptr = multistate_gatewayports; 1377e146993eSDag-Erling Smørgrav goto parse_multistate; 1378e8aafc91SKris Kennaway 1379cf2b5f3bSDag-Erling Smørgrav case sUseDNS: 1380cf2b5f3bSDag-Erling Smørgrav intptr = &options->use_dns; 1381ca3176e7SBrian Feldman goto parse_flag; 1382ca3176e7SBrian Feldman 1383511b41d2SMark Murray case sLogFacility: 1384d4af9e69SDag-Erling Smørgrav log_facility_ptr = &options->log_facility; 1385c2d3a559SKris Kennaway arg = strdelim(&cp); 1386c2d3a559SKris Kennaway value = log_facility_number(arg); 1387af12a3e7SDag-Erling Smørgrav if (value == SYSLOG_FACILITY_NOT_SET) 1388ca3176e7SBrian Feldman fatal("%.200s line %d: unsupported log facility '%s'", 1389c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 1390d4af9e69SDag-Erling Smørgrav if (*log_facility_ptr == -1) 1391d4af9e69SDag-Erling Smørgrav *log_facility_ptr = (SyslogFacility) value; 1392511b41d2SMark Murray break; 1393511b41d2SMark Murray 1394511b41d2SMark Murray case sLogLevel: 1395d4af9e69SDag-Erling Smørgrav log_level_ptr = &options->log_level; 1396c2d3a559SKris Kennaway arg = strdelim(&cp); 1397c2d3a559SKris Kennaway value = log_level_number(arg); 1398af12a3e7SDag-Erling Smørgrav if (value == SYSLOG_LEVEL_NOT_SET) 1399ca3176e7SBrian Feldman fatal("%.200s line %d: unsupported log level '%s'", 1400c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 1401d4af9e69SDag-Erling Smørgrav if (*log_level_ptr == -1) 1402d4af9e69SDag-Erling Smørgrav *log_level_ptr = (LogLevel) value; 1403511b41d2SMark Murray break; 1404511b41d2SMark Murray 140509958426SBrian Feldman case sAllowTcpForwarding: 140609958426SBrian Feldman intptr = &options->allow_tcp_forwarding; 14076888a9beSDag-Erling Smørgrav multistate_ptr = multistate_tcpfwd; 14086888a9beSDag-Erling Smørgrav goto parse_multistate; 140909958426SBrian Feldman 1410a0ee8cc6SDag-Erling Smørgrav case sAllowStreamLocalForwarding: 1411a0ee8cc6SDag-Erling Smørgrav intptr = &options->allow_streamlocal_forwarding; 1412a0ee8cc6SDag-Erling Smørgrav multistate_ptr = multistate_tcpfwd; 1413a0ee8cc6SDag-Erling Smørgrav goto parse_multistate; 1414a0ee8cc6SDag-Erling Smørgrav 1415d4af9e69SDag-Erling Smørgrav case sAllowAgentForwarding: 1416d4af9e69SDag-Erling Smørgrav intptr = &options->allow_agent_forwarding; 1417d4af9e69SDag-Erling Smørgrav goto parse_flag; 1418d4af9e69SDag-Erling Smørgrav 141980628bacSDag-Erling Smørgrav case sUsePrivilegeSeparation: 142080628bacSDag-Erling Smørgrav intptr = &use_privsep; 1421e146993eSDag-Erling Smørgrav multistate_ptr = multistate_privsep; 1422e146993eSDag-Erling Smørgrav goto parse_multistate; 142380628bacSDag-Erling Smørgrav 1424511b41d2SMark Murray case sAllowUsers: 1425c2d3a559SKris Kennaway while ((arg = strdelim(&cp)) && *arg != '\0') { 142642f71286SMark Murray if (options->num_allow_users >= MAX_ALLOW_USERS) 1427af12a3e7SDag-Erling Smørgrav fatal("%s line %d: too many allow users.", 1428e8aafc91SKris Kennaway filename, linenum); 1429462c32cbSDag-Erling Smørgrav if (!*activep) 1430462c32cbSDag-Erling Smørgrav continue; 1431a82e551fSDag-Erling Smørgrav options->allow_users[options->num_allow_users++] = 1432a82e551fSDag-Erling Smørgrav xstrdup(arg); 1433511b41d2SMark Murray } 1434511b41d2SMark Murray break; 1435511b41d2SMark Murray 1436511b41d2SMark Murray case sDenyUsers: 1437c2d3a559SKris Kennaway while ((arg = strdelim(&cp)) && *arg != '\0') { 14382803b77eSBrian Feldman if (options->num_deny_users >= MAX_DENY_USERS) 1439af12a3e7SDag-Erling Smørgrav fatal("%s line %d: too many deny users.", 1440e8aafc91SKris Kennaway filename, linenum); 1441462c32cbSDag-Erling Smørgrav if (!*activep) 1442462c32cbSDag-Erling Smørgrav continue; 1443a82e551fSDag-Erling Smørgrav options->deny_users[options->num_deny_users++] = 1444a82e551fSDag-Erling Smørgrav xstrdup(arg); 1445511b41d2SMark Murray } 1446511b41d2SMark Murray break; 1447511b41d2SMark Murray 1448511b41d2SMark Murray case sAllowGroups: 1449c2d3a559SKris Kennaway while ((arg = strdelim(&cp)) && *arg != '\0') { 145042f71286SMark Murray if (options->num_allow_groups >= MAX_ALLOW_GROUPS) 1451af12a3e7SDag-Erling Smørgrav fatal("%s line %d: too many allow groups.", 1452e8aafc91SKris Kennaway filename, linenum); 1453462c32cbSDag-Erling Smørgrav if (!*activep) 1454462c32cbSDag-Erling Smørgrav continue; 1455a82e551fSDag-Erling Smørgrav options->allow_groups[options->num_allow_groups++] = 1456a82e551fSDag-Erling Smørgrav xstrdup(arg); 1457511b41d2SMark Murray } 1458511b41d2SMark Murray break; 1459511b41d2SMark Murray 1460511b41d2SMark Murray case sDenyGroups: 1461c2d3a559SKris Kennaway while ((arg = strdelim(&cp)) && *arg != '\0') { 146242f71286SMark Murray if (options->num_deny_groups >= MAX_DENY_GROUPS) 1463af12a3e7SDag-Erling Smørgrav fatal("%s line %d: too many deny groups.", 1464e8aafc91SKris Kennaway filename, linenum); 1465462c32cbSDag-Erling Smørgrav if (!*activep) 1466462c32cbSDag-Erling Smørgrav continue; 1467462c32cbSDag-Erling Smørgrav options->deny_groups[options->num_deny_groups++] = 1468462c32cbSDag-Erling Smørgrav xstrdup(arg); 1469511b41d2SMark Murray } 1470511b41d2SMark Murray break; 1471511b41d2SMark Murray 1472e8aafc91SKris Kennaway case sCiphers: 1473c2d3a559SKris Kennaway arg = strdelim(&cp); 1474c2d3a559SKris Kennaway if (!arg || *arg == '\0') 1475c322fe35SKris Kennaway fatal("%s line %d: Missing argument.", filename, linenum); 1476eccfee6eSDag-Erling Smørgrav if (!ciphers_valid(*arg == '+' ? arg + 1 : arg)) 1477e8aafc91SKris Kennaway fatal("%s line %d: Bad SSH2 cipher spec '%s'.", 1478c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 1479e8aafc91SKris Kennaway if (options->ciphers == NULL) 1480c2d3a559SKris Kennaway options->ciphers = xstrdup(arg); 1481e8aafc91SKris Kennaway break; 1482e8aafc91SKris Kennaway 1483ca3176e7SBrian Feldman case sMacs: 1484ca3176e7SBrian Feldman arg = strdelim(&cp); 1485ca3176e7SBrian Feldman if (!arg || *arg == '\0') 1486ca3176e7SBrian Feldman fatal("%s line %d: Missing argument.", filename, linenum); 1487eccfee6eSDag-Erling Smørgrav if (!mac_valid(*arg == '+' ? arg + 1 : arg)) 1488ca3176e7SBrian Feldman fatal("%s line %d: Bad SSH2 mac spec '%s'.", 1489ca3176e7SBrian Feldman filename, linenum, arg ? arg : "<NONE>"); 1490ca3176e7SBrian Feldman if (options->macs == NULL) 1491ca3176e7SBrian Feldman options->macs = xstrdup(arg); 1492ca3176e7SBrian Feldman break; 1493ca3176e7SBrian Feldman 14944a421b63SDag-Erling Smørgrav case sKexAlgorithms: 14954a421b63SDag-Erling Smørgrav arg = strdelim(&cp); 14964a421b63SDag-Erling Smørgrav if (!arg || *arg == '\0') 14974a421b63SDag-Erling Smørgrav fatal("%s line %d: Missing argument.", 14984a421b63SDag-Erling Smørgrav filename, linenum); 1499eccfee6eSDag-Erling Smørgrav if (!kex_names_valid(*arg == '+' ? arg + 1 : arg)) 15004a421b63SDag-Erling Smørgrav fatal("%s line %d: Bad SSH2 KexAlgorithms '%s'.", 15014a421b63SDag-Erling Smørgrav filename, linenum, arg ? arg : "<NONE>"); 15024a421b63SDag-Erling Smørgrav if (options->kex_algorithms == NULL) 15034a421b63SDag-Erling Smørgrav options->kex_algorithms = xstrdup(arg); 15044a421b63SDag-Erling Smørgrav break; 15054a421b63SDag-Erling Smørgrav 1506e8aafc91SKris Kennaway case sProtocol: 1507e8aafc91SKris Kennaway intptr = &options->protocol; 1508c2d3a559SKris Kennaway arg = strdelim(&cp); 1509c2d3a559SKris Kennaway if (!arg || *arg == '\0') 1510c322fe35SKris Kennaway fatal("%s line %d: Missing argument.", filename, linenum); 1511c2d3a559SKris Kennaway value = proto_spec(arg); 1512e8aafc91SKris Kennaway if (value == SSH_PROTO_UNKNOWN) 1513e8aafc91SKris Kennaway fatal("%s line %d: Bad protocol spec '%s'.", 1514c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 1515e8aafc91SKris Kennaway if (*intptr == SSH_PROTO_UNKNOWN) 1516e8aafc91SKris Kennaway *intptr = value; 1517e8aafc91SKris Kennaway break; 1518e8aafc91SKris Kennaway 1519c2d3a559SKris Kennaway case sSubsystem: 1520c2d3a559SKris Kennaway if (options->num_subsystems >= MAX_SUBSYSTEMS) { 1521c2d3a559SKris Kennaway fatal("%s line %d: too many subsystems defined.", 1522c2d3a559SKris Kennaway filename, linenum); 1523c2d3a559SKris Kennaway } 1524c2d3a559SKris Kennaway arg = strdelim(&cp); 1525c2d3a559SKris Kennaway if (!arg || *arg == '\0') 1526c2d3a559SKris Kennaway fatal("%s line %d: Missing subsystem name.", 1527c2d3a559SKris Kennaway filename, linenum); 1528333ee039SDag-Erling Smørgrav if (!*activep) { 1529333ee039SDag-Erling Smørgrav arg = strdelim(&cp); 1530333ee039SDag-Erling Smørgrav break; 1531333ee039SDag-Erling Smørgrav } 1532c2d3a559SKris Kennaway for (i = 0; i < options->num_subsystems; i++) 1533c2d3a559SKris Kennaway if (strcmp(arg, options->subsystem_name[i]) == 0) 1534c2d3a559SKris Kennaway fatal("%s line %d: Subsystem '%s' already defined.", 1535c2d3a559SKris Kennaway filename, linenum, arg); 1536c2d3a559SKris Kennaway options->subsystem_name[options->num_subsystems] = xstrdup(arg); 1537c2d3a559SKris Kennaway arg = strdelim(&cp); 1538c2d3a559SKris Kennaway if (!arg || *arg == '\0') 1539c2d3a559SKris Kennaway fatal("%s line %d: Missing subsystem command.", 1540c2d3a559SKris Kennaway filename, linenum); 1541c2d3a559SKris Kennaway options->subsystem_command[options->num_subsystems] = xstrdup(arg); 1542333ee039SDag-Erling Smørgrav 1543333ee039SDag-Erling Smørgrav /* Collect arguments (separate to executable) */ 1544333ee039SDag-Erling Smørgrav p = xstrdup(arg); 1545333ee039SDag-Erling Smørgrav len = strlen(p) + 1; 1546333ee039SDag-Erling Smørgrav while ((arg = strdelim(&cp)) != NULL && *arg != '\0') { 1547333ee039SDag-Erling Smørgrav len += 1 + strlen(arg); 1548557f75e5SDag-Erling Smørgrav p = xreallocarray(p, 1, len); 1549333ee039SDag-Erling Smørgrav strlcat(p, " ", len); 1550333ee039SDag-Erling Smørgrav strlcat(p, arg, len); 1551333ee039SDag-Erling Smørgrav } 1552333ee039SDag-Erling Smørgrav options->subsystem_args[options->num_subsystems] = p; 1553c2d3a559SKris Kennaway options->num_subsystems++; 1554c2d3a559SKris Kennaway break; 1555c2d3a559SKris Kennaway 1556c2d3a559SKris Kennaway case sMaxStartups: 1557c2d3a559SKris Kennaway arg = strdelim(&cp); 1558c2d3a559SKris Kennaway if (!arg || *arg == '\0') 1559c2d3a559SKris Kennaway fatal("%s line %d: Missing MaxStartups spec.", 1560c2d3a559SKris Kennaway filename, linenum); 1561af12a3e7SDag-Erling Smørgrav if ((n = sscanf(arg, "%d:%d:%d", 1562c2d3a559SKris Kennaway &options->max_startups_begin, 1563c2d3a559SKris Kennaway &options->max_startups_rate, 1564af12a3e7SDag-Erling Smørgrav &options->max_startups)) == 3) { 1565c2d3a559SKris Kennaway if (options->max_startups_begin > 1566c2d3a559SKris Kennaway options->max_startups || 1567c2d3a559SKris Kennaway options->max_startups_rate > 100 || 1568c2d3a559SKris Kennaway options->max_startups_rate < 1) 1569c2d3a559SKris Kennaway fatal("%s line %d: Illegal MaxStartups spec.", 1570c2d3a559SKris Kennaway filename, linenum); 1571af12a3e7SDag-Erling Smørgrav } else if (n != 1) 1572af12a3e7SDag-Erling Smørgrav fatal("%s line %d: Illegal MaxStartups spec.", 1573af12a3e7SDag-Erling Smørgrav filename, linenum); 1574af12a3e7SDag-Erling Smørgrav else 1575af12a3e7SDag-Erling Smørgrav options->max_startups = options->max_startups_begin; 1576933ca70fSBrian Feldman break; 1577933ca70fSBrian Feldman 157821e764dfSDag-Erling Smørgrav case sMaxAuthTries: 157921e764dfSDag-Erling Smørgrav intptr = &options->max_authtries; 158021e764dfSDag-Erling Smørgrav goto parse_int; 158121e764dfSDag-Erling Smørgrav 1582d4af9e69SDag-Erling Smørgrav case sMaxSessions: 1583d4af9e69SDag-Erling Smørgrav intptr = &options->max_sessions; 1584d4af9e69SDag-Erling Smørgrav goto parse_int; 1585d4af9e69SDag-Erling Smørgrav 1586ca3176e7SBrian Feldman case sBanner: 1587ca3176e7SBrian Feldman charptr = &options->banner; 1588ca3176e7SBrian Feldman goto parse_filename; 1589d4af9e69SDag-Erling Smørgrav 1590af12a3e7SDag-Erling Smørgrav /* 1591af12a3e7SDag-Erling Smørgrav * These options can contain %X options expanded at 1592af12a3e7SDag-Erling Smørgrav * connect time, so that you can specify paths like: 1593af12a3e7SDag-Erling Smørgrav * 1594af12a3e7SDag-Erling Smørgrav * AuthorizedKeysFile /etc/ssh_keys/%u 1595af12a3e7SDag-Erling Smørgrav */ 1596af12a3e7SDag-Erling Smørgrav case sAuthorizedKeysFile: 1597e146993eSDag-Erling Smørgrav if (*activep && options->num_authkeys_files == 0) { 1598e146993eSDag-Erling Smørgrav while ((arg = strdelim(&cp)) && *arg != '\0') { 1599e146993eSDag-Erling Smørgrav if (options->num_authkeys_files >= 1600e146993eSDag-Erling Smørgrav MAX_AUTHKEYS_FILES) 1601e146993eSDag-Erling Smørgrav fatal("%s line %d: " 1602e146993eSDag-Erling Smørgrav "too many authorized keys files.", 1603e146993eSDag-Erling Smørgrav filename, linenum); 1604e146993eSDag-Erling Smørgrav options->authorized_keys_files[ 1605e146993eSDag-Erling Smørgrav options->num_authkeys_files++] = 1606e146993eSDag-Erling Smørgrav tilde_expand_filename(arg, getuid()); 1607e146993eSDag-Erling Smørgrav } 1608e146993eSDag-Erling Smørgrav } 1609e146993eSDag-Erling Smørgrav return 0; 1610e146993eSDag-Erling Smørgrav 1611e2f6069cSDag-Erling Smørgrav case sAuthorizedPrincipalsFile: 1612e2f6069cSDag-Erling Smørgrav charptr = &options->authorized_principals_file; 16138ad9b54aSDag-Erling Smørgrav arg = strdelim(&cp); 16148ad9b54aSDag-Erling Smørgrav if (!arg || *arg == '\0') 16158ad9b54aSDag-Erling Smørgrav fatal("%s line %d: missing file name.", 16168ad9b54aSDag-Erling Smørgrav filename, linenum); 16178ad9b54aSDag-Erling Smørgrav if (*activep && *charptr == NULL) { 16188ad9b54aSDag-Erling Smørgrav *charptr = tilde_expand_filename(arg, getuid()); 16198ad9b54aSDag-Erling Smørgrav /* increase optional counter */ 16208ad9b54aSDag-Erling Smørgrav if (intptr != NULL) 16218ad9b54aSDag-Erling Smørgrav *intptr = *intptr + 1; 16228ad9b54aSDag-Erling Smørgrav } 16238ad9b54aSDag-Erling Smørgrav break; 1624af12a3e7SDag-Erling Smørgrav 1625ca3176e7SBrian Feldman case sClientAliveInterval: 1626ca3176e7SBrian Feldman intptr = &options->client_alive_interval; 1627af12a3e7SDag-Erling Smørgrav goto parse_time; 1628af12a3e7SDag-Erling Smørgrav 1629ca3176e7SBrian Feldman case sClientAliveCountMax: 1630ca3176e7SBrian Feldman intptr = &options->client_alive_count_max; 1631ca3176e7SBrian Feldman goto parse_int; 1632af12a3e7SDag-Erling Smørgrav 163321e764dfSDag-Erling Smørgrav case sAcceptEnv: 163421e764dfSDag-Erling Smørgrav while ((arg = strdelim(&cp)) && *arg != '\0') { 163521e764dfSDag-Erling Smørgrav if (strchr(arg, '=') != NULL) 163621e764dfSDag-Erling Smørgrav fatal("%s line %d: Invalid environment name.", 163721e764dfSDag-Erling Smørgrav filename, linenum); 163821e764dfSDag-Erling Smørgrav if (options->num_accept_env >= MAX_ACCEPT_ENV) 163921e764dfSDag-Erling Smørgrav fatal("%s line %d: too many allow env.", 164021e764dfSDag-Erling Smørgrav filename, linenum); 1641333ee039SDag-Erling Smørgrav if (!*activep) 1642462c32cbSDag-Erling Smørgrav continue; 164321e764dfSDag-Erling Smørgrav options->accept_env[options->num_accept_env++] = 164421e764dfSDag-Erling Smørgrav xstrdup(arg); 164521e764dfSDag-Erling Smørgrav } 164621e764dfSDag-Erling Smørgrav break; 164721e764dfSDag-Erling Smørgrav 1648b74df5b2SDag-Erling Smørgrav case sPermitTunnel: 1649b74df5b2SDag-Erling Smørgrav intptr = &options->permit_tun; 1650b74df5b2SDag-Erling Smørgrav arg = strdelim(&cp); 1651b74df5b2SDag-Erling Smørgrav if (!arg || *arg == '\0') 1652b74df5b2SDag-Erling Smørgrav fatal("%s line %d: Missing yes/point-to-point/" 1653b74df5b2SDag-Erling Smørgrav "ethernet/no argument.", filename, linenum); 1654d4af9e69SDag-Erling Smørgrav value = -1; 1655d4af9e69SDag-Erling Smørgrav for (i = 0; tunmode_desc[i].val != -1; i++) 1656d4af9e69SDag-Erling Smørgrav if (strcmp(tunmode_desc[i].text, arg) == 0) { 1657d4af9e69SDag-Erling Smørgrav value = tunmode_desc[i].val; 1658d4af9e69SDag-Erling Smørgrav break; 1659d4af9e69SDag-Erling Smørgrav } 1660d4af9e69SDag-Erling Smørgrav if (value == -1) 1661b74df5b2SDag-Erling Smørgrav fatal("%s line %d: Bad yes/point-to-point/ethernet/" 1662b74df5b2SDag-Erling Smørgrav "no argument: %s", filename, linenum, arg); 1663557f75e5SDag-Erling Smørgrav if (*activep && *intptr == -1) 1664b74df5b2SDag-Erling Smørgrav *intptr = value; 1665b74df5b2SDag-Erling Smørgrav break; 1666b74df5b2SDag-Erling Smørgrav 1667333ee039SDag-Erling Smørgrav case sMatch: 1668333ee039SDag-Erling Smørgrav if (cmdline) 1669333ee039SDag-Erling Smørgrav fatal("Match directive not supported as a command-line " 1670333ee039SDag-Erling Smørgrav "option"); 1671462c32cbSDag-Erling Smørgrav value = match_cfg_line(&cp, linenum, connectinfo); 1672333ee039SDag-Erling Smørgrav if (value < 0) 1673333ee039SDag-Erling Smørgrav fatal("%s line %d: Bad Match condition", filename, 1674333ee039SDag-Erling Smørgrav linenum); 1675333ee039SDag-Erling Smørgrav *activep = value; 1676333ee039SDag-Erling Smørgrav break; 1677333ee039SDag-Erling Smørgrav 1678333ee039SDag-Erling Smørgrav case sPermitOpen: 1679333ee039SDag-Erling Smørgrav arg = strdelim(&cp); 1680333ee039SDag-Erling Smørgrav if (!arg || *arg == '\0') 1681333ee039SDag-Erling Smørgrav fatal("%s line %d: missing PermitOpen specification", 1682333ee039SDag-Erling Smørgrav filename, linenum); 1683d4af9e69SDag-Erling Smørgrav n = options->num_permitted_opens; /* modified later */ 1684333ee039SDag-Erling Smørgrav if (strcmp(arg, "any") == 0) { 1685d4af9e69SDag-Erling Smørgrav if (*activep && n == -1) { 1686333ee039SDag-Erling Smørgrav channel_clear_adm_permitted_opens(); 1687333ee039SDag-Erling Smørgrav options->num_permitted_opens = 0; 1688333ee039SDag-Erling Smørgrav } 1689333ee039SDag-Erling Smørgrav break; 1690333ee039SDag-Erling Smørgrav } 1691462c32cbSDag-Erling Smørgrav if (strcmp(arg, "none") == 0) { 1692462c32cbSDag-Erling Smørgrav if (*activep && n == -1) { 1693462c32cbSDag-Erling Smørgrav options->num_permitted_opens = 1; 1694462c32cbSDag-Erling Smørgrav channel_disable_adm_local_opens(); 1695462c32cbSDag-Erling Smørgrav } 1696462c32cbSDag-Erling Smørgrav break; 1697462c32cbSDag-Erling Smørgrav } 1698d4af9e69SDag-Erling Smørgrav if (*activep && n == -1) 1699d4af9e69SDag-Erling Smørgrav channel_clear_adm_permitted_opens(); 1700333ee039SDag-Erling Smørgrav for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) { 1701333ee039SDag-Erling Smørgrav p = hpdelim(&arg); 1702333ee039SDag-Erling Smørgrav if (p == NULL) 1703333ee039SDag-Erling Smørgrav fatal("%s line %d: missing host in PermitOpen", 1704333ee039SDag-Erling Smørgrav filename, linenum); 1705333ee039SDag-Erling Smørgrav p = cleanhostname(p); 1706462c32cbSDag-Erling Smørgrav if (arg == NULL || ((port = permitopen_port(arg)) < 0)) 1707333ee039SDag-Erling Smørgrav fatal("%s line %d: bad port number in " 1708333ee039SDag-Erling Smørgrav "PermitOpen", filename, linenum); 1709d4af9e69SDag-Erling Smørgrav if (*activep && n == -1) 1710333ee039SDag-Erling Smørgrav options->num_permitted_opens = 1711333ee039SDag-Erling Smørgrav channel_add_adm_permitted_opens(p, port); 1712333ee039SDag-Erling Smørgrav } 1713333ee039SDag-Erling Smørgrav break; 1714333ee039SDag-Erling Smørgrav 1715333ee039SDag-Erling Smørgrav case sForceCommand: 1716557f75e5SDag-Erling Smørgrav if (cp == NULL || *cp == '\0') 1717333ee039SDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", filename, 1718333ee039SDag-Erling Smørgrav linenum); 1719333ee039SDag-Erling Smørgrav len = strspn(cp, WHITESPACE); 1720333ee039SDag-Erling Smørgrav if (*activep && options->adm_forced_command == NULL) 1721333ee039SDag-Erling Smørgrav options->adm_forced_command = xstrdup(cp + len); 1722333ee039SDag-Erling Smørgrav return 0; 1723333ee039SDag-Erling Smørgrav 1724d4af9e69SDag-Erling Smørgrav case sChrootDirectory: 1725d4af9e69SDag-Erling Smørgrav charptr = &options->chroot_directory; 1726d4af9e69SDag-Erling Smørgrav 1727d4af9e69SDag-Erling Smørgrav arg = strdelim(&cp); 1728d4af9e69SDag-Erling Smørgrav if (!arg || *arg == '\0') 1729d4af9e69SDag-Erling Smørgrav fatal("%s line %d: missing file name.", 1730d4af9e69SDag-Erling Smørgrav filename, linenum); 1731d4af9e69SDag-Erling Smørgrav if (*activep && *charptr == NULL) 1732d4af9e69SDag-Erling Smørgrav *charptr = xstrdup(arg); 1733d4af9e69SDag-Erling Smørgrav break; 1734d4af9e69SDag-Erling Smørgrav 1735b15c8340SDag-Erling Smørgrav case sTrustedUserCAKeys: 1736b15c8340SDag-Erling Smørgrav charptr = &options->trusted_user_ca_keys; 1737b15c8340SDag-Erling Smørgrav goto parse_filename; 1738b15c8340SDag-Erling Smørgrav 1739b15c8340SDag-Erling Smørgrav case sRevokedKeys: 1740b15c8340SDag-Erling Smørgrav charptr = &options->revoked_keys_file; 1741b15c8340SDag-Erling Smørgrav goto parse_filename; 1742b15c8340SDag-Erling Smørgrav 17434a421b63SDag-Erling Smørgrav case sIPQoS: 17444a421b63SDag-Erling Smørgrav arg = strdelim(&cp); 17454a421b63SDag-Erling Smørgrav if ((value = parse_ipqos(arg)) == -1) 17464a421b63SDag-Erling Smørgrav fatal("%s line %d: Bad IPQoS value: %s", 17474a421b63SDag-Erling Smørgrav filename, linenum, arg); 17484a421b63SDag-Erling Smørgrav arg = strdelim(&cp); 17494a421b63SDag-Erling Smørgrav if (arg == NULL) 17504a421b63SDag-Erling Smørgrav value2 = value; 17514a421b63SDag-Erling Smørgrav else if ((value2 = parse_ipqos(arg)) == -1) 17524a421b63SDag-Erling Smørgrav fatal("%s line %d: Bad IPQoS value: %s", 17534a421b63SDag-Erling Smørgrav filename, linenum, arg); 17544a421b63SDag-Erling Smørgrav if (*activep) { 17554a421b63SDag-Erling Smørgrav options->ip_qos_interactive = value; 17564a421b63SDag-Erling Smørgrav options->ip_qos_bulk = value2; 17574a421b63SDag-Erling Smørgrav } 17584a421b63SDag-Erling Smørgrav break; 17594a421b63SDag-Erling Smørgrav 1760db58a8e4SDag-Erling Smørgrav case sVersionAddendum: 1761557f75e5SDag-Erling Smørgrav if (cp == NULL || *cp == '\0') 1762462c32cbSDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", filename, 1763462c32cbSDag-Erling Smørgrav linenum); 1764462c32cbSDag-Erling Smørgrav len = strspn(cp, WHITESPACE); 1765462c32cbSDag-Erling Smørgrav if (*activep && options->version_addendum == NULL) { 1766462c32cbSDag-Erling Smørgrav if (strcasecmp(cp + len, "none") == 0) 1767462c32cbSDag-Erling Smørgrav options->version_addendum = xstrdup(""); 1768462c32cbSDag-Erling Smørgrav else if (strchr(cp + len, '\r') != NULL) 1769462c32cbSDag-Erling Smørgrav fatal("%.200s line %d: Invalid argument", 1770462c32cbSDag-Erling Smørgrav filename, linenum); 1771462c32cbSDag-Erling Smørgrav else 1772462c32cbSDag-Erling Smørgrav options->version_addendum = xstrdup(cp + len); 1773462c32cbSDag-Erling Smørgrav } 1774462c32cbSDag-Erling Smørgrav return 0; 1775db58a8e4SDag-Erling Smørgrav 17766888a9beSDag-Erling Smørgrav case sAuthorizedKeysCommand: 1777bc5531deSDag-Erling Smørgrav if (cp == NULL) 1778bc5531deSDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", filename, 1779bc5531deSDag-Erling Smørgrav linenum); 17806888a9beSDag-Erling Smørgrav len = strspn(cp, WHITESPACE); 17816888a9beSDag-Erling Smørgrav if (*activep && options->authorized_keys_command == NULL) { 17826888a9beSDag-Erling Smørgrav if (cp[len] != '/' && strcasecmp(cp + len, "none") != 0) 17836888a9beSDag-Erling Smørgrav fatal("%.200s line %d: AuthorizedKeysCommand " 17846888a9beSDag-Erling Smørgrav "must be an absolute path", 17856888a9beSDag-Erling Smørgrav filename, linenum); 17866888a9beSDag-Erling Smørgrav options->authorized_keys_command = xstrdup(cp + len); 17876888a9beSDag-Erling Smørgrav } 17886888a9beSDag-Erling Smørgrav return 0; 17896888a9beSDag-Erling Smørgrav 17906888a9beSDag-Erling Smørgrav case sAuthorizedKeysCommandUser: 17916888a9beSDag-Erling Smørgrav charptr = &options->authorized_keys_command_user; 17926888a9beSDag-Erling Smørgrav 17936888a9beSDag-Erling Smørgrav arg = strdelim(&cp); 1794bc5531deSDag-Erling Smørgrav if (!arg || *arg == '\0') 1795bc5531deSDag-Erling Smørgrav fatal("%s line %d: missing AuthorizedKeysCommandUser " 1796bc5531deSDag-Erling Smørgrav "argument.", filename, linenum); 17976888a9beSDag-Erling Smørgrav if (*activep && *charptr == NULL) 17986888a9beSDag-Erling Smørgrav *charptr = xstrdup(arg); 17996888a9beSDag-Erling Smørgrav break; 18006888a9beSDag-Erling Smørgrav 1801557f75e5SDag-Erling Smørgrav case sAuthorizedPrincipalsCommand: 1802557f75e5SDag-Erling Smørgrav if (cp == NULL) 1803557f75e5SDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", filename, 1804557f75e5SDag-Erling Smørgrav linenum); 1805557f75e5SDag-Erling Smørgrav len = strspn(cp, WHITESPACE); 1806557f75e5SDag-Erling Smørgrav if (*activep && 1807557f75e5SDag-Erling Smørgrav options->authorized_principals_command == NULL) { 1808557f75e5SDag-Erling Smørgrav if (cp[len] != '/' && strcasecmp(cp + len, "none") != 0) 1809557f75e5SDag-Erling Smørgrav fatal("%.200s line %d: " 1810557f75e5SDag-Erling Smørgrav "AuthorizedPrincipalsCommand must be " 1811557f75e5SDag-Erling Smørgrav "an absolute path", filename, linenum); 1812557f75e5SDag-Erling Smørgrav options->authorized_principals_command = 1813557f75e5SDag-Erling Smørgrav xstrdup(cp + len); 1814557f75e5SDag-Erling Smørgrav } 1815557f75e5SDag-Erling Smørgrav return 0; 1816557f75e5SDag-Erling Smørgrav 1817557f75e5SDag-Erling Smørgrav case sAuthorizedPrincipalsCommandUser: 1818557f75e5SDag-Erling Smørgrav charptr = &options->authorized_principals_command_user; 1819557f75e5SDag-Erling Smørgrav 1820557f75e5SDag-Erling Smørgrav arg = strdelim(&cp); 1821557f75e5SDag-Erling Smørgrav if (!arg || *arg == '\0') 1822557f75e5SDag-Erling Smørgrav fatal("%s line %d: missing " 1823557f75e5SDag-Erling Smørgrav "AuthorizedPrincipalsCommandUser argument.", 1824557f75e5SDag-Erling Smørgrav filename, linenum); 1825557f75e5SDag-Erling Smørgrav if (*activep && *charptr == NULL) 1826557f75e5SDag-Erling Smørgrav *charptr = xstrdup(arg); 1827557f75e5SDag-Erling Smørgrav break; 1828557f75e5SDag-Erling Smørgrav 18296888a9beSDag-Erling Smørgrav case sAuthenticationMethods: 1830557f75e5SDag-Erling Smørgrav if (options->num_auth_methods == 0) { 1831*076ad2f8SDag-Erling Smørgrav value = 0; /* seen "any" pseudo-method */ 1832*076ad2f8SDag-Erling Smørgrav value2 = 0; /* sucessfully parsed any method */ 18336888a9beSDag-Erling Smørgrav while ((arg = strdelim(&cp)) && *arg != '\0') { 18346888a9beSDag-Erling Smørgrav if (options->num_auth_methods >= 18356888a9beSDag-Erling Smørgrav MAX_AUTH_METHODS) 18366888a9beSDag-Erling Smørgrav fatal("%s line %d: " 18376888a9beSDag-Erling Smørgrav "too many authentication methods.", 18386888a9beSDag-Erling Smørgrav filename, linenum); 1839*076ad2f8SDag-Erling Smørgrav if (strcmp(arg, "any") == 0) { 1840*076ad2f8SDag-Erling Smørgrav if (options->num_auth_methods > 0) { 1841*076ad2f8SDag-Erling Smørgrav fatal("%s line %d: \"any\" " 1842*076ad2f8SDag-Erling Smørgrav "must appear alone in " 1843*076ad2f8SDag-Erling Smørgrav "AuthenticationMethods", 1844*076ad2f8SDag-Erling Smørgrav filename, linenum); 1845*076ad2f8SDag-Erling Smørgrav } 1846*076ad2f8SDag-Erling Smørgrav value = 1; 1847*076ad2f8SDag-Erling Smørgrav } else if (value) { 1848*076ad2f8SDag-Erling Smørgrav fatal("%s line %d: \"any\" must appear " 1849*076ad2f8SDag-Erling Smørgrav "alone in AuthenticationMethods", 1850*076ad2f8SDag-Erling Smørgrav filename, linenum); 1851*076ad2f8SDag-Erling Smørgrav } else if (auth2_methods_valid(arg, 0) != 0) { 18526888a9beSDag-Erling Smørgrav fatal("%s line %d: invalid " 18536888a9beSDag-Erling Smørgrav "authentication method list.", 18546888a9beSDag-Erling Smørgrav filename, linenum); 1855*076ad2f8SDag-Erling Smørgrav } 1856*076ad2f8SDag-Erling Smørgrav value2 = 1; 1857557f75e5SDag-Erling Smørgrav if (!*activep) 1858557f75e5SDag-Erling Smørgrav continue; 18596888a9beSDag-Erling Smørgrav options->auth_methods[ 18606888a9beSDag-Erling Smørgrav options->num_auth_methods++] = xstrdup(arg); 18616888a9beSDag-Erling Smørgrav } 1862*076ad2f8SDag-Erling Smørgrav if (value2 == 0) { 1863*076ad2f8SDag-Erling Smørgrav fatal("%s line %d: no AuthenticationMethods " 1864*076ad2f8SDag-Erling Smørgrav "specified", filename, linenum); 1865*076ad2f8SDag-Erling Smørgrav } 18666888a9beSDag-Erling Smørgrav } 18676888a9beSDag-Erling Smørgrav return 0; 18686888a9beSDag-Erling Smørgrav 1869a0ee8cc6SDag-Erling Smørgrav case sStreamLocalBindMask: 1870a0ee8cc6SDag-Erling Smørgrav arg = strdelim(&cp); 1871a0ee8cc6SDag-Erling Smørgrav if (!arg || *arg == '\0') 1872557f75e5SDag-Erling Smørgrav fatal("%s line %d: missing StreamLocalBindMask " 1873557f75e5SDag-Erling Smørgrav "argument.", filename, linenum); 1874a0ee8cc6SDag-Erling Smørgrav /* Parse mode in octal format */ 1875a0ee8cc6SDag-Erling Smørgrav value = strtol(arg, &p, 8); 1876a0ee8cc6SDag-Erling Smørgrav if (arg == p || value < 0 || value > 0777) 1877a0ee8cc6SDag-Erling Smørgrav fatal("%s line %d: Bad mask.", filename, linenum); 1878557f75e5SDag-Erling Smørgrav if (*activep) 1879a0ee8cc6SDag-Erling Smørgrav options->fwd_opts.streamlocal_bind_mask = (mode_t)value; 1880a0ee8cc6SDag-Erling Smørgrav break; 1881a0ee8cc6SDag-Erling Smørgrav 1882a0ee8cc6SDag-Erling Smørgrav case sStreamLocalBindUnlink: 1883a0ee8cc6SDag-Erling Smørgrav intptr = &options->fwd_opts.streamlocal_bind_unlink; 1884a0ee8cc6SDag-Erling Smørgrav goto parse_flag; 1885a0ee8cc6SDag-Erling Smørgrav 1886bc5531deSDag-Erling Smørgrav case sFingerprintHash: 1887bc5531deSDag-Erling Smørgrav arg = strdelim(&cp); 1888bc5531deSDag-Erling Smørgrav if (!arg || *arg == '\0') 1889bc5531deSDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", 1890bc5531deSDag-Erling Smørgrav filename, linenum); 1891bc5531deSDag-Erling Smørgrav if ((value = ssh_digest_alg_by_name(arg)) == -1) 1892bc5531deSDag-Erling Smørgrav fatal("%.200s line %d: Invalid hash algorithm \"%s\".", 1893bc5531deSDag-Erling Smørgrav filename, linenum, arg); 1894bc5531deSDag-Erling Smørgrav if (*activep) 1895bc5531deSDag-Erling Smørgrav options->fingerprint_hash = value; 1896bc5531deSDag-Erling Smørgrav break; 1897bc5531deSDag-Erling Smørgrav 1898b2af61ecSKurt Lidl case sUseBlacklist: 1899b2af61ecSKurt Lidl intptr = &options->use_blacklist; 1900b2af61ecSKurt Lidl goto parse_flag; 1901b2af61ecSKurt Lidl 1902af12a3e7SDag-Erling Smørgrav case sDeprecated: 1903cf2b5f3bSDag-Erling Smørgrav logit("%s line %d: Deprecated option %s", 1904cf2b5f3bSDag-Erling Smørgrav filename, linenum, arg); 1905cf2b5f3bSDag-Erling Smørgrav while (arg) 1906cf2b5f3bSDag-Erling Smørgrav arg = strdelim(&cp); 1907cf2b5f3bSDag-Erling Smørgrav break; 1908cf2b5f3bSDag-Erling Smørgrav 1909cf2b5f3bSDag-Erling Smørgrav case sUnsupported: 1910cf2b5f3bSDag-Erling Smørgrav logit("%s line %d: Unsupported option %s", 1911af12a3e7SDag-Erling Smørgrav filename, linenum, arg); 1912af12a3e7SDag-Erling Smørgrav while (arg) 1913af12a3e7SDag-Erling Smørgrav arg = strdelim(&cp); 1914af12a3e7SDag-Erling Smørgrav break; 1915af12a3e7SDag-Erling Smørgrav 191642f71286SMark Murray default: 1917af12a3e7SDag-Erling Smørgrav fatal("%s line %d: Missing handler for opcode %s (%d)", 1918c2d3a559SKris Kennaway filename, linenum, arg, opcode); 1919511b41d2SMark Murray } 1920ca3176e7SBrian Feldman if ((arg = strdelim(&cp)) != NULL && *arg != '\0') 1921ca3176e7SBrian Feldman fatal("%s line %d: garbage at end of line; \"%.200s\".", 1922c2d3a559SKris Kennaway filename, linenum, arg); 1923af12a3e7SDag-Erling Smørgrav return 0; 1924af12a3e7SDag-Erling Smørgrav } 1925af12a3e7SDag-Erling Smørgrav 1926af12a3e7SDag-Erling Smørgrav /* Reads the server configuration file. */ 1927af12a3e7SDag-Erling Smørgrav 1928af12a3e7SDag-Erling Smørgrav void 192921e764dfSDag-Erling Smørgrav load_server_config(const char *filename, Buffer *conf) 1930af12a3e7SDag-Erling Smørgrav { 1931462c32cbSDag-Erling Smørgrav char line[4096], *cp; 1932a82e551fSDag-Erling Smørgrav FILE *f; 1933462c32cbSDag-Erling Smørgrav int lineno = 0; 1934af12a3e7SDag-Erling Smørgrav 193521e764dfSDag-Erling Smørgrav debug2("%s: filename %s", __func__, filename); 193621e764dfSDag-Erling Smørgrav if ((f = fopen(filename, "r")) == NULL) { 1937af12a3e7SDag-Erling Smørgrav perror(filename); 1938af12a3e7SDag-Erling Smørgrav exit(1); 1939af12a3e7SDag-Erling Smørgrav } 194021e764dfSDag-Erling Smørgrav buffer_clear(conf); 1941af12a3e7SDag-Erling Smørgrav while (fgets(line, sizeof(line), f)) { 1942462c32cbSDag-Erling Smørgrav lineno++; 1943462c32cbSDag-Erling Smørgrav if (strlen(line) == sizeof(line) - 1) 1944462c32cbSDag-Erling Smørgrav fatal("%s line %d too long", filename, lineno); 194521e764dfSDag-Erling Smørgrav /* 194621e764dfSDag-Erling Smørgrav * Trim out comments and strip whitespace 194721e764dfSDag-Erling Smørgrav * NB - preserve newlines, they are needed to reproduce 194821e764dfSDag-Erling Smørgrav * line numbers later for error messages 194921e764dfSDag-Erling Smørgrav */ 195021e764dfSDag-Erling Smørgrav if ((cp = strchr(line, '#')) != NULL) 195121e764dfSDag-Erling Smørgrav memcpy(cp, "\n", 2); 195221e764dfSDag-Erling Smørgrav cp = line + strspn(line, " \t\r"); 195321e764dfSDag-Erling Smørgrav 195421e764dfSDag-Erling Smørgrav buffer_append(conf, cp, strlen(cp)); 195521e764dfSDag-Erling Smørgrav } 195621e764dfSDag-Erling Smørgrav buffer_append(conf, "\0", 1); 195721e764dfSDag-Erling Smørgrav fclose(f); 195821e764dfSDag-Erling Smørgrav debug2("%s: done config len = %d", __func__, buffer_len(conf)); 195921e764dfSDag-Erling Smørgrav } 196021e764dfSDag-Erling Smørgrav 196121e764dfSDag-Erling Smørgrav void 1962462c32cbSDag-Erling Smørgrav parse_server_match_config(ServerOptions *options, 1963462c32cbSDag-Erling Smørgrav struct connection_info *connectinfo) 196421e764dfSDag-Erling Smørgrav { 1965333ee039SDag-Erling Smørgrav ServerOptions mo; 1966333ee039SDag-Erling Smørgrav 1967333ee039SDag-Erling Smørgrav initialize_server_options(&mo); 1968462c32cbSDag-Erling Smørgrav parse_server_config(&mo, "reprocess config", &cfg, connectinfo); 1969d4af9e69SDag-Erling Smørgrav copy_set_server_options(options, &mo, 0); 1970333ee039SDag-Erling Smørgrav } 1971333ee039SDag-Erling Smørgrav 1972462c32cbSDag-Erling Smørgrav int parse_server_match_testspec(struct connection_info *ci, char *spec) 1973462c32cbSDag-Erling Smørgrav { 1974462c32cbSDag-Erling Smørgrav char *p; 1975462c32cbSDag-Erling Smørgrav 1976462c32cbSDag-Erling Smørgrav while ((p = strsep(&spec, ",")) && *p != '\0') { 1977462c32cbSDag-Erling Smørgrav if (strncmp(p, "addr=", 5) == 0) { 1978462c32cbSDag-Erling Smørgrav ci->address = xstrdup(p + 5); 1979462c32cbSDag-Erling Smørgrav } else if (strncmp(p, "host=", 5) == 0) { 1980462c32cbSDag-Erling Smørgrav ci->host = xstrdup(p + 5); 1981462c32cbSDag-Erling Smørgrav } else if (strncmp(p, "user=", 5) == 0) { 1982462c32cbSDag-Erling Smørgrav ci->user = xstrdup(p + 5); 1983462c32cbSDag-Erling Smørgrav } else if (strncmp(p, "laddr=", 6) == 0) { 1984462c32cbSDag-Erling Smørgrav ci->laddress = xstrdup(p + 6); 1985462c32cbSDag-Erling Smørgrav } else if (strncmp(p, "lport=", 6) == 0) { 1986462c32cbSDag-Erling Smørgrav ci->lport = a2port(p + 6); 1987462c32cbSDag-Erling Smørgrav if (ci->lport == -1) { 1988462c32cbSDag-Erling Smørgrav fprintf(stderr, "Invalid port '%s' in test mode" 1989462c32cbSDag-Erling Smørgrav " specification %s\n", p+6, p); 1990462c32cbSDag-Erling Smørgrav return -1; 1991462c32cbSDag-Erling Smørgrav } 1992462c32cbSDag-Erling Smørgrav } else { 1993462c32cbSDag-Erling Smørgrav fprintf(stderr, "Invalid test mode specification %s\n", 1994462c32cbSDag-Erling Smørgrav p); 1995462c32cbSDag-Erling Smørgrav return -1; 1996462c32cbSDag-Erling Smørgrav } 1997462c32cbSDag-Erling Smørgrav } 1998462c32cbSDag-Erling Smørgrav return 0; 1999462c32cbSDag-Erling Smørgrav } 2000462c32cbSDag-Erling Smørgrav 2001462c32cbSDag-Erling Smørgrav /* 2002462c32cbSDag-Erling Smørgrav * returns 1 for a complete spec, 0 for partial spec and -1 for an 2003462c32cbSDag-Erling Smørgrav * empty spec. 2004462c32cbSDag-Erling Smørgrav */ 2005462c32cbSDag-Erling Smørgrav int server_match_spec_complete(struct connection_info *ci) 2006462c32cbSDag-Erling Smørgrav { 2007462c32cbSDag-Erling Smørgrav if (ci->user && ci->host && ci->address) 2008462c32cbSDag-Erling Smørgrav return 1; /* complete */ 2009462c32cbSDag-Erling Smørgrav if (!ci->user && !ci->host && !ci->address) 2010462c32cbSDag-Erling Smørgrav return -1; /* empty */ 2011462c32cbSDag-Erling Smørgrav return 0; /* partial */ 2012462c32cbSDag-Erling Smørgrav } 2013462c32cbSDag-Erling Smørgrav 2014d4af9e69SDag-Erling Smørgrav /* 2015d4af9e69SDag-Erling Smørgrav * Copy any supported values that are set. 2016d4af9e69SDag-Erling Smørgrav * 20177aee6ffeSDag-Erling Smørgrav * If the preauth flag is set, we do not bother copying the string or 2018d4af9e69SDag-Erling Smørgrav * array values that are not used pre-authentication, because any that we 2019d4af9e69SDag-Erling Smørgrav * do use must be explictly sent in mm_getpwnamallow(). 2020d4af9e69SDag-Erling Smørgrav */ 2021333ee039SDag-Erling Smørgrav void 2022d4af9e69SDag-Erling Smørgrav copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) 2023333ee039SDag-Erling Smørgrav { 2024f7167e0eSDag-Erling Smørgrav #define M_CP_INTOPT(n) do {\ 2025f7167e0eSDag-Erling Smørgrav if (src->n != -1) \ 2026f7167e0eSDag-Erling Smørgrav dst->n = src->n; \ 2027f7167e0eSDag-Erling Smørgrav } while (0) 2028f7167e0eSDag-Erling Smørgrav 2029d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(password_authentication); 2030d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(gss_authentication); 2031d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(rsa_authentication); 2032d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(pubkey_authentication); 2033d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(kerberos_authentication); 2034d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(hostbased_authentication); 2035e2f6069cSDag-Erling Smørgrav M_CP_INTOPT(hostbased_uses_name_from_packet_only); 2036d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(kbd_interactive_authentication); 2037d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(permit_root_login); 2038cce7d346SDag-Erling Smørgrav M_CP_INTOPT(permit_empty_passwd); 2039d4af9e69SDag-Erling Smørgrav 2040d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(allow_tcp_forwarding); 2041a0ee8cc6SDag-Erling Smørgrav M_CP_INTOPT(allow_streamlocal_forwarding); 2042d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(allow_agent_forwarding); 2043e2f6069cSDag-Erling Smørgrav M_CP_INTOPT(permit_tun); 2044a0ee8cc6SDag-Erling Smørgrav M_CP_INTOPT(fwd_opts.gateway_ports); 2045*076ad2f8SDag-Erling Smørgrav M_CP_INTOPT(fwd_opts.streamlocal_bind_unlink); 2046d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(x11_display_offset); 2047d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(x11_forwarding); 2048d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(x11_use_localhost); 2049f7167e0eSDag-Erling Smørgrav M_CP_INTOPT(permit_tty); 2050a0ee8cc6SDag-Erling Smørgrav M_CP_INTOPT(permit_user_rc); 2051d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(max_sessions); 2052d4af9e69SDag-Erling Smørgrav M_CP_INTOPT(max_authtries); 20534a421b63SDag-Erling Smørgrav M_CP_INTOPT(ip_qos_interactive); 20544a421b63SDag-Erling Smørgrav M_CP_INTOPT(ip_qos_bulk); 2055e4a9863fSDag-Erling Smørgrav M_CP_INTOPT(rekey_limit); 2056e4a9863fSDag-Erling Smørgrav M_CP_INTOPT(rekey_interval); 2057d4af9e69SDag-Erling Smørgrav 2058*076ad2f8SDag-Erling Smørgrav /* 2059*076ad2f8SDag-Erling Smørgrav * The bind_mask is a mode_t that may be unsigned, so we can't use 2060*076ad2f8SDag-Erling Smørgrav * M_CP_INTOPT - it does a signed comparison that causes compiler 2061*076ad2f8SDag-Erling Smørgrav * warnings. 2062*076ad2f8SDag-Erling Smørgrav */ 2063*076ad2f8SDag-Erling Smørgrav if (src->fwd_opts.streamlocal_bind_mask != (mode_t)-1) { 2064*076ad2f8SDag-Erling Smørgrav dst->fwd_opts.streamlocal_bind_mask = 2065*076ad2f8SDag-Erling Smørgrav src->fwd_opts.streamlocal_bind_mask; 2066*076ad2f8SDag-Erling Smørgrav } 2067*076ad2f8SDag-Erling Smørgrav 2068f7167e0eSDag-Erling Smørgrav /* M_CP_STROPT and M_CP_STRARRAYOPT should not appear before here */ 2069f7167e0eSDag-Erling Smørgrav #define M_CP_STROPT(n) do {\ 2070f7167e0eSDag-Erling Smørgrav if (src->n != NULL && dst->n != src->n) { \ 2071f7167e0eSDag-Erling Smørgrav free(dst->n); \ 2072f7167e0eSDag-Erling Smørgrav dst->n = src->n; \ 2073f7167e0eSDag-Erling Smørgrav } \ 2074f7167e0eSDag-Erling Smørgrav } while(0) 2075f7167e0eSDag-Erling Smørgrav #define M_CP_STRARRAYOPT(n, num_n) do {\ 2076f7167e0eSDag-Erling Smørgrav if (src->num_n != 0) { \ 2077f7167e0eSDag-Erling Smørgrav for (dst->num_n = 0; dst->num_n < src->num_n; dst->num_n++) \ 2078f7167e0eSDag-Erling Smørgrav dst->n[dst->num_n] = xstrdup(src->n[dst->num_n]); \ 2079f7167e0eSDag-Erling Smørgrav } \ 2080f7167e0eSDag-Erling Smørgrav } while(0) 2081f7167e0eSDag-Erling Smørgrav 2082e146993eSDag-Erling Smørgrav /* See comment in servconf.h */ 2083e146993eSDag-Erling Smørgrav COPY_MATCH_STRING_OPTS(); 2084e146993eSDag-Erling Smørgrav 2085acc1a9efSDag-Erling Smørgrav /* Arguments that accept '+...' need to be expanded */ 2086acc1a9efSDag-Erling Smørgrav assemble_algorithms(dst); 2087acc1a9efSDag-Erling Smørgrav 2088e146993eSDag-Erling Smørgrav /* 2089e146993eSDag-Erling Smørgrav * The only things that should be below this point are string options 2090e146993eSDag-Erling Smørgrav * which are only used after authentication. 2091e146993eSDag-Erling Smørgrav */ 2092d4af9e69SDag-Erling Smørgrav if (preauth) 2093d4af9e69SDag-Erling Smørgrav return; 2094e146993eSDag-Erling Smørgrav 2095acc1a9efSDag-Erling Smørgrav /* These options may be "none" to clear a global setting */ 2096d4af9e69SDag-Erling Smørgrav M_CP_STROPT(adm_forced_command); 2097acc1a9efSDag-Erling Smørgrav if (option_clear_or_none(dst->adm_forced_command)) { 2098acc1a9efSDag-Erling Smørgrav free(dst->adm_forced_command); 2099acc1a9efSDag-Erling Smørgrav dst->adm_forced_command = NULL; 2100acc1a9efSDag-Erling Smørgrav } 2101d4af9e69SDag-Erling Smørgrav M_CP_STROPT(chroot_directory); 2102acc1a9efSDag-Erling Smørgrav if (option_clear_or_none(dst->chroot_directory)) { 2103acc1a9efSDag-Erling Smørgrav free(dst->chroot_directory); 2104acc1a9efSDag-Erling Smørgrav dst->chroot_directory = NULL; 2105acc1a9efSDag-Erling Smørgrav } 2106333ee039SDag-Erling Smørgrav } 2107d4af9e69SDag-Erling Smørgrav 2108d4af9e69SDag-Erling Smørgrav #undef M_CP_INTOPT 2109d4af9e69SDag-Erling Smørgrav #undef M_CP_STROPT 2110e146993eSDag-Erling Smørgrav #undef M_CP_STRARRAYOPT 2111333ee039SDag-Erling Smørgrav 2112333ee039SDag-Erling Smørgrav void 2113333ee039SDag-Erling Smørgrav parse_server_config(ServerOptions *options, const char *filename, Buffer *conf, 2114462c32cbSDag-Erling Smørgrav struct connection_info *connectinfo) 2115333ee039SDag-Erling Smørgrav { 2116333ee039SDag-Erling Smørgrav int active, linenum, bad_options = 0; 211721e764dfSDag-Erling Smørgrav char *cp, *obuf, *cbuf; 211821e764dfSDag-Erling Smørgrav 211921e764dfSDag-Erling Smørgrav debug2("%s: config %s len %d", __func__, filename, buffer_len(conf)); 212021e764dfSDag-Erling Smørgrav 2121*076ad2f8SDag-Erling Smørgrav if ((obuf = cbuf = sshbuf_dup_string(conf)) == NULL) 2122*076ad2f8SDag-Erling Smørgrav fatal("%s: sshbuf_dup_string failed", __func__); 2123462c32cbSDag-Erling Smørgrav active = connectinfo ? 0 : 1; 212421e764dfSDag-Erling Smørgrav linenum = 1; 212521e764dfSDag-Erling Smørgrav while ((cp = strsep(&cbuf, "\n")) != NULL) { 212621e764dfSDag-Erling Smørgrav if (process_server_config_line(options, cp, filename, 2127462c32cbSDag-Erling Smørgrav linenum++, &active, connectinfo) != 0) 2128af12a3e7SDag-Erling Smørgrav bad_options++; 2129511b41d2SMark Murray } 2130e4a9863fSDag-Erling Smørgrav free(obuf); 2131ca3176e7SBrian Feldman if (bad_options > 0) 2132af12a3e7SDag-Erling Smørgrav fatal("%s: terminating, %d bad configuration options", 2133511b41d2SMark Murray filename, bad_options); 2134557f75e5SDag-Erling Smørgrav process_queued_listen_addrs(options); 2135511b41d2SMark Murray } 2136d4af9e69SDag-Erling Smørgrav 2137d4af9e69SDag-Erling Smørgrav static const char * 2138e146993eSDag-Erling Smørgrav fmt_multistate_int(int val, const struct multistate *m) 2139d4af9e69SDag-Erling Smørgrav { 2140e146993eSDag-Erling Smørgrav u_int i; 2141e146993eSDag-Erling Smørgrav 2142e146993eSDag-Erling Smørgrav for (i = 0; m[i].key != NULL; i++) { 2143e146993eSDag-Erling Smørgrav if (m[i].value == val) 2144e146993eSDag-Erling Smørgrav return m[i].key; 2145e146993eSDag-Erling Smørgrav } 2146d4af9e69SDag-Erling Smørgrav return "UNKNOWN"; 2147d4af9e69SDag-Erling Smørgrav } 2148e146993eSDag-Erling Smørgrav 2149e146993eSDag-Erling Smørgrav static const char * 2150e146993eSDag-Erling Smørgrav fmt_intarg(ServerOpCodes code, int val) 2151e146993eSDag-Erling Smørgrav { 2152e146993eSDag-Erling Smørgrav if (val == -1) 2153e146993eSDag-Erling Smørgrav return "unset"; 2154e146993eSDag-Erling Smørgrav switch (code) { 2155e146993eSDag-Erling Smørgrav case sAddressFamily: 2156e146993eSDag-Erling Smørgrav return fmt_multistate_int(val, multistate_addressfamily); 2157e146993eSDag-Erling Smørgrav case sPermitRootLogin: 2158e146993eSDag-Erling Smørgrav return fmt_multistate_int(val, multistate_permitrootlogin); 2159e146993eSDag-Erling Smørgrav case sGatewayPorts: 2160e146993eSDag-Erling Smørgrav return fmt_multistate_int(val, multistate_gatewayports); 2161e146993eSDag-Erling Smørgrav case sCompression: 2162e146993eSDag-Erling Smørgrav return fmt_multistate_int(val, multistate_compression); 2163e146993eSDag-Erling Smørgrav case sUsePrivilegeSeparation: 2164e146993eSDag-Erling Smørgrav return fmt_multistate_int(val, multistate_privsep); 21656888a9beSDag-Erling Smørgrav case sAllowTcpForwarding: 21666888a9beSDag-Erling Smørgrav return fmt_multistate_int(val, multistate_tcpfwd); 2167a0ee8cc6SDag-Erling Smørgrav case sAllowStreamLocalForwarding: 2168a0ee8cc6SDag-Erling Smørgrav return fmt_multistate_int(val, multistate_tcpfwd); 2169bc5531deSDag-Erling Smørgrav case sFingerprintHash: 2170bc5531deSDag-Erling Smørgrav return ssh_digest_alg_name(val); 2171e146993eSDag-Erling Smørgrav case sProtocol: 2172d4af9e69SDag-Erling Smørgrav switch (val) { 2173d4af9e69SDag-Erling Smørgrav case SSH_PROTO_1: 2174d4af9e69SDag-Erling Smørgrav return "1"; 2175d4af9e69SDag-Erling Smørgrav case SSH_PROTO_2: 2176d4af9e69SDag-Erling Smørgrav return "2"; 2177d4af9e69SDag-Erling Smørgrav case (SSH_PROTO_1|SSH_PROTO_2): 2178d4af9e69SDag-Erling Smørgrav return "2,1"; 2179d4af9e69SDag-Erling Smørgrav default: 2180d4af9e69SDag-Erling Smørgrav return "UNKNOWN"; 2181d4af9e69SDag-Erling Smørgrav } 2182e146993eSDag-Erling Smørgrav default: 2183d4af9e69SDag-Erling Smørgrav switch (val) { 2184d4af9e69SDag-Erling Smørgrav case 0: 2185d4af9e69SDag-Erling Smørgrav return "no"; 2186d4af9e69SDag-Erling Smørgrav case 1: 2187d4af9e69SDag-Erling Smørgrav return "yes"; 2188e146993eSDag-Erling Smørgrav default: 2189d4af9e69SDag-Erling Smørgrav return "UNKNOWN"; 2190d4af9e69SDag-Erling Smørgrav } 2191e146993eSDag-Erling Smørgrav } 2192e146993eSDag-Erling Smørgrav } 2193d4af9e69SDag-Erling Smørgrav 2194d4af9e69SDag-Erling Smørgrav static const char * 2195d4af9e69SDag-Erling Smørgrav lookup_opcode_name(ServerOpCodes code) 2196d4af9e69SDag-Erling Smørgrav { 2197d4af9e69SDag-Erling Smørgrav u_int i; 2198d4af9e69SDag-Erling Smørgrav 2199d4af9e69SDag-Erling Smørgrav for (i = 0; keywords[i].name != NULL; i++) 2200d4af9e69SDag-Erling Smørgrav if (keywords[i].opcode == code) 2201d4af9e69SDag-Erling Smørgrav return(keywords[i].name); 2202d4af9e69SDag-Erling Smørgrav return "UNKNOWN"; 2203d4af9e69SDag-Erling Smørgrav } 2204d4af9e69SDag-Erling Smørgrav 2205d4af9e69SDag-Erling Smørgrav static void 2206d4af9e69SDag-Erling Smørgrav dump_cfg_int(ServerOpCodes code, int val) 2207d4af9e69SDag-Erling Smørgrav { 2208d4af9e69SDag-Erling Smørgrav printf("%s %d\n", lookup_opcode_name(code), val); 2209d4af9e69SDag-Erling Smørgrav } 2210d4af9e69SDag-Erling Smørgrav 2211d4af9e69SDag-Erling Smørgrav static void 2212557f75e5SDag-Erling Smørgrav dump_cfg_oct(ServerOpCodes code, int val) 2213557f75e5SDag-Erling Smørgrav { 2214557f75e5SDag-Erling Smørgrav printf("%s 0%o\n", lookup_opcode_name(code), val); 2215557f75e5SDag-Erling Smørgrav } 2216557f75e5SDag-Erling Smørgrav 2217557f75e5SDag-Erling Smørgrav static void 2218d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(ServerOpCodes code, int val) 2219d4af9e69SDag-Erling Smørgrav { 2220d4af9e69SDag-Erling Smørgrav printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val)); 2221d4af9e69SDag-Erling Smørgrav } 2222d4af9e69SDag-Erling Smørgrav 2223d4af9e69SDag-Erling Smørgrav static void 2224d4af9e69SDag-Erling Smørgrav dump_cfg_string(ServerOpCodes code, const char *val) 2225d4af9e69SDag-Erling Smørgrav { 2226d4af9e69SDag-Erling Smørgrav if (val == NULL) 2227d4af9e69SDag-Erling Smørgrav return; 2228bc5531deSDag-Erling Smørgrav printf("%s %s\n", lookup_opcode_name(code), 2229bc5531deSDag-Erling Smørgrav val == NULL ? "none" : val); 2230d4af9e69SDag-Erling Smørgrav } 2231d4af9e69SDag-Erling Smørgrav 2232d4af9e69SDag-Erling Smørgrav static void 2233d4af9e69SDag-Erling Smørgrav dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals) 2234d4af9e69SDag-Erling Smørgrav { 2235d4af9e69SDag-Erling Smørgrav u_int i; 2236d4af9e69SDag-Erling Smørgrav 2237d4af9e69SDag-Erling Smørgrav for (i = 0; i < count; i++) 2238d4af9e69SDag-Erling Smørgrav printf("%s %s\n", lookup_opcode_name(code), vals[i]); 2239d4af9e69SDag-Erling Smørgrav } 2240d4af9e69SDag-Erling Smørgrav 2241e146993eSDag-Erling Smørgrav static void 2242e146993eSDag-Erling Smørgrav dump_cfg_strarray_oneline(ServerOpCodes code, u_int count, char **vals) 2243e146993eSDag-Erling Smørgrav { 2244e146993eSDag-Erling Smørgrav u_int i; 2245e146993eSDag-Erling Smørgrav 2246*076ad2f8SDag-Erling Smørgrav if (count <= 0 && code != sAuthenticationMethods) 2247557f75e5SDag-Erling Smørgrav return; 2248e146993eSDag-Erling Smørgrav printf("%s", lookup_opcode_name(code)); 2249e146993eSDag-Erling Smørgrav for (i = 0; i < count; i++) 2250e146993eSDag-Erling Smørgrav printf(" %s", vals[i]); 2251*076ad2f8SDag-Erling Smørgrav if (code == sAuthenticationMethods && count == 0) 2252*076ad2f8SDag-Erling Smørgrav printf(" any"); 2253e146993eSDag-Erling Smørgrav printf("\n"); 2254e146993eSDag-Erling Smørgrav } 2255e146993eSDag-Erling Smørgrav 2256d4af9e69SDag-Erling Smørgrav void 2257d4af9e69SDag-Erling Smørgrav dump_config(ServerOptions *o) 2258d4af9e69SDag-Erling Smørgrav { 2259d4af9e69SDag-Erling Smørgrav u_int i; 2260d4af9e69SDag-Erling Smørgrav int ret; 2261d4af9e69SDag-Erling Smørgrav struct addrinfo *ai; 2262d4af9e69SDag-Erling Smørgrav char addr[NI_MAXHOST], port[NI_MAXSERV], *s = NULL; 2263557f75e5SDag-Erling Smørgrav char *laddr1 = xstrdup(""), *laddr2 = NULL; 2264d4af9e69SDag-Erling Smørgrav 2265d4af9e69SDag-Erling Smørgrav /* these are usually at the top of the config */ 2266d4af9e69SDag-Erling Smørgrav for (i = 0; i < o->num_ports; i++) 2267d4af9e69SDag-Erling Smørgrav printf("port %d\n", o->ports[i]); 2268d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sProtocol, o->protocol); 2269d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sAddressFamily, o->address_family); 2270d4af9e69SDag-Erling Smørgrav 2271557f75e5SDag-Erling Smørgrav /* 2272557f75e5SDag-Erling Smørgrav * ListenAddress must be after Port. add_one_listen_addr pushes 2273557f75e5SDag-Erling Smørgrav * addresses onto a stack, so to maintain ordering we need to 2274557f75e5SDag-Erling Smørgrav * print these in reverse order. 2275557f75e5SDag-Erling Smørgrav */ 2276d4af9e69SDag-Erling Smørgrav for (ai = o->listen_addrs; ai; ai = ai->ai_next) { 2277d4af9e69SDag-Erling Smørgrav if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr, 2278d4af9e69SDag-Erling Smørgrav sizeof(addr), port, sizeof(port), 2279d4af9e69SDag-Erling Smørgrav NI_NUMERICHOST|NI_NUMERICSERV)) != 0) { 2280d4af9e69SDag-Erling Smørgrav error("getnameinfo failed: %.100s", 2281d4af9e69SDag-Erling Smørgrav (ret != EAI_SYSTEM) ? gai_strerror(ret) : 2282d4af9e69SDag-Erling Smørgrav strerror(errno)); 2283d4af9e69SDag-Erling Smørgrav } else { 2284557f75e5SDag-Erling Smørgrav laddr2 = laddr1; 2285d4af9e69SDag-Erling Smørgrav if (ai->ai_family == AF_INET6) 2286557f75e5SDag-Erling Smørgrav xasprintf(&laddr1, "listenaddress [%s]:%s\n%s", 2287557f75e5SDag-Erling Smørgrav addr, port, laddr2); 2288d4af9e69SDag-Erling Smørgrav else 2289557f75e5SDag-Erling Smørgrav xasprintf(&laddr1, "listenaddress %s:%s\n%s", 2290557f75e5SDag-Erling Smørgrav addr, port, laddr2); 2291557f75e5SDag-Erling Smørgrav free(laddr2); 2292d4af9e69SDag-Erling Smørgrav } 2293d4af9e69SDag-Erling Smørgrav } 2294557f75e5SDag-Erling Smørgrav printf("%s", laddr1); 2295557f75e5SDag-Erling Smørgrav free(laddr1); 2296d4af9e69SDag-Erling Smørgrav 2297d4af9e69SDag-Erling Smørgrav /* integer arguments */ 2298cce7d346SDag-Erling Smørgrav #ifdef USE_PAM 2299557f75e5SDag-Erling Smørgrav dump_cfg_fmtint(sUsePAM, o->use_pam); 2300cce7d346SDag-Erling Smørgrav #endif 2301d4af9e69SDag-Erling Smørgrav dump_cfg_int(sServerKeyBits, o->server_key_bits); 2302d4af9e69SDag-Erling Smørgrav dump_cfg_int(sLoginGraceTime, o->login_grace_time); 2303d4af9e69SDag-Erling Smørgrav dump_cfg_int(sKeyRegenerationTime, o->key_regeneration_time); 2304d4af9e69SDag-Erling Smørgrav dump_cfg_int(sX11DisplayOffset, o->x11_display_offset); 2305d4af9e69SDag-Erling Smørgrav dump_cfg_int(sMaxAuthTries, o->max_authtries); 2306cce7d346SDag-Erling Smørgrav dump_cfg_int(sMaxSessions, o->max_sessions); 2307d4af9e69SDag-Erling Smørgrav dump_cfg_int(sClientAliveInterval, o->client_alive_interval); 2308d4af9e69SDag-Erling Smørgrav dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max); 2309557f75e5SDag-Erling Smørgrav dump_cfg_oct(sStreamLocalBindMask, o->fwd_opts.streamlocal_bind_mask); 2310d4af9e69SDag-Erling Smørgrav 2311d4af9e69SDag-Erling Smørgrav /* formatted integer arguments */ 2312d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login); 2313d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts); 2314d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts); 2315d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sRhostsRSAAuthentication, o->rhosts_rsa_authentication); 2316d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication); 2317d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly, 2318d4af9e69SDag-Erling Smørgrav o->hostbased_uses_name_from_packet_only); 2319d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sRSAAuthentication, o->rsa_authentication); 2320d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication); 2321cce7d346SDag-Erling Smørgrav #ifdef KRB5 2322d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication); 2323d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd); 2324d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup); 2325cce7d346SDag-Erling Smørgrav # ifdef USE_AFS 2326d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); 2327cce7d346SDag-Erling Smørgrav # endif 2328cce7d346SDag-Erling Smørgrav #endif 2329cce7d346SDag-Erling Smørgrav #ifdef GSSAPI 2330d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); 2331d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); 2332cce7d346SDag-Erling Smørgrav #endif 2333d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); 2334d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sKbdInteractiveAuthentication, 2335d4af9e69SDag-Erling Smørgrav o->kbd_interactive_authentication); 2336d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sChallengeResponseAuthentication, 2337d4af9e69SDag-Erling Smørgrav o->challenge_response_authentication); 2338d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sPrintMotd, o->print_motd); 2339acc1a9efSDag-Erling Smørgrav #ifndef DISABLE_LASTLOG 2340d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sPrintLastLog, o->print_lastlog); 2341acc1a9efSDag-Erling Smørgrav #endif 2342d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding); 2343d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost); 2344f7167e0eSDag-Erling Smørgrav dump_cfg_fmtint(sPermitTTY, o->permit_tty); 2345a0ee8cc6SDag-Erling Smørgrav dump_cfg_fmtint(sPermitUserRC, o->permit_user_rc); 2346d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sStrictModes, o->strict_modes); 2347d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive); 2348d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd); 2349d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env); 2350d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sUseLogin, o->use_login); 2351d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sCompression, o->compression); 2352a0ee8cc6SDag-Erling Smørgrav dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports); 2353d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sUseDNS, o->use_dns); 2354d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); 2355557f75e5SDag-Erling Smørgrav dump_cfg_fmtint(sAllowAgentForwarding, o->allow_agent_forwarding); 2356a0ee8cc6SDag-Erling Smørgrav dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding); 2357*076ad2f8SDag-Erling Smørgrav dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink); 2358d4af9e69SDag-Erling Smørgrav dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); 2359bc5531deSDag-Erling Smørgrav dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); 2360b2af61ecSKurt Lidl dump_cfg_fmtint(sUseBlacklist, o->use_blacklist); 2361d4af9e69SDag-Erling Smørgrav 2362d4af9e69SDag-Erling Smørgrav /* string arguments */ 2363d4af9e69SDag-Erling Smørgrav dump_cfg_string(sPidFile, o->pid_file); 2364d4af9e69SDag-Erling Smørgrav dump_cfg_string(sXAuthLocation, o->xauth_location); 2365bc5531deSDag-Erling Smørgrav dump_cfg_string(sCiphers, o->ciphers ? o->ciphers : KEX_SERVER_ENCRYPT); 2366bc5531deSDag-Erling Smørgrav dump_cfg_string(sMacs, o->macs ? o->macs : KEX_SERVER_MAC); 2367d4af9e69SDag-Erling Smørgrav dump_cfg_string(sBanner, o->banner); 2368d4af9e69SDag-Erling Smørgrav dump_cfg_string(sForceCommand, o->adm_forced_command); 2369b15c8340SDag-Erling Smørgrav dump_cfg_string(sChrootDirectory, o->chroot_directory); 2370b15c8340SDag-Erling Smørgrav dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys); 2371b15c8340SDag-Erling Smørgrav dump_cfg_string(sRevokedKeys, o->revoked_keys_file); 2372e2f6069cSDag-Erling Smørgrav dump_cfg_string(sAuthorizedPrincipalsFile, 2373e2f6069cSDag-Erling Smørgrav o->authorized_principals_file); 2374557f75e5SDag-Erling Smørgrav dump_cfg_string(sVersionAddendum, *o->version_addendum == '\0' 2375557f75e5SDag-Erling Smørgrav ? "none" : o->version_addendum); 23766888a9beSDag-Erling Smørgrav dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command); 23776888a9beSDag-Erling Smørgrav dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user); 2378557f75e5SDag-Erling Smørgrav dump_cfg_string(sAuthorizedPrincipalsCommand, o->authorized_principals_command); 2379557f75e5SDag-Erling Smørgrav dump_cfg_string(sAuthorizedPrincipalsCommandUser, o->authorized_principals_command_user); 2380e4a9863fSDag-Erling Smørgrav dump_cfg_string(sHostKeyAgent, o->host_key_agent); 2381bc5531deSDag-Erling Smørgrav dump_cfg_string(sKexAlgorithms, 2382bc5531deSDag-Erling Smørgrav o->kex_algorithms ? o->kex_algorithms : KEX_SERVER_KEX); 2383bc5531deSDag-Erling Smørgrav dump_cfg_string(sHostbasedAcceptedKeyTypes, o->hostbased_key_types ? 2384bc5531deSDag-Erling Smørgrav o->hostbased_key_types : KEX_DEFAULT_PK_ALG); 2385eccfee6eSDag-Erling Smørgrav dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms ? 2386eccfee6eSDag-Erling Smørgrav o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG); 2387bc5531deSDag-Erling Smørgrav dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ? 2388bc5531deSDag-Erling Smørgrav o->pubkey_key_types : KEX_DEFAULT_PK_ALG); 2389d4af9e69SDag-Erling Smørgrav 2390d4af9e69SDag-Erling Smørgrav /* string arguments requiring a lookup */ 2391d4af9e69SDag-Erling Smørgrav dump_cfg_string(sLogLevel, log_level_name(o->log_level)); 2392d4af9e69SDag-Erling Smørgrav dump_cfg_string(sLogFacility, log_facility_name(o->log_facility)); 2393d4af9e69SDag-Erling Smørgrav 2394d4af9e69SDag-Erling Smørgrav /* string array arguments */ 2395e146993eSDag-Erling Smørgrav dump_cfg_strarray_oneline(sAuthorizedKeysFile, o->num_authkeys_files, 2396e146993eSDag-Erling Smørgrav o->authorized_keys_files); 2397d4af9e69SDag-Erling Smørgrav dump_cfg_strarray(sHostKeyFile, o->num_host_key_files, 2398d4af9e69SDag-Erling Smørgrav o->host_key_files); 2399557f75e5SDag-Erling Smørgrav dump_cfg_strarray(sHostCertificate, o->num_host_cert_files, 2400b15c8340SDag-Erling Smørgrav o->host_cert_files); 2401d4af9e69SDag-Erling Smørgrav dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users); 2402d4af9e69SDag-Erling Smørgrav dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users); 2403d4af9e69SDag-Erling Smørgrav dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups); 2404d4af9e69SDag-Erling Smørgrav dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups); 2405d4af9e69SDag-Erling Smørgrav dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env); 24066888a9beSDag-Erling Smørgrav dump_cfg_strarray_oneline(sAuthenticationMethods, 24076888a9beSDag-Erling Smørgrav o->num_auth_methods, o->auth_methods); 2408d4af9e69SDag-Erling Smørgrav 2409d4af9e69SDag-Erling Smørgrav /* other arguments */ 2410d4af9e69SDag-Erling Smørgrav for (i = 0; i < o->num_subsystems; i++) 2411d4af9e69SDag-Erling Smørgrav printf("subsystem %s %s\n", o->subsystem_name[i], 2412d4af9e69SDag-Erling Smørgrav o->subsystem_args[i]); 2413d4af9e69SDag-Erling Smørgrav 2414d4af9e69SDag-Erling Smørgrav printf("maxstartups %d:%d:%d\n", o->max_startups_begin, 2415d4af9e69SDag-Erling Smørgrav o->max_startups_rate, o->max_startups); 2416d4af9e69SDag-Erling Smørgrav 2417d4af9e69SDag-Erling Smørgrav for (i = 0; tunmode_desc[i].val != -1; i++) 2418d4af9e69SDag-Erling Smørgrav if (tunmode_desc[i].val == o->permit_tun) { 2419d4af9e69SDag-Erling Smørgrav s = tunmode_desc[i].text; 2420d4af9e69SDag-Erling Smørgrav break; 2421d4af9e69SDag-Erling Smørgrav } 2422d4af9e69SDag-Erling Smørgrav dump_cfg_string(sPermitTunnel, s); 2423d4af9e69SDag-Erling Smørgrav 2424e146993eSDag-Erling Smørgrav printf("ipqos %s ", iptos2str(o->ip_qos_interactive)); 2425e146993eSDag-Erling Smørgrav printf("%s\n", iptos2str(o->ip_qos_bulk)); 24264a421b63SDag-Erling Smørgrav 2427acc1a9efSDag-Erling Smørgrav printf("rekeylimit %llu %d\n", (unsigned long long)o->rekey_limit, 2428e4a9863fSDag-Erling Smørgrav o->rekey_interval); 2429e4a9863fSDag-Erling Smørgrav 2430d4af9e69SDag-Erling Smørgrav channel_print_adm_permitted_opens(); 2431d4af9e69SDag-Erling Smørgrav } 2432