mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-07-01 11:32:48 -05:00
Windows Pageant: establish a named-pipe server.
This reuses all the named-pipe IPC code I set up for connection sharing a few years ago, to set up a named pipe with a predictable name and speak the stream-oriented SSH agent protocol over it. In this commit, we just set up the server, and there's no code that speaks the client end of the new IPC yet. But my plan is that clients should switch over to using this interface if possible, because it's generally better: it doesn't have to be handled synchronously in the middle of a GUI event loop (either in Pageant itself _or_ in its client), and it's a better fit to the connection-oriented nature of forwarded agent connections (so if any features ever appear in the agent protocol that require state within a connection, we'll now be able to support them).
This commit is contained in:
@ -16,6 +16,7 @@
|
||||
#include "misc.h"
|
||||
#include "tree234.h"
|
||||
#include "winsecur.h"
|
||||
#include "wincapi.h"
|
||||
#include "pageant.h"
|
||||
#include "licence.h"
|
||||
|
||||
@ -1125,6 +1126,16 @@ void agent_schedule_callback(void (*callback)(void *, void *, int),
|
||||
unreachable("all Pageant's own agent requests should be synchronous");
|
||||
}
|
||||
|
||||
void logevent(LogContext *logctx, const char *event)
|
||||
{
|
||||
unreachable("Pageant can't create a LogContext, so this can't be called");
|
||||
}
|
||||
|
||||
void noise_ultralight(NoiseSourceId id, unsigned long data)
|
||||
{
|
||||
/* Pageant doesn't use random numbers, so we ignore this */
|
||||
}
|
||||
|
||||
void cleanup_exit(int code)
|
||||
{
|
||||
shutdown_help();
|
||||
@ -1279,6 +1290,29 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined NO_SECURITY
|
||||
|
||||
/*
|
||||
* Set up a named-pipe listener.
|
||||
*/
|
||||
{
|
||||
Plug *pl_plug;
|
||||
struct pageant_listen_state *pl = pageant_listener_new(&pl_plug);
|
||||
char *pipename = agent_named_pipe_name();
|
||||
Socket *sock = new_named_pipe_listener(pipename, pl_plug);
|
||||
if (sk_socket_error(sock)) {
|
||||
char *err = dupprintf("Unable to open named pipe at %s "
|
||||
"for SSH agent:\n", pipename,
|
||||
sk_socket_error(sock));
|
||||
MessageBox(NULL, err, "Pageant Error", MB_ICONERROR | MB_OK);
|
||||
return 1;
|
||||
}
|
||||
pageant_listener_got_socket(pl, sock);
|
||||
sfree(pipename);
|
||||
}
|
||||
|
||||
#endif /* !defined NO_SECURITY */
|
||||
|
||||
if (!prev) {
|
||||
wndclass.style = 0;
|
||||
wndclass.lpfnWndProc = WndProc;
|
||||
@ -1300,6 +1334,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
|
||||
WS_OVERLAPPEDWINDOW | WS_VSCROLL,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
100, 100, NULL, NULL, inst, NULL);
|
||||
winselgui_set_hwnd(hwnd);
|
||||
|
||||
/* Set up a system tray icon */
|
||||
AddTrayIcon(hwnd);
|
||||
@ -1332,13 +1367,35 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
|
||||
/*
|
||||
* Main message loop.
|
||||
*/
|
||||
while (GetMessage(&msg, NULL, 0, 0) == 1) {
|
||||
if (!(IsWindow(keylist) && IsDialogMessage(keylist, &msg)) &&
|
||||
!(IsWindow(aboutbox) && IsDialogMessage(aboutbox, &msg))) {
|
||||
while (true) {
|
||||
HANDLE *handles;
|
||||
int nhandles, n;
|
||||
|
||||
handles = handle_get_events(&nhandles);
|
||||
|
||||
n = MsgWaitForMultipleObjects(nhandles, handles, false,
|
||||
INFINITE, QS_ALLINPUT);
|
||||
|
||||
if ((unsigned)(n - WAIT_OBJECT_0) < (unsigned)nhandles) {
|
||||
handle_got_event(handles[n - WAIT_OBJECT_0]);
|
||||
sfree(handles);
|
||||
} else
|
||||
sfree(handles);
|
||||
|
||||
while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||
if (msg.message == WM_QUIT)
|
||||
goto finished; /* two-level break */
|
||||
|
||||
if (IsWindow(keylist) && IsDialogMessage(keylist, &msg))
|
||||
continue;
|
||||
if (IsWindow(aboutbox) && IsDialogMessage(aboutbox, &msg))
|
||||
continue;
|
||||
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
finished:
|
||||
|
||||
/* Clean up the system tray icon */
|
||||
{
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#ifndef NO_SECURITY
|
||||
#include "winsecur.h"
|
||||
#include "wincapi.h"
|
||||
#endif
|
||||
|
||||
#define AGENT_COPYDATA_ID 0x804e50ba /* random goop */
|
||||
@ -136,6 +137,21 @@ agent_pending_query *agent_query(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef NO_SECURITY
|
||||
|
||||
char *agent_named_pipe_name(void)
|
||||
{
|
||||
char *username, *suffix, *pipename;
|
||||
username = get_username();
|
||||
suffix = capi_obfuscate_string("Pageant");
|
||||
pipename = dupprintf("\\\\.\\pipe\\pageant.%s.%s", username, suffix);
|
||||
sfree(username);
|
||||
sfree(suffix);
|
||||
return pipename;
|
||||
}
|
||||
|
||||
#endif /* NO_SECURITY */
|
||||
|
||||
Socket *agent_connect(void *vctx, Plug *plug)
|
||||
{
|
||||
unreachable("no agent_connect_ctx can be constructed on this platform");
|
||||
|
@ -653,6 +653,11 @@ struct handle_sink {
|
||||
};
|
||||
void handle_sink_init(handle_sink *sink, struct handle *h);
|
||||
|
||||
/*
|
||||
* Exports from winpgntc.c.
|
||||
*/
|
||||
char *agent_named_pipe_name(void);
|
||||
|
||||
/*
|
||||
* winpgntc.c needs to schedule callbacks for asynchronous agent
|
||||
* requests. This has to be done differently in GUI and console, so
|
||||
|
Reference in New Issue
Block a user