freebsd-dev/crypto/openssh/servconf.c

2716 lines
80 KiB
C
Raw Normal View History

2015-08-26 09:25:17 +00:00
2019-02-05 15:03:53 +00:00
/* $OpenBSD: servconf.c,v 1.342 2018/09/20 23:40:16 djm Exp $ */
2000-02-24 14:29:47 +00:00
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
*
* As far as I am concerned, the code I have written for this software
* can be used freely for any purpose. Any derived versions of this
* software must be clearly marked as such, and if the derived work is
* incompatible with the protocol description in the RFC file, it must be
* called by a name other than "ssh" or "Secure Shell".
2000-02-24 14:29:47 +00:00
*/
#include "includes.h"
2006-09-30 13:38:06 +00:00
__RCSID("$FreeBSD$");
2000-02-24 14:29:47 +00:00
2006-09-30 13:38:06 +00:00
#include <sys/types.h>
#include <sys/socket.h>
2018-05-06 12:27:04 +00:00
#ifdef HAVE_SYS_SYSCTL_H
#include <sys/sysctl.h>
#endif
2006-09-30 13:38:06 +00:00
2011-02-17 11:47:40 +00:00
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
2018-05-06 12:27:04 +00:00
#ifdef HAVE_NET_ROUTE_H
#include <net/route.h>
#endif
2011-02-17 11:47:40 +00:00
2013-09-18 17:27:38 +00:00
#include <ctype.h>
2006-09-30 13:38:06 +00:00
#include <netdb.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
2015-07-02 13:15:34 +00:00
#include <limits.h>
2006-09-30 13:38:06 +00:00
#include <stdarg.h>
2008-07-23 09:33:08 +00:00
#include <errno.h>
2013-09-18 17:27:38 +00:00
#ifdef HAVE_UTIL_H
#include <util.h>
#endif
2006-09-30 13:38:06 +00:00
2008-07-23 09:33:08 +00:00
#include "openbsd-compat/sys-queue.h"
2006-09-30 13:38:06 +00:00
#include "xmalloc.h"
2000-02-24 14:29:47 +00:00
#include "ssh.h"
2001-05-04 04:14:23 +00:00
#include "log.h"
2018-08-28 10:47:58 +00:00
#include "sshbuf.h"
2015-01-05 16:09:55 +00:00
#include "misc.h"
2000-02-24 14:29:47 +00:00
#include "servconf.h"
#include "compat.h"
2001-05-04 04:14:23 +00:00
#include "pathnames.h"
#include "cipher.h"
2018-08-28 10:47:58 +00:00
#include "sshkey.h"
2001-05-04 04:14:23 +00:00
#include "kex.h"
#include "mac.h"
2006-09-30 13:38:06 +00:00
#include "match.h"
#include "channels.h"
#include "groupaccess.h"
2012-08-29 15:55:54 +00:00
#include "canohost.h"
#include "packet.h"
2018-08-28 10:47:58 +00:00
#include "ssherr.h"
2013-03-22 11:19:48 +00:00
#include "hostfile.h"
#include "auth.h"
2015-07-02 13:15:34 +00:00
#include "myproposal.h"
#include "digest.h"
#include "version.h"
2001-05-04 04:14:23 +00:00
2018-05-06 12:27:04 +00:00
static void add_listen_addr(ServerOptions *, const char *,
const char *, int);
static void add_one_listen_addr(ServerOptions *, const char *,
const char *, int);
2000-02-24 14:29:47 +00:00
/* Use of privilege separation or not */
extern int use_privsep;
2018-08-28 10:47:58 +00:00
extern struct sshbuf *cfg;
2000-02-24 14:29:47 +00:00
/* Initializes the server options to their default values. */
void
2000-02-24 14:29:47 +00:00
initialize_server_options(ServerOptions *options)
{
memset(options, 0, sizeof(*options));
2002-06-27 22:42:11 +00:00
/* Portable-specific options */
options->use_pam = -1;
2002-06-27 22:42:11 +00:00
/* Standard Options */
2000-02-24 14:29:47 +00:00
options->num_ports = 0;
options->ports_from_cmdline = 0;
2015-07-02 13:18:50 +00:00
options->queued_listen_addrs = NULL;
options->num_queued_listens = 0;
2000-02-24 14:29:47 +00:00
options->listen_addrs = NULL;
2018-05-06 12:27:04 +00:00
options->num_listen_addrs = 0;
2005-06-05 15:46:09 +00:00
options->address_family = -1;
2018-05-06 12:27:04 +00:00
options->routing_domain = NULL;
2001-05-04 04:14:23 +00:00
options->num_host_key_files = 0;
2010-03-08 11:19:52 +00:00
options->num_host_cert_files = 0;
2013-09-18 17:27:38 +00:00
options->host_key_agent = NULL;
options->pid_file = NULL;
2000-02-24 14:29:47 +00:00
options->login_grace_time = -1;
2001-05-04 04:14:23 +00:00
options->permit_root_login = PERMIT_NOT_SET;
2000-02-24 14:29:47 +00:00
options->ignore_rhosts = -1;
options->ignore_user_known_hosts = -1;
options->print_motd = -1;
2001-05-04 04:14:23 +00:00
options->print_lastlog = -1;
2000-02-24 14:29:47 +00:00
options->x11_forwarding = -1;
options->x11_display_offset = -1;
2002-03-18 10:09:43 +00:00
options->x11_use_localhost = -1;
2014-01-30 10:56:49 +00:00
options->permit_tty = -1;
2015-01-05 16:09:55 +00:00
options->permit_user_rc = -1;
options->xauth_location = NULL;
2000-02-24 14:29:47 +00:00
options->strict_modes = -1;
2004-02-26 10:52:33 +00:00
options->tcp_keep_alive = -1;
2002-03-18 10:09:43 +00:00
options->log_facility = SYSLOG_FACILITY_NOT_SET;
options->log_level = SYSLOG_LEVEL_NOT_SET;
2001-05-04 04:14:23 +00:00
options->hostbased_authentication = -1;
options->hostbased_uses_name_from_packet_only = -1;
2015-07-02 13:15:34 +00:00
options->hostbased_key_types = NULL;
2015-08-26 09:25:17 +00:00
options->hostkeyalgorithms = NULL;
2001-05-04 04:14:23 +00:00
options->pubkey_authentication = -1;
2015-07-02 13:15:34 +00:00
options->pubkey_key_types = NULL;
options->kerberos_authentication = -1;
2002-03-18 10:09:43 +00:00
options->kerberos_or_local_passwd = -1;
options->kerberos_ticket_cleanup = -1;
2004-02-26 10:52:33 +00:00
options->kerberos_get_afs_token = -1;
options->gss_authentication=-1;
options->gss_cleanup_creds = -1;
2015-07-02 13:18:50 +00:00
options->gss_strict_acceptor = -1;
2000-02-24 14:29:47 +00:00
options->password_authentication = -1;
options->kbd_interactive_authentication = -1;
2002-03-18 10:09:43 +00:00
options->challenge_response_authentication = -1;
2000-02-24 14:29:47 +00:00
options->permit_empty_passwd = -1;
2002-10-29 10:16:02 +00:00
options->permit_user_env = -1;
2018-08-28 10:47:58 +00:00
options->permit_user_env_whitelist = NULL;
options->compression = -1;
2013-09-18 17:27:38 +00:00
options->rekey_limit = -1;
options->rekey_interval = -1;
options->allow_tcp_forwarding = -1;
2015-01-05 16:09:55 +00:00
options->allow_streamlocal_forwarding = -1;
2008-07-23 09:33:08 +00:00
options->allow_agent_forwarding = -1;
2000-02-24 14:29:47 +00:00
options->num_allow_users = 0;
options->num_deny_users = 0;
options->num_allow_groups = 0;
options->num_deny_groups = 0;
options->ciphers = NULL;
2001-05-04 04:14:23 +00:00
options->macs = NULL;
2011-02-17 11:47:40 +00:00
options->kex_algorithms = NULL;
2019-02-05 15:03:53 +00:00
options->ca_sign_algorithms = NULL;
2015-01-05 16:09:55 +00:00
options->fwd_opts.gateway_ports = -1;
options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
options->fwd_opts.streamlocal_bind_unlink = -1;
options->num_subsystems = 0;
options->max_startups_begin = -1;
options->max_startups_rate = -1;
options->max_startups = -1;
2004-10-28 16:11:31 +00:00
options->max_authtries = -1;
2008-07-23 09:33:08 +00:00
options->max_sessions = -1;
2001-05-04 04:14:23 +00:00
options->banner = NULL;
options->use_dns = -1;
2001-05-04 04:14:23 +00:00
options->client_alive_interval = -1;
options->client_alive_count_max = -1;
2011-09-28 08:14:41 +00:00
options->num_authkeys_files = 0;
2004-10-28 16:11:31 +00:00
options->num_accept_env = 0;
2018-08-28 10:47:58 +00:00
options->num_setenv = 0;
2006-03-22 20:41:37 +00:00
options->permit_tun = -1;
2018-05-06 12:24:45 +00:00
options->permitted_opens = NULL;
2018-08-28 10:47:58 +00:00
options->permitted_listens = NULL;
2006-09-30 13:38:06 +00:00
options->adm_forced_command = NULL;
options->chroot_directory = NULL;
2013-03-22 11:19:48 +00:00
options->authorized_keys_command = NULL;
options->authorized_keys_command_user = NULL;
2010-03-08 11:19:52 +00:00
options->revoked_keys_file = NULL;
options->trusted_user_ca_keys = NULL;
2010-11-08 10:45:44 +00:00
options->authorized_principals_file = NULL;
2015-07-02 13:18:50 +00:00
options->authorized_principals_command = NULL;
options->authorized_principals_command_user = NULL;
2011-02-17 11:47:40 +00:00
options->ip_qos_interactive = -1;
options->ip_qos_bulk = -1;
2012-08-29 15:55:54 +00:00
options->version_addendum = NULL;
2015-07-02 13:15:34 +00:00
options->fingerprint_hash = -1;
2017-01-31 12:33:47 +00:00
options->disable_forwarding = -1;
2018-05-06 12:24:45 +00:00
options->expose_userauth_info = -1;
options->use_blacklist = -1;
2015-07-02 13:15:34 +00:00
}
/* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
static int
option_clear_or_none(const char *o)
{
return o == NULL || strcasecmp(o, "none") == 0;
2000-02-24 14:29:47 +00:00
}
2016-03-10 20:10:25 +00:00
static void
assemble_algorithms(ServerOptions *o)
{
2019-02-05 15:03:53 +00:00
char *all_cipher, *all_mac, *all_kex, *all_key, *all_sig;
2018-08-28 10:47:58 +00:00
int r;
all_cipher = cipher_alg_list(',', 0);
all_mac = mac_alg_list(',');
all_kex = kex_alg_list(',');
all_key = sshkey_alg_list(0, 0, 1, ',');
2019-02-05 15:03:53 +00:00
all_sig = sshkey_alg_list(0, 1, 1, ',');
2018-08-28 10:47:58 +00:00
#define ASSEMBLE(what, defaults, all) \
do { \
if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \
fatal("%s: %s: %s", __func__, #what, ssh_err(r)); \
} while (0)
ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, all_cipher);
ASSEMBLE(macs, KEX_SERVER_MAC, all_mac);
ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, all_kex);
ASSEMBLE(hostkeyalgorithms, KEX_DEFAULT_PK_ALG, all_key);
ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key);
ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key);
2019-02-05 15:03:53 +00:00
ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, all_sig);
2018-08-28 10:47:58 +00:00
#undef ASSEMBLE
free(all_cipher);
free(all_mac);
free(all_kex);
free(all_key);
2019-02-05 15:03:53 +00:00
free(all_sig);
2016-03-10 20:10:25 +00:00
}
2018-05-06 12:27:04 +00:00
static void
array_append(const char *file, const int line, const char *directive,
char ***array, u_int *lp, const char *s)
{
if (*lp >= INT_MAX)
fatal("%s line %d: Too many %s entries", file, line, directive);
*array = xrecallocarray(*array, *lp, *lp + 1, sizeof(**array));
(*array)[*lp] = xstrdup(s);
(*lp)++;
}
2018-05-11 13:22:43 +00:00
static const char *defaultkey = "[default]";
2018-05-06 12:27:04 +00:00
void
servconf_add_hostkey(const char *file, const int line,
ServerOptions *options, const char *path)
{
char *apath = derelativise_path(path);
2018-05-11 13:22:43 +00:00
if (file == defaultkey && access(path, R_OK) != 0)
return;
2018-05-06 12:27:04 +00:00
array_append(file, line, "HostKey",
&options->host_key_files, &options->num_host_key_files, apath);
free(apath);
}
void
servconf_add_hostcert(const char *file, const int line,
ServerOptions *options, const char *path)
{
char *apath = derelativise_path(path);
array_append(file, line, "HostCertificate",
&options->host_cert_files, &options->num_host_cert_files, apath);
free(apath);
}
void
2000-02-24 14:29:47 +00:00
fill_default_server_options(ServerOptions *options)
{
2018-05-06 12:27:04 +00:00
u_int i;
2015-07-02 13:15:34 +00:00
2002-06-27 22:42:11 +00:00
/* Portable-specific options */
if (options->use_pam == -1)
options->use_pam = 1;
2002-06-27 22:42:11 +00:00
/* Standard Options */
2001-05-04 04:14:23 +00:00
if (options->num_host_key_files == 0) {
/* fill default hostkeys for protocols */
2018-05-11 13:22:43 +00:00
servconf_add_hostkey(defaultkey, 0, options,
2018-05-06 12:27:04 +00:00
_PATH_HOST_RSA_KEY_FILE);
2018-05-11 13:22:43 +00:00
servconf_add_hostkey(defaultkey, 0, options,
_PATH_HOST_DSA_KEY_FILE);
2011-02-17 11:47:40 +00:00
#ifdef OPENSSL_HAS_ECC
2018-05-11 13:22:43 +00:00
servconf_add_hostkey(defaultkey, 0, options,
2018-05-06 12:27:04 +00:00
_PATH_HOST_ECDSA_KEY_FILE);
2011-02-17 11:47:40 +00:00
#endif
2018-05-11 13:22:43 +00:00
servconf_add_hostkey(defaultkey, 0, options,
2018-05-06 12:27:04 +00:00
_PATH_HOST_ED25519_KEY_FILE);
#ifdef WITH_XMSS
2018-05-11 13:22:43 +00:00
servconf_add_hostkey(defaultkey, 0, options,
2018-05-06 12:27:04 +00:00
_PATH_HOST_XMSS_KEY_FILE);
#endif /* WITH_XMSS */
2001-05-04 04:14:23 +00:00
}
if (options->num_host_key_files == 0)
fatal("No host key files found");
2010-03-08 11:19:52 +00:00
/* No certificates by default */
2000-02-24 14:29:47 +00:00
if (options->num_ports == 0)
options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
2015-07-02 13:18:50 +00:00
if (options->address_family == -1)
options->address_family = AF_UNSPEC;
2000-02-24 14:29:47 +00:00
if (options->listen_addrs == NULL)
2018-05-06 12:27:04 +00:00
add_listen_addr(options, NULL, NULL, 0);
if (options->pid_file == NULL)
2015-07-02 13:15:34 +00:00
options->pid_file = xstrdup(_PATH_SSH_DAEMON_PID_FILE);
2000-02-24 14:29:47 +00:00
if (options->login_grace_time == -1)
options->login_grace_time = 120;
2001-05-04 04:14:23 +00:00
if (options->permit_root_login == PERMIT_NOT_SET)
options->permit_root_login = PERMIT_NO;
2000-02-24 14:29:47 +00:00
if (options->ignore_rhosts == -1)
options->ignore_rhosts = 1;
2000-02-24 14:29:47 +00:00
if (options->ignore_user_known_hosts == -1)
options->ignore_user_known_hosts = 0;
if (options->print_motd == -1)
options->print_motd = 1;
2001-05-04 04:14:23 +00:00
if (options->print_lastlog == -1)
options->print_lastlog = 1;
2000-02-24 14:29:47 +00:00
if (options->x11_forwarding == -1)
options->x11_forwarding = 1;
2000-02-24 14:29:47 +00:00
if (options->x11_display_offset == -1)
options->x11_display_offset = 10;
2002-03-18 10:09:43 +00:00
if (options->x11_use_localhost == -1)
options->x11_use_localhost = 1;
if (options->xauth_location == NULL)
2015-07-02 13:15:34 +00:00
options->xauth_location = xstrdup(_PATH_XAUTH);
2014-01-30 10:56:49 +00:00
if (options->permit_tty == -1)
options->permit_tty = 1;
2015-01-05 16:09:55 +00:00
if (options->permit_user_rc == -1)
options->permit_user_rc = 1;
2000-02-24 14:29:47 +00:00
if (options->strict_modes == -1)
options->strict_modes = 1;
2004-02-26 10:52:33 +00:00
if (options->tcp_keep_alive == -1)
options->tcp_keep_alive = 1;
2002-03-18 10:09:43 +00:00
if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
2000-02-24 14:29:47 +00:00
options->log_facility = SYSLOG_FACILITY_AUTH;
2002-03-18 10:09:43 +00:00
if (options->log_level == SYSLOG_LEVEL_NOT_SET)
2000-02-24 14:29:47 +00:00
options->log_level = SYSLOG_LEVEL_INFO;
2001-05-04 04:14:23 +00:00
if (options->hostbased_authentication == -1)
options->hostbased_authentication = 0;
if (options->hostbased_uses_name_from_packet_only == -1)
options->hostbased_uses_name_from_packet_only = 0;
if (options->pubkey_authentication == -1)
options->pubkey_authentication = 1;
2002-06-27 22:42:11 +00:00
if (options->kerberos_authentication == -1)
options->kerberos_authentication = 0;
2002-03-18 10:09:43 +00:00
if (options->kerberos_or_local_passwd == -1)
options->kerberos_or_local_passwd = 1;
if (options->kerberos_ticket_cleanup == -1)
options->kerberos_ticket_cleanup = 1;
2004-02-26 10:52:33 +00:00
if (options->kerberos_get_afs_token == -1)
options->kerberos_get_afs_token = 0;
if (options->gss_authentication == -1)
options->gss_authentication = 0;
if (options->gss_cleanup_creds == -1)
options->gss_cleanup_creds = 1;
2015-07-02 13:18:50 +00:00
if (options->gss_strict_acceptor == -1)
2017-08-03 10:10:20 +00:00
options->gss_strict_acceptor = 1;
2000-02-24 14:29:47 +00:00
if (options->password_authentication == -1)
options->password_authentication = 0;
if (options->kbd_interactive_authentication == -1)
options->kbd_interactive_authentication = 0;
2002-03-18 10:09:43 +00:00
if (options->challenge_response_authentication == -1)
2002-04-25 16:53:25 +00:00
options->challenge_response_authentication = 1;
2000-02-24 14:29:47 +00:00
if (options->permit_empty_passwd == -1)
options->permit_empty_passwd = 0;
2018-08-28 10:47:58 +00:00
if (options->permit_user_env == -1) {
2002-10-29 10:16:02 +00:00
options->permit_user_env = 0;
2018-08-28 10:47:58 +00:00
options->permit_user_env_whitelist = NULL;
}
if (options->compression == -1)
2005-09-03 07:04:25 +00:00
options->compression = COMP_DELAYED;
2013-09-18 17:27:38 +00:00
if (options->rekey_limit == -1)
options->rekey_limit = 0;
if (options->rekey_interval == -1)
options->rekey_interval = 0;
if (options->allow_tcp_forwarding == -1)
2013-03-22 11:19:48 +00:00
options->allow_tcp_forwarding = FORWARD_ALLOW;
2015-01-05 16:09:55 +00:00
if (options->allow_streamlocal_forwarding == -1)
options->allow_streamlocal_forwarding = FORWARD_ALLOW;
2008-07-23 09:33:08 +00:00
if (options->allow_agent_forwarding == -1)
options->allow_agent_forwarding = 1;
2015-01-05 16:09:55 +00:00
if (options->fwd_opts.gateway_ports == -1)
options->fwd_opts.gateway_ports = 0;
if (options->max_startups == -1)
2013-03-22 11:19:48 +00:00
options->max_startups = 100;
if (options->max_startups_rate == -1)
2013-03-22 11:19:48 +00:00
options->max_startups_rate = 30; /* 30% */
if (options->max_startups_begin == -1)
2013-03-22 11:19:48 +00:00
options->max_startups_begin = 10;
2004-10-28 16:11:31 +00:00
if (options->max_authtries == -1)
options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
2008-07-23 09:33:08 +00:00
if (options->max_sessions == -1)
options->max_sessions = DEFAULT_SESSIONS_MAX;
if (options->use_dns == -1)
2016-01-27 13:40:44 +00:00
options->use_dns = 1;
2001-05-04 04:14:23 +00:00
if (options->client_alive_interval == -1)
2002-03-18 10:09:43 +00:00
options->client_alive_interval = 0;
2001-05-04 04:14:23 +00:00
if (options->client_alive_count_max == -1)
options->client_alive_count_max = 3;
2011-09-28 08:14:41 +00:00
if (options->num_authkeys_files == 0) {
2018-05-11 13:22:43 +00:00
array_append(defaultkey, 0, "AuthorizedKeysFiles",
2018-05-06 12:27:04 +00:00
&options->authorized_keys_files,
&options->num_authkeys_files,
_PATH_SSH_USER_PERMITTED_KEYS);
2018-05-11 13:22:43 +00:00
array_append(defaultkey, 0, "AuthorizedKeysFiles",
2018-05-06 12:27:04 +00:00
&options->authorized_keys_files,
&options->num_authkeys_files,
_PATH_SSH_USER_PERMITTED_KEYS2);
2002-03-18 10:09:43 +00:00
}
2006-03-22 20:41:37 +00:00
if (options->permit_tun == -1)
options->permit_tun = SSH_TUNMODE_NO;
2011-02-17 11:47:40 +00:00
if (options->ip_qos_interactive == -1)
2018-08-28 10:47:58 +00:00
options->ip_qos_interactive = IPTOS_DSCP_AF21;
2011-02-17 11:47:40 +00:00
if (options->ip_qos_bulk == -1)
2018-08-28 10:47:58 +00:00
options->ip_qos_bulk = IPTOS_DSCP_CS1;
2012-08-29 15:55:54 +00:00
if (options->version_addendum == NULL)
2012-09-03 16:51:41 +00:00
options->version_addendum = xstrdup(SSH_VERSION_FREEBSD);
2015-01-05 16:09:55 +00:00
if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
options->fwd_opts.streamlocal_bind_mask = 0177;
if (options->fwd_opts.streamlocal_bind_unlink == -1)
options->fwd_opts.streamlocal_bind_unlink = 0;
2015-07-02 13:15:34 +00:00
if (options->fingerprint_hash == -1)
options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
2017-01-31 12:33:47 +00:00
if (options->disable_forwarding == -1)
options->disable_forwarding = 0;
2018-05-06 12:24:45 +00:00
if (options->expose_userauth_info == -1)
options->expose_userauth_info = 0;
if (options->use_blacklist == -1)
options->use_blacklist = 0;
2015-08-26 09:25:17 +00:00
2016-03-10 20:10:25 +00:00
assemble_algorithms(options);
2015-08-26 09:25:17 +00:00
2016-03-10 20:10:25 +00:00
/* Turn privilege separation and sandboxing on by default */
2002-06-23 14:01:54 +00:00
if (use_privsep == -1)
2014-02-01 00:07:16 +00:00
use_privsep = PRIVSEP_ON;
2002-06-27 22:31:32 +00:00
2015-07-02 13:15:34 +00:00
#define CLEAR_ON_NONE(v) \
do { \
if (option_clear_or_none(v)) { \
free(v); \
v = NULL; \
} \
} while(0)
CLEAR_ON_NONE(options->pid_file);
CLEAR_ON_NONE(options->xauth_location);
CLEAR_ON_NONE(options->banner);
CLEAR_ON_NONE(options->trusted_user_ca_keys);
CLEAR_ON_NONE(options->revoked_keys_file);
2015-07-02 13:18:50 +00:00
CLEAR_ON_NONE(options->authorized_principals_file);
2016-03-10 20:10:25 +00:00
CLEAR_ON_NONE(options->adm_forced_command);
CLEAR_ON_NONE(options->chroot_directory);
2018-05-06 12:27:04 +00:00
CLEAR_ON_NONE(options->routing_domain);
2015-07-02 13:15:34 +00:00
for (i = 0; i < options->num_host_key_files; i++)
CLEAR_ON_NONE(options->host_key_files[i]);
for (i = 0; i < options->num_host_cert_files; i++)
CLEAR_ON_NONE(options->host_cert_files[i]);
#undef CLEAR_ON_NONE
2017-01-31 12:29:48 +00:00
/* Similar handling for AuthenticationMethods=any */
if (options->num_auth_methods == 1 &&
strcmp(options->auth_methods[0], "any") == 0) {
free(options->auth_methods[0]);
options->auth_methods[0] = NULL;
options->num_auth_methods = 0;
}
#ifndef HAVE_MMAP
2002-06-27 22:31:32 +00:00
if (use_privsep && options->compression == 1) {
error("This platform does not support both privilege "
"separation and compression");
error("Compression disabled");
options->compression = 0;
}
#endif
2000-02-24 14:29:47 +00:00
}
/* Keyword tokens. */
typedef enum {
sBadOption, /* == unknown option */
2002-06-27 22:42:11 +00:00
/* Portable-specific options */
sUsePAM,
2002-06-27 22:42:11 +00:00
/* Standard Options */
2017-01-31 12:33:47 +00:00
sPort, sHostKeyFile, sLoginGraceTime,
sPermitRootLogin, sLogFacility, sLogLevel,
sRhostsRSAAuthentication, sRSAAuthentication,
2002-03-18 10:09:43 +00:00
sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
2018-05-06 12:27:04 +00:00
sKerberosGetAFSToken, sChallengeResponseAuthentication,
2005-06-05 15:46:09 +00:00
sPasswordAuthentication, sKbdInteractiveAuthentication,
sListenAddress, sAddressFamily,
2001-05-04 04:14:23 +00:00
sPrintMotd, sPrintLastLog, sIgnoreRhosts,
2002-03-18 10:09:43 +00:00
sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
2014-01-30 10:56:49 +00:00
sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive,
2017-01-31 12:33:47 +00:00
sPermitUserEnvironment, sAllowTcpForwarding, sCompression,
2013-09-18 17:27:38 +00:00
sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
2017-01-31 12:33:47 +00:00
sIgnoreUserKnownHosts, sCiphers, sMacs, sPidFile,
2015-07-02 13:15:34 +00:00
sGatewayPorts, sPubkeyAuthentication, sPubkeyAcceptedKeyTypes,
sXAuthLocation, sSubsystem, sMaxStartups, sMaxAuthTries, sMaxSessions,
sBanner, sUseDNS, sHostbasedAuthentication,
2015-07-02 13:15:34 +00:00
sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes,
2015-08-26 09:25:17 +00:00
sHostKeyAlgorithms,
2015-07-02 13:15:34 +00:00
sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
2015-07-02 13:18:50 +00:00
sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
2018-08-28 10:47:58 +00:00
sAcceptEnv, sSetEnv, sPermitTunnel,
sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory,
2008-07-23 09:33:08 +00:00
sUsePrivilegeSeparation, sAllowAgentForwarding,
2014-03-22 15:23:38 +00:00
sHostCertificate,
2010-11-08 10:45:44 +00:00
sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
2015-07-02 13:18:50 +00:00
sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser,
2019-02-05 15:03:53 +00:00
sKexAlgorithms, sCASignatureAlgorithms, sIPQoS, sVersionAddendum,
2013-03-22 11:19:48 +00:00
sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
2015-01-05 16:09:55 +00:00
sAuthenticationMethods, sHostKeyAgent, sPermitUserRC,
sStreamLocalBindMask, sStreamLocalBindUnlink,
2017-01-31 12:33:47 +00:00
sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding,
2018-05-06 12:27:04 +00:00
sExposeAuthInfo, sRDomain,
sUseBlacklist,
2017-01-31 12:33:47 +00:00
sDeprecated, sIgnore, sUnsupported
2000-02-24 14:29:47 +00:00
} ServerOpCodes;
2006-09-30 13:38:06 +00:00
#define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */
#define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
#define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
2000-02-24 14:29:47 +00:00
/* Textual representation of the tokens. */
static struct {
const char *name;
ServerOpCodes opcode;
2006-09-30 13:38:06 +00:00
u_int flags;
2000-02-24 14:29:47 +00:00
} keywords[] = {
2002-06-27 22:42:11 +00:00
/* Portable-specific options */
#ifdef USE_PAM
2006-09-30 13:38:06 +00:00
{ "usepam", sUsePAM, SSHCFG_GLOBAL },
#else
2006-09-30 13:38:06 +00:00
{ "usepam", sUnsupported, SSHCFG_GLOBAL },
#endif
2006-09-30 13:38:06 +00:00
{ "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
2002-06-27 22:42:11 +00:00
/* Standard Options */
2006-09-30 13:38:06 +00:00
{ "port", sPort, SSHCFG_GLOBAL },
{ "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
{ "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */
2013-09-18 17:27:38 +00:00
{ "hostkeyagent", sHostKeyAgent, SSHCFG_GLOBAL },
2006-09-30 13:38:06 +00:00
{ "pidfile", sPidFile, SSHCFG_GLOBAL },
2017-01-31 12:33:47 +00:00
{ "serverkeybits", sDeprecated, SSHCFG_GLOBAL },
2006-09-30 13:38:06 +00:00
{ "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
2017-01-31 12:33:47 +00:00
{ "keyregenerationinterval", sDeprecated, SSHCFG_GLOBAL },
{ "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
2006-09-30 13:38:06 +00:00
{ "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
2018-05-06 12:24:45 +00:00
{ "loglevel", sLogLevel, SSHCFG_ALL },
2006-09-30 13:38:06 +00:00
{ "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
2017-01-31 12:33:47 +00:00
{ "rhostsrsaauthentication", sDeprecated, SSHCFG_ALL },
{ "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
2010-11-08 10:45:44 +00:00
{ "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_ALL },
2015-07-02 13:15:34 +00:00
{ "hostbasedacceptedkeytypes", sHostbasedAcceptedKeyTypes, SSHCFG_ALL },
2015-08-26 09:25:17 +00:00
{ "hostkeyalgorithms", sHostKeyAlgorithms, SSHCFG_GLOBAL },
2017-01-31 12:33:47 +00:00
{ "rsaauthentication", sDeprecated, SSHCFG_ALL },
{ "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
2015-07-02 13:15:34 +00:00
{ "pubkeyacceptedkeytypes", sPubkeyAcceptedKeyTypes, SSHCFG_ALL },
2009-10-01 15:19:37 +00:00
{ "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
#ifdef KRB5
{ "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
2006-09-30 13:38:06 +00:00
{ "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
{ "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
2004-02-26 10:52:33 +00:00
#ifdef USE_AFS
2006-09-30 13:38:06 +00:00
{ "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
2004-02-26 10:52:33 +00:00
#else
2006-09-30 13:38:06 +00:00
{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
2004-02-26 10:52:33 +00:00
#endif
#else
{ "kerberosauthentication", sUnsupported, SSHCFG_ALL },
2006-09-30 13:38:06 +00:00
{ "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
{ "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
#endif
2006-09-30 13:38:06 +00:00
{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
#ifdef GSSAPI
{ "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
2006-09-30 13:38:06 +00:00
{ "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
2015-07-02 13:18:50 +00:00
{ "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
#else
{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
2006-09-30 13:38:06 +00:00
{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
2015-07-02 13:18:50 +00:00
{ "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
2000-02-24 14:29:47 +00:00
#endif
{ "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
2006-09-30 13:38:06 +00:00
{ "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
2018-08-28 10:47:58 +00:00
{ "skeyauthentication", sDeprecated, SSHCFG_GLOBAL },
2006-09-30 13:38:06 +00:00
{ "checkmail", sDeprecated, SSHCFG_GLOBAL },
{ "listenaddress", sListenAddress, SSHCFG_GLOBAL },
{ "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
{ "printmotd", sPrintMotd, SSHCFG_GLOBAL },
2016-03-10 20:10:25 +00:00
#ifdef DISABLE_LASTLOG
{ "printlastlog", sUnsupported, SSHCFG_GLOBAL },
#else
2006-09-30 13:38:06 +00:00
{ "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
2016-03-10 20:10:25 +00:00
#endif
2006-09-30 13:38:06 +00:00
{ "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
{ "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
{ "x11forwarding", sX11Forwarding, SSHCFG_ALL },
{ "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
{ "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
{ "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
{ "strictmodes", sStrictModes, SSHCFG_GLOBAL },
2009-02-24 18:49:27 +00:00
{ "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL },
2006-09-30 13:38:06 +00:00
{ "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
2017-01-31 12:33:47 +00:00
{ "uselogin", sDeprecated, SSHCFG_GLOBAL },
2006-09-30 13:38:06 +00:00
{ "compression", sCompression, SSHCFG_GLOBAL },
2013-09-18 17:27:38 +00:00
{ "rekeylimit", sRekeyLimit, SSHCFG_ALL },
2006-09-30 13:38:06 +00:00
{ "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
{ "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
{ "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
2008-07-23 09:33:08 +00:00
{ "allowagentforwarding", sAllowAgentForwarding, SSHCFG_ALL },
2012-08-29 15:55:54 +00:00
{ "allowusers", sAllowUsers, SSHCFG_ALL },
{ "denyusers", sDenyUsers, SSHCFG_ALL },
{ "allowgroups", sAllowGroups, SSHCFG_ALL },
{ "denygroups", sDenyGroups, SSHCFG_ALL },
2006-09-30 13:38:06 +00:00
{ "ciphers", sCiphers, SSHCFG_GLOBAL },
{ "macs", sMacs, SSHCFG_GLOBAL },
2017-01-31 12:33:47 +00:00
{ "protocol", sIgnore, SSHCFG_GLOBAL },
2006-09-30 13:38:06 +00:00
{ "gatewayports", sGatewayPorts, SSHCFG_ALL },
{ "subsystem", sSubsystem, SSHCFG_GLOBAL },
{ "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
2008-07-23 09:33:08 +00:00
{ "maxauthtries", sMaxAuthTries, SSHCFG_ALL },
{ "maxsessions", sMaxSessions, SSHCFG_ALL },
{ "banner", sBanner, SSHCFG_ALL },
2006-09-30 13:38:06 +00:00
{ "usedns", sUseDNS, SSHCFG_GLOBAL },
{ "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
{ "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
2017-01-31 12:33:47 +00:00
{ "clientaliveinterval", sClientAliveInterval, SSHCFG_ALL },
{ "clientalivecountmax", sClientAliveCountMax, SSHCFG_ALL },
2010-11-08 10:45:44 +00:00
{ "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_ALL },
2011-09-28 08:14:41 +00:00
{ "authorizedkeysfile2", sDeprecated, SSHCFG_ALL },
2017-08-03 10:10:20 +00:00
{ "useprivilegeseparation", sDeprecated, SSHCFG_GLOBAL},
2012-08-29 15:55:54 +00:00
{ "acceptenv", sAcceptEnv, SSHCFG_ALL },
2018-08-28 10:47:58 +00:00
{ "setenv", sSetEnv, SSHCFG_ALL },
2010-11-08 10:45:44 +00:00
{ "permittunnel", sPermitTunnel, SSHCFG_ALL },
2014-01-30 10:56:49 +00:00
{ "permittty", sPermitTTY, SSHCFG_ALL },
2015-01-05 16:09:55 +00:00
{ "permituserrc", sPermitUserRC, SSHCFG_ALL },
2009-10-01 15:19:37 +00:00
{ "match", sMatch, SSHCFG_ALL },
2006-09-30 13:38:06 +00:00
{ "permitopen", sPermitOpen, SSHCFG_ALL },
2018-08-28 10:47:58 +00:00
{ "permitlisten", sPermitListen, SSHCFG_ALL },
2006-09-30 13:38:06 +00:00
{ "forcecommand", sForceCommand, SSHCFG_ALL },
{ "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
2010-03-08 11:19:52 +00:00
{ "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
{ "revokedkeys", sRevokedKeys, SSHCFG_ALL },
{ "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
2010-11-08 10:45:44 +00:00
{ "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
2011-02-17 11:47:40 +00:00
{ "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
{ "ipqos", sIPQoS, SSHCFG_ALL },
2013-03-22 11:19:48 +00:00
{ "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL },
{ "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL },
2015-07-02 13:18:50 +00:00
{ "authorizedprincipalscommand", sAuthorizedPrincipalsCommand, SSHCFG_ALL },
{ "authorizedprincipalscommanduser", sAuthorizedPrincipalsCommandUser, SSHCFG_ALL },
2012-08-29 15:55:54 +00:00
{ "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
2013-03-22 11:19:48 +00:00
{ "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL },
2015-01-05 16:09:55 +00:00
{ "streamlocalbindmask", sStreamLocalBindMask, SSHCFG_ALL },
{ "streamlocalbindunlink", sStreamLocalBindUnlink, SSHCFG_ALL },
{ "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL },
2015-07-02 13:15:34 +00:00
{ "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL },
2017-01-31 12:33:47 +00:00
{ "disableforwarding", sDisableForwarding, SSHCFG_ALL },
2018-05-06 12:24:45 +00:00
{ "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL },
2018-05-06 12:27:04 +00:00
{ "rdomain", sRDomain, SSHCFG_ALL },
2019-02-05 15:03:53 +00:00
{ "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL },
{ "useblacklist", sUseBlacklist, SSHCFG_GLOBAL },
{ "useblocklist", sUseBlacklist, SSHCFG_GLOBAL }, /* alias */
{ "noneenabled", sUnsupported, SSHCFG_ALL },
{ "hpndisabled", sDeprecated, SSHCFG_ALL },
{ "hpnbuffersize", sDeprecated, SSHCFG_ALL },
{ "tcprcvbufpoll", sDeprecated, SSHCFG_ALL },
2006-09-30 13:38:06 +00:00
{ NULL, sBadOption, 0 }
2000-02-24 14:29:47 +00:00
};
2008-07-23 09:33:08 +00:00
static struct {
int val;
char *text;
} tunmode_desc[] = {
{ SSH_TUNMODE_NO, "no" },
{ SSH_TUNMODE_POINTOPOINT, "point-to-point" },
{ SSH_TUNMODE_ETHERNET, "ethernet" },
{ SSH_TUNMODE_YES, "yes" },
{ -1, NULL }
};
2018-08-28 10:47:58 +00:00
/* Returns an opcode name from its number */
static const char *
lookup_opcode_name(ServerOpCodes code)
{
u_int i;
for (i = 0; keywords[i].name != NULL; i++)
if (keywords[i].opcode == code)
return(keywords[i].name);
return "UNKNOWN";
}
2000-02-24 14:29:47 +00:00
/*
2001-05-04 04:14:23 +00:00
* Returns the number of the token pointed to by cp or sBadOption.
2000-02-24 14:29:47 +00:00
*/
static ServerOpCodes
2000-02-24 14:29:47 +00:00
parse_token(const char *cp, const char *filename,
2006-09-30 13:38:06 +00:00
int linenum, u_int *flags)
2000-02-24 14:29:47 +00:00
{
2001-05-04 04:14:23 +00:00
u_int i;
2000-02-24 14:29:47 +00:00
for (i = 0; keywords[i].name; i++)
2006-09-30 13:38:06 +00:00
if (strcasecmp(cp, keywords[i].name) == 0) {
*flags = keywords[i].flags;
2000-02-24 14:29:47 +00:00
return keywords[i].opcode;
2006-09-30 13:38:06 +00:00
}
2000-02-24 14:29:47 +00:00
2001-05-04 04:14:23 +00:00
error("%s: line %d: Bad configuration option: %s",
filename, linenum, cp);
2000-02-24 14:29:47 +00:00
return sBadOption;
}
2010-03-08 11:19:52 +00:00
char *
derelativise_path(const char *path)
{
2015-07-02 13:15:34 +00:00
char *expanded, *ret, cwd[PATH_MAX];
2010-03-08 11:19:52 +00:00
2015-07-02 13:15:34 +00:00
if (strcasecmp(path, "none") == 0)
return xstrdup("none");
2010-03-08 11:19:52 +00:00
expanded = tilde_expand_filename(path, getuid());
if (*expanded == '/')
return expanded;
2010-04-28 08:37:00 +00:00
if (getcwd(cwd, sizeof(cwd)) == NULL)
2010-03-08 11:19:52 +00:00
fatal("%s: getcwd: %s", __func__, strerror(errno));
xasprintf(&ret, "%s/%s", cwd, expanded);
2013-09-18 17:27:38 +00:00
free(expanded);
2010-03-08 11:19:52 +00:00
return ret;
}
2002-03-18 10:09:43 +00:00
static void
2018-05-06 12:27:04 +00:00
add_listen_addr(ServerOptions *options, const char *addr,
const char *rdomain, int port)
2000-02-24 14:29:47 +00:00
{
2005-09-03 07:04:25 +00:00
u_int i;
2000-02-24 14:29:47 +00:00
2018-05-06 12:27:04 +00:00
if (port > 0)
add_one_listen_addr(options, addr, rdomain, port);
else {
for (i = 0; i < options->num_ports; i++) {
add_one_listen_addr(options, addr, rdomain,
options->ports[i]);
}
}
2001-05-04 04:14:23 +00:00
}
2002-03-18 10:09:43 +00:00
static void
2018-05-06 12:27:04 +00:00
add_one_listen_addr(ServerOptions *options, const char *addr,
const char *rdomain, int port)
2001-05-04 04:14:23 +00:00
{
struct addrinfo hints, *ai, *aitop;
char strport[NI_MAXSERV];
int gaierr;
2018-05-06 12:27:04 +00:00
u_int i;
/* Find listen_addrs entry for this rdomain */
for (i = 0; i < options->num_listen_addrs; i++) {
if (rdomain == NULL && options->listen_addrs[i].rdomain == NULL)
break;
if (rdomain == NULL || options->listen_addrs[i].rdomain == NULL)
continue;
if (strcmp(rdomain, options->listen_addrs[i].rdomain) == 0)
break;
}
if (i >= options->num_listen_addrs) {
/* No entry for this rdomain; allocate one */
if (i >= INT_MAX)
fatal("%s: too many listen addresses", __func__);
options->listen_addrs = xrecallocarray(options->listen_addrs,
options->num_listen_addrs, options->num_listen_addrs + 1,
sizeof(*options->listen_addrs));
i = options->num_listen_addrs++;
if (rdomain != NULL)
options->listen_addrs[i].rdomain = xstrdup(rdomain);
}
/* options->listen_addrs[i] points to the addresses for this rdomain */
2001-05-04 04:14:23 +00:00
memset(&hints, 0, sizeof(hints));
2005-06-05 15:46:09 +00:00
hints.ai_family = options->address_family;
2001-05-04 04:14:23 +00:00
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
2009-02-24 18:49:27 +00:00
snprintf(strport, sizeof strport, "%d", port);
2001-05-04 04:14:23 +00:00
if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
fatal("bad addr or host: %s (%s)",
addr ? addr : "<NULL>",
ssh_gai_strerror(gaierr));
2001-05-04 04:14:23 +00:00
for (ai = aitop; ai->ai_next; ai = ai->ai_next)
;
2018-05-06 12:27:04 +00:00
ai->ai_next = options->listen_addrs[i].addrs;
options->listen_addrs[i].addrs = aitop;
}
/* Returns nonzero if the routing domain name is valid */
static int
valid_rdomain(const char *name)
{
#if defined(HAVE_SYS_VALID_RDOMAIN)
return sys_valid_rdomain(name);
#elif defined(__OpenBSD__)
const char *errstr;
long long num;
struct rt_tableinfo info;
int mib[6];
size_t miblen = sizeof(mib);
if (name == NULL)
return 1;
num = strtonum(name, 0, 255, &errstr);
if (errstr != NULL)
return 0;
/* Check whether the table actually exists */
memset(mib, 0, sizeof(mib));
mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
mib[4] = NET_RT_TABLE;
mib[5] = (int)num;
if (sysctl(mib, 6, &info, &miblen, NULL, 0) == -1)
return 0;
return 1;
#else /* defined(__OpenBSD__) */
error("Routing domains are not supported on this platform");
return 0;
#endif
2000-02-24 14:29:47 +00:00
}
2015-07-02 13:18:50 +00:00
/*
* Queue a ListenAddress to be processed once we have all of the Ports
* and AddressFamily options.
*/
static void
2018-05-06 12:27:04 +00:00
queue_listen_addr(ServerOptions *options, const char *addr,
const char *rdomain, int port)
2015-07-02 13:18:50 +00:00
{
2018-05-06 12:27:04 +00:00
struct queued_listenaddr *qla;
options->queued_listen_addrs = xrecallocarray(
options->queued_listen_addrs,
options->num_queued_listens, options->num_queued_listens + 1,
sizeof(*options->queued_listen_addrs));
qla = &options->queued_listen_addrs[options->num_queued_listens++];
qla->addr = xstrdup(addr);
qla->port = port;
qla->rdomain = rdomain == NULL ? NULL : xstrdup(rdomain);
2015-07-02 13:18:50 +00:00
}
/*
* Process queued (text) ListenAddress entries.
*/
static void
process_queued_listen_addrs(ServerOptions *options)
{
u_int i;
2018-05-06 12:27:04 +00:00
struct queued_listenaddr *qla;
2015-07-02 13:18:50 +00:00
if (options->num_ports == 0)
options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
if (options->address_family == -1)
options->address_family = AF_UNSPEC;
for (i = 0; i < options->num_queued_listens; i++) {
2018-05-06 12:27:04 +00:00
qla = &options->queued_listen_addrs[i];
add_listen_addr(options, qla->addr, qla->rdomain, qla->port);
free(qla->addr);
free(qla->rdomain);
2015-07-02 13:18:50 +00:00
}
free(options->queued_listen_addrs);
options->queued_listen_addrs = NULL;
options->num_queued_listens = 0;
}
2018-05-06 12:24:45 +00:00
/*
2018-08-28 10:47:58 +00:00
* Inform channels layer of permitopen options for a single forwarding
* direction (local/remote).
2018-05-06 12:24:45 +00:00
*/
2018-08-28 10:47:58 +00:00
static void
process_permitopen_list(struct ssh *ssh, ServerOpCodes opcode,
char **opens, u_int num_opens)
2018-05-06 12:24:45 +00:00
{
u_int i;
int port;
char *host, *arg, *oarg;
2018-08-28 10:47:58 +00:00
int where = opcode == sPermitOpen ? FORWARD_LOCAL : FORWARD_REMOTE;
const char *what = lookup_opcode_name(opcode);
2018-05-06 12:24:45 +00:00
2018-08-28 10:47:58 +00:00
channel_clear_permission(ssh, FORWARD_ADM, where);
if (num_opens == 0)
2018-05-06 12:24:45 +00:00
return; /* permit any */
/* handle keywords: "any" / "none" */
2018-08-28 10:47:58 +00:00
if (num_opens == 1 && strcmp(opens[0], "any") == 0)
2018-05-06 12:24:45 +00:00
return;
2018-08-28 10:47:58 +00:00
if (num_opens == 1 && strcmp(opens[0], "none") == 0) {
channel_disable_admin(ssh, where);
2018-05-06 12:24:45 +00:00
return;
}
/* Otherwise treat it as a list of permitted host:port */
2018-08-28 10:47:58 +00:00
for (i = 0; i < num_opens; i++) {
oarg = arg = xstrdup(opens[i]);
2018-05-06 12:24:45 +00:00
host = hpdelim(&arg);
if (host == NULL)
2018-08-28 10:47:58 +00:00
fatal("%s: missing host in %s", __func__, what);
2018-05-06 12:24:45 +00:00
host = cleanhostname(host);
if (arg == NULL || ((port = permitopen_port(arg)) < 0))
2018-08-28 10:47:58 +00:00
fatal("%s: bad port number in %s", __func__, what);
2018-05-06 12:24:45 +00:00
/* Send it to channels layer */
2018-08-28 10:47:58 +00:00
channel_add_permission(ssh, FORWARD_ADM,
where, host, port);
2018-05-06 12:24:45 +00:00
free(oarg);
}
}
2018-08-28 10:47:58 +00:00
/*
* Inform channels layer of permitopen options from configuration.
*/
void
process_permitopen(struct ssh *ssh, ServerOptions *options)
{
process_permitopen_list(ssh, sPermitOpen,
options->permitted_opens, options->num_permitted_opens);
process_permitopen_list(ssh, sPermitListen,
options->permitted_listens,
options->num_permitted_listens);
}
2012-08-29 15:55:54 +00:00
struct connection_info *
get_connection_info(int populate, int use_dns)
{
2017-01-31 12:29:48 +00:00
struct ssh *ssh = active_state; /* XXX */
2012-08-29 15:55:54 +00:00
static struct connection_info ci;
if (!populate)
return &ci;
2017-01-31 12:29:48 +00:00
ci.host = auth_get_canonical_hostname(ssh, use_dns);
ci.address = ssh_remote_ipaddr(ssh);
ci.laddress = ssh_local_ipaddr(ssh);
ci.lport = ssh_local_port(ssh);
2018-05-06 12:27:04 +00:00
ci.rdomain = ssh_packet_rdomain_in(ssh);
2012-08-29 15:55:54 +00:00
return &ci;
}
2006-09-30 13:38:06 +00:00
/*
* The strategy for the Match blocks is that the config file is parsed twice.
*
* The first time is at startup. activep is initialized to 1 and the
* directives in the global context are processed and acted on. Hitting a
* Match directive unsets activep and the directives inside the block are
* checked for syntax only.
*
* The second time is after a connection has been established but before
* authentication. activep is initialized to 2 and global config directives
* are ignored since they have already been processed. If the criteria in a
* Match block is met, activep is set and the subsequent directives
* processed and actioned until EOF or another Match block unsets it. Any
* options set are copied into the main server config.
*
* Potential additions/improvements:
2017-01-31 12:33:47 +00:00
* - Add Match support for pre-kex directives, eg. Ciphers.
2006-09-30 13:38:06 +00:00
*
* - Add a Tag directive (idea from David Leonard) ala pf, eg:
* Match Address 192.168.0.*
* Tag trusted
* Match Group wheel
* Tag trusted
* Match Tag trusted
* AllowTcpForwarding yes
* GatewayPorts clientspecified
* [...]
*
* - Add a PermittedChannelRequests directive
* Match Group shell
* PermittedChannelRequests session,forwarded-tcpip
*/
static int
match_cfg_line_group(const char *grps, int line, const char *user)
{
int result = 0;
struct passwd *pw;
if (user == NULL)
goto out;
if ((pw = getpwnam(user)) == NULL) {
debug("Can't match group at line %d because user %.100s does "
"not exist", line, user);
} else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
debug("Can't Match group because user %.100s not in any group "
"at line %d", user, line);
2008-07-23 09:33:08 +00:00
} else if (ga_match_pattern_list(grps) != 1) {
debug("user %.100s does not match group list %.100s at line %d",
user, grps, line);
2006-09-30 13:38:06 +00:00
} else {
2008-07-23 09:33:08 +00:00
debug("user %.100s matched group list %.100s at line %d", user,
grps, line);
2006-09-30 13:38:06 +00:00
result = 1;
}
out:
ga_free();
return result;
}
2018-05-06 12:27:04 +00:00
static void
match_test_missing_fatal(const char *criteria, const char *attrib)
{
fatal("'Match %s' in configuration but '%s' not in connection "
"test specification.", criteria, attrib);
}
2012-08-29 15:55:54 +00:00
/*
2013-03-22 11:19:48 +00:00
* All of the attributes on a single Match line are ANDed together, so we need
2014-01-30 10:56:49 +00:00
* to check every attribute and set the result to zero if any attribute does
2013-03-22 11:19:48 +00:00
* not match.
2012-08-29 15:55:54 +00:00
*/
2006-09-30 13:38:06 +00:00
static int
2012-08-29 15:55:54 +00:00
match_cfg_line(char **condition, int line, struct connection_info *ci)
2006-09-30 13:38:06 +00:00
{
2014-01-30 10:56:49 +00:00
int result = 1, attributes = 0, port;
2006-09-30 13:38:06 +00:00
char *arg, *attrib, *cp = *condition;
2012-08-29 15:55:54 +00:00
if (ci == NULL)
2006-09-30 13:38:06 +00:00
debug3("checking syntax for 'Match %s'", cp);
else
2012-08-29 15:55:54 +00:00
debug3("checking match for '%s' user %s host %s addr %s "
"laddr %s lport %d", cp, ci->user ? ci->user : "(null)",
ci->host ? ci->host : "(null)",
ci->address ? ci->address : "(null)",
ci->laddress ? ci->laddress : "(null)", ci->lport);
2006-09-30 13:38:06 +00:00
while ((attrib = strdelim(&cp)) && *attrib != '\0') {
2014-01-30 10:56:49 +00:00
attributes++;
if (strcasecmp(attrib, "all") == 0) {
if (attributes != 1 ||
((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
error("'all' cannot be combined with other "
"Match attributes");
return -1;
}
*condition = cp;
return 1;
}
2006-09-30 13:38:06 +00:00
if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
error("Missing Match criteria for %s", attrib);
return -1;
}
if (strcasecmp(attrib, "user") == 0) {
2018-05-06 12:27:04 +00:00
if (ci == NULL) {
2006-09-30 13:38:06 +00:00
result = 0;
continue;
}
2018-05-06 12:27:04 +00:00
if (ci->user == NULL)
match_test_missing_fatal("User", "user");
2015-07-02 13:18:50 +00:00
if (match_pattern_list(ci->user, arg, 0) != 1)
2006-09-30 13:38:06 +00:00
result = 0;
else
debug("user %.100s matched 'User %.100s' at "
2012-08-29 15:55:54 +00:00
"line %d", ci->user, arg, line);
2006-09-30 13:38:06 +00:00
} else if (strcasecmp(attrib, "group") == 0) {
2018-05-06 12:27:04 +00:00
if (ci == NULL) {
2012-08-29 15:55:54 +00:00
result = 0;
continue;
}
2018-05-06 12:27:04 +00:00
if (ci->user == NULL)
match_test_missing_fatal("Group", "user");
2012-08-29 15:55:54 +00:00
switch (match_cfg_line_group(arg, line, ci->user)) {
2006-09-30 13:38:06 +00:00
case -1:
return -1;
case 0:
result = 0;
}
} else if (strcasecmp(attrib, "host") == 0) {
2018-05-06 12:27:04 +00:00
if (ci == NULL) {
2006-09-30 13:38:06 +00:00
result = 0;
continue;
}
2018-05-06 12:27:04 +00:00
if (ci->host == NULL)
match_test_missing_fatal("Host", "host");
2015-07-02 13:18:50 +00:00
if (match_hostname(ci->host, arg) != 1)
2006-09-30 13:38:06 +00:00
result = 0;
else
debug("connection from %.100s matched 'Host "
2012-08-29 15:55:54 +00:00
"%.100s' at line %d", ci->host, arg, line);
2006-09-30 13:38:06 +00:00
} else if (strcasecmp(attrib, "address") == 0) {
2018-05-06 12:27:04 +00:00
if (ci == NULL) {
2012-08-29 15:55:54 +00:00
result = 0;
continue;
}
2018-05-06 12:27:04 +00:00
if (ci->address == NULL)
match_test_missing_fatal("Address", "addr");
2012-08-29 15:55:54 +00:00
switch (addr_match_list(ci->address, arg)) {
2008-07-23 09:33:08 +00:00
case 1:
2006-09-30 13:38:06 +00:00
debug("connection from %.100s matched 'Address "
2012-08-29 15:55:54 +00:00
"%.100s' at line %d", ci->address, arg, line);
2008-07-23 09:33:08 +00:00
break;
case 0:
case -1:
result = 0;
break;
case -2:
return -1;
}
2012-08-29 15:55:54 +00:00
} else if (strcasecmp(attrib, "localaddress") == 0){
2018-05-06 12:27:04 +00:00
if (ci == NULL) {
2012-08-29 15:55:54 +00:00
result = 0;
continue;
}
2018-05-06 12:27:04 +00:00
if (ci->laddress == NULL)
match_test_missing_fatal("LocalAddress",
"laddr");
2012-08-29 15:55:54 +00:00
switch (addr_match_list(ci->laddress, arg)) {
case 1:
debug("connection from %.100s matched "
"'LocalAddress %.100s' at line %d",
ci->laddress, arg, line);
break;
case 0:
case -1:
result = 0;
break;
case -2:
return -1;
}
} else if (strcasecmp(attrib, "localport") == 0) {
if ((port = a2port(arg)) == -1) {
error("Invalid LocalPort '%s' on Match line",
arg);
return -1;
}
2018-05-06 12:27:04 +00:00
if (ci == NULL) {
2012-08-29 15:55:54 +00:00
result = 0;
continue;
}
2018-05-06 12:27:04 +00:00
if (ci->lport == 0)
match_test_missing_fatal("LocalPort", "lport");
2012-08-29 15:55:54 +00:00
/* TODO support port lists */
if (port == ci->lport)
debug("connection from %.100s matched "
"'LocalPort %d' at line %d",
ci->laddress, port, line);
else
result = 0;
2018-05-06 12:27:04 +00:00
} else if (strcasecmp(attrib, "rdomain") == 0) {
if (ci == NULL || ci->rdomain == NULL) {
result = 0;
continue;
}
if (match_pattern_list(ci->rdomain, arg, 0) != 1)
result = 0;
else
debug("user %.100s matched 'RDomain %.100s' at "
"line %d", ci->rdomain, arg, line);
2006-09-30 13:38:06 +00:00
} else {
error("Unsupported Match attribute %s", attrib);
return -1;
}
}
2014-01-30 10:56:49 +00:00
if (attributes == 0) {
error("One or more attributes required for Match");
return -1;
}
2012-08-29 15:55:54 +00:00
if (ci != NULL)
2006-09-30 13:38:06 +00:00
debug3("match %sfound", result ? "" : "not ");
*condition = cp;
return result;
}
#define WHITESPACE " \t\r\n"
2011-09-28 08:14:41 +00:00
/* Multistate option parsing */
struct multistate {
char *key;
int value;
};
2018-05-06 12:27:04 +00:00
static const struct multistate multistate_flag[] = {
{ "yes", 1 },
{ "no", 0 },
{ NULL, -1 }
};
2011-09-28 08:14:41 +00:00
static const struct multistate multistate_addressfamily[] = {
{ "inet", AF_INET },
{ "inet6", AF_INET6 },
{ "any", AF_UNSPEC },
{ NULL, -1 }
};
static const struct multistate multistate_permitrootlogin[] = {
{ "without-password", PERMIT_NO_PASSWD },
2015-08-26 09:25:17 +00:00
{ "prohibit-password", PERMIT_NO_PASSWD },
2011-09-28 08:14:41 +00:00
{ "forced-commands-only", PERMIT_FORCED_ONLY },
{ "yes", PERMIT_YES },
{ "no", PERMIT_NO },
{ NULL, -1 }
};
static const struct multistate multistate_compression[] = {
2017-01-31 12:33:47 +00:00
{ "yes", COMP_DELAYED },
2011-09-28 08:14:41 +00:00
{ "delayed", COMP_DELAYED },
{ "no", COMP_NONE },
{ NULL, -1 }
};
static const struct multistate multistate_gatewayports[] = {
{ "clientspecified", 2 },
{ "yes", 1 },
{ "no", 0 },
{ NULL, -1 }
};
2013-03-22 11:19:48 +00:00
static const struct multistate multistate_tcpfwd[] = {
{ "yes", FORWARD_ALLOW },
{ "all", FORWARD_ALLOW },
{ "no", FORWARD_DENY },
{ "remote", FORWARD_REMOTE },
{ "local", FORWARD_LOCAL },
{ NULL, -1 }
};
2011-09-28 08:14:41 +00:00
2002-03-18 10:09:43 +00:00
int
process_server_config_line(ServerOptions *options, char *line,
2012-08-29 15:55:54 +00:00
const char *filename, int linenum, int *activep,
struct connection_info *connectinfo)
2000-02-24 14:29:47 +00:00
{
2018-08-28 10:47:58 +00:00
char *cp, ***chararrayptr, **charptr, *arg, *arg2, *p;
2013-09-18 17:27:38 +00:00
int cmdline = 0, *intptr, value, value2, n, port;
SyslogFacility *log_facility_ptr;
LogLevel *log_level_ptr;
2000-02-24 14:29:47 +00:00
ServerOpCodes opcode;
2018-08-28 10:47:58 +00:00
u_int i, *uintptr, uvalue, flags = 0;
2006-09-30 13:38:06 +00:00
size_t len;
2013-09-18 17:27:38 +00:00
long long val64;
2011-09-28 08:14:41 +00:00
const struct multistate *multistate_ptr;
2018-05-06 12:27:04 +00:00
const char *errstr;
2000-02-24 14:29:47 +00:00
2017-08-03 10:10:20 +00:00
/* Strip trailing whitespace. Allow \f (form feed) at EOL only */
if ((len = strlen(line)) == 0)
return 0;
for (len--; len > 0; len--) {
if (strchr(WHITESPACE "\f", line[len]) == NULL)
break;
line[len] = '\0';
}
2002-03-18 10:09:43 +00:00
cp = line;
2006-09-30 13:38:06 +00:00
if ((arg = strdelim(&cp)) == NULL)
return 0;
2002-03-18 10:09:43 +00:00
/* Ignore leading whitespace */
if (*arg == '\0')
arg = strdelim(&cp);
2002-03-18 10:09:43 +00:00
if (!arg || !*arg || *arg == '#')
return 0;
intptr = NULL;
charptr = NULL;
2006-09-30 13:38:06 +00:00
opcode = parse_token(arg, filename, linenum, &flags);
if (activep == NULL) { /* We are processing a command line directive */
cmdline = 1;
activep = &cmdline;
}
if (*activep && opcode != sMatch)
debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
2012-08-29 15:55:54 +00:00
if (connectinfo == NULL) {
2006-09-30 13:38:06 +00:00
fatal("%s line %d: Directive '%s' is not allowed "
"within a Match block", filename, linenum, arg);
} else { /* this is a directive we have already processed */
while (arg)
arg = strdelim(&cp);
return 0;
}
}
2002-03-18 10:09:43 +00:00
switch (opcode) {
2002-06-27 22:42:11 +00:00
/* Portable-specific options */
case sUsePAM:
intptr = &options->use_pam;
2002-06-27 22:42:11 +00:00
goto parse_flag;
/* Standard Options */
2002-03-18 10:09:43 +00:00
case sBadOption:
return -1;
case sPort:
/* ignore ports from configfile if cmdline specifies ports */
if (options->ports_from_cmdline)
return 0;
if (options->num_ports >= MAX_PORTS)
fatal("%s line %d: too many ports.",
filename, linenum);
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: missing port number.",
filename, linenum);
options->ports[options->num_ports++] = a2port(arg);
2009-02-24 18:49:27 +00:00
if (options->ports[options->num_ports-1] <= 0)
2002-03-18 10:09:43 +00:00
fatal("%s line %d: Badly formatted port number.",
filename, linenum);
break;
case sLoginGraceTime:
intptr = &options->login_grace_time;
2008-07-23 09:33:08 +00:00
parse_time:
2002-03-18 10:09:43 +00:00
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: missing time value.",
filename, linenum);
if ((value = convtime(arg)) == -1)
fatal("%s line %d: invalid time value.",
filename, linenum);
2015-07-02 13:18:50 +00:00
if (*activep && *intptr == -1)
2002-03-18 10:09:43 +00:00
*intptr = value;
break;
case sListenAddress:
arg = strdelim(&cp);
2005-06-05 15:46:09 +00:00
if (arg == NULL || *arg == '\0')
fatal("%s line %d: missing address",
2002-03-18 10:09:43 +00:00
filename, linenum);
2005-09-03 07:04:25 +00:00
/* check for bare IPv6 address: no "[]" and 2 or more ":" */
if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
&& strchr(p+1, ':') != NULL) {
2005-06-05 15:46:09 +00:00
port = 0;
2018-05-06 12:27:04 +00:00
p = arg;
} else {
p = hpdelim(&arg);
if (p == NULL)
fatal("%s line %d: bad address:port usage",
filename, linenum);
p = cleanhostname(p);
if (arg == NULL)
port = 0;
else if ((port = a2port(arg)) <= 0)
fatal("%s line %d: bad port number",
filename, linenum);
}
/* Optional routing table */
arg2 = NULL;
if ((arg = strdelim(&cp)) != NULL) {
if (strcmp(arg, "rdomain") != 0 ||
(arg2 = strdelim(&cp)) == NULL)
fatal("%s line %d: bad ListenAddress syntax",
filename, linenum);
if (!valid_rdomain(arg2))
fatal("%s line %d: bad routing domain",
filename, linenum);
}
2000-02-24 14:29:47 +00:00
2018-05-06 12:27:04 +00:00
queue_listen_addr(options, p, arg2, port);
2005-06-05 15:46:09 +00:00
break;
case sAddressFamily:
2011-09-28 08:14:41 +00:00
intptr = &options->address_family;
multistate_ptr = multistate_addressfamily;
parse_multistate:
2005-06-05 15:46:09 +00:00
arg = strdelim(&cp);
2005-09-03 07:04:25 +00:00
if (!arg || *arg == '\0')
2011-09-28 08:14:41 +00:00
fatal("%s line %d: missing argument.",
2005-09-03 07:04:25 +00:00
filename, linenum);
2011-09-28 08:14:41 +00:00
value = -1;
for (i = 0; multistate_ptr[i].key != NULL; i++) {
if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
value = multistate_ptr[i].value;
break;
}
}
if (value == -1)
fatal("%s line %d: unsupported option \"%s\".",
2005-06-05 15:46:09 +00:00
filename, linenum, arg);
2011-09-28 08:14:41 +00:00
if (*activep && *intptr == -1)
2005-06-05 15:46:09 +00:00
*intptr = value;
2002-03-18 10:09:43 +00:00
break;
case sHostKeyFile:
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: missing file name.",
filename, linenum);
2018-05-06 12:27:04 +00:00
if (*activep)
servconf_add_hostkey(filename, linenum, options, arg);
2002-03-18 10:09:43 +00:00
break;
2000-02-24 14:29:47 +00:00
2013-09-18 17:27:38 +00:00
case sHostKeyAgent:
charptr = &options->host_key_agent;
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: missing socket name.",
filename, linenum);
if (*activep && *charptr == NULL)
*charptr = !strcmp(arg, SSH_AUTHSOCKET_ENV_NAME) ?
xstrdup(arg) : derelativise_path(arg);
break;
2010-03-08 11:19:52 +00:00
case sHostCertificate:
2018-05-06 12:27:04 +00:00
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: missing file name.",
filename, linenum);
if (*activep)
servconf_add_hostcert(filename, linenum, options, arg);
break;
2010-03-08 11:19:52 +00:00
2002-03-18 10:09:43 +00:00
case sPidFile:
charptr = &options->pid_file;
2018-05-06 12:27:04 +00:00
parse_filename:
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: missing file name.",
filename, linenum);
if (*activep && *charptr == NULL) {
*charptr = derelativise_path(arg);
/* increase optional counter */
if (intptr != NULL)
*intptr = *intptr + 1;
}
break;
2000-02-24 14:29:47 +00:00
2002-03-18 10:09:43 +00:00
case sPermitRootLogin:
intptr = &options->permit_root_login;
2011-09-28 08:14:41 +00:00
multistate_ptr = multistate_permitrootlogin;
goto parse_multistate;
2002-03-18 10:09:43 +00:00
case sIgnoreRhosts:
intptr = &options->ignore_rhosts;
2008-07-23 09:33:08 +00:00
parse_flag:
2018-05-06 12:27:04 +00:00
multistate_ptr = multistate_flag;
goto parse_multistate;
2002-03-18 10:09:43 +00:00
case sIgnoreUserKnownHosts:
intptr = &options->ignore_user_known_hosts;
goto parse_flag;
case sHostbasedAuthentication:
intptr = &options->hostbased_authentication;
goto parse_flag;
case sHostbasedUsesNameFromPacketOnly:
intptr = &options->hostbased_uses_name_from_packet_only;
goto parse_flag;
2015-07-02 13:15:34 +00:00
case sHostbasedAcceptedKeyTypes:
charptr = &options->hostbased_key_types;
parse_keytypes:
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: Missing argument.",
filename, linenum);
2017-08-03 10:10:20 +00:00
if (*arg != '-' &&
!sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1))
2015-07-02 13:15:34 +00:00
fatal("%s line %d: Bad key types '%s'.",
filename, linenum, arg ? arg : "<NONE>");
if (*activep && *charptr == NULL)
*charptr = xstrdup(arg);
break;
2015-08-26 09:25:17 +00:00
case sHostKeyAlgorithms:
charptr = &options->hostkeyalgorithms;
goto parse_keytypes;
2019-02-05 15:03:53 +00:00
case sCASignatureAlgorithms:
charptr = &options->ca_sign_algorithms;
goto parse_keytypes;
2002-03-18 10:09:43 +00:00
case sPubkeyAuthentication:
intptr = &options->pubkey_authentication;
goto parse_flag;
2015-07-02 13:15:34 +00:00
case sPubkeyAcceptedKeyTypes:
charptr = &options->pubkey_key_types;
goto parse_keytypes;
2002-03-18 10:09:43 +00:00
case sKerberosAuthentication:
intptr = &options->kerberos_authentication;
goto parse_flag;
2000-02-24 14:29:47 +00:00
2002-03-18 10:09:43 +00:00
case sKerberosOrLocalPasswd:
intptr = &options->kerberos_or_local_passwd;
goto parse_flag;
2002-03-18 10:09:43 +00:00
case sKerberosTicketCleanup:
intptr = &options->kerberos_ticket_cleanup;
goto parse_flag;
2004-02-26 10:52:33 +00:00
case sKerberosGetAFSToken:
intptr = &options->kerberos_get_afs_token;
goto parse_flag;
case sGssAuthentication:
intptr = &options->gss_authentication;
2002-03-18 10:09:43 +00:00
goto parse_flag;
case sGssCleanupCreds:
intptr = &options->gss_cleanup_creds;
2002-03-18 10:09:43 +00:00
goto parse_flag;
2000-02-24 14:29:47 +00:00
2015-07-02 13:18:50 +00:00
case sGssStrictAcceptor:
intptr = &options->gss_strict_acceptor;
goto parse_flag;
2002-03-18 10:09:43 +00:00
case sPasswordAuthentication:
intptr = &options->password_authentication;
goto parse_flag;
2000-02-24 14:29:47 +00:00
2002-03-18 10:09:43 +00:00
case sKbdInteractiveAuthentication:
intptr = &options->kbd_interactive_authentication;
goto parse_flag;
2000-02-24 14:29:47 +00:00
2002-03-18 10:09:43 +00:00
case sChallengeResponseAuthentication:
intptr = &options->challenge_response_authentication;
goto parse_flag;
2000-02-24 14:29:47 +00:00
2002-03-18 10:09:43 +00:00
case sPrintMotd:
intptr = &options->print_motd;
goto parse_flag;
2001-05-04 04:14:23 +00:00
2002-03-18 10:09:43 +00:00
case sPrintLastLog:
intptr = &options->print_lastlog;
goto parse_flag;
2000-02-24 14:29:47 +00:00
2002-03-18 10:09:43 +00:00
case sX11Forwarding:
intptr = &options->x11_forwarding;
goto parse_flag;
2000-02-24 14:29:47 +00:00
2002-03-18 10:09:43 +00:00
case sX11DisplayOffset:
intptr = &options->x11_display_offset;
2017-01-31 12:33:47 +00:00
parse_int:
arg = strdelim(&cp);
2018-05-06 12:27:04 +00:00
if ((errstr = atoi_err(arg, &value)) != NULL)
fatal("%s line %d: integer value %s.",
filename, linenum, errstr);
2017-01-31 12:33:47 +00:00
if (*activep && *intptr == -1)
*intptr = value;
break;
2001-05-04 04:14:23 +00:00
2002-03-18 10:09:43 +00:00
case sX11UseLocalhost:
intptr = &options->x11_use_localhost;
goto parse_flag;
2000-02-24 14:29:47 +00:00
2002-03-18 10:09:43 +00:00
case sXAuthLocation:
charptr = &options->xauth_location;
goto parse_filename;
2000-02-24 14:29:47 +00:00
2014-01-30 10:56:49 +00:00
case sPermitTTY:
intptr = &options->permit_tty;
goto parse_flag;
2015-01-05 16:09:55 +00:00
case sPermitUserRC:
intptr = &options->permit_user_rc;
goto parse_flag;
2002-03-18 10:09:43 +00:00
case sStrictModes:
intptr = &options->strict_modes;
goto parse_flag;
2000-02-24 14:29:47 +00:00
2004-02-26 10:52:33 +00:00
case sTCPKeepAlive:
intptr = &options->tcp_keep_alive;
2002-03-18 10:09:43 +00:00
goto parse_flag;
2000-02-24 14:29:47 +00:00
2002-03-18 10:09:43 +00:00
case sEmptyPasswd:
intptr = &options->permit_empty_passwd;
goto parse_flag;
2002-10-29 10:16:02 +00:00
case sPermitUserEnvironment:
intptr = &options->permit_user_env;
2018-08-28 10:47:58 +00:00
charptr = &options->permit_user_env_whitelist;
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: missing argument.",
filename, linenum);
value = 0;
p = NULL;
if (strcmp(arg, "yes") == 0)
value = 1;
else if (strcmp(arg, "no") == 0)
value = 0;
else {
/* Pattern-list specified */
value = 1;
p = xstrdup(arg);
}
if (*activep && *intptr == -1) {
*intptr = value;
*charptr = p;
p = NULL;
}
free(p);
break;
2002-10-29 10:16:02 +00:00
case sCompression:
intptr = &options->compression;
2011-09-28 08:14:41 +00:00
multistate_ptr = multistate_compression;
goto parse_multistate;
2013-09-18 17:27:38 +00:00
case sRekeyLimit:
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%.200s line %d: Missing argument.", filename,
linenum);
if (strcmp(arg, "default") == 0) {
val64 = 0;
} else {
if (scan_scaled(arg, &val64) == -1)
fatal("%.200s line %d: Bad number '%s': %s",
filename, linenum, arg, strerror(errno));
if (val64 != 0 && val64 < 16)
fatal("%.200s line %d: RekeyLimit too small",
filename, linenum);
}
if (*activep && options->rekey_limit == -1)
2016-03-10 20:10:25 +00:00
options->rekey_limit = val64;
2013-09-18 17:27:38 +00:00
if (cp != NULL) { /* optional rekey interval present */
if (strcmp(cp, "none") == 0) {
(void)strdelim(&cp); /* discard */
break;
}
intptr = &options->rekey_interval;
goto parse_time;
}
break;
2002-03-18 10:09:43 +00:00
case sGatewayPorts:
2015-01-05 16:09:55 +00:00
intptr = &options->fwd_opts.gateway_ports;
2011-09-28 08:14:41 +00:00
multistate_ptr = multistate_gatewayports;
goto parse_multistate;
2000-02-24 14:29:47 +00:00
case sUseDNS:
intptr = &options->use_dns;
2002-03-18 10:09:43 +00:00
goto parse_flag;
2002-03-18 10:09:43 +00:00
case sLogFacility:
log_facility_ptr = &options->log_facility;
2002-03-18 10:09:43 +00:00
arg = strdelim(&cp);
value = log_facility_number(arg);
if (value == SYSLOG_FACILITY_NOT_SET)
fatal("%.200s line %d: unsupported log facility '%s'",
filename, linenum, arg ? arg : "<NONE>");
if (*log_facility_ptr == -1)
*log_facility_ptr = (SyslogFacility) value;
2002-03-18 10:09:43 +00:00
break;
case sLogLevel:
log_level_ptr = &options->log_level;
2002-03-18 10:09:43 +00:00
arg = strdelim(&cp);
value = log_level_number(arg);
if (value == SYSLOG_LEVEL_NOT_SET)
fatal("%.200s line %d: unsupported log level '%s'",
filename, linenum, arg ? arg : "<NONE>");
2018-05-06 12:24:45 +00:00
if (*activep && *log_level_ptr == -1)
*log_level_ptr = (LogLevel) value;
2002-03-18 10:09:43 +00:00
break;
case sAllowTcpForwarding:
intptr = &options->allow_tcp_forwarding;
2013-03-22 11:19:48 +00:00
multistate_ptr = multistate_tcpfwd;
goto parse_multistate;
2002-03-18 10:09:43 +00:00
2015-01-05 16:09:55 +00:00
case sAllowStreamLocalForwarding:
intptr = &options->allow_streamlocal_forwarding;
multistate_ptr = multistate_tcpfwd;
goto parse_multistate;
2008-07-23 09:33:08 +00:00
case sAllowAgentForwarding:
intptr = &options->allow_agent_forwarding;
goto parse_flag;
2017-01-31 12:33:47 +00:00
case sDisableForwarding:
intptr = &options->disable_forwarding;
goto parse_flag;
2002-03-18 10:09:43 +00:00
case sAllowUsers:
while ((arg = strdelim(&cp)) && *arg != '\0') {
2017-01-31 12:33:47 +00:00
if (match_user(NULL, NULL, NULL, arg) == -1)
fatal("%s line %d: invalid AllowUsers pattern: "
"\"%.100s\"", filename, linenum, arg);
2012-08-29 15:55:54 +00:00
if (!*activep)
continue;
2018-05-06 12:27:04 +00:00
array_append(filename, linenum, "AllowUsers",
&options->allow_users, &options->num_allow_users,
arg);
2002-03-18 10:09:43 +00:00
}
break;
2000-02-24 14:29:47 +00:00
2002-03-18 10:09:43 +00:00
case sDenyUsers:
while ((arg = strdelim(&cp)) && *arg != '\0') {
2017-01-31 12:33:47 +00:00
if (match_user(NULL, NULL, NULL, arg) == -1)
fatal("%s line %d: invalid DenyUsers pattern: "
"\"%.100s\"", filename, linenum, arg);
2012-08-29 15:55:54 +00:00
if (!*activep)
continue;
2018-05-06 12:27:04 +00:00
array_append(filename, linenum, "DenyUsers",
&options->deny_users, &options->num_deny_users,
arg);
2002-03-18 10:09:43 +00:00
}
break;
2000-02-24 14:29:47 +00:00
2002-03-18 10:09:43 +00:00
case sAllowGroups:
while ((arg = strdelim(&cp)) && *arg != '\0') {
2012-08-29 15:55:54 +00:00
if (!*activep)
continue;
2018-05-06 12:27:04 +00:00
array_append(filename, linenum, "AllowGroups",
&options->allow_groups, &options->num_allow_groups,
arg);
2002-03-18 10:09:43 +00:00
}
break;
2002-03-18 10:09:43 +00:00
case sDenyGroups:
while ((arg = strdelim(&cp)) && *arg != '\0') {
2012-08-29 15:55:54 +00:00
if (!*activep)
continue;
2018-05-06 12:27:04 +00:00
array_append(filename, linenum, "DenyGroups",
&options->deny_groups, &options->num_deny_groups,
arg);
2002-03-18 10:09:43 +00:00
}
break;
2001-05-04 04:14:23 +00:00
2002-03-18 10:09:43 +00:00
case sCiphers:
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: Missing argument.", filename, linenum);
2017-08-03 10:10:20 +00:00
if (*arg != '-' && !ciphers_valid(*arg == '+' ? arg + 1 : arg))
2002-03-18 10:09:43 +00:00
fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
filename, linenum, arg ? arg : "<NONE>");
if (options->ciphers == NULL)
options->ciphers = xstrdup(arg);
break;
case sMacs:
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: Missing argument.", filename, linenum);
2017-08-03 10:10:20 +00:00
if (*arg != '-' && !mac_valid(*arg == '+' ? arg + 1 : arg))
2002-03-18 10:09:43 +00:00
fatal("%s line %d: Bad SSH2 mac spec '%s'.",
filename, linenum, arg ? arg : "<NONE>");
if (options->macs == NULL)
options->macs = xstrdup(arg);
break;
2011-02-17 11:47:40 +00:00
case sKexAlgorithms:
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: Missing argument.",
filename, linenum);
2017-08-03 10:10:20 +00:00
if (*arg != '-' &&
!kex_names_valid(*arg == '+' ? arg + 1 : arg))
2011-02-17 11:47:40 +00:00
fatal("%s line %d: Bad SSH2 KexAlgorithms '%s'.",
filename, linenum, arg ? arg : "<NONE>");
if (options->kex_algorithms == NULL)
options->kex_algorithms = xstrdup(arg);
break;
2002-03-18 10:09:43 +00:00
case sSubsystem:
if (options->num_subsystems >= MAX_SUBSYSTEMS) {
fatal("%s line %d: too many subsystems defined.",
filename, linenum);
}
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: Missing subsystem name.",
filename, linenum);
2006-09-30 13:38:06 +00:00
if (!*activep) {
arg = strdelim(&cp);
break;
}
2002-03-18 10:09:43 +00:00
for (i = 0; i < options->num_subsystems; i++)
if (strcmp(arg, options->subsystem_name[i]) == 0)
fatal("%s line %d: Subsystem '%s' already defined.",
filename, linenum, arg);
options->subsystem_name[options->num_subsystems] = xstrdup(arg);
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: Missing subsystem command.",
filename, linenum);
options->subsystem_command[options->num_subsystems] = xstrdup(arg);
2006-09-30 13:38:06 +00:00
/* Collect arguments (separate to executable) */
p = xstrdup(arg);
len = strlen(p) + 1;
while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
len += 1 + strlen(arg);
2015-07-02 13:18:50 +00:00
p = xreallocarray(p, 1, len);
2006-09-30 13:38:06 +00:00
strlcat(p, " ", len);
strlcat(p, arg, len);
}
options->subsystem_args[options->num_subsystems] = p;
2002-03-18 10:09:43 +00:00
options->num_subsystems++;
break;
case sMaxStartups:
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: Missing MaxStartups spec.",
filename, linenum);
if ((n = sscanf(arg, "%d:%d:%d",
&options->max_startups_begin,
&options->max_startups_rate,
&options->max_startups)) == 3) {
if (options->max_startups_begin >
options->max_startups ||
options->max_startups_rate > 100 ||
options->max_startups_rate < 1)
fatal("%s line %d: Illegal MaxStartups spec.",
filename, linenum);
} else if (n != 1)
fatal("%s line %d: Illegal MaxStartups spec.",
filename, linenum);
else
options->max_startups = options->max_startups_begin;
break;
2004-10-28 16:11:31 +00:00
case sMaxAuthTries:
intptr = &options->max_authtries;
goto parse_int;
2008-07-23 09:33:08 +00:00
case sMaxSessions:
intptr = &options->max_sessions;
goto parse_int;
2002-03-18 10:09:43 +00:00
case sBanner:
charptr = &options->banner;
goto parse_filename;
2002-03-18 10:09:43 +00:00
/*
* These options can contain %X options expanded at
* connect time, so that you can specify paths like:
*
* AuthorizedKeysFile /etc/ssh_keys/%u
*/
case sAuthorizedKeysFile:
2011-09-28 08:14:41 +00:00
if (*activep && options->num_authkeys_files == 0) {
while ((arg = strdelim(&cp)) && *arg != '\0') {
2018-05-06 12:27:04 +00:00
arg = tilde_expand_filename(arg, getuid());
array_append(filename, linenum,
"AuthorizedKeysFile",
&options->authorized_keys_files,
&options->num_authkeys_files, arg);
free(arg);
2011-09-28 08:14:41 +00:00
}
}
return 0;
2010-11-08 10:45:44 +00:00
case sAuthorizedPrincipalsFile:
charptr = &options->authorized_principals_file;
2010-04-28 08:37:00 +00:00
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: missing file name.",
filename, linenum);
if (*activep && *charptr == NULL) {
*charptr = tilde_expand_filename(arg, getuid());
/* increase optional counter */
if (intptr != NULL)
*intptr = *intptr + 1;
}
break;
2002-03-18 10:09:43 +00:00
case sClientAliveInterval:
intptr = &options->client_alive_interval;
goto parse_time;
case sClientAliveCountMax:
intptr = &options->client_alive_count_max;
goto parse_int;
2004-10-28 16:11:31 +00:00
case sAcceptEnv:
while ((arg = strdelim(&cp)) && *arg != '\0') {
if (strchr(arg, '=') != NULL)
fatal("%s line %d: Invalid environment name.",
filename, linenum);
2006-09-30 13:38:06 +00:00
if (!*activep)
2012-08-29 15:55:54 +00:00
continue;
2018-05-06 12:27:04 +00:00
array_append(filename, linenum, "AcceptEnv",
&options->accept_env, &options->num_accept_env,
arg);
2004-10-28 16:11:31 +00:00
}
break;
2018-08-28 10:47:58 +00:00
case sSetEnv:
uvalue = options->num_setenv;
while ((arg = strdelimw(&cp)) && *arg != '\0') {
if (strchr(arg, '=') == NULL)
fatal("%s line %d: Invalid environment.",
filename, linenum);
if (!*activep || uvalue != 0)
continue;
array_append(filename, linenum, "SetEnv",
&options->setenv, &options->num_setenv, arg);
}
break;
2006-03-22 20:41:37 +00:00
case sPermitTunnel:
intptr = &options->permit_tun;
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: Missing yes/point-to-point/"
"ethernet/no argument.", filename, linenum);
2008-07-23 09:33:08 +00:00
value = -1;
for (i = 0; tunmode_desc[i].val != -1; i++)
if (strcmp(tunmode_desc[i].text, arg) == 0) {
value = tunmode_desc[i].val;
break;
}
if (value == -1)
2006-03-22 20:41:37 +00:00
fatal("%s line %d: Bad yes/point-to-point/ethernet/"
"no argument: %s", filename, linenum, arg);
2015-07-02 13:18:50 +00:00
if (*activep && *intptr == -1)
2006-03-22 20:41:37 +00:00
*intptr = value;
break;
2006-09-30 13:38:06 +00:00
case sMatch:
if (cmdline)
fatal("Match directive not supported as a command-line "
"option");
2012-08-29 15:55:54 +00:00
value = match_cfg_line(&cp, linenum, connectinfo);
2006-09-30 13:38:06 +00:00
if (value < 0)
fatal("%s line %d: Bad Match condition", filename,
linenum);
*activep = value;
break;
2018-08-28 10:47:58 +00:00
case sPermitListen:
2006-09-30 13:38:06 +00:00
case sPermitOpen:
2018-08-28 10:47:58 +00:00
if (opcode == sPermitListen) {
uintptr = &options->num_permitted_listens;
chararrayptr = &options->permitted_listens;
} else {
uintptr = &options->num_permitted_opens;
chararrayptr = &options->permitted_opens;
}
2006-09-30 13:38:06 +00:00
arg = strdelim(&cp);
if (!arg || *arg == '\0')
2018-08-28 10:47:58 +00:00
fatal("%s line %d: missing %s specification",
filename, linenum, lookup_opcode_name(opcode));
uvalue = *uintptr; /* modified later */
2018-05-06 12:24:45 +00:00
if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) {
2018-08-28 10:47:58 +00:00
if (*activep && uvalue == 0) {
*uintptr = 1;
*chararrayptr = xcalloc(1,
sizeof(**chararrayptr));
(*chararrayptr)[0] = xstrdup(arg);
2012-08-29 15:55:54 +00:00
}
break;
}
2006-09-30 13:38:06 +00:00
for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
2018-08-28 10:47:58 +00:00
if (opcode == sPermitListen &&
strchr(arg, ':') == NULL) {
/*
* Allow bare port number for PermitListen
* to indicate a wildcard listen host.
*/
xasprintf(&arg2, "*:%s", arg);
} else {
arg2 = xstrdup(arg);
p = hpdelim(&arg);
if (p == NULL) {
fatal("%s line %d: missing host in %s",
filename, linenum,
lookup_opcode_name(opcode));
}
p = cleanhostname(p);
}
if (arg == NULL ||
((port = permitopen_port(arg)) < 0)) {
fatal("%s line %d: bad port number in %s",
filename, linenum,
lookup_opcode_name(opcode));
}
if (*activep && uvalue == 0) {
2018-05-06 12:27:04 +00:00
array_append(filename, linenum,
2018-08-28 10:47:58 +00:00
lookup_opcode_name(opcode),
chararrayptr, uintptr, arg2);
2018-05-06 12:27:04 +00:00
}
free(arg2);
2006-09-30 13:38:06 +00:00
}
break;
case sForceCommand:
2015-07-02 13:18:50 +00:00
if (cp == NULL || *cp == '\0')
2006-09-30 13:38:06 +00:00
fatal("%.200s line %d: Missing argument.", filename,
linenum);
len = strspn(cp, WHITESPACE);
if (*activep && options->adm_forced_command == NULL)
options->adm_forced_command = xstrdup(cp + len);
return 0;
case sChrootDirectory:
charptr = &options->chroot_directory;
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: missing file name.",
filename, linenum);
if (*activep && *charptr == NULL)
*charptr = xstrdup(arg);
break;
2010-03-08 11:19:52 +00:00
case sTrustedUserCAKeys:
charptr = &options->trusted_user_ca_keys;
goto parse_filename;
case sRevokedKeys:
charptr = &options->revoked_keys_file;
goto parse_filename;
2011-02-17 11:47:40 +00:00
case sIPQoS:
arg = strdelim(&cp);
if ((value = parse_ipqos(arg)) == -1)
fatal("%s line %d: Bad IPQoS value: %s",
filename, linenum, arg);
arg = strdelim(&cp);
if (arg == NULL)
value2 = value;
else if ((value2 = parse_ipqos(arg)) == -1)
fatal("%s line %d: Bad IPQoS value: %s",
filename, linenum, arg);
if (*activep) {
options->ip_qos_interactive = value;
options->ip_qos_bulk = value2;
}
break;
case sVersionAddendum:
2015-07-02 13:18:50 +00:00
if (cp == NULL || *cp == '\0')
2012-08-29 15:55:54 +00:00
fatal("%.200s line %d: Missing argument.", filename,
linenum);
len = strspn(cp, WHITESPACE);
if (*activep && options->version_addendum == NULL) {
if (strcasecmp(cp + len, "none") == 0)
options->version_addendum = xstrdup("");
else if (strchr(cp + len, '\r') != NULL)
fatal("%.200s line %d: Invalid argument",
filename, linenum);
else
options->version_addendum = xstrdup(cp + len);
}
return 0;
2013-03-22 11:19:48 +00:00
case sAuthorizedKeysCommand:
2015-07-02 13:15:34 +00:00
if (cp == NULL)
fatal("%.200s line %d: Missing argument.", filename,
linenum);
2013-03-22 11:19:48 +00:00
len = strspn(cp, WHITESPACE);
if (*activep && options->authorized_keys_command == NULL) {
if (cp[len] != '/' && strcasecmp(cp + len, "none") != 0)
fatal("%.200s line %d: AuthorizedKeysCommand "
"must be an absolute path",
filename, linenum);
options->authorized_keys_command = xstrdup(cp + len);
}
return 0;
case sAuthorizedKeysCommandUser:
charptr = &options->authorized_keys_command_user;
arg = strdelim(&cp);
2015-07-02 13:15:34 +00:00
if (!arg || *arg == '\0')
fatal("%s line %d: missing AuthorizedKeysCommandUser "
"argument.", filename, linenum);
2013-03-22 11:19:48 +00:00
if (*activep && *charptr == NULL)
*charptr = xstrdup(arg);
break;
2015-07-02 13:18:50 +00:00
case sAuthorizedPrincipalsCommand:
if (cp == NULL)
fatal("%.200s line %d: Missing argument.", filename,
linenum);
len = strspn(cp, WHITESPACE);
if (*activep &&
options->authorized_principals_command == NULL) {
if (cp[len] != '/' && strcasecmp(cp + len, "none") != 0)
fatal("%.200s line %d: "
"AuthorizedPrincipalsCommand must be "
"an absolute path", filename, linenum);
options->authorized_principals_command =
xstrdup(cp + len);
}
return 0;
case sAuthorizedPrincipalsCommandUser:
charptr = &options->authorized_principals_command_user;
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: missing "
"AuthorizedPrincipalsCommandUser argument.",
filename, linenum);
if (*activep && *charptr == NULL)
*charptr = xstrdup(arg);
break;
2013-03-22 11:19:48 +00:00
case sAuthenticationMethods:
2015-07-02 13:18:50 +00:00
if (options->num_auth_methods == 0) {
2017-01-31 12:29:48 +00:00
value = 0; /* seen "any" pseudo-method */
2018-08-28 10:47:58 +00:00
value2 = 0; /* successfully parsed any method */
2013-03-22 11:19:48 +00:00
while ((arg = strdelim(&cp)) && *arg != '\0') {
2017-01-31 12:29:48 +00:00
if (strcmp(arg, "any") == 0) {
if (options->num_auth_methods > 0) {
fatal("%s line %d: \"any\" "
"must appear alone in "
"AuthenticationMethods",
filename, linenum);
}
value = 1;
} else if (value) {
fatal("%s line %d: \"any\" must appear "
"alone in AuthenticationMethods",
filename, linenum);
} else if (auth2_methods_valid(arg, 0) != 0) {
2013-03-22 11:19:48 +00:00
fatal("%s line %d: invalid "
"authentication method list.",
filename, linenum);
2017-01-31 12:29:48 +00:00
}
value2 = 1;
2015-07-02 13:18:50 +00:00
if (!*activep)
continue;
2018-05-06 12:27:04 +00:00
array_append(filename, linenum,
"AuthenticationMethods",
&options->auth_methods,
&options->num_auth_methods, arg);
2013-03-22 11:19:48 +00:00
}
2017-01-31 12:29:48 +00:00
if (value2 == 0) {
fatal("%s line %d: no AuthenticationMethods "
"specified", filename, linenum);
}
2013-03-22 11:19:48 +00:00
}
return 0;
2015-01-05 16:09:55 +00:00
case sStreamLocalBindMask:
arg = strdelim(&cp);
if (!arg || *arg == '\0')
2015-07-02 13:18:50 +00:00
fatal("%s line %d: missing StreamLocalBindMask "
"argument.", filename, linenum);
2015-01-05 16:09:55 +00:00
/* Parse mode in octal format */
value = strtol(arg, &p, 8);
if (arg == p || value < 0 || value > 0777)
fatal("%s line %d: Bad mask.", filename, linenum);
2015-07-02 13:18:50 +00:00
if (*activep)
options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
2015-01-05 16:09:55 +00:00
break;
case sStreamLocalBindUnlink:
intptr = &options->fwd_opts.streamlocal_bind_unlink;
goto parse_flag;
2015-07-02 13:15:34 +00:00
case sFingerprintHash:
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%.200s line %d: Missing argument.",
filename, linenum);
if ((value = ssh_digest_alg_by_name(arg)) == -1)
fatal("%.200s line %d: Invalid hash algorithm \"%s\".",
filename, linenum, arg);
if (*activep)
options->fingerprint_hash = value;
break;
2018-05-06 12:24:45 +00:00
case sExposeAuthInfo:
intptr = &options->expose_userauth_info;
goto parse_flag;
2018-05-06 12:27:04 +00:00
case sRDomain:
charptr = &options->routing_domain;
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%.200s line %d: Missing argument.",
filename, linenum);
if (strcasecmp(arg, "none") != 0 && strcmp(arg, "%D") != 0 &&
!valid_rdomain(arg))
fatal("%s line %d: bad routing domain",
filename, linenum);
if (*activep && *charptr == NULL)
*charptr = xstrdup(arg);
break;
case sUseBlacklist:
intptr = &options->use_blacklist;
goto parse_flag;
2002-03-18 10:09:43 +00:00
case sDeprecated:
2017-01-31 12:33:47 +00:00
case sIgnore:
case sUnsupported:
2017-01-31 12:33:47 +00:00
do_log2(opcode == sIgnore ?
SYSLOG_LEVEL_DEBUG2 : SYSLOG_LEVEL_INFO,
"%s line %d: %s option %s", filename, linenum,
opcode == sUnsupported ? "Unsupported" : "Deprecated", arg);
2002-03-18 10:09:43 +00:00
while (arg)
arg = strdelim(&cp);
break;
default:
fatal("%s line %d: Missing handler for opcode %s (%d)",
filename, linenum, arg, opcode);
}
if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
fatal("%s line %d: garbage at end of line; \"%.200s\".",
filename, linenum, arg);
return 0;
}
2002-03-18 10:09:43 +00:00
/* Reads the server configuration file. */
2002-03-18 10:09:43 +00:00
void
2018-08-28 10:47:58 +00:00
load_server_config(const char *filename, struct sshbuf *conf)
2002-03-18 10:09:43 +00:00
{
2018-08-28 10:47:58 +00:00
char *line = NULL, *cp;
size_t linesize = 0;
FILE *f;
2018-08-28 10:47:58 +00:00
int r, lineno = 0;
2004-10-28 16:11:31 +00:00
debug2("%s: filename %s", __func__, filename);
if ((f = fopen(filename, "r")) == NULL) {
2002-03-18 10:09:43 +00:00
perror(filename);
exit(1);
}
2018-08-28 10:47:58 +00:00
sshbuf_reset(conf);
while (getline(&line, &linesize, f) != -1) {
2012-08-29 15:55:54 +00:00
lineno++;
2004-10-28 16:11:31 +00:00
/*
* Trim out comments and strip whitespace
* NB - preserve newlines, they are needed to reproduce
* line numbers later for error messages
*/
if ((cp = strchr(line, '#')) != NULL)
memcpy(cp, "\n", 2);
cp = line + strspn(line, " \t\r");
2018-08-28 10:47:58 +00:00
if ((r = sshbuf_put(conf, cp, strlen(cp))) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
2000-02-24 14:29:47 +00:00
}
2018-08-28 10:47:58 +00:00
free(line);
if ((r = sshbuf_put_u8(conf, 0)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
2000-02-24 14:29:47 +00:00
fclose(f);
2018-08-28 10:47:58 +00:00
debug2("%s: done config len = %zu", __func__, sshbuf_len(conf));
2004-10-28 16:11:31 +00:00
}
void
2012-08-29 15:55:54 +00:00
parse_server_match_config(ServerOptions *options,
struct connection_info *connectinfo)
2006-09-30 13:38:06 +00:00
{
ServerOptions mo;
initialize_server_options(&mo);
2018-08-28 10:47:58 +00:00
parse_server_config(&mo, "reprocess config", cfg, connectinfo);
copy_set_server_options(options, &mo, 0);
2006-09-30 13:38:06 +00:00
}
2012-08-29 15:55:54 +00:00
int parse_server_match_testspec(struct connection_info *ci, char *spec)
{
char *p;
while ((p = strsep(&spec, ",")) && *p != '\0') {
if (strncmp(p, "addr=", 5) == 0) {
ci->address = xstrdup(p + 5);
} else if (strncmp(p, "host=", 5) == 0) {
ci->host = xstrdup(p + 5);
} else if (strncmp(p, "user=", 5) == 0) {
ci->user = xstrdup(p + 5);
} else if (strncmp(p, "laddr=", 6) == 0) {
ci->laddress = xstrdup(p + 6);
2018-05-06 12:27:04 +00:00
} else if (strncmp(p, "rdomain=", 8) == 0) {
ci->rdomain = xstrdup(p + 8);
2012-08-29 15:55:54 +00:00
} else if (strncmp(p, "lport=", 6) == 0) {
ci->lport = a2port(p + 6);
if (ci->lport == -1) {
fprintf(stderr, "Invalid port '%s' in test mode"
" specification %s\n", p+6, p);
return -1;
}
} else {
fprintf(stderr, "Invalid test mode specification %s\n",
p);
return -1;
}
}
return 0;
}
/*
* Copy any supported values that are set.
*
2009-10-01 15:19:37 +00:00
* If the preauth flag is set, we do not bother copying the string or
* array values that are not used pre-authentication, because any that we
2018-08-28 10:47:58 +00:00
* do use must be explicitly sent in mm_getpwnamallow().
*/
2006-09-30 13:38:06 +00:00
void
copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
2006-09-30 13:38:06 +00:00
{
2014-01-30 10:56:49 +00:00
#define M_CP_INTOPT(n) do {\
if (src->n != -1) \
dst->n = src->n; \
} while (0)
M_CP_INTOPT(password_authentication);
M_CP_INTOPT(gss_authentication);
M_CP_INTOPT(pubkey_authentication);
M_CP_INTOPT(kerberos_authentication);
M_CP_INTOPT(hostbased_authentication);
2010-11-08 10:45:44 +00:00
M_CP_INTOPT(hostbased_uses_name_from_packet_only);
M_CP_INTOPT(kbd_interactive_authentication);
M_CP_INTOPT(permit_root_login);
2009-02-24 18:49:27 +00:00
M_CP_INTOPT(permit_empty_passwd);
M_CP_INTOPT(allow_tcp_forwarding);
2015-01-05 16:09:55 +00:00
M_CP_INTOPT(allow_streamlocal_forwarding);
2008-07-23 09:33:08 +00:00
M_CP_INTOPT(allow_agent_forwarding);
2017-01-31 12:33:47 +00:00
M_CP_INTOPT(disable_forwarding);
2018-05-06 12:24:45 +00:00
M_CP_INTOPT(expose_userauth_info);
2010-11-08 10:45:44 +00:00
M_CP_INTOPT(permit_tun);
2015-01-05 16:09:55 +00:00
M_CP_INTOPT(fwd_opts.gateway_ports);
2017-01-31 12:29:48 +00:00
M_CP_INTOPT(fwd_opts.streamlocal_bind_unlink);
M_CP_INTOPT(x11_display_offset);
M_CP_INTOPT(x11_forwarding);
M_CP_INTOPT(x11_use_localhost);
2014-01-30 10:56:49 +00:00
M_CP_INTOPT(permit_tty);
2015-01-05 16:09:55 +00:00
M_CP_INTOPT(permit_user_rc);
2008-07-23 09:33:08 +00:00
M_CP_INTOPT(max_sessions);
M_CP_INTOPT(max_authtries);
2017-01-31 12:33:47 +00:00
M_CP_INTOPT(client_alive_count_max);
M_CP_INTOPT(client_alive_interval);
2011-02-17 11:47:40 +00:00
M_CP_INTOPT(ip_qos_interactive);
M_CP_INTOPT(ip_qos_bulk);
2013-09-18 17:27:38 +00:00
M_CP_INTOPT(rekey_limit);
M_CP_INTOPT(rekey_interval);
2018-05-06 12:24:45 +00:00
M_CP_INTOPT(log_level);
2017-01-31 12:29:48 +00:00
/*
* The bind_mask is a mode_t that may be unsigned, so we can't use
* M_CP_INTOPT - it does a signed comparison that causes compiler
* warnings.
*/
if (src->fwd_opts.streamlocal_bind_mask != (mode_t)-1) {
dst->fwd_opts.streamlocal_bind_mask =
src->fwd_opts.streamlocal_bind_mask;
}
2014-01-30 10:56:49 +00:00
/* M_CP_STROPT and M_CP_STRARRAYOPT should not appear before here */
#define M_CP_STROPT(n) do {\
if (src->n != NULL && dst->n != src->n) { \
free(dst->n); \
dst->n = src->n; \
} \
} while(0)
2018-05-06 12:27:04 +00:00
#define M_CP_STRARRAYOPT(s, num_s) do {\
u_int i; \
if (src->num_s != 0) { \
for (i = 0; i < dst->num_s; i++) \
free(dst->s[i]); \
free(dst->s); \
dst->s = xcalloc(src->num_s, sizeof(*dst->s)); \
for (i = 0; i < src->num_s; i++) \
dst->s[i] = xstrdup(src->s[i]); \
dst->num_s = src->num_s; \
2018-05-06 12:24:45 +00:00
} \
} while(0)
2014-01-30 10:56:49 +00:00
2011-09-28 08:14:41 +00:00
/* See comment in servconf.h */
COPY_MATCH_STRING_OPTS();
2016-03-10 20:10:25 +00:00
/* Arguments that accept '+...' need to be expanded */
assemble_algorithms(dst);
2011-09-28 08:14:41 +00:00
/*
* The only things that should be below this point are string options
* which are only used after authentication.
*/
if (preauth)
return;
2011-09-28 08:14:41 +00:00
2016-03-10 20:10:25 +00:00
/* These options may be "none" to clear a global setting */
M_CP_STROPT(adm_forced_command);
2016-03-10 20:10:25 +00:00
if (option_clear_or_none(dst->adm_forced_command)) {
free(dst->adm_forced_command);
dst->adm_forced_command = NULL;
}
M_CP_STROPT(chroot_directory);
2016-03-10 20:10:25 +00:00
if (option_clear_or_none(dst->chroot_directory)) {
free(dst->chroot_directory);
dst->chroot_directory = NULL;
}
2006-09-30 13:38:06 +00:00
}
#undef M_CP_INTOPT
#undef M_CP_STROPT
2011-09-28 08:14:41 +00:00
#undef M_CP_STRARRAYOPT
2006-09-30 13:38:06 +00:00
void
2018-08-28 10:47:58 +00:00
parse_server_config(ServerOptions *options, const char *filename,
struct sshbuf *conf, struct connection_info *connectinfo)
2004-10-28 16:11:31 +00:00
{
2006-09-30 13:38:06 +00:00
int active, linenum, bad_options = 0;
2004-10-28 16:11:31 +00:00
char *cp, *obuf, *cbuf;
2018-08-28 10:47:58 +00:00
debug2("%s: config %s len %zu", __func__, filename, sshbuf_len(conf));
2004-10-28 16:11:31 +00:00
2017-01-31 12:29:48 +00:00
if ((obuf = cbuf = sshbuf_dup_string(conf)) == NULL)
fatal("%s: sshbuf_dup_string failed", __func__);
2012-08-29 15:55:54 +00:00
active = connectinfo ? 0 : 1;
2004-10-28 16:11:31 +00:00
linenum = 1;
2005-06-05 15:46:09 +00:00
while ((cp = strsep(&cbuf, "\n")) != NULL) {
2004-10-28 16:11:31 +00:00
if (process_server_config_line(options, cp, filename,
2012-08-29 15:55:54 +00:00
linenum++, &active, connectinfo) != 0)
2004-10-28 16:11:31 +00:00
bad_options++;
}
2013-09-18 17:27:38 +00:00
free(obuf);
2001-05-04 04:14:23 +00:00
if (bad_options > 0)
2002-03-18 10:09:43 +00:00
fatal("%s: terminating, %d bad configuration options",
2001-05-04 04:14:23 +00:00
filename, bad_options);
2015-07-02 13:18:50 +00:00
process_queued_listen_addrs(options);
2000-02-24 14:29:47 +00:00
}
2008-07-23 09:33:08 +00:00
static const char *
2011-09-28 08:14:41 +00:00
fmt_multistate_int(int val, const struct multistate *m)
2008-07-23 09:33:08 +00:00
{
2011-09-28 08:14:41 +00:00
u_int i;
for (i = 0; m[i].key != NULL; i++) {
if (m[i].value == val)
return m[i].key;
2008-07-23 09:33:08 +00:00
}
2011-09-28 08:14:41 +00:00
return "UNKNOWN";
}
static const char *
fmt_intarg(ServerOpCodes code, int val)
{
if (val == -1)
return "unset";
switch (code) {
case sAddressFamily:
return fmt_multistate_int(val, multistate_addressfamily);
case sPermitRootLogin:
return fmt_multistate_int(val, multistate_permitrootlogin);
case sGatewayPorts:
return fmt_multistate_int(val, multistate_gatewayports);
case sCompression:
return fmt_multistate_int(val, multistate_compression);
2013-03-22 11:19:48 +00:00
case sAllowTcpForwarding:
return fmt_multistate_int(val, multistate_tcpfwd);
2015-01-05 16:09:55 +00:00
case sAllowStreamLocalForwarding:
return fmt_multistate_int(val, multistate_tcpfwd);
2015-07-02 13:15:34 +00:00
case sFingerprintHash:
return ssh_digest_alg_name(val);
2011-09-28 08:14:41 +00:00
default:
switch (val) {
case 0:
return "no";
case 1:
return "yes";
default:
return "UNKNOWN";
}
2008-07-23 09:33:08 +00:00
}
}
static void
dump_cfg_int(ServerOpCodes code, int val)
{
printf("%s %d\n", lookup_opcode_name(code), val);
}
2015-07-02 13:18:50 +00:00
static void
dump_cfg_oct(ServerOpCodes code, int val)
{
printf("%s 0%o\n", lookup_opcode_name(code), val);
}
2008-07-23 09:33:08 +00:00
static void
dump_cfg_fmtint(ServerOpCodes code, int val)
{
printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
}
static void
dump_cfg_string(ServerOpCodes code, const char *val)
{
2015-07-02 13:15:34 +00:00
printf("%s %s\n", lookup_opcode_name(code),
val == NULL ? "none" : val);
2008-07-23 09:33:08 +00:00
}
static void
dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals)
{
u_int i;
for (i = 0; i < count; i++)
2011-09-28 08:14:41 +00:00
printf("%s %s\n", lookup_opcode_name(code), vals[i]);
}
static void
dump_cfg_strarray_oneline(ServerOpCodes code, u_int count, char **vals)
{
u_int i;
2017-01-31 12:29:48 +00:00
if (count <= 0 && code != sAuthenticationMethods)
2015-07-02 13:18:50 +00:00
return;
2011-09-28 08:14:41 +00:00
printf("%s", lookup_opcode_name(code));
for (i = 0; i < count; i++)
printf(" %s", vals[i]);
2017-01-31 12:29:48 +00:00
if (code == sAuthenticationMethods && count == 0)
printf(" any");
2011-09-28 08:14:41 +00:00
printf("\n");
2008-07-23 09:33:08 +00:00
}
2018-05-06 12:27:04 +00:00
static char *
format_listen_addrs(struct listenaddr *la)
2008-07-23 09:33:08 +00:00
{
2018-05-06 12:27:04 +00:00
int r;
2008-07-23 09:33:08 +00:00
struct addrinfo *ai;
2018-05-06 12:27:04 +00:00
char addr[NI_MAXHOST], port[NI_MAXSERV];
2015-07-02 13:18:50 +00:00
char *laddr1 = xstrdup(""), *laddr2 = NULL;
2008-07-23 09:33:08 +00:00
2015-07-02 13:18:50 +00:00
/*
* ListenAddress must be after Port. add_one_listen_addr pushes
* addresses onto a stack, so to maintain ordering we need to
* print these in reverse order.
*/
2018-05-06 12:27:04 +00:00
for (ai = la->addrs; ai; ai = ai->ai_next) {
if ((r = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
2008-07-23 09:33:08 +00:00
sizeof(addr), port, sizeof(port),
NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
2018-05-06 12:27:04 +00:00
error("getnameinfo: %.100s", ssh_gai_strerror(r));
continue;
}
laddr2 = laddr1;
if (ai->ai_family == AF_INET6) {
xasprintf(&laddr1, "listenaddress [%s]:%s%s%s\n%s",
addr, port,
la->rdomain == NULL ? "" : " rdomain ",
la->rdomain == NULL ? "" : la->rdomain,
laddr2);
2008-07-23 09:33:08 +00:00
} else {
2018-05-06 12:27:04 +00:00
xasprintf(&laddr1, "listenaddress %s:%s%s%s\n%s",
addr, port,
la->rdomain == NULL ? "" : " rdomain ",
la->rdomain == NULL ? "" : la->rdomain,
laddr2);
2008-07-23 09:33:08 +00:00
}
2018-05-06 12:27:04 +00:00
free(laddr2);
}
return laddr1;
}
void
dump_config(ServerOptions *o)
{
char *s;
u_int i;
/* these are usually at the top of the config */
for (i = 0; i < o->num_ports; i++)
printf("port %d\n", o->ports[i]);
dump_cfg_fmtint(sAddressFamily, o->address_family);
for (i = 0; i < o->num_listen_addrs; i++) {
s = format_listen_addrs(&o->listen_addrs[i]);
printf("%s", s);
free(s);
2008-07-23 09:33:08 +00:00
}
/* integer arguments */
2009-02-24 18:49:27 +00:00
#ifdef USE_PAM
2015-07-02 13:18:50 +00:00
dump_cfg_fmtint(sUsePAM, o->use_pam);
2009-02-24 18:49:27 +00:00
#endif
2008-07-23 09:33:08 +00:00
dump_cfg_int(sLoginGraceTime, o->login_grace_time);
dump_cfg_int(sX11DisplayOffset, o->x11_display_offset);
dump_cfg_int(sMaxAuthTries, o->max_authtries);
2009-02-24 18:49:27 +00:00
dump_cfg_int(sMaxSessions, o->max_sessions);
2008-07-23 09:33:08 +00:00
dump_cfg_int(sClientAliveInterval, o->client_alive_interval);
dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max);
2015-07-02 13:18:50 +00:00
dump_cfg_oct(sStreamLocalBindMask, o->fwd_opts.streamlocal_bind_mask);
2008-07-23 09:33:08 +00:00
/* formatted integer arguments */
dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login);
dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts);
dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts);
dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication);
dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly,
o->hostbased_uses_name_from_packet_only);
dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication);
2009-02-24 18:49:27 +00:00
#ifdef KRB5
2008-07-23 09:33:08 +00:00
dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication);
dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd);
dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup);
2009-02-24 18:49:27 +00:00
# ifdef USE_AFS
2008-07-23 09:33:08 +00:00
dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
2009-02-24 18:49:27 +00:00
# endif
#endif
#ifdef GSSAPI
2008-07-23 09:33:08 +00:00
dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
2009-02-24 18:49:27 +00:00
#endif
2008-07-23 09:33:08 +00:00
dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
dump_cfg_fmtint(sKbdInteractiveAuthentication,
o->kbd_interactive_authentication);
dump_cfg_fmtint(sChallengeResponseAuthentication,
o->challenge_response_authentication);
dump_cfg_fmtint(sPrintMotd, o->print_motd);
2016-03-10 20:10:25 +00:00
#ifndef DISABLE_LASTLOG
2008-07-23 09:33:08 +00:00
dump_cfg_fmtint(sPrintLastLog, o->print_lastlog);
2016-03-10 20:10:25 +00:00
#endif
2008-07-23 09:33:08 +00:00
dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding);
dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost);
2014-01-30 10:56:49 +00:00
dump_cfg_fmtint(sPermitTTY, o->permit_tty);
2015-01-05 16:09:55 +00:00
dump_cfg_fmtint(sPermitUserRC, o->permit_user_rc);
2008-07-23 09:33:08 +00:00
dump_cfg_fmtint(sStrictModes, o->strict_modes);
dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive);
dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd);
dump_cfg_fmtint(sCompression, o->compression);
2015-01-05 16:09:55 +00:00
dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports);
2008-07-23 09:33:08 +00:00
dump_cfg_fmtint(sUseDNS, o->use_dns);
dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
2015-07-02 13:18:50 +00:00
dump_cfg_fmtint(sAllowAgentForwarding, o->allow_agent_forwarding);
2017-01-31 12:33:47 +00:00
dump_cfg_fmtint(sDisableForwarding, o->disable_forwarding);
2015-01-05 16:09:55 +00:00
dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding);
2017-01-31 12:29:48 +00:00
dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2015-07-02 13:15:34 +00:00
dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash);
2018-05-06 12:24:45 +00:00
dump_cfg_fmtint(sExposeAuthInfo, o->expose_userauth_info);
dump_cfg_fmtint(sUseBlacklist, o->use_blacklist);
2008-07-23 09:33:08 +00:00
/* string arguments */
dump_cfg_string(sPidFile, o->pid_file);
dump_cfg_string(sXAuthLocation, o->xauth_location);
2015-07-02 13:15:34 +00:00
dump_cfg_string(sCiphers, o->ciphers ? o->ciphers : KEX_SERVER_ENCRYPT);
dump_cfg_string(sMacs, o->macs ? o->macs : KEX_SERVER_MAC);
2008-07-23 09:33:08 +00:00
dump_cfg_string(sBanner, o->banner);
dump_cfg_string(sForceCommand, o->adm_forced_command);
2010-03-08 11:19:52 +00:00
dump_cfg_string(sChrootDirectory, o->chroot_directory);
dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);
dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
2010-11-08 10:45:44 +00:00
dump_cfg_string(sAuthorizedPrincipalsFile,
o->authorized_principals_file);
2015-07-02 13:18:50 +00:00
dump_cfg_string(sVersionAddendum, *o->version_addendum == '\0'
? "none" : o->version_addendum);
2013-03-22 11:19:48 +00:00
dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command);
dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user);
2015-07-02 13:18:50 +00:00
dump_cfg_string(sAuthorizedPrincipalsCommand, o->authorized_principals_command);
dump_cfg_string(sAuthorizedPrincipalsCommandUser, o->authorized_principals_command_user);
2013-09-18 17:27:38 +00:00
dump_cfg_string(sHostKeyAgent, o->host_key_agent);
2015-07-02 13:15:34 +00:00
dump_cfg_string(sKexAlgorithms,
o->kex_algorithms ? o->kex_algorithms : KEX_SERVER_KEX);
2019-02-05 15:03:53 +00:00
dump_cfg_string(sCASignatureAlgorithms, o->ca_sign_algorithms ?
o->ca_sign_algorithms : SSH_ALLOWED_CA_SIGALGS);
2015-07-02 13:15:34 +00:00
dump_cfg_string(sHostbasedAcceptedKeyTypes, o->hostbased_key_types ?
o->hostbased_key_types : KEX_DEFAULT_PK_ALG);
2015-08-26 09:25:17 +00:00
dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms ?
o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG);
2015-07-02 13:15:34 +00:00
dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ?
o->pubkey_key_types : KEX_DEFAULT_PK_ALG);
2018-05-06 12:27:04 +00:00
dump_cfg_string(sRDomain, o->routing_domain);
2008-07-23 09:33:08 +00:00
/* string arguments requiring a lookup */
dump_cfg_string(sLogLevel, log_level_name(o->log_level));
dump_cfg_string(sLogFacility, log_facility_name(o->log_facility));
/* string array arguments */
2011-09-28 08:14:41 +00:00
dump_cfg_strarray_oneline(sAuthorizedKeysFile, o->num_authkeys_files,
o->authorized_keys_files);
2008-07-23 09:33:08 +00:00
dump_cfg_strarray(sHostKeyFile, o->num_host_key_files,
o->host_key_files);
2015-07-02 13:18:50 +00:00
dump_cfg_strarray(sHostCertificate, o->num_host_cert_files,
2010-03-08 11:19:52 +00:00
o->host_cert_files);
2008-07-23 09:33:08 +00:00
dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users);
dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users);
dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups);
dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups);
dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env);
2018-08-28 10:47:58 +00:00
dump_cfg_strarray(sSetEnv, o->num_setenv, o->setenv);
2013-03-22 11:19:48 +00:00
dump_cfg_strarray_oneline(sAuthenticationMethods,
o->num_auth_methods, o->auth_methods);
2008-07-23 09:33:08 +00:00
/* other arguments */
for (i = 0; i < o->num_subsystems; i++)
printf("subsystem %s %s\n", o->subsystem_name[i],
o->subsystem_args[i]);
printf("maxstartups %d:%d:%d\n", o->max_startups_begin,
o->max_startups_rate, o->max_startups);
2018-05-06 12:27:04 +00:00
s = NULL;
for (i = 0; tunmode_desc[i].val != -1; i++) {
2008-07-23 09:33:08 +00:00
if (tunmode_desc[i].val == o->permit_tun) {
s = tunmode_desc[i].text;
break;
}
2018-05-06 12:27:04 +00:00
}
2008-07-23 09:33:08 +00:00
dump_cfg_string(sPermitTunnel, s);
2011-09-28 08:14:41 +00:00
printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
printf("%s\n", iptos2str(o->ip_qos_bulk));
2011-02-17 11:47:40 +00:00
2016-03-10 20:10:25 +00:00
printf("rekeylimit %llu %d\n", (unsigned long long)o->rekey_limit,
o->rekey_interval);
2013-09-18 17:27:38 +00:00
2018-05-06 12:24:45 +00:00
printf("permitopen");
if (o->num_permitted_opens == 0)
printf(" any");
else {
for (i = 0; i < o->num_permitted_opens; i++)
printf(" %s", o->permitted_opens[i]);
}
printf("\n");
2018-08-28 10:47:58 +00:00
printf("permitlisten");
if (o->num_permitted_listens == 0)
printf(" any");
else {
for (i = 0; i < o->num_permitted_listens; i++)
printf(" %s", o->permitted_listens[i]);
}
printf("\n");
if (o->permit_user_env_whitelist == NULL) {
dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env);
} else {
printf("permituserenvironment %s\n",
o->permit_user_env_whitelist);
}
2008-07-23 09:33:08 +00:00
}