upstream commit

add %-escapes to AuthorizedPrincipalsCommand to match those
supported for AuthorizedKeysCommand (key, key type, fingerprint, etc) and a
few more to provide access to the certificate's CA key; 'looks ok' dtucker@

Upstream-ID: 6b00fd446dbebe67f4e4e146d2e492d650ae04eb
This commit is contained in:
djm@openbsd.org 2016-09-14 05:42:25 +00:00 committed by Damien Miller
parent 2b939c272a
commit e7907c1cb9
2 changed files with 49 additions and 10 deletions

View File

@ -1,4 +1,4 @@
/* $OpenBSD: auth2-pubkey.c,v 1.55 2016/01/27 00:53:12 djm Exp $ */ /* $OpenBSD: auth2-pubkey.c,v 1.56 2016/09/14 05:42:25 djm Exp $ */
/* /*
* Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2000 Markus Friedl. All rights reserved.
* *
@ -560,7 +560,7 @@ match_principals_option(const char *principal_list, struct sshkey_cert *cert)
static int static int
process_principals(FILE *f, char *file, struct passwd *pw, process_principals(FILE *f, char *file, struct passwd *pw,
struct sshkey_cert *cert) const struct sshkey_cert *cert)
{ {
char line[SSH_MAX_PUBKEY_BYTES], *cp, *ep, *line_opts; char line[SSH_MAX_PUBKEY_BYTES], *cp, *ep, *line_opts;
u_long linenum = 0; u_long linenum = 0;
@ -629,14 +629,16 @@ match_principals_file(char *file, struct passwd *pw, struct sshkey_cert *cert)
* returns 1 if the principal is allowed or 0 otherwise. * returns 1 if the principal is allowed or 0 otherwise.
*/ */
static int static int
match_principals_command(struct passwd *user_pw, struct sshkey_cert *cert) match_principals_command(struct passwd *user_pw, const struct sshkey *key)
{ {
const struct sshkey_cert *cert = key->cert;
FILE *f = NULL; FILE *f = NULL;
int ok, found_principal = 0; int r, ok, found_principal = 0;
struct passwd *pw; struct passwd *pw;
int i, ac = 0, uid_swapped = 0; int i, ac = 0, uid_swapped = 0;
pid_t pid; pid_t pid;
char *tmp, *username = NULL, *command = NULL, **av = NULL; char *tmp, *username = NULL, *command = NULL, **av = NULL;
char *ca_fp = NULL, *key_fp = NULL, *catext = NULL, *keytext = NULL;
void (*osigchld)(int); void (*osigchld)(int);
if (options.authorized_principals_command == NULL) if (options.authorized_principals_command == NULL)
@ -674,10 +676,34 @@ match_principals_command(struct passwd *user_pw, struct sshkey_cert *cert)
command); command);
goto out; goto out;
} }
if ((ca_fp = sshkey_fingerprint(cert->signature_key,
options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) {
error("%s: sshkey_fingerprint failed", __func__);
goto out;
}
if ((key_fp = sshkey_fingerprint(cert->signature_key,
options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) {
error("%s: sshkey_fingerprint failed", __func__);
goto out;
}
if ((r = sshkey_to_base64(cert->signature_key, &catext)) != 0) {
error("%s: sshkey_to_base64 failed: %s", __func__, ssh_err(r));
goto out;
}
if ((r = sshkey_to_base64(key, &keytext)) != 0) {
error("%s: sshkey_to_base64 failed: %s", __func__, ssh_err(r));
goto out;
}
for (i = 1; i < ac; i++) { for (i = 1; i < ac; i++) {
tmp = percent_expand(av[i], tmp = percent_expand(av[i],
"u", user_pw->pw_name, "u", user_pw->pw_name,
"h", user_pw->pw_dir, "h", user_pw->pw_dir,
"t", sshkey_ssh_name(key),
"T", sshkey_ssh_name(cert->signature_key),
"f", key_fp,
"F", ca_fp,
"k", keytext,
"K", catext,
(char *)NULL); (char *)NULL);
if (tmp == NULL) if (tmp == NULL)
fatal("%s: percent_expand failed", __func__); fatal("%s: percent_expand failed", __func__);
@ -712,6 +738,10 @@ match_principals_command(struct passwd *user_pw, struct sshkey_cert *cert)
restore_uid(); restore_uid();
free(command); free(command);
free(username); free(username);
free(ca_fp);
free(key_fp);
free(catext);
free(keytext);
return found_principal; return found_principal;
} }
/* /*
@ -863,7 +893,7 @@ user_cert_trusted_ca(struct passwd *pw, Key *key)
found_principal = 1; found_principal = 1;
} }
/* Try querying command if specified */ /* Try querying command if specified */
if (!found_principal && match_principals_command(pw, key->cert)) if (!found_principal && match_principals_command(pw, key))
found_principal = 1; found_principal = 1;
/* If principals file or command is specified, then require a match */ /* If principals file or command is specified, then require a match */
use_authorized_principals = principals_file != NULL || use_authorized_principals = principals_file != NULL ||

View File

@ -33,8 +33,8 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.\" $OpenBSD: sshd_config.5,v 1.231 2016/09/07 18:39:24 jmc Exp $ .\" $OpenBSD: sshd_config.5,v 1.232 2016/09/14 05:42:25 djm Exp $
.Dd $Mdocdate: September 7 2016 $ .Dd $Mdocdate: September 14 2016 $
.Dt SSHD_CONFIG 5 .Dt SSHD_CONFIG 5
.Os .Os
.Sh NAME .Sh NAME
@ -304,9 +304,18 @@ specified by an absolute path.
Arguments to Arguments to
.Cm AuthorizedPrincipalsCommand .Cm AuthorizedPrincipalsCommand
may be provided using the following tokens, which will be expanded may be provided using the following tokens, which will be expanded
at runtime: %% is replaced by a literal '%', %u is replaced by the at runtime:
username being authenticated and %h is replaced by the home directory %% is replaced by a literal '%',
of the user being authenticated. %u is replaced by the username being authenticated,
%h is replaced by the home directory of the user being authenticated,
%t is replaced with type of the certificate being offered,
%T with the type of the CA key,
%f is replaced with certificate fingerprint,
%F with the fingerprint of the CA key,
%k is replaced with the full base-64 encoded certificate and
%K is replaced with the base-64 encoded CA key.
If no arguments are specified then the username of the target user
will be supplied.
.Pp .Pp
The program should produce on standard output zero or The program should produce on standard output zero or
more lines of more lines of