mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-10 09:58:01 +00:00
1b3edafcff
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]
85 lines
2.3 KiB
C
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 */
|