| ︙ | | | ︙ | |
217
218
219
220
221
222
223
224
225
226
227
228
229
230
|
long savedpos;
long maxlen;
};
static struct Packet pktin = { 0, 0, NULL, NULL, 0 };
static struct Packet pktout = { 0, 0, NULL, NULL, 0 };
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 int (*s_rdpkt)(unsigned char **data, int *datalen);
|
>
|
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
|
long savedpos;
long maxlen;
};
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 int (*s_rdpkt)(unsigned char **data, int *datalen);
|
| ︙ | | | ︙ | |
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
|
sha_string(&exhash, vstring, strcspn(vstring, "\r\n"));
sprintf(vstring, "%s\n", verstring);
sprintf(vlog, "We claim version: %s", verstring);
logevent(vlog);
logevent("Using SSH protocol version 2");
s_write(vstring, strlen(vstring));
ssh_protocol = ssh2_protocol;
s_rdpkt = ssh2_rdpkt;
} else {
/*
* This is a v1 server. Begin v1 protocol.
*/
sprintf(vstring, "SSH-%s-PuTTY\n",
(ssh_versioncmp(version, "1.5") <= 0 ? version : "1.5"));
sprintf(vlog, "We claim version: %s", vstring);
vlog[strcspn(vlog, "\r\n")] = '\0';
logevent(vlog);
logevent("Using SSH protocol version 1");
s_write(vstring, strlen(vstring));
ssh_protocol = ssh1_protocol;
s_rdpkt = ssh1_rdpkt;
}
return 1;
}
/*
* Handle the key exchange and user authentication phases.
|
>
>
|
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
|
sha_string(&exhash, vstring, strcspn(vstring, "\r\n"));
sprintf(vstring, "%s\n", verstring);
sprintf(vlog, "We claim version: %s", verstring);
logevent(vlog);
logevent("Using SSH protocol version 2");
s_write(vstring, strlen(vstring));
ssh_protocol = ssh2_protocol;
ssh_version = 2;
s_rdpkt = ssh2_rdpkt;
} else {
/*
* This is a v1 server. Begin v1 protocol.
*/
sprintf(vstring, "SSH-%s-PuTTY\n",
(ssh_versioncmp(version, "1.5") <= 0 ? version : "1.5"));
sprintf(vlog, "We claim version: %s", vstring);
vlog[strcspn(vlog, "\r\n")] = '\0';
logevent(vlog);
logevent("Using SSH protocol version 1");
s_write(vstring, strlen(vstring));
ssh_protocol = ssh1_protocol;
ssh_version = 1;
s_rdpkt = ssh1_rdpkt;
}
return 1;
}
/*
* Handle the key exchange and user authentication phases.
|
| ︙ | | | ︙ | |
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
|
fatalbox("Protocol confusion");
} else if (pktin.type == SSH1_SMSG_FAILURE) {
c_write("Server refused to allocate pty\r\n", 32);
}
logevent("Allocated pty");
}
send_packet(SSH1_CMSG_EXEC_SHELL, PKT_END);
logevent("Started session");
ssh_state = SSH_STATE_SESSION;
if (size_needed)
ssh_size();
while (1) {
|
>
>
>
|
|
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
|
fatalbox("Protocol confusion");
} else if (pktin.type == SSH1_SMSG_FAILURE) {
c_write("Server refused to allocate pty\r\n", 32);
}
logevent("Allocated pty");
}
if (*cfg.remote_cmd)
send_packet(SSH1_CMSG_EXEC_CMD, PKT_STR, cfg.remote_cmd, PKT_END);
else
send_packet(SSH1_CMSG_EXEC_SHELL, PKT_END);
logevent("Started session");
ssh_state = SSH_STATE_SESSION;
if (size_needed)
ssh_size();
while (1) {
|
| ︙ | | | ︙ | |
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
|
crReturn(1);
} while (!(ispkt && pktin.type == SSH2_MSG_KEXINIT));
goto begin_key_exchange;
crFinish(1);
}
/*
* Handle the SSH2 userauth and connection layers.
*/
static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
{
static unsigned long their_channel;
static unsigned long remote_winsize;
static unsigned long remote_maxpkt;
crBegin;
/*
* Request userauth protocol, and await a response to it.
|
>
>
>
>
>
<
|
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
|
crReturn(1);
} while (!(ispkt && pktin.type == SSH2_MSG_KEXINIT));
goto begin_key_exchange;
crFinish(1);
}
/*
* SSH2: remote identifier for the main session channel.
*/
static unsigned long ssh_remote_channel;
/*
* Handle the SSH2 userauth and connection layers.
*/
static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
{
static unsigned long remote_winsize;
static unsigned long remote_maxpkt;
crBegin;
/*
* Request userauth protocol, and await a response to it.
|
| ︙ | | | ︙ | |
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
|
if (pktin.type != SSH2_MSG_CHANNEL_OPEN_CONFIRMATION) {
fatalbox("Server refused to open a session");
/* FIXME: error data comes back in FAILURE packet */
}
if (ssh2_pkt_getuint32() != 100) {
fatalbox("Server's channel confirmation cited wrong channel");
}
their_channel = ssh2_pkt_getuint32();
remote_winsize = ssh2_pkt_getuint32();
remote_maxpkt = ssh2_pkt_getuint32();
logevent("Opened channel for session");
/*
* Now allocate a pty for the session.
*/
ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
ssh2_pkt_adduint32(their_channel); /* recipient channel */
ssh2_pkt_addstring("pty-req");
ssh2_pkt_addbool(1); /* want reply */
ssh2_pkt_addstring(cfg.termtype);
ssh2_pkt_adduint32(cols);
ssh2_pkt_adduint32(rows);
ssh2_pkt_adduint32(0); /* pixel width */
ssh2_pkt_adduint32(0); /* pixel height */
|
|
|
|
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
|
if (pktin.type != SSH2_MSG_CHANNEL_OPEN_CONFIRMATION) {
fatalbox("Server refused to open a session");
/* FIXME: error data comes back in FAILURE packet */
}
if (ssh2_pkt_getuint32() != 100) {
fatalbox("Server's channel confirmation cited wrong channel");
}
ssh_remote_channel = ssh2_pkt_getuint32();
remote_winsize = ssh2_pkt_getuint32();
remote_maxpkt = ssh2_pkt_getuint32();
logevent("Opened channel for session");
/*
* Now allocate a pty for the session.
*/
ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
ssh2_pkt_adduint32(ssh_remote_channel); /* recipient channel */
ssh2_pkt_addstring("pty-req");
ssh2_pkt_addbool(1); /* want reply */
ssh2_pkt_addstring(cfg.termtype);
ssh2_pkt_adduint32(cols);
ssh2_pkt_adduint32(rows);
ssh2_pkt_adduint32(0); /* pixel width */
ssh2_pkt_adduint32(0); /* pixel height */
|
| ︙ | | | ︙ | |
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
|
logevent("Allocated pty");
}
/*
* Start a shell.
*/
ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
ssh2_pkt_adduint32(their_channel); /* recipient channel */
ssh2_pkt_addstring("shell");
ssh2_pkt_addbool(1); /* want reply */
ssh2_pkt_send();
do { /* FIXME: pay attention to these */
crWaitUntilV(ispkt);
} while (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST);
if (pktin.type != SSH2_MSG_CHANNEL_SUCCESS) {
|
|
|
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
|
logevent("Allocated pty");
}
/*
* Start a shell.
*/
ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
ssh2_pkt_adduint32(ssh_remote_channel); /* recipient channel */
ssh2_pkt_addstring("shell");
ssh2_pkt_addbool(1); /* want reply */
ssh2_pkt_send();
do { /* FIXME: pay attention to these */
crWaitUntilV(ispkt);
} while (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST);
if (pktin.type != SSH2_MSG_CHANNEL_SUCCESS) {
|
| ︙ | | | ︙ | |
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
|
continue; /* ignore for now (FIXME!) */
} else {
fatalbox("Strange packet received: type %d", pktin.type);
}
} else {
/* FIXME: for now, ignore window size */
ssh2_pkt_init(SSH2_MSG_CHANNEL_DATA);
ssh2_pkt_adduint32(their_channel);
ssh2_pkt_addstring_start();
ssh2_pkt_addstring_data(in, inlen);
ssh2_pkt_send();
}
}
crFinishV;
|
|
|
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
|
continue; /* ignore for now (FIXME!) */
} else {
fatalbox("Strange packet received: type %d", pktin.type);
}
} else {
/* FIXME: for now, ignore window size */
ssh2_pkt_init(SSH2_MSG_CHANNEL_DATA);
ssh2_pkt_adduint32(ssh_remote_channel);
ssh2_pkt_addstring_start();
ssh2_pkt_addstring_data(in, inlen);
ssh2_pkt_send();
}
}
crFinishV;
|
| ︙ | | | ︙ | |
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
|
PKT_INT, rows, PKT_INT, cols,
PKT_INT, 0, PKT_INT, 0, PKT_END);
}
}
}
/*
* (Send Telnet special codes)
*/
static void ssh_special (Telnet_Special code) {
/* do nothing */
}
/*
* Read and decrypt one incoming SSH packet.
* (only used by pSCP)
*/
|
|
>
>
>
>
>
>
>
>
>
>
>
|
>
|
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
|
PKT_INT, rows, PKT_INT, cols,
PKT_INT, 0, PKT_INT, 0, PKT_END);
}
}
}
/*
* 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_version = 1) {
send_packet(SSH1_CMSG_EOF, PKT_END);
} else {
ssh2_pkt_init(SSH2_MSG_CHANNEL_EOF);
ssh2_pkt_adduint32(ssh_remote_channel);
ssh2_pkt_send();
}
} else {
/* do nothing */
}
}
/*
* Read and decrypt one incoming SSH packet.
* (only used by pSCP)
*/
|
| ︙ | | | ︙ | |