예제 #1
0
 def setUp(self):
     find.data_path_append('data/server')
     web_root = os.path.join(os.getcwd(), 'data', 'server', 'king_phisher')
     config = smoke_zephyr.configuration.Configuration(
         find.find_data_file('server_config.yml'))
     config.set('server.address.host', '127.0.0.1')
     config.set('server.address.port', 0)
     config.set('server.addresses', [])
     config.set('server.database', 'sqlite://')
     config.set(
         'server.geoip.database',
         os.environ.get('KING_PHISHER_TEST_GEOIP_DB',
                        './GeoLite2-City.mmdb'))
     config.set('server.web_root', web_root)
     config.set('server.rest_api.enabled', True)
     config.set('server.rest_api.token', rest_api.generate_token())
     self.config = config
     self.plugin_manager = plugins.ServerPluginManager(config)
     self.server = build.server_from_config(
         config,
         handler_klass=KingPhisherRequestHandlerTest,
         plugin_manager=self.plugin_manager)
     config.set('server.address.port',
                self.server.sub_servers[0].server_port)
     self.assertIsInstance(self.server, server.KingPhisherServer)
     self.server_thread = threading.Thread(target=self.server.serve_forever)
     self.server_thread.daemon = True
     self.server_thread.start()
     self.assertTrue(self.server_thread.is_alive())
     self.shutdown_requested = False
     self.rpc = client_rpc.KingPhisherRPCClient(
         ('localhost', self.config.get('server.address.port')))
     self.rpc.login(username='******', password='******')
예제 #2
0
 def setUp(self):
     find.data_path_append('data/server')
     web_root = os.path.join(os.getcwd(), 'data', 'server', 'king_phisher')
     config = configuration.Configuration(
         find.find_data_file('server_config.yml'))
     config.set('server.address.port', 0)
     config.set('server.database', 'sqlite://')
     config.set('server.web_root', web_root)
     self.config = config
     self.server = build_king_phisher_server(
         config, HandlerClass=KingPhisherRequestHandlerTest)
     config.set('server.address.port', self.server.http_server.server_port)
     self.assertIsInstance(self.server, KingPhisherServer)
     self.server_thread = threading.Thread(target=self.server.serve_forever)
     self.server_thread.daemon = True
     self.server_thread.start()
     self.assertTrue(self.server_thread.is_alive())
     self.shutdown_requested = False
     self.rpc = client_rpc.KingPhisherRPCClient(
         ('localhost', self.config.get('server.address.port')),
         username='******',
         password='******')
예제 #3
0
    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
예제 #4
0
    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
예제 #5
0
    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 server[0] == 'localhost' or (utilities.is_valid_ip_address(
                server[0]) and ipaddress.ip_address(server[0]).is_loopback):
            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))

        connection_failed = True
        try:
            server_version_info = rpc('version')
            assert server_version_info is not None
        except AdvancedHTTPServerRPCError as error:
            self.logger.warning(
                'failed to connect to the remote rpc service with 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 socket.error as error:
            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,
                'Ensure that the King Phisher Server is currently running.')
        else:
            connection_failed = False

        if connection_failed:
            self.server_disconnect()
            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.server_disconnect()
            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.server_disconnect()
            return False, login_reason
        rpc.username = username
        self.logger.debug(
            'successfully authenticated to the remote king phisher service')

        self.rpc = rpc
        self.emit('server-connected')
        return True, ConnectionErrorReason.SUCCESS