def test_too_slow(self, req1, req2, too_slow):
     """
     Regression test for a bug where if the channel was closed before the
     HTTP responses arrived, the responses finally arriving crashed Gabble.
     """
 
     # User gets bored, and ends the call.
     e = EventPattern('dbus-signal', signal='Closed',
         path=chan.object_path)
 
     if too_slow == TOO_SLOW_CLOSE:
         call_async(self.q, self.chan, 'Close', dbus_interface=cs.CHANNEL)
     elif too_slow == TOO_SLOW_REMOVE_SELF:
         self.chan.Hangup (0, "", "",
             dbus_interface=cs.CHANNEL_TYPE_CALL)
     elif too_slow == TOO_SLOW_DISCONNECT:
         disconnect_conn(q, conn, stream, [e])
 
         try:
             chan.GetMembers()
         except dbus.DBusException, e:
             # This should fail because the object's gone away, not because
             # Gabble's crashed.
             assert cs.DBUS_ERROR_UNKNOWN_METHOD == e.get_dbus_name(), \
                 "maybe Gabble crashed? %s" % e
         else:
             # Gabble will probably also crash in a moment, because the http
             # request callbacks will be called after the channel's meant to
             # have died, which will cause the channel to try to call
             # methods on the (finalized) connection.
             assert False, "the channel should be dead by now"
 
         return
示例#2
0
def worker(q, bus, conn, stream, should_decloak):
    decloak_automatically = conn.Get(cs.CONN_IFACE_GABBLE_DECLOAK,
            'DecloakAutomatically', dbus_interface=cs.PROPERTIES_IFACE)
    assertEquals(should_decloak, decloak_automatically)

    amy_handle = conn.get_contact_handle_sync('*****@*****.**')

    # Amy directs presence to us

    presence = make_presence('[email protected]/panopticon')
    decloak = presence.addElement((ns.TEMPPRES, 'temppres'))
    decloak['reason'] = 'media'
    stream.send(presence)

    events = [
            EventPattern('dbus-signal', signal='PresencesChanged',
                args=[{amy_handle: (cs.PRESENCE_AVAILABLE, 'available', '')}]),
            EventPattern('dbus-signal', signal='DecloakRequested',
                args=[amy_handle, 'media', should_decloak]),
            ]
    forbidden = []

    if should_decloak:
        events.append(EventPattern('stream-presence',
            to='[email protected]/panopticon'))
    else:
        forbidden = [EventPattern('stream-presence')]

    q.forbid_events(forbidden)
    q.expect_many(*events)

    presence = make_presence('[email protected]/panopticon', type='unavailable')
    stream.send(presence)
    q.expect('dbus-signal', signal='PresencesChanged',
                args=[{amy_handle: (cs.PRESENCE_OFFLINE, 'offline', '')}])

    q.unforbid_events(forbidden)
    def receiving_failed(self, content):

        self.receiving = False

        assert self.contents[0].stream.Properties.Get(
            cs.CALL_STREAM_IFACE_MEDIA,
            'SendingState') == cs.CALL_STREAM_FLOW_STATE_STARTED

        content.stream.Media.ReportReceivingFailure(
            cs.CALL_STATE_CHANGE_REASON_MEDIA_ERROR, "", "receiving error")

        o = self.q.expect_many(
            EventPattern('dbus-signal',
                         signal='ReceivingStateChanged',
                         args=[cs.CALL_STREAM_FLOW_STATE_STOPPED],
                         path=content.stream.__dbus_object_path__),
            EventPattern('dbus-signal',
                         signal='RemoteMembersChanged',
                         path=content.stream.__dbus_object_path__,
                         predicate=lambda e: e.args[0] == {
                             self.remote_handle:
                             cs.CALL_SENDING_STATE_PENDING_STOP_SENDING
                         }), EventPattern('sip-invite'))

        reinvite_event = o[2]

        assertContains('a=sendonly', reinvite_event.sip_message.body)
        self.context.check_call_sdp(reinvite_event.sip_message.body)
        body = reinvite_event.sip_message.body.replace(
            'sendonly', self.sending and 'recvonly' or 'inactive')

        self.context.accept(reinvite_event.sip_message, body)

        ack_cseq = "%s ACK" % reinvite_event.cseq.split()[0]
        self.q.expect('sip-ack', cseq=ack_cseq)

        self.start_receiving(content)
示例#4
0
def returns_bees_from_search(q, stream, conn):
    server = 'hivemind.localhost'
    iq = call_create(q, conn, server)

    result = make_result_iq(stream, iq)
    query = result.firstChildElement()
    query.addElement("nick")
    stream.send(result)

    event = q.expect('dbus-return', method='CreateChannel')
    c = make_channel_proxy(conn, event.value[0], 'Channel')
    c_search = dbus.Interface(c, cs.CHANNEL_TYPE_CONTACT_SEARCH)

    call_async(q, c_search, 'Search', {'nickname': 'Buzzy'})
    iq_event, _ = q.expect_many(
        EventPattern('stream-iq', to=server, query_ns=ns.SEARCH),
        EventPattern('dbus-signal', signal='SearchStateChanged'),
    )
    iq = iq_event.stanza

    result = IQ(stream, 'result')
    result['id'] = iq['id']
    result['from'] = iq['to']
    result.addElement((ns.SEARCH, 'bees')).addElement('bzzzzzzz')
    stream.send(result)

    ssc = q.expect('dbus-signal', signal='SearchStateChanged')
    new_state, reason, details = ssc.args

    assert new_state == cs.SEARCH_FAILED, new_state
    assert reason == cs.NOT_AVAILABLE, reason

    # We call stop after the search has failed; it should succeed and do nothing.
    call_async(q, c_search, 'Stop')
    event = q.expect('dbus-return', method='Stop')

    c.Close()
def test_connect_success(q, bus, conn, stream):
    chan, hostname, certificate_path = connect_and_get_tls_objects(
        q, bus, conn)

    certificate = TlsCertificateWrapper(
        bus.get_object(conn.bus_name, certificate_path))
    certificate.TLSCertificate.Accept()

    q.expect('dbus-signal', signal='Accepted')

    cert_props = dbus.Interface(certificate, cs.PROPERTIES_IFACE)
    state = cert_props.Get(cs.AUTH_TLS_CERT, 'State')
    rejections = cert_props.Get(cs.AUTH_TLS_CERT, 'Rejections')

    assertLength(0, rejections)

    chan.Close()

    q.expect_many(
        EventPattern('dbus-signal', signal='Closed'),
        EventPattern('dbus-signal', signal='ChannelClosed'),
        EventPattern('dbus-signal',
                     signal='StatusChanged',
                     args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED]))
    def close_and_check(self):
        self.channel.Close()

        state_event, event, _ = self.q.expect_many(
            EventPattern('dbus-signal',
                         signal='FileTransferStateChanged',
                         path=self.channel.object_path),
            EventPattern('stream-iq',
                         stream=self.stream,
                         iq_type='set',
                         query_name='session'),
            EventPattern('dbus-signal',
                         signal='Closed',
                         path=self.channel.object_path))

        state, reason = state_event.args
        assert state == cs.FT_STATE_CANCELLED
        assert reason == cs.FT_STATE_CHANGE_REASON_LOCAL_STOPPED

        while event.query.getAttribute('type') != 'terminate':
            event = self.q.expect('stream-iq',
                                  stream=self.stream,
                                  iq_type='set',
                                  query_name='session')
def test_privacy_list_push_valid(q, bus, conn, stream):
    test_invisible_on_connect(q, bus, conn, stream)

    set_id = stream.send_privacy_list_push_iq("invisible")

    _, req_list = q.expect_many(
        EventPattern('stream-iq', iq_type='result', iq_id=set_id),
        EventPattern('stream-iq', query_ns=ns.PRIVACY, iq_type="get"))

    stream.send_privacy_list(req_list.stanza, [
        elem('item', action='deny', order='1')(elem(u'presence-out')),
        elem('item',
             type='jid',
             value='*****@*****.**',
             action='deny',
             order='2')(elem(u'message'))
    ])

    # We redundantly re-activate the 'invisible' list. These lines also
    # check to see that we didn't switch over to 'invisible-gabble'
    activate_list = q.expect('stream-iq', query_ns=ns.PRIVACY, iq_type='set')
    active = xpath.queryForNodes('//active', activate_list.stanza)[0]
    assertEquals(active["name"], 'invisible')
    acknowledge_iq(stream, activate_list.stanza)
def abort_auth(q, chan, reason, message):
    reason_err_map = {
        cs.SASL_ABORT_REASON_USER_ABORT : cs.CANCELLED,
        cs.SASL_ABORT_REASON_INVALID_CHALLENGE : cs.SERVICE_CONFUSED }

    mapped_error = reason_err_map.get(reason, cs.CANCELLED)

    chan.SASLAuthentication.AbortSASL(reason, message)

    ssc, ce, _ = q.expect_many(
        EventPattern(
            'dbus-signal', signal='SASLStatusChanged',
            interface=cs.CHANNEL_IFACE_SASL_AUTH,
            predicate=lambda e: e.args[0] == cs.SASL_STATUS_CLIENT_FAILED),
        EventPattern('dbus-signal', signal='ConnectionError'),
        EventPattern(
            'dbus-signal', signal="StatusChanged",
            args=[cs.CONN_STATUS_DISCONNECTED,
                  cs.CSR_AUTHENTICATION_FAILED]))

    assertEquals(cs.SASL_STATUS_CLIENT_FAILED, ssc.args[0])
    assertEquals(mapped_error, ssc.args[1])
    assertEquals(message, ssc.args[2].get('debug-message')),
    assertEquals(mapped_error, ce.args[0])
def expect_sasl_channel(q, bus, conn):
    signal, = q.expect_many(
            EventPattern('dbus-signal', signal='NewChannels',
                predicate=lambda e:
                    e.args[0][0][1].get(cs.CHANNEL_TYPE) ==
                        cs.CHANNEL_TYPE_SERVER_AUTHENTICATION),
                )
    path = signal.args[0][0][0]

    chan = SaslChannelWrapper(bus.get_object(conn.bus_name, path))
    assertLength(1, signal.args[0])
    props = signal.args[0][0][1]

    assertEquals(cs.CHANNEL_IFACE_SASL_AUTH, props.get(cs.AUTH_METHOD))
    return chan, props
示例#10
0
def test_plain_success(q, bus, conn, stream):
    chan, props = connect_and_get_sasl_channel(q, bus, conn)

    assertEquals(JID, props.get(cs.SASL_AUTHORIZATION_IDENTITY))

    # On some servers we can't do DIGEST auth without this information.
    assertEquals('example.org', props.get(cs.SASL_DEFAULT_REALM))
    # We can't necessarily do PLAIN auth without this information.
    assertEquals('test', props.get(cs.SASL_DEFAULT_USERNAME))

    chan.SASLAuthentication.StartMechanismWithData('PLAIN', INITIAL_RESPONSE)
    e, _ = q.expect_many(
        EventPattern('sasl-auth', initial_response=INITIAL_RESPONSE),
        EventPattern('dbus-signal',
                     signal='SASLStatusChanged',
                     interface=cs.CHANNEL_IFACE_SASL_AUTH,
                     args=[cs.SASL_STATUS_IN_PROGRESS, '', {}]),
    )
    authenticator = e.authenticator

    authenticator.success(None)
    q.expect('dbus-signal',
             signal='SASLStatusChanged',
             interface=cs.CHANNEL_IFACE_SASL_AUTH,
             args=[cs.SASL_STATUS_SERVER_SUCCEEDED, '', {}])

    chan.SASLAuthentication.AcceptSASL()

    q.expect('dbus-signal',
             signal='SASLStatusChanged',
             interface=cs.CHANNEL_IFACE_SASL_AUTH,
             args=[cs.SASL_STATUS_SUCCEEDED, '', {}])

    e = q.expect('dbus-signal',
                 signal='StatusChanged',
                 args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED])
    def reject_start_receiving(self, content):
        self.stop_receiving(content)

        content.stream.RequestReceiving(self.remote_handle, True)

        self.q.expect('dbus-signal',
                      signal='ReceivingStateChanged',
                      args=[cs.CALL_STREAM_FLOW_STATE_PENDING_START],
                      path=content.stream.__dbus_object_path__),

        content.stream.Media.CompleteReceivingStateChange(
            cs.CALL_STREAM_FLOW_STATE_STARTED)

        o = self.q.expect_many(
            EventPattern('dbus-signal',
                         signal='ReceivingStateChanged',
                         args=[cs.CALL_STREAM_FLOW_STATE_STARTED],
                         path=content.stream.__dbus_object_path__),
            EventPattern('dbus-signal',
                         signal='RemoteMembersChanged',
                         path=content.stream.__dbus_object_path__),
            EventPattern('sip-invite'))

        assertLength(0, o[1].args[2])
        assertLength(1, o[1].args[0])
        assertEquals(cs.CALL_SENDING_STATE_PENDING_SEND,
                     o[1].args[0][self.remote_handle])
        assertEquals(self.self_handle, o[1].args[3][0])
        assertEquals(cs.CALL_STATE_CHANGE_REASON_USER_REQUESTED,
                     o[1].args[3][1])
        reinvite_event = o[2]

        assertDoesNotContain('a=sendonly', reinvite_event.sip_message.body)
        assertDoesNotContain('a=inactive', reinvite_event.sip_message.body)

        self.context.check_call_sdp(reinvite_event.sip_message.body)
        body = reinvite_event.sip_message.body + 'a=recvonly\r\r'
        self.context.accept(reinvite_event.sip_message, body)

        ack_cseq = "%s ACK" % reinvite_event.cseq.split()[0]
        self.q.expect_many(EventPattern('sip-ack', cseq=ack_cseq))

        # Now let's restart receiving for real
        self.receiving = True
        self.context.reinvite()

        acc, rmb = self.q.expect_many(
            EventPattern('sip-response', code=200),
            EventPattern('dbus-signal',
                         signal='RemoteMembersChanged',
                         path=content.stream.__dbus_object_path__,
                         predicate=lambda e: e.args[0] ==
                         {self.remote_handle: cs.CALL_SENDING_STATE_SENDING}))

        self.context.check_call_sdp(acc.sip_message.body, self.medias)
        self.context.ack(acc.sip_message)
    def stop_sending(self, content):

        self.sending = False

        content.stream.SetSending(False)
        self.q.expect('dbus-signal',
                      signal='SendingStateChanged',
                      args=[cs.CALL_STREAM_FLOW_STATE_PENDING_STOP],
                      path=content.stream.__dbus_object_path__)

        content.stream.Media.CompleteSendingStateChange(
            cs.CALL_STREAM_FLOW_STATE_STOPPED)

        o = self.q.expect_many(
            EventPattern('dbus-signal',
                         signal='SendingStateChanged',
                         args=[cs.CALL_STREAM_FLOW_STATE_STOPPED],
                         path=content.stream.__dbus_object_path__),
            EventPattern('dbus-signal',
                         signal='LocalSendingStateChanged',
                         path=content.stream.__dbus_object_path__),
            EventPattern('sip-invite'))

        assertEquals(cs.CALL_SENDING_STATE_NONE, o[1].args[0])
        assertEquals(self.self_handle, o[1].args[1][0])
        reinvite_event = o[2]

        assertContains('a=recvonly', reinvite_event.sip_message.body)
        self.context.check_call_sdp(reinvite_event.sip_message.body)
        body = reinvite_event.sip_message.body.replace(
            'recvonly', self.receiving and 'sendonly' or 'inactive')

        self.context.accept(reinvite_event.sip_message, body)

        ack_cseq = "%s ACK" % reinvite_event.cseq.split()[0]
        self.q.expect('sip-ack', cseq=ack_cseq)
def test_join_bouncer(q, conn, stream, room):
    stream.sendJoin(room)

    new_channels = EventPattern('dbus-signal', signal='NewChannels')
    event = q.expect_many(new_channels)[0]
    q.forbid_events([new_channels])
    channel_details = event.args[0]
    assertEquals(1, len(channel_details))
    path, props = channel_details[0]
    assertEquals(HT_ROOM, props[TARGET_HANDLE_TYPE])
    assertEquals(CHANNEL_TYPE_TEXT, props[CHANNEL_TYPE])

    q.expect('dbus-signal', signal='MembersChanged')

    q.unforbid_events([new_channels])
    return path
示例#14
0
    def send_file(self):
        s = self.create_socket()
        s.connect(self.address)
        s.send(self.file.data[self.file.offset:])

        to_receive = self.file.size - self.file.offset
        self.count = 0

        def bytes_changed_cb(bytes):
            self.count = bytes

        self.ft_channel.connect_to_signal('TransferredBytesChanged', bytes_changed_cb)

        # FileTransferStateChanged can be fired while we are receiving data
        # (in the SOCKS5 case for example)
        self.completed = False
        def ft_state_changed_cb(state, reason):
            if state == cs.FT_STATE_COMPLETED:
                self.completed = True
        self.ft_channel.connect_to_signal('FileTransferStateChanged', ft_state_changed_cb)

        # get data from bytestream
        data = b''
        while len(data) < to_receive:
            data += self.bytestream.get_data()

        assert data == self.file.data[self.file.offset:]

        if self.completed:
            # FileTransferStateChanged has already been received
            waiting = []
        else:
            waiting = [EventPattern('dbus-signal', signal='FileTransferStateChanged')]

        events = self.bytestream.wait_bytestream_closed(waiting)

        # If not all the bytes transferred have been announced using
        # TransferredBytesChanged, wait for them
        while self.count < to_receive:
            self.q.expect('dbus-signal', signal='TransferredBytesChanged')

        assert self.count == to_receive

        if len(waiting) > 1:
            state, reason = events[0].args
            assert state == cs.FT_STATE_COMPLETED
            assert reason == cs.FT_STATE_CHANGE_REASON_NONE
示例#15
0
def test_limit(q, bus, conn, stream):
    chan = setup(q, bus, conn, stream)

    # do nothing, really
    forbidden = [EventPattern('stream-MODE'),
                 EventPattern('dbus-signal', signal='PropertiesChanged')]
    q.forbid_events(forbidden)

    call_async(q, chan.RoomConfig1, 'UpdateConfiguration',
               {'Limit': dbus.UInt32(0)})

    q.expect_many(EventPattern('dbus-return', method='UpdateConfiguration'))

    sync_stream(q, stream)
    q.unforbid_events(forbidden)

    # set a limit
    call_async(q, chan.RoomConfig1, 'UpdateConfiguration',
               {'Limit': dbus.UInt32(1337)}) # totally 1337

    q.expect_many(EventPattern('dbus-return', method='UpdateConfiguration'),
                  EventPattern('stream-MODE', data=['#test', '+l', '1337']),
                  EventPattern('dbus-signal', signal='PropertiesChanged',
                               args=[cs.CHANNEL_IFACE_ROOM_CONFIG,
                                     {'Limit': 1337},
                                     []])
                  )

    # unset the limit
    call_async(q, chan.RoomConfig1, 'UpdateConfiguration',
               {'Limit': dbus.UInt32(0)})

    q.expect_many(EventPattern('dbus-return', method='UpdateConfiguration'),
                  EventPattern('stream-MODE', data=['#test', '-l']),
                  EventPattern('dbus-signal', signal='PropertiesChanged',
                               args=[cs.CHANNEL_IFACE_ROOM_CONFIG,
                                     {'Limit': 0},
                                     []])
                  )
示例#16
0
    def _socks5_expect_connection(self, expected_before, expected_after):
        events_before, _ = wait_events(self.q, expected_before,
                                       EventPattern('s5b-connected'))

        self._wait_auth_request()
        self._send_auth_reply()
        self._wait_connect_cmd()

        # pretend the hash was wrong and close the transport
        self.transport.loseConnection()

        iq_event = self.q.expect('stream-iq',
                                 iq_type='error',
                                 to=self.initiator)
        self.check_error_stanza(iq_event.stanza)

        return events_before, []
def _test_on_connect(q,
                     bus,
                     conn,
                     stream,
                     shared_status,
                     show,
                     msg,
                     expected_show=None,
                     min_version=None):
    expected_show = expected_show or show
    _status, _show, _invisible = shared_status
    stream.shared_status = shared_status
    if min_version is not None:
        stream.min_version = min_version

    forbidden_event_patterns = [
        EventPattern('stream-presence'),
        EventPattern('stream-iq', query_ns=ns.PRIVACY, iq_type='get')
    ]
    q.forbid_events(forbidden_event_patterns)

    conn.SimplePresence.SetPresence(show, msg)
    conn.Connect()

    _, event = q.expect_many(
        EventPattern('stream-iq',
                     query_ns=ns.GOOGLE_SHARED_STATUS,
                     iq_type='get'),
        EventPattern('stream-iq',
                     query_ns=ns.GOOGLE_SHARED_STATUS,
                     iq_type='set'))

    shared_show, shared_invisible = _show_to_shared_status_show(show)

    _status = xpath.queryForNodes('//status', event.query)[0]
    assertEquals(msg, _status.children[0])
    _show = xpath.queryForNodes('//show', event.query)[0]
    assertEquals(shared_show, _show.children[0])
    _invisible = xpath.queryForNodes('//invisible', event.query)[0]
    assertEquals(shared_invisible, _invisible.getAttribute('value'))

    q.expect_many(
        EventPattern('dbus-signal',
                     signal='PresencesChanged',
                     interface=cs.CONN_IFACE_SIMPLE_PRESENCE,
                     args=[{
                         1: (presence_types[expected_show], expected_show, msg)
                     }]),
        EventPattern('dbus-signal',
                     signal='StatusChanged',
                     args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED]))

    q.unforbid_events(forbidden_event_patterns)
def recreate_text(q, bus, conn, stream):
    jid = '*****@*****.**'

    tube_chan, _, _ = stream_tube(q, bus, conn, stream, 'CreateChannel', jid)
    text_chan, text_path, text_props = text_channel(q,
                                                    bus,
                                                    conn,
                                                    stream,
                                                    'CreateChannel',
                                                    jid,
                                                    presence=False)

    text_chan.Close()
    expect_close(q, text_path)

    assert_on_bus(q, tube_chan)
    assert_not_on_bus(q, text_chan)

    # now let's try and create the same text channel and hope we get
    # back the same channel
    q.forbid_events([EventPattern('stream-presence', to='%s/test' % jid)])

    request_text_channel(q, bus, conn, 'CreateChannel', jid)

    ret = q.expect('dbus-return', method='CreateChannel')

    path, props = ret.value
    assertEquals(cs.CHANNEL_TYPE_TEXT, props[cs.CHANNEL_TYPE])

    new_sig = q.expect('dbus-signal', signal='NewChannels')

    channels = new_sig.args[0]
    assertEquals(1, len(channels))

    assertEquals(path, channels[0][0])
    assertEquals(props, channels[0][1])

    # the channel should be identical given it's the same MucChannel
    assertEquals(text_path, path)
    assertEquals(text_props, props)

    assert_on_bus(q, tube_chan)
    assert_on_bus(q, text_chan)

    q.unforbid_all()
示例#19
0
    def open_bytestream(self, expected_before=[], expected_after=[]):
        # first propose to peer to connect using SOCKS5
        # We set an invalid IP so that won't work
        self.socks5._send_socks5_init([
            # Not working streamhost
            (self.initiator, 'invalid.invalid', 12345),
        ])

        events_before, iq_event = wait_events(
            self.q, expected_before,
            EventPattern('stream-iq', iq_type='error', to=self.initiator))

        self.socks5.check_error_stanza(iq_event.stanza)

        # socks5 failed, let's try IBB
        _, events_after = self.ibb.open_bytestream([], expected_after)

        return events_before, events_after
def _test_remote_status_away(q, bus, conn, stream, msg, show, list_attrs):
    events = [
        EventPattern('dbus-signal',
                     signal='PresencesChanged',
                     interface=cs.CONN_IFACE_SIMPLE_PRESENCE,
                     args=[{
                         1: (presence_types[show], show, msg)
                     }])
    ]
    q.forbid_events(events)

    list_attrs['status'] = list_attrs.get('status', msg)
    stream.set_shared_status_lists(**list_attrs)

    q.expect('stream-iq', iq_type='result')

    sync_dbus(bus, q, conn)

    q.unforbid_events(events)
示例#21
0
def test_invisible_on_connect(q, bus, conn, stream):
    props = conn.Properties.GetAll(cs.CONN_IFACE_SIMPLE_PRESENCE)
    assertNotEquals({}, props['Statuses'])

    presence_event_pattern = EventPattern('stream-presence')

    q.forbid_events([presence_event_pattern])

    conn.SimplePresence.SetPresence("hidden", "")

    conn.Connect()

    event = q.expect('stream-iq', query_name='invisible')
    acknowledge_iq(stream, event.stanza)

    q.unforbid_events([presence_event_pattern])

    q.expect('dbus-signal', signal='StatusChanged',
             args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED])
    def during_call(self):
        content = self.contents[0]

        remote_hold_event = [
            EventPattern('dbus-signal', signal='CallStateChanged')
        ]
        self.q.forbid_events(remote_hold_event)

        self.stop_start_sending_user_requested(content)
        self.stop_start_sending_remote_requested(content)

        self.stop_start_receiving_user_requested(content)

        self.running_check()

        self.reject_stop_receiving(content)
        self.stop_start_receiving_user_requested(content)
        self.reject_start_receiving(content)

        self.running_check()

        self.sending_failed(content)
        self.receiving_failed(content)

        self.running_check()

        direction_change_events = \
            self.stream_dbus_signal_event('LocalSendingStateChanged') + \
            self.stream_dbus_signal_event('RemoteMembersChanged')

        self.q.forbid_events(direction_change_events)
        self.hold()
        self.add_local_content_during_hold()
        self.add_remote_content_during_hold()
        self.unhold_fail(receiving=True)
        self.unhold_fail(receiving=False)
        self.unhold_succeed()
        self.q.unforbid_events(direction_change_events)

        self.q.unforbid_events(remote_hold_event)

        return calltest.CallTest.during_call(self)
def test(q, bus, conn, stream):
    event = q.expect('stream-iq',
                     to=None,
                     query_ns='vcard-temp',
                     query_name='vCard')

    acknowledge_iq(stream, event.stanza)
    sync_stream(q, stream)
    sync_dbus(bus, q, conn)

    # A presence from a contact
    stream.send(
        make_presence('contact1@localhost/client', 'SHA1SUM-FOR-CONTACT1'))
    event = q.expect('dbus-signal', signal='AvatarUpdated')
    assert event.args[0] == 2, event.args
    assert event.args[1] == "SHA1SUM-FOR-CONTACT1", event.args

    AvatarRetrieved_event = EventPattern('dbus-signal',
                                         signal='AvatarRetrieved')
    AvatarUpdated_event = EventPattern('dbus-signal', signal='AvatarUpdated')
    StreamPresence_event = EventPattern('stream-presence')
    StreamIqVcard_event = EventPattern('stream-iq', query_ns='vcard-temp')

    # A presence from myself on another resource
    stream.send(
        make_presence('test@localhost/resource1', 'SHA1SUM-FOR-MYSELF-RES1'))
    q.forbid_events([AvatarRetrieved_event, AvatarUpdated_event])
    stream_presence, stream_iq = q.expect_many(
        EventPattern('stream-presence'),
        EventPattern('stream-iq',
                     to=None,
                     query_ns='vcard-temp',
                     query_name='vCard'))
    sync_dbus(bus, q, conn)
    q.unforbid_events([AvatarRetrieved_event, AvatarUpdated_event])

    # If the server wrongly send a presence stanza with our resource,
    # AvatarUpdated must not be emitted
    q.forbid_events([
        StreamPresence_event, StreamIqVcard_event, AvatarRetrieved_event,
        AvatarUpdated_event
    ])
    stream.send(make_presence('test@localhost/Resource', 'SHA1SUM-FOR-MYSELF'))
    sync_dbus(bus, q, conn)
    sync_stream(q, stream)
    q.unforbid_events([
        StreamPresence_event, StreamIqVcard_event, AvatarRetrieved_event,
        AvatarUpdated_event
    ])
示例#24
0
def test(q, bus, conn):
    # Request a sidecar thate we support before we're connected; it should just
    # wait around until we're connected.
    call_async(q, conn.Sidecars1, 'EnsureSidecar', TEST_PLUGIN_IFACE)

    conn.Connect()

    if PLUGINS_ENABLED:
        # Now we're connected, the call we made earlier should return.
        path, props = q.expect('dbus-return', method='EnsureSidecar').value
        # This sidecar doesn't even implement get_immutable_properties; it
        # should just get the empty dict filled in for it.
        assertEquals({}, props)

        # We should get the same sidecar if we request it again
        path2, props2 = conn.Sidecars1.EnsureSidecar(TEST_PLUGIN_IFACE)
        assertEquals((path, props), (path2, props2))
    else:
        # Only now does it fail.
        q.expect('dbus-error', method='EnsureSidecar')

    # This is not a valid interface name
    call_async(q, conn.Sidecars1, 'EnsureSidecar', 'not an interface')
    q.expect('dbus-error', name=cs.INVALID_ARGUMENT)

    # The test plugin makes no reference to this interface.
    call_async(q, conn.Sidecars1, 'EnsureSidecar', 'unsupported.sidecar')
    q.expect('dbus-error', name=cs.NOT_IMPLEMENTED)

    call_async(q, conn, 'Disconnect')

    q.expect_many(
        EventPattern('dbus-signal', signal='StatusChanged',
            args=[cs.CONN_STATUS_DISCONNECTED, cs.CSR_REQUESTED]),
        )

    call_async(q, conn.Sidecars1, 'EnsureSidecar', 'zomg.what')
    # With older telepathy-glib this would be DISCONNECTED;
    # with newer telepathy-glib the Connection disappears from the bus
    # sooner, and you get UnknownMethod or something from dbus-glib.
    q.expect('dbus-error')
示例#25
0
def double_server(q, bus, conn, stream):
    # For some reason the 2 proxies are actually the same. Check that we don't
    # set them twice in the SOCKS5 init stanza
    connect_and_announce_alice(q, bus, conn, stream)

    send_file_to_alice(q, conn)

    return_event, e1, e2 = q.expect_many(
        EventPattern('dbus-return', method='CreateChannel'),
        proxy_query_events[0], proxy_query_events[1])

    send_socks5_reply(stream, e1.stanza)

    # send the same reply for the second stanza with with a different port
    send_socks5_reply(stream, e2.stanza, 'fallback1-proxy.localhost',
                      '127.0.0.1', '6789')

    proxies = wait_si_and_return_proxies(q, stream)
    # check that the proxy has been set only once
    check_proxies([('fallback1-proxy.localhost', '127.0.0.1', '6789')],
                  proxies)
def connect_and_get_tls_objects(q, bus, conn, expect_example_jid=True):
    conn.Connect()

    q.expect('dbus-signal', signal='StatusChanged',
             args=[cs.CONN_STATUS_CONNECTING, cs.CSR_REQUESTED])

    ev, = q.expect_many(
        EventPattern('dbus-signal', signal='NewChannels',
                     predicate=is_server_tls_chan_event))

    channels = ev.args[0]
    path, props = channels[0]

    chan = ServerTlsChanWrapper(bus.get_object(conn.bus_name, path))
    hostname = props[cs.TLS_HOSTNAME]
    certificate_path = props[cs.TLS_CERT_PATH]

    if expect_example_jid:
        assertEquals(hostname, 'example.org')

    return chan, hostname, certificate_path
示例#27
0
def send_file(q, bus, conn, stream):
    connect_and_announce_alice(q, bus, conn, stream)

    # Send a file; proxy queries are send when creating the FT channel
    send_file_to_alice(q, conn)

    return_event, e1, e2 = q.expect_many(
        EventPattern('dbus-return', method='CreateChannel'),
        proxy_query_events[0], proxy_query_events[1])

    send_socks5_reply(stream, e1.stanza)
    send_socks5_reply(stream, e2.stanza)

    # ensure that the same proxy is not queried more than once
    q.forbid_events(proxy_query_events)

    proxies = wait_si_and_return_proxies(q, stream)

    check_proxies([('fallback2-proxy.localhost', '127.0.0.1', '6789'),
                   ('fallback1-proxy.localhost', '127.0.0.1', '12345')],
                  proxies)
示例#28
0
def proxy_error(q, bus, conn, stream):
    # Test if another proxy is queried if a query failed
    connect_and_announce_alice(q, bus, conn, stream)

    send_file_to_alice(q, conn)

    return_event, e1, e2, e3 = q.expect_many(
        EventPattern('dbus-return', method='CreateChannel'),
        EventPattern('stream-iq', iq_type='get', query_ns=ns.BYTESTREAMS),
        EventPattern('stream-iq', iq_type='get', query_ns=ns.BYTESTREAMS),
        EventPattern('stream-iq', iq_type='get', query_ns=ns.BYTESTREAMS))

    # Return errors for all the requests; the bugged proxies shouldn't be queried again
    q.forbid_events([
        EventPattern('stream-iq',
                     to=e1.stanza['to'],
                     iq_type='get',
                     query_ns=ns.BYTESTREAMS)
    ])
    send_error_reply(stream, e1.stanza)

    # the fourth proxy is queried
    q.expect('stream-iq', iq_type='get', query_ns=ns.BYTESTREAMS)

    q.forbid_events([
        EventPattern('stream-iq',
                     to=e2.stanza['to'],
                     iq_type='get',
                     query_ns=ns.BYTESTREAMS)
    ])
    send_error_reply(stream, e2.stanza)
    sync_stream(q, stream)

    q.forbid_events([
        EventPattern('stream-iq',
                     to=e3.stanza['to'],
                     iq_type='get',
                     query_ns=ns.BYTESTREAMS)
    ])
    send_error_reply(stream, e3.stanza)
    sync_stream(q, stream)
def test(q, bus, conn, stream):
    # This sidecar sends a stanza, and waits for a reply, before being
    # created.
    pattern = EventPattern('stream-iq',
                           to='sidecar.example.com',
                           query_ns='http://example.com/sidecar')
    call_async(q, conn.Sidecars1, 'EnsureSidecar', TEST_PLUGIN_IFACE + ".IQ")
    e = q.expect_many(pattern)[0]

    # The server said yes, so we should get a sidecar back!
    acknowledge_iq(stream, e.stanza)
    q.expect('dbus-return', method='EnsureSidecar')

    identities = ["test/app-list//Test"]
    features = ["com.example.test1", "com.example.test2"]
    ver = compute_caps_hash(identities, features, {})

    iq = IQ(stream, "get")
    query = iq.addElement((ns.DISCO_INFO, 'query'))
    query['node'] = ns.GABBLE_CAPS + '#' + ver
    stream.send(iq)
    e = q.expect('stream-iq', query_ns='http://jabber.org/protocol/disco#info')

    returned_features = [
        feature['var']
        for feature in xpath.queryForNodes('/iq/query/feature', e.stanza)
    ]
    assertEquals(features, returned_features)

    returned_identities = [
        identity['category'] + "/" + identity['type'] + "//" + identity['name']
        for identity in xpath.queryForNodes('/iq/query/identity', e.stanza)
    ]
    assertEquals(identities, returned_identities)

    new_ver = compute_caps_hash(returned_identities, returned_features, {})
    assertEquals(new_ver, ver)
示例#30
0
def test_caps(q, conn, stream, contact, features, audio, video, google=False):
    caps['ver'] = compute_caps_hash ([], features, {})

    h = presence_and_disco(q, conn, stream, contact, True,
        client, caps, features)

    cflags = 0
    call_expected_media_caps = []

    if audio:
      cflags |= cs.MEDIA_CAP_AUDIO
      call_expected_media_caps.append (cs.CALL_INITIAL_AUDIO)
      call_expected_media_caps.append (cs.CALL_INITIAL_AUDIO_NAME)
    if video:
      cflags |= cs.MEDIA_CAP_VIDEO
      call_expected_media_caps.append (cs.CALL_INITIAL_VIDEO)
      call_expected_media_caps.append (cs.CALL_INITIAL_VIDEO_NAME)

    # If the contact can only do one of audio or video, or uses a Google
    # client, they'll have the ImmutableStreams cap.
    if cflags < (cs.MEDIA_CAP_AUDIO | cs.MEDIA_CAP_VIDEO) or google:
        cflags |= cs.MEDIA_CAP_IMMUTABLE_STREAMS
    else:
        call_expected_media_caps.append(cs.CALL_MUTABLE_CONTENTS)

    event, = q.expect_many(
            EventPattern('dbus-signal', signal='ContactCapabilitiesChanged')
        )

    # Check Contact capabilities
    assertEquals(len(event.args), 1)
    assertEquals (event.args[0],
        get_contacts_capabilities_sync(conn, [h]))

    check_contact_caps (event.args[0][h],
        cs.CHANNEL_TYPE_CALL, call_expected_media_caps)
def test(q, bus, conn, stream):
    iq_event = q.expect('stream-iq', to=None, query_ns='vcard-temp',
            query_name='vCard')

    acknowledge_iq(stream, iq_event.stanza)

    handle = conn.get_contact_handle_sync('*****@*****.**')
    conn.Avatars.RequestAvatars([handle])
    conn.Avatars.RequestAvatars([handle])
    conn.Avatars.RequestAvatars([handle])
    conn.Avatars.RequestAvatars([handle])

    iq_event = q.expect('stream-iq', to='*****@*****.**', query_ns='vcard-temp',
        query_name='vCard')
    iq = make_result_iq(stream, iq_event.stanza)
    vcard = iq.firstChildElement()
    photo = vcard.addElement('PHOTO')
    photo.addElement('TYPE', content='image/png')
    photo.addElement('BINVAL', content=base64.b64encode(b'hello').decode())
    stream.send(iq)

    event = q.expect('dbus-signal', signal='AvatarRetrieved')

    q.forbid_events([EventPattern('dbus-signal', signal='AvatarRetrieved')])