summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2015-01-13 07:39:19 +0000
committerDamien Miller <djm@mindrot.org>2015-01-13 19:27:18 +1100
commit1f729f0614d1376c3332fa1edb6a5e5cec7e9e03 (patch)
treef651f10aa00dcecdf8e9362c0abb6282bbc99c95
parent816d1538c24209a93ba0560b27c4fda57c3fff65 (diff)
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@
-rw-r--r--auth2-hostbased.c11
-rw-r--r--auth2-pubkey.c9
-rw-r--r--key.h3
-rw-r--r--monitor.c14
-rw-r--r--readconf.c4
-rw-r--r--servconf.c44
-rw-r--r--servconf.h6
-rw-r--r--sshd_config.528
-rw-r--r--sshkey.c32
-rw-r--r--sshkey.h4
10 files changed, 131 insertions, 24 deletions
diff --git a/auth2-hostbased.c b/auth2-hostbased.c
index 2db3d252..9f8a01cb 100644
--- a/auth2-hostbased.c
+++ b/auth2-hostbased.c
@@ -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);
diff --git a/auth2-pubkey.c b/auth2-pubkey.c
index 2b048622..d922eea2 100644
--- a/auth2-pubkey.c
+++ b/auth2-pubkey.c
@@ -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();
diff --git a/key.h b/key.h
index 7190b842..bf884970 100644
--- a/key.h
+++ b/key.h
@@ -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
diff --git a/monitor.c b/monitor.c
index b830e037..5a28d1b3 100644
--- a/monitor.c
+++ b/monitor.c
@@ -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,
diff --git a/readconf.c b/readconf.c
index f1601af2..d7f1cf03 100644
--- a/readconf.c
+++ b/readconf.c
@@ -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)
diff --git a/servconf.c b/servconf.c
index 6eb36866..1b6bdb4a 100644
--- a/servconf.c
+++ b/servconf.c
@@ -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));
diff --git a/servconf.h b/servconf.h
index 49b228bd..9922f0c8 100644
--- a/servconf.h
+++ b/servconf.h
@@ -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); \
diff --git a/sshd_config.5 b/sshd_config.5
index cec2a023..88fe9019 100644
--- a/sshd_config.5
+++ b/sshd_config.5
@@ -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
diff --git a/sshkey.c b/sshkey.c
index a680929f..30f209a2 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -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;
}
diff --git a/sshkey.h b/sshkey.h
index 65194d6e..7217f887 100644
--- a/sshkey.h
+++ b/sshkey.h
@@ -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 **);