Skip to content
Switch branches/tags
Go to file

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

This project is intended to serve as part of a larger pipeline for mass concurrent invocations of the great SSL/TLS testing tool via command files.

See the sibling project for a engine that can react to JSON result output files to send notifications or perform other actions.

Provides a long lived watchdog process that monitors a directory (via watchdog) for command files. As new files appear within the --input-dir containing the --filename-filter they are consumed and evaluated for commands, one per line. Each command is processed in a separate thread and processing results are logged to a YAML or JSON result file under the --output-dir. The actual output from each invoked invocation (i.e. via --*file arguments) is also written to disk scoped within a timestamped output directory under the --output-dir


Python 3


pip install twisted pyyaml python-dateutil watchdog


./ --help                                                                                       

usage: [-h] [-i INPUT_DIR] [-O OUTPUT_DIR]
                            [-m TESTSSL_PATH_IF_MISSING] [-f FILENAME_FILTER]
                            [-o RESULT_FILENAME_PREFIX] [-q RESULT_FORMAT]
                            [-l LOG_FILE] [-x LOG_LEVEL] [-w WATCHDOG_THREADS]
                            [-t TESTSSL_THREADS]
                            [-W OUTPUT_DIR_HTTPSERVER_PORT]
                            [-u RETAIN_OUTPUT_DAYS]

optional arguments:
  -h, --help            show this help message and exit
  -i INPUT_DIR, --input-dir INPUT_DIR
                        Directory path to recursively monitor for new
                        `--filename-filter` command files. Default
  -O OUTPUT_DIR, --output-dir OUTPUT_DIR
                        Directory path to place all processor output, and
               output files to if relative paths are in
                        command files. If absoluate paths are in
                        command files they will be respected and only
                        processor output will go into --output-dir. Default
                        If the commands in the command files do not
                        reference an absolute path to the command,
                        it assumes its already on the PATH or in the current
                        working directory of the processor. Otherwise you can
                        specify the PATH to it with this argument. Default
                        Only react to filenames in --input-dir that contain
                        the string --filename-filter, default 'testssl_cmds'
                        processor execution result filename prefix. Default
  -q RESULT_FORMAT, --result-format RESULT_FORMAT
                        processor result filename format, json or yaml.
                        Default 'json'
  -l LOG_FILE, --log-file LOG_FILE
                        Path to log file, default None which means STDOUT
  -x LOG_LEVEL, --log-level LOG_LEVEL
                        log level, default DEBUG
                        max threads for watchdog file processing, default 1
                        for each watchdog file event, the maximum number of
                        commands to be processed concurrently by
                        invocations, default 5
                        Default None, if a numeric port is specified, this
                        will startup a simple twisted http server who's
                        document root is the --output-dir
  -u RETAIN_OUTPUT_DAYS, --retain-output-days RETAIN_OUTPUT_DAYS
                        Optional, default 7, the number of days of data to
                        retain that ends up under `--output-dir`, purges
                        output dirs older than this time threshold


docker build -t testssl-processor .

docker run \
  -v /pathto/input:/input -v /pathto/output:/output \
  testssl-processor:latest \ \
    --input-dir /input \
    --output-dir /output \
    --output-dir-httpserver-port 8888 \
    --testssl-threads 5 \
    --retain-output-days .1


Run the command:

git clone

mkdir input
mkdir output

./ \
  --input-dir ./input \
  --testssl-path-if-missing ./ \
  --output-dir ./output \
  --filename-filter testssl_cmds \
  --result-format json \
  --output-dir-httpserver-port 8888

Given a testssl_cmds file (see sample/ dir) dropped into directory input/.

cp sample/ input/

Now the output shows:

2018-11-13 19:49:10,022 - root - INFO - Monitoring for new testssl_cmds files at: ./input with filename filter: testssl_cmds
2018-11-13 19:49:10,023 - root - INFO - Starting HTTP server listening on: 8888 and serving up: ./output
2018-11-13 19:49:12,311 - root - INFO - Responding to creation of file: ./input/
2018-11-13 19:49:17,317 - root - INFO - Processing testssl_cmds: './input/'
2018-11-13 19:49:17,340 - root - INFO - Processing testssl_cmd: ' -S -P -p --fast --logfile --jsonfile-pretty --csvfile --htmlfile'
making dir: ./output/
2018-11-13 19:50:03,392 - root - DEBUG - Command finished: exit code: 0 stdout.len:5752 stderr.len:0 cmd: /home/bitsofinfo/code/ -S -P -p --fast --logfile --jsonfile-pretty --csvfile --htmlfile
2018-11-13 19:50:03,394 - root - DEBUG - Event 20181113_194917 Testssl processor result written to: ./output/
2018-11-13 19:50:03,495 - root - DEBUG - Pool closed and terminated

The contents of our input/ and output/ dirs is now as follows. The actual output of the commands --*file directives are in the respective html/json files etc, while the output from the processor itself that invokes all the commands is in the testssl_processor_result_*.json files.

Contents of testssl_processor_result_*.json:

        "success": true,
        "orig_cmd": " -S -P -p --fast --logfile --jsonfile-pretty --csvfile --htmlfile",
        "timestamp": "20181113_194917",
        "testssl_path_if_missing": "./",
        "actual_cmd": "/home/bitsofinfo/ -S -P -p --fast --logfile --jsonfile-pretty --csvfile --htmlfile",
        "cwd": "./output/",
        "returncode": 0,
        "stdout": "\u001b[1m\n###########################################################\n       3.0rc2 from \u001b[m\u001b[1m ... .. . . ( <<--\u001b[m\n\n\n",
        "stderr": "",
        "exec_ms": 46051.146

Hitting http://localhost:8888 in a browser: