mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 17:38:00 +00:00
Backport of the pre-0.77 demo features to 0.76.
This is a combined cherry-pick of three commits on the 0.77 branch:896bcd5068
"Resurrect the test backends"9294ee3496
"Windows PuTTYgen: saw load_key_file in half"bc7e06c494
"Windows tools: assorted '-demo' options" Of course, these commits aren't in 0.76 itself, and I don't see any reason to publish a binary build of 0.76 containing them. This is just a branch I can build from myself to get a version of PuTTY that will look exactly like the real 0.76 but permit automated generation of demo screenshots.
This commit is contained in:
parent
1fd7baa734
commit
11192e2e33
3
Recipe
3
Recipe
@ -330,7 +330,9 @@ KEYGEN = sshrsag sshdssg sshecdsag
|
||||
# X/GTK Unix app, [U] for command-line Unix app.
|
||||
|
||||
putty : [G] GUITERM NONSSH WINSSH W_BE_ALL WINMISC winx11 putty.res LIBS
|
||||
+ screenshot testback
|
||||
puttytel : [G] GUITERM NONSSH W_BE_NOSSH WINMISC puttytel.res nogss LIBS
|
||||
+ screenshot testback
|
||||
plink : [C] winplink wincons console NONSSH WINSSH W_BE_ALL logging WINMISC
|
||||
+ winx11 plink.res winnojmp sessprep noterm winnohlp winselcli
|
||||
+ clicons wincliloop console LIBS
|
||||
@ -353,6 +355,7 @@ puttygen : [G] winpgen KEYGEN SSHPRIME sshdes ARITH sshmd5 version
|
||||
+ sshpubk sshaes sshsh256 sshsh512 IMPORT winutils puttygen.res
|
||||
+ tree234 notiming winhelp winnojmp CONF LIBS wintime sshecc sshprng
|
||||
+ sshauxcrypt sshhmac winsecur winmiscs sshsha3 sshblake2 sshargon2
|
||||
+ screenshot
|
||||
|
||||
pterm : [X] GTKTERM uxmisc misc ldisc settings uxpty uxsel BE_NONE uxstore
|
||||
+ uxsignal CHARSET cmdline uxpterm version time xpmpterm xpmptcfg
|
||||
|
18
settings.c
18
settings.c
@ -1302,6 +1302,8 @@ static int sessioncmp(const void *av, const void *bv)
|
||||
return strcmp(a, b); /* otherwise, compare normally */
|
||||
}
|
||||
|
||||
bool sesslist_demo_mode = false;
|
||||
|
||||
void get_sesslist(struct sesslist *list, bool allocate)
|
||||
{
|
||||
int i;
|
||||
@ -1311,12 +1313,18 @@ void get_sesslist(struct sesslist *list, bool allocate)
|
||||
if (allocate) {
|
||||
strbuf *sb = strbuf_new();
|
||||
|
||||
if ((handle = enum_settings_start()) != NULL) {
|
||||
while (enum_settings_next(handle, sb))
|
||||
put_byte(sb, '\0');
|
||||
enum_settings_finish(handle);
|
||||
if (sesslist_demo_mode) {
|
||||
put_asciz(sb, "demo-server");
|
||||
put_asciz(sb, "demo-server-2");
|
||||
} else {
|
||||
if ((handle = enum_settings_start()) != NULL) {
|
||||
while (enum_settings_next(handle, sb))
|
||||
put_byte(sb, '\0');
|
||||
enum_settings_finish(handle);
|
||||
}
|
||||
put_byte(sb, '\0');
|
||||
}
|
||||
put_byte(sb, '\0');
|
||||
|
||||
list->buffer = strbuf_to_str(sb);
|
||||
|
||||
/*
|
||||
|
27
testback.c
27
testback.c
@ -32,11 +32,8 @@
|
||||
|
||||
#include "putty.h"
|
||||
|
||||
static char *null_init(const BackendVtable *, Seat *, Backend **, LogContext *,
|
||||
Conf *, const char *, int, char **, bool, bool);
|
||||
static char *loop_init(const BackendVtable *, Seat *, Backend **, LogContext *,
|
||||
Conf *, const char *, int, char **, bool, bool);
|
||||
static void null_free(Backend *);
|
||||
static void loop_free(Backend *);
|
||||
static void null_reconfig(Backend *, Conf *);
|
||||
static size_t null_send(Backend *, const char *, size_t);
|
||||
@ -54,8 +51,8 @@ static void null_unthrottle(Backend *, size_t);
|
||||
static int null_cfg_info(Backend *);
|
||||
|
||||
const BackendVtable null_backend = {
|
||||
.init = null_init,
|
||||
.free = null_free,
|
||||
.init = loop_init,
|
||||
.free = loop_free,
|
||||
.reconfig = null_reconfig,
|
||||
.send = null_send,
|
||||
.sendbuffer = null_sendbuffer,
|
||||
@ -102,17 +99,6 @@ struct loop_state {
|
||||
Backend backend;
|
||||
};
|
||||
|
||||
static char *null_init(const BackendVtable *vt, Seat *seat,
|
||||
Backend **backend_handle, LogContext *logctx,
|
||||
Conf *conf, const char *host, int port,
|
||||
char **realhost, bool nodelay, bool keepalive) {
|
||||
/* No local authentication phase in this protocol */
|
||||
seat_set_trust_status(seat, false);
|
||||
|
||||
*backend_handle = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *loop_init(const BackendVtable *vt, Seat *seat,
|
||||
Backend **backend_handle, LogContext *logctx,
|
||||
Conf *conf, const char *host, int port,
|
||||
@ -123,15 +109,14 @@ static char *loop_init(const BackendVtable *vt, Seat *seat,
|
||||
seat_set_trust_status(seat, false);
|
||||
|
||||
st->seat = seat;
|
||||
st->backend.vt = vt;
|
||||
*backend_handle = &st->backend;
|
||||
|
||||
*realhost = dupstr(host);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void null_free(Backend *be)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void loop_free(Backend *be)
|
||||
{
|
||||
struct loop_state *st = container_of(be, struct loop_state, backend);
|
||||
|
114
windows/screenshot.c
Normal file
114
windows/screenshot.c
Normal file
@ -0,0 +1,114 @@
|
||||
#include "putty.h"
|
||||
|
||||
#include <dwmapi.h>
|
||||
|
||||
char *save_screenshot(HWND hwnd, const char *outfile)
|
||||
{
|
||||
HDC dcWindow = NULL, dcSave = NULL;
|
||||
HBITMAP bmSave = NULL;
|
||||
uint8_t *buffer = NULL;
|
||||
char *err = NULL;
|
||||
|
||||
static HMODULE dwmapi_module;
|
||||
DECL_WINDOWS_FUNCTION(static, HRESULT, DwmGetWindowAttribute,
|
||||
(HWND, DWORD, PVOID, DWORD));
|
||||
|
||||
if (!dwmapi_module) {
|
||||
dwmapi_module = load_system32_dll("dwmapi.dll");
|
||||
GET_WINDOWS_FUNCTION(dwmapi_module, DwmGetWindowAttribute);
|
||||
}
|
||||
|
||||
dcWindow = GetDC(NULL);
|
||||
if (!dcWindow) {
|
||||
err = dupprintf("GetDC(window): %s", win_strerror(GetLastError()));
|
||||
goto out;
|
||||
}
|
||||
|
||||
int x, y, w, h;
|
||||
RECT wr;
|
||||
|
||||
/* Use DwmGetWindowAttribute in place of GetWindowRect to exclude
|
||||
* drop shadow, otherwise we get a load of unwanted desktop
|
||||
* background under the shadow */
|
||||
if (p_DwmGetWindowAttribute &&
|
||||
0 <= p_DwmGetWindowAttribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS,
|
||||
&wr, sizeof(wr))) {
|
||||
x = wr.left;
|
||||
y = wr.top;
|
||||
w = wr.right - wr.left;
|
||||
h = wr.bottom - wr.top;
|
||||
} else {
|
||||
BITMAP bmhdr;
|
||||
memset(&bmhdr, 0, sizeof(bmhdr));
|
||||
GetObject(GetCurrentObject(dcWindow, OBJ_BITMAP),
|
||||
sizeof(bmhdr), &bmhdr);
|
||||
x = y = 0;
|
||||
w = bmhdr.bmWidth;
|
||||
h = bmhdr.bmHeight;
|
||||
}
|
||||
|
||||
dcSave = CreateCompatibleDC(dcWindow);
|
||||
if (!dcSave) {
|
||||
err = dupprintf("CreateCompatibleDC(desktop window dc): %s",
|
||||
win_strerror(GetLastError()));
|
||||
goto out;
|
||||
}
|
||||
|
||||
bmSave = CreateCompatibleBitmap(dcWindow, w, h);
|
||||
if (!bmSave) {
|
||||
err = dupprintf("CreateCompatibleBitmap: %s",
|
||||
win_strerror(GetLastError()));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!SelectObject(dcSave, bmSave)) {
|
||||
err = dupprintf("SelectObject: %s", win_strerror(GetLastError()));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!BitBlt(dcSave, 0, 0, w, h, dcWindow, x, y, SRCCOPY)) {
|
||||
err = dupprintf("BitBlt: %s", win_strerror(GetLastError()));
|
||||
goto out;
|
||||
}
|
||||
|
||||
BITMAPINFO bmInfo;
|
||||
memset(&bmInfo, 0, sizeof(bmInfo));
|
||||
bmInfo.bmiHeader.biSize = sizeof(bmInfo.bmiHeader);
|
||||
bmInfo.bmiHeader.biWidth = w;
|
||||
bmInfo.bmiHeader.biHeight = h;
|
||||
bmInfo.bmiHeader.biPlanes = 1;
|
||||
bmInfo.bmiHeader.biBitCount = 32;
|
||||
bmInfo.bmiHeader.biCompression = BI_RGB;
|
||||
|
||||
size_t bmPixels = (size_t)w*h, bmBytes = bmPixels * 4;
|
||||
buffer = snewn(bmBytes, uint8_t);
|
||||
|
||||
if (!GetDIBits(dcWindow, bmSave, 0, h, buffer, &bmInfo, DIB_RGB_COLORS))
|
||||
err = dupprintf("GetDIBits (get data): %s",
|
||||
win_strerror(GetLastError()));
|
||||
|
||||
FILE *fp = fopen(outfile, "wb");
|
||||
if (!fp) {
|
||||
err = dupprintf("'%s': unable to open file", outfile);
|
||||
goto out;
|
||||
}
|
||||
|
||||
BITMAPFILEHEADER bmFileHdr;
|
||||
bmFileHdr.bfType = 'B' | ('M' << 8);
|
||||
bmFileHdr.bfSize = sizeof(bmFileHdr) + sizeof(bmInfo.bmiHeader) + bmBytes;
|
||||
bmFileHdr.bfOffBits = sizeof(bmFileHdr) + sizeof(bmInfo.bmiHeader);
|
||||
fwrite((void *)&bmFileHdr, 1, sizeof(bmFileHdr), fp);
|
||||
fwrite((void *)&bmInfo.bmiHeader, 1, sizeof(bmInfo.bmiHeader), fp);
|
||||
fwrite((void *)buffer, 1, bmBytes, fp);
|
||||
fclose(fp);
|
||||
|
||||
out:
|
||||
if (dcWindow)
|
||||
ReleaseDC(NULL, dcWindow);
|
||||
if (bmSave)
|
||||
DeleteObject(bmSave);
|
||||
if (dcSave)
|
||||
DeleteObject(dcSave);
|
||||
sfree(buffer);
|
||||
return err;
|
||||
}
|
@ -388,6 +388,8 @@ static void create_controls(HWND hwnd, char *path)
|
||||
}
|
||||
}
|
||||
|
||||
const char *dialog_box_demo_screenshot_filename = NULL;
|
||||
|
||||
/*
|
||||
* This function is the configuration box.
|
||||
* (Being a dialog procedure, in general it returns 0 if the default
|
||||
@ -396,6 +398,7 @@ static void create_controls(HWND hwnd, char *path)
|
||||
static INT_PTR CALLBACK GenericMainDlgProc(HWND hwnd, UINT msg,
|
||||
WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
const int DEMO_SCREENSHOT_TIMER_ID = 1230;
|
||||
HWND hw, treeview;
|
||||
struct treeview_faff tvfaff;
|
||||
int ret;
|
||||
@ -565,6 +568,21 @@ static INT_PTR CALLBACK GenericMainDlgProc(HWND hwnd, UINT msg,
|
||||
* spurious firing during the above setup procedure.
|
||||
*/
|
||||
SetWindowLongPtr(hwnd, GWLP_USERDATA, 1);
|
||||
|
||||
if (dialog_box_demo_screenshot_filename)
|
||||
SetTimer(hwnd, DEMO_SCREENSHOT_TIMER_ID, TICKSPERSEC, NULL);
|
||||
return 0;
|
||||
case WM_TIMER:
|
||||
if (dialog_box_demo_screenshot_filename &&
|
||||
(UINT_PTR)wParam == DEMO_SCREENSHOT_TIMER_ID) {
|
||||
KillTimer(hwnd, DEMO_SCREENSHOT_TIMER_ID);
|
||||
const char *err = save_screenshot(
|
||||
hwnd, dialog_box_demo_screenshot_filename);
|
||||
if (err)
|
||||
MessageBox(hwnd, err, "Demo screenshot failure",
|
||||
MB_OK | MB_ICONERROR);
|
||||
SaneEndDialog(hwnd, 0);
|
||||
}
|
||||
return 0;
|
||||
case WM_LBUTTONUP:
|
||||
/*
|
||||
|
@ -231,6 +231,11 @@ static int compose_state = 0;
|
||||
|
||||
static UINT wm_mousewheel = WM_MOUSEWHEEL;
|
||||
|
||||
extern bool sesslist_demo_mode;
|
||||
extern const char *dialog_box_demo_screenshot_filename;
|
||||
static strbuf *demo_terminal_data = NULL;
|
||||
static const char *terminal_demo_screenshot_filename;
|
||||
|
||||
#define IS_HIGH_VARSEL(wch1, wch2) \
|
||||
((wch1) == 0xDB40 && ((wch2) >= 0xDD00 && (wch2) <= 0xDDEF))
|
||||
#define IS_LOW_VARSEL(wch) \
|
||||
@ -369,7 +374,10 @@ static void start_backend(void)
|
||||
* Select protocol. This is farmed out into a table in a
|
||||
* separate file to enable an ssh-free variant.
|
||||
*/
|
||||
vt = backend_vt_from_proto(conf_get_int(conf, CONF_protocol));
|
||||
if (demo_terminal_data)
|
||||
vt = &null_backend;
|
||||
else
|
||||
vt = backend_vt_from_proto(conf_get_int(conf, CONF_protocol));
|
||||
if (!vt) {
|
||||
char *str = dupprintf("%s Internal Error", appname);
|
||||
MessageBox(NULL, "Unsupported protocol number found",
|
||||
@ -520,6 +528,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
|
||||
{
|
||||
char *p;
|
||||
bool special_launchable_argument = false;
|
||||
bool demo_config_box = false;
|
||||
|
||||
settings_set_default_protocol(be_default_protocol);
|
||||
/* Find the appropriate default port. */
|
||||
@ -646,6 +655,30 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
|
||||
} else if (!strcmp(p, "-pgpfp")) {
|
||||
pgp_fingerprints_msgbox(NULL);
|
||||
exit(1);
|
||||
} else if (!strcmp(p, "-demo-config-box")) {
|
||||
if (i+1 >= argc) {
|
||||
cmdline_error("%s expects an output filename", p);
|
||||
} else {
|
||||
demo_config_box = true;
|
||||
dialog_box_demo_screenshot_filename = argv[++i];
|
||||
}
|
||||
} else if (!strcmp(p, "-demo-terminal")) {
|
||||
if (i+2 >= argc) {
|
||||
cmdline_error("%s expects input and output filenames",
|
||||
p);
|
||||
} else {
|
||||
const char *infile = argv[++i];
|
||||
terminal_demo_screenshot_filename = argv[++i];
|
||||
FILE *fp = fopen(infile, "rb");
|
||||
if (!fp)
|
||||
cmdline_error("can't open input file '%s'", argv);
|
||||
demo_terminal_data = strbuf_new();
|
||||
char buf[4096];
|
||||
int retd;
|
||||
while ((retd = fread(buf, 1, sizeof(buf), fp)) > 0)
|
||||
put_data(demo_terminal_data, buf, retd);
|
||||
fclose(fp);
|
||||
}
|
||||
} else if (*p != '-') {
|
||||
cmdline_error("unexpected argument \"%s\"", p);
|
||||
} else {
|
||||
@ -656,13 +689,26 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
|
||||
|
||||
cmdline_run_saved(conf);
|
||||
|
||||
/*
|
||||
* Bring up the config dialog if the command line hasn't
|
||||
* (explicitly) specified a launchable configuration.
|
||||
*/
|
||||
if (!(special_launchable_argument || cmdline_host_ok(conf))) {
|
||||
if (!do_config(conf))
|
||||
cleanup_exit(0);
|
||||
if (demo_config_box) {
|
||||
sesslist_demo_mode = true;
|
||||
load_open_settings(NULL, conf);
|
||||
conf_set_str(conf, CONF_host, "demo-server.example.com");
|
||||
do_config(conf);
|
||||
cleanup_exit(0);
|
||||
} else if (demo_terminal_data) {
|
||||
/* Ensure conf will cause an immediate session launch */
|
||||
load_open_settings(NULL, conf);
|
||||
conf_set_str(conf, CONF_host, "demo-server.example.com");
|
||||
conf_set_int(conf, CONF_close_on_exit, FORCE_OFF);
|
||||
} else {
|
||||
/*
|
||||
* Bring up the config dialog if the command line hasn't
|
||||
* (explicitly) specified a launchable configuration.
|
||||
*/
|
||||
if (!(special_launchable_argument || cmdline_host_ok(conf))) {
|
||||
if (!do_config(conf))
|
||||
cleanup_exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
prepare_session(conf);
|
||||
@ -885,6 +931,8 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
|
||||
term_set_focus(term, GetForegroundWindow() == wgs.term_hwnd);
|
||||
UpdateWindow(wgs.term_hwnd);
|
||||
|
||||
gui_terminal_ready(wgs.term_hwnd, &wgs.seat, backend);
|
||||
|
||||
while (1) {
|
||||
HANDLE *handles;
|
||||
int nhandles, n;
|
||||
@ -5858,3 +5906,19 @@ static bool win_seat_get_window_pixel_size(Seat *seat, int *x, int *y)
|
||||
*y = r.bottom - r.top;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void demo_terminal_screenshot(void *ctx, unsigned long now)
|
||||
{
|
||||
HWND hwnd = (HWND)ctx;
|
||||
save_screenshot(hwnd, terminal_demo_screenshot_filename);
|
||||
cleanup_exit(0);
|
||||
}
|
||||
|
||||
void gui_terminal_ready(HWND hwnd, Seat *seat, Backend *backend)
|
||||
{
|
||||
if (demo_terminal_data) {
|
||||
ptrlen data = ptrlen_from_strbuf(demo_terminal_data);
|
||||
seat_stdout(seat, data.ptr, data.len);
|
||||
schedule_timer(TICKSPERSEC, demo_terminal_screenshot, (void *)hwnd);
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,8 @@
|
||||
#define DEFAULT_EDCURVE_INDEX 0
|
||||
|
||||
static char *cmdline_keyfile = NULL;
|
||||
static ptrlen cmdline_demo_keystr;
|
||||
static const char *demo_screenshot_filename = NULL;
|
||||
|
||||
/*
|
||||
* Print a modal (Really Bad) message box and perform a fatal exit.
|
||||
@ -966,6 +968,65 @@ void ui_set_fptype(HWND hwnd, struct MainDlgState *state, int option)
|
||||
}
|
||||
}
|
||||
|
||||
static void update_ui_after_load(HWND hwnd, struct MainDlgState *state,
|
||||
const char *passphrase, int type,
|
||||
RSAKey *newkey1, ssh2_userkey *newkey2)
|
||||
{
|
||||
SetDlgItemText(hwnd, IDC_PASSPHRASE1EDIT, passphrase);
|
||||
SetDlgItemText(hwnd, IDC_PASSPHRASE2EDIT, passphrase);
|
||||
|
||||
if (type == SSH_KEYTYPE_SSH1) {
|
||||
char *fingerprint, *savecomment;
|
||||
|
||||
state->ssh2 = false;
|
||||
state->commentptr = &state->key.comment;
|
||||
state->key = *newkey1; /* structure copy */
|
||||
|
||||
/*
|
||||
* Set the key fingerprint.
|
||||
*/
|
||||
savecomment = state->key.comment;
|
||||
state->key.comment = NULL;
|
||||
fingerprint = rsa_ssh1_fingerprint(&state->key);
|
||||
state->key.comment = savecomment;
|
||||
SetDlgItemText(hwnd, IDC_FINGERPRINT, fingerprint);
|
||||
sfree(fingerprint);
|
||||
|
||||
/*
|
||||
* Construct a decimal representation of the key, for pasting
|
||||
* into .ssh/authorized_keys on a Unix box.
|
||||
*/
|
||||
setupbigedit1(hwnd, IDC_KEYDISPLAY, IDC_PKSTATIC, &state->key);
|
||||
} else {
|
||||
char *fp;
|
||||
char *savecomment;
|
||||
|
||||
state->ssh2 = true;
|
||||
state->commentptr = &state->ssh2key.comment;
|
||||
state->ssh2key = *newkey2; /* structure copy */
|
||||
sfree(newkey2);
|
||||
|
||||
savecomment = state->ssh2key.comment;
|
||||
state->ssh2key.comment = NULL;
|
||||
fp = ssh2_fingerprint(state->ssh2key.key, state->fptype);
|
||||
state->ssh2key.comment = savecomment;
|
||||
|
||||
SetDlgItemText(hwnd, IDC_FINGERPRINT, fp);
|
||||
sfree(fp);
|
||||
|
||||
setupbigedit2(hwnd, IDC_KEYDISPLAY,
|
||||
IDC_PKSTATIC, &state->ssh2key);
|
||||
}
|
||||
SetDlgItemText(hwnd, IDC_COMMENTEDIT,
|
||||
*state->commentptr);
|
||||
|
||||
/*
|
||||
* Finally, hide the progress bar and show the key data.
|
||||
*/
|
||||
ui_set_state(hwnd, state, 2);
|
||||
state->key_exists = true;
|
||||
}
|
||||
|
||||
void load_key_file(HWND hwnd, struct MainDlgState *state,
|
||||
Filename *filename, bool was_import_cmd)
|
||||
{
|
||||
@ -1055,65 +1116,7 @@ void load_key_file(HWND hwnd, struct MainDlgState *state,
|
||||
* Now update the key controls with all the
|
||||
* key data.
|
||||
*/
|
||||
{
|
||||
SetDlgItemText(hwnd, IDC_PASSPHRASE1EDIT,
|
||||
passphrase);
|
||||
SetDlgItemText(hwnd, IDC_PASSPHRASE2EDIT,
|
||||
passphrase);
|
||||
if (type == SSH_KEYTYPE_SSH1) {
|
||||
char *fingerprint, *savecomment;
|
||||
|
||||
state->ssh2 = false;
|
||||
state->commentptr = &state->key.comment;
|
||||
state->key = newkey1;
|
||||
|
||||
/*
|
||||
* Set the key fingerprint.
|
||||
*/
|
||||
savecomment = state->key.comment;
|
||||
state->key.comment = NULL;
|
||||
fingerprint = rsa_ssh1_fingerprint(&state->key);
|
||||
state->key.comment = savecomment;
|
||||
SetDlgItemText(hwnd, IDC_FINGERPRINT, fingerprint);
|
||||
sfree(fingerprint);
|
||||
|
||||
/*
|
||||
* Construct a decimal representation
|
||||
* of the key, for pasting into
|
||||
* .ssh/authorized_keys on a Unix box.
|
||||
*/
|
||||
setupbigedit1(hwnd, IDC_KEYDISPLAY,
|
||||
IDC_PKSTATIC, &state->key);
|
||||
} else {
|
||||
char *fp;
|
||||
char *savecomment;
|
||||
|
||||
state->ssh2 = true;
|
||||
state->commentptr =
|
||||
&state->ssh2key.comment;
|
||||
state->ssh2key = *newkey2; /* structure copy */
|
||||
sfree(newkey2);
|
||||
|
||||
savecomment = state->ssh2key.comment;
|
||||
state->ssh2key.comment = NULL;
|
||||
fp = ssh2_fingerprint(state->ssh2key.key, state->fptype);
|
||||
state->ssh2key.comment = savecomment;
|
||||
|
||||
SetDlgItemText(hwnd, IDC_FINGERPRINT, fp);
|
||||
sfree(fp);
|
||||
|
||||
setupbigedit2(hwnd, IDC_KEYDISPLAY,
|
||||
IDC_PKSTATIC, &state->ssh2key);
|
||||
}
|
||||
SetDlgItemText(hwnd, IDC_COMMENTEDIT,
|
||||
*state->commentptr);
|
||||
}
|
||||
/*
|
||||
* Finally, hide the progress bar and show
|
||||
* the key data.
|
||||
*/
|
||||
ui_set_state(hwnd, state, 2);
|
||||
state->key_exists = true;
|
||||
update_ui_after_load(hwnd, state, passphrase, type, &newkey1, newkey2);
|
||||
|
||||
/*
|
||||
* If the user has imported a foreign key
|
||||
@ -1179,6 +1182,7 @@ static void start_generating_key(HWND hwnd, struct MainDlgState *state)
|
||||
static INT_PTR CALLBACK MainDlgProc(HWND hwnd, UINT msg,
|
||||
WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
const int DEMO_SCREENSHOT_TIMER_ID = 1230;
|
||||
static const char entropy_msg[] =
|
||||
"Please generate some randomness by moving the mouse over the blank area.";
|
||||
struct MainDlgState *state;
|
||||
@ -1402,9 +1406,33 @@ static INT_PTR CALLBACK MainDlgProc(HWND hwnd, UINT msg,
|
||||
Filename *fn = filename_from_str(cmdline_keyfile);
|
||||
load_key_file(hwnd, state, fn, false);
|
||||
filename_free(fn);
|
||||
} else if (cmdline_demo_keystr.ptr) {
|
||||
BinarySource src[1];
|
||||
BinarySource_BARE_INIT_PL(src, cmdline_demo_keystr);
|
||||
const char *errmsg;
|
||||
ssh2_userkey *k = ppk_load_s(src, NULL, &errmsg);
|
||||
assert(!errmsg);
|
||||
|
||||
update_ui_after_load(hwnd, state, "demo passphrase",
|
||||
SSH_KEYTYPE_SSH2, NULL, k);
|
||||
/* BODGE for the 0.66 backport */
|
||||
ui_set_key_type(hwnd, state, IDC_KEYSSH2EDDSA);
|
||||
SetDlgItemInt(hwnd, IDC_BITS, 255, false);
|
||||
|
||||
SetTimer(hwnd, DEMO_SCREENSHOT_TIMER_ID, TICKSPERSEC, NULL);
|
||||
}
|
||||
|
||||
return 1;
|
||||
case WM_TIMER:
|
||||
if ((UINT_PTR)wParam == DEMO_SCREENSHOT_TIMER_ID) {
|
||||
KillTimer(hwnd, DEMO_SCREENSHOT_TIMER_ID);
|
||||
const char *err = save_screenshot(hwnd, demo_screenshot_filename);
|
||||
if (err)
|
||||
MessageBox(hwnd, err, "Demo screenshot failure",
|
||||
MB_OK | MB_ICONERROR);
|
||||
EndDialog(hwnd, 0);
|
||||
}
|
||||
return 0;
|
||||
case WM_MOUSEMOVE:
|
||||
state = (struct MainDlgState *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
||||
if (state->collecting_entropy &&
|
||||
@ -2006,6 +2034,21 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
|
||||
!strcmp(argv[i], "-restrict_acl") ||
|
||||
!strcmp(argv[i], "-restrictacl")) {
|
||||
restrict_process_acl();
|
||||
} else if (!strcmp(argv[i], "-demo-screenshot")) {
|
||||
demo_screenshot_filename = (i+1 < argc ? argv[++i] :
|
||||
"puttygen.bmp");
|
||||
cmdline_demo_keystr = PTRLEN_LITERAL(
|
||||
"PuTTY-User-Key-File-3: ssh-ed25519\n"
|
||||
"Encryption: none\n"
|
||||
"Comment: ed25519-key-20220402\n"
|
||||
"Public-Lines: 2\n"
|
||||
"AAAAC3NzaC1lZDI1NTE5AAAAILzuIFwZ"
|
||||
"8ZhgOlilcSb+9zPuCf/DmKJiloVlmWGy\n"
|
||||
"xa/F\n"
|
||||
"Private-Lines: 1\n"
|
||||
"AAAAIPca6vLwtB2NJhZUpABQISR0gcQH8jjQLta19VyzA3wc\n"
|
||||
"Private-MAC: 1159e9628259b35933b397379bbe8a14"
|
||||
"a1f1d97fe91e446e45a9581a3408b70e\n");
|
||||
} else {
|
||||
/*
|
||||
* Assume the first argument to be a private key file, and
|
||||
|
@ -701,4 +701,7 @@ void cli_main_loop(cliloop_pre_t pre, cliloop_post_t post, void *ctx);
|
||||
bool cliloop_null_pre(void *vctx, const HANDLE **, size_t *);
|
||||
bool cliloop_null_post(void *vctx, size_t);
|
||||
|
||||
char *save_screenshot(HWND hwnd, const char *outfile);
|
||||
void gui_terminal_ready(HWND hwnd, Seat *seat, Backend *backend);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user