Diff

Differences From Artifact [23d48db6e4]:

To Artifact [4edef356f3]:


258
259
260
261
262
263
264







265
266
267
268
269
270
271
static struct rdpkt1_state_tag {
    long len, pad, biglen, to_read;
    unsigned long realcrc, gotcrc;
    unsigned char *p;
    int i;
    int chunk;
} rdpkt1_state;








static int ssh_channelcmp(void *av, void *bv) {
    struct ssh_channel *a = (struct ssh_channel *)av;
    struct ssh_channel *b = (struct ssh_channel *)bv;
    if (a->localid < b->localid) return -1;
    if (a->localid > b->localid) return +1;
    return 0;







>
>
>
>
>
>
>







258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
static struct rdpkt1_state_tag {
    long len, pad, biglen, to_read;
    unsigned long realcrc, gotcrc;
    unsigned char *p;
    int i;
    int chunk;
} rdpkt1_state;

static struct rdpkt2_state_tag {
    long len, pad, payload, packetlen, maclen;
    int i;
    int cipherblk;
    unsigned long incoming_sequence;
} rdpkt2_state;

static int ssh_channelcmp(void *av, void *bv) {
    struct ssh_channel *a = (struct ssh_channel *)av;
    struct ssh_channel *b = (struct ssh_channel *)bv;
    if (a->localid < b->localid) return -1;
    if (a->localid > b->localid) return +1;
    return 0;
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514

515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
    }

    crFinish(0);
}

static int ssh2_rdpkt(unsigned char **data, int *datalen)
{
    static long len, pad, payload, packetlen, maclen;
    static int i;
    static int cipherblk;
    static unsigned long incoming_sequence = 0;

    crBegin;

next_packet:

    pktin.type = 0;
    pktin.length = 0;

    if (cipher)
        cipherblk = cipher->blksize;
    else
        cipherblk = 8;
    if (cipherblk < 8)
        cipherblk = 8;

    if (pktin.maxlen < cipherblk) {
	pktin.maxlen = cipherblk;
	pktin.data = (pktin.data == NULL ? malloc(cipherblk+APIEXTRA) :
	              realloc(pktin.data, cipherblk+APIEXTRA));
	if (!pktin.data)
	    fatalbox("Out of memory");
    }

    /*
     * Acquire and decrypt the first block of the packet. This will
     * contain the length and padding details.
     */
     for (i = len = 0; i < cipherblk; i++) {
	while ((*datalen) == 0)
	    crReturn(cipherblk-i);
	pktin.data[i] = *(*data)++;
        (*datalen)--;
    }
#ifdef FWHACK
    if (!memcmp(pktin.data, "Remo", 4)) {/* "Remo"te server has closed ... */
        /* FIXME */
    }
#endif
    if (sccipher)
        sccipher->decrypt(pktin.data, cipherblk);

    /*
     * Now get the length and padding figures.
     */
    len = GET_32BIT(pktin.data);
    pad = pktin.data[4];

    /*
     * This enables us to deduce the payload length.
     */
    payload = len - pad - 1;

    pktin.length = payload + 5;

    /*
     * So now we can work out the total packet length.
     */
    packetlen = len + 4;
    maclen = scmac ? scmac->len : 0;

    /*
     * Adjust memory allocation if packet is too big.
     */
    if (pktin.maxlen < packetlen+maclen) {
	pktin.maxlen = packetlen+maclen;
	pktin.data = (pktin.data == NULL ? malloc(pktin.maxlen+APIEXTRA) :
	              realloc(pktin.data, pktin.maxlen+APIEXTRA));
	if (!pktin.data)
	    fatalbox("Out of memory");
    }

    /*
     * Read and decrypt the remainder of the packet.
     */
    for (i = cipherblk; i < packetlen + maclen; i++) {
	while ((*datalen) == 0)
	    crReturn(packetlen + maclen - i);
	pktin.data[i] = *(*data)++;
        (*datalen)--;
    }
    /* Decrypt everything _except_ the MAC. */
    if (sccipher)
        sccipher->decrypt(pktin.data + cipherblk, packetlen - cipherblk);


#if 0
    debug(("Got packet len=%d pad=%d\r\n", len, pad));
    for (i = 0; i < packetlen; i++)
        debug(("  %02x", (unsigned char)pktin.data[i]));
    debug(("\r\n"));
#endif

    /*
     * Check the MAC.
     */
    if (scmac && !scmac->verify(pktin.data, len+4, incoming_sequence)) {
	bombout(("Incorrect MAC received on packet"));
        crReturn(0);
    }
    incoming_sequence++;               /* whether or not we MACed */

    pktin.savedpos = 6;
    pktin.type = pktin.data[5];

    if (pktin.type == SSH2_MSG_IGNORE || pktin.type == SSH2_MSG_DEBUG)
        goto next_packet;              /* FIXME: print DEBUG message */








<
|
<
<




<


|
<
|

|
|
|

|
|
|
|








|

|
|








|




|
|




|

|




|
|




|
|









|

|
|




|
>


|
|
|






|



|







428
429
430
431
432
433
434

435


436
437
438
439

440
441
442

443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
    }

    crFinish(0);
}

static int ssh2_rdpkt(unsigned char **data, int *datalen)
{

    struct rdpkt2_state_tag *st = &rdpkt2_state;



    crBegin;

next_packet:

    pktin.type = 0;
    pktin.length = 0;
    if (sccipher)

        st->cipherblk = sccipher->blksize;
    else
        st->cipherblk = 8;
    if (st->cipherblk < 8)
        st->cipherblk = 8;

    if (pktin.maxlen < st->cipherblk) {
	pktin.maxlen = st->cipherblk;
	pktin.data = (pktin.data == NULL ? malloc(st->cipherblk+APIEXTRA) :
	              realloc(pktin.data, st->cipherblk+APIEXTRA));
	if (!pktin.data)
	    fatalbox("Out of memory");
    }

    /*
     * Acquire and decrypt the first block of the packet. This will
     * contain the length and padding details.
     */
     for (st->i = st->len = 0; st->i < st->cipherblk; st->i++) {
	while ((*datalen) == 0)
	    crReturn(st->cipherblk-st->i);
	pktin.data[st->i] = *(*data)++;
        (*datalen)--;
    }
#ifdef FWHACK
    if (!memcmp(pktin.data, "Remo", 4)) {/* "Remo"te server has closed ... */
        /* FIXME */
    }
#endif
    if (sccipher)
        sccipher->decrypt(pktin.data, st->cipherblk);

    /*
     * Now get the length and padding figures.
     */
    st->len = GET_32BIT(pktin.data);
    st->pad = pktin.data[4];

    /*
     * This enables us to deduce the payload length.
     */
    st->payload = st->len - st->pad - 1;

    pktin.length = st->payload + 5;

    /*
     * So now we can work out the total packet length.
     */
    st->packetlen = st->len + 4;
    st->maclen = scmac ? scmac->len : 0;

    /*
     * Adjust memory allocation if packet is too big.
     */
    if (pktin.maxlen < st->packetlen+st->maclen) {
	pktin.maxlen = st->packetlen+st->maclen;
	pktin.data = (pktin.data == NULL ? malloc(pktin.maxlen+APIEXTRA) :
	              realloc(pktin.data, pktin.maxlen+APIEXTRA));
	if (!pktin.data)
	    fatalbox("Out of memory");
    }

    /*
     * Read and decrypt the remainder of the packet.
     */
    for (st->i = st->cipherblk; st->i < st->packetlen + st->maclen; st->i++) {
	while ((*datalen) == 0)
	    crReturn(st->packetlen + st->maclen - st->i);
	pktin.data[st->i] = *(*data)++;
        (*datalen)--;
    }
    /* Decrypt everything _except_ the MAC. */
    if (sccipher)
        sccipher->decrypt(pktin.data + st->cipherblk,
                          st->packetlen - st->cipherblk);

#if 0
    debug(("Got packet len=%d pad=%d\r\n", st->len, st->pad));
    for (st->i = 0; st->i < st->packetlen; st->i++)
        debug(("  %02x", (unsigned char)pktin.data[st->i]));
    debug(("\r\n"));
#endif

    /*
     * Check the MAC.
     */
    if (scmac && !scmac->verify(pktin.data, st->len+4, st->incoming_sequence)) {
	bombout(("Incorrect MAC received on packet"));
        crReturn(0);
    }
    st->incoming_sequence++;               /* whether or not we MACed */

    pktin.savedpos = 6;
    pktin.type = pktin.data[5];

    if (pktin.type == SSH2_MSG_IGNORE || pktin.type == SSH2_MSG_DEBUG)
        goto next_packet;              /* FIXME: print DEBUG message */

1023
1024
1025
1026
1027
1028
1029


1030
1031
1032
1033
1034
1035
1036
		i = -1;
	    } else if (i < sizeof(version)-1)
		version[i++] = c;
	}
	else if (c == '\n')
	    break;
    }



    *vsp = 0;
    sprintf(vlog, "Server version: %s", vstring);
    vlog[strcspn(vlog, "\r\n")] = '\0';
    logevent(vlog);

    /*







>
>







1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
		i = -1;
	    } else if (i < sizeof(version)-1)
		version[i++] = c;
	}
	else if (c == '\n')
	    break;
    }

    rdpkt2_state.incoming_sequence = 0;

    *vsp = 0;
    sprintf(vlog, "Server version: %s", vstring);
    vlog[strcspn(vlog, "\r\n")] = '\0';
    logevent(vlog);

    /*