1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-10 01:48:00 +00:00
putty-source/windows/named-pipe-client.c
Simon Tatham f39c51f9a7 Rename most of the platform source files.
This gets rid of all those annoying 'win', 'ux' and 'gtk' prefixes
which made filenames annoying to type and to tab-complete. Also, as
with my other recent renaming sprees, I've taken the opportunity to
expand and clarify some of the names so that they're not such cryptic
abbreviations.
2021-04-26 18:00:01 +01:00

95 lines
2.8 KiB
C

/*
* Windows support module which deals with being a named-pipe client.
*/
#include <stdio.h>
#include <assert.h>
#include "tree234.h"
#include "putty.h"
#include "network.h"
#include "proxy.h"
#include "ssh.h"
#include "security-api.h"
HANDLE connect_to_named_pipe(const char *pipename, char **err)
{
HANDLE pipehandle;
PSID usersid, pipeowner;
PSECURITY_DESCRIPTOR psd;
assert(strncmp(pipename, "\\\\.\\pipe\\", 9) == 0);
assert(strchr(pipename + 9, '\\') == NULL);
while (1) {
pipehandle = CreateFile(pipename, GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING,
FILE_FLAG_OVERLAPPED, NULL);
if (pipehandle != INVALID_HANDLE_VALUE)
break;
if (GetLastError() != ERROR_PIPE_BUSY) {
*err = dupprintf(
"Unable to open named pipe '%s': %s",
pipename, win_strerror(GetLastError()));
return INVALID_HANDLE_VALUE;
}
/*
* If we got ERROR_PIPE_BUSY, wait for the server to
* create a new pipe instance. (Since the server is
* expected to be winnps.c, which will do that immediately
* after a previous connection is accepted, that shouldn't
* take excessively long.)
*/
if (!WaitNamedPipe(pipename, NMPWAIT_USE_DEFAULT_WAIT)) {
*err = dupprintf(
"Error waiting for named pipe '%s': %s",
pipename, win_strerror(GetLastError()));
return INVALID_HANDLE_VALUE;
}
}
if ((usersid = get_user_sid()) == NULL) {
CloseHandle(pipehandle);
*err = dupprintf(
"Unable to get user SID: %s", win_strerror(GetLastError()));
return INVALID_HANDLE_VALUE;
}
if (p_GetSecurityInfo(pipehandle, SE_KERNEL_OBJECT,
OWNER_SECURITY_INFORMATION,
&pipeowner, NULL, NULL, NULL,
&psd) != ERROR_SUCCESS) {
CloseHandle(pipehandle);
*err = dupprintf(
"Unable to get named pipe security information: %s",
win_strerror(GetLastError()));
return INVALID_HANDLE_VALUE;
}
if (!EqualSid(pipeowner, usersid)) {
CloseHandle(pipehandle);
LocalFree(psd);
*err = dupprintf(
"Owner of named pipe '%s' is not us", pipename);
return INVALID_HANDLE_VALUE;
}
LocalFree(psd);
return pipehandle;
}
Socket *new_named_pipe_client(const char *pipename, Plug *plug)
{
char *err = NULL;
HANDLE pipehandle = connect_to_named_pipe(pipename, &err);
if (pipehandle == INVALID_HANDLE_VALUE)
return new_error_socket_consume_string(plug, err);
else
return make_handle_socket(pipehandle, pipehandle, NULL, plug, true);
}