def scan(hostname, port): # Setup the servers to scan and ensure they are reachable try: server_info = ServerConnectivityInfo(hostname=hostname, port=port) server_info.test_connectivity_to_server() except ServerConnectivityError as e: # Could not establish an SSL connection to the server raise RuntimeError('Error when connecting to {}: {}'.format(hostname, e.error_msg)) # Get the list of available plugins sslyze_plugins = PluginsFinder() # Create a process pool to run scanning commands concurrently plugins_process_pool = PluginsProcessPool(sslyze_plugins) # Queue some scan commands; the commands are same as what is described in the SSLyze CLI --help text. # print '\nQueuing some commands...' plugins_process_pool.queue_plugin_task(server_info, 'sslv3') plugins_process_pool.queue_plugin_task(server_info, 'certinfo_basic') plugins_process_pool.queue_plugin_task(server_info, 'tlsv1') plugins_process_pool.queue_plugin_task(server_info, 'tlsv1_1') plugins_process_pool.queue_plugin_task(server_info, 'tlsv1_2') plugins_process_pool.queue_plugin_task(server_info, 'sslv2') result = {} result['server_info'] = server_info.__dict__ for res in plugins_process_pool.get_results(): if res.plugin_command in ['sslv2','sslv3','tlsv1','tlsv1_1','tlsv1_2']: supported = False if len(res.accepted_cipher_list) > 0: supported = True acc_ciphers = [] rej_ciphers = [] for cipher in res.accepted_cipher_list: acc_ciphers.append(cipher.name) result[res.plugin_command] = {'supported': supported, 'accepted_ciphers': acc_ciphers} elif res.plugin_command == 'certinfo_basic': result['certinfo'] = parse_certinfo(res.__dict__) return result
def test_plugin_process_pool(self): server_info = ServerConnectivityInfo(hostname=u'www.google.com') server_info.test_connectivity_to_server() # Get the list of available plugins sslyze_plugins = PluginsFinder.get() # Create a process pool to run scanning commands concurrently plugins_process_pool = PluginsProcessPool(sslyze_plugins) # Queue some scan commands that are quick plugins_process_pool.queue_plugin_task(server_info, 'certinfo_basic') plugins_process_pool.queue_plugin_task(server_info, 'reneg') plugins_process_pool.queue_plugin_task(server_info, 'compression') # Process the results nb_results = 0 for plugin_result in plugins_process_pool.get_results(): self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) nb_results +=1 self.assertEquals(nb_results, 3)
def test_plugin_process_pool(self): server_info = ServerConnectivityInfo(hostname=u'www.google.com') server_info.test_connectivity_to_server() # Get the list of available plugins sslyze_plugins = PluginsFinder.get() # Create a process pool to run scanning commands concurrently plugins_process_pool = PluginsProcessPool(sslyze_plugins) # Queue some scan commands that are quick plugins_process_pool.queue_plugin_task(server_info, 'certinfo_basic') plugins_process_pool.queue_plugin_task(server_info, 'reneg') plugins_process_pool.queue_plugin_task(server_info, 'compression') # Process the results nb_results = 0 for plugin_result in plugins_process_pool.get_results(): self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) nb_results += 1 self.assertEquals(nb_results, 3)
def main(): # For py2exe builds freeze_support() # Handle SIGINT to terminate processes signal.signal(signal.SIGINT, sigint_handler) start_time = time() #--PLUGINS INITIALIZATION-- 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__) online_servers_list = [] invalid_servers_list = [] # Parse the command line try: good_server_list, bad_server_list, args_command_list = sslyze_parser.parse_command_line() invalid_servers_list.extend(bad_server_list) except CommandLineParsingError as e: print e.get_error_msg() return 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: print '\n\n\n' + _format_title('Available plugins') for plugin in available_plugins: print ' ' + plugin.__name__ print '\n\n' #--PROCESSES INITIALIZATION-- 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) #--TESTING SECTION-- # Figure out which hosts are up and fill the task queue with work to do if should_print_text_results: print _format_title('Checking host(s) availability') connectivity_tester = ServersConnectivityTester(good_server_list) connectivity_tester.start_connectivity_testing() SERVER_OK_FORMAT = ' {host}:{port:<25} => {ip_address} {client_auth_msg}' SERVER_INVALID_FORMAT = ' {server_string:<35} => WARNING: {error_msg}; discarding corresponding tasks.' # Store and print servers we were able to connect to for server_connectivity_info in connectivity_tester.get_reachable_servers(): online_servers_list.append(server_connectivity_info) if should_print_text_results: client_auth_msg = '' client_auth_requirement = server_connectivity_info.client_auth_requirement if client_auth_requirement == ClientAuthenticationServerConfigurationEnum.REQUIRED: client_auth_msg = ' WARNING: Server REQUIRED client authentication, specific plugins will fail.' elif client_auth_requirement == ClientAuthenticationServerConfigurationEnum.OPTIONAL: client_auth_msg = ' WARNING: Server requested optional client authentication' print SERVER_OK_FORMAT.format(host=server_connectivity_info.hostname, port=server_connectivity_info.port, ip_address=server_connectivity_info.ip_address, client_auth_msg=client_auth_msg) # 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) for tentative_server_info, exception in connectivity_tester.get_invalid_servers(): invalid_servers_list.append(('{}:{}'.format(tentative_server_info.hostname, tentative_server_info.port), exception)) # Print servers we were NOT able to connect to if should_print_text_results: for server_string, exception in invalid_servers_list: if isinstance(exception, ServerConnectivityError): print SERVER_INVALID_FORMAT.format(server_string=server_string, error_msg=exception.error_msg) else: # Unexpected bug in SSLyze raise exception print '\n\n' # Keep track of how many tasks have to be performed for each target task_num = 0 for command in available_commands: if getattr(args_command_list, command): task_num += 1 # --REPORTING SECTION-- # XML output xml_output_list = [] # 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 = '{ip_address}:{port}'.format for server_info in online_servers_list: result_dict[RESULT_KEY_FORMAT(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(ip_address=server_info.ip_address, port=server_info.port)].append(plugin_result) result_list = result_dict[RESULT_KEY_FORMAT(ip_address=server_info.ip_address, port=server_info.port)] if len(result_list) == task_num: # Done with this server; print the results and update the xml doc if args_command_list.xml_file: xml_output_list.append(_format_xml_target_result(server_info, result_list)) if should_print_text_results: print _format_txt_target_result(server_info, result_list) # --TERMINATE-- exec_time = time()-start_time # Output JSON to a file if needed if args_command_list.json_file: json_output = {'total_scan_time': str(exec_time), 'network_timeout': str(args_command_list.timeout), 'network_max_retries': str(args_command_list.nb_retries), 'invalid_targets': {}} # Add the list of invalid targets for server_string, exception in invalid_servers_list: if isinstance(exception, ServerConnectivityError): json_output['invalidTargets'][server_string] = exception.error_msg else: # Unexpected bug in SSLyze raise exception # Add the output of the plugins for each server for host_str, plugin_result_list in result_dict.iteritems(): server_info = plugin_result_list[0].server_info json_output[host_str] = _format_json_result(server_info, plugin_result_list) final_json_output = json.dumps(json_output, default=lambda o: o.__dict__, sort_keys=True, indent=4) if args_command_list.json_file == '-': # Print XML output to the console if needed print final_json_output else: # Otherwise save the XML output to the console with open(args_command_list.json_file, 'w') as json_file: json_file.write(final_json_output) # Output XML doc to a file if needed if args_command_list.xml_file: result_xml_attr = {'totalScanTime': str(exec_time), 'networkTimeout': str(args_command_list.timeout), 'networkMaxRetries': str(args_command_list.nb_retries)} result_xml = Element('results', attrib = result_xml_attr) # Sort results in alphabetical order to make the XML files (somewhat) diff-able xml_output_list.sort(key=lambda xml_elem: xml_elem.attrib['host']) for xml_element in xml_output_list: result_xml.append(xml_element) xml_final_doc = Element('document', title="SSLyze Scan Results", SSLyzeVersion=__version__, SSLyzeWeb=PROJECT_URL) # Add the list of invalid targets invalid_targets_xml = Element('invalidTargets') for server_string, exception in invalid_servers_list: if isinstance(exception, ServerConnectivityError): error_xml = Element('invalidTarget', error=exception.error_msg) error_xml.text = server_string invalid_targets_xml.append(error_xml) else: # Unexpected bug in SSLyze raise exception xml_final_doc.append(invalid_targets_xml) # Add the output of the plugins xml_final_doc.append(result_xml) # Remove characters that are illegal for XML # https://lsimons.wordpress.com/2011/03/17/stripping-illegal-characters-out-of-xml-in-python/ xml_final_string = tostring(xml_final_doc, encoding='UTF-8') illegal_xml_chars_RE = re.compile(u'[\x00-\x08\x0b\x0c\x0e-\x1F\uD800-\uDFFF\uFFFE\uFFFF]') xml_sanitized_final_string = illegal_xml_chars_RE.sub('', xml_final_string) # Hack: Prettify the XML file so it's (somewhat) diff-able xml_final_pretty = minidom.parseString(xml_sanitized_final_string).toprettyxml(indent=" ", encoding="utf-8" ) if args_command_list.xml_file == '-': # Print XML output to the console if needed print xml_final_pretty else: # Otherwise save the XML output to the console with open(args_command_list.xml_file, 'w') as xml_file: xml_file.write(xml_final_pretty) if should_print_text_results: print _format_title('Scan Completed in {0:.2f} s'.format(exec_time))
def main(): # For py2exe builds freeze_support() # Handle SIGINT to terminate processes signal.signal(signal.SIGINT, sigint_handler) start_time = time() #--PLUGINS INITIALIZATION-- 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__) online_servers_list = [] invalid_servers_list = [] # Parse the command line try: good_server_list, bad_server_list, args_command_list = sslyze_parser.parse_command_line( ) invalid_servers_list.extend(bad_server_list) except CommandLineParsingError as e: print e.get_error_msg() return 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: print '\n\n\n' + _format_title('Available plugins') for plugin in available_plugins: print ' ' + plugin.__name__ print '\n\n' #--PROCESSES INITIALIZATION-- 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) #--TESTING SECTION-- # Figure out which hosts are up and fill the task queue with work to do if should_print_text_results: print _format_title('Checking host(s) availability') connectivity_tester = ServersConnectivityTester(good_server_list) connectivity_tester.start_connectivity_testing( network_timeout=args_command_list.timeout) SERVER_OK_FORMAT = u' {host}:{port:<25} => {ip_address} {client_auth_msg}' SERVER_INVALID_FORMAT = u' {server_string:<35} => WARNING: {error_msg}; discarding corresponding tasks.' # Store and print servers we were able to connect to for server_connectivity_info in connectivity_tester.get_reachable_servers( ): online_servers_list.append(server_connectivity_info) if should_print_text_results: client_auth_msg = '' client_auth_requirement = server_connectivity_info.client_auth_requirement if client_auth_requirement == ClientAuthenticationServerConfigurationEnum.REQUIRED: client_auth_msg = ' WARNING: Server REQUIRED client authentication, specific plugins will fail.' elif client_auth_requirement == ClientAuthenticationServerConfigurationEnum.OPTIONAL: client_auth_msg = ' WARNING: Server requested optional client authentication' print SERVER_OK_FORMAT.format( host=server_connectivity_info.hostname, port=server_connectivity_info.port, ip_address=server_connectivity_info.ip_address, client_auth_msg=client_auth_msg) # 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) for tentative_server_info, exception in connectivity_tester.get_invalid_servers( ): invalid_servers_list.append( (tentative_server_info.server_string, exception)) # Print servers we were NOT able to connect to if should_print_text_results: for server_string, exception in invalid_servers_list: if isinstance(exception, ServerConnectivityError): print SERVER_INVALID_FORMAT.format( server_string=server_string, error_msg=exception.error_msg) else: # Unexpected bug in SSLyze raise exception print '\n\n' # Keep track of how many tasks have to be performed for each target task_num = 0 for command in available_commands: if getattr(args_command_list, command): task_num += 1 # --REPORTING SECTION-- # XML output xml_output_list = [] # 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) result_list = result_dict[RESULT_KEY_FORMAT( hostname=server_info.hostname, ip_address=server_info.ip_address, port=server_info.port)] if len(result_list) == task_num: # Done with this server; print the results and update the xml doc if args_command_list.xml_file: xml_output_list.append( _format_xml_target_result(server_info, result_list)) if should_print_text_results: print _format_txt_target_result(server_info, result_list) # --TERMINATE-- exec_time = time() - start_time # Output JSON to a file if needed if args_command_list.json_file: json_output = { 'total_scan_time': str(exec_time), 'network_timeout': str(args_command_list.timeout), 'network_max_retries': str(args_command_list.nb_retries), 'invalid_targets': [], 'accepted_targets': [] } # Add the list of invalid targets for server_string, exception in invalid_servers_list: if isinstance(exception, ServerConnectivityError): json_output['invalid_targets'].append( {server_string: exception.error_msg}) else: # Unexpected bug in SSLyze raise exception # Add the output of the plugins for each server for host_str, plugin_result_list in result_dict.iteritems(): server_info = plugin_result_list[0].server_info json_output['accepted_targets'].append( _format_json_result(server_info, plugin_result_list)) final_json_output = json.dumps(json_output, default=lambda o: o.__dict__, sort_keys=True, indent=4) if args_command_list.json_file == '-': # Print XML output to the console if needed print final_json_output else: # Otherwise save the XML output to the console with open(args_command_list.json_file, 'w') as json_file: json_file.write(final_json_output) # Output XML doc to a file if needed if args_command_list.xml_file: result_xml_attr = { 'totalScanTime': str(exec_time), 'networkTimeout': str(args_command_list.timeout), 'networkMaxRetries': str(args_command_list.nb_retries) } result_xml = Element('results', attrib=result_xml_attr) # Sort results in alphabetical order to make the XML files (somewhat) diff-able xml_output_list.sort(key=lambda xml_elem: xml_elem.attrib['host']) for xml_element in xml_output_list: result_xml.append(xml_element) xml_final_doc = Element('document', title="SSLyze Scan Results", SSLyzeVersion=__version__, SSLyzeWeb=PROJECT_URL) # Add the list of invalid targets invalid_targets_xml = Element('invalidTargets') for server_string, exception in invalid_servers_list: if isinstance(exception, ServerConnectivityError): error_xml = Element('invalidTarget', error=exception.error_msg) error_xml.text = server_string invalid_targets_xml.append(error_xml) else: # Unexpected bug in SSLyze raise exception xml_final_doc.append(invalid_targets_xml) # Add the output of the plugins xml_final_doc.append(result_xml) # Remove characters that are illegal for XML # https://lsimons.wordpress.com/2011/03/17/stripping-illegal-characters-out-of-xml-in-python/ xml_final_string = tostring(xml_final_doc, encoding='UTF-8') illegal_xml_chars_RE = re.compile( u'[\x00-\x08\x0b\x0c\x0e-\x1F\uD800-\uDFFF\uFFFE\uFFFF]') xml_sanitized_final_string = illegal_xml_chars_RE.sub( '', xml_final_string) # Hack: Prettify the XML file so it's (somewhat) diff-able xml_final_pretty = minidom.parseString( xml_sanitized_final_string).toprettyxml(indent=" ", encoding="utf-8") if args_command_list.xml_file == '-': # Print XML output to the console if needed print xml_final_pretty else: # Otherwise save the XML output to the console with open(args_command_list.xml_file, 'w') as xml_file: xml_file.write(xml_final_pretty) if should_print_text_results: print _format_title('Scan Completed in {0:.2f} s'.format(exec_time))
# Setup the servers to scan and ensure they are reachable hostname = u'smtp.gmail.com' try: server_info = ServerConnectivityInfo( hostname=hostname, port=587, tls_wrapped_protocol=TlsWrappedProtocolEnum.STARTTLS_SMTP) server_info.test_connectivity_to_server() except ServerConnectivityError as e: # Could not establish an SSL connection to the server raise RuntimeError('Error when connecting to {}: {}'.format( hostname, e.error_msg)) # Get the list of available plugins sslyze_plugins = PluginsFinder.get() # Create a process pool to run scanning commands concurrently plugins_process_pool = PluginsProcessPool(sslyze_plugins) # Queue some scan commands; the commands are same as what is described in the SSLyze CLI --help text. print '\nQueuing some commands...' plugins_process_pool.queue_plugin_task(server_info, 'sslv3') plugins_process_pool.queue_plugin_task(server_info, 'reneg') plugins_process_pool.queue_plugin_task(server_info, 'certinfo_basic') # Process the results reneg_result = None print '\nProcessing results...' for plugin_result in plugins_process_pool.get_results(): # Sometimes a plugin command can unexpectedly fail (as a bug); it is returned as a PluginRaisedExceptionResult
# Setup the servers to scan and ensure they are reachable hostname = 'smtp.gmail.com' try: server_info = ServerConnectivityInfo( hostname=hostname, port=587, tls_wrapped_protocol=TlsWrappedProtocolEnum.STARTTLS_SMTP) server_info.test_connectivity_to_server() except ServerConnectivityError as e: # Could not establish an SSL connection to the server raise RuntimeError('Error when connecting to {}: {}'.format( hostname, e.error_msg)) # Get the list of available plugins sslyze_plugins = PluginsFinder() # Create a process pool to run scanning commands concurrently plugins_process_pool = PluginsProcessPool(sslyze_plugins) # Queue some scan commands; the commands are same as what is described in the SSLyze CLI --help text. print '\nQueuing some commands...' plugins_process_pool.queue_plugin_task(server_info, 'sslv3') plugins_process_pool.queue_plugin_task(server_info, 'reneg') plugins_process_pool.queue_plugin_task(server_info, 'certinfo_basic') # Process the results reneg_result = None print '\nProcessing results...' for plugin_result in plugins_process_pool.get_results(): # Sometimes a plugin command can unexpectedly fail (as a bug); it is returned as a PluginRaisedExceptionResult
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)
if __name__ == '__main__': # Setup the servers to scan and ensure they are reachable hostname = u'smtp.gmail.com' try: server_info = ServerConnectivityInfo(hostname=hostname, port=587, tls_wrapped_protocol=TlsWrappedProtocolEnum.STARTTLS_SMTP) server_info.test_connectivity_to_server() except ServerConnectivityError as e: # Could not establish an SSL connection to the server raise RuntimeError('Error when connecting to {}: {}'.format(hostname, e.error_msg)) # Get the list of available plugins sslyze_plugins = PluginsFinder.get() # Create a process pool to run scanning commands concurrently plugins_process_pool = PluginsProcessPool(sslyze_plugins) # Queue some scan commands; the commands are same as what is described in the SSLyze CLI --help text. print '\nQueuing some commands...' plugins_process_pool.queue_plugin_task(server_info, 'sslv3') plugins_process_pool.queue_plugin_task(server_info, 'reneg') plugins_process_pool.queue_plugin_task(server_info, 'certinfo_basic') # Process the results reneg_result = None print '\nProcessing results...' for plugin_result in plugins_process_pool.get_results(): # Sometimes a plugin command can unexpectedly fail (as a bug); it is returned as a PluginRaisedExceptionResult
def get_scan(host): try: server_info = ServerConnectivityInfo(hostname=host, port=443) server_info.test_connectivity_to_server() found = 'True' except: found = 'False' if found == 'True': sslyze_plugins = PluginsFinder() plugins_process_pool = PluginsProcessPool(sslyze_plugins) cmds = [ 'sslv2', 'sslv3', 'tlsv1', 'tlsv1_1', 'tlsv1_2', 'certinfo_full' ] for x in cmds: plugins_process_pool.queue_plugin_task(server_info, x) commonn = host_match = cert_sha1 = cert_start = extendedval = trusted = cert_end = ouline = isline = puline = cert_alt = cert_unix_start = cert_unix_end = crts = '' for x in plugins_process_pool.get_results(): if x.plugin_command == 'certinfo_full': try: y = x.certificate_chain[0].as_dict cert_sha1 = str(x.certificate_chain[0].sha1_fingerprint) host_match = str(x.hostname_validation_result) extendedval = str(x.is_leaf_certificate_ev) for z in x.path_validation_result_list: if z.trust_store.name == 'Microsoft': # check against the MS certificate store using "Microsoft", but you can also use "Mozilla NSS", "Apple" or "Java 6" trusted = str(z.is_certificate_trusted) except: y = '' if y != '': cert_start = y['validity']['notBefore'] cert_end = y['validity']['notAfter'] commonn = y['subject']['commonName'].lower() cert_unix_start = str( time.mktime( time.strptime( str(cert_start), "%b %d %H:%M:%S %Y %Z"))).split('.')[0] cert_unix_end = str( time.mktime( time.strptime( str(cert_end), "%b %d %H:%M:%S %Y %Z"))).split('.')[0] for z in [ 'organizationName', 'organizationalUnitName', 'localityName', 'stateOrProvinceName', 'countryName' ]: try: a = y['subject'][z] ouline += str(a) + ', ' except: pass for z in [ 'organizationalUnitName', 'organizationName', 'commonName', 'countryName' ]: try: a = y['issuer'][z] isline += str(a) + ', ' except: pass for z in ['publicKeyAlgorithm', 'publicKeySize']: try: a = y['subjectPublicKeyInfo'][z] puline += str(a) + ', ' except: pass try: c = y['extensions']['X509v3 Subject Alternative Name'][ 'DNS'] cert_alt = ', '.join(c) except: cert_alt = '' elif x.plugin_command != 'certinfo_full': if len(x.accepted_cipher_list) != 0: crts += str(x.plugin_command) + ', ' crts = crts[:-2] puline = puline[:-2] isline = isline[:-2] ouline = ouline[:-2] a = '' b = [ host, commonn, cert_sha1, host_match, extendedval, trusted, cert_start, cert_unix_start, cert_end, cert_unix_end, cert_alt, ouline, isline, puline, crts, timest, unixtime ] for c in b: a += '"' + c + '",' resu.append(str(a[:-1])) print a[:-1]
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.get() 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)