~ubuntu-branches/ubuntu/vivid/libssh2/vivid-proposed

« back to all changes in this revision

Viewing changes to src/packet.c

  • Committer: Bazaar Package Importer
  • Author(s): Mikhail Gusarov
  • Date: 2010-02-28 13:11:14 UTC
  • mto: (1.1.6 upstream) (2.1.8 sid)
  • mto: This revision was merged to the branch mainline in revision 9.
  • Revision ID: james.westby@ubuntu.com-20100228131114-g8d2ps9p1u8i80s3
Tags: upstream-1.2.4
ImportĀ upstreamĀ versionĀ 1.2.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
2
2
 * Copyright (c) 2009 by Daniel Stenberg
 
3
 * Copyright (c) 2010 Simon Josefsson
3
4
 * All rights reserved.
4
5
 *
5
6
 * Redistribution and use in source and binary forms,
108
109
        listen_state->sport = _libssh2_ntohu32(s);
109
110
        s += 4;
110
111
 
111
 
        _libssh2_debug(session, LIBSSH2_DBG_CONN,
 
112
        _libssh2_debug(session, LIBSSH2_TRACE_CONN,
112
113
                       "Remote received connection from %s:%ld to %s:%ld",
113
114
                       listen_state->shost, listen_state->sport,
114
115
                       listen_state->host, listen_state->port);
131
132
                        (listen->queue_maxsize <= listen->queue_size)) {
132
133
                        /* Queue is full */
133
134
                        failure_code = 4;       /* SSH_OPEN_RESOURCE_SHORTAGE */
134
 
                        _libssh2_debug(session, LIBSSH2_DBG_CONN,
 
135
                        _libssh2_debug(session, LIBSSH2_TRACE_CONN,
135
136
                                       "Listener queue full, ignoring");
136
137
                        listen_state->state = libssh2_NB_state_sent;
137
138
                        break;
183
184
                        listen_state->initial_window_size;
184
185
                    channel->local.packet_size = listen_state->packet_size;
185
186
 
186
 
                    _libssh2_debug(session, LIBSSH2_DBG_CONN,
 
187
                    _libssh2_debug(session, LIBSSH2_TRACE_CONN,
187
188
                                   "Connection queued: channel %lu/%lu win %lu/%lu packet %lu/%lu",
188
189
                                   channel->local.id, channel->remote.id,
189
190
                                   channel->local.window_size,
294
295
        x11open_state->sport = _libssh2_ntohu32(s);
295
296
        s += 4;
296
297
 
297
 
        _libssh2_debug(session, LIBSSH2_DBG_CONN,
 
298
        _libssh2_debug(session, LIBSSH2_TRACE_CONN,
298
299
                       "X11 Connection Received from %s:%ld on channel %lu",
299
300
                       x11open_state->shost, x11open_state->sport,
300
301
                       x11open_state->sender_channel);
342
343
            channel->local.window_size = x11open_state->initial_window_size;
343
344
            channel->local.packet_size = x11open_state->packet_size;
344
345
 
345
 
            _libssh2_debug(session, LIBSSH2_DBG_CONN,
 
346
            _libssh2_debug(session, LIBSSH2_TRACE_CONN,
346
347
                           "X11 Connection established: channel %lu/%lu win %lu/%lu packet %lu/%lu",
347
348
                           channel->local.id, channel->remote.id,
348
349
                           channel->local.window_size,
420
421
 * _libssh2_packet_add
421
422
 *
422
423
 * Create a new packet and attach it to the brigade. Called from the transport
423
 
 * layer when it as received a packet.
 
424
 * layer when it has received a packet.
424
425
 *
425
426
 * The input pointer 'data' is pointing to allocated data that this function
426
427
 * is asked to deal with so on failure OR success, it must be freed fine.
446
447
        memset(&session->packAdd_x11open_state, 0,
447
448
               sizeof(session->packAdd_x11open_state));
448
449
 
449
 
        _libssh2_debug(session, LIBSSH2_DBG_TRANS,
 
450
        _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
450
451
                       "Packet type %d received, length=%d",
451
452
                       (int) data[0], (int) datalen);
452
453
        if (macstate == LIBSSH2_MAC_INVALID) {
483
484
        goto libssh2_packet_add_jump_point2;
484
485
    } else if (session->packAdd_state == libssh2_NB_state_jump3) {
485
486
        goto libssh2_packet_add_jump_point3;
 
487
    } else if (session->packAdd_state == libssh2_NB_state_jump4) {
 
488
        goto libssh2_packet_add_jump_point4;
 
489
    } else if (session->packAdd_state == libssh2_NB_state_jump5) {
 
490
        goto libssh2_packet_add_jump_point5;
486
491
    }
487
492
 
 
493
/* FIXME: I've noticed that DATA is accessed without proper
 
494
 * out-of-bounds checking (i.e., DATALEN) in many places
 
495
 * below. --simon */
 
496
 
488
497
    if (session->packAdd_state == libssh2_NB_state_allocated) {
489
498
        /* A couple exceptions to the packet adding rule: */
490
499
        switch (data[0]) {
520
529
                    LIBSSH2_DISCONNECT(session, reason, message,
521
530
                                       message_len, language, language_len);
522
531
                }
523
 
                _libssh2_debug(session, LIBSSH2_DBG_TRANS,
 
532
                _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
524
533
                               "Disconnect(%d): %s(%s)", reason,
525
534
                               message, language);
526
535
                LIBSSH2_FREE(session, data);
583
592
                 * _libssh2_debug will actually truncate this for us so
584
593
                 * that it's not an inordinate about of data
585
594
                 */
586
 
                _libssh2_debug(session, LIBSSH2_DBG_TRANS,
 
595
                _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
587
596
                               "Debug Packet: %s", message);
588
597
                LIBSSH2_FREE(session, data);
589
598
                session->packAdd_state = libssh2_NB_state_idle;
591
600
            }
592
601
            break;
593
602
 
 
603
        case SSH_MSG_GLOBAL_REQUEST:
 
604
        {
 
605
            uint32_t strlen = _libssh2_ntohu32(data + 1);
 
606
            unsigned char want_reply = data[5 + strlen];
 
607
 
 
608
            _libssh2_debug(session,
 
609
                           LIBSSH2_TRACE_CONN,
 
610
                           "Received global request type %.*s (wr %X)",
 
611
                           strlen, data + 5, want_reply);
 
612
 
 
613
            if (want_reply) {
 
614
              libssh2_packet_add_jump_point5:
 
615
                session->packAdd_state = libssh2_NB_state_jump5;
 
616
                data[0] = SSH_MSG_REQUEST_FAILURE;
 
617
                rc = _libssh2_transport_write(session, data, 1);
 
618
                if (rc == PACKET_EAGAIN)
 
619
                    return rc;
 
620
                LIBSSH2_FREE(session, data);
 
621
                session->packAdd_state = libssh2_NB_state_idle;
 
622
                return 0;
 
623
            }
 
624
        }
 
625
        break;
 
626
 
594
627
        case SSH_MSG_CHANNEL_EXTENDED_DATA:
595
628
            /* streamid(4) */
596
629
            session->packAdd_data_head += 4;
616
649
                    stream_id = _libssh2_ntohu32(data + 5);
617
650
                }
618
651
 
619
 
                _libssh2_debug(session, LIBSSH2_DBG_CONN,
 
652
                _libssh2_debug(session, LIBSSH2_TRACE_CONN,
620
653
                               "%d bytes packet_add() for %lu/%lu/%lu",
621
654
                               (int) (datalen - session->packAdd_data_head),
622
655
                               session->packAdd_channel->local.id,
630
663
                /* Pretend we didn't receive this */
631
664
                LIBSSH2_FREE(session, data);
632
665
 
633
 
                _libssh2_debug(session, LIBSSH2_DBG_CONN,
 
666
                _libssh2_debug(session, LIBSSH2_TRACE_CONN,
634
667
                               "Ignoring extended data and refunding %d bytes",
635
668
                               (int) (datalen - 13));
636
669
                /* Adjust the window based on the block we just freed */
713
746
            }
714
747
 
715
748
            _libssh2_debug(session,
716
 
                           LIBSSH2_DBG_CONN,
 
749
                           LIBSSH2_TRACE_CONN,
717
750
                           "EOF received for channel %lu/%lu",
718
751
                           session->packAdd_channel->local.id,
719
752
                           session->packAdd_channel->remote.id);
724
757
            return 0;
725
758
 
726
759
        case SSH_MSG_CHANNEL_REQUEST:
727
 
            if (_libssh2_ntohu32(data + 5) == sizeof("exit-status") - 1
 
760
        {
 
761
            uint32_t channel = _libssh2_ntohu32(data + 1);
 
762
            uint32_t strlen = _libssh2_ntohu32(data + 5);
 
763
            unsigned char want_reply = data[9 + strlen];
 
764
 
 
765
            _libssh2_debug(session,
 
766
                           LIBSSH2_TRACE_CONN,
 
767
                           "Channel %d received request type %.*s (wr %X)",
 
768
                           channel, strlen, data + 9, want_reply);
 
769
 
 
770
            if (strlen == sizeof("exit-status") - 1
728
771
                && !memcmp("exit-status", data + 9,
729
772
                           sizeof("exit-status") - 1)) {
730
773
 
731
774
                /* we've got "exit-status" packet. Set the session value */
732
775
                session->packAdd_channel =
733
 
                    _libssh2_channel_locate(session,
734
 
                                            _libssh2_ntohu32(data + 1));
 
776
                    _libssh2_channel_locate(session, channel);
735
777
 
736
778
                if (session->packAdd_channel) {
737
779
                    session->packAdd_channel->exit_status =
738
780
                        _libssh2_ntohu32(data + 9 + sizeof("exit-status"));
739
 
                    _libssh2_debug(session, LIBSSH2_DBG_CONN,
 
781
                    _libssh2_debug(session, LIBSSH2_TRACE_CONN,
740
782
                                   "Exit status %lu received for channel %lu/%lu",
741
783
                                   session->packAdd_channel->exit_status,
742
784
                                   session->packAdd_channel->local.id,
747
789
                session->packAdd_state = libssh2_NB_state_idle;
748
790
                return 0;
749
791
            }
 
792
 
 
793
            if (want_reply) {
 
794
              libssh2_packet_add_jump_point4:
 
795
                session->packAdd_state = libssh2_NB_state_jump4;
 
796
                data[0] = SSH_MSG_CHANNEL_FAILURE;
 
797
                rc = _libssh2_transport_write(session, data, 5);
 
798
                if (rc == PACKET_EAGAIN)
 
799
                    return rc;
 
800
                LIBSSH2_FREE(session, data);
 
801
                session->packAdd_state = libssh2_NB_state_idle;
 
802
                return 0;
 
803
            }
750
804
            break;
 
805
       }
751
806
 
752
807
        case SSH_MSG_CHANNEL_CLOSE:
753
808
            session->packAdd_channel =
759
814
                session->packAdd_state = libssh2_NB_state_idle;
760
815
                return 0;
761
816
            }
762
 
            _libssh2_debug(session, LIBSSH2_DBG_CONN,
 
817
            _libssh2_debug(session, LIBSSH2_TRACE_CONN,
763
818
                           "Close received for channel %lu/%lu",
764
819
                           session->packAdd_channel->local.id,
765
820
                           session->packAdd_channel->remote.id);
816
871
                if (session->packAdd_channel && bytestoadd) {
817
872
                    session->packAdd_channel->local.window_size += bytestoadd;
818
873
                }
819
 
                _libssh2_debug(session, LIBSSH2_DBG_CONN,
 
874
                _libssh2_debug(session, LIBSSH2_TRACE_CONN,
820
875
                               "Window adjust received for channel %lu/%lu, adding %lu bytes, new window_size=%lu",
821
876
                               session->packAdd_channel->local.id,
822
877
                               session->packAdd_channel->remote.id,
864
919
             * Well, it's already in the brigade,
865
920
             * let's just call back into ourselves
866
921
             */
867
 
            _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Renegotiating Keys");
 
922
            _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Renegotiating Keys");
868
923
 
869
924
            session->packAdd_state = libssh2_NB_state_sent2;
870
925
        }
915
970
{
916
971
    LIBSSH2_PACKET *packet = _libssh2_list_first(&session->packets);
917
972
 
918
 
    _libssh2_debug(session, LIBSSH2_DBG_TRANS,
 
973
    _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
919
974
                   "Looking for packet of type: %d", (int) packet_type);
920
975
 
921
976
    while (packet) {
1054
1109
            return i;
1055
1110
        }
1056
1111
 
1057
 
        _libssh2_debug(session, LIBSSH2_DBG_TRANS,
 
1112
        _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
1058
1113
                       "Blocking until packet becomes available to burn");
1059
1114
        *state = libssh2_NB_state_created;
1060
1115
    }