summaryrefslogtreecommitdiff
path: root/kex.c
diff options
context:
space:
mode:
Diffstat (limited to 'kex.c')
-rw-r--r--kex.c41
1 files changed, 27 insertions, 14 deletions
diff --git a/kex.c b/kex.c
index d87086844..556a32e98 100644
--- a/kex.c
+++ b/kex.c
@@ -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)
194char * 194char *
195kex_names_cat(const char *a, const char *b) 195kex_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 */
232int 235int
233kex_assemble_names(const char *def, char **list) 236kex_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
356static int 362static 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;