diff options
author | Colin Watson <cjwatson@debian.org> | 2013-09-14 23:42:11 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2013-09-14 23:42:11 +0100 |
commit | 327155e6824b3ee13837bdde04e4eb47e147ff46 (patch) | |
tree | 8f8743122403c7a2e6ed919156711fb1520c657f /auth2.c | |
parent | 0334ce32304e9ba2a10ee5ca49ca6e8ff3ba6cf4 (diff) | |
parent | 74e339b8f8936bc0d985e053a076d0c9b5e9ea51 (diff) |
* New upstream release (http://www.openssh.com/txt/release-6.3).
- sftp(1): add support for resuming partial downloads using the "reget"
command and on the sftp commandline or on the "get" commandline using
the "-a" (append) option (closes: #158590).
- ssh(1): add an "IgnoreUnknown" configuration option to selectively
suppress errors arising from unknown configuration directives (closes:
#436052).
- sftp(1): update progressmeter when data is acknowledged, not when it's
sent (partially addresses #708372).
- ssh(1): do not fatally exit when attempting to cleanup multiplexing-
created channels that are incompletely opened (closes: #651357).
Diffstat (limited to 'auth2.c')
-rw-r--r-- | auth2.c | 93 |
1 files changed, 63 insertions, 30 deletions
@@ -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.129 2013/05/19 02:42:42 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -100,8 +100,12 @@ static void input_userauth_request(int, u_int32_t, void *); | |||
100 | /* helper */ | 100 | /* helper */ |
101 | static Authmethod *authmethod_lookup(Authctxt *, const char *); | 101 | static Authmethod *authmethod_lookup(Authctxt *, const char *); |
102 | static char *authmethods_get(Authctxt *authctxt); | 102 | static char *authmethods_get(Authctxt *authctxt); |
103 | static int method_allowed(Authctxt *, const char *); | 103 | |
104 | static int list_starts_with(const char *, const char *); | 104 | #define MATCH_NONE 0 /* method or submethod mismatch */ |
105 | #define MATCH_METHOD 1 /* method matches (no submethod specified) */ | ||
106 | #define MATCH_BOTH 2 /* method and submethod match */ | ||
107 | #define MATCH_PARTIAL 3 /* method matches, submethod can't be checked */ | ||
108 | static int list_starts_with(const char *, const char *, const char *); | ||
105 | 109 | ||
106 | char * | 110 | char * |
107 | auth2_read_banner(void) | 111 | auth2_read_banner(void) |
@@ -128,7 +132,7 @@ auth2_read_banner(void) | |||
128 | close(fd); | 132 | close(fd); |
129 | 133 | ||
130 | if (n != len) { | 134 | if (n != len) { |
131 | xfree(banner); | 135 | free(banner); |
132 | return (NULL); | 136 | return (NULL); |
133 | } | 137 | } |
134 | banner[n] = '\0'; | 138 | banner[n] = '\0'; |
@@ -164,8 +168,7 @@ userauth_banner(void) | |||
164 | userauth_send_banner(banner); | 168 | userauth_send_banner(banner); |
165 | 169 | ||
166 | done: | 170 | done: |
167 | if (banner) | 171 | free(banner); |
168 | xfree(banner); | ||
169 | } | 172 | } |
170 | 173 | ||
171 | /* | 174 | /* |
@@ -210,7 +213,7 @@ input_service_request(int type, u_int32_t seq, void *ctxt) | |||
210 | debug("bad service request %s", service); | 213 | debug("bad service request %s", service); |
211 | packet_disconnect("bad service request %s", service); | 214 | packet_disconnect("bad service request %s", service); |
212 | } | 215 | } |
213 | xfree(service); | 216 | free(service); |
214 | } | 217 | } |
215 | 218 | ||
216 | /*ARGSUSED*/ | 219 | /*ARGSUSED*/ |
@@ -296,9 +299,9 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) | |||
296 | } | 299 | } |
297 | userauth_finish(authctxt, authenticated, method, NULL); | 300 | userauth_finish(authctxt, authenticated, method, NULL); |
298 | 301 | ||
299 | xfree(service); | 302 | free(service); |
300 | xfree(user); | 303 | free(user); |
301 | xfree(method); | 304 | free(method); |
302 | } | 305 | } |
303 | 306 | ||
304 | void | 307 | void |
@@ -324,14 +327,14 @@ userauth_finish(Authctxt *authctxt, int authenticated, const char *method, | |||
324 | } | 327 | } |
325 | 328 | ||
326 | if (authenticated && options.num_auth_methods != 0) { | 329 | if (authenticated && options.num_auth_methods != 0) { |
327 | if (!auth2_update_methods_lists(authctxt, method)) { | 330 | if (!auth2_update_methods_lists(authctxt, method, submethod)) { |
328 | authenticated = 0; | 331 | authenticated = 0; |
329 | partial = 1; | 332 | partial = 1; |
330 | } | 333 | } |
331 | } | 334 | } |
332 | 335 | ||
333 | /* Log before sending the reply */ | 336 | /* Log before sending the reply */ |
334 | auth_log(authctxt, authenticated, partial, method, submethod, " ssh2"); | 337 | auth_log(authctxt, authenticated, partial, method, submethod); |
335 | 338 | ||
336 | if (authctxt->postponed) | 339 | if (authctxt->postponed) |
337 | return; | 340 | return; |
@@ -386,7 +389,7 @@ userauth_finish(Authctxt *authctxt, int authenticated, const char *method, | |||
386 | packet_put_char(partial); | 389 | packet_put_char(partial); |
387 | packet_send(); | 390 | packet_send(); |
388 | packet_write_wait(); | 391 | packet_write_wait(); |
389 | xfree(methods); | 392 | free(methods); |
390 | } | 393 | } |
391 | } | 394 | } |
392 | 395 | ||
@@ -395,8 +398,9 @@ userauth_finish(Authctxt *authctxt, int authenticated, const char *method, | |||
395 | * methods list. Returns 1 if allowed, or no methods lists configured. | 398 | * methods list. Returns 1 if allowed, or no methods lists configured. |
396 | * 0 otherwise. | 399 | * 0 otherwise. |
397 | */ | 400 | */ |
398 | static int | 401 | int |
399 | method_allowed(Authctxt *authctxt, const char *method) | 402 | auth2_method_allowed(Authctxt *authctxt, const char *method, |
403 | const char *submethod) | ||
400 | { | 404 | { |
401 | u_int i; | 405 | u_int i; |
402 | 406 | ||
@@ -407,7 +411,8 @@ method_allowed(Authctxt *authctxt, const char *method) | |||
407 | if (options.num_auth_methods == 0) | 411 | if (options.num_auth_methods == 0) |
408 | return 1; | 412 | return 1; |
409 | for (i = 0; i < authctxt->num_auth_methods; i++) { | 413 | for (i = 0; i < authctxt->num_auth_methods; i++) { |
410 | if (list_starts_with(authctxt->auth_methods[i], method)) | 414 | if (list_starts_with(authctxt->auth_methods[i], method, |
415 | submethod) != MATCH_NONE) | ||
411 | return 1; | 416 | return 1; |
412 | } | 417 | } |
413 | return 0; | 418 | return 0; |
@@ -427,7 +432,8 @@ authmethods_get(Authctxt *authctxt) | |||
427 | if (authmethods[i]->enabled == NULL || | 432 | if (authmethods[i]->enabled == NULL || |
428 | *(authmethods[i]->enabled) == 0) | 433 | *(authmethods[i]->enabled) == 0) |
429 | continue; | 434 | continue; |
430 | if (!method_allowed(authctxt, authmethods[i]->name)) | 435 | if (!auth2_method_allowed(authctxt, authmethods[i]->name, |
436 | NULL)) | ||
431 | continue; | 437 | continue; |
432 | if (buffer_len(&b) > 0) | 438 | if (buffer_len(&b) > 0) |
433 | buffer_append(&b, ",", 1); | 439 | buffer_append(&b, ",", 1); |
@@ -450,7 +456,8 @@ authmethod_lookup(Authctxt *authctxt, const char *name) | |||
450 | if (authmethods[i]->enabled != NULL && | 456 | if (authmethods[i]->enabled != NULL && |
451 | *(authmethods[i]->enabled) != 0 && | 457 | *(authmethods[i]->enabled) != 0 && |
452 | strcmp(name, authmethods[i]->name) == 0 && | 458 | strcmp(name, authmethods[i]->name) == 0 && |
453 | method_allowed(authctxt, authmethods[i]->name)) | 459 | auth2_method_allowed(authctxt, |
460 | authmethods[i]->name, NULL)) | ||
454 | return authmethods[i]; | 461 | return authmethods[i]; |
455 | debug2("Unrecognized authentication method name: %s", | 462 | debug2("Unrecognized authentication method name: %s", |
456 | name ? name : "NULL"); | 463 | name ? name : "NULL"); |
@@ -465,7 +472,7 @@ authmethod_lookup(Authctxt *authctxt, const char *name) | |||
465 | int | 472 | int |
466 | auth2_methods_valid(const char *_methods, int need_enable) | 473 | auth2_methods_valid(const char *_methods, int need_enable) |
467 | { | 474 | { |
468 | char *methods, *omethods, *method; | 475 | char *methods, *omethods, *method, *p; |
469 | u_int i, found; | 476 | u_int i, found; |
470 | int ret = -1; | 477 | int ret = -1; |
471 | 478 | ||
@@ -476,6 +483,8 @@ auth2_methods_valid(const char *_methods, int need_enable) | |||
476 | omethods = methods = xstrdup(_methods); | 483 | omethods = methods = xstrdup(_methods); |
477 | while ((method = strsep(&methods, ",")) != NULL) { | 484 | while ((method = strsep(&methods, ",")) != NULL) { |
478 | for (found = i = 0; !found && authmethods[i] != NULL; i++) { | 485 | for (found = i = 0; !found && authmethods[i] != NULL; i++) { |
486 | if ((p = strchr(method, ':')) != NULL) | ||
487 | *p = '\0'; | ||
479 | if (strcmp(method, authmethods[i]->name) != 0) | 488 | if (strcmp(method, authmethods[i]->name) != 0) |
480 | continue; | 489 | continue; |
481 | if (need_enable) { | 490 | if (need_enable) { |
@@ -541,15 +550,30 @@ auth2_setup_methods_lists(Authctxt *authctxt) | |||
541 | } | 550 | } |
542 | 551 | ||
543 | static int | 552 | static int |
544 | list_starts_with(const char *methods, const char *method) | 553 | list_starts_with(const char *methods, const char *method, |
554 | const char *submethod) | ||
545 | { | 555 | { |
546 | size_t l = strlen(method); | 556 | size_t l = strlen(method); |
557 | int match; | ||
558 | const char *p; | ||
547 | 559 | ||
548 | if (strncmp(methods, method, l) != 0) | 560 | if (strncmp(methods, method, l) != 0) |
549 | return 0; | 561 | return MATCH_NONE; |
550 | if (methods[l] != ',' && methods[l] != '\0') | 562 | p = methods + l; |
551 | return 0; | 563 | match = MATCH_METHOD; |
552 | return 1; | 564 | if (*p == ':') { |
565 | if (!submethod) | ||
566 | return MATCH_PARTIAL; | ||
567 | l = strlen(submethod); | ||
568 | p += 1; | ||
569 | if (strncmp(submethod, p, l)) | ||
570 | return MATCH_NONE; | ||
571 | p += l; | ||
572 | match = MATCH_BOTH; | ||
573 | } | ||
574 | if (*p != ',' && *p != '\0') | ||
575 | return MATCH_NONE; | ||
576 | return match; | ||
553 | } | 577 | } |
554 | 578 | ||
555 | /* | 579 | /* |
@@ -558,14 +582,21 @@ list_starts_with(const char *methods, const char *method) | |||
558 | * if it did. | 582 | * if it did. |
559 | */ | 583 | */ |
560 | static int | 584 | static int |
561 | remove_method(char **methods, const char *method) | 585 | remove_method(char **methods, const char *method, const char *submethod) |
562 | { | 586 | { |
563 | char *omethods = *methods; | 587 | char *omethods = *methods, *p; |
564 | size_t l = strlen(method); | 588 | size_t l = strlen(method); |
589 | int match; | ||
565 | 590 | ||
566 | if (!list_starts_with(omethods, method)) | 591 | match = list_starts_with(omethods, method, submethod); |
592 | if (match != MATCH_METHOD && match != MATCH_BOTH) | ||
567 | return 0; | 593 | return 0; |
568 | *methods = xstrdup(omethods + l + (omethods[l] == ',' ? 1 : 0)); | 594 | p = omethods + l; |
595 | if (submethod && match == MATCH_BOTH) | ||
596 | p += 1 + strlen(submethod); /* include colon */ | ||
597 | if (*p == ',') | ||
598 | p++; | ||
599 | *methods = xstrdup(p); | ||
569 | free(omethods); | 600 | free(omethods); |
570 | return 1; | 601 | return 1; |
571 | } | 602 | } |
@@ -577,13 +608,15 @@ remove_method(char **methods, const char *method) | |||
577 | * Returns 1 if the method completed any authentication list or 0 otherwise. | 608 | * Returns 1 if the method completed any authentication list or 0 otherwise. |
578 | */ | 609 | */ |
579 | int | 610 | int |
580 | auth2_update_methods_lists(Authctxt *authctxt, const char *method) | 611 | auth2_update_methods_lists(Authctxt *authctxt, const char *method, |
612 | const char *submethod) | ||
581 | { | 613 | { |
582 | u_int i, found = 0; | 614 | u_int i, found = 0; |
583 | 615 | ||
584 | debug3("%s: updating methods list after \"%s\"", __func__, method); | 616 | debug3("%s: updating methods list after \"%s\"", __func__, method); |
585 | for (i = 0; i < authctxt->num_auth_methods; i++) { | 617 | for (i = 0; i < authctxt->num_auth_methods; i++) { |
586 | if (!remove_method(&(authctxt->auth_methods[i]), method)) | 618 | if (!remove_method(&(authctxt->auth_methods[i]), method, |
619 | submethod)) | ||
587 | continue; | 620 | continue; |
588 | found = 1; | 621 | found = 1; |
589 | if (*authctxt->auth_methods[i] == '\0') { | 622 | if (*authctxt->auth_methods[i] == '\0') { |