4.2. Client Plugins¶
For information on how client plugins are installed, see the Client Plugins wiki page.
Client plugins need to inherit from the
ClientPlugin
class which provides the
basic outline. Client plugins have access to a dictionary for persistent
configuration storage through the
config
attribute. In order
for the plugin’s meta-data to be available to the GUI, class attributes are
used. This allows information such as the title, description, etc. to be
accessed without initializing the class.
4.2.1. Plugin Manager¶
When the Plugin Manager window is loaded, all available plugins are loaded in order for their information to be retrieved from the class attributes. This is the effective equivalent of importing the module in Python. When the module is enabled, an instance of the Plugin class created allowing it to fulfill its intended purpose.
4.2.1.1. Reloading Plugins¶
Plugin modules and classes can be “reloaded” to allow changes made to the plugin on disk to take effect. This can be accomplished by right clicking the plugin and selecting the “Reload” option from the manager window. If an enabled plugin is reloaded, it will first be disabled before being re-enabled causing it to lose any state information it may have been storing.
4.2.1.2. Plugin Compatibility¶
Plugin modules that have requirements can have their compatibility checked by
viewing the plugin information pane. This includes a simple yes or no regarding
whether all of the plugin’s requirements are met and the plugin is thus
compatible. Additional information regarding the specific requirements a
particular plugin has can be accessed by clicking the Compatible
link which
will show each of the requirements, their values and whether or not they are
met. This allows users to easily determine why a particular plugin may not be
compatible.
4.2.2. Plugin Options¶
Client plugins have special ClientOption classes available to them for
specifying options that the user can set. The
king_phisher.client.plugins.ClientOptionMixin.__init__()
method offers
additional parameters such as display_name to configure the information shown
to the end user in the configuration widget.
The following are the different option classes available for client plugins:
4.2.3. Example¶
The following is a commented example of a basic “Hello World” plugin.
import king_phisher.client.plugins as plugins
import king_phisher.client.gui_utilities as gui_utilities
try:
# imports that may not be available need to be an exception handler so
# the plugin module will still load
import advancedhttpserver
except ImportError:
# set a variable to whether this package is available or not for later use
has_ahs = False
else:
has_ahs = True
# this is the main plugin class, it is necessary to inherit from plugins.ClientPlugin
class Plugin(plugins.ClientPlugin):
authors = ['Spencer McIntyre'] # the plugins author
title = 'Hello World!' # the title of the plugin to be shown to users
description = """
A 'hello world' plugin to serve as a basic template and demonstration. This
plugin will display a message box when King Phisher exits.
""" # a description of the plugin to be shown to users
homepage = 'https://github.com/securestate/king-phisher-plugins' # an optional home page
options = [ # specify options which can be configured through the GUI
plugins.ClientOptionString(
'name', # the name of the option as it will appear in the configuration
'The name to which to say goodbye.', # the description of the option as shown to users
default='Alice Liddle', # a default value for the option
display_name='Your Name' # a name of the option as shown to users
),
plugins.ClientOptionBoolean(
'validiction',
'Whether or not this plugin say good bye.',
default=True,
display_name='Say Good Bye'
),
plugins.ClientOptionInteger(
'some_number',
'An example number option.',
default=1337,
display_name='A Number'
),
plugins.ClientOptionPort(
'tcp_port',
'The TCP port to connect to.',
default=80,
display_name='Connection Port'
)
]
req_min_py_version = '3.3.0' # (optional) specify the required minimum version of python
req_min_version = '1.4.0' # (optional) specify the required minimum version of king phisher
req_packages = { # (optional) specify a dictionary of required package names
'advancedhttpserver': has_ahs # set from within the exception handler when importing
}
req_platforms = ('Linux', 'Windows') # (optional) specify the supported platforms
version = '1.0' # (optional) specify this plugin's version
# this is the primary plugin entry point which is executed when the plugin is enabled
def initialize(self):
print('Hello World!')
self.signal_connect('exit', self.signal_exit)
# it is necessary to return True to indicate that the initialization was successful
# this allows the plugin to check its options and return false to indicate a failure
return True
# this is a cleanup method to allow the plugin to close any open resources
def finalize(self):
print('Good Bye World!')
# the plugin connects this handler to the applications 'exit' signal
def signal_exit(self, app):
# check the 'validiction' option in the configuration
if not self.config['validiction']:
return
gui_utilities.show_dialog_info(
"Good bye {0}!".format(self.config['name']),
app.get_active_window()
)