mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 01:18:00 +00:00
Divide seat_set_trust_status into query and update.
This complicates the API in one sense (more separate functions), but in another sense, simplifies it (each function does something simpler). When I start putting one Seat in front of another during SSH proxying, the latter will be more important - in particular, it means you can find out _whether_ a seat can support changing trust status without having to actually attempt a destructive modification.
This commit is contained in:
parent
c06c9c730f
commit
82177956da
3
pscp.c
3
pscp.c
@ -82,7 +82,8 @@ static const SeatVtable pscp_seat_vt = {
|
||||
.get_windowid = nullseat_get_windowid,
|
||||
.get_window_pixel_size = nullseat_get_window_pixel_size,
|
||||
.stripctrl_new = console_stripctrl_new,
|
||||
.set_trust_status = nullseat_set_trust_status_vacuously,
|
||||
.set_trust_status = nullseat_set_trust_status,
|
||||
.can_set_trust_status = nullseat_can_set_trust_status_yes,
|
||||
.verbose = cmdline_seat_verbose,
|
||||
.interactive = nullseat_interactive_no,
|
||||
.get_cursor_position = nullseat_get_cursor_position,
|
||||
|
3
psftp.c
3
psftp.c
@ -64,7 +64,8 @@ static const SeatVtable psftp_seat_vt = {
|
||||
.get_windowid = nullseat_get_windowid,
|
||||
.get_window_pixel_size = nullseat_get_window_pixel_size,
|
||||
.stripctrl_new = console_stripctrl_new,
|
||||
.set_trust_status = nullseat_set_trust_status_vacuously,
|
||||
.set_trust_status = nullseat_set_trust_status,
|
||||
.can_set_trust_status = nullseat_can_set_trust_status_yes,
|
||||
.verbose = cmdline_seat_verbose,
|
||||
.interactive = nullseat_interactive_yes,
|
||||
.get_cursor_position = nullseat_get_cursor_position,
|
||||
|
22
putty.h
22
putty.h
@ -1097,13 +1097,19 @@ struct SeatVtable {
|
||||
* (and hence, can be trusted if it's asking you for secrets such
|
||||
* as your passphrase); false means output is coming from the
|
||||
* server.
|
||||
*/
|
||||
void (*set_trust_status)(Seat *seat, bool trusted);
|
||||
|
||||
/*
|
||||
* Query whether this Seat can do anything user-visible in
|
||||
* response to set_trust_status.
|
||||
*
|
||||
* Returns true if the seat has a way to indicate this
|
||||
* distinction. Returns false if not, in which case the backend
|
||||
* should use a fallback defence against spoofing of PuTTY's local
|
||||
* prompts by malicious servers.
|
||||
*/
|
||||
bool (*set_trust_status)(Seat *seat, bool trusted);
|
||||
bool (*can_set_trust_status)(Seat *seat);
|
||||
|
||||
/*
|
||||
* Ask the seat whether it would like verbose messages.
|
||||
@ -1169,8 +1175,10 @@ static inline bool seat_get_window_pixel_size(Seat *seat, int *w, int *h)
|
||||
static inline StripCtrlChars *seat_stripctrl_new(
|
||||
Seat *seat, BinarySink *bs, SeatInteractionContext sic)
|
||||
{ return seat->vt->stripctrl_new(seat, bs, sic); }
|
||||
static inline bool seat_set_trust_status(Seat *seat, bool trusted)
|
||||
{ return seat->vt->set_trust_status(seat, trusted); }
|
||||
static inline void seat_set_trust_status(Seat *seat, bool trusted)
|
||||
{ seat->vt->set_trust_status(seat, trusted); }
|
||||
static inline bool seat_can_set_trust_status(Seat *seat)
|
||||
{ return seat->vt->can_set_trust_status(seat); }
|
||||
static inline bool seat_verbose(Seat *seat)
|
||||
{ return seat->vt->verbose(seat); }
|
||||
static inline bool seat_interactive(Seat *seat)
|
||||
@ -1229,8 +1237,9 @@ bool nullseat_get_windowid(Seat *seat, long *id_out);
|
||||
bool nullseat_get_window_pixel_size(Seat *seat, int *width, int *height);
|
||||
StripCtrlChars *nullseat_stripctrl_new(
|
||||
Seat *seat, BinarySink *bs_out, SeatInteractionContext sic);
|
||||
bool nullseat_set_trust_status(Seat *seat, bool trusted);
|
||||
bool nullseat_set_trust_status_vacuously(Seat *seat, bool trusted);
|
||||
void nullseat_set_trust_status(Seat *seat, bool trusted);
|
||||
bool nullseat_can_set_trust_status_yes(Seat *seat);
|
||||
bool nullseat_can_set_trust_status_no(Seat *seat);
|
||||
bool nullseat_verbose_no(Seat *seat);
|
||||
bool nullseat_verbose_yes(Seat *seat);
|
||||
bool nullseat_interactive_no(Seat *seat);
|
||||
@ -1255,7 +1264,8 @@ int console_confirm_weak_cached_hostkey(
|
||||
void (*callback)(void *ctx, int result), void *ctx);
|
||||
StripCtrlChars *console_stripctrl_new(
|
||||
Seat *seat, BinarySink *bs_out, SeatInteractionContext sic);
|
||||
bool console_set_trust_status(Seat *seat, bool trusted);
|
||||
void console_set_trust_status(Seat *seat, bool trusted);
|
||||
bool console_can_set_trust_status(Seat *seat);
|
||||
|
||||
/*
|
||||
* Other centralised seat functions.
|
||||
|
@ -543,5 +543,6 @@ SshChannel *ssh1_serverside_agent_open(ConnectionLayer *cl, Channel *chan)
|
||||
|
||||
bool ssh1_connection_need_antispoof_prompt(struct ssh1_connection_state *s)
|
||||
{
|
||||
return !seat_set_trust_status(s->ppl.seat, false);
|
||||
seat_set_trust_status(s->ppl.seat, false);
|
||||
return !seat_can_set_trust_status(s->ppl.seat);
|
||||
}
|
||||
|
@ -500,6 +500,7 @@ void ssh2channel_send_terminal_size_change(SshChannel *sc, int w, int h)
|
||||
|
||||
bool ssh2_connection_need_antispoof_prompt(struct ssh2_connection_state *s)
|
||||
{
|
||||
bool success = seat_set_trust_status(s->ppl.seat, false);
|
||||
seat_set_trust_status(s->ppl.seat, false);
|
||||
bool success = seat_can_set_trust_status(s->ppl.seat);
|
||||
return (!success && !ssh_is_bare(s->ppl.ssh));
|
||||
}
|
||||
|
@ -125,6 +125,7 @@ static const SeatVtable server_seat_vt = {
|
||||
.get_window_pixel_size = nullseat_get_window_pixel_size,
|
||||
.stripctrl_new = nullseat_stripctrl_new,
|
||||
.set_trust_status = nullseat_set_trust_status,
|
||||
.can_set_trust_status = nullseat_can_set_trust_status_no,
|
||||
.verbose = nullseat_verbose_no,
|
||||
.interactive = nullseat_interactive_no,
|
||||
.get_cursor_position = nullseat_get_cursor_position,
|
||||
|
@ -204,6 +204,7 @@ static const SeatVtable sesschan_seat_vt = {
|
||||
.get_window_pixel_size = sesschan_get_window_pixel_size,
|
||||
.stripctrl_new = nullseat_stripctrl_new,
|
||||
.set_trust_status = nullseat_set_trust_status,
|
||||
.can_set_trust_status = nullseat_can_set_trust_status_no,
|
||||
.verbose = nullseat_verbose_no,
|
||||
.interactive = nullseat_interactive_no,
|
||||
.get_cursor_position = nullseat_get_cursor_position,
|
||||
|
@ -1950,7 +1950,8 @@ static void ssh2_userauth_antispoof_msg(
|
||||
struct ssh2_userauth_state *s, const char *msg)
|
||||
{
|
||||
strbuf *sb = strbuf_new();
|
||||
if (seat_set_trust_status(s->ppl.seat, true)) {
|
||||
seat_set_trust_status(s->ppl.seat, true);
|
||||
if (seat_can_set_trust_status(s->ppl.seat)) {
|
||||
/*
|
||||
* If the seat can directly indicate that this message is
|
||||
* generated by the client, then we can just use the message
|
||||
|
25
sshproxy.c
25
sshproxy.c
@ -405,20 +405,24 @@ static int sshproxy_confirm_weak_cached_hostkey(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool sshproxy_set_trust_status(Seat *seat, bool trusted)
|
||||
static void sshproxy_set_trust_status(Seat *seat, bool trusted)
|
||||
{
|
||||
/*
|
||||
* This is called by the proxy SSH connection, to set our Seat
|
||||
* into a given trust status. We can safely do nothing here and
|
||||
* return true to claim we did something (effectively eliminating
|
||||
* the spoofing defences completely, by suppressing the 'press
|
||||
* Return to begin session' prompt and not providing anything in
|
||||
* place of it), on the basis that session I/O from the proxy SSH
|
||||
* connection is never passed directly on to the end user, so a
|
||||
* malicious proxy SSH server wouldn't be able to spoof our human
|
||||
* in any case.
|
||||
* into a given trust status. We can safely do nothing here, and
|
||||
* have can_set_trust_status return true to claim we did something
|
||||
* (effectively eliminating the spoofing defences completely, by
|
||||
* suppressing the 'press Return to begin session' prompt and not
|
||||
* providing anything in place of it), on the basis that session
|
||||
* I/O from the proxy SSH connection is never passed directly on
|
||||
* to the end user, so a malicious proxy SSH server wouldn't be
|
||||
* able to spoof our human in any case.
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool sshproxy_can_set_trust_status(Seat *seat)
|
||||
{
|
||||
return true; /* see comment above */
|
||||
}
|
||||
|
||||
static const SeatVtable SshProxy_seat_vt = {
|
||||
@ -442,6 +446,7 @@ static const SeatVtable SshProxy_seat_vt = {
|
||||
.get_window_pixel_size = nullseat_get_window_pixel_size,
|
||||
.stripctrl_new = nullseat_stripctrl_new,
|
||||
.set_trust_status = sshproxy_set_trust_status,
|
||||
.can_set_trust_status = sshproxy_can_set_trust_status,
|
||||
.verbose = nullseat_verbose_no,
|
||||
.interactive = nullseat_interactive_no,
|
||||
.get_cursor_position = nullseat_get_cursor_position,
|
||||
|
@ -321,7 +321,16 @@ int console_askappend(LogPolicy *lp, Filename *filename,
|
||||
}
|
||||
|
||||
bool console_antispoof_prompt = true;
|
||||
bool console_set_trust_status(Seat *seat, bool trusted)
|
||||
|
||||
void console_set_trust_status(Seat *seat, bool trusted)
|
||||
{
|
||||
/* Do nothing in response to a change of trust status, because
|
||||
* there's nothing we can do in a console environment. However,
|
||||
* the query function below will make a fiddly decision about
|
||||
* whether to tell the backend to enable fallback handling. */
|
||||
}
|
||||
|
||||
bool console_can_set_trust_status(Seat *seat)
|
||||
{
|
||||
if (console_batch_mode || !is_interactive() || !console_antispoof_prompt) {
|
||||
/*
|
||||
@ -334,8 +343,8 @@ bool console_set_trust_status(Seat *seat, bool trusted)
|
||||
* prompt, the user couldn't respond to it via the terminal
|
||||
* anyway.
|
||||
*
|
||||
* We also vacuously return success if the user has purposely
|
||||
* disabled the antispoof prompt.
|
||||
* We also return true without enabling any defences if the
|
||||
* user has purposely disabled the antispoof prompt.
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
@ -407,6 +407,7 @@ static const SeatVtable plink_seat_vt = {
|
||||
.get_window_pixel_size = nullseat_get_window_pixel_size,
|
||||
.stripctrl_new = console_stripctrl_new,
|
||||
.set_trust_status = console_set_trust_status,
|
||||
.can_set_trust_status = console_can_set_trust_status,
|
||||
.verbose = cmdline_seat_verbose,
|
||||
.interactive = plink_seat_interactive,
|
||||
.get_cursor_position = nullseat_get_cursor_position,
|
||||
|
@ -383,7 +383,8 @@ static const char *gtk_seat_get_x_display(Seat *seat);
|
||||
#ifndef NOT_X_WINDOWS
|
||||
static bool gtk_seat_get_windowid(Seat *seat, long *id);
|
||||
#endif
|
||||
static bool gtk_seat_set_trust_status(Seat *seat, bool trusted);
|
||||
static void gtk_seat_set_trust_status(Seat *seat, bool trusted);
|
||||
static bool gtk_seat_can_set_trust_status(Seat *seat);
|
||||
static bool gtk_seat_get_cursor_position(Seat *seat, int *x, int *y);
|
||||
|
||||
static const SeatVtable gtk_seat_vt = {
|
||||
@ -411,6 +412,7 @@ static const SeatVtable gtk_seat_vt = {
|
||||
.get_window_pixel_size = gtk_seat_get_window_pixel_size,
|
||||
.stripctrl_new = gtk_seat_stripctrl_new,
|
||||
.set_trust_status = gtk_seat_set_trust_status,
|
||||
.can_set_trust_status = gtk_seat_can_set_trust_status,
|
||||
.verbose = nullseat_verbose_yes,
|
||||
.interactive = nullseat_interactive_yes,
|
||||
.get_cursor_position = gtk_seat_get_cursor_position,
|
||||
@ -5415,10 +5417,14 @@ void new_session_window(Conf *conf, const char *geometry_string)
|
||||
ldisc_echoedit_update(inst->ldisc); /* cause ldisc to notice changes */
|
||||
}
|
||||
|
||||
static bool gtk_seat_set_trust_status(Seat *seat, bool trusted)
|
||||
static void gtk_seat_set_trust_status(Seat *seat, bool trusted)
|
||||
{
|
||||
GtkFrontend *inst = container_of(seat, GtkFrontend, seat);
|
||||
term_set_trust_status(inst->term, trusted);
|
||||
}
|
||||
|
||||
static bool gtk_seat_can_set_trust_status(Seat *seat)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -35,8 +35,9 @@ bool nullseat_get_window_pixel_size(
|
||||
Seat *seat, int *width, int *height) { return false; }
|
||||
StripCtrlChars *nullseat_stripctrl_new(
|
||||
Seat *seat, BinarySink *bs_out, SeatInteractionContext sic) {return NULL;}
|
||||
bool nullseat_set_trust_status(Seat *seat, bool tr) { return false; }
|
||||
bool nullseat_set_trust_status_vacuously(Seat *seat, bool tr) { return true; }
|
||||
void nullseat_set_trust_status(Seat *seat, bool trusted) {}
|
||||
bool nullseat_can_set_trust_status_yes(Seat *seat) { return true; }
|
||||
bool nullseat_can_set_trust_status_no(Seat *seat) { return false; }
|
||||
bool nullseat_verbose_no(Seat *seat) { return false; }
|
||||
bool nullseat_verbose_yes(Seat *seat) { return true; }
|
||||
bool nullseat_interactive_no(Seat *seat) { return false; }
|
||||
|
@ -187,7 +187,16 @@ bool is_interactive(void)
|
||||
}
|
||||
|
||||
bool console_antispoof_prompt = true;
|
||||
bool console_set_trust_status(Seat *seat, bool trusted)
|
||||
|
||||
void console_set_trust_status(Seat *seat, bool trusted)
|
||||
{
|
||||
/* Do nothing in response to a change of trust status, because
|
||||
* there's nothing we can do in a console environment. However,
|
||||
* the query function below will make a fiddly decision about
|
||||
* whether to tell the backend to enable fallback handling. */
|
||||
}
|
||||
|
||||
bool console_can_set_trust_status(Seat *seat)
|
||||
{
|
||||
if (console_batch_mode || !is_interactive() || !console_antispoof_prompt) {
|
||||
/*
|
||||
@ -200,8 +209,8 @@ bool console_set_trust_status(Seat *seat, bool trusted)
|
||||
* prompt, the user couldn't respond to it via the terminal
|
||||
* anyway.
|
||||
*
|
||||
* We also vacuously return success if the user has purposely
|
||||
* disabled the antispoof prompt.
|
||||
* We also return true without enabling any defences if the
|
||||
* user has purposely disabled the antispoof prompt.
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
@ -101,6 +101,7 @@ static const SeatVtable plink_seat_vt = {
|
||||
.get_window_pixel_size = nullseat_get_window_pixel_size,
|
||||
.stripctrl_new = console_stripctrl_new,
|
||||
.set_trust_status = console_set_trust_status,
|
||||
.can_set_trust_status = console_can_set_trust_status,
|
||||
.verbose = cmdline_seat_verbose,
|
||||
.interactive = plink_seat_interactive,
|
||||
.get_cursor_position = nullseat_get_cursor_position,
|
||||
|
@ -323,7 +323,8 @@ static void win_seat_notify_remote_exit(Seat *seat);
|
||||
static void win_seat_connection_fatal(Seat *seat, const char *msg);
|
||||
static void win_seat_update_specials_menu(Seat *seat);
|
||||
static void win_seat_set_busy_status(Seat *seat, BusyStatus status);
|
||||
static bool win_seat_set_trust_status(Seat *seat, bool trusted);
|
||||
static void win_seat_set_trust_status(Seat *seat, bool trusted);
|
||||
static bool win_seat_can_set_trust_status(Seat *seat);
|
||||
static bool win_seat_get_cursor_position(Seat *seat, int *x, int *y);
|
||||
static bool win_seat_get_window_pixel_size(Seat *seat, int *x, int *y);
|
||||
|
||||
@ -348,6 +349,7 @@ static const SeatVtable win_seat_vt = {
|
||||
.get_window_pixel_size = win_seat_get_window_pixel_size,
|
||||
.stripctrl_new = win_seat_stripctrl_new,
|
||||
.set_trust_status = win_seat_set_trust_status,
|
||||
.can_set_trust_status = win_seat_can_set_trust_status,
|
||||
.verbose = nullseat_verbose_yes,
|
||||
.interactive = nullseat_interactive_yes,
|
||||
.get_cursor_position = win_seat_get_cursor_position,
|
||||
@ -5753,9 +5755,13 @@ static int win_seat_get_userpass_input(
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool win_seat_set_trust_status(Seat *seat, bool trusted)
|
||||
static void win_seat_set_trust_status(Seat *seat, bool trusted)
|
||||
{
|
||||
term_set_trust_status(term, trusted);
|
||||
}
|
||||
|
||||
static bool win_seat_can_set_trust_status(Seat *seat)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user