diff options
Diffstat (limited to 'kex.c')
-rw-r--r-- | kex.c | 66 |
1 files changed, 63 insertions, 3 deletions
@@ -57,11 +57,16 @@ | |||
57 | #include "misc.h" | 57 | #include "misc.h" |
58 | #include "dispatch.h" | 58 | #include "dispatch.h" |
59 | #include "monitor.h" | 59 | #include "monitor.h" |
60 | #include "xmalloc.h" | ||
60 | 61 | ||
61 | #include "ssherr.h" | 62 | #include "ssherr.h" |
62 | #include "sshbuf.h" | 63 | #include "sshbuf.h" |
63 | #include "digest.h" | 64 | #include "digest.h" |
64 | 65 | ||
66 | #ifdef GSSAPI | ||
67 | #include "ssh-gss.h" | ||
68 | #endif | ||
69 | |||
65 | /* prototype */ | 70 | /* prototype */ |
66 | static int kex_choose_conf(struct ssh *); | 71 | static int kex_choose_conf(struct ssh *); |
67 | static int kex_input_newkeys(int, u_int32_t, struct ssh *); | 72 | static int kex_input_newkeys(int, u_int32_t, struct ssh *); |
@@ -115,15 +120,28 @@ static const struct kexalg kexalgs[] = { | |||
115 | #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ | 120 | #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ |
116 | { NULL, 0, -1, -1}, | 121 | { NULL, 0, -1, -1}, |
117 | }; | 122 | }; |
123 | static const struct kexalg gss_kexalgs[] = { | ||
124 | #ifdef GSSAPI | ||
125 | { KEX_GSS_GEX_SHA1_ID, KEX_GSS_GEX_SHA1, 0, SSH_DIGEST_SHA1 }, | ||
126 | { KEX_GSS_GRP1_SHA1_ID, KEX_GSS_GRP1_SHA1, 0, SSH_DIGEST_SHA1 }, | ||
127 | { KEX_GSS_GRP14_SHA1_ID, KEX_GSS_GRP14_SHA1, 0, SSH_DIGEST_SHA1 }, | ||
128 | { KEX_GSS_GRP14_SHA256_ID, KEX_GSS_GRP14_SHA256, 0, SSH_DIGEST_SHA256 }, | ||
129 | { KEX_GSS_GRP16_SHA512_ID, KEX_GSS_GRP16_SHA512, 0, SSH_DIGEST_SHA512 }, | ||
130 | { KEX_GSS_NISTP256_SHA256_ID, KEX_GSS_NISTP256_SHA256, | ||
131 | NID_X9_62_prime256v1, SSH_DIGEST_SHA256 }, | ||
132 | { KEX_GSS_C25519_SHA256_ID, KEX_GSS_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, | ||
133 | #endif | ||
134 | { NULL, 0, -1, -1}, | ||
135 | }; | ||
118 | 136 | ||
119 | char * | 137 | static char * |
120 | kex_alg_list(char sep) | 138 | kex_alg_list_internal(char sep, const struct kexalg *algs) |
121 | { | 139 | { |
122 | char *ret = NULL, *tmp; | 140 | char *ret = NULL, *tmp; |
123 | size_t nlen, rlen = 0; | 141 | size_t nlen, rlen = 0; |
124 | const struct kexalg *k; | 142 | const struct kexalg *k; |
125 | 143 | ||
126 | for (k = kexalgs; k->name != NULL; k++) { | 144 | for (k = algs; k->name != NULL; k++) { |
127 | if (ret != NULL) | 145 | if (ret != NULL) |
128 | ret[rlen++] = sep; | 146 | ret[rlen++] = sep; |
129 | nlen = strlen(k->name); | 147 | nlen = strlen(k->name); |
@@ -138,6 +156,18 @@ kex_alg_list(char sep) | |||
138 | return ret; | 156 | return ret; |
139 | } | 157 | } |
140 | 158 | ||
159 | char * | ||
160 | kex_alg_list(char sep) | ||
161 | { | ||
162 | return kex_alg_list_internal(sep, kexalgs); | ||
163 | } | ||
164 | |||
165 | char * | ||
166 | kex_gss_alg_list(char sep) | ||
167 | { | ||
168 | return kex_alg_list_internal(sep, gss_kexalgs); | ||
169 | } | ||
170 | |||
141 | static const struct kexalg * | 171 | static const struct kexalg * |
142 | kex_alg_by_name(const char *name) | 172 | kex_alg_by_name(const char *name) |
143 | { | 173 | { |
@@ -147,6 +177,10 @@ kex_alg_by_name(const char *name) | |||
147 | if (strcmp(k->name, name) == 0) | 177 | if (strcmp(k->name, name) == 0) |
148 | return k; | 178 | return k; |
149 | } | 179 | } |
180 | for (k = gss_kexalgs; k->name != NULL; k++) { | ||
181 | if (strncmp(k->name, name, strlen(k->name)) == 0) | ||
182 | return k; | ||
183 | } | ||
150 | return NULL; | 184 | return NULL; |
151 | } | 185 | } |
152 | 186 | ||
@@ -315,6 +349,29 @@ kex_assemble_names(char **listp, const char *def, const char *all) | |||
315 | return r; | 349 | return r; |
316 | } | 350 | } |
317 | 351 | ||
352 | /* Validate GSS KEX method name list */ | ||
353 | int | ||
354 | kex_gss_names_valid(const char *names) | ||
355 | { | ||
356 | char *s, *cp, *p; | ||
357 | |||
358 | if (names == NULL || *names == '\0') | ||
359 | return 0; | ||
360 | s = cp = xstrdup(names); | ||
361 | for ((p = strsep(&cp, ",")); p && *p != '\0'; | ||
362 | (p = strsep(&cp, ","))) { | ||
363 | if (strncmp(p, "gss-", 4) != 0 | ||
364 | || kex_alg_by_name(p) == NULL) { | ||
365 | error("Unsupported KEX algorithm \"%.100s\"", p); | ||
366 | free(s); | ||
367 | return 0; | ||
368 | } | ||
369 | } | ||
370 | debug3("gss kex names ok: [%s]", names); | ||
371 | free(s); | ||
372 | return 1; | ||
373 | } | ||
374 | |||
318 | /* put algorithm proposal into buffer */ | 375 | /* put algorithm proposal into buffer */ |
319 | int | 376 | int |
320 | kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX]) | 377 | kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX]) |
@@ -698,6 +755,9 @@ kex_free(struct kex *kex) | |||
698 | sshbuf_free(kex->server_version); | 755 | sshbuf_free(kex->server_version); |
699 | sshbuf_free(kex->client_pub); | 756 | sshbuf_free(kex->client_pub); |
700 | free(kex->session_id); | 757 | free(kex->session_id); |
758 | #ifdef GSSAPI | ||
759 | free(kex->gss_host); | ||
760 | #endif /* GSSAPI */ | ||
701 | free(kex->failed_choice); | 761 | free(kex->failed_choice); |
702 | free(kex->hostkey_alg); | 762 | free(kex->hostkey_alg); |
703 | free(kex->name); | 763 | free(kex->name); |