def test_open(): w = WinDivert("false") w.open() assert w.is_open w.close() assert not w.is_open with w: # open a second one. with WinDivert("false") as w2: assert w2.is_open assert w.is_open assert "open" in repr(w) with pytest.raises(RuntimeError): w.open() assert not w.is_open assert "closed" in repr(w) with pytest.raises(RuntimeError): w.recv() with pytest.raises(RuntimeError): w.close()
def test_register(self): """ Tests DLL registration """ d = WinDivert().register() assert d.is_registered() assert os.path.abspath(d.dll_path) == DEFAULT_DLL_PATH
def test_parse_packet_raise_exc(self): """ Tests the parsing packet function to raise an exception when invoked with wrong number of arguments """ driver = WinDivert().register() with pytest.raises(ValueError): driver.parse_packet("", "", "")
def test_register(self): """ Tests DLL registration """ w = WinDivert(self.dll_path) w.register() self.assertTrue(w.is_registered())
def test_construct_handle(self): """ Tests constructing an handle from a WinDivert instance """ driver = WinDivert() handle = Handle(driver, filter="tcp.DstPort == 23", priority=1000) self.assertIsInstance(handle, Handle) self.assertFalse(handle.is_opened)
def test_register(self): """ Tests DLL registration """ d = WinDivert(self.dll_path).register() self.assertTrue(d.is_registered()) self.assertEquals(os.path.abspath(d.dll_path), os.path.abspath(self.dll_path))
def setUp(self): super(WinDivertTCPIPv6TestCase, self).setUp() # Initialize the fake tcp server self.server = FakeTCPServerIPv6(("::1", 0), EchoUpperTCPHandler) WinDivert(os.path.join(self.driver_dir, "WinDivert.dll")).register() self.server_thread = threading.Thread(target=self.server.serve_forever) self.server_thread.start()
def setUp(self): super(WinDivertUDPTestCase, self).setUp() # Initialize the fake tcp server self.server = FakeUDPServer(("127.0.0.1", 0), EchoUpperUDPHandler) self.driver = WinDivert(os.path.join(self.driver_dir, "WinDivert.dll")) self.server_thread = threading.Thread(target=self.server.serve_forever) self.server_thread.start()
def test_load_ok(self): """ Tests DLL loading with a correct path """ try: WinDivert(self.dll_path) except WindowsError as e: self.fail("WinDivert() constructor raised %s" % e)
def setUp(self): os.chdir(driver_dir) # Initialize the fake tcp server self.server = FakeTCPServerIPv4(("127.0.0.1", 0), EchoUpperTCPHandler) self.driver = WinDivert(os.path.join(driver_dir, "WinDivert.dll")) self.server_thread = threading.Thread(target=self.server.serve_forever) self.server_thread.start()
def setUp(self): super(WinDivertExternalInterfaceTestCase, self).setUp() # Initialize the fake tcp server self.server = FakeTCPServerIPv4((socket.gethostbyname(socket.gethostname()), 0), EchoUpperTCPHandler) WinDivert().register() self.server_thread = threading.Thread(target=self.server.serve_forever) self.server_thread.start()
def test_load_ok(self): """ Tests DLL loading with a correct path """ try: d = WinDivert() assert os.path.abspath(d.get_reference()._name) == DEFAULT_DLL_PATH except WindowsError as e: self.fail("WinDivert() constructor raised %s" % e)
def setUp(self): super(WinDivertTCPIPv4TestCase, self).setUp() # Initialize the fake tcp server self.server = FakeTCPServerIPv4(("127.0.0.1", 0), EchoUpperTCPHandler) self.driver = WinDivert() self.server_thread = threading.Thread(target=self.server.serve_forever) self.server_thread.start()
def test_load_already_registered(self): """ Tests WinDivert loading from the default path (DLLs dir inside python's home). This assumes the driver has been previously registered """ try: WinDivert() except WindowsError as e: self.fail("WinDivert() constructor raised %s" % e)
def check_driver_path(cls, path): """ Checks driver registration after installation :param path: The path where is expected to find the WinDivert.dll """ try: return WinDivert(dll_path=path).register() except Exception as e: sys.stderr.write("Driver registration failed: %s" % str(e))
def test_parse_ipv6_address(self): """ Tests parsing of an ipv4 address into a network byte value """ address = "2607:f0d0:1002:0051:0000:0000:0000:0004" driver = WinDivert(self.dll_path).register() result = inet_ntop(socket.AF_INET6, driver.parse_ipv6_address(address)) self.assertEqual(inet_pton(socket.AF_INET6, address), inet_pton(socket.AF_INET6, result))
def setUp(self): os.chdir(driver_dir) # Initialize the fake tcp server self.server = FakeTCPServerIPv4( (socket.gethostbyname(socket.gethostname()), 0), EchoUpperTCPHandler) WinDivert(os.path.join(driver_dir, "WinDivert.dll")).register() self.server_thread = threading.Thread(target=self.server.serve_forever) self.server_thread.start()
def test_open_handle(self): """ Tests the open_handle method. """ handle = WinDivert(self.dll_path).open_handle( filter="tcp.DstPort == 23", priority=1000) self.assertIsInstance(handle, Handle) self.assertTrue(handle.is_opened) handle.close() self.assertFalse(handle.is_opened)
def test_load_ok(self): """ Tests DLL loading with a correct path """ try: d = WinDivert(self.dll_path) self.assertEquals(os.path.abspath(d.get_reference()._name), os.path.abspath(self.dll_path)) except WindowsError as e: self.fail("WinDivert() constructor raised %s" % e)
def test_parse_ipv4_address(self): """ Tests parsing of an ipv4 address into a network byte value """ address = "192.168.1.1" driver = WinDivert() driver.register() result = driver.parse_ipv4_address(address) self.assertEqual( struct.unpack(">I", inet_pton(socket.AF_INET, address))[0], result)
def test_open_handle(self): """ Tests the open_handle method. """ # with cd(os.path.dirname(self.dll_path)): handle = WinDivert().open_handle(filter="tcp.DstPort == 23") assert isinstance(handle, Handle) assert handle.is_opened handle.close() assert not handle.is_opened
def test_unregister(): w = WinDivert("false") w.open() WinDivert.unregister() time.sleep(0.1) assert WinDivert.is_registered() w.close() # may not trigger immediately. while WinDivert.is_registered(): time.sleep(0.01) # pragma: no cover
def test_open_handle(self): """ Tests the open_handle method. """ # with cd(os.path.dirname(self.dll_path)): handle = WinDivert( self.dll_path).open_handle(filter="tcp.DstPort == 23") self.assertIsInstance(handle, Handle) self.assertTrue(handle.is_opened) handle.close() self.assertFalse(handle.is_opened)
def test_load_from_registry(self): """ Tesst WinDivert loading from registry key. This assumes the driver has been previously registered """ try: reg_key = "SYSTEM\\CurrentControlSet\\Services\\WinDivert1.0" if get_reg_values(reg_key): WinDivert(reg_key=reg_key) except WindowsError as e: self.fail("WinDivert() constructor raised %s" % e)
def test_parse_ipv6_address(self): """ Tests parsing of an ipv4 address into a network byte value """ address = "2607:f0d0:1002:0051:0000:0000:0000:0004" driver = WinDivert(self.dll_path) driver.register() result = driver.parse_ipv6_address(address) self.assertEqual( struct.unpack("<HHHHHHHH", inet_pton(socket.AF_INET6, address)), tuple(result))
def __init__(self, redirect_ports=(80, 443), proxy_addr=False, proxy_port=8080, api_host="localhost", api_port=PROXY_API_PORT, cache_size=65536): """ :param redirect_ports: if the destination port is in this tuple, the requests are redirected to the proxy. :param proxy_addr: IP address of the proxy (IP within a network, 127.0.0.1 does not work). By default, this is detected automatically. :param proxy_port: Port the proxy is listenting on. :param api_host: Host the forward module API is listening on. :param api_port: Port the forward module API is listening on. :param cache_size: Maximum number of connection tuples that are stored. Only relevant in very high load scenarios. """ if not proxy_addr: # Auto-Detect local IP. # https://stackoverflow.com/questions/166506/finding-local-ip-addresses-using-pythons-stdlib s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(("8.8.8.8", 80)) proxy_addr = s.getsockname()[0] s.close() self.client_server_map = OrderedDict() self.proxy_addr, self.proxy_port = proxy_addr, proxy_port self.connection_cache_size = cache_size self.api_server = APIServer((api_host, api_port), APIRequestHandler) self.api_server.proxifier = self self.api_server_thread = threading.Thread(target=self.api_server.serve_forever) self.api_server_thread.daemon = True arch = "amd64" if platform.architecture()[0] == "64bit" else "x86" self.driver = WinDivert(os.path.join(os.path.dirname(__file__), "..", "contrib", "windivert", arch, "WinDivert.dll")) self.driver.register() filter_forward = " or ".join( ("tcp.DstPort == %d" % p) for p in redirect_ports) self.handle_forward = self.driver.open_handle(filter=filter_forward, layer=Layer.NETWORK_FORWARD) self.forward_thread = threading.Thread(target=self.redirect) self.forward_thread.daemon = True filter_local = "outbound and tcp.SrcPort == %d" % proxy_port self.handle_local = self.driver.open_handle(filter=filter_local, layer=Layer.NETWORK) self.local_thread = threading.Thread(target=self.adjust_source) self.local_thread.daemon = True self.handle_icmp = self.driver.open_handle(filter="icmp", layer=Layer.NETWORK, flags=Flag.DROP)
def setUp(self): super(WinDivertAsyncTestCase, self).setUp() # Initialize the fake tcp server self.server = FakeTCPServerIPv4(("127.0.0.1", 0), EchoUpperTCPHandler) filter = "outbound and tcp.DstPort == %d and tcp.PayloadLength > 0" % self.server.server_address[1] self.driver = WinDivert() self.driver.register() self.handle = self.driver.open_handle(filter=filter) self.server_thread = threading.Thread(target=self.server.serve_forever) self.server_thread.start() # Initialize the fake tcp client self.text = "Hello World!" self.client = FakeTCPClient(self.server.server_address, self.text.encode("UTF-8")) self.client_thread = threading.Thread(target=self.client.send) self.client_thread.start()
def setUp(self): super(WinDivertTestCase, self).setUp() WinDivert(self.dll_path).register()
def test_parse_packet_raise_exc(self): """ Tests the parsing packet function to raise an exception when invoked with wrong number of arguments """ driver = WinDivert(self.dll_path).register() self.assertRaises(ValueError, driver.parse_packet, "", "", "")
def __init__(self, mode="both", redirect_ports=(80, 443), custom_filter=None, proxy_addr=False, proxy_port=8080, api_host="localhost", api_port=PROXY_API_PORT, cache_size=65536): """ :param mode: Redirection operation mode: "forward" to only redirect forwarded packets, "local" to only redirect packets originating from the local machine, "both" to redirect both. :param redirect_ports: if the destination port is in this tuple, the requests are redirected to the proxy. :param custom_filter: specify a custom WinDivert filter to select packets that should be intercepted. Overrides redirect_ports setting. :param proxy_addr: IP address of the proxy (IP within a network, 127.0.0.1 does not work). By default, this is detected automatically. :param proxy_port: Port the proxy is listenting on. :param api_host: Host the forward module API is listening on. :param api_port: Port the forward module API is listening on. :param cache_size: Maximum number of connection tuples that are stored. Only relevant in very high load scenarios. """ if proxy_port in redirect_ports: raise ValueError("The proxy port must not be a redirect port.") if not proxy_addr: # Auto-Detect local IP. # https://stackoverflow.com/questions/166506/finding-local-ip-addresses-using-pythons-stdlib s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(("8.8.8.8", 80)) proxy_addr = s.getsockname()[0] s.close() self.mode = mode self.proxy_addr, self.proxy_port = proxy_addr, proxy_port self.connection_cache_size = cache_size self.client_server_map = OrderedDict() self.api = APIServer(self, (api_host, api_port), APIRequestHandler) self.api_thread = threading.Thread(target=self.api.serve_forever) self.api_thread.daemon = True self.driver = WinDivert() self.driver.register() self.request_filter = custom_filter or " or ".join( ("tcp.DstPort == %d" % p) for p in redirect_ports) self.request_forward_handle = None self.request_forward_thread = threading.Thread( target=self.request_forward) self.request_forward_thread.daemon = True self.addr_pid_map = dict() self.trusted_pids = set() self.tcptable2 = MIB_TCPTABLE2(0) self.tcptable2_size = DWORD(0) self.request_local_handle = None self.request_local_thread = threading.Thread(target=self.request_local) self.request_local_thread.daemon = True # The proxy server responds to the client. To the client, # this response should look like it has been sent by the real target self.response_filter = "outbound and tcp.SrcPort == %d" % proxy_port self.response_handle = None self.response_thread = threading.Thread(target=self.response) self.response_thread.daemon = True self.icmp_handle = None