diff --git a/ssh-agent.c b/ssh-agent.c index 618bb198..8ea831f4 100644 diff -up openssh-9.3p1/ssh-agent.c.cve openssh-9.3p1/ssh-agent.c --- openssh-9.3p1/ssh-agent.c.cve 2023-07-21 15:38:13.237276580 +0200 +++ openssh-9.3p1/ssh-agent.c 2023-07-21 15:41:30.269943569 +0200 @@ -169,6 +169,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 @@ -1228,6 +1234,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, @@ -1368,7 +1380,7 @@ no_identities(SocketEntry *e) #ifdef ENABLE_PKCS11 static char * -sanitize_pkcs11_provider(const char *provider) +sanitize_pkcs11_provider(SocketEntry *e, const char *provider) { struct pkcs11_uri *uri = NULL; char *sane_uri, *module_path = NULL; /* default path */ @@ -1399,6 +1411,11 @@ sanitize_pkcs11_provider(const char *pro module_path = strdup(provider); /* simple path */ if (module_path != NULL) { /* do not validate default NULL path in URI */ + if (e->nsession_ids != 0 && !remote_add_provider) { + verbose("failed PKCS#11 add of \"%.100s\": remote addition of " + "providers is disabled", provider); + return NULL; + } if (realpath(module_path, canonical_provider) == NULL) { verbose("failed PKCS#11 provider \"%.100s\": realpath: %s", module_path, strerror(errno)); @@ -1455,7 +1472,7 @@ process_add_smartcard_key(SocketEntry *e goto send; } - sane_uri = sanitize_pkcs11_provider(provider); + sane_uri = sanitize_pkcs11_provider(e, provider); if (sane_uri == NULL) goto send; @@ -1516,7 +1533,7 @@ process_remove_smartcard_key(SocketEntry } free(pin); - sane_uri = sanitize_pkcs11_provider(provider); + sane_uri = sanitize_pkcs11_provider(e, provider); if (sane_uri == NULL) goto send; @@ -2108,7 +2125,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; diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c index 6be647ec..ebddf6c3 100644 --- a/ssh-pkcs11.c +++ b/ssh-pkcs11.c @@ -1537,10 +1537,8 @@ pkcs11_register_provider(char *provider_id, char *pin, error("dlopen %s failed: %s", provider_module, dlerror()); goto fail; } - if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL) { - error("dlsym(C_GetFunctionList) failed: %s", dlerror()); - goto fail; - } + if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL) + fatal("dlsym(C_GetFunctionList) failed: %s", dlerror()); p->module->handle = handle; /* setup the pkcs11 callbacks */ --- a/ssh-agent.1 2023-03-15 22:28:19.000000000 +0100 +++ b/ssh-agent.1 2023-07-19 21:39:17.981406432 +0200 @@ -107,9 +107,27 @@ .It Fl O Ar option Specify an option when starting .Nm . -Currently only one option is supported: +Currently two options are supported: +.Cm allow-remote-pkcs11 +and .Cm no-restrict-websafe . -This instructs +.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 .Nm to permit signatures using FIDO keys that might be web authentication requests.