diff options
Diffstat (limited to 'auth2-pubkey.c')
-rw-r--r-- | auth2-pubkey.c | 95 |
1 files changed, 63 insertions, 32 deletions
diff --git a/auth2-pubkey.c b/auth2-pubkey.c index 73151b57c..1ea40f2da 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c | |||
@@ -579,6 +579,42 @@ match_principals_command(struct ssh *ssh, struct passwd *user_pw, | |||
579 | return found_principal; | 579 | return found_principal; |
580 | } | 580 | } |
581 | 581 | ||
582 | static int | ||
583 | check_authkey_line_for_wildcard(struct sshkey *key, char *cp, const char *loc, struct sshauthopt **authoptsp) | ||
584 | { | ||
585 | struct sshauthopt *keyopts = NULL; | ||
586 | const char *reason = NULL; | ||
587 | char *key_options = cp; | ||
588 | |||
589 | if (advance_past_options(&cp) != 0) return -1; | ||
590 | skip_space(&cp); | ||
591 | |||
592 | if (!(*cp == '*' && (cp[1] == ' ' || cp[1] == '\n' || cp[1] == '\t' || cp[1] == '\0'))) { | ||
593 | return -1; // This is not a wildcard auth line. | ||
594 | } | ||
595 | |||
596 | if ((keyopts = sshauthopt_parse(key_options, &reason)) == NULL) { | ||
597 | debug("%s: bad key options: %s", loc, reason); | ||
598 | auth_debug_add("%s: bad key options: %s", loc, reason); | ||
599 | return -1; | ||
600 | } | ||
601 | |||
602 | if (keyopts->force_command) { /* We have a valid wildcard entry! */ | ||
603 | |||
604 | *authoptsp = keyopts; | ||
605 | return 0; | ||
606 | |||
607 | } else { | ||
608 | |||
609 | sshauthopt_free(keyopts); | ||
610 | reason = "Wildcard login is not allowed without specifying a forced command"; | ||
611 | error("%s", reason); | ||
612 | auth_debug_add("%s", reason); | ||
613 | return -1; | ||
614 | |||
615 | } | ||
616 | } | ||
617 | |||
582 | /* | 618 | /* |
583 | * Check a single line of an authorized_keys-format file. Returns 0 if key | 619 | * Check a single line of an authorized_keys-format file. Returns 0 if key |
584 | * matches, -1 otherwise. Will return key/cert options via *authoptsp | 620 | * matches, -1 otherwise. Will return key/cert options via *authoptsp |
@@ -605,8 +641,6 @@ check_authkey_line(struct ssh *ssh, struct passwd *pw, struct sshkey *key, | |||
605 | 641 | ||
606 | /* XXX djm: peek at key type in line and skip if unwanted */ | 642 | /* XXX djm: peek at key type in line and skip if unwanted */ |
607 | 643 | ||
608 | int wild = 0; | ||
609 | |||
610 | if (sshkey_read(found, &cp) != 0) { | 644 | if (sshkey_read(found, &cp) != 0) { |
611 | /* no key? check for options */ | 645 | /* no key? check for options */ |
612 | debug2("%s: check options: '%s'", loc, cp); | 646 | debug2("%s: check options: '%s'", loc, cp); |
@@ -617,8 +651,8 @@ check_authkey_line(struct ssh *ssh, struct passwd *pw, struct sshkey *key, | |||
617 | } | 651 | } |
618 | skip_space(&cp); | 652 | skip_space(&cp); |
619 | if (*cp == '*' && (cp[1] == ' ' || cp[1] == '\n' || cp[1] == '\t' || cp[1] == '\0')) { | 653 | if (*cp == '*' && (cp[1] == ' ' || cp[1] == '\n' || cp[1] == '\t' || cp[1] == '\0')) { |
620 | cp += 2; | 654 | /* This is a wildcard entry. Ignore it silently. */ |
621 | wild = 1; | 655 | goto out; |
622 | } else if (sshkey_read(found, &cp) != 0) { | 656 | } else if (sshkey_read(found, &cp) != 0) { |
623 | /* still no key? advance to next line*/ | 657 | /* still no key? advance to next line*/ |
624 | debug2("%s: advance: '%s'", loc, cp); | 658 | debug2("%s: advance: '%s'", loc, cp); |
@@ -631,33 +665,6 @@ check_authkey_line(struct ssh *ssh, struct passwd *pw, struct sshkey *key, | |||
631 | auth_debug_add("%s: bad key options: %s", loc, reason); | 665 | auth_debug_add("%s: bad key options: %s", loc, reason); |
632 | goto out; | 666 | goto out; |
633 | } | 667 | } |
634 | |||
635 | if (wild) { | ||
636 | int r; | ||
637 | char *keytext = NULL; | ||
638 | if ((r = sshkey_to_base64(key, &keytext)) != 0) { | ||
639 | error("%s: sshkey_to_base64 failed: %s", __func__, ssh_err(r)); | ||
640 | goto out; | ||
641 | } | ||
642 | if (!keyopts->force_command) { | ||
643 | reason = "Wildcard login is not allowed without specifying a forced command"; | ||
644 | goto fail_reason; | ||
645 | } | ||
646 | |||
647 | wildcard_remote_key = keytext; | ||
648 | wildcard_remote_key_type = sshkey_type(key); | ||
649 | wildcard_remote_key_fingerprint = sshkey_fingerprint(key, SSH_DIGEST_SHA256, SSH_FP_HEX); | ||
650 | |||
651 | verbose("Accepted wildcard authorization for %s key %s with forced_command=%s", | ||
652 | sshkey_type(key), | ||
653 | wildcard_remote_key_fingerprint, | ||
654 | keyopts->force_command); | ||
655 | |||
656 | finalopts = keyopts; | ||
657 | keyopts = NULL; | ||
658 | goto success; | ||
659 | } | ||
660 | |||
661 | /* Ignore keys that don't match or incorrectly marked as CAs */ | 668 | /* Ignore keys that don't match or incorrectly marked as CAs */ |
662 | if (sshkey_is_cert(key)) { | 669 | if (sshkey_is_cert(key)) { |
663 | /* Certificate; check signature key against CA */ | 670 | /* Certificate; check signature key against CA */ |
@@ -763,6 +770,7 @@ check_authkeys_file(struct ssh *ssh, struct passwd *pw, FILE *f, | |||
763 | size_t linesize = 0; | 770 | size_t linesize = 0; |
764 | int found_key = 0; | 771 | int found_key = 0; |
765 | u_long linenum = 0; | 772 | u_long linenum = 0; |
773 | struct sshauthopt *wildcardoptsp = NULL; | ||
766 | 774 | ||
767 | if (authoptsp != NULL) | 775 | if (authoptsp != NULL) |
768 | *authoptsp = NULL; | 776 | *authoptsp = NULL; |
@@ -781,9 +789,32 @@ check_authkeys_file(struct ssh *ssh, struct passwd *pw, FILE *f, | |||
781 | snprintf(loc, sizeof(loc), "%.200s:%lu", file, linenum); | 789 | snprintf(loc, sizeof(loc), "%.200s:%lu", file, linenum); |
782 | if (check_authkey_line(ssh, pw, key, cp, loc, authoptsp) == 0) | 790 | if (check_authkey_line(ssh, pw, key, cp, loc, authoptsp) == 0) |
783 | found_key = 1; | 791 | found_key = 1; |
792 | else if (wildcardoptsp == NULL) { | ||
793 | check_authkey_line_for_wildcard(key, cp, loc, &wildcardoptsp); | ||
794 | } | ||
784 | } | 795 | } |
785 | free(line); | 796 | free(line); |
786 | return found_key; | 797 | if (found_key) { |
798 | return 1; | ||
799 | } else if (!wildcardoptsp) { | ||
800 | return 0; | ||
801 | } else { | ||
802 | |||
803 | if (1) { // This block is obsoleted by SSH_USER_AUTH | ||
804 | int r; | ||
805 | char *keytext = NULL; | ||
806 | if ((r = sshkey_to_base64(key, &keytext)) != 0) { | ||
807 | error("%s: sshkey_to_base64 failed: %s", __func__, ssh_err(r)); | ||
808 | return -1; | ||
809 | } | ||
810 | wildcard_remote_key = keytext; | ||
811 | wildcard_remote_key_type = sshkey_type(key); | ||
812 | wildcard_remote_key_fingerprint = sshkey_fingerprint(key, SSH_DIGEST_SHA256, SSH_FP_HEX); | ||
813 | } | ||
814 | |||
815 | *authoptsp = wildcardoptsp; | ||
816 | return 1; | ||
817 | } | ||
787 | } | 818 | } |
788 | 819 | ||
789 | /* Authenticate a certificate key against TrustedUserCAKeys */ | 820 | /* Authenticate a certificate key against TrustedUserCAKeys */ |