libssh2

Форк
0
/
transport.c 
1141 строка · 44.9 Кб
1
/* Copyright (C) The Written Word, Inc.
2
 * Copyright (C) Daniel Stenberg
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms,
6
 * with or without modification, are permitted provided
7
 * that the following conditions are met:
8
 *
9
 *   Redistributions of source code must retain the above
10
 *   copyright notice, this list of conditions and the
11
 *   following disclaimer.
12
 *
13
 *   Redistributions in binary form must reproduce the above
14
 *   copyright notice, this list of conditions and the following
15
 *   disclaimer in the documentation and/or other materials
16
 *   provided with the distribution.
17
 *
18
 *   Neither the name of the copyright holder nor the names
19
 *   of any other contributors may be used to endorse or
20
 *   promote products derived from this software without
21
 *   specific prior written permission.
22
 *
23
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
24
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
25
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
28
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
35
 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
36
 * OF SUCH DAMAGE.
37
 *
38
 * SPDX-License-Identifier: BSD-3-Clause
39
 */
40

41
/*
42
 * This file handles reading and writing to the SECSH transport layer. RFC4253.
43
 */
44

45
#include "libssh2_priv.h"
46

47
#include <errno.h>
48
#include <ctype.h>
49
#include <assert.h>
50

51
#include "transport.h"
52
#include "mac.h"
53

54
#ifdef LIBSSH2DEBUG
55
#define UNPRINTABLE_CHAR '.'
56
static void
57
debugdump(LIBSSH2_SESSION * session,
58
          const char *desc, const unsigned char *ptr, size_t size)
59
{
60
    size_t i;
61
    size_t c;
62
    unsigned int width = 0x10;
63
    char buffer[256];  /* Must be enough for width*4 + about 30 or so */
64
    size_t used;
65
    static const char *hex_chars = "0123456789ABCDEF";
66

67
    if(!(session->showmask & LIBSSH2_TRACE_TRANS)) {
68
        /* not asked for, bail out */
69
        return;
70
    }
71

72
    used = snprintf(buffer, sizeof(buffer), "=> %s (%lu bytes)\n",
73
                    desc, (unsigned long) size);
74
    if(session->tracehandler)
75
        (session->tracehandler)(session, session->tracehandler_context,
76
                                buffer, used);
77
    else
78
        fprintf(stderr, "%s", buffer);
79

80
    for(i = 0; i < size; i += width) {
81

82
        used = snprintf(buffer, sizeof(buffer), "%04lx: ", (long)i);
83

84
        /* hex not disabled, show it */
85
        for(c = 0; c < width; c++) {
86
            if(i + c < size) {
87
                buffer[used++] = hex_chars[(ptr[i + c] >> 4) & 0xF];
88
                buffer[used++] = hex_chars[ptr[i + c] & 0xF];
89
            }
90
            else {
91
                buffer[used++] = ' ';
92
                buffer[used++] = ' ';
93
            }
94

95
            buffer[used++] = ' ';
96
            if((width/2) - 1 == c)
97
                buffer[used++] = ' ';
98
        }
99

100
        buffer[used++] = ':';
101
        buffer[used++] = ' ';
102

103
        for(c = 0; (c < width) && (i + c < size); c++) {
104
            buffer[used++] = isprint(ptr[i + c]) ?
105
                ptr[i + c] : UNPRINTABLE_CHAR;
106
        }
107
        buffer[used++] = '\n';
108
        buffer[used] = 0;
109

110
        if(session->tracehandler)
111
            (session->tracehandler)(session, session->tracehandler_context,
112
                                    buffer, used);
113
        else
114
            fprintf(stderr, "%s", buffer);
115
    }
116
}
117
#else
118
#define debugdump(a,x,y,z) do {} while(0)
119
#endif
120

121

122
/* decrypt() decrypts 'len' bytes from 'source' to 'dest' in units of
123
 * blocksize.
124
 *
125
 * returns 0 on success and negative on failure
126
 */
127

128
static int
129
decrypt(LIBSSH2_SESSION * session, unsigned char *source,
130
        unsigned char *dest, ssize_t len, int firstlast)
131
{
132
    struct transportpacket *p = &session->packet;
133
    int blocksize = session->remote.crypt->blocksize;
134

135
    /* if we get called with a len that isn't an even number of blocksizes
136
       we risk losing those extra bytes. AAD is an exception, since those first
137
       few bytes aren't encrypted so it throws off the rest of the count. */
138
    if(!CRYPT_FLAG_L(session, PKTLEN_AAD))
139
        assert((len % blocksize) == 0);
140

141
    while(len > 0) {
142
        /* normally decrypt up to blocksize bytes at a time */
143
        ssize_t decryptlen = LIBSSH2_MIN(blocksize, len);
144
        /* The first block is special (since it needs to be decoded to get the
145
           length of the remainder of the block) and takes priority. When the
146
           length finally gets to the last blocksize bytes, and there's no
147
           more data to come, it's the end. */
148
        int lowerfirstlast = IS_FIRST(firstlast) ? FIRST_BLOCK :
149
            ((len <= blocksize) ? firstlast : MIDDLE_BLOCK);
150
        /* If the last block would be less than a whole blocksize, combine it
151
           with the previous block to make it larger. This ensures that the
152
           whole MAC is included in a single decrypt call. */
153
        if(CRYPT_FLAG_L(session, PKTLEN_AAD) && IS_LAST(firstlast)
154
           && (len < blocksize*2)) {
155
            decryptlen = len;
156
            lowerfirstlast = LAST_BLOCK;
157
        }
158

159
        if(session->remote.crypt->crypt(session, source, decryptlen,
160
                                        &session->remote.crypt_abstract,
161
                                        lowerfirstlast)) {
162
            LIBSSH2_FREE(session, p->payload);
163
            return LIBSSH2_ERROR_DECRYPT;
164
        }
165

166
        /* if the crypt() function would write to a given address it
167
           wouldn't have to memcpy() and we could avoid this memcpy()
168
           too */
169
        memcpy(dest, source, decryptlen);
170

171
        len -= decryptlen;       /* less bytes left */
172
        dest += decryptlen;      /* advance write pointer */
173
        source += decryptlen;    /* advance read pointer */
174
    }
175
    return LIBSSH2_ERROR_NONE;         /* all is fine */
176
}
177

178
/*
179
 * fullpacket() gets called when a full packet has been received and properly
180
 * collected.
181
 */
182
static int
183
fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
184
{
185
    unsigned char macbuf[MAX_MACSIZE];
186
    struct transportpacket *p = &session->packet;
187
    int rc;
188
    int compressed;
189
    uint32_t seq = session->remote.seqno;
190

191
    if(session->fullpacket_state == libssh2_NB_state_idle) {
192
        session->fullpacket_macstate = LIBSSH2_MAC_CONFIRMED;
193
        session->fullpacket_payload_len = p->packet_length - 1;
194

195
        if(encrypted && !CRYPT_FLAG_L(session, INTEGRATED_MAC)) {
196

197
            /* Calculate MAC hash */
198
            int etm = session->remote.mac->etm;
199
            size_t mac_len = session->remote.mac->mac_len;
200
            if(etm) {
201
                /* store hash here */
202
                session->remote.mac->hash(session, macbuf,
203
                                          session->remote.seqno,
204
                                          p->payload, p->total_num - mac_len,
205
                                          NULL, 0,
206
                                          &session->remote.mac_abstract);
207
            }
208
            else {
209
                /* store hash here */
210
                session->remote.mac->hash(session, macbuf,
211
                                          session->remote.seqno,
212
                                          p->init, 5,
213
                                          p->payload,
214
                                          session->fullpacket_payload_len,
215
                                          &session->remote.mac_abstract);
216
            }
217

218
            /* Compare the calculated hash with the MAC we just read from
219
             * the network. The read one is at the very end of the payload
220
             * buffer. Note that 'payload_len' here is the packet_length
221
             * field which includes the padding but not the MAC.
222
             */
223
            if(memcmp(macbuf, p->payload + p->total_num - mac_len, mac_len)) {
224
                _libssh2_debug((session, LIBSSH2_TRACE_SOCKET,
225
                               "Failed MAC check"));
226
                session->fullpacket_macstate = LIBSSH2_MAC_INVALID;
227

228
            }
229
            else if(etm) {
230
                /* MAC was ok and we start by decrypting the first block that
231
                   contains padding length since this allows us to decrypt
232
                   all other blocks to the right location in memory
233
                   avoiding moving a larger block of memory one byte. */
234
                unsigned char first_block[MAX_BLOCKSIZE];
235
                ssize_t decrypt_size;
236
                unsigned char *decrypt_buffer;
237
                int blocksize = session->remote.crypt->blocksize;
238

239
                rc = decrypt(session, p->payload + 4,
240
                             first_block, blocksize, FIRST_BLOCK);
241
                if(rc) {
242
                    return rc;
243
                }
244

245
                /* we need buffer for decrypt */
246
                decrypt_size = p->total_num - mac_len - 4;
247
                decrypt_buffer = LIBSSH2_ALLOC(session, decrypt_size);
248
                if(!decrypt_buffer) {
249
                    return LIBSSH2_ERROR_ALLOC;
250
                }
251

252
                /* grab padding length and copy anything else
253
                   into target buffer */
254
                p->padding_length = first_block[0];
255
                if(blocksize > 1) {
256
                    memcpy(decrypt_buffer, first_block + 1, blocksize - 1);
257
                }
258

259
                /* decrypt all other blocks packet */
260
                if(blocksize < decrypt_size) {
261
                    rc = decrypt(session, p->payload + blocksize + 4,
262
                                 decrypt_buffer + blocksize - 1,
263
                                 decrypt_size - blocksize, LAST_BLOCK);
264
                    if(rc) {
265
                        LIBSSH2_FREE(session, decrypt_buffer);
266
                        return rc;
267
                    }
268
                }
269

270
                /* replace encrypted payload with plain text payload */
271
                LIBSSH2_FREE(session, p->payload);
272
                p->payload = decrypt_buffer;
273
            }
274
        }
275

276
        session->remote.seqno++;
277

278
        /* ignore the padding */
279
        session->fullpacket_payload_len -= p->padding_length;
280

281
        /* Check for and deal with decompression */
282
        compressed = session->local.comp &&
283
                     session->local.comp->compress &&
284
                     ((session->state & LIBSSH2_STATE_AUTHENTICATED) ||
285
                      session->local.comp->use_in_auth);
286

287
        if(compressed && session->remote.comp_abstract) {
288
            /*
289
             * The buffer for the decompression (remote.comp_abstract) is
290
             * initialised in time when it is needed so as long it is NULL we
291
             * cannot decompress.
292
             */
293

294
            unsigned char *data;
295
            size_t data_len;
296
            rc = session->remote.comp->decomp(session,
297
                                              &data, &data_len,
298
                                              LIBSSH2_PACKET_MAXDECOMP,
299
                                              p->payload,
300
                                              session->fullpacket_payload_len,
301
                                              &session->remote.comp_abstract);
302
            LIBSSH2_FREE(session, p->payload);
303
            if(rc)
304
                return rc;
305

306
            p->payload = data;
307
            session->fullpacket_payload_len = data_len;
308
        }
309

310
        session->fullpacket_packet_type = p->payload[0];
311

312
        debugdump(session, "libssh2_transport_read() plain",
313
                  p->payload, session->fullpacket_payload_len);
314

315
        session->fullpacket_state = libssh2_NB_state_created;
316
    }
317

318
    if(session->fullpacket_state == libssh2_NB_state_created) {
319
        rc = _libssh2_packet_add(session, p->payload,
320
                                 session->fullpacket_payload_len,
321
                                 session->fullpacket_macstate, seq);
322
        if(rc == LIBSSH2_ERROR_EAGAIN)
323
            return rc;
324
        if(rc) {
325
            session->fullpacket_state = libssh2_NB_state_idle;
326
            return rc;
327
        }
328
    }
329

330
    session->fullpacket_state = libssh2_NB_state_idle;
331

332
    if(session->kex_strict &&
333
        session->fullpacket_packet_type == SSH_MSG_NEWKEYS) {
334
        session->remote.seqno = 0;
335
    }
336

337
    return session->fullpacket_packet_type;
338
}
339

340

341
/*
342
 * _libssh2_transport_read
343
 *
344
 * Collect a packet into the input queue.
345
 *
346
 * Returns packet type added to input queue (0 if nothing added), or a
347
 * negative error number.
348
 */
349

350
/*
351
 * This function reads the binary stream as specified in chapter 6 of RFC4253
352
 * "The Secure Shell (SSH) Transport Layer Protocol"
353
 *
354
 * DOES NOT call _libssh2_error() for ANY error case.
355
 */
356
int _libssh2_transport_read(LIBSSH2_SESSION * session)
357
{
358
    int rc;
359
    struct transportpacket *p = &session->packet;
360
    ssize_t remainpack; /* how much there is left to add to the current payload
361
                           package */
362
    ssize_t remainbuf;  /* how much data there is remaining in the buffer to
363
                           deal with before we should read more from the
364
                           network */
365
    ssize_t numbytes;   /* how much data to deal with from the buffer on this
366
                           iteration through the loop */
367
    ssize_t numdecrypt; /* number of bytes to decrypt this iteration */
368
    unsigned char block[MAX_BLOCKSIZE]; /* working block buffer */
369
    int blocksize;  /* minimum number of bytes we need before we can
370
                       use them */
371
    int encrypted = 1; /* whether the packet is encrypted or not */
372
    int firstlast = FIRST_BLOCK; /* if the first or last block to decrypt */
373

374
    /* default clear the bit */
375
    session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_INBOUND;
376

377
    /*
378
     * All channels, systems, subsystems, etc eventually make it down here
379
     * when looking for more incoming data. If a key exchange is going on
380
     * (LIBSSH2_STATE_EXCHANGING_KEYS bit is set) then the remote end will
381
     * ONLY send key exchange related traffic. In non-blocking mode, there is
382
     * a chance to break out of the kex_exchange function with an EAGAIN
383
     * status, and never come back to it. If LIBSSH2_STATE_EXCHANGING_KEYS is
384
     * active, then we must redirect to the key exchange. However, if
385
     * kex_exchange is active (as in it is the one that calls this execution
386
     * of packet_read, then don't redirect, as that would be an infinite loop!
387
     */
388

389
    if(session->state & LIBSSH2_STATE_EXCHANGING_KEYS &&
390
        !(session->state & LIBSSH2_STATE_KEX_ACTIVE)) {
391

392
        /* Whoever wants a packet won't get anything until the key re-exchange
393
         * is done!
394
         */
395
        _libssh2_debug((session, LIBSSH2_TRACE_TRANS, "Redirecting into the"
396
                       " key re-exchange from _libssh2_transport_read"));
397
        rc = _libssh2_kex_exchange(session, 1, &session->startup_key_state);
398
        if(rc)
399
            return rc;
400
    }
401

402
    /*
403
     * =============================== NOTE ===============================
404
     * I know this is very ugly and not a really good use of "goto", but
405
     * this case statement would be even uglier to do it any other way
406
     */
407
    if(session->readPack_state == libssh2_NB_state_jump1) {
408
        session->readPack_state = libssh2_NB_state_idle;
409
        encrypted = session->readPack_encrypted;
410
        goto libssh2_transport_read_point1;
411
    }
412

413
    do {
414
        int etm;
415
        if(session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) {
416
            return LIBSSH2_ERROR_SOCKET_DISCONNECT;
417
        }
418

419
        if(session->state & LIBSSH2_STATE_NEWKEYS) {
420
            blocksize = session->remote.crypt->blocksize;
421
        }
422
        else {
423
            encrypted = 0;      /* not encrypted */
424
            blocksize = 5;      /* not strictly true, but we can use 5 here to
425
                                   make the checks below work fine still */
426
        }
427

428
        etm = encrypted && session->remote.mac ? session->remote.mac->etm : 0;
429

430
        /* read/use a whole big chunk into a temporary area stored in
431
           the LIBSSH2_SESSION struct. We will decrypt data from that
432
           buffer into the packet buffer so this temp one doesn't have
433
           to be able to keep a whole SSH packet, just be large enough
434
           so that we can read big chunks from the network layer. */
435

436
        /* how much data there is remaining in the buffer to deal with
437
           before we should read more from the network */
438
        remainbuf = p->writeidx - p->readidx;
439

440
        /* if remainbuf turns negative we have a bad internal error */
441
        assert(remainbuf >= 0);
442

443
        if(remainbuf < blocksize) {
444
            /* If we have less than a blocksize left, it is too
445
               little data to deal with, read more */
446
            ssize_t nread;
447

448
            /* move any remainder to the start of the buffer so
449
               that we can do a full refill */
450
            if(remainbuf) {
451
                memmove(p->buf, &p->buf[p->readidx], remainbuf);
452
                p->readidx = 0;
453
                p->writeidx = remainbuf;
454
            }
455
            else {
456
                /* nothing to move, just zero the indexes */
457
                p->readidx = p->writeidx = 0;
458
            }
459

460
            /* now read a big chunk from the network into the temp buffer */
461
            nread = LIBSSH2_RECV(session, &p->buf[remainbuf],
462
                                 PACKETBUFSIZE - remainbuf,
463
                                 LIBSSH2_SOCKET_RECV_FLAGS(session));
464
            if(nread <= 0) {
465
                /* check if this is due to EAGAIN and return the special
466
                   return code if so, error out normally otherwise */
467
                if((nread < 0) && (nread == -EAGAIN)) {
468
                    session->socket_block_directions |=
469
                        LIBSSH2_SESSION_BLOCK_INBOUND;
470
                    return LIBSSH2_ERROR_EAGAIN;
471
                }
472
                _libssh2_debug((session, LIBSSH2_TRACE_SOCKET,
473
                               "Error recving %ld bytes (got %ld)",
474
                               (long)(PACKETBUFSIZE - remainbuf),
475
                               (long)-nread));
476
                return LIBSSH2_ERROR_SOCKET_RECV;
477
            }
478
            _libssh2_debug((session, LIBSSH2_TRACE_SOCKET,
479
                           "Recved %ld/%ld bytes to %p+%ld", (long)nread,
480
                           (long)(PACKETBUFSIZE - remainbuf), (void *)p->buf,
481
                           (long)remainbuf));
482

483
            debugdump(session, "libssh2_transport_read() raw",
484
                      &p->buf[remainbuf], nread);
485
            /* advance write pointer */
486
            p->writeidx += nread;
487

488
            /* update remainbuf counter */
489
            remainbuf = p->writeidx - p->readidx;
490
        }
491

492
        /* how much data to deal with from the buffer */
493
        numbytes = remainbuf;
494

495
        if(!p->total_num) {
496
            size_t total_num; /* the number of bytes following the initial
497
                                 (5 bytes) packet length and padding length
498
                                 fields */
499

500
            /* packet length is not encrypted in encode-then-mac mode
501
               and we donøt need to decrypt first block */
502
            ssize_t required_size = etm ? 4 : blocksize;
503

504
            /* No payload package area allocated yet. To know the
505
               size of this payload, we need enough to decrypt the first
506
               blocksize data. */
507

508
            if(numbytes < required_size) {
509
                /* we can't act on anything less than blocksize, but this
510
                   check is only done for the initial block since once we have
511
                   got the start of a block we can in fact deal with fractions
512
                */
513
                session->socket_block_directions |=
514
                    LIBSSH2_SESSION_BLOCK_INBOUND;
515
                return LIBSSH2_ERROR_EAGAIN;
516
            }
517

518
            if(etm) {
519
                p->packet_length = _libssh2_ntohu32(&p->buf[p->readidx]);
520
            }
521
            else {
522
                if(encrypted) {
523
                    /* first decrypted block */
524
                    rc = decrypt(session, &p->buf[p->readidx],
525
                                 block, blocksize, FIRST_BLOCK);
526
                    if(rc != LIBSSH2_ERROR_NONE) {
527
                        return rc;
528
                    }
529
                    /* Save the first 5 bytes of the decrypted package, to be
530
                       used in the hash calculation later down.
531
                       This is ignored in the INTEGRATED_MAC case. */
532
                    memcpy(p->init, block, 5);
533
                }
534
                else {
535
                    /* the data is plain, just copy it verbatim to
536
                       the working block buffer */
537
                    memcpy(block, &p->buf[p->readidx], blocksize);
538
                }
539

540
                /* advance the read pointer */
541
                p->readidx += blocksize;
542

543
                /* we now have the initial blocksize bytes decrypted,
544
                 * and we can extract packet and padding length from it
545
                 */
546
                p->packet_length = _libssh2_ntohu32(block);
547
            }
548

549
            if(p->packet_length < 1) {
550
                return LIBSSH2_ERROR_DECRYPT;
551
            }
552
            else if(p->packet_length > LIBSSH2_PACKET_MAXPAYLOAD) {
553
                return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
554
            }
555

556
            if(etm) {
557
                /* we collect entire undecrypted packet including the
558
                   packet length field that we run MAC over */
559
                total_num = 4 + p->packet_length +
560
                            session->remote.mac->mac_len;
561
            }
562
            else {
563
                /* padding_length has not been authenticated yet, but it won't
564
                   actually be used (except for the sanity check immediately
565
                   following) until after the entire packet is authenticated,
566
                   so this is safe. */
567
                p->padding_length = block[4];
568
                if(p->padding_length > p->packet_length - 1) {
569
                    return LIBSSH2_ERROR_DECRYPT;
570
                }
571

572
                /* total_num is the number of bytes following the initial
573
                   (5 bytes) packet length and padding length fields */
574
                total_num = p->packet_length - 1 +
575
                            (encrypted ? session->remote.mac->mac_len : 0);
576
            }
577

578
            /* RFC4253 section 6.1 Maximum Packet Length says:
579
             *
580
             * "All implementations MUST be able to process
581
             * packets with uncompressed payload length of 32768
582
             * bytes or less and total packet size of 35000 bytes
583
             * or less (including length, padding length, payload,
584
             * padding, and MAC.)."
585
             */
586
            if(total_num > LIBSSH2_PACKET_MAXPAYLOAD || total_num == 0) {
587
                return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
588
            }
589

590
            /* Get a packet handle put data into. We get one to
591
               hold all data, including padding and MAC. */
592
            p->payload = LIBSSH2_ALLOC(session, total_num);
593
            if(!p->payload) {
594
                return LIBSSH2_ERROR_ALLOC;
595
            }
596
            p->total_num = total_num;
597
            /* init write pointer to start of payload buffer */
598
            p->wptr = p->payload;
599

600
            if(!etm && blocksize > 5) {
601
                /* copy the data from index 5 to the end of
602
                   the blocksize from the temporary buffer to
603
                   the start of the decrypted buffer */
604
                if(blocksize - 5 <= (int) total_num) {
605
                    memcpy(p->wptr, &block[5], blocksize - 5);
606
                    p->wptr += blocksize - 5;       /* advance write pointer */
607
                    if(etm) {
608
                        /* advance past unencrypted packet length */
609
                        p->wptr += 4;
610
                    }
611
                }
612
                else {
613
                    if(p->payload)
614
                        LIBSSH2_FREE(session, p->payload);
615
                    return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
616
                }
617
            }
618

619
            /* init the data_num field to the number of bytes of
620
               the package read so far */
621
            p->data_num = p->wptr - p->payload;
622

623
            /* we already dealt with a blocksize worth of data */
624
            if(!etm)
625
                numbytes -= blocksize;
626
        }
627

628
        /* how much there is left to add to the current payload
629
           package */
630
        remainpack = p->total_num - p->data_num;
631

632
        if(numbytes > remainpack) {
633
            /* if we have more data in the buffer than what is going into this
634
               particular packet, we limit this round to this packet only */
635
            numbytes = remainpack;
636
        }
637

638
        if(encrypted && !etm) {
639
            /* At the end of the incoming stream, there is a MAC,
640
               and we don't want to decrypt that since we need it
641
               "raw". We MUST however decrypt the padding data
642
               since it is used for the hash later on. */
643
            int skip = session->remote.mac->mac_len;
644

645
            if(CRYPT_FLAG_R(session, INTEGRATED_MAC))
646
                /* This crypto method DOES need the MAC to go through
647
                   decryption so it can be authenticated. */
648
                skip = 0;
649

650
            /* if what we have plus numbytes is bigger than the
651
               total minus the skip margin, we should lower the
652
               amount to decrypt even more */
653
            if((p->data_num + numbytes) >= (p->total_num - skip)) {
654
                /* decrypt the entire rest of the package */
655
                numdecrypt = LIBSSH2_MAX(0,
656
                    (int)(p->total_num - skip) - (int)p->data_num);
657
                firstlast = LAST_BLOCK;
658
            }
659
            else {
660
                ssize_t frac;
661
                numdecrypt = numbytes;
662
                frac = numdecrypt % blocksize;
663
                if(frac) {
664
                    /* not an aligned amount of blocks, align it by reducing
665
                       the number of bytes processed this loop */
666
                    numdecrypt -= frac;
667
                    /* and make it no unencrypted data
668
                       after it */
669
                    numbytes = 0;
670
                }
671
                if(CRYPT_FLAG_R(session, INTEGRATED_MAC)) {
672
                    /* Make sure that we save enough bytes to make the last
673
                     * block large enough to hold the entire integrated MAC */
674
                    numdecrypt = LIBSSH2_MIN(numdecrypt,
675
                        (int)(p->total_num - skip - blocksize - p->data_num));
676
                    numbytes = 0;
677
                }
678
                firstlast = MIDDLE_BLOCK;
679
            }
680
        }
681
        else {
682
            /* unencrypted data should not be decrypted at all */
683
            numdecrypt = 0;
684
        }
685
        assert(numdecrypt >= 0);
686

687
        /* if there are bytes to decrypt, do that */
688
        if(numdecrypt > 0) {
689
            /* now decrypt the lot */
690
            rc = decrypt(session, &p->buf[p->readidx], p->wptr, numdecrypt,
691
                         firstlast);
692
            if(rc != LIBSSH2_ERROR_NONE) {
693
                p->total_num = 0;   /* no packet buffer available */
694
                return rc;
695
            }
696

697
            /* advance the read pointer */
698
            p->readidx += numdecrypt;
699
            /* advance write pointer */
700
            p->wptr += numdecrypt;
701
            /* increase data_num */
702
            p->data_num += numdecrypt;
703

704
            /* bytes left to take care of without decryption */
705
            numbytes -= numdecrypt;
706
        }
707

708
        /* if there are bytes to copy that aren't decrypted,
709
           copy them as-is to the target buffer */
710
        if(numbytes > 0) {
711

712
            if((size_t)numbytes <= (p->total_num - (p->wptr - p->payload))) {
713
                memcpy(p->wptr, &p->buf[p->readidx], numbytes);
714
            }
715
            else {
716
                if(p->payload)
717
                    LIBSSH2_FREE(session, p->payload);
718
                return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
719
            }
720

721
            /* advance the read pointer */
722
            p->readidx += numbytes;
723
            /* advance write pointer */
724
            p->wptr += numbytes;
725
            /* increase data_num */
726
            p->data_num += numbytes;
727
        }
728

729
        /* now check how much data there's left to read to finish the
730
           current packet */
731
        remainpack = p->total_num - p->data_num;
732

733
        if(!remainpack) {
734
            /* we have a full packet */
735
libssh2_transport_read_point1:
736
            rc = fullpacket(session, encrypted);
737
            if(rc == LIBSSH2_ERROR_EAGAIN) {
738

739
                if(session->packAdd_state != libssh2_NB_state_idle) {
740
                    /* fullpacket only returns LIBSSH2_ERROR_EAGAIN if
741
                     * libssh2_packet_add() returns LIBSSH2_ERROR_EAGAIN. If
742
                     * that returns LIBSSH2_ERROR_EAGAIN but the packAdd_state
743
                     * is idle, then the packet has been added to the brigade,
744
                     * but some immediate action that was taken based on the
745
                     * packet type (such as key re-exchange) is not yet
746
                     * complete.  Clear the way for a new packet to be read
747
                     * in.
748
                     */
749
                    session->readPack_encrypted = encrypted;
750
                    session->readPack_state = libssh2_NB_state_jump1;
751
                }
752

753
                return rc;
754
            }
755

756
            p->total_num = 0;   /* no packet buffer available */
757

758
            return rc;
759
        }
760
    } while(1);                /* loop */
761

762
    return LIBSSH2_ERROR_SOCKET_RECV; /* we never reach this point */
763
}
764

765
static int
766
send_existing(LIBSSH2_SESSION *session, const unsigned char *data,
767
              size_t data_len, ssize_t *ret)
768
{
769
    ssize_t rc;
770
    ssize_t length;
771
    struct transportpacket *p = &session->packet;
772

773
    if(!p->olen) {
774
        *ret = 0;
775
        return LIBSSH2_ERROR_NONE;
776
    }
777

778
    /* send as much as possible of the existing packet */
779
    if((data != p->odata) || (data_len != p->olen)) {
780
        /* When we are about to complete the sending of a packet, it is vital
781
           that the caller doesn't try to send a new/different packet since
782
           we don't add this one up until the previous one has been sent. To
783
           make the caller really notice his/hers flaw, we return error for
784
           this case */
785
        _libssh2_debug((session, LIBSSH2_TRACE_SOCKET,
786
                       "Address is different, but will resume nonetheless"));
787
    }
788

789
    *ret = 1;                   /* set to make our parent return */
790

791
    /* number of bytes left to send */
792
    length = p->ototal_num - p->osent;
793

794
    rc = LIBSSH2_SEND(session, &p->outbuf[p->osent], length,
795
                      LIBSSH2_SOCKET_SEND_FLAGS(session));
796
    if(rc < 0)
797
        _libssh2_debug((session, LIBSSH2_TRACE_SOCKET,
798
                       "Error sending %ld bytes: %ld",
799
                       (long)length, (long)-rc));
800
    else {
801
        _libssh2_debug((session, LIBSSH2_TRACE_SOCKET,
802
                       "Sent %ld/%ld bytes at %p+%lu", (long)rc, (long)length,
803
                       (void *)p->outbuf, (unsigned long)p->osent));
804
        debugdump(session, "libssh2_transport_write send()",
805
                  &p->outbuf[p->osent], rc);
806
    }
807

808
    if(rc == length) {
809
        /* the remainder of the package was sent */
810
        p->ototal_num = 0;
811
        p->olen = 0;
812
        /* we leave *ret set so that the parent returns as we MUST return back
813
           a send success now, so that we don't risk sending EAGAIN later
814
           which then would confuse the parent function */
815
        return LIBSSH2_ERROR_NONE;
816

817
    }
818
    else if(rc < 0) {
819
        /* nothing was sent */
820
        if(rc != -EAGAIN)
821
            /* send failure! */
822
            return LIBSSH2_ERROR_SOCKET_SEND;
823

824
        session->socket_block_directions |= LIBSSH2_SESSION_BLOCK_OUTBOUND;
825
        return LIBSSH2_ERROR_EAGAIN;
826
    }
827

828
    p->osent += rc;         /* we sent away this much data */
829

830
    return rc < length ? LIBSSH2_ERROR_EAGAIN : LIBSSH2_ERROR_NONE;
831
}
832

833
/*
834
 * libssh2_transport_send
835
 *
836
 * Send a packet, encrypting it and adding a MAC code if necessary
837
 * Returns 0 on success, non-zero on failure.
838
 *
839
 * The data is provided as _two_ data areas that are combined by this
840
 * function.  The 'data' part is sent immediately before 'data2'. 'data2' may
841
 * be set to NULL to only use a single part.
842
 *
843
 * Returns LIBSSH2_ERROR_EAGAIN if it would block or if the whole packet was
844
 * not sent yet. If it does so, the caller should call this function again as
845
 * soon as it is likely that more data can be sent, and this function MUST
846
 * then be called with the same argument set (same data pointer and same
847
 * data_len) until ERROR_NONE or failure is returned.
848
 *
849
 * This function DOES NOT call _libssh2_error() on any errors.
850
 */
851
int _libssh2_transport_send(LIBSSH2_SESSION *session,
852
                            const unsigned char *data, size_t data_len,
853
                            const unsigned char *data2, size_t data2_len)
854
{
855
    int blocksize =
856
        (session->state & LIBSSH2_STATE_NEWKEYS) ?
857
        session->local.crypt->blocksize : 8;
858
    ssize_t padding_length;
859
    size_t packet_length;
860
    ssize_t total_length;
861
#ifdef LIBSSH2_RANDOM_PADDING
862
    int rand_max;
863
    int seed = data[0];         /* FIXME: make this random */
864
#endif
865
    struct transportpacket *p = &session->packet;
866
    int encrypted;
867
    int compressed;
868
    int etm;
869
    ssize_t ret;
870
    int rc;
871
    const unsigned char *orgdata = data;
872
    size_t orgdata_len = data_len;
873
    size_t crypt_offset, etm_crypt_offset;
874

875
    /*
876
     * If the last read operation was interrupted in the middle of a key
877
     * exchange, we must complete that key exchange before continuing to write
878
     * further data.
879
     *
880
     * See the similar block in _libssh2_transport_read for more details.
881
     */
882
    if(session->state & LIBSSH2_STATE_EXCHANGING_KEYS &&
883
        !(session->state & LIBSSH2_STATE_KEX_ACTIVE)) {
884
        /* Don't write any new packets if we're still in the middle of a key
885
         * exchange. */
886
        _libssh2_debug((session, LIBSSH2_TRACE_TRANS, "Redirecting into the"
887
                       " key re-exchange from _libssh2_transport_send"));
888
        rc = _libssh2_kex_exchange(session, 1, &session->startup_key_state);
889
        if(rc)
890
            return rc;
891
    }
892

893
    debugdump(session, "libssh2_transport_write plain", data, data_len);
894
    if(data2)
895
        debugdump(session, "libssh2_transport_write plain2", data2, data2_len);
896

897
    /* FIRST, check if we have a pending write to complete. send_existing
898
       only sanity-check data and data_len and not data2 and data2_len! */
899
    rc = send_existing(session, data, data_len, &ret);
900
    if(rc)
901
        return rc;
902

903
    session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_OUTBOUND;
904

905
    if(ret)
906
        /* set by send_existing if data was sent */
907
        return rc;
908

909
    encrypted = (session->state & LIBSSH2_STATE_NEWKEYS) ? 1 : 0;
910

911
    etm = encrypted && session->local.mac ? session->local.mac->etm : 0;
912

913
    compressed = session->local.comp &&
914
                 session->local.comp->compress &&
915
                 ((session->state & LIBSSH2_STATE_AUTHENTICATED) ||
916
                  session->local.comp->use_in_auth);
917

918
    if(encrypted && compressed && session->local.comp_abstract) {
919
        /* the idea here is that these function must fail if the output gets
920
           larger than what fits in the assigned buffer so thus they don't
921
           check the input size as we don't know how much it compresses */
922
        size_t dest_len = MAX_SSH_PACKET_LEN-5-256;
923
        size_t dest2_len = dest_len;
924

925
        /* compress directly to the target buffer */
926
        rc = session->local.comp->comp(session,
927
                                       &p->outbuf[5], &dest_len,
928
                                       data, data_len,
929
                                       &session->local.comp_abstract);
930
        if(rc)
931
            return rc;     /* compression failure */
932

933
        if(data2 && data2_len) {
934
            /* compress directly to the target buffer right after where the
935
               previous call put data */
936
            dest2_len -= dest_len;
937

938
            rc = session->local.comp->comp(session,
939
                                           &p->outbuf[5 + dest_len],
940
                                           &dest2_len,
941
                                           data2, data2_len,
942
                                           &session->local.comp_abstract);
943
        }
944
        else
945
            dest2_len = 0;
946
        if(rc)
947
            return rc;     /* compression failure */
948

949
        data_len = dest_len + dest2_len; /* use the combined length */
950
    }
951
    else {
952
        if((data_len + data2_len) >= (MAX_SSH_PACKET_LEN-0x100))
953
            /* too large packet, return error for this until we make this
954
               function split it up and send multiple SSH packets */
955
            return LIBSSH2_ERROR_INVAL;
956

957
        /* copy the payload data */
958
        memcpy(&p->outbuf[5], data, data_len);
959
        if(data2 && data2_len)
960
            memcpy(&p->outbuf[5 + data_len], data2, data2_len);
961
        data_len += data2_len; /* use the combined length */
962
    }
963

964

965
    /* RFC4253 says: Note that the length of the concatenation of
966
       'packet_length', 'padding_length', 'payload', and 'random padding'
967
       MUST be a multiple of the cipher block size or 8, whichever is
968
       larger. */
969

970
    /* Plain math: (4 + 1 + packet_length + padding_length) % blocksize == 0 */
971

972
    packet_length = data_len + 1 + 4;   /* 1 is for padding_length field
973
                                           4 for the packet_length field */
974
    /* subtract 4 bytes of the packet_length field when padding AES-GCM
975
       or with ETM */
976
    crypt_offset = (etm || (encrypted && CRYPT_FLAG_R(session, PKTLEN_AAD)))
977
                   ? 4 : 0;
978
    etm_crypt_offset = etm ? 4 : 0;
979

980
    /* at this point we have it all except the padding */
981

982
    /* first figure out our minimum padding amount to make it an even
983
       block size */
984
    padding_length = blocksize - ((packet_length - crypt_offset) % blocksize);
985

986
    /* if the padding becomes too small we add another blocksize worth
987
       of it (taken from the original libssh2 where it didn't have any
988
       real explanation) */
989
    if(padding_length < 4) {
990
        padding_length += blocksize;
991
    }
992
#ifdef LIBSSH2_RANDOM_PADDING
993
    /* FIXME: we can add padding here, but that also makes the packets
994
       bigger etc */
995

996
    /* now we can add 'blocksize' to the padding_length N number of times
997
       (to "help thwart traffic analysis") but it must be less than 255 in
998
       total */
999
    rand_max = (255 - padding_length) / blocksize + 1;
1000
    padding_length += blocksize * (seed % rand_max);
1001
#endif
1002

1003
    packet_length += padding_length;
1004

1005
    /* append the MAC length to the total_length size */
1006
    total_length =
1007
        packet_length + (encrypted ? session->local.mac->mac_len : 0);
1008

1009
    /* store packet_length, which is the size of the whole packet except
1010
       the MAC and the packet_length field itself */
1011
    _libssh2_htonu32(p->outbuf, (uint32_t)(packet_length - 4));
1012
    /* store padding_length */
1013
    p->outbuf[4] = (unsigned char)padding_length;
1014

1015
    /* fill the padding area with random junk */
1016
    if(_libssh2_random(p->outbuf + 5 + data_len, padding_length)) {
1017
        return _libssh2_error(session, LIBSSH2_ERROR_RANDGEN,
1018
                              "Unable to get random bytes for packet padding");
1019
    }
1020

1021
    if(encrypted) {
1022
        size_t i;
1023

1024
        /* Calculate MAC hash. Put the output at index packet_length,
1025
           since that size includes the whole packet. The MAC is
1026
           calculated on the entire unencrypted packet, including all
1027
           fields except the MAC field itself. This is skipped in the
1028
           INTEGRATED_MAC case, where the crypto algorithm also does its
1029
           own hash. */
1030
        if(!etm && !CRYPT_FLAG_R(session, INTEGRATED_MAC)) {
1031
            if(session->local.mac->hash(session, p->outbuf + packet_length,
1032
                                        session->local.seqno, p->outbuf,
1033
                                        packet_length, NULL, 0,
1034
                                        &session->local.mac_abstract))
1035
                return _libssh2_error(session, LIBSSH2_ERROR_MAC_FAILURE,
1036
                                      "Failed to calculate MAC");
1037
        }
1038

1039
        /* Encrypt the whole packet data, one block size at a time.
1040
           The MAC field is not encrypted unless INTEGRATED_MAC. */
1041
        /* Some crypto back-ends could handle a single crypt() call for
1042
           encryption, but (presumably) others cannot, so break it up
1043
           into blocksize-sized chunks to satisfy them all. */
1044
        for(i = etm_crypt_offset; i < packet_length;
1045
            i += session->local.crypt->blocksize) {
1046
            unsigned char *ptr = &p->outbuf[i];
1047
            size_t bsize = LIBSSH2_MIN(session->local.crypt->blocksize,
1048
                                       (int)(packet_length-i));
1049
            /* The INTEGRATED_MAC case always has an extra call below, so it
1050
               will never be LAST_BLOCK up here. */
1051
            int firstlast = i == 0 ? FIRST_BLOCK :
1052
                (!CRYPT_FLAG_L(session, INTEGRATED_MAC)
1053
                 && (i == packet_length - session->local.crypt->blocksize)
1054
                   ? LAST_BLOCK: MIDDLE_BLOCK);
1055
            /* In the AAD case, the last block would be only 4 bytes because
1056
               everything is offset by 4 since the initial packet_length isn't
1057
               encrypted. In this case, combine that last short packet with the
1058
               previous one since AES-GCM crypt() assumes that the entire MAC
1059
               is available in that packet so it can set that to the
1060
               authentication tag. */
1061
            if(!CRYPT_FLAG_L(session, INTEGRATED_MAC))
1062
                if(i > packet_length - 2*bsize) {
1063
                    /* increase the final block size */
1064
                    bsize = packet_length - i;
1065
                    /* advance the loop counter by the extra amount */
1066
                    i += bsize - session->local.crypt->blocksize;
1067
                }
1068
            _libssh2_debug((session, LIBSSH2_TRACE_SOCKET,
1069
                           "crypting bytes %lu-%lu", (unsigned long)i,
1070
                           (unsigned long)(i + bsize - 1)));
1071
            if(session->local.crypt->crypt(session, ptr,
1072
                                           bsize,
1073
                                           &session->local.crypt_abstract,
1074
                                           firstlast))
1075
                return LIBSSH2_ERROR_ENCRYPT;     /* encryption failure */
1076
        }
1077
        /* Call crypt() one last time so it can be filled in with the MAC */
1078
        if(CRYPT_FLAG_L(session, INTEGRATED_MAC)) {
1079
            int authlen = session->local.mac->mac_len;
1080
            assert((size_t)total_length <=
1081
                   packet_length + session->local.crypt->blocksize);
1082
            if(session->local.crypt->crypt(session, &p->outbuf[packet_length],
1083
                                           authlen,
1084
                                           &session->local.crypt_abstract,
1085
                                           LAST_BLOCK))
1086
                return LIBSSH2_ERROR_ENCRYPT;     /* encryption failure */
1087
        }
1088

1089
        if(etm) {
1090
            /* Calculate MAC hash. Put the output at index packet_length,
1091
               since that size includes the whole packet. The MAC is
1092
               calculated on the entire packet (length plain the rest
1093
               encrypted), including all fields except the MAC field
1094
               itself. */
1095
            if(session->local.mac->hash(session, p->outbuf + packet_length,
1096
                                        session->local.seqno, p->outbuf,
1097
                                        packet_length, NULL, 0,
1098
                                        &session->local.mac_abstract))
1099
                return _libssh2_error(session, LIBSSH2_ERROR_MAC_FAILURE,
1100
                                      "Failed to calculate MAC");
1101
        }
1102
    }
1103

1104
    session->local.seqno++;
1105

1106
    if(session->kex_strict && data[0] == SSH_MSG_NEWKEYS) {
1107
        session->local.seqno = 0;
1108
    }
1109

1110
    ret = LIBSSH2_SEND(session, p->outbuf, total_length,
1111
                       LIBSSH2_SOCKET_SEND_FLAGS(session));
1112
    if(ret < 0)
1113
        _libssh2_debug((session, LIBSSH2_TRACE_SOCKET,
1114
                       "Error sending %ld bytes: %ld",
1115
                       (long)total_length, (long)-ret));
1116
    else {
1117
        _libssh2_debug((session, LIBSSH2_TRACE_SOCKET,
1118
                       "Sent %ld/%ld bytes at %p",
1119
                       (long)ret, (long)total_length, (void *)p->outbuf));
1120
        debugdump(session, "libssh2_transport_write send()", p->outbuf, ret);
1121
    }
1122

1123
    if(ret != total_length) {
1124
        if(ret >= 0 || ret == -EAGAIN) {
1125
            /* the whole packet could not be sent, save the rest */
1126
            session->socket_block_directions |= LIBSSH2_SESSION_BLOCK_OUTBOUND;
1127
            p->odata = orgdata;
1128
            p->olen = orgdata_len;
1129
            p->osent = ret <= 0 ? 0 : ret;
1130
            p->ototal_num = total_length;
1131
            return LIBSSH2_ERROR_EAGAIN;
1132
        }
1133
        return LIBSSH2_ERROR_SOCKET_SEND;
1134
    }
1135

1136
    /* the whole thing got sent away */
1137
    p->odata = NULL;
1138
    p->olen = 0;
1139

1140
    return LIBSSH2_ERROR_NONE;         /* all is good */
1141
}
1142

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.