diff options
author | joe <joe@jerkface.net> | 2016-04-22 01:00:23 -0400 |
---|---|---|
committer | Andrew Cady <d@jerkface.net> | 2019-06-06 11:51:49 -0400 |
commit | 25fc10d774e95dff10918b889e61f171d6081d95 (patch) | |
tree | 66abd6c6d1362f26dce7fb500d824b80f4ae49dc | |
parent | ba627ba172d6649919baedff5ba2789610da382a (diff) |
Added wildcard authorization for authorized_keys.
-rw-r--r-- | auth-options.c | 3 | ||||
-rw-r--r-- | auth-options.h | 4 | ||||
-rw-r--r-- | auth2-pubkey.c | 34 | ||||
-rw-r--r-- | session.c | 7 |
4 files changed, 47 insertions, 1 deletions
diff --git a/auth-options.c b/auth-options.c index b05d6d6f3..d4569b091 100644 --- a/auth-options.c +++ b/auth-options.c | |||
@@ -39,6 +39,9 @@ | |||
39 | #include "ssh2.h" | 39 | #include "ssh2.h" |
40 | #include "auth-options.h" | 40 | #include "auth-options.h" |
41 | 41 | ||
42 | char *wildcard_match = NULL; | ||
43 | char *wildcard_fingerprint = NULL; | ||
44 | |||
42 | /* | 45 | /* |
43 | * Match flag 'opt' in *optsp, and if allow_negate is set then also match | 46 | * Match flag 'opt' in *optsp, and if allow_negate is set then also match |
44 | * 'no-opt'. Returns -1 if option not matched, 1 if option matches or 0 | 47 | * 'no-opt'. Returns -1 if option not matched, 1 if option matches or 0 |
diff --git a/auth-options.h b/auth-options.h index 0462983b5..a6efa8ee3 100644 --- a/auth-options.h +++ b/auth-options.h | |||
@@ -67,6 +67,10 @@ struct sshauthopt { | |||
67 | char *required_from_host_keys; | 67 | char *required_from_host_keys; |
68 | }; | 68 | }; |
69 | 69 | ||
70 | |||
71 | extern char *wildcard_match; | ||
72 | extern char *wildcard_fingerprint; | ||
73 | |||
70 | struct sshauthopt *sshauthopt_new(void); | 74 | struct sshauthopt *sshauthopt_new(void); |
71 | struct sshauthopt *sshauthopt_new_with_keys_defaults(void); | 75 | struct sshauthopt *sshauthopt_new_with_keys_defaults(void); |
72 | void sshauthopt_free(struct sshauthopt *opts); | 76 | void sshauthopt_free(struct sshauthopt *opts); |
diff --git a/auth2-pubkey.c b/auth2-pubkey.c index 2fb5950ea..bf075c47d 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c | |||
@@ -67,6 +67,7 @@ | |||
67 | #include "ssherr.h" | 67 | #include "ssherr.h" |
68 | #include "channels.h" /* XXX for session.h */ | 68 | #include "channels.h" /* XXX for session.h */ |
69 | #include "session.h" /* XXX for child_set_env(); refactor? */ | 69 | #include "session.h" /* XXX for child_set_env(); refactor? */ |
70 | #include "digest.h" | ||
70 | 71 | ||
71 | /* import */ | 72 | /* import */ |
72 | extern ServerOptions options; | 73 | extern ServerOptions options; |
@@ -580,6 +581,8 @@ check_authkey_line(struct ssh *ssh, struct passwd *pw, struct sshkey *key, | |||
580 | 581 | ||
581 | /* XXX djm: peek at key type in line and skip if unwanted */ | 582 | /* XXX djm: peek at key type in line and skip if unwanted */ |
582 | 583 | ||
584 | int wild = 0; | ||
585 | |||
583 | if (sshkey_read(found, &cp) != 0) { | 586 | if (sshkey_read(found, &cp) != 0) { |
584 | /* no key? check for options */ | 587 | /* no key? check for options */ |
585 | debug2("%s: check options: '%s'", loc, cp); | 588 | debug2("%s: check options: '%s'", loc, cp); |
@@ -589,7 +592,10 @@ check_authkey_line(struct ssh *ssh, struct passwd *pw, struct sshkey *key, | |||
589 | goto fail_reason; | 592 | goto fail_reason; |
590 | } | 593 | } |
591 | skip_space(&cp); | 594 | skip_space(&cp); |
592 | if (sshkey_read(found, &cp) != 0) { | 595 | if (*cp == '*' && (cp[1] == ' ' || cp[1] == '\n' || cp[1] == '\t' || cp[1] == '\0')) { |
596 | cp += 2; | ||
597 | wild = 1; | ||
598 | } else if (sshkey_read(found, &cp) != 0) { | ||
593 | /* still no key? advance to next line*/ | 599 | /* still no key? advance to next line*/ |
594 | debug2("%s: advance: '%s'", loc, cp); | 600 | debug2("%s: advance: '%s'", loc, cp); |
595 | goto out; | 601 | goto out; |
@@ -601,6 +607,32 @@ check_authkey_line(struct ssh *ssh, struct passwd *pw, struct sshkey *key, | |||
601 | auth_debug_add("%s: bad key options: %s", loc, reason); | 607 | auth_debug_add("%s: bad key options: %s", loc, reason); |
602 | goto out; | 608 | goto out; |
603 | } | 609 | } |
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_match = keytext; | ||
624 | wildcard_fingerprint = sshkey_fingerprint(key, SSH_DIGEST_SHA256, SSH_FP_HEX); | ||
625 | |||
626 | verbose("Accepted wildcard authorization for %s key %s with forced_command=%s", | ||
627 | sshkey_type(key), | ||
628 | wildcard_fingerprint, | ||
629 | keyopts->force_command); | ||
630 | |||
631 | finalopts = keyopts; | ||
632 | keyopts = NULL; | ||
633 | goto success; | ||
634 | } | ||
635 | |||
604 | /* Ignore keys that don't match or incorrectly marked as CAs */ | 636 | /* Ignore keys that don't match or incorrectly marked as CAs */ |
605 | if (sshkey_is_cert(key)) { | 637 | if (sshkey_is_cert(key)) { |
606 | /* Certificate; check signature key against CA */ | 638 | /* Certificate; check signature key against CA */ |
@@ -1094,6 +1094,13 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell) | |||
1094 | child_set_env(&env, &envsize, "TERM", s->term); | 1094 | child_set_env(&env, &envsize, "TERM", s->term); |
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_match) { | ||
1098 | child_set_env(&env, &envsize, "SSH_REMOTE_KEY", | ||
1099 | wildcard_match); | ||
1100 | child_set_env(&env, &envsize, "SSH_REMOTE_FINGERPRINT", | ||
1101 | wildcard_fingerprint); | ||
1102 | } | ||
1103 | |||
1097 | 1104 | ||
1098 | /* | 1105 | /* |
1099 | * Since we clear KRB5CCNAME at startup, if it's set now then it | 1106 | * Since we clear KRB5CCNAME at startup, if it's set now then it |