summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Cady <d@jerkface.net>2018-08-26 09:18:57 -0400
committerAndrew Cady <d@jerkface.net>2020-10-27 17:45:23 -0400
commit6a53bc2f7b339aec4dbb0b7b79c15fe179c2215f (patch)
treef16916c1299494c1c49252848e0c9406d72fc4c2
parentef9269c4983dd3706c90157bdb39717d83e7d085 (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 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
582static int
583check_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 */
diff --git a/session.c b/session.c
index 4ae9cab66..fa6a01996 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",