Exemple #1
0
    def test_auth_fail(self):
        handler = EventRecorder()
        settings = XMPPSettings({
            u"username": u"user",
            u"password": u"bad",
        })
        self.stream = StreamBase(u"jabber:client", None,
                                 [StreamSASLHandler(settings), handler],
                                 settings)
        self.start_transport([handler])
        self.stream.initiate(self.transport)
        self.connect_transport()
        self.server.write(C2S_SERVER_STREAM_HEAD)
        self.server.write(AUTH_FEATURES)
        xml = self.wait(expect=re.compile(br".*(<auth.*</auth>)"))
        self.assertIsNotNone(xml)
        element = ElementTree.XML(xml)
        self.assertEqual(element.tag, "{urn:ietf:params:xml:ns:xmpp-sasl}auth")
        mech = element.get("mechanism")
        self.assertEqual(mech, "PLAIN")
        data = binascii.a2b_base64(element.text.encode("utf-8"))
        self.assertNotEqual(data, b"\000user\000secret")
        self.server.write(
            b"""<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
<not-authorized/></failure>""")
        with self.assertRaises(SASLAuthenticationFailed):
            self.wait()
        self.assertFalse(self.stream.authenticated)
        self.server.disconnect()
        self.wait()
        event_classes = [e.__class__ for e in handler.events_received]
        self.assertEqual(event_classes, [
            ConnectingEvent, ConnectedEvent, StreamConnectedEvent,
            GotFeaturesEvent, DisconnectedEvent
        ])
Exemple #2
0
 def test_bind_no_resource(self):
     handler = AuthorizedEventHandler()
     handlers = [ResourceBindingHandler(), handler]
     processor = StanzaProcessor()
     processor.setup_stanza_handlers(handlers, "post-auth")
     self.stream = StreamBase(u"jabber:client", processor, handlers)
     processor.uplink = self.stream
     self.stream.me = JID("[email protected]")
     self.start_transport([handler])
     self.stream.initiate(self.transport)
     self.connect_transport()
     self.server.write(C2S_SERVER_STREAM_HEAD)
     self.wait_short(1)
     self.server.write(BIND_FEATURES)
     req_id = self.wait(
         1, expect=re.compile(br".*<iq[^>]*id=[\"']([^\"']*)[\"']"))
     self.assertIsNotNone(req_id)
     req_id = req_id.decode("utf-8")
     self.server.write(
         BIND_GENERATED_RESPONSE.format(req_id).encode("utf-8"))
     self.wait()
     self.assertFalse(self.stream.is_connected())
     event_classes = [e.__class__ for e in handler.events_received]
     self.assertEqual(event_classes, [
         ConnectingEvent, ConnectedEvent, StreamConnectedEvent,
         GotFeaturesEvent, BindingResourceEvent, AuthorizedEvent,
         DisconnectedEvent
     ])
Exemple #3
0
 def test_parse_error(self):
     handler = IgnoreEventHandler()
     self.start_transport([handler])
     self.stream = StreamBase(u"jabber:client", None, [])
     self.stream.receive(self.transport, self.addr[0])
     self.client.write(C2S_CLIENT_STREAM_HEAD)
     self.wait_short(0.25)
     self.wait_short(0.25)
     self.client.write(b"</stream:test>")
     logger.debug("waiting for exception...")
     with self.assertRaises(StreamParseError):
         self.wait()
     logger.debug(" got it!")
     self.assertFalse(self.stream.is_connected())
     self.wait_short(0.1)
     logger.debug("waiting for connection close...")
     self.client.wait(1)
     logger.debug(" done")
     self.assertTrue(self.client.eof)
     self.assertTrue(self.client.rdata.endswith(PARSE_ERROR_RESPONSE))
     self.client.disconnect()
     logger.debug("final wait...")
     self.wait()
     logger.debug(" done")
     event_classes = [e.__class__ for e in handler.events_received]
     self.assertEqual(event_classes,
                      [StreamConnectedEvent, DisconnectedEvent])
Exemple #4
0
 def test_required_missing(self):
     """Test TLS required in settings, and missing on the server."""
     self.start_server()
     settings = XMPPSettings({
         u"starttls":
         True,
         u"tls_require":
         True,
         u"tls_cacert_file":
         os.path.join(DATA_DIR, "ca.pem"),
     })
     handler = EventRecorder()
     handlers = [StreamTLSHandler(settings), handler]
     self.stream = StreamBase(u"jabber:client", None, handlers, settings)
     self.start_transport(handlers)
     self.stream.initiate(self.transport, to="server.example.org")
     self.connect_transport()
     self.server.write(C2S_SERVER_STREAM_HEAD)
     self.server.write(EMPTY_FEATURES)
     self.server.write(b"</stream:stream>")
     with self.assertRaises(TLSNegotiationFailed):
         self.wait()
     self.server.disconnect()
     self.wait()
     event_classes = [e.__class__ for e in handler.events_received]
     self.assertEqual(event_classes, [
         ConnectingEvent, ConnectedEvent, StreamConnectedEvent,
         GotFeaturesEvent, DisconnectedEvent
     ])
Exemple #5
0
 def test_stanza_receive(self):
     handler = IgnoreEventHandler()
     route = RecordingRoute()
     self.stream = StreamBase(u"jabber:client", route, [])
     self.start_transport([handler])
     self.stream.initiate(self.transport)
     self.connect_transport()
     logger.debug("-- waiting for connect")
     self.wait_short(0.25)
     self.wait_short(0.25)
     logger.debug("-- checking connected")
     self.assertTrue(self.stream.is_connected())
     self.server.write(C2S_SERVER_STREAM_HEAD)
     self.server.write(b"<message><body>Test</body></message>")
     self.server.write(STREAM_TAIL)
     self.server.disconnect()
     self.wait(expect=re.compile(b".*(</stream:stream>)"))
     self.stream.disconnect()
     self.wait()
     self.assertEqual(route.sent, [])
     self.assertEqual(len(route.received), 1)
     stanza = route.received[0]
     self.assertIsInstance(stanza, Message)
     self.assertEqual(stanza.body, u"Test")
     event_classes = [e.__class__ for e in handler.events_received]
     self.assertEqual(event_classes, [
         ConnectingEvent, ConnectedEvent, StreamConnectedEvent,
         DisconnectedEvent
     ])
Exemple #6
0
 def test_stanza_send(self):
     handler = IgnoreEventHandler()
     route = RecordingRoute()
     self.stream = StreamBase(u"jabber:client", route, [])
     self.start_transport([handler])
     self.stream.initiate(self.transport)
     self.connect_transport()
     self.server.write(C2S_SERVER_STREAM_HEAD)
     self.wait_short(0.25)
     self.wait_short(0.25)
     self.assertTrue(self.stream.is_connected())
     self.stream.send(Message(to_jid=JID(u"*****@*****.**"),
                              body=u"Test"))
     xml = self.wait(expect=re.compile(b".*(<message.*</message>)"))
     self.assertIsNotNone(xml)
     if b"xmlns" not in xml:
         xml = xml.replace(b"<message", b"<message xmlns='jabber:client'")
     element = XML(xml)
     stanza = Message(element)
     self.assertEqual(stanza.body, u"Test")
     self.stream.disconnect()
     self.server.write(STREAM_TAIL)
     self.server.disconnect()
     self.wait()
     self.assertEqual(route.sent, [])
     self.assertEqual(route.received, [])
     event_classes = [e.__class__ for e in handler.events_received]
     self.assertEqual(event_classes, [
         ConnectingEvent, ConnectedEvent, StreamConnectedEvent,
         DisconnectedEvent
     ])
Exemple #7
0
 def test_parse_error(self):
     handler = IgnoreEventHandler()
     self.stream = StreamBase(u"jabber:client", None, [])
     self.start_transport([handler])
     self.stream.initiate(self.transport)
     self.connect_transport()
     self.server.write(C2S_SERVER_STREAM_HEAD)
     self.wait_short()
     self.server.write(b"</stream:test>")
     with self.assertRaises(StreamParseError):
         logger.debug("-- WAIT start")
         self.wait()
         logger.debug("-- WAIT end")
     self.assertFalse(self.stream.is_connected())
     self.wait_short()
     self.server.wait(1)
     self.assertTrue(self.server.eof)
     self.assertTrue(self.server.rdata.endswith(PARSE_ERROR_RESPONSE))
     self.server.disconnect()
     self.wait()
     event_classes = [e.__class__ for e in handler.events_received]
     self.assertEqual(event_classes, [
         ConnectingEvent, ConnectedEvent, StreamConnectedEvent,
         DisconnectedEvent
     ])
Exemple #8
0
 def test_bind_resource(self):
     handler = EventRecorder()
     handlers = [ResourceBindingHandler(), handler]
     processor = StanzaProcessor()
     self.start_transport(handlers)
     self.stream = StreamBase(u"jabber:client", processor, handlers)
     processor.uplink = self.stream
     self.stream.receive(self.transport, self.addr[0])
     self.stream.set_peer_authenticated(JID("[email protected]"))
     processor.setup_stanza_handlers(handlers, "post-auth")
     self.client.write(C2S_CLIENT_STREAM_HEAD)
     features = self.wait(
         expect=re.compile(br".*<stream:features>"
                           br"(.*<bind.*urn:ietf:params:xml:ns:xmpp-bind.*)"
                           br"</stream:features>"))
     self.assertIsNotNone(features)
     self.client.write(BIND_PROVIDED_REQUEST)
     resource = self.wait(expect=re.compile(
         br".*<iq.*id=(?:\"42\"|'42').*>"
         br"<bind.*<jid>[email protected]/(.*)</jid>.*</bind>"))
     self.assertEqual(resource, b"Provided")
     self.client.write(STREAM_TAIL)
     self.client.disconnect()
     self.wait()
     event_classes = [e.__class__ for e in handler.events_received]
     self.assertEqual(event_classes, [
         AuthenticatedEvent, StreamConnectedEvent, AuthorizedEvent,
         DisconnectedEvent
     ])
Exemple #9
0
class TestBindingInitiator(InitiatorSelectTestCase):
    def test_bind_no_resource(self):
        handler = AuthorizedEventHandler()
        handlers = [ResourceBindingHandler(), handler]
        processor = StanzaProcessor()
        processor.setup_stanza_handlers(handlers, "post-auth")
        self.stream = StreamBase(u"jabber:client", processor, handlers)
        processor.uplink = self.stream
        self.stream.me = JID("[email protected]")
        self.start_transport([handler])
        self.stream.initiate(self.transport)
        self.connect_transport()
        self.server.write(C2S_SERVER_STREAM_HEAD)
        self.wait_short(1)
        self.server.write(BIND_FEATURES)
        req_id = self.wait(1,
                    expect = re.compile(br".*<iq[^>]*id=[\"']([^\"']*)[\"']"))
        self.assertIsNotNone(req_id)
        req_id = req_id.decode("utf-8")
        self.server.write(BIND_GENERATED_RESPONSE.format(req_id)
                                                            .encode("utf-8"))
        self.wait()
        self.assertFalse(self.stream.is_connected())
        event_classes = [e.__class__ for e in handler.events_received]
        self.assertEqual(event_classes, [ConnectingEvent,
                    ConnectedEvent, StreamConnectedEvent, GotFeaturesEvent,
                    BindingResourceEvent, AuthorizedEvent, DisconnectedEvent])
 
    def test_bind(self):
        handler = AuthorizedEventHandler()
        handlers = [ResourceBindingHandler(), handler]
        processor = StanzaProcessor()
        processor.setup_stanza_handlers(handlers, "post-auth")
        self.stream = StreamBase(u"jabber:client", processor, handlers,
                                        XMPPSettings({"resource": "Provided"}))
        processor.uplink = self.stream
        self.stream.me = JID("[email protected]")
        self.start_transport([handler])
        self.stream.initiate(self.transport)
        self.connect_transport()
        self.server.write(C2S_SERVER_STREAM_HEAD)
        self.wait_short(1)
        self.server.write(BIND_FEATURES)
        req_id = self.wait(1,
                    expect = re.compile(br".*<iq[^>]*id=[\"']([^\"']*)[\"'].*"
                                            br"<resource>Provided</resource>"))
        self.assertIsNotNone(req_id)
        req_id = req_id.decode("utf-8")
        self.server.write(BIND_PROVIDED_RESPONSE.format(req_id).encode("utf-8"))
        self.wait()
        event_classes = [e.__class__ for e in handler.events_received]
        self.assertEqual(event_classes, [ConnectingEvent,
                    ConnectedEvent, StreamConnectedEvent, GotFeaturesEvent,
                    BindingResourceEvent, AuthorizedEvent, DisconnectedEvent])
Exemple #10
0
 def test_connect_close(self):
     handler = JustConnectEventHandler()
     self.stream = StreamBase(u"jabber:client", None, [])
     self.start_transport([handler])
     self.stream.initiate(self.transport)
     self.connect_transport()
     self.wait()
     self.assertFalse(self.stream.is_connected())
     event_classes = [e.__class__ for e in handler.events_received]
     self.assertEqual(event_classes,
                      [ConnectingEvent, ConnectedEvent, DisconnectedEvent])
Exemple #11
0
 def test_stream_connect_disconnect(self):
     handler = JustStreamConnectEventHandler()
     self.start_transport([handler])
     self.stream = StreamBase(u"jabber:client", None, [])
     self.stream.receive(self.transport, self.addr[0])
     self.client.write(C2S_CLIENT_STREAM_HEAD)
     self.wait_short(0.25)
     self.wait_short(0.25)
     self.client.write(STREAM_TAIL)
     self.wait()
     self.assertFalse(self.stream.is_connected())
     event_classes = [e.__class__ for e in handler.events_received]
     self.assertEqual(event_classes,
                      [StreamConnectedEvent, DisconnectedEvent])
 def test_stanza_send(self):
     handler = IgnoreEventHandler()
     route = RecordingRoute()
     self.stream = StreamBase("jabber:client", route, [])
     self.start_transport([handler])
     self.stream.initiate(self.transport)
     self.connect_transport()
     self.server.write(C2S_SERVER_STREAM_HEAD)
     self.wait_short(0.25)
     self.wait_short(0.25)
     self.assertTrue(self.stream.is_connected())
     self.stream.send(Message(to_jid = JID("*****@*****.**"),
                                                         body = "Test"))
     xml = self.wait(expect = re.compile(b".*(<message.*</message>)"))
     self.assertIsNotNone(xml)
     if b"xmlns" not in xml:
         xml = xml.replace(b"<message", b"<message xmlns='jabber:client'")
     element = XML(xml)
     stanza = Message(element)
     self.assertEqual(stanza.body, "Test")
     self.stream.disconnect()
     self.server.write(STREAM_TAIL)
     self.server.disconnect()
     self.wait()
     self.assertEqual(route.sent, [])
     self.assertEqual(route.received, [])
     event_classes = [e.__class__ for e in handler.events_received]
     self.assertEqual(event_classes, [ConnectingEvent, ConnectedEvent,
                                 StreamConnectedEvent, DisconnectedEvent])
 def test_stanza_receive(self):
     handler = IgnoreEventHandler()
     route = RecordingRoute()
     self.stream = StreamBase("jabber:client", route, [])
     self.start_transport([handler])
     self.stream.initiate(self.transport)
     self.connect_transport()
     logger.debug("-- waiting for connect")
     self.wait_short(0.25)
     self.wait_short(0.25)
     logger.debug("-- checking connected")
     self.assertTrue(self.stream.is_connected())
     self.server.write(C2S_SERVER_STREAM_HEAD)
     self.server.write(b"<message><body>Test</body></message>")
     self.server.write(STREAM_TAIL)
     self.server.disconnect()
     self.wait(expect = re.compile(b".*(</stream:stream>)"))
     self.stream.disconnect()
     self.wait()
     self.assertEqual(route.sent, [])
     self.assertEqual(len(route.received), 1)
     stanza = route.received[0]
     self.assertIsInstance(stanza, Message)
     self.assertEqual(stanza.body, "Test")
     event_classes = [e.__class__ for e in handler.events_received]
     self.assertEqual(event_classes, [ConnectingEvent, ConnectedEvent,
                                 StreamConnectedEvent, DisconnectedEvent])
 def test_parse_error(self):
     handler = IgnoreEventHandler()
     self.start_transport([handler])
     self.stream = StreamBase("jabber:client", None, [])
     self.stream.receive(self.transport, self.addr[0])
     self.client.write(C2S_CLIENT_STREAM_HEAD)
     self.wait_short(0.25)
     self.wait_short(0.25)
     self.client.write(b"</stream:test>")
     logger.debug("waiting for exception...")
     with self.assertRaises(StreamParseError):
         self.wait()
     logger.debug(" got it!")
     self.assertFalse(self.stream.is_connected())
     self.wait_short(0.1)
     logger.debug("waiting for connection close...")
     self.client.wait(1)
     logger.debug(" done")
     self.assertTrue(self.client.eof)
     self.assertTrue(self.client.rdata.endswith(PARSE_ERROR_RESPONSE))
     self.client.disconnect()
     logger.debug("final wait...")
     self.wait()
     logger.debug(" done")
     event_classes = [e.__class__ for e in handler.events_received]
     self.assertEqual(event_classes, [StreamConnectedEvent,
                                                     DisconnectedEvent])
    def test_auth_fail(self):
        handler = EventRecorder()
        settings = XMPPSettings({
                                "username": "******", 
                                "password": "******",
                                })
        self.stream = StreamBase("jabber:client", None,
                            [StreamSASLHandler(settings), handler], settings)
        self.start_transport([handler])
        self.stream.initiate(self.transport)
        self.connect_transport()
        self.server.write(C2S_SERVER_STREAM_HEAD)
        self.server.write(AUTH_FEATURES)
        xml = self.wait(expect = re.compile(br".*(<auth.*</auth>)"))
        self.assertIsNotNone(xml)
        element = ElementTree.XML(xml)
        self.assertEqual(element.tag, "{urn:ietf:params:xml:ns:xmpp-sasl}auth")
        mech = element.get("mechanism")
        self.assertEqual(mech, "PLAIN")
        data = binascii.a2b_base64(element.text.encode("utf-8"))
        self.assertNotEqual(data, b"\000user\000secret")
        self.server.write(b"""<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
<not-authorized/></failure>""")
        with self.assertRaises(SASLAuthenticationFailed):
            self.wait()
        self.assertFalse(self.stream.authenticated)
        self.server.disconnect()
        self.wait()
        event_classes = [e.__class__ for e in handler.events_received]
        self.assertEqual(event_classes, [ConnectingEvent, ConnectedEvent,
                    StreamConnectedEvent, GotFeaturesEvent, DisconnectedEvent])
 def test_required_missing(self):
     """Test TLS required in settings, and missing on the server."""
     self.start_server()
     settings = XMPPSettings({
                     "starttls": True, 
                     "tls_require": True, 
                     "tls_cacert_file": os.path.join(DATA_DIR, "ca.pem"), 
                             })
     handler = EventRecorder()
     handlers = [StreamTLSHandler(settings), handler]
     self.stream = StreamBase("jabber:client", None, handlers, settings)
     self.start_transport(handlers)
     self.stream.initiate(self.transport, to = "server.example.org")
     self.connect_transport()
     self.server.write(C2S_SERVER_STREAM_HEAD)
     self.server.write(EMPTY_FEATURES)
     self.server.write(b"</stream:stream>")
     with self.assertRaises(TLSNegotiationFailed):
         self.wait()
     self.server.disconnect()
     self.wait()
     event_classes = [e.__class__ for e in handler.events_received]
     self.assertEqual(event_classes, [ConnectingEvent,
                 ConnectedEvent, StreamConnectedEvent, GotFeaturesEvent,
                 DisconnectedEvent])
Exemple #17
0
 def test_bind_resource(self):
     handler = EventRecorder()
     handlers = [ResourceBindingHandler(), handler]
     processor = StanzaProcessor()
     self.start_transport(handlers)
     self.stream = StreamBase(u"jabber:client", processor, handlers)
     processor.uplink = self.stream
     self.stream.receive(self.transport, self.addr[0])
     self.stream.set_peer_authenticated(JID("[email protected]"))
     processor.setup_stanza_handlers(handlers, "post-auth")
     self.client.write(C2S_CLIENT_STREAM_HEAD)
     features = self.wait(
             expect = re.compile(br".*<stream:features>"
                 br"(.*<bind.*urn:ietf:params:xml:ns:xmpp-bind.*)"
                                                 br"</stream:features>"))
     self.assertIsNotNone(features)
     self.client.write(BIND_PROVIDED_REQUEST)
     resource = self.wait(
             expect = re.compile(br".*<iq.*id=(?:\"42\"|'42').*>"
                         br"<bind.*<jid>[email protected]/(.*)</jid>.*</bind>"))
     self.assertEqual(resource, b"Provided")
     self.client.write(STREAM_TAIL)
     self.client.disconnect()
     self.wait()
     event_classes = [e.__class__ for e in handler.events_received]
     self.assertEqual(event_classes, [AuthenticatedEvent,
                 StreamConnectedEvent, AuthorizedEvent, DisconnectedEvent])
Exemple #18
0
 def test_enabled_required(self):
     """Test TLS enabled in settings, and required on the server."""
     self.start_server()
     settings = XMPPSettings({
         u"starttls":
         True,
         u"tls_cacert_file":
         os.path.join(DATA_DIR, "ca.pem"),
     })
     handler = EventRecorder()
     handlers = [StreamTLSHandler(settings), handler]
     self.stream = StreamBase(u"jabber:client", None, handlers, settings)
     self.start_transport(handlers)
     self.stream.initiate(self.transport, to="server.example.org")
     self.connect_transport()
     self.server.write(C2S_SERVER_STREAM_HEAD)
     self.server.write(TLS_REQUIRED_FEATURES)
     xml = self.wait(expect=re.compile(br".*(<starttls.*/>)"))
     self.assertIsNotNone(xml)
     element = XML(xml)
     self.assertEqual(element.tag,
                      "{urn:ietf:params:xml:ns:xmpp-tls}starttls")
     self.server.write(PROCEED)
     self.server.starttls(
         self.server.sock,
         keyfile=os.path.join(DATA_DIR, "server-key.pem"),
         certfile=os.path.join(DATA_DIR, "server.pem"),
         server_side=True,
         ca_certs=os.path.join(DATA_DIR, "ca.pem"),
     )
     stream_start = self.wait(expect=re.compile(br"(<stream:stream[^>]*>)"))
     self.assertIsNotNone(stream_start)
     self.assertTrue(self.stream.tls_established)
     self.stream.disconnect()
     self.server.write(C2S_SERVER_STREAM_HEAD)
     self.server.write(EMPTY_FEATURES)
     self.server.write(b"</stream:stream>")
     self.wait()
     event_classes = [e.__class__ for e in handler.events_received]
     self.assertEqual(event_classes, [
         ConnectingEvent, ConnectedEvent, StreamConnectedEvent,
         GotFeaturesEvent, TLSConnectingEvent, TLSConnectedEvent,
         StreamRestartedEvent, GotFeaturesEvent, DisconnectedEvent
     ])
Exemple #19
0
 def test_auth(self):
     handler = EventRecorder()
     self.start_transport([handler])
     settings = XMPPSettings({
         u"user_passwords": {
             u"user": u"secret",
         },
         u"sasl_mechanisms": ["SCRAM-SHA-1", "PLAIN"],
     })
     self.stream = StreamBase(u"jabber:client", None,
                              [StreamSASLHandler(settings), handler],
                              settings)
     self.stream.receive(self.transport, self.addr[0])
     self.client.write(C2S_CLIENT_STREAM_HEAD)
     xml = self.wait(
         expect=re.compile(br".*<stream:features>(.*)</stream:features>"))
     self.assertIsNotNone(xml)
     element = ElementTree.XML(xml)
     self.assertEqual(element.tag,
                      "{urn:ietf:params:xml:ns:xmpp-sasl}mechanisms")
     self.assertEqual(element[0].tag,
                      "{urn:ietf:params:xml:ns:xmpp-sasl}mechanism")
     self.assertEqual(element[0].text, "SCRAM-SHA-1")
     self.assertEqual(element[1].tag,
                      "{urn:ietf:params:xml:ns:xmpp-sasl}mechanism")
     self.assertEqual(element[1].text, "PLAIN")
     response = base64.standard_b64encode(b"\000user\000secret")
     self.client.write(
         PLAIN_AUTH.format(response.decode("utf-8")).encode("utf-8"))
     xml = self.wait(expect=re.compile(br".*(<success.*>)"))
     self.assertIsNotNone(xml)
     self.client.write(C2S_CLIENT_STREAM_HEAD)
     xml = self.wait(expect=re.compile(br".*(<stream:stream.*>)"))
     self.assertIsNotNone(xml)
     self.assertTrue(self.stream.peer_authenticated)
     self.client.write(b"</stream:stream>")
     self.client.disconnect()
     self.wait()
     event_classes = [e.__class__ for e in handler.events_received]
     self.assertEqual(event_classes, [
         StreamConnectedEvent, AuthenticatedEvent, StreamRestartedEvent,
         DisconnectedEvent
     ])
Exemple #20
0
 def test_stream_connect_disconnect(self):
     handler = JustStreamConnectEventHandler()
     self.stream = StreamBase(u"jabber:client", None, [])
     self.start_transport([handler])
     self.stream.initiate(self.transport)
     self.connect_transport()
     self.wait_short(0.25)
     self.wait_short(0.25)
     self.assertTrue(self.stream.is_connected())
     self.server.write(C2S_SERVER_STREAM_HEAD)
     self.wait(expect=re.compile(b".*(</stream:stream>)"))
     self.server.write(STREAM_TAIL)
     self.server.disconnect()
     self.wait()
     self.assertFalse(self.stream.is_connected())
     event_classes = [e.__class__ for e in handler.events_received]
     self.assertEqual(event_classes, [
         ConnectingEvent, ConnectedEvent, StreamConnectedEvent,
         DisconnectedEvent
     ])
 def test_connect_close(self):
     handler = JustConnectEventHandler()
     self.stream = StreamBase("jabber:client", None, [])
     self.start_transport([handler])
     self.stream.initiate(self.transport)
     self.connect_transport()
     self.wait()
     self.assertFalse(self.stream.is_connected())
     event_classes = [e.__class__ for e in handler.events_received]
     self.assertEqual(event_classes, [ConnectingEvent,
                                         ConnectedEvent, DisconnectedEvent])
Exemple #22
0
 def test_auth(self):
     handler = EventRecorder()
     settings = XMPPSettings({
         u"username": u"user",
         u"password": u"secret",
     })
     self.stream = StreamBase(u"jabber:client", None,
                              [StreamSASLHandler(settings), handler],
                              settings)
     self.start_transport([handler])
     self.stream.initiate(self.transport)
     self.connect_transport()
     self.server.write(C2S_SERVER_STREAM_HEAD)
     self.server.write(AUTH_FEATURES)
     xml = self.wait(expect=re.compile(br".*(<auth.*</auth>)"))
     self.assertIsNotNone(xml)
     element = ElementTree.XML(xml)
     self.assertEqual(element.tag, "{urn:ietf:params:xml:ns:xmpp-sasl}auth")
     mech = element.get("mechanism")
     self.assertEqual(mech, "PLAIN")
     data = binascii.a2b_base64(element.text.encode("utf-8"))
     self.assertEqual(data, b"\000user\000secret")
     self.server.rdata = b""
     self.server.write(
         b"<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>")
     stream_start = self.wait(expect=re.compile(br"(<stream:stream[^>]*>)"))
     self.assertIsNotNone(stream_start)
     self.assertTrue(self.stream.authenticated)
     self.server.write(C2S_SERVER_STREAM_HEAD)
     self.server.write(BIND_FEATURES)
     self.server.write(b"</stream:stream>")
     self.server.disconnect()
     self.wait()
     event_classes = [e.__class__ for e in handler.events_received]
     self.assertEqual(event_classes, [
         ConnectingEvent, ConnectedEvent, StreamConnectedEvent,
         GotFeaturesEvent, AuthenticatedEvent, StreamRestartedEvent,
         GotFeaturesEvent, DisconnectedEvent
     ])
 def test_stream_connect_disconnect(self):
     handler = JustStreamConnectEventHandler()
     self.start_transport([handler])
     self.stream = StreamBase("jabber:client", None, [])
     self.stream.receive(self.transport, self.addr[0])
     self.client.write(C2S_CLIENT_STREAM_HEAD)
     self.wait_short(0.25)
     self.wait_short(0.25)
     self.client.write(STREAM_TAIL)
     self.wait()
     self.assertFalse(self.stream.is_connected())
     event_classes = [e.__class__ for e in handler.events_received]
     self.assertEqual(event_classes, [StreamConnectedEvent,
                                                         DisconnectedEvent])
 def test_stream_connect_disconnect(self):
     handler = JustStreamConnectEventHandler()
     self.stream = StreamBase("jabber:client", None, [])
     self.start_transport([handler])
     self.stream.initiate(self.transport)
     self.connect_transport()
     self.wait_short(0.25)
     self.wait_short(0.25)
     self.assertTrue(self.stream.is_connected())
     self.server.write(C2S_SERVER_STREAM_HEAD)
     self.wait(expect = re.compile(b".*(</stream:stream>)"))
     self.server.write(STREAM_TAIL)
     self.server.disconnect()
     self.wait()
     self.assertFalse(self.stream.is_connected())
     event_classes = [e.__class__ for e in handler.events_received]
     self.assertEqual(event_classes, [ConnectingEvent, ConnectedEvent,
                                 StreamConnectedEvent, DisconnectedEvent])
Exemple #25
0
	def __init__(self, transport, avatars):
		StanzaProcessor.__init__(self)

		logger.debug('-- New connection')

		self.avatars = avatars

		self.settings = XMPPSettings()

		self.handlers = [self, ResourceBindingHandler(self.settings)]
		self.stream = StreamBase(u"jabber:client", self, self.handlers, self.settings)
		self.stream.set_authenticated(JID(domain='tlen.pl'))

		self.tlen = None
		self.transport = transport
		self.stream.receive(self.transport, 'tlen.pl')

		self.uplink = self.stream
		self.stream.set_authenticated(JID(domain='tlen.pl'))
 def test_enabled_required(self):
     """Test TLS enabled in settings, and required on the server."""
     self.start_server()
     settings = XMPPSettings({
                     "starttls": True, 
                     "tls_cacert_file": os.path.join(DATA_DIR, "ca.pem"), 
                             })
     handler = EventRecorder()
     handlers = [StreamTLSHandler(settings), handler]
     self.stream = StreamBase("jabber:client", None, handlers, settings)
     self.start_transport(handlers)
     self.stream.initiate(self.transport, to = "server.example.org")
     self.connect_transport()
     self.server.write(C2S_SERVER_STREAM_HEAD)
     self.server.write(TLS_REQUIRED_FEATURES)
     xml = self.wait(expect = re.compile(br".*(<starttls.*/>)"))
     self.assertIsNotNone(xml)
     element = XML(xml)
     self.assertEqual(element.tag, 
                             "{urn:ietf:params:xml:ns:xmpp-tls}starttls")
     self.server.write(PROCEED)
     self.server.starttls(self.server.sock,
                         keyfile = os.path.join(DATA_DIR, "server-key.pem"),
                         certfile = os.path.join(DATA_DIR, "server.pem"),
                         server_side = True,
                         ca_certs = os.path.join(DATA_DIR, "ca.pem"),
                             )
     stream_start = self.wait(expect = re.compile(
                                                 br"(<stream:stream[^>]*>)"))
     self.assertIsNotNone(stream_start)
     self.assertTrue(self.stream.tls_established)
     self.stream.disconnect()
     self.server.write(C2S_SERVER_STREAM_HEAD)
     self.server.write(EMPTY_FEATURES)
     self.server.write(b"</stream:stream>")
     self.wait()
     event_classes = [e.__class__ for e in handler.events_received]
     self.assertEqual(event_classes, [ConnectingEvent,
                 ConnectedEvent, StreamConnectedEvent, GotFeaturesEvent,
                 TLSConnectingEvent, TLSConnectedEvent, StreamRestartedEvent,
                 GotFeaturesEvent, DisconnectedEvent])
 def test_auth(self):
     handler = EventRecorder()
     self.start_transport([handler])
     settings = XMPPSettings({
                             "user_passwords": {
                                     "user": "******",
                                 },
                             "sasl_mechanisms": ["SCRAM-SHA-1", "PLAIN"],
                             })
     self.stream = StreamBase("jabber:client", None,
                         [StreamSASLHandler(settings), handler], settings)
     self.stream.receive(self.transport, self.addr[0])
     self.client.write(C2S_CLIENT_STREAM_HEAD)
     xml = self.wait(expect = re.compile(
                             br".*<stream:features>(.*)</stream:features>"))
     self.assertIsNotNone(xml)
     element = ElementTree.XML(xml)
     self.assertEqual(element.tag,
                             "{urn:ietf:params:xml:ns:xmpp-sasl}mechanisms")
     self.assertEqual(element[0].tag,
                             "{urn:ietf:params:xml:ns:xmpp-sasl}mechanism")
     self.assertEqual(element[0].text, "SCRAM-SHA-1")
     self.assertEqual(element[1].tag,
                             "{urn:ietf:params:xml:ns:xmpp-sasl}mechanism")
     self.assertEqual(element[1].text, "PLAIN")
     response = base64.standard_b64encode(b"\000user\000secret")
     self.client.write(PLAIN_AUTH.format(response.decode("utf-8"))
                                                 .encode("utf-8"))
     xml = self.wait(expect = re.compile(br".*(<success.*>)"))
     self.assertIsNotNone(xml)
     self.client.write(C2S_CLIENT_STREAM_HEAD)
     xml = self.wait(expect = re.compile(br".*(<stream:stream.*>)"))
     self.assertIsNotNone(xml)
     self.assertTrue(self.stream.peer_authenticated)
     self.client.write(b"</stream:stream>")
     self.client.disconnect()
     self.wait()
     event_classes = [e.__class__ for e in handler.events_received]
     self.assertEqual(event_classes, [
                             StreamConnectedEvent, AuthenticatedEvent,
                             StreamRestartedEvent, DisconnectedEvent])
 def test_auth(self):
     handler = EventRecorder()
     settings = XMPPSettings({
                             "username": "******", 
                             "password": "******",
                             })
     self.stream = StreamBase("jabber:client", None,
                         [StreamSASLHandler(settings), handler], settings)
     self.start_transport([handler])
     self.stream.initiate(self.transport)
     self.connect_transport()
     self.server.write(C2S_SERVER_STREAM_HEAD)
     self.server.write(AUTH_FEATURES)
     xml = self.wait(expect = re.compile(br".*(<auth.*</auth>)"))
     self.assertIsNotNone(xml)
     element = ElementTree.XML(xml)
     self.assertEqual(element.tag, "{urn:ietf:params:xml:ns:xmpp-sasl}auth")
     mech = element.get("mechanism")
     self.assertEqual(mech, "PLAIN")
     data = binascii.a2b_base64(element.text.encode("utf-8"))
     self.assertEqual(data, b"\000user\000secret")
     self.server.rdata = b""
     self.server.write(
                     b"<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>")
     stream_start = self.wait(expect = re.compile(
                                             br"(<stream:stream[^>]*>)"))
     self.assertIsNotNone(stream_start)
     self.assertTrue(self.stream.authenticated)
     self.server.write(C2S_SERVER_STREAM_HEAD)
     self.server.write(BIND_FEATURES)
     self.server.write(b"</stream:stream>")
     self.server.disconnect()
     self.wait()
     event_classes = [e.__class__ for e in handler.events_received]
     self.assertEqual(event_classes, [ConnectingEvent, ConnectedEvent,
                 StreamConnectedEvent, GotFeaturesEvent,
                 AuthenticatedEvent, StreamRestartedEvent, GotFeaturesEvent, 
                 DisconnectedEvent])
 def test_parse_error(self):
     handler = IgnoreEventHandler()
     self.stream = StreamBase("jabber:client", None, [])
     self.start_transport([handler])
     self.stream.initiate(self.transport)
     self.connect_transport()
     self.server.write(C2S_SERVER_STREAM_HEAD)
     self.wait_short()
     self.server.write(b"</stream:test>")
     with self.assertRaises(StreamParseError):
         logger.debug("-- WAIT start")
         self.wait()
         logger.debug("-- WAIT end")
     self.assertFalse(self.stream.is_connected())
     self.wait_short()
     self.server.wait(1)
     self.assertTrue(self.server.eof)
     self.assertTrue(self.server.rdata.endswith(PARSE_ERROR_RESPONSE))
     self.server.disconnect()
     self.wait()
     event_classes = [e.__class__ for e in handler.events_received]
     self.assertEqual(event_classes, [ConnectingEvent, ConnectedEvent,
                                 StreamConnectedEvent, DisconnectedEvent])
Exemple #30
0
class Server(StanzaProcessor, EventHandler, TimeoutHandler, XMPPFeatureHandler):
	"""
	The XMPP end of the proxy.

	Handles local XMPP client connections. Forwards stanzas from the 
	client to the Tlen server, and the other way around. Stanzas are 
	adapted to achieve maximum satisfaction on both sides ;)
	"""

	def __init__(self, transport, avatars):
		StanzaProcessor.__init__(self)

		logger.debug('-- New connection')

		self.avatars = avatars

		self.settings = XMPPSettings()

		self.handlers = [self, ResourceBindingHandler(self.settings)]
		self.stream = StreamBase(u"jabber:client", self, self.handlers, self.settings)
		self.stream.set_authenticated(JID(domain='tlen.pl'))

		self.tlen = None
		self.transport = transport
		self.stream.receive(self.transport, 'tlen.pl')

		self.uplink = self.stream
		self.stream.set_authenticated(JID(domain='tlen.pl'))


	@event_handler(AuthenticatedEvent)
	def authenticated(self, event):
		self.setup_stanza_handlers(self.handlers, 'post-auth')

	@event_handler(DisconnectedEvent)
	def disconnected(self, event):
		logger.debug('Client disconnected')
		if self.tlen:
			self.tlen.close()
			self.tlen = None
		return QUIT

	# Stanza handlers. Except for authentication stuff, they
	# push everything to the TlenClient. Anything that needs
	# fixing up before being sent to the server is performed
	# in TlenClient.send()

	@iq_get_stanza_handler(XMLPayload, '{jabber:iq:auth}query')
	def handle_auth_get(self, stanza):
		logger.debug('auth get %s', stanza.serialize())
		resp = stanza.make_result_response()

		query = ElementTree.Element('{jabber:iq:auth}query')
		for x in ('username', 'password', 'resource'):
			query.append(ElementTree.Element('{jabber:iq:auth}' + x))

		resp.add_payload(query)

		return resp
		
	@iq_set_stanza_handler(XMLPayload, '{jabber:iq:auth}query')
	def handle_auth_set(self, stanza):
		"""
		This is the part that actually starts the Tlen end
		of the proxy.

		We're expecting PLAIN XMPP authentication here, so we
		can grab the auth data and log in to Tlen.pl, on behalf
		of the user.
		"""

		query = stanza.get_payload(None, 'query').as_xml()

		# XXX: Assuming the client will use legacy auth
		username = query.findtext('{jabber:iq:auth}username')
		password = query.findtext('{jabber:iq:auth}password')
		resource = query.findtext('{jabber:iq:auth}resource')

		if not username or not password:
			# XXX
			return stanza.make_error_response('bad-request')

		self.tlen = TlenStream(JID(username, 'tlen.pl'), password, resource, self.avatars)
		self.tlen.uplink = self.stream
		self.tlen.start()

		if self.tlen.wait_for_auth():
			return stanza.make_result_response()
		else:
			# XXX: is this code ok?
			return stanza.make_error_response('not-authorized')

	@iq_get_stanza_handler(XMLPayload, '{jabber:iq:roster}query')
	def handle_roster_get(self, stanza):
		self.tlen.send(stanza)

	@iq_set_stanza_handler(XMLPayload, '{jabber:iq:roster}query')
	def handle_roster_set(self, stanza):
		self.tlen.send(stanza)

	@iq_get_stanza_handler(XMLPayload, DISCO_INFO_NS_QNP + 'query')
	def handle_disco_info_get(self, stanza):
		"""
		Handle feature discovery on behalf of a @tlen.pl user.
		"""

		logger.debug('DISCO INFO get, jid=%s', stanza.to_jid)

		resp = stanza.make_result_response()

		# Target is client entity
		query = ElementTree.Element(DISCO_INFO_NS_QNP + 'query')
		if stanza.to_jid.local:
			logger.debug('disco to client')
			query.append(ElementTree.Element(DISCO_INFO_NS_QNP + 'feature', var=CHATSTATES_NS))
		else:
			query.append(ElementTree.Element(DISCO_INFO_NS_QNP + 'feature', var='urn:xmpp:blocking'))

		resp.add_payload(query)
		return resp

	@iq_get_stanza_handler(XMLPayload, DISCO_ITEMS_NS_QNP + 'query')
	def handle_disco_items_get(self, stanza):
		response = stanza.make_result_response()
		query = ElementTree.Element(DISCO_ITEMS_NS_QNP + 'query')
		response.add_payload(query)

		return response

	@iq_get_stanza_handler(XMLPayload, '{vcard-temp}vCard')
	def handle_vcard_get(self, iq):
		logger.debug('vCard: %s', iq)

		job = jobs.VCardGet(self)
		return job.perform(iq)

	@presence_stanza_handler()
	def handle_presence(self, stanza):
		logger.debug('handle presence=%s', stanza.serialize())
		self.tlen.send(stanza)

	@presence_stanza_handler('subscribed')
	def handle_presence_subscribed(self, stanza):
		logger.debug('handle presence subscr=%s', stanza.serialize())
		self.tlen.send(stanza)

	@presence_stanza_handler('subscribe')
	def handle_presence_subscribe(self, stanza):
		logger.debug('handle presence subscr=%s', stanza.serialize())
		self.tlen.send(stanza)

	@presence_stanza_handler('unsubscribe')
	def handle_presence_unsubscribe(self, stanza):
		logger.debug('handle presence subscr=%s', stanza.serialize())
		self.tlen.send(stanza)

	@presence_stanza_handler('unsubscribed')
	def handle_presence_unsubscribed(self, stanza):
		logger.debug('handle presence subscr=%s', stanza.serialize())
		self.tlen.send(stanza)

	@message_stanza_handler()
	def handle_message(self, stanza):
		self.tlen.send(stanza)
Exemple #31
0
class TestInitiatorSelect(InitiatorSelectTestCase):
    def test_connect_close(self):
        handler = JustConnectEventHandler()
        self.stream = StreamBase(u"jabber:client", None, [])
        self.start_transport([handler])
        self.stream.initiate(self.transport)
        self.connect_transport()
        self.wait()
        self.assertFalse(self.stream.is_connected())
        event_classes = [e.__class__ for e in handler.events_received]
        self.assertEqual(event_classes,
                         [ConnectingEvent, ConnectedEvent, DisconnectedEvent])

    def test_stream_connect_disconnect(self):
        handler = JustStreamConnectEventHandler()
        self.stream = StreamBase(u"jabber:client", None, [])
        self.start_transport([handler])
        self.stream.initiate(self.transport)
        self.connect_transport()
        self.wait_short(0.25)
        self.wait_short(0.25)
        self.assertTrue(self.stream.is_connected())
        self.server.write(C2S_SERVER_STREAM_HEAD)
        self.wait(expect=re.compile(b".*(</stream:stream>)"))
        self.server.write(STREAM_TAIL)
        self.server.disconnect()
        self.wait()
        self.assertFalse(self.stream.is_connected())
        event_classes = [e.__class__ for e in handler.events_received]
        self.assertEqual(event_classes, [
            ConnectingEvent, ConnectedEvent, StreamConnectedEvent,
            DisconnectedEvent
        ])

    def test_parse_error(self):
        handler = IgnoreEventHandler()
        self.stream = StreamBase(u"jabber:client", None, [])
        self.start_transport([handler])
        self.stream.initiate(self.transport)
        self.connect_transport()
        self.server.write(C2S_SERVER_STREAM_HEAD)
        self.wait_short()
        self.server.write(b"</stream:test>")
        with self.assertRaises(StreamParseError):
            logger.debug("-- WAIT start")
            self.wait()
            logger.debug("-- WAIT end")
        self.assertFalse(self.stream.is_connected())
        self.wait_short()
        self.server.wait(1)
        self.assertTrue(self.server.eof)
        self.assertTrue(self.server.rdata.endswith(PARSE_ERROR_RESPONSE))
        self.server.disconnect()
        self.wait()
        event_classes = [e.__class__ for e in handler.events_received]
        self.assertEqual(event_classes, [
            ConnectingEvent, ConnectedEvent, StreamConnectedEvent,
            DisconnectedEvent
        ])

    def test_stanza_send(self):
        handler = IgnoreEventHandler()
        route = RecordingRoute()
        self.stream = StreamBase(u"jabber:client", route, [])
        self.start_transport([handler])
        self.stream.initiate(self.transport)
        self.connect_transport()
        self.server.write(C2S_SERVER_STREAM_HEAD)
        self.wait_short(0.25)
        self.wait_short(0.25)
        self.assertTrue(self.stream.is_connected())
        self.stream.send(Message(to_jid=JID(u"*****@*****.**"),
                                 body=u"Test"))
        xml = self.wait(expect=re.compile(b".*(<message.*</message>)"))
        self.assertIsNotNone(xml)
        if b"xmlns" not in xml:
            xml = xml.replace(b"<message", b"<message xmlns='jabber:client'")
        element = XML(xml)
        stanza = Message(element)
        self.assertEqual(stanza.body, u"Test")
        self.stream.disconnect()
        self.server.write(STREAM_TAIL)
        self.server.disconnect()
        self.wait()
        self.assertEqual(route.sent, [])
        self.assertEqual(route.received, [])
        event_classes = [e.__class__ for e in handler.events_received]
        self.assertEqual(event_classes, [
            ConnectingEvent, ConnectedEvent, StreamConnectedEvent,
            DisconnectedEvent
        ])

    def test_stanza_receive(self):
        handler = IgnoreEventHandler()
        route = RecordingRoute()
        self.stream = StreamBase(u"jabber:client", route, [])
        self.start_transport([handler])
        self.stream.initiate(self.transport)
        self.connect_transport()
        logger.debug("-- waiting for connect")
        self.wait_short(0.25)
        self.wait_short(0.25)
        logger.debug("-- checking connected")
        self.assertTrue(self.stream.is_connected())
        self.server.write(C2S_SERVER_STREAM_HEAD)
        self.server.write(b"<message><body>Test</body></message>")
        self.server.write(STREAM_TAIL)
        self.server.disconnect()
        self.wait(expect=re.compile(b".*(</stream:stream>)"))
        self.stream.disconnect()
        self.wait()
        self.assertEqual(route.sent, [])
        self.assertEqual(len(route.received), 1)
        stanza = route.received[0]
        self.assertIsInstance(stanza, Message)
        self.assertEqual(stanza.body, u"Test")
        event_classes = [e.__class__ for e in handler.events_received]
        self.assertEqual(event_classes, [
            ConnectingEvent, ConnectedEvent, StreamConnectedEvent,
            DisconnectedEvent
        ])
class TestInitiatorSelect(InitiatorSelectTestCase):
    def test_connect_close(self):
        handler = JustConnectEventHandler()
        self.stream = StreamBase("jabber:client", None, [])
        self.start_transport([handler])
        self.stream.initiate(self.transport)
        self.connect_transport()
        self.wait()
        self.assertFalse(self.stream.is_connected())
        event_classes = [e.__class__ for e in handler.events_received]
        self.assertEqual(event_classes, [ConnectingEvent,
                                            ConnectedEvent, DisconnectedEvent])

    def test_stream_connect_disconnect(self):
        handler = JustStreamConnectEventHandler()
        self.stream = StreamBase("jabber:client", None, [])
        self.start_transport([handler])
        self.stream.initiate(self.transport)
        self.connect_transport()
        self.wait_short(0.25)
        self.wait_short(0.25)
        self.assertTrue(self.stream.is_connected())
        self.server.write(C2S_SERVER_STREAM_HEAD)
        self.wait(expect = re.compile(b".*(</stream:stream>)"))
        self.server.write(STREAM_TAIL)
        self.server.disconnect()
        self.wait()
        self.assertFalse(self.stream.is_connected())
        event_classes = [e.__class__ for e in handler.events_received]
        self.assertEqual(event_classes, [ConnectingEvent, ConnectedEvent,
                                    StreamConnectedEvent, DisconnectedEvent])
 
    def test_parse_error(self):
        handler = IgnoreEventHandler()
        self.stream = StreamBase("jabber:client", None, [])
        self.start_transport([handler])
        self.stream.initiate(self.transport)
        self.connect_transport()
        self.server.write(C2S_SERVER_STREAM_HEAD)
        self.wait_short()
        self.server.write(b"</stream:test>")
        with self.assertRaises(StreamParseError):
            logger.debug("-- WAIT start")
            self.wait()
            logger.debug("-- WAIT end")
        self.assertFalse(self.stream.is_connected())
        self.wait_short()
        self.server.wait(1)
        self.assertTrue(self.server.eof)
        self.assertTrue(self.server.rdata.endswith(PARSE_ERROR_RESPONSE))
        self.server.disconnect()
        self.wait()
        event_classes = [e.__class__ for e in handler.events_received]
        self.assertEqual(event_classes, [ConnectingEvent, ConnectedEvent,
                                    StreamConnectedEvent, DisconnectedEvent])

    def test_stanza_send(self):
        handler = IgnoreEventHandler()
        route = RecordingRoute()
        self.stream = StreamBase("jabber:client", route, [])
        self.start_transport([handler])
        self.stream.initiate(self.transport)
        self.connect_transport()
        self.server.write(C2S_SERVER_STREAM_HEAD)
        self.wait_short(0.25)
        self.wait_short(0.25)
        self.assertTrue(self.stream.is_connected())
        self.stream.send(Message(to_jid = JID("*****@*****.**"),
                                                            body = "Test"))
        xml = self.wait(expect = re.compile(b".*(<message.*</message>)"))
        self.assertIsNotNone(xml)
        if b"xmlns" not in xml:
            xml = xml.replace(b"<message", b"<message xmlns='jabber:client'")
        element = XML(xml)
        stanza = Message(element)
        self.assertEqual(stanza.body, "Test")
        self.stream.disconnect()
        self.server.write(STREAM_TAIL)
        self.server.disconnect()
        self.wait()
        self.assertEqual(route.sent, [])
        self.assertEqual(route.received, [])
        event_classes = [e.__class__ for e in handler.events_received]
        self.assertEqual(event_classes, [ConnectingEvent, ConnectedEvent,
                                    StreamConnectedEvent, DisconnectedEvent])
 
    def test_stanza_receive(self):
        handler = IgnoreEventHandler()
        route = RecordingRoute()
        self.stream = StreamBase("jabber:client", route, [])
        self.start_transport([handler])
        self.stream.initiate(self.transport)
        self.connect_transport()
        logger.debug("-- waiting for connect")
        self.wait_short(0.25)
        self.wait_short(0.25)
        logger.debug("-- checking connected")
        self.assertTrue(self.stream.is_connected())
        self.server.write(C2S_SERVER_STREAM_HEAD)
        self.server.write(b"<message><body>Test</body></message>")
        self.server.write(STREAM_TAIL)
        self.server.disconnect()
        self.wait(expect = re.compile(b".*(</stream:stream>)"))
        self.stream.disconnect()
        self.wait()
        self.assertEqual(route.sent, [])
        self.assertEqual(len(route.received), 1)
        stanza = route.received[0]
        self.assertIsInstance(stanza, Message)
        self.assertEqual(stanza.body, "Test")
        event_classes = [e.__class__ for e in handler.events_received]
        self.assertEqual(event_classes, [ConnectingEvent, ConnectedEvent,
                                    StreamConnectedEvent, DisconnectedEvent])