1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-06-30 19:12: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

@ -102,20 +102,18 @@ static int block_and_read(int fd, void *buf, size_t len)
return ret;
}
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)
{
char line[32];
struct termios cf;
const char *prompt = NULL;
stdio_sink errsink[1];
stdio_sink_init(errsink, stderr);
premsg(&cf);
for (SeatDialogTextItem *item = text->items,
*end = item+text->nitems; item < end; item++) {
switch (item->type) {
@ -135,8 +133,7 @@ SeatPromptResult console_confirm_ssh_host_key(
if (console_batch_mode) {
fprintf(stderr, "%s\n", item->text);
fflush(stderr);
postmsg(&cf);
return SPR_SW_ABORT("Cannot confirm a host key in batch mode");
return NULL;
}
break;
case SDT_PROMPT:
@ -146,7 +143,26 @@ SeatPromptResult console_confirm_ssh_host_key(
break;
}
}
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)
{
char line[32];
struct termios cf;
premsg(&cf);
const char *prompt = console_print_seatdialogtext(text);
if (!prompt) {
postmsg(&cf);
return SPR_SW_ABORT("Cannot confirm a host key in batch mode");
}
while (true) {
fprintf(stderr,
@ -202,23 +218,22 @@ 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)
{
char line[32];
struct termios cf;
premsg(&cf);
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) {
postmsg(&cf);
return SPR_SW_ABORT("Cannot confirm a weak crypto primitive "
"in batch mode");
}
fputs(console_continue_prompt, stderr);
fprintf(stderr, "%s (y/n) ", prompt);
fflush(stderr);
{
@ -244,23 +259,22 @@ 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)
{
char line[32];
struct termios cf;
premsg(&cf);
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) {
postmsg(&cf);
return SPR_SW_ABORT("Cannot confirm a weak cached host key "
"in batch mode");
}
fputs(console_continue_prompt, stderr);
fprintf(stderr, "%s (y/n) ", prompt);
fflush(stderr);
{

View File

@ -3609,10 +3609,54 @@ const SeatDialogPromptDescriptions *gtk_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;
}
/*
* Format a SeatDialogText into a strbuf, also adjusting the box width
* to cope with displayed text. Returns the dialog box title.
*/
static const char *gtk_format_seatdialogtext(
SeatDialogText *text, strbuf *dlg_text, int *width)
{
const char *dlg_title = NULL;
for (SeatDialogTextItem *item = text->items,
*end = item + text->nitems; item < end; item++) {
switch (item->type) {
case SDT_PARA:
put_fmt(dlg_text, "%s\n\n", item->text);
break;
case SDT_DISPLAY: {
put_fmt(dlg_text, "%s\n\n", item->text);
int thiswidth = string_width(item->text);
if (*width < thiswidth)
*width = thiswidth;
break;
}
case SDT_SCARY_HEADING:
/* Can't change font size or weight in this context */
put_fmt(dlg_text, "%s\n\n", item->text);
break;
case SDT_TITLE:
dlg_title = item->text;
break;
default:
break;
}
}
/*
* Trim trailing newlines.
*/
while (strbuf_chomp(dlg_text, '\n'));
return dlg_title;
}
SeatPromptResult gtk_seat_confirm_ssh_host_key(
Seat *seat, const char *host, int port, const char *keytype,
char *keystr, SeatDialogText *text, HelpCtx helpctx,
@ -3627,35 +3671,9 @@ SeatPromptResult gtk_seat_confirm_ssh_host_key(
button_array_hostkey, lenof(button_array_hostkey),
};
const char *dlg_title = NULL;
strbuf *dlg_text = strbuf_new();
int width = string_width("default dialog width determination string");
for (SeatDialogTextItem *item = text->items,
*end = item + text->nitems; item < end; item++) {
switch (item->type) {
case SDT_PARA:
put_fmt(dlg_text, "%s\n\n", item->text);
break;
case SDT_DISPLAY: {
put_fmt(dlg_text, "%s\n\n", item->text);
int thiswidth = string_width(item->text);
if (width < thiswidth)
width = thiswidth;
break;
}
case SDT_SCARY_HEADING:
/* Can't change font size or weight in this context */
put_fmt(dlg_text, "%s\n\n", item->text);
break;
case SDT_TITLE:
dlg_title = item->text;
break;
default:
break;
}
}
while (strbuf_chomp(dlg_text, '\n'));
strbuf *dlg_text = strbuf_new();
const char *dlg_title = gtk_format_seatdialogtext(text, dlg_text, &width);
GtkWidget *mainwin, *msgbox;
@ -3752,19 +3770,16 @@ static void simple_prompt_result_spr_callback(void *vctx, int result)
* below the configured 'warn' threshold).
*/
SeatPromptResult gtk_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 msg[] =
"The first %s supported by the server is "
"%s, which is below the configured warning threshold.\n"
"Continue with connection?";
char *text;
struct simple_prompt_result_spr_ctx *result_ctx;
GtkWidget *mainwin, *msgbox;
text = dupprintf(msg, algtype, algname);
int width = string_width("Reasonably long line of text "
"as a width template");
strbuf *dlg_text = strbuf_new();
const char *dlg_title = gtk_format_seatdialogtext(text, dlg_text, &width);
result_ctx = snew(struct simple_prompt_result_spr_ctx);
result_ctx->callback = callback;
@ -3774,33 +3789,26 @@ SeatPromptResult gtk_seat_confirm_weak_crypto_primitive(
mainwin = GTK_WIDGET(gtk_seat_get_window(seat));
msgbox = create_message_box(
mainwin, "PuTTY Security Alert", text,
string_width("Reasonably long line of text as a width template"),
false, &buttons_yn, simple_prompt_result_spr_callback, result_ctx);
mainwin, dlg_title, dlg_text->s, width, false,
&buttons_yn, simple_prompt_result_spr_callback, result_ctx);
register_dialog(seat, result_ctx->dialog_slot, msgbox);
sfree(text);
strbuf_free(dlg_text);
return SPR_INCOMPLETE;
}
SeatPromptResult gtk_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 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"
"Continue with connection?";
char *text;
struct simple_prompt_result_spr_ctx *result_ctx;
GtkWidget *mainwin, *msgbox;
text = dupprintf(msg, algname, betteralgs);
int width = string_width("is ecdsa-nistp521, which is below the configured"
" warning threshold.");
strbuf *dlg_text = strbuf_new();
const char *dlg_title = gtk_format_seatdialogtext(text, dlg_text, &width);
result_ctx = snew(struct simple_prompt_result_spr_ctx);
result_ctx->callback = callback;
@ -3810,13 +3818,11 @@ SeatPromptResult gtk_seat_confirm_weak_cached_hostkey(
mainwin = GTK_WIDGET(gtk_seat_get_window(seat));
msgbox = create_message_box(
mainwin, "PuTTY Security Alert", text,
string_width("is ecdsa-nistp521, which is below the configured"
" warning threshold."),
false, &buttons_yn, simple_prompt_result_spr_callback, result_ctx);
mainwin, dlg_title, dlg_text->s, width, false,
&buttons_yn, simple_prompt_result_spr_callback, result_ctx);
register_dialog(seat, result_ctx->dialog_slot, msgbox);
sfree(text);
strbuf_free(dlg_text);
return SPR_INCOMPLETE;
}

View File

@ -225,10 +225,10 @@ SeatPromptResult gtk_seat_confirm_ssh_host_key(
char *keystr, SeatDialogText *text, HelpCtx helpctx,
void (*callback)(void *ctx, SeatPromptResult result), void *ctx);
SeatPromptResult gtk_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 gtk_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 *gtk_seat_prompt_descriptions(Seat *seat);
#ifdef MAY_REFER_TO_GTK_IN_HEADERS