1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 09:27:59 +00: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:
Simon Tatham 2020-01-01 15:55:06 +00:00
parent 39248737a4
commit f93b260694
4 changed files with 83 additions and 4 deletions

3
Recipe
View File

@ -340,7 +340,8 @@ psftp : [C] psftp winsftp wincons WINSSH BE_SSH SFTP wildcard WINMISC
pageant : [G] winpgnt pageant sshrsa sshpubk sshdes ARITH sshmd5 version
+ tree234 MISC sshaes sshsha winsecur winpgntc aqsync sshdss sshsh256
+ sshsh512 winutils sshecc winmisc winmiscs winhelp conf pageant.res
+ sshauxcrypt sshhmac LIBS
+ sshauxcrypt sshhmac wincapi winnps winnpc winhsock errsock winnet
+ winhandl callback be_misc winselgui LIBS
puttygen : [G] winpgen sshrsag sshdssg sshprime sshdes ARITH sshmd5 version
+ sshrand winnoise sshsha winstore MISC winctrls sshrsa sshdss winmisc

View File

@ -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 */
{

View File

@ -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");

View File

@ -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