~ubuntu-branches/ubuntu/utopic/pgadmin3/utopic-proposed

« back to all changes in this revision

Viewing changes to pgadmin/libssh2/transport.c

  • Committer: Package Import Robot
  • Author(s): Christoph Berg
  • Date: 2013-09-10 16:16:38 UTC
  • mfrom: (1.3.4)
  • Revision ID: package-import@ubuntu.com-20130910161638-wwup1q553ylww7dr
Tags: 1.18.0-1
* New upstream release.
* Don't install /usr/bin/png2c anymore.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2007 The Written Word, Inc.  All rights reserved.
 
2
 * Copyright (C) 2009-2010 by Daniel Stenberg
 
3
 * Author: Daniel Stenberg <daniel@haxx.se>
 
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
 * This file handles reading and writing to the SECSH transport layer. RFC4253.
 
39
 */
 
40
 
 
41
#include "libssh2_priv.h"
 
42
#include <errno.h>
 
43
#include <fcntl.h>
 
44
#include <ctype.h>
 
45
#ifdef LIBSSH2DEBUG
 
46
#include <stdio.h>
 
47
#endif
 
48
 
 
49
#include <assert.h>
 
50
 
 
51
#include "transport.h"
 
52
#include "mac.h"
 
53
 
 
54
#define MAX_BLOCKSIZE 32    /* MUST fit biggest crypto block size we use/get */
 
55
#define MAX_MACSIZE 20      /* MUST fit biggest MAC length we support */
 
56
 
 
57
#ifdef LIBSSH2DEBUG
 
58
#define UNPRINTABLE_CHAR '.'
 
59
static void
 
60
debugdump(LIBSSH2_SESSION * session,
 
61
          const char *desc, const unsigned char *ptr, size_t size)
 
62
{
 
63
    size_t i;
 
64
    size_t c;
 
65
    unsigned int width = 0x10;
 
66
    char buffer[256];  /* Must be enough for width*4 + about 30 or so */
 
67
    size_t used;
 
68
    static const char* hex_chars = "0123456789ABCDEF";
 
69
 
 
70
    if (!(session->showmask & LIBSSH2_TRACE_TRANS)) {
 
71
        /* not asked for, bail out */
 
72
        return;
 
73
    }
 
74
 
 
75
    used = snprintf(buffer, sizeof(buffer), "=> %s (%d bytes)\n",
 
76
                    desc, (int) size);
 
77
    if (session->tracehandler)
 
78
        (session->tracehandler)(session, session->tracehandler_context,
 
79
                                buffer, used);
 
80
    else
 
81
        fprintf(stderr, "%s", buffer);
 
82
 
 
83
    for(i = 0; i < size; i += width) {
 
84
 
 
85
        used = snprintf(buffer, sizeof(buffer), "%04lx: ", (long)i);
 
86
 
 
87
        /* hex not disabled, show it */
 
88
        for(c = 0; c < width; c++) {
 
89
            if (i + c < size) {
 
90
                buffer[used++] = hex_chars[(ptr[i+c] >> 4) & 0xF];
 
91
                buffer[used++] = hex_chars[ptr[i+c] & 0xF];
 
92
            }
 
93
            else {
 
94
                buffer[used++] = ' ';
 
95
                buffer[used++] = ' ';
 
96
            }
 
97
 
 
98
            buffer[used++] = ' ';
 
99
            if ((width/2) - 1 == c)
 
100
                buffer[used++] = ' ';
 
101
        }
 
102
 
 
103
        buffer[used++] = ':';
 
104
        buffer[used++] = ' ';
 
105
 
 
106
        for(c = 0; (c < width) && (i + c < size); c++) {
 
107
            buffer[used++] = isprint(ptr[i + c]) ?
 
108
                ptr[i + c] : UNPRINTABLE_CHAR;
 
109
        }
 
110
        buffer[used++] = '\n';
 
111
        buffer[used] = 0;
 
112
 
 
113
        if (session->tracehandler)
 
114
            (session->tracehandler)(session, session->tracehandler_context,
 
115
                                    buffer, used);
 
116
        else
 
117
            fprintf(stderr, "%s", buffer);
 
118
    }
 
119
}
 
120
#else
 
121
#define debugdump(a,x,y,z)
 
122
#endif
 
123
 
 
124
 
 
125
/* decrypt() decrypts 'len' bytes from 'source' to 'dest'.
 
126
 *
 
127
 * returns 0 on success and negative on failure
 
128
 */
 
129
 
 
130
static int
 
131
decrypt(LIBSSH2_SESSION * session, unsigned char *source,
 
132
        unsigned char *dest, int len)
 
133
{
 
134
    struct transportpacket *p = &session->packet;
 
135
    int blocksize = session->remote.crypt->blocksize;
 
136
 
 
137
    /* if we get called with a len that isn't an even number of blocksizes
 
138
       we risk losing those extra bytes */
 
139
    assert((len % blocksize) == 0);
 
140
 
 
141
    while (len >= blocksize) {
 
142
        if (session->remote.crypt->crypt(session, source, blocksize,
 
143
                                         &session->remote.crypt_abstract)) {
 
144
            LIBSSH2_FREE(session, p->payload);
 
145
            return LIBSSH2_ERROR_DECRYPT;
 
146
        }
 
147
 
 
148
        /* if the crypt() function would write to a given address it
 
149
           wouldn't have to memcpy() and we could avoid this memcpy()
 
150
           too */
 
151
        memcpy(dest, source, blocksize);
 
152
 
 
153
        len -= blocksize;       /* less bytes left */
 
154
        dest += blocksize;      /* advance write pointer */
 
155
        source += blocksize;    /* advance read pointer */
 
156
    }
 
157
    return LIBSSH2_ERROR_NONE;         /* all is fine */
 
158
}
 
159
 
 
160
/*
 
161
 * fullpacket() gets called when a full packet has been received and properly
 
162
 * collected.
 
163
 */
 
164
static int
 
165
fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
 
166
{
 
167
    unsigned char macbuf[MAX_MACSIZE];
 
168
    struct transportpacket *p = &session->packet;
 
169
    int rc;
 
170
    int compressed;
 
171
 
 
172
    if (session->fullpacket_state == libssh2_NB_state_idle) {
 
173
        session->fullpacket_macstate = LIBSSH2_MAC_CONFIRMED;
 
174
        session->fullpacket_payload_len = p->packet_length - 1;
 
175
 
 
176
        if (encrypted) {
 
177
 
 
178
            /* Calculate MAC hash */
 
179
            session->remote.mac->hash(session, macbuf,  /* store hash here */
 
180
                                      session->remote.seqno,
 
181
                                      p->init, 5,
 
182
                                      p->payload,
 
183
                                      session->fullpacket_payload_len,
 
184
                                      &session->remote.mac_abstract);
 
185
 
 
186
            /* Compare the calculated hash with the MAC we just read from
 
187
             * the network. The read one is at the very end of the payload
 
188
             * buffer. Note that 'payload_len' here is the packet_length
 
189
             * field which includes the padding but not the MAC.
 
190
             */
 
191
            if (memcmp(macbuf, p->payload + session->fullpacket_payload_len,
 
192
                       session->remote.mac->mac_len)) {
 
193
                session->fullpacket_macstate = LIBSSH2_MAC_INVALID;
 
194
            }
 
195
        }
 
196
 
 
197
        session->remote.seqno++;
 
198
 
 
199
        /* ignore the padding */
 
200
        session->fullpacket_payload_len -= p->padding_length;
 
201
 
 
202
        /* Check for and deal with decompression */
 
203
        compressed =
 
204
            session->local.comp != NULL &&
 
205
            session->local.comp->compress &&
 
206
            ((session->state & LIBSSH2_STATE_AUTHENTICATED) ||
 
207
             session->local.comp->use_in_auth);
 
208
 
 
209
        if (compressed && session->remote.comp_abstract) {
 
210
            /*
 
211
             * The buffer for the decompression (remote.comp_abstract) is
 
212
             * initialised in time when it is needed so as long it is NULL we
 
213
             * cannot decompress.
 
214
             */
 
215
 
 
216
            unsigned char *data;
 
217
            size_t data_len;
 
218
            rc = session->remote.comp->decomp(session,
 
219
                                              &data, &data_len,
 
220
                                              LIBSSH2_PACKET_MAXDECOMP,
 
221
                                              p->payload,
 
222
                                              session->fullpacket_payload_len,
 
223
                                              &session->remote.comp_abstract);
 
224
            LIBSSH2_FREE(session, p->payload);
 
225
            if(rc)
 
226
                return rc;
 
227
 
 
228
            p->payload = data;
 
229
            session->fullpacket_payload_len = data_len;
 
230
        }
 
231
 
 
232
        session->fullpacket_packet_type = p->payload[0];
 
233
 
 
234
        debugdump(session, "libssh2_transport_read() plain",
 
235
                  p->payload, session->fullpacket_payload_len);
 
236
 
 
237
        session->fullpacket_state = libssh2_NB_state_created;
 
238
    }
 
239
 
 
240
    if (session->fullpacket_state == libssh2_NB_state_created) {
 
241
        rc = _libssh2_packet_add(session, p->payload,
 
242
                                 session->fullpacket_payload_len,
 
243
                                 session->fullpacket_macstate);
 
244
        if (rc)
 
245
            return rc;
 
246
    }
 
247
 
 
248
    session->fullpacket_state = libssh2_NB_state_idle;
 
249
 
 
250
    return session->fullpacket_packet_type;
 
251
}
 
252
 
 
253
 
 
254
/*
 
255
 * _libssh2_transport_read
 
256
 *
 
257
 * Collect a packet into the input queue.
 
258
 *
 
259
 * Returns packet type added to input queue (0 if nothing added), or a
 
260
 * negative error number.
 
261
 */
 
262
 
 
263
/*
 
264
 * This function reads the binary stream as specified in chapter 6 of RFC4253
 
265
 * "The Secure Shell (SSH) Transport Layer Protocol"
 
266
 *
 
267
 * DOES NOT call _libssh2_error() for ANY error case.
 
268
 */
 
269
int _libssh2_transport_read(LIBSSH2_SESSION * session)
 
270
{
 
271
    int rc;
 
272
    struct transportpacket *p = &session->packet;
 
273
    int remainbuf;
 
274
    int remainpack;
 
275
    int numbytes;
 
276
    int numdecrypt;
 
277
    unsigned char block[MAX_BLOCKSIZE];
 
278
    int blocksize;
 
279
    int encrypted = 1;
 
280
    size_t total_num;
 
281
 
 
282
    /* default clear the bit */
 
283
    session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_INBOUND;
 
284
 
 
285
    /*
 
286
     * All channels, systems, subsystems, etc eventually make it down here
 
287
     * when looking for more incoming data. If a key exchange is going on
 
288
     * (LIBSSH2_STATE_EXCHANGING_KEYS bit is set) then the remote end will
 
289
     * ONLY send key exchange related traffic. In non-blocking mode, there is
 
290
     * a chance to break out of the kex_exchange function with an EAGAIN
 
291
     * status, and never come back to it. If LIBSSH2_STATE_EXCHANGING_KEYS is
 
292
     * active, then we must redirect to the key exchange. However, if
 
293
     * kex_exchange is active (as in it is the one that calls this execution
 
294
     * of packet_read, then don't redirect, as that would be an infinite loop!
 
295
     */
 
296
 
 
297
    if (session->state & LIBSSH2_STATE_EXCHANGING_KEYS &&
 
298
        !(session->state & LIBSSH2_STATE_KEX_ACTIVE)) {
 
299
 
 
300
        /* Whoever wants a packet won't get anything until the key re-exchange
 
301
         * is done!
 
302
         */
 
303
        _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Redirecting into the"
 
304
                       " key re-exchange from _libssh2_transport_read");
 
305
        rc = _libssh2_kex_exchange(session, 1, &session->startup_key_state);
 
306
        if (rc)
 
307
            return rc;
 
308
    }
 
309
 
 
310
    /*
 
311
     * =============================== NOTE ===============================
 
312
     * I know this is very ugly and not a really good use of "goto", but
 
313
     * this case statement would be even uglier to do it any other way
 
314
     */
 
315
    if (session->readPack_state == libssh2_NB_state_jump1) {
 
316
        session->readPack_state = libssh2_NB_state_idle;
 
317
        encrypted = session->readPack_encrypted;
 
318
        goto libssh2_transport_read_point1;
 
319
    }
 
320
 
 
321
    do {
 
322
        if (session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) {
 
323
            return LIBSSH2_ERROR_NONE;
 
324
        }
 
325
 
 
326
        if (session->state & LIBSSH2_STATE_NEWKEYS) {
 
327
            blocksize = session->remote.crypt->blocksize;
 
328
        } else {
 
329
            encrypted = 0;      /* not encrypted */
 
330
            blocksize = 5;      /* not strictly true, but we can use 5 here to
 
331
                                   make the checks below work fine still */
 
332
        }
 
333
 
 
334
        /* read/use a whole big chunk into a temporary area stored in
 
335
           the LIBSSH2_SESSION struct. We will decrypt data from that
 
336
           buffer into the packet buffer so this temp one doesn't have
 
337
           to be able to keep a whole SSH packet, just be large enough
 
338
           so that we can read big chunks from the network layer. */
 
339
 
 
340
        /* how much data there is remaining in the buffer to deal with
 
341
           before we should read more from the network */
 
342
        remainbuf = p->writeidx - p->readidx;
 
343
 
 
344
        /* if remainbuf turns negative we have a bad internal error */
 
345
        assert(remainbuf >= 0);
 
346
 
 
347
        if (remainbuf < blocksize) {
 
348
            /* If we have less than a blocksize left, it is too
 
349
               little data to deal with, read more */
 
350
            ssize_t nread;
 
351
 
 
352
            /* move any remainder to the start of the buffer so
 
353
               that we can do a full refill */
 
354
            if (remainbuf) {
 
355
                memmove(p->buf, &p->buf[p->readidx], remainbuf);
 
356
                p->readidx = 0;
 
357
                p->writeidx = remainbuf;
 
358
            } else {
 
359
                /* nothing to move, just zero the indexes */
 
360
                p->readidx = p->writeidx = 0;
 
361
            }
 
362
 
 
363
            /* now read a big chunk from the network into the temp buffer */
 
364
            nread =
 
365
                LIBSSH2_RECV(session, &p->buf[remainbuf],
 
366
                              PACKETBUFSIZE - remainbuf,
 
367
                              LIBSSH2_SOCKET_RECV_FLAGS(session));
 
368
            if (nread <= 0) {
 
369
                /* check if this is due to EAGAIN and return the special
 
370
                   return code if so, error out normally otherwise */
 
371
                if ((nread < 0) && (nread == -EAGAIN)) {
 
372
                    session->socket_block_directions |=
 
373
                        LIBSSH2_SESSION_BLOCK_INBOUND;
 
374
                    return LIBSSH2_ERROR_EAGAIN;
 
375
                }
 
376
                _libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
 
377
                               "Error recving %d bytes (got %d)",
 
378
                               PACKETBUFSIZE - remainbuf, -nread);
 
379
                return LIBSSH2_ERROR_SOCKET_RECV;
 
380
            }
 
381
            _libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
 
382
                           "Recved %d/%d bytes to %p+%d", nread,
 
383
                           PACKETBUFSIZE - remainbuf, p->buf, remainbuf);
 
384
 
 
385
            debugdump(session, "libssh2_transport_read() raw",
 
386
                      &p->buf[remainbuf], nread);
 
387
            /* advance write pointer */
 
388
            p->writeidx += nread;
 
389
 
 
390
            /* update remainbuf counter */
 
391
            remainbuf = p->writeidx - p->readidx;
 
392
        }
 
393
 
 
394
        /* how much data to deal with from the buffer */
 
395
        numbytes = remainbuf;
 
396
 
 
397
        if (!p->total_num) {
 
398
            /* No payload package area allocated yet. To know the
 
399
               size of this payload, we need to decrypt the first
 
400
               blocksize data. */
 
401
 
 
402
            if (numbytes < blocksize) {
 
403
                /* we can't act on anything less than blocksize, but this
 
404
                   check is only done for the initial block since once we have
 
405
                   got the start of a block we can in fact deal with fractions
 
406
                */
 
407
                session->socket_block_directions |=
 
408
                    LIBSSH2_SESSION_BLOCK_INBOUND;
 
409
                return LIBSSH2_ERROR_EAGAIN;
 
410
            }
 
411
 
 
412
            if (encrypted) {
 
413
                rc = decrypt(session, &p->buf[p->readidx], block, blocksize);
 
414
                if (rc != LIBSSH2_ERROR_NONE) {
 
415
                    return rc;
 
416
                }
 
417
                /* save the first 5 bytes of the decrypted package, to be
 
418
                   used in the hash calculation later down. */
 
419
                memcpy(p->init, &p->buf[p->readidx], 5);
 
420
            } else {
 
421
                /* the data is plain, just copy it verbatim to
 
422
                   the working block buffer */
 
423
                memcpy(block, &p->buf[p->readidx], blocksize);
 
424
            }
 
425
 
 
426
            /* advance the read pointer */
 
427
            p->readidx += blocksize;
 
428
 
 
429
            /* we now have the initial blocksize bytes decrypted,
 
430
             * and we can extract packet and padding length from it
 
431
             */
 
432
            p->packet_length = _libssh2_ntohu32(block);
 
433
            if (p->packet_length < 1)
 
434
                return LIBSSH2_ERROR_DECRYPT;
 
435
 
 
436
            p->padding_length = block[4];
 
437
 
 
438
            /* total_num is the number of bytes following the initial
 
439
               (5 bytes) packet length and padding length fields */
 
440
            total_num =
 
441
                p->packet_length - 1 +
 
442
                (encrypted ? session->remote.mac->mac_len : 0);
 
443
 
 
444
            /* RFC4253 section 6.1 Maximum Packet Length says:
 
445
             *
 
446
             * "All implementations MUST be able to process
 
447
             * packets with uncompressed payload length of 32768
 
448
             * bytes or less and total packet size of 35000 bytes
 
449
             * or less (including length, padding length, payload,
 
450
             * padding, and MAC.)."
 
451
             */
 
452
            if (total_num > LIBSSH2_PACKET_MAXPAYLOAD) {
 
453
                return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
 
454
            }
 
455
 
 
456
            /* Get a packet handle put data into. We get one to
 
457
               hold all data, including padding and MAC. */
 
458
            p->payload = LIBSSH2_ALLOC(session, total_num);
 
459
            if (!p->payload) {
 
460
                return LIBSSH2_ERROR_ALLOC;
 
461
            }
 
462
            p->total_num = total_num;
 
463
            /* init write pointer to start of payload buffer */
 
464
            p->wptr = p->payload;
 
465
 
 
466
            if (blocksize > 5) {
 
467
                /* copy the data from index 5 to the end of
 
468
                   the blocksize from the temporary buffer to
 
469
                   the start of the decrypted buffer */
 
470
                memcpy(p->wptr, &block[5], blocksize - 5);
 
471
                p->wptr += blocksize - 5;       /* advance write pointer */
 
472
            }
 
473
 
 
474
            /* init the data_num field to the number of bytes of
 
475
               the package read so far */
 
476
            p->data_num = p->wptr - p->payload;
 
477
 
 
478
            /* we already dealt with a blocksize worth of data */
 
479
            numbytes -= blocksize;
 
480
        }
 
481
 
 
482
        /* how much there is left to add to the current payload
 
483
           package */
 
484
        remainpack = p->total_num - p->data_num;
 
485
 
 
486
        if (numbytes > remainpack) {
 
487
            /* if we have more data in the buffer than what is going into this
 
488
               particular packet, we limit this round to this packet only */
 
489
            numbytes = remainpack;
 
490
        }
 
491
 
 
492
        if (encrypted) {
 
493
            /* At the end of the incoming stream, there is a MAC,
 
494
               and we don't want to decrypt that since we need it
 
495
               "raw". We MUST however decrypt the padding data
 
496
               since it is used for the hash later on. */
 
497
            int skip = session->remote.mac->mac_len;
 
498
 
 
499
            /* if what we have plus numbytes is bigger than the
 
500
               total minus the skip margin, we should lower the
 
501
               amount to decrypt even more */
 
502
            if ((p->data_num + numbytes) > (p->total_num - skip)) {
 
503
                numdecrypt = (p->total_num - skip) - p->data_num;
 
504
            } else {
 
505
                int frac;
 
506
                numdecrypt = numbytes;
 
507
                frac = numdecrypt % blocksize;
 
508
                if (frac) {
 
509
                    /* not an aligned amount of blocks,
 
510
                       align it */
 
511
                    numdecrypt -= frac;
 
512
                    /* and make it no unencrypted data
 
513
                       after it */
 
514
                    numbytes = 0;
 
515
                }
 
516
            }
 
517
        } else {
 
518
            /* unencrypted data should not be decrypted at all */
 
519
            numdecrypt = 0;
 
520
        }
 
521
 
 
522
        /* if there are bytes to decrypt, do that */
 
523
        if (numdecrypt > 0) {
 
524
            /* now decrypt the lot */
 
525
            rc = decrypt(session, &p->buf[p->readidx], p->wptr, numdecrypt);
 
526
            if (rc != LIBSSH2_ERROR_NONE) {
 
527
                return rc;
 
528
            }
 
529
 
 
530
            /* advance the read pointer */
 
531
            p->readidx += numdecrypt;
 
532
            /* advance write pointer */
 
533
            p->wptr += numdecrypt;
 
534
            /* increse data_num */
 
535
            p->data_num += numdecrypt;
 
536
 
 
537
            /* bytes left to take care of without decryption */
 
538
            numbytes -= numdecrypt;
 
539
        }
 
540
 
 
541
        /* if there are bytes to copy that aren't decrypted, simply
 
542
           copy them as-is to the target buffer */
 
543
        if (numbytes > 0) {
 
544
            memcpy(p->wptr, &p->buf[p->readidx], numbytes);
 
545
 
 
546
            /* advance the read pointer */
 
547
            p->readidx += numbytes;
 
548
            /* advance write pointer */
 
549
            p->wptr += numbytes;
 
550
            /* increse data_num */
 
551
            p->data_num += numbytes;
 
552
        }
 
553
 
 
554
        /* now check how much data there's left to read to finish the
 
555
           current packet */
 
556
        remainpack = p->total_num - p->data_num;
 
557
 
 
558
        if (!remainpack) {
 
559
            /* we have a full packet */
 
560
          libssh2_transport_read_point1:
 
561
            rc = fullpacket(session, encrypted);
 
562
            if (rc == LIBSSH2_ERROR_EAGAIN) {
 
563
 
 
564
                if (session->packAdd_state != libssh2_NB_state_idle)
 
565
                {
 
566
                    /* fullpacket only returns LIBSSH2_ERROR_EAGAIN if
 
567
                     * libssh2_packet_add returns LIBSSH2_ERROR_EAGAIN. If that
 
568
                     * returns LIBSSH2_ERROR_EAGAIN but the packAdd_state is idle,
 
569
                     * then the packet has been added to the brigade, but some
 
570
                     * immediate action that was taken based on the packet
 
571
                     * type (such as key re-exchange) is not yet complete.
 
572
                     * Clear the way for a new packet to be read in.
 
573
                     */
 
574
                    session->readPack_encrypted = encrypted;
 
575
                    session->readPack_state = libssh2_NB_state_jump1;
 
576
                }
 
577
 
 
578
                return rc;
 
579
            }
 
580
 
 
581
            p->total_num = 0;   /* no packet buffer available */
 
582
 
 
583
            return rc;
 
584
        }
 
585
    } while (1);                /* loop */
 
586
 
 
587
    return LIBSSH2_ERROR_SOCKET_RECV; /* we never reach this point */
 
588
}
 
589
 
 
590
static int
 
591
send_existing(LIBSSH2_SESSION *session, const unsigned char *data,
 
592
              size_t data_len, ssize_t *ret)
 
593
{
 
594
    ssize_t rc;
 
595
    ssize_t length;
 
596
    struct transportpacket *p = &session->packet;
 
597
 
 
598
    if (!p->olen) {
 
599
        *ret = 0;
 
600
        return LIBSSH2_ERROR_NONE;
 
601
    }
 
602
 
 
603
    /* send as much as possible of the existing packet */
 
604
    if ((data != p->odata) || (data_len != p->olen)) {
 
605
        /* When we are about to complete the sending of a packet, it is vital
 
606
           that the caller doesn't try to send a new/different packet since
 
607
           we don't add this one up until the previous one has been sent. To
 
608
           make the caller really notice his/hers flaw, we return error for
 
609
           this case */
 
610
        return LIBSSH2_ERROR_BAD_USE;
 
611
    }
 
612
 
 
613
    *ret = 1;                   /* set to make our parent return */
 
614
 
 
615
    /* number of bytes left to send */
 
616
    length = p->ototal_num - p->osent;
 
617
 
 
618
    rc = LIBSSH2_SEND(session, &p->outbuf[p->osent], length,
 
619
                       LIBSSH2_SOCKET_SEND_FLAGS(session));
 
620
    if (rc < 0)
 
621
        _libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
 
622
                       "Error sending %d bytes: %d", length, -rc);
 
623
    else {
 
624
        _libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
 
625
                       "Sent %d/%d bytes at %p+%d", rc, length, p->outbuf,
 
626
                       p->osent);
 
627
        debugdump(session, "libssh2_transport_write send()",
 
628
                  &p->outbuf[p->osent], rc);
 
629
    }
 
630
 
 
631
    if (rc == length) {
 
632
        /* the remainder of the package was sent */
 
633
        p->ototal_num = 0;
 
634
        p->olen = 0;
 
635
        /* we leave *ret set so that the parent returns as we MUST return back
 
636
           a send success now, so that we don't risk sending EAGAIN later
 
637
           which then would confuse the parent function */
 
638
        return LIBSSH2_ERROR_NONE;
 
639
 
 
640
    }
 
641
    else if (rc < 0) {
 
642
        /* nothing was sent */
 
643
        if (rc != -EAGAIN)
 
644
            /* send failure! */
 
645
            return LIBSSH2_ERROR_SOCKET_SEND;
 
646
 
 
647
        session->socket_block_directions |= LIBSSH2_SESSION_BLOCK_OUTBOUND;
 
648
        return LIBSSH2_ERROR_EAGAIN;
 
649
    }
 
650
 
 
651
    p->osent += rc;         /* we sent away this much data */
 
652
 
 
653
    return rc < length ? LIBSSH2_ERROR_EAGAIN : LIBSSH2_ERROR_NONE;
 
654
}
 
655
 
 
656
/*
 
657
 * libssh2_transport_send
 
658
 *
 
659
 * Send a packet, encrypting it and adding a MAC code if necessary
 
660
 * Returns 0 on success, non-zero on failure.
 
661
 *
 
662
 * The data is provided as _two_ data areas that are combined by this
 
663
 * function.  The 'data' part is sent immediately before 'data2'. 'data2' may
 
664
 * be set to NULL to only use a single part.
 
665
 *
 
666
 * Returns LIBSSH2_ERROR_EAGAIN if it would block or if the whole packet was
 
667
 * not sent yet. If it does so, the caller should call this function again as
 
668
 * soon as it is likely that more data can be sent, and this function MUST
 
669
 * then be called with the same argument set (same data pointer and same
 
670
 * data_len) until ERROR_NONE or failure is returned.
 
671
 *
 
672
 * This function DOES NOT call _libssh2_error() on any errors.
 
673
 */
 
674
int _libssh2_transport_send(LIBSSH2_SESSION *session,
 
675
                            const unsigned char *data, size_t data_len,
 
676
                            const unsigned char *data2, size_t data2_len)
 
677
{
 
678
    int blocksize =
 
679
        (session->state & LIBSSH2_STATE_NEWKEYS) ?
 
680
        session->local.crypt->blocksize : 8;
 
681
    int padding_length;
 
682
    size_t packet_length;
 
683
    int total_length;
 
684
#ifdef RANDOM_PADDING
 
685
    int rand_max;
 
686
    int seed = data[0];         /* FIXME: make this random */
 
687
#endif
 
688
    struct transportpacket *p = &session->packet;
 
689
    int encrypted;
 
690
    int compressed;
 
691
    ssize_t ret;
 
692
    int rc;
 
693
    const unsigned char *orgdata = data;
 
694
    size_t orgdata_len = data_len;
 
695
 
 
696
    /*
 
697
     * If the last read operation was interrupted in the middle of a key
 
698
     * exchange, we must complete that key exchange before continuing to write
 
699
     * further data.
 
700
     *
 
701
     * See the similar block in _libssh2_transport_read for more details.
 
702
     */
 
703
    if (session->state & LIBSSH2_STATE_EXCHANGING_KEYS &&
 
704
        !(session->state & LIBSSH2_STATE_KEX_ACTIVE)) {
 
705
        /* Don't write any new packets if we're still in the middle of a key
 
706
         * exchange. */
 
707
        _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Redirecting into the"
 
708
                       " key re-exchange from _libssh2_transport_send");
 
709
        rc = _libssh2_kex_exchange(session, 1, &session->startup_key_state);
 
710
        if (rc)
 
711
            return rc;
 
712
    }
 
713
 
 
714
    debugdump(session, "libssh2_transport_write plain", data, data_len);
 
715
    if(data2)
 
716
        debugdump(session, "libssh2_transport_write plain2", data2, data2_len);
 
717
 
 
718
    /* FIRST, check if we have a pending write to complete. send_existing
 
719
       only sanity-check data and data_len and not data2 and data2_len!! */
 
720
    rc = send_existing(session, data, data_len, &ret);
 
721
    if (rc)
 
722
        return rc;
 
723
 
 
724
    session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_OUTBOUND;
 
725
 
 
726
    if (ret)
 
727
        /* set by send_existing if data was sent */
 
728
        return rc;
 
729
 
 
730
    encrypted = (session->state & LIBSSH2_STATE_NEWKEYS) ? 1 : 0;
 
731
 
 
732
    compressed =
 
733
        session->local.comp != NULL &&
 
734
        session->local.comp->compress &&
 
735
        ((session->state & LIBSSH2_STATE_AUTHENTICATED) ||
 
736
         session->local.comp->use_in_auth);
 
737
 
 
738
    if (encrypted && compressed) {
 
739
        /* the idea here is that these function must fail if the output gets
 
740
           larger than what fits in the assigned buffer so thus they don't
 
741
           check the input size as we don't know how much it compresses */
 
742
        size_t dest_len = MAX_SSH_PACKET_LEN-5-256;
 
743
        size_t dest2_len = dest_len;
 
744
 
 
745
        /* compress directly to the target buffer */
 
746
        rc = session->local.comp->comp(session,
 
747
                                       &p->outbuf[5], &dest_len,
 
748
                                       data, data_len,
 
749
                                       &session->local.comp_abstract);
 
750
        if(rc)
 
751
            return rc;     /* compression failure */
 
752
 
 
753
        if(data2 && data2_len) {
 
754
            /* compress directly to the target buffer right after where the
 
755
               previous call put data */
 
756
            dest2_len -= dest_len;
 
757
 
 
758
            rc = session->local.comp->comp(session,
 
759
                                           &p->outbuf[5+dest_len], &dest2_len,
 
760
                                           data2, data2_len,
 
761
                                           &session->local.comp_abstract);
 
762
        }
 
763
        else
 
764
            dest2_len = 0;
 
765
        if(rc)
 
766
            return rc;     /* compression failure */
 
767
 
 
768
        data_len = dest_len + dest2_len; /* use the combined length */
 
769
    }
 
770
    else {
 
771
        if((data_len + data2_len) >= (MAX_SSH_PACKET_LEN-0x100))
 
772
            /* too large packet, return error for this until we make this
 
773
               function split it up and send multiple SSH packets */
 
774
            return LIBSSH2_ERROR_INVAL;
 
775
 
 
776
        /* copy the payload data */
 
777
        memcpy(&p->outbuf[5], data, data_len);
 
778
        if(data2 && data2_len)
 
779
            memcpy(&p->outbuf[5+data_len], data2, data2_len);
 
780
        data_len += data2_len; /* use the combined length */
 
781
    }
 
782
 
 
783
 
 
784
    /* RFC4253 says: Note that the length of the concatenation of
 
785
       'packet_length', 'padding_length', 'payload', and 'random padding'
 
786
       MUST be a multiple of the cipher block size or 8, whichever is
 
787
       larger. */
 
788
 
 
789
    /* Plain math: (4 + 1 + packet_length + padding_length) % blocksize == 0 */
 
790
 
 
791
    packet_length = data_len + 1 + 4;   /* 1 is for padding_length field
 
792
                                           4 for the packet_length field */
 
793
 
 
794
    /* at this point we have it all except the padding */
 
795
 
 
796
    /* first figure out our minimum padding amount to make it an even
 
797
       block size */
 
798
    padding_length = blocksize - (packet_length % blocksize);
 
799
 
 
800
    /* if the padding becomes too small we add another blocksize worth
 
801
       of it (taken from the original libssh2 where it didn't have any
 
802
       real explanation) */
 
803
    if (padding_length < 4) {
 
804
        padding_length += blocksize;
 
805
    }
 
806
#ifdef RANDOM_PADDING
 
807
    /* FIXME: we can add padding here, but that also makes the packets
 
808
       bigger etc */
 
809
 
 
810
    /* now we can add 'blocksize' to the padding_length N number of times
 
811
       (to "help thwart traffic analysis") but it must be less than 255 in
 
812
       total */
 
813
    rand_max = (255 - padding_length) / blocksize + 1;
 
814
    padding_length += blocksize * (seed % rand_max);
 
815
#endif
 
816
 
 
817
    packet_length += padding_length;
 
818
 
 
819
    /* append the MAC length to the total_length size */
 
820
    total_length =
 
821
        packet_length + (encrypted ? session->local.mac->mac_len : 0);
 
822
 
 
823
    /* store packet_length, which is the size of the whole packet except
 
824
       the MAC and the packet_length field itself */
 
825
    _libssh2_htonu32(p->outbuf, packet_length - 4);
 
826
    /* store padding_length */
 
827
    p->outbuf[4] = padding_length;
 
828
 
 
829
    /* fill the padding area with random junk */
 
830
    _libssh2_random(p->outbuf + 5 + data_len, padding_length);
 
831
 
 
832
    if (encrypted) {
 
833
        size_t i;
 
834
 
 
835
        /* Calculate MAC hash. Put the output at index packet_length,
 
836
           since that size includes the whole packet. The MAC is
 
837
           calculated on the entire unencrypted packet, including all
 
838
           fields except the MAC field itself. */
 
839
        session->local.mac->hash(session, p->outbuf + packet_length,
 
840
                                 session->local.seqno, p->outbuf,
 
841
                                 packet_length, NULL, 0,
 
842
                                 &session->local.mac_abstract);
 
843
 
 
844
        /* Encrypt the whole packet data, one block size at a time.
 
845
           The MAC field is not encrypted. */
 
846
        for(i = 0; i < packet_length; i += session->local.crypt->blocksize) {
 
847
            unsigned char *ptr = &p->outbuf[i];
 
848
            if (session->local.crypt->crypt(session, ptr,
 
849
                                            session->local.crypt->blocksize,
 
850
                                            &session->local.crypt_abstract))
 
851
                return LIBSSH2_ERROR_ENCRYPT;     /* encryption failure */
 
852
        }
 
853
    }
 
854
 
 
855
    session->local.seqno++;
 
856
 
 
857
    ret = LIBSSH2_SEND(session, p->outbuf, total_length,
 
858
                        LIBSSH2_SOCKET_SEND_FLAGS(session));
 
859
    if (ret < 0)
 
860
        _libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
 
861
                       "Error sending %d bytes: %d", total_length, -ret);
 
862
    else {
 
863
        _libssh2_debug(session, LIBSSH2_TRACE_SOCKET, "Sent %d/%d bytes at %p",
 
864
                       ret, total_length, p->outbuf);
 
865
        debugdump(session, "libssh2_transport_write send()", p->outbuf, ret);
 
866
    }
 
867
 
 
868
    if (ret != total_length) {
 
869
        if (ret >= 0 || ret == -EAGAIN) {
 
870
            /* the whole packet could not be sent, save the rest */
 
871
            session->socket_block_directions |= LIBSSH2_SESSION_BLOCK_OUTBOUND;
 
872
            p->odata = orgdata;
 
873
            p->olen = orgdata_len;
 
874
            p->osent = ret <= 0 ? 0 : ret;
 
875
            p->ototal_num = total_length;
 
876
            return LIBSSH2_ERROR_EAGAIN;
 
877
        }
 
878
        return LIBSSH2_ERROR_SOCKET_SEND;
 
879
    }
 
880
 
 
881
    /* the whole thing got sent away */
 
882
    p->odata = NULL;
 
883
    p->olen = 0;
 
884
 
 
885
    return LIBSSH2_ERROR_NONE;         /* all is good */
 
886
}