1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-10 01:48:00 +00:00
putty-source/windows/winpgntc.c
Simon Tatham f864265e39 Remove the commented-out WINDOWS_ASYNC_AGENT code.
It's been commented out for ages because it never really worked, and
it's about to become further out of date when I make other changes to
the agent client code, so it's time to get rid of it before it gets in
the way.

If and when I do get round to supporting asynchronous agent requests
on Windows, it's now pretty clear to me that trying to coerce this
ghastly window-message IPC into the right shape is the wrong way, and
a better approach will be to make Pageant support a named-pipe based
alternative transport for its agent connections, and speaking the
ordinary stream-oriented agent protocol over that. Then Pageant will
be able to start adding interactive features (like confirmation
dialogs or on-demand decryption) with freedom to reply to multiple
simultaneous agent connections in whatever order it finds convenient.
2017-01-29 20:24:09 +00:00

116 lines
3.1 KiB
C

/*
* Pageant client code.
*/
#include <stdio.h>
#include <stdlib.h>
#include "putty.h"
#ifndef NO_SECURITY
#include "winsecur.h"
#endif
#define AGENT_COPYDATA_ID 0x804e50ba /* random goop */
#define AGENT_MAX_MSGLEN 8192
int agent_exists(void)
{
HWND hwnd;
hwnd = FindWindow("Pageant", "Pageant");
if (!hwnd)
return FALSE;
else
return TRUE;
}
int agent_query(void *in, int inlen, void **out, int *outlen,
void (*callback)(void *, void *, int), void *callback_ctx)
{
HWND hwnd;
char *mapname;
HANDLE filemap;
unsigned char *p, *ret;
int id, retlen;
COPYDATASTRUCT cds;
SECURITY_ATTRIBUTES sa, *psa;
PSECURITY_DESCRIPTOR psd = NULL;
PSID usersid = NULL;
*out = NULL;
*outlen = 0;
hwnd = FindWindow("Pageant", "Pageant");
if (!hwnd)
return 1; /* *out == NULL, so failure */
mapname = dupprintf("PageantRequest%08x", (unsigned)GetCurrentThreadId());
psa = NULL;
#ifndef NO_SECURITY
if (got_advapi()) {
/*
* Make the file mapping we create for communication with
* Pageant owned by the user SID rather than the default. This
* should make communication between processes with slightly
* different contexts more reliable: in particular, command
* prompts launched as administrator should still be able to
* run PSFTPs which refer back to the owning user's
* unprivileged Pageant.
*/
usersid = get_user_sid();
if (usersid) {
psd = (PSECURITY_DESCRIPTOR)
LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
if (psd) {
if (p_InitializeSecurityDescriptor
(psd, SECURITY_DESCRIPTOR_REVISION) &&
p_SetSecurityDescriptorOwner(psd, usersid, FALSE)) {
sa.nLength = sizeof(sa);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = psd;
psa = &sa;
} else {
LocalFree(psd);
psd = NULL;
}
}
}
}
#endif /* NO_SECURITY */
filemap = CreateFileMapping(INVALID_HANDLE_VALUE, psa, PAGE_READWRITE,
0, AGENT_MAX_MSGLEN, mapname);
if (filemap == NULL || filemap == INVALID_HANDLE_VALUE) {
sfree(mapname);
return 1; /* *out == NULL, so failure */
}
p = MapViewOfFile(filemap, FILE_MAP_WRITE, 0, 0, 0);
memcpy(p, in, inlen);
cds.dwData = AGENT_COPYDATA_ID;
cds.cbData = 1 + strlen(mapname);
cds.lpData = mapname;
/*
* The user either passed a null callback (indicating that the
* query is required to be synchronous) or CreateThread failed.
* Either way, we need a synchronous request.
*/
id = SendMessage(hwnd, WM_COPYDATA, (WPARAM) NULL, (LPARAM) &cds);
if (id > 0) {
retlen = 4 + GET_32BIT(p);
ret = snewn(retlen, unsigned char);
if (ret) {
memcpy(ret, p, retlen);
*out = ret;
*outlen = retlen;
}
}
UnmapViewOfFile(p);
CloseHandle(filemap);
sfree(mapname);
if (psd)
LocalFree(psd);
return 1;
}