1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-10 09:58:01 +00:00
putty-source/windows/winnpc.c
Simon Tatham 1b3edafcff Add support for Windows named pipes.
This commit adds two new support modules, winnpc.c and winnps.c, which
deal respectively with being a client and server of a Windows named
pipe (which, in spite of what Unix programmers will infer from that
name, is actually closer to Windows's analogue of a Unix-domain
socket). Each one provides a fully featured Socket wrapper around the
hairy Windows named pipe API, so that the rest of the code base should
be able to use these interchangeably with ordinary sockets and hardly
notice the difference.

As part of this work, I've introduced a mechanism in winhandl.c to
permit it to store handles of event objects on behalf of other Windows
support modules and deal with passing them to applications' main event
loops as necessary. (Perhaps it would have been cleaner to split
winhandl.c into an event-object tracking layer analogous to uxsel, and
the handle management which is winhandl.c's proper job, but this is
less disruptive for the present.)

[originally from svn r10069]
2013-11-17 14:04:01 +00:00

85 lines
2.3 KiB
C

/*
* Windows support module which deals with being a named-pipe client.
*/
#include <stdio.h>
#include <assert.h>
#define DEFINE_PLUG_METHOD_MACROS
#include "tree234.h"
#include "putty.h"
#include "network.h"
#include "proxy.h"
#include "ssh.h"
#if !defined NO_SECURITY
#include <aclapi.h>
Socket make_handle_socket(HANDLE send_H, HANDLE recv_H, Plug plug,
int overlapped);
Socket new_named_pipe_client(const char *pipename, Plug plug)
{
HANDLE pipehandle;
PSID usersid, pipeowner;
PSECURITY_DESCRIPTOR psd;
char *err;
Socket ret;
extern int advapi_initialised;
init_advapi(); /* for get_user_sid. FIXME: do better. */
assert(strncmp(pipename, "\\\\.\\pipe\\", 9) == 0);
assert(strchr(pipename + 9, '\\') == NULL);
pipehandle = CreateFile(pipename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if (pipehandle == INVALID_HANDLE_VALUE) {
err = dupprintf("Unable to open named pipe '%s': %s",
pipename, win_strerror(GetLastError()));
ret = new_error_socket(err, plug);
sfree(err);
return ret;
}
if ((usersid = get_user_sid()) == NULL) {
CloseHandle(pipehandle);
err = dupprintf("Unable to get user SID");
ret = new_error_socket(err, plug);
sfree(err);
return ret;
}
if (GetSecurityInfo(pipehandle, SE_KERNEL_OBJECT,
OWNER_SECURITY_INFORMATION,
&pipeowner, NULL, NULL, NULL,
&psd) != ERROR_SUCCESS) {
err = dupprintf("Unable to get named pipe security information: %s",
win_strerror(GetLastError()));
ret = new_error_socket(err, plug);
sfree(err);
CloseHandle(pipehandle);
sfree(usersid);
return ret;
}
if (!EqualSid(pipeowner, usersid)) {
err = dupprintf("Owner of named pipe '%s' is not us", pipename);
ret = new_error_socket(err, plug);
sfree(err);
CloseHandle(pipehandle);
LocalFree(psd);
sfree(usersid);
return ret;
}
LocalFree(psd);
sfree(usersid);
return make_handle_socket(pipehandle, pipehandle, plug, TRUE);
}
#endif /* !defined NO_SECURITY */