diff options
Diffstat (limited to 'kex.c')
-rw-r--r-- | kex.c | 64 |
1 files changed, 63 insertions, 1 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kex.c,v 1.108 2015/07/29 08:34:54 djm Exp $ */ | 1 | /* $OpenBSD: kex.c,v 1.109 2015/07/30 00:01:34 djm 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 | * |
@@ -155,6 +155,68 @@ kex_names_valid(const char *names) | |||
155 | return 1; | 155 | return 1; |
156 | } | 156 | } |
157 | 157 | ||
158 | /* | ||
159 | * Concatenate algorithm names, avoiding duplicates in the process. | ||
160 | * Caller must free returned string. | ||
161 | */ | ||
162 | char * | ||
163 | kex_names_cat(const char *a, const char *b) | ||
164 | { | ||
165 | char *ret = NULL, *tmp = NULL, *cp, *p; | ||
166 | size_t len; | ||
167 | |||
168 | if (a == NULL || *a == '\0') | ||
169 | return NULL; | ||
170 | if (b == NULL || *b == '\0') | ||
171 | return strdup(a); | ||
172 | if (strlen(b) > 1024*1024) | ||
173 | return NULL; | ||
174 | len = strlen(a) + strlen(b) + 2; | ||
175 | if ((tmp = cp = strdup(b)) == NULL || | ||
176 | (ret = calloc(1, len)) == NULL) { | ||
177 | free(tmp); | ||
178 | return NULL; | ||
179 | } | ||
180 | strlcpy(ret, a, len); | ||
181 | for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) { | ||
182 | if (match_list(ret, p, NULL) != NULL) | ||
183 | continue; /* Algorithm already present */ | ||
184 | if (strlcat(ret, ",", len) >= len || | ||
185 | strlcat(ret, p, len) >= len) { | ||
186 | free(tmp); | ||
187 | free(ret); | ||
188 | return NULL; /* Shouldn't happen */ | ||
189 | } | ||
190 | } | ||
191 | free(tmp); | ||
192 | return ret; | ||
193 | } | ||
194 | |||
195 | /* | ||
196 | * Assemble a list of algorithms from a default list and a string from a | ||
197 | * configuration file. The user-provided string may begin with '+' to | ||
198 | * indicate that it should be appended to the default. | ||
199 | */ | ||
200 | int | ||
201 | kex_assemble_names(const char *def, char **list) | ||
202 | { | ||
203 | char *ret; | ||
204 | |||
205 | if (list == NULL || *list == NULL || **list == '\0') { | ||
206 | *list = strdup(def); | ||
207 | return 0; | ||
208 | } | ||
209 | if (**list != '+') { | ||
210 | return 0; | ||
211 | } | ||
212 | |||
213 | if ((ret = kex_names_cat(def, *list + 1)) == NULL) | ||
214 | return SSH_ERR_ALLOC_FAIL; | ||
215 | free(*list); | ||
216 | *list = ret; | ||
217 | return 0; | ||
218 | } | ||
219 | |||
158 | /* put algorithm proposal into buffer */ | 220 | /* put algorithm proposal into buffer */ |
159 | int | 221 | int |
160 | kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX]) | 222 | kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX]) |