Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package ssh-audit for openSUSE:Factory 
checked in at 2021-09-02 23:20:19
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ssh-audit (Old)
 and      /work/SRC/openSUSE:Factory/.ssh-audit.new.1899 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ssh-audit"

Thu Sep  2 23:20:19 2021 rev:5 rq:915764 version:2.5.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/ssh-audit/ssh-audit.changes      2021-03-03 
18:35:07.467388522 +0100
+++ /work/SRC/openSUSE:Factory/.ssh-audit.new.1899/ssh-audit.changes    
2021-09-02 23:20:39.348578990 +0200
@@ -1,0 +2,30 @@
+Mon Aug 30 10:11:06 UTC 2021 - Martin Hauke <mar...@gmx.de>
+
+- Require correct python version
+
+-------------------------------------------------------------------
+Thu Aug 26 20:12:17 UTC 2021 - Martin Hauke <mar...@gmx.de>
+
+- Update to version 2.5.0
+  * Fixed crash when running host key tests.
+  * Handles server connection failures more gracefully.
+  * Now prints JSON with indents when -jj is used (useful for
+    debugging).
+  * Added MD5 fingerprints to verbose output.
+  * Added -d/--debug option for getting debugging output.
+  * Updated JSON output to include MD5 fingerprints. Note that
+    this results in a breaking change in the 'fingerprints'
+    dictionary format.
+  * Updated OpenSSH 8.1 (and earlier) policies to include
+    rsa-sha2-512 and rsa-sha2-256.
+  * Added OpenSSH v8.6 & v8.7 policies.
+  * Added 3 new key exchanges:
+    + gss-gex-sha1-eipGX3TCiQSrx573bT1o1Q==
+    + gss-group1-sha1-eipGX3TCiQSrx573bT1o1Q==
+    + gss-group14-sha1-eipGX3TCiQSrx573bT1o1Q==
+  * Added 3 new MACs:
+    + hmac-ripemd160-96
+    + AEAD_AES_128_GCM
+    + AEAD_AES_256_GCM
+
+-------------------------------------------------------------------

Old:
----
  ssh-audit-2.4.0.tar.gz
  ssh-audit-2.4.0.tar.gz.sig

New:
----
  ssh-audit-2.5.0.tar.gz
  ssh-audit-2.5.0.tar.gz.sig

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ ssh-audit.spec ++++++
--- /var/tmp/diff_new_pack.UCh7Zn/_old  2021-09-02 23:20:39.924579708 +0200
+++ /var/tmp/diff_new_pack.UCh7Zn/_new  2021-09-02 23:20:39.928579712 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           ssh-audit
-Version:        2.4.0
+Version:        2.5.0
 Release:        0
 Summary:        SSH server auditing
 License:        MIT
@@ -30,7 +30,7 @@
 BuildRequires:  python3-pytest
 BuildRequires:  python3-rpm-macros
 BuildRequires:  python3-setuptools
-Requires:       python >= 3
+Requires:       python3
 BuildArch:      noarch
 
 %description

++++++ ssh-audit-2.4.0.tar.gz -> ssh-audit-2.5.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ssh-audit-2.4.0/.github/workflows/tox.yaml 
new/ssh-audit-2.5.0/.github/workflows/tox.yaml
--- old/ssh-audit-2.4.0/.github/workflows/tox.yaml      1970-01-01 
01:00:00.000000000 +0100
+++ new/ssh-audit-2.5.0/.github/workflows/tox.yaml      2021-08-26 
21:24:34.000000000 +0200
@@ -0,0 +1,24 @@
+name: ssh-audit
+on: [push, pull_request]
+
+jobs:
+  build:
+
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        python-version: [3.6, 3.7, 3.8, 3.9]
+
+    steps:
+      - uses: actions/checkout@v2
+      - name: Set up Python ${{ matrix.python-version }}
+        uses: actions/setup-python@v2
+        with:
+          python-version: ${{ matrix.python-version }}
+      - name: Install dependencies
+        run: |
+          python -m pip install --upgrade pip
+          pip install codecov coveralls flake8 mypy pylint tox vulture
+      - name: Run Tox
+        run: |
+          tox
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ssh-audit-2.4.0/.travis.yml 
new/ssh-audit-2.5.0/.travis.yml
--- old/ssh-audit-2.4.0/.travis.yml     2021-02-24 02:39:18.000000000 +0100
+++ new/ssh-audit-2.5.0/.travis.yml     2021-08-26 21:24:34.000000000 +0200
@@ -10,6 +10,7 @@
   - "3.7"
   - "3.8"
   - "3.9"
+  - "3.10"
 
 cache:
   - pip
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ssh-audit-2.4.0/CONTRIBUTING.md 
new/ssh-audit-2.5.0/CONTRIBUTING.md
--- old/ssh-audit-2.4.0/CONTRIBUTING.md 2021-02-24 02:39:18.000000000 +0100
+++ new/ssh-audit-2.5.0/CONTRIBUTING.md 2021-08-26 21:24:34.000000000 +0200
@@ -11,26 +11,8 @@
 
 Tox is used to do unit testing, linting with 
[pylint](http://pylint.pycqa.org/en/latest/) & 
[flake8](https://flake8.pycqa.org/en/latest/), and static type-checking with 
[mypy](https://mypy.readthedocs.io/en/stable/).
 
-### Running tests on Ubuntu 18.04 and later
-
 For Ubuntu 18.04 or later, install tox with `apt install tox`, then simply run 
`tox` in the top-level directory.  Look for any error messages in the (verbose) 
output.
 
-### Running tests on Ubuntu 16.04
-
-For Ubuntu 16.04 (which is still supported until April 2021), a newer version 
of tox is needed.  The easiest way is to use virtualenv:
-```
-$ sudo apt install python3-virtualenv
-$ virtualenv -p /usr/bin/python3 ~/venv_ssh-audit
-$ source ~/venv_ssh-audit/bin/activate
-$ pip install tox
-```
-Then, to run the tox tests:
-```
-$ source ~/venv_ssh-audit/bin/activate
-$ cd path/to/ssh-audit
-$ tox
-```
-
 
 ## Docker Tests
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ssh-audit-2.4.0/PACKAGING.md 
new/ssh-audit-2.5.0/PACKAGING.md
--- old/ssh-audit-2.4.0/PACKAGING.md    2021-02-24 02:39:18.000000000 +0100
+++ new/ssh-audit-2.5.0/PACKAGING.md    2021-08-26 21:24:34.000000000 +0200
@@ -2,8 +2,6 @@
 
 An executable can only be made on a Windows host because the PyInstaller tool 
(https://www.pyinstaller.org/) does not support cross-compilation.
 
-On a Windows machine, do the following:
-
 1.) Install Python v3.9.x from https://www.python.org/.  To make life easier, 
check the option to add Python to the PATH environment variable.
 
 2.) Using pip, install pyinstaller and colorama:
@@ -12,14 +10,15 @@
     pip install pyinstaller colorama
 ```
 
-3.) Create the executable with:
+3.) Install Cygwin (https://www.cygwin.com/).
+
+4.) Create the executable with:
 
 ```
-    cd src\ssh_audit
-    rename ssh_audit.py ssh-audit.py
-    pyinstaller -F --icon ..\..\windows_icon.ico ssh-audit.py
+    $ ./build_windows_executable.sh
 ```
 
+
 # PyPI
 
 To create package and upload to test server:
@@ -38,7 +37,7 @@
     $ pip3 install --index-url https://test.pypi.org/simple ssh-audit
 ```
 
-To upload to production server (hint: use username '__token__' and API token):
+To upload to production server (hint: use username '\_\_token\_\_' and API 
token):
 
 ```
     $ make -f Makefile.pypi uploadprod
@@ -60,7 +59,7 @@
 
 ```
     $ sudo apt install make snapcraft
-    $ sudo snap install review-tools
+    $ sudo snap install review-tools lxd
 ```
 
 Initialize LXD (leave all options default):
@@ -91,8 +90,8 @@
     $ make -f Makefile.docker
 ```
 
-Then upload them to Dockerhub with:
+Then upload it to Dockerhub with:
 
 ```
     $ make -f Makefile.docker upload
-```
\ No newline at end of file
+```
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ssh-audit-2.4.0/README.md 
new/ssh-audit-2.5.0/README.md
--- old/ssh-audit-2.4.0/README.md       2021-02-24 02:39:18.000000000 +0100
+++ new/ssh-audit-2.5.0/README.md       2021-08-26 21:24:34.000000000 +0200
@@ -1,14 +1,25 @@
 # ssh-audit
-[![Build 
Status](https://travis-ci.org/jtesta/ssh-audit.svg?branch=master)](https://travis-ci.org/jtesta/ssh-audit)
-<!--
-[![appveyor build 
status](https://ci.appveyor.com/api/projects/status/4m5r73m0r023edil/branch/develop?svg=true)](https://ci.appveyor.com/project/arthepsy/ssh-audit)
-[![codecov](https://codecov.io/gh/arthepsy/ssh-audit/branch/develop/graph/badge.svg)](https://codecov.io/gh/arthepsy/ssh-audit)
-[![Quality 
Gate](https://sonarqube.com/api/badges/gate?key=arthepsy-github%3Assh-audit%3Adevelop&template=ROUNDED)](https://sq.evolutiongaming.com/dashboard?id=arthepsy-github%3Assh-audit%3Adevelop)
  
--->
+[![License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](https://github.com/jtesta/ssh-audit/blob/master/LICENSE)
+[![PyPI 
Downloads](https://img.shields.io/pypi/dm/ssh-audit)](https://pypi.org/project/ssh-audit/)
+[![Docker 
Pulls](https://img.shields.io/docker/pulls/positronsecurity/ssh-audit)](https://hub.docker.com/r/positronsecurity/ssh-audit)
+[![Build 
Status](https://github.com/jtesta/ssh-audit/actions/workflows/tox.yaml/badge.svg)](https://github.com/jtesta/ssh-audit/actions)
+[![PRs 
Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/jtesta/ssh-audit/blob/master/CONTRIBUTING.md)
+
 **ssh-audit** is a tool for ssh server & client configuration auditing.
 
 [jtesta/ssh-audit](https://github.com/jtesta/ssh-audit/) (v2.0+) is the 
updated and maintained version of ssh-audit forked from 
[arthepsy/ssh-audit](https://github.com/arthepsy/ssh-audit) (v1.x) due to 
inactivity.
 
+- [Features](#features)
+- [Usage](#usage)
+- [Screenshots](#screenshots)
+    - [Server Standard Audit Example](#server-standard-audit-example)
+    - [Server Policy Audit Example](#server-policy-audit-example)
+    - [Client Standard Audit Example](#client-standard-audit-example)
+- [Hardening Guides](#hardening-guides)
+- [Pre-Built Packages](#pre-built-packages)
+- [Web Front-End](#web-front-end)
+- [ChangeLog](#changelog)
+
 ## Features
 - SSH1 and SSH2 protocol server support;
 - analyze SSH client configuration;
@@ -37,7 +48,8 @@
    -c,  --client-audit     starts a server on port 2222 to audit client
                                software config (use -p to change port;
                                use -t to change timeout)
-   -j,  --json             JSON output
+   -d,  --debug            Enable debug output.
+   -j,  --json             JSON output (use -jj to enable indents)
    -l,  --level=<level>    minimum output level (info|warn|fail)
    -L,  --list-policies    list all the official, built-in policies
         --lookup=<alg1,alg2,...>    looks up an algorithm(s) without
@@ -115,6 +127,8 @@
 ssh-audit -M new_policy.txt targetserver
 ```
 
+## Screenshots
+
 ### Server Standard Audit Example
 Below is a screen shot of the standard server-auditing output when connecting 
to an unhardened OpenSSH v5.3 service:
 
![screenshot](https://user-images.githubusercontent.com/2982011/64388792-317e6f80-d00e-11e9-826e-a4934769bb07.png)
@@ -130,10 +144,10 @@
 Below is a screen shot of the client-auditing output when an unhardened 
OpenSSH v7.2 client connects:
 
![client_screenshot](https://user-images.githubusercontent.com/2982011/68867998-b946c100-06c4-11ea-975f-1f47e4178a74.png)
 
-### Hardening Guides
+## Hardening Guides
 Guides to harden server & client configuration can be found here: 
[https://www.ssh-audit.com/hardening_guides.html](https://www.ssh-audit.com/hardening_guides.html)
 
-### Pre-Built Packages
+## Pre-Built Packages
 Pre-built packages are available for Windows (see the releases page), on PyPI, 
Snap, and Homebrew.
 
 To install from PyPI:
@@ -157,10 +171,22 @@
 ```
 (Then run with: `docker run -it -p 2222:2222 positronsecurity/ssh-audit 
10.1.1.1`)
 
-### Web Front-End
+## Web Front-End
 For convenience, a web front-end on top of the command-line tool is available 
at [https://www.ssh-audit.com/](https://www.ssh-audit.com/).
 
 ## ChangeLog
+### v2.5.0 (2021-08-26)
+ - Fixed crash when running host key tests.
+ - Handles server connection failures more gracefully.
+ - Now prints JSON with indents when `-jj` is used (useful for debugging).
+ - Added MD5 fingerprints to verbose output.
+ - Added `-d`/`--debug` option for getting debugging output; credit [Adam 
Russell](https://github.com/thecliguy).
+ - Updated JSON output to include MD5 fingerprints.  Note that this results in 
a breaking change in the 'fingerprints' dictionary format.
+ - Updated OpenSSH 8.1 (and earlier) policies to include `rsa-sha2-512` and 
`rsa-sha2-256`.
+ - Added OpenSSH v8.6 & v8.7 policies.
+ - Added 3 new key exchanges: `gss-gex-sha1-eipGX3TCiQSrx573bT1o1Q==`, 
`gss-group1-sha1-eipGX3TCiQSrx573bT1o1Q==`, and 
`gss-group14-sha1-eipGX3TCiQSrx573bT1o1Q==`.
+ - Added 3 new MACs: `hmac-ripemd160-96`, `AEAD_AES_128_GCM`, and 
`AEAD_AES_256_GCM`.
+
 ### v2.4.0 (2021-02-23)
  - Added multi-threaded scanning support.
  - Added built-in Windows manual page (see `-m`/`--manual`); credit [Adam 
Russell](https://github.com/thecliguy).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ssh-audit-2.4.0/build_windows_executable.sh 
new/ssh-audit-2.5.0/build_windows_executable.sh
--- old/ssh-audit-2.4.0/build_windows_executable.sh     2021-02-24 
02:39:18.000000000 +0100
+++ new/ssh-audit-2.5.0/build_windows_executable.sh     2021-08-26 
21:24:34.000000000 +0200
@@ -58,6 +58,29 @@
     exit 1
 fi
 
+# Prompt for the version to release.
+echo -n "Enter the version to release, using format 'vX.X.X': "
+read -r version
+
+# Ensure that entered version fits required format.
+if [[ ! $version =~ ^v[0-9]\.[0-9]\.[0-9]$ ]]; then
+   echo "Error: version string does not match format vX.X.X!"
+   exit 1
+fi
+
+# Verify that version is correct.
+echo -n "Version will be set to '${version}'.  Is this correct? (y/n): "
+read -r yn
+echo
+
+if [[ $yn != "y" ]]; then
+   echo "Build cancelled."
+   exit 1
+fi
+
+# Reset any local changes made to globals.py from a previous run.
+git checkout src/ssh_audit/globals.py 2> /dev/null
+
 # Update the man page.
 ./update_windows_man_page.sh
 if [[ $? != 0 ]]; then
@@ -68,12 +91,14 @@
 # Do all operations from this point from the main source directory.
 pushd src/ssh_audit > /dev/null
 
-# Delete the executable if it exists from a prior run.
-if [[ -f dist/ssh-audit.exe ]]; then
-    rm dist/ssh-audit.exe
-fi
+# Delete the existing VERSION variable and add the value that the user 
entered, above.
+sed -i '/^VERSION/d' globals.py
+echo "VERSION = '$version'" >> globals.py
 
-# Create a link from ssh_audit.py to ssh-audit.py.
+# Delete cached files if they exist from a prior run.
+rm -rf dist/ build/ ssh-audit.spec
+
+# Create a hard link from ssh_audit.py to ssh-audit.py.
 if [[ ! -f ssh-audit.py ]]; then
     ln ssh_audit.py ssh-audit.py
 fi
@@ -83,10 +108,23 @@
 
 if [[ -f dist/ssh-audit.exe ]]; then
     echo -e "\nExecutable created in $(pwd)/dist/ssh-audit.exe\n"
+else
+    echo -e "\nFAILED to create $(pwd)/dist/ssh-audit.exe!\n"
+    exit 1
+fi
+
+# Ensure that the version string doesn't have '-dev' in it.
+X=`dist/ssh-audit.exe | grep -E 'ssh-audit.exe v.+\-dev'` > /dev/null
+if [[ $? == 0 ]]; then
+    echo -e "\nError: executable's version number includes '-dev'."
+    exit 1
 fi
 
-# Remove the link we created, above.
-rm ssh-audit.py
+# Remove the cache files created during the build process, along with the link 
we created, above.
+rm -rf build/ ssh-audit.spec ssh-audit.py
+
+# Reset the changes we made to globals.py.
+git checkout globals.py 2> /dev/null
 
 popd > /dev/null
 exit 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ssh-audit-2.4.0/docker_test.sh 
new/ssh-audit-2.5.0/docker_test.sh
--- old/ssh-audit-2.4.0/docker_test.sh  2021-02-24 02:39:18.000000000 +0100
+++ new/ssh-audit-2.5.0/docker_test.sh  2021-08-26 21:24:34.000000000 +0200
@@ -700,10 +700,10 @@
 run_custom_policy_test 'config2' 'test14' $PROGRAM_RETVAL_FAILURE
 
 # Passing test for built-in OpenSSH 8.0p1 server policy.
-run_builtin_policy_test "Hardened OpenSSH Server v8.0 (version 1)" "8.0p1" 
"test1" "-o HostKeyAlgorithms=ssh-ed25519 -o 
KexAlgorithms=curve25519-sha256,curve25519-sha...@libssh.org,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha256
 -o 
Ciphers=chacha20-poly1...@openssh.com,aes256-...@openssh.com,aes128-...@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
 -o 
MACs=hmac-sha2-256-...@openssh.com,hmac-sha2-512-...@openssh.com,umac-128-...@openssh.com"
 $PROGRAM_RETVAL_GOOD
+run_builtin_policy_test "Hardened OpenSSH Server v8.0 (version 1)" "8.0p1" 
"test1" "-o HostKeyAlgorithms=rsa-sha2-512,rsa-sha2-256,ssh-ed25519 -o 
KexAlgorithms=curve25519-sha256,curve25519-sha...@libssh.org,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha256
 -o 
Ciphers=chacha20-poly1...@openssh.com,aes256-...@openssh.com,aes128-...@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
 -o 
MACs=hmac-sha2-256-...@openssh.com,hmac-sha2-512-...@openssh.com,umac-128-...@openssh.com"
 $PROGRAM_RETVAL_GOOD
 
 # Failing test for built-in OpenSSH 8.0p1 server policy (MACs not hardened).
-run_builtin_policy_test "Hardened OpenSSH Server v8.0 (version 1)" "8.0p1" 
"test2" "-o HostKeyAlgorithms=ssh-ed25519 -o 
KexAlgorithms=curve25519-sha256,curve25519-sha...@libssh.org,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha256
 -o 
Ciphers=chacha20-poly1...@openssh.com,aes256-...@openssh.com,aes128-...@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr"
 $PROGRAM_RETVAL_FAILURE
+run_builtin_policy_test "Hardened OpenSSH Server v8.0 (version 1)" "8.0p1" 
"test2" "-o HostKeyAlgorithms=rsa-sha2-512,rsa-sha2-256,ssh-ed25519 -o 
KexAlgorithms=curve25519-sha256,curve25519-sha...@libssh.org,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha256
 -o 
Ciphers=chacha20-poly1...@openssh.com,aes256-...@openssh.com,aes128-...@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr"
 $PROGRAM_RETVAL_FAILURE
 
 
 if [[ $num_failures == 0 ]]; then
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ssh-audit-2.4.0/src/ssh_audit/algorithms.py 
new/ssh-audit-2.5.0/src/ssh_audit/algorithms.py
--- old/ssh-audit-2.4.0/src/ssh_audit/algorithms.py     2021-02-24 
02:39:18.000000000 +0100
+++ new/ssh-audit-2.5.0/src/ssh_audit/algorithms.py     2021-08-26 
21:24:34.000000000 +0200
@@ -1,7 +1,7 @@
 """
    The MIT License (MIT)
 
-   Copyright (C) 2017-2020 Joe Testa (jte...@positronsecurity.com)
+   Copyright (C) 2017-2021 Joe Testa (jte...@positronsecurity.com)
    Copyright (C) 2017 Andris Raugulis (m...@arthepsy.eu)
 
    Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -55,7 +55,7 @@
         if self.ssh1kex is None:
             return None
         item = Algorithms.Item(1, SSH1_KexDB.ALGORITHMS)
-        item.add('key', [u'ssh-rsa1'])
+        item.add('key', ['ssh-rsa1'])
         item.add('enc', self.ssh1kex.supported_ciphers)
         item.add('aut', self.ssh1kex.supported_authentications)
         return item
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ssh-audit-2.4.0/src/ssh_audit/auditconf.py 
new/ssh-audit-2.5.0/src/ssh_audit/auditconf.py
--- old/ssh-audit-2.4.0/src/ssh_audit/auditconf.py      2021-02-24 
02:39:18.000000000 +0100
+++ new/ssh-audit-2.5.0/src/ssh_audit/auditconf.py      2021-08-26 
21:24:34.000000000 +0200
@@ -1,7 +1,7 @@
 """
    The MIT License (MIT)
 
-   Copyright (C) 2017-2020 Joe Testa (jte...@positronsecurity.com)
+   Copyright (C) 2017-2021 Joe Testa (jte...@positronsecurity.com)
    Copyright (C) 2017 Andris Raugulis (m...@arthepsy.eu)
 
    Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -41,6 +41,7 @@
         self.client_audit = False
         self.colors = True
         self.json = False
+        self.json_print_indent = False
         self.verbose = False
         self.level = 'info'
         self.ip_version_preference: List[int] = []  # Holds only 5 possible 
values: [] (no preference), [4] (use IPv4 only), [6] (use IPv6 only), [46] (use 
both IPv4 and IPv6, but prioritize v4), and [64] (use both IPv4 and IPv6, but 
prioritize v6).
@@ -57,10 +58,11 @@
         self.list_policies = False
         self.lookup = ''
         self.manual = False
+        self.debug = False
 
     def __setattr__(self, name: str, value: Union[str, int, float, bool, 
Sequence[int]]) -> None:
         valid = False
-        if name in ['batch', 'client_audit', 'colors', 'json', 
'list_policies', 'manual', 'make_policy', 'ssh1', 'ssh2', 'timeout_set', 
'verbose']:
+        if name in ['batch', 'client_audit', 'colors', 'json', 
'json_print_indent', 'list_policies', 'manual', 'make_policy', 'ssh1', 'ssh2', 
'timeout_set', 'verbose', 'debug']:
             valid, value = True, bool(value)
         elif name in ['ipv4', 'ipv6']:
             valid, value = True, bool(value)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ssh-audit-2.4.0/src/ssh_audit/fingerprint.py 
new/ssh-audit-2.5.0/src/ssh_audit/fingerprint.py
--- old/ssh-audit-2.4.0/src/ssh_audit/fingerprint.py    2021-02-24 
02:39:18.000000000 +0100
+++ new/ssh-audit-2.5.0/src/ssh_audit/fingerprint.py    2021-08-26 
21:24:34.000000000 +0200
@@ -1,7 +1,7 @@
 """
    The MIT License (MIT)
 
-   Copyright (C) 2017-2020 Joe Testa (jte...@positronsecurity.com)
+   Copyright (C) 2017-2021 Joe Testa (jte...@positronsecurity.com)
    Copyright (C) 2017 Andris Raugulis (m...@arthepsy.eu)
 
    Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -33,11 +33,11 @@
     @property
     def md5(self) -> str:
         h = hashlib.md5(self.__fpd).hexdigest()
-        r = u':'.join(h[i:i + 2] for i in range(0, len(h), 2))
-        return u'MD5:{}'.format(r)
+        r = ':'.join(h[i:i + 2] for i in range(0, len(h), 2))
+        return 'MD5:{}'.format(r)
 
     @property
     def sha256(self) -> str:
         h = base64.b64encode(hashlib.sha256(self.__fpd).digest())
         r = h.decode('ascii').rstrip('=')
-        return u'SHA256:{}'.format(r)
+        return 'SHA256:{}'.format(r)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ssh-audit-2.4.0/src/ssh_audit/gextest.py 
new/ssh-audit-2.5.0/src/ssh_audit/gextest.py
--- old/ssh-audit-2.4.0/src/ssh_audit/gextest.py        2021-02-24 
02:39:18.000000000 +0100
+++ new/ssh-audit-2.5.0/src/ssh_audit/gextest.py        2021-08-26 
21:24:34.000000000 +0200
@@ -26,10 +26,13 @@
 from typing import Dict, List, Set, Sequence, Tuple, Iterable  # noqa: F401
 from typing import Callable, Optional, Union, Any  # noqa: F401
 
+import traceback
+
 from ssh_audit.kexdh import KexGroupExchange_SHA1, KexGroupExchange_SHA256
 from ssh_audit.ssh2_kexdb import SSH2_KexDB
 from ssh_audit.ssh2_kex import SSH2_Kex
 from ssh_audit.ssh_socket import SSH_Socket
+from ssh_audit.outputbuffer import OutputBuffer
 
 
 # Performs DH group exchanges to find what moduli are supported, and checks
@@ -38,16 +41,18 @@
 
     # Creates a new connection to the server.  Returns True on success, or 
False.
     @staticmethod
-    def reconnect(s: 'SSH_Socket', kex: 'SSH2_Kex', gex_alg: str) -> bool:
+    def reconnect(out: 'OutputBuffer', s: 'SSH_Socket', kex: 'SSH2_Kex', 
gex_alg: str) -> bool:
         if s.is_connected():
             return True
 
         err = s.connect()
         if err is not None:
+            out.v(err, write_now=True)
             return False
 
         _, _, err = s.get_banner()
         if err is not None:
+            out.v(err, write_now=True)
             s.close()
             return False
 
@@ -55,15 +60,19 @@
         # server's own values.
         s.send_kexinit(key_exchanges=[gex_alg], hostkeys=kex.key_algorithms, 
ciphers=kex.server.encryption, macs=kex.server.mac, 
compressions=kex.server.compression, languages=kex.server.languages)
 
-        # Parse the server's KEX.
-        _, payload = s.read_packet(2)
-        SSH2_Kex.parse(payload)
+        try:
+            # Parse the server's KEX.
+            _, payload = s.read_packet(2)
+            SSH2_Kex.parse(payload)
+        except Exception:
+            out.v("Failed to parse server's kex.  Stack trace:\n%s" % 
str(traceback.format_exc()), write_now=True)
+            return False
 
         return True
 
     # Runs the DH moduli test against the specified target.
     @staticmethod
-    def run(s: 'SSH_Socket', kex: 'SSH2_Kex') -> None:
+    def run(out: 'OutputBuffer', s: 'SSH_Socket', kex: 'SSH2_Kex') -> None:
         GEX_ALGS = {
             'diffie-hellman-group-exchange-sha1': KexGroupExchange_SHA1,
             'diffie-hellman-group-exchange-sha256': KexGroupExchange_SHA256,
@@ -77,13 +86,14 @@
 
         # Check if the server supports any of the group-exchange
         # algorithms.  If so, test each one.
-        for gex_alg in GEX_ALGS:
+        for gex_alg, kex_group_class in GEX_ALGS.items():
             if gex_alg in kex.kex_algorithms:
+                out.d('Preparing to perform DH group exchange using ' + 
gex_alg + '...', write_now=True)
 
-                if GEXTest.reconnect(s, kex, gex_alg) is False:
+                if GEXTest.reconnect(out, s, kex, gex_alg) is False:
                     break
 
-                kex_group = GEX_ALGS[gex_alg]()
+                kex_group = kex_group_class()
                 smallest_modulus = -1
 
                 # First try a range of weak sizes.
@@ -110,7 +120,9 @@
                     if bits >= smallest_modulus > 0:
                         break
 
-                    if GEXTest.reconnect(s, kex, gex_alg) is False:
+                    out.d('Preparing to perform DH group exchange using ' + 
gex_alg + ' with modulus size ' + str(bits) + '...', write_now=True)
+
+                    if GEXTest.reconnect(out, s, kex, gex_alg) is False:
                         reconnect_failed = True
                         break
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ssh-audit-2.4.0/src/ssh_audit/globals.py 
new/ssh-audit-2.5.0/src/ssh_audit/globals.py
--- old/ssh-audit-2.4.0/src/ssh_audit/globals.py        2021-02-24 
02:39:18.000000000 +0100
+++ new/ssh-audit-2.5.0/src/ssh_audit/globals.py        2021-08-26 
21:24:34.000000000 +0200
@@ -21,7 +21,7 @@
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    THE SOFTWARE.
 """
-VERSION = 'v2.4.0'
+VERSION = 'v2.5.0'
 SSH_HEADER = 'SSH-{0}-OpenSSH_8.2'  # SSH software to impersonate
 GITHUB_ISSUES_URL = 'https://github.com/jtesta/ssh-audit/issues'  # The URL to 
the Github issues tracker.
 WINDOWS_MAN_PAGE = ''
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ssh-audit-2.4.0/src/ssh_audit/hostkeytest.py 
new/ssh-audit-2.5.0/src/ssh_audit/hostkeytest.py
--- old/ssh-audit-2.4.0/src/ssh_audit/hostkeytest.py    2021-02-24 
02:39:18.000000000 +0100
+++ new/ssh-audit-2.5.0/src/ssh_audit/hostkeytest.py    2021-08-26 
21:24:34.000000000 +0200
@@ -26,10 +26,13 @@
 from typing import Dict, List, Set, Sequence, Tuple, Iterable  # noqa: F401
 from typing import Callable, Optional, Union, Any  # noqa: F401
 
+import traceback
+
 from ssh_audit.kexdh import KexDH, KexGroup1, KexGroup14_SHA1, 
KexGroup14_SHA256, KexCurve25519_SHA256, KexGroup16_SHA512, KexGroup18_SHA512, 
KexGroupExchange_SHA1, KexGroupExchange_SHA256, KexNISTP256, KexNISTP384, 
KexNISTP521
 from ssh_audit.ssh2_kex import SSH2_Kex
 from ssh_audit.ssh2_kexdb import SSH2_KexDB
 from ssh_audit.ssh_socket import SSH_Socket
+from ssh_audit.outputbuffer import OutputBuffer
 
 
 # Obtains host keys, checks their size, and derives their fingerprints.
@@ -52,7 +55,7 @@
     }
 
     @staticmethod
-    def run(s: 'SSH_Socket', server_kex: 'SSH2_Kex') -> None:
+    def run(out: 'OutputBuffer', s: 'SSH_Socket', server_kex: 'SSH2_Kex') -> 
None:
         KEX_TO_DHGROUP = {
             'diffie-hellman-group1-sha1': KexGroup1,
             'diffie-hellman-group14-sha1': KexGroup14_SHA1,
@@ -80,10 +83,10 @@
                 break
 
         if kex_str is not None and kex_group is not None:
-            HostKeyTest.perform_test(s, server_kex, kex_str, kex_group, 
HostKeyTest.HOST_KEY_TYPES)
+            HostKeyTest.perform_test(out, s, server_kex, kex_str, kex_group, 
HostKeyTest.HOST_KEY_TYPES)
 
     @staticmethod
-    def perform_test(s: 'SSH_Socket', server_kex: 'SSH2_Kex', kex_str: str, 
kex_group: 'KexDH', host_key_types: Dict[str, Dict[str, bool]]) -> None:
+    def perform_test(out: 'OutputBuffer', s: 'SSH_Socket', server_kex: 
'SSH2_Kex', kex_str: str, kex_group: 'KexDH', host_key_types: Dict[str, 
Dict[str, bool]]) -> None:
         hostkey_modulus_size = 0
         ca_modulus_size = 0
 
@@ -101,6 +104,8 @@
 
             # If this host key type is supported by the server, we test it.
             if host_key_type in server_kex.key_algorithms:
+                out.d('Preparing to obtain ' + host_key_type + ' host key...', 
write_now=True)
+
                 cert = host_key_types[host_key_type]['cert']
                 variable_key_len = 
host_key_types[host_key_type]['variable_key_len']
 
@@ -108,20 +113,25 @@
                 if not s.is_connected():
                     err = s.connect()
                     if err is not None:
+                        out.v(err, write_now=True)
                         return
 
                     _, _, err = s.get_banner()
                     if err is not None:
+                        out.v(err, write_now=True)
                         s.close()
                         return
 
                     # Send our KEX using the specified group-exchange and most 
of the server's own values.
                     s.send_kexinit(key_exchanges=[kex_str], 
hostkeys=[host_key_type], ciphers=server_kex.server.encryption, 
macs=server_kex.server.mac, compressions=server_kex.server.compression, 
languages=server_kex.server.languages)
 
-                    # Parse the server's KEX.
-                    _, payload = s.read_packet()
-                    SSH2_Kex.parse(payload)
-
+                    try:
+                        # Parse the server's KEX.
+                        _, payload = s.read_packet()
+                        SSH2_Kex.parse(payload)
+                    except Exception:
+                        out.v("Failed to parse server's kex.  Stack 
trace:\n%s" % str(traceback.format_exc()), write_now=True)
+                        return
 
                 # Do the initial DH exchange.  The server responds back
                 # with the host key and its length.  Bingo.  We also get back 
the host key fingerprint.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ssh-audit-2.4.0/src/ssh_audit/kexdh.py 
new/ssh-audit-2.5.0/src/ssh_audit/kexdh.py
--- old/ssh-audit-2.4.0/src/ssh_audit/kexdh.py  2021-02-24 02:39:18.000000000 
+0100
+++ new/ssh-audit-2.5.0/src/ssh_audit/kexdh.py  2021-08-26 21:24:34.000000000 
+0200
@@ -1,7 +1,7 @@
 """
    The MIT License (MIT)
 
-   Copyright (C) 2017-2020 Joe Testa (jte...@positronsecurity.com)
+   Copyright (C) 2017-2021 Joe Testa (jte...@positronsecurity.com)
    Copyright (C) 2017 Andris Raugulis (m...@arthepsy.eu)
 
    Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -37,8 +37,8 @@
 
 class KexDH:  # pragma: nocover
     def __init__(self, kex_name: str, hash_alg: str, g: int, p: int) -> None:
-        self.__kex_name = kex_name
-        self.__hash_alg = hash_alg
+        self.__kex_name = kex_name  # pylint: disable=unused-private-member
+        self.__hash_alg = hash_alg  # pylint: disable=unused-private-member
         self.__g = 0
         self.__p = 0
         self.__q = 0
@@ -46,10 +46,10 @@
         self.__e = 0
         self.set_params(g, p)
 
-        self.__ed25519_pubkey: Optional[bytes] = None
+        self.__ed25519_pubkey: Optional[bytes] = None  # pylint: 
disable=unused-private-member
         self.__hostkey_type: Optional[bytes] = None
-        self.__hostkey_e = 0
-        self.__hostkey_n = 0
+        self.__hostkey_e = 0  # pylint: disable=unused-private-member
+        self.__hostkey_n = 0  # pylint: disable=unused-private-member
         self.__hostkey_n_len = 0  # Length of the host key modulus.
         self.__ca_n_len = 0  # Length of the CA key modulus (if hostkey is a 
cert).
 
@@ -121,11 +121,11 @@
 
         # The public key exponent.
         hostkey_e, hostkey_e_len, ptr = KexDH.__get_bytes(hostkey, ptr)
-        self.__hostkey_e = int(binascii.hexlify(hostkey_e), 16)
+        self.__hostkey_e = int(binascii.hexlify(hostkey_e), 16)  # pylint: 
disable=unused-private-member
 
         # Here is the modulus size & actual modulus of the host key public key.
         hostkey_n, self.__hostkey_n_len, ptr = KexDH.__get_bytes(hostkey, ptr)
-        self.__hostkey_n = int(binascii.hexlify(hostkey_n), 16)
+        self.__hostkey_n = int(binascii.hexlify(hostkey_n), 16)  # pylint: 
disable=unused-private-member
 
         # If this is an RSA certificate, continue parsing to extract the CA
         # key.
@@ -327,7 +327,7 @@
         s.send_packet()
 
         packet_type, payload = s.read_packet(2)
-        if (packet_type != Protocol.MSG_KEXDH_GEX_GROUP) and (packet_type != 
Protocol.MSG_DEBUG):  # pylint: disable=consider-using-in
+        if packet_type not in [Protocol.MSG_KEXDH_GEX_GROUP, 
Protocol.MSG_DEBUG]:
             # TODO: replace with a better exception type.
             raise Exception('Expected MSG_KEXDH_GEX_REPLY (%d), but got %d 
instead.' % (Protocol.MSG_KEXDH_GEX_REPLY, packet_type))
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ssh-audit-2.4.0/src/ssh_audit/outputbuffer.py 
new/ssh-audit-2.5.0/src/ssh_audit/outputbuffer.py
--- old/ssh-audit-2.4.0/src/ssh_audit/outputbuffer.py   2021-02-24 
02:39:18.000000000 +0100
+++ new/ssh-audit-2.5.0/src/ssh_audit/outputbuffer.py   2021-08-26 
21:24:34.000000000 +0200
@@ -47,6 +47,7 @@
         self.section: List[str] = []
         self.batch = False
         self.verbose = False
+        self.debug = False
         self.use_colors = True
         self.json = False
         self.__level = 0
@@ -167,7 +168,16 @@
 
     def v(self, s: str, write_now: bool = False) -> 'OutputBuffer':
         '''Prints a message if verbose output is enabled.'''
-        if self.verbose:
+        if self.verbose or self.debug:
+            self.info(s)
+            if write_now:
+                self.write()
+
+        return self
+
+    def d(self, s: str, write_now: bool = False) -> 'OutputBuffer':
+        '''Prints a message if verbose output is enabled.'''
+        if self.debug:
             self.info(s)
             if write_now:
                 self.write()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ssh-audit-2.4.0/src/ssh_audit/policy.py 
new/ssh-audit-2.5.0/src/ssh_audit/policy.py
--- old/ssh-audit-2.4.0/src/ssh_audit/policy.py 2021-02-24 02:39:18.000000000 
+0100
+++ new/ssh-audit-2.5.0/src/ssh_audit/policy.py 2021-08-26 21:24:34.000000000 
+0200
@@ -1,7 +1,7 @@
 """
    The MIT License (MIT)
 
-   Copyright (C) 2020 Joe Testa (jte...@positronsecurity.com)
+   Copyright (C) 2020-2021 Joe Testa (jte...@positronsecurity.com)
 
    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to 
deal
@@ -49,15 +49,15 @@
 
         # Generic OpenSSH Server policies
 
-        'Hardened OpenSSH Server v7.7 (version 1)': {'version': '1', 'banner': 
None, 'compressions': None, 'host_keys': ['ssh-ed25519'], 'optional_host_keys': 
['ssh-ed25519-cert-...@openssh.com', 'rsa-sha2-256-cert-...@openssh.com', 
'rsa-sha2-512-cert-...@openssh.com'], 'kex': ['curve25519-sha256', 
'curve25519-sha...@libssh.org', 'diffie-hellman-group16-sha512', 
'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], 
'ciphers': ['chacha20-poly1...@openssh.com', 'aes256-...@openssh.com', 
'aes128-...@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': 
['hmac-sha2-256-...@openssh.com', 'hmac-sha2-512-...@openssh.com', 
'umac-128-...@openssh.com'], 'hostkey_sizes': None, 'cakey_sizes': None, 
'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 2048}, 
'server_policy': True},
+        'Hardened OpenSSH Server v7.7 (version 1)': {'version': '1', 'banner': 
None, 'compressions': None, 'host_keys': ['rsa-sha2-512', 'rsa-sha2-256', 
'ssh-ed25519'], 'optional_host_keys': ['ssh-ed25519-cert-...@openssh.com', 
'rsa-sha2-256-cert-...@openssh.com', 'rsa-sha2-512-cert-...@openssh.com'], 
'kex': ['curve25519-sha256', 'curve25519-sha...@libssh.org', 
'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 
'diffie-hellman-group-exchange-sha256'], 'ciphers': 
['chacha20-poly1...@openssh.com', 'aes256-...@openssh.com', 
'aes128-...@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': 
['hmac-sha2-256-...@openssh.com', 'hmac-sha2-512-...@openssh.com', 
'umac-128-...@openssh.com'], 'hostkey_sizes': None, 'cakey_sizes': None, 
'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 2048}, 
'server_policy': True},
 
-        'Hardened OpenSSH Server v7.8 (version 1)': {'version': '1', 'banner': 
None, 'compressions': None, 'host_keys': ['ssh-ed25519'], 'optional_host_keys': 
['ssh-ed25519-cert-...@openssh.com', 'rsa-sha2-256-cert-...@openssh.com', 
'rsa-sha2-512-cert-...@openssh.com'], 'kex': ['curve25519-sha256', 
'curve25519-sha...@libssh.org', 'diffie-hellman-group16-sha512', 
'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], 
'ciphers': ['chacha20-poly1...@openssh.com', 'aes256-...@openssh.com', 
'aes128-...@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': 
['hmac-sha2-256-...@openssh.com', 'hmac-sha2-512-...@openssh.com', 
'umac-128-...@openssh.com'], 'hostkey_sizes': None, 'cakey_sizes': None, 
'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 2048}, 
'server_policy': True},
+        'Hardened OpenSSH Server v7.8 (version 1)': {'version': '1', 'banner': 
None, 'compressions': None, 'host_keys': ['rsa-sha2-512', 'rsa-sha2-256', 
'ssh-ed25519'], 'optional_host_keys': ['ssh-ed25519-cert-...@openssh.com', 
'rsa-sha2-256-cert-...@openssh.com', 'rsa-sha2-512-cert-...@openssh.com'], 
'kex': ['curve25519-sha256', 'curve25519-sha...@libssh.org', 
'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 
'diffie-hellman-group-exchange-sha256'], 'ciphers': 
['chacha20-poly1...@openssh.com', 'aes256-...@openssh.com', 
'aes128-...@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': 
['hmac-sha2-256-...@openssh.com', 'hmac-sha2-512-...@openssh.com', 
'umac-128-...@openssh.com'], 'hostkey_sizes': None, 'cakey_sizes': None, 
'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 2048}, 
'server_policy': True},
 
-        'Hardened OpenSSH Server v7.9 (version 1)': {'version': '1', 'banner': 
None, 'compressions': None, 'host_keys': ['ssh-ed25519'], 'optional_host_keys': 
['ssh-ed25519-cert-...@openssh.com', 'rsa-sha2-256-cert-...@openssh.com', 
'rsa-sha2-512-cert-...@openssh.com'], 'kex': ['curve25519-sha256', 
'curve25519-sha...@libssh.org', 'diffie-hellman-group16-sha512', 
'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], 
'ciphers': ['chacha20-poly1...@openssh.com', 'aes256-...@openssh.com', 
'aes128-...@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': 
['hmac-sha2-256-...@openssh.com', 'hmac-sha2-512-...@openssh.com', 
'umac-128-...@openssh.com'], 'hostkey_sizes': None, 'cakey_sizes': None, 
'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 2048}, 
'server_policy': True},
+        'Hardened OpenSSH Server v7.9 (version 1)': {'version': '1', 'banner': 
None, 'compressions': None, 'host_keys': ['rsa-sha2-512', 'rsa-sha2-256', 
'ssh-ed25519'], 'optional_host_keys': ['ssh-ed25519-cert-...@openssh.com', 
'rsa-sha2-256-cert-...@openssh.com', 'rsa-sha2-512-cert-...@openssh.com'], 
'kex': ['curve25519-sha256', 'curve25519-sha...@libssh.org', 
'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 
'diffie-hellman-group-exchange-sha256'], 'ciphers': 
['chacha20-poly1...@openssh.com', 'aes256-...@openssh.com', 
'aes128-...@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': 
['hmac-sha2-256-...@openssh.com', 'hmac-sha2-512-...@openssh.com', 
'umac-128-...@openssh.com'], 'hostkey_sizes': None, 'cakey_sizes': None, 
'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 2048}, 
'server_policy': True},
 
-        'Hardened OpenSSH Server v8.0 (version 1)': {'version': '1', 'banner': 
None, 'compressions': None, 'host_keys': ['ssh-ed25519'], 'optional_host_keys': 
['ssh-ed25519-cert-...@openssh.com', 'rsa-sha2-256-cert-...@openssh.com', 
'rsa-sha2-512-cert-...@openssh.com'], 'kex': ['curve25519-sha256', 
'curve25519-sha...@libssh.org', 'diffie-hellman-group16-sha512', 
'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], 
'ciphers': ['chacha20-poly1...@openssh.com', 'aes256-...@openssh.com', 
'aes128-...@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': 
['hmac-sha2-256-...@openssh.com', 'hmac-sha2-512-...@openssh.com', 
'umac-128-...@openssh.com'], 'hostkey_sizes': None, 'cakey_sizes': None, 
'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 2048}, 
'server_policy': True},
+        'Hardened OpenSSH Server v8.0 (version 1)': {'version': '1', 'banner': 
None, 'compressions': None, 'host_keys': ['rsa-sha2-512', 'rsa-sha2-256', 
'ssh-ed25519'], 'optional_host_keys': ['ssh-ed25519-cert-...@openssh.com', 
'rsa-sha2-256-cert-...@openssh.com', 'rsa-sha2-512-cert-...@openssh.com'], 
'kex': ['curve25519-sha256', 'curve25519-sha...@libssh.org', 
'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 
'diffie-hellman-group-exchange-sha256'], 'ciphers': 
['chacha20-poly1...@openssh.com', 'aes256-...@openssh.com', 
'aes128-...@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': 
['hmac-sha2-256-...@openssh.com', 'hmac-sha2-512-...@openssh.com', 
'umac-128-...@openssh.com'], 'hostkey_sizes': None, 'cakey_sizes': None, 
'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 2048}, 
'server_policy': True},
 
-        'Hardened OpenSSH Server v8.1 (version 1)': {'version': '1', 'banner': 
None, 'compressions': None, 'host_keys': ['ssh-ed25519'], 'optional_host_keys': 
['sk-ssh-ed25...@openssh.com', 'ssh-ed25519-cert-...@openssh.com', 
'sk-ssh-ed25519-cert-...@openssh.com', 'rsa-sha2-256-cert-...@openssh.com', 
'rsa-sha2-512-cert-...@openssh.com'], 'kex': ['curve25519-sha256', 
'curve25519-sha...@libssh.org', 'diffie-hellman-group16-sha512', 
'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], 
'ciphers': ['chacha20-poly1...@openssh.com', 'aes256-...@openssh.com', 
'aes128-...@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': 
['hmac-sha2-256-...@openssh.com', 'hmac-sha2-512-...@openssh.com', 
'umac-128-...@openssh.com'], 'hostkey_sizes': None, 'cakey_sizes': None, 
'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 2048}, 
'server_policy': True},
+        'Hardened OpenSSH Server v8.1 (version 1)': {'version': '1', 'banner': 
None, 'compressions': None, 'host_keys': ['rsa-sha2-512', 'rsa-sha2-256', 
'ssh-ed25519'], 'optional_host_keys': ['sk-ssh-ed25...@openssh.com', 
'ssh-ed25519-cert-...@openssh.com', 'sk-ssh-ed25519-cert-...@openssh.com', 
'rsa-sha2-256-cert-...@openssh.com', 'rsa-sha2-512-cert-...@openssh.com'], 
'kex': ['curve25519-sha256', 'curve25519-sha...@libssh.org', 
'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 
'diffie-hellman-group-exchange-sha256'], 'ciphers': 
['chacha20-poly1...@openssh.com', 'aes256-...@openssh.com', 
'aes128-...@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': 
['hmac-sha2-256-...@openssh.com', 'hmac-sha2-512-...@openssh.com', 
'umac-128-...@openssh.com'], 'hostkey_sizes': None, 'cakey_sizes': None, 
'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 2048}, 
'server_policy': True},
 
         'Hardened OpenSSH Server v8.2 (version 1)': {'version': '1', 'banner': 
None, 'compressions': None, 'host_keys': ['rsa-sha2-512', 'rsa-sha2-256', 
'ssh-ed25519'], 'optional_host_keys': ['sk-ssh-ed25...@openssh.com', 
'ssh-ed25519-cert-...@openssh.com', 'sk-ssh-ed25519-cert-...@openssh.com', 
'rsa-sha2-256-cert-...@openssh.com', 'rsa-sha2-512-cert-...@openssh.com'], 
'kex': ['curve25519-sha256', 'curve25519-sha...@libssh.org', 
'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 
'diffie-hellman-group-exchange-sha256'], 'ciphers': 
['chacha20-poly1...@openssh.com', 'aes256-...@openssh.com', 
'aes128-...@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': 
['hmac-sha2-256-...@openssh.com', 'hmac-sha2-512-...@openssh.com', 
'umac-128-...@openssh.com'], 'hostkey_sizes': {'rsa-sha2-256': 4096, 
'rsa-sha2-512': 4096}, 'cakey_sizes': {'rsa-sha2-256-cert-...@openssh.com': 
4096, 'rsa-sha2-512-cert-...@openssh.com': 4096}, 'dh_modulus_sizes': 
{'diffie-hellman-group-exch
 ange-sha256': 2048}, 'server_policy': True},
 
@@ -67,6 +67,10 @@
 
         'Hardened OpenSSH Server v8.5 (version 1)': {'version': '1', 'banner': 
None, 'compressions': None, 'host_keys': ['rsa-sha2-512', 'rsa-sha2-256', 
'ssh-ed25519'], 'optional_host_keys': ['sk-ssh-ed25...@openssh.com', 
'ssh-ed25519-cert-...@openssh.com', 'sk-ssh-ed25519-cert-...@openssh.com', 
'rsa-sha2-256-cert-...@openssh.com', 'rsa-sha2-512-cert-...@openssh.com'], 
'kex': ['curve25519-sha256', 'curve25519-sha...@libssh.org', 
'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 
'diffie-hellman-group-exchange-sha256'], 'ciphers': 
['chacha20-poly1...@openssh.com', 'aes256-...@openssh.com', 
'aes128-...@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': 
['hmac-sha2-256-...@openssh.com', 'hmac-sha2-512-...@openssh.com', 
'umac-128-...@openssh.com'], 'hostkey_sizes': {'rsa-sha2-256': 4096, 
'rsa-sha2-512': 4096}, 'cakey_sizes': {'rsa-sha2-256-cert-...@openssh.com': 
4096, 'rsa-sha2-512-cert-...@openssh.com': 4096}, 'dh_modulus_sizes': 
{'diffie-hellman-group-exch
 ange-sha256': 2048}, 'server_policy': True},
 
+        'Hardened OpenSSH Server v8.6 (version 1)': {'version': '1', 'banner': 
None, 'compressions': None, 'host_keys': ['rsa-sha2-512', 'rsa-sha2-256', 
'ssh-ed25519'], 'optional_host_keys': ['sk-ssh-ed25...@openssh.com', 
'ssh-ed25519-cert-...@openssh.com', 'sk-ssh-ed25519-cert-...@openssh.com', 
'rsa-sha2-256-cert-...@openssh.com', 'rsa-sha2-512-cert-...@openssh.com'], 
'kex': ['curve25519-sha256', 'curve25519-sha...@libssh.org', 
'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 
'diffie-hellman-group-exchange-sha256'], 'ciphers': 
['chacha20-poly1...@openssh.com', 'aes256-...@openssh.com', 
'aes128-...@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': 
['hmac-sha2-256-...@openssh.com', 'hmac-sha2-512-...@openssh.com', 
'umac-128-...@openssh.com'], 'hostkey_sizes': {'rsa-sha2-256': 4096, 
'rsa-sha2-512': 4096}, 'cakey_sizes': {'rsa-sha2-256-cert-...@openssh.com': 
4096, 'rsa-sha2-512-cert-...@openssh.com': 4096}, 'dh_modulus_sizes': 
{'diffie-hellman-group-exch
 ange-sha256': 2048}, 'server_policy': True},
+
+        'Hardened OpenSSH Server v8.7 (version 1)': {'version': '1', 'banner': 
None, 'compressions': None, 'host_keys': ['rsa-sha2-512', 'rsa-sha2-256', 
'ssh-ed25519'], 'optional_host_keys': ['sk-ssh-ed25...@openssh.com', 
'ssh-ed25519-cert-...@openssh.com', 'sk-ssh-ed25519-cert-...@openssh.com', 
'rsa-sha2-256-cert-...@openssh.com', 'rsa-sha2-512-cert-...@openssh.com'], 
'kex': ['curve25519-sha256', 'curve25519-sha...@libssh.org', 
'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 
'diffie-hellman-group-exchange-sha256'], 'ciphers': 
['chacha20-poly1...@openssh.com', 'aes256-...@openssh.com', 
'aes128-...@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': 
['hmac-sha2-256-...@openssh.com', 'hmac-sha2-512-...@openssh.com', 
'umac-128-...@openssh.com'], 'hostkey_sizes': {'rsa-sha2-256': 4096, 
'rsa-sha2-512': 4096}, 'cakey_sizes': {'rsa-sha2-256-cert-...@openssh.com': 
4096, 'rsa-sha2-512-cert-...@openssh.com': 4096}, 'dh_modulus_sizes': 
{'diffie-hellman-group-exch
 ange-sha256': 2048}, 'server_policy': True},
+
 
         # Ubuntu Client policies
 
@@ -113,7 +117,7 @@
 
         if policy_file is not None:
             try:
-                with open(policy_file, "r") as f:
+                with open(policy_file, "r", encoding='utf-8') as f:
                     policy_data = f.read()
             except FileNotFoundError:
                 print("Error: policy file not found: %s" % policy_file)
@@ -421,8 +425,8 @@
         server_policy_names = []
         client_policy_names = []
 
-        for policy_name in Policy.BUILTIN_POLICIES:
-            if Policy.BUILTIN_POLICIES[policy_name]['server_policy']:
+        for policy_name, policy in Policy.BUILTIN_POLICIES.items():
+            if policy['server_policy']:
                 server_policy_names.append(policy_name)
             else:
                 client_policy_names.append(policy_name)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ssh-audit-2.4.0/src/ssh_audit/ssh1_publickeymessage.py 
new/ssh-audit-2.5.0/src/ssh_audit/ssh1_publickeymessage.py
--- old/ssh-audit-2.4.0/src/ssh_audit/ssh1_publickeymessage.py  2021-02-24 
02:39:18.000000000 +0100
+++ new/ssh-audit-2.5.0/src/ssh_audit/ssh1_publickeymessage.py  2021-08-26 
21:24:34.000000000 +0200
@@ -90,7 +90,7 @@
     @property
     def supported_ciphers(self) -> List[str]:
         ciphers = []
-        for i in range(len(SSH1.CIPHERS)):
+        for i in range(len(SSH1.CIPHERS)):  # pylint: 
disable=consider-using-enumerate
             if self.__supported_ciphers_mask & (1 << i) != 0:
                 ciphers.append(Utils.to_text(SSH1.CIPHERS[i]))
         return ciphers
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ssh-audit-2.4.0/src/ssh_audit/ssh2_kexdb.py 
new/ssh-audit-2.5.0/src/ssh_audit/ssh2_kexdb.py
--- old/ssh-audit-2.4.0/src/ssh_audit/ssh2_kexdb.py     2021-02-24 
02:39:18.000000000 +0100
+++ new/ssh-audit-2.5.0/src/ssh_audit/ssh2_kexdb.py     2021-08-26 
21:24:34.000000000 +0200
@@ -1,7 +1,7 @@
 """
    The MIT License (MIT)
 
-   Copyright (C) 2017-2020 Joe Testa (jte...@positronsecurity.com)
+   Copyright (C) 2017-2021 Joe Testa (jte...@positronsecurity.com)
    Copyright (C) 2017 Andris Raugulis (m...@arthepsy.eu)
 
    Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -66,10 +66,13 @@
         'kex': {
             'diffie-hellman-group1-sha1': [['2.3.0,d0.28,l10.2', '6.6', 
'6.9'], [FAIL_1024BIT_MODULUS, FAIL_OPENSSH67_UNSAFE, FAIL_OPENSSH70_LOGJAM], 
[WARN_HASH_WEAK]],
             'gss-group1-sha1-toWM5Slw5Ew8Mqkay+al2g==': [[], 
[FAIL_1024BIT_MODULUS, FAIL_OPENSSH67_UNSAFE, FAIL_OPENSSH70_LOGJAM], 
[WARN_HASH_WEAK]],
+            'gss-gex-sha1-eipGX3TCiQSrx573bT1o1Q==': [[], [], 
[WARN_HASH_WEAK]],
             'gss-gex-sha1-toWM5Slw5Ew8Mqkay+al2g==': [[], [], 
[WARN_HASH_WEAK]],
             'gss-gex-sha1-': [[], [], [WARN_HASH_WEAK]],
+            'gss-group1-sha1-eipGX3TCiQSrx573bT1o1Q==': [[], 
[FAIL_1024BIT_MODULUS], [WARN_HASH_WEAK]],
             'gss-group1-sha1-': [[], [FAIL_1024BIT_MODULUS], [WARN_HASH_WEAK]],
             'gss-group14-sha1-': [[], [], [WARN_HASH_WEAK]],
+            'gss-group14-sha1-eipGX3TCiQSrx573bT1o1Q==': [[], [], 
[WARN_HASH_WEAK]],
             'gss-group14-sha1-toWM5Slw5Ew8Mqkay+al2g==': [[], [], 
[WARN_HASH_WEAK]],
             'gss-group14-sha256-': [[]],
             'gss-group14-sha256-toWM5Slw5Ew8Mqkay+al2g==': [[]],
@@ -250,6 +253,7 @@
             'hmac-md5-96': [['2.5.0', '6.6', '7.1'], [FAIL_OPENSSH67_UNSAFE], 
[WARN_OPENSSH72_LEGACY, WARN_ENCRYPT_AND_MAC, WARN_HASH_WEAK]],
             'hmac-ripemd': [[], [FAIL_DEPRECATED_MAC], [WARN_OPENSSH72_LEGACY, 
WARN_ENCRYPT_AND_MAC]],
             'hmac-ripemd160': [['2.5.0', '6.6', '7.1'], 
[FAIL_OPENSSH67_UNSAFE], [WARN_OPENSSH72_LEGACY, WARN_ENCRYPT_AND_MAC]],
+            'hmac-ripemd160-96': [[], [FAIL_DEPRECATED_MAC], 
[WARN_ENCRYPT_AND_MAC, WARN_TAG_SIZE]],
             'hmac-ripemd...@openssh.com': [['2.1.0', '6.6', '7.1'], 
[FAIL_OPENSSH67_UNSAFE], [WARN_OPENSSH72_LEGACY, WARN_ENCRYPT_AND_MAC]],
             'umac...@openssh.com': [['4.7'], [], [WARN_ENCRYPT_AND_MAC, 
WARN_TAG_SIZE]],
             'umac-...@openssh.com': [['6.2'], [], [WARN_ENCRYPT_AND_MAC]],
@@ -270,5 +274,7 @@
             'aes256-gcm': [[]],
             'chacha20-poly1...@openssh.com': [[]],  # Despite the @openssh.com 
tag, this was never shipped as a MAC in OpenSSH (only as a cipher); it is only 
implemented as a MAC in Syncplify.
             'crypticore-...@ssh.com': [[], [FAIL_UNPROVEN]],
+            'AEAD_AES_128_GCM': [[]],
+            'AEAD_AES_256_GCM': [[]],
         }
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ssh-audit-2.4.0/src/ssh_audit/ssh_audit.py 
new/ssh-audit-2.5.0/src/ssh_audit/ssh_audit.py
--- old/ssh-audit-2.4.0/src/ssh_audit/ssh_audit.py      2021-02-24 
02:39:18.000000000 +0100
+++ new/ssh-audit-2.5.0/src/ssh_audit/ssh_audit.py      2021-08-26 
21:24:34.000000000 +0200
@@ -84,7 +84,8 @@
     uout.info('   -6,  --ipv6             enable IPv6 (order of precedence)')
     uout.info('   -b,  --batch            batch output')
     uout.info('   -c,  --client-audit     starts a server on port 2222 to 
audit client\n                               software config (use -p to change 
port;\n                               use -t to change timeout)')
-    uout.info('   -j,  --json             JSON output')
+    uout.info('   -d,  --debug            debug output')
+    uout.info('   -j,  --json             JSON output (use -jj to enable 
indents)')
     uout.info('   -l,  --level=<level>    minimum output level 
(info|warn|fail)')
     uout.info('   -L,  --list-policies    list all the official, built-in 
policies')
     uout.info('        --lookup=<alg1,alg2,...>    looks up an algorithm(s) 
without\n                                    connecting to a server')
@@ -263,7 +264,7 @@
         out.sep()
 
 
-def output_fingerprints(out: OutputBuffer, algs: Algorithms, is_json_output: 
bool, sha256: bool = True) -> None:
+def output_fingerprints(out: OutputBuffer, algs: Algorithms, is_json_output: 
bool) -> None:
     with out:
         fps = []
         if algs.ssh1kex is not None:
@@ -290,10 +291,12 @@
         fps = sorted(fps)
         for fpp in fps:
             name, fp = fpp
-            fpo = fp.sha256 if sha256 else fp.md5
-            # p = '' if out.batch else ' ' * (padlen - len(name))
-            # out.good('(fin) {0}{1} -- {2} {3}'.format(name, p, bits, fpo))
-            out.good('(fin) {}: {}'.format(name, fpo))
+            out.good('(fin) {}: {}'.format(name, fp.sha256))
+
+            # Output the MD5 hash too if verbose mode is enabled.
+            if out.verbose:
+                out.info('(fin) {}: {} -- [info] do not rely on MD5 
fingerprints for server identification; it is insecure for this use 
case'.format(name, fp.md5))
+
     if not out.is_section_empty() and not is_json_output:
         out.head('# fingerprints')
         out.flush_section()
@@ -467,14 +470,14 @@
         program_retval = output_algorithms(out, title, adb, atype, 
kex.server.encryption, unknown_algorithms, aconf.json, program_retval, maxlen)
         title, atype = 'message authentication code algorithms', 'mac'
         program_retval = output_algorithms(out, title, adb, atype, 
kex.server.mac, unknown_algorithms, aconf.json, program_retval, maxlen)
-    output_fingerprints(out, algs, aconf.json, True)
+    output_fingerprints(out, algs, aconf.json)
     perfect_config = output_recommendations(out, algs, software, aconf.json, 
maxlen)
     output_info(out, software, client_audit, not perfect_config, aconf.json)
 
     if aconf.json:
         out.reset()
         # Build & write the JSON struct.
-        out.info(json.dumps(build_struct(aconf.host, banner, kex=kex, 
client_host=client_host), sort_keys=True))
+        out.info(json.dumps(build_struct(aconf.host, banner, kex=kex, 
client_host=client_host), indent=4 if aconf.json_print_indent else None, 
sort_keys=True))
     elif len(unknown_algorithms) > 0:  # If we encountered any unknown 
algorithms, ask the user to report them.
         out.warn("\n\n!!! WARNING: unknown algorithm(s) found!: %s.  Please 
email the full output above to the maintainer (jte...@positronsecurity.com), or 
create a Github issue at <https://github.com/jtesta/ssh-audit/issues>.\n" % 
','.join(unknown_algorithms))
 
@@ -489,7 +492,7 @@
     passed, error_struct, error_str = aconf.policy.evaluate(banner, kex)
     if aconf.json:
         json_struct = {'host': aconf.host, 'policy': 
aconf.policy.get_name_and_version(), 'passed': passed, 'errors': error_struct}
-        out.info(json.dumps(json_struct, sort_keys=True))
+        out.info(json.dumps(json_struct, indent=4 if aconf.json_print_indent 
else None, sort_keys=True))
     else:
         spacing = ''
         if aconf.client_audit:
@@ -560,7 +563,7 @@
     # Open with mode 'x' (creates the file, or fails if it already exist).
     succeeded = True
     try:
-        with open(aconf.policy_file, 'x') as f:
+        with open(aconf.policy_file, 'x', encoding='utf-8') as f:
             f.write(policy_data)
     except FileExistsError:
         succeeded = False
@@ -575,8 +578,8 @@
     # pylint: disable=too-many-branches
     aconf = AuditConf()
     try:
-        sopts = 'h1246M:p:P:jbcnvl:t:T:Lm'
-        lopts = ['help', 'ssh1', 'ssh2', 'ipv4', 'ipv6', 'make-policy=', 
'port=', 'policy=', 'json', 'batch', 'client-audit', 'no-colors', 'verbose', 
'level=', 'timeout=', 'targets=', 'list-policies', 'lookup=', 'threads=', 
'manual']
+        sopts = 'h1246M:p:P:jbcnvl:t:T:Lmd'
+        lopts = ['help', 'ssh1', 'ssh2', 'ipv4', 'ipv6', 'make-policy=', 
'port=', 'policy=', 'json', 'batch', 'client-audit', 'no-colors', 'verbose', 
'level=', 'timeout=', 'targets=', 'list-policies', 'lookup=', 'threads=', 
'manual', 'debug']
         opts, args = getopt.gnu_getopt(args, sopts, lopts)
     except getopt.GetoptError as err:
         usage_cb(str(err))
@@ -606,7 +609,10 @@
             aconf.colors = False
             out.use_colors = False
         elif o in ('-j', '--json'):
-            aconf.json = True
+            if aconf.json:  # If specified twice, enable indent printing.
+                aconf.json_print_indent = True
+            else:
+                aconf.json = True
         elif o in ('-v', '--verbose'):
             aconf.verbose = True
             out.verbose = True
@@ -632,6 +638,9 @@
             aconf.lookup = a
         elif o in ('-m', '--manual'):
             aconf.manual = True
+        elif o in ('-d', '--debug'):
+            aconf.debug = True
+            out.debug = True
 
     if len(args) == 0 and aconf.client_audit is False and aconf.target_file is 
None and aconf.list_policies is False and aconf.lookup == '' and aconf.manual 
is False:
         usage_cb()
@@ -672,7 +681,7 @@
 
     # If a file containing a list of targets was given, read it.
     if aconf.target_file is not None:
-        with open(aconf.target_file, 'r') as f:
+        with open(aconf.target_file, 'r', encoding='utf-8') as f:
             aconf.target_list = f.readlines()
 
         # Strip out whitespace from each line in target file, and skip empty 
lines.
@@ -783,11 +792,18 @@
             # Skip over certificate host types (or we would return invalid 
fingerprints).
             if '-cert-' in host_key_type:
                 continue
-            entry = {
-                'type': host_key_type,
-                'fp': fp.sha256,
-            }
-            res['fingerprints'].append(entry)
+
+            # Add the SHA256 and MD5 fingerprints.
+            res['fingerprints'].append({
+                'hostkey': host_key_type,
+                'hash_alg': 'SHA256',
+                'hash': fp.sha256[7:]
+            })
+            res['fingerprints'].append({
+                'hostkey': host_key_type,
+                'hash_alg': 'MD5',
+                'hash': fp.md5[4:]
+            })
     else:
         pkm_supported_ciphers = None
         pkm_supported_authentications = None
@@ -813,15 +829,18 @@
     program_retval = exitcodes.GOOD
     out.batch = aconf.batch
     out.verbose = aconf.verbose
+    out.debug = aconf.debug
     out.level = aconf.level
     out.use_colors = aconf.colors
-    s = SSH_Socket(aconf.host, aconf.port, aconf.ip_version_preference, 
aconf.timeout, aconf.timeout_set)
+    s = SSH_Socket(out, aconf.host, aconf.port, aconf.ip_version_preference, 
aconf.timeout, aconf.timeout_set)
+
     if aconf.client_audit:
         out.v("Listening for client connection on port %d..." % aconf.port, 
write_now=True)
         s.listen_and_accept()
     else:
-        out.v("Connecting to %s:%d..." % ('[%s]' % aconf.host if 
Utils.is_ipv6_address(aconf.host) else aconf.host, aconf.port), write_now=True)
+        out.v("Starting audit of %s:%d..." % ('[%s]' % aconf.host if 
Utils.is_ipv6_address(aconf.host) else aconf.host, aconf.port), write_now=True)
         err = s.connect()
+
         if err is not None:
             out.fail(err)
 
@@ -850,10 +869,10 @@
                 if len(payload) > 0:
                     payload_txt = payload.decode('utf-8')
                 else:
-                    payload_txt = u'empty'
+                    payload_txt = 'empty'
             except UnicodeDecodeError:
-                payload_txt = u'"{}"'.format(repr(payload).lstrip('b')[1:-1])
-            if payload_txt == u'Protocol major versions differ.':
+                payload_txt = '"{}"'.format(repr(payload).lstrip('b')[1:-1])
+            if payload_txt == 'Protocol major versions differ.':
                 if sshv == 2 and aconf.ssh1:
                     ret = audit(out, aconf, 1)
                     out.write()
@@ -876,10 +895,15 @@
     if sshv == 1:
         program_retval = output(out, aconf, banner, header, 
pkm=SSH1_PublicKeyMessage.parse(payload))
     elif sshv == 2:
-        kex = SSH2_Kex.parse(payload)
+        try:
+            kex = SSH2_Kex.parse(payload)
+        except Exception:
+            out.fail("Failed to parse server's kex.  Stack trace:\n%s" % 
str(traceback.format_exc()))
+            return exitcodes.CONNECTION_ERROR
+
         if aconf.client_audit is False:
-            HostKeyTest.run(s, kex)
-            GEXTest.run(s, kex)
+            HostKeyTest.run(out, s, kex)
+            GEXTest.run(out, s, kex)
 
         # This is a standard audit scan.
         if (aconf.policy is None) and (aconf.make_policy is False):
@@ -948,8 +972,8 @@
     similar_algorithms = [
         alg_unknown + " --> (" + alg_type + ") " + alg_name
         for alg_unknown in algorithms_not_found
-        for alg_type in adb
-        for alg_name in adb[alg_type]
+        for alg_type, alg_names in adb.items()
+        for alg_name in alg_names
         # Perform a case-insensitive comparison using 'casefold'
         # and match substrings using the 'in' operator.
         if alg_unknown.casefold() in alg_name.casefold()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ssh-audit-2.4.0/src/ssh_audit/ssh_socket.py 
new/ssh-audit-2.5.0/src/ssh_audit/ssh_socket.py
--- old/ssh-audit-2.4.0/src/ssh_audit/ssh_socket.py     2021-02-24 
02:39:18.000000000 +0100
+++ new/ssh-audit-2.5.0/src/ssh_audit/ssh_socket.py     2021-08-26 
21:24:34.000000000 +0200
@@ -52,8 +52,9 @@
 
     SM_BANNER_SENT = 1
 
-    def __init__(self, host: Optional[str], port: int, ip_version_preference: 
List[int] = [], timeout: Union[int, float] = 5, timeout_set: bool = False) -> 
None:  # pylint: disable=dangerous-default-value
+    def __init__(self, outputbuffer: 'OutputBuffer', host: Optional[str], 
port: int, ip_version_preference: List[int] = [], timeout: Union[int, float] = 
5, timeout_set: bool = False) -> None:  # pylint: 
disable=dangerous-default-value
         super(SSH_Socket, self).__init__()
+        self.__outputbuffer = outputbuffer
         self.__sock: Optional[socket.socket] = None
         self.__sock_map: Dict[int, socket.socket] = {}
         self.__block_size = 8
@@ -90,7 +91,7 @@
                 if socktype == socket.SOCK_STREAM:
                     yield af, addr
         except socket.error as e:
-            OutputBuffer().fail('[exception] {}'.format(e)).write()
+            self.__outputbuffer.fail('[exception] {}'.format(e)).write()
             sys.exit(exitcodes.CONNECTION_ERROR)
 
     # Listens on a server socket and accepts one connection (used for
@@ -156,6 +157,7 @@
             try:
                 s = socket.socket(af, socket.SOCK_STREAM)
                 s.settimeout(self.__timeout)
+                self.__outputbuffer.d(("Connecting to %s:%d..." % ('[%s]' % 
addr[0] if Utils.is_ipv6_address(addr[0]) else addr[0], addr[1])), 
write_now=True)
                 s.connect(addr)
                 self.__sock = s
                 return None
@@ -170,6 +172,8 @@
         return '[exception] {}'.format(errm)
 
     def get_banner(self, sshv: int = 2) -> Tuple[Optional['Banner'], 
List[str], Optional[str]]:
+        self.__outputbuffer.d('Getting banner...', write_now=True)
+
         if self.__sock is None:
             return self.__banner, self.__header, 'not connected'
         if self.__banner is not None:
@@ -229,6 +233,8 @@
     def send_kexinit(self, key_exchanges: List[str] = ['curve25519-sha256', 
'curve25519-sha...@libssh.org', 'ecdh-sha2-nistp256', 'ecdh-sha2-nistp384', 
'ecdh-sha2-nistp521', 'diffie-hellman-group-exchange-sha256', 
'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 
'diffie-hellman-group14-sha256'], hostkeys: List[str] = ['rsa-sha2-512', 
'rsa-sha2-256', 'ssh-rsa', 'ecdsa-sha2-nistp256', 'ssh-ed25519'], ciphers: 
List[str] = ['chacha20-poly1...@openssh.com', 'aes128-ctr', 'aes192-ctr', 
'aes256-ctr', 'aes128-...@openssh.com', 'aes256-...@openssh.com'], macs: 
List[str] = ['umac-64-...@openssh.com', 'umac-128-...@openssh.com', 
'hmac-sha2-256-...@openssh.com', 'hmac-sha2-512-...@openssh.com', 
'hmac-sha1-...@openssh.com', 'umac...@openssh.com', 'umac-...@openssh.com', 
'hmac-sha2-256', 'hmac-sha2-512', 'hmac-sha1'], compressions: List[str] = 
['none', 'z...@openssh.com'], languages: List[str] = ['']) -> None:  # pylint: 
disable=dangerous-default-value
         '''Sends the list of supported host keys, key exchanges, ciphers, and 
MACs.  Emulates OpenSSH v8.2.'''
 
+        self.__outputbuffer.d('KEX initialisation...', write_now=True)
+
         kexparty = SSH2_KexParty(ciphers, macs, compressions, languages)
         kex = SSH2_Kex(os.urandom(16), key_exchanges, hostkeys, kexparty, 
kexparty, False, 0)
 
@@ -268,7 +274,7 @@
                 payload_length = packet_length - padding_length - 1
                 check_size = 4 + 1 + payload_length + padding_length
             if check_size % self.__block_size != 0:
-                OutputBuffer().fail('[exception] invalid ssh packet (block 
size)').write()
+                self.__outputbuffer.fail('[exception] invalid ssh packet 
(block size)').write()
                 sys.exit(exitcodes.CONNECTION_ERROR)
             self.ensure_read(payload_length)
             if sshv == 1:
@@ -283,7 +289,7 @@
             if sshv == 1:
                 rcrc = SSH1.crc32(padding + payload)
                 if crc != rcrc:
-                    OutputBuffer().fail('[exception] packet checksum CRC32 
mismatch.').write()
+                    self.__outputbuffer.fail('[exception] packet checksum 
CRC32 mismatch.').write()
                     sys.exit(exitcodes.CONNECTION_ERROR)
             else:
                 self.ensure_read(padding_length)
@@ -332,6 +338,6 @@
 
     def __cleanup(self) -> None:
         self._close_socket(self.__sock)
-        for fd in self.__sock_map:
-            self._close_socket(self.__sock_map[fd])
+        for sock in self.__sock_map.values():
+            self._close_socket(sock)
         self.__sock = None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ssh-audit-2.4.0/src/ssh_audit/writebuf.py 
new/ssh-audit-2.5.0/src/ssh_audit/writebuf.py
--- old/ssh-audit-2.4.0/src/ssh_audit/writebuf.py       2021-02-24 
02:39:18.000000000 +0100
+++ new/ssh-audit-2.5.0/src/ssh_audit/writebuf.py       2021-08-26 
21:24:34.000000000 +0200
@@ -54,7 +54,7 @@
         return self.write(v)
 
     def write_list(self, v: List[str]) -> 'WriteBuf':
-        return self.write_string(u','.join(v))
+        return self.write_string(','.join(v))
 
     @classmethod
     def _bitlength(cls, n: int) -> int:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ssh-audit-2.4.0/ssh-audit.1 
new/ssh-audit-2.5.0/ssh-audit.1
--- old/ssh-audit-2.4.0/ssh-audit.1     2021-02-24 02:39:18.000000000 +0100
+++ new/ssh-audit-2.5.0/ssh-audit.1     2021-08-26 21:24:34.000000000 +0200
@@ -1,4 +1,4 @@
-.TH SSH-AUDIT 1 "February 7, 2021"
+.TH SSH-AUDIT 1 "March 2, 2021"
 .SH NAME
 \fBssh-audit\fP \- SSH server & client configuration auditor
 .SH SYNOPSIS
@@ -47,9 +47,14 @@
 Starts a server on port 2222 to audit client software configuration.  Use 
-p/--port=<port> to change port and -t/--timeout=<secs> to change listen 
timeout.
 
 .TP
+.B -d, \-\-debug
+.br
+Enable debug output.
+
+.TP
 .B -j, \-\-json
 .br
-Output results in JSON format.
+Output results in JSON format.  Specify twice (-jj) to enable indent printing 
(useful for debugging).
 
 .TP
 .B -l, \-\-level=<info|warn|fail>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ssh-audit-2.4.0/test/docker/expected_results/dropbear_2019.78_test1.json 
new/ssh-audit-2.5.0/test/docker/expected_results/dropbear_2019.78_test1.json
--- 
old/ssh-audit-2.4.0/test/docker/expected_results/dropbear_2019.78_test1.json    
    2021-02-24 02:39:18.000000000 +0100
+++ 
new/ssh-audit-2.5.0/test/docker/expected_results/dropbear_2019.78_test1.json    
    2021-08-26 21:24:34.000000000 +0200
@@ -1 +1 @@
-{"banner": {"comments": null, "protocol": [2, 0], "raw": 
"SSH-2.0-dropbear_2019.78", "software": "dropbear_2019.78"}, "compression": 
["z...@openssh.com", "none"], "enc": ["aes128-ctr", "aes256-ctr", "aes128-cbc", 
"aes256-cbc", "3des-ctr", "3des-cbc"], "fingerprints": [{"fp": 
"SHA256:CDfAU12pjQS7/91kg7gYacza0U/6PDbE04Ic3IpYxkM", "type": "ssh-rsa"}], 
"kex": [{"algorithm": "curve25519-sha256"}, {"algorithm": 
"curve25519-sha...@libssh.org"}, {"algorithm": "ecdh-sha2-nistp521"}, 
{"algorithm": "ecdh-sha2-nistp384"}, {"algorithm": "ecdh-sha2-nistp256"}, 
{"algorithm": "diffie-hellman-group14-sha256"}, {"algorithm": 
"diffie-hellman-group14-sha1"}, {"algorithm": "kexgue...@matt.ucc.asn.au"}], 
"key": [{"algorithm": "ecdsa-sha2-nistp256"}, {"algorithm": "ssh-rsa", 
"keysize": 1024}, {"algorithm": "ssh-dss"}], "mac": ["hmac-sha1-96", 
"hmac-sha1", "hmac-sha2-256"], "target": "localhost"}
+{"banner": {"comments": null, "protocol": [2, 0], "raw": 
"SSH-2.0-dropbear_2019.78", "software": "dropbear_2019.78"}, "compression": 
["z...@openssh.com", "none"], "enc": ["aes128-ctr", "aes256-ctr", "aes128-cbc", 
"aes256-cbc", "3des-ctr", "3des-cbc"], "fingerprints": [{"hash": 
"CDfAU12pjQS7/91kg7gYacza0U/6PDbE04Ic3IpYxkM", "hash_alg": "SHA256", "hostkey": 
"ssh-rsa"}, {"hash": "63:7f:54:f7:0a:28:7f:75:0b:f4:07:0b:fc:66:51:a2", 
"hash_alg": "MD5", "hostkey": "ssh-rsa"}], "kex": [{"algorithm": 
"curve25519-sha256"}, {"algorithm": "curve25519-sha...@libssh.org"}, 
{"algorithm": "ecdh-sha2-nistp521"}, {"algorithm": "ecdh-sha2-nistp384"}, 
{"algorithm": "ecdh-sha2-nistp256"}, {"algorithm": 
"diffie-hellman-group14-sha256"}, {"algorithm": "diffie-hellman-group14-sha1"}, 
{"algorithm": "kexgue...@matt.ucc.asn.au"}], "key": [{"algorithm": 
"ecdsa-sha2-nistp256"}, {"algorithm": "ssh-rsa", "keysize": 1024}, 
{"algorithm": "ssh-dss"}], "mac": ["hmac-sha1-96", "hmac-sha1", 
"hmac-sha2-256"], "target": "l
 ocalhost"}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ssh-audit-2.4.0/test/docker/expected_results/openssh_4.0p1_test1.json 
new/ssh-audit-2.5.0/test/docker/expected_results/openssh_4.0p1_test1.json
--- old/ssh-audit-2.4.0/test/docker/expected_results/openssh_4.0p1_test1.json   
2021-02-24 02:39:18.000000000 +0100
+++ new/ssh-audit-2.5.0/test/docker/expected_results/openssh_4.0p1_test1.json   
2021-08-26 21:24:34.000000000 +0200
@@ -1 +1 @@
-{"banner": {"comments": null, "protocol": [1, 99], "raw": 
"SSH-1.99-OpenSSH_4.0", "software": "OpenSSH_4.0"}, "compression": ["none", 
"zlib"], "enc": ["aes128-cbc", "3des-cbc", "blowfish-cbc", "cast128-cbc", 
"arcfour", "aes192-cbc", "aes256-cbc", "rijndael-...@lysator.liu.se", 
"aes128-ctr", "aes192-ctr", "aes256-ctr"], "fingerprints": [{"fp": 
"SHA256:YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4", "type": "ssh-rsa"}], 
"kex": [{"algorithm": "diffie-hellman-group-exchange-sha1", "keysize": 1024}, 
{"algorithm": "diffie-hellman-group14-sha1"}, {"algorithm": 
"diffie-hellman-group1-sha1"}], "key": [{"algorithm": "ssh-rsa", "keysize": 
1024}, {"algorithm": "ssh-dss"}], "mac": ["hmac-md5", "hmac-sha1", 
"hmac-ripemd160", "hmac-ripemd...@openssh.com", "hmac-sha1-96", "hmac-md5-96"], 
"target": "localhost"}
+{"banner": {"comments": null, "protocol": [1, 99], "raw": 
"SSH-1.99-OpenSSH_4.0", "software": "OpenSSH_4.0"}, "compression": ["none", 
"zlib"], "enc": ["aes128-cbc", "3des-cbc", "blowfish-cbc", "cast128-cbc", 
"arcfour", "aes192-cbc", "aes256-cbc", "rijndael-...@lysator.liu.se", 
"aes128-ctr", "aes192-ctr", "aes256-ctr"], "fingerprints": [{"hash": 
"YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4", "hash_alg": "SHA256", "hostkey": 
"ssh-rsa"}, {"hash": "3c:c3:38:f8:55:39:c0:4a:5a:17:89:60:2c:a1:fc:6a", 
"hash_alg": "MD5", "hostkey": "ssh-rsa"}], "kex": [{"algorithm": 
"diffie-hellman-group-exchange-sha1", "keysize": 1024}, {"algorithm": 
"diffie-hellman-group14-sha1"}, {"algorithm": "diffie-hellman-group1-sha1"}], 
"key": [{"algorithm": "ssh-rsa", "keysize": 1024}, {"algorithm": "ssh-dss"}], 
"mac": ["hmac-md5", "hmac-sha1", "hmac-ripemd160", 
"hmac-ripemd...@openssh.com", "hmac-sha1-96", "hmac-md5-96"], "target": 
"localhost"}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ssh-audit-2.4.0/test/docker/expected_results/openssh_5.6p1_test1.json 
new/ssh-audit-2.5.0/test/docker/expected_results/openssh_5.6p1_test1.json
--- old/ssh-audit-2.4.0/test/docker/expected_results/openssh_5.6p1_test1.json   
2021-02-24 02:39:18.000000000 +0100
+++ new/ssh-audit-2.5.0/test/docker/expected_results/openssh_5.6p1_test1.json   
2021-08-26 21:24:34.000000000 +0200
@@ -1 +1 @@
-{"banner": {"comments": null, "protocol": [2, 0], "raw": 
"SSH-2.0-OpenSSH_5.6", "software": "OpenSSH_5.6"}, "compression": ["none", 
"z...@openssh.com"], "enc": ["aes128-ctr", "aes192-ctr", "aes256-ctr", 
"arcfour256", "arcfour128", "aes128-cbc", "3des-cbc", "blowfish-cbc", 
"cast128-cbc", "aes192-cbc", "aes256-cbc", "arcfour", 
"rijndael-...@lysator.liu.se"], "fingerprints": [{"fp": 
"SHA256:YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4", "type": "ssh-rsa"}], 
"kex": [{"algorithm": "diffie-hellman-group-exchange-sha256", "keysize": 1024}, 
{"algorithm": "diffie-hellman-group-exchange-sha1", "keysize": 1024}, 
{"algorithm": "diffie-hellman-group14-sha1"}, {"algorithm": 
"diffie-hellman-group1-sha1"}], "key": [{"algorithm": "ssh-rsa", "keysize": 
1024}, {"algorithm": "ssh-dss"}], "mac": ["hmac-md5", "hmac-sha1", 
"umac...@openssh.com", "hmac-ripemd160", "hmac-ripemd...@openssh.com", 
"hmac-sha1-96", "hmac-md5-96"], "target": "localhost"}
+{"banner": {"comments": null, "protocol": [2, 0], "raw": 
"SSH-2.0-OpenSSH_5.6", "software": "OpenSSH_5.6"}, "compression": ["none", 
"z...@openssh.com"], "enc": ["aes128-ctr", "aes192-ctr", "aes256-ctr", 
"arcfour256", "arcfour128", "aes128-cbc", "3des-cbc", "blowfish-cbc", 
"cast128-cbc", "aes192-cbc", "aes256-cbc", "arcfour", 
"rijndael-...@lysator.liu.se"], "fingerprints": [{"hash": 
"YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4", "hash_alg": "SHA256", "hostkey": 
"ssh-rsa"}, {"hash": "3c:c3:38:f8:55:39:c0:4a:5a:17:89:60:2c:a1:fc:6a", 
"hash_alg": "MD5", "hostkey": "ssh-rsa"}], "kex": [{"algorithm": 
"diffie-hellman-group-exchange-sha256", "keysize": 1024}, {"algorithm": 
"diffie-hellman-group-exchange-sha1", "keysize": 1024}, {"algorithm": 
"diffie-hellman-group14-sha1"}, {"algorithm": "diffie-hellman-group1-sha1"}], 
"key": [{"algorithm": "ssh-rsa", "keysize": 1024}, {"algorithm": "ssh-dss"}], 
"mac": ["hmac-md5", "hmac-sha1", "umac...@openssh.com", "hmac-ripemd160", 
"hmac-ripemd160@openssh
 .com", "hmac-sha1-96", "hmac-md5-96"], "target": "localhost"}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ssh-audit-2.4.0/test/docker/expected_results/openssh_5.6p1_test2.json 
new/ssh-audit-2.5.0/test/docker/expected_results/openssh_5.6p1_test2.json
--- old/ssh-audit-2.4.0/test/docker/expected_results/openssh_5.6p1_test2.json   
2021-02-24 02:39:18.000000000 +0100
+++ new/ssh-audit-2.5.0/test/docker/expected_results/openssh_5.6p1_test2.json   
2021-08-26 21:24:34.000000000 +0200
@@ -1 +1 @@
-{"banner": {"comments": null, "protocol": [2, 0], "raw": 
"SSH-2.0-OpenSSH_5.6", "software": "OpenSSH_5.6"}, "compression": ["none", 
"z...@openssh.com"], "enc": ["aes128-ctr", "aes192-ctr", "aes256-ctr", 
"arcfour256", "arcfour128", "aes128-cbc", "3des-cbc", "blowfish-cbc", 
"cast128-cbc", "aes192-cbc", "aes256-cbc", "arcfour", 
"rijndael-...@lysator.liu.se"], "fingerprints": [{"fp": 
"SHA256:YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4", "type": "ssh-rsa"}], 
"kex": [{"algorithm": "diffie-hellman-group-exchange-sha256", "keysize": 1024}, 
{"algorithm": "diffie-hellman-group-exchange-sha1", "keysize": 1024}, 
{"algorithm": "diffie-hellman-group14-sha1"}, {"algorithm": 
"diffie-hellman-group1-sha1"}], "key": [{"algorithm": "ssh-rsa", "keysize": 
1024}, {"algorithm": "ssh-rsa-cert-...@openssh.com", "casize": 1024, "keysize": 
1024}], "mac": ["hmac-md5", "hmac-sha1", "umac...@openssh.com", 
"hmac-ripemd160", "hmac-ripemd...@openssh.com", "hmac-sha1-96", "hmac-md5-96"], 
"target": "localhost"}
+{"banner": {"comments": null, "protocol": [2, 0], "raw": 
"SSH-2.0-OpenSSH_5.6", "software": "OpenSSH_5.6"}, "compression": ["none", 
"z...@openssh.com"], "enc": ["aes128-ctr", "aes192-ctr", "aes256-ctr", 
"arcfour256", "arcfour128", "aes128-cbc", "3des-cbc", "blowfish-cbc", 
"cast128-cbc", "aes192-cbc", "aes256-cbc", "arcfour", 
"rijndael-...@lysator.liu.se"], "fingerprints": [{"hash": 
"YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4", "hash_alg": "SHA256", "hostkey": 
"ssh-rsa"}, {"hash": "3c:c3:38:f8:55:39:c0:4a:5a:17:89:60:2c:a1:fc:6a", 
"hash_alg": "MD5", "hostkey": "ssh-rsa"}], "kex": [{"algorithm": 
"diffie-hellman-group-exchange-sha256", "keysize": 1024}, {"algorithm": 
"diffie-hellman-group-exchange-sha1", "keysize": 1024}, {"algorithm": 
"diffie-hellman-group14-sha1"}, {"algorithm": "diffie-hellman-group1-sha1"}], 
"key": [{"algorithm": "ssh-rsa", "keysize": 1024}, {"algorithm": 
"ssh-rsa-cert-...@openssh.com", "casize": 1024, "keysize": 1024}], "mac": 
["hmac-md5", "hmac-sha1", "umac-64@o
 penssh.com", "hmac-ripemd160", "hmac-ripemd...@openssh.com", "hmac-sha1-96", 
"hmac-md5-96"], "target": "localhost"}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ssh-audit-2.4.0/test/docker/expected_results/openssh_5.6p1_test3.json 
new/ssh-audit-2.5.0/test/docker/expected_results/openssh_5.6p1_test3.json
--- old/ssh-audit-2.4.0/test/docker/expected_results/openssh_5.6p1_test3.json   
2021-02-24 02:39:18.000000000 +0100
+++ new/ssh-audit-2.5.0/test/docker/expected_results/openssh_5.6p1_test3.json   
2021-08-26 21:24:34.000000000 +0200
@@ -1 +1 @@
-{"banner": {"comments": null, "protocol": [2, 0], "raw": 
"SSH-2.0-OpenSSH_5.6", "software": "OpenSSH_5.6"}, "compression": ["none", 
"z...@openssh.com"], "enc": ["aes128-ctr", "aes192-ctr", "aes256-ctr", 
"arcfour256", "arcfour128", "aes128-cbc", "3des-cbc", "blowfish-cbc", 
"cast128-cbc", "aes192-cbc", "aes256-cbc", "arcfour", 
"rijndael-...@lysator.liu.se"], "fingerprints": [{"fp": 
"SHA256:YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4", "type": "ssh-rsa"}], 
"kex": [{"algorithm": "diffie-hellman-group-exchange-sha256", "keysize": 1024}, 
{"algorithm": "diffie-hellman-group-exchange-sha1", "keysize": 1024}, 
{"algorithm": "diffie-hellman-group14-sha1"}, {"algorithm": 
"diffie-hellman-group1-sha1"}], "key": [{"algorithm": "ssh-rsa", "keysize": 
1024}, {"algorithm": "ssh-rsa-cert-...@openssh.com", "casize": 3072, "keysize": 
1024}], "mac": ["hmac-md5", "hmac-sha1", "umac...@openssh.com", 
"hmac-ripemd160", "hmac-ripemd...@openssh.com", "hmac-sha1-96", "hmac-md5-96"], 
"target": "localhost"}
+{"banner": {"comments": null, "protocol": [2, 0], "raw": 
"SSH-2.0-OpenSSH_5.6", "software": "OpenSSH_5.6"}, "compression": ["none", 
"z...@openssh.com"], "enc": ["aes128-ctr", "aes192-ctr", "aes256-ctr", 
"arcfour256", "arcfour128", "aes128-cbc", "3des-cbc", "blowfish-cbc", 
"cast128-cbc", "aes192-cbc", "aes256-cbc", "arcfour", 
"rijndael-...@lysator.liu.se"], "fingerprints": [{"hash": 
"YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4", "hash_alg": "SHA256", "hostkey": 
"ssh-rsa"}, {"hash": "3c:c3:38:f8:55:39:c0:4a:5a:17:89:60:2c:a1:fc:6a", 
"hash_alg": "MD5", "hostkey": "ssh-rsa"}], "kex": [{"algorithm": 
"diffie-hellman-group-exchange-sha256", "keysize": 1024}, {"algorithm": 
"diffie-hellman-group-exchange-sha1", "keysize": 1024}, {"algorithm": 
"diffie-hellman-group14-sha1"}, {"algorithm": "diffie-hellman-group1-sha1"}], 
"key": [{"algorithm": "ssh-rsa", "keysize": 1024}, {"algorithm": 
"ssh-rsa-cert-...@openssh.com", "casize": 3072, "keysize": 1024}], "mac": 
["hmac-md5", "hmac-sha1", "umac-64@o
 penssh.com", "hmac-ripemd160", "hmac-ripemd...@openssh.com", "hmac-sha1-96", 
"hmac-md5-96"], "target": "localhost"}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ssh-audit-2.4.0/test/docker/expected_results/openssh_5.6p1_test4.json 
new/ssh-audit-2.5.0/test/docker/expected_results/openssh_5.6p1_test4.json
--- old/ssh-audit-2.4.0/test/docker/expected_results/openssh_5.6p1_test4.json   
2021-02-24 02:39:18.000000000 +0100
+++ new/ssh-audit-2.5.0/test/docker/expected_results/openssh_5.6p1_test4.json   
2021-08-26 21:24:34.000000000 +0200
@@ -1 +1 @@
-{"banner": {"comments": null, "protocol": [2, 0], "raw": 
"SSH-2.0-OpenSSH_5.6", "software": "OpenSSH_5.6"}, "compression": ["none", 
"z...@openssh.com"], "enc": ["aes128-ctr", "aes192-ctr", "aes256-ctr", 
"arcfour256", "arcfour128", "aes128-cbc", "3des-cbc", "blowfish-cbc", 
"cast128-cbc", "aes192-cbc", "aes256-cbc", "arcfour", 
"rijndael-...@lysator.liu.se"], "fingerprints": [{"fp": 
"SHA256:nsWtdJ9Z67Vrf7OsUzQov7esXhsWAfVppArGh25u244", "type": "ssh-rsa"}], 
"kex": [{"algorithm": "diffie-hellman-group-exchange-sha256", "keysize": 1024}, 
{"algorithm": "diffie-hellman-group-exchange-sha1", "keysize": 1024}, 
{"algorithm": "diffie-hellman-group14-sha1"}, {"algorithm": 
"diffie-hellman-group1-sha1"}], "key": [{"algorithm": "ssh-rsa", "keysize": 
3072}, {"algorithm": "ssh-rsa-cert-...@openssh.com", "casize": 1024, "keysize": 
3072}], "mac": ["hmac-md5", "hmac-sha1", "umac...@openssh.com", 
"hmac-ripemd160", "hmac-ripemd...@openssh.com", "hmac-sha1-96", "hmac-md5-96"], 
"target": "localhost"}
+{"banner": {"comments": null, "protocol": [2, 0], "raw": 
"SSH-2.0-OpenSSH_5.6", "software": "OpenSSH_5.6"}, "compression": ["none", 
"z...@openssh.com"], "enc": ["aes128-ctr", "aes192-ctr", "aes256-ctr", 
"arcfour256", "arcfour128", "aes128-cbc", "3des-cbc", "blowfish-cbc", 
"cast128-cbc", "aes192-cbc", "aes256-cbc", "arcfour", 
"rijndael-...@lysator.liu.se"], "fingerprints": [{"hash": 
"nsWtdJ9Z67Vrf7OsUzQov7esXhsWAfVppArGh25u244", "hash_alg": "SHA256", "hostkey": 
"ssh-rsa"}, {"hash": "18:e2:51:fe:21:6c:78:d0:b8:cf:32:d4:bd:56:42:e1", 
"hash_alg": "MD5", "hostkey": "ssh-rsa"}], "kex": [{"algorithm": 
"diffie-hellman-group-exchange-sha256", "keysize": 1024}, {"algorithm": 
"diffie-hellman-group-exchange-sha1", "keysize": 1024}, {"algorithm": 
"diffie-hellman-group14-sha1"}, {"algorithm": "diffie-hellman-group1-sha1"}], 
"key": [{"algorithm": "ssh-rsa", "keysize": 3072}, {"algorithm": 
"ssh-rsa-cert-...@openssh.com", "casize": 1024, "keysize": 3072}], "mac": 
["hmac-md5", "hmac-sha1", "umac-64@o
 penssh.com", "hmac-ripemd160", "hmac-ripemd...@openssh.com", "hmac-sha1-96", 
"hmac-md5-96"], "target": "localhost"}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ssh-audit-2.4.0/test/docker/expected_results/openssh_5.6p1_test5.json 
new/ssh-audit-2.5.0/test/docker/expected_results/openssh_5.6p1_test5.json
--- old/ssh-audit-2.4.0/test/docker/expected_results/openssh_5.6p1_test5.json   
2021-02-24 02:39:18.000000000 +0100
+++ new/ssh-audit-2.5.0/test/docker/expected_results/openssh_5.6p1_test5.json   
2021-08-26 21:24:34.000000000 +0200
@@ -1 +1 @@
-{"banner": {"comments": null, "protocol": [2, 0], "raw": 
"SSH-2.0-OpenSSH_5.6", "software": "OpenSSH_5.6"}, "compression": ["none", 
"z...@openssh.com"], "enc": ["aes128-ctr", "aes192-ctr", "aes256-ctr", 
"arcfour256", "arcfour128", "aes128-cbc", "3des-cbc", "blowfish-cbc", 
"cast128-cbc", "aes192-cbc", "aes256-cbc", "arcfour", 
"rijndael-...@lysator.liu.se"], "fingerprints": [{"fp": 
"SHA256:nsWtdJ9Z67Vrf7OsUzQov7esXhsWAfVppArGh25u244", "type": "ssh-rsa"}], 
"kex": [{"algorithm": "diffie-hellman-group-exchange-sha256", "keysize": 1024}, 
{"algorithm": "diffie-hellman-group-exchange-sha1", "keysize": 1024}, 
{"algorithm": "diffie-hellman-group14-sha1"}, {"algorithm": 
"diffie-hellman-group1-sha1"}], "key": [{"algorithm": "ssh-rsa", "keysize": 
3072}, {"algorithm": "ssh-rsa-cert-...@openssh.com", "casize": 3072, "keysize": 
3072}], "mac": ["hmac-md5", "hmac-sha1", "umac...@openssh.com", 
"hmac-ripemd160", "hmac-ripemd...@openssh.com", "hmac-sha1-96", "hmac-md5-96"], 
"target": "localhost"}
+{"banner": {"comments": null, "protocol": [2, 0], "raw": 
"SSH-2.0-OpenSSH_5.6", "software": "OpenSSH_5.6"}, "compression": ["none", 
"z...@openssh.com"], "enc": ["aes128-ctr", "aes192-ctr", "aes256-ctr", 
"arcfour256", "arcfour128", "aes128-cbc", "3des-cbc", "blowfish-cbc", 
"cast128-cbc", "aes192-cbc", "aes256-cbc", "arcfour", 
"rijndael-...@lysator.liu.se"], "fingerprints": [{"hash": 
"nsWtdJ9Z67Vrf7OsUzQov7esXhsWAfVppArGh25u244", "hash_alg": "SHA256", "hostkey": 
"ssh-rsa"}, {"hash": "18:e2:51:fe:21:6c:78:d0:b8:cf:32:d4:bd:56:42:e1", 
"hash_alg": "MD5", "hostkey": "ssh-rsa"}], "kex": [{"algorithm": 
"diffie-hellman-group-exchange-sha256", "keysize": 1024}, {"algorithm": 
"diffie-hellman-group-exchange-sha1", "keysize": 1024}, {"algorithm": 
"diffie-hellman-group14-sha1"}, {"algorithm": "diffie-hellman-group1-sha1"}], 
"key": [{"algorithm": "ssh-rsa", "keysize": 3072}, {"algorithm": 
"ssh-rsa-cert-...@openssh.com", "casize": 3072, "keysize": 3072}], "mac": 
["hmac-md5", "hmac-sha1", "umac-64@o
 penssh.com", "hmac-ripemd160", "hmac-ripemd...@openssh.com", "hmac-sha1-96", 
"hmac-md5-96"], "target": "localhost"}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ssh-audit-2.4.0/test/docker/expected_results/openssh_8.0p1_test1.json 
new/ssh-audit-2.5.0/test/docker/expected_results/openssh_8.0p1_test1.json
--- old/ssh-audit-2.4.0/test/docker/expected_results/openssh_8.0p1_test1.json   
2021-02-24 02:39:18.000000000 +0100
+++ new/ssh-audit-2.5.0/test/docker/expected_results/openssh_8.0p1_test1.json   
2021-08-26 21:24:34.000000000 +0200
@@ -1 +1 @@
-{"banner": {"comments": null, "protocol": [2, 0], "raw": 
"SSH-2.0-OpenSSH_8.0", "software": "OpenSSH_8.0"}, "compression": ["none", 
"z...@openssh.com"], "enc": ["chacha20-poly1...@openssh.com", "aes128-ctr", 
"aes192-ctr", "aes256-ctr", "aes128-...@openssh.com", 
"aes256-...@openssh.com"], "fingerprints": [{"fp": 
"SHA256:UrnXIVH+7dlw8UqYocl48yUEcKrthGDQG2CPCgp7MxU", "type": "ssh-ed25519"}, 
{"fp": "SHA256:nsWtdJ9Z67Vrf7OsUzQov7esXhsWAfVppArGh25u244", "type": 
"ssh-rsa"}], "kex": [{"algorithm": "curve25519-sha256"}, {"algorithm": 
"curve25519-sha...@libssh.org"}, {"algorithm": "ecdh-sha2-nistp256"}, 
{"algorithm": "ecdh-sha2-nistp384"}, {"algorithm": "ecdh-sha2-nistp521"}, 
{"algorithm": "diffie-hellman-group-exchange-sha256", "keysize": 2048}, 
{"algorithm": "diffie-hellman-group16-sha512"}, {"algorithm": 
"diffie-hellman-group18-sha512"}, {"algorithm": 
"diffie-hellman-group14-sha256"}, {"algorithm": 
"diffie-hellman-group14-sha1"}], "key": [{"algorithm": "rsa-sha2-512", 
"keysize": 3072}, {"a
 lgorithm": "rsa-sha2-256", "keysize": 3072}, {"algorithm": "ssh-rsa", 
"keysize": 3072}, {"algorithm": "ecdsa-sha2-nistp256"}, {"algorithm": 
"ssh-ed25519"}], "mac": ["umac-64-...@openssh.com", "umac-128-...@openssh.com", 
"hmac-sha2-256-...@openssh.com", "hmac-sha2-512-...@openssh.com", 
"hmac-sha1-...@openssh.com", "umac...@openssh.com", "umac-...@openssh.com", 
"hmac-sha2-256", "hmac-sha2-512", "hmac-sha1"], "target": "localhost"}
+{"banner": {"comments": null, "protocol": [2, 0], "raw": 
"SSH-2.0-OpenSSH_8.0", "software": "OpenSSH_8.0"}, "compression": ["none", 
"z...@openssh.com"], "enc": ["chacha20-poly1...@openssh.com", "aes128-ctr", 
"aes192-ctr", "aes256-ctr", "aes128-...@openssh.com", 
"aes256-...@openssh.com"], "fingerprints": [{"hash": 
"UrnXIVH+7dlw8UqYocl48yUEcKrthGDQG2CPCgp7MxU", "hash_alg": "SHA256", "hostkey": 
"ssh-ed25519"}, {"hash": "1e:0c:7b:34:73:bf:52:41:b0:f9:d1:a9:ab:98:c7:c9", 
"hash_alg": "MD5", "hostkey": "ssh-ed25519"}, {"hash": 
"nsWtdJ9Z67Vrf7OsUzQov7esXhsWAfVppArGh25u244", "hash_alg": "SHA256", "hostkey": 
"ssh-rsa"}, {"hash": "18:e2:51:fe:21:6c:78:d0:b8:cf:32:d4:bd:56:42:e1", 
"hash_alg": "MD5", "hostkey": "ssh-rsa"}], "kex": [{"algorithm": 
"curve25519-sha256"}, {"algorithm": "curve25519-sha...@libssh.org"}, 
{"algorithm": "ecdh-sha2-nistp256"}, {"algorithm": "ecdh-sha2-nistp384"}, 
{"algorithm": "ecdh-sha2-nistp521"}, {"algorithm": 
"diffie-hellman-group-exchange-sha256", "keysize": 2048}, {"
 algorithm": "diffie-hellman-group16-sha512"}, {"algorithm": 
"diffie-hellman-group18-sha512"}, {"algorithm": 
"diffie-hellman-group14-sha256"}, {"algorithm": 
"diffie-hellman-group14-sha1"}], "key": [{"algorithm": "rsa-sha2-512", 
"keysize": 3072}, {"algorithm": "rsa-sha2-256", "keysize": 3072}, {"algorithm": 
"ssh-rsa", "keysize": 3072}, {"algorithm": "ecdsa-sha2-nistp256"}, 
{"algorithm": "ssh-ed25519"}], "mac": ["umac-64-...@openssh.com", 
"umac-128-...@openssh.com", "hmac-sha2-256-...@openssh.com", 
"hmac-sha2-512-...@openssh.com", "hmac-sha1-...@openssh.com", 
"umac...@openssh.com", "umac-...@openssh.com", "hmac-sha2-256", 
"hmac-sha2-512", "hmac-sha1"], "target": "localhost"}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ssh-audit-2.4.0/test/docker/expected_results/openssh_8.0p1_test2.json 
new/ssh-audit-2.5.0/test/docker/expected_results/openssh_8.0p1_test2.json
--- old/ssh-audit-2.4.0/test/docker/expected_results/openssh_8.0p1_test2.json   
2021-02-24 02:39:18.000000000 +0100
+++ new/ssh-audit-2.5.0/test/docker/expected_results/openssh_8.0p1_test2.json   
2021-08-26 21:24:34.000000000 +0200
@@ -1 +1 @@
-{"banner": {"comments": null, "protocol": [2, 0], "raw": 
"SSH-2.0-OpenSSH_8.0", "software": "OpenSSH_8.0"}, "compression": ["none", 
"z...@openssh.com"], "enc": ["chacha20-poly1...@openssh.com", "aes128-ctr", 
"aes192-ctr", "aes256-ctr", "aes128-...@openssh.com", 
"aes256-...@openssh.com"], "fingerprints": [{"fp": 
"SHA256:UrnXIVH+7dlw8UqYocl48yUEcKrthGDQG2CPCgp7MxU", "type": "ssh-ed25519"}], 
"kex": [{"algorithm": "curve25519-sha256"}, {"algorithm": 
"curve25519-sha...@libssh.org"}, {"algorithm": "ecdh-sha2-nistp256"}, 
{"algorithm": "ecdh-sha2-nistp384"}, {"algorithm": "ecdh-sha2-nistp521"}, 
{"algorithm": "diffie-hellman-group-exchange-sha256", "keysize": 2048}, 
{"algorithm": "diffie-hellman-group16-sha512"}, {"algorithm": 
"diffie-hellman-group18-sha512"}, {"algorithm": 
"diffie-hellman-group14-sha256"}, {"algorithm": 
"diffie-hellman-group14-sha1"}], "key": [{"algorithm": "ssh-ed25519"}, 
{"algorithm": "ssh-ed25519-cert-...@openssh.com"}], "mac": 
["umac-64-...@openssh.com", "umac-128-etm@o
 penssh.com", "hmac-sha2-256-...@openssh.com", "hmac-sha2-512-...@openssh.com", 
"hmac-sha1-...@openssh.com", "umac...@openssh.com", "umac-...@openssh.com", 
"hmac-sha2-256", "hmac-sha2-512", "hmac-sha1"], "target": "localhost"}
+{"banner": {"comments": null, "protocol": [2, 0], "raw": 
"SSH-2.0-OpenSSH_8.0", "software": "OpenSSH_8.0"}, "compression": ["none", 
"z...@openssh.com"], "enc": ["chacha20-poly1...@openssh.com", "aes128-ctr", 
"aes192-ctr", "aes256-ctr", "aes128-...@openssh.com", 
"aes256-...@openssh.com"], "fingerprints": [{"hash": 
"UrnXIVH+7dlw8UqYocl48yUEcKrthGDQG2CPCgp7MxU", "hash_alg": "SHA256", "hostkey": 
"ssh-ed25519"}, {"hash": "1e:0c:7b:34:73:bf:52:41:b0:f9:d1:a9:ab:98:c7:c9", 
"hash_alg": "MD5", "hostkey": "ssh-ed25519"}], "kex": [{"algorithm": 
"curve25519-sha256"}, {"algorithm": "curve25519-sha...@libssh.org"}, 
{"algorithm": "ecdh-sha2-nistp256"}, {"algorithm": "ecdh-sha2-nistp384"}, 
{"algorithm": "ecdh-sha2-nistp521"}, {"algorithm": 
"diffie-hellman-group-exchange-sha256", "keysize": 2048}, {"algorithm": 
"diffie-hellman-group16-sha512"}, {"algorithm": 
"diffie-hellman-group18-sha512"}, {"algorithm": 
"diffie-hellman-group14-sha256"}, {"algorithm": 
"diffie-hellman-group14-sha1"}], "key": [{"algo
 rithm": "ssh-ed25519"}, {"algorithm": "ssh-ed25519-cert-...@openssh.com"}], 
"mac": ["umac-64-...@openssh.com", "umac-128-...@openssh.com", 
"hmac-sha2-256-...@openssh.com", "hmac-sha2-512-...@openssh.com", 
"hmac-sha1-...@openssh.com", "umac...@openssh.com", "umac-...@openssh.com", 
"hmac-sha2-256", "hmac-sha2-512", "hmac-sha1"], "target": "localhost"}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ssh-audit-2.4.0/test/docker/expected_results/openssh_8.0p1_test3.json 
new/ssh-audit-2.5.0/test/docker/expected_results/openssh_8.0p1_test3.json
--- old/ssh-audit-2.4.0/test/docker/expected_results/openssh_8.0p1_test3.json   
2021-02-24 02:39:18.000000000 +0100
+++ new/ssh-audit-2.5.0/test/docker/expected_results/openssh_8.0p1_test3.json   
2021-08-26 21:24:34.000000000 +0200
@@ -1 +1 @@
-{"banner": {"comments": null, "protocol": [2, 0], "raw": 
"SSH-2.0-OpenSSH_8.0", "software": "OpenSSH_8.0"}, "compression": ["none", 
"z...@openssh.com"], "enc": ["chacha20-poly1...@openssh.com", 
"aes256-...@openssh.com", "aes128-...@openssh.com", "aes256-ctr", "aes192-ctr", 
"aes128-ctr"], "fingerprints": [{"fp": 
"SHA256:UrnXIVH+7dlw8UqYocl48yUEcKrthGDQG2CPCgp7MxU", "type": "ssh-ed25519"}], 
"kex": [{"algorithm": "curve25519-sha256"}, {"algorithm": 
"curve25519-sha...@libssh.org"}, {"algorithm": 
"diffie-hellman-group-exchange-sha256", "keysize": 2048}], "key": 
[{"algorithm": "ssh-ed25519"}], "mac": ["hmac-sha2-256-...@openssh.com", 
"hmac-sha2-512-...@openssh.com", "umac-128-...@openssh.com"], "target": 
"localhost"}
+{"banner": {"comments": null, "protocol": [2, 0], "raw": 
"SSH-2.0-OpenSSH_8.0", "software": "OpenSSH_8.0"}, "compression": ["none", 
"z...@openssh.com"], "enc": ["chacha20-poly1...@openssh.com", 
"aes256-...@openssh.com", "aes128-...@openssh.com", "aes256-ctr", "aes192-ctr", 
"aes128-ctr"], "fingerprints": [{"hash": 
"UrnXIVH+7dlw8UqYocl48yUEcKrthGDQG2CPCgp7MxU", "hash_alg": "SHA256", "hostkey": 
"ssh-ed25519"}, {"hash": "1e:0c:7b:34:73:bf:52:41:b0:f9:d1:a9:ab:98:c7:c9", 
"hash_alg": "MD5", "hostkey": "ssh-ed25519"}], "kex": [{"algorithm": 
"curve25519-sha256"}, {"algorithm": "curve25519-sha...@libssh.org"}, 
{"algorithm": "diffie-hellman-group-exchange-sha256", "keysize": 2048}], "key": 
[{"algorithm": "ssh-ed25519"}], "mac": ["hmac-sha2-256-...@openssh.com", 
"hmac-sha2-512-...@openssh.com", "umac-128-...@openssh.com"], "target": 
"localhost"}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ssh-audit-2.4.0/test/docker/expected_results/tinyssh_20190101_test1.json 
new/ssh-audit-2.5.0/test/docker/expected_results/tinyssh_20190101_test1.json
--- 
old/ssh-audit-2.4.0/test/docker/expected_results/tinyssh_20190101_test1.json    
    2021-02-24 02:39:18.000000000 +0100
+++ 
new/ssh-audit-2.5.0/test/docker/expected_results/tinyssh_20190101_test1.json    
    2021-08-26 21:24:34.000000000 +0200
@@ -1 +1 @@
-{"banner": {"comments": "", "protocol": [2, 0], "raw": "", "software": 
"tinyssh_noversion"}, "compression": ["none"], "enc": 
["chacha20-poly1...@openssh.com"], "fingerprints": [{"fp": 
"SHA256:89ocln1x7KNqnMgWffGoYtD70ksJ4FrH7BMJHa7SrwU", "type": "ssh-ed25519"}], 
"kex": [{"algorithm": "curve25519-sha256"}, {"algorithm": 
"curve25519-sha...@libssh.org"}, {"algorithm": 
"sntrup4591761x25519-sha...@tinyssh.org"}], "key": [{"algorithm": 
"ssh-ed25519"}], "mac": ["hmac-sha2-256"], "target": "localhost"}
+{"banner": {"comments": "", "protocol": [2, 0], "raw": "", "software": 
"tinyssh_noversion"}, "compression": ["none"], "enc": 
["chacha20-poly1...@openssh.com"], "fingerprints": [{"hash": 
"89ocln1x7KNqnMgWffGoYtD70ksJ4FrH7BMJHa7SrwU", "hash_alg": "SHA256", "hostkey": 
"ssh-ed25519"}, {"hash": "dd:9c:6d:f9:b0:8c:af:fa:c2:65:81:5d:5d:56:f8:21", 
"hash_alg": "MD5", "hostkey": "ssh-ed25519"}], "kex": [{"algorithm": 
"curve25519-sha256"}, {"algorithm": "curve25519-sha...@libssh.org"}, 
{"algorithm": "sntrup4591761x25519-sha...@tinyssh.org"}], "key": [{"algorithm": 
"ssh-ed25519"}], "mac": ["hmac-sha2-256"], "target": "localhost"}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ssh-audit-2.4.0/test/test_build_struct.py 
new/ssh-audit-2.5.0/test/test_build_struct.py
--- old/ssh-audit-2.4.0/test/test_build_struct.py       2021-02-24 
02:39:18.000000000 +0100
+++ new/ssh-audit-2.5.0/test/test_build_struct.py       2021-08-26 
21:24:34.000000000 +0200
@@ -37,7 +37,7 @@
 
     rv = ssh_audit.build_struct('localhost', banner=None, kex=kex)
 
-    assert len(rv["fingerprints"]) == 9
+    assert len(rv["fingerprints"]) == (9 * 2)  # Each host key generates two 
hash fingerprints: one using SHA256, and one using MD5.
 
     for key in ['banner', 'compression', 'enc', 'fingerprints', 'kex', 'key', 
'mac']:
         assert key in rv
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ssh-audit-2.4.0/test/test_resolve.py 
new/ssh-audit-2.5.0/test/test_resolve.py
--- old/ssh-audit-2.4.0/test/test_resolve.py    2021-02-24 02:39:18.000000000 
+0100
+++ new/ssh-audit-2.5.0/test/test_resolve.py    2021-08-26 21:24:34.000000000 
+0200
@@ -8,6 +8,7 @@
     def init(self, ssh_audit):
         self.AuditConf = ssh_audit.AuditConf
         self.audit = ssh_audit.audit
+        self.OutputBuffer = ssh_audit.OutputBuffer
         self.ssh_socket = ssh_audit.SSH_Socket
 
     def _conf(self):
@@ -20,7 +21,7 @@
         vsocket = virtual_socket
         vsocket.gsock.addrinfodata['localhost#22'] = socket.gaierror(8, 
'hostname nor servname provided, or not known')
         conf = self._conf()
-        s = self.ssh_socket('localhost', 22, conf.ip_version_preference)
+        s = self.ssh_socket(self.OutputBuffer(), 'localhost', 22, 
conf.ip_version_preference)
         output_spy.begin()
         with pytest.raises(SystemExit):
             list(s._resolve())
@@ -32,7 +33,7 @@
         vsocket = virtual_socket
         vsocket.gsock.addrinfodata['localhost#22'] = []
         conf = self._conf()
-        s = self.ssh_socket('localhost', 22, conf.ip_version_preference)
+        s = self.ssh_socket(self.OutputBuffer(), 'localhost', 22, 
conf.ip_version_preference)
         output_spy.begin()
         r = list(s._resolve())
         assert len(r) == 0
@@ -40,7 +41,7 @@
     def test_resolve_ipv4(self, virtual_socket):
         conf = self._conf()
         conf.ipv4 = True
-        s = self.ssh_socket('localhost', 22, conf.ip_version_preference)
+        s = self.ssh_socket(self.OutputBuffer(), 'localhost', 22, 
conf.ip_version_preference)
         r = list(s._resolve())
         assert len(r) == 1
         assert r[0] == (socket.AF_INET, ('127.0.0.1', 22))
@@ -48,14 +49,14 @@
     def test_resolve_ipv6(self, virtual_socket):
         conf = self._conf()
         conf.ipv6 = True
-        s = self.ssh_socket('localhost', 22, conf.ip_version_preference)
+        s = self.ssh_socket(self.OutputBuffer(), 'localhost', 22, 
conf.ip_version_preference)
         r = list(s._resolve())
         assert len(r) == 1
         assert r[0] == (socket.AF_INET6, ('::1', 22))
 
     def test_resolve_ipv46_both(self, virtual_socket):
         conf = self._conf()
-        s = self.ssh_socket('localhost', 22, conf.ip_version_preference)
+        s = self.ssh_socket(self.OutputBuffer(), 'localhost', 22, 
conf.ip_version_preference)
         r = list(s._resolve())
         assert len(r) == 2
         assert r[0] == (socket.AF_INET, ('127.0.0.1', 22))
@@ -65,7 +66,7 @@
         conf = self._conf()
         conf.ipv4 = True
         conf.ipv6 = True
-        s = self.ssh_socket('localhost', 22, conf.ip_version_preference)
+        s = self.ssh_socket(self.OutputBuffer(), 'localhost', 22, 
conf.ip_version_preference)
         r = list(s._resolve())
         assert len(r) == 2
         assert r[0] == (socket.AF_INET, ('127.0.0.1', 22))
@@ -73,7 +74,7 @@
         conf = self._conf()
         conf.ipv6 = True
         conf.ipv4 = True
-        s = self.ssh_socket('localhost', 22, conf.ip_version_preference)
+        s = self.ssh_socket(self.OutputBuffer(), 'localhost', 22, 
conf.ip_version_preference)
         r = list(s._resolve())
         assert len(r) == 2
         assert r[0] == (socket.AF_INET6, ('::1', 22))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ssh-audit-2.4.0/test/test_socket.py 
new/ssh-audit-2.5.0/test/test_socket.py
--- old/ssh-audit-2.4.0/test/test_socket.py     2021-02-24 02:39:18.000000000 
+0100
+++ new/ssh-audit-2.5.0/test/test_socket.py     2021-08-26 21:24:34.000000000 
+0200
@@ -1,5 +1,6 @@
 import pytest
 
+from ssh_audit.outputbuffer import OutputBuffer
 from ssh_audit.ssh_socket import SSH_Socket
 
 
@@ -7,24 +8,25 @@
 class TestSocket:
     @pytest.fixture(autouse=True)
     def init(self, ssh_audit):
+        self.OutputBuffer = OutputBuffer
         self.ssh_socket = SSH_Socket
 
     def test_invalid_host(self, virtual_socket):
         with pytest.raises(ValueError):
-            self.ssh_socket(None, 22)
+            self.ssh_socket(self.OutputBuffer(), None, 22)
 
     def test_invalid_port(self, virtual_socket):
         with pytest.raises(ValueError):
-            self.ssh_socket('localhost', 'abc')
+            self.ssh_socket(self.OutputBuffer(), 'localhost', 'abc')
         with pytest.raises(ValueError):
-            self.ssh_socket('localhost', -1)
+            self.ssh_socket(self.OutputBuffer(), 'localhost', -1)
         with pytest.raises(ValueError):
-            self.ssh_socket('localhost', 0)
+            self.ssh_socket(self.OutputBuffer(), 'localhost', 0)
         with pytest.raises(ValueError):
-            self.ssh_socket('localhost', 65536)
+            self.ssh_socket(self.OutputBuffer(), 'localhost', 65536)
 
     def test_not_connected_socket(self, virtual_socket):
-        sock = self.ssh_socket('localhost', 22)
+        sock = self.ssh_socket(self.OutputBuffer(), 'localhost', 22)
         banner, header, err = sock.get_banner()
         assert banner is None
         assert len(header) == 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ssh-audit-2.4.0/test/test_ssh1.py 
new/ssh-audit-2.5.0/test/test_ssh1.py
--- old/ssh-audit-2.4.0/test/test_ssh1.py       2021-02-24 02:39:18.000000000 
+0100
+++ new/ssh-audit-2.5.0/test/test_ssh1.py       2021-08-26 21:24:34.000000000 
+0200
@@ -138,7 +138,7 @@
         self.audit(out, self._conf())
         out.write()
         lines = output_spy.flush()
-        assert len(lines) == 16
+        assert len(lines) == 17
 
     def test_ssh1_server_invalid_first_packet(self, output_spy, 
virtual_socket):
         vsocket = virtual_socket

Reply via email to