make sshd_config AuthorizedPrincipalsCommand and AuthorizedKeysCommand
authordjm <djm@openbsd.org>
Thu, 27 Jul 2023 22:25:17 +0000 (22:25 +0000)
committerdjm <djm@openbsd.org>
Thu, 27 Jul 2023 22:25:17 +0000 (22:25 +0000)
accept the %D (routing domain) and a new %C (connection address/port
4-tuple) as expansion sequences; ok markus

usr.bin/ssh/auth2-pubkey.c
usr.bin/ssh/sshd_config.5

index a507dca..1e536b1 100644 (file)
@@ -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.
@@ -337,8 +337,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;
@@ -413,6 +413,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,
@@ -474,7 +476,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;
@@ -511,7 +513,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 ||
@@ -610,7 +612,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;
@@ -672,6 +674,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,
@@ -746,11 +750,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;
@@ -761,6 +763,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;
@@ -778,18 +788,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;
index f7cc6f1..901d7db 100644 (file)
@@ -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
@@ -1998,6 +1998,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
@@ -2025,13 +2029,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.