From bc4ef0f373657d1de39e368c4b8dbbebf52efcc3 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Aug 19 2015 11:18:07 +0000 Subject: Add GSSAPIKexAlgorithms option for server and client application --- diff --git a/openssh-6.7p1-fips.patch b/openssh-6.7p1-fips.patch index 923793d..c5c5dda 100644 --- a/openssh-6.7p1-fips.patch +++ b/openssh-6.7p1-fips.patch @@ -1,6 +1,6 @@ diff -up openssh-7.0p1/cipher.c.fips openssh-7.0p1/cipher.c ---- openssh-7.0p1/cipher.c.fips 2015-08-12 11:34:11.722803020 +0200 -+++ openssh-7.0p1/cipher.c 2015-08-12 11:34:11.733803003 +0200 +--- openssh-7.0p1/cipher.c.fips 2015-08-19 12:36:51.144412908 +0200 ++++ openssh-7.0p1/cipher.c 2015-08-19 12:36:51.150412894 +0200 @@ -39,6 +39,8 @@ #include @@ -74,8 +74,8 @@ diff -up openssh-7.0p1/cipher.c.fips openssh-7.0p1/cipher.c return c->number; return -1; diff -up openssh-7.0p1/cipher-ctr.c.fips openssh-7.0p1/cipher-ctr.c ---- openssh-7.0p1/cipher-ctr.c.fips 2015-08-12 11:34:11.650803133 +0200 -+++ openssh-7.0p1/cipher-ctr.c 2015-08-12 11:34:11.734803002 +0200 +--- openssh-7.0p1/cipher-ctr.c.fips 2015-08-19 12:36:51.079413054 +0200 ++++ openssh-7.0p1/cipher-ctr.c 2015-08-19 12:36:51.150412894 +0200 @@ -179,7 +179,8 @@ evp_aes_128_ctr(void) aes_ctr.do_cipher = ssh_aes_ctr; #ifndef SSH_OLD_EVP @@ -88,7 +88,7 @@ diff -up openssh-7.0p1/cipher-ctr.c.fips openssh-7.0p1/cipher-ctr.c } diff -up openssh-7.0p1/dh.h.fips openssh-7.0p1/dh.h --- openssh-7.0p1/dh.h.fips 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/dh.h 2015-08-12 11:34:11.734803002 +0200 ++++ openssh-7.0p1/dh.h 2015-08-19 12:36:51.150412894 +0200 @@ -46,6 +46,7 @@ u_int dh_estimate(int); /* Min and max values from RFC4419. */ @@ -98,8 +98,8 @@ diff -up openssh-7.0p1/dh.h.fips openssh-7.0p1/dh.h /* diff -up openssh-7.0p1/entropy.c.fips openssh-7.0p1/entropy.c ---- openssh-7.0p1/entropy.c.fips 2015-08-12 11:34:11.643803144 +0200 -+++ openssh-7.0p1/entropy.c 2015-08-12 11:34:11.734803002 +0200 +--- openssh-7.0p1/entropy.c.fips 2015-08-19 12:36:51.070413074 +0200 ++++ openssh-7.0p1/entropy.c 2015-08-19 12:36:51.150412894 +0200 @@ -217,6 +217,9 @@ seed_rng(void) fatal("OpenSSL version mismatch. Built against %lx, you " "have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay()); @@ -111,8 +111,8 @@ diff -up openssh-7.0p1/entropy.c.fips openssh-7.0p1/entropy.c if (RAND_status() == 1) { debug3("RNG is ready, skipping seeding"); diff -up openssh-7.0p1/kex.c.fips openssh-7.0p1/kex.c ---- openssh-7.0p1/kex.c.fips 2015-08-12 11:34:11.723803019 +0200 -+++ openssh-7.0p1/kex.c 2015-08-12 11:34:11.734803002 +0200 +--- openssh-7.0p1/kex.c.fips 2015-08-19 12:36:51.145412905 +0200 ++++ openssh-7.0p1/kex.c 2015-08-19 12:36:51.151412892 +0200 @@ -35,6 +35,7 @@ #ifdef WITH_OPENSSL @@ -170,7 +170,7 @@ diff -up openssh-7.0p1/kex.c.fips openssh-7.0p1/kex.c } diff -up openssh-7.0p1/kexgexc.c.fips openssh-7.0p1/kexgexc.c --- openssh-7.0p1/kexgexc.c.fips 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/kexgexc.c 2015-08-12 11:34:11.734803002 +0200 ++++ openssh-7.0p1/kexgexc.c 2015-08-19 12:36:51.151412892 +0200 @@ -28,6 +28,7 @@ #ifdef WITH_OPENSSL @@ -190,7 +190,7 @@ diff -up openssh-7.0p1/kexgexc.c.fips openssh-7.0p1/kexgexc.c if (datafellows & SSH_BUG_DHGEX_LARGE) diff -up openssh-7.0p1/kexgexs.c.fips openssh-7.0p1/kexgexs.c --- openssh-7.0p1/kexgexs.c.fips 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/kexgexs.c 2015-08-12 11:34:11.735803000 +0200 ++++ openssh-7.0p1/kexgexs.c 2015-08-19 12:36:51.151412892 +0200 @@ -81,11 +81,11 @@ input_kex_dh_gex_request(int type, u_int (r = sshpkt_get_end(ssh)) != 0) goto out; @@ -207,8 +207,8 @@ diff -up openssh-7.0p1/kexgexs.c.fips openssh-7.0p1/kexgexs.c if (kex->max < kex->min || kex->nbits < kex->min || diff -up openssh-7.0p1/mac.c.fips openssh-7.0p1/mac.c ---- openssh-7.0p1/mac.c.fips 2015-08-12 11:34:11.725803016 +0200 -+++ openssh-7.0p1/mac.c 2015-08-12 11:34:11.735803000 +0200 +--- openssh-7.0p1/mac.c.fips 2015-08-19 12:36:51.145412905 +0200 ++++ openssh-7.0p1/mac.c 2015-08-19 12:36:51.151412892 +0200 @@ -27,6 +27,8 @@ #include @@ -271,8 +271,8 @@ diff -up openssh-7.0p1/mac.c.fips openssh-7.0p1/mac.c continue; if (mac != NULL) diff -up openssh-7.0p1/Makefile.in.fips openssh-7.0p1/Makefile.in ---- openssh-7.0p1/Makefile.in.fips 2015-08-12 11:34:11.725803016 +0200 -+++ openssh-7.0p1/Makefile.in 2015-08-12 11:34:11.735803000 +0200 +--- openssh-7.0p1/Makefile.in.fips 2015-08-19 12:36:51.145412905 +0200 ++++ openssh-7.0p1/Makefile.in 2015-08-19 12:36:51.151412892 +0200 @@ -168,25 +168,25 @@ libssh.a: $(LIBSSH_OBJS) $(RANLIB) $@ @@ -316,7 +316,7 @@ diff -up openssh-7.0p1/Makefile.in.fips openssh-7.0p1/Makefile.in $(LD) -o $@ sftp-server.o sftp-common.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) diff -up openssh-7.0p1/myproposal.h.fips openssh-7.0p1/myproposal.h --- openssh-7.0p1/myproposal.h.fips 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/myproposal.h 2015-08-12 11:34:11.735803000 +0200 ++++ openssh-7.0p1/myproposal.h 2015-08-19 12:36:51.151412892 +0200 @@ -138,6 +138,28 @@ "hmac-sha1-96," \ "hmac-md5-96" @@ -347,9 +347,9 @@ diff -up openssh-7.0p1/myproposal.h.fips openssh-7.0p1/myproposal.h #define KEX_SERVER_KEX \ diff -up openssh-7.0p1/readconf.c.fips openssh-7.0p1/readconf.c ---- openssh-7.0p1/readconf.c.fips 2015-08-12 14:37:39.206466634 +0200 -+++ openssh-7.0p1/readconf.c 2015-08-12 14:47:00.342350208 +0200 -@@ -1897,9 +1897,12 @@ fill_default_options(Options * options) +--- openssh-7.0p1/readconf.c.fips 2015-08-19 12:36:51.138412921 +0200 ++++ openssh-7.0p1/readconf.c 2015-08-19 12:36:51.152412889 +0200 +@@ -1915,9 +1915,12 @@ fill_default_options(Options * options) options->fingerprint_hash = SSH_FP_HASH_DEFAULT; if (options->update_hostkeys == -1) options->update_hostkeys = 0; @@ -366,9 +366,9 @@ diff -up openssh-7.0p1/readconf.c.fips openssh-7.0p1/readconf.c &options->hostbased_key_types) != 0 || kex_assemble_names(KEX_DEFAULT_PK_ALG, diff -up openssh-7.0p1/servconf.c.fips openssh-7.0p1/servconf.c ---- openssh-7.0p1/servconf.c.fips 2015-08-12 11:34:11.714803033 +0200 -+++ openssh-7.0p1/servconf.c 2015-08-12 14:50:14.608951396 +0200 -@@ -357,9 +357,12 @@ fill_default_server_options(ServerOption +--- openssh-7.0p1/servconf.c.fips 2015-08-19 12:36:51.139412919 +0200 ++++ openssh-7.0p1/servconf.c 2015-08-19 12:36:51.152412889 +0200 +@@ -361,9 +361,12 @@ fill_default_server_options(ServerOption if (options->use_kuserok == -1) options->use_kuserok = 1; @@ -384,7 +384,7 @@ diff -up openssh-7.0p1/servconf.c.fips openssh-7.0p1/servconf.c kex_assemble_names(KEX_DEFAULT_PK_ALG, &options->hostbased_key_types) != 0 || kex_assemble_names(KEX_DEFAULT_PK_ALG, -@@ -2336,8 +2339,10 @@ dump_config(ServerOptions *o) +@@ -2355,8 +2358,10 @@ dump_config(ServerOptions *o) /* string arguments */ dump_cfg_string(sPidFile, o->pid_file); dump_cfg_string(sXAuthLocation, o->xauth_location); @@ -397,7 +397,7 @@ diff -up openssh-7.0p1/servconf.c.fips openssh-7.0p1/servconf.c dump_cfg_string(sBanner, o->banner != NULL ? o->banner : "none"); dump_cfg_string(sForceCommand, o->adm_forced_command); dump_cfg_string(sChrootDirectory, o->chroot_directory); -@@ -2352,8 +2357,8 @@ dump_config(ServerOptions *o) +@@ -2371,8 +2376,8 @@ dump_config(ServerOptions *o) dump_cfg_string(sAuthorizedPrincipalsCommand, o->authorized_principals_command); dump_cfg_string(sAuthorizedPrincipalsCommandUser, o->authorized_principals_command_user); dump_cfg_string(sHostKeyAgent, o->host_key_agent); @@ -410,7 +410,7 @@ diff -up openssh-7.0p1/servconf.c.fips openssh-7.0p1/servconf.c dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms ? diff -up openssh-7.0p1/ssh.c.fips openssh-7.0p1/ssh.c --- openssh-7.0p1/ssh.c.fips 2015-08-11 10:57:29.000000000 +0200 -+++ openssh-7.0p1/ssh.c 2015-08-12 11:34:11.736802999 +0200 ++++ openssh-7.0p1/ssh.c 2015-08-19 12:36:51.153412887 +0200 @@ -75,6 +75,8 @@ #include #include @@ -478,8 +478,8 @@ diff -up openssh-7.0p1/ssh.c.fips openssh-7.0p1/ssh.c if (ssh_connect(host, addrs, &hostaddr, options.port, options.address_family, options.connection_attempts, diff -up openssh-7.0p1/sshconnect2.c.fips openssh-7.0p1/sshconnect2.c ---- openssh-7.0p1/sshconnect2.c.fips 2015-08-12 11:34:11.678803089 +0200 -+++ openssh-7.0p1/sshconnect2.c 2015-08-12 11:34:11.737802997 +0200 +--- openssh-7.0p1/sshconnect2.c.fips 2015-08-19 12:36:51.140412916 +0200 ++++ openssh-7.0p1/sshconnect2.c 2015-08-19 12:39:52.455004667 +0200 @@ -44,6 +44,8 @@ #include #endif @@ -489,7 +489,7 @@ diff -up openssh-7.0p1/sshconnect2.c.fips openssh-7.0p1/sshconnect2.c #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" -@@ -170,20 +172,25 @@ ssh_kex2(char *host, struct sockaddr *ho +@@ -170,21 +172,26 @@ ssh_kex2(char *host, struct sockaddr *ho #ifdef GSSAPI if (options.gss_keyex) { @@ -502,7 +502,8 @@ diff -up openssh-7.0p1/sshconnect2.c.fips openssh-7.0p1/sshconnect2.c - 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], @@ -520,7 +521,8 @@ diff -up openssh-7.0p1/sshconnect2.c.fips openssh-7.0p1/sshconnect2.c + 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], @@ -530,8 +532,8 @@ diff -up openssh-7.0p1/sshconnect2.c.fips openssh-7.0p1/sshconnect2.c } #endif diff -up openssh-7.0p1/sshd.c.fips openssh-7.0p1/sshd.c ---- openssh-7.0p1/sshd.c.fips 2015-08-12 11:34:11.729803010 +0200 -+++ openssh-7.0p1/sshd.c 2015-08-12 11:34:11.738802995 +0200 +--- openssh-7.0p1/sshd.c.fips 2015-08-19 12:36:51.148412898 +0200 ++++ openssh-7.0p1/sshd.c 2015-08-19 12:36:51.153412887 +0200 @@ -66,6 +66,7 @@ #include #include @@ -619,8 +621,8 @@ diff -up openssh-7.0p1/sshd.c.fips openssh-7.0p1/sshd.c if (gss && orig) xasprintf(&newstr, "%s,%s", gss, orig); diff -up openssh-7.0p1/sshkey.c.fips openssh-7.0p1/sshkey.c ---- openssh-7.0p1/sshkey.c.fips 2015-08-12 11:34:11.729803010 +0200 -+++ openssh-7.0p1/sshkey.c 2015-08-12 11:34:11.738802995 +0200 +--- openssh-7.0p1/sshkey.c.fips 2015-08-19 12:36:51.148412898 +0200 ++++ openssh-7.0p1/sshkey.c 2015-08-19 12:36:51.154412885 +0200 @@ -35,6 +35,7 @@ #include #include @@ -629,7 +631,7 @@ diff -up openssh-7.0p1/sshkey.c.fips openssh-7.0p1/sshkey.c #endif #include "crypto_api.h" -@@ -1554,6 +1555,8 @@ rsa_generate_private_key(u_int bits, RSA +@@ -1552,6 +1553,8 @@ rsa_generate_private_key(u_int bits, RSA } if (!BN_set_word(f4, RSA_F4) || !RSA_generate_key_ex(private, bits, f4, NULL)) { diff --git a/openssh-7.0p1-gssKexAlgorithms.patch b/openssh-7.0p1-gssKexAlgorithms.patch new file mode 100644 index 0000000..9ea42e3 --- /dev/null +++ b/openssh-7.0p1-gssKexAlgorithms.patch @@ -0,0 +1,405 @@ +diff -up openssh-7.0p1/gss-genr.c.gsskexalg openssh-7.0p1/gss-genr.c +--- openssh-7.0p1/gss-genr.c.gsskexalg 2015-08-19 12:28:38.024518959 +0200 ++++ openssh-7.0p1/gss-genr.c 2015-08-19 12:28:38.078518839 +0200 +@@ -78,7 +78,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; + +@@ -86,12 +87,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; +@@ -100,6 +101,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++) +@@ -113,6 +115,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)) { +@@ -131,26 +134,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-7.0p1/gss-serv.c.gsskexalg openssh-7.0p1/gss-serv.c +--- openssh-7.0p1/gss-serv.c.gsskexalg 2015-08-19 12:28:38.024518959 +0200 ++++ openssh-7.0p1/gss-serv.c 2015-08-19 12:28:38.078518839 +0200 +@@ -150,7 +150,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-7.0p1/kex.c.gsskexalg openssh-7.0p1/kex.c +--- openssh-7.0p1/kex.c.gsskexalg 2015-08-19 12:28:38.078518839 +0200 ++++ openssh-7.0p1/kex.c 2015-08-19 12:30:13.249306371 +0200 +@@ -232,6 +232,29 @@ kex_assemble_names(const char *def, char + return 0; + } + ++/* 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 */ + int + kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX]) +diff -up openssh-7.0p1/kex.h.gsskexalg openssh-7.0p1/kex.h +--- openssh-7.0p1/kex.h.gsskexalg 2015-08-19 12:28:38.078518839 +0200 ++++ openssh-7.0p1/kex.h 2015-08-19 12:30:52.404218958 +0200 +@@ -173,6 +173,7 @@ int kex_names_valid(const char *); + char *kex_alg_list(char); + char *kex_names_cat(const char *, const char *); + int kex_assemble_names(const char *, char **); ++int gss_kex_names_valid(const char *); + + int kex_new(struct ssh *, char *[PROPOSAL_MAX], struct kex **); + int kex_setup(struct ssh *, char *[PROPOSAL_MAX]); +diff -up openssh-7.0p1/readconf.c.gsskexalg openssh-7.0p1/readconf.c +--- openssh-7.0p1/readconf.c.gsskexalg 2015-08-19 12:28:38.026518955 +0200 ++++ openssh-7.0p1/readconf.c 2015-08-19 12:31:28.333138747 +0200 +@@ -61,6 +61,7 @@ + #include "uidswap.h" + #include "myproposal.h" + #include "digest.h" ++#include "ssh-gss.h" + + /* Format of the configuration file: + +@@ -148,7 +149,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, +@@ -200,6 +201,7 @@ static struct { + { "gssapiclientidentity", oGssClientIdentity }, + { "gssapiserveridentity", oGssServerIdentity }, + { "gssapirenewalforcesrekey", oGssRenewalRekey }, ++ { "gssapikexalgorithms", oGssKexAlgorithms }, + #else + { "gssapiauthentication", oUnsupported }, + { "gssapikeyexchange", oUnsupported }, +@@ -207,6 +209,7 @@ static struct { + { "gssapitrustdns", oUnsupported }, + { "gssapiclientidentity", oUnsupported }, + { "gssapirenewalforcesrekey", oUnsupported }, ++ { "gssapikexalgorithms", oUnsupported }, + #endif + { "fallbacktorsh", oDeprecated }, + { "usersh", oDeprecated }, +@@ -929,6 +932,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 : ""); ++ if (*activep && options->gss_kex_algorithms == NULL) ++ options->gss_kex_algorithms = xstrdup(arg); ++ break; ++ + case oBatchMode: + intptr = &options->batch_mode; + goto parse_flag; +@@ -1638,6 +1653,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; +@@ -1773,6 +1789,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-7.0p1/readconf.h.gsskexalg openssh-7.0p1/readconf.h +--- openssh-7.0p1/readconf.h.gsskexalg 2015-08-19 12:28:38.026518955 +0200 ++++ openssh-7.0p1/readconf.h 2015-08-19 12:28:38.079518836 +0200 +@@ -51,6 +51,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-7.0p1/servconf.c.gsskexalg openssh-7.0p1/servconf.c +--- openssh-7.0p1/servconf.c.gsskexalg 2015-08-19 12:28:38.074518847 +0200 ++++ openssh-7.0p1/servconf.c 2015-08-19 12:33:13.599902732 +0200 +@@ -57,6 +57,7 @@ + #include "auth.h" + #include "myproposal.h" + #include "digest.h" ++#include "ssh-gss.h" + + static void add_listen_addr(ServerOptions *, char *, int); + static void add_one_listen_addr(ServerOptions *, char *, int); +@@ -121,6 +122,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; +@@ -288,6 +290,8 @@ fill_default_server_options(ServerOption + options->gss_strict_acceptor = 0; + 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) +@@ -427,7 +431,7 @@ typedef enum { + sHostKeyAlgorithms, + sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, + sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, +- sGssKeyEx, sGssStoreRekey, sAcceptEnv, sPermitTunnel, ++ sGssKeyEx, sGssStoreRekey, sGssKexAlgorithms, sAcceptEnv, sPermitTunnel, + sMatch, sPermitOpen, sForceCommand, sChrootDirectory, + sUsePrivilegeSeparation, sAllowAgentForwarding, + sHostCertificate, +@@ -506,6 +510,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 }, +@@ -513,6 +518,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 }, +@@ -1273,6 +1279,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 : ""); ++ if (*activep && options->gss_kex_algorithms == NULL) ++ options->gss_kex_algorithms = xstrdup(arg); ++ break; ++ + case sPasswordAuthentication: + intptr = &options->password_authentication; + goto parse_flag; +@@ -2304,6 +2322,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-7.0p1/servconf.h.gsskexalg openssh-7.0p1/servconf.h +--- openssh-7.0p1/servconf.h.gsskexalg 2015-08-19 12:28:38.080518834 +0200 ++++ openssh-7.0p1/servconf.h 2015-08-19 12:34:46.328693944 +0200 +@@ -122,6 +122,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-7.0p1/ssh.1.gsskexalg openssh-7.0p1/ssh.1 +--- openssh-7.0p1/ssh.1.gsskexalg 2015-08-19 12:28:38.081518832 +0200 ++++ openssh-7.0p1/ssh.1 2015-08-19 12:35:31.741591692 +0200 +@@ -496,6 +496,7 @@ For full details of the options listed b + .It GSSAPIDelegateCredentials + .It GSSAPIRenewalForcesRekey + .It GSSAPITrustDNS ++.It GSSAPIKexAlgorithms + .It HashKnownHosts + .It Host + .It HostbasedAuthentication +diff -up openssh-7.0p1/ssh_config.5.gsskexalg openssh-7.0p1/ssh_config.5 +--- openssh-7.0p1/ssh_config.5.gsskexalg 2015-08-19 12:28:38.028518950 +0200 ++++ openssh-7.0p1/ssh_config.5 2015-08-19 12:28:38.082518830 +0200 +@@ -786,6 +786,18 @@ command line will be passed untouched to + 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-group14-sha1- . ++This option only applies to protocol version 2 connections using GSSAPI. + .It Cm HashKnownHosts + Indicates that + .Xr ssh 1 +diff -up openssh-7.0p1/sshconnect2.c.gsskexalg openssh-7.0p1/sshconnect2.c +--- openssh-7.0p1/sshconnect2.c.gsskexalg 2015-08-19 12:28:38.045518912 +0200 ++++ openssh-7.0p1/sshconnect2.c 2015-08-19 12:28:38.081518832 +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-7.0p1/sshd_config.5.gsskexalg openssh-7.0p1/sshd_config.5 +--- openssh-7.0p1/sshd_config.5.gsskexalg 2015-08-19 12:28:38.082518830 +0200 ++++ openssh-7.0p1/sshd_config.5 2015-08-19 12:36:25.121471501 +0200 +@@ -659,6 +659,18 @@ Controls whether the user's GSSAPI crede + 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-group14-sha1- . ++This option only applies to protocol version 2 connections using GSSAPI. + .It Cm HostbasedAcceptedKeyTypes + Specifies the key types that will be accepted for hostbased authentication + as a comma-separated pattern list. +diff -up openssh-7.0p1/ssh-gss.h.gsskexalg openssh-7.0p1/ssh-gss.h +--- openssh-7.0p1/ssh-gss.h.gsskexalg 2015-08-19 12:28:38.031518944 +0200 ++++ openssh-7.0p1/ssh-gss.h 2015-08-19 12:28:38.081518832 +0200 +@@ -76,6 +76,10 @@ 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_GRP14_SHA1_ID ++ + typedef struct { + char *filename; + char *envvar; +@@ -147,9 +151,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/openssh.spec b/openssh.spec index 84fc143..dc92806 100644 --- a/openssh.spec +++ b/openssh.spec @@ -225,6 +225,8 @@ Patch928: openssh-6.8p1-memory-problems.patch Patch929: openssh-6.9p1-permit-root-login.patch # Handle terminal control characters in scp progressmeter (#1247204) Patch931: openssh-6.9p1-scp-progressmeter.patch +# Add GSSAPIKexAlgorithms option for server and client application +Patch932: openssh-7.0p1-gssKexAlgorithms.patch @@ -461,6 +463,7 @@ popd %patch928 -p1 -b .memory %patch929 -p1 -b .root-login %patch931 -p1 -b .progressmeter +%patch932 -p1 -b .gsskexalg %patch200 -p1 -b .audit %patch700 -p1 -b .fips