summaryrefslogtreecommitdiff
path: root/auth2.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2013-04-23 15:18:10 +1000
committerDamien Miller <djm@mindrot.org>2013-04-23 15:18:10 +1000
commit91a55f28f35431f9000b95815c343b5a18fda712 (patch)
treedc3339c3a51fd5f78776b0f80220e4c078f52cfb /auth2.c
parent4ce189d9108c62090a0dd5dea973d175328440db (diff)
- markus@cvs.openbsd.org 2013/03/07 19:27:25
[auth.h auth2-chall.c auth2.c monitor.c sshd_config.5] add submethod support to AuthenticationMethods; ok and freedback djm@
Diffstat (limited to 'auth2.c')
-rw-r--r--auth2.c76
1 files changed, 55 insertions, 21 deletions
diff --git a/auth2.c b/auth2.c
index e367a1045..e44482164 100644
--- a/auth2.c
+++ b/auth2.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2.c,v 1.126 2012/12/02 20:34:09 djm Exp $ */ 1/* $OpenBSD: auth2.c,v 1.127 2013/03/07 19:27:25 markus Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -98,8 +98,12 @@ static void input_userauth_request(int, u_int32_t, void *);
98/* helper */ 98/* helper */
99static Authmethod *authmethod_lookup(Authctxt *, const char *); 99static Authmethod *authmethod_lookup(Authctxt *, const char *);
100static char *authmethods_get(Authctxt *authctxt); 100static char *authmethods_get(Authctxt *authctxt);
101static int method_allowed(Authctxt *, const char *); 101
102static int list_starts_with(const char *, const char *); 102#define MATCH_NONE 0 /* method or submethod mismatch */
103#define MATCH_METHOD 1 /* method matches (no submethod specified) */
104#define MATCH_BOTH 2 /* method and submethod match */
105#define MATCH_PARTIAL 3 /* method matches, submethod can't be checked */
106static int list_starts_with(const char *, const char *, const char *);
103 107
104char * 108char *
105auth2_read_banner(void) 109auth2_read_banner(void)
@@ -316,7 +320,7 @@ userauth_finish(Authctxt *authctxt, int authenticated, const char *method,
316 } 320 }
317 321
318 if (authenticated && options.num_auth_methods != 0) { 322 if (authenticated && options.num_auth_methods != 0) {
319 if (!auth2_update_methods_lists(authctxt, method)) { 323 if (!auth2_update_methods_lists(authctxt, method, submethod)) {
320 authenticated = 0; 324 authenticated = 0;
321 partial = 1; 325 partial = 1;
322 } 326 }
@@ -387,8 +391,9 @@ userauth_finish(Authctxt *authctxt, int authenticated, const char *method,
387 * methods list. Returns 1 if allowed, or no methods lists configured. 391 * methods list. Returns 1 if allowed, or no methods lists configured.
388 * 0 otherwise. 392 * 0 otherwise.
389 */ 393 */
390static int 394int
391method_allowed(Authctxt *authctxt, const char *method) 395auth2_method_allowed(Authctxt *authctxt, const char *method,
396 const char *submethod)
392{ 397{
393 u_int i; 398 u_int i;
394 399
@@ -399,7 +404,8 @@ method_allowed(Authctxt *authctxt, const char *method)
399 if (options.num_auth_methods == 0) 404 if (options.num_auth_methods == 0)
400 return 1; 405 return 1;
401 for (i = 0; i < authctxt->num_auth_methods; i++) { 406 for (i = 0; i < authctxt->num_auth_methods; i++) {
402 if (list_starts_with(authctxt->auth_methods[i], method)) 407 if (list_starts_with(authctxt->auth_methods[i], method,
408 submethod) != MATCH_NONE)
403 return 1; 409 return 1;
404 } 410 }
405 return 0; 411 return 0;
@@ -419,7 +425,8 @@ authmethods_get(Authctxt *authctxt)
419 if (authmethods[i]->enabled == NULL || 425 if (authmethods[i]->enabled == NULL ||
420 *(authmethods[i]->enabled) == 0) 426 *(authmethods[i]->enabled) == 0)
421 continue; 427 continue;
422 if (!method_allowed(authctxt, authmethods[i]->name)) 428 if (!auth2_method_allowed(authctxt, authmethods[i]->name,
429 NULL))
423 continue; 430 continue;
424 if (buffer_len(&b) > 0) 431 if (buffer_len(&b) > 0)
425 buffer_append(&b, ",", 1); 432 buffer_append(&b, ",", 1);
@@ -442,7 +449,8 @@ authmethod_lookup(Authctxt *authctxt, const char *name)
442 if (authmethods[i]->enabled != NULL && 449 if (authmethods[i]->enabled != NULL &&
443 *(authmethods[i]->enabled) != 0 && 450 *(authmethods[i]->enabled) != 0 &&
444 strcmp(name, authmethods[i]->name) == 0 && 451 strcmp(name, authmethods[i]->name) == 0 &&
445 method_allowed(authctxt, authmethods[i]->name)) 452 auth2_method_allowed(authctxt,
453 authmethods[i]->name, NULL))
446 return authmethods[i]; 454 return authmethods[i];
447 debug2("Unrecognized authentication method name: %s", 455 debug2("Unrecognized authentication method name: %s",
448 name ? name : "NULL"); 456 name ? name : "NULL");
@@ -457,7 +465,7 @@ authmethod_lookup(Authctxt *authctxt, const char *name)
457int 465int
458auth2_methods_valid(const char *_methods, int need_enable) 466auth2_methods_valid(const char *_methods, int need_enable)
459{ 467{
460 char *methods, *omethods, *method; 468 char *methods, *omethods, *method, *p;
461 u_int i, found; 469 u_int i, found;
462 int ret = -1; 470 int ret = -1;
463 471
@@ -468,6 +476,8 @@ auth2_methods_valid(const char *_methods, int need_enable)
468 omethods = methods = xstrdup(_methods); 476 omethods = methods = xstrdup(_methods);
469 while ((method = strsep(&methods, ",")) != NULL) { 477 while ((method = strsep(&methods, ",")) != NULL) {
470 for (found = i = 0; !found && authmethods[i] != NULL; i++) { 478 for (found = i = 0; !found && authmethods[i] != NULL; i++) {
479 if ((p = strchr(method, ':')) != NULL)
480 *p = '\0';
471 if (strcmp(method, authmethods[i]->name) != 0) 481 if (strcmp(method, authmethods[i]->name) != 0)
472 continue; 482 continue;
473 if (need_enable) { 483 if (need_enable) {
@@ -533,15 +543,30 @@ auth2_setup_methods_lists(Authctxt *authctxt)
533} 543}
534 544
535static int 545static int
536list_starts_with(const char *methods, const char *method) 546list_starts_with(const char *methods, const char *method,
547 const char *submethod)
537{ 548{
538 size_t l = strlen(method); 549 size_t l = strlen(method);
550 int match;
551 const char *p;
539 552
540 if (strncmp(methods, method, l) != 0) 553 if (strncmp(methods, method, l) != 0)
541 return 0; 554 return MATCH_NONE;
542 if (methods[l] != ',' && methods[l] != '\0') 555 p = methods + l;
543 return 0; 556 match = MATCH_METHOD;
544 return 1; 557 if (*p == ':') {
558 if (!submethod)
559 return MATCH_PARTIAL;
560 l = strlen(submethod);
561 p += 1;
562 if (strncmp(submethod, p, l))
563 return MATCH_NONE;
564 p += l;
565 match = MATCH_BOTH;
566 }
567 if (*p != ',' && *p != '\0')
568 return MATCH_NONE;
569 return match;
545} 570}
546 571
547/* 572/*
@@ -550,14 +575,21 @@ list_starts_with(const char *methods, const char *method)
550 * if it did. 575 * if it did.
551 */ 576 */
552static int 577static int
553remove_method(char **methods, const char *method) 578remove_method(char **methods, const char *method, const char *submethod)
554{ 579{
555 char *omethods = *methods; 580 char *omethods = *methods, *p;
556 size_t l = strlen(method); 581 size_t l = strlen(method);
582 int match;
557 583
558 if (!list_starts_with(omethods, method)) 584 match = list_starts_with(omethods, method, submethod);
585 if (match != MATCH_METHOD && match != MATCH_BOTH)
559 return 0; 586 return 0;
560 *methods = xstrdup(omethods + l + (omethods[l] == ',' ? 1 : 0)); 587 p = omethods + l;
588 if (submethod && match == MATCH_BOTH)
589 p += 1 + strlen(submethod); /* include colon */
590 if (*p == ',')
591 p++;
592 *methods = xstrdup(p);
561 free(omethods); 593 free(omethods);
562 return 1; 594 return 1;
563} 595}
@@ -569,13 +601,15 @@ remove_method(char **methods, const char *method)
569 * Returns 1 if the method completed any authentication list or 0 otherwise. 601 * Returns 1 if the method completed any authentication list or 0 otherwise.
570 */ 602 */
571int 603int
572auth2_update_methods_lists(Authctxt *authctxt, const char *method) 604auth2_update_methods_lists(Authctxt *authctxt, const char *method,
605 const char *submethod)
573{ 606{
574 u_int i, found = 0; 607 u_int i, found = 0;
575 608
576 debug3("%s: updating methods list after \"%s\"", __func__, method); 609 debug3("%s: updating methods list after \"%s\"", __func__, method);
577 for (i = 0; i < authctxt->num_auth_methods; i++) { 610 for (i = 0; i < authctxt->num_auth_methods; i++) {
578 if (!remove_method(&(authctxt->auth_methods[i]), method)) 611 if (!remove_method(&(authctxt->auth_methods[i]), method,
612 submethod))
579 continue; 613 continue;
580 found = 1; 614 found = 1;
581 if (*authctxt->auth_methods[i] == '\0') { 615 if (*authctxt->auth_methods[i] == '\0') {