diff --git a/Recipe b/Recipe index 077ae7cf..352bee21 100644 --- a/Recipe +++ b/Recipe @@ -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 diff --git a/windows/winpgnt.c b/windows/winpgnt.c index 0dbf32e8..888ff261 100644 --- a/windows/winpgnt.c +++ b/windows/winpgnt.c @@ -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 */ { diff --git a/windows/winpgntc.c b/windows/winpgntc.c index fb7f02e6..af1ae7e2 100644 --- a/windows/winpgntc.c +++ b/windows/winpgntc.c @@ -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"); diff --git a/windows/winstuff.h b/windows/winstuff.h index b6cce929..d6cc1b68 100644 --- a/windows/winstuff.h +++ b/windows/winstuff.h @@ -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