From 1f2731f5d7a8f8a8385c6031667ed29072c0d92a Mon Sep 17 00:00:00 2001
From: "djm@openbsd.org" <djm@openbsd.org>
Date: Wed, 19 Jul 2023 13:56:33 +0000
Subject: [PATCH 4/4] upstream: Disallow remote addition of FIDO/PKCS11
 provider libraries to ssh-agent by default.

The old behaviour of allowing remote clients from loading providers
can be restored using `ssh-agent -O allow-remote-pkcs11`.

Detection of local/remote clients requires a ssh(1) that supports
the `session-bind@openssh.com` extension. Forwarding access to a
ssh-agent socket using non-OpenSSH tools may circumvent this control.

ok markus@

OpenBSD-Commit-ID: 4c2bdf79b214ae7e60cc8c39a45501344fa7bd7c

Upstream-Status: Backport [https://github.com/openssh/openssh-portable/commit/1f2731f5d7a8f8a8385c6031667ed29072c0d92a]

CVE: CVE-2023-38408

Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com>
---
 ssh-agent.1 | 21 +++++++++++++++++++++
 ssh-agent.c | 21 ++++++++++++++++++++-
 2 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/ssh-agent.1 b/ssh-agent.1
index ed8c870..15d0a47 100644
--- a/ssh-agent.1
+++ b/ssh-agent.1
@@ -102,6 +102,27 @@ The default is
 Kill the current agent (given by the
 .Ev SSH_AGENT_PID
 environment variable).
+Currently two options are supported:
+.Cm allow-remote-pkcs11
+and
+.Cm no-restrict-websafe .
+.Pp
+The
+.Cm allow-remote-pkcs11
+option allows clients of a forwarded
+.Nm
+to load PKCS#11 or FIDO provider libraries.
+By default only local clients may perform this operation.
+Note that signalling that a
+.Nm
+client remote is performed by
+.Xr ssh 1 ,
+and use of other tools to forward access to the agent socket may circumvent
+this restriction.
+.Pp
+The
+.Cm no-restrict-websafe ,
+instructs
 .It Fl P Ar allowed_providers
 Specify a pattern-list of acceptable paths for PKCS#11 provider and FIDO
 authenticator middleware shared libraries that may be used with the
diff --git a/ssh-agent.c b/ssh-agent.c
index 03ae2b0..19eeaae 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -171,6 +171,12 @@ char socket_dir[PATH_MAX];
 /* Pattern-list of allowed PKCS#11/Security key paths */
 static char *allowed_providers;

+/*
+ * Allows PKCS11 providers or SK keys that use non-internal providers to
+ * be added over a remote connection (identified by session-bind@openssh.com).
+ */
+static int remote_add_provider;
+
 /* locking */
 #define LOCK_SIZE	32
 #define LOCK_SALT_SIZE	16
@@ -1239,6 +1245,12 @@ process_add_identity(SocketEntry *e)
		if (strcasecmp(sk_provider, "internal") == 0) {
			debug_f("internal provider");
		} else {
+			if (e->nsession_ids != 0 && !remote_add_provider) {
+				verbose("failed add of SK provider \"%.100s\": "
+				    "remote addition of providers is disabled",
+				    sk_provider);
+				goto out;
+			}
			if (realpath(sk_provider, canonical_provider) == NULL) {
				verbose("failed provider \"%.100s\": "
				    "realpath: %s", sk_provider,
@@ -1402,6 +1414,11 @@ process_add_smartcard_key(SocketEntry *e)
		error_f("failed to parse constraints");
		goto send;
	}
+	if (e->nsession_ids != 0 && !remote_add_provider) {
+		verbose("failed PKCS#11 add of \"%.100s\": remote addition of "
+		    "providers is disabled", provider);
+		goto send;
+	}
	if (realpath(provider, canonical_provider) == NULL) {
		verbose("failed PKCS#11 add of \"%.100s\": realpath: %s",
		    provider, strerror(errno));
@@ -2061,7 +2078,9 @@ main(int ac, char **av)
			break;
		case 'O':
			if (strcmp(optarg, "no-restrict-websafe") == 0)
-				restrict_websafe  = 0;
+				restrict_websafe = 0;
+			else if (strcmp(optarg, "allow-remote-pkcs11") == 0)
+				remote_add_provider = 1;
			else
				fatal("Unknown -O option");
			break;
--
2.40.0
