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:
@ -1161,7 +1161,7 @@ char *portfwdmgr_connect(PortFwdManager *mgr, Channel **chan_ret,
|
||||
|
||||
pf->s = new_connection(addr, dummy_realhost, port,
|
||||
false, true, false, false, &pf->plug, mgr->conf,
|
||||
NULL);
|
||||
NULL, NULL);
|
||||
sfree(dummy_realhost);
|
||||
if ((err = sk_socket_error(pf->s)) != NULL) {
|
||||
char *err_ret = dupstr(err);
|
||||
|
14
ssh/ssh.c
14
ssh/ssh.c
@ -598,6 +598,15 @@ static void ssh_socket_log(Plug *plug, PlugLogType type, SockAddr *addr,
|
||||
backend_socket_log(ssh->seat, ssh->logctx, type, addr, port,
|
||||
error_msg, error_code, ssh->conf,
|
||||
ssh->session_started);
|
||||
|
||||
if (type == PLUGLOG_CONNECT_SUCCESS) {
|
||||
if (is_tempseat(ssh->seat)) {
|
||||
Seat *ts = ssh->seat;
|
||||
tempseat_flush(ts);
|
||||
ssh->seat = tempseat_get_real(ts);
|
||||
tempseat_free(ts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ssh_closing(Plug *plug, const char *error_msg, int error_code,
|
||||
@ -790,7 +799,7 @@ static char *connect_to_host(
|
||||
ssh->s = new_connection(addr, *realhost, port,
|
||||
false, true, nodelay, keepalive,
|
||||
&ssh->plug, ssh->conf,
|
||||
log_get_policy(ssh->logctx));
|
||||
log_get_policy(ssh->logctx), &ssh->seat);
|
||||
if ((err = sk_socket_error(ssh->s)) != NULL) {
|
||||
ssh->s = NULL;
|
||||
seat_notify_remote_exit(ssh->seat);
|
||||
@ -955,6 +964,9 @@ static void ssh_free(Backend *be)
|
||||
|
||||
ssh_shutdown(ssh);
|
||||
|
||||
if (is_tempseat(ssh->seat))
|
||||
tempseat_free(ssh->seat);
|
||||
|
||||
conf_free(ssh->conf);
|
||||
if (ssh->connshare)
|
||||
sharestate_free(ssh->connshare);
|
||||
|
@ -564,7 +564,7 @@ static size_t x11_send(
|
||||
xconn->s = new_connection(sk_addr_dup(xconn->disp->addr),
|
||||
xconn->disp->realhost, xconn->disp->port,
|
||||
false, true, false, false, &xconn->plug,
|
||||
sshfwd_get_conf(xconn->c), NULL);
|
||||
sshfwd_get_conf(xconn->c), NULL, NULL);
|
||||
if ((err = sk_socket_error(xconn->s)) != NULL) {
|
||||
char *err_message = dupprintf("unable to connect to"
|
||||
" forwarded X server: %s", err);
|
||||
|
Reference in New Issue
Block a user