コード例 #1
0
    def test_formatDataForResponse_no_data(self):
        request = DummyRequest([self.pagename])
        request.method = b'GET'

        rendered = self.resource.formatDataForResponse(None, request)

        self.assertEqual(rendered, b'')
コード例 #2
0
 def test_IndexResource_render_GET_lang_ta(self):
     """renderGet() with ?lang=ta should return the index page in Tamil."""
     request = DummyRequest([self.pagename])
     request.method = b'GET'
     request.addArg('lang', 'ta')
     page = self.indexResource.render_GET(request)
     self.assertSubstring("bridge-களை Tor Browser-உள்", page)
コード例 #3
0
    def test_render_GET_RTLlang_obfs3(self):
        """Test rendering a request for obfs3 bridges in Farsi."""
        self.useBenignBridges()

        request = DummyRequest([b"bridges?transport=obfs3"])
        request.method = b'GET'
        request.getClientIP = lambda: '3.3.3.3'
        request.headers.update({'accept-language': 'fa,en,en_US,'})
        # We actually have to set the request args manually when using a
        # DummyRequest:
        request.args.update({'transport': ['obfs3']})

        page = self.bridgesResource.render(request)
        self.assertSubstring("rtl.css", page)
        self.assertSubstring(
            # "How to use the above bridge lines" (since there should be
            # bridges in this response, we don't tell them about alternative
            # mechanisms for getting bridges)
            "چگونگی از پل‌های خود استفاده کنید",
            page)

        for bridgeLine in self.parseBridgesFromHTMLPage(page):
            # Check that each bridge line had the expected number of fields:
            bridgeLine = bridgeLine.split(' ')
            self.assertEqual(len(bridgeLine), 3)
            self.assertEqual(bridgeLine[0], 'obfs3')

            # Check that the IP and port seem okay:
            ip, port = bridgeLine[1].rsplit(':')
            self.assertIsInstance(ipaddr.IPv4Address(ip), ipaddr.IPv4Address)
            self.assertIsInstance(int(port), int)
            self.assertGreater(int(port), 0)
            self.assertLessEqual(int(port), 65535)
コード例 #4
0
    def test_render_GET_RTLlang_obfs3(self):
        """Test rendering a request for obfs3 bridges in Farsi."""
        self.useBenignBridges()

        request = DummyRequest([b"bridges?transport=obfs3"])
        request.method = b'GET'
        request.getClientIP = lambda: '3.3.3.3'
        request.headers.update({'accept-language': 'fa,en,en_US,'})
        # We actually have to set the request args manually when using a
        # DummyRequest:
        request.args.update({'transport': ['obfs3']})

        page = self.bridgesResource.render(request)
        self.assertSubstring("rtl.css", page)
        self.assertSubstring(
            # "How to use the above bridge lines" (since there should be
            # bridges in this response, we don't tell them about alternative
            # mechanisms for getting bridges)
            "چگونگی از پل‌های خود استفاده کنید", page)

        for bridgeLine in self.parseBridgesFromHTMLPage(page):
            # Check that each bridge line had the expected number of fields:
            bridgeLine = bridgeLine.split(' ')
            self.assertEqual(len(bridgeLine), 3)
            self.assertEqual(bridgeLine[0], 'obfs3')

            # Check that the IP and port seem okay:
            ip, port = bridgeLine[1].rsplit(':')
            self.assertIsInstance(ipaddr.IPv4Address(ip), ipaddr.IPv4Address)
            self.assertIsInstance(int(port), int)
            self.assertGreater(int(port), 0)
            self.assertLessEqual(int(port), 65535)
コード例 #5
0
ファイル: test_https_server.py プロジェクト: agiix/bridgedb
    def test_render_GET_vanilla(self):
        """Test rendering a request for normal, vanilla bridges."""
        self.useBenignBridges()

        request = DummyRequest([self.pagename])
        request.method = b'GET'
        request.getClientIP = lambda: '1.1.1.1'

        page = self.bridgesResource.render(request)

        # The response should explain how to use the bridge lines:
        self.assertTrue("How to start using your bridges" in str(page))

        for b in self.parseBridgesFromHTMLPage(page):
            # Check that each bridge line had the expected number of fields:
            fields = b.split(' ')
            self.assertEqual(len(fields), 2)

            # Check that the IP and port seem okay:
            ip, port = fields[0].rsplit(':')
            self.assertIsInstance(ipaddress.ip_address(ip),
                                  ipaddress.IPv4Address)
            self.assertIsInstance(int(port), int)
            self.assertGreater(int(port), 0)
            self.assertLessEqual(int(port), 65535)
コード例 #6
0
ファイル: test_https_server.py プロジェクト: agiix/bridgedb
    def setUp(self):
        """Create a :class:`server.BridgesResource` and protect it with
        a :class:`GimpCaptchaProtectedResource`.
        """
        # Create our cached CAPTCHA directory:
        self.captchaDir = 'captchas'
        if not os.path.isdir(self.captchaDir):
            os.makedirs(self.captchaDir)

        # Set up our resources to fake a minimal HTTP(S) server:
        self.pagename = b'captcha.html'
        self.root = Resource()
        # (None, None) is the (distributor, scheduleInterval):
        self.protectedResource = server.BridgesResource(None, None)
        self.captchaResource = server.GimpCaptchaProtectedResource(
            secretKey='42',
            publicKey='23',
            hmacKey='abcdefghijklmnopqrstuvwxyz012345',
            captchaDir='captchas',
            useForwardedHeader=True,
            protectedResource=self.protectedResource)

        self.root.putChild(self.pagename, self.captchaResource)

        # Set up the basic parts of our faked request:
        self.request = DummyRequest([self.pagename])
コード例 #7
0
    def test_renderAnswer_textplain(self):
        """If the request format specifies 'plain', we should return content
        with mimetype 'text/plain'.
        """
        self.useBenignBridges()

        request = DummyRequest([self.pagename])
        request.args.update({'format': ['plain']})
        request.getClientIP = lambda: '4.4.4.4'
        request.method = b'GET'

        page = self.bridgesResource.render(request)
        self.assertTrue("html" not in str(page))

        # We just need to strip and split it because it looks like:
        #
        #   94.235.85.233:9492 0d9d0547c3471cddc473f7288a6abfb54562dc06
        #   255.225.204.145:9511 1fb89d618b3a12afe3529fd072127ea08fb50466
        #
        # (Yes, there are two leading spaces at the beginning of each line)
        #
        bridgeLines = [line.strip() for line in page.strip().split('\n')]

        for bridgeLine in bridgeLines:
            bridgeLine = bridgeLine.split(' ')
            self.assertEqual(len(bridgeLine), 2)

            # Check that the IP and port seem okay:
            ip, port = bridgeLine[0].rsplit(':')
            self.assertIsInstance(ipaddr.IPv4Address(ip), ipaddr.IPv4Address)
            self.assertIsInstance(int(port), int)
            self.assertGreater(int(port), 0)
            self.assertLessEqual(int(port), 65535)
コード例 #8
0
 def test_HowtoResource_render_GET_lang_ru(self):
     """renderGet() with ?lang=ru should return the howto page in Russian."""
     request = DummyRequest([self.pagename])
     request.method = b'GET'
     request.addArg('lang', 'ru')
     page = self.howtoResource.render_GET(request)
     self.assertSubstring("следуйте инструкциям установщика", page)
コード例 #9
0
    def test_formatDataForResponse_no_data(self):
        request = DummyRequest([self.pagename])
        request.method = b'GET'

        rendered = self.resource.formatDataForResponse(None, request)

        self.assertEqual(rendered, b'')
コード例 #10
0
 def test_HowtoResource_render_GET_lang_ru(self):
     """renderGet() with ?lang=ru should return the howto page in Russian."""
     request = DummyRequest([self.pagename])
     request.method = b'GET'
     request.addArg('lang', 'ru')
     page = self.howtoResource.render_GET(request)
     self.assertSubstring("следуйте инструкциям установщика", page)
コード例 #11
0
 def test_IndexResource_render_GET_lang_ta(self):
     """renderGet() with ?lang=ta should return the index page in Tamil."""
     request = DummyRequest([self.pagename])
     request.method = b'GET'
     request.addArg('lang', 'ta')
     page = self.indexResource.render_GET(request)
     self.assertSubstring("bridge-களை Tor Browser-உள்", page)
コード例 #12
0
ファイル: test_https_server.py プロジェクト: agiix/bridgedb
    def test_render_GET_RTLlang(self):
        """Test rendering a request for plain bridges in Arabic."""

        if 'ar' not in _langs.get_langs():
            self.skipTest("'ar' language unsupported")

        self.useBenignBridges()

        request = DummyRequest([b"bridges?transport=obfs3"])
        request.method = b'GET'
        request.getClientIP = lambda: '3.3.3.3'
        # For some strange reason, the 'Accept-Language' value *should not* be
        # a list, unlike all the other headers and args…
        request.headers.update({'accept-language': 'ar,en,en_US,'})

        page = self.bridgesResource.render(request)
        self.assertSubstring(b"rtl.css", page)
        self.assertSubstring(
            # "I need an alternative way to get bridges!"
            "أحتاج إلى وسيلة بديلة للحصول على bridges".encode("utf-8"),
            page)

        for bridgeLine in self.parseBridgesFromHTMLPage(page):
            # Check that each bridge line had the expected number of fields:
            bridgeLine = bridgeLine.split(' ')
            self.assertEqual(len(bridgeLine), 2)
コード例 #13
0
ファイル: test_https_server.py プロジェクト: agiix/bridgedb
    def test_renderAnswer_textplain(self):
        """If the request format specifies 'plain', we should return content
        with mimetype 'text/plain'.
        """
        self.useBenignBridges()

        request = DummyRequest([self.pagename])
        request.args.update({'format': ['plain']})
        request.getClientIP = lambda: '4.4.4.4'
        request.method = b'GET'

        page = self.bridgesResource.render(request)
        self.assertTrue("html" not in str(page))

        # We just need to strip and split it because it looks like:
        #
        #   94.235.85.233:9492 0d9d0547c3471cddc473f7288a6abfb54562dc06
        #   255.225.204.145:9511 1fb89d618b3a12afe3529fd072127ea08fb50466
        #
        # (Yes, there are two leading spaces at the beginning of each line)
        #
        bridgeLines = [line.strip() for line in page.strip().split(b'\n')]

        for bridgeLine in bridgeLines:
            bridgeLine = bridgeLine.split(b' ')
            self.assertEqual(len(bridgeLine), 2)

            # Check that the IP and port seem okay:
            ip, port = bridgeLine[0].rsplit(b':')
            self.assertIsInstance(ipaddress.ip_address(ip.decode("utf-8")),
                                  ipaddress.IPv4Address)
            self.assertIsInstance(int(port), int)
            self.assertGreater(int(port), 0)
            self.assertLessEqual(int(port), 65535)
コード例 #14
0
    def test_getCaptchaImage(self):
        request = DummyRequest([self.pagename])
        request.method = b'GET'

        image, challenge = self.resource.getCaptchaImage(request)

        self.assertIsNotNone(image)
        self.assertIsNotNone(challenge)
コード例 #15
0
    def create_POST_with_data(self, data):
        request = DummyRequest([self.pagename])
        request.requestHeaders.addRawHeader('Content-Type', 'application/vnd.api+json')
        request.requestHeaders.addRawHeader('Accept', 'application/vnd.api+json')
        request.method = b'POST'
        request.writeContent(data)

        return request
コード例 #16
0
    def test_getCaptchaImage(self):
        request = DummyRequest([self.pagename])
        request.method = b'GET'

        image, challenge = self.resource.getCaptchaImage(request)

        self.assertIsNotNone(image)
        self.assertIsNotNone(challenge)
コード例 #17
0
 def test_render_POST(self):
     """render_POST() with a wrong 'captcha_response_field' should return
     a redirect to the CaptchaProtectedResource page.
     """
     request = DummyRequest([self.pagename])
     request.method = b'POST'
     page = self.captchaResource.render_POST(request)
     self.assertEqual(BeautifulSoup(page).find('meta')['http-equiv'],
                      'refresh')
コード例 #18
0
 def test_render_GET_noCaptcha(self):
     """render_GET() should return a page without a CAPTCHA, which has the
     image alt text.
     """
     request = DummyRequest([self.pagename])
     request.method = b'GET'
     page = self.captchaResource.render_GET(request)
     self.assertSubstring(
         "Your browser is not displaying images properly", page)
コード例 #19
0
 def test_render_POST(self):
     """render_POST() with a wrong 'captcha_response_field' should return
     a redirect to the CaptchaProtectedResource page.
     """
     request = DummyRequest([self.pagename])
     request.method = b'POST'
     page = self.captchaResource.render_POST(request)
     self.assertEqual(
         BeautifulSoup(page).find('meta')['http-equiv'], 'refresh')
コード例 #20
0
ファイル: test_https_server.py プロジェクト: agiix/bridgedb
 def test_render_GET_noCaptcha(self):
     """render_GET() should return a page without a CAPTCHA, which has the
     image alt text.
     """
     request = DummyRequest([self.pagename])
     request.method = b'GET'
     page = self.captchaResource.render_GET(request)
     self.assertSubstring(b"Your browser is not displaying images properly",
                          page)
コード例 #21
0
    def create_POST_with_data(self, data):
        request = DummyRequest([self.pagename])
        request.requestHeaders.addRawHeader('Content-Type',
                                            'application/vnd.api+json')
        request.requestHeaders.addRawHeader('Accept',
                                            'application/vnd.api+json')
        request.method = b'POST'
        request.writeContent(data)

        return request
コード例 #22
0
ファイル: test_https_server.py プロジェクト: agiix/bridgedb
    def test_HowtoResource_render_GET_lang_ru(self):
        """renderGet() with ?lang=ru should return the howto page in Russian."""

        if 'ru' not in _langs.get_langs():
            self.skipTest("'ru' language unsupported")

        request = DummyRequest([self.pagename])
        request.method = b'GET'
        request.addArg(b'lang', 'ru')
        page = self.howtoResource.render_GET(request)
        self.assertSubstring("Как использовать мосты".encode("utf-8"), page)
コード例 #23
0
 def createRequestWithIPs(self):
     """Set the IP address returned from ``request.getClientIP()`` to
     '3.3.3.3', and the IP address reported in the 'X-Forwarded-For' header
     to '2.2.2.2'.
     """
     request = DummyRequest([''])
     request.headers.update({'x-forwarded-for': '2.2.2.2'})
     # See :api:`twisted.test.requesthelper.DummyRequest.getClientIP`
     request.client = requesthelper.IPv4Address('TCP', '3.3.3.3', 443)
     request.method = b'GET'
     return request
コード例 #24
0
ファイル: test_https_server.py プロジェクト: agiix/bridgedb
    def test_IndexResource_render_GET_lang_ta(self):
        """renderGet() with ?lang=ta should return the index page in Tamil."""

        if 'ta' not in _langs.get_langs():
            self.skipTest("'ta' language unsupported")

        request = DummyRequest([self.pagename])
        request.method = b'GET'
        request.addArg(b'lang', 'ta')
        page = self.indexResource.render_GET(request)
        self.assertSubstring("bridge-களை Tor Browser-உள்".encode("utf-8"),
                             page)
コード例 #25
0
    def test_getChild(self):
        request = DummyRequest(['foo'])
        request.method = b'GET'
        response_resource = self.resource.getChild('/foo', request)

        self.assertTrue(response_resource)
        self.assertIsInstance(response_resource, server.JsonAPIErrorResource)

        response = response_resource.render(request)
        detail = json.loads(response)['errors'][0]['detail']

        self.assertIn('does not implement GET http://dummy/', detail)
コード例 #26
0
    def test_getChild(self):
        request = DummyRequest(['foo'])
        request.method = b'GET'
        response_resource = self.resource.getChild('/foo', request)

        self.assertTrue(response_resource)
        self.assertIsInstance(response_resource, server.JsonAPIErrorResource)

        response = response_resource.render(request)
        detail = json.loads(response)['errors'][0]['detail']

        self.assertIn('does not implement GET http://dummy/', detail)
コード例 #27
0
    def test_getCaptchaImage_empty_captcha_dir(self):
        request = DummyRequest([self.pagename])
        request.method = b'GET'

        captchaDirOrig = self.resource.captchaDir
        captchaDirNew = tempfile.mkdtemp()
        self.resource.captchaDir = captchaDirNew
        image, challenge = self.resource.getCaptchaImage(request)
        self.resource.captchaDir = captchaDirOrig
        shutil.rmtree(captchaDirNew)

        self.assertIsNone(image)
        self.assertIsNone(challenge)
コード例 #28
0
    def test_render_GET_RTLlang(self):
        """Test rendering a request for obfs3 bridges in Hebrew."""
        request = DummyRequest(["bridges?transport=obfs3"])
        request.method = b'GET'
        request.getClientIP = lambda: '3.3.3.3'
        request.headers.update({'accept-language': 'he'})
        # We actually have to set the request args manually when using a
        # DummyRequest:
        request.args.update({'transport': ['obfs2']})

        page = self.optionsResource.render(request)
        self.assertSubstring("rtl.css", page)
        self.assertSubstring("מהם גשרים?", page)
コード例 #29
0
    def test_getCaptchaImage_empty_captcha_dir(self):
        request = DummyRequest([self.pagename])
        request.method = b'GET'

        captchaDirOrig = self.resource.captchaDir
        captchaDirNew = tempfile.mkdtemp()
        self.resource.captchaDir = captchaDirNew
        image, challenge = self.resource.getCaptchaImage(request)
        self.resource.captchaDir = captchaDirOrig
        shutil.rmtree(captchaDirNew)

        self.assertIsNone(image)
        self.assertIsNone(challenge)
コード例 #30
0
    def test_render_GET_RTLlang(self):
        """Test rendering a request for obfs3 bridges in Hebrew."""
        request = DummyRequest(["bridges?transport=obfs3"])
        request.method = b'GET'
        request.getClientIP = lambda: '3.3.3.3'
        request.headers.update({'accept-language': 'he'})
        # We actually have to set the request args manually when using a
        # DummyRequest:
        request.args.update({'transport': ['obfs2']})

        page = self.optionsResource.render(request)
        self.assertSubstring("rtl.css", page)
        self.assertSubstring("מהם גשרים?", page)
コード例 #31
0
 def test_render_GET_missingTemplate(self):
     """render_GET() with a missing template should raise an error and
     return the result of replaceErrorPage().
     """
     oldLookup = server.lookup
     try:
         server.lookup = None
         request = DummyRequest([self.pagename])
         request.method = b'GET'
         page = self.captchaResource.render_GET(request)
         errorPage = server.replaceErrorPage(request, Exception('kablam'))
         self.assertEqual(page, errorPage)
     finally:
         server.lookup = oldLookup
コード例 #32
0
    def test_render_GET_malicious_newlines(self):
        """Test rendering a request when the some of the bridges returned have
        malicious (HTML, Javascript, etc., in their) PT arguments.
        """
        self.useMaliciousBridges()

        request = DummyRequest([self.pagename])
        request.method = b'GET'
        request.getClientIP = lambda: '1.1.1.1'

        page = self.bridgesResource.render(request)
        self.assertTrue(
            'bad=Bridge 6.6.6.6:6666 0123456789abcdef0123456789abcdef01234567' in str(page),
            "Newlines in bridge lines should be removed.")
コード例 #33
0
    def test_render_GET_malicious_returnchar(self):
        """Test rendering a request when the some of the bridges returned have
        malicious (HTML, Javascript, etc., in their) PT arguments.
        """
        self.useMaliciousBridges()

        request = DummyRequest([self.pagename])
        request.method = b'GET'
        request.getClientIP = lambda: '1.1.1.1'

        page = self.bridgesResource.render(request)
        self.assertTrue(
            'eww=Bridge 1.2.3.4:1234' in str(page),
            "Return characters in bridge lines should be removed.")
コード例 #34
0
    def test_checkRequestHeaders_accept_with_media_parameters(self):
        data = {
            'data': [{
                'type': 'client-transports',
                'version': server.MOAT_API_VERSION,
                'supported': ['obfs4'],
            }]
        }
        encoded_data = json.dumps(data)

        request = DummyRequest([self.pagename])
        request.requestHeaders.addRawHeader('Accept', 'application/vnd.api+json;mp3')
        request.method = b'POST'
        request.writeContent(encoded_data)
コード例 #35
0
ファイル: test_https_server.py プロジェクト: agiix/bridgedb
    def test_render_GET_malicious_newlines(self):
        """Test rendering a request when the some of the bridges returned have
        malicious (HTML, Javascript, etc., in their) PT arguments.
        """
        self.useMaliciousBridges()

        request = DummyRequest([self.pagename])
        request.method = b'GET'
        request.getClientIP = lambda: '1.1.1.1'

        page = self.bridgesResource.render(request)
        self.assertTrue(
            'bad=Bridge 6.6.6.6:6666 0123456789abcdef0123456789abcdef01234567'
            in str(page), "Newlines in bridge lines should be removed.")
コード例 #36
0
ファイル: test_https_server.py プロジェクト: agiix/bridgedb
    def test_render_GET_malicious_returnchar(self):
        """Test rendering a request when the some of the bridges returned have
        malicious (HTML, Javascript, etc., in their) PT arguments.
        """
        self.useMaliciousBridges()

        request = DummyRequest([self.pagename])
        request.method = b'GET'
        request.getClientIP = lambda: '1.1.1.1'

        page = self.bridgesResource.render(request)
        self.assertTrue(
            'eww=Bridge 1.2.3.4:1234' in str(page),
            "Return characters in bridge lines should be removed.")
コード例 #37
0
ファイル: test_https_server.py プロジェクト: agiix/bridgedb
 def test_render_GET_missingTemplate(self):
     """render_GET() with a missing template should raise an error and
     return the result of replaceErrorPage().
     """
     oldLookup = server.lookup
     try:
         server.lookup = None
         request = DummyRequest([self.pagename])
         request.method = b'GET'
         page = self.captchaResource.render_GET(request)
         errorPage = server.replaceErrorPage(request, Exception('kablam'))
         self.assertEqual(page, errorPage)
     finally:
         server.lookup = oldLookup
コード例 #38
0
ファイル: test_https_server.py プロジェクト: agiix/bridgedb
 def createRequestWithIPs(self):
     """Set the IP address returned from ``request.getClientIP()`` to
     '3.3.3.3', and the IP address reported in the 'X-Forwarded-For' header
     to '2.2.2.2'.
     """
     request = DummyRequest([self.pagename])
     # Since we do not set ``request.getClientIP`` here like we do in some
     # of the other unittests, an exception would be raised here if
     # ``getBridgesForRequest()`` is unable to get the IP address from this
     # 'X-Forwarded-For' header (because ``ip`` would get set to ``None``).
     request.headers.update({'x-forwarded-for': '2.2.2.2'})
     # See :api:`twisted.test.requesthelper.DummyRequest.getClientIP`
     request.client = requesthelper.IPv4Address('TCP', '3.3.3.3', 443)
     request.method = b'GET'
     return request
コード例 #39
0
    def test_render_GET_malicious_javascript(self):
        """Test rendering a request when the some of the bridges returned have
        malicious (HTML, Javascript, etc., in their) PT arguments.
        """
        self.useMaliciousBridges()

        request = DummyRequest([self.pagename])
        request.method = b'GET'
        request.getClientIP = lambda: '1.1.1.1'

        page = self.bridgesResource.render(request)
        self.assertTrue(
            "evil=<script>alert('fuuuu');</script>" in str(page),
            ("The characters &, <, >, ', and \" in bridge lines should be "
             "replaced with their corresponding HTML special characters."))
コード例 #40
0
    def test_checkRequestHeaders_accept_with_media_parameters(self):
        data = {
            'data': [{
                'type': 'client-transports',
                'version': server.MOAT_API_VERSION,
                'supported': ['obfs4'],
            }]
        }
        encoded_data = json.dumps(data)

        request = DummyRequest([self.pagename])
        request.requestHeaders.addRawHeader('Accept',
                                            'application/vnd.api+json;mp3')
        request.method = b'POST'
        request.writeContent(encoded_data)
コード例 #41
0
 def createRequestWithIPs(self):
     """Set the IP address returned from ``request.getClientIP()`` to
     '3.3.3.3', and the IP address reported in the 'X-Forwarded-For' header
     to '2.2.2.2'.
     """
     request = DummyRequest([self.pagename])
     # Since we do not set ``request.getClientIP`` here like we do in some
     # of the other unittests, an exception would be raised here if
     # ``getBridgesForRequest()`` is unable to get the IP address from this
     # 'X-Forwarded-For' header (because ``ip`` would get set to ``None``).
     request.headers.update({'x-forwarded-for': '2.2.2.2'})
     # See :api:`twisted.test.requesthelper.DummyRequest.getClientIP`
     request.client = requesthelper.IPv4Address('TCP', '3.3.3.3', 443)
     request.method = b'GET'
     return request
コード例 #42
0
ファイル: test_https_server.py プロジェクト: agiix/bridgedb
 def test_replaceErrorPage(self):
     """``replaceErrorPage`` should return the error-500.html page."""
     request = DummyRequest([''])
     exc = Exception("Under Maintenance")
     errorPage = server.replaceErrorPage(request, exc)
     self.assertSubstring(b"Internal Error", errorPage)
     self.assertNotSubstring("Under Maintenance".encode("utf-8"), errorPage)
コード例 #43
0
    def test_formatDataForResponse(self):
        request = DummyRequest([self.pagename])
        request.method = b'GET'

        data = {'data': { 'version': 'wow',
                          'dinosaurs': 'cool',
                          'triceratops': 'awesome',
                          'velociraptors': 'terrifying', }}

        rendered = self.resource.formatDataForResponse(data, request)

        self.assertTrue(rendered)
        self.assertTrue(request.responseHeaders.hasHeader('content-type'))
        self.assertTrue(request.responseHeaders.hasHeader('server'))
        self.assertEqual(request.responseHeaders.getRawHeaders('content-type'),
                         ['application/vnd.api+json'])
コード例 #44
0
ファイル: test_https_server.py プロジェクト: agiix/bridgedb
 def test_replaceErrorPage_matches_resource500(self):
     """``replaceErrorPage`` should return the error-500.html page."""
     request = DummyRequest([''])
     exc = Exception("Under Maintenance")
     errorPage = server.replaceErrorPage(request, exc)
     error500Page = server.resource500.render(request)
     self.assertEqual(errorPage, error500Page)
コード例 #45
0
 def randomClientRequestForNotBlockedIn(self, cc):
     httpRequest = DummyRequest([''])
     httpRequest.args.update({'unblocked': [cc]})
     bridgeRequest = self.randomClientRequest()
     bridgeRequest.withoutBlockInCountry(httpRequest)
     bridgeRequest.generateFilters()
     return bridgeRequest
コード例 #46
0
 def test_replaceErrorPage(self):
     """``replaceErrorPage`` should return the error-500.html page."""
     request = DummyRequest([''])
     exc = Exception("vegan gümmibären")
     errorPage = server.replaceErrorPage(request, exc)
     self.assertSubstring(b"Bad News Bears", errorPage)
     self.assertNotSubstring("vegan gümmibären".encode("utf-8"), errorPage)
コード例 #47
0
ファイル: test_https_server.py プロジェクト: agiix/bridgedb
    def test_render_GET_malicious_javascript(self):
        """Test rendering a request when the some of the bridges returned have
        malicious (HTML, Javascript, etc., in their) PT arguments.
        """
        self.useMaliciousBridges()

        request = DummyRequest([self.pagename])
        request.method = b'GET'
        request.getClientIP = lambda: '1.1.1.1'

        page = self.bridgesResource.render(request)
        self.assertTrue(
            "evil=&lt;script&gt;alert(&#39;fuuuu&#39;);&lt;/script&gt;"
            in str(page),
            ("The characters &, <, >, ', and \" in bridge lines should be "
             "replaced with their corresponding HTML special characters."))
コード例 #48
0
    def setUp(self):
        """Create a :class:`server.BridgesResource` and protect it with
        a :class:`GimpCaptchaProtectedResource`.
        """
        # Create our cached CAPTCHA directory:
        self.captchaDir = 'captchas'
        if not os.path.isdir(self.captchaDir):
            os.makedirs(self.captchaDir)

        # Set up our resources to fake a minimal HTTP(S) server:
        self.pagename = b'captcha.html'
        self.root = Resource()
        # (None, None) is the (distributor, scheduleInterval):
        self.protectedResource = server.BridgesResource(None, None)
        self.captchaResource = server.GimpCaptchaProtectedResource(
            secretKey='42',
            publicKey='23',
            hmacKey='abcdefghijklmnopqrstuvwxyz012345',
            captchaDir='captchas',
            useForwardedHeader=True,
            protectedResource=self.protectedResource)

        self.root.putChild(self.pagename, self.captchaResource)

        # Set up the basic parts of our faked request:
        self.request = DummyRequest([self.pagename])
コード例 #49
0
    def test_render_POST_unexpired_with_qrcode(self):
        request = DummyRequest([self.pagename])
        request.client = requesthelper.IPv4Address('TCP', '3.3.3.3', 443)
        request.requestHeaders.addRawHeader('Content-Type',
                                            'application/vnd.api+json')
        request.requestHeaders.addRawHeader('Accept',
                                            'application/vnd.api+json')
        request.requestHeaders.addRawHeader('X-Forwarded-For', '3.3.3.3')

        resource = server.CaptchaFetchResource(self.hmacKey,
                                               self.publicKey,
                                               self.secretKey,
                                               self.captchaDir,
                                               useForwardedHeader=False)
        image, challenge = resource.getCaptchaImage(request)

        data = {
            'data': [{
                'id': '2',
                'type': 'moat-solution',
                'version': server.MOAT_API_VERSION,
                'transport': 'obfs4',
                'challenge': challenge,
                'solution': self.solution,
                'qrcode': 'true',
            }]
        }
        encoded_data = json.dumps(data)
        request = self.create_POST_with_data(encoded_data)
        request.client = requesthelper.IPv4Address('TCP', '3.3.3.3', 443)
        request.requestHeaders.addRawHeader('X-Forwarded-For', '3.3.3.3')

        response = self.resource.render(request)
        decoded = json.loads(response)

        self.assertTrue(decoded)
        self.assertIsNotNone(decoded.get('data'))

        datas = decoded['data']
        self.assertEqual(len(datas), 1)

        data = datas[0]
        self.assertIsNotNone(data['qrcode'])
        self.assertIsNotNone(data['bridges'])
        self.assertEqual(data['version'], server.MOAT_API_VERSION)
        self.assertEqual(data['type'], 'moat-bridges')
        self.assertEqual(data['id'], '3')
コード例 #50
0
ファイル: test_https_server.py プロジェクト: agiix/bridgedb
 def test_getChild(self):
     """``CustomErrorHandlingResource.getChild`` should return a rendered
     copy of ``server.resource404``.
     """
     request = DummyRequest([''])
     resource = server.CustomErrorHandlingResource()
     self.assertEqual(server.resource404,
                      resource.getChild('foobar', request))
コード例 #51
0
    def create_valid_POST_make_new_challenge(self):
        request = DummyRequest([self.pagename])
        request.client = requesthelper.IPv4Address('TCP', '3.3.3.3', 443)
        request.requestHeaders.addRawHeader('Content-Type', 'application/vnd.api+json')
        request.requestHeaders.addRawHeader('Accept', 'application/vnd.api+json')
        request.requestHeaders.addRawHeader('X-Forwarded-For', '3.3.3.3')

        resource = server.CaptchaFetchResource(self.hmacKey, self.publicKey,
                                               self.secretKey, self.captchaDir,
                                               useForwardedHeader=False)
        image, challenge = resource.getCaptchaImage(request)

        request = self.create_valid_POST_with_challenge(challenge)
        request.client = requesthelper.IPv4Address('TCP', '3.3.3.3', 443)
        request.requestHeaders.addRawHeader('X-Forwarded-For', '3.3.3.3')

        return request
コード例 #52
0
    def test_renderAnswer_GET_textplain_malicious(self):
        """If the request format specifies 'plain', we should return content
        with mimetype 'text/plain' and ASCII control characters replaced.
        """
        self.useMaliciousBridges()

        request = DummyRequest([self.pagename])
        request.args.update({'format': ['plain']})
        request.getClientIP = lambda: '4.4.4.4'
        request.method = b'GET'

        page = self.bridgesResource.render(request)
        self.assertTrue("html" not in str(page))
        self.assertTrue(
            'eww=Bridge 1.2.3.4:1234' in str(page),
            "Return characters in bridge lines should be removed.")
        self.assertTrue(
            'bad=Bridge 6.6.6.6:6666' in str(page),
            "Newlines in bridge lines should be removed.")
コード例 #53
0
    def test_render_POST_unexpired_with_qrcode(self):
        request = DummyRequest([self.pagename])
        request.client = requesthelper.IPv4Address('TCP', '3.3.3.3', 443)
        request.requestHeaders.addRawHeader('Content-Type', 'application/vnd.api+json')
        request.requestHeaders.addRawHeader('Accept', 'application/vnd.api+json')
        request.requestHeaders.addRawHeader('X-Forwarded-For', '3.3.3.3')

        resource = server.CaptchaFetchResource(self.hmacKey, self.publicKey,
                                               self.secretKey, self.captchaDir,
                                               useForwardedHeader=False)
        image, challenge = resource.getCaptchaImage(request)

        data = {
            'data': [{
                'id': '2',
                'type': 'moat-solution',
                'version': server.MOAT_API_VERSION,
                'transport': 'obfs4',
                'challenge': challenge,
                'solution': self.solution,
                'qrcode': 'true',
            }]
        }
        encoded_data = json.dumps(data)
        request = self.create_POST_with_data(encoded_data)
        request.client = requesthelper.IPv4Address('TCP', '3.3.3.3', 443)
        request.requestHeaders.addRawHeader('X-Forwarded-For', '3.3.3.3')

        response = self.resource.render(request)
        decoded = json.loads(response)

        self.assertTrue(decoded)
        self.assertIsNotNone(decoded.get('data'))

        datas = decoded['data']
        self.assertEqual(len(datas), 1)

        data = datas[0]
        self.assertIsNotNone(data['qrcode'])
        self.assertIsNotNone(data['bridges'])
        self.assertEqual(data['version'], server.MOAT_API_VERSION)
        self.assertEqual(data['type'], 'moat-bridges')
        self.assertEqual(data['id'], '3')
コード例 #54
0
    def test_renderAnswer_textplain_error(self):
        """If we hit some error while returning bridge lines in text/plain
        format, then our custom plaintext error message (the hardcoded HTML in
        ``server.replaceErrorPage``) should be returned.
        """
        self.useBenignBridges()

        request = DummyRequest([self.pagename])
        request.args.update({'format': ['plain']})
        request.getClientIP = lambda: '4.4.4.4'
        request.method = b'GET'

        # We'll cause a TypeError here due to calling '\n'.join(None)
        page = self.bridgesResource.renderAnswer(request, bridgeLines=None)

        # We don't want the fancy version:
        self.assertNotSubstring("Bad News Bears", page)
        self.assertSubstring("Sorry! Something went wrong with your request.",
                             page)
コード例 #55
0
    def test_render_GET_XForwardedFor(self):
        """The client's IP address should be obtainable from the
        'X-Forwarded-For' header in the request.
        """
        self.useBenignBridges()

        self.bridgesResource.useForwardedHeader = True
        request = DummyRequest([self.pagename])
        request.method = b'GET'
        # Since we do not set ``request.getClientIP`` here like we do in some
        # of the other unittests, an exception would be raised here if
        # ``getBridgesForRequest()`` is unable to get the IP address from this
        # 'X-Forwarded-For' header (because ``ip`` would get set to ``None``).
        request.headers.update({'x-forwarded-for': '2.2.2.2'})

        page = self.bridgesResource.render(request)
        self.bridgesResource.useForwardedHeader = False  # Reset it

        # The response should explain how to use the bridge lines:
        self.assertTrue("To enter bridges into Tor Browser" in str(page))
コード例 #56
0
    def test_render_GET_RTLlang(self):
        """Test rendering a request for plain bridges in Arabic."""
        self.useBenignBridges()

        request = DummyRequest([b"bridges?transport=obfs3"])
        request.method = b'GET'
        request.getClientIP = lambda: '3.3.3.3'
        # For some strange reason, the 'Accept-Language' value *should not* be
        # a list, unlike all the other headers and args…
        request.headers.update({'accept-language': 'ar,en,en_US,'})

        page = self.bridgesResource.render(request)
        self.assertSubstring("rtl.css", page)
        self.assertSubstring(
            # "I need an alternative way to get bridges!"
            "أحتاج إلى وسيلة بديلة للحصول على bridges", page)

        for bridgeLine in self.parseBridgesFromHTMLPage(page):
            # Check that each bridge line had the expected number of fields:
            bridgeLine = bridgeLine.split(' ')
            self.assertEqual(len(bridgeLine), 2)
コード例 #57
0
    def do_render_for_method(self, method):
        request = DummyRequest([self.pagename])
        request.method = method

        rendered = self.resource.render(request)

        self.assertTrue(rendered)
        self.assertTrue(request.responseHeaders.hasHeader('content-type'))
        self.assertTrue(request.responseHeaders.hasHeader('server'))
        self.assertEqual(request.responseHeaders.getRawHeaders('content-type'),
                         ['application/vnd.api+json'])

        decoded = json.loads(rendered)

        self.assertTrue(decoded)
        self.assertIsNotNone(decoded.get('errors'))

        errors = decoded['errors']

        self.assertEqual(len(errors), 1)

        error = errors[0]

        return error
コード例 #58
0
    def test_render_GET_vanilla(self):
        """Test rendering a request for normal, vanilla bridges."""
        self.useBenignBridges()

        request = DummyRequest([self.pagename])
        request.method = b'GET'
        request.getClientIP = lambda: '1.1.1.1'

        page = self.bridgesResource.render(request)

        # The response should explain how to use the bridge lines:
        self.assertTrue("To enter bridges into Tor Browser" in str(page))

        for b in self.parseBridgesFromHTMLPage(page):
            # Check that each bridge line had the expected number of fields:
            fields = b.split(' ')
            self.assertEqual(len(fields), 2)

            # Check that the IP and port seem okay:
            ip, port = fields[0].rsplit(':')
            self.assertIsInstance(ipaddr.IPv4Address(ip), ipaddr.IPv4Address)
            self.assertIsInstance(int(port), int)
            self.assertGreater(int(port), 0)
            self.assertLessEqual(int(port), 65535)
コード例 #59
0
    def setUp(self):
        """Create a :class:`server.BridgesResource` and protect it with
        a :class:`ReCaptchaProtectedResource`.
        """
        self.timeout = 10.0  # Can't take longer than that, right?
        # Set up our resources to fake a minimal HTTP(S) server:
        self.pagename = b'captcha.html'
        self.root = Resource()
        # (None, None) is the (distributor, scheduleInterval):
        self.protectedResource = server.BridgesResource(None, None)
        self.captchaResource = server.ReCaptchaProtectedResource(
            publicKey='23',
            secretKey='42',
            remoteIP='111.111.111.111',
            useForwardedHeader=True,
            protectedResource=self.protectedResource)

        self.root.putChild(self.pagename, self.captchaResource)

        # Set up the basic parts of our faked request:
        self.request = DummyRequest([self.pagename])