1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-07-01 03:22:48 -05:00

Refactor confirm_weak to use SeatDialogText.

This centralises the messages for weak crypto algorithms (general, and
host keys in particular, the latter including a list of all the other
available host key types) into ssh/common.c, in much the same way as
we previously did for ordinary host key warnings.

The reason is the same too: I'm about to want to vary the text in one
of those dialog boxes, so it's convenient to start by putting it
somewhere that I can modify just once.
This commit is contained in:
Simon Tatham
2023-11-22 08:57:54 +00:00
parent f2e7086902
commit 9fcbb86f71
16 changed files with 342 additions and 218 deletions

View File

@ -32,20 +32,18 @@ void console_print_error_msg(const char *prefix, const char *msg)
fflush(stderr);
}
SeatPromptResult console_confirm_ssh_host_key(
Seat *seat, const char *host, int port, const char *keytype,
char *keystr, SeatDialogText *text, HelpCtx helpctx,
void (*callback)(void *ctx, SeatPromptResult result), void *ctx)
/*
* Helper function to print the message from a SeatDialogText. Returns
* the final prompt to print on the input line, or NULL if a
* batch-mode abort is needed. In the latter case it will have printed
* the abort text already.
*/
static const char *console_print_seatdialogtext(SeatDialogText *text)
{
HANDLE hin;
DWORD savemode, i;
const char *prompt = NULL;
stdio_sink errsink[1];
stdio_sink_init(errsink, stderr);
char line[32];
for (SeatDialogTextItem *item = text->items,
*end = item+text->nitems; item < end; item++) {
switch (item->type) {
@ -65,7 +63,7 @@ SeatPromptResult console_confirm_ssh_host_key(
if (console_batch_mode) {
fprintf(stderr, "%s\n", item->text);
fflush(stderr);
return SPR_SW_ABORT("Cannot confirm a host key in batch mode");
return NULL;
}
break;
case SDT_PROMPT:
@ -76,6 +74,22 @@ SeatPromptResult console_confirm_ssh_host_key(
}
}
assert(prompt); /* something in the SeatDialogText should have set this */
return prompt;
}
SeatPromptResult console_confirm_ssh_host_key(
Seat *seat, const char *host, int port, const char *keytype,
char *keystr, SeatDialogText *text, HelpCtx helpctx,
void (*callback)(void *ctx, SeatPromptResult result), void *ctx)
{
HANDLE hin;
DWORD savemode, i;
const char *prompt = console_print_seatdialogtext(text);
if (!prompt)
return SPR_SW_ABORT("Cannot confirm a host key in batch mode");
char line[32];
while (true) {
fprintf(stderr,
@ -128,23 +142,20 @@ SeatPromptResult console_confirm_ssh_host_key(
}
SeatPromptResult console_confirm_weak_crypto_primitive(
Seat *seat, const char *algtype, const char *algname,
Seat *seat, SeatDialogText *text,
void (*callback)(void *ctx, SeatPromptResult result), void *ctx)
{
HANDLE hin;
DWORD savemode, i;
char line[32];
fprintf(stderr, weakcrypto_msg_common_fmt, algtype, algname);
if (console_batch_mode) {
fputs(console_abandoned_msg, stderr);
const char *prompt = console_print_seatdialogtext(text);
if (!prompt)
return SPR_SW_ABORT("Cannot confirm a weak crypto primitive "
"in batch mode");
}
fputs(console_continue_prompt, stderr);
char line[32];
fprintf(stderr, "%s (y/n) ", prompt);
fflush(stderr);
hin = GetStdHandle(STD_INPUT_HANDLE);
@ -163,23 +174,20 @@ SeatPromptResult console_confirm_weak_crypto_primitive(
}
SeatPromptResult console_confirm_weak_cached_hostkey(
Seat *seat, const char *algname, const char *betteralgs,
Seat *seat, SeatDialogText *text,
void (*callback)(void *ctx, SeatPromptResult result), void *ctx)
{
HANDLE hin;
DWORD savemode, i;
char line[32];
fprintf(stderr, weakhk_msg_common_fmt, algname, betteralgs);
if (console_batch_mode) {
fputs(console_abandoned_msg, stderr);
const char *prompt = console_print_seatdialogtext(text);
if (!prompt)
return SPR_SW_ABORT("Cannot confirm a weak cached host key "
"in batch mode");
}
fputs(console_continue_prompt, stderr);
char line[32];
fprintf(stderr, "%s (y/n) ", prompt);
fflush(stderr);
hin = GetStdHandle(STD_INPUT_HANDLE);

View File

@ -963,6 +963,39 @@ static INT_PTR HostKeyMoreInfoProc(HWND hwnd, UINT msg, WPARAM wParam,
return 0;
}
static const char *process_seatdialogtext(
strbuf *dlg_text, const char **scary_heading, SeatDialogText *text)
{
const char *dlg_title = "";
for (SeatDialogTextItem *item = text->items,
*end = item + text->nitems; item < end; item++) {
switch (item->type) {
case SDT_PARA:
put_fmt(dlg_text, "%s\r\n\r\n", item->text);
break;
case SDT_DISPLAY:
put_fmt(dlg_text, "%s\r\n\r\n", item->text);
break;
case SDT_SCARY_HEADING:
assert(scary_heading != NULL && "only expect a scary heading if "
"the dialog has somewhere to put it");
*scary_heading = item->text;
break;
case SDT_TITLE:
dlg_title = item->text;
break;
default:
break;
}
}
/* Trim any trailing newlines */
while (strbuf_chomp(dlg_text, '\r') || strbuf_chomp(dlg_text, '\n'));
return dlg_title;
}
static INT_PTR HostKeyDialogProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam, void *vctx)
{
@ -971,32 +1004,15 @@ static INT_PTR HostKeyDialogProc(HWND hwnd, UINT msg,
switch (msg) {
case WM_INITDIALOG: {
strbuf *dlg_text = strbuf_new();
const char *dlg_title = "";
ctx->has_title = false;
LPCTSTR iconid = IDI_QUESTION;
const char *scary_heading = NULL;
const char *dlg_title = process_seatdialogtext(
dlg_text, &scary_heading, ctx->text);
for (SeatDialogTextItem *item = ctx->text->items,
*end = item + ctx->text->nitems; item < end; item++) {
switch (item->type) {
case SDT_PARA:
put_fmt(dlg_text, "%s\r\n\r\n", item->text);
break;
case SDT_DISPLAY:
put_fmt(dlg_text, "%s\r\n\r\n", item->text);
break;
case SDT_SCARY_HEADING:
SetDlgItemText(hwnd, IDC_HK_TITLE, item->text);
iconid = IDI_WARNING;
ctx->has_title = true;
break;
case SDT_TITLE:
dlg_title = item->text;
break;
default:
break;
}
LPCTSTR iconid = IDI_QUESTION;
if (scary_heading) {
SetDlgItemText(hwnd, IDC_HK_TITLE, scary_heading);
iconid = IDI_WARNING;
}
while (strbuf_chomp(dlg_text, '\r') || strbuf_chomp(dlg_text, '\n'));
SetDlgItemText(hwnd, IDC_HK_TEXT, dlg_text->s);
MakeDlgItemBorderless(hwnd, IDC_HK_TEXT);
@ -1135,6 +1151,8 @@ const SeatDialogPromptDescriptions *win_seat_prompt_descriptions(Seat *seat)
.hk_connect_once_action = "press \"Connect Once\"",
.hk_cancel_action = "press \"Cancel\"",
.hk_cancel_action_Participle = "Pressing \"Cancel\"",
.weak_accept_action = "press \"Yes\"",
.weak_cancel_action = "press \"No\"",
};
return &descs;
}
@ -1169,25 +1187,17 @@ SeatPromptResult win_seat_confirm_ssh_host_key(
* below the configured 'warn' threshold).
*/
SeatPromptResult win_seat_confirm_weak_crypto_primitive(
Seat *seat, const char *algtype, const char *algname,
Seat *seat, SeatDialogText *text,
void (*callback)(void *ctx, SeatPromptResult result), void *ctx)
{
static const char mbtitle[] = "%s Security Alert";
static const char msg[] =
"The first %s supported by the server\n"
"is %s, which is below the configured\n"
"warning threshold.\n"
"Do you want to continue with this connection?\n";
char *message, *title;
int mbret;
strbuf *dlg_text = strbuf_new();
const char *dlg_title = process_seatdialogtext(dlg_text, NULL, text);
message = dupprintf(msg, algtype, algname);
title = dupprintf(mbtitle, appname);
mbret = MessageBox(NULL, message, title,
MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2);
int mbret = MessageBox(NULL, dlg_text->s, dlg_title,
MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2);
socket_reselect_all();
sfree(message);
sfree(title);
strbuf_free(dlg_text);
if (mbret == IDYES)
return SPR_OK;
else
@ -1195,27 +1205,17 @@ SeatPromptResult win_seat_confirm_weak_crypto_primitive(
}
SeatPromptResult win_seat_confirm_weak_cached_hostkey(
Seat *seat, const char *algname, const char *betteralgs,
Seat *seat, SeatDialogText *text,
void (*callback)(void *ctx, SeatPromptResult result), void *ctx)
{
static const char mbtitle[] = "%s Security Alert";
static const char msg[] =
"The first host key type we have stored for this server\n"
"is %s, which is below the configured warning threshold.\n"
"The server also provides the following types of host key\n"
"above the threshold, which we do not have stored:\n"
"%s\n"
"Do you want to continue with this connection?\n";
char *message, *title;
int mbret;
strbuf *dlg_text = strbuf_new();
const char *dlg_title = process_seatdialogtext(dlg_text, NULL, text);
message = dupprintf(msg, algname, betteralgs);
title = dupprintf(mbtitle, appname);
mbret = MessageBox(NULL, message, title,
MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2);
int mbret = MessageBox(NULL, dlg_text->s, dlg_title,
MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2);
socket_reselect_all();
sfree(message);
sfree(title);
strbuf_free(dlg_text);
if (mbret == IDYES)
return SPR_OK;
else

View File

@ -237,10 +237,10 @@ SeatPromptResult win_seat_confirm_ssh_host_key(
char *keystr, SeatDialogText *text, HelpCtx helpctx,
void (*callback)(void *ctx, SeatPromptResult result), void *ctx);
SeatPromptResult win_seat_confirm_weak_crypto_primitive(
Seat *seat, const char *algtype, const char *algname,
Seat *seat, SeatDialogText *text,
void (*callback)(void *ctx, SeatPromptResult result), void *ctx);
SeatPromptResult win_seat_confirm_weak_cached_hostkey(
Seat *seat, const char *algname, const char *betteralgs,
Seat *seat, SeatDialogText *text,
void (*callback)(void *ctx, SeatPromptResult result), void *ctx);
const SeatDialogPromptDescriptions *win_seat_prompt_descriptions(Seat *seat);