summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Cady <d@jerkface.net>2018-08-26 09:18:57 -0400
committerAndrew Cady <d@jerkface.net>2020-08-16 14:44:23 -0400
commit075d1a82801ad898eeb02446d0b5399c622a329d (patch)
tree06af2f513642444737b28e297c3eb024c1efd0e5
parent0c69b8b9c83b9f6e6ff5114514a25e70a52b14ce (diff)
Restore wildcard semantics
We now ignore the wildcard if we have another matching key -- even if the wildcard entry comes first in authorized_keys. This is how it worked before the forward port.
-rw-r--r--auth2-pubkey.c95
-rw-r--r--session.c4
2 files changed, 65 insertions, 34 deletions
diff --git a/auth2-pubkey.c b/auth2-pubkey.c
index 92c37accf..0e39f6abd 100644
--- a/auth2-pubkey.c
+++ b/auth2-pubkey.c
@@ -565,6 +565,42 @@ match_principals_command(struct ssh *ssh, struct passwd *user_pw,
565 return found_principal; 565 return found_principal;
566} 566}
567 567
568static int
569check_authkey_line_for_wildcard(struct sshkey *key, char *cp, const char *loc, struct sshauthopt **authoptsp)
570{
571 struct sshauthopt *keyopts = NULL;
572 const char *reason = NULL;
573 char *key_options = cp;
574
575 if (advance_past_options(&cp) != 0) return -1;
576 skip_space(&cp);
577
578 if (!(*cp == '*' && (cp[1] == ' ' || cp[1] == '\n' || cp[1] == '\t' || cp[1] == '\0'))) {
579 return -1; // This is not a wildcard auth line.
580 }
581
582 if ((keyopts = sshauthopt_parse(key_options, &reason)) == NULL) {
583 debug("%s: bad key options: %s", loc, reason);
584 auth_debug_add("%s: bad key options: %s", loc, reason);
585 return -1;
586 }
587
588 if (keyopts->force_command) { /* We have a valid wildcard entry! */
589
590 *authoptsp = keyopts;
591 return 0;
592
593 } else {
594
595 sshauthopt_free(keyopts);
596 reason = "Wildcard login is not allowed without specifying a forced command";
597 error("%s", reason);
598 auth_debug_add("%s", reason);
599 return -1;
600
601 }
602}
603
568/* 604/*
569 * Check a single line of an authorized_keys-format file. Returns 0 if key 605 * Check a single line of an authorized_keys-format file. Returns 0 if key
570 * matches, -1 otherwise. Will return key/cert options via *authoptsp 606 * matches, -1 otherwise. Will return key/cert options via *authoptsp
@@ -591,8 +627,6 @@ check_authkey_line(struct ssh *ssh, struct passwd *pw, struct sshkey *key,
591 627
592 /* XXX djm: peek at key type in line and skip if unwanted */ 628 /* XXX djm: peek at key type in line and skip if unwanted */
593 629
594 int wild = 0;
595
596 if (sshkey_read(found, &cp) != 0) { 630 if (sshkey_read(found, &cp) != 0) {
597 /* no key? check for options */ 631 /* no key? check for options */
598 debug2("%s: check options: '%s'", loc, cp); 632 debug2("%s: check options: '%s'", loc, cp);
@@ -603,8 +637,8 @@ check_authkey_line(struct ssh *ssh, struct passwd *pw, struct sshkey *key,
603 } 637 }
604 skip_space(&cp); 638 skip_space(&cp);
605 if (*cp == '*' && (cp[1] == ' ' || cp[1] == '\n' || cp[1] == '\t' || cp[1] == '\0')) { 639 if (*cp == '*' && (cp[1] == ' ' || cp[1] == '\n' || cp[1] == '\t' || cp[1] == '\0')) {
606 cp += 2; 640 /* This is a wildcard entry. Ignore it silently. */
607 wild = 1; 641 goto out;
608 } else if (sshkey_read(found, &cp) != 0) { 642 } else if (sshkey_read(found, &cp) != 0) {
609 /* still no key? advance to next line*/ 643 /* still no key? advance to next line*/
610 debug2("%s: advance: '%s'", loc, cp); 644 debug2("%s: advance: '%s'", loc, cp);
@@ -617,33 +651,6 @@ check_authkey_line(struct ssh *ssh, struct passwd *pw, struct sshkey *key,
617 auth_debug_add("%s: bad key options: %s", loc, reason); 651 auth_debug_add("%s: bad key options: %s", loc, reason);
618 goto out; 652 goto out;
619 } 653 }
620
621 if (wild) {
622 int r;
623 char *keytext = NULL;
624 if ((r = sshkey_to_base64(key, &keytext)) != 0) {
625 error("%s: sshkey_to_base64 failed: %s", __func__, ssh_err(r));
626 goto out;
627 }
628 if (!keyopts->force_command) {
629 reason = "Wildcard login is not allowed without specifying a forced command";
630 goto fail_reason;
631 }
632
633 wildcard_remote_key = keytext;
634 wildcard_remote_key_type = sshkey_type(key);
635 wildcard_remote_key_fingerprint = sshkey_fingerprint(key, SSH_DIGEST_SHA256, SSH_FP_HEX);
636
637 verbose("Accepted wildcard authorization for %s key %s with forced_command=%s",
638 sshkey_type(key),
639 wildcard_remote_key_fingerprint,
640 keyopts->force_command);
641
642 finalopts = keyopts;
643 keyopts = NULL;
644 goto success;
645 }
646
647 /* Ignore keys that don't match or incorrectly marked as CAs */ 654 /* Ignore keys that don't match or incorrectly marked as CAs */
648 if (sshkey_is_cert(key)) { 655 if (sshkey_is_cert(key)) {
649 /* Certificate; check signature key against CA */ 656 /* Certificate; check signature key against CA */
@@ -749,6 +756,7 @@ check_authkeys_file(struct ssh *ssh, struct passwd *pw, FILE *f,
749 size_t linesize = 0; 756 size_t linesize = 0;
750 int found_key = 0; 757 int found_key = 0;
751 u_long linenum = 0; 758 u_long linenum = 0;
759 struct sshauthopt *wildcardoptsp = NULL;
752 760
753 if (authoptsp != NULL) 761 if (authoptsp != NULL)
754 *authoptsp = NULL; 762 *authoptsp = NULL;
@@ -767,9 +775,32 @@ check_authkeys_file(struct ssh *ssh, struct passwd *pw, FILE *f,
767 snprintf(loc, sizeof(loc), "%.200s:%lu", file, linenum); 775 snprintf(loc, sizeof(loc), "%.200s:%lu", file, linenum);
768 if (check_authkey_line(ssh, pw, key, cp, loc, authoptsp) == 0) 776 if (check_authkey_line(ssh, pw, key, cp, loc, authoptsp) == 0)
769 found_key = 1; 777 found_key = 1;
778 else if (wildcardoptsp == NULL) {
779 check_authkey_line_for_wildcard(key, cp, loc, &wildcardoptsp);
780 }
770 } 781 }
771 free(line); 782 free(line);
772 return found_key; 783 if (found_key) {
784 return 1;
785 } else if (!wildcardoptsp) {
786 return 0;
787 } else {
788
789 if (1) { // This block is obsoleted by SSH_USER_AUTH
790 int r;
791 char *keytext = NULL;
792 if ((r = sshkey_to_base64(key, &keytext)) != 0) {
793 error("%s: sshkey_to_base64 failed: %s", __func__, ssh_err(r));
794 return -1;
795 }
796 wildcard_remote_key = keytext;
797 wildcard_remote_key_type = sshkey_type(key);
798 wildcard_remote_key_fingerprint = sshkey_fingerprint(key, SSH_DIGEST_SHA256, SSH_FP_HEX);
799 }
800
801 *authoptsp = wildcardoptsp;
802 return 1;
803 }
773} 804}
774 805
775/* Authenticate a certificate key against TrustedUserCAKeys */ 806/* Authenticate a certificate key against TrustedUserCAKeys */
diff --git a/session.c b/session.c
index 18c9755f3..0b9eeed77 100644
--- a/session.c
+++ b/session.c
@@ -1072,8 +1072,8 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
1072 if (s->display) 1072 if (s->display)
1073 child_set_env(&env, &envsize, "DISPLAY", s->display); 1073 child_set_env(&env, &envsize, "DISPLAY", s->display);
1074 if (wildcard_remote_key) { 1074 if (wildcard_remote_key) {
1075 /* This is basically obsolete because of SSH_USER_AUTH */ 1075 /* This is basically obsolete because of SSH_USER_AUTH */
1076 /* I'm leaving it here only because I have code that uses these variables. */ 1076 /* I'm leaving it here only because I have code that uses these variables. */
1077 child_set_env(&env, &envsize, "SSH_REMOTE_KEY", 1077 child_set_env(&env, &envsize, "SSH_REMOTE_KEY",
1078 wildcard_remote_key); 1078 wildcard_remote_key);
1079 child_set_env(&env, &envsize, "SSH_REMOTE_KEY_TYPE", 1079 child_set_env(&env, &envsize, "SSH_REMOTE_KEY_TYPE",