diff options
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); |