From 25fc10d774e95dff10918b889e61f171d6081d95 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 b05d6d6f3..d4569b091 100644 --- a/auth-options.c +++ b/auth-options.c @@ -39,6 +39,9 @@ #include "ssh2.h" #include "auth-options.h" +char *wildcard_match = NULL; +char *wildcard_fingerprint = NULL; + /* * Match flag 'opt' in *optsp, and if allow_negate is set then also match * '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 { char *required_from_host_keys; }; + +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 2fb5950ea..bf075c47d 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c @@ -67,6 +67,7 @@ #include "ssherr.h" #include "channels.h" /* XXX for session.h */ #include "session.h" /* XXX for child_set_env(); refactor? */ +#include "digest.h" /* import */ extern ServerOptions options; @@ -580,6 +581,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); @@ -589,7 +592,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; @@ -601,6 +607,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 19f38637e..a5634ccc2 100644 --- a/session.c +++ b/session.c @@ -1094,6 +1094,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