class TestInitiator(InitiatorSelectTestCase): def test_enabled_optional(self): """Test TLS enabled in settings, and optional on the 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_FEATURES) xml = self.wait(2, 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_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_enabled_missing(self): """Test TLS enabled in settings, and missing 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(EMPTY_FEATURES) self.server.write(b"</stream:stream>") self.wait(expect = re.compile(br".*(</stream:stream>)")) self.assertFalse(self.stream.tls_established) self.stream.disconnect() 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])
class TestInitiator(InitiatorSelectTestCase): def test_enabled_optional(self): """Test TLS enabled in settings, and optional on the 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_FEATURES) xml = self.wait(2, 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_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 ]) def test_enabled_missing(self): """Test TLS enabled in settings, and missing 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(EMPTY_FEATURES) self.server.write(b"</stream:stream>") self.wait(expect=re.compile(br".*(</stream:stream>)")) self.assertFalse(self.stream.tls_established) self.stream.disconnect() 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({ 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 ])
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])
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 ])