Explorar o código

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

Source commit: c41ad6a0ef7e1eaacdd7720d90c0af124f6a0563
Martin Prikryl %!s(int64=6) %!d(string=hai) anos
pai
achega
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
 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
 
 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. */
 	tm = ltime();
 	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, logxfovr) \
     X(INT, NONE, logflush) \
+    X(INT, NONE, logheader) \
     X(INT, NONE, logomitpass) \
     X(INT, NONE, logomitdata) \
     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, ...)
 {
-    if (ssh->base_layer) {
+    if (ssh->base_layer || !ssh->session_started) {
         GET_FORMATTED_MSG;
 
         /* 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, ...)
 {
-    if (ssh->base_layer) {
+    if (ssh->base_layer || !ssh->session_started) {
         GET_FORMATTED_MSG;
 
         /* 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, ...)
 {
-    if (ssh->base_layer) {
+    if (ssh->base_layer || !ssh->session_started) {
         GET_FORMATTED_MSG;
 
         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, ...)
 {
-    if (ssh->base_layer) {
+    if (ssh->base_layer || !ssh->session_started) {
         GET_FORMATTED_MSG;
 
         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, ...)
 {
-    if (ssh->base_layer) {
+    if (ssh->base_layer || !ssh->session_started) {
         GET_FORMATTED_MSG;
 
         /* 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)
 {
     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;
         queue_idempotent_callback(&ssh->bpp->ic_in_raw);
     }
@@ -966,9 +968,6 @@ static const SessionSpecial *ssh_get_specials(Backend *be)
     if (ssh->base_layer)
         ssh_ppl_get_specials(ssh->base_layer, ssh_add_special, &ctx);
 
-    if (!ssh->specials)
-        return NULL;
-
     if (ctx.specials) {
         /* If the list is non-empty, terminate it with a SS_EXITMENU. */
         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)(
         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 */
     int (*agent_forwarding_permitted)(ConnectionLayer *cl);
 
@@ -281,6 +284,8 @@ struct ConnectionLayer {
     ((cl)->vt->delete_sharing_channel(cl, ch))
 #define ssh_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) \
     ((cl)->vt->agent_forwarding_permitted(cl))
 #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_SECRET, 31, 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_FAILURE, 51)                                 \
     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 {
         ssh_remote_eof(s->bpp.ssh, "Server closed network connection");
     }
+    return;  /* avoid touching s now it's been freed */
 
     crFinishV;
 }

+ 2 - 0
source/putty/ssh1connection.c

@@ -119,6 +119,7 @@ static const struct ConnectionLayerVtable ssh1_connlayer_vtable = {
     NULL /* alloc_sharing_channel */,
     NULL /* delete_sharing_channel */,
     NULL /* sharing_queue_global_request */,
+    NULL /* sharing_no_more_downstreams */,
     ssh1_agent_forwarding_permitted,
     ssh1_terminal_size,
     ssh1_stdout_unthrottle,
@@ -751,6 +752,7 @@ static void ssh1_connection_process_queue(PacketProtocolLayer *ppl)
     }
 
     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
      * 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) {
                         /* 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;
                     }
                     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
              * 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;
         }
 

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

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

+ 5 - 3
source/putty/ssh2bpp.c

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

+ 12 - 1
source/putty/ssh2connection.c

@@ -127,6 +127,7 @@ static void ssh2_delete_sharing_channel(
     ConnectionLayer *cl, unsigned localid);
 static void ssh2_sharing_queue_global_request(
     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 void ssh2_terminal_size(ConnectionLayer *cl, int width, int height);
 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_delete_sharing_channel,
     ssh2_sharing_queue_global_request,
+    ssh2_sharing_no_more_downstreams,
     ssh2_agent_forwarding_permitted,
     ssh2_terminal_size,
     ssh2_stdout_unthrottle,
@@ -1335,8 +1337,10 @@ static void ssh2_connection_process_queue(PacketProtocolLayer *ppl)
     }
 
     s->mainchan_ready = TRUE;
-    if (s->mainchan)
+    if (s->mainchan) {
 	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
      * 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);
 }
 
+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(
     ConnectionLayer *cl, int authtype, ssh_sharing_connstate *share_cs,
     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));
             }
         }
-    } while (s->rekey_reason == RK_NONE);
+    } while (s->rekey_class == RK_NONE);
 
     /* Once we exit the above loop, we really are rekeying. */
     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 &&
         count234(cs->channels_by_us) == 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.
          */
-        del234(cs->parent->connections, cs);
+        del234(sharestate->connections, cs);
         log_downstream(cs, "disconnected");
         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:
     ssh_remote_error(s->bpp.ssh,
                      "Server unexpectedly closed network connection");
+    return;  /* avoid touching s now it's been freed */
 
     crFinishV;
 }