Skip to content

Writing a Plugin

takeshix edited this page Jul 20, 2018 · 4 revisions

Writing new plugins for deen should be fairly simple. Each plugin must be a subclass of DeenPlugin. The following example plugin (available in tests/example_plugin.py) must be put in plugins/codecs/example.py:

import sys

from .. import DeenPlugin


class DeenPluginExample(DeenPlugin):
    name = 'example'
    display_name = 'Example Plugin'
    aliases = ['ex',
               'myexampleplugin']

    def __init__(self):
        super(DeenPluginExample, self).__init__()

    @staticmethod
    def prerequisites():
        if sys.version_info.major < 3 or \
                (sys.version_info.major == 3 and
                         sys.version_info.minor < 4):
            return False
        else:
            return True

    def process(self, data):
        super(DeenPluginExample, self).process(data)
        try:
            data = data + b'EXAMPLEPLUGINSTUFF'
        except Exception as e:
            self.error = e
        return data

    def unprocess(self, data):
        super(DeenPluginExample, self).unprocess(data)
        if data.endswith(b'EXAMPLEPLUGINSTUFF'):
            data = data[:-18]
        return data

Plugin Metadata

The following three class variables should be set for a plugin:

  • name (required): The internal plugin name. It should be a short, distinctive name that is unique.
  • display_name (required): The name of the module that will be displayed in the GUI.
  • aliases (optional): A list of alias names for the plugin. This can be used to make a plugin available via shorter names. E.g. the Base64 plugin is available via base64 but has an alias b64:
deen -p base64 -d testdata

is the same as:

deen -p b64 -d testdata

prerequisite()

The prerequisite() function will be called when deen loads the plugins. It allows plugins to check whether the plugin can run in the current environment. The example plugin above uses this function to check if the current Python version is at least 3.4. If this requirement is not met, the plugin will not be available. This can also be used for plugins that require third party modules that might not be available.

process()

The process() function applies the plugin functionality to the input. For codecs it represents encode and for compressions it's compress. Every plugin must have a process() function.

unprocess()

The unprocess() function is the counterpart of process(). It is e.g. decode or uncompress for codecs and compressions. However, some modules like hashs will not have an unprocess() function because their functionality is not (easily) reversible.

process_cli()

More advanced plugins might require some specific routines to be processed via the CLI. This can be implemented in the process_cli() function, which can be used to process additional CLI arguments (see add_argparser()) for multiple inputs or outputs.

process_gui()

If a plugin requires additional inputs or outputs in the GUI, the process_gui() function can be used to add additional GUI elements.

add_argparser()

If a plugin requires additional arguments, these can be added with the add_argparser() function. The function takes the main argparse object where it can cann add_parser(). See the following example code of the DeenPluginX509CertificateCloner plugin:

@staticmethod
def add_argparser(argparser, *args):
    # Python 2 argparse does not support aliases
    if sys.version_info.major < 3 or \
        (sys.version_info.major == 3 and
            sys.version_info.minor < 2):
        parser = argparser.add_parser(DeenPluginX509CertificateCloner.cmd_name,
                                        help=DeenPluginX509CertificateCloner.cmd_help)
    else:
        parser = argparser.add_parser(DeenPluginX509CertificateCloner.cmd_name,
                                        help=DeenPluginX509CertificateCloner.cmd_help,
                                        aliases=DeenPluginX509CertificateCloner.aliases)
    parser.add_argument('CERT_TO_CLONE')
    parser.add_argument('-o', '--out', help='name of output files (w/o extension)',
                        default='cloned_cert', metavar='filename')
    parser.add_argument('-a', '--signature-algorithm', help='hash algorithm for signature', default=None,
                        type=str.lower, metavar='algorithm')
    xor = parser.add_mutually_exclusive_group(required=True)
    xor.add_argument('-s', '--self-signed', action='store_true', dest='self_signed')
    xor.add_argument('CA_CERT', nargs='?')
    parser.add_argument('CA_KEY', nargs='?')

Plugin Categories

Plugins are split into the following modules:

  • codecs
  • compressions
  • assemblies
  • formatters
  • hashs
  • misc

Each plugin must be a submodule of one of these modules. codecs and compressions will be able to process and unprocess data. Hashs and Miscellaneous plugins will only be able to process data, but in the GUI the result will be displayed in a new window below the source window. In contrast, Formatters will reformat the data in a corresponding window and will put the reformatted data back to the original window.