SSH2 connections weren't closing cleanly after socket revamp. Fixed.
[sgt/putty] / ssh.c
diff --git a/ssh.c b/ssh.c
index 744c86d..524a750 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -993,6 +993,13 @@ static int ssh_receive(Socket s, int urgent, char *data, int len) {
        return 0;
     }
     ssh_gotdata (data, len);
+    if (ssh_state == SSH_STATE_CLOSED) {
+        if (s) {
+            sk_close(s);
+            s = NULL;
+        }
+        return 0;
+    }
     return 1;
 }
 
@@ -1641,6 +1648,7 @@ static void ssh1_protocol(unsigned char *in, int inlen, int ispkt) {
            } else if (pktin.type == SSH1_MSG_DISCONNECT) {
                 ssh_state = SSH_STATE_CLOSED;
                logevent("Received disconnect request");
+                crReturnV;
             } else if (pktin.type == SSH1_SMSG_AGENT_OPEN) {
                 /* Remote side is trying to open a channel to talk to our
                  * agent. Give them back a local channel number. */
@@ -2304,6 +2312,7 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
         ssh2_pkt_addstring_start();
         ssh2_pkt_addstring_data("\0", 1);/* TTY_OP_END, no special options */
         ssh2_pkt_send();
+        ssh_state = SSH_STATE_INTERMED;
 
         do {
             crWaitUntilV(ispkt);
@@ -2360,6 +2369,10 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
         logevent("Started a shell/command");
     }
 
+    ssh_state = SSH_STATE_SESSION;
+    if (size_needed)
+       ssh_size();
+
     /*
      * Transfer data!
      */
@@ -2397,6 +2410,7 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
            } else if (pktin.type == SSH2_MSG_DISCONNECT) {
                 ssh_state = SSH_STATE_CLOSED;
                logevent("Received disconnect message");
+                crReturnV;
            } else if (pktin.type == SSH2_MSG_CHANNEL_REQUEST) {
                 continue;              /* exit status et al; ignore (FIXME?) */
            } else if (pktin.type == SSH2_MSG_CHANNEL_EOF) {
@@ -2414,8 +2428,7 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
                     ssh2_pkt_init(SSH2_MSG_DISCONNECT);
                     ssh2_pkt_send();
                     ssh_state = SSH_STATE_CLOSED;
-                    sk_close(s);
-                    s = NULL;
+                    crReturnV;
                 }
                 continue;              /* remote sends close; ignore (FIXME) */
            } else if (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST) {
@@ -2515,7 +2528,7 @@ static void ssh_send (char *buf, int len) {
 }
 
 /*
- * Called to set the size of the window from Telnet's POV.
+ * Called to set the size of the window from SSH's POV.
  */
 static void ssh_size(void) {
     switch (ssh_state) {
@@ -2527,9 +2540,21 @@ static void ssh_size(void) {
        break;
       case SSH_STATE_SESSION:
         if (!cfg.nopty) {
-           send_packet(SSH1_CMSG_WINDOW_SIZE,
-                       PKT_INT, rows, PKT_INT, cols,
-                       PKT_INT, 0, PKT_INT, 0, PKT_END);
+            if (ssh_version == 1) {
+                send_packet(SSH1_CMSG_WINDOW_SIZE,
+                            PKT_INT, rows, PKT_INT, cols,
+                            PKT_INT, 0, PKT_INT, 0, PKT_END);
+            } else {
+                ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
+                ssh2_pkt_adduint32(mainchan->remoteid);
+                ssh2_pkt_addstring("window-change");
+                ssh2_pkt_addbool(0);
+                ssh2_pkt_adduint32(cols);
+                ssh2_pkt_adduint32(rows);
+                ssh2_pkt_adduint32(0);
+                ssh2_pkt_adduint32(0);
+                ssh2_pkt_send();
+            }
         }
     }
 }