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