diff options
author | Simon Wilkinson <simon@sxw.org.uk> | 2014-02-09 16:09:48 +0000 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2019-10-09 23:06:20 +0100 |
commit | 9da806e67101afdc0d3a1d304659927acf18f5c5 (patch) | |
tree | 4cb56e13b3b3b14147366a04a7ff691f76908bf7 /kex.c | |
parent | 4213eec74e74de6310c27a40c3e9759a08a73996 (diff) |
GSSAPI key exchange support
This patch has been rejected upstream: "None of the OpenSSH developers are
in favour of adding this, and this situation has not changed for several
years. This is not a slight on Simon's patch, which is of fine quality, but
just that a) we don't trust GSSAPI implementations that much and b) we don't
like adding new KEX since they are pre-auth attack surface. This one is
particularly scary, since it requires hooks out to typically root-owned
system resources."
However, quite a lot of people rely on this in Debian, and it's better to
have it merged into the main openssh package rather than having separate
-krb5 packages (as we used to have). It seems to have a generally good
security history.
Origin: other, https://github.com/openssh-gsskex/openssh-gsskex/commits/debian/master
Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1242
Last-Updated: 2019-10-09
Patch-Name: gssapi.patch
Diffstat (limited to 'kex.c')
-rw-r--r-- | kex.c | 66 |
1 files changed, 63 insertions, 3 deletions
@@ -55,11 +55,16 @@ | |||
55 | #include "misc.h" | 55 | #include "misc.h" |
56 | #include "dispatch.h" | 56 | #include "dispatch.h" |
57 | #include "monitor.h" | 57 | #include "monitor.h" |
58 | #include "xmalloc.h" | ||
58 | 59 | ||
59 | #include "ssherr.h" | 60 | #include "ssherr.h" |
60 | #include "sshbuf.h" | 61 | #include "sshbuf.h" |
61 | #include "digest.h" | 62 | #include "digest.h" |
62 | 63 | ||
64 | #ifdef GSSAPI | ||
65 | #include "ssh-gss.h" | ||
66 | #endif | ||
67 | |||
63 | /* prototype */ | 68 | /* prototype */ |
64 | static int kex_choose_conf(struct ssh *); | 69 | static int kex_choose_conf(struct ssh *); |
65 | static int kex_input_newkeys(int, u_int32_t, struct ssh *); | 70 | static int kex_input_newkeys(int, u_int32_t, struct ssh *); |
@@ -113,15 +118,28 @@ static const struct kexalg kexalgs[] = { | |||
113 | #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ | 118 | #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ |
114 | { NULL, 0, -1, -1}, | 119 | { NULL, 0, -1, -1}, |
115 | }; | 120 | }; |
121 | static const struct kexalg gss_kexalgs[] = { | ||
122 | #ifdef GSSAPI | ||
123 | { KEX_GSS_GEX_SHA1_ID, KEX_GSS_GEX_SHA1, 0, SSH_DIGEST_SHA1 }, | ||
124 | { KEX_GSS_GRP1_SHA1_ID, KEX_GSS_GRP1_SHA1, 0, SSH_DIGEST_SHA1 }, | ||
125 | { KEX_GSS_GRP14_SHA1_ID, KEX_GSS_GRP14_SHA1, 0, SSH_DIGEST_SHA1 }, | ||
126 | { KEX_GSS_GRP14_SHA256_ID, KEX_GSS_GRP14_SHA256, 0, SSH_DIGEST_SHA256 }, | ||
127 | { KEX_GSS_GRP16_SHA512_ID, KEX_GSS_GRP16_SHA512, 0, SSH_DIGEST_SHA512 }, | ||
128 | { KEX_GSS_NISTP256_SHA256_ID, KEX_GSS_NISTP256_SHA256, | ||
129 | NID_X9_62_prime256v1, SSH_DIGEST_SHA256 }, | ||
130 | { KEX_GSS_C25519_SHA256_ID, KEX_GSS_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, | ||
131 | #endif | ||
132 | { NULL, 0, -1, -1 }, | ||
133 | }; | ||
116 | 134 | ||
117 | char * | 135 | static char * |
118 | kex_alg_list(char sep) | 136 | kex_alg_list_internal(char sep, const struct kexalg *algs) |
119 | { | 137 | { |
120 | char *ret = NULL, *tmp; | 138 | char *ret = NULL, *tmp; |
121 | size_t nlen, rlen = 0; | 139 | size_t nlen, rlen = 0; |
122 | const struct kexalg *k; | 140 | const struct kexalg *k; |
123 | 141 | ||
124 | for (k = kexalgs; k->name != NULL; k++) { | 142 | for (k = algs; k->name != NULL; k++) { |
125 | if (ret != NULL) | 143 | if (ret != NULL) |
126 | ret[rlen++] = sep; | 144 | ret[rlen++] = sep; |
127 | nlen = strlen(k->name); | 145 | nlen = strlen(k->name); |
@@ -136,6 +154,18 @@ kex_alg_list(char sep) | |||
136 | return ret; | 154 | return ret; |
137 | } | 155 | } |
138 | 156 | ||
157 | char * | ||
158 | kex_alg_list(char sep) | ||
159 | { | ||
160 | return kex_alg_list_internal(sep, kexalgs); | ||
161 | } | ||
162 | |||
163 | char * | ||
164 | kex_gss_alg_list(char sep) | ||
165 | { | ||
166 | return kex_alg_list_internal(sep, gss_kexalgs); | ||
167 | } | ||
168 | |||
139 | static const struct kexalg * | 169 | static const struct kexalg * |
140 | kex_alg_by_name(const char *name) | 170 | kex_alg_by_name(const char *name) |
141 | { | 171 | { |
@@ -145,6 +175,10 @@ kex_alg_by_name(const char *name) | |||
145 | if (strcmp(k->name, name) == 0) | 175 | if (strcmp(k->name, name) == 0) |
146 | return k; | 176 | return k; |
147 | } | 177 | } |
178 | for (k = gss_kexalgs; k->name != NULL; k++) { | ||
179 | if (strncmp(k->name, name, strlen(k->name)) == 0) | ||
180 | return k; | ||
181 | } | ||
148 | return NULL; | 182 | return NULL; |
149 | } | 183 | } |
150 | 184 | ||
@@ -313,6 +347,29 @@ kex_assemble_names(char **listp, const char *def, const char *all) | |||
313 | return r; | 347 | return r; |
314 | } | 348 | } |
315 | 349 | ||
350 | /* Validate GSS KEX method name list */ | ||
351 | int | ||
352 | kex_gss_names_valid(const char *names) | ||
353 | { | ||
354 | char *s, *cp, *p; | ||
355 | |||
356 | if (names == NULL || *names == '\0') | ||
357 | return 0; | ||
358 | s = cp = xstrdup(names); | ||
359 | for ((p = strsep(&cp, ",")); p && *p != '\0'; | ||
360 | (p = strsep(&cp, ","))) { | ||
361 | if (strncmp(p, "gss-", 4) != 0 | ||
362 | || kex_alg_by_name(p) == NULL) { | ||
363 | error("Unsupported KEX algorithm \"%.100s\"", p); | ||
364 | free(s); | ||
365 | return 0; | ||
366 | } | ||
367 | } | ||
368 | debug3("gss kex names ok: [%s]", names); | ||
369 | free(s); | ||
370 | return 1; | ||
371 | } | ||
372 | |||
316 | /* put algorithm proposal into buffer */ | 373 | /* put algorithm proposal into buffer */ |
317 | int | 374 | int |
318 | kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX]) | 375 | kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX]) |
@@ -696,6 +753,9 @@ kex_free(struct kex *kex) | |||
696 | sshbuf_free(kex->server_version); | 753 | sshbuf_free(kex->server_version); |
697 | sshbuf_free(kex->client_pub); | 754 | sshbuf_free(kex->client_pub); |
698 | free(kex->session_id); | 755 | free(kex->session_id); |
756 | #ifdef GSSAPI | ||
757 | free(kex->gss_host); | ||
758 | #endif /* GSSAPI */ | ||
699 | free(kex->failed_choice); | 759 | free(kex->failed_choice); |
700 | free(kex->hostkey_alg); | 760 | free(kex->hostkey_alg); |
701 | free(kex->name); | 761 | free(kex->name); |