Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mRemoteNG/PuTTYNG.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Tatham <anakin@pobox.com>2021-09-13 19:17:20 +0300
committerSimon Tatham <anakin@pobox.com>2021-09-13 19:24:47 +0300
commit6d272ee007aab95f5bedc690371ecfcdda4fd079 (patch)
tree14aae9bb11bceb048a3449f1aa4487718561fa37 /otherbackends
parenta08f953bd6c1a3d19e125c7958243b64a0136823 (diff)
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.
Diffstat (limited to 'otherbackends')
-rw-r--r--otherbackends/raw.c19
-rw-r--r--otherbackends/rlogin.c13
-rw-r--r--otherbackends/supdup.c13
-rw-r--r--otherbackends/telnet.c19
4 files changed, 50 insertions, 14 deletions
diff --git a/otherbackends/raw.c b/otherbackends/raw.c
index 638e2a50..87a136ba 100644
--- a/otherbackends/raw.c
+++ b/otherbackends/raw.c
@@ -39,8 +39,15 @@ static void raw_log(Plug *plug, PlugLogType type, SockAddr *addr, int port,
Raw *raw = container_of(plug, Raw, plug);
backend_socket_log(raw->seat, raw->logctx, type, addr, port, error_msg,
error_code, raw->conf, raw->socket_connected);
- if (type == PLUGLOG_CONNECT_SUCCESS)
+ if (type == PLUGLOG_CONNECT_SUCCESS) {
raw->socket_connected = true;
+ if (is_tempseat(raw->seat)) {
+ Seat *ts = raw->seat;
+ tempseat_flush(ts);
+ raw->seat = tempseat_get_real(ts);
+ tempseat_free(ts);
+ }
+ }
}
static void raw_check_close(Raw *raw)
@@ -132,9 +139,6 @@ static char *raw_init(const BackendVtable *vt, Seat *seat,
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 = vt;
@@ -168,10 +172,13 @@ static char *raw_init(const BackendVtable *vt, Seat *seat,
*/
raw->s = new_connection(addr, *realhost, port, false, true, nodelay,
keepalive, &raw->plug, conf,
- log_get_policy(logctx));
+ log_get_policy(logctx), &raw->seat);
if ((err = sk_socket_error(raw->s)) != NULL)
return dupstr(err);
+ /* No local authentication phase in this protocol */
+ seat_set_trust_status(raw->seat, false);
+
loghost = conf_get_str(conf, CONF_loghost);
if (*loghost) {
char *colon;
@@ -191,6 +198,8 @@ static void raw_free(Backend *be)
{
Raw *raw = container_of(be, Raw, backend);
+ if (is_tempseat(raw->seat))
+ tempseat_free(raw->seat);
if (raw->s)
sk_close(raw->s);
conf_free(raw->conf);
diff --git a/otherbackends/rlogin.c b/otherbackends/rlogin.c
index 3748e536..ecdb2c36 100644
--- a/otherbackends/rlogin.c
+++ b/otherbackends/rlogin.c
@@ -45,8 +45,15 @@ static void rlogin_log(Plug *plug, PlugLogType type, SockAddr *addr, int port,
backend_socket_log(rlogin->seat, rlogin->logctx, type, addr, port,
error_msg, error_code,
rlogin->conf, rlogin->socket_connected);
- if (type == PLUGLOG_CONNECT_SUCCESS)
+ if (type == PLUGLOG_CONNECT_SUCCESS) {
rlogin->socket_connected = true;
+ if (is_tempseat(rlogin->seat)) {
+ Seat *ts = rlogin->seat;
+ tempseat_flush(ts);
+ rlogin->seat = tempseat_get_real(ts);
+ tempseat_free(ts);
+ }
+ }
}
static void rlogin_closing(Plug *plug, const char *error_msg, int error_code,
@@ -205,7 +212,7 @@ static char *rlogin_init(const BackendVtable *vt, Seat *seat,
*/
rlogin->s = new_connection(addr, *realhost, port, true, false,
nodelay, keepalive, &rlogin->plug, conf,
- log_get_policy(logctx));
+ log_get_policy(logctx), &rlogin->seat);
if ((err = sk_socket_error(rlogin->s)) != NULL)
return dupstr(err);
@@ -256,6 +263,8 @@ static void rlogin_free(Backend *be)
{
Rlogin *rlogin = container_of(be, Rlogin, backend);
+ if (is_tempseat(rlogin->seat))
+ tempseat_free(rlogin->seat);
if (rlogin->prompt)
free_prompts(rlogin->prompt);
if (rlogin->s)
diff --git a/otherbackends/supdup.c b/otherbackends/supdup.c
index cfa1b2ad..ae7e67f7 100644
--- a/otherbackends/supdup.c
+++ b/otherbackends/supdup.c
@@ -563,8 +563,15 @@ static void supdup_log(Plug *plug, PlugLogType type, SockAddr *addr, int port,
backend_socket_log(supdup->seat, supdup->logctx, type, addr, port,
error_msg, error_code,
supdup->conf, supdup->socket_connected);
- if (type == PLUGLOG_CONNECT_SUCCESS)
+ if (type == PLUGLOG_CONNECT_SUCCESS) {
supdup->socket_connected = true;
+ if (is_tempseat(supdup->seat)) {
+ Seat *ts = supdup->seat;
+ tempseat_flush(ts);
+ supdup->seat = tempseat_get_real(ts);
+ tempseat_free(ts);
+ }
+ }
}
static void supdup_closing(Plug *plug, const char *error_msg, int error_code,
@@ -713,7 +720,7 @@ static char *supdup_init(const BackendVtable *x, Seat *seat,
*/
supdup->s = new_connection(addr, *realhost, port, false, true,
nodelay, keepalive, &supdup->plug, supdup->conf,
- log_get_policy(logctx));
+ log_get_policy(logctx), &supdup->seat);
if ((err = sk_socket_error(supdup->s)) != NULL)
return dupstr(err);
@@ -783,6 +790,8 @@ static void supdup_free(Backend *be)
{
Supdup *supdup = container_of(be, Supdup, backend);
+ if (is_tempseat(supdup->seat))
+ tempseat_free(supdup->seat);
if (supdup->s)
sk_close(supdup->s);
if (supdup->pinger)
diff --git a/otherbackends/telnet.c b/otherbackends/telnet.c
index b006305d..540d384c 100644
--- a/otherbackends/telnet.c
+++ b/otherbackends/telnet.c
@@ -626,8 +626,15 @@ static void telnet_log(Plug *plug, PlugLogType type, SockAddr *addr, int port,
backend_socket_log(telnet->seat, telnet->logctx, type, addr, port,
error_msg, error_code, telnet->conf,
telnet->socket_connected);
- if (type == PLUGLOG_CONNECT_SUCCESS)
+ if (type == PLUGLOG_CONNECT_SUCCESS) {
telnet->socket_connected = true;
+ if (is_tempseat(telnet->seat)) {
+ Seat *ts = telnet->seat;
+ tempseat_flush(ts);
+ telnet->seat = tempseat_get_real(ts);
+ tempseat_free(ts);
+ }
+ }
}
static void telnet_closing(Plug *plug, const char *error_msg, int error_code,
@@ -698,9 +705,6 @@ static char *telnet_init(const BackendVtable *vt, Seat *seat,
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 = vt;
@@ -740,10 +744,13 @@ static char *telnet_init(const BackendVtable *vt, Seat *seat,
*/
telnet->s = new_connection(addr, *realhost, port, false, true, nodelay,
keepalive, &telnet->plug, telnet->conf,
- log_get_policy(logctx));
+ log_get_policy(logctx), &telnet->seat);
if ((err = sk_socket_error(telnet->s)) != NULL)
return dupstr(err);
+ /* No local authentication phase in this protocol */
+ seat_set_trust_status(telnet->seat, false);
+
telnet->pinger = pinger_new(telnet->conf, &telnet->backend);
/*
@@ -797,6 +804,8 @@ static void telnet_free(Backend *be)
{
Telnet *telnet = container_of(be, Telnet, backend);
+ if (is_tempseat(telnet->seat))
+ tempseat_free(telnet->seat);
strbuf_free(telnet->sb_buf);
if (telnet->s)
sk_close(telnet->s);