You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
398 lines
15 KiB
398 lines
15 KiB
diff -up openssh-6.6p1/gss-genr.c.gsskexalg openssh-6.6p1/gss-genr.c |
|
--- openssh-6.6p1/gss-genr.c.gsskexalg 2015-08-14 16:07:33.271343064 +0200 |
|
+++ openssh-6.6p1/gss-genr.c 2015-08-14 16:07:33.338342936 +0200 |
|
@@ -76,7 +76,8 @@ ssh_gssapi_oid_table_ok() { |
|
*/ |
|
|
|
char * |
|
-ssh_gssapi_client_mechanisms(const char *host, const char *client) { |
|
+ssh_gssapi_client_mechanisms(const char *host, const char *client, |
|
+ const char *kex) { |
|
gss_OID_set gss_supported; |
|
OM_uint32 min_status; |
|
|
|
@@ -84,12 +85,12 @@ ssh_gssapi_client_mechanisms(const char |
|
return NULL; |
|
|
|
return(ssh_gssapi_kex_mechs(gss_supported, ssh_gssapi_check_mechanism, |
|
- host, client)); |
|
+ host, client, kex)); |
|
} |
|
|
|
char * |
|
ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check, |
|
- const char *host, const char *client) { |
|
+ const char *host, const char *client, const char *kex) { |
|
Buffer buf; |
|
size_t i; |
|
int oidpos, enclen; |
|
@@ -98,6 +99,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup |
|
char deroid[2]; |
|
const EVP_MD *evp_md = EVP_md5(); |
|
EVP_MD_CTX md; |
|
+ char *s, *cp, *p; |
|
|
|
if (gss_enc2oid != NULL) { |
|
for (i = 0; gss_enc2oid[i].encoded != NULL; i++) |
|
@@ -111,6 +113,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup |
|
buffer_init(&buf); |
|
|
|
oidpos = 0; |
|
+ s = cp = xstrdup(kex); |
|
for (i = 0; i < gss_supported->count; i++) { |
|
if (gss_supported->elements[i].length < 128 && |
|
(*check)(NULL, &(gss_supported->elements[i]), host, client)) { |
|
@@ -129,26 +132,22 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup |
|
enclen = __b64_ntop(digest, EVP_MD_size(evp_md), |
|
encoded, EVP_MD_size(evp_md) * 2); |
|
|
|
- if (oidpos != 0) |
|
- buffer_put_char(&buf, ','); |
|
- |
|
- buffer_append(&buf, KEX_GSS_GEX_SHA1_ID, |
|
- sizeof(KEX_GSS_GEX_SHA1_ID) - 1); |
|
- buffer_append(&buf, encoded, enclen); |
|
- buffer_put_char(&buf, ','); |
|
- buffer_append(&buf, KEX_GSS_GRP1_SHA1_ID, |
|
- sizeof(KEX_GSS_GRP1_SHA1_ID) - 1); |
|
- buffer_append(&buf, encoded, enclen); |
|
- buffer_put_char(&buf, ','); |
|
- buffer_append(&buf, KEX_GSS_GRP14_SHA1_ID, |
|
- sizeof(KEX_GSS_GRP14_SHA1_ID) - 1); |
|
- buffer_append(&buf, encoded, enclen); |
|
+ cp = strncpy(s, kex, strlen(kex)); |
|
+ for ((p = strsep(&cp, ",")); p && *p != '\0'; |
|
+ (p = strsep(&cp, ","))) { |
|
+ if (buffer_len(&buf) != 0) |
|
+ buffer_put_char(&buf, ','); |
|
+ buffer_append(&buf, p, |
|
+ strlen(p)); |
|
+ buffer_append(&buf, encoded, enclen); |
|
+ } |
|
|
|
gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]); |
|
gss_enc2oid[oidpos].encoded = encoded; |
|
oidpos++; |
|
} |
|
} |
|
+ free(s); |
|
gss_enc2oid[oidpos].oid = NULL; |
|
gss_enc2oid[oidpos].encoded = NULL; |
|
|
|
diff -up openssh-6.6p1/gss-serv.c.gsskexalg openssh-6.6p1/gss-serv.c |
|
--- openssh-6.6p1/gss-serv.c.gsskexalg 2015-08-14 16:07:33.296343016 +0200 |
|
+++ openssh-6.6p1/gss-serv.c 2015-08-14 16:07:33.338342936 +0200 |
|
@@ -151,7 +151,7 @@ ssh_gssapi_server_mechanisms() { |
|
|
|
ssh_gssapi_supported_oids(&supported); |
|
return (ssh_gssapi_kex_mechs(supported, &ssh_gssapi_server_check_mech, |
|
- NULL, NULL)); |
|
+ NULL, NULL, options.gss_kex_algorithms)); |
|
} |
|
|
|
/* Unprivileged */ |
|
diff -up openssh-6.6p1/kex.c.gsskexalg openssh-6.6p1/kex.c |
|
--- openssh-6.6p1/kex.c.gsskexalg 2015-08-14 16:07:33.271343064 +0200 |
|
+++ openssh-6.6p1/kex.c 2015-08-14 16:07:33.339342935 +0200 |
|
@@ -160,6 +160,29 @@ kex_names_valid(const char *names) |
|
return 1; |
|
} |
|
|
|
+/* Validate GSS KEX method name list */ |
|
+int |
|
+gss_kex_names_valid(const char *names) |
|
+{ |
|
+ char *s, *cp, *p; |
|
+ |
|
+ if (names == NULL || *names == '\0') |
|
+ return 0; |
|
+ s = cp = xstrdup(names); |
|
+ for ((p = strsep(&cp, ",")); p && *p != '\0'; |
|
+ (p = strsep(&cp, ","))) { |
|
+ if (strncmp(p, "gss-", 4) != 0 |
|
+ || kex_alg_by_name(p) == NULL) { |
|
+ error("Unsupported KEX algorithm \"%.100s\"", p); |
|
+ free(s); |
|
+ return 0; |
|
+ } |
|
+ } |
|
+ debug3("gss kex names ok: [%s]", names); |
|
+ free(s); |
|
+ return 1; |
|
+} |
|
+ |
|
/* put algorithm proposal into buffer */ |
|
static void |
|
kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX]) |
|
diff -up openssh-6.6p1/readconf.c.gsskexalg openssh-6.6p1/readconf.c |
|
--- openssh-6.6p1/readconf.c.gsskexalg 2015-08-14 16:07:33.274343058 +0200 |
|
+++ openssh-6.6p1/readconf.c 2015-08-14 16:14:17.600574919 +0200 |
|
@@ -55,6 +55,7 @@ |
|
#include "kex.h" |
|
#include "mac.h" |
|
#include "uidswap.h" |
|
+#include "ssh-gss.h" |
|
|
|
/* Format of the configuration file: |
|
|
|
@@ -142,7 +143,7 @@ typedef enum { |
|
oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, |
|
oAddressFamily, oGssAuthentication, oGssDelegateCreds, |
|
oGssTrustDns, oGssKeyEx, oGssClientIdentity, oGssRenewalRekey, |
|
- oGssServerIdentity, |
|
+ oGssServerIdentity, oGssKexAlgorithms, |
|
oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, |
|
oSendEnv, oControlPath, oControlMaster, oControlPersist, |
|
oHashKnownHosts, |
|
@@ -191,6 +192,7 @@ static struct { |
|
{ "gssapiclientidentity", oGssClientIdentity }, |
|
{ "gssapiserveridentity", oGssServerIdentity }, |
|
{ "gssapirenewalforcesrekey", oGssRenewalRekey }, |
|
+ { "gssapikexalgorithms", oGssKexAlgorithms }, |
|
#else |
|
{ "gssapiauthentication", oUnsupported }, |
|
{ "gssapikeyexchange", oUnsupported }, |
|
@@ -198,6 +200,7 @@ static struct { |
|
{ "gssapitrustdns", oUnsupported }, |
|
{ "gssapiclientidentity", oUnsupported }, |
|
{ "gssapirenewalforcesrekey", oUnsupported }, |
|
+ { "gssapikexalgorithms", oUnsupported }, |
|
#endif |
|
{ "fallbacktorsh", oDeprecated }, |
|
{ "usersh", oDeprecated }, |
|
@@ -876,6 +879,18 @@ parse_time: |
|
intptr = &options->gss_renewal_rekey; |
|
goto parse_flag; |
|
|
|
+ case oGssKexAlgorithms: |
|
+ arg = strdelim(&s); |
|
+ if (!arg || *arg == '\0') |
|
+ fatal("%.200s line %d: Missing argument.", |
|
+ filename, linenum); |
|
+ if (!gss_kex_names_valid(arg)) |
|
+ fatal("%.200s line %d: Bad GSSAPI KexAlgorithms '%s'.", |
|
+ filename, linenum, arg ? arg : "<NONE>"); |
|
+ if (*activep && options->gss_kex_algorithms == NULL) |
|
+ options->gss_kex_algorithms = xstrdup(arg); |
|
+ break; |
|
+ |
|
case oBatchMode: |
|
intptr = &options->batch_mode; |
|
goto parse_flag; |
|
@@ -1534,6 +1549,7 @@ initialize_options(Options * options) |
|
options->gss_renewal_rekey = -1; |
|
options->gss_client_identity = NULL; |
|
options->gss_server_identity = NULL; |
|
+ options->gss_kex_algorithms = NULL; |
|
options->password_authentication = -1; |
|
options->kbd_interactive_authentication = -1; |
|
options->kbd_interactive_devices = NULL; |
|
@@ -1660,6 +1676,8 @@ fill_default_options(Options * options) |
|
options->gss_trust_dns = 0; |
|
if (options->gss_renewal_rekey == -1) |
|
options->gss_renewal_rekey = 0; |
|
+ if (options->gss_kex_algorithms == NULL) |
|
+ options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX); |
|
if (options->password_authentication == -1) |
|
options->password_authentication = 1; |
|
if (options->kbd_interactive_authentication == -1) |
|
diff -up openssh-6.6p1/readconf.h.gsskexalg openssh-6.6p1/readconf.h |
|
--- openssh-6.6p1/readconf.h.gsskexalg 2015-08-14 16:07:33.274343058 +0200 |
|
+++ openssh-6.6p1/readconf.h 2015-08-14 16:07:33.339342935 +0200 |
|
@@ -60,6 +60,7 @@ typedef struct { |
|
int gss_renewal_rekey; /* Credential renewal forces rekey */ |
|
char *gss_client_identity; /* Principal to initiate GSSAPI with */ |
|
char *gss_server_identity; /* GSSAPI target principal */ |
|
+ char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */ |
|
int password_authentication; /* Try password |
|
* authentication. */ |
|
int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ |
|
diff -up openssh-6.6p1/servconf.c.gsskexalg openssh-6.6p1/servconf.c |
|
--- openssh-6.6p1/servconf.c.gsskexalg 2015-08-14 16:07:45.704319443 +0200 |
|
+++ openssh-6.6p1/servconf.c 2015-08-14 16:14:15.306579277 +0200 |
|
@@ -54,6 +54,7 @@ |
|
#include "packet.h" |
|
#include "hostfile.h" |
|
#include "auth.h" |
|
+#include "ssh-gss.h" |
|
|
|
static void add_listen_addr(ServerOptions *, char *, int); |
|
static void add_one_listen_addr(ServerOptions *, char *, int); |
|
@@ -112,6 +113,7 @@ initialize_server_options(ServerOptions |
|
options->gss_cleanup_creds = -1; |
|
options->gss_strict_acceptor = -1; |
|
options->gss_store_rekey = -1; |
|
+ options->gss_kex_algorithms = NULL; |
|
options->password_authentication = -1; |
|
options->kbd_interactive_authentication = -1; |
|
options->challenge_response_authentication = -1; |
|
@@ -258,6 +260,8 @@ fill_default_server_options(ServerOption |
|
options->gss_strict_acceptor = 1; |
|
if (options->gss_store_rekey == -1) |
|
options->gss_store_rekey = 0; |
|
+ if (options->gss_kex_algorithms == NULL) |
|
+ options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX); |
|
if (options->password_authentication == -1) |
|
options->password_authentication = 1; |
|
if (options->kbd_interactive_authentication == -1) |
|
@@ -360,7 +364,7 @@ typedef enum { |
|
sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, |
|
sClientAliveCountMax, sAuthorizedKeysFile, |
|
sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, |
|
- sGssKeyEx, sGssStoreRekey, sAcceptEnv, sPermitTunnel, |
|
+ sGssKeyEx, sGssStoreRekey, sGssKexAlgorithms, sAcceptEnv, sPermitTunnel, |
|
sMatch, sPermitOpen, sForceCommand, sChrootDirectory, |
|
sUsePrivilegeSeparation, sAllowAgentForwarding, |
|
sHostCertificate, |
|
@@ -434,6 +438,7 @@ static struct { |
|
{ "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, |
|
{ "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, |
|
{ "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL }, |
|
+ { "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL }, |
|
#else |
|
{ "gssapiauthentication", sUnsupported, SSHCFG_ALL }, |
|
{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, |
|
@@ -442,6 +447,7 @@ static struct { |
|
{ "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, |
|
{ "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, |
|
{ "gssapienablek5users", sUnsupported, SSHCFG_ALL }, |
|
+ { "gssapikexalgorithms", sUnsupported, SSHCFG_GLOBAL }, |
|
#endif |
|
{ "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL }, |
|
{ "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL }, |
|
@@ -1137,6 +1143,18 @@ process_server_config_line(ServerOptions |
|
intptr = &options->gss_store_rekey; |
|
goto parse_flag; |
|
|
|
+ case sGssKexAlgorithms: |
|
+ arg = strdelim(&cp); |
|
+ if (!arg || *arg == '\0') |
|
+ fatal("%.200s line %d: Missing argument.", |
|
+ filename, linenum); |
|
+ if (!gss_kex_names_valid(arg)) |
|
+ fatal("%.200s line %d: Bad GSSAPI KexAlgorithms '%s'.", |
|
+ filename, linenum, arg ? arg : "<NONE>"); |
|
+ if (*activep && options->gss_kex_algorithms == NULL) |
|
+ options->gss_kex_algorithms = xstrdup(arg); |
|
+ break; |
|
+ |
|
case sPasswordAuthentication: |
|
intptr = &options->password_authentication; |
|
goto parse_flag; |
|
@@ -2068,6 +2086,7 @@ dump_config(ServerOptions *o) |
|
dump_cfg_fmtint(sGssKeyEx, o->gss_keyex); |
|
dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor); |
|
dump_cfg_fmtint(sGssStoreRekey, o->gss_store_rekey); |
|
+ dump_cfg_string(sGssKexAlgorithms, o->gss_kex_algorithms); |
|
#endif |
|
dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); |
|
dump_cfg_fmtint(sKbdInteractiveAuthentication, |
|
diff -up openssh-6.6p1/servconf.h.gsskexalg openssh-6.6p1/servconf.h |
|
--- openssh-6.6p1/servconf.h.gsskexalg 2015-08-14 16:07:48.160314777 +0200 |
|
+++ openssh-6.6p1/servconf.h 2015-08-14 16:09:34.447112854 +0200 |
|
@@ -116,6 +116,7 @@ typedef struct { |
|
int gss_cleanup_creds; /* If true, destroy cred cache on logout */ |
|
int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ |
|
int gss_store_rekey; |
|
+ char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */ |
|
int password_authentication; /* If true, permit password |
|
* authentication. */ |
|
int kbd_interactive_authentication; /* If true, permit */ |
|
diff -up openssh-6.6p1/sshconnect2.c.gsskexalg openssh-6.6p1/sshconnect2.c |
|
--- openssh-6.6p1/sshconnect2.c.gsskexalg 2015-08-14 16:07:33.304343001 +0200 |
|
+++ openssh-6.6p1/sshconnect2.c 2015-08-14 16:07:33.339342935 +0200 |
|
@@ -179,7 +179,8 @@ ssh_kex2(char *host, struct sockaddr *ho |
|
else |
|
gss_host = host; |
|
|
|
- gss = ssh_gssapi_client_mechanisms(gss_host, options.gss_client_identity); |
|
+ gss = ssh_gssapi_client_mechanisms(gss_host, |
|
+ options.gss_client_identity, options.gss_kex_algorithms); |
|
if (gss) { |
|
debug("Offering GSSAPI proposal: %s", gss); |
|
xasprintf(&myproposal[PROPOSAL_KEX_ALGS], |
|
diff -up openssh-6.6p1/ssh-gss.h.gsskexalg openssh-6.6p1/ssh-gss.h |
|
--- openssh-6.6p1/ssh-gss.h.gsskexalg 2015-08-14 16:07:33.278343050 +0200 |
|
+++ openssh-6.6p1/ssh-gss.h 2015-08-14 16:07:33.340342932 +0200 |
|
@@ -76,6 +76,11 @@ extern char **k5users_allowed_cmds; |
|
#define KEX_GSS_GRP14_SHA1_ID "gss-group14-sha1-" |
|
#define KEX_GSS_GEX_SHA1_ID "gss-gex-sha1-" |
|
|
|
+#define GSS_KEX_DEFAULT_KEX \ |
|
+ KEX_GSS_GEX_SHA1_ID "," \ |
|
+ KEX_GSS_GRP1_SHA1_ID "," \ |
|
+ KEX_GSS_GRP14_SHA1_ID |
|
+ |
|
typedef struct { |
|
char *filename; |
|
char *envvar; |
|
@@ -147,9 +152,9 @@ int ssh_gssapi_credentials_updated(Gssct |
|
/* In the server */ |
|
typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, |
|
const char *); |
|
-char *ssh_gssapi_client_mechanisms(const char *, const char *); |
|
+char *ssh_gssapi_client_mechanisms(const char *, const char *, const char *); |
|
char *ssh_gssapi_kex_mechs(gss_OID_set, ssh_gssapi_check_fn *, const char *, |
|
- const char *); |
|
+ const char *, const char *); |
|
gss_OID ssh_gssapi_id_kex(Gssctxt *, char *, int); |
|
int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *, |
|
const char *); |
|
diff --git a/ssh.1 b/ssh.1 |
|
index 4a7d1cd..c795c40 100644 |
|
--- a/ssh.1 |
|
+++ b/ssh.1 |
|
@@ -449,6 +449,7 @@ For full details of the options listed below, and their possible values, see |
|
.It GSSAPIDelegateCredentials |
|
.It GSSAPIRenewalForcesRekey |
|
.It GSSAPITrustDns |
|
+.It GSSAPIKexAlgorithms |
|
.It HashKnownHosts |
|
.It Host |
|
.It HostbasedAuthentication |
|
diff --git a/ssh_config.5 b/ssh_config.5 |
|
index c95fda6..a2af9c4 100644 |
|
--- a/ssh_config.5 |
|
+++ b/ssh_config.5 |
|
@@ -719,6 +719,18 @@ command line will be passed untouched to the GSSAPI library. |
|
The default is |
|
.Dq no . |
|
This option only applies to protocol version 2 connections using GSSAPI. |
|
+.It Cm GSSAPIKexAlgorithms |
|
+The list of key exchange algorithms that are offered for GSSAPI |
|
+key exchange. Possible values are |
|
+.Bd -literal -offset 3n |
|
+gss-gex-sha1-, |
|
+gss-group1-sha1-, |
|
+gss-group14-sha1- |
|
+.Ed |
|
+.Pp |
|
+The default is |
|
+.Dq gss-gex-sha1-,gss-group1-sha1-,gss-group14-sha1- . |
|
+This option only applies to protocol version 2 connections using GSSAPI. |
|
.It Cm HashKnownHosts |
|
Indicates that |
|
.Xr ssh 1 |
|
diff --git a/sshd_config.5 b/sshd_config.5 |
|
index 5e8c6c6..4c670aa 100644 |
|
--- a/sshd_config.5 |
|
+++ b/sshd_config.5 |
|
@@ -545,6 +545,18 @@ Controls whether the user's GSSAPI credentials should be updated following a |
|
successful connection rekeying. This option can be used to accepted renewed |
|
or updated credentials from a compatible client. The default is |
|
.Dq no . |
|
+.It Cm GSSAPIKexAlgorithms |
|
+The list of key exchange algorithms that are accepted by GSSAPI |
|
+key exchange. Possible values are |
|
+.Bd -literal -offset 3n |
|
+gss-gex-sha1-, |
|
+gss-group1-sha1-, |
|
+gss-group14-sha1- |
|
+.Ed |
|
+.Pp |
|
+The default is |
|
+.Dq gss-gex-sha1-,gss-group1-sha1-,gss-group14-sha1- . |
|
+This option only applies to protocol version 2 connections using GSSAPI. |
|
.It Cm HostbasedAuthentication |
|
Specifies whether rhosts or /etc/hosts.equiv authentication together |
|
with successful public key client host authentication is allowed
|
|
|