diff options
author | joe <joe@jerkface.net> | 2016-04-22 01:00:23 -0400 |
---|---|---|
committer | Andrew Cady <d@jerkface.net> | 2020-08-16 14:42:26 -0400 |
commit | 31329e74d517caf07ce189df27441bc9659a7074 (patch) | |
tree | 5e1382979e3a7f9639919cf09c217878b2f733d4 | |
parent | e429009cde648a41479cd1b60ce972760a2bdabc (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 696ba6ac6..5614b8ef7 100644 --- a/auth-options.c +++ b/auth-options.c | |||
@@ -40,6 +40,9 @@ | |||
40 | #include "ssh2.h" | 40 | #include "ssh2.h" |
41 | #include "auth-options.h" | 41 | #include "auth-options.h" |
42 | 42 | ||
43 | char *wildcard_match = NULL; | ||
44 | char *wildcard_fingerprint = NULL; | ||
45 | |||
43 | static int | 46 | static int |
44 | dup_strings(char ***dstp, size_t *ndstp, char **src, size_t nsrc) | 47 | dup_strings(char ***dstp, size_t *ndstp, char **src, size_t nsrc) |
45 | { | 48 | { |
diff --git a/auth-options.h b/auth-options.h index d96ffedee..d79943876 100644 --- a/auth-options.h +++ b/auth-options.h | |||
@@ -73,6 +73,10 @@ struct sshauthopt { | |||
73 | int no_require_user_presence; | 73 | int no_require_user_presence; |
74 | }; | 74 | }; |
75 | 75 | ||
76 | |||
77 | extern char *wildcard_match; | ||
78 | extern char *wildcard_fingerprint; | ||
79 | |||
76 | struct sshauthopt *sshauthopt_new(void); | 80 | struct sshauthopt *sshauthopt_new(void); |
77 | struct sshauthopt *sshauthopt_new_with_keys_defaults(void); | 81 | struct sshauthopt *sshauthopt_new_with_keys_defaults(void); |
78 | void sshauthopt_free(struct sshauthopt *opts); | 82 | void sshauthopt_free(struct sshauthopt *opts); |
diff --git a/auth2-pubkey.c b/auth2-pubkey.c index 815ea0f25..f89716a21 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c | |||
@@ -69,6 +69,7 @@ | |||
69 | #include "channels.h" /* XXX for session.h */ | 69 | #include "channels.h" /* XXX for session.h */ |
70 | #include "session.h" /* XXX for child_set_env(); refactor? */ | 70 | #include "session.h" /* XXX for child_set_env(); refactor? */ |
71 | #include "sk-api.h" | 71 | #include "sk-api.h" |
72 | #include "digest.h" | ||
72 | 73 | ||
73 | /* import */ | 74 | /* import */ |
74 | extern ServerOptions options; | 75 | extern ServerOptions options; |
@@ -590,6 +591,8 @@ check_authkey_line(struct ssh *ssh, struct passwd *pw, struct sshkey *key, | |||
590 | 591 | ||
591 | /* XXX djm: peek at key type in line and skip if unwanted */ | 592 | /* XXX djm: peek at key type in line and skip if unwanted */ |
592 | 593 | ||
594 | int wild = 0; | ||
595 | |||
593 | if (sshkey_read(found, &cp) != 0) { | 596 | if (sshkey_read(found, &cp) != 0) { |
594 | /* no key? check for options */ | 597 | /* no key? check for options */ |
595 | debug2("%s: check options: '%s'", loc, cp); | 598 | debug2("%s: check options: '%s'", loc, cp); |
@@ -599,7 +602,10 @@ check_authkey_line(struct ssh *ssh, struct passwd *pw, struct sshkey *key, | |||
599 | goto fail_reason; | 602 | goto fail_reason; |
600 | } | 603 | } |
601 | skip_space(&cp); | 604 | skip_space(&cp); |
602 | if (sshkey_read(found, &cp) != 0) { | 605 | if (*cp == '*' && (cp[1] == ' ' || cp[1] == '\n' || cp[1] == '\t' || cp[1] == '\0')) { |
606 | cp += 2; | ||
607 | wild = 1; | ||
608 | } else if (sshkey_read(found, &cp) != 0) { | ||
603 | /* still no key? advance to next line*/ | 609 | /* still no key? advance to next line*/ |
604 | debug2("%s: advance: '%s'", loc, cp); | 610 | debug2("%s: advance: '%s'", loc, cp); |
605 | goto out; | 611 | goto out; |
@@ -611,6 +617,32 @@ check_authkey_line(struct ssh *ssh, struct passwd *pw, struct sshkey *key, | |||
611 | auth_debug_add("%s: bad key options: %s", loc, reason); | 617 | auth_debug_add("%s: bad key options: %s", loc, reason); |
612 | goto out; | 618 | goto out; |
613 | } | 619 | } |
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_match = keytext; | ||
634 | wildcard_fingerprint = sshkey_fingerprint(key, SSH_DIGEST_SHA256, SSH_FP_HEX); | ||
635 | |||
636 | verbose("Accepted wildcard authorization for %s key %s with forced_command=%s", | ||
637 | sshkey_type(key), | ||
638 | wildcard_fingerprint, | ||
639 | keyopts->force_command); | ||
640 | |||
641 | finalopts = keyopts; | ||
642 | keyopts = NULL; | ||
643 | goto success; | ||
644 | } | ||
645 | |||
614 | /* Ignore keys that don't match or incorrectly marked as CAs */ | 646 | /* Ignore keys that don't match or incorrectly marked as CAs */ |
615 | if (sshkey_is_cert(key)) { | 647 | if (sshkey_is_cert(key)) { |
616 | /* Certificate; check signature key against CA */ | 648 | /* Certificate; check signature key against CA */ |
@@ -1071,6 +1071,13 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell) | |||
1071 | child_set_env(&env, &envsize, "TERM", s->term); | 1071 | child_set_env(&env, &envsize, "TERM", s->term); |
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_match) { | ||
1075 | child_set_env(&env, &envsize, "SSH_REMOTE_KEY", | ||
1076 | wildcard_match); | ||
1077 | child_set_env(&env, &envsize, "SSH_REMOTE_FINGERPRINT", | ||
1078 | wildcard_fingerprint); | ||
1079 | } | ||
1080 | |||
1074 | 1081 | ||
1075 | /* | 1082 | /* |
1076 | * Since we clear KRB5CCNAME at startup, if it's set now then it | 1083 | * Since we clear KRB5CCNAME at startup, if it's set now then it |