upstream commit

add sshd_config HostbasedAcceptedKeyTypes and
 PubkeyAcceptedKeyTypes options to allow sshd to control what public key types
 will be accepted. Currently defaults to all. Feedback & ok markus@
This commit is contained in:
djm@openbsd.org 2015-01-13 07:39:19 +00:00 committed by Damien Miller
parent 816d1538c2
commit 1f729f0614
10 changed files with 131 additions and 24 deletions

View File

@ -1,4 +1,4 @@
/* $OpenBSD: auth2-hostbased.c,v 1.21 2015/01/08 10:14:08 djm Exp $ */
/* $OpenBSD: auth2-hostbased.c,v 1.22 2015/01/13 07:39:19 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -48,6 +48,7 @@
#endif
#include "monitor_wrap.h"
#include "pathnames.h"
#include "match.h"
/* import */
extern ServerOptions options;
@ -108,6 +109,14 @@ userauth_hostbased(Authctxt *authctxt)
"signature format");
goto done;
}
if (match_pattern_list(sshkey_ssh_name(key),
options.hostbased_key_types,
strlen(options.hostbased_key_types), 0) != 1) {
logit("%s: key type %s not in HostbasedAcceptedKeyTypes",
__func__, sshkey_type(key));
goto done;
}
service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" :
authctxt->service;
buffer_init(&b);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: auth2-pubkey.c,v 1.44 2014/12/22 07:51:30 djm Exp $ */
/* $OpenBSD: auth2-pubkey.c,v 1.45 2015/01/13 07:39:19 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -127,6 +127,13 @@ userauth_pubkey(Authctxt *authctxt)
logit("refusing previously-used %s key", key_type(key));
goto done;
}
if (match_pattern_list(sshkey_ssh_name(key), options.pubkey_key_types,
strlen(options.pubkey_key_types), 0) != 1) {
logit("%s: key type %s not in PubkeyAcceptedKeyTypes",
__func__, sshkey_ssh_name(key));
goto done;
}
if (have_sig) {
sig = packet_get_string(&slen);
packet_check_eom();

3
key.h
View File

@ -1,4 +1,4 @@
/* $OpenBSD: key.h,v 1.45 2015/01/08 10:14:08 djm Exp $ */
/* $OpenBSD: key.h,v 1.46 2015/01/13 07:39:19 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@ -50,7 +50,6 @@ typedef struct sshkey Key;
#define key_size sshkey_size
#define key_ecdsa_bits_to_nid sshkey_ecdsa_bits_to_nid
#define key_ecdsa_key_to_nid sshkey_ecdsa_key_to_nid
#define key_names_valid2 sshkey_names_valid2
#define key_is_cert sshkey_is_cert
#define key_type_plain sshkey_type_plain
#define key_cert_is_legacy sshkey_cert_is_legacy

View File

@ -1,4 +1,4 @@
/* $OpenBSD: monitor.c,v 1.136 2014/12/22 07:51:30 djm Exp $ */
/* $OpenBSD: monitor.c,v 1.137 2015/01/13 07:39:19 djm Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
@ -100,6 +100,7 @@
#include "ssh2.h"
#include "roaming.h"
#include "authfd.h"
#include "match.h"
#ifdef GSSAPI
static Gssctxt *gsscontext = NULL;
@ -1167,10 +1168,18 @@ mm_answer_keyallowed(int sock, Buffer *m)
debug3("%s: key_from_blob: %p", __func__, key);
if (key != NULL && authctxt->valid) {
/* These should not make it past the privsep child */
if (key_type_plain(key->type) == KEY_RSA &&
(datafellows & SSH_BUG_RSASIGMD5) != 0)
fatal("%s: passed a SSH_BUG_RSASIGMD5 key", __func__);
switch (type) {
case MM_USERKEY:
allowed = options.pubkey_authentication &&
!auth2_userkey_already_used(authctxt, key) &&
match_pattern_list(sshkey_ssh_name(key),
options.pubkey_key_types,
strlen(options.pubkey_key_types), 0) == 1 &&
user_key_allowed(authctxt->pw, key);
pubkey_auth_info(authctxt, key, NULL);
auth_method = "publickey";
@ -1179,6 +1188,9 @@ mm_answer_keyallowed(int sock, Buffer *m)
break;
case MM_HOSTKEY:
allowed = options.hostbased_authentication &&
match_pattern_list(sshkey_ssh_name(key),
options.hostbased_key_types,
strlen(options.hostbased_key_types), 0) == 1 &&
hostbased_key_allowed(authctxt->pw,
cuser, chost, key);
pubkey_auth_info(authctxt, key,

View File

@ -1,4 +1,4 @@
/* $OpenBSD: readconf.c,v 1.225 2015/01/08 13:44:36 djm Exp $ */
/* $OpenBSD: readconf.c,v 1.226 2015/01/13 07:39:19 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -1116,7 +1116,7 @@ parse_int:
arg = strdelim(&s);
if (!arg || *arg == '\0')
fatal("%.200s line %d: Missing argument.", filename, linenum);
if (!key_names_valid2(arg))
if (!sshkey_names_valid2(arg, 1))
fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
filename, linenum, arg ? arg : "<NONE>");
if (*activep && options->hostkeyalgorithms == NULL)

View File

@ -1,5 +1,5 @@
/* $OpenBSD: servconf.c,v 1.257 2014/12/22 07:55:51 djm Exp $ */
/* $OpenBSD: servconf.c,v 1.258 2015/01/13 07:39:19 djm Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@ -104,8 +104,10 @@ initialize_server_options(ServerOptions *options)
options->rhosts_rsa_authentication = -1;
options->hostbased_authentication = -1;
options->hostbased_uses_name_from_packet_only = -1;
options->hostbased_key_types = NULL;
options->rsa_authentication = -1;
options->pubkey_authentication = -1;
options->pubkey_key_types = NULL;
options->kerberos_authentication = -1;
options->kerberos_or_local_passwd = -1;
options->kerberos_ticket_cleanup = -1;
@ -248,10 +250,14 @@ fill_default_server_options(ServerOptions *options)
options->hostbased_authentication = 0;
if (options->hostbased_uses_name_from_packet_only == -1)
options->hostbased_uses_name_from_packet_only = 0;
if (options->hostbased_key_types == NULL)
options->hostbased_key_types = xstrdup("*");
if (options->rsa_authentication == -1)
options->rsa_authentication = 1;
if (options->pubkey_authentication == -1)
options->pubkey_authentication = 1;
if (options->pubkey_key_types == NULL)
options->pubkey_key_types = xstrdup("*");
if (options->kerberos_authentication == -1)
options->kerberos_authentication = 0;
if (options->kerberos_or_local_passwd == -1)
@ -365,8 +371,8 @@ typedef enum {
/* Portable-specific options */
sUsePAM,
/* Standard Options */
sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
sPermitRootLogin, sLogFacility, sLogLevel,
sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime,
sKeyRegenerationTime, sPermitRootLogin, sLogFacility, sLogLevel,
sRhostsRSAAuthentication, sRSAAuthentication,
sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
sKerberosGetAFSToken,
@ -379,11 +385,11 @@ typedef enum {
sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
sMaxStartups, sMaxAuthTries, sMaxSessions,
sGatewayPorts, sPubkeyAuthentication, sPubkeyAcceptedKeyTypes,
sXAuthLocation, sSubsystem, sMaxStartups, sMaxAuthTries, sMaxSessions,
sBanner, sUseDNS, sHostbasedAuthentication,
sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
sClientAliveCountMax, sAuthorizedKeysFile,
sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes,
sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
sUsePrivilegeSeparation, sAllowAgentForwarding,
@ -430,8 +436,10 @@ static struct {
{ "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_ALL },
{ "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
{ "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_ALL },
{ "hostbasedacceptedkeytypes", sHostbasedAcceptedKeyTypes, SSHCFG_ALL },
{ "rsaauthentication", sRSAAuthentication, SSHCFG_ALL },
{ "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
{ "pubkeyacceptedkeytypes", sPubkeyAcceptedKeyTypes, SSHCFG_ALL },
{ "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
#ifdef KRB5
{ "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
@ -1111,6 +1119,20 @@ process_server_config_line(ServerOptions *options, char *line,
intptr = &options->hostbased_uses_name_from_packet_only;
goto parse_flag;
case sHostbasedAcceptedKeyTypes:
charptr = &options->hostbased_key_types;
parse_keytypes:
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: Missing argument.",
filename, linenum);
if (!sshkey_names_valid2(arg, 1))
fatal("%s line %d: Bad key types '%s'.",
filename, linenum, arg ? arg : "<NONE>");
if (*activep && *charptr == NULL)
*charptr = xstrdup(arg);
break;
case sRSAAuthentication:
intptr = &options->rsa_authentication;
goto parse_flag;
@ -1119,6 +1141,10 @@ process_server_config_line(ServerOptions *options, char *line,
intptr = &options->pubkey_authentication;
goto parse_flag;
case sPubkeyAcceptedKeyTypes:
charptr = &options->pubkey_key_types;
goto parse_keytypes;
case sKerberosAuthentication:
intptr = &options->kerberos_authentication;
goto parse_flag;
@ -2142,6 +2168,10 @@ dump_config(ServerOptions *o)
dump_cfg_string(sHostKeyAgent, o->host_key_agent);
dump_cfg_string(sKexAlgorithms,
o->kex_algorithms ? o->kex_algorithms : KEX_SERVER_KEX);
dump_cfg_string(sHostbasedAcceptedKeyTypes, o->hostbased_key_types ?
o->hostbased_key_types : KEX_DEFAULT_PK_ALG);
dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ?
o->pubkey_key_types : KEX_DEFAULT_PK_ALG);
/* string arguments requiring a lookup */
dump_cfg_string(sLogLevel, log_level_name(o->log_level));

View File

@ -1,4 +1,4 @@
/* $OpenBSD: servconf.h,v 1.115 2014/12/21 22:27:56 djm Exp $ */
/* $OpenBSD: servconf.h,v 1.116 2015/01/13 07:39:19 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -99,8 +99,10 @@ typedef struct {
* authentication. */
int hostbased_authentication; /* If true, permit ssh2 hostbased auth */
int hostbased_uses_name_from_packet_only; /* experimental */
char *hostbased_key_types; /* Key types allowed for hostbased */
int rsa_authentication; /* If true, permit RSA authentication. */
int pubkey_authentication; /* If true, permit ssh2 pubkey authentication. */
char *pubkey_key_types; /* Key types allowed for public key */
int kerberos_authentication; /* If true, permit Kerberos
* authentication. */
int kerberos_or_local_passwd; /* If true, permit kerberos
@ -215,6 +217,8 @@ struct connection_info {
M_CP_STROPT(authorized_principals_file); \
M_CP_STROPT(authorized_keys_command); \
M_CP_STROPT(authorized_keys_command_user); \
M_CP_STROPT(hostbased_key_types); \
M_CP_STROPT(pubkey_key_types); \
M_CP_STRARRAYOPT(authorized_keys_files, num_authkeys_files); \
M_CP_STRARRAYOPT(allow_users, num_allow_users); \
M_CP_STRARRAYOPT(deny_users, num_deny_users); \

View File

@ -33,8 +33,8 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $OpenBSD: sshd_config.5,v 1.188 2014/12/22 09:05:17 djm Exp $
.Dd $Mdocdate: December 22 2014 $
.\" $OpenBSD: sshd_config.5,v 1.189 2015/01/13 07:39:19 djm Exp $
.Dd $Mdocdate: January 13 2015 $
.Dt SSHD_CONFIG 5
.Os
.Sh NAME
@ -561,6 +561,17 @@ on logout.
The default is
.Dq yes .
Note that this option applies to protocol version 2 only.
.It Cm HostbasedAcceptedKeyTypes
Specifies the key types that will be accepted for hostbased authentication
as a comma-separated pattern list.
The default
.Dq *
will allow all key types.
The
.Fl Q
option of
.Xr ssh 1
may be used to list supported key types.
.It Cm HostbasedAuthentication
Specifies whether rhosts or /etc/hosts.equiv authentication together
with successful public key client host authentication is allowed
@ -962,6 +973,7 @@ Available keywords are
.Cm ForceCommand ,
.Cm GatewayPorts ,
.Cm GSSAPIAuthentication ,
.Cm HostbasedAcceptedKeyTypes ,
.Cm HostbasedAuthentication ,
.Cm HostbasedUsesNameFromPacketOnly ,
.Cm KbdInteractiveAuthentication ,
@ -975,6 +987,7 @@ Available keywords are
.Cm PermitTTY ,
.Cm PermitTunnel ,
.Cm PermitUserRC ,
.Cm PubkeyAcceptedKeyTypes ,
.Cm PubkeyAuthentication ,
.Cm RekeyLimit ,
.Cm RhostsRSAAuthentication ,
@ -1182,6 +1195,17 @@ Specifying
.Dq 2,1
is identical to
.Dq 1,2 .
.It Cm PubkeyAcceptedKeyTypes
Specifies the key types that will be accepted for public key authentication
as a comma-separated pattern list.
The default
.Dq *
will allow all key types.
The
.Fl Q
option of
.Xr ssh 1
may be used to list supported key types.
.It Cm PubkeyAuthentication
Specifies whether public key authentication is allowed.
The default is

View File

@ -1,4 +1,4 @@
/* $OpenBSD: sshkey.c,v 1.10 2015/01/12 20:13:27 markus Exp $ */
/* $OpenBSD: sshkey.c,v 1.11 2015/01/13 07:39:19 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2008 Alexander von Gernler. All rights reserved.
@ -54,6 +54,7 @@
#include "digest.h"
#define SSHKEY_INTERNAL
#include "sshkey.h"
#include "match.h"
/* openssh private key file format */
#define MARK_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----\n"
@ -219,9 +220,11 @@ key_alg_list(int certs_only, int plain_only)
}
int
sshkey_names_valid2(const char *names)
sshkey_names_valid2(const char *names, int allow_wildcard)
{
char *s, *cp, *p;
const struct keytype *kt;
int type;
if (names == NULL || strcmp(names, "") == 0)
return 0;
@ -229,9 +232,28 @@ sshkey_names_valid2(const char *names)
return 0;
for ((p = strsep(&cp, ",")); p && *p != '\0';
(p = strsep(&cp, ","))) {
switch (sshkey_type_from_name(p)) {
case KEY_RSA1:
case KEY_UNSPEC:
type = sshkey_type_from_name(p);
if (type == KEY_RSA1) {
free(s);
return 0;
}
if (type == KEY_UNSPEC) {
if (allow_wildcard) {
/*
* Try matching key types against the string.
* If any has a positive or negative match then
* the component is accepted.
*/
for (kt = keytypes; kt->type != -1; kt++) {
if (kt->type == KEY_RSA1)
continue;
if (match_pattern_list(kt->name,
p, strlen(p), 0) != 0)
break;
}
if (kt->type != -1)
continue;
}
free(s);
return 0;
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: sshkey.h,v 1.3 2015/01/08 10:14:08 djm Exp $ */
/* $OpenBSD: sshkey.h,v 1.4 2015/01/13 07:39:19 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@ -156,7 +156,7 @@ int sshkey_ec_validate_public(const EC_GROUP *, const EC_POINT *);
int sshkey_ec_validate_private(const EC_KEY *);
const char *sshkey_ssh_name(const struct sshkey *);
const char *sshkey_ssh_name_plain(const struct sshkey *);
int sshkey_names_valid2(const char *);
int sshkey_names_valid2(const char *, int);
char *key_alg_list(int, int);
int sshkey_from_blob(const u_char *, size_t, struct sshkey **);