| ︙ | | |
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
|
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
|
+
-
+
-
+
+
|
static int savedport;
static int ssh_send_ok;
static tree234 *ssh_channels; /* indexed by local id */
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 = 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 int ssh_version;
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 ssh_special (Telnet_Special);
static int (*s_rdpkt)(unsigned char **data, int *datalen);
static struct rdpkt1_state_tag {
long len, pad, biglen, to_read;
unsigned long realcrc, gotcrc;
unsigned char *p;
|
| ︙ | | |
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
|
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
|
+
|
logevent(vlog);
logevent("Using SSH protocol version 1");
sk_write(s, vstring, strlen(vstring));
ssh_protocol = ssh1_protocol;
ssh_version = 1;
s_rdpkt = ssh1_rdpkt;
}
ssh_state = SSH_STATE_BEFORE_SIZE;
crFinish(0);
}
static void ssh_gotdata(unsigned char *data, int datalen)
{
crBegin;
|
| ︙ | | |
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
|
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
|
-
|
}
crFinishV;
}
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;
}
ssh_gotdata (data, len);
if (ssh_state == SSH_STATE_CLOSED) {
if (s) {
|
| ︙ | | |
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
|
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
|
+
+
|
else
send_packet(SSH1_CMSG_EXEC_SHELL, PKT_END);
logevent("Started session");
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);
begin_session();
while (1) {
crReturnV;
if (ispkt) {
|
| ︙ | | |
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
|
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
|
+
+
|
} else {
logevent("Started a shell/command");
}
ssh_state = SSH_STATE_SESSION;
if (size_needed)
ssh_size();
if (eof_needed)
ssh_special(TS_EOF);
/*
* Transfer data!
*/
ssh_send_ok = 1;
begin_session();
while (1) {
|
| ︙ | | |
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
|
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
|
+
|
/*
* Called to set the size of the window from SSH's POV.
*/
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:
size_needed = TRUE; /* buffer for later */
break;
case SSH_STATE_SESSION:
if (!cfg.nopty) {
|
| ︙ | | |
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
|
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
|
+
+
+
+
+
+
+
+
+
+
+
+
|
ssh2_pkt_adduint32(cols);
ssh2_pkt_adduint32(rows);
ssh2_pkt_adduint32(0);
ssh2_pkt_adduint32(0);
ssh2_pkt_send();
}
}
break;
}
}
/*
* Send Telnet special codes. TS_EOF is useful for `plink', so you
* can send an EOF and collect resulting output (e.g. `plink
* hostname sort').
*/
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 {
ssh2_pkt_init(SSH2_MSG_CHANNEL_EOF);
ssh2_pkt_adduint32(mainchan->remoteid);
ssh2_pkt_send();
}
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 {
ssh2_pkt_init(SSH2_MSG_IGNORE);
ssh2_pkt_addstring_start();
ssh2_pkt_send();
}
|
| ︙ | | |