Skip to content

Commit

Permalink
agent: Move Win32 OpenSSH static globals into agent struct
Browse files Browse the repository at this point in the history
  • Loading branch information
yodaldevoid committed Nov 13, 2020
1 parent c1dd457 commit a4febfb
Showing 1 changed file with 49 additions and 49 deletions.
98 changes: 49 additions & 49 deletions src/agent.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,12 @@ struct _LIBSSH2_AGENT
struct list_head head; /* list of public keys */

char *identity_agent_path; /* Path to a custom identity agent socket */

#if WIN32
OVERLAPPED overlapped;
HANDLE pipe;
BOOL pending_io;
#endif
};

#ifdef PF_UNIX
Expand Down Expand Up @@ -432,9 +438,6 @@ struct agent_ops agent_ops_pageant = {

#define WIN32_OPENSSH_AGENT_SOCK "\\\\.\\pipe\\openssh-ssh-agent"

static HANDLE win32_openssh_socket_handle = INVALID_HANDLE_VALUE;
static OVERLAPPED win32_openssh_socket_overlapped = { 0 };

static int
agent_connect_openssh(LIBSSH2_AGENT *agent)
{
Expand Down Expand Up @@ -492,9 +495,9 @@ agent_connect_openssh(LIBSSH2_AGENT *agent)
goto cleanup;
}

win32_openssh_socket_handle = pipe;
agent->pipe = pipe;
pipe = INVALID_HANDLE_VALUE;
win32_openssh_socket_overlapped.hEvent = event;
agent->overlapped.hEvent = event;
event = NULL;
agent->fd = 0; /* Mark as the connection has been established */

Expand All @@ -510,90 +513,83 @@ agent_connect_openssh(LIBSSH2_AGENT *agent)
static int
agent_transact_openssh(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
{
static BOOL pending_io = FALSE;
unsigned char buf[4];
BOOL ret;
DWORD err;

/* Send the length of the request */
if(transctx->state == agent_NB_state_request_created) {
if(!pending_io) {
if(!agent->pending_io) {
_libssh2_htonu32(buf, transctx->request_len);
ret = WriteFile(win32_openssh_socket_handle, buf, 4, NULL,
&win32_openssh_socket_overlapped);
ret = WriteFile(agent->pipe, buf, 4, NULL, &agent->overlapped);
}
else {
ret = GetOverlappedResult(win32_openssh_socket_handle,
&win32_openssh_socket_overlapped, NULL,
ret = GetOverlappedResult(agent->pipe, &agent->overlapped, NULL,
FALSE);
}
if(!ret) {
err = GetLastError();
if((!pending_io && ERROR_IO_PENDING == err)
|| (pending_io && ERROR_IO_INCOMPLETE == err)) {
pending_io = TRUE;
if((!agent->pending_io && ERROR_IO_PENDING == err)
|| (agent->pending_io && ERROR_IO_INCOMPLETE == err)) {
agent->pending_io = TRUE;
return LIBSSH2_ERROR_EAGAIN;
}

return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND,
"agent send failed");
}
pending_io = FALSE;
agent->pending_io = FALSE;

transctx->state = agent_NB_state_request_length_sent;
}

/* Send the request body */
if(transctx->state == agent_NB_state_request_length_sent) {
if(!pending_io) {
ret = WriteFile(win32_openssh_socket_handle, transctx->request,
transctx->request_len, NULL,
&win32_openssh_socket_overlapped);
if(!agent->pending_io) {
ret = WriteFile(agent->pipe, transctx->request,
transctx->request_len, NULL, &agent->overlapped);
}
else {
ret = GetOverlappedResult(win32_openssh_socket_handle,
&win32_openssh_socket_overlapped, NULL,
ret = GetOverlappedResult(agent->pipe, &agent->overlapped, NULL,
FALSE);
}
if(!ret) {
err = GetLastError();
if((!pending_io && ERROR_IO_PENDING == err)
|| (pending_io && ERROR_IO_INCOMPLETE == err)) {
pending_io = TRUE;
if((!agent->pending_io && ERROR_IO_PENDING == err)
|| (agent->pending_io && ERROR_IO_INCOMPLETE == err)) {
agent->pending_io = TRUE;
return LIBSSH2_ERROR_EAGAIN;
}

return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND,
"agent send failed");
}
pending_io = FALSE;
agent->pending_io = FALSE;

transctx->state = agent_NB_state_request_sent;
}

/* Receive the length of the body */
if(transctx->state == agent_NB_state_request_sent) {
if(!pending_io) {
ret = ReadFile(win32_openssh_socket_handle, buf, 4, NULL,
&win32_openssh_socket_overlapped);
if(!agent->pending_io) {
ret = ReadFile(agent->pipe, buf, 4, NULL, &agent->overlapped);
}
else {
ret = GetOverlappedResult(win32_openssh_socket_handle,
&win32_openssh_socket_overlapped, NULL,
ret = GetOverlappedResult(agent->pipe, &agent->overlapped, NULL,
FALSE);
}
if(!ret) {
err = GetLastError();
if((!pending_io && ERROR_IO_PENDING == err)
|| (pending_io && ERROR_IO_INCOMPLETE == err)) {
pending_io = TRUE;
if((!agent->pending_io && ERROR_IO_PENDING == err)
|| (agent->pending_io && ERROR_IO_INCOMPLETE == err)) {
agent->pending_io = TRUE;
return LIBSSH2_ERROR_EAGAIN;
}

return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_RECV,
"agent recv failed");
}
pending_io = FALSE;
agent->pending_io = FALSE;

transctx->response_len = _libssh2_ntohu32(buf);
transctx->response = LIBSSH2_ALLOC(agent->session,
Expand All @@ -606,28 +602,26 @@ agent_transact_openssh(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)

/* Receive the response body */
if(transctx->state == agent_NB_state_response_length_received) {
if(!pending_io) {
ret = ReadFile(win32_openssh_socket_handle, transctx->response,
transctx->response_len, NULL,
&win32_openssh_socket_overlapped);
if(!agent->pending_io) {
ret = ReadFile(agent->pipe, transctx->response,
transctx->response_len, NULL, &agent->overlapped);
}
else {
ret = GetOverlappedResult(win32_openssh_socket_handle,
&win32_openssh_socket_overlapped, NULL,
ret = GetOverlappedResult(agent->pipe, &agent->overlapped, NULL,
FALSE);
}
if(!ret) {
err = GetLastError();
if((!pending_io && ERROR_IO_PENDING == err)
|| (pending_io && ERROR_IO_INCOMPLETE == err)) {
pending_io = TRUE;
if((!agent->pending_io && ERROR_IO_PENDING == err)
|| (agent->pending_io && ERROR_IO_INCOMPLETE == err)) {
agent->pending_io = TRUE;
return LIBSSH2_ERROR_EAGAIN;
}

return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_RECV,
"agent recv failed");
}
pending_io = FALSE;
agent->pending_io = FALSE;

transctx->state = agent_NB_state_response_received;
}
Expand All @@ -638,20 +632,20 @@ agent_transact_openssh(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
static int
agent_disconnect_openssh(LIBSSH2_AGENT *agent)
{
if(!CancelIo(win32_openssh_socket_handle))
if(!CancelIo(agent->pipe))
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_DISCONNECT,
"failed to cancel pending IO of agent pipe");
if(!CloseHandle(win32_openssh_socket_overlapped.hEvent))
if(!CloseHandle(agent->overlapped.hEvent))
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_DISCONNECT,
"failed to close handle to async I/O event");
win32_openssh_socket_overlapped.hEvent = NULL;
agent->overlapped.hEvent = NULL;
/* let queued APCs (if any) drain */
SleepEx(0, TRUE);
if(!CloseHandle(win32_openssh_socket_handle))
if(!CloseHandle(agent->pipe))
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_DISCONNECT,
"failed to close handle to agent pipe");

win32_openssh_socket_handle = INVALID_HANDLE_VALUE;
agent->pipe = INVALID_HANDLE_VALUE;
agent->fd = LIBSSH2_INVALID_SOCKET;

return LIBSSH2_ERROR_NONE;
Expand Down Expand Up @@ -984,6 +978,12 @@ libssh2_agent_init(LIBSSH2_SESSION *session)
agent->identity_agent_path = NULL;
_libssh2_list_init(&agent->head);

#ifdef WIN32
agent->pipe = INVALID_HANDLE_VALUE;
memset(&agent->overlapped, 0, sizeof(OVERLAPPED));
agent->pending_io = FALSE;
#endif

return agent;
}

Expand Down

0 comments on commit a4febfb

Please sign in to comment.