1 2""" 3Test connecting to a server with 2 accounts. Check one account does not block 4the second account. 5""" 6 7import os 8import sys 9import dbus 10import servicetest 11 12from twisted.words.xish import domish 13from twisted.words.protocols.jabber import xmlstream 14import twisted.internet.protocol 15from twisted.internet import reactor 16 17from servicetest import (Event, unwrap) 18 19from gabbletest import ( 20 make_connection, make_stream, XmppAuthenticator, XmppXmlStream, 21 disconnect_conn, GabbleAuthenticator) 22import constants as cs 23 24NS_XMPP_TLS = 'urn:ietf:params:xml:ns:xmpp-tls' 25NS_XMPP_SASL = 'urn:ietf:params:xml:ns:xmpp-sasl' 26 27class BlockForeverTlsAuthenticator(GabbleAuthenticator): 28 """A TLS stream authenticator that is deliberately broken. It sends 29 <proceed/> to the client but then do nothing, so the TLS handshake will 30 not work. Useful for testing regression of bug #14341.""" 31 32 def __init__(self, username, password): 33 GabbleAuthenticator.__init__(self, username, password) 34 self.username = username 35 self.password = password 36 self.authenticated = False 37 38 def streamStarted(self, root=None): 39 if root: 40 self.xmlstream.sid = root.getAttribute('id') 41 42 self.xmlstream.sendHeader() 43 44 features = domish.Element((xmlstream.NS_STREAMS, 'features')) 45 mechanisms = features.addElement((NS_XMPP_SASL, 'mechanisms')) 46 mechanism = mechanisms.addElement('mechanism', content='DIGEST-MD5') 47 starttls = features.addElement((NS_XMPP_TLS, 'starttls')) 48 starttls.addElement('required') 49 self.xmlstream.send(features) 50 51 self.xmlstream.addOnetimeObserver("/starttls", self.auth) 52 53 def auth(self, auth): 54 proceed = domish.Element((NS_XMPP_TLS, 'proceed')) 55 self.xmlstream.send(proceed) 56 57 return; # auth blocks 58 59 self.xmlstream.reset() 60 self.authenticated = True 61 62 63def test(q, bus, conn1, conn2, stream1, stream2): 64 # Connection 1 65 conn1.Connect() 66 q.expect('dbus-signal', signal='StatusChanged', 67 args=[cs.CONN_STATUS_CONNECTING, cs.CSR_REQUESTED]) 68 69 # Connection 1 blocks because the fake jabber server behind conn1 does not 70 # proceed to the tls handshake. The second connection is independant and 71 # should work. 72 73 # Connection 2 74 conn2.Connect() 75 q.expect('dbus-signal', signal='StatusChanged', 76 args=[cs.CONN_STATUS_CONNECTING, cs.CSR_REQUESTED]) 77 q.expect('stream-authenticated') 78 q.expect('dbus-signal', signal='PresencesChanged', 79 args=[{1L: (cs.PRESENCE_AVAILABLE, 'available', '')}]) 80 q.expect('dbus-signal', signal='StatusChanged', 81 args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED]) 82 83 # Disconnection 2 84 disconnect_conn(q, conn2, stream2) 85 86if __name__ == '__main__': 87 queue = servicetest.IteratingEventQueue(None) 88 queue.verbose = ( 89 os.environ.get('CHECK_TWISTED_VERBOSE', '') != '' 90 or '-v' in sys.argv) 91 92 bus = dbus.SessionBus() 93 94 params = { 95 'account': 'test1@localhost/Resource', 96 'password': 'pass', 97 'resource': 'Resource', 98 'server': 'localhost', 99 'port': dbus.UInt32(4242), 100 } 101 conn1, jid1 = make_connection(bus, queue.append, params) 102 authenticator = BlockForeverTlsAuthenticator('test1', 'pass') 103 stream1 = make_stream(queue.append, authenticator, protocol=XmppXmlStream) 104 105 factory = twisted.internet.protocol.Factory() 106 factory.protocol = lambda:stream1 107 port1 = reactor.listenTCP(4242, factory, interface='localhost') 108 109 params = { 110 'account': 'test2@localhost/Resource', 111 'password': 'pass', 112 'resource': 'Resource', 113 'server': 'localhost', 114 'port': dbus.UInt32(4343), 115 } 116 conn2, jid2 = make_connection(bus, queue.append, params) 117 authenticator = XmppAuthenticator('test2', 'pass') 118 stream2 = make_stream(queue.append, authenticator, protocol=XmppXmlStream) 119 120 factory = twisted.internet.protocol.Factory() 121 factory.protocol = lambda:stream2 122 port1 = reactor.listenTCP(4343, factory, interface='localhost') 123 124 125 bus.add_signal_receiver( 126 lambda *args, **kw: 127 queue.append(Event('dbus-signal', 128 path=unwrap(kw['path']), 129 signal=kw['member'], args=map(unwrap, args), 130 interface=kw['interface'])), 131 None, # signal name 132 None, # interface 133 None, 134 path_keyword='path', 135 member_keyword='member', 136 interface_keyword='interface', 137 byte_arrays=True 138 ) 139 140 try: 141 test(queue, bus, conn1, conn2, stream1, stream2) 142 finally: 143 try: 144 conn1.Disconnect() 145 conn2.Disconnect() 146 except dbus.DBusException, e: 147 pass 148 149