Ejemplo n.º 1
0
    def command_line_parsed(self, available_plugins, args_command_list,
                            malformed_servers):
        # type: (Set[Type[Plugin]], Any, List[ServerStringParsingError]) -> None
        # Configure the console output
        should_print_text_results = not args_command_list.quiet and args_command_list.xml_file != '-' \
                                    and args_command_list.json_file != '-'
        if should_print_text_results:
            self._output_generator_list.append(
                ConsoleOutputGenerator(sys.stdout))

        # Configure the JSON output
        if args_command_list.json_file:
            json_file_to = sys.stdout if args_command_list.json_file == '-' else open(
                args_command_list.json_file, 'wt')
            self._output_generator_list.append(
                JsonOutputGenerator(json_file_to))  # type: ignore

        # Configure the XML output
        if args_command_list.xml_file:
            xml_file_to = sys.stdout if args_command_list.xml_file == '-' else open(
                args_command_list.xml_file, 'wt')
            self._output_generator_list.append(
                XmlOutputGenerator(xml_file_to))  # type: ignore

        # Forward the notification
        for out_generator in self._output_generator_list:
            out_generator.command_line_parsed(available_plugins,
                                              args_command_list,
                                              malformed_servers)
Ejemplo n.º 2
0
    def command_line_parsed(
        self,
        available_plugins: Set[Type[Plugin]],
        args_command_list: Any,
        malformed_servers: List[ServerStringParsingError],
    ) -> None:
        # Configure the console output
        should_print_text_results = (
            not args_command_list.quiet and args_command_list.xml_file != "-" and args_command_list.json_file != "-"
        )
        if should_print_text_results:
            self._output_generator_list.append(ConsoleOutputGenerator(sys.stdout))

        # Configure the JSON output
        if args_command_list.json_file:
            json_file_to = (
                sys.stdout
                if args_command_list.json_file == "-"
                else open(args_command_list.json_file, "wt", encoding="utf-8")
            )
            self._output_generator_list.append(JsonOutputGenerator(json_file_to))  # type: ignore

        # Configure the XML output
        if args_command_list.xml_file:
            xml_file_to = (
                sys.stdout
                if args_command_list.xml_file == "-"
                else open(args_command_list.xml_file, "wt", encoding="utf-8")
            )
            self._output_generator_list.append(XmlOutputGenerator(xml_file_to))  # type: ignore

        # Forward the notification
        for out_generator in self._output_generator_list:
            out_generator.command_line_parsed(available_plugins, args_command_list, malformed_servers)
Ejemplo n.º 3
0
    def command_line_parsed(self, available_plugins, args_command_list):
        # Configure the console output
        should_print_text_results = not args_command_list.quiet and args_command_list.xml_file != '-' \
                                    and args_command_list.json_file != '-'
        if should_print_text_results:
            self._output_generator_list.append(
                ConsoleOutputGenerator(sys.stdout))

        # Configure the JSON output
        json_file_to = None
        if args_command_list.json_file:
            json_file_to = sys.stdout if args_command_list.json_file == '-' else open(
                args_command_list.json_file, 'w')
        if json_file_to:
            self._output_generator_list.append(
                JsonOutputGenerator(json_file_to))

        # Configure the XML output
        xml_file_to = None
        if args_command_list.xml_file:
            xml_file_to = sys.stdout if args_command_list.xml_file == '-' else open(
                args_command_list.xml_file, 'w')
        if xml_file_to:
            self._output_generator_list.append(XmlOutputGenerator(xml_file_to))

        # Forward the notification
        for out_generator in self._output_generator_list:
            out_generator.command_line_parsed(available_plugins,
                                              args_command_list)
Ejemplo n.º 4
0
    def command_line_parsed(self, parsed_command_line: ParsedCommandLine) -> None:
        if not parsed_command_line.should_disable_console_output:
            self._output_generator_list.append(ConsoleOutputGenerator(sys.stdout))

        if parsed_command_line.json_file_out:
            self._output_generator_list.append(JsonOutputGenerator(parsed_command_line.json_file_out))

        # Forward the notification
        for out_generator in self._output_generator_list:
            out_generator.command_line_parsed(parsed_command_line)
Ejemplo n.º 5
0
    def test_json_serializer_functions(self):
        # Given a completed scan for a server with the CERTIFICATE_INFO scan command
        server_location = ServerNetworkLocationViaDirectConnection.with_ip_address_lookup(
            "www.hotmail.com", 443)
        server_info = ServerConnectivityTester().perform(server_location)
        plugin_result = CertificateInfoImplementation.perform(server_info)
        scan_results = {ScanCommandEnum.CERTIFICATE_INFO: plugin_result}
        scan_result = ServerScanResultFactory.create(
            scan_commands_results=scan_results)

        # When generating the JSON output for this server scan
        with StringIO() as file_out:
            json_generator = JsonOutputGenerator(file_to=file_out)
            json_generator.server_scan_completed(scan_result)

            # We call scans_completed() because this is when the output actually gets written to the file
            json_generator.scans_completed(0.2)
            final_output = file_out.getvalue()

        # It succeeds
        assert final_output

        # And complex object like certificates were properly serialized
        assert "notBefore" in final_output
        assert "issuer" in final_output
        assert "subject" in final_output
Ejemplo n.º 6
0
    def command_line_parsed(self, parsed_command_line: ParsedCommandLine) -> None:
        # Setup console output if needed
        if not parsed_command_line.should_disable_console_output:
            self._output_generator_list.append(ConsoleOutputGenerator(sys.stdout))

        # Setup JSON output if needed
        json_file_out = 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:
            self._output_generator_list.append(JsonOutputGenerator(json_file_out))

        # Forward the notification
        for out_generator in self._output_generator_list:
            out_generator.command_line_parsed(parsed_command_line)
Ejemplo n.º 7
0
    def test_server_connectivity_test_failed(self):
        # Given a server to scan to which sslyze could not connect
        error = ConnectionToServerFailedFactory.create()

        # When generating the JSON output for this
        with StringIO() as file_out:
            json_generator = JsonOutputGenerator(file_to=file_out)
            json_generator.server_connectivity_test_failed(error)

            # We call scans_completed() because this is when the output actually gets written to the file
            json_generator.scans_completed(0.2)
            final_output = file_out.getvalue()

        # It succeeds and the connectivity error was displayed
        assert final_output
        assert json.dumps(error.error_message) in final_output
Ejemplo n.º 8
0
    def test_server_scan_completed(self):
        # Given a completed scan for a server
        scan_results = {
            ScanCommandEnum.TLS_COMPRESSION:
            CompressionScanResult(supports_compression=True)
        }
        scan_result = ServerScanResultFactory.create(
            scan_commands_results=scan_results)

        # When generating the JSON output for this server scan
        with StringIO() as file_out:
            json_generator = JsonOutputGenerator(file_to=file_out)
            json_generator.server_scan_completed(scan_result)

            # We call scans_completed() because this is when the output actually gets written to the file
            json_generator.scans_completed(0.2)
            final_output = file_out.getvalue()

        # It succeeds
        assert final_output
        assert "supports_compression" in final_output
Ejemplo n.º 9
0
    def test_command_line_parsed(self):
        # Given a command line used to run sslyze
        parsed_cmd_line = ParsedCommandLineFactory.create()

        # Which contained some valid, and some invalid servers
        assert parsed_cmd_line.invalid_servers
        assert parsed_cmd_line.servers_to_scans

        # When generating the JSON output for this
        with StringIO() as file_out:
            json_generator = JsonOutputGenerator(file_out)
            json_generator.command_line_parsed(parsed_cmd_line)

            # We call scans_completed() because this is when the output actually gets written to the file
            json_generator.scans_completed(0.2)
            final_output = file_out.getvalue()

        # It succeeds and the invalid servers were displayed
        assert final_output
        for bad_server in parsed_cmd_line.invalid_servers:
            assert json.dumps(bad_server.server_string) in final_output
            assert json.dumps(bad_server.error_message) in final_output
Ejemplo n.º 10
0
    def test_server_scan_completed_with_error(self):
        # Given a completed scan for a server that triggered an error
        error_trace = TracebackExceptionFactory.create()
        scan_errors = {
            ScanCommandEnum.TLS_COMPRESSION:
            ScanCommandError(reason=ScanCommandErrorReasonEnum.BUG_IN_SSLYZE,
                             exception_trace=error_trace)
        }
        scan_result = ServerScanResultFactory.create(
            scan_commands_errors=scan_errors)

        # When generating the JSON output for this server scan
        with StringIO() as file_out:
            json_generator = JsonOutputGenerator(file_to=file_out)
            json_generator.server_scan_completed(scan_result)

            # We call scans_completed() because this is when the output actually gets written to the file
            json_generator.scans_completed(0.2)
            final_output = file_out.getvalue()

        # It succeeds and displays the error
        assert final_output
        assert error_trace.exc_type.__name__ in final_output
Ejemplo n.º 11
0
    def test(self):
        """The final output only gets written at the end, when calling scans_completed(). Hence we need to call all the
        methods in the right order and validate the final output at the end.
        """
        output_file = StringIO()
        generator = JsonOutputGenerator(output_file)

        generator.command_line_parsed(None, MockCommandLineValues())

        failed_scan = FailedServerScan(server_string=u'unibadeéè.com',
                                       connection_exception=ServerConnectivityError(error_msg=u'Some érrôr'))
        generator.server_connectivity_test_failed(failed_scan)

        server_info = MockServerConnectivityInfo()
        generator.server_connectivity_test_succeeded(server_info)

        generator.scans_started()

        # noinspection PyTypeChecker
        plugin_result_1 = MockPluginResult('plugin1', u'Plugin ûnicôdé output', None)
        # noinspection PyTypeChecker
        plugin_result_2 = MockPluginResult('plugin2', u'other plugin Output', None)
        # noinspection PyTypeChecker
        server_scan = CompletedServerScan(server_info, [plugin_result_1, plugin_result_2])
        generator.server_scan_completed(server_scan)

        scan_time = 1.3
        generator.scans_completed(scan_time)

        received_output = output_file.getvalue()
        output_file.close()

        # Ensure the output properly listed the connectivity error with unicode escaped as \u sequences
        self.assertIn(json.dumps(u'unibadeéè.com', ensure_ascii=True), received_output)
        self.assertIn(json.dumps(u'Some érrôr', ensure_ascii=True), received_output)

        # Ensure the output properly listed the online domain
        self.assertIn(json.dumps(server_info.hostname, ensure_ascii=True), received_output)
        self.assertIn(str(server_info.port), received_output)
        self.assertIn(server_info.ip_address, received_output)

        # Ensure the output displayed the plugin's attributes as JSON
        self.assertIn(plugin_result_1.plugin_command, received_output)
        self.assertIn(plugin_result_2.plugin_command, received_output)
        self.assertIn('"text_output":', received_output)
        self.assertIn(json.dumps(plugin_result_1.text_output, ensure_ascii=True), received_output)
        self.assertIn(plugin_result_2.text_output, received_output)

        # Ensure the console output displayed the total scan time
        self.assertIn(str(scan_time), received_output)
        self.assertIn('"network_timeout": "{}"'.format(MockCommandLineValues().timeout), received_output)
        self.assertIn('"network_max_retries": "{}"'.format(MockCommandLineValues().nb_retries), received_output)
Ejemplo n.º 12
0
    def test(self):
        """The final output only gets written at the end, when calling scans_completed(). Hence we need to call all the
        methods in the right order and validate the final output at the end.
        """
        output_file = StringIO()
        generator = JsonOutputGenerator(output_file)

        failed_parsing = ServerStringParsingError(
            supplied_server_string='www.badpãrsing.com',
            error_message='Pãrsing error'
        )
        generator.command_line_parsed(set(), MockCommandLineValues(), [failed_parsing])

        failed_scan = ServerConnectivityError(
            server_info=MockServerConnectivityTester(hostname='unibadeéè.com'),
            error_message='Some érrôr'
        )
        generator.server_connectivity_test_failed(failed_scan)

        server_info = MockServerConnectivityInfo()
        generator.server_connectivity_test_succeeded(server_info)

        generator.scans_started()

        plugin_result_1 = MockPluginScanResult(server_info, MockPluginScanCommandOne(), 'Plugin ûnicôdé output', None)
        plugin_result_2 = MockPluginScanResult(server_info, MockPluginScanCommandTwo(), 'other plugin Output', None)
        server_scan = CompletedServerScan(server_info, [plugin_result_1, plugin_result_2])
        generator.server_scan_completed(server_scan)

        scan_time = 1.3
        generator.scans_completed(scan_time)

        received_output = output_file.getvalue()
        output_file.close()

        # Ensure the output properly listed the parsing error with unicode escaped as \u sequences
        assert 'www.badp\\u00e3rsing.com' in received_output
        assert 'P\\u00e3rsing error' in received_output

        # Ensure the output properly listed the connectivity error with unicode escaped as \u sequences
        assert 'unibade\\u00e9\\u00e8.com:443' in received_output
        assert 'Some \\u00e9rr\\u00f4r' in received_output

        # Ensure the output properly listed the online domain
        assert json.dumps(server_info.hostname, ensure_ascii=True) in received_output
        assert str(server_info.port) in received_output
        assert server_info.ip_address in received_output

        # Ensure the output displayed the plugin's attributes as JSON
        assert plugin_result_1.scan_command.get_cli_argument() in received_output
        assert plugin_result_2.scan_command.get_cli_argument() in received_output
        assert '"text_output":' in received_output
        assert json.dumps(plugin_result_1.text_output, ensure_ascii=True) in received_output
        assert plugin_result_2.text_output in received_output

        # Ensure the console output displayed the total scan time
        assert str(scan_time) in received_output
Ejemplo n.º 13
0
    def test(self):
        """The final output only gets written at the end, when calling scans_completed(). Hence we need to call all the
        methods in the right order and validate the final output at the end.
        """
        output_file = StringIO()
        generator = JsonOutputGenerator(output_file)

        failed_parsing = ServerStringParsingError(
            supplied_server_string='www.badpãrsing.com',
            error_message='Pãrsing error')
        generator.command_line_parsed(set(), MockCommandLineValues(),
                                      [failed_parsing])

        failed_scan = ServerConnectivityError(
            server_info=MockServerConnectivityTester(hostname='unibadeéè.com'),
            error_message='Some érrôr')
        generator.server_connectivity_test_failed(failed_scan)

        server_info = MockServerConnectivityInfo()
        generator.server_connectivity_test_succeeded(server_info)

        generator.scans_started()

        plugin_result_1 = MockPluginScanResult(server_info,
                                               MockPluginScanCommandOne(),
                                               'Plugin ûnicôdé output', None)
        plugin_result_2 = MockPluginScanResult(server_info,
                                               MockPluginScanCommandTwo(),
                                               'other plugin Output', None)
        server_scan = CompletedServerScan(server_info,
                                          [plugin_result_1, plugin_result_2])
        generator.server_scan_completed(server_scan)

        scan_time = 1.3
        generator.scans_completed(scan_time)

        received_output = output_file.getvalue()
        output_file.close()

        # Ensure the output properly listed the parsing error with unicode escaped as \u sequences
        self.assertIn('www.badp\\u00e3rsing.com', received_output)
        self.assertIn('P\\u00e3rsing error', received_output)

        # Ensure the output properly listed the connectivity error with unicode escaped as \u sequences
        self.assertIn('unibade\\u00e9\\u00e8.com:443', received_output)
        self.assertIn('Some \\u00e9rr\\u00f4r', received_output)

        # Ensure the output properly listed the online domain
        self.assertIn(json.dumps(server_info.hostname, ensure_ascii=True),
                      received_output)
        self.assertIn(str(server_info.port), received_output)
        self.assertIn(server_info.ip_address, received_output)

        # Ensure the output displayed the plugin's attributes as JSON
        self.assertIn(plugin_result_1.scan_command.get_cli_argument(),
                      received_output)
        self.assertIn(plugin_result_2.scan_command.get_cli_argument(),
                      received_output)
        self.assertIn('"text_output":', received_output)
        self.assertIn(
            json.dumps(plugin_result_1.text_output, ensure_ascii=True),
            received_output)
        self.assertIn(plugin_result_2.text_output, received_output)

        # Ensure the console output displayed the total scan time
        self.assertIn(str(scan_time), received_output)