| ︙ | | | ︙ | |
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
#define SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED 1 /* 0x1 */
#define SSH2_OPEN_CONNECT_FAILED 2 /* 0x2 */
#define SSH2_OPEN_UNKNOWN_CHANNEL_TYPE 3 /* 0x3 */
#define SSH2_OPEN_RESOURCE_SHORTAGE 4 /* 0x4 */
#define SSH2_EXTENDED_DATA_STDERR 1 /* 0x1 */
#define GET_32BIT(cp) \
(((unsigned long)(unsigned char)(cp)[0] << 24) | \
((unsigned long)(unsigned char)(cp)[1] << 16) | \
((unsigned long)(unsigned char)(cp)[2] << 8) | \
((unsigned long)(unsigned char)(cp)[3]))
#define PUT_32BIT(cp, value) { \
|
>
>
>
>
>
>
|
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
#define SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED 1 /* 0x1 */
#define SSH2_OPEN_CONNECT_FAILED 2 /* 0x2 */
#define SSH2_OPEN_UNKNOWN_CHANNEL_TYPE 3 /* 0x3 */
#define SSH2_OPEN_RESOURCE_SHORTAGE 4 /* 0x4 */
#define SSH2_EXTENDED_DATA_STDERR 1 /* 0x1 */
/*
* Various remote-bug flags.
*/
#define BUG_CHOKES_ON_SSH1_IGNORE 1
#define BUG_SSH2_HMAC 2
#define GET_32BIT(cp) \
(((unsigned long)(unsigned char)(cp)[0] << 24) | \
((unsigned long)(unsigned char)(cp)[1] << 16) | \
((unsigned long)(unsigned char)(cp)[2] << 8) | \
((unsigned long)(unsigned char)(cp)[3]))
#define PUT_32BIT(cp, value) { \
|
| ︙ | | | ︙ | |
248
249
250
251
252
253
254
255
256
257
258
259
260
261
|
static Socket s = NULL;
static unsigned char session_key[32];
static int ssh1_compressing;
static int ssh_agentfwd_enabled;
static int ssh_X11_fwd_enabled;
static const struct ssh_cipher *cipher = NULL;
static const struct ssh2_cipher *cscipher = NULL;
static const struct ssh2_cipher *sccipher = NULL;
static const struct ssh_mac *csmac = NULL;
static const struct ssh_mac *scmac = NULL;
static const struct ssh_compress *cscomp = NULL;
static const struct ssh_compress *sccomp = NULL;
|
>
|
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
|
static Socket s = NULL;
static unsigned char session_key[32];
static int ssh1_compressing;
static int ssh_agentfwd_enabled;
static int ssh_X11_fwd_enabled;
static int ssh_remote_bugs;
static const struct ssh_cipher *cipher = NULL;
static const struct ssh2_cipher *cscipher = NULL;
static const struct ssh2_cipher *sccipher = NULL;
static const struct ssh_mac *csmac = NULL;
static const struct ssh_mac *scmac = NULL;
static const struct ssh_compress *cscomp = NULL;
static const struct ssh_compress *sccomp = NULL;
|
| ︙ | | | ︙ | |
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
|
static int s_wrpkt_prepare(void) {
int pad, len, biglen, i;
unsigned long crc;
pktout.body[-1] = pktout.type;
if (ssh1_compressing) {
unsigned char *compblk;
int complen;
#if 0
debug(("Packet payload pre-compression:\n"));
for (i = -1; i < pktout.length; i++)
debug((" %02x", (unsigned char)pktout.body[i]));
debug(("\r\n"));
#endif
zlib_compress_block(pktout.body-1, pktout.length+1,
&compblk, &complen);
ssh1_pktout_size(complen-1);
memcpy(pktout.body-1, compblk, complen);
sfree(compblk);
#if 0
debug(("Packet payload post-compression:\n"));
|
>
>
>
>
>
>
>
<
<
<
<
<
<
|
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
|
static int s_wrpkt_prepare(void) {
int pad, len, biglen, i;
unsigned long crc;
pktout.body[-1] = pktout.type;
#if 0
debug(("Packet payload pre-compression:\n"));
for (i = -1; i < pktout.length; i++)
debug((" %02x", (unsigned char)pktout.body[i]));
debug(("\r\n"));
#endif
if (ssh1_compressing) {
unsigned char *compblk;
int complen;
zlib_compress_block(pktout.body-1, pktout.length+1,
&compblk, &complen);
ssh1_pktout_size(complen-1);
memcpy(pktout.body-1, compblk, complen);
sfree(compblk);
#if 0
debug(("Packet payload post-compression:\n"));
|
| ︙ | | | ︙ | |
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
|
if (p[0] & 0x80) {
bombout(("internal error: Can't handle negative mpints"));
return NULL;
}
b = bignum_from_bytes(p, length);
return b;
}
static int do_ssh_init(unsigned char c) {
static char *vsp;
static char version[10];
static char vstring[80];
static char vlog[sizeof(vstring)+20];
static int i;
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
|
if (p[0] & 0x80) {
bombout(("internal error: Can't handle negative mpints"));
return NULL;
}
b = bignum_from_bytes(p, length);
return b;
}
/*
* Examine the remote side's version string and compare it against
* a list of known buggy implementations.
*/
static void ssh_detect_bugs(char *vstring) {
char *imp; /* pointer to implementation part */
imp = vstring;
imp += strcspn(imp, "-");
imp += strcspn(imp, "-");
ssh_remote_bugs = 0;
if (!strcmp(imp, "1.2.18") || !strcmp(imp, "1.2.19") ||
!strcmp(imp, "1.2.20") || !strcmp(imp, "1.2.21") ||
!strcmp(imp, "1.2.22")) {
/*
* These versions don't support SSH1_MSG_IGNORE, so we have
* to use a different defence against password length
* sniffing.
*/
ssh_remote_bugs |= BUG_CHOKES_ON_SSH1_IGNORE;
logevent("We believe remote version has SSH1 ignore bug");
}
if (!strncmp(imp, "2.1.0", 5) || !strncmp(imp, "2.0.", 4) ||
!strncmp(imp, "2.2.0", 5) || !strncmp(imp, "2.3.0", 5) ||
!strncmp(imp, "2.1 ", 4)) {
/*
* These versions have the HMAC bug.
*/
ssh_remote_bugs |= BUG_SSH2_HMAC;
logevent("We believe remote version has SSH2 HMAC bug");
}
}
static int do_ssh_init(unsigned char c) {
static char *vsp;
static char version[10];
static char vstring[80];
static char vlog[sizeof(vstring)+20];
static int i;
|
| ︙ | | | ︙ | |
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
|
}
ssh_agentfwd_enabled = FALSE;
rdpkt2_state.incoming_sequence = 0;
*vsp = 0;
sprintf(vlog, "Server version: %s", vstring);
vlog[strcspn(vlog, "\r\n")] = '\0';
logevent(vlog);
/*
* Server version "1.99" means we can choose whether we use v1
* or v2 protocol. Choice is based on cfg.sshprot.
*/
|
>
|
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
|
}
ssh_agentfwd_enabled = FALSE;
rdpkt2_state.incoming_sequence = 0;
*vsp = 0;
sprintf(vlog, "Server version: %s", vstring);
ssh_detect_bugs(vstring);
vlog[strcspn(vlog, "\r\n")] = '\0';
logevent(vlog);
/*
* Server version "1.99" means we can choose whether we use v1
* or v2 protocol. Choice is based on cfg.sshprot.
*/
|
| ︙ | | | ︙ | |
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
|
*
* - otherwise, we let N be the nearest multiple
* of 8 below the password length, and send 8
* packets containing string lengths N through
* N+7. This won't obscure the order of
* magnitude of the password length, but it will
* introduce a bit of extra uncertainty.
*/
int bottom, top, pwlen, i;
char *randomstr;
pwlen = strlen(password);
if (pwlen < 16) {
bottom = 1;
top = 15;
} else {
bottom = pwlen &~ 7;
top = bottom + 7;
}
assert(pwlen >= bottom && pwlen <= top);
randomstr = smalloc(top+1);
for (i = bottom; i <= top; i++) {
if (i == pwlen)
defer_packet(pwpkt_type, PKT_STR, password, PKT_END);
else {
for (j = 0; j < i; j++) {
do {
randomstr[j] = random_byte();
} while (randomstr[j] == '\0');
}
randomstr[i] = '\0';
defer_packet(SSH1_MSG_IGNORE,
PKT_STR, randomstr, PKT_END);
}
}
ssh_pkt_defersend();
} else {
send_packet(pwpkt_type, PKT_STR, password, PKT_END);
}
}
logevent("Sent password");
memset(password, 0, strlen(password));
crWaitUntil(ispkt);
|
>
>
>
>
>
>
>
>
|
|
>
|
|
|
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
|
*
* - otherwise, we let N be the nearest multiple
* of 8 below the password length, and send 8
* packets containing string lengths N through
* N+7. This won't obscure the order of
* magnitude of the password length, but it will
* introduce a bit of extra uncertainty.
*
* A few servers (the old 1.2.18 through 1.2.22)
* can't deal with SSH1_MSG_IGNORE. For these
* servers, we need an alternative defence. We make
* use of the fact that the password is interpreted
* as a C string: so we can append a NUL, then some
* random data.
*/
if (ssh_remote_bugs & BUG_CHOKES_ON_SSH1_IGNORE) {
char string[64];
char *s;
int len;
len = strlen(password);
if (len < sizeof(string)) {
s = string;
strcpy(string, password);
len++; /* cover the zero byte */
while (len < sizeof(string)) {
string[len++] = (char)random_byte();
}
} else {
s = password;
}
send_packet(pwpkt_type, PKT_INT, len,
PKT_DATA, s, len, PKT_END);
} else {
int bottom, top, pwlen, i;
char *randomstr;
pwlen = strlen(password);
if (pwlen < 16) {
bottom = 1;
top = 15;
} else {
bottom = pwlen &~ 7;
top = bottom + 7;
}
assert(pwlen >= bottom && pwlen <= top);
randomstr = smalloc(top+1);
for (i = bottom; i <= top; i++) {
if (i == pwlen)
defer_packet(pwpkt_type, PKT_STR, password, PKT_END);
else {
for (j = 0; j < i; j++) {
do {
randomstr[j] = random_byte();
} while (randomstr[j] == '\0');
}
randomstr[i] = '\0';
defer_packet(SSH1_MSG_IGNORE,
PKT_STR, randomstr, PKT_END);
}
}
ssh_pkt_defersend();
}
} else {
send_packet(pwpkt_type, PKT_STR, password, PKT_END);
}
}
logevent("Sent password");
memset(password, 0, strlen(password));
crWaitUntil(ispkt);
|
| ︙ | | | ︙ | |
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
|
preferred_comp = &ssh_zlib;
else
preferred_comp = &ssh_comp_none;
/*
* Be prepared to work around the buggy MAC problem.
*/
if (cfg.buggymac)
maclist = buggymacs, nmacs = lenof(buggymacs);
else
maclist = macs, nmacs = lenof(macs);
begin_key_exchange:
/*
* Construct and send our key exchange packet.
|
|
|
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
|
preferred_comp = &ssh_zlib;
else
preferred_comp = &ssh_comp_none;
/*
* Be prepared to work around the buggy MAC problem.
*/
if (cfg.buggymac || (ssh_remote_bugs & BUG_SSH2_HMAC))
maclist = buggymacs, nmacs = lenof(buggymacs);
else
maclist = macs, nmacs = lenof(macs);
begin_key_exchange:
/*
* Construct and send our key exchange packet.
|
| ︙ | | | ︙ | |