diff options
Diffstat (limited to 'kex.c')
-rw-r--r-- | kex.c | 41 |
1 files changed, 27 insertions, 14 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kex.c,v 1.127 2016/10/10 19:28:48 markus Exp $ */ | 1 | /* $OpenBSD: kex.c,v 1.131 2017/03/15 07:07:39 markus Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -194,7 +194,7 @@ kex_names_valid(const char *names) | |||
194 | char * | 194 | char * |
195 | kex_names_cat(const char *a, const char *b) | 195 | kex_names_cat(const char *a, const char *b) |
196 | { | 196 | { |
197 | char *ret = NULL, *tmp = NULL, *cp, *p; | 197 | char *ret = NULL, *tmp = NULL, *cp, *p, *m; |
198 | size_t len; | 198 | size_t len; |
199 | 199 | ||
200 | if (a == NULL || *a == '\0') | 200 | if (a == NULL || *a == '\0') |
@@ -211,8 +211,10 @@ kex_names_cat(const char *a, const char *b) | |||
211 | } | 211 | } |
212 | strlcpy(ret, a, len); | 212 | strlcpy(ret, a, len); |
213 | for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) { | 213 | for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) { |
214 | if (match_list(ret, p, NULL) != NULL) | 214 | if ((m = match_list(ret, p, NULL)) != NULL) { |
215 | free(m); | ||
215 | continue; /* Algorithm already present */ | 216 | continue; /* Algorithm already present */ |
217 | } | ||
216 | if (strlcat(ret, ",", len) >= len || | 218 | if (strlcat(ret, ",", len) >= len || |
217 | strlcat(ret, p, len) >= len) { | 219 | strlcat(ret, p, len) >= len) { |
218 | free(tmp); | 220 | free(tmp); |
@@ -227,7 +229,8 @@ kex_names_cat(const char *a, const char *b) | |||
227 | /* | 229 | /* |
228 | * Assemble a list of algorithms from a default list and a string from a | 230 | * Assemble a list of algorithms from a default list and a string from a |
229 | * configuration file. The user-provided string may begin with '+' to | 231 | * configuration file. The user-provided string may begin with '+' to |
230 | * indicate that it should be appended to the default. | 232 | * indicate that it should be appended to the default or '-' that the |
233 | * specified names should be removed. | ||
231 | */ | 234 | */ |
232 | int | 235 | int |
233 | kex_assemble_names(const char *def, char **list) | 236 | kex_assemble_names(const char *def, char **list) |
@@ -238,14 +241,18 @@ kex_assemble_names(const char *def, char **list) | |||
238 | *list = strdup(def); | 241 | *list = strdup(def); |
239 | return 0; | 242 | return 0; |
240 | } | 243 | } |
241 | if (**list != '+') { | 244 | if (**list == '+') { |
242 | return 0; | 245 | if ((ret = kex_names_cat(def, *list + 1)) == NULL) |
246 | return SSH_ERR_ALLOC_FAIL; | ||
247 | free(*list); | ||
248 | *list = ret; | ||
249 | } else if (**list == '-') { | ||
250 | if ((ret = match_filter_list(def, *list + 1)) == NULL) | ||
251 | return SSH_ERR_ALLOC_FAIL; | ||
252 | free(*list); | ||
253 | *list = ret; | ||
243 | } | 254 | } |
244 | 255 | ||
245 | if ((ret = kex_names_cat(def, *list + 1)) == NULL) | ||
246 | return SSH_ERR_ALLOC_FAIL; | ||
247 | free(*list); | ||
248 | *list = ret; | ||
249 | return 0; | 256 | return 0; |
250 | } | 257 | } |
251 | 258 | ||
@@ -350,7 +357,6 @@ kex_reset_dispatch(struct ssh *ssh) | |||
350 | { | 357 | { |
351 | ssh_dispatch_range(ssh, SSH2_MSG_TRANSPORT_MIN, | 358 | ssh_dispatch_range(ssh, SSH2_MSG_TRANSPORT_MIN, |
352 | SSH2_MSG_TRANSPORT_MAX, &kex_protocol_error); | 359 | SSH2_MSG_TRANSPORT_MAX, &kex_protocol_error); |
353 | ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit); | ||
354 | } | 360 | } |
355 | 361 | ||
356 | static int | 362 | static int |
@@ -359,7 +365,7 @@ kex_send_ext_info(struct ssh *ssh) | |||
359 | int r; | 365 | int r; |
360 | char *algs; | 366 | char *algs; |
361 | 367 | ||
362 | if ((algs = sshkey_alg_list(0, 1, ',')) == NULL) | 368 | if ((algs = sshkey_alg_list(0, 1, 1, ',')) == NULL) |
363 | return SSH_ERR_ALLOC_FAIL; | 369 | return SSH_ERR_ALLOC_FAIL; |
364 | if ((r = sshpkt_start(ssh, SSH2_MSG_EXT_INFO)) != 0 || | 370 | if ((r = sshpkt_start(ssh, SSH2_MSG_EXT_INFO)) != 0 || |
365 | (r = sshpkt_put_u32(ssh, 1)) != 0 || | 371 | (r = sshpkt_put_u32(ssh, 1)) != 0 || |
@@ -440,6 +446,7 @@ kex_input_newkeys(int type, u_int32_t seq, void *ctxt) | |||
440 | 446 | ||
441 | debug("SSH2_MSG_NEWKEYS received"); | 447 | debug("SSH2_MSG_NEWKEYS received"); |
442 | ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_protocol_error); | 448 | ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_protocol_error); |
449 | ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit); | ||
443 | if ((r = sshpkt_get_end(ssh)) != 0) | 450 | if ((r = sshpkt_get_end(ssh)) != 0) |
444 | return r; | 451 | return r; |
445 | if ((r = ssh_set_newkeys(ssh, MODE_IN)) != 0) | 452 | if ((r = ssh_set_newkeys(ssh, MODE_IN)) != 0) |
@@ -554,6 +561,7 @@ kex_new(struct ssh *ssh, char *proposal[PROPOSAL_MAX], struct kex **kexp) | |||
554 | goto out; | 561 | goto out; |
555 | kex->done = 0; | 562 | kex->done = 0; |
556 | kex_reset_dispatch(ssh); | 563 | kex_reset_dispatch(ssh); |
564 | ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit); | ||
557 | r = 0; | 565 | r = 0; |
558 | *kexp = kex; | 566 | *kexp = kex; |
559 | out: | 567 | out: |
@@ -665,8 +673,10 @@ choose_enc(struct sshenc *enc, char *client, char *server) | |||
665 | 673 | ||
666 | if (name == NULL) | 674 | if (name == NULL) |
667 | return SSH_ERR_NO_CIPHER_ALG_MATCH; | 675 | return SSH_ERR_NO_CIPHER_ALG_MATCH; |
668 | if ((enc->cipher = cipher_by_name(name)) == NULL) | 676 | if ((enc->cipher = cipher_by_name(name)) == NULL) { |
677 | free(name); | ||
669 | return SSH_ERR_INTERNAL_ERROR; | 678 | return SSH_ERR_INTERNAL_ERROR; |
679 | } | ||
670 | enc->name = name; | 680 | enc->name = name; |
671 | enc->enabled = 0; | 681 | enc->enabled = 0; |
672 | enc->iv = NULL; | 682 | enc->iv = NULL; |
@@ -684,8 +694,10 @@ choose_mac(struct ssh *ssh, struct sshmac *mac, char *client, char *server) | |||
684 | 694 | ||
685 | if (name == NULL) | 695 | if (name == NULL) |
686 | return SSH_ERR_NO_MAC_ALG_MATCH; | 696 | return SSH_ERR_NO_MAC_ALG_MATCH; |
687 | if (mac_setup(mac, name) < 0) | 697 | if (mac_setup(mac, name) < 0) { |
698 | free(name); | ||
688 | return SSH_ERR_INTERNAL_ERROR; | 699 | return SSH_ERR_INTERNAL_ERROR; |
700 | } | ||
689 | /* truncate the key */ | 701 | /* truncate the key */ |
690 | if (ssh->compat & SSH_BUG_HMAC) | 702 | if (ssh->compat & SSH_BUG_HMAC) |
691 | mac->key_len = 16; | 703 | mac->key_len = 16; |
@@ -709,6 +721,7 @@ choose_comp(struct sshcomp *comp, char *client, char *server) | |||
709 | } else if (strcmp(name, "none") == 0) { | 721 | } else if (strcmp(name, "none") == 0) { |
710 | comp->type = COMP_NONE; | 722 | comp->type = COMP_NONE; |
711 | } else { | 723 | } else { |
724 | free(name); | ||
712 | return SSH_ERR_INTERNAL_ERROR; | 725 | return SSH_ERR_INTERNAL_ERROR; |
713 | } | 726 | } |
714 | comp->name = name; | 727 | comp->name = name; |