Exemplo n.º 1
0
def punch_hole_in_firewall(ips):
    if current_os() == 'macos':
        pf = PFCtl()
        ip_list = '{ ' + ', '.join(ips) + ' }'
        pf.set_rules([
            "pass in quick from {} no state".format(ip_list),
            "pass out quick to {} no state".format(ip_list)
        ])
    elif current_os() == 'windows':
        L.warning(
            "Ignoring option to open up firewall for {} on Windows".format(
                ', '.join(ips)))
    else:
        raise XVEx('Editing the firewall is only supported for PF/macOS')
    def discover_device(self, discovery_keys):
        if 'device_id' not in discovery_keys or discovery_keys['device_id'] != 'localhost':
            return None

        if len(discovery_keys) != 1:
            L.warning(
                "Only the 'device_id' discovery key is valid for discovering localhost. The others "
                "will be ignored: {}".format(discovery_keys))

        if current_os() == 'windows':
            connector = WindowsLocalShellConnector()
        else:
            connector = LocalShellConnector()
        return create_device(current_os(), self._localhost_config, connector)
Exemplo n.º 3
0
    def test_current_os(self):
        for plat in ['linux', 'linux2']:
            with mock.patch.object(sys, 'platform', plat):
                self.assertEqual(current_os(), 'linux')

        with mock.patch.object(sys, 'platform', 'darwin'):
            self.assertEqual(current_os(), 'macos')

        for plat in ['win32', 'cygwin']:
            with mock.patch.object(sys, 'platform', plat):
                self.assertEqual(current_os(), 'windows')

        with mock.patch.object(sys, 'platform', 'unknown'):
            with self.assertRaises(Exception):
                current_os()
Exemplo n.º 4
0
 def _create_route_to_ip(self, ip):
     default_gateway = netifaces.gateways()['default'][netifaces.AF_INET][0]
     L.debug("Adding route to ip: {} -> {}".format(ip, default_gateway))
     if current_os() == 'windows':
         raise XVEx("TODO: Implement route on windows")
     else:
         route = [ip, default_gateway]
         subprocess.check_output(['route', 'add'] + route)
         self._routes_to_remote.append(route)
Exemplo n.º 5
0
    def detect(self):
        if current_os() != "macos":
            return None

        L.debug("Trying to determine if we're using a macOS network extension")
        vpn_info = VPNInfo()

        if not self._ne_processes():
            L.debug('Not using a network extension')
            return None

        L.info("Detected a VPN network extension (unknown protocol)")

        vpn_info.vpn_processes = self._ne_processes()
        return vpn_info
Exemplo n.º 6
0
def main(argv=None):
    if argv is None:
        argv = sys.argv[1:]

    # Some of these command line args are also specified in the context. This is just for
    # convenience as certain of the arguments are changed often enough to warrant specifying them
    # on the command line.
    parser = argparse.ArgumentParser(
        description=
        'Run a set of tests locally on the current machine. The exit code of this '
        '"command will be the number of tests which failed or, if an unexpected error occured, -1.'
    )
    parser.add_argument(
        '-o',
        '--output-root',
        help='Root folder where all output for this test run will be '
        'written. Defaults to a system temp directory for the current user.')
    parser.add_argument(
        '-c',
        '--test-configs',
        default=[],
        nargs='+',
        help='Either: a python file with a module '
        'level list attribute TESTS is list of tests; a json file whose top level element is an '
        'array of tests; or a json string parsable to a list of tests.')
    parser.add_argument(
        '-d',
        '--test-devices',
        default=[],
        nargs='+',
        help='Either: a python file with a module '
        'level list attribute DEVICES is list of devices; a json file whose top level element is '
        'an array of devices; or a json string parsable to a list of tests.')
    parser.add_argument(
        '-r',
        '--run-directory',
        default=None,
        help='A unique subdirectory of the output_root '
        'where results for this specific run will go. If not specified then a unique one will be '
        "generated based on the run timestamp. The directory will be created if it doesn't exist"
    )
    parser.add_argument(
        '-m',
        '--allow-manual',
        default=None,
        action='store_true',
        help=
        'Allow manual tests. If this is not specified then any test which requires manual '
        'interaction will fail')
    parser.add_argument(
        '-s',
        '--stop-on-fail',
        default=None,
        action='store_true',
        help=
        'If specified, the test run will stop as soon as the first test fails.'
    )
    parser.add_argument('-t',
                        '--test-regex',
                        default=None,
                        help='If specified, only run tests whose test class '
                        'name matches the passed regex.')
    parser.add_argument('-x',
                        '--context',
                        default='default_context.py',
                        help='If specified, only run tests whose '
                        'test class name matches the passed regex.')
    parser.add_argument('-l',
                        '--log-level',
                        default=None,
                        help='Log level. Valid values ["ERROR", "WARNING", '
                        '"INFO", "DEBUG", "VERBOSE"].')
    parser.add_argument('-2',
                        '--v2',
                        default=False,
                        action='store_true',
                        help='DEPRECATED: Does nothing')
    args = parser.parse_args(argv)

    args.log_level = args.log_level.upper() if args.log_level else None
    # We'll reconfigure in a second but lets get logging going asap!
    inital_log_level = args.log_level if args.log_level else "INFO"
    TestRunner.configure_logger(level=inital_log_level)

    if args.output_root is None:
        if current_os() == "windows":
            args.output_root = tempfile.mkdtemp()
        else:
            # Don't make the folder as root else we'll get perms issues. This also ensures we use
            # the user's temp directory not root's temp directory.
            args.output_root = subprocess.check_output(
                ['sudo', '-u', tools_user()[1], 'mktemp',
                 '-d']).decode().strip()
        L.warning("You didn't specify an output folder. Using: {}".format(
            args.output_root))

    args.output_root = windows_safe_path(args.output_root)

    if not os.path.exists(args.output_root):
        makedirs_safe(args.output_root)

    if args.run_directory is None:
        args.run_directory = "Run_{}".format(time.time())

    # Just add output_directory to the args object as it makes life simpler.
    args.output_directory = os.path.join(args.output_root, args.run_directory)
    makedirs_safe(args.output_directory)

    context_dict = import_by_filename(args.context).CONTEXT
    cmd_line_overrides = [
        'run_directory',
        'output_directory',
        'allow_manual',
        'stop_on_fail',
        'log_level',
    ]

    for override in cmd_line_overrides:
        value = getattr(args, override)
        if value is not None:
            context_dict[override] = value

    # Log level might need updating based on config
    TestRunner.configure_logger(args.output_directory,
                                level=getattr(L, context_dict['log_level']))

    test_configs = []
    for test_config_file in args.test_configs:
        test_configs += object_from_command_line(test_config_file, 'TESTS')

    test_devices = []
    for test_device_file in args.test_devices:
        test_devices += object_from_command_line(test_device_file, 'DEVICES')

    if args.test_regex:
        test_configs = filter_tests(test_configs, args.test_regex)

    # This call shouldn't throw. If it does then we need to tweak the TestRunner.
    if args.v2:
        L.warning(
            "Argument -2 is DEPRECATED and will be ignored. Test runner v2 is the default now"
        )
    return TestRunner(TestRunContext(context_dict), test_devices,
                      test_configs).run()
Exemplo n.º 7
0
def bin_path():
    if current_os() == 'macos':
        return '/usr/local/bin/'
    return '/usr/bin/'
Exemplo n.º 8
0
def getch():
    if current_os() == 'windows' and is_dos():
        import msvcrt # pylint: disable=import-error
        return msvcrt.getch()
    return _getch_unix()
Exemplo n.º 9
0
        "device_name": "localhost",
        'components': {
            'vpn_application': {
                'name': 'generic',
            }
        },
    }],
    'parameters': {
        'browser': Replacee('$BROWSER'),
        'ask_perms': True,
    }
}

# Run the tests on all major browsers for the current OS.
BROWSERS = ['chrome', 'opera', 'firefox']

if current_os() == 'macos':
    BROWSERS.append('safari')
elif current_os() == 'windows':
    BROWSERS.append('edge')

# Duplicate the test templates for each browser
TESTS += TemplateEvaluator.generate([{
    'TEMPLATE': TEMPLATE_VANILLA,
    '$BROWSER': Each(BROWSERS)
}])
TESTS += TemplateEvaluator.generate([{
    'TEMPLATE': TEMPLATE_PERMISSIONS_GRANTED,
    '$BROWSER': Each(BROWSERS)
}])
from xv_leak_tools.helpers import current_os
from xv_leak_tools.test_templating.templating import TemplateEvaluator, Replacee, Each

# TODO: Add variants of the test which explicitly require local and public DNS servers.
# TODO: Ensure the tests check for number of adapters (they will fail, but checking is nicer)

# Note that packet capture tests are inherently noisy at the moment. Very few (if any) VPN providers
# guarantee no non-tunnel traffic so false positives are almost guaranteed. The tests are still
# useful for investigatory purposes.

# This list will contain all the individual test configurations
TESTS = []

if current_os() == "macos":
    TEST_NAMES = [
        "TestMacOSDNSDisruptEnableNewService",
        "TestMacOSDNSDisruptInterface",
        "TestMacOSDNSDisruptService",
        "TestMacOSDNSDisruptWifiPower",
        "TestMacOSIPResponderDisruptEnableNewService",
        "TestMacOSIPResponderDisruptInterface",
        "TestMacOSIPResponderDisruptService",
        "TestMacOSIPResponderDisruptWifiPower",
        "TestMacOSPacketCaptureDisruptEnableNewService",
        "TestMacOSPacketCaptureDisruptInterface",
        "TestMacOSPacketCaptureDisruptService",
        "TestMacOSPacketCaptureDisruptWifiPower",
    ]
elif current_os() == "windows":
    TEST_NAMES = [
        "TestWindowsDNSDisruptEnableNewAdapter",
Exemplo n.º 11
0
 def _vmrun_path():
     if current_os() == 'macos':
         return '/Applications/VMware Fusion.app/Contents/Library/vmrun'
     raise XVEx("TODO: Implement VMWare support for OS '{}'".format(current_os()))