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)
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)
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)
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)
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
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)
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
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
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
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
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)
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
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)