diff --git a/include/libssh/libssh.h b/include/libssh/libssh.h index b37121cf..cee9d8c2 100644 --- a/include/libssh/libssh.h +++ b/include/libssh/libssh.h @@ -421,6 +421,7 @@ enum ssh_options_e { SSH_OPTIONS_CERTIFICATE, SSH_OPTIONS_PROXYJUMP, SSH_OPTIONS_PROXYJUMP_CB_LIST_APPEND, + SSH_OPTIONS_PKI_CONTEXT, }; enum { diff --git a/include/libssh/session.h b/include/libssh/session.h index 3bb8ff44..0512fe05 100644 --- a/include/libssh/session.h +++ b/include/libssh/session.h @@ -288,6 +288,10 @@ struct ssh_session_struct { /* counters */ ssh_counter socket_counter; ssh_counter raw_counter; + + /* PKI context structure containing various parameters to configure PKI + * operations */ + struct ssh_pki_ctx_struct *pki_context; }; /** @internal diff --git a/src/options.c b/src/options.c index 8059c438..d878423a 100644 --- a/src/options.c +++ b/src/options.c @@ -258,6 +258,15 @@ int ssh_options_copy(ssh_session src, ssh_session *dest) new->common.log_verbosity = src->common.log_verbosity; new->common.callbacks = src->common.callbacks; + SSH_PKI_CTX_FREE(new->pki_context); + if (src->pki_context != NULL) { + new->pki_context = ssh_pki_ctx_dup(src->pki_context); + if (new->pki_context == NULL) { + ssh_free(new); + return -1; + } + } + *dest = new; return 0; @@ -629,6 +638,15 @@ int ssh_options_set_algo(ssh_session session, * Set to "none" to disable connection sharing. * (const char *) * + * - SSH_OPTIONS_PKI_CONTEXT + * Attach a previously created generic PKI context to the + * session. This allows supplying per-session PKI + * configuration options for PKI operations. + * All fields from the user's context are copied to the session's + * own context. The user retains ownership of the original + * context and can free it after this call. + * (ssh_pki_ctx) + * * * @param value The value to set. This is a generic pointer and the * datatype which is used should be set according to the @@ -1358,6 +1376,20 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type, } } break; + case SSH_OPTIONS_PKI_CONTEXT: + if (value == NULL) { + ssh_set_error_invalid(session); + return -1; + } + + SSH_PKI_CTX_FREE(session->pki_context); + + session->pki_context = ssh_pki_ctx_dup((const ssh_pki_ctx)value); + if (session->pki_context == NULL) { + ssh_set_error_oom(session); + return -1; + } + break; default: ssh_set_error(session, SSH_REQUEST_DENIED, "Unknown ssh option %d", type); return -1; diff --git a/src/session.c b/src/session.c index 061cafa7..199fa603 100644 --- a/src/session.c +++ b/src/session.c @@ -108,6 +108,12 @@ ssh_session ssh_new(void) goto err; } + /* Initialise a default PKI context */ + session->pki_context = ssh_pki_ctx_new(); + if (session->pki_context == NULL) { + goto err; + } + /* OPTIONS */ session->opts.StrictHostKeyChecking = 1; session->opts.port = 22; @@ -266,6 +272,8 @@ void ssh_free(ssh_session session) ssh_agent_free(session->agent); + SSH_PKI_CTX_FREE(session->pki_context); + ssh_key_free(session->srv.rsa_key); session->srv.rsa_key = NULL; ssh_key_free(session->srv.ecdsa_key);