summaryrefslogtreecommitdiffstats
path: root/kex.c
diff options
context:
space:
mode:
Diffstat (limited to 'kex.c')
-rw-r--r--kex.c64
1 files changed, 63 insertions, 1 deletions
diff --git a/kex.c b/kex.c
index af2a41cc..5100c661 100644
--- a/kex.c
+++ b/kex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kex.c,v 1.108 2015/07/29 08:34:54 djm Exp $ */
+/* $OpenBSD: kex.c,v 1.109 2015/07/30 00:01:34 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*
@@ -155,6 +155,68 @@ kex_names_valid(const char *names)
return 1;
}
+/*
+ * Concatenate algorithm names, avoiding duplicates in the process.
+ * Caller must free returned string.
+ */
+char *
+kex_names_cat(const char *a, const char *b)
+{
+ char *ret = NULL, *tmp = NULL, *cp, *p;
+ size_t len;
+
+ if (a == NULL || *a == '\0')
+ return NULL;
+ if (b == NULL || *b == '\0')
+ return strdup(a);
+ if (strlen(b) > 1024*1024)
+ return NULL;
+ len = strlen(a) + strlen(b) + 2;
+ if ((tmp = cp = strdup(b)) == NULL ||
+ (ret = calloc(1, len)) == NULL) {
+ free(tmp);
+ return NULL;
+ }
+ strlcpy(ret, a, len);
+ for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) {
+ if (match_list(ret, p, NULL) != NULL)
+ continue; /* Algorithm already present */
+ if (strlcat(ret, ",", len) >= len ||
+ strlcat(ret, p, len) >= len) {
+ free(tmp);
+ free(ret);
+ return NULL; /* Shouldn't happen */
+ }
+ }
+ free(tmp);
+ return ret;
+}
+
+/*
+ * Assemble a list of algorithms from a default list and a string from a
+ * configuration file. The user-provided string may begin with '+' to
+ * indicate that it should be appended to the default.
+ */
+int
+kex_assemble_names(const char *def, char **list)
+{
+ char *ret;
+
+ if (list == NULL || *list == NULL || **list == '\0') {
+ *list = strdup(def);
+ return 0;
+ }
+ if (**list != '+') {
+ return 0;
+ }
+
+ if ((ret = kex_names_cat(def, *list + 1)) == NULL)
+ return SSH_ERR_ALLOC_FAIL;
+ free(*list);
+ *list = ret;
+ return 0;
+}
+
/* put algorithm proposal into buffer */
int
kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX])