def expect_tube_activity(q, bus, conn, stream, bytestream_cls, address_type, address, access_control, access_control_param): event_socket, event_iq, conn_id = t.connect_to_cm_socket( q, bob_jid, address_type, address, access_control, access_control_param) protocol = event_socket.protocol data = "hello initiator" protocol.sendData(data) bytestream, profile = create_from_si_offer(stream, q, bytestream_cls, event_iq.stanza, 'test@localhost/Resource') assert profile == ns.TUBES stream_node = xpath.queryForNodes('/iq/si/stream[@xmlns="%s"]' % ns.TUBES, event_iq.stanza)[0] assert stream_node is not None assert stream_node['tube'] == str(stream_tube_id) result, si = bytestream.create_si_reply(event_iq.stanza) si.addElement((ns.TUBES, 'tube')) stream.send(result) bytestream.wait_bytestream_open() binary = bytestream.get_data(len(data)) assert data == binary, binary # reply to the initiator bytestream.send_data('hello joiner') e = q.expect('socket-data') assert e.data == 'hello joiner' return bytestream, conn_id
def expect_tube_activity(q, bus, conn, stream, bytestream_cls, address_type, address, access_control, access_control_param): event_socket, event_iq, conn_id = t.connect_to_cm_socket(q, bob_jid, address_type, address, access_control, access_control_param) protocol = event_socket.protocol data = "hello initiator" protocol.sendData(data) bytestream, profile = create_from_si_offer(stream, q, bytestream_cls, event_iq.stanza, 'test@localhost/Resource') assert profile == ns.TUBES stream_node = xpath.queryForNodes('/iq/si/stream[@xmlns="%s"]' % ns.TUBES, event_iq.stanza)[0] assert stream_node is not None assert stream_node['tube'] == str(stream_tube_id) result, si = bytestream.create_si_reply(event_iq.stanza) si.addElement((ns.TUBES, 'tube')) stream.send(result) bytestream.wait_bytestream_open() binary = bytestream.get_data(len(data)) assert data == binary, binary # reply to the initiator bytestream.send_data('hello joiner') e = q.expect('socket-data') assert e.data == 'hello joiner' return bytestream, conn_id
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 if access_control == cs.SOCKET_ACCESS_CONTROL_CREDENTIALS: print("Skip Socket_Access_Control_Credentials (fdo #45445)") return iq_event, disco_event = q.expect_many( EventPattern('stream-iq', to=None, query_ns='vcard-temp', query_name='vCard'), EventPattern('stream-iq', to='localhost', query_ns=ns.DISCO_ITEMS)) acknowledge_iq(stream, iq_event.stanza) announce_socks5_proxy(q, stream, disco_event.stanza) # join the muc 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_many( EventPattern( 'dbus-signal', signal='MembersChangedDetailed', predicate=lambda e: e.args[0] == [] and # added e.args[1] == [] and # removed e.args[2] == [] and # local pending len(e.args[3]) == 1 and # remote pending e.args[4].get('actor', 0) == 0 and e.args[4].get( 'change-reason', 0) == 0 and e.args[4]['contact-ids'][e.args[ 3][0]] == '[email protected]/test'), EventPattern('stream-presence', to='[email protected]/test')) # Send presence for other member of room. stream.send( make_muc_presence('owner', 'moderator', '*****@*****.**', 'bob')) # Send presence for own membership of room. stream.send( make_muc_presence('none', 'participant', '*****@*****.**', 'test')) event = q.expect( 'dbus-signal', signal='MembersChangedDetailed', predicate=lambda e: len(e.args[0]) == 2 and # added e.args[1] == [] and # removed e.args[2] == [] and # local pending e.args[3] == [] and # remote pending e.args[4].get('actor', 0) == 0 and e.args[4].get('change-reason', 0) == 0 and set([e.args[4]['contact-ids'][h] for h in e.args[0]]) == set( ['[email protected]/test', '[email protected]/bob'])) for h in event.args[0]: if event.args[4]['contact-ids'][h] == '[email protected]/bob': bob_handle = h event = q.expect('dbus-return', method='CreateChannel') # Bob offers a stream tube stream_tube_id = 666 presence = make_muc_presence('owner', 'moderator', '*****@*****.**', 'bob') tubes = presence.addElement((ns.TUBES, 'tubes')) tube = tubes.addElement((None, 'tube')) tube['type'] = 'stream' tube['service'] = 'echo' tube['id'] = str(stream_tube_id) parameters = tube.addElement((None, 'parameters')) parameter = parameters.addElement((None, 'parameter')) parameter['name'] = 's' parameter['type'] = 'str' parameter.addContent('hello') parameter = parameters.addElement((None, 'parameter')) parameter['name'] = 'ay' parameter['type'] = 'bytes' parameter.addContent('aGVsbG8=') parameter = parameters.addElement((None, 'parameter')) parameter['name'] = 'u' parameter['type'] = 'uint' parameter.addContent('123') parameter = parameters.addElement((None, 'parameter')) parameter['name'] = 'i' parameter['type'] = 'int' parameter.addContent('-123') stream.send(presence) # text channel new_event = q.expect('dbus-signal', signal='NewChannels') channels = new_event.args[0] assert len(channels) == 1 path, props = channels[0] assert props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_TEXT def new_chan_predicate(e): path, props = e.args[0][0] return props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_STREAM_TUBE # tube channel is announced new_event = q.expect('dbus-signal', signal='NewChannels', predicate=new_chan_predicate) channels = new_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] == bob_handle assert props[cs.INITIATOR_ID] == '[email protected]/bob' assertSameSets([cs.CHANNEL_IFACE_GROUP, cs.CHANNEL_IFACE_TUBE], props[cs.INTERFACES]) assert props[cs.REQUESTED] == False assert props[cs.TARGET_ID] == '*****@*****.**' assert props[cs.STREAM_TUBE_SERVICE] == 'echo' assert props[cs.TUBE_PARAMETERS] == { 's': 'hello', 'ay': b'hello', 'u': 123, 'i': -123 } assert access_control in \ props[cs.STREAM_TUBE_SUPPORTED_SOCKET_TYPES][address_type] 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) tube_iface = dbus.Interface(tube_chan, cs.CHANNEL_TYPE_STREAM_TUBE) assert tube_props['Parameters'] == sample_parameters assert tube_props['State'] == cs.TUBE_CHANNEL_STATE_LOCAL_PENDING # Accept the tube call_async(q, tube_iface, 'Accept', address_type, access_control, access_control_param, byte_arrays=True) accept_return_event, _ = q.expect_many( EventPattern('dbus-return', method='Accept'), EventPattern('dbus-signal', signal='TubeChannelStateChanged', args=[2])) address = accept_return_event.value[0] if isinstance(address, bytes): address = address.decode() socket_event, si_event, conn_id = t.connect_to_cm_socket( q, '[email protected]/bob', address_type, address, access_control, access_control_param) protocol = socket_event.protocol protocol.sendData(b"hello initiator") def accept_tube_si_connection(): bytestream, profile = create_from_si_offer(stream, q, bytestream_cls, si_event.stanza, '[email protected]/test') assert profile == ns.TUBES muc_stream_node = xpath.queryForNodes( '/iq/si/muc-stream[@xmlns="%s"]' % ns.TUBES, si_event.stanza)[0] assert muc_stream_node is not None assert muc_stream_node['tube'] == str(stream_tube_id) # set the real jid of the target as 'to' because the XMPP server changes # it when delivering the IQ result, si = bytestream.create_si_reply(si_event.stanza, 'test@localhost/Resource') si.addElement((ns.TUBES, 'tube')) stream.send(result) bytestream.wait_bytestream_open() return bytestream bytestream = accept_tube_si_connection() binary = bytestream.get_data() assert binary == b'hello initiator' # reply on the socket bytestream.send_data(b'hi joiner!') q.expect('socket-data', protocol=protocol, data=b"hi joiner!") # peer closes the bytestream bytestream.close() e = q.expect('dbus-signal', signal='ConnectionClosed') assertEquals(conn_id, e.args[0]) assertEquals(cs.CONNECTION_LOST, e.args[1]) # establish another tube connection socket_event, si_event, conn_id = t.connect_to_cm_socket( q, '[email protected]/bob', address_type, address, access_control, access_control_param) # bytestream is refused send_error_reply(stream, si_event.stanza) e, _ = q.expect_many( EventPattern('dbus-signal', signal='ConnectionClosed'), EventPattern('socket-disconnected')) assertEquals(conn_id, e.args[0]) assertEquals(cs.CONNECTION_REFUSED, e.args[1]) # establish another tube connection socket_event, si_event, conn_id = t.connect_to_cm_socket( q, '[email protected]/bob', address_type, address, access_control, access_control_param) protocol = socket_event.protocol bytestream = accept_tube_si_connection() # disconnect local socket protocol.transport.loseConnection() e, _ = q.expect_many( EventPattern('dbus-signal', signal='ConnectionClosed'), EventPattern('socket-disconnected')) assertEquals(conn_id, e.args[0]) assertEquals(cs.CANCELLED, e.args[1]) # OK, we're done disconnect_conn(q, conn, stream)
def test(q, bus, conn, stream, bytestream_cls, address_type, access_control, access_control_param): vcard_event, roster_event, disco_event = q.expect_many( EventPattern('stream-iq', to=None, query_ns='vcard-temp', query_name='vCard'), EventPattern('stream-iq', query_ns=ns.ROSTER), EventPattern('stream-iq', to='localhost', query_ns=ns.DISCO_ITEMS)) acknowledge_iq(stream, vcard_event.stanza) announce_socks5_proxy(q, stream, disco_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) # Send Bob presence and his caps presence = domish.Element(('jabber:client', 'presence')) presence['from'] = 'bob@localhost/Bob' presence['to'] = 'test@localhost/Resource' 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@localhost/Bob') 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) sync_dbus(bus, q, conn) # Receive a tube offer from Bob (tubes_chan, tubes_iface, new_tube_chan, new_tube_iface) = \ receive_tube_offer(q, bus, conn, stream) # Try bad parameters on the old iface call_async(q, tubes_iface, 'AcceptStreamTube', stream_tube_id+1, 2, 0, '', byte_arrays=True) q.expect('dbus-error', method='AcceptStreamTube') call_async(q, tubes_iface, 'AcceptStreamTube', stream_tube_id, 2, 1, '', byte_arrays=True) q.expect('dbus-error', method='AcceptStreamTube') call_async(q, tubes_iface, 'AcceptStreamTube', stream_tube_id, 20, 0, '', byte_arrays=True) q.expect('dbus-error', method='AcceptStreamTube') # Try bad parameters on the new iface call_async(q, new_tube_iface, 'Accept', 20, 0, '', byte_arrays=True) q.expect('dbus-error', method='Accept') call_async(q, new_tube_iface, 'Accept', 0, 1, '', byte_arrays=True) q.expect('dbus-error', method='Accept') # Accept the tube with old iface call_async(q, tubes_iface, 'AcceptStreamTube', stream_tube_id, address_type, access_control, access_control_param, byte_arrays=True) accept_return_event, _ = q.expect_many( EventPattern('dbus-return', method='AcceptStreamTube'), EventPattern('dbus-signal', signal='TubeStateChanged', args=[stream_tube_id, 2])) socket_address = accept_return_event.value[0] bytestream, conn_id = expect_tube_activity(q, bus, conn, stream, bytestream_cls, address_type, socket_address, access_control, access_control_param) tubes_chan.Close() bytestream.wait_bytestream_closed() # Receive a tube offer from Bob (tubes_chan, tubes_iface, new_tube_chan, new_tube_iface) = \ receive_tube_offer(q, bus, conn, stream) # Accept the tube with old iface, and use UNIX sockets call_async(q, tubes_iface, 'AcceptStreamTube', stream_tube_id, address_type, access_control, access_control_param, byte_arrays=True) accept_return_event, _ = q.expect_many( EventPattern('dbus-return', method='AcceptStreamTube'), EventPattern('dbus-signal', signal='TubeStateChanged', args=[stream_tube_id, 2])) socket_address = accept_return_event.value[0] bytestream, conn_id = expect_tube_activity(q, bus, conn, stream, bytestream_cls, address_type, socket_address, access_control, access_control_param) tubes_chan.Close() bytestream.wait_bytestream_closed() # Receive a tube offer from Bob (tubes_chan, tubes_iface, new_tube_chan, new_tube_iface) = \ receive_tube_offer(q, bus, conn, stream) # Accept the tube with new iface, and use IPv4 call_async(q, new_tube_iface, 'Accept', address_type, access_control, access_control_param, byte_arrays=True) accept_return_event, _ = q.expect_many( EventPattern('dbus-return', method='Accept'), EventPattern('dbus-signal', signal='TubeStateChanged', args=[stream_tube_id, 2])) socket_address = accept_return_event.value[0] bytestream, conn_id = expect_tube_activity(q, bus, conn, stream, bytestream_cls, address_type, socket_address, access_control, access_control_param) tubes_chan.Close() e, _ = bytestream.wait_bytestream_closed([ EventPattern('dbus-signal', signal='ConnectionClosed'), EventPattern('socket-disconnected')]) assertEquals(conn_id, e.args[0]) assertEquals(cs.CANCELLED, e.args[1]) # Receive a tube offer from Bob (tubes_chan, tubes_iface, new_tube_chan, new_tube_iface) = \ receive_tube_offer(q, bus, conn, stream) # Accept the tube with new iface, and use UNIX sockets call_async(q, new_tube_iface, 'Accept', address_type, access_control, access_control_param, byte_arrays=True) accept_return_event, _ = q.expect_many( EventPattern('dbus-return', method='Accept'), EventPattern('dbus-signal', signal='TubeStateChanged', args=[stream_tube_id, 2])) socket_address = accept_return_event.value[0] bytestream, conn_id = expect_tube_activity(q, bus, conn, stream, bytestream_cls, address_type, socket_address, access_control, access_control_param) # peer closes the bytestream bytestream.close() e = q.expect('dbus-signal', signal='ConnectionClosed') assertEquals(conn_id, e.args[0]) assertEquals(cs.CONNECTION_LOST, e.args[1]) # establish another tube connection event_socket, si_event, conn_id = t.connect_to_cm_socket(q, bob_jid, address_type, socket_address, access_control, access_control_param) # bytestream is refused send_error_reply(stream, si_event.stanza) e = q.expect('dbus-signal', signal='ConnectionClosed') assertEquals(conn_id, e.args[0]) assertEquals(cs.CONNECTION_REFUSED, e.args[1]) tubes_chan.Close() # Receive a tube offer from Bob (tubes_chan, tubes_iface, new_tube_chan, new_tube_iface) = \ receive_tube_offer(q, bus, conn, stream) # Just close the tube tubes_chan.Close() # Receive a tube offer from Bob (tubes_chan, tubes_iface, new_tube_chan, new_tube_iface) = \ receive_tube_offer(q, bus, conn, stream) # Just close the tube new_tube_chan.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, disco_event = q.expect_many( EventPattern('stream-iq', to=None, query_ns='vcard-temp', query_name='vCard'), EventPattern('stream-iq', to='localhost', query_ns=ns.DISCO_ITEMS)) acknowledge_iq(stream, iq_event.stanza) announce_socks5_proxy(q, stream, disco_event.stanza) call_async(q, conn, 'RequestHandles', 2, ['*****@*****.**']) event = q.expect('dbus-return', method='RequestHandles') handles = event.value[0] room_handle = handles[0] # join the muc call_async(q, conn, 'RequestChannel', cs.CHANNEL_TYPE_TEXT, cs.HT_ROOM, room_handle, True) _, stream_event = q.expect_many( EventPattern('dbus-signal', signal='MembersChanged', args=[u'', [], [], [], [2], 0, 0]), EventPattern('stream-presence', to='[email protected]/test')) # Send presence for other member of room. stream.send(make_muc_presence('owner', 'moderator', '*****@*****.**', 'bob')) # Send presence for own membership of room. stream.send(make_muc_presence('none', 'participant', '*****@*****.**', 'test')) q.expect('dbus-signal', signal='MembersChanged', args=[u'', [2, 3], [], [], [], 0, 0]) assert conn.InspectHandles(1, [2]) == ['[email protected]/test'] assert conn.InspectHandles(1, [3]) == ['[email protected]/bob'] bob_handle = 3 event = q.expect('dbus-return', method='RequestChannel') # Bob offers a stream tube stream_tube_id = 666 presence = make_muc_presence('owner', 'moderator', '*****@*****.**', 'bob') tubes = presence.addElement((ns.TUBES, 'tubes')) tube = tubes.addElement((None, 'tube')) tube['type'] = 'stream' tube['service'] = 'echo' tube['id'] = str(stream_tube_id) parameters = tube.addElement((None, 'parameters')) parameter = parameters.addElement((None, 'parameter')) parameter['name'] = 's' parameter['type'] = 'str' parameter.addContent('hello') parameter = parameters.addElement((None, 'parameter')) parameter['name'] = 'ay' parameter['type'] = 'bytes' parameter.addContent('aGVsbG8=') parameter = parameters.addElement((None, 'parameter')) parameter['name'] = 'u' parameter['type'] = 'uint' parameter.addContent('123') parameter = parameters.addElement((None, 'parameter')) parameter['name'] = 'i' parameter['type'] = 'int' parameter.addContent('-123') stream.send(presence) # text channel event, new_event = q.expect_many( EventPattern('dbus-signal', signal='NewChannel'), EventPattern('dbus-signal', signal='NewChannels')) assert event.args[1] == cs.CHANNEL_TYPE_TEXT, event.args channels = new_event.args[0] assert len(channels) == 1 path, props = channels[0] assert props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_TEXT # tubes channel is automatically created event, new_event = q.expect_many( EventPattern('dbus-signal', signal='NewChannel'), EventPattern('dbus-signal', signal='NewChannels')) assert event.args[1] == cs.CHANNEL_TYPE_TUBES, event.args assert event.args[2] == cs.HT_ROOM assert event.args[3] == room_handle tubes_chan = bus.get_object(conn.bus_name, event.args[0]) tubes_iface = dbus.Interface(tubes_chan, event.args[1]) channel_props = tubes_chan.GetAll(cs.CHANNEL, dbus_interface=cs.PROPERTIES_IFACE) assert channel_props['TargetID'] == '*****@*****.**', channel_props assert channel_props['Requested'] == False assert channel_props['InitiatorID'] == '' assert channel_props['InitiatorHandle'] == 0 channels = new_event.args[0] assert len(channels) == 1 path, props = channels[0] assert props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_TUBES tubes_self_handle = tubes_chan.GetSelfHandle(dbus_interface=cs.CHANNEL_IFACE_GROUP) q.expect('dbus-signal', signal='NewTube', args=[stream_tube_id, bob_handle, 1, 'echo', sample_parameters, 0]) expected_tube = (stream_tube_id, bob_handle, cs.TUBE_TYPE_STREAM, 'echo', sample_parameters, cs.TUBE_STATE_LOCAL_PENDING) tubes = tubes_iface.ListTubes(byte_arrays=True) assert tubes == [( stream_tube_id, bob_handle, 1, # Stream 'echo', sample_parameters, cs.TUBE_CHANNEL_STATE_LOCAL_PENDING )] assert len(tubes) == 1, unwrap(tubes) t.check_tube_in_tubes(expected_tube, tubes) # tube channel is also announced (new API) new_event = q.expect('dbus-signal', signal='NewChannels') channels = new_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] == bob_handle assert props[cs.INITIATOR_ID] == '[email protected]/bob' assert props[cs.INTERFACES] == [cs.CHANNEL_IFACE_GROUP, cs.CHANNEL_IFACE_TUBE] assert props[cs.REQUESTED] == False assert props[cs.TARGET_HANDLE] == room_handle assert props[cs.TARGET_ID] == '*****@*****.**' assert props[cs.STREAM_TUBE_SERVICE] == 'echo' assert props[cs.TUBE_PARAMETERS] == {'s': 'hello', 'ay': 'hello', 'u': 123, 'i': -123} assert access_control in \ props[cs.STREAM_TUBE_SUPPORTED_SOCKET_TYPES][address_type] 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_LOCAL_PENDING # Accept the tube call_async(q, tubes_iface, 'AcceptStreamTube', stream_tube_id, address_type, access_control, access_control_param, byte_arrays=True) accept_return_event, _ = q.expect_many( EventPattern('dbus-return', method='AcceptStreamTube'), EventPattern('dbus-signal', signal='TubeStateChanged', args=[stream_tube_id, 2])) address = accept_return_event.value[0] socket_event, si_event, conn_id = t.connect_to_cm_socket(q, '[email protected]/bob', address_type, address, access_control, access_control_param) protocol = socket_event.protocol protocol.sendData("hello initiator") def accept_tube_si_connection(): bytestream, profile = create_from_si_offer(stream, q, bytestream_cls, si_event.stanza, '[email protected]/test') assert profile == ns.TUBES muc_stream_node = xpath.queryForNodes('/iq/si/muc-stream[@xmlns="%s"]' % ns.TUBES, si_event.stanza)[0] assert muc_stream_node is not None assert muc_stream_node['tube'] == str(stream_tube_id) # set the real jid of the target as 'to' because the XMPP server changes # it when delivering the IQ result, si = bytestream.create_si_reply(si_event.stanza, 'test@localhost/Resource') si.addElement((ns.TUBES, 'tube')) stream.send(result) bytestream.wait_bytestream_open() return bytestream bytestream = accept_tube_si_connection() binary = bytestream.get_data() assert binary == 'hello initiator' # reply on the socket bytestream.send_data('hi joiner!') q.expect('socket-data', protocol=protocol, data="hi joiner!") # peer closes the bytestream bytestream.close() e = q.expect('dbus-signal', signal='ConnectionClosed') assertEquals(conn_id, e.args[0]) assertEquals(cs.CONNECTION_LOST, e.args[1]) # establish another tube connection socket_event, si_event, conn_id = t.connect_to_cm_socket(q, '[email protected]/bob', address_type, address, access_control, access_control_param) # bytestream is refused send_error_reply(stream, si_event.stanza) e, _ = q.expect_many( EventPattern('dbus-signal', signal='ConnectionClosed'), EventPattern('socket-disconnected')) assertEquals(conn_id, e.args[0]) assertEquals(cs.CONNECTION_REFUSED, e.args[1]) # establish another tube connection socket_event, si_event, conn_id = t.connect_to_cm_socket(q, '[email protected]/bob', address_type, address, access_control, access_control_param) protocol = socket_event.protocol bytestream = accept_tube_si_connection() # disconnect local socket protocol.transport.loseConnection() e, _ = q.expect_many( EventPattern('dbus-signal', signal='ConnectionClosed'), EventPattern('socket-disconnected')) assertEquals(conn_id, e.args[0]) assertEquals(cs.CANCELLED, e.args[1]) # OK, we're done disconnect_conn(q, conn, stream, [EventPattern('dbus-signal', signal='TubeClosed', args=[stream_tube_id])])
def test(q, bus, conn, stream, bytestream_cls, address_type, access_control, access_control_param): if access_control == cs.SOCKET_ACCESS_CONTROL_CREDENTIALS: print "Skip Socket_Access_Control_Credentials (fdo #45445)" return vcard_event, roster_event, disco_event = q.expect_many( EventPattern('stream-iq', to=None, query_ns='vcard-temp', query_name='vCard'), EventPattern('stream-iq', query_ns=ns.ROSTER), EventPattern('stream-iq', to='localhost', query_ns=ns.DISCO_ITEMS)) acknowledge_iq(stream, vcard_event.stanza) announce_socks5_proxy(q, stream, disco_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) # Send Bob presence and his caps presence = domish.Element(('jabber:client', 'presence')) presence['from'] = 'bob@localhost/Bob' presence['to'] = 'test@localhost/Resource' 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@localhost/Bob') 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) sync_dbus(bus, q, conn) # Receive a tube offer from Bob (new_tube_chan, new_tube_iface) = \ receive_tube_offer(q, bus, conn, stream) # Try bad parameters on the new iface call_async(q, new_tube_iface, 'Accept', 20, 0, '', byte_arrays=True) q.expect('dbus-error', method='Accept') call_async(q, new_tube_iface, 'Accept', 0, 1, '', byte_arrays=True) q.expect('dbus-error', method='Accept') # Receive a tube offer from Bob (new_tube_chan, new_tube_iface) = \ receive_tube_offer(q, bus, conn, stream) # Accept the tube with new iface, and use UNIX sockets call_async(q, new_tube_iface, 'Accept', address_type, access_control, access_control_param, byte_arrays=True) accept_return_event, _ = q.expect_many( EventPattern('dbus-return', method='Accept'), EventPattern('dbus-signal', signal='TubeChannelStateChanged', args=[2])) socket_address = accept_return_event.value[0] bytestream, conn_id = expect_tube_activity(q, bus, conn, stream, bytestream_cls, address_type, socket_address, access_control, access_control_param) # peer closes the bytestream bytestream.close() e = q.expect('dbus-signal', signal='ConnectionClosed') assertEquals(conn_id, e.args[0]) assertEquals(cs.CONNECTION_LOST, e.args[1]) # establish another tube connection event_socket, si_event, conn_id = t.connect_to_cm_socket( q, bob_jid, address_type, socket_address, access_control, access_control_param) # bytestream is refused send_error_reply(stream, si_event.stanza) e = q.expect('dbus-signal', signal='ConnectionClosed') assertEquals(conn_id, e.args[0]) assertEquals(cs.CONNECTION_REFUSED, e.args[1]) new_tube_chan.Close() # Receive a tube offer from Bob (new_tube_chan, new_tube_iface) = \ receive_tube_offer(q, bus, conn, stream) # Just close the tube new_tube_chan.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 if access_control == cs.SOCKET_ACCESS_CONTROL_CREDENTIALS: print "Skip Socket_Access_Control_Credentials (fdo #45445)" return iq_event, disco_event = q.expect_many( EventPattern('stream-iq', to=None, query_ns='vcard-temp', query_name='vCard'), EventPattern('stream-iq', to='localhost', query_ns=ns.DISCO_ITEMS)) acknowledge_iq(stream, iq_event.stanza) announce_socks5_proxy(q, stream, disco_event.stanza) # join the muc 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_many( EventPattern('dbus-signal', signal='MembersChangedDetailed', predicate=lambda e: e.args[0] == [] and # added e.args[1] == [] and # removed e.args[2] == [] and # local pending len(e.args[3]) == 1 and # remote pending e.args[4].get('actor', 0) == 0 and e.args[4].get('change-reason', 0) == 0 and e.args[4]['contact-ids'][e.args[3][0]] == '[email protected]/test'), EventPattern('stream-presence', to='[email protected]/test')) # Send presence for other member of room. stream.send(make_muc_presence('owner', 'moderator', '*****@*****.**', 'bob')) # Send presence for own membership of room. stream.send(make_muc_presence('none', 'participant', '*****@*****.**', 'test')) event = q.expect('dbus-signal', signal='MembersChangedDetailed', predicate=lambda e: len(e.args[0]) == 2 and # added e.args[1] == [] and # removed e.args[2] == [] and # local pending e.args[3] == [] and # remote pending e.args[4].get('actor', 0) == 0 and e.args[4].get('change-reason', 0) == 0 and set([e.args[4]['contact-ids'][h] for h in e.args[0]]) == set(['[email protected]/test', '[email protected]/bob'])) for h in event.args[0]: if event.args[4]['contact-ids'][h] == '[email protected]/bob': bob_handle = h event = q.expect('dbus-return', method='CreateChannel') # Bob offers a stream tube stream_tube_id = 666 presence = make_muc_presence('owner', 'moderator', '*****@*****.**', 'bob') tubes = presence.addElement((ns.TUBES, 'tubes')) tube = tubes.addElement((None, 'tube')) tube['type'] = 'stream' tube['service'] = 'echo' tube['id'] = str(stream_tube_id) parameters = tube.addElement((None, 'parameters')) parameter = parameters.addElement((None, 'parameter')) parameter['name'] = 's' parameter['type'] = 'str' parameter.addContent('hello') parameter = parameters.addElement((None, 'parameter')) parameter['name'] = 'ay' parameter['type'] = 'bytes' parameter.addContent('aGVsbG8=') parameter = parameters.addElement((None, 'parameter')) parameter['name'] = 'u' parameter['type'] = 'uint' parameter.addContent('123') parameter = parameters.addElement((None, 'parameter')) parameter['name'] = 'i' parameter['type'] = 'int' parameter.addContent('-123') stream.send(presence) # text channel new_event = q.expect('dbus-signal', signal='NewChannels') channels = new_event.args[0] assert len(channels) == 1 path, props = channels[0] assert props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_TEXT def new_chan_predicate(e): path, props = e.args[0][0] return props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_STREAM_TUBE # tube channel is announced new_event = q.expect('dbus-signal', signal='NewChannels', predicate=new_chan_predicate) channels = new_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] == bob_handle assert props[cs.INITIATOR_ID] == '[email protected]/bob' assertSameSets([cs.CHANNEL_IFACE_GROUP, cs.CHANNEL_IFACE_TUBE], props[cs.INTERFACES]) assert props[cs.REQUESTED] == False assert props[cs.TARGET_ID] == '*****@*****.**' assert props[cs.STREAM_TUBE_SERVICE] == 'echo' assert props[cs.TUBE_PARAMETERS] == {'s': 'hello', 'ay': 'hello', 'u': 123, 'i': -123} assert access_control in \ props[cs.STREAM_TUBE_SUPPORTED_SOCKET_TYPES][address_type] 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) tube_iface = dbus.Interface(tube_chan, cs.CHANNEL_TYPE_STREAM_TUBE) assert tube_props['Parameters'] == sample_parameters assert tube_props['State'] == cs.TUBE_CHANNEL_STATE_LOCAL_PENDING # Accept the tube call_async(q, tube_iface, 'Accept', address_type, access_control, access_control_param, byte_arrays=True) accept_return_event, _ = q.expect_many( EventPattern('dbus-return', method='Accept'), EventPattern('dbus-signal', signal='TubeChannelStateChanged', args=[2])) address = accept_return_event.value[0] socket_event, si_event, conn_id = t.connect_to_cm_socket(q, '[email protected]/bob', address_type, address, access_control, access_control_param) protocol = socket_event.protocol protocol.sendData("hello initiator") def accept_tube_si_connection(): bytestream, profile = create_from_si_offer(stream, q, bytestream_cls, si_event.stanza, '[email protected]/test') assert profile == ns.TUBES muc_stream_node = xpath.queryForNodes('/iq/si/muc-stream[@xmlns="%s"]' % ns.TUBES, si_event.stanza)[0] assert muc_stream_node is not None assert muc_stream_node['tube'] == str(stream_tube_id) # set the real jid of the target as 'to' because the XMPP server changes # it when delivering the IQ result, si = bytestream.create_si_reply(si_event.stanza, 'test@localhost/Resource') si.addElement((ns.TUBES, 'tube')) stream.send(result) bytestream.wait_bytestream_open() return bytestream bytestream = accept_tube_si_connection() binary = bytestream.get_data() assert binary == 'hello initiator' # reply on the socket bytestream.send_data('hi joiner!') q.expect('socket-data', protocol=protocol, data="hi joiner!") # peer closes the bytestream bytestream.close() e = q.expect('dbus-signal', signal='ConnectionClosed') assertEquals(conn_id, e.args[0]) assertEquals(cs.CONNECTION_LOST, e.args[1]) # establish another tube connection socket_event, si_event, conn_id = t.connect_to_cm_socket(q, '[email protected]/bob', address_type, address, access_control, access_control_param) # bytestream is refused send_error_reply(stream, si_event.stanza) e, _ = q.expect_many( EventPattern('dbus-signal', signal='ConnectionClosed'), EventPattern('socket-disconnected')) assertEquals(conn_id, e.args[0]) assertEquals(cs.CONNECTION_REFUSED, e.args[1]) # establish another tube connection socket_event, si_event, conn_id = t.connect_to_cm_socket(q, '[email protected]/bob', address_type, address, access_control, access_control_param) protocol = socket_event.protocol bytestream = accept_tube_si_connection() # disconnect local socket protocol.transport.loseConnection() e, _ = q.expect_many( EventPattern('dbus-signal', signal='ConnectionClosed'), EventPattern('socket-disconnected')) assertEquals(conn_id, e.args[0]) assertEquals(cs.CANCELLED, e.args[1]) # OK, we're done disconnect_conn(q, conn, stream)