From ede8986e4a0e4f19dcc8b972987d29c398c414b9 Mon Sep 17 00:00:00 2001 From: joe Date: Fri, 22 Apr 2016 01:00:23 -0400 Subject: Added wildcard authorization for authorized_keys. --- auth-options.c | 3 +++ auth-options.h | 4 ++++ auth2-pubkey.c | 34 +++++++++++++++++++++++++++++++++- session.c | 7 +++++++ 4 files changed, 47 insertions(+), 1 deletion(-) diff --git a/auth-options.c b/auth-options.c index 98afdf5fe..4a4ba9016 100644 --- a/auth-options.c +++ b/auth-options.c @@ -40,6 +40,9 @@ #include "ssh2.h" #include "auth-options.h" +char *wildcard_match = NULL; +char *wildcard_fingerprint = NULL; + static int dup_strings(char ***dstp, size_t *ndstp, char **src, size_t nsrc) { diff --git a/auth-options.h b/auth-options.h index 118a32087..165180187 100644 --- a/auth-options.h +++ b/auth-options.h @@ -75,6 +75,10 @@ struct sshauthopt { int require_verify; }; + +extern char *wildcard_match; +extern char *wildcard_fingerprint; + struct sshauthopt *sshauthopt_new(void); struct sshauthopt *sshauthopt_new_with_keys_defaults(void); void sshauthopt_free(struct sshauthopt *opts); diff --git a/auth2-pubkey.c b/auth2-pubkey.c index c3ecd9afc..bba8dfefa 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c @@ -69,6 +69,7 @@ #include "channels.h" /* XXX for session.h */ #include "session.h" /* XXX for child_set_env(); refactor? */ #include "sk-api.h" +#include "digest.h" /* import */ extern ServerOptions options; @@ -604,6 +605,8 @@ check_authkey_line(struct ssh *ssh, struct passwd *pw, struct sshkey *key, /* XXX djm: peek at key type in line and skip if unwanted */ + int wild = 0; + if (sshkey_read(found, &cp) != 0) { /* no key? check for options */ debug2("%s: check options: '%s'", loc, cp); @@ -613,7 +616,10 @@ check_authkey_line(struct ssh *ssh, struct passwd *pw, struct sshkey *key, goto fail_reason; } skip_space(&cp); - if (sshkey_read(found, &cp) != 0) { + if (*cp == '*' && (cp[1] == ' ' || cp[1] == '\n' || cp[1] == '\t' || cp[1] == '\0')) { + cp += 2; + wild = 1; + } else if (sshkey_read(found, &cp) != 0) { /* still no key? advance to next line*/ debug2("%s: advance: '%s'", loc, cp); goto out; @@ -625,6 +631,32 @@ check_authkey_line(struct ssh *ssh, struct passwd *pw, struct sshkey *key, auth_debug_add("%s: bad key options: %s", loc, reason); goto out; } + + if (wild) { + int r; + char *keytext = NULL; + if ((r = sshkey_to_base64(key, &keytext)) != 0) { + error("%s: sshkey_to_base64 failed: %s", __func__, ssh_err(r)); + goto out; + } + if (!keyopts->force_command) { + reason = "Wildcard login is not allowed without specifying a forced command"; + goto fail_reason; + } + + wildcard_match = keytext; + wildcard_fingerprint = sshkey_fingerprint(key, SSH_DIGEST_SHA256, SSH_FP_HEX); + + verbose("Accepted wildcard authorization for %s key %s with forced_command=%s", + sshkey_type(key), + wildcard_fingerprint, + keyopts->force_command); + + finalopts = keyopts; + keyopts = NULL; + goto success; + } + /* Ignore keys that don't match or incorrectly marked as CAs */ if (sshkey_is_cert(key)) { /* Certificate; check signature key against CA */ diff --git a/session.c b/session.c index b1796a803..b36e8b1fb 100644 --- a/session.c +++ b/session.c @@ -1071,6 +1071,13 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell) child_set_env(&env, &envsize, "TERM", s->term); if (s->display) child_set_env(&env, &envsize, "DISPLAY", s->display); + if (wildcard_match) { + child_set_env(&env, &envsize, "SSH_REMOTE_KEY", + wildcard_match); + child_set_env(&env, &envsize, "SSH_REMOTE_FINGERPRINT", + wildcard_fingerprint); + } + /* * Since we clear KRB5CCNAME at startup, if it's set now then it -- cgit v1.2.3