def test(q, bus, conn, stream, bytestream_cls, access_control): disco_event = q.expect('stream-iq', to='localhost', query_ns=ns.DISCO_ITEMS) announce_socks5_proxy(q, stream, disco_event.stanza) t.check_conn_properties(q, conn) self_handle = conn.Properties.Get(cs.CONN, "SelfHandle") alice_handle = conn.get_contact_handle_sync('alice@localhost') # send Alice's presence caps = { 'ext': '', 'ver': '0.0.0', 'node': 'http://example.com/fake-client0' } presence = make_presence('alice@localhost/Test', caps=caps) stream.send(presence) _, disco_event = q.expect_many( EventPattern('dbus-signal', signal='PresencesChanged', args = [{alice_handle: (2L, u'available', u'')}]), EventPattern('stream-iq', to='alice@localhost/Test', query_ns=ns.DISCO_INFO), ) # reply to disco query send_disco_reply(stream, disco_event.stanza, [], [ns.TUBES]) sync_stream(q, stream) offer_new_dbus_tube(q, bus, conn, stream, self_handle, alice_handle, bytestream_cls, access_control)
def test(q, bus, conn, stream, access_control): iq_event = q.expect('stream-iq', to=None, query_ns='vcard-temp', query_name='vCard') acknowledge_iq(stream, iq_event.stanza) # check if we can request muc D-Bus tube t.check_conn_properties(q, conn) self_handle = conn.Properties.Get(cs.CONN, "SelfHandle") self_name = conn.inspect_contact_sync(self_handle) # offer a D-Bus tube to another room using new API muc = '*****@*****.**' request = { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_DBUS_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, cs.TARGET_ID: '*****@*****.**', cs.DBUS_TUBE_SERVICE_NAME: 'com.example.TestCase', } join_muc(q, bus, conn, stream, muc, request=request) e = q.expect('dbus-signal', signal='NewChannels') channels = e.args[0] assert len(channels) == 1 path, prop = channels[0] assert prop[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_DBUS_TUBE assert prop[cs.INITIATOR_ID] == '[email protected]/test' assert prop[cs.REQUESTED] == True assert prop[cs.TARGET_HANDLE_TYPE] == cs.HT_ROOM assert prop[cs.TARGET_ID] == '*****@*****.**' assert prop[cs.DBUS_TUBE_SERVICE_NAME] == 'com.example.TestCase' assert prop[cs.DBUS_TUBE_SUPPORTED_ACCESS_CONTROLS] == [ cs.SOCKET_ACCESS_CONTROL_CREDENTIALS, cs.SOCKET_ACCESS_CONTROL_LOCALHOST ] # check that the tube channel is in the channels list all_channels = conn.Get(cs.CONN_IFACE_REQUESTS, 'Channels', dbus_interface=cs.PROPERTIES_IFACE, byte_arrays=True) assertContains((path, prop), all_channels) tube_chan = wrap_channel(bus.get_object(conn.bus_name, path), 'DBusTube') tube_props = tube_chan.Properties.GetAll(cs.CHANNEL_IFACE_TUBE, byte_arrays=True) assert tube_props['State'] == cs.TUBE_CHANNEL_STATE_NOT_OFFERED # try to offer using a wrong access control try: tube_chan.DBusTube.Offer(sample_parameters, cs.SOCKET_ACCESS_CONTROL_PORT) except dbus.DBusException, e: assertEquals(e.get_dbus_name(), cs.INVALID_ARGUMENT)
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) t.check_conn_properties(q, conn) # Create new style tube channel and make sure that is indeed # returned. muc = '*****@*****.**' call_async( q, conn.Requests, 'CreateChannel', { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_DBUS_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, cs.TARGET_ID: muc, cs.DBUS_TUBE_SERVICE_NAME: 'com.example.LolDongs' }) q.expect('stream-presence', to='%s/test' % muc) stream.send(make_muc_presence('owner', 'moderator', muc, 'bob')) stream.send(make_muc_presence('none', 'participant', muc, 'test')) ret, _ = q.expect_many( EventPattern('dbus-return', method='CreateChannel'), EventPattern('dbus-signal', signal='NewChannels'), ) _, props = ret.value assertEquals(props[cs.CHANNEL_TYPE], cs.CHANNEL_TYPE_DBUS_TUBE) assertEquals(props[cs.TARGET_HANDLE_TYPE], cs.HT_ROOM) assertEquals(props[cs.TARGET_ID], muc) # Now try joining the text muc before asking for the tube channel. muc = '*****@*****.**' join_muc(q, bus, conn, stream, muc) call_async( q, conn.Requests, 'CreateChannel', { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_DBUS_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, cs.TARGET_ID: muc, cs.DBUS_TUBE_SERVICE_NAME: 'com.example.LolDongs' }) ret, _ = q.expect_many( EventPattern('dbus-return', method='CreateChannel'), EventPattern('dbus-signal', signal='NewChannels'), ) _, props = ret.value assertEquals(props[cs.CHANNEL_TYPE], cs.CHANNEL_TYPE_DBUS_TUBE) assertEquals(props[cs.TARGET_HANDLE_TYPE], cs.HT_ROOM) assertEquals(props[cs.TARGET_ID], muc)
def test(q, bus, conn, stream, access_control): iq_event = q.expect('stream-iq', to=None, query_ns='vcard-temp', query_name='vCard') acknowledge_iq(stream, iq_event.stanza) # check if we can request muc D-Bus tube t.check_conn_properties(q, conn) self_handle = conn.Properties.Get(cs.CONN, "SelfHandle") self_name = conn.inspect_contact_sync(self_handle) # offer a D-Bus tube to another room using new API muc = '*****@*****.**' request = { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_DBUS_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, cs.TARGET_ID: '*****@*****.**', cs.DBUS_TUBE_SERVICE_NAME: 'com.example.TestCase', } join_muc(q, bus, conn, stream, muc, request=request) e = q.expect('dbus-signal', signal='NewChannels') channels = e.args[0] assert len(channels) == 1 path, prop = channels[0] assert prop[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_DBUS_TUBE assert prop[cs.INITIATOR_ID] == '[email protected]/test' assert prop[cs.REQUESTED] == True assert prop[cs.TARGET_HANDLE_TYPE] == cs.HT_ROOM assert prop[cs.TARGET_ID] == '*****@*****.**' assert prop[cs.DBUS_TUBE_SERVICE_NAME] == 'com.example.TestCase' assert prop[cs.DBUS_TUBE_SUPPORTED_ACCESS_CONTROLS] == [cs.SOCKET_ACCESS_CONTROL_CREDENTIALS, cs.SOCKET_ACCESS_CONTROL_LOCALHOST] # check that the tube channel is in the channels list all_channels = conn.Get(cs.CONN_IFACE_REQUESTS, 'Channels', dbus_interface=cs.PROPERTIES_IFACE, byte_arrays=True) assertContains((path, prop), all_channels) tube_chan = wrap_channel(bus.get_object(conn.bus_name, path), 'DBusTube') tube_props = tube_chan.Properties.GetAll(cs.CHANNEL_IFACE_TUBE, byte_arrays=True) assert tube_props['State'] == cs.TUBE_CHANNEL_STATE_NOT_OFFERED # try to offer using a wrong access control try: tube_chan.DBusTube.Offer(sample_parameters, cs.SOCKET_ACCESS_CONTROL_PORT) except dbus.DBusException, e: assertEquals(e.get_dbus_name(), cs.INVALID_ARGUMENT)
def test(q, bus, conn, stream, bytestream_cls, access_control): disco_event = q.expect('stream-iq', to='localhost', query_ns=ns.DISCO_ITEMS) announce_socks5_proxy(q, stream, disco_event.stanza) t.check_conn_properties(q, conn) self_handle = conn.Properties.Get(cs.CONN, "SelfHandle") alice_handle = conn.get_contact_handle_sync('alice@localhost') # send Alice's presence caps = { 'ext': '', 'ver': '0.0.0', 'node': 'http://example.com/fake-client0' } presence = make_presence('alice@localhost/Test', caps=caps) stream.send(presence) _, disco_event = q.expect_many( EventPattern('dbus-signal', signal='PresencesChanged', args=[{ alice_handle: (2L, u'available', u'') }]), EventPattern('stream-iq', to='alice@localhost/Test', query_ns=ns.DISCO_INFO), ) # reply to disco query send_disco_reply(stream, disco_event.stanza, [], [ns.TUBES]) sync_stream(q, stream) offer_new_dbus_tube(q, bus, conn, stream, self_handle, alice_handle, bytestream_cls, access_control)
def test(q, bus, conn, stream, bytestream_cls, access_control): global last_tube_id t.check_conn_properties(q, conn) vcard_event, roster_event = q.expect_many( EventPattern('stream-iq', to=None, query_ns='vcard-temp', query_name='vCard'), EventPattern('stream-iq', query_ns=ns.ROSTER)) self_handle = conn.Properties.Get(cs.CONN, "SelfHandle") acknowledge_iq(stream, vcard_event.stanza) roster = roster_event.stanza roster['type'] = 'result' item = roster_event.query.addElement('item') item['jid'] = 'bob@localhost' # Bob can do tubes item['subscription'] = 'both' stream.send(roster) bob_full_jid = 'bob@localhost/Bob' self_full_jid = 'test@localhost/Resource' # Send Bob presence and his tube caps presence = domish.Element(('jabber:client', 'presence')) presence['from'] = bob_full_jid presence['to'] = self_full_jid c = presence.addElement('c') c['xmlns'] = 'http://jabber.org/protocol/caps' c['node'] = 'http://example.com/ICantBelieveItsNotTelepathy' c['ver'] = '1.2.3' stream.send(presence) event = q.expect('stream-iq', iq_type='get', query_ns='http://jabber.org/protocol/disco#info', to=bob_full_jid) result = event.stanza result['type'] = 'result' assert event.query['node'] == \ 'http://example.com/ICantBelieveItsNotTelepathy#1.2.3' feature = event.query.addElement('feature') feature['var'] = ns.TUBES stream.send(result) # A tube request can be done only if the contact has tube capabilities # Ensure that Bob's caps have been received sync_stream(q, stream) # Also ensure that all the new contact list channels have been announced, # so that the NewChannel(s) signals we look for after calling # RequestChannel are the ones we wanted. sync_dbus(bus, q, conn) bob_handle = conn.get_contact_handle_sync('bob@localhost') # let's try to accept a D-Bus tube using the new API bytestream = bytestream_cls(stream, q, 'gamma', bob_full_jid, self_full_jid, True) last_tube_id += 1 contact_offer_dbus_tube(bytestream, last_tube_id) def new_chan_predicate(e): path, props = e.args[0][0] return props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_DBUS_TUBE e = q.expect('dbus-signal', signal='NewChannels', predicate=new_chan_predicate) channels = e.args[0] assert len(channels) == 1 path, props = channels[0] assert props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_DBUS_TUBE assert props[cs.INITIATOR_HANDLE] == bob_handle assert props[cs.INITIATOR_ID] == 'bob@localhost' assert props[cs.INTERFACES] == [cs.CHANNEL_IFACE_TUBE] assert props[cs.REQUESTED] == False assert props[cs.TARGET_HANDLE] == bob_handle assert props[cs.TARGET_ID] == 'bob@localhost' assert props[cs.DBUS_TUBE_SERVICE_NAME] == 'com.example.TestCase2' assert props[cs.TUBE_PARAMETERS] == {'login': '******'} assert props[cs.DBUS_TUBE_SUPPORTED_ACCESS_CONTROLS] == [cs.SOCKET_ACCESS_CONTROL_CREDENTIALS, cs.SOCKET_ACCESS_CONTROL_LOCALHOST] assert cs.TUBE_STATE not in props tube_chan = bus.get_object(conn.bus_name, path) tube_chan_iface = dbus.Interface(tube_chan, cs.CHANNEL) dbus_tube_iface = dbus.Interface(tube_chan, cs.CHANNEL_TYPE_DBUS_TUBE) status = tube_chan.Get(cs.CHANNEL_IFACE_TUBE, 'State', dbus_interface=cs.PROPERTIES_IFACE) assert status == cs.TUBE_STATE_LOCAL_PENDING # try to accept using a wrong access control try: dbus_tube_iface.Accept(cs.SOCKET_ACCESS_CONTROL_PORT) except dbus.DBusException, e: assertEquals(e.get_dbus_name(), cs.INVALID_ARGUMENT)
def test(q, bus, conn, stream, bytestream_cls, address_type, access_control, access_control_param): if bytestream_cls in [BytestreamS5BRelay, BytestreamS5BRelayBugged]: # disable SOCKS5 relay tests because proxy can't be used with muc # contacts atm return conn.Connect() _, iq_event = q.expect_many( EventPattern("dbus-signal", signal="StatusChanged", args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED]), EventPattern("stream-iq", to=None, query_ns="vcard-temp", query_name="vCard"), ) acknowledge_iq(stream, iq_event.stanza) self_handle = conn.GetSelfHandle() self_name = conn.InspectHandles(cs.HT_CONTACT, [self_handle])[0] t.check_conn_properties(q, conn) room_handle, tubes_chan, tubes_iface = get_muc_tubes_channel(q, bus, conn, stream, "*****@*****.**") tubes_self_handle = tubes_chan.GetSelfHandle(dbus_interface=cs.CHANNEL_IFACE_GROUP) bob_handle = conn.RequestHandles(cs.HT_CONTACT, ["[email protected]/bob"])[0] address = t.create_server(q, address_type) # offer stream tube (old API) using an Unix socket call_async( q, tubes_iface, "OfferStreamTube", "echo", sample_parameters, address_type, address, access_control, access_control_param, ) new_tube_event, stream_event, _, new_channels_event = q.expect_many( EventPattern("dbus-signal", signal="NewTube"), EventPattern("stream-presence", to="[email protected]/test"), EventPattern("dbus-return", method="OfferStreamTube"), EventPattern("dbus-signal", signal="NewChannels"), ) # handle new_tube_event stream_tube_id = new_tube_event.args[0] assert new_tube_event.args[1] == tubes_self_handle assert new_tube_event.args[2] == 1 # Stream assert new_tube_event.args[3] == "echo" assert new_tube_event.args[4] == sample_parameters assert new_tube_event.args[5] == cs.TUBE_CHANNEL_STATE_OPEN # handle stream_event # We announce our newly created tube in our muc presence presence = stream_event.stanza x_nodes = xpath.queryForNodes('/presence/x[@xmlns="http://jabber.org/' 'protocol/muc"]', presence) assert x_nodes is not None assert len(x_nodes) == 1 tubes_nodes = xpath.queryForNodes('/presence/tubes[@xmlns="%s"]' % ns.TUBES, presence) assert tubes_nodes is not None assert len(tubes_nodes) == 1 tube_nodes = xpath.queryForNodes("/tubes/tube", tubes_nodes[0]) assert tube_nodes is not None assert len(tube_nodes) == 1 for tube in tube_nodes: assert tube["type"] == "stream" assert not tube.hasAttribute("initiator") assert tube["service"] == "echo" assert not tube.hasAttribute("stream-id") assert not tube.hasAttribute("dbus-name") assert tube["id"] == str(stream_tube_id) params = {} parameter_nodes = xpath.queryForNodes("/tube/parameters/parameter", tube) for node in parameter_nodes: assert node["name"] not in params params[node["name"]] = (node["type"], str(node)) assert params == {"ay": ("bytes", "aGVsbG8="), "s": ("str", "hello"), "i": ("int", "-123"), "u": ("uint", "123")} # tube is also announced using new API channels = new_channels_event.args[0] assert len(channels) == 1 path, props = channels[0] assert props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_STREAM_TUBE assert props[cs.INITIATOR_HANDLE] == tubes_self_handle assert props[cs.INITIATOR_ID] == "[email protected]/test" assert props[cs.INTERFACES] == [cs.CHANNEL_IFACE_GROUP, cs.CHANNEL_IFACE_TUBE] assert props[cs.REQUESTED] == True assert props[cs.TARGET_HANDLE] == room_handle assert props[cs.TARGET_ID] == "*****@*****.**" assert props[cs.STREAM_TUBE_SERVICE] == "echo" tube_chan = bus.get_object(conn.bus_name, path) tube_props = tube_chan.GetAll(cs.CHANNEL_IFACE_TUBE, dbus_interface=cs.PROPERTIES_IFACE, byte_arrays=True) assert tube_props["Parameters"] == sample_parameters assert tube_props["State"] == cs.TUBE_CHANNEL_STATE_OPEN tubes = tubes_iface.ListTubes(byte_arrays=True) assert tubes == [ (stream_tube_id, tubes_self_handle, 1, "echo", sample_parameters, cs.TUBE_CHANNEL_STATE_OPEN) # Stream ] assert len(tubes) == 1, unwrap(tubes) expected_tube = ( stream_tube_id, tubes_self_handle, cs.TUBE_TYPE_STREAM, "echo", sample_parameters, cs.TUBE_STATE_OPEN, ) t.check_tube_in_tubes(expected_tube, tubes) # FIXME: if we use an unknown JID here, everything fails # (the code uses lookup where it should use ensure) bytestream = connect_to_tube(stream, q, bytestream_cls, "*****@*****.**", stream_tube_id) iq_event, socket_event, _, conn_event = q.expect_many( EventPattern("stream-iq", iq_type="result"), EventPattern("socket-connected"), EventPattern( "dbus-signal", signal="StreamTubeNewConnection", args=[stream_tube_id, bob_handle], interface=cs.CHANNEL_TYPE_TUBES, ), EventPattern("dbus-signal", signal="NewRemoteConnection", interface=cs.CHANNEL_TYPE_STREAM_TUBE), ) protocol = socket_event.protocol # handle iq_event bytestream.check_si_reply(iq_event.stanza) tube = xpath.queryForNodes('/iq//si/tube[@xmlns="%s"]' % ns.TUBES, iq_event.stanza) assert len(tube) == 1 handle, access, conn_id = conn_event.args assert handle == bob_handle use_tube(q, bytestream, protocol, conn_id) # offer a stream tube to another room (new API) address = t.create_server(q, address_type, block_reading=True) request = { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, cs.TARGET_ID: "*****@*****.**", cs.STREAM_TUBE_SERVICE: "newecho", } _, _, new_tube_path, new_tube_props = join_muc(q, bus, conn, stream, "*****@*****.**", request) # first text and tubes channels are announced event = q.expect("dbus-signal", signal="NewChannels") channels = event.args[0] assert len(channels) == 2 path1, prop1 = channels[0] path2, prop2 = channels[1] assert sorted([prop1[cs.CHANNEL_TYPE], prop2[cs.CHANNEL_TYPE]]) == [cs.CHANNEL_TYPE_TEXT, cs.CHANNEL_TYPE_TUBES] got_text, got_tubes = False, False for path, props in channels: if props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_TEXT: got_text = True elif props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_TUBES: got_tubes = True else: assert False assert props[cs.INITIATOR_HANDLE] == self_handle assert props[cs.INITIATOR_ID] == self_name assert cs.CHANNEL_IFACE_GROUP in props[cs.INTERFACES] assert props[cs.TARGET_ID] == "*****@*****.**" assert props[cs.REQUESTED] == False assert (got_text, got_tubes) == (True, True) # now the tube channel is announced # FIXME: in this case, all channels should probably be announced together event = q.expect("dbus-signal", signal="NewChannels") channels = event.args[0] assert len(channels) == 1 path, prop = channels[0] assert prop[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_STREAM_TUBE assert prop[cs.INITIATOR_ID] == "[email protected]/test" assert prop[cs.REQUESTED] == True assert prop[cs.TARGET_HANDLE_TYPE] == cs.HT_ROOM assert prop[cs.TARGET_ID] == "*****@*****.**" assert prop[cs.STREAM_TUBE_SERVICE] == "newecho" # check that the tube channel is in the channels list all_channels = conn.Get(cs.CONN_IFACE_REQUESTS, "Channels", dbus_interface=cs.PROPERTIES_IFACE, byte_arrays=True) assertContains((path, prop), all_channels) tube_chan = bus.get_object(conn.bus_name, path) stream_tube_iface = dbus.Interface(tube_chan, cs.CHANNEL_TYPE_STREAM_TUBE) chan_iface = dbus.Interface(tube_chan, cs.CHANNEL) tube_props = tube_chan.GetAll(cs.CHANNEL_IFACE_TUBE, dbus_interface=cs.PROPERTIES_IFACE) assert tube_props["State"] == cs.TUBE_CHANNEL_STATE_NOT_OFFERED # offer the tube call_async(q, stream_tube_iface, "Offer", address_type, address, access_control, {"foo": "bar"}) new_tube_event, stream_event, _, status_event = q.expect_many( EventPattern("dbus-signal", signal="NewTube"), EventPattern("stream-presence", to="[email protected]/test"), EventPattern("dbus-return", method="Offer"), EventPattern("dbus-signal", signal="TubeChannelStateChanged", args=[cs.TUBE_CHANNEL_STATE_OPEN]), ) tube_self_handle = tube_chan.GetSelfHandle(dbus_interface=cs.CHANNEL_IFACE_GROUP) assert conn.InspectHandles(cs.HT_CONTACT, [tube_self_handle]) == ["[email protected]/test"] # handle new_tube_event stream_tube_id = new_tube_event.args[0] assert new_tube_event.args[2] == 1 # Stream assert new_tube_event.args[3] == "newecho" assert new_tube_event.args[4] == {"foo": "bar"} assert new_tube_event.args[5] == cs.TUBE_CHANNEL_STATE_OPEN presence = stream_event.stanza x_nodes = xpath.queryForNodes('/presence/x[@xmlns="http://jabber.org/' 'protocol/muc"]', presence) assert x_nodes is not None assert len(x_nodes) == 1 tubes_nodes = xpath.queryForNodes('/presence/tubes[@xmlns="%s"]' % ns.TUBES, presence) assert tubes_nodes is not None assert len(tubes_nodes) == 1 tube_nodes = xpath.queryForNodes("/tubes/tube", tubes_nodes[0]) assert tube_nodes is not None assert len(tube_nodes) == 1 for tube in tube_nodes: assert tube["type"] == "stream" assert not tube.hasAttribute("initiator") assert tube["service"] == "newecho" assert not tube.hasAttribute("stream-id") assert not tube.hasAttribute("dbus-name") assert tube["id"] == str(stream_tube_id) params = {} parameter_nodes = xpath.queryForNodes("/tube/parameters/parameter", tube) for node in parameter_nodes: assert node["name"] not in params params[node["name"]] = (node["type"], str(node)) assert params == {"foo": ("str", "bar")} bob_handle = conn.RequestHandles(cs.HT_CONTACT, ["[email protected]/bob"])[0] bytestream = connect_to_tube(stream, q, bytestream_cls, "*****@*****.**", stream_tube_id) iq_event, socket_event, conn_event = q.expect_many( EventPattern("stream-iq", iq_type="result"), EventPattern("socket-connected"), EventPattern("dbus-signal", signal="NewRemoteConnection", interface=cs.CHANNEL_TYPE_STREAM_TUBE), ) handle, access, conn_id = conn_event.args assert handle == bob_handle protocol = socket_event.protocol # start to read from the transport so we can read the control byte protocol.transport.startReading() t.check_new_connection_access(q, access_control, access, protocol) # handle iq_event bytestream.check_si_reply(iq_event.stanza) tube = xpath.queryForNodes('/iq//si/tube[@xmlns="%s"]' % ns.TUBES, iq_event.stanza) assert len(tube) == 1 use_tube(q, bytestream, protocol, conn_id) chan_iface.Close() q.expect_many(EventPattern("dbus-signal", signal="Closed"), EventPattern("dbus-signal", signal="ChannelClosed"))
def test(q, bus, conn, stream, bytestream_cls, address_type, access_control, access_control_param): if bytestream_cls in [BytestreamS5BRelay, BytestreamS5BRelayBugged]: # disable SOCKS5 relay tests because proxy can't be used with muc # contacts atm return iq_event = q.expect('stream-iq', to=None, query_ns='vcard-temp', query_name='vCard') acknowledge_iq(stream, iq_event.stanza) t.check_conn_properties(q, conn) bob_handle = conn.get_contact_handle_sync('[email protected]/bob') address = t.create_server(q, address_type) def new_chan_predicate(e): types = [] for _, props in e.args[0]: types.append(props[cs.CHANNEL_TYPE]) return cs.CHANNEL_TYPE_STREAM_TUBE in types def find_stream_tube(channels): for path, props in channels: if props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_STREAM_TUBE: return path, props return None, None # offer a stream tube to another room (new API) address = t.create_server(q, address_type, block_reading=True) request = { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, cs.TARGET_ID: '*****@*****.**', cs.STREAM_TUBE_SERVICE: 'newecho', } _, new_tube_path, new_tube_props = \ join_muc(q, bus, conn, stream, '*****@*****.**', request) e = q.expect('dbus-signal', signal='NewChannels', predicate=new_chan_predicate) path, prop = find_stream_tube(e.args[0]) assert prop[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_STREAM_TUBE assert prop[cs.INITIATOR_ID] == '[email protected]/test' assert prop[cs.REQUESTED] == True assert prop[cs.TARGET_HANDLE_TYPE] == cs.HT_ROOM assert prop[cs.TARGET_ID] == '*****@*****.**' assert prop[cs.STREAM_TUBE_SERVICE] == 'newecho' # check that the tube channel is in the channels list all_channels = conn.Get(cs.CONN_IFACE_REQUESTS, 'Channels', dbus_interface=cs.PROPERTIES_IFACE, byte_arrays=True) assertContains((path, prop), all_channels) tube_chan = wrap_channel(bus.get_object(conn.bus_name, path), 'StreamTube') tube_props = tube_chan.GetAll(cs.CHANNEL_IFACE_TUBE, dbus_interface=cs.PROPERTIES_IFACE) assert tube_props['State'] == cs.TUBE_CHANNEL_STATE_NOT_OFFERED # offer the tube call_async(q, tube_chan.StreamTube, 'Offer', address_type, address, access_control, {'foo': 'bar'}) stream_event, _, status_event = q.expect_many( EventPattern('stream-presence', to='[email protected]/test', predicate=lambda e: t.presence_contains_tube(e)), EventPattern('dbus-return', method='Offer'), EventPattern('dbus-signal', signal='TubeChannelStateChanged', args=[cs.TUBE_CHANNEL_STATE_OPEN])) tube_self_handle = tube_chan.Properties.Get(cs.CHANNEL_IFACE_GROUP, 'SelfHandle') assert conn.inspect_contact_sync(tube_self_handle) == '[email protected]/test' presence = stream_event.stanza tubes_nodes = xpath.queryForNodes('/presence/tubes[@xmlns="%s"]' % ns.TUBES, presence) assert tubes_nodes is not None assert len(tubes_nodes) == 1 stream_tube_id = 666 tube_nodes = xpath.queryForNodes('/tubes/tube', tubes_nodes[0]) assert tube_nodes is not None assert len(tube_nodes) == 1 for tube in tube_nodes: assert tube['type'] == 'stream' assert not tube.hasAttribute('initiator') assert tube['service'] == 'newecho' assert not tube.hasAttribute('stream-id') assert not tube.hasAttribute('dbus-name') stream_tube_id = int(tube['id']) params = {} parameter_nodes = xpath.queryForNodes('/tube/parameters/parameter', tube) for node in parameter_nodes: assert node['name'] not in params params[node['name']] = (node['type'], str(node)) assert params == {'foo': ('str', 'bar')} bob_handle = conn.get_contact_handle_sync('[email protected]/bob') bytestream = connect_to_tube(stream, q, bytestream_cls, '*****@*****.**', stream_tube_id) iq_event, socket_event, conn_event = q.expect_many( EventPattern('stream-iq', iq_type='result'), EventPattern('socket-connected'), EventPattern('dbus-signal', signal='NewRemoteConnection', interface=cs.CHANNEL_TYPE_STREAM_TUBE)) handle, access, conn_id = conn_event.args assert handle == bob_handle protocol = socket_event.protocol # start to read from the transport so we can read the control byte protocol.transport.startReading() t.check_new_connection_access(q, access_control, access, protocol) # handle iq_event bytestream.check_si_reply(iq_event.stanza) tube = xpath.queryForNodes('/iq//si/tube[@xmlns="%s"]' % ns.TUBES, iq_event.stanza) assert len(tube) == 1 use_tube(q, bytestream, protocol, conn_id) tube_chan.Channel.Close() q.expect_many( EventPattern('dbus-signal', signal='Closed'), EventPattern('dbus-signal', signal='ChannelClosed')) t.cleanup()
def test(q, bus, conn, stream, bytestream_cls, address_type, access_control, access_control_param): address1 = t.set_up_echo(q, address_type, True, streamfile='stream') address2 = t.set_up_echo(q, address_type, True, streamfile='stream2') t.check_conn_properties(q, conn) vcard_event, roster_event = q.expect_many( EventPattern('stream-iq', to=None, query_ns='vcard-temp', query_name='vCard'), EventPattern('stream-iq', query_ns=ns.ROSTER)) self_handle = conn.Properties.Get(cs.CONN, "SelfHandle") acknowledge_iq(stream, vcard_event.stanza) roster = roster_event.stanza roster['type'] = 'result' item = roster_event.query.addElement('item') item['jid'] = 'bob@localhost' # Bob can do tubes item['subscription'] = 'both' stream.send(roster) bob_full_jid = 'bob@localhost/Bob' self_full_jid = 'test@localhost/Resource' # Send Bob presence and his tube caps presence = domish.Element(('jabber:client', 'presence')) presence['from'] = bob_full_jid presence['to'] = self_full_jid c = presence.addElement('c') c['xmlns'] = 'http://jabber.org/protocol/caps' c['node'] = 'http://example.com/ICantBelieveItsNotTelepathy' c['ver'] = '1.2.3' stream.send(presence) event = q.expect('stream-iq', iq_type='get', query_ns='http://jabber.org/protocol/disco#info', to=bob_full_jid) assert event.query['node'] == \ 'http://example.com/ICantBelieveItsNotTelepathy#1.2.3' result = make_result_iq(stream, event.stanza) query = result.firstChildElement() feature = query.addElement('feature') feature['var'] = ns.TUBES stream.send(result) # A tube request can be done only if the contact has tube capabilities # Ensure that Bob's caps have been received sync_stream(q, stream) # Also ensure that all the new contact list channels have been announced, # so that the NewChannel(s) signals we look for after calling # RequestChannel are the ones we wanted. sync_dbus(bus, q, conn) # Test tubes with Bob. Bob has tube capabilities. bob_handle = conn.get_contact_handle_sync('bob@localhost') # Try CreateChannel with correct properties # Gabble must succeed call_async( q, conn.Requests, 'CreateChannel', { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT, cs.TARGET_HANDLE: bob_handle, cs.STREAM_TUBE_SERVICE: "newecho", }) def find_stream_tube(channels): for path, props in channels: if props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_STREAM_TUBE: return path, props return None, None def new_chan_predicate(e): path, _ = find_stream_tube(e.args[0]) return path is not None ret, new_sig = q.expect_many( EventPattern('dbus-return', method='CreateChannel'), EventPattern('dbus-signal', signal='NewChannels', predicate=new_chan_predicate), ) new_chan_path = ret.value[0] new_chan_prop_asv = ret.value[1] # State and Parameters are mutables so not announced assert cs.TUBE_STATE not in new_chan_prop_asv assert cs.TUBE_PARAMETERS not in new_chan_prop_asv assert new_chan_path.find("StreamTube") != -1, new_chan_path assert new_chan_path.find("SITubesChannel") == -1, new_chan_path new_tube_chan = bus.get_object(conn.bus_name, new_chan_path) new_tube_iface = dbus.Interface(new_tube_chan, cs.CHANNEL_TYPE_STREAM_TUBE) # check State and Parameters new_tube_props = new_tube_chan.GetAll(cs.CHANNEL_IFACE_TUBE, dbus_interface=cs.PROPERTIES_IFACE) # the tube created using the new API is in the "not offered" state assert new_tube_props['State'] == cs.TUBE_CHANNEL_STATE_NOT_OFFERED _, stream_tube_channel_properties = find_stream_tube(new_sig.args[0]) assert cs.TUBE_STATE not in stream_tube_channel_properties assert cs.TUBE_PARAMETERS not in stream_tube_channel_properties # Offer the first tube created call_async(q, new_tube_iface, 'Offer', address_type, address2, access_control, new_sample_parameters) msg_event, state_event = q.expect_many( EventPattern('stream-message'), EventPattern('dbus-signal', signal='TubeChannelStateChanged')) assert state_event.args[0] == cs.TUBE_CHANNEL_STATE_REMOTE_PENDING message = msg_event.stanza assert message['to'] == bob_full_jid tube_nodes = xpath.queryForNodes('/message/tube[@xmlns="%s"]' % ns.TUBES, message) assert tube_nodes is not None assert len(tube_nodes) == 1 tube = tube_nodes[0] assert tube['service'] == 'newecho' assert tube['type'] == 'stream' assert not tube.hasAttribute('initiator') stream_tube_id = long(tube['id']) params = {} parameter_nodes = xpath.queryForNodes('/tube/parameters/parameter', tube) for node in parameter_nodes: assert node['name'] not in params params[node['name']] = (node['type'], str(node)) assert params == { 'ay': ('bytes', 'bmV3aGVsbG8='), 's': ('str', 'newhello'), 'i': ('int', '-123'), 'u': ('uint', '123'), } # The new tube has been offered, the parameters cannot be changed anymore # We need to use call_async to check the error tube_prop_iface = dbus.Interface(new_tube_chan, cs.PROPERTIES_IFACE) call_async(q, tube_prop_iface, 'Set', cs.CHANNEL_IFACE_TUBE, 'Parameters', dbus.Dictionary({dbus.String(u'foo2'): dbus.String(u'bar2')}, signature=dbus.Signature('sv')), dbus_interface=cs.PROPERTIES_IFACE) set_error = q.expect('dbus-error') # check it is *not* correctly changed new_tube_props = new_tube_chan.GetAll(cs.CHANNEL_IFACE_TUBE, dbus_interface=cs.PROPERTIES_IFACE, byte_arrays=True) assert new_tube_props.get("Parameters") == new_sample_parameters, \ new_tube_props.get("Parameters") # The CM is the server, so fake a client wanting to talk to it # Old API tube bytestream1 = bytestream_cls(stream, q, 'alpha', bob_full_jid, self_full_jid, True) iq, si = bytestream1.create_si_offer(ns.TUBES) stream_node = si.addElement((ns.TUBES, 'stream')) stream_node['tube'] = str(stream_tube_id) stream.send(iq) si_reply_event, _, new_conn_event, socket_event = q.expect_many( EventPattern('stream-iq', iq_type='result'), EventPattern('dbus-signal', signal='TubeChannelStateChanged', args=[cs.TUBE_STATE_OPEN]), EventPattern('dbus-signal', signal='NewRemoteConnection'), EventPattern('socket-connected')) bytestream1.check_si_reply(si_reply_event.stanza) tube = xpath.queryForNodes('/iq/si/tube[@xmlns="%s"]' % ns.TUBES, si_reply_event.stanza) assert len(tube) == 1 handle, access, id = new_conn_event.args assert handle == bob_handle protocol = socket_event.protocol # we don't want to echo the access control byte protocol.echoed = False # start to read from the transport so we can read the control byte protocol.transport.startReading() t.check_new_connection_access(q, access_control, access, protocol) protocol.echoed = True # The CM is the server, so fake a client wanting to talk to it # New API tube bytestream2 = bytestream_cls(stream, q, 'beta', bob_full_jid, self_full_jid, True) iq, si = bytestream2.create_si_offer(ns.TUBES) stream_node = si.addElement((ns.TUBES, 'stream')) stream_node['tube'] = str(stream_tube_id) stream.send(iq) si_reply_event, new_conn_event, socket_event = q.expect_many( EventPattern('stream-iq', iq_type='result'), EventPattern('dbus-signal', signal='NewRemoteConnection'), EventPattern('socket-connected')) bytestream2.check_si_reply(si_reply_event.stanza) tube = xpath.queryForNodes('/iq/si/tube[@xmlns="%s"]' % ns.TUBES, si_reply_event.stanza) assert len(tube) == 1 handle, access, conn_id = new_conn_event.args assert handle == bob_handle protocol = socket_event.protocol # we don't want to echo the access control byte protocol.echoed = False # start to read from the transport so we can read the control byte protocol.transport.startReading() t.check_new_connection_access(q, access_control, access, protocol) protocol.echoed = True # have the fake client open the stream bytestream1.open_bytestream() # have the fake client send us some data data = 'hello, world' bytestream1.send_data(data) binary = bytestream1.get_data(len(data)) assert binary == data, binary # have the fake client open the stream bytestream2.open_bytestream() # have the fake client send us some data data = 'hello, new world' bytestream2.send_data(data) binary = bytestream2.get_data(len(data)) assert binary == data, binary # peer closes the bytestream bytestream2.close() e = q.expect('dbus-signal', signal='ConnectionClosed') assertEquals(conn_id, e.args[0]) assertEquals(cs.CONNECTION_LOST, e.args[1]) t.cleanup()
def test(q, bus, conn, stream, bytestream_cls, address_type, access_control, access_control_param): address1 = t.set_up_echo(q, address_type, True, streamfile='stream') address2 = t.set_up_echo(q, address_type, True, streamfile='stream2') t.check_conn_properties(q, conn) vcard_event, roster_event = q.expect_many( EventPattern('stream-iq', to=None, query_ns='vcard-temp', query_name='vCard'), EventPattern('stream-iq', query_ns=ns.ROSTER)) self_handle = conn.GetSelfHandle() acknowledge_iq(stream, vcard_event.stanza) roster = roster_event.stanza roster['type'] = 'result' item = roster_event.query.addElement('item') item['jid'] = 'bob@localhost' # Bob can do tubes item['subscription'] = 'both' stream.send(roster) bob_full_jid = 'bob@localhost/Bob' self_full_jid = 'test@localhost/Resource' # Send Bob presence and his tube caps presence = domish.Element(('jabber:client', 'presence')) presence['from'] = bob_full_jid presence['to'] = self_full_jid c = presence.addElement('c') c['xmlns'] = 'http://jabber.org/protocol/caps' c['node'] = 'http://example.com/ICantBelieveItsNotTelepathy' c['ver'] = '1.2.3' stream.send(presence) event = q.expect('stream-iq', iq_type='get', query_ns='http://jabber.org/protocol/disco#info', to=bob_full_jid) assert event.query['node'] == \ 'http://example.com/ICantBelieveItsNotTelepathy#1.2.3' result = make_result_iq(stream, event.stanza) query = result.firstChildElement() feature = query.addElement('feature') feature['var'] = ns.TUBES stream.send(result) # A tube request can be done only if the contact has tube capabilities # Ensure that Bob's caps have been received sync_stream(q, stream) # Also ensure that all the new contact list channels have been announced, # so that the NewChannel(s) signals we look for after calling # RequestChannel are the ones we wanted. sync_dbus(bus, q, conn) # Test tubes with Bob. Bob has tube capabilities. bob_handle = conn.RequestHandles(1, ['bob@localhost'])[0] # old tubes API call_async(q, conn, 'RequestChannel', cs.CHANNEL_TYPE_TUBES, cs.HT_CONTACT, bob_handle, True) ret, old_sig, new_sig = q.expect_many( EventPattern('dbus-return', method='RequestChannel'), EventPattern('dbus-signal', signal='NewChannel'), EventPattern('dbus-signal', signal='NewChannels'), ) assert len(ret.value) == 1 chan_path = ret.value[0] t.check_NewChannel_signal(old_sig.args, cs.CHANNEL_TYPE_TUBES, chan_path, bob_handle, True) t.check_NewChannels_signal(conn, new_sig.args, cs.CHANNEL_TYPE_TUBES, chan_path, bob_handle, 'bob@localhost', self_handle) old_tubes_channel_properties = new_sig.args[0][0] t.check_conn_properties(q, conn, [old_tubes_channel_properties]) # Try CreateChannel with correct properties # Gabble must succeed call_async(q, conn.Requests, 'CreateChannel', {cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT, cs.TARGET_HANDLE: bob_handle, cs.STREAM_TUBE_SERVICE: "newecho", }) # the NewTube signal (old API) is not fired now as the tube wasn't offered # yet ret, old_sig, new_sig = q.expect_many( EventPattern('dbus-return', method='CreateChannel'), EventPattern('dbus-signal', signal='NewChannel'), EventPattern('dbus-signal', signal='NewChannels'), ) assert len(ret.value) == 2 # CreateChannel returns 2 values: o, a{sv} new_chan_path = ret.value[0] new_chan_prop_asv = ret.value[1] # State and Parameters are mutables so not announced assert cs.TUBE_STATE not in new_chan_prop_asv assert cs.TUBE_PARAMETERS not in new_chan_prop_asv assert new_chan_path.find("StreamTube") != -1, new_chan_path assert new_chan_path.find("SITubesChannel") == -1, new_chan_path # The path of the Channel.Type.Tubes object MUST be different to the path # of the Channel.Type.StreamTube object ! assert chan_path != new_chan_path new_tube_chan = bus.get_object(conn.bus_name, new_chan_path) new_tube_iface = dbus.Interface(new_tube_chan, cs.CHANNEL_TYPE_STREAM_TUBE) # check State and Parameters new_tube_props = new_tube_chan.GetAll(cs.CHANNEL_IFACE_TUBE, dbus_interface=cs.PROPERTIES_IFACE) # the tube created using the new API is in the "not offered" state assert new_tube_props['State'] == cs.TUBE_CHANNEL_STATE_NOT_OFFERED t.check_NewChannel_signal(old_sig.args, cs.CHANNEL_TYPE_STREAM_TUBE, new_chan_path, bob_handle, True) t.check_NewChannels_signal(conn, new_sig.args, cs.CHANNEL_TYPE_STREAM_TUBE, new_chan_path, bob_handle, 'bob@localhost', self_handle) stream_tube_channel_properties = new_sig.args[0][0] assert cs.TUBE_STATE not in stream_tube_channel_properties assert cs.TUBE_PARAMETERS not in stream_tube_channel_properties t.check_conn_properties(q, conn, [old_tubes_channel_properties, stream_tube_channel_properties]) tubes_chan = bus.get_object(conn.bus_name, chan_path) tubes_iface = dbus.Interface(tubes_chan, cs.CHANNEL_TYPE_TUBES) t.check_channel_properties(q, bus, conn, tubes_chan, cs.CHANNEL_TYPE_TUBES, bob_handle, "bob@localhost") # Create another tube using old API call_async(q, tubes_iface, 'OfferStreamTube', 'echo', sample_parameters, address_type, address1, access_control, access_control_param) event, return_event, new_chan, new_chans = q.expect_many( EventPattern('stream-message'), EventPattern('dbus-return', method='OfferStreamTube'), EventPattern('dbus-signal', signal='NewChannel'), EventPattern('dbus-signal', signal='NewChannels')) message = event.stanza assert message['to'] == bob_full_jid tube_nodes = xpath.queryForNodes('/message/tube[@xmlns="%s"]' % ns.TUBES, message) assert tube_nodes is not None assert len(tube_nodes) == 1 tube = tube_nodes[0] assert tube['service'] == 'echo' assert tube['type'] == 'stream' assert not tube.hasAttribute('initiator') stream_tube_id = long(tube['id']) params = {} parameter_nodes = xpath.queryForNodes('/tube/parameters/parameter', tube) for node in parameter_nodes: assert node['name'] not in params params[node['name']] = (node['type'], str(node)) assert params == {'ay': ('bytes', 'aGVsbG8='), 's': ('str', 'hello'), 'i': ('int', '-123'), 'u': ('uint', '123'), } # the tube channel (new API) is announced t.check_NewChannel_signal(new_chan.args, cs.CHANNEL_TYPE_STREAM_TUBE, None, bob_handle, False) t.check_NewChannels_signal(conn, new_chans.args, cs.CHANNEL_TYPE_STREAM_TUBE, new_chan.args[0], bob_handle, "bob@localhost", self_handle) props = new_chans.args[0][0][1] assert cs.TUBE_STATE not in props assert cs.TUBE_PARAMETERS not in props # We offered a tube using the old tube API and created one with the new # API, so there are 2 tubes. Check the new tube API works assert len(filter(lambda x: x[1] == cs.CHANNEL_TYPE_TUBES, conn.ListChannels())) == 1 channels = filter(lambda x: x[1] == cs.CHANNEL_TYPE_STREAM_TUBE and x[0] == new_chan_path, conn.ListChannels()) assert len(channels) == 1 assert new_chan_path == channels[0][0] old_tube_chan = bus.get_object(conn.bus_name, new_chan.args[0]) tube_basic_props = old_tube_chan.GetAll(cs.CHANNEL, dbus_interface=cs.PROPERTIES_IFACE) assert tube_basic_props.get("InitiatorHandle") == self_handle stream_tube_props = old_tube_chan.GetAll(cs.CHANNEL_TYPE_STREAM_TUBE, dbus_interface=cs.PROPERTIES_IFACE) assert stream_tube_props.get("Service") == "echo", stream_tube_props old_tube_props = old_tube_chan.GetAll(cs.CHANNEL_IFACE_TUBE, dbus_interface=cs.PROPERTIES_IFACE, byte_arrays=True) assert old_tube_props.get("Parameters") == dbus.Dictionary(sample_parameters) # Tube have been created using the old API and so is already offered assert old_tube_props['State'] == cs.TUBE_CHANNEL_STATE_REMOTE_PENDING t.check_channel_properties(q, bus, conn, tubes_chan, cs.CHANNEL_TYPE_TUBES, bob_handle, "bob@localhost") t.check_channel_properties(q, bus, conn, old_tube_chan, cs.CHANNEL_TYPE_STREAM_TUBE, bob_handle, "bob@localhost", cs.TUBE_CHANNEL_STATE_REMOTE_PENDING) # Offer the first tube created (new API) call_async(q, new_tube_iface, 'Offer', address_type, address2, access_control, new_sample_parameters) msg_event, new_tube_sig, state_event = q.expect_many( EventPattern('stream-message'), EventPattern('dbus-signal', signal='NewTube'), EventPattern('dbus-signal', signal='TubeChannelStateChanged')) assert state_event.args[0] == cs.TUBE_CHANNEL_STATE_REMOTE_PENDING message = msg_event.stanza assert message['to'] == bob_full_jid tube_nodes = xpath.queryForNodes('/message/tube[@xmlns="%s"]' % ns.TUBES, message) assert tube_nodes is not None assert len(tube_nodes) == 1 tube = tube_nodes[0] assert tube['service'] == 'newecho' assert tube['type'] == 'stream' assert not tube.hasAttribute('initiator') new_stream_tube_id = long(tube['id']) params = {} parameter_nodes = xpath.queryForNodes('/tube/parameters/parameter', tube) for node in parameter_nodes: assert node['name'] not in params params[node['name']] = (node['type'], str(node)) assert params == {'ay': ('bytes', 'bmV3aGVsbG8='), 's': ('str', 'newhello'), 'i': ('int', '-123'), 'u': ('uint', '123'), } # check NewTube signal (old API) id, initiator_handle, type, service, params, state = new_tube_sig.args assert initiator_handle == self_handle assert type == 1 # stream assert service == 'newecho' assert params == new_sample_parameters assert state == 1 # remote pending # The new tube has been offered, the parameters cannot be changed anymore # We need to use call_async to check the error tube_prop_iface = dbus.Interface(old_tube_chan, cs.PROPERTIES_IFACE) call_async(q, tube_prop_iface, 'Set', cs.CHANNEL_IFACE_TUBE, 'Parameters', dbus.Dictionary( {dbus.String(u'foo2'): dbus.String(u'bar2')}, signature=dbus.Signature('sv')), dbus_interface=cs.PROPERTIES_IFACE) set_error = q.expect('dbus-error') # check it is *not* correctly changed new_tube_props = new_tube_chan.GetAll(cs.CHANNEL_IFACE_TUBE, dbus_interface=cs.PROPERTIES_IFACE, byte_arrays=True) assert new_tube_props.get("Parameters") == new_sample_parameters, \ new_tube_props.get("Parameters") # The CM is the server, so fake a client wanting to talk to it # Old API tube bytestream1 = bytestream_cls(stream, q, 'alpha', bob_full_jid, self_full_jid, True) iq, si = bytestream1.create_si_offer(ns.TUBES) stream_node = si.addElement((ns.TUBES, 'stream')) stream_node['tube'] = str(stream_tube_id) stream.send(iq) si_reply_event, _, _, new_conn_event, socket_event = q.expect_many( EventPattern('stream-iq', iq_type='result'), EventPattern('dbus-signal', signal='TubeStateChanged', args=[stream_tube_id, cs.TUBE_STATE_OPEN]), EventPattern('dbus-signal', signal='StreamTubeNewConnection', args=[stream_tube_id, bob_handle]), EventPattern('dbus-signal', signal='NewRemoteConnection'), EventPattern('socket-connected')) bytestream1.check_si_reply(si_reply_event.stanza) tube = xpath.queryForNodes('/iq/si/tube[@xmlns="%s"]' % ns.TUBES, si_reply_event.stanza) assert len(tube) == 1 handle, access, id = new_conn_event.args assert handle == bob_handle protocol = socket_event.protocol # we don't want to echo the access control byte protocol.echoed = False # start to read from the transport so we can read the control byte protocol.transport.startReading() t.check_new_connection_access(q, access_control, access, protocol) protocol.echoed = True expected_tube = (stream_tube_id, self_handle, cs.TUBE_TYPE_STREAM, 'echo', sample_parameters, cs.TUBE_STATE_OPEN) tubes = tubes_iface.ListTubes(byte_arrays=True) t.check_tube_in_tubes(expected_tube, tubes) # The CM is the server, so fake a client wanting to talk to it # New API tube bytestream2 = bytestream_cls(stream, q, 'beta', bob_full_jid, self_full_jid, True) iq, si = bytestream2.create_si_offer(ns.TUBES) stream_node = si.addElement((ns.TUBES, 'stream')) stream_node['tube'] = str(new_stream_tube_id) stream.send(iq) si_reply_event, _, new_conn_event, socket_event = q.expect_many( EventPattern('stream-iq', iq_type='result'), EventPattern('dbus-signal', signal='TubeChannelStateChanged', args=[cs.TUBE_STATE_OPEN]), EventPattern('dbus-signal', signal='NewRemoteConnection'), EventPattern('socket-connected')) bytestream2.check_si_reply(si_reply_event.stanza) tube = xpath.queryForNodes('/iq/si/tube[@xmlns="%s"]' % ns.TUBES, si_reply_event.stanza) assert len(tube) == 1 handle, access, conn_id = new_conn_event.args assert handle == bob_handle protocol = socket_event.protocol # we don't want to echo the access control byte protocol.echoed = False # start to read from the transport so we can read the control byte protocol.transport.startReading() t.check_new_connection_access(q, access_control, access, protocol) protocol.echoed = True expected_tube = (new_stream_tube_id, self_handle, cs.TUBE_TYPE_STREAM, 'newecho', new_sample_parameters, cs.TUBE_STATE_OPEN) t.check_tube_in_tubes (expected_tube, tubes_iface.ListTubes(byte_arrays=True)) # have the fake client open the stream bytestream1.open_bytestream() # have the fake client send us some data data = 'hello, world' bytestream1.send_data(data) binary = bytestream1.get_data(len(data)) assert binary == data, binary # have the fake client open the stream bytestream2.open_bytestream() # have the fake client send us some data data = 'hello, new world' bytestream2.send_data(data) binary = bytestream2.get_data(len(data)) assert binary == data, binary # peer closes the bytestream bytestream2.close() e = q.expect('dbus-signal', signal='ConnectionClosed') assertEquals(conn_id, e.args[0]) assertEquals(cs.CONNECTION_LOST, e.args[1]) t.cleanup()
def test(q, bus, conn, stream, access_control): iq_event = q.expect('stream-iq', to=None, query_ns='vcard-temp', query_name='vCard') acknowledge_iq(stream, iq_event.stanza) # check if we can request muc D-Bus tube t.check_conn_properties(q, conn) self_handle = conn.Properties.Get(cs.CONN, "SelfHandle") self_name = conn.inspect_contact_sync(self_handle) # offer a D-Bus tube to another room using new API muc = '*****@*****.**' request = { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_DBUS_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, cs.TARGET_ID: '*****@*****.**', cs.DBUS_TUBE_SERVICE_NAME: 'com.example.TestCase', } join_muc(q, bus, conn, stream, muc, request=request) exv = q.expect('dbus-signal', signal='NewChannels') channels = exv.args[0] assert len(channels) == 1 path, prop = channels[0] assert prop[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_DBUS_TUBE assert prop[cs.INITIATOR_ID] == '[email protected]/test' assert prop[cs.REQUESTED] == True assert prop[cs.TARGET_HANDLE_TYPE] == cs.HT_ROOM assert prop[cs.TARGET_ID] == '*****@*****.**' assert prop[cs.DBUS_TUBE_SERVICE_NAME] == 'com.example.TestCase' assert prop[cs.DBUS_TUBE_SUPPORTED_ACCESS_CONTROLS] == [ cs.SOCKET_ACCESS_CONTROL_CREDENTIALS, cs.SOCKET_ACCESS_CONTROL_LOCALHOST ] # check that the tube channel is in the channels list all_channels = conn.Get(cs.CONN_IFACE_REQUESTS, 'Channels', dbus_interface=cs.PROPERTIES_IFACE, byte_arrays=True) assertContains((path, prop), all_channels) tube_chan = wrap_channel(bus.get_object(conn.bus_name, path), 'DBusTube') tube_props = tube_chan.Properties.GetAll(cs.CHANNEL_IFACE_TUBE, byte_arrays=True) assert tube_props['State'] == cs.TUBE_CHANNEL_STATE_NOT_OFFERED # try to offer using a wrong access control try: tube_chan.DBusTube.Offer(sample_parameters, cs.SOCKET_ACCESS_CONTROL_PORT) except dbus.DBusException as e: assertEquals(e.get_dbus_name(), cs.INVALID_ARGUMENT) else: assert False # offer the tube call_async(q, tube_chan.DBusTube, 'Offer', sample_parameters, access_control) presence_event, return_event, status_event, dbus_changed_event = q.expect_many( EventPattern('stream-presence', to='[email protected]/test', predicate=lambda e: t.presence_contains_tube(e)), EventPattern('dbus-return', method='Offer'), EventPattern('dbus-signal', signal='TubeChannelStateChanged', args=[cs.TUBE_CHANNEL_STATE_OPEN]), EventPattern('dbus-signal', signal='DBusNamesChanged', interface=cs.CHANNEL_TYPE_DBUS_TUBE)) tube_self_handle = tube_chan.Properties.Get(cs.CHANNEL_IFACE_GROUP, 'SelfHandle') assert tube_self_handle != 0 # handle presence_event # We announce our newly created tube in our muc presence presence = presence_event.stanza dbus_stream_id, my_bus_name, dbus_tube_id = check_tube_in_presence( presence, '[email protected]/test') # handle dbus_changed_event added, removed = dbus_changed_event.args assert added == {tube_self_handle: my_bus_name} assert removed == [] dbus_tube_adr = return_event.value[0] bob_bus_name = ':2.Ym9i' bob_handle = conn.get_contact_handle_sync('[email protected]/bob') def bob_in_tube(): presence = elem('presence', from_='[email protected]/bob', to='*****@*****.**')( elem('x', xmlns=ns.MUC_USER), elem('tubes', xmlns=ns.TUBES)( elem('tube', type='dbus', initiator='[email protected]/test', service='com.example.TestCase', id=str(dbus_tube_id))(elem('parameters')( elem('parameter', name='ay', type='bytes')(u'aGVsbG8='), elem('parameter', name='s', type='str')(u'hello'), elem('parameter', name='i', type='int')(u'-123'), elem('parameter', name='u', type='uint')(u'123'))))) # have to add stream-id and dbus-name attributes manually as we can't use # keyword with '-'... tube_node = xpath.queryForNodes('/presence/tubes/tube', presence)[0] tube_node['stream-id'] = dbus_stream_id tube_node['dbus-name'] = bob_bus_name stream.send(presence) # Bob joins the tube bob_in_tube() dbus_changed_event = q.expect('dbus-signal', signal='DBusNamesChanged', interface=cs.CHANNEL_TYPE_DBUS_TUBE) added, removed = dbus_changed_event.args assert added == {bob_handle: bob_bus_name} assert removed == [] tube = Connection(dbus_tube_adr) fire_signal_on_tube(q, tube, '*****@*****.**', dbus_stream_id, my_bus_name) names = tube_chan.Get(cs.CHANNEL_TYPE_DBUS_TUBE, 'DBusNames', dbus_interface=cs.PROPERTIES_IFACE) assert names == {tube_self_handle: my_bus_name, bob_handle: bob_bus_name} # Bob leave the tube presence = elem('presence', from_='[email protected]/bob', to='*****@*****.**')(elem('x', xmlns=ns.MUC_USER), elem('tubes', xmlns=ns.TUBES)) stream.send(presence) dbus_changed_event = q.expect('dbus-signal', signal='DBusNamesChanged', interface=cs.CHANNEL_TYPE_DBUS_TUBE) added, removed = dbus_changed_event.args assert added == {} assert removed == [bob_handle] names = tube_chan.Get(cs.CHANNEL_TYPE_DBUS_TUBE, 'DBusNames', dbus_interface=cs.PROPERTIES_IFACE) assert names == {tube_self_handle: my_bus_name} tube_chan.Channel.Close() _, _, event = q.expect_many( EventPattern('dbus-signal', signal='Closed'), EventPattern('dbus-signal', signal='ChannelClosed'), EventPattern('stream-presence', to='[email protected]/test', presence_type='unavailable')) # we must echo the MUC presence so the room will actually close # and we should wait to make sure gabble has actually parsed our # echo before trying to rejoin echo_muc_presence(q, stream, event.stanza, 'none', 'participant') sync_stream(q, stream) # rejoin the room call_async( q, conn.Requests, 'CreateChannel', { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT, cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, cs.TARGET_ID: '*****@*****.**' }) q.expect('stream-presence', to='[email protected]/test') # Bob is in the room and in the tube bob_in_tube() # Send presence for own membership of room. stream.send(make_muc_presence('none', 'participant', muc, 'test')) def new_tube(e): path, props = e.args[0][0] return props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_DBUS_TUBE def new_text(e): path, props = e.args[0][0] return props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_TEXT # tube and text is created text_event, tube_event = q.expect_many( EventPattern('dbus-signal', signal='NewChannels', predicate=new_text), EventPattern('dbus-signal', signal='NewChannels', predicate=new_tube)) channels = exv.args[0] tube_path, props = tube_event.args[0][0] assertEquals(cs.CHANNEL_TYPE_DBUS_TUBE, props[cs.CHANNEL_TYPE]) assertEquals('[email protected]/test', props[cs.INITIATOR_ID]) assertEquals(False, props[cs.REQUESTED]) assertEquals(cs.HT_ROOM, props[cs.TARGET_HANDLE_TYPE]) assertEquals('com.example.TestCase', props[cs.DBUS_TUBE_SERVICE_NAME]) _, props = text_event.args[0][0] assertEquals(cs.CHANNEL_TYPE_TEXT, props[cs.CHANNEL_TYPE]) assertEquals(True, props[cs.REQUESTED]) # tube is local-pending tube_chan = bus.get_object(conn.bus_name, tube_path) state = tube_chan.Get(cs.CHANNEL_IFACE_TUBE, 'State', dbus_interface=dbus.PROPERTIES_IFACE) assertEquals(cs.TUBE_STATE_LOCAL_PENDING, state)
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) t.check_conn_properties(q, conn) # Create new style tube channel and make sure that is indeed # returned. muc = '*****@*****.**' call_async(q, conn.Requests, 'CreateChannel', { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_DBUS_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, cs.TARGET_ID: muc, cs.DBUS_TUBE_SERVICE_NAME: 'com.example.LolDongs'}) q.expect('stream-presence', to='%s/test' % muc) stream.send(make_muc_presence('owner', 'moderator', muc, 'bob')) stream.send(make_muc_presence('none', 'participant', muc, 'test')) ret, _, _ = q.expect_many( EventPattern('dbus-return', method='CreateChannel'), EventPattern('dbus-signal', signal='NewChannel'), EventPattern('dbus-signal', signal='NewChannels'), ) _, props = ret.value assertEquals(props[cs.CHANNEL_TYPE], cs.CHANNEL_TYPE_DBUS_TUBE) assertEquals(props[cs.TARGET_HANDLE_TYPE], cs.HT_ROOM) assertEquals(props[cs.TARGET_ID], muc) # Now try joining the text muc before asking for the tube channel. muc = '*****@*****.**' join_muc(q, bus, conn, stream, muc) call_async(q, conn.Requests, 'CreateChannel', { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_DBUS_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, cs.TARGET_ID: muc, cs.DBUS_TUBE_SERVICE_NAME: 'com.example.LolDongs'}) ret, _, _ = q.expect_many( EventPattern('dbus-return', method='CreateChannel'), EventPattern('dbus-signal', signal='NewChannel'), EventPattern('dbus-signal', signal='NewChannels'), ) _, props = ret.value assertEquals(props[cs.CHANNEL_TYPE], cs.CHANNEL_TYPE_DBUS_TUBE) assertEquals(props[cs.TARGET_HANDLE_TYPE], cs.HT_ROOM) assertEquals(props[cs.TARGET_ID], muc) # Now make sure we can get our Tubes channel if we request it. muc = '*****@*****.**' call_async(q, conn.Requests, 'CreateChannel', { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TUBES, cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, cs.TARGET_ID: muc}) q.expect('stream-presence', to='%s/test' % muc) stream.send(make_muc_presence('owner', 'moderator', muc, 'bob')) stream.send(make_muc_presence('none', 'participant', muc, 'test')) ret, _, _ = q.expect_many( EventPattern('dbus-return', method='CreateChannel'), EventPattern('dbus-signal', signal='NewChannel'), EventPattern('dbus-signal', signal='NewChannels'), ) _, props = ret.value assertEquals(props[cs.CHANNEL_TYPE], cs.CHANNEL_TYPE_TUBES) assertEquals(props[cs.TARGET_HANDLE_TYPE], cs.HT_ROOM) assertEquals(props[cs.TARGET_ID], muc)
def test(q, bus, conn, stream, bytestream_cls, access_control): t.check_conn_properties(q, conn) conn.Connect() _, vcard_event, roster_event = q.expect_many( EventPattern('dbus-signal', signal='StatusChanged', args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED]), EventPattern('stream-iq', to=None, query_ns='vcard-temp', query_name='vCard'), EventPattern('stream-iq', query_ns=ns.ROSTER)) self_handle = conn.GetSelfHandle() acknowledge_iq(stream, vcard_event.stanza) roster = roster_event.stanza roster['type'] = 'result' item = roster_event.query.addElement('item') item['jid'] = 'bob@localhost' # Bob can do tubes item['subscription'] = 'both' stream.send(roster) bob_full_jid = 'bob@localhost/Bob' self_full_jid = 'test@localhost/Resource' # Send Bob presence and his tube caps presence = domish.Element(('jabber:client', 'presence')) presence['from'] = bob_full_jid presence['to'] = self_full_jid c = presence.addElement('c') c['xmlns'] = 'http://jabber.org/protocol/caps' c['node'] = 'http://example.com/ICantBelieveItsNotTelepathy' c['ver'] = '1.2.3' stream.send(presence) event = q.expect('stream-iq', iq_type='get', query_ns='http://jabber.org/protocol/disco#info', to=bob_full_jid) result = event.stanza result['type'] = 'result' assert event.query['node'] == \ 'http://example.com/ICantBelieveItsNotTelepathy#1.2.3' feature = event.query.addElement('feature') feature['var'] = ns.TUBES stream.send(result) # A tube request can be done only if the contact has tube capabilities # Ensure that Bob's caps have been received sync_stream(q, stream) # Also ensure that all the new contact list channels have been announced, # so that the NewChannel(s) signals we look for after calling # RequestChannel are the ones we wanted. sync_dbus(bus, q, conn) # let's try to accept a D-Bus tube using the old API bytestream = bytestream_cls(stream, q, 'beta', bob_full_jid, 'test@localhost/Reource', True) contact_offer_dbus_tube(bytestream, '69') # tubes channel is created event = q.expect('dbus-signal', signal='NewChannel') bob_handle = conn.RequestHandles(cs.HT_CONTACT, ['bob@localhost'])[0] t.check_NewChannel_signal(event.args, cs.CHANNEL_TYPE_TUBES, None, bob_handle, False) tubes_chan = bus.get_object(conn.bus_name, event.args[0]) tubes_iface = dbus.Interface(tubes_chan, cs.CHANNEL_TYPE_TUBES) event = q.expect('dbus-signal', signal='NewTube') id = event.args[0] initiator = event.args[1] type = event.args[2] service = event.args[3] parameters = event.args[4] state = event.args[5] assert id == 69 initiator_jid = conn.InspectHandles(1, [initiator])[0] assert initiator_jid == 'bob@localhost' assert type == cs.TUBE_TYPE_DBUS assert service == 'com.example.TestCase2' assert parameters == {'login': '******'} assert state == cs.TUBE_STATE_LOCAL_PENDING # accept the tube (old API) call_async(q, tubes_iface, 'AcceptDBusTube', id) event = q.expect('stream-iq', iq_type='result') bytestream.check_si_reply(event.stanza) tube = xpath.queryForNodes('/iq/si/tube[@xmlns="%s"]' % ns.TUBES, event.stanza) assert len(tube) == 1 # Init the bytestream events, _ = bytestream.open_bytestream([EventPattern('dbus-return', method='AcceptDBusTube')], [EventPattern('dbus-signal', signal='TubeStateChanged', args=[69, 2])]) return_event = events[0] address = return_event.value[0] assert len(address) > 0 # OK, now let's try to accept a D-Bus tube using the new API bytestream = bytestream_cls(stream, q, 'gamma', bob_full_jid, self_full_jid, True) contact_offer_dbus_tube(bytestream, '70') e = q.expect('dbus-signal', signal='NewChannels') channels = e.args[0] assert len(channels) == 1 path, props = channels[0] assert props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_DBUS_TUBE assert props[cs.INITIATOR_HANDLE] == bob_handle assert props[cs.INITIATOR_ID] == 'bob@localhost' assert props[cs.INTERFACES] == [cs.CHANNEL_IFACE_TUBE] assert props[cs.REQUESTED] == False assert props[cs.TARGET_HANDLE] == bob_handle assert props[cs.TARGET_ID] == 'bob@localhost' assert props[cs.DBUS_TUBE_SERVICE_NAME] == 'com.example.TestCase2' assert props[cs.TUBE_PARAMETERS] == {'login': '******'} assert props[cs.DBUS_TUBE_SUPPORTED_ACCESS_CONTROLS] == [cs.SOCKET_ACCESS_CONTROL_CREDENTIALS, cs.SOCKET_ACCESS_CONTROL_LOCALHOST] assert cs.TUBE_STATE not in props tube_chan = bus.get_object(conn.bus_name, path) tube_chan_iface = dbus.Interface(tube_chan, cs.CHANNEL) dbus_tube_iface = dbus.Interface(tube_chan, cs.CHANNEL_TYPE_DBUS_TUBE) status = tube_chan.Get(cs.CHANNEL_IFACE_TUBE, 'State', dbus_interface=cs.PROPERTIES_IFACE) assert status == cs.TUBE_STATE_LOCAL_PENDING # try to accept using a wrong access control try: dbus_tube_iface.Accept(cs.SOCKET_ACCESS_CONTROL_PORT) except dbus.DBusException, e: assertEquals(e.get_dbus_name(), cs.INVALID_ARGUMENT)
def test(q, bus, conn, stream, bytestream_cls, address_type, access_control, access_control_param): if bytestream_cls in [BytestreamS5BRelay, BytestreamS5BRelayBugged]: # disable SOCKS5 relay tests because proxy can't be used with muc # contacts atm return iq_event = q.expect('stream-iq', to=None, query_ns='vcard-temp', query_name='vCard') acknowledge_iq(stream, iq_event.stanza) self_handle = conn.GetSelfHandle() self_name = conn.InspectHandles(cs.HT_CONTACT, [self_handle])[0] t.check_conn_properties(q, conn) room_handle, tubes_chan, tubes_iface = get_muc_tubes_channel(q, bus, conn, stream, '*****@*****.**') tubes_self_handle = tubes_chan.GetSelfHandle(dbus_interface=cs.CHANNEL_IFACE_GROUP) bob_handle = conn.RequestHandles(cs.HT_CONTACT, ['[email protected]/bob'])[0] address = t.create_server(q, address_type) # offer stream tube (old API) using an Unix socket call_async(q, tubes_iface, 'OfferStreamTube', 'echo', sample_parameters, address_type, address, access_control, access_control_param) new_tube_event, stream_event, _, new_channels_event = q.expect_many( EventPattern('dbus-signal', signal='NewTube'), EventPattern('stream-presence', to='[email protected]/test'), EventPattern('dbus-return', method='OfferStreamTube'), EventPattern('dbus-signal', signal='NewChannels')) # handle new_tube_event stream_tube_id = new_tube_event.args[0] assert new_tube_event.args[1] == tubes_self_handle assert new_tube_event.args[2] == 1 # Stream assert new_tube_event.args[3] == 'echo' assert new_tube_event.args[4] == sample_parameters assert new_tube_event.args[5] == cs.TUBE_CHANNEL_STATE_OPEN # handle stream_event # We announce our newly created tube in our muc presence presence = stream_event.stanza tubes_nodes = xpath.queryForNodes('/presence/tubes[@xmlns="%s"]' % ns.TUBES, presence) assert tubes_nodes is not None assert len(tubes_nodes) == 1 tube_nodes = xpath.queryForNodes('/tubes/tube', tubes_nodes[0]) assert tube_nodes is not None assert len(tube_nodes) == 1 for tube in tube_nodes: assert tube['type'] == 'stream' assert not tube.hasAttribute('initiator') assert tube['service'] == 'echo' assert not tube.hasAttribute('stream-id') assert not tube.hasAttribute('dbus-name') assert tube['id'] == str(stream_tube_id) params = {} parameter_nodes = xpath.queryForNodes('/tube/parameters/parameter', tube) for node in parameter_nodes: assert node['name'] not in params params[node['name']] = (node['type'], str(node)) assert params == {'ay': ('bytes', 'aGVsbG8='), 's': ('str', 'hello'), 'i': ('int', '-123'), 'u': ('uint', '123'), } # tube is also announced using new API channels = new_channels_event.args[0] assert len(channels) == 1 path, props = channels[0] assert props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_STREAM_TUBE assert props[cs.INITIATOR_HANDLE] == tubes_self_handle assert props[cs.INITIATOR_ID] == '[email protected]/test' assert props[cs.INTERFACES] == [cs.CHANNEL_IFACE_GROUP, cs.CHANNEL_IFACE_TUBE] assert props[cs.REQUESTED] == True assert props[cs.TARGET_HANDLE] == room_handle assert props[cs.TARGET_ID] == '*****@*****.**' assert props[cs.STREAM_TUBE_SERVICE] == 'echo' tube_chan = bus.get_object(conn.bus_name, path) tube_props = tube_chan.GetAll(cs.CHANNEL_IFACE_TUBE, dbus_interface=cs.PROPERTIES_IFACE, byte_arrays=True) assert tube_props['Parameters'] == sample_parameters assert tube_props['State'] == cs.TUBE_CHANNEL_STATE_OPEN tubes = tubes_iface.ListTubes(byte_arrays=True) assert tubes == [( stream_tube_id, tubes_self_handle, 1, # Stream 'echo', sample_parameters, cs.TUBE_CHANNEL_STATE_OPEN )] assert len(tubes) == 1, unwrap(tubes) expected_tube = (stream_tube_id, tubes_self_handle, cs.TUBE_TYPE_STREAM, 'echo', sample_parameters, cs.TUBE_STATE_OPEN) t.check_tube_in_tubes(expected_tube, tubes) # FIXME: if we use an unknown JID here, everything fails # (the code uses lookup where it should use ensure) bytestream = connect_to_tube(stream, q, bytestream_cls, '*****@*****.**', stream_tube_id) iq_event, socket_event, _, conn_event = q.expect_many( EventPattern('stream-iq', iq_type='result'), EventPattern('socket-connected'), EventPattern('dbus-signal', signal='StreamTubeNewConnection', args=[stream_tube_id, bob_handle], interface=cs.CHANNEL_TYPE_TUBES), EventPattern('dbus-signal', signal='NewRemoteConnection', interface=cs.CHANNEL_TYPE_STREAM_TUBE)) protocol = socket_event.protocol # handle iq_event bytestream.check_si_reply(iq_event.stanza) tube = xpath.queryForNodes('/iq//si/tube[@xmlns="%s"]' % ns.TUBES, iq_event.stanza) assert len(tube) == 1 handle, access, conn_id = conn_event.args assert handle == bob_handle use_tube(q, bytestream, protocol, conn_id) # offer a stream tube to another room (new API) address = t.create_server(q, address_type, block_reading=True) request = { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, cs.TARGET_ID: '*****@*****.**', cs.STREAM_TUBE_SERVICE: 'newecho', } _, _, new_tube_path, new_tube_props = \ join_muc(q, bus, conn, stream, '*****@*****.**', request) # The order in which the NewChannels signals are fired is # undefined -- it could be the (tubes, text) channels first, or it # could be the tube channel first; so let's accept either order # here. first, second = q.expect_many( EventPattern('dbus-signal', signal='NewChannels'), EventPattern('dbus-signal', signal='NewChannels')) # NewChannels signal with the text and tubes channels together. def nc_textandtubes(event): channels = event.args[0] assert len(channels) == 2 path1, prop1 = channels[0] path2, prop2 = channels[1] assert sorted([prop1[cs.CHANNEL_TYPE], prop2[cs.CHANNEL_TYPE]]) == \ [cs.CHANNEL_TYPE_TEXT, cs.CHANNEL_TYPE_TUBES] got_text, got_tubes = False, False for path, props in channels: if props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_TEXT: got_text = True elif props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_TUBES: got_tubes = True else: assert False assert props[cs.INITIATOR_HANDLE] == self_handle assert props[cs.INITIATOR_ID] == self_name assert cs.CHANNEL_IFACE_GROUP in props[cs.INTERFACES] assert props[cs.TARGET_ID] == '*****@*****.**' assert props[cs.REQUESTED] == False assert (got_text, got_tubes) == (True, True) # NewChannels signal with the tube channel. def nc_tube(event): # FIXME: in this case, all channels should probably be announced together channels = event.args[0] assert len(channels) == 1 path, prop = channels[0] assert prop[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_STREAM_TUBE assert prop[cs.INITIATOR_ID] == '[email protected]/test' assert prop[cs.REQUESTED] == True assert prop[cs.TARGET_HANDLE_TYPE] == cs.HT_ROOM assert prop[cs.TARGET_ID] == '*****@*****.**' assert prop[cs.STREAM_TUBE_SERVICE] == 'newecho' return path, prop if len(first.args[0]) == 1: path, prop = nc_tube(first) nc_textandtubes(second) else: nc_textandtubes(first) path, prop = nc_tube(second) # check that the tube channel is in the channels list all_channels = conn.Get(cs.CONN_IFACE_REQUESTS, 'Channels', dbus_interface=cs.PROPERTIES_IFACE, byte_arrays=True) assertContains((path, prop), all_channels) tube_chan = bus.get_object(conn.bus_name, path) stream_tube_iface = dbus.Interface(tube_chan, cs.CHANNEL_TYPE_STREAM_TUBE) chan_iface = dbus.Interface(tube_chan, cs.CHANNEL) tube_props = tube_chan.GetAll(cs.CHANNEL_IFACE_TUBE, dbus_interface=cs.PROPERTIES_IFACE) assert tube_props['State'] == cs.TUBE_CHANNEL_STATE_NOT_OFFERED # offer the tube call_async(q, stream_tube_iface, 'Offer', address_type, address, access_control, {'foo': 'bar'}) new_tube_event, stream_event, _, status_event = q.expect_many( EventPattern('dbus-signal', signal='NewTube'), EventPattern('stream-presence', to='[email protected]/test'), EventPattern('dbus-return', method='Offer'), EventPattern('dbus-signal', signal='TubeChannelStateChanged', args=[cs.TUBE_CHANNEL_STATE_OPEN])) tube_self_handle = tube_chan.GetSelfHandle(dbus_interface=cs.CHANNEL_IFACE_GROUP) assert conn.InspectHandles(cs.HT_CONTACT, [tube_self_handle]) == ['[email protected]/test'] # handle new_tube_event stream_tube_id = new_tube_event.args[0] assert new_tube_event.args[2] == 1 # Stream assert new_tube_event.args[3] == 'newecho' assert new_tube_event.args[4] == {'foo': 'bar'} assert new_tube_event.args[5] == cs.TUBE_CHANNEL_STATE_OPEN presence = stream_event.stanza tubes_nodes = xpath.queryForNodes('/presence/tubes[@xmlns="%s"]' % ns.TUBES, presence) assert tubes_nodes is not None assert len(tubes_nodes) == 1 tube_nodes = xpath.queryForNodes('/tubes/tube', tubes_nodes[0]) assert tube_nodes is not None assert len(tube_nodes) == 1 for tube in tube_nodes: assert tube['type'] == 'stream' assert not tube.hasAttribute('initiator') assert tube['service'] == 'newecho' assert not tube.hasAttribute('stream-id') assert not tube.hasAttribute('dbus-name') assert tube['id'] == str(stream_tube_id) params = {} parameter_nodes = xpath.queryForNodes('/tube/parameters/parameter', tube) for node in parameter_nodes: assert node['name'] not in params params[node['name']] = (node['type'], str(node)) assert params == {'foo': ('str', 'bar')} bob_handle = conn.RequestHandles(cs.HT_CONTACT, ['[email protected]/bob'])[0] bytestream = connect_to_tube(stream, q, bytestream_cls, '*****@*****.**', stream_tube_id) iq_event, socket_event, conn_event = q.expect_many( EventPattern('stream-iq', iq_type='result'), EventPattern('socket-connected'), EventPattern('dbus-signal', signal='NewRemoteConnection', interface=cs.CHANNEL_TYPE_STREAM_TUBE)) handle, access, conn_id = conn_event.args assert handle == bob_handle protocol = socket_event.protocol # start to read from the transport so we can read the control byte protocol.transport.startReading() t.check_new_connection_access(q, access_control, access, protocol) # handle iq_event bytestream.check_si_reply(iq_event.stanza) tube = xpath.queryForNodes('/iq//si/tube[@xmlns="%s"]' % ns.TUBES, iq_event.stanza) assert len(tube) == 1 use_tube(q, bytestream, protocol, conn_id) chan_iface.Close() q.expect_many( EventPattern('dbus-signal', signal='Closed'), EventPattern('dbus-signal', signal='ChannelClosed'))
def test(q, bus, conn, stream, access_control): iq_event = q.expect("stream-iq", to=None, query_ns="vcard-temp", query_name="vCard") acknowledge_iq(stream, iq_event.stanza) # check if we can request muc D-Bus tube t.check_conn_properties(q, conn) self_handle = conn.GetSelfHandle() self_name = conn.InspectHandles(1, [self_handle])[0] handle, tubes_chan, tubes_iface = get_muc_tubes_channel(q, bus, conn, stream, "*****@*****.**") # Exercise basic Channel Properties from spec 0.17.7 channel_props = tubes_chan.GetAll(cs.CHANNEL, dbus_interface=dbus.PROPERTIES_IFACE) assert channel_props.get("TargetHandle") == handle, (channel_props.get("TargetHandle"), handle) assert channel_props.get("TargetHandleType") == 2, channel_props.get("TargetHandleType") assert channel_props.get("ChannelType") == cs.CHANNEL_TYPE_TUBES, channel_props.get("ChannelType") assert "Interfaces" in channel_props, channel_props assert cs.CHANNEL_IFACE_GROUP in channel_props["Interfaces"], channel_props["Interfaces"] assert channel_props["TargetID"] == "*****@*****.**", channel_props assert channel_props["Requested"] == True assert channel_props["InitiatorID"] == "test@localhost" assert channel_props["InitiatorHandle"] == conn.GetSelfHandle() # Exercise Group Properties from spec 0.17.6 (in a basic way) group_props = tubes_chan.GetAll(cs.CHANNEL_IFACE_GROUP, dbus_interface=dbus.PROPERTIES_IFACE) assert "SelfHandle" in group_props, group_props assert "HandleOwners" in group_props, group_props assert "Members" in group_props, group_props assert "LocalPendingMembers" in group_props, group_props assert "RemotePendingMembers" in group_props, group_props assert "GroupFlags" in group_props, group_props tubes_self_handle = tubes_chan.GetSelfHandle(dbus_interface=cs.CHANNEL_IFACE_GROUP) assert group_props["SelfHandle"] == tubes_self_handle # Offer a D-Bus tube (old API) call_async(q, tubes_iface, "OfferDBusTube", "com.example.TestCase", sample_parameters) new_tube_event, presence_event, offer_return_event, dbus_changed_event = q.expect_many( EventPattern("dbus-signal", signal="NewTube"), EventPattern("stream-presence", to="[email protected]/test"), EventPattern("dbus-return", method="OfferDBusTube"), EventPattern("dbus-signal", signal="DBusNamesChanged", interface=cs.CHANNEL_TYPE_TUBES), ) # handle new_tube_event dbus_tube_id = new_tube_event.args[0] assert new_tube_event.args[1] == tubes_self_handle assert new_tube_event.args[2] == cs.TUBE_TYPE_DBUS assert new_tube_event.args[3] == "com.example.TestCase" assert new_tube_event.args[4] == sample_parameters assert new_tube_event.args[5] == cs.TUBE_STATE_OPEN # handle offer_return_event assert offer_return_event.value[0] == dbus_tube_id # handle presence_event # We announce our newly created tube in our muc presence presence = presence_event.stanza dbus_stream_id, my_bus_name = check_tube_in_presence(presence, dbus_tube_id, "[email protected]/test") # handle dbus_changed_event assert dbus_changed_event.args[0] == dbus_tube_id assert dbus_changed_event.args[1][0][0] == tubes_self_handle assert dbus_changed_event.args[1][0][1] == my_bus_name # handle offer_return_event assert dbus_tube_id == offer_return_event.value[0] tubes = tubes_iface.ListTubes(byte_arrays=True) assert len(tubes) == 1 expected_tube = ( dbus_tube_id, tubes_self_handle, cs.TUBE_TYPE_DBUS, "com.example.TestCase", sample_parameters, cs.TUBE_STATE_OPEN, ) t.check_tube_in_tubes(expected_tube, tubes) dbus_tube_adr = tubes_iface.GetDBusTubeAddress(dbus_tube_id) tube = Connection(dbus_tube_adr) fire_signal_on_tube(q, tube, "*****@*****.**", dbus_stream_id, my_bus_name) # offer a D-Bus tube to another room using new API muc = "*****@*****.**" request = { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_DBUS_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, cs.TARGET_ID: "*****@*****.**", cs.DBUS_TUBE_SERVICE_NAME: "com.example.TestCase", } join_muc(q, bus, conn, stream, muc, request=request) # The order in which the NewChannels signals are fired is # undefined -- it could be the (tubes, text) channels first, or it # could be the tube channel first; so let's accept either order # here. first, second = q.expect_many( EventPattern("dbus-signal", signal="NewChannels"), EventPattern("dbus-signal", signal="NewChannels") ) # NewChannels signal with the text and tubes channels together. def nc_textandtubes(event): channels = event.args[0] assert len(channels) == 2 path1, prop1 = channels[0] path2, prop2 = channels[1] assert sorted([prop1[cs.CHANNEL_TYPE], prop2[cs.CHANNEL_TYPE]]) == [cs.CHANNEL_TYPE_TEXT, cs.CHANNEL_TYPE_TUBES] got_text, got_tubes = False, False for path, props in channels: if props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_TEXT: got_text = True text_chan = dbus.Interface(bus.get_object(conn.bus_name, path), cs.CHANNEL) elif props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_TUBES: got_tubes = True tubes_iface = dbus.Interface(bus.get_object(conn.bus_name, path), cs.CHANNEL_TYPE_TUBES) else: assert False assert props[cs.INITIATOR_HANDLE] == self_handle assert props[cs.INITIATOR_ID] == self_name assert cs.CHANNEL_IFACE_GROUP in props[cs.INTERFACES] assert props[cs.TARGET_ID] == "*****@*****.**" assert props[cs.REQUESTED] == False assert (got_text, got_tubes) == (True, True) return text_chan # NewChannels signal with the tube channel. def nc_tube(event): # FIXME: in this case, all channels should probably be announced together channels = event.args[0] assert len(channels) == 1 path, prop = channels[0] assert prop[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_DBUS_TUBE assert prop[cs.INITIATOR_ID] == "[email protected]/test" assert prop[cs.REQUESTED] == True assert prop[cs.TARGET_HANDLE_TYPE] == cs.HT_ROOM assert prop[cs.TARGET_ID] == "*****@*****.**" assert prop[cs.DBUS_TUBE_SERVICE_NAME] == "com.example.TestCase" assert prop[cs.DBUS_TUBE_SUPPORTED_ACCESS_CONTROLS] == [ cs.SOCKET_ACCESS_CONTROL_CREDENTIALS, cs.SOCKET_ACCESS_CONTROL_LOCALHOST, ] return path, prop if len(first.args[0]) == 1: path, prop = nc_tube(first) text_chan = nc_textandtubes(second) else: text_chan = nc_textandtubes(first) path, prop = nc_tube(second) # check that the tube channel is in the channels list all_channels = conn.Get(cs.CONN_IFACE_REQUESTS, "Channels", dbus_interface=cs.PROPERTIES_IFACE, byte_arrays=True) assertContains((path, prop), all_channels) tube_chan = bus.get_object(conn.bus_name, path) dbus_tube_iface = dbus.Interface(tube_chan, cs.CHANNEL_TYPE_DBUS_TUBE) chan_iface = dbus.Interface(tube_chan, cs.CHANNEL) tube_props = tube_chan.GetAll(cs.CHANNEL_IFACE_TUBE, dbus_interface=cs.PROPERTIES_IFACE, byte_arrays=True) assert tube_props["State"] == cs.TUBE_CHANNEL_STATE_NOT_OFFERED # try to offer using a wrong access control try: dbus_tube_iface.Offer(sample_parameters, cs.SOCKET_ACCESS_CONTROL_PORT) except dbus.DBusException, e: assertEquals(e.get_dbus_name(), cs.INVALID_ARGUMENT)
def test(q, bus, conn, stream, bytestream_cls, address_type, access_control, access_control_param): if bytestream_cls in [BytestreamS5BRelay, BytestreamS5BRelayBugged]: # disable SOCKS5 relay tests because proxy can't be used with muc # contacts atm return iq_event = q.expect('stream-iq', to=None, query_ns='vcard-temp', query_name='vCard') acknowledge_iq(stream, iq_event.stanza) t.check_conn_properties(q, conn) bob_handle = conn.get_contact_handle_sync('[email protected]/bob') address = t.create_server(q, address_type) def new_chan_predicate(e): types = [] for _, props in e.args[0]: types.append(props[cs.CHANNEL_TYPE]) return cs.CHANNEL_TYPE_STREAM_TUBE in types def find_stream_tube(channels): for path, props in channels: if props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_STREAM_TUBE: return path, props return None, None # offer a stream tube to another room (new API) address = t.create_server(q, address_type, block_reading=True) request = { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, cs.TARGET_ID: '*****@*****.**', cs.STREAM_TUBE_SERVICE: 'newecho', } _, new_tube_path, new_tube_props = \ join_muc(q, bus, conn, stream, '*****@*****.**', request) e = q.expect('dbus-signal', signal='NewChannels', predicate=new_chan_predicate) path, prop = find_stream_tube(e.args[0]) assert prop[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_STREAM_TUBE assert prop[cs.INITIATOR_ID] == '[email protected]/test' assert prop[cs.REQUESTED] == True assert prop[cs.TARGET_HANDLE_TYPE] == cs.HT_ROOM assert prop[cs.TARGET_ID] == '*****@*****.**' assert prop[cs.STREAM_TUBE_SERVICE] == 'newecho' # check that the tube channel is in the channels list all_channels = conn.Get(cs.CONN_IFACE_REQUESTS, 'Channels', dbus_interface=cs.PROPERTIES_IFACE, byte_arrays=True) assertContains((path, prop), all_channels) tube_chan = wrap_channel(bus.get_object(conn.bus_name, path), 'StreamTube') tube_props = tube_chan.GetAll(cs.CHANNEL_IFACE_TUBE, dbus_interface=cs.PROPERTIES_IFACE) assert tube_props['State'] == cs.TUBE_CHANNEL_STATE_NOT_OFFERED # offer the tube call_async(q, tube_chan.StreamTube, 'Offer', address_type, address, access_control, {'foo': 'bar'}) stream_event, _, status_event = q.expect_many( EventPattern('stream-presence', to='[email protected]/test', predicate=lambda e: t.presence_contains_tube(e)), EventPattern('dbus-return', method='Offer'), EventPattern('dbus-signal', signal='TubeChannelStateChanged', args=[cs.TUBE_CHANNEL_STATE_OPEN])) tube_self_handle = tube_chan.Properties.Get(cs.CHANNEL_IFACE_GROUP, 'SelfHandle') assert conn.inspect_contact_sync( tube_self_handle) == '[email protected]/test' presence = stream_event.stanza tubes_nodes = xpath.queryForNodes( '/presence/tubes[@xmlns="%s"]' % ns.TUBES, presence) assert tubes_nodes is not None assert len(tubes_nodes) == 1 stream_tube_id = 666 tube_nodes = xpath.queryForNodes('/tubes/tube', tubes_nodes[0]) assert tube_nodes is not None assert len(tube_nodes) == 1 for tube in tube_nodes: assert tube['type'] == 'stream' assert not tube.hasAttribute('initiator') assert tube['service'] == 'newecho' assert not tube.hasAttribute('stream-id') assert not tube.hasAttribute('dbus-name') stream_tube_id = int(tube['id']) params = {} parameter_nodes = xpath.queryForNodes('/tube/parameters/parameter', tube) for node in parameter_nodes: assert node['name'] not in params params[node['name']] = (node['type'], str(node)) assert params == {'foo': ('str', 'bar')} bob_handle = conn.get_contact_handle_sync('[email protected]/bob') bytestream = connect_to_tube(stream, q, bytestream_cls, '*****@*****.**', stream_tube_id) iq_event, socket_event, conn_event = q.expect_many( EventPattern('stream-iq', iq_type='result'), EventPattern('socket-connected'), EventPattern('dbus-signal', signal='NewRemoteConnection', interface=cs.CHANNEL_TYPE_STREAM_TUBE)) handle, access, conn_id = conn_event.args assert handle == bob_handle protocol = socket_event.protocol # start to read from the transport so we can read the control byte protocol.transport.startReading() t.check_new_connection_access(q, access_control, access, protocol) # handle iq_event bytestream.check_si_reply(iq_event.stanza) tube = xpath.queryForNodes('/iq//si/tube[@xmlns="%s"]' % ns.TUBES, iq_event.stanza) assert len(tube) == 1 use_tube(q, bytestream, protocol, conn_id) tube_chan.Channel.Close() q.expect_many(EventPattern('dbus-signal', signal='Closed'), EventPattern('dbus-signal', signal='ChannelClosed')) t.cleanup()
def test(q, bus, conn, stream, access_control): conn.Connect() _, iq_event = q.expect_many( EventPattern('dbus-signal', signal='StatusChanged', args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED]), EventPattern('stream-iq', to=None, query_ns='vcard-temp', query_name='vCard')) acknowledge_iq(stream, iq_event.stanza) # check if we can request muc D-Bus tube t.check_conn_properties(q, conn) self_handle = conn.GetSelfHandle() self_name = conn.InspectHandles(1, [self_handle])[0] handle, tubes_chan, tubes_iface = get_muc_tubes_channel(q, bus, conn, stream, '*****@*****.**') # Exercise basic Channel Properties from spec 0.17.7 channel_props = tubes_chan.GetAll(cs.CHANNEL, dbus_interface=dbus.PROPERTIES_IFACE) assert channel_props.get('TargetHandle') == handle,\ (channel_props.get('TargetHandle'), handle) assert channel_props.get('TargetHandleType') == 2,\ channel_props.get('TargetHandleType') assert channel_props.get('ChannelType') == cs.CHANNEL_TYPE_TUBES,\ channel_props.get('ChannelType') assert 'Interfaces' in channel_props, channel_props assert cs.CHANNEL_IFACE_GROUP in channel_props['Interfaces'], \ channel_props['Interfaces'] assert channel_props['TargetID'] == '*****@*****.**', channel_props assert channel_props['Requested'] == True assert channel_props['InitiatorID'] == 'test@localhost' assert channel_props['InitiatorHandle'] == conn.GetSelfHandle() # Exercise Group Properties from spec 0.17.6 (in a basic way) group_props = tubes_chan.GetAll(cs.CHANNEL_IFACE_GROUP, dbus_interface=dbus.PROPERTIES_IFACE) assert 'SelfHandle' in group_props, group_props assert 'HandleOwners' in group_props, group_props assert 'Members' in group_props, group_props assert 'LocalPendingMembers' in group_props, group_props assert 'RemotePendingMembers' in group_props, group_props assert 'GroupFlags' in group_props, group_props tubes_self_handle = tubes_chan.GetSelfHandle( dbus_interface=cs.CHANNEL_IFACE_GROUP) assert group_props['SelfHandle'] == tubes_self_handle # Offer a D-Bus tube (old API) call_async(q, tubes_iface, 'OfferDBusTube', 'com.example.TestCase', sample_parameters) new_tube_event, presence_event, offer_return_event, dbus_changed_event = \ q.expect_many( EventPattern('dbus-signal', signal='NewTube'), EventPattern('stream-presence', to='[email protected]/test'), EventPattern('dbus-return', method='OfferDBusTube'), EventPattern('dbus-signal', signal='DBusNamesChanged', interface=cs.CHANNEL_TYPE_TUBES)) # handle new_tube_event dbus_tube_id = new_tube_event.args[0] assert new_tube_event.args[1] == tubes_self_handle assert new_tube_event.args[2] == cs.TUBE_TYPE_DBUS assert new_tube_event.args[3] == 'com.example.TestCase' assert new_tube_event.args[4] == sample_parameters assert new_tube_event.args[5] == cs.TUBE_STATE_OPEN # handle offer_return_event assert offer_return_event.value[0] == dbus_tube_id # handle presence_event # We announce our newly created tube in our muc presence presence = presence_event.stanza dbus_stream_id, my_bus_name = check_tube_in_presence(presence, dbus_tube_id, '[email protected]/test') # handle dbus_changed_event assert dbus_changed_event.args[0] == dbus_tube_id assert dbus_changed_event.args[1][0][0] == tubes_self_handle assert dbus_changed_event.args[1][0][1] == my_bus_name # handle offer_return_event assert dbus_tube_id == offer_return_event.value[0] tubes = tubes_iface.ListTubes(byte_arrays=True) assert len(tubes) == 1 expected_tube = (dbus_tube_id, tubes_self_handle, cs.TUBE_TYPE_DBUS, 'com.example.TestCase', sample_parameters, cs.TUBE_STATE_OPEN) t.check_tube_in_tubes(expected_tube, tubes) dbus_tube_adr = tubes_iface.GetDBusTubeAddress(dbus_tube_id) tube = Connection(dbus_tube_adr) fire_signal_on_tube(q, tube, '*****@*****.**', dbus_stream_id, my_bus_name) # offer a D-Bus tube to another room using new API muc = '*****@*****.**' request = { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_DBUS_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, cs.TARGET_ID: '*****@*****.**', cs.DBUS_TUBE_SERVICE_NAME: 'com.example.TestCase', } join_muc(q, bus, conn, stream, muc, request=request) # first text and tubes channels are announced event = q.expect('dbus-signal', signal='NewChannels') channels = event.args[0] assert len(channels) == 2 path1, prop1 = channels[0] path2, prop2 = channels[1] assert sorted([prop1[cs.CHANNEL_TYPE], prop2[cs.CHANNEL_TYPE]]) == \ [cs.CHANNEL_TYPE_TEXT, cs.CHANNEL_TYPE_TUBES] got_text, got_tubes = False, False for path, props in channels: if props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_TEXT: got_text = True text_chan = dbus.Interface(bus.get_object(conn.bus_name, path), cs.CHANNEL) elif props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_TUBES: got_tubes = True tubes_iface = dbus.Interface(bus.get_object(conn.bus_name, path), cs.CHANNEL_TYPE_TUBES) else: assert False assert props[cs.INITIATOR_HANDLE] == self_handle assert props[cs.INITIATOR_ID] == self_name assert cs.CHANNEL_IFACE_GROUP in props[cs.INTERFACES] assert props[cs.TARGET_ID] == '*****@*****.**' assert props[cs.REQUESTED] == False assert (got_text, got_tubes) == (True, True) # now the tube channel is announced # FIXME: in this case, all channels should probably be announced together event = q.expect('dbus-signal', signal='NewChannels') channels = event.args[0] assert len(channels) == 1 path, prop = channels[0] assert prop[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_DBUS_TUBE assert prop[cs.INITIATOR_ID] == '[email protected]/test' assert prop[cs.REQUESTED] == True assert prop[cs.TARGET_HANDLE_TYPE] == cs.HT_ROOM assert prop[cs.TARGET_ID] == '*****@*****.**' assert prop[cs.DBUS_TUBE_SERVICE_NAME] == 'com.example.TestCase' assert prop[cs.DBUS_TUBE_SUPPORTED_ACCESS_CONTROLS] == [cs.SOCKET_ACCESS_CONTROL_CREDENTIALS, cs.SOCKET_ACCESS_CONTROL_LOCALHOST] # check that the tube channel is in the channels list all_channels = conn.Get(cs.CONN_IFACE_REQUESTS, 'Channels', dbus_interface=cs.PROPERTIES_IFACE, byte_arrays=True) assertContains((path, prop), all_channels) tube_chan = bus.get_object(conn.bus_name, path) dbus_tube_iface = dbus.Interface(tube_chan, cs.CHANNEL_TYPE_DBUS_TUBE) chan_iface = dbus.Interface(tube_chan, cs.CHANNEL) tube_props = tube_chan.GetAll(cs.CHANNEL_IFACE_TUBE, dbus_interface=cs.PROPERTIES_IFACE, byte_arrays=True) assert tube_props['State'] == cs.TUBE_CHANNEL_STATE_NOT_OFFERED # try to offer using a wrong access control try: dbus_tube_iface.Offer(sample_parameters, cs.SOCKET_ACCESS_CONTROL_PORT) except dbus.DBusException, e: assertEquals(e.get_dbus_name(), cs.INVALID_ARGUMENT)
def test(q, bus, conn, stream, bytestream_cls, access_control): global last_tube_id t.check_conn_properties(q, conn) vcard_event, roster_event = q.expect_many( EventPattern('stream-iq', to=None, query_ns='vcard-temp', query_name='vCard'), EventPattern('stream-iq', query_ns=ns.ROSTER)) self_handle = conn.Properties.Get(cs.CONN, "SelfHandle") acknowledge_iq(stream, vcard_event.stanza) roster = roster_event.stanza roster['type'] = 'result' item = roster_event.query.addElement('item') item['jid'] = 'bob@localhost' # Bob can do tubes item['subscription'] = 'both' stream.send(roster) bob_full_jid = 'bob@localhost/Bob' self_full_jid = 'test@localhost/Resource' # Send Bob presence and his tube caps presence = domish.Element(('jabber:client', 'presence')) presence['from'] = bob_full_jid presence['to'] = self_full_jid c = presence.addElement('c') c['xmlns'] = 'http://jabber.org/protocol/caps' c['node'] = 'http://example.com/ICantBelieveItsNotTelepathy' c['ver'] = '1.2.3' stream.send(presence) event = q.expect('stream-iq', iq_type='get', query_ns='http://jabber.org/protocol/disco#info', to=bob_full_jid) result = event.stanza result['type'] = 'result' assert event.query['node'] == \ 'http://example.com/ICantBelieveItsNotTelepathy#1.2.3' feature = event.query.addElement('feature') feature['var'] = ns.TUBES stream.send(result) # A tube request can be done only if the contact has tube capabilities # Ensure that Bob's caps have been received sync_stream(q, stream) # Also ensure that all the new contact list channels have been announced, # so that the NewChannel(s) signals we look for after calling # RequestChannel are the ones we wanted. sync_dbus(bus, q, conn) bob_handle = conn.get_contact_handle_sync('bob@localhost') # let's try to accept a D-Bus tube using the new API bytestream = bytestream_cls(stream, q, 'gamma', bob_full_jid, self_full_jid, True) last_tube_id += 1 contact_offer_dbus_tube(bytestream, last_tube_id) def new_chan_predicate(e): path, props = e.args[0][0] return props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_DBUS_TUBE e = q.expect('dbus-signal', signal='NewChannels', predicate=new_chan_predicate) channels = e.args[0] assert len(channels) == 1 path, props = channels[0] assert props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_DBUS_TUBE assert props[cs.INITIATOR_HANDLE] == bob_handle assert props[cs.INITIATOR_ID] == 'bob@localhost' assert props[cs.INTERFACES] == [cs.CHANNEL_IFACE_TUBE] assert props[cs.REQUESTED] == False assert props[cs.TARGET_HANDLE] == bob_handle assert props[cs.TARGET_ID] == 'bob@localhost' assert props[cs.DBUS_TUBE_SERVICE_NAME] == 'com.example.TestCase2' assert props[cs.TUBE_PARAMETERS] == {'login': '******'} assert props[cs.DBUS_TUBE_SUPPORTED_ACCESS_CONTROLS] == [ cs.SOCKET_ACCESS_CONTROL_CREDENTIALS, cs.SOCKET_ACCESS_CONTROL_LOCALHOST ] assert cs.TUBE_STATE not in props tube_chan = bus.get_object(conn.bus_name, path) tube_chan_iface = dbus.Interface(tube_chan, cs.CHANNEL) dbus_tube_iface = dbus.Interface(tube_chan, cs.CHANNEL_TYPE_DBUS_TUBE) status = tube_chan.Get(cs.CHANNEL_IFACE_TUBE, 'State', dbus_interface=cs.PROPERTIES_IFACE) assert status == cs.TUBE_STATE_LOCAL_PENDING # try to accept using a wrong access control try: dbus_tube_iface.Accept(cs.SOCKET_ACCESS_CONTROL_PORT) except dbus.DBusException, e: assertEquals(e.get_dbus_name(), cs.INVALID_ARGUMENT)
def test(q, bus, conn, stream, bytestream_cls, access_control): global last_tube_id t.check_conn_properties(q, conn) vcard_event, roster_event = q.expect_many( EventPattern("stream-iq", to=None, query_ns="vcard-temp", query_name="vCard"), EventPattern("stream-iq", query_ns=ns.ROSTER), ) self_handle = conn.GetSelfHandle() acknowledge_iq(stream, vcard_event.stanza) roster = roster_event.stanza roster["type"] = "result" item = roster_event.query.addElement("item") item["jid"] = "bob@localhost" # Bob can do tubes item["subscription"] = "both" stream.send(roster) bob_full_jid = "bob@localhost/Bob" self_full_jid = "test@localhost/Resource" # Send Bob presence and his tube caps presence = domish.Element(("jabber:client", "presence")) presence["from"] = bob_full_jid presence["to"] = self_full_jid c = presence.addElement("c") c["xmlns"] = "http://jabber.org/protocol/caps" c["node"] = "http://example.com/ICantBelieveItsNotTelepathy" c["ver"] = "1.2.3" stream.send(presence) event = q.expect("stream-iq", iq_type="get", query_ns="http://jabber.org/protocol/disco#info", to=bob_full_jid) result = event.stanza result["type"] = "result" assert event.query["node"] == "http://example.com/ICantBelieveItsNotTelepathy#1.2.3" feature = event.query.addElement("feature") feature["var"] = ns.TUBES stream.send(result) # A tube request can be done only if the contact has tube capabilities # Ensure that Bob's caps have been received sync_stream(q, stream) # Also ensure that all the new contact list channels have been announced, # so that the NewChannel(s) signals we look for after calling # RequestChannel are the ones we wanted. sync_dbus(bus, q, conn) # let's try to accept a D-Bus tube using the old API bytestream = bytestream_cls(stream, q, "beta", bob_full_jid, "test@localhost/Reource", True) last_tube_id += 1 contact_offer_dbus_tube(bytestream, last_tube_id) # tubes channel is created event = q.expect("dbus-signal", signal="NewChannel") bob_handle = conn.RequestHandles(cs.HT_CONTACT, ["bob@localhost"])[0] t.check_NewChannel_signal(event.args, cs.CHANNEL_TYPE_TUBES, None, bob_handle, False) tubes_chan = bus.get_object(conn.bus_name, event.args[0]) tubes_iface = dbus.Interface(tubes_chan, cs.CHANNEL_TYPE_TUBES) event = q.expect("dbus-signal", signal="NewTube") id = event.args[0] initiator = event.args[1] type = event.args[2] service = event.args[3] parameters = event.args[4] state = event.args[5] assertEquals(last_tube_id, id) initiator_jid = conn.InspectHandles(1, [initiator])[0] assert initiator_jid == "bob@localhost" assert type == cs.TUBE_TYPE_DBUS assert service == "com.example.TestCase2" assert parameters == {"login": "******"} assert state == cs.TUBE_STATE_LOCAL_PENDING # accept the tube (old API) call_async(q, tubes_iface, "AcceptDBusTube", id) event = q.expect("stream-iq", iq_type="result") bytestream.check_si_reply(event.stanza) tube = xpath.queryForNodes('/iq/si/tube[@xmlns="%s"]' % ns.TUBES, event.stanza) assert len(tube) == 1 # Init the bytestream events, _ = bytestream.open_bytestream( [EventPattern("dbus-return", method="AcceptDBusTube")], [EventPattern("dbus-signal", signal="TubeStateChanged", args=[last_tube_id, 2])], ) return_event = events[0] address = return_event.value[0] assert len(address) > 0 # OK, now let's try to accept a D-Bus tube using the new API bytestream = bytestream_cls(stream, q, "gamma", bob_full_jid, self_full_jid, True) last_tube_id += 1 contact_offer_dbus_tube(bytestream, last_tube_id) e = q.expect("dbus-signal", signal="NewChannels") channels = e.args[0] assert len(channels) == 1 path, props = channels[0] assert props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_DBUS_TUBE assert props[cs.INITIATOR_HANDLE] == bob_handle assert props[cs.INITIATOR_ID] == "bob@localhost" assert props[cs.INTERFACES] == [cs.CHANNEL_IFACE_TUBE] assert props[cs.REQUESTED] == False assert props[cs.TARGET_HANDLE] == bob_handle assert props[cs.TARGET_ID] == "bob@localhost" assert props[cs.DBUS_TUBE_SERVICE_NAME] == "com.example.TestCase2" assert props[cs.TUBE_PARAMETERS] == {"login": "******"} assert props[cs.DBUS_TUBE_SUPPORTED_ACCESS_CONTROLS] == [ cs.SOCKET_ACCESS_CONTROL_CREDENTIALS, cs.SOCKET_ACCESS_CONTROL_LOCALHOST, ] assert cs.TUBE_STATE not in props tube_chan = bus.get_object(conn.bus_name, path) tube_chan_iface = dbus.Interface(tube_chan, cs.CHANNEL) dbus_tube_iface = dbus.Interface(tube_chan, cs.CHANNEL_TYPE_DBUS_TUBE) status = tube_chan.Get(cs.CHANNEL_IFACE_TUBE, "State", dbus_interface=cs.PROPERTIES_IFACE) assert status == cs.TUBE_STATE_LOCAL_PENDING # try to accept using a wrong access control try: dbus_tube_iface.Accept(cs.SOCKET_ACCESS_CONTROL_PORT) except dbus.DBusException, e: assertEquals(e.get_dbus_name(), cs.INVALID_ARGUMENT)