summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Cady <d@jerkface.net>2018-08-26 09:18:57 -0400
committerAndrew Cady <d@jerkface.net>2019-06-06 11:52:37 -0400
commit4dc8da7eea0ecc009239dff4ad8f79c9c148c142 (patch)
treef234fef0988f63a68fa320f8bce4d40cf2c4464f
parent4738aeb85fa56865244969dee521ef7f24d4f7c1 (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 d630d43ef..1f0436ebd 100644
--- a/auth2-pubkey.c
+++ b/auth2-pubkey.c
@@ -555,6 +555,42 @@ advance_past_options(char **cpp)
555 return (*cp == '\0' && quoted) ? -1 : 0; 555 return (*cp == '\0' && quoted) ? -1 : 0;
556} 556}
557 557
558static int
559check_authkey_line_for_wildcard(struct sshkey *key, char *cp, const char *loc, struct sshauthopt **authoptsp)
560{
561 struct sshauthopt *keyopts = NULL;
562 const char *reason = NULL;
563 char *key_options = cp;
564
565 if (advance_past_options(&cp) != 0) return -1;
566 skip_space(&cp);
567
568 if (!(*cp == '*' && (cp[1] == ' ' || cp[1] == '\n' || cp[1] == '\t' || cp[1] == '\0'))) {
569 return -1; // This is not a wildcard auth line.
570 }
571
572 if ((keyopts = sshauthopt_parse(key_options, &reason)) == NULL) {
573 debug("%s: bad key options: %s", loc, reason);
574 auth_debug_add("%s: bad key options: %s", loc, reason);
575 return -1;
576 }
577
578 if (keyopts->force_command) { /* We have a valid wildcard entry! */
579
580 *authoptsp = keyopts;
581 return 0;
582
583 } else {
584
585 sshauthopt_free(keyopts);
586 reason = "Wildcard login is not allowed without specifying a forced command";
587 error("%s", reason);
588 auth_debug_add("%s", reason);
589 return -1;
590
591 }
592}
593
558/* 594/*
559 * Check a single line of an authorized_keys-format file. Returns 0 if key 595 * Check a single line of an authorized_keys-format file. Returns 0 if key
560 * matches, -1 otherwise. Will return key/cert options via *authoptsp 596 * matches, -1 otherwise. Will return key/cert options via *authoptsp
@@ -581,8 +617,6 @@ check_authkey_line(struct ssh *ssh, struct passwd *pw, struct sshkey *key,
581 617
582 /* XXX djm: peek at key type in line and skip if unwanted */ 618 /* XXX djm: peek at key type in line and skip if unwanted */
583 619
584 int wild = 0;
585
586 if (sshkey_read(found, &cp) != 0) { 620 if (sshkey_read(found, &cp) != 0) {
587 /* no key? check for options */ 621 /* no key? check for options */
588 debug2("%s: check options: '%s'", loc, cp); 622 debug2("%s: check options: '%s'", loc, cp);
@@ -593,8 +627,8 @@ check_authkey_line(struct ssh *ssh, struct passwd *pw, struct sshkey *key,
593 } 627 }
594 skip_space(&cp); 628 skip_space(&cp);
595 if (*cp == '*' && (cp[1] == ' ' || cp[1] == '\n' || cp[1] == '\t' || cp[1] == '\0')) { 629 if (*cp == '*' && (cp[1] == ' ' || cp[1] == '\n' || cp[1] == '\t' || cp[1] == '\0')) {
596 cp += 2; 630 /* This is a wildcard entry. Ignore it silently. */
597 wild = 1; 631 goto out;
598 } else if (sshkey_read(found, &cp) != 0) { 632 } else if (sshkey_read(found, &cp) != 0) {
599 /* still no key? advance to next line*/ 633 /* still no key? advance to next line*/
600 debug2("%s: advance: '%s'", loc, cp); 634 debug2("%s: advance: '%s'", loc, cp);
@@ -607,33 +641,6 @@ check_authkey_line(struct ssh *ssh, struct passwd *pw, struct sshkey *key,
607 auth_debug_add("%s: bad key options: %s", loc, reason); 641 auth_debug_add("%s: bad key options: %s", loc, reason);
608 goto out; 642 goto out;
609 } 643 }
610
611 if (wild) {
612 int r;
613 char *keytext = NULL;
614 if ((r = sshkey_to_base64(key, &keytext)) != 0) {
615 error("%s: sshkey_to_base64 failed: %s", __func__, ssh_err(r));
616 goto out;
617 }
618 if (!keyopts->force_command) {
619 reason = "Wildcard login is not allowed without specifying a forced command";
620 goto fail_reason;
621 }
622
623 wildcard_remote_key = keytext;
624 wildcard_remote_key_type = sshkey_type(key);
625 wildcard_remote_key_fingerprint = sshkey_fingerprint(key, SSH_DIGEST_SHA256, SSH_FP_HEX);
626
627 verbose("Accepted wildcard authorization for %s key %s with forced_command=%s",
628 sshkey_type(key),
629 wildcard_remote_key_fingerprint,
630 keyopts->force_command);
631
632 finalopts = keyopts;
633 keyopts = NULL;
634 goto success;
635 }
636
637 /* Ignore keys that don't match or incorrectly marked as CAs */ 644 /* Ignore keys that don't match or incorrectly marked as CAs */
638 if (sshkey_is_cert(key)) { 645 if (sshkey_is_cert(key)) {
639 /* Certificate; check signature key against CA */ 646 /* Certificate; check signature key against CA */
@@ -739,6 +746,7 @@ check_authkeys_file(struct ssh *ssh, struct passwd *pw, FILE *f,
739 size_t linesize = 0; 746 size_t linesize = 0;
740 int found_key = 0; 747 int found_key = 0;
741 u_long linenum = 0; 748 u_long linenum = 0;
749 struct sshauthopt *wildcardoptsp = NULL;
742 750
743 if (authoptsp != NULL) 751 if (authoptsp != NULL)
744 *authoptsp = NULL; 752 *authoptsp = NULL;
@@ -757,9 +765,32 @@ check_authkeys_file(struct ssh *ssh, struct passwd *pw, FILE *f,
757 snprintf(loc, sizeof(loc), "%.200s:%lu", file, linenum); 765 snprintf(loc, sizeof(loc), "%.200s:%lu", file, linenum);
758 if (check_authkey_line(ssh, pw, key, cp, loc, authoptsp) == 0) 766 if (check_authkey_line(ssh, pw, key, cp, loc, authoptsp) == 0)
759 found_key = 1; 767 found_key = 1;
768 else if (wildcardoptsp == NULL) {
769 check_authkey_line_for_wildcard(key, cp, loc, &wildcardoptsp);
770 }
760 } 771 }
761 free(line); 772 free(line);
762 return found_key; 773 if (found_key) {
774 return 1;
775 } else if (!wildcardoptsp) {
776 return 0;
777 } else {
778
779 if (1) { // This block is obsoleted by SSH_USER_AUTH
780 int r;
781 char *keytext = NULL;
782 if ((r = sshkey_to_base64(key, &keytext)) != 0) {
783 error("%s: sshkey_to_base64 failed: %s", __func__, ssh_err(r));
784 return -1;
785 }
786 wildcard_remote_key = keytext;
787 wildcard_remote_key_type = sshkey_type(key);
788 wildcard_remote_key_fingerprint = sshkey_fingerprint(key, SSH_DIGEST_SHA256, SSH_FP_HEX);
789 }
790
791 *authoptsp = wildcardoptsp;
792 return 1;
793 }
763} 794}
764 795
765/* Authenticate a certificate key against TrustedUserCAKeys */ 796/* Authenticate a certificate key against TrustedUserCAKeys */
diff --git a/session.c b/session.c
index fca7e4095..694c41a4c 100644
--- a/session.c
+++ b/session.c
@@ -1095,8 +1095,8 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
1095 if (s->display) 1095 if (s->display)
1096 child_set_env(&env, &envsize, "DISPLAY", s->display); 1096 child_set_env(&env, &envsize, "DISPLAY", s->display);
1097 if (wildcard_remote_key) { 1097 if (wildcard_remote_key) {
1098 /* This is basically obsolete because of SSH_USER_AUTH */ 1098 /* This is basically obsolete because of SSH_USER_AUTH */
1099 /* I'm leaving it here only because I have code that uses these variables. */ 1099 /* I'm leaving it here only because I have code that uses these variables. */
1100 child_set_env(&env, &envsize, "SSH_REMOTE_KEY", 1100 child_set_env(&env, &envsize, "SSH_REMOTE_KEY",
1101 wildcard_remote_key); 1101 wildcard_remote_key);
1102 child_set_env(&env, &envsize, "SSH_REMOTE_KEY_TYPE", 1102 child_set_env(&env, &envsize, "SSH_REMOTE_KEY_TYPE",