def test_parse_timespan(self): self.assertRaises(ValueError, utilities.parse_timespan, 'fake') self.assertEqual(utilities.parse_timespan(''), 0) self.assertEqual(utilities.parse_timespan('30'), 30) self.assertEqual(utilities.parse_timespan('1m30s'), 90) self.assertEqual(utilities.parse_timespan('2h1m30s'), 7290) self.assertEqual(utilities.parse_timespan('3d2h1m30s'), 266490)
def update_options(self, config): self.repositories.extend(config.get('repositories', [])) if 'room' in config: self.report_rooms.append(config['room']) check_frequency = config.get('frequency', 1200) if isinstance(check_frequency, str): check_frequency = utilities.parse_timespan(check_frequency) self.check_frequency = datetime.timedelta(0, check_frequency) return self.options
def __init__(self, timeout='30m'): """ :param timeout: The length of time in seconds for which sessions are valid. :type timeout: int, str """ if isinstance(timeout, str): timeout = utilities.parse_timespan(timeout) self.session_timeout = timeout self._sessions = {} self._lock = threading.Lock()
def __init__(self, *args, **kwargs): super(CampaignViewGenericTab, self).__init__(*args, **kwargs) self.label = Gtk.Label(label=self.label_text) """The :py:class:`Gtk.Label` representing this tab with text from :py:attr:`~.CampaignViewGenericTab.label_text`.""" self.is_destroyed = threading.Event() getattr(self, self.top_gobject).connect('destroy', self.signal_destroy) self.last_load_time = float('-inf') """The last time the data was loaded from the server.""" self.refresh_frequency = parse_timespan(str(self.config.get('gui.refresh_frequency', '5m'))) """The lifetime in seconds to wait before refreshing the data from the server.""" self.loader_thread = None """The thread object which loads the data from the server.""" self.loader_thread_lock = threading.Lock() """The :py:class:`threading.Lock` object used for synchronization between the loader and main threads."""
def __init__(self, timeout='30m'): """ :param timeout: The length of time in seconds for which sessions are valid. :type timeout: int, str """ self.logger = logging.getLogger('KingPhisher.Server.SessionManager') if isinstance(timeout, str): timeout = utilities.parse_timespan(timeout) self.session_timeout = timeout self._sessions = {} self._lock = threading.Lock() # get valid sessions from the database expired = 0 session = db_manager.Session() for stored_session in session.query(db_models.AuthenticatedSession): if stored_session.last_seen < time.time() - self.session_timeout: expired += 1 continue auth_session = AuthenticatedSession.from_db_authenticated_session(stored_session) self._sessions[stored_session.id] = auth_session session.query(db_models.AuthenticatedSession).delete() session.commit() self.logger.info("restored {0:,} valid sessions and skipped {1:,} expired sessions from the database".format(len(self._sessions), expired))
def server_connect(self, username, password, otp=None): # pylint: disable=too-many-locals server_version_info = None title_rpc_error = 'Failed To Connect To The King Phisher RPC Service' active_window = self.get_active_window() server = parse_server(self.config['server'], 22) if ipaddress.is_loopback(server[0]): local_server = ('localhost', self.config['server_remote_port']) self.logger.info("connecting to local king phisher instance") else: local_server = self._create_ssh_forwarder(server, username, password) if not local_server: return False, ConnectionErrorReason.ERROR_PORT_FORWARD rpc = client_rpc.KingPhisherRPCClient( local_server, use_ssl=self.config.get('server_use_ssl')) if self.config.get('rpc.serializer'): try: rpc.set_serializer(self.config['rpc.serializer']) except ValueError as error: self.logger.error( "failed to set the rpc serializer, error: '{0}'".format( error.message)) generic_message = 'Can not contact the RPC HTTP service, ensure that the ' generic_message += "King Phisher Server is currently running on port {0}.".format( int(self.config['server_remote_port'])) connection_failed = True try: server_version_info = rpc('version') if server_version_info is None: raise RuntimeError( 'no version information was retrieved from the server') except advancedhttpserver.RPCError as error: self.logger.warning( 'failed to connect to the remote rpc service due to http status: ' + str(error.status)) gui_utilities.show_dialog_error( title_rpc_error, active_window, "The server responded with HTTP status: {0}.".format( str(error.status))) except BadStatusLine as error: self.logger.warning( 'failed to connect to the remote rpc service due to http bad status line: ' + error.line) gui_utilities.show_dialog_error(title_rpc_error, active_window, generic_message) except socket.error as error: self.logger.debug( 'failed to connect to the remote rpc service due to a socket error', exc_info=True) gui_utilities.show_dialog_exc_socket_error(error, active_window) except ssl.CertificateError as error: self.logger.warning( 'failed to connect to the remote rpc service with a https certificate error: ' + error.message) gui_utilities.show_dialog_error( title_rpc_error, active_window, 'The server presented an invalid SSL certificate.') except Exception: self.logger.warning('failed to connect to the remote rpc service', exc_info=True) gui_utilities.show_dialog_error(title_rpc_error, active_window, generic_message) else: connection_failed = False if connection_failed: self.emit('server-disconnected') return False, ConnectionErrorReason.ERROR_CONNECTION server_rpc_api_version = server_version_info.get('rpc_api_version', -1) if isinstance(server_rpc_api_version, int): # compatibility with pre-0.2.0 version server_rpc_api_version = (server_rpc_api_version, 0) self.logger.info( "successfully connected to the king phisher server (version: {0} rpc api version: {1}.{2})" .format(server_version_info['version'], server_rpc_api_version[0], server_rpc_api_version[1])) error_text = None if server_rpc_api_version[0] < version.rpc_api_version.major or ( server_rpc_api_version[0] == version.rpc_api_version.major and server_rpc_api_version[1] < version.rpc_api_version.minor): error_text = 'The server is running an old and incompatible version.' error_text += '\nPlease update the remote server installation.' elif server_rpc_api_version[0] > version.rpc_api_version.major: error_text = 'The client is running an old and incompatible version.' error_text += '\nPlease update the local client installation.' if error_text: gui_utilities.show_dialog_error( 'The RPC API Versions Are Incompatible', active_window, error_text) self.emit('server-disconnected') return False, ConnectionErrorReason.ERROR_INCOMPATIBLE_VERSIONS login_result, login_reason = rpc.login(username, password, otp) if not login_result: self.logger.warning( 'failed to authenticate to the remote king phisher service, reason: ' + login_reason) self.emit('server-disconnected') return False, login_reason rpc.username = username self.logger.debug( 'successfully authenticated to the remote king phisher service') self._rpc_ping_event = GLib.timeout_add_seconds( parse_timespan('5m'), rpc.ping) self.rpc = rpc event_subscriber = server_events.ServerEventSubscriber(rpc) if not event_subscriber.is_connected: self.logger.error('failed to connect the server event socket') event_subscriber.reconnect = False event_subscriber.shutdown() return False, ConnectionErrorReason.ERROR_UNKNOWN self.server_events = event_subscriber self.emit('server-connected') return True, ConnectionErrorReason.SUCCESS
def server_connect(self, username, password, otp=None, window=None): """ Initialize the connection to the King Phisher server. :param str username: The username to authenticate with. :param str password: The password to authenticate with. :param str otp: The optional one-time password to authenticate with. :param window: The GTK window to use as the parent for error dialogs. :type window: :py:class:`Gtk.Window` :rtype: tuple """ # pylint: disable=too-many-locals server_version_info = None title_rpc_error = 'Failed To Connect To The King Phisher RPC Service' window = window or self.get_active_window() server = parse_server(self.config['server'], 22) if ipaddress.is_loopback(server[0]): local_server = ('localhost', self.config['server_remote_port']) self.logger.info("connecting to local king phisher instance") else: local_server = self._create_ssh_forwarder(server, username, password, window=window) if not local_server: return False, ConnectionErrorReason.ERROR_PORT_FORWARD rpc = client_rpc.KingPhisherRPCClient( local_server, use_ssl=self.config.get('server_use_ssl')) if self.config.get('rpc.serializer'): try: rpc.set_serializer(self.config['rpc.serializer']) except ValueError as error: self.logger.error( "failed to set the rpc serializer, error: '{0}'".format( error.message)) generic_message = 'Can not contact the RPC HTTP service, ensure that the ' generic_message += "King Phisher Server is currently running on port {0}.".format( int(self.config['server_remote_port'])) connection_failed = True try: server_version_info = rpc('version') if server_version_info is None: rpc.shutdown() raise RuntimeError( 'no version information was retrieved from the server') except advancedhttpserver.RPCError as error: self.logger.warning( 'failed to connect to the remote rpc service due to http status: ' + str(error.status)) gui_utilities.show_dialog_error( title_rpc_error, window, "The server responded with HTTP status: {0}.".format( str(error.status))) except http.client.BadStatusLine as error: self.logger.warning( 'failed to connect to the remote rpc service due to http bad status line: ' + error.line) gui_utilities.show_dialog_error(title_rpc_error, window, generic_message) except socket.error as error: self.logger.debug( 'failed to connect to the remote rpc service due to a socket error', exc_info=True) gui_utilities.show_dialog_exc_socket_error(error, window) except ssl.CertificateError as error: self.logger.warning( 'failed to connect to the remote rpc service with a https certificate error: ' + error.message) gui_utilities.show_dialog_error( title_rpc_error, window, 'The server presented an invalid SSL certificate.') except Exception: self.logger.warning('failed to connect to the remote rpc service', exc_info=True) gui_utilities.show_dialog_error(title_rpc_error, window, generic_message) else: connection_failed = False if connection_failed: rpc.shutdown() self.emit('server-disconnected') return False, ConnectionErrorReason.ERROR_CONNECTION server_rpc_api_version = server_version_info.get('rpc_api_version', -1) if isinstance(server_rpc_api_version, int): # compatibility with pre-0.2.0 version server_rpc_api_version = (server_rpc_api_version, 0) self.logger.info( "successfully connected to the king phisher server (version: {0} rpc api version: {1}.{2})" .format(server_version_info['version'], server_rpc_api_version[0], server_rpc_api_version[1])) error_text = None if server_rpc_api_version[0] < version.rpc_api_version.major or ( server_rpc_api_version[0] == version.rpc_api_version.major and server_rpc_api_version[1] < version.rpc_api_version.minor): error_text = 'The server is running an old and incompatible version.' error_text += '\nPlease update the remote server installation.' elif server_rpc_api_version[0] > version.rpc_api_version.major: error_text = 'The client is running an old and incompatible version.' error_text += '\nPlease update the local client installation.' if error_text: gui_utilities.show_dialog_error( 'The RPC API Versions Are Incompatible', window, error_text) rpc.shutdown() self.emit('server-disconnected') return False, ConnectionErrorReason.ERROR_INCOMPATIBLE_VERSIONS login_result, login_reason = rpc.login(username, password, otp) if not login_result: self.logger.warning( 'failed to authenticate to the remote king phisher service, reason: ' + login_reason) rpc.shutdown() self.emit('server-disconnected') return False, login_reason rpc.username = username self.logger.debug( 'successfully authenticated to the remote king phisher service') server_str = self.config['server'] history = self.config['server.history'] if server_str in history: history.remove(server_str) history.insert(0, server_str) self.config['server.history'] = history event_subscriber = server_events.ServerEventSubscriber(rpc) if not event_subscriber.is_connected: event_subscriber.reconnect = False event_subscriber.shutdown() rpc.shutdown() self.emit('server-disconnected') return False, ConnectionErrorReason.ERROR_UNKNOWN self.rpc = rpc self.server_events = event_subscriber self._rpc_ping_event = GLib.timeout_add_seconds( parse_timespan('5m'), functools.partial(_rpc_ping, rpc)) user = self.rpc.graphql( """\ query getUser($name: String!) { db { user(name: $name) { id name } } }""", {'name': self.config['server_username']})['db']['user'] self.server_user = ServerUser(id=user['id'], name=user['name']) self.emit('server-connected') return True, ConnectionErrorReason.SUCCESS
def server_connect(self, username, password, otp=None): # pylint: disable=too-many-locals server_version_info = None title_rpc_error = 'Failed To Connect To The King Phisher RPC Service' active_window = self.get_active_window() server = parse_server(self.config['server'], 22) if ipaddress.is_loopback(server[0]): local_server = ('localhost', self.config['server_remote_port']) self.logger.info("connecting to local king phisher instance") else: local_server = self._create_ssh_forwarder(server, username, password) if not local_server: return False, ConnectionErrorReason.ERROR_PORT_FORWARD rpc = client_rpc.KingPhisherRPCClient(local_server, use_ssl=self.config.get('server_use_ssl')) if self.config.get('rpc.serializer'): try: rpc.set_serializer(self.config['rpc.serializer']) except ValueError as error: self.logger.error("failed to set the rpc serializer, error: '{0}'".format(error.message)) generic_message = 'Can not contact the RPC HTTP service, ensure that the ' generic_message += "King Phisher Server is currently running on port {0}.".format(int(self.config['server_remote_port'])) connection_failed = True try: server_version_info = rpc('version') if server_version_info is None: raise RuntimeError('no version information was retrieved from the server') except advancedhttpserver.RPCError as error: self.logger.warning('failed to connect to the remote rpc service due to http status: ' + str(error.status)) gui_utilities.show_dialog_error(title_rpc_error, active_window, "The server responded with HTTP status: {0}.".format(str(error.status))) except BadStatusLine as error: self.logger.warning('failed to connect to the remote rpc service due to http bad status line: ' + error.line) gui_utilities.show_dialog_error(title_rpc_error, active_window, generic_message) except socket.error as error: self.logger.debug('failed to connect to the remote rpc service due to a socket error', exc_info=True) gui_utilities.show_dialog_exc_socket_error(error, active_window) except ssl.CertificateError as error: self.logger.warning('failed to connect to the remote rpc service with a https certificate error: ' + error.message) gui_utilities.show_dialog_error(title_rpc_error, active_window, 'The server presented an invalid SSL certificate.') except Exception: self.logger.warning('failed to connect to the remote rpc service', exc_info=True) gui_utilities.show_dialog_error(title_rpc_error, active_window, generic_message) else: connection_failed = False if connection_failed: self.emit('server-disconnected') return False, ConnectionErrorReason.ERROR_CONNECTION server_rpc_api_version = server_version_info.get('rpc_api_version', -1) if isinstance(server_rpc_api_version, int): # compatibility with pre-0.2.0 version server_rpc_api_version = (server_rpc_api_version, 0) self.logger.info( "successfully connected to the king phisher server (version: {0} rpc api version: {1}.{2})".format( server_version_info['version'], server_rpc_api_version[0], server_rpc_api_version[1] ) ) error_text = None if server_rpc_api_version[0] < version.rpc_api_version.major or (server_rpc_api_version[0] == version.rpc_api_version.major and server_rpc_api_version[1] < version.rpc_api_version.minor): error_text = 'The server is running an old and incompatible version.' error_text += '\nPlease update the remote server installation.' elif server_rpc_api_version[0] > version.rpc_api_version.major: error_text = 'The client is running an old and incompatible version.' error_text += '\nPlease update the local client installation.' if error_text: gui_utilities.show_dialog_error('The RPC API Versions Are Incompatible', active_window, error_text) self.emit('server-disconnected') return False, ConnectionErrorReason.ERROR_INCOMPATIBLE_VERSIONS login_result, login_reason = rpc.login(username, password, otp) if not login_result: self.logger.warning('failed to authenticate to the remote king phisher service, reason: ' + login_reason) self.emit('server-disconnected') return False, login_reason rpc.username = username self.logger.debug('successfully authenticated to the remote king phisher service') self._rpc_ping_event = GLib.timeout_add_seconds(parse_timespan('5m'), rpc.ping) self.rpc = rpc event_subscriber = server_events.ServerEventSubscriber(rpc) if not event_subscriber.is_connected: self.logger.error('failed to connect the server event socket') event_subscriber.reconnect = False event_subscriber.shutdown() return False, ConnectionErrorReason.ERROR_UNKNOWN self.server_events = event_subscriber self.emit('server-connected') return True, ConnectionErrorReason.SUCCESS