Mercurial > dropbear
comparison common-algo.c @ 741:eafdf8b363f5 kexguess
Get rid of client/server specific buf_match_algo, use single
function with a couple of if statements instead
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sat, 30 Mar 2013 23:55:05 +0800 |
parents | 3062da90dab8 |
children | 15999b098cc9 |
comparison
equal
deleted
inserted
replaced
740:3062da90dab8 | 741:eafdf8b363f5 |
---|---|
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | 22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | 23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
24 * SOFTWARE. */ | 24 * SOFTWARE. */ |
25 | 25 |
26 #include "algo.h" | 26 #include "algo.h" |
27 #include "session.h" | |
27 #include "dbutil.h" | 28 #include "dbutil.h" |
28 | 29 |
29 /* This file (algo.c) organises the ciphers which can be used, and is used to | 30 /* This file (algo.c) organises the ciphers which can be used, and is used to |
30 * decide which ciphers/hashes/compression/signing to use during key exchange*/ | 31 * decide which ciphers/hashes/compression/signing to use during key exchange*/ |
31 | 32 |
304 buf_putbytes(algolist, localalgos[i].name, len); | 305 buf_putbytes(algolist, localalgos[i].name, len); |
305 } | 306 } |
306 } | 307 } |
307 buf_putstring(buf, algolist->data, algolist->len); | 308 buf_putstring(buf, algolist->data, algolist->len); |
308 buf_free(algolist); | 309 buf_free(algolist); |
310 } | |
311 | |
312 /* match the first algorithm in the comma-separated list in buf which is | |
313 * also in localalgos[], or return NULL on failure. | |
314 * (*goodguess) is set to 1 if the preferred client/server algos match, | |
315 * 0 otherwise. This is used for checking if the kexalgo/hostkeyalgos are | |
316 * guessed correctly */ | |
317 algo_type * buf_match_algo(buffer* buf, algo_type localalgos[], | |
318 enum kexguess2_used *kexguess2, int *goodguess) | |
319 { | |
320 | |
321 unsigned char * algolist = NULL; | |
322 const unsigned char *remotenames[MAX_PROPOSED_ALGO], *localnames[MAX_PROPOSED_ALGO]; | |
323 unsigned int len; | |
324 unsigned int remotecount, localcount, clicount, servcount, i, j; | |
325 algo_type * ret = NULL; | |
326 const unsigned char **clinames, **servnames; | |
327 | |
328 if (goodguess) { | |
329 *goodguess = 0; | |
330 } | |
331 | |
332 /* get the comma-separated list from the buffer ie "algo1,algo2,algo3" */ | |
333 algolist = buf_getstring(buf, &len); | |
334 TRACE(("buf_match_algo: %s", algolist)) | |
335 if (len > MAX_PROPOSED_ALGO*(MAX_NAME_LEN+1)) { | |
336 goto out; | |
337 } | |
338 | |
339 /* remotenames will contain a list of the strings parsed out */ | |
340 /* We will have at least one string (even if it's just "") */ | |
341 remotenames[0] = algolist; | |
342 remotecount = 1; | |
343 for (i = 0; i < len; i++) { | |
344 if (algolist[i] == '\0') { | |
345 /* someone is trying something strange */ | |
346 goto out; | |
347 } | |
348 if (algolist[i] == ',') { | |
349 algolist[i] = '\0'; | |
350 remotenames[remotecount] = &algolist[i+1]; | |
351 remotecount++; | |
352 } | |
353 if (remotecount >= MAX_PROPOSED_ALGO) { | |
354 break; | |
355 } | |
356 } | |
357 if (kexguess2 && *kexguess2 == KEXGUESS2_LOOK) { | |
358 for (i = 0; i < remotecount; i++) | |
359 { | |
360 if (strcmp(remotenames[i], KEXGUESS2_ALGO_NAME) == 0) { | |
361 *kexguess2 = KEXGUESS2_YES; | |
362 break; | |
363 } | |
364 } | |
365 if (*kexguess2 == KEXGUESS2_LOOK) { | |
366 *kexguess2 = KEXGUESS2_NO; | |
367 } | |
368 } | |
369 | |
370 for (i = 0; localalgos[i].name != NULL; i++) { | |
371 if (localalgos[i].usable) { | |
372 localnames[i] = localalgos[i].name; | |
373 } else { | |
374 localnames[i] = NULL; | |
375 } | |
376 } | |
377 localcount = i; | |
378 | |
379 if (IS_DROPBEAR_SERVER) { | |
380 clinames = remotenames; | |
381 clicount = remotecount; | |
382 servnames = localnames; | |
383 servcount = localcount; | |
384 } else { | |
385 clinames = localnames; | |
386 clicount = localcount; | |
387 servnames = remotenames; | |
388 servcount = remotecount; | |
389 } | |
390 | |
391 /* iterate and find the first match */ | |
392 for (i = 0; i < clicount; i++) { | |
393 for (j = 0; j < servcount; j++) { | |
394 if (!(servnames[j] && clinames[i])) { | |
395 // unusable algos are NULL | |
396 continue; | |
397 } | |
398 if (strcmp(servnames[j], clinames[i]) == 0) { | |
399 /* set if it was a good guess */ | |
400 if (goodguess && kexguess2) { | |
401 if (*kexguess2 == KEXGUESS2_YES) { | |
402 if (i == 0) { | |
403 *goodguess = 1; | |
404 } | |
405 | |
406 } else { | |
407 if (i == 0 && j == 0) { | |
408 *goodguess = 1; | |
409 } | |
410 } | |
411 } | |
412 /* set the algo to return */ | |
413 if (IS_DROPBEAR_SERVER) { | |
414 ret = &localalgos[j]; | |
415 } else { | |
416 ret = &localalgos[i]; | |
417 } | |
418 goto out; | |
419 } | |
420 } | |
421 } | |
422 | |
423 out: | |
424 m_free(algolist); | |
425 return ret; | |
309 } | 426 } |
310 | 427 |
311 #ifdef DROPBEAR_NONE_CIPHER | 428 #ifdef DROPBEAR_NONE_CIPHER |
312 | 429 |
313 void | 430 void |