Пример #1
0
    def run_tests(self):
        # import here, cause outside the eggs aren't loaded
        import pytest

        import advocate
        import advocate.packages.ipaddress as ipaddress
        from test.monkeypatching import AdvocateEnforcer, CheckedSocket

        # We need to change to the checkout dir, requests' test suite expects certain files
        # to be in the CWD.
        with pushd(self.requests_location):
            validator = advocate.AddrValidator(
                ip_whitelist={
                    # requests needs to be able to hit these for its tests!
                    ipaddress.ip_network("127.0.0.1"),
                    ipaddress.ip_network("127.0.1.1"),
                    ipaddress.ip_network("10.255.255.1"),
                },
                # the `httpbin` fixture uses a random fixture, we need to allow all ports
                port_whitelist=set(range(0, 65535)),
            )
            enforcer = AdvocateEnforcer(validator)
            with enforcer.monkeypatch_requests_module():
                socket.socket = CheckedSocket
                errno = pytest.main(self.pytest_args,
                                    plugins=["requests_pytest_plugin"])
                sys.exit(errno)
Пример #2
0
 def test_ip_whitelist_blacklist_conflict(self):
     """Manual whitelist should take precedence over manual blacklist"""
     validator = AddrValidator(
         ip_whitelist=(ipaddress.ip_network("127.0.0.1"), ),
         ip_blacklist=(ipaddress.ip_network("127.0.0.1"), ),
     )
     self.assertTrue(validator.is_ip_allowed("127.0.0.1"))
Пример #3
0
 def test_manual_ip_blacklist(self):
     """Test manually blacklisting based on IP"""
     validator = AddrValidator(
         allow_ipv6=True,
         ip_blacklist=(
             ipaddress.ip_network("132.0.5.0/24"),
             ipaddress.ip_network("152.0.0.0/8"),
             ipaddress.ip_network("::1"),
         ),
     )
     self.assertFalse(validator.is_ip_allowed("132.0.5.1"))
     self.assertFalse(validator.is_ip_allowed("152.254.90.1"))
     self.assertTrue(validator.is_ip_allowed("178.254.90.1"))
     self.assertFalse(validator.is_ip_allowed("::1"))
     # Google, found via `dig google.com AAAA`
     self.assertTrue(validator.is_ip_allowed("2607:f8b0:400a:807::200e"))
Пример #4
0
    def test_advocate_wrapper_futures(self):
        wrapper = RequestsAPIWrapper(validator=AddrValidator())
        local_validator = AddrValidator(ip_whitelist={
            ipaddress.ip_network("127.0.0.1"),
        })
        local_wrapper = RequestsAPIWrapper(validator=local_validator)

        with self.assertRaises(UnacceptableAddressException):
            sess = wrapper.FuturesSession()
            sess.get("http://127.0.0.1/").result()

        with self.assertRaises(Exception) as cm:
            sess = local_wrapper.FuturesSession()
            sess.get("http://127.0.0.1:1/").result()
        # Check that we got a connection exception instead of a validation one
        # This might be either exception depending on the requests version
        self.assertRegexpMatches(
            cm.exception.__class__.__name__,
            r"\A(Connection|Protocol)Error",
        )

        with self.assertRaises(UnacceptableAddressException):
            sess = wrapper.FuturesSession()
            sess.get("http://localhost:1/").result()
        with self.assertRaises(UnacceptableAddressException):
            sess = wrapper.FuturesSession()
            sess.get("https://localhost:1/").result()
Пример #5
0
def pytest_runtestloop():
    validator = advocate.AddrValidator(
        ip_whitelist={
            # requests needs to be able to hit these for its tests!
            ipaddress.ip_network("127.0.0.1"),
            ipaddress.ip_network("127.0.1.1"),
            ipaddress.ip_network("10.255.255.1"),
        },
        # the `httpbin` fixture uses a random port, we need to allow all ports
        port_whitelist=set(range(0, 65535)),
    )

    # this will yell at us if we failed to patch something
    socket.socket = CheckedSocket

    # requests' tests rely on being able to pickle a `Session`
    advocate.api.RequestsAPIWrapper.SUPPORT_WRAPPER_PICKLING = True
    wrapper = advocate.api.RequestsAPIWrapper(validator)

    for attr in advocate.api.__all__:
        setattr(requests, attr, getattr(wrapper, attr))
Пример #6
0
    def test_connect_without_local_addresses(self,
                                             mock_determine_local_addresses):
        fake_addresses = [ipaddress.ip_network("200.1.1.1")]
        mock_determine_local_addresses.return_value = fake_addresses

        validator = permissive_validator(autodetect_local_addresses=True)
        advocate.get("http://example.com/", validator=validator)
        # Check that `is_ip_allowed` didn't make its own call to determine
        # local addresses
        mock_determine_local_addresses.assert_called_once_with()
        mock_determine_local_addresses.reset_mock()

        validator = permissive_validator(autodetect_local_addresses=False)
        advocate.get("http://example.com", validator=validator)
        mock_determine_local_addresses.assert_not_called()
Пример #7
0
    def test_wrapper_session_pickle(self):
        # Make sure the validator still works after a pickle round-trip
        wrapper = RequestsAPIWrapper(validator=AddrValidator(ip_whitelist={
            ipaddress.ip_network("127.0.0.1"),
        }))
        sess_instance = pickle.loads(pickle.dumps(wrapper.Session()))

        with self.assertRaises(Exception) as cm:
            sess_instance.get("http://127.0.0.1:1/")
        self.assertRegexpMatches(
            cm.exception.__class__.__name__,
            r"\A(Connection|Protocol)Error",
        )
        self.assertRaises(UnacceptableAddressException, sess_instance.get,
                          "http://127.0.1.1:1/")
Пример #8
0
    def test_local_address_handling(self, mock_determine_local_addresses):
        fake_addresses = [ipaddress.ip_network("200.1.1.1")]
        mock_determine_local_addresses.return_value = fake_addresses

        self.assertFalse(
            self._is_addrinfo_allowed("200.1.1.1",
                                      80,
                                      autodetect_local_addresses=True))
        # Check that `is_ip_allowed` didn't make its own call to determine
        # local addresses
        mock_determine_local_addresses.assert_called_once_with()
        mock_determine_local_addresses.reset_mock()

        self.assertTrue(
            self._is_addrinfo_allowed(
                "200.1.1.1",
                80,
                autodetect_local_addresses=False,
            ))
        mock_determine_local_addresses.assert_not_called()
Пример #9
0
    def test_wrapper_session_subclass(self):
        # Make sure pickle doesn't explode if we try to pickle a subclass
        # of `wrapper.Session`
        wrapper = RequestsAPIWrapper(validator=AddrValidator(ip_whitelist={
            ipaddress.ip_network("127.0.0.1"),
        }))

        class _SessionThing(wrapper.Session):
            pass

        sess_instance = pickle.loads(pickle.dumps(_SessionThing()))

        with self.assertRaises(Exception) as cm:
            sess_instance.get("http://127.0.0.1:1/")
        self.assertRegexpMatches(
            cm.exception.__class__.__name__,
            r"\A(Connection|Protocol)Error",
        )
        self.assertRaises(UnacceptableAddressException, sess_instance.get,
                          "http://127.0.1.1:1/")
Пример #10
0
 def test_safecurl_blacklist(self):
     """Test that we at least disallow everything SafeCurl does"""
     # All IPs that SafeCurl would disallow
     bad_netblocks = (ipaddress.ip_network(x)
                      for x in ('0.0.0.0/8', '10.0.0.0/8', '100.64.0.0/10',
                                '127.0.0.0/8', '169.254.0.0/16',
                                '172.16.0.0/12', '192.0.0.0/29',
                                '192.0.2.0/24', '192.88.99.0/24',
                                '192.168.0.0/16', '198.18.0.0/15',
                                '198.51.100.0/24', '203.0.113.0/24',
                                '224.0.0.0/4', '240.0.0.0/4'))
     i = 0
     validator = AddrValidator()
     for bad_netblock in bad_netblocks:
         num_ips = bad_netblock.num_addresses
         # Don't test *every* IP in large netblocks
         step_size = int(min(max(num_ips / 255, 1), 128))
         for ip_idx in six.moves.range(0, num_ips, step_size):
             i += 1
             bad_ip = bad_netblock[ip_idx]
             bad_ip_allowed = validator.is_ip_allowed(bad_ip)
             if bad_ip_allowed:
                 print(i, bad_ip)
             self.assertFalse(bad_ip_allowed)
Пример #11
0
 def test_ip_whitelist(self):
     """Test manually whitelisting based on IP"""
     validator = AddrValidator(
         ip_whitelist=(ipaddress.ip_network("127.0.0.1"), ), )
     self.assertTrue(validator.is_ip_allowed("127.0.0.1"))
Пример #12
0
from advocate.connection import advocate_getaddrinfo
from advocate.exceptions import (
    MountDisabledException,
    NameserverException,
    UnacceptableAddressException,
)
from advocate.packages import ipaddress
from advocate.futures import FuturesSession

# We use port 1 for testing because nothing is likely to legitimately listen
# on it.
AddrValidator.DEFAULT_PORT_WHITELIST.add(1)

RequestsAPIWrapper.SUPPORT_WRAPPER_PICKLING = True
global_wrapper = RequestsAPIWrapper(validator=AddrValidator(ip_whitelist={
    ipaddress.ip_network("127.0.0.1"),
}))
RequestsAPIWrapper.SUPPORT_WRAPPER_PICKLING = False


class _WrapperSubclass(global_wrapper.Session):
    def good_method(self):
        return "foo"


def canonname_supported():
    """Check if the nameserver supports the AI_CANONNAME flag

    travis-ci.org's Python 3 env doesn't seem to support it, so don't try
    any of the test that rely on it.
    """