Browse Source

PuTTY snapshot 57553bda (sshshare: notify cl when last downstream goes away - 2018-09-28)

Source commit: c41ad6a0ef7e1eaacdd7720d90c0af124f6a0563
Martin Prikryl 6 years ago
parent
commit
61c7b51420

+ 9 - 0
source/putty/doc/config.but

@@ -246,6 +246,15 @@ warned that the log file may not always be up to date as a result
 (although it will of course be flushed when it is closed, for instance
 (although it will of course be flushed when it is closed, for instance
 at the end of a session).
 at the end of a session).
 
 
+\S{config-logheader} \I{log file, header}\q{Include header}
+
+\cfg{winhelp-topic}{logging.header}
+
+This option allows you to choose whether to include a header line
+with the date and time when the log file is opened. It may be useful to
+disable this if the log file is being used as realtime input to other
+programs that don't expect the header line.
+
 \S{config-logssh} Options specific to \i{SSH packet log}ging
 \S{config-logssh} Options specific to \i{SSH packet log}ging
 
 
 These options only apply if SSH packet data is being logged.
 These options only apply if SSH packet data is being logged.

+ 1 - 1
source/putty/logging.c

@@ -103,7 +103,7 @@ static void logfopen_callback(void *vctx, int mode)
         }
         }
     }
     }
 
 
-    if (ctx->state == L_OPEN) {
+    if (ctx->state == L_OPEN && conf_get_int(ctx->conf, CONF_logheader)) {
 	/* Write header line into log file. */
 	/* Write header line into log file. */
 	tm = ltime();
 	tm = ltime();
 	strftime(buf, 24, "%Y.%m.%d %H:%M:%S", &tm);
 	strftime(buf, 24, "%Y.%m.%d %H:%M:%S", &tm);

+ 1 - 0
source/putty/putty.h

@@ -931,6 +931,7 @@ void cleanup_exit(int);
     X(INT, NONE, logtype) \
     X(INT, NONE, logtype) \
     X(INT, NONE, logxfovr) \
     X(INT, NONE, logxfovr) \
     X(INT, NONE, logflush) \
     X(INT, NONE, logflush) \
+    X(INT, NONE, logheader) \
     X(INT, NONE, logomitpass) \
     X(INT, NONE, logomitpass) \
     X(INT, NONE, logomitdata) \
     X(INT, NONE, logomitdata) \
     X(INT, NONE, hide_mouseptr) \
     X(INT, NONE, hide_mouseptr) \

+ 8 - 9
source/putty/ssh.c

@@ -387,7 +387,7 @@ static void ssh_initiate_connection_close(Ssh ssh)
 
 
 void ssh_remote_error(Ssh ssh, const char *fmt, ...)
 void ssh_remote_error(Ssh ssh, const char *fmt, ...)
 {
 {
-    if (ssh->base_layer) {
+    if (ssh->base_layer || !ssh->session_started) {
         GET_FORMATTED_MSG;
         GET_FORMATTED_MSG;
 
 
         /* Error messages sent by the remote don't count as clean exits */
         /* Error messages sent by the remote don't count as clean exits */
@@ -405,7 +405,7 @@ void ssh_remote_error(Ssh ssh, const char *fmt, ...)
 
 
 void ssh_remote_eof(Ssh ssh, const char *fmt, ...)
 void ssh_remote_eof(Ssh ssh, const char *fmt, ...)
 {
 {
-    if (ssh->base_layer) {
+    if (ssh->base_layer || !ssh->session_started) {
         GET_FORMATTED_MSG;
         GET_FORMATTED_MSG;
 
 
         /* EOF from the remote, if we were expecting it, does count as
         /* EOF from the remote, if we were expecting it, does count as
@@ -428,7 +428,7 @@ void ssh_remote_eof(Ssh ssh, const char *fmt, ...)
 
 
 void ssh_proto_error(Ssh ssh, const char *fmt, ...)
 void ssh_proto_error(Ssh ssh, const char *fmt, ...)
 {
 {
-    if (ssh->base_layer) {
+    if (ssh->base_layer || !ssh->session_started) {
         GET_FORMATTED_MSG;
         GET_FORMATTED_MSG;
 
 
         ssh->exitcode = 128;
         ssh->exitcode = 128;
@@ -445,7 +445,7 @@ void ssh_proto_error(Ssh ssh, const char *fmt, ...)
 
 
 void ssh_sw_abort(Ssh ssh, const char *fmt, ...)
 void ssh_sw_abort(Ssh ssh, const char *fmt, ...)
 {
 {
-    if (ssh->base_layer) {
+    if (ssh->base_layer || !ssh->session_started) {
         GET_FORMATTED_MSG;
         GET_FORMATTED_MSG;
 
 
         ssh->exitcode = 128;
         ssh->exitcode = 128;
@@ -462,7 +462,7 @@ void ssh_sw_abort(Ssh ssh, const char *fmt, ...)
 
 
 void ssh_user_close(Ssh ssh, const char *fmt, ...)
 void ssh_user_close(Ssh ssh, const char *fmt, ...)
 {
 {
-    if (ssh->base_layer) {
+    if (ssh->base_layer || !ssh->session_started) {
         GET_FORMATTED_MSG;
         GET_FORMATTED_MSG;
 
 
         /* Closing the connection due to user action, even if the
         /* Closing the connection due to user action, even if the
@@ -507,7 +507,9 @@ static void ssh_closing(Plug plug, const char *error_msg, int error_code,
 			int calling_back)
 			int calling_back)
 {
 {
     Ssh ssh = FROMFIELD(plug, struct ssh_tag, plugvt);
     Ssh ssh = FROMFIELD(plug, struct ssh_tag, plugvt);
-    if (ssh->bpp) {
+    if (error_msg) {
+        ssh_remote_error(ssh, "Network error: %s", error_msg);
+    } else if (ssh->bpp) {
         ssh->bpp->input_eof = TRUE;
         ssh->bpp->input_eof = TRUE;
         queue_idempotent_callback(&ssh->bpp->ic_in_raw);
         queue_idempotent_callback(&ssh->bpp->ic_in_raw);
     }
     }
@@ -966,9 +968,6 @@ static const SessionSpecial *ssh_get_specials(Backend *be)
     if (ssh->base_layer)
     if (ssh->base_layer)
         ssh_ppl_get_specials(ssh->base_layer, ssh_add_special, &ctx);
         ssh_ppl_get_specials(ssh->base_layer, ssh_add_special, &ctx);
 
 
-    if (!ssh->specials)
-        return NULL;
-
     if (ctx.specials) {
     if (ctx.specials) {
         /* If the list is non-empty, terminate it with a SS_EXITMENU. */
         /* If the list is non-empty, terminate it with a SS_EXITMENU. */
         ssh_add_special(&ctx, NULL, SS_EXITMENU, 0);
         ssh_add_special(&ctx, NULL, SS_EXITMENU, 0);

+ 7 - 2
source/putty/ssh.h

@@ -236,6 +236,9 @@ struct ConnectionLayerVtable {
     void (*sharing_queue_global_request)(
     void (*sharing_queue_global_request)(
         ConnectionLayer *cl, ssh_sharing_connstate *connstate);
         ConnectionLayer *cl, ssh_sharing_connstate *connstate);
 
 
+    /* Indicate that the last downstream has disconnected */
+    void (*sharing_no_more_downstreams)(ConnectionLayer *cl);
+
     /* Query whether the connection layer is doing agent forwarding */
     /* Query whether the connection layer is doing agent forwarding */
     int (*agent_forwarding_permitted)(ConnectionLayer *cl);
     int (*agent_forwarding_permitted)(ConnectionLayer *cl);
 
 
@@ -281,6 +284,8 @@ struct ConnectionLayer {
     ((cl)->vt->delete_sharing_channel(cl, ch))
     ((cl)->vt->delete_sharing_channel(cl, ch))
 #define ssh_sharing_queue_global_request(cl, cs) \
 #define ssh_sharing_queue_global_request(cl, cs) \
     ((cl)->vt->sharing_queue_global_request(cl, cs))
     ((cl)->vt->sharing_queue_global_request(cl, cs))
+#define ssh_sharing_no_more_downstreams(cl) \
+    ((cl)->vt->sharing_no_more_downstreams(cl))
 #define ssh_agent_forwarding_permitted(cl) \
 #define ssh_agent_forwarding_permitted(cl) \
     ((cl)->vt->agent_forwarding_permitted(cl))
     ((cl)->vt->agent_forwarding_permitted(cl))
 #define ssh_terminal_size(cl, w, h) ((cl)->vt->terminal_size(cl, w, h))
 #define ssh_terminal_size(cl, w, h) ((cl)->vt->terminal_size(cl, w, h))
@@ -1247,8 +1252,8 @@ void platform_ssh_share_cleanup(const char *name);
     K(y, SSH2_MSG_KEXRSA_PUBKEY, 30, SSH2_PKTCTX_RSAKEX)                \
     K(y, SSH2_MSG_KEXRSA_PUBKEY, 30, SSH2_PKTCTX_RSAKEX)                \
     K(y, SSH2_MSG_KEXRSA_SECRET, 31, SSH2_PKTCTX_RSAKEX)                \
     K(y, SSH2_MSG_KEXRSA_SECRET, 31, SSH2_PKTCTX_RSAKEX)                \
     K(y, SSH2_MSG_KEXRSA_DONE, 32, SSH2_PKTCTX_RSAKEX)                  \
     K(y, SSH2_MSG_KEXRSA_DONE, 32, SSH2_PKTCTX_RSAKEX)                  \
-    K(y, SSH2_MSG_KEX_ECDH_INIT, 30, SSH2_PKTCTX_DHGEX)                 \
-    K(y, SSH2_MSG_KEX_ECDH_REPLY, 31, SSH2_PKTCTX_DHGEX)                \
+    K(y, SSH2_MSG_KEX_ECDH_INIT, 30, SSH2_PKTCTX_ECDHKEX)               \
+    K(y, SSH2_MSG_KEX_ECDH_REPLY, 31, SSH2_PKTCTX_ECDHKEX)              \
     X(y, SSH2_MSG_USERAUTH_REQUEST, 50)                                 \
     X(y, SSH2_MSG_USERAUTH_REQUEST, 50)                                 \
     X(y, SSH2_MSG_USERAUTH_FAILURE, 51)                                 \
     X(y, SSH2_MSG_USERAUTH_FAILURE, 51)                                 \
     X(y, SSH2_MSG_USERAUTH_SUCCESS, 52)                                 \
     X(y, SSH2_MSG_USERAUTH_SUCCESS, 52)                                 \

+ 1 - 0
source/putty/ssh1bpp.c

@@ -245,6 +245,7 @@ static void ssh1_bpp_handle_input(BinaryPacketProtocol *bpp)
     } else {
     } else {
         ssh_remote_eof(s->bpp.ssh, "Server closed network connection");
         ssh_remote_eof(s->bpp.ssh, "Server closed network connection");
     }
     }
+    return;  /* avoid touching s now it's been freed */
 
 
     crFinishV;
     crFinishV;
 }
 }

+ 2 - 0
source/putty/ssh1connection.c

@@ -119,6 +119,7 @@ static const struct ConnectionLayerVtable ssh1_connlayer_vtable = {
     NULL /* alloc_sharing_channel */,
     NULL /* alloc_sharing_channel */,
     NULL /* delete_sharing_channel */,
     NULL /* delete_sharing_channel */,
     NULL /* sharing_queue_global_request */,
     NULL /* sharing_queue_global_request */,
+    NULL /* sharing_no_more_downstreams */,
     ssh1_agent_forwarding_permitted,
     ssh1_agent_forwarding_permitted,
     ssh1_terminal_size,
     ssh1_terminal_size,
     ssh1_stdout_unthrottle,
     ssh1_stdout_unthrottle,
@@ -751,6 +752,7 @@ static void ssh1_connection_process_queue(PacketProtocolLayer *ppl)
     }
     }
 
 
     s->session_ready = TRUE;
     s->session_ready = TRUE;
+    ssh_ppl_got_user_input(&s->ppl); /* in case any input is already queued */
 
 
     /* If an EOF or a window-size change arrived before we were ready
     /* If an EOF or a window-size change arrived before we were ready
      * to handle either one, handle them now. */
      * to handle either one, handle them now. */

+ 3 - 2
source/putty/ssh1login.c

@@ -712,7 +712,8 @@ static void ssh1_login_process_queue(PacketProtocolLayer *ppl)
                     }
                     }
                     if (!s->userpass_ret) {
                     if (!s->userpass_ret) {
                         /* Failed to get a passphrase. Terminate. */
                         /* Failed to get a passphrase. Terminate. */
-                        ssh_sw_abort(s->ppl.ssh, "Unable to authenticate");
+                        ssh_user_close(s->ppl.ssh,
+                                       "User aborted at passphrase prompt");
                         return;
                         return;
                     }
                     }
                     passphrase = dupstr(s->cur_prompt->prompts[0]->result);
                     passphrase = dupstr(s->cur_prompt->prompts[0]->result);
@@ -968,7 +969,7 @@ static void ssh1_login_process_queue(PacketProtocolLayer *ppl)
              * because one was supplied on the command line
              * because one was supplied on the command line
              * which has already failed to work). Terminate.
              * which has already failed to work). Terminate.
              */
              */
-            ssh_sw_abort(s->ppl.ssh, "Unable to authenticate");
+            ssh_user_close(s->ppl.ssh, "User aborted at password prompt");
             return;
             return;
         }
         }
 
 

+ 1 - 0
source/putty/ssh2bpp-bare.c

@@ -136,6 +136,7 @@ static void ssh2_bare_bpp_handle_input(BinaryPacketProtocol *bpp)
     } else {
     } else {
         ssh_remote_eof(s->bpp.ssh, "Server closed network connection");
         ssh_remote_eof(s->bpp.ssh, "Server closed network connection");
     }
     }
+    return;  /* avoid touching s now it's been freed */
 
 
     crFinishV;
     crFinishV;
 }
 }

+ 5 - 3
source/putty/ssh2bpp.c

@@ -463,13 +463,14 @@ static void ssh2_bpp_handle_input(BinaryPacketProtocol *bpp)
              * SSH_MSG_UNIMPLEMENTED.
              * SSH_MSG_UNIMPLEMENTED.
              */
              */
             s->pktin->type = SSH_MSG_NO_TYPE_CODE;
             s->pktin->type = SSH_MSG_NO_TYPE_CODE;
+            s->data += 5;
             s->length = 0;
             s->length = 0;
-            BinarySource_INIT(s->pktin, s->data + 5, 0);
         } else {
         } else {
             s->pktin->type = s->data[5];
             s->pktin->type = s->data[5];
+            s->data += 6;
             s->length -= 6;
             s->length -= 6;
-            BinarySource_INIT(s->pktin, s->data + 6, s->length);
         }
         }
+        BinarySource_INIT(s->pktin, s->data, s->length);
 
 
         if (s->bpp.logctx) {
         if (s->bpp.logctx) {
             logblank_t blanks[MAX_BLANKS];
             logblank_t blanks[MAX_BLANKS];
@@ -479,7 +480,7 @@ static void ssh2_bpp_handle_input(BinaryPacketProtocol *bpp)
             log_packet(s->bpp.logctx, PKT_INCOMING, s->pktin->type,
             log_packet(s->bpp.logctx, PKT_INCOMING, s->pktin->type,
                        ssh2_pkt_type(s->bpp.pls->kctx, s->bpp.pls->actx,
                        ssh2_pkt_type(s->bpp.pls->kctx, s->bpp.pls->actx,
                                      s->pktin->type),
                                      s->pktin->type),
-                       get_ptr(s->pktin), get_avail(s->pktin), nblanks, blanks,
+                       s->data, s->length, nblanks, blanks,
                        &s->pktin->sequence, 0, NULL);
                        &s->pktin->sequence, 0, NULL);
         }
         }
 
 
@@ -515,6 +516,7 @@ static void ssh2_bpp_handle_input(BinaryPacketProtocol *bpp)
     } else {
     } else {
         ssh_remote_eof(s->bpp.ssh, "Server closed network connection");
         ssh_remote_eof(s->bpp.ssh, "Server closed network connection");
     }
     }
+    return;  /* avoid touching s now it's been freed */
 
 
     crFinishV;
     crFinishV;
 }
 }

+ 12 - 1
source/putty/ssh2connection.c

@@ -127,6 +127,7 @@ static void ssh2_delete_sharing_channel(
     ConnectionLayer *cl, unsigned localid);
     ConnectionLayer *cl, unsigned localid);
 static void ssh2_sharing_queue_global_request(
 static void ssh2_sharing_queue_global_request(
     ConnectionLayer *cl, ssh_sharing_connstate *share_ctx);
     ConnectionLayer *cl, ssh_sharing_connstate *share_ctx);
+static void ssh2_sharing_no_more_downstreams(ConnectionLayer *cl);
 static int ssh2_agent_forwarding_permitted(ConnectionLayer *cl);
 static int ssh2_agent_forwarding_permitted(ConnectionLayer *cl);
 static void ssh2_terminal_size(ConnectionLayer *cl, int width, int height);
 static void ssh2_terminal_size(ConnectionLayer *cl, int width, int height);
 static void ssh2_stdout_unthrottle(ConnectionLayer *cl, int bufsize);
 static void ssh2_stdout_unthrottle(ConnectionLayer *cl, int bufsize);
@@ -144,6 +145,7 @@ static const struct ConnectionLayerVtable ssh2_connlayer_vtable = {
     ssh2_alloc_sharing_channel,
     ssh2_alloc_sharing_channel,
     ssh2_delete_sharing_channel,
     ssh2_delete_sharing_channel,
     ssh2_sharing_queue_global_request,
     ssh2_sharing_queue_global_request,
+    ssh2_sharing_no_more_downstreams,
     ssh2_agent_forwarding_permitted,
     ssh2_agent_forwarding_permitted,
     ssh2_terminal_size,
     ssh2_terminal_size,
     ssh2_stdout_unthrottle,
     ssh2_stdout_unthrottle,
@@ -1335,8 +1337,10 @@ static void ssh2_connection_process_queue(PacketProtocolLayer *ppl)
     }
     }
 
 
     s->mainchan_ready = TRUE;
     s->mainchan_ready = TRUE;
-    if (s->mainchan)
+    if (s->mainchan) {
 	s->want_user_input = TRUE;
 	s->want_user_input = TRUE;
+        ssh_ppl_got_user_input(&s->ppl); /* in case any is already queued */
+    }
 
 
     /* If an EOF or a window-size change arrived before we were ready
     /* If an EOF or a window-size change arrived before we were ready
      * to handle either one, handle them now. */
      * to handle either one, handle them now. */
@@ -2094,6 +2098,13 @@ static void ssh2_sharing_queue_global_request(
     ssh2_queue_global_request_handler(s, ssh2_sharing_globreq_response, cs);
     ssh2_queue_global_request_handler(s, ssh2_sharing_globreq_response, cs);
 }
 }
 
 
+static void ssh2_sharing_no_more_downstreams(ConnectionLayer *cl)
+{
+    struct ssh2_connection_state *s =
+        FROMFIELD(cl, struct ssh2_connection_state, cl);
+    queue_toplevel_callback(ssh2_check_termination_callback, s);
+}
+
 static struct X11FakeAuth *ssh2_add_sharing_x11_display(
 static struct X11FakeAuth *ssh2_add_sharing_x11_display(
     ConnectionLayer *cl, int authtype, ssh_sharing_connstate *share_cs,
     ConnectionLayer *cl, int authtype, ssh_sharing_connstate *share_cs,
     share_channel *share_chan)
     share_channel *share_chan)

+ 1 - 1
source/putty/ssh2transport.c

@@ -2392,7 +2392,7 @@ static void ssh2_transport_process_queue(PacketProtocolLayer *ppl)
                               s->rekey_reason));
                               s->rekey_reason));
             }
             }
         }
         }
-    } while (s->rekey_reason == RK_NONE);
+    } while (s->rekey_class == RK_NONE);
 
 
     /* Once we exit the above loop, we really are rekeying. */
     /* Once we exit the above loop, we really are rekeying. */
     goto begin_key_exchange;
     goto begin_key_exchange;

+ 11 - 1
source/putty/sshshare.c

@@ -905,12 +905,22 @@ static void share_try_cleanup(struct ssh_sharing_connstate *cs)
     if (count234(cs->halfchannels) == 0 &&
     if (count234(cs->halfchannels) == 0 &&
         count234(cs->channels_by_us) == 0 &&
         count234(cs->channels_by_us) == 0 &&
         count234(cs->forwardings) == 0) {
         count234(cs->forwardings) == 0) {
+        struct ssh_sharing_state *sharestate = cs->parent;
+
         /*
         /*
          * Now we're _really_ done, so we can get rid of cs completely.
          * Now we're _really_ done, so we can get rid of cs completely.
          */
          */
-        del234(cs->parent->connections, cs);
+        del234(sharestate->connections, cs);
         log_downstream(cs, "disconnected");
         log_downstream(cs, "disconnected");
         share_connstate_free(cs);
         share_connstate_free(cs);
+
+        /*
+         * And if this was the last downstream, notify the connection
+         * layer, because it might now be time to wind up the whole
+         * SSH connection.
+         */
+        if (count234(sharestate->connections) == 0 && sharestate->cl)
+            ssh_sharing_no_more_downstreams(sharestate->cl);
     }
     }
 }
 }
 
 

+ 1 - 0
source/putty/sshverstring.c

@@ -396,6 +396,7 @@ void ssh_verstring_handle_input(BinaryPacketProtocol *bpp)
   eof:
   eof:
     ssh_remote_error(s->bpp.ssh,
     ssh_remote_error(s->bpp.ssh,
                      "Server unexpectedly closed network connection");
                      "Server unexpectedly closed network connection");
+    return;  /* avoid touching s now it's been freed */
 
 
     crFinishV;
     crFinishV;
 }
 }