mirror of
https://github.com/libssh2/libssh2.git
synced 2025-11-20 02:42:09 +03:00
Agent forwarding implementation (#752)
This PR contains a series of patches that date back many years and I believe were discussed on the mailing list, but never merged. We have been using these in our local copy of libssh2 without issue since 2015, if not earlier. I believe this is the full set of changes, as we tried to use comments to mark where our copy of libssh2 differs from the canonical version. This also contains changes I made earlier this year, but which were not discussed on the mailing list, to support certificates and FIDO2 keys with agent forwarding. Note that this is not a complete implementation of agent forwarding, as that is outside the scope of libssh2. Clients still need to provide their own implementation that parses ssh-agent methods after calling libssh2_channel_read() and calls the appropriate callback messages in libssh2. See the man page changes in this PR for more details. Integration-patches-by: Viktor Szakats * prefer size_t * prefer unsigned int over u_int in public function * add const * docs, indent, checksrc, debug call, compiler warning fixes
This commit is contained in:
60
src/agent.c
60
src/agent.c
@@ -383,6 +383,7 @@ agent_sign(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
|
||||
int rc;
|
||||
unsigned char *method_name = NULL;
|
||||
uint32_t sign_flags = 0;
|
||||
ssize_t plain_len;
|
||||
|
||||
/* Create a request to sign the data */
|
||||
if(transctx->state == agent_NB_state_init) {
|
||||
@@ -478,9 +479,13 @@ agent_sign(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
|
||||
memcpy(method_name, s, method_len);
|
||||
s += method_len;
|
||||
|
||||
plain_len = plain_method((char *)session->userauth_pblc_method,
|
||||
session->userauth_pblc_method_len);
|
||||
|
||||
/* check to see if we match requested */
|
||||
if((size_t)method_len != session->userauth_pblc_method_len ||
|
||||
memcmp(method_name, session->userauth_pblc_method, method_len)) {
|
||||
if(((size_t)method_len != session->userauth_pblc_method_len &&
|
||||
method_len != plain_len) ||
|
||||
memcmp(method_name, session->userauth_pblc_method, method_len)) {
|
||||
_libssh2_debug((session,
|
||||
LIBSSH2_TRACE_KEX,
|
||||
"Agent sign method %.*s",
|
||||
@@ -829,6 +834,57 @@ libssh2_agent_userauth(LIBSSH2_AGENT *agent,
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* libssh2_agent_sign
|
||||
*
|
||||
* Sign a payload using a system-installed ssh-agent.
|
||||
*
|
||||
* Returns 0 if succeeded, or a negative value for error.
|
||||
*/
|
||||
LIBSSH2_API int
|
||||
libssh2_agent_sign(LIBSSH2_AGENT *agent,
|
||||
struct libssh2_agent_publickey *identity,
|
||||
unsigned char **sig,
|
||||
size_t *s_len,
|
||||
const unsigned char *data,
|
||||
size_t d_len,
|
||||
const char *method,
|
||||
unsigned int method_len)
|
||||
{
|
||||
void *abstract = agent;
|
||||
int rc;
|
||||
uint32_t methodLen;
|
||||
|
||||
if(agent->session->userauth_pblc_state == libssh2_NB_state_idle) {
|
||||
memset(&agent->transctx, 0, sizeof(agent->transctx));
|
||||
agent->identity = identity->node;
|
||||
}
|
||||
|
||||
if(identity->blob_len < sizeof(uint32_t)) {
|
||||
return LIBSSH2_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
methodLen = _libssh2_ntohu32(identity->blob);
|
||||
|
||||
if(identity->blob_len < sizeof(uint32_t) + methodLen) {
|
||||
return LIBSSH2_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
agent->session->userauth_pblc_method_len = method_len;
|
||||
agent->session->userauth_pblc_method = LIBSSH2_ALLOC(agent->session,
|
||||
method_len);
|
||||
|
||||
memcpy(agent->session->userauth_pblc_method, method, methodLen);
|
||||
|
||||
rc = agent_sign(agent->session, sig, s_len, data, d_len, &abstract);
|
||||
|
||||
LIBSSH2_FREE(agent->session, agent->session->userauth_pblc_method);
|
||||
agent->session->userauth_pblc_method = NULL;
|
||||
agent->session->userauth_pblc_method_len = 0;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* libssh2_agent_disconnect
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user