1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-06-30 19:12:48 -05:00

Allow new_connection to take an optional Seat. (NFC)

This is working towards allowing the subsidiary SSH connection in an
SshProxy to share the main user-facing Seat, so as to be able to pass
through interactive prompts.

This is more difficult than the similar change with LogPolicy, because
Seats are stateful. In particular, the trust-sigil status will need to
be controlled by the SshProxy until it's ready to pass over control to
the main SSH (or whatever) connection.

To make this work, I've introduced a thing called a TempSeat, which is
(yet) another Seat implementation. When a backend hands its Seat to
new_connection(), it does it in a way that allows new_connection() to
borrow it completely, and replace it in the main backend structure
with a TempSeat, which acts as a temporary placeholder. If the main
backend tries to do things like changing trust status or sending
output, the TempSeat will buffer them; later on, when the connection
is established, TempSeat will replay the changes into the real Seat.

So, in each backend, I've made the following changes:
 - pass &foo->seat to new_connection, which may overwrite it with a
   TempSeat.
 - if it has done so (which we can tell via the is_tempseat() query
   function), then we have to free the TempSeat and reinstate our main
   Seat. The signal that we can do so is the PLUGLOG_CONNECT_SUCCESS
   notification, which indicates that SshProxy has finished all its
   connection setup work.
 - we also have to remember to free the TempSeat if our backend is
   disposed of without that having happened (e.g. because the
   connection _doesn't_ succeed).
 - in backends which have no local auth phase to worry about, ensure
   we don't call seat_set_trust_status on the main Seat _before_ it
   gets potentially replaced with a TempSeat. Moved some calls of
   seat_set_trust_status to just after new_connection(), so that now
   the initial trust status setup will go into the TempSeat (if
   appropriate) and be buffered until that seat is relinquished.

In all other uses of new_connection, where we don't have a Seat
available at all, we just pass NULL.

This is NFC, because neither new_connection() nor any of its delegates
will _actually_ do this replacement yet. We're just setting up the
framework to enable it to do so in the next commit.
This commit is contained in:
Simon Tatham
2021-09-13 17:17:20 +01:00
parent a08f953bd6
commit 6d272ee007
14 changed files with 465 additions and 21 deletions

25
putty.h
View File

@ -1295,6 +1295,31 @@ bool console_can_set_trust_status(Seat *seat);
int filexfer_get_userpass_input(Seat *seat, prompts_t *p, bufchain *input);
bool cmdline_seat_verbose(Seat *seat);
/*
* TempSeat: a seat implementation that can be given to a backend
* temporarily while network proxy setup is using the real seat.
* Buffers output and trust-status changes until the real seat is
* available again.
*/
/* Called by the proxy code to make a TempSeat. */
Seat *tempseat_new(Seat *real);
/* Query functions to tell if a Seat _is_ temporary, and if so, to
* return the underlying real Seat. */
bool is_tempseat(Seat *seat);
Seat *tempseat_get_real(Seat *seat);
/* Called by the backend once the proxy connection has finished
* setting up (or failed), to pass on any buffered stuff to the real
* seat. */
void tempseat_flush(Seat *ts);
/* Frees a TempSeat, without flushing anything it has buffered. (Call
* this after tempseat_flush, or alternatively, when you were going to
* abandon the whole connection anyway.) */
void tempseat_free(Seat *ts);
typedef struct rgb {
uint8_t r, g, b;
} rgb;