mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 09:27:59 +00:00
Seat method to set the current trust status.
In terminal-based GUI applications, this is passed through to term_set_trust_status, to toggle whether lines are prefixed with the new trust sigil. In console applications, the function returns false, indicating to the backend that it should employ some other technique for spoofing protection.
This commit is contained in:
parent
9c367eba4c
commit
76d8d363be
2
misc.c
2
misc.c
@ -343,6 +343,8 @@ 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 sk_free_peer_info(SocketPeerInfo *pi)
|
||||
{
|
||||
|
1
pscp.c
1
pscp.c
@ -81,6 +81,7 @@ static const SeatVtable pscp_seat_vt = {
|
||||
nullseat_get_windowid,
|
||||
nullseat_get_window_pixel_size,
|
||||
console_stripctrl_new,
|
||||
nullseat_set_trust_status_vacuously,
|
||||
};
|
||||
static Seat pscp_seat[1] = {{ &pscp_seat_vt }};
|
||||
|
||||
|
1
psftp.c
1
psftp.c
@ -62,6 +62,7 @@ static const SeatVtable psftp_seat_vt = {
|
||||
nullseat_get_windowid,
|
||||
nullseat_get_window_pixel_size,
|
||||
console_stripctrl_new,
|
||||
nullseat_set_trust_status_vacuously,
|
||||
};
|
||||
static Seat psftp_seat[1] = {{ &psftp_seat_vt }};
|
||||
|
||||
|
21
putty.h
21
putty.h
@ -952,6 +952,20 @@ struct SeatVtable {
|
||||
*/
|
||||
StripCtrlChars *(*stripctrl_new)(
|
||||
Seat *seat, BinarySink *bs_out, SeatInteractionContext sic);
|
||||
|
||||
/*
|
||||
* Set the seat's current idea of where output is coming from.
|
||||
* True means that output is being generated by our own code base
|
||||
* (and hence, can be trusted if it's asking you for secrets such
|
||||
* as your passphrase); false means output is coming from the
|
||||
* server.
|
||||
*
|
||||
* 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);
|
||||
};
|
||||
|
||||
static inline size_t seat_output(
|
||||
@ -995,6 +1009,8 @@ 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); }
|
||||
|
||||
/* Unlike the seat's actual method, the public entry point
|
||||
* seat_connection_fatal is a wrapper function with a printf-like API,
|
||||
@ -1045,6 +1061,8 @@ 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);
|
||||
|
||||
/*
|
||||
* Seat functions provided by the platform's console-application
|
||||
@ -1064,6 +1082,7 @@ 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);
|
||||
|
||||
/*
|
||||
* Other centralised seat functions.
|
||||
@ -1627,7 +1646,7 @@ void term_provide_logctx(Terminal *term, LogContext *logctx);
|
||||
void term_set_focus(Terminal *term, bool has_focus);
|
||||
char *term_get_ttymode(Terminal *term, const char *mode);
|
||||
int term_get_userpass_input(Terminal *term, prompts_t *p, bufchain *input);
|
||||
void term_set_trust_status(Terminal *term, SeatTrustStatus status);
|
||||
void term_set_trust_status(Terminal *term, bool trusted);
|
||||
|
||||
typedef enum SmallKeypadKey {
|
||||
SKK_HOME, SKK_END, SKK_INSERT, SKK_DELETE, SKK_PGUP, SKK_PGDN,
|
||||
|
3
raw.c
3
raw.c
@ -130,6 +130,9 @@ static const char *raw_init(Seat *seat, Backend **backend_handle,
|
||||
int addressfamily;
|
||||
char *loghost;
|
||||
|
||||
/* No local authentication phase in this protocol */
|
||||
seat_set_trust_status(seat, false);
|
||||
|
||||
raw = snew(Raw);
|
||||
raw->plug.vt = &Raw_plugvt;
|
||||
raw->backend.vt = &raw_backend;
|
||||
|
@ -194,6 +194,7 @@ static const SeatVtable sesschan_seat_vt = {
|
||||
nullseat_get_windowid,
|
||||
sesschan_get_window_pixel_size,
|
||||
nullseat_stripctrl_new,
|
||||
nullseat_set_trust_status,
|
||||
};
|
||||
|
||||
Channel *sesschan_new(SshChannel *c, LogContext *logctx,
|
||||
|
@ -485,9 +485,11 @@ static void ssh2_userauth_process_queue(PacketProtocolLayer *ppl)
|
||||
*/
|
||||
if (bufchain_size(&s->banner) &&
|
||||
(flags & (FLAG_VERBOSE | FLAG_INTERACTIVE))) {
|
||||
if (s->banner_scc)
|
||||
if (s->banner_scc) {
|
||||
ssh2_userauth_antispoof_msg(
|
||||
s, "Pre-authentication banner message from server:");
|
||||
seat_set_trust_status(s->ppl.seat, false);
|
||||
}
|
||||
|
||||
bool mid_line = false;
|
||||
while (bufchain_size(&s->banner) > 0) {
|
||||
@ -502,9 +504,11 @@ static void ssh2_userauth_process_queue(PacketProtocolLayer *ppl)
|
||||
if (mid_line)
|
||||
seat_stderr_pl(s->ppl.seat, PTRLEN_LITERAL("\r\n"));
|
||||
|
||||
if (s->banner_scc)
|
||||
if (s->banner_scc) {
|
||||
seat_set_trust_status(s->ppl.seat, true);
|
||||
ssh2_userauth_antispoof_msg(
|
||||
s, "End of banner message from server");
|
||||
}
|
||||
}
|
||||
|
||||
if (pktin && pktin->type == SSH2_MSG_USERAUTH_SUCCESS) {
|
||||
@ -1269,6 +1273,7 @@ static void ssh2_userauth_process_queue(PacketProtocolLayer *ppl)
|
||||
s, "Keyboard-interactive authentication "
|
||||
"prompts from server:");
|
||||
s->ki_printed_header = true;
|
||||
seat_set_trust_status(s->ppl.seat, false);
|
||||
}
|
||||
|
||||
sb = strbuf_new();
|
||||
@ -1359,9 +1364,11 @@ static void ssh2_userauth_process_queue(PacketProtocolLayer *ppl)
|
||||
/*
|
||||
* Print our trailer line, if we printed a header.
|
||||
*/
|
||||
if (s->ki_printed_header)
|
||||
if (s->ki_printed_header) {
|
||||
seat_set_trust_status(s->ppl.seat, true);
|
||||
ssh2_userauth_antispoof_msg(
|
||||
s, "End of keyboard-interactive prompts from server");
|
||||
}
|
||||
|
||||
/*
|
||||
* We should have SUCCESS or FAILURE now.
|
||||
@ -1835,9 +1842,23 @@ static void ssh2_userauth_antispoof_msg(
|
||||
struct ssh2_userauth_state *s, const char *msg)
|
||||
{
|
||||
strbuf *sb = strbuf_new();
|
||||
strbuf_catf(sb, "-- %s ", msg);
|
||||
while (sb->len < 78)
|
||||
put_byte(sb, '-');
|
||||
if (seat_set_trust_status(s->ppl.seat, true)) {
|
||||
/*
|
||||
* If the seat can directly indicate that this message is
|
||||
* generated by the client, then we can just use the message
|
||||
* unmodified as an unspoofable header.
|
||||
*/
|
||||
put_datapl(sb, ptrlen_from_asciz(msg));
|
||||
} else {
|
||||
/*
|
||||
* Otherwise, add enough padding around it that the server
|
||||
* wouldn't be able to mimic it within our line-length
|
||||
* constraint.
|
||||
*/
|
||||
strbuf_catf(sb, "-- %s ", msg);
|
||||
while (sb->len < 78)
|
||||
put_byte(sb, '-');
|
||||
}
|
||||
put_datapl(sb, PTRLEN_LITERAL("\r\n"));
|
||||
seat_stderr_pl(s->ppl.seat, ptrlen_from_strbuf(sb));
|
||||
strbuf_free(sb);
|
||||
|
@ -114,6 +114,7 @@ static const SeatVtable server_seat_vt = {
|
||||
nullseat_get_windowid,
|
||||
nullseat_get_window_pixel_size,
|
||||
nullseat_stripctrl_new,
|
||||
nullseat_set_trust_status,
|
||||
};
|
||||
|
||||
static void server_socket_log(Plug *plug, int type, SockAddr *addr, int port,
|
||||
|
3
telnet.c
3
telnet.c
@ -689,6 +689,9 @@ static const char *telnet_init(Seat *seat, Backend **backend_handle,
|
||||
char *loghost;
|
||||
int addressfamily;
|
||||
|
||||
/* No local authentication phase in this protocol */
|
||||
seat_set_trust_status(seat, false);
|
||||
|
||||
telnet = snew(Telnet);
|
||||
telnet->plug.vt = &Telnet_plugvt;
|
||||
telnet->backend.vt = &telnet_backend;
|
||||
|
@ -1810,12 +1810,9 @@ void term_free(Terminal *term)
|
||||
sfree(term);
|
||||
}
|
||||
|
||||
void term_set_trust_status(Terminal *term, SeatTrustStatus status)
|
||||
void term_set_trust_status(Terminal *term, bool trusted)
|
||||
{
|
||||
/* We don't need to distinguish STS_UNTRUSTED from STS_SESSION,
|
||||
* because the terminal's method of communicating trust can flip
|
||||
* back and forth between trusted and untrusted easily. */
|
||||
term->trusted = (status == STS_TRUSTED);
|
||||
term->trusted = trusted;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -76,6 +76,9 @@ static const char *null_init(Seat *seat, Backend **backend_handle,
|
||||
LogContext *logctx, Conf *conf,
|
||||
const char *host, int port, char **realhost,
|
||||
int nodelay, int keepalive) {
|
||||
/* No local authentication phase in this protocol */
|
||||
seat_set_trust_status(seat, false);
|
||||
|
||||
*backend_handle = NULL;
|
||||
return NULL;
|
||||
}
|
||||
@ -86,6 +89,9 @@ static const char *loop_init(Seat *seat, Backend **backend_handle,
|
||||
int nodelay, int keepalive) {
|
||||
struct loop_state *st = snew(struct loop_state);
|
||||
|
||||
/* No local authentication phase in this protocol */
|
||||
seat_set_trust_status(seat, false);
|
||||
|
||||
st->seat = seat;
|
||||
*backend_handle = &st->backend;
|
||||
return NULL;
|
||||
|
@ -373,6 +373,7 @@ 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 const SeatVtable gtk_seat_vt = {
|
||||
gtk_seat_output,
|
||||
@ -396,6 +397,7 @@ static const SeatVtable gtk_seat_vt = {
|
||||
#endif
|
||||
gtk_seat_get_window_pixel_size,
|
||||
gtk_seat_stripctrl_new,
|
||||
gtk_seat_set_trust_status,
|
||||
};
|
||||
|
||||
static void gtk_eventlog(LogPolicy *lp, const char *string)
|
||||
@ -5503,3 +5505,10 @@ void new_session_window(Conf *conf, const char *geometry_string)
|
||||
if (inst->ldisc) /* early backend failure might make this NULL already */
|
||||
ldisc_echoedit_update(inst->ldisc); /* cause ldisc to notice changes */
|
||||
}
|
||||
|
||||
static bool gtk_seat_set_trust_status(Seat *seat, bool trusted)
|
||||
{
|
||||
GtkFrontend *inst = container_of(seat, GtkFrontend, seat);
|
||||
term_set_trust_status(inst->term, trusted);
|
||||
return true;
|
||||
}
|
||||
|
@ -414,6 +414,11 @@ static int console_askappend(LogPolicy *lp, Filename *filename,
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool console_set_trust_status(Seat *seat, bool trusted)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Warn about the obsolescent key file format.
|
||||
*
|
||||
|
@ -401,6 +401,7 @@ static const SeatVtable plink_seat_vt = {
|
||||
nullseat_get_windowid,
|
||||
nullseat_get_window_pixel_size,
|
||||
console_stripctrl_new,
|
||||
console_set_trust_status,
|
||||
};
|
||||
static Seat plink_seat[1] = {{ &plink_seat_vt }};
|
||||
|
||||
|
@ -868,6 +868,9 @@ Backend *pty_backend_create(
|
||||
Pty *pty;
|
||||
int i;
|
||||
|
||||
/* No local authentication phase in this protocol */
|
||||
seat_set_trust_status(seat, false);
|
||||
|
||||
if (single_pty) {
|
||||
pty = single_pty;
|
||||
assert(pty->conf == NULL);
|
||||
|
@ -288,6 +288,9 @@ static const char *serial_init(Seat *seat, Backend **backend_handle,
|
||||
const char *err;
|
||||
char *line;
|
||||
|
||||
/* No local authentication phase in this protocol */
|
||||
seat_set_trust_status(seat, false);
|
||||
|
||||
serial = snew(Serial);
|
||||
serial->backend.vt = &serial_backend;
|
||||
*backend_handle = &serial->backend;
|
||||
|
@ -279,6 +279,11 @@ int console_confirm_weak_cached_hostkey(
|
||||
}
|
||||
}
|
||||
|
||||
bool console_set_trust_status(Seat *seat, bool trusted)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ask whether to wipe a session log file before writing to it.
|
||||
* Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
|
||||
|
@ -339,6 +339,7 @@ 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 const SeatVtable win_seat_vt = {
|
||||
win_seat_output,
|
||||
@ -358,6 +359,7 @@ static const SeatVtable win_seat_vt = {
|
||||
nullseat_get_windowid,
|
||||
win_seat_get_window_pixel_size,
|
||||
win_seat_stripctrl_new,
|
||||
win_seat_set_trust_status,
|
||||
};
|
||||
static Seat win_seat_impl = { &win_seat_vt };
|
||||
Seat *const win_seat = &win_seat_impl;
|
||||
@ -5824,3 +5826,9 @@ void agent_schedule_callback(void (*callback)(void *, void *, int),
|
||||
c->len = len;
|
||||
PostMessage(hwnd, WM_AGENT_CALLBACK, 0, (LPARAM)c);
|
||||
}
|
||||
|
||||
static bool win_seat_set_trust_status(Seat *seat, bool trusted)
|
||||
{
|
||||
term_set_trust_status(term, trusted);
|
||||
return true;
|
||||
}
|
||||
|
@ -106,6 +106,7 @@ static const SeatVtable plink_seat_vt = {
|
||||
nullseat_get_windowid,
|
||||
nullseat_get_window_pixel_size,
|
||||
console_stripctrl_new,
|
||||
console_set_trust_status,
|
||||
};
|
||||
static Seat plink_seat[1] = {{ &plink_seat_vt }};
|
||||
|
||||
|
@ -201,6 +201,9 @@ static const char *serial_init(Seat *seat, Backend **backend_handle,
|
||||
const char *err;
|
||||
char *serline;
|
||||
|
||||
/* No local authentication phase in this protocol */
|
||||
seat_set_trust_status(seat, false);
|
||||
|
||||
serial = snew(Serial);
|
||||
serial->port = INVALID_HANDLE_VALUE;
|
||||
serial->out = serial->in = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user