| ︙ | | |
325
326
327
328
329
330
331
332
333
334
335
336
337
338
|
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
|
+
|
static void ssh2_pkt_addstring_str(struct Packet *, char *data);
static void ssh2_pkt_addstring_data(struct Packet *, char *data, int len);
static void ssh2_pkt_addstring(struct Packet *, char *data);
static unsigned char *ssh2_mpint_fmt(Bignum b, int *len);
static void ssh2_pkt_addmp(struct Packet *, Bignum b);
static int ssh2_pkt_construct(Ssh, struct Packet *);
static void ssh2_pkt_send(Ssh, struct Packet *);
static void ssh2_pkt_send_noqueue(Ssh, struct Packet *);
static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen,
struct Packet *pktin);
static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen,
struct Packet *pktin);
/*
* Buffer management constants. There are several of these for
|
| ︙ | | |
611
612
613
614
615
616
617
618
619
620
621
622
623
624
|
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
|
+
+
+
|
SSH_STATE_INTERMED,
SSH_STATE_SESSION,
SSH_STATE_CLOSED
} state;
int size_needed, eof_needed;
struct Packet **queue;
int queuelen, queuesize;
int queueing;
unsigned char *deferred_send_data;
int deferred_len, deferred_size;
/*
* Gross hack: pscp will try to start SFTP but fall back to
* scp1 if that fails. This variable is the means by which
* scp.c can reach into the SSH code and find out which one it
|
| ︙ | | |
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
|
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
|
+
+
-
+
|
* For anything else we send SSH2_MSG_UNIMPLEMENTED.
*/
default:
{
struct Packet *pktout;
pktout = ssh2_pkt_init(SSH2_MSG_UNIMPLEMENTED);
ssh2_pkt_adduint32(pktout, st->incoming_sequence - 1);
/* UNIMPLEMENTED messages MUST appear in the same order as
* the messages they respond to. Hence, never queue them. */
ssh2_pkt_send(ssh, pktout);
ssh2_pkt_send_noqueue(ssh, pktout);
}
break;
}
crFinish(st->pktin);
}
|
| ︙ | | |
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
|
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
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
1877
1878
1879
1880
1881
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
-
-
-
-
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
pkt->data, pkt->length + padding);
/* Ready-to-send packet starts at pkt->data. We return length. */
return pkt->length + padding + maclen;
}
/*
* Routines called from the main SSH code to send packets. There
* are quite a few of these, because we have two separate
* mechanisms for delaying the sending of packets:
*
* - In order to send an IGNORE message and a password message in
* a single fixed-length blob, we require the ability to
* concatenate the encrypted forms of those two packets _into_ a
* single blob and then pass it to our <network.h> transport
* layer in one go. Hence, there's a deferment mechanism which
* works after packet encryption.
*
* - In order to avoid sending any connection-layer messages
* during repeat key exchange, we have to queue up any such
* outgoing messages _before_ they are encrypted (and in
* particular before they're allocated sequence numbers), and
* then send them once we've finished.
*
* I call these mechanisms `defer' and `queue' respectively, so as
* to distinguish them reasonably easily.
*
* The functions send_noqueue() and defer_noqueue() free the packet
* structure they are passed. Every outgoing packet goes through
* precisely one of these functions in its life; packets passed to
* ssh2_pkt_send() or ssh2_pkt_defer() either go straight to one of
* these or get queued, and then when the queue is later emptied
* the packets are all passed to defer_noqueue().
*/
/*
* Construct and send an SSH2 packet immediately.
* Send an SSH2 packet immediately, without queuing or deferring.
*/
static void ssh2_pkt_send(Ssh ssh, struct Packet *pkt)
static void ssh2_pkt_send_noqueue(Ssh ssh, struct Packet *pkt)
{
int len;
int backlog;
len = ssh2_pkt_construct(ssh, pkt);
backlog = sk_write(ssh->s, (char *)pkt->data, len);
if (backlog > SSH_MAX_BACKLOG)
ssh_throttle_all(ssh, 1, backlog);
ssh_free_packet(pkt);
}
/*
* Construct an SSH2 packet and add it to a deferred data block.
* Useful for sending multiple packets in a single sk_write() call,
* to prevent a traffic-analysing listener from being able to work
* out the length of any particular packet (such as the password
* packet).
* Defer an SSH2 packet.
*
* Note that because SSH2 sequence-numbers its packets, this can
* NOT be used as an m4-style `defer' allowing packets to be
* constructed in one order and sent in another.
*/
static void ssh2_pkt_defer(Ssh ssh, struct Packet *pkt)
static void ssh2_pkt_defer_noqueue(Ssh ssh, struct Packet *pkt)
{
int len = ssh2_pkt_construct(ssh, pkt);
if (ssh->deferred_len + len > ssh->deferred_size) {
ssh->deferred_size = ssh->deferred_len + len + 128;
ssh->deferred_send_data = sresize(ssh->deferred_send_data,
ssh->deferred_size,
unsigned char);
}
memcpy(ssh->deferred_send_data + ssh->deferred_len, pkt->data, len);
ssh->deferred_len += len;
ssh_free_packet(pkt);
}
/*
* Queue an SSH2 packet.
*/
static void ssh2_pkt_queue(Ssh ssh, struct Packet *pkt)
{
assert(ssh->queueing);
if (ssh->queuelen >= ssh->queuesize) {
ssh->queuesize = ssh->queuelen + 32;
ssh->queue = sresize(ssh->queue, ssh->queuesize, struct Packet *);
}
ssh->queue[ssh->queuelen++] = pkt;
}
/*
* Either queue or send a packet, depending on whether queueing is
* set.
*/
static void ssh2_pkt_send(Ssh ssh, struct Packet *pkt)
{
if (ssh->queueing)
ssh2_pkt_queue(ssh, pkt);
else
ssh2_pkt_send_noqueue(ssh, pkt);
}
/*
* Either queue or defer a packet, depending on whether queueing is
* set.
*/
static void ssh2_pkt_defer(Ssh ssh, struct Packet *pkt)
{
if (ssh->queueing)
ssh2_pkt_queue(ssh, pkt);
else
ssh2_pkt_defer_noqueue(ssh, pkt);
}
/*
* Send the whole deferred data block constructed by
* ssh2_pkt_defer() or SSH1's defer_packet().
*
* The expected use of the defer mechanism is that you call
* ssh2_pkt_defer() a few times, then call ssh_pkt_defersend(). If
* not currently queueing, this simply sets up deferred_send_data
* and then sends it. If we _are_ currently queueing, the calls to
* ssh2_pkt_defer() put the deferred packets on to the queue
* instead, and therefore ssh_pkt_defersend() has no deferred data
* to send. Hence, there's no need to make it conditional on
* ssh->queueing.
*/
static void ssh_pkt_defersend(Ssh ssh)
{
int backlog;
backlog = sk_write(ssh->s, (char *)ssh->deferred_send_data,
ssh->deferred_len);
ssh->deferred_len = ssh->deferred_size = 0;
sfree(ssh->deferred_send_data);
ssh->deferred_send_data = NULL;
if (backlog > SSH_MAX_BACKLOG)
ssh_throttle_all(ssh, 1, backlog);
}
/*
* Send all queued SSH2 packets. We send them by means of
* ssh2_pkt_defer_noqueue(), in case they included a pair of
* packets that needed to be lumped together.
*/
static void ssh2_pkt_queuesend(Ssh ssh)
{
int i;
assert(!ssh->queueing);
for (i = 0; i < ssh->queuelen; i++)
ssh2_pkt_defer_noqueue(ssh, ssh->queue[i]);
ssh->queuelen = 0;
ssh_pkt_defersend(ssh);
}
#if 0
void bndebug(char *string, Bignum b)
{
unsigned char *p;
int i, len;
p = ssh2_mpint_fmt(b, &len);
|
| ︙ | | |
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
|
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
|
+
+
+
+
+
+
|
else
s->maclist = macs, s->nmacs = lenof(macs);
begin_key_exchange:
{
int i, j, cipherstr_started;
/*
* Enable queueing of outgoing auth- or connection-layer
* packets while we are in the middle of a key exchange.
*/
ssh->queueing = TRUE;
/*
* Construct and send our key exchange packet.
*/
s->pktout = ssh2_pkt_init(SSH2_MSG_KEXINIT);
for (i = 0; i < 16; i++)
ssh2_pkt_addbyte(s->pktout, (unsigned char) random_byte());
/* List key exchange algorithms. */
|
| ︙ | | |
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
|
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
|
-
+
|
/* Reserved. */
ssh2_pkt_adduint32(s->pktout, 0);
}
ssh->exhash = ssh->exhashbase;
sha_string(&ssh->exhash, s->pktout->data + 5, s->pktout->length - 5);
ssh2_pkt_send(ssh, s->pktout);
ssh2_pkt_send_noqueue(ssh, s->pktout);
if (!pktin)
crWaitUntil(pktin);
if (pktin->length > 5)
sha_string(&ssh->exhash, pktin->data + 5, pktin->length - 5);
/*
|
| ︙ | | |
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
|
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
|
-
+
|
/*
* Work out how big a DH group we will need to allow that
* much data.
*/
s->pbits = 512 << ((s->nbits - 1) / 64);
s->pktout = ssh2_pkt_init(SSH2_MSG_KEX_DH_GEX_REQUEST);
ssh2_pkt_adduint32(s->pktout, s->pbits);
ssh2_pkt_send(ssh, s->pktout);
ssh2_pkt_send_noqueue(ssh, s->pktout);
crWaitUntil(pktin);
if (pktin->type != SSH2_MSG_KEX_DH_GEX_GROUP) {
bombout(("expected key exchange group packet from server"));
crStop(0);
}
s->p = ssh2_pkt_getmp(pktin);
|
| ︙ | | |
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
|
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
|
-
+
|
logevent("Doing Diffie-Hellman key exchange");
/*
* Now generate and send e for Diffie-Hellman.
*/
s->e = dh_create_e(ssh->kex_ctx, s->nbits * 2);
s->pktout = ssh2_pkt_init(s->kex_init_value);
ssh2_pkt_addmp(s->pktout, s->e);
ssh2_pkt_send(ssh, s->pktout);
ssh2_pkt_send_noqueue(ssh, s->pktout);
crWaitUntil(pktin);
if (pktin->type != s->kex_reply_value) {
bombout(("expected key exchange reply packet from server"));
crStop(0);
}
ssh_pkt_getstring(pktin, &s->hostkeydata, &s->hostkeylen);
|
| ︙ | | |
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
|
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
|
-
+
+
+
+
+
+
+
+
|
sfree(s->keystr);
ssh->hostkey->freekey(s->hkey);
/*
* Send SSH2_MSG_NEWKEYS.
*/
s->pktout = ssh2_pkt_init(SSH2_MSG_NEWKEYS);
ssh2_pkt_send(ssh, s->pktout);
ssh2_pkt_send_noqueue(ssh, s->pktout);
/*
* Now our end of the key exchange is complete, we can send all
* our queued higher-layer packets.
*/
ssh->queueing = FALSE;
ssh2_pkt_queuesend(ssh);
/*
* Expect SSH2_MSG_NEWKEYS from server.
*/
crWaitUntil(pktin);
if (pktin->type != SSH2_MSG_NEWKEYS) {
bombout(("expected new-keys packet from server"));
|
| ︙ | | |
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
|
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
|
-
+
|
* work). Terminate.
*/
s->pktout = ssh2_pkt_init(SSH2_MSG_DISCONNECT);
ssh2_pkt_adduint32(s->pktout,SSH2_DISCONNECT_BY_APPLICATION);
ssh2_pkt_addstring(s->pktout, "No more passwords available"
" to try");
ssh2_pkt_addstring(s->pktout, "en"); /* language tag */
ssh2_pkt_send(ssh, s->pktout);
ssh2_pkt_send_noqueue(ssh, s->pktout);
logevent("Unable to authenticate");
connection_fatal(ssh->frontend,
"Unable to authenticate");
ssh_closing((Plug)ssh, NULL, 0, 0);
crStopV;
}
} else {
|
| ︙ | | |
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
|
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
|
-
+
|
logevent("No supported authentications offered."
" Disconnecting");
s->pktout = ssh2_pkt_init(SSH2_MSG_DISCONNECT);
ssh2_pkt_adduint32(s->pktout, SSH2_DISCONNECT_BY_APPLICATION);
ssh2_pkt_addstring(s->pktout, "No supported authentication"
" methods available");
ssh2_pkt_addstring(s->pktout, "en"); /* language tag */
ssh2_pkt_send(ssh, s->pktout);
ssh2_pkt_send_noqueue(ssh, s->pktout);
ssh_closing((Plug)ssh, NULL, 0, 0);
crStopV;
}
}
} while (!s->we_are_in);
/*
|
| ︙ | | |
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
|
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
|
-
+
|
* this is more polite than sending a
* DISCONNECT. So now we don't.
*/
s->pktout = ssh2_pkt_init(SSH2_MSG_DISCONNECT);
ssh2_pkt_adduint32(s->pktout, SSH2_DISCONNECT_BY_APPLICATION);
ssh2_pkt_addstring(s->pktout, "All open channels closed");
ssh2_pkt_addstring(s->pktout, "en"); /* language tag */
ssh2_pkt_send(ssh, s->pktout);
ssh2_pkt_send_noqueue(ssh, s->pktout);
#endif
ssh_closing((Plug)ssh, NULL, 0, 0);
crStopV;
}
continue; /* remote sends close; ignore (FIXME) */
} else if (pktin->type == SSH2_MSG_CHANNEL_WINDOW_ADJUST) {
unsigned i = ssh_pkt_getuint32(pktin);
|
| ︙ | | |
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
|
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
|
-
+
|
sprintf(buf, "Received channel request for nonexistent"
" channel %d", localid);
logevent(buf);
s->pktout = ssh2_pkt_init(SSH2_MSG_DISCONNECT);
ssh2_pkt_adduint32(s->pktout, SSH2_DISCONNECT_BY_APPLICATION);
ssh2_pkt_addstring(s->pktout, buf);
ssh2_pkt_addstring(s->pktout, "en"); /* language tag */
ssh2_pkt_send(ssh, s->pktout);
ssh2_pkt_send_noqueue(ssh, s->pktout);
connection_fatal(ssh->frontend, "%s", buf);
ssh_closing((Plug)ssh, NULL, 0, 0);
crStopV;
}
/*
* Having got the channel number, we now look at
|
| ︙ | | |
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
|
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
|
+
+
+
|
ssh->do_ssh_init_state = NULL;
ssh->do_ssh1_login_state = NULL;
ssh->do_ssh2_transport_state = NULL;
ssh->do_ssh2_authconn_state = NULL;
ssh->mainchan = NULL;
ssh->throttled_all = 0;
ssh->v1_stdout_throttling = 0;
ssh->queue = NULL;
ssh->queuelen = ssh->queuesize = 0;
ssh->queueing = FALSE;
*backend_handle = ssh;
#ifdef MSCRYPTOAPI
if (crypto_startup() == 0)
return "Microsoft high encryption pack not installed!";
#endif
|
| ︙ | | |
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
|
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
|
+
+
+
+
|
ssh->sccomp->decompress_cleanup(ssh->sc_comp_ctx);
else
zlib_decompress_cleanup(ssh->sc_comp_ctx);
}
if (ssh->kex_ctx)
dh_cleanup(ssh->kex_ctx);
sfree(ssh->savedhost);
while (ssh->queuelen-- > 0)
ssh_free_packet(ssh->queue[ssh->queuelen]);
sfree(ssh->queue);
if (ssh->channels) {
while ((c = delpos234(ssh->channels, 0)) != NULL) {
switch (c->type) {
case CHAN_X11:
if (c->u.x11.s != NULL)
x11_close(c->u.x11.s);
|
| ︙ | | |
7092
7093
7094
7095
7096
7097
7098
7099
7100
7101
7102
7103
7104
7105
7106
|
7205
7206
7207
7208
7209
7210
7211
7212
7213
7214
7215
7216
7217
7218
7219
|
-
+
|
|| ssh->state == SSH_STATE_PREPACKET) return;
if (ssh->version == 1) {
if (!(ssh->remote_bugs & BUG_CHOKES_ON_SSH1_IGNORE))
send_packet(ssh, SSH1_MSG_IGNORE, PKT_STR, "", PKT_END);
} else {
pktout = ssh2_pkt_init(SSH2_MSG_IGNORE);
ssh2_pkt_addstring_start(pktout);
ssh2_pkt_send(ssh, pktout);
ssh2_pkt_send_noqueue(ssh, pktout);
}
} else if (code == TS_BRK) {
if (ssh->state == SSH_STATE_CLOSED
|| ssh->state == SSH_STATE_PREPACKET) return;
if (ssh->version == 1) {
logevent("Unable to send BREAK signal in SSH1");
} else if (ssh->mainchan) {
|
| ︙ | | |