From d1ffde6b55170cd4b9a72bfd9a3f17508e6cf714 Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Thu, 27 Jul 2023 22:25:17 +0000 Subject: upstream: make sshd_config AuthorizedPrincipalsCommand and AuthorizedKeysCommand accept the %D (routing domain) and a new %C (connection address/port 4-tuple) as expansion sequences; ok markus OpenBSD-Commit-ID: ee9a48bf1a74c4ace71b69de69cfdaa2a7388565 --- auth2-pubkey.c | 35 +++++++++++++++++++++++------------ sshd_config.5 | 12 ++++++++---- 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/auth2-pubkey.c b/auth2-pubkey.c index b4f1f638..3f49e1df 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-pubkey.c,v 1.118 2023/02/17 04:22:50 dtucker Exp $ */ +/* $OpenBSD: auth2-pubkey.c,v 1.119 2023/07/27 22:25:17 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. @@ -340,8 +340,8 @@ match_principals_file(struct passwd *pw, char *file, * returns 1 if the principal is allowed or 0 otherwise. */ static int -match_principals_command(struct passwd *user_pw, - const struct sshkey *key, struct sshauthopt **authoptsp) +match_principals_command(struct passwd *user_pw, const struct sshkey *key, + const char *conn_id, const char *rdomain, struct sshauthopt **authoptsp) { struct passwd *runas_pw = NULL; const struct sshkey_cert *cert = key->cert; @@ -416,6 +416,8 @@ match_principals_command(struct passwd *user_pw, (unsigned long long)user_pw->pw_uid); for (i = 1; i < ac; i++) { tmp = percent_expand(av[i], + "C", conn_id, + "D", rdomain, "U", uidstr, "u", user_pw->pw_name, "h", user_pw->pw_dir, @@ -477,7 +479,7 @@ match_principals_command(struct passwd *user_pw, static int user_cert_trusted_ca(struct passwd *pw, struct sshkey *key, const char *remote_ip, const char *remote_host, - struct sshauthopt **authoptsp) + const char *conn_id, const char *rdomain, struct sshauthopt **authoptsp) { char *ca_fp, *principals_file = NULL; const char *reason; @@ -514,7 +516,7 @@ user_cert_trusted_ca(struct passwd *pw, struct sshkey *key, } /* Try querying command if specified */ if (!found_principal && match_principals_command(pw, key, - &principals_opts)) + conn_id, rdomain, &principals_opts)) found_principal = 1; /* If principals file or command is specified, then require a match */ use_authorized_principals = principals_file != NULL || @@ -613,7 +615,7 @@ user_key_allowed2(struct passwd *pw, struct sshkey *key, static int user_key_command_allowed2(struct passwd *user_pw, struct sshkey *key, const char *remote_ip, const char *remote_host, - struct sshauthopt **authoptsp) + const char *conn_id, const char *rdomain, struct sshauthopt **authoptsp) { struct passwd *runas_pw = NULL; FILE *f = NULL; @@ -675,6 +677,8 @@ user_key_command_allowed2(struct passwd *user_pw, struct sshkey *key, (unsigned long long)user_pw->pw_uid); for (i = 1; i < ac; i++) { tmp = percent_expand(av[i], + "C", conn_id, + "D", rdomain, "U", uidstr, "u", user_pw->pw_name, "h", user_pw->pw_dir, @@ -749,11 +753,9 @@ user_key_allowed(struct ssh *ssh, struct passwd *pw, struct sshkey *key, int auth_attempt, struct sshauthopt **authoptsp) { u_int success = 0, i; - char *file; + char *file, *conn_id; struct sshauthopt *opts = NULL; - const char *remote_ip = ssh_remote_ipaddr(ssh); - const char *remote_host = auth_get_canonical_hostname(ssh, - options.use_dns); + const char *rdomain, *remote_ip, *remote_host; if (authoptsp != NULL) *authoptsp = NULL; @@ -764,6 +766,14 @@ user_key_allowed(struct ssh *ssh, struct passwd *pw, struct sshkey *key, auth_key_is_revoked(key->cert->signature_key)) return 0; + if ((rdomain = ssh_packet_rdomain_in(ssh)) == NULL) + rdomain = ""; + remote_ip = ssh_remote_ipaddr(ssh); + remote_host = auth_get_canonical_hostname(ssh, options.use_dns); + xasprintf(&conn_id, "%s %d %s %d", + ssh_local_ipaddr(ssh), ssh_local_port(ssh), + remote_ip, ssh_remote_port(ssh)); + for (i = 0; !success && i < options.num_authkeys_files; i++) { if (strcasecmp(options.authorized_keys_files[i], "none") == 0) continue; @@ -781,18 +791,19 @@ user_key_allowed(struct ssh *ssh, struct passwd *pw, struct sshkey *key, goto out; if ((success = user_cert_trusted_ca(pw, key, remote_ip, remote_host, - &opts)) != 0) + conn_id, rdomain, &opts)) != 0) goto out; sshauthopt_free(opts); opts = NULL; if ((success = user_key_command_allowed2(pw, key, remote_ip, - remote_host, &opts)) != 0) + remote_host, conn_id, rdomain, &opts)) != 0) goto out; sshauthopt_free(opts); opts = NULL; out: + free(conn_id); if (success && authoptsp != NULL) { *authoptsp = opts; opts = NULL; diff --git a/sshd_config.5 b/sshd_config.5 index 9a1578f7..b5b77245 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.348 2023/03/03 04:36:20 djm Exp $ -.Dd $Mdocdate: March 3 2023 $ +.\" $OpenBSD: sshd_config.5,v 1.349 2023/07/27 22:25:17 djm Exp $ +.Dd $Mdocdate: July 27 2023 $ .Dt SSHD_CONFIG 5 .Os .Sh NAME @@ -2021,6 +2021,10 @@ which are expanded at runtime: .It %% A literal .Sq % . +.It %C +Identifies the connection endpoints, containing +four space-separated values: client address, client port number, +server address, and server port number. .It \&%D The routing domain in which the incoming connection was received. .It %F @@ -2048,13 +2052,13 @@ The username. .El .Pp .Cm AuthorizedKeysCommand -accepts the tokens %%, %f, %h, %k, %t, %U, and %u. +accepts the tokens %%, %C, %D, %f, %h, %k, %t, %U, and %u. .Pp .Cm AuthorizedKeysFile accepts the tokens %%, %h, %U, and %u. .Pp .Cm AuthorizedPrincipalsCommand -accepts the tokens %%, %F, %f, %h, %i, %K, %k, %s, %T, %t, %U, and %u. +accepts the tokens %%, %C, %D, %F, %f, %h, %i, %K, %k, %s, %T, %t, %U, and %u. .Pp .Cm AuthorizedPrincipalsFile accepts the tokens %%, %h, %U, and %u. -- cgit v1.2.3