Пример #1
0
def main() -> None:
    global global_scanner

    # For py2exe builds
    freeze_support()

    # Handle SIGINT to terminate processes
    signal.signal(signal.SIGINT, sigint_handler)
    start_time = time()

    # Create the command line parser and the list of available options
    sslyze_parser = CommandLineParser(__version__)
    try:
        parsed_command_line = sslyze_parser.parse_command_line()
    except CommandLineParsingError as e:
        print(e.get_error_msg())
        return

    output_hub = OutputHub()
    output_hub.command_line_parsed(parsed_command_line)

    global_scanner = Scanner(
        per_server_concurrent_connections_limit=parsed_command_line.per_server_concurrent_connections_limit,
        concurrent_server_scans_limit=parsed_command_line.concurrent_server_scans_limit,
    )

    # Figure out which hosts are up and fill the task queue with work to do
    connectivity_tester = ServerConnectivityTester()
    with ThreadPoolExecutor(max_workers=10) as thread_pool:
        futures = [
            thread_pool.submit(connectivity_tester.perform, server_location, network_config)
            for server_location, network_config in parsed_command_line.servers_to_scans
        ]
        for completed_future in as_completed(futures):
            try:
                server_connectivity_info = completed_future.result()
                output_hub.server_connectivity_test_succeeded(server_connectivity_info)

                # Send scan commands for this server to the scanner
                scan_request = ServerScanRequest(
                    server_info=server_connectivity_info,
                    scan_commands=parsed_command_line.scan_commands,
                    scan_commands_extra_arguments=parsed_command_line.scan_commands_extra_arguments,
                )
                global_scanner.queue_scan(scan_request)

            except ConnectionToServerFailed as e:
                output_hub.server_connectivity_test_failed(e)

    output_hub.scans_started()

    # Process the results as they come
    for scan_result in global_scanner.get_results():
        output_hub.server_scan_completed(scan_result)

    # All done
    exec_time = time() - start_time
    output_hub.scans_completed(exec_time)
Пример #2
0
def main() -> None:
    start_time = time()

    # Create the command line parser and the list of available options
    sslyze_parser = CommandLineParser(__version__)
    try:
        # Parse the supplied command line
        parsed_command_line = sslyze_parser.parse_command_line()
    except CommandLineParsingError as e:
        print(e.get_error_msg())
        return

    output_hub = OutputHub()
    output_hub.command_line_parsed(parsed_command_line)

    # Figure out which servers are reachable
    connectivity_tester = ServerConnectivityTester()
    all_server_scan_requests = []
    with ThreadPoolExecutor(max_workers=10) as thread_pool:
        futures = [
            thread_pool.submit(connectivity_tester.perform, server_location, network_config)
            for server_location, network_config in parsed_command_line.servers_to_scans
        ]
        for completed_future in as_completed(futures):
            try:
                server_connectivity_info = completed_future.result()
                output_hub.server_connectivity_test_succeeded(server_connectivity_info)

                # Server is only; add it to the list of servers to scan
                scan_request = ServerScanRequest(
                    server_info=server_connectivity_info,
                    scan_commands=parsed_command_line.scan_commands,
                    scan_commands_extra_arguments=parsed_command_line.scan_commands_extra_arguments,
                )
                all_server_scan_requests.append(scan_request)

            except ConnectionToServerFailed as e:
                output_hub.server_connectivity_test_failed(e)

    # For the servers that are reachable, start the scans
    output_hub.scans_started()
    if all_server_scan_requests:
        sslyze_scanner = Scanner(
            per_server_concurrent_connections_limit=parsed_command_line.per_server_concurrent_connections_limit,
            concurrent_server_scans_limit=parsed_command_line.concurrent_server_scans_limit,
        )
        sslyze_scanner.start_scans(all_server_scan_requests)

        # Process the results as they come
        for scan_result in sslyze_scanner.get_results():
            output_hub.server_scan_completed(scan_result)

    # All done
    exec_time = time() - start_time
    output_hub.scans_completed(exec_time)
Пример #3
0
def main() -> None:
    global global_scanner

    # For py2exe builds
    freeze_support()

    # Handle SIGINT to terminate processes
    signal.signal(signal.SIGINT, sigint_handler)
    start_time = time()

    plugins_repository = PluginsRepository()
    available_plugins = plugins_repository.get_available_plugins()
    available_commands = plugins_repository.get_available_commands()

    # Create the command line parser and the list of available options
    sslyze_parser = CommandLineParser(available_plugins, __version__)
    try:
        good_server_list, malformed_server_list, args_command_list = sslyze_parser.parse_command_line(
        )
    except CommandLineParsingError as e:
        print(e.get_error_msg())
        return

    output_hub = OutputHub()
    output_hub.command_line_parsed(available_plugins, args_command_list,
                                   malformed_server_list)

    # Initialize the pool of processes that will run each plugin
    if args_command_list.https_tunnel or args_command_list.slow_connection:
        # Maximum one process to not kill the proxy or the connection
        global_scanner = ConcurrentScanner(max_processes_nb=1)
    else:
        global_scanner = ConcurrentScanner()

    # Figure out which hosts are up and fill the task queue with work to do
    connectivity_tester = ConcurrentServerConnectivityTester(good_server_list)
    connectivity_tester.start_connectivity_testing()

    # Store and print servers we were able to connect to
    online_servers_list = []
    for server_connectivity_info in connectivity_tester.get_reachable_servers(
    ):
        online_servers_list.append(server_connectivity_info)
        output_hub.server_connectivity_test_succeeded(server_connectivity_info)

        # Send tasks to worker processes
        for scan_command_class in available_commands:
            if getattr(args_command_list,
                       scan_command_class.get_cli_argument()):
                # Get this command's optional argument if there's any
                optional_args = {}
                for optional_arg_name in scan_command_class.get_optional_arguments(
                ):
                    # Was this option set ?
                    if getattr(args_command_list, optional_arg_name):
                        optional_args[optional_arg_name] = getattr(
                            args_command_list, optional_arg_name)
                scan_command = scan_command_class(
                    **optional_args)  # type: ignore

                global_scanner.queue_scan_command(server_connectivity_info,
                                                  scan_command)

    # Store and print servers we were NOT able to connect to
    for connectivity_exception in connectivity_tester.get_invalid_servers():
        output_hub.server_connectivity_test_failed(connectivity_exception)

    # Keep track of how many tasks have to be performed for each target
    task_num = 0
    output_hub.scans_started()
    for scan_command_class in available_commands:
        if getattr(args_command_list, scan_command_class.get_cli_argument()):
            task_num += 1

    # Each host has a list of results
    result_dict: Dict[Text, List[PluginScanResult]] = {}
    # We cannot use the server_info object directly as its address will change due to multiprocessing
    RESULT_KEY_FORMAT = '{hostname}:{ip_address}:{port}'
    for server_info in online_servers_list:
        result_dict[RESULT_KEY_FORMAT.format(hostname=server_info.hostname,
                                             ip_address=server_info.ip_address,
                                             port=server_info.port)] = []

    # Process the results as they come
    for plugin_result in global_scanner.get_results():
        server_info = plugin_result.server_info
        result_dict[RESULT_KEY_FORMAT.format(
            hostname=server_info.hostname,
            ip_address=server_info.ip_address,
            port=server_info.port)].append(plugin_result)

        plugin_result_list = result_dict[RESULT_KEY_FORMAT.format(
            hostname=server_info.hostname,
            ip_address=server_info.ip_address,
            port=server_info.port)]

        if len(plugin_result_list) == task_num:
            # Done with this server; send the result to the output hub
            output_hub.server_scan_completed(
                CompletedServerScan(server_info, plugin_result_list))

    # All done
    exec_time = time() - start_time
    output_hub.scans_completed(exec_time)
Пример #4
0
def main():
    # For py2exe builds
    freeze_support()

    # Handle SIGINT to terminate processes
    signal.signal(signal.SIGINT, sigint_handler)

    start_time = time()

    # Retrieve available plugins
    sslyze_plugins = PluginsFinder()
    available_plugins = sslyze_plugins.get_plugins()
    available_commands = sslyze_plugins.get_commands()

    # Create the command line parser and the list of available options
    sslyze_parser = CommandLineParser(available_plugins, __version__)
    try:
        good_server_list, bad_server_list, args_command_list = sslyze_parser.parse_command_line()
    except CommandLineParsingError as e:
        print e.get_error_msg()
        return

    output_hub = OutputHub()
    output_hub.command_line_parsed(available_plugins, args_command_list)


    # Initialize the pool of processes that will run each plugin
    if args_command_list.https_tunnel:
        # Maximum one process to not kill the proxy
        plugins_process_pool = PluginsProcessPool(sslyze_plugins, args_command_list.nb_retries,
                                                  args_command_list.timeout, max_processes_nb=1)
    else:
        plugins_process_pool = PluginsProcessPool(sslyze_plugins, args_command_list.nb_retries,
                                                  args_command_list.timeout)


    # Figure out which hosts are up and fill the task queue with work to do
    connectivity_tester = ServersConnectivityTester(good_server_list)
    connectivity_tester.start_connectivity_testing(network_timeout=args_command_list.timeout)

    # Store and print server whose command line string was bad
    for failed_scan in bad_server_list:
        output_hub.server_connectivity_test_failed(failed_scan)

    # Store and print servers we were able to connect to
    online_servers_list = []
    for server_connectivity_info in connectivity_tester.get_reachable_servers():
        online_servers_list.append(server_connectivity_info)
        output_hub.server_connectivity_test_succeeded(server_connectivity_info)

        # Send tasks to worker processes
        for plugin_command in available_commands:
            if getattr(args_command_list, plugin_command):
                # Get this plugin's options if there's any
                plugin_options_dict = {}
                for option in available_commands[plugin_command].get_interface().get_options():
                    # Was this option set ?
                    if getattr(args_command_list,option.dest):
                        plugin_options_dict[option.dest] = getattr(args_command_list, option.dest)

                plugins_process_pool.queue_plugin_task(server_connectivity_info, plugin_command, plugin_options_dict)


    # Store and print servers we were NOT able to connect to
    for tentative_server_info, exception in connectivity_tester.get_invalid_servers():
        failed_scan = FailedServerScan(tentative_server_info.server_string, exception)
        output_hub.server_connectivity_test_failed(failed_scan)


    # Keep track of how many tasks have to be performed for each target
    task_num = 0
    output_hub.scans_started()
    for command in available_commands:
        if getattr(args_command_list, command):
            task_num += 1


    # Each host has a list of results
    result_dict = {}
    # We cannot use the server_info object directly as its address will change due to multiprocessing
    RESULT_KEY_FORMAT = u'{hostname}:{ip_address}:{port}'.format
    for server_info in online_servers_list:
        result_dict[RESULT_KEY_FORMAT(hostname=server_info.hostname, ip_address=server_info.ip_address,
                                      port=server_info.port)] = []

    # Process the results as they come
    for plugin_result in plugins_process_pool.get_results():
        server_info = plugin_result.server_info
        result_dict[RESULT_KEY_FORMAT(hostname=server_info.hostname, ip_address=server_info.ip_address,
                                      port=server_info.port)].append(plugin_result)

        plugin_result_list = result_dict[RESULT_KEY_FORMAT(hostname=server_info.hostname,
                                                           ip_address=server_info.ip_address,
                                                           port=server_info.port)]

        if len(plugin_result_list) == task_num:
            # Done with this server; send the result to the output hub
            output_hub.server_scan_completed(CompletedServerScan(server_info, plugin_result_list))


    # All done
    exec_time = time()-start_time
    output_hub.scans_completed(exec_time)
Пример #5
0
def main() -> None:
    # Parse the supplied command line
    date_scans_started = datetime.utcnow()
    sslyze_parser = CommandLineParser(__version__)
    try:
        parsed_command_line = sslyze_parser.parse_command_line()
    except CommandLineParsingError as e:
        print(e.get_error_msg())
        return

    # Setup the observer to print to the console, if needed
    scanner_observers = []
    if not parsed_command_line.should_disable_console_output:
        observer_for_console_output = ObserverToGenerateConsoleOutput(
            file_to=sys.stdout, json_path_out=parsed_command_line.json_path_out
        )
        observer_for_console_output.command_line_parsed(parsed_command_line=parsed_command_line)

        scanner_observers.append(observer_for_console_output)

    # Setup the scanner
    sslyze_scanner = Scanner(
        per_server_concurrent_connections_limit=parsed_command_line.per_server_concurrent_connections_limit,
        concurrent_server_scans_limit=parsed_command_line.concurrent_server_scans_limit,
        observers=scanner_observers,
    )

    # Queue the scans
    all_server_scan_requests = []
    for server_location, network_config in parsed_command_line.servers_to_scans:
        scan_request = ServerScanRequest(
            server_location=server_location,
            network_configuration=network_config,
            scan_commands=parsed_command_line.scan_commands,
            scan_commands_extra_arguments=parsed_command_line.scan_commands_extra_arguments,
        )
        all_server_scan_requests.append(scan_request)

    # If there are servers that we were able to resolve, scan them
    all_server_scan_results = []
    if all_server_scan_requests:
        sslyze_scanner.queue_scans(all_server_scan_requests)
        for result in sslyze_scanner.get_results():
            # Results are actually displayed by the observer; here we just store them
            all_server_scan_results.append(result)

    # Write results to a JSON file if needed
    json_file_out: Optional[TextIO] = None
    if parsed_command_line.should_print_json_to_console:
        json_file_out = sys.stdout
    elif parsed_command_line.json_path_out:
        json_file_out = parsed_command_line.json_path_out.open("wt", encoding="utf-8")

    if json_file_out:
        json_output = SslyzeOutputAsJson(
            server_scan_results=[ServerScanResultAsJson.from_orm(result) for result in all_server_scan_results],
            invalid_server_strings=[
                InvalidServerStringAsJson.from_orm(bad_server) for bad_server in parsed_command_line.invalid_servers
            ],
            date_scans_started=date_scans_started,
            date_scans_completed=datetime.utcnow(),
        )
        json_output_as_str = json_output.json(sort_keys=True, indent=4, ensure_ascii=True)
        json_file_out.write(json_output_as_str)

    # If we printed the JSON results to the console, don't run the Mozilla compliance check so we return valid JSON
    if parsed_command_line.should_print_json_to_console:
        sys.exit(0)

    if not all_server_scan_results:
        # There are no results to present: all supplied server strings were invalid?
        sys.exit(0)

    # Check the results against the Mozilla config if needed
    are_all_servers_compliant = True
    # TODO(AD): Expose format_title method
    title = ObserverToGenerateConsoleOutput._format_title("Compliance against Mozilla TLS configuration")
    print()
    print(title)
    if not parsed_command_line.check_against_mozilla_config:
        print("    Disabled; use --mozilla_config={old, intermediate, modern}.\n")
    else:

        print(
            f'    Checking results against Mozilla\'s "{parsed_command_line.check_against_mozilla_config}"'
            f" configuration. See https://ssl-config.mozilla.org/ for more details.\n"
        )
        mozilla_checker = MozillaTlsConfigurationChecker.get_default()
        for server_scan_result in all_server_scan_results:
            try:
                mozilla_checker.check_server(
                    against_config=parsed_command_line.check_against_mozilla_config,
                    server_scan_result=server_scan_result,
                )
                print(f"    {server_scan_result.server_location.display_string}: OK - Compliant.\n")

            except ServerNotCompliantWithMozillaTlsConfiguration as e:
                are_all_servers_compliant = False
                print(f"    {server_scan_result.server_location.display_string}: FAILED - Not compliant.")
                for criteria, error_description in e.issues.items():
                    print(f"        * {criteria}: {error_description}")
                print()

            except ServerScanResultIncomplete:
                are_all_servers_compliant = False
                print(
                    f"    {server_scan_result.server_location.display_string}: ERROR - Scan did not run successfully;"
                    f" review the scan logs above."
                )

    if not are_all_servers_compliant:
        # Return a non-zero error code to signal failure (for example to fail a CI/CD pipeline)
        sys.exit(1)
Пример #6
0
def main():
    global global_scanner

    # For py2exe builds
    freeze_support()

    # Handle SIGINT to terminate processes
    signal.signal(signal.SIGINT, sigint_handler)
    start_time = time()

    plugins_repository = PluginsRepository()
    available_plugins = plugins_repository.get_available_plugins()
    available_commands = plugins_repository.get_available_commands()

    # Create the command line parser and the list of available options
    sslyze_parser = CommandLineParser(available_plugins, __version__)
    try:
        good_server_list, bad_server_list, args_command_list = sslyze_parser.parse_command_line()
    except CommandLineParsingError as e:
        print(e.get_error_msg())
        return

    output_hub = OutputHub()
    output_hub.command_line_parsed(available_plugins, args_command_list)


    # Initialize the pool of processes that will run each plugin
    if args_command_list.https_tunnel:
        # Maximum one process to not kill the proxy
        global_scanner  = ConcurrentScanner(args_command_list.nb_retries, args_command_list.timeout, max_processes_nb=1)
    else:
        global_scanner = ConcurrentScanner(args_command_list.nb_retries, args_command_list.timeout)


    # Figure out which hosts are up and fill the task queue with work to do
    connectivity_tester = ServersConnectivityTester(good_server_list)
    connectivity_tester.start_connectivity_testing(network_timeout=args_command_list.timeout)

    # Store and print server whose command line string was bad
    for failed_scan in bad_server_list:
        output_hub.server_connectivity_test_failed(failed_scan)

    # Store and print servers we were able to connect to
    online_servers_list = []
    for server_connectivity_info in connectivity_tester.get_reachable_servers():
        online_servers_list.append(server_connectivity_info)
        output_hub.server_connectivity_test_succeeded(server_connectivity_info)

        # Send tasks to worker processes
        for scan_command_class in available_commands:
            if getattr(args_command_list, scan_command_class.get_cli_argument()):
                # Get this command's optional argument if there's any
                optional_args = {}
                for optional_arg_name in scan_command_class.get_optional_arguments():
                    # Was this option set ?
                    if getattr(args_command_list, optional_arg_name):
                        optional_args[optional_arg_name] = getattr(args_command_list, optional_arg_name)
                scan_command = scan_command_class(**optional_args)

                global_scanner.queue_scan_command(server_connectivity_info, scan_command)


    # Store and print servers we were NOT able to connect to
    for tentative_server_info, exception in connectivity_tester.get_invalid_servers():
        failed_scan = FailedServerScan(tentative_server_info.server_string, exception)
        output_hub.server_connectivity_test_failed(failed_scan)


    # Keep track of how many tasks have to be performed for each target
    task_num = 0
    output_hub.scans_started()
    for scan_command_class in available_commands:
        if getattr(args_command_list, scan_command_class.get_cli_argument()):
            task_num += 1


    # Each host has a list of results
    result_dict = {}
    # We cannot use the server_info object directly as its address will change due to multiprocessing
    RESULT_KEY_FORMAT = '{hostname}:{ip_address}:{port}'
    for server_info in online_servers_list:
        result_dict[RESULT_KEY_FORMAT.format(hostname=server_info.hostname, ip_address=server_info.ip_address,
                                             port=server_info.port)] = []

    # Process the results as they come
    for plugin_result in global_scanner.get_results():
        server_info = plugin_result.server_info
        result_dict[RESULT_KEY_FORMAT.format(hostname=server_info.hostname, ip_address=server_info.ip_address,
                                             port=server_info.port)].append(plugin_result)

        plugin_result_list = result_dict[RESULT_KEY_FORMAT.format(hostname=server_info.hostname,
                                                                  ip_address=server_info.ip_address,
                                                                  port=server_info.port)]

        if len(plugin_result_list) == task_num:
            # Done with this server; send the result to the output hub
            output_hub.server_scan_completed(CompletedServerScan(server_info, plugin_result_list))

    # All done
    exec_time = time()-start_time
    output_hub.scans_completed(exec_time)