diff --git a/misc.c b/misc.c index fea296b6..30b7c7d3 100644 --- a/misc.c +++ b/misc.c @@ -333,6 +333,8 @@ const char *nullseat_get_x_display(Seat *seat) { return NULL; } bool nullseat_get_windowid(Seat *seat, long *id_out) { return false; } bool nullseat_get_window_pixel_size( Seat *seat, int *width, int *height) { return false; } +StripCtrlChars *nullseat_stripctrl_new( + Seat *seat, BinarySink *bs, bool cr, wchar_t sub) { return NULL; } void sk_free_peer_info(SocketPeerInfo *pi) { diff --git a/pscp.c b/pscp.c index 367cb28a..17f03dac 100644 --- a/pscp.c +++ b/pscp.c @@ -80,6 +80,7 @@ static const SeatVtable pscp_seat_vt = { nullseat_get_x_display, nullseat_get_windowid, nullseat_get_window_pixel_size, + console_stripctrl_new, }; static Seat pscp_seat[1] = {{ &pscp_seat_vt }}; diff --git a/psftp.c b/psftp.c index 7adbab70..9d90deba 100644 --- a/psftp.c +++ b/psftp.c @@ -61,6 +61,7 @@ static const SeatVtable psftp_seat_vt = { nullseat_get_x_display, nullseat_get_windowid, nullseat_get_window_pixel_size, + console_stripctrl_new, }; static Seat psftp_seat[1] = {{ &psftp_seat_vt }}; diff --git a/putty.h b/putty.h index e3767eec..9a67b932 100644 --- a/putty.h +++ b/putty.h @@ -930,6 +930,15 @@ struct SeatVtable { * true. */ bool (*get_window_pixel_size)(Seat *seat, int *width, int *height); + + /* + * Return a StripCtrlChars appropriate for sanitising untrusted + * terminal data (e.g. SSH banners, prompts) being sent to the + * user of this seat. May return NULL if no sanitisation is + * needed. + */ + StripCtrlChars *(*stripctrl_new)(Seat *seat, BinarySink *bs_out, + bool permit_cr, wchar_t substitution); }; static inline size_t seat_output( @@ -970,6 +979,9 @@ static inline bool seat_get_windowid(Seat *seat, long *id_out) { return seat->vt->get_windowid(seat, id_out); } static inline bool seat_get_window_pixel_size(Seat *seat, int *w, int *h) { return seat->vt->get_window_pixel_size(seat, w, h); } +static inline StripCtrlChars *seat_stripctrl_new( + Seat *seat, BinarySink *bs, bool cr, wchar_t sub) +{ return seat->vt->stripctrl_new(seat, bs, cr, sub); } /* Unlike the seat's actual method, the public entry point * seat_connection_fatal is a wrapper function with a printf-like API, @@ -1014,6 +1026,8 @@ void nullseat_echoedit_update(Seat *seat, bool echoing, bool editing); const char *nullseat_get_x_display(Seat *seat); 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, + bool permit_cr, wchar_t substitution); /* * Seat functions provided by the platform's console-application @@ -1031,6 +1045,8 @@ int console_confirm_weak_crypto_primitive( int console_confirm_weak_cached_hostkey( Seat *seat, const char *algname, const char *betteralgs, void (*callback)(void *ctx, int result), void *ctx); +StripCtrlChars *console_stripctrl_new(Seat *seat, BinarySink *bs_out, + bool permit_cr, wchar_t substitution); /* * Other centralised seat functions. diff --git a/sesschan.c b/sesschan.c index b844e5b4..8a9a5d4e 100644 --- a/sesschan.c +++ b/sesschan.c @@ -193,6 +193,7 @@ static const SeatVtable sesschan_seat_vt = { nullseat_get_x_display, nullseat_get_windowid, sesschan_get_window_pixel_size, + nullseat_stripctrl_new, }; Channel *sesschan_new(SshChannel *c, LogContext *logctx, diff --git a/sshserver.c b/sshserver.c index d1b877b5..a27d38c0 100644 --- a/sshserver.c +++ b/sshserver.c @@ -113,6 +113,7 @@ static const SeatVtable server_seat_vt = { nullseat_get_x_display, nullseat_get_windowid, nullseat_get_window_pixel_size, + nullseat_stripctrl_new, }; static void server_socket_log(Plug *plug, int type, SockAddr *addr, int port, diff --git a/unix/gtkwin.c b/unix/gtkwin.c index 162e1f48..6532b9ff 100644 --- a/unix/gtkwin.c +++ b/unix/gtkwin.c @@ -351,6 +351,13 @@ static bool gtk_seat_get_window_pixel_size(Seat *seat, int *w, int *h) return true; } +StripCtrlChars *gtk_seat_stripctrl_new(Seat *seat, BinarySink *bs_out, + bool permit_cr, wchar_t substitution) +{ + GtkFrontend *inst = container_of(seat, GtkFrontend, seat); + return stripctrl_new_term(bs_out, permit_cr, substitution, inst->term); +} + static void gtk_seat_notify_remote_exit(Seat *seat); static void gtk_seat_update_specials_menu(Seat *seat); static void gtk_seat_set_busy_status(Seat *seat, BusyStatus status); @@ -380,6 +387,7 @@ static const SeatVtable gtk_seat_vt = { gtk_seat_get_windowid, #endif gtk_seat_get_window_pixel_size, + gtk_seat_stripctrl_new, }; static void gtk_eventlog(LogPolicy *lp, const char *string) diff --git a/unix/uxcons.c b/unix/uxcons.c index 6bb36e54..b74b21cd 100644 --- a/unix/uxcons.c +++ b/unix/uxcons.c @@ -465,6 +465,12 @@ static void console_eventlog(LogPolicy *lp, const char *string) console_logging_error(lp, string); } +StripCtrlChars *console_stripctrl_new(Seat *seat, BinarySink *bs_out, + bool permit_cr, wchar_t substitution) +{ + return stripctrl_new(bs_out, permit_cr, substitution); +} + /* * Special functions to read and print to the console for password * prompts and the like. Uses /dev/tty or stdin/stderr, in that order diff --git a/unix/uxplink.c b/unix/uxplink.c index f7fc1126..ed4cd91e 100644 --- a/unix/uxplink.c +++ b/unix/uxplink.c @@ -403,6 +403,7 @@ static const SeatVtable plink_seat_vt = { nullseat_get_x_display, nullseat_get_windowid, nullseat_get_window_pixel_size, + console_stripctrl_new, }; static Seat plink_seat[1] = {{ &plink_seat_vt }}; diff --git a/windows/wincons.c b/windows/wincons.c index c7d70a61..93d8f91d 100644 --- a/windows/wincons.c +++ b/windows/wincons.c @@ -388,6 +388,12 @@ static void console_eventlog(LogPolicy *lp, const char *string) console_logging_error(lp, string); } +StripCtrlChars *console_stripctrl_new(Seat *seat, BinarySink *bs_out, + bool permit_cr, wchar_t substitution) +{ + return stripctrl_new(bs_out, permit_cr, substitution); +} + static void console_data_untrusted(HANDLE hout, const char *data, size_t len) { DWORD dummy; diff --git a/windows/window.c b/windows/window.c index 6c1e1931..cd1e2169 100644 --- a/windows/window.c +++ b/windows/window.c @@ -320,6 +320,12 @@ bool win_seat_get_window_pixel_size(Seat *seat, int *x, int *y) return true; } +StripCtrlChars *win_seat_stripctrl_new(Seat *seat, BinarySink *bs_out, + bool permit_cr, wchar_t substitution) +{ + return stripctrl_new_term(bs_out, permit_cr, substitution, term); +} + static size_t win_seat_output( Seat *seat, bool is_stderr, const void *, size_t); static bool win_seat_eof(Seat *seat); @@ -347,6 +353,7 @@ static const SeatVtable win_seat_vt = { nullseat_get_x_display, nullseat_get_windowid, win_seat_get_window_pixel_size, + win_seat_stripctrl_new, }; static Seat win_seat_impl = { &win_seat_vt }; Seat *const win_seat = &win_seat_impl; diff --git a/windows/winplink.c b/windows/winplink.c index 37fb4890..c3e03afe 100644 --- a/windows/winplink.c +++ b/windows/winplink.c @@ -105,6 +105,7 @@ static const SeatVtable plink_seat_vt = { nullseat_get_x_display, nullseat_get_windowid, nullseat_get_window_pixel_size, + console_stripctrl_new, }; static Seat plink_seat[1] = {{ &plink_seat_vt }};