projects
/
u
/
mdw
/
putty
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Ensure ssh specials (EOF and PING) don't occur except in connection
[u/mdw/putty]
/
ssh.c
diff --git
a/ssh.c
b/ssh.c
index
af1a542
..
a4e45cd
100644
(file)
--- a/
ssh.c
+++ b/
ssh.c
@@
-257,13
+257,14
@@
static tree234 *ssh_channels; /* indexed by local id */
static struct ssh_channel *mainchan; /* primary session channel */
static enum {
static struct ssh_channel *mainchan; /* primary session channel */
static enum {
+ SSH_STATE_PREPACKET,
SSH_STATE_BEFORE_SIZE,
SSH_STATE_INTERMED,
SSH_STATE_SESSION,
SSH_STATE_CLOSED
SSH_STATE_BEFORE_SIZE,
SSH_STATE_INTERMED,
SSH_STATE_SESSION,
SSH_STATE_CLOSED
-} ssh_state = SSH_STATE_
BEFORE_SIZE
;
+} ssh_state = SSH_STATE_
PREPACKET
;
-static int size_needed = FALSE;
+static int size_needed = FALSE
, eof_needed = FALSE
;
static struct Packet pktin = { 0, 0, NULL, NULL, 0 };
static struct Packet pktout = { 0, 0, NULL, NULL, 0 };
static struct Packet pktin = { 0, 0, NULL, NULL, 0 };
static struct Packet pktout = { 0, 0, NULL, NULL, 0 };
@@
-273,6
+274,7
@@
static void (*ssh_protocol)(unsigned char *in, int inlen, int ispkt);
static void ssh1_protocol(unsigned char *in, int inlen, int ispkt);
static void ssh2_protocol(unsigned char *in, int inlen, int ispkt);
static void ssh_size(void);
static void ssh1_protocol(unsigned char *in, int inlen, int ispkt);
static void ssh2_protocol(unsigned char *in, int inlen, int ispkt);
static void ssh_size(void);
+static void ssh_special (Telnet_Special);
static int (*s_rdpkt)(unsigned char **data, int *datalen);
static int (*s_rdpkt)(unsigned char **data, int *datalen);
@@
-1072,6
+1074,7
@@
static int do_ssh_init(unsigned char c) {
ssh_version = 1;
s_rdpkt = ssh1_rdpkt;
}
ssh_version = 1;
s_rdpkt = ssh1_rdpkt;
}
+ ssh_state = SSH_STATE_BEFORE_SIZE;
crFinish(0);
}
crFinish(0);
}
@@
-1121,7
+1124,6
@@
static void ssh_gotdata(unsigned char *data, int datalen)
static int ssh_receive(Socket skt, int urgent, char *data, int len) {
if (!len) {
/* Connection has closed. */
static int ssh_receive(Socket skt, int urgent, char *data, int len) {
if (!len) {
/* Connection has closed. */
- ssh_state = SSH_STATE_CLOSED;
sk_close(s);
s = NULL;
return 0;
sk_close(s);
s = NULL;
return 0;
@@
-1784,6
+1786,8
@@
static void ssh1_protocol(unsigned char *in, int inlen, int ispkt) {
ssh_state = SSH_STATE_SESSION;
if (size_needed)
ssh_size();
ssh_state = SSH_STATE_SESSION;
if (size_needed)
ssh_size();
+ if (eof_needed)
+ ssh_special(TS_EOF);
ssh_send_ok = 1;
ssh_channels = newtree234(ssh_channelcmp);
ssh_send_ok = 1;
ssh_channels = newtree234(ssh_channelcmp);
@@
-2563,6
+2567,8
@@
static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
ssh_state = SSH_STATE_SESSION;
if (size_needed)
ssh_size();
ssh_state = SSH_STATE_SESSION;
if (size_needed)
ssh_size();
+ if (eof_needed)
+ ssh_special(TS_EOF);
/*
* Transfer data!
/*
* Transfer data!
@@
-2727,6
+2733,7
@@
static void ssh_send (char *buf, int len) {
static void ssh_size(void) {
switch (ssh_state) {
case SSH_STATE_BEFORE_SIZE:
static void ssh_size(void) {
switch (ssh_state) {
case SSH_STATE_BEFORE_SIZE:
+ case SSH_STATE_PREPACKET:
case SSH_STATE_CLOSED:
break; /* do nothing */
case SSH_STATE_INTERMED:
case SSH_STATE_CLOSED:
break; /* do nothing */
case SSH_STATE_INTERMED:
@@
-2750,6
+2757,7
@@
static void ssh_size(void) {
ssh2_pkt_send();
}
}
ssh2_pkt_send();
}
}
+ break;
}
}
}
}
@@
-2760,6
+2768,15
@@
static void ssh_size(void) {
*/
static void ssh_special (Telnet_Special code) {
if (code == TS_EOF) {
*/
static void ssh_special (Telnet_Special code) {
if (code == TS_EOF) {
+ if (ssh_state != SSH_STATE_SESSION) {
+ /*
+ * Buffer the EOF in case we are pre-SESSION, so we can
+ * send it as soon as we reach SESSION.
+ */
+ if (code == TS_EOF)
+ eof_needed = TRUE;
+ return;
+ }
if (ssh_version == 1) {
send_packet(SSH1_CMSG_EOF, PKT_END);
} else {
if (ssh_version == 1) {
send_packet(SSH1_CMSG_EOF, PKT_END);
} else {
@@
-2769,6
+2786,8
@@
static void ssh_special (Telnet_Special code) {
}
logevent("Sent EOF message");
} else if (code == TS_PING) {
}
logevent("Sent EOF message");
} else if (code == TS_PING) {
+ if (ssh_state == SSH_STATE_CLOSED || ssh_state == SSH_STATE_PREPACKET)
+ return;
if (ssh_version == 1) {
send_packet(SSH1_MSG_IGNORE, PKT_STR, "", PKT_END);
} else {
if (ssh_version == 1) {
send_packet(SSH1_MSG_IGNORE, PKT_STR, "", PKT_END);
} else {