1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-02-26 20:31:06 +01:00

Implement the procedure to handle requests from client.

Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
NIIBE Yutaka 2022-07-27 18:56:17 +09:00
parent f057a71e7f
commit 6f9bb301b7
3 changed files with 96 additions and 56 deletions

View File

@ -453,6 +453,7 @@ gpg_error_t ssh_search_control_file (ssh_control_file_t cf,
int *r_disabled, int *r_disabled,
int *r_ttl, int *r_confirm); int *r_ttl, int *r_confirm);
void start_command_handler_ssh_stream (ctrl_t ctrl, estream_t stream);
void start_command_handler_ssh (ctrl_t, gnupg_fd_t); void start_command_handler_ssh (ctrl_t, gnupg_fd_t);
/*-- findkey.c --*/ /*-- findkey.c --*/

View File

@ -3768,23 +3768,59 @@ get_client_info (gnupg_fd_t fd, struct peer_info_s *out)
} }
/* Start serving client on STREAM. */
void
start_command_handler_ssh_stream (ctrl_t ctrl, estream_t stream)
{
gpg_error_t err;
int ret;
err = agent_copy_startup_env (ctrl);
if (err)
goto out;
/* We have to disable the estream buffering, because the estream
core doesn't know about secure memory. */
ret = es_setvbuf (stream, NULL, _IONBF, 0);
if (ret)
{
log_error ("failed to disable buffering on socket stream: %s\n",
strerror (errno));
goto out;
}
/* Main processing loop. */
while ( !ssh_request_process (ctrl, stream) )
{
/* Check whether we have reached EOF before trying to read
another request. */
int c;
c = es_fgetc (stream);
if (c == EOF)
break;
es_ungetc (c, stream);
}
/* Reset the daemon in case it has been used. */
agent_reset_daemon (ctrl);
out:
es_fclose (stream);
}
/* Start serving client on SOCK_CLIENT. */ /* Start serving client on SOCK_CLIENT. */
void void
start_command_handler_ssh (ctrl_t ctrl, gnupg_fd_t sock_client) start_command_handler_ssh (ctrl_t ctrl, gnupg_fd_t sock_client)
{ {
estream_t stream_sock = NULL; estream_t stream_sock;
gpg_error_t err;
int ret;
struct peer_info_s peer_info; struct peer_info_s peer_info;
es_syshd_t syshd; es_syshd_t syshd;
syshd.type = ES_SYSHD_SOCK; syshd.type = ES_SYSHD_SOCK;
syshd.u.sock = sock_client; syshd.u.sock = sock_client;
err = agent_copy_startup_env (ctrl);
if (err)
goto out;
get_client_info (sock_client, &peer_info); get_client_info (sock_client, &peer_info);
ctrl->client_pid = peer_info.pid; ctrl->client_pid = peer_info.pid;
ctrl->client_uid = peer_info.uid; ctrl->client_uid = peer_info.uid;
@ -3793,42 +3829,12 @@ start_command_handler_ssh (ctrl_t ctrl, gnupg_fd_t sock_client)
stream_sock = es_sysopen (&syshd, "r+"); stream_sock = es_sysopen (&syshd, "r+");
if (!stream_sock) if (!stream_sock)
{ {
err = gpg_error_from_syserror ();
log_error (_("failed to create stream from socket: %s\n"), log_error (_("failed to create stream from socket: %s\n"),
gpg_strerror (err)); strerror (errno));
goto out; return;
}
/* We have to disable the estream buffering, because the estream
core doesn't know about secure memory. */
ret = es_setvbuf (stream_sock, NULL, _IONBF, 0);
if (ret)
{
err = gpg_error_from_syserror ();
log_error ("failed to disable buffering "
"on socket stream: %s\n", gpg_strerror (err));
goto out;
} }
/* Main processing loop. */ start_command_handler_ssh_stream (ctrl, stream_sock);
while ( !ssh_request_process (ctrl, stream_sock) )
{
/* Check whether we have reached EOF before trying to read
another request. */
int c;
c = es_fgetc (stream_sock);
if (c == EOF)
break;
es_ungetc (c, stream_sock);
}
/* Reset the daemon in case it has been used. */
agent_reset_daemon (ctrl);
out:
if (stream_sock)
es_fclose (stream_sock);
} }

View File

@ -2767,6 +2767,7 @@ putty_message_thread (void *arg)
#define AGENT_PIPE_NAME "\\\\.\\pipe\\openssh-ssh-agent" #define AGENT_PIPE_NAME "\\\\.\\pipe\\openssh-ssh-agent"
/* FIXME: Don't know exact semantics, but copied from Win32-Openssh */ /* FIXME: Don't know exact semantics, but copied from Win32-Openssh */
#define SDDL_STR "D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;0x12019b;;;AU)" #define SDDL_STR "D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;0x12019b;;;AU)"
#define BUFSIZE 5 * 1024
/* The thread handling Win32-OpenSSH requests through NamedPipe. */ /* The thread handling Win32-OpenSSH requests through NamedPipe. */
static void * static void *
@ -2774,7 +2775,6 @@ win32_openssh_thread (void *arg)
{ {
HANDLE pipe; HANDLE pipe;
SECURITY_ATTRIBUTES sa; SECURITY_ATTRIBUTES sa;
const char *;
(void)arg; (void)arg;
@ -2783,10 +2783,10 @@ win32_openssh_thread (void *arg)
memset(&sa, 0, sizeof (SECURITY_ATTRIBUTES)); memset(&sa, 0, sizeof (SECURITY_ATTRIBUTES));
sa.nLength = sizeof (sa); sa.nLength = sizeof (sa);
if (!ConvertStringSecurityDescriptorToSecurityDescriptorA (SDDL_STR, SDDL_REVISION_1, if (!ConvertStringSecurityDescriptorToSecurityDescriptorA
&sa.lpSecurityDescriptor, &sa.nLength)) (SDDL_STR, SDDL_REVISION_1, &sa.lpSecurityDescriptor, &sa.nLength))
{ {
log_error ("cannot convert sddl: %d\n", GetLastError ()); log_error ("cannot convert sddl: %ld\n", GetLastError ());
return NULL; return NULL;
} }
@ -2794,12 +2794,12 @@ win32_openssh_thread (void *arg)
while (1) while (1)
{ {
/* The message loop runs as thread independent from our nPth system. ctrl_t ctrl = NULL;
This also means that we need to make sure that we switch back to estream_t ssh_stream = NULL;
our system before calling any no-windows function. */ es_syshd_t syshd;
npth_unprotect ();
pipe = CreateNamedPipeW (AGENT_PIPE_NAME, npth_unprotect ();
pipe = CreateNamedPipeA (AGENT_PIPE_NAME,
PIPE_ACCESS_DUPLEX, // | FILE_FLAG_OVERLAPPED PIPE_ACCESS_DUPLEX, // | FILE_FLAG_OVERLAPPED
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES, PIPE_UNLIMITED_INSTANCES,
@ -2807,26 +2807,59 @@ win32_openssh_thread (void *arg)
if (pipe == INVALID_HANDLE_VALUE) if (pipe == INVALID_HANDLE_VALUE)
{ {
log_error ("cannot create pipe: %d\n", GetLastError()); npth_protect ();
log_error ("cannot create pipe: %ld\n", GetLastError());
break; break;
} }
if (ConnectNamedPipe (pipe, NULL) != FALSE) if (ConnectNamedPipe (pipe, NULL) != FALSE)
{ {
CloseHandle (pipe);
npth_protect (); npth_protect ();
CloseHandle (pipe);
log_error ("ConnectNamedPipe returned TRUE unexpectedly\n"); log_error ("ConnectNamedPipe returned TRUE unexpectedly\n");
return NULL; break;
} }
/* FIXME: Here, handle the requests from ssh client */ npth_protect ();
ctrl = xtrycalloc (1, sizeof *ctrl);
if (!ctrl)
{
CloseHandle (pipe);
log_error ("error allocating connection control data: %s\n",
strerror (errno));
break;
}
ctrl->session_env = session_env_new ();
if (!ctrl->session_env)
{
log_error ("error allocating session environment block: %s\n",
strerror (errno));
agent_deinit_default_ctrl (ctrl);
xfree (ctrl);
CloseHandle (pipe);
break;
}
agent_init_default_ctrl (ctrl);
syshd.type = ES_SYSHD_HANDLE;
syshd.u.handle = pipe;
ssh_stream = es_sysopen (&syshd, "r+");
if (!ssh_stream)
{
agent_deinit_default_ctrl (ctrl);
xfree (ctrl);
CloseHandle (pipe);
break;
}
start_command_handler_ssh_stream (ctrl, ssh_stream);
agent_deinit_default_ctrl (ctrl);
xfree (ctrl);
CloseHandle (pipe); CloseHandle (pipe);
} }
/* Back to nPth. */
npth_protect ();
if (opt.verbose) if (opt.verbose)
log_info ("Win32-OpenSSH thread stopped\n"); log_info ("Win32-OpenSSH thread stopped\n");
return NULL; return NULL;