Esempio n. 1
0
	def server_ssh_connect(self):
		"""
		Connect to the remote SMTP server over SSH and configure port forwarding
		with :py:class:`.SSHTCPForwarder` for tunneling SMTP traffic.

		:return: The connection status as one of the :py:class:`.ConnectionErrorReason` constants.
		"""
		server = parse_server(self.config['ssh_server'], 22)
		username = self.config['ssh_username']
		password = self.config['ssh_password']
		remote_server = parse_server(self.config['smtp_server'], 25)
		try:
			self._ssh_forwarder = SSHTCPForwarder(
				server,
				username,
				password,
				remote_server,
				private_key=self.config.get('ssh_preferred_key'),
				missing_host_key_policy=ssh_host_key.MissingHostKeyPolicy(self.application)
			)
			self._ssh_forwarder.start()
		except errors.KingPhisherAbortError as error:
			self.logger.info("ssh connection aborted ({0})".format(error.message))
		except paramiko.AuthenticationException:
			self.logger.warning('failed to authenticate to the remote ssh server')
			return ConnectionErrorReason.ERROR_AUTHENTICATION_FAILED
		except paramiko.SSHException as error:
			self.logger.warning("failed with ssh exception '{0}'".format(error.message))
		except Exception:
			self.logger.warning('failed to connect to the remote ssh server', exc_info=True)
		else:
			self.smtp_server = self._ssh_forwarder.local_server
			return ConnectionErrorReason.SUCCESS
		return ConnectionErrorReason.ERROR_UNKNOWN
Esempio n. 2
0
	def server_ssh_connect(self):
		"""
		Connect to the remote SMTP server over SSH and configure port forwarding
		with :py:class:`.SSHTCPForwarder` for tunneling SMTP traffic.

		:return: The connection status as one of the :py:class:`.ConnectionErrorReason` constants.
		"""
		server = parse_server(self.config['ssh_server'], 22)
		username = self.config['ssh_username']
		password = self.config['ssh_password']
		remote_server = parse_server(self.config['smtp_server'], 25)
		try:
			self._ssh_forwarder = SSHTCPForwarder(
				server,
				username,
				password,
				remote_server,
				private_key=self.config.get('ssh_preferred_key'),
				missing_host_key_policy=ssh_host_key.MissingHostKeyPolicy(self.application)
			)
			self._ssh_forwarder.start()
		except errors.KingPhisherAbortError as error:
			self.logger.info("ssh connection aborted ({0})".format(error.message))
		except paramiko.AuthenticationException:
			self.logger.warning('failed to authenticate to the remote ssh server')
			return ConnectionErrorReason.ERROR_AUTHENTICATION_FAILED
		except paramiko.SSHException as error:
			self.logger.warning("failed with ssh exception '{0}'".format(error.message))
		except Exception:
			self.logger.warning('failed to connect to the remote ssh server', exc_info=True)
		else:
			self.smtp_server = self._ssh_forwarder.local_server
			return ConnectionErrorReason.SUCCESS
		return ConnectionErrorReason.ERROR_UNKNOWN
Esempio n. 3
0
    def server_ssh_connect(self):
        """
		Connect to the remote SMTP server over SSH and configure port
		forwarding with :py:class:`.SSHTCPForwarder` for tunneling SMTP
		traffic.

		:return: The connection status as one of the :py:class:`.ConnectionErrorReason` constants.
		"""
        server = parse_server(self.config['ssh_server'], 22)
        username = self.config['ssh_username']
        password = self.config['ssh_password']
        remote_server = parse_server(self.config['smtp_server'], 25)
        try:
            self._ssh_forwarder = SSHTCPForwarder(
                server,
                username,
                password,
                remote_server,
                preferred_private_key=self.config.get('ssh_preferred_key'))
            self._ssh_forwarder.start()
        except paramiko.AuthenticationException:
            self.logger.warning(
                'failed to authenticate to the remote ssh server')
            return ConnectionErrorReason.ERROR_AUTHENTICATION_FAILED
        except Exception:
            self.logger.warning('failed to connect to the remote ssh server',
                                exc_info=True)
            return ConnectionErrorReason.ERROR_UNKNOWN
        self.logger.info(
            "started ssh port forwarding to the remote smtp server ({0})".
            format(str(self._ssh_forwarder)))
        self.smtp_server = self._ssh_forwarder.local_server
        return ConnectionErrorReason.SUCCESS
Esempio n. 4
0
	def __init__(self, application, target_file, rpc, tab=None):
		"""
		:param application: The GTK application that the thread is associated with.
		:type application: :py:class:`.KingPhisherClientApplication`
		:param str target_file: The CSV formatted file to read message targets from.
		:param tab: The GUI tab to report information to.
		:type tab: :py:class:`.MailSenderSendTab`
		:param rpc: The client's connected RPC instance.
		:type rpc: :py:class:`.KingPhisherRPCClient`
		"""
		super(MailSenderThread, self).__init__()
		self.daemon = True
		self.logger = logging.getLogger('KingPhisher.Client.' + self.__class__.__name__)
		self.application = application
		self.config = self.application.config
		self.target_file = target_file
		"""The name of the target file in CSV format."""
		self.tab = tab
		"""The optional :py:class:`.MailSenderSendTab` instance for reporting status messages to the GUI."""
		self.rpc = rpc
		self._ssh_forwarder = None
		self.smtp_connection = None
		"""The :py:class:`smtplib.SMTP` connection instance."""
		self.smtp_server = parse_server(self.config['smtp_server'], 25)
		self.running = threading.Event()
		"""A :py:class:`threading.Event` object indicating if emails are being sent."""
		self.paused = threading.Event()
		"""A :py:class:`threading.Event` object indicating if the email sending operation is or should be paused."""
		self.should_stop = threading.Event()
		self.max_messages_per_minute = float(self.config.get('smtp_max_send_rate', 0.0))
Esempio n. 5
0
	def test_parse_server(self):
		parsed = utilities.parse_server('127.0.0.1', 80)
		self.assertIsInstance(parsed, tuple)
		self.assertEqual(len(parsed), 2)
		self.assertEqual(parsed[0], '127.0.0.1')
		self.assertEqual(parsed[1], 80)
		parsed = utilities.parse_server('127.0.0.1:8080', 80)
		self.assertIsInstance(parsed, tuple)
		self.assertEqual(len(parsed), 2)
		self.assertEqual(parsed[0], '127.0.0.1')
		self.assertEqual(parsed[1], 8080)
		parsed = utilities.parse_server('[::1]:8080', 80)
		self.assertIsInstance(parsed, tuple)
		self.assertEqual(len(parsed), 2)
		self.assertEqual(parsed[0], '::1')
		self.assertEqual(parsed[1], 8080)
Esempio n. 6
0
 def test_parse_server(self):
     parsed = utilities.parse_server('127.0.0.1', 80)
     self.assertIsInstance(parsed, tuple)
     self.assertEqual(len(parsed), 2)
     self.assertEqual(parsed[0], '127.0.0.1')
     self.assertEqual(parsed[1], 80)
     parsed = utilities.parse_server('127.0.0.1:8080', 80)
     self.assertIsInstance(parsed, tuple)
     self.assertEqual(len(parsed), 2)
     self.assertEqual(parsed[0], '127.0.0.1')
     self.assertEqual(parsed[1], 8080)
     parsed = utilities.parse_server('[::1]:8080', 80)
     self.assertIsInstance(parsed, tuple)
     self.assertEqual(len(parsed), 2)
     self.assertEqual(parsed[0], '::1')
     self.assertEqual(parsed[1], 8080)
Esempio n. 7
0
    def __init__(self, application, target_file, rpc, tab=None):
        """
		:param application: The GTK application that the thread is associated with.
		:type application: :py:class:`.KingPhisherClientApplication`
		:param str target_file: The CSV formatted file to read message targets from.
		:param tab: The GUI tab to report information to.
		:type tab: :py:class:`.MailSenderSendTab`
		:param rpc: The client's connected RPC instance.
		:type rpc: :py:class:`.KingPhisherRPCClient`
		"""
        super(MailSenderThread, self).__init__()
        self.daemon = True
        self.logger = logging.getLogger('KingPhisher.Client.' +
                                        self.__class__.__name__)
        self.application = application
        self.config = self.application.config
        self.target_file = target_file
        """The name of the target file in CSV format."""
        self.tab = tab
        """The optional :py:class:`.MailSenderSendTab` instance for reporting status messages to the GUI."""
        self.rpc = rpc
        self._ssh_forwarder = None
        self.smtp_connection = None
        """The :py:class:`smtplib.SMTP` connection instance."""
        self.smtp_server = parse_server(self.config['smtp_server'], 25)
        self.running = threading.Event()
        """A :py:class:`threading.Event` object indicating if emails are being sent."""
        self.paused = threading.Event()
        """A :py:class:`threading.Event` object indicating if the email sending operation is or should be paused."""
        self.should_stop = threading.Event()
        self.max_messages_per_minute = float(
            self.config.get('smtp_max_send_rate', 0.0))
        self._mime_attachments = None
Esempio n. 8
0
	def on_server_initialized(self, server):
		self.bot = NotificationBot(
			self.config['jid'],
			self.config['password'],
			self.config['room'],
			self.config['verify_cert']
		)
		self.bot.connect(utilities.parse_server(self.config['server'], 5222))
		self.bot.process(block=False)
	def on_server_initialized(self, server):
		self.bot = NotificationBot(
			self.config['jid'],
			self.config['password'],
			self.config['room'],
			self.config['verify_cert']
		)
		self.bot.connect(utilities.parse_server(self.config['server'], 5222))
		self.bot.process(block=False)
Esempio n. 10
0
	def server_ssh_connect(self):
		"""
		Connect to the remote SMTP server over SSH and configure port
		forwarding with :py:class:`.SSHTCPForwarder` for tunneling SMTP
		traffic.

		:return: The connection status.
		:rtype: bool
		"""
		server = parse_server(self.config['ssh_server'], 22)
		username = self.config['ssh_username']
		password = self.config['ssh_password']
		remote_server = parse_server(self.config['smtp_server'], 25)
		local_port = random.randint(2000, 6000)
		try:
			self._ssh_forwarder = SSHTCPForwarder(server, username, password, local_port, remote_server, preferred_private_key=self.config.get('ssh_preferred_key'))
			self._ssh_forwarder.start()
			time.sleep(0.5)
		except Exception:
			self.logger.warning('failed to connect to remote ssh server', exc_info=True)
			return False
		self.smtp_server = ('localhost', local_port)
		return True
Esempio n. 11
0
    def build(self):
        self.root = RootWidget()
        if self.xmpp_config_ok:
            self.xmpp_client = OperatorXMPPClient(
                sz_utils.parse_server(self.configuration.get('xmpp', 'server'),
                                      5222),
                self.configuration.get('xmpp', 'username'),
                self.configuration.get('xmpp', 'password'),
                self.configuration.get('xmpp', 'room'),
                self.configuration.getboolean('xmpp', 'filter'))
            self.xmpp_client.bind(
                on_user_location_update=self.on_user_location_update)
            self.xmpp_client.bind(on_message_receive=self.on_message_receive)
            self.xmpp_client.bind(on_muc_receive=self.on_muc_receive)
        else:
            self.logger.warning(
                "XMMP config invalid, disabling XMPP operations")

        self.map = self.root.ids.map_panel_widget.ids.map_widget
        self.messaging = self.root.ids.message_menu
        gps.configure(on_location=self.on_gps_location)
        gps.start()
        return self.root
Esempio n. 12
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')
			assert server_version_info is not None
		except AdvancedHTTPServerRPCError 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:
			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 = rpc
		self.emit('server-connected')
		return True, ConnectionErrorReason.SUCCESS
Esempio n. 13
0
	def server_connect(self):
		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)
		username = self.config['server_username']
		password = self.config['server_password']
		if server[0] == 'localhost' or (utilities.is_valid_ip_address(server[0]) and ipaddress.ip_address(server[0]).is_loopback):
			local_port = self.config['server_remote_port']
			self.logger.info("connecting to local king-phisher instance")
		else:
			local_port = self._create_ssh_forwarder(server, username, password)
		if not local_port:
			return

		self.rpc = client_rpc.KingPhisherRPCClient(('localhost', local_port), username=username, password=password, use_ssl=self.config.get('server_use_ssl'))
		if self.config.get('rpc.serializer'):
			try:
				self.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:
			assert self.rpc('client/initialize')
			server_version_info = self.rpc('version')
			assert server_version_info != None
		except AdvancedHTTPServerRPCError as err:
			if err.status == 401:
				self.logger.warning('failed to authenticate to the remote king phisher service')
				gui_utilities.show_dialog_error(title_rpc_error, active_window, 'The server responded that the credentials are invalid.')
			else:
				self.logger.warning('failed to connect to the remote rpc server with http status: ' + str(err.status))
				gui_utilities.show_dialog_error(title_rpc_error, active_window, 'The server responded with HTTP status: ' + str(err.status))
		except socket.error as error:
			gui_utilities.show_dialog_exc_socket_error(error, active_window)
		except Exception as error:
			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
		finally:
			if connection_failed:
				self.rpc = None
				self.server_disconnect()
				return

		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
		self.emit('server-connected')
		return
Esempio n. 14
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
Esempio n. 15
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
Esempio n. 16
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
Esempio n. 17
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:
				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:
			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)
			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')

		event_subscriber = server_events.ServerEventSubscriber(rpc)
		if not event_subscriber.is_connected:
			event_subscriber.reconnect = False
			event_subscriber.shutdown()
			return False, ConnectionErrorReason.ERROR_UNKNOWN
		self.rpc = rpc
		self.server_events = event_subscriber
		self._rpc_ping_event = GLib.timeout_add_seconds(parse_timespan('5m'), rpc.ping)
		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