mirror of
https://github.com/jtesta/ssh-audit.git
synced 2026-10-27 03:21:29 +01:00
Moved built-in policies from external files to internal database. (#75)
This commit is contained in:
1 parent
2a7b9292bb
commit
046c866da4
53 files changed
+256
-437
No files matched your search
@@ -47,7 +47,8 @@ usage: ssh-audit.py [options] <host>
|
||||
adhere to)
|
||||
-n, --no-colors disable colors
|
||||
-p, --port=<port> port to connect
|
||||
-P, --policy=<policy.txt> run a policy test using the specified policy
|
||||
-P, --policy=<"policy name" | policy.txt> run a policy test using the
|
||||
specified policy
|
||||
-t, --timeout=<secs> timeout (in seconds) for connection and reading
|
||||
(default: 5)
|
||||
-T, --targets=<hosts.txt> a file containing a list of target hosts (one
|
||||
@@ -92,17 +93,17 @@ ssh-audit -L
|
||||
|
||||
To run a policy audit against a server:
|
||||
```
|
||||
ssh-audit -P path/to/server_policy targetserver
|
||||
ssh-audit -P ["policy name" | path/to/server_policy.txt] targetserver
|
||||
```
|
||||
|
||||
To run a policy audit against a client:
|
||||
```
|
||||
ssh-audit -c -P path/to/client_policy
|
||||
ssh-audit -c -P ["policy name" | path/to/client_policy.txt]
|
||||
```
|
||||
|
||||
To run a policy audit against many servers:
|
||||
```
|
||||
ssh-audit -T servers.txt -P path/to/server_policy
|
||||
ssh-audit -T servers.txt -P ["policy name" | path/to/server_policy.txt]
|
||||
```
|
||||
|
||||
To create a policy based on a target server (which can be manually edited; see official built-in policies for syntax examples):
|
||||
@@ -151,8 +152,9 @@ For convenience, a web front-end on top of the command-line tool is available at
|
||||
|
||||
## ChangeLog
|
||||
### v2.3.1-dev (???)
|
||||
- Migrated pre-made policies from external files to internal database.
|
||||
- Split single 3,500 line script into many files (by class).
|
||||
- Added setup.py support; credit [Ganden Schaffner](https://github.com/gschaffner)
|
||||
- Added setup.py support; credit [Ganden Schaffner](https://github.com/gschaffner).
|
||||
- Added 1 new cipher: `des-cbc@ssh.com`.
|
||||
|
||||
### v2.3.0 (2020-09-27)
|
||||
|
||||
+60
-24
@@ -489,8 +489,25 @@ function run_test {
|
||||
echo -e "${test_name} ${GREEN}passed${CLR}."
|
||||
}
|
||||
|
||||
function run_builtin_policy_test {
|
||||
policy_name=$1 # The built-in policy name to use.
|
||||
version=$2 # Version of OpenSSH to test with.
|
||||
test_number=$3 # The test number to run.
|
||||
server_options=$4 # The options to start the server with (i.e.: "-o option1,options2,...")
|
||||
expected_exit_code=$5 # The expected exit code of ssh-audit.py.
|
||||
|
||||
function run_policy_test {
|
||||
server_exec="/openssh/sshd-${version} -D -f /etc/ssh/sshd_config-8.0p1_test1 ${server_options}"
|
||||
test_result_stdout="${TEST_RESULT_DIR}/openssh_${version}_builtin_policy_${test_number}.txt"
|
||||
test_result_json="${TEST_RESULT_DIR}/openssh_${version}_builtin_policy_${test_number}.json"
|
||||
expected_result_stdout="test/docker/expected_results/openssh_${version}_builtin_policy_${test_number}.txt"
|
||||
expected_result_json="test/docker/expected_results/openssh_${version}_builtin_policy_${test_number}.json"
|
||||
test_name="OpenSSH ${version} built-in policy ${test_number}"
|
||||
|
||||
run_policy_test "${test_name}" "${server_exec}" "${policy_name}" "${test_result_stdout}" "${test_result_json}" "${expected_exit_code}"
|
||||
}
|
||||
|
||||
|
||||
function run_custom_policy_test {
|
||||
config_number=$1 # The configuration number to use.
|
||||
test_number=$2 # The policy test number to run.
|
||||
expected_exit_code=$3 # The expected exit code of ssh-audit.py.
|
||||
@@ -510,11 +527,24 @@ function run_policy_test {
|
||||
|
||||
server_exec="/openssh/sshd-${version} -D -f /etc/ssh/${config}"
|
||||
policy_path="test/docker/policies/policy_${test_number}.txt"
|
||||
test_result_stdout="${TEST_RESULT_DIR}/openssh_${version}_policy_${test_number}.txt"
|
||||
test_result_json="${TEST_RESULT_DIR}/openssh_${version}_policy_${test_number}.json"
|
||||
expected_result_stdout="test/docker/expected_results/openssh_${version}_policy_${test_number}.txt"
|
||||
expected_result_json="test/docker/expected_results/openssh_${version}_policy_${test_number}.json"
|
||||
test_name="OpenSSH ${version} policy ${test_number}"
|
||||
test_result_stdout="${TEST_RESULT_DIR}/openssh_${version}_custom_policy_${test_number}.txt"
|
||||
test_result_json="${TEST_RESULT_DIR}/openssh_${version}_custom_policy_${test_number}.json"
|
||||
expected_result_stdout="test/docker/expected_results/openssh_${version}_custom_policy_${test_number}.txt"
|
||||
expected_result_json="test/docker/expected_results/openssh_${version}_custom_policy_${test_number}.json"
|
||||
test_name="OpenSSH ${version} custom policy ${test_number}"
|
||||
|
||||
run_policy_test "${test_name}" "${server_exec}" "${policy_path}" "${test_result_stdout}" "${test_result_json}" "${expected_exit_code}"
|
||||
}
|
||||
|
||||
|
||||
function run_policy_test {
|
||||
test_name=$1
|
||||
server_exec=$2
|
||||
policy_path=$3
|
||||
test_result_stdout=$4
|
||||
test_result_json=$5
|
||||
expected_exit_code=$6
|
||||
|
||||
|
||||
#echo "Running: docker run -d -p 2222:22 ${IMAGE_NAME}:${IMAGE_VERSION} ${server_exec}"
|
||||
cid=`docker run -d -p 2222:22 ${IMAGE_NAME}:${IMAGE_VERSION} ${server_exec}`
|
||||
@@ -523,8 +553,8 @@ function run_policy_test {
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#echo "Running: ./ssh-audit.py -P ${policy_path} localhost:2222 > ${test_result_stdout}"
|
||||
./ssh-audit.py -P ${policy_path} localhost:2222 > ${test_result_stdout}
|
||||
#echo "Running: ./ssh-audit.py -P \"${policy_path}\" localhost:2222 > ${test_result_stdout}"
|
||||
./ssh-audit.py -P "${policy_path}" localhost:2222 > ${test_result_stdout}
|
||||
actual_exit_code=$?
|
||||
if [[ ${actual_exit_code} != ${expected_exit_code} ]]; then
|
||||
echo -e "${test_name} ${REDB}FAILED${CLR} (expected exit code: ${expected_exit_code}; actual exit code: ${actual_exit_code}\n"
|
||||
@@ -533,8 +563,8 @@ function run_policy_test {
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#echo "Running: ./ssh-audit.py -P ${policy_path} -j localhost:2222 > ${test_result_json}"
|
||||
./ssh-audit.py -P ${policy_path} -j localhost:2222 > ${test_result_json}
|
||||
#echo "Running: ./ssh-audit.py -P \"${policy_path}\" -j localhost:2222 > ${test_result_json}"
|
||||
./ssh-audit.py -P "${policy_path}" -j localhost:2222 > ${test_result_json}
|
||||
actual_exit_code=$?
|
||||
if [[ ${actual_exit_code} != ${expected_exit_code} ]]; then
|
||||
echo -e "${test_name} ${REDB}FAILED${CLR} (expected exit code: ${expected_exit_code}; actual exit code: ${actual_exit_code}\n"
|
||||
@@ -627,36 +657,42 @@ echo
|
||||
run_tinyssh_test '20190101' 'test1' $PROGRAM_RETVAL_WARNING
|
||||
echo
|
||||
echo
|
||||
run_policy_test 'config1' 'test1' $PROGRAM_RETVAL_GOOD
|
||||
run_policy_test 'config1' 'test2' $PROGRAM_RETVAL_FAILURE
|
||||
run_policy_test 'config1' 'test3' $PROGRAM_RETVAL_FAILURE
|
||||
run_policy_test 'config1' 'test4' $PROGRAM_RETVAL_FAILURE
|
||||
run_policy_test 'config1' 'test5' $PROGRAM_RETVAL_FAILURE
|
||||
run_policy_test 'config2' 'test6' $PROGRAM_RETVAL_GOOD
|
||||
run_custom_policy_test 'config1' 'test1' $PROGRAM_RETVAL_GOOD
|
||||
run_custom_policy_test 'config1' 'test2' $PROGRAM_RETVAL_FAILURE
|
||||
run_custom_policy_test 'config1' 'test3' $PROGRAM_RETVAL_FAILURE
|
||||
run_custom_policy_test 'config1' 'test4' $PROGRAM_RETVAL_FAILURE
|
||||
run_custom_policy_test 'config1' 'test5' $PROGRAM_RETVAL_FAILURE
|
||||
run_custom_policy_test 'config2' 'test6' $PROGRAM_RETVAL_GOOD
|
||||
|
||||
# Passing test with host key certificate and CA key certificates.
|
||||
run_policy_test 'config3' 'test7' $PROGRAM_RETVAL_GOOD
|
||||
run_custom_policy_test 'config3' 'test7' $PROGRAM_RETVAL_GOOD
|
||||
|
||||
# Failing test with host key certificate and non-compliant CA key length.
|
||||
run_policy_test 'config3' 'test8' $PROGRAM_RETVAL_FAILURE
|
||||
run_custom_policy_test 'config3' 'test8' $PROGRAM_RETVAL_FAILURE
|
||||
|
||||
# Failing test with non-compliant host key certificate and CA key certificate.
|
||||
run_policy_test 'config3' 'test9' $PROGRAM_RETVAL_FAILURE
|
||||
run_custom_policy_test 'config3' 'test9' $PROGRAM_RETVAL_FAILURE
|
||||
|
||||
# Failing test with non-compliant host key certificate and non-compliant CA key certificate.
|
||||
run_policy_test 'config3' 'test10' $PROGRAM_RETVAL_FAILURE
|
||||
run_custom_policy_test 'config3' 'test10' $PROGRAM_RETVAL_FAILURE
|
||||
|
||||
# Passing test with host key size check.
|
||||
run_policy_test 'config2' 'test11' $PROGRAM_RETVAL_GOOD
|
||||
run_custom_policy_test 'config2' 'test11' $PROGRAM_RETVAL_GOOD
|
||||
|
||||
# Failing test with non-compliant host key size check.
|
||||
run_policy_test 'config2' 'test12' $PROGRAM_RETVAL_FAILURE
|
||||
run_custom_policy_test 'config2' 'test12' $PROGRAM_RETVAL_FAILURE
|
||||
|
||||
# Passing test with DH modulus test.
|
||||
run_policy_test 'config2' 'test13' $PROGRAM_RETVAL_GOOD
|
||||
run_custom_policy_test 'config2' 'test13' $PROGRAM_RETVAL_GOOD
|
||||
|
||||
# Failing test with DH modulus test.
|
||||
run_policy_test 'config2' 'test14' $PROGRAM_RETVAL_FAILURE
|
||||
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-sha256@libssh.org,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha256 -o Ciphers=chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr -o MACs=hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,umac-128-etm@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-sha256@libssh.org,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha256 -o Ciphers=chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr" $PROGRAM_RETVAL_FAILURE
|
||||
|
||||
|
||||
# The test functions above will terminate the script on failure, so if we reached here,
|
||||
|
||||
@@ -36,9 +36,6 @@ python_requires = >=3.5,<4
|
||||
[options.packages.find]
|
||||
where = src
|
||||
|
||||
[options.package_data]
|
||||
ssh_audit = policies/*
|
||||
|
||||
[options.entry_points]
|
||||
console_scripts =
|
||||
ssh-audit = ssh_audit.ssh_audit:main
|
||||
@@ -1,24 +0,0 @@
|
||||
#
|
||||
# Official policy for hardened OpenSSH v7.7.
|
||||
#
|
||||
|
||||
name = "Hardened OpenSSH v7.7"
|
||||
version = 1
|
||||
|
||||
# Group exchange DH modulus sizes.
|
||||
dh_modulus_size_diffie-hellman-group-exchange-sha256 = 2048
|
||||
|
||||
# The host key types that must match exactly (order matters).
|
||||
host keys = ssh-ed25519
|
||||
|
||||
# Host key types that may optionally appear.
|
||||
optional host keys = ssh-ed25519-cert-v01@openssh.com, rsa-sha2-256-cert-v01@openssh.com, rsa-sha2-512-cert-v01@openssh.com
|
||||
|
||||
# The key exchange algorithms that must match exactly (order matters).
|
||||
key exchanges = curve25519-sha256, curve25519-sha256@libssh.org, diffie-hellman-group16-sha512, diffie-hellman-group18-sha512, diffie-hellman-group-exchange-sha256
|
||||
|
||||
# The ciphers that must match exactly (order matters).
|
||||
ciphers = chacha20-poly1305@openssh.com, aes256-gcm@openssh.com, aes128-gcm@openssh.com, aes256-ctr, aes192-ctr, aes128-ctr
|
||||
|
||||
# The MACs that must match exactly (order matters).
|
||||
macs = hmac-sha2-256-etm@openssh.com, hmac-sha2-512-etm@openssh.com, umac-128-etm@openssh.com
|
||||
@@ -1,24 +0,0 @@
|
||||
#
|
||||
# Official policy for hardened OpenSSH v7.8.
|
||||
#
|
||||
|
||||
name = "Hardened OpenSSH v7.8"
|
||||
version = 1
|
||||
|
||||
# Group exchange DH modulus sizes.
|
||||
dh_modulus_size_diffie-hellman-group-exchange-sha256 = 2048
|
||||
|
||||
# The host key types that must match exactly (order matters).
|
||||
host keys = ssh-ed25519
|
||||
|
||||
# Host key types that may optionally appear.
|
||||
optional host keys = ssh-ed25519-cert-v01@openssh.com, rsa-sha2-256-cert-v01@openssh.com, rsa-sha2-512-cert-v01@openssh.com
|
||||
|
||||
# The key exchange algorithms that must match exactly (order matters).
|
||||
key exchanges = curve25519-sha256, curve25519-sha256@libssh.org, diffie-hellman-group16-sha512, diffie-hellman-group18-sha512, diffie-hellman-group-exchange-sha256
|
||||
|
||||
# The ciphers that must match exactly (order matters).
|
||||
ciphers = chacha20-poly1305@openssh.com, aes256-gcm@openssh.com, aes128-gcm@openssh.com, aes256-ctr, aes192-ctr, aes128-ctr
|
||||
|
||||
# The MACs that must match exactly (order matters).
|
||||
macs = hmac-sha2-256-etm@openssh.com, hmac-sha2-512-etm@openssh.com, umac-128-etm@openssh.com
|
||||
@@ -1,24 +0,0 @@
|
||||
#
|
||||
# Official policy for hardened OpenSSH v7.9.
|
||||
#
|
||||
|
||||
name = "Hardened OpenSSH v7.9"
|
||||
version = 1
|
||||
|
||||
# Group exchange DH modulus sizes.
|
||||
dh_modulus_size_diffie-hellman-group-exchange-sha256 = 2048
|
||||
|
||||
# The host key types that must match exactly (order matters).
|
||||
host keys = ssh-ed25519
|
||||
|
||||
# Host key types that may optionally appear.
|
||||
optional host keys = ssh-ed25519-cert-v01@openssh.com, rsa-sha2-256-cert-v01@openssh.com, rsa-sha2-512-cert-v01@openssh.com
|
||||
|
||||
# The key exchange algorithms that must match exactly (order matters).
|
||||
key exchanges = curve25519-sha256, curve25519-sha256@libssh.org, diffie-hellman-group16-sha512, diffie-hellman-group18-sha512, diffie-hellman-group-exchange-sha256
|
||||
|
||||
# The ciphers that must match exactly (order matters).
|
||||
ciphers = chacha20-poly1305@openssh.com, aes256-gcm@openssh.com, aes128-gcm@openssh.com, aes256-ctr, aes192-ctr, aes128-ctr
|
||||
|
||||
# The MACs that must match exactly (order matters).
|
||||
macs = hmac-sha2-256-etm@openssh.com, hmac-sha2-512-etm@openssh.com, umac-128-etm@openssh.com
|
||||
@@ -1,24 +0,0 @@
|
||||
#
|
||||
# Official policy for hardened OpenSSH v8.0.
|
||||
#
|
||||
|
||||
name = "Hardened OpenSSH v8.0"
|
||||
version = 1
|
||||
|
||||
# Group exchange DH modulus sizes.
|
||||
dh_modulus_size_diffie-hellman-group-exchange-sha256 = 2048
|
||||
|
||||
# The host key types that must match exactly (order matters).
|
||||
host keys = ssh-ed25519
|
||||
|
||||
# Host key types that may optionally appear.
|
||||
optional host keys = ssh-ed25519-cert-v01@openssh.com, rsa-sha2-256-cert-v01@openssh.com, rsa-sha2-512-cert-v01@openssh.com
|
||||
|
||||
# The key exchange algorithms that must match exactly (order matters).
|
||||
key exchanges = curve25519-sha256, curve25519-sha256@libssh.org, diffie-hellman-group16-sha512, diffie-hellman-group18-sha512, diffie-hellman-group-exchange-sha256
|
||||
|
||||
# The ciphers that must match exactly (order matters).
|
||||
ciphers = chacha20-poly1305@openssh.com, aes256-gcm@openssh.com, aes128-gcm@openssh.com, aes256-ctr, aes192-ctr, aes128-ctr
|
||||
|
||||
# The MACs that must match exactly (order matters).
|
||||
macs = hmac-sha2-256-etm@openssh.com, hmac-sha2-512-etm@openssh.com, umac-128-etm@openssh.com
|
||||
@@ -1,24 +0,0 @@
|
||||
#
|
||||
# Official policy for hardened OpenSSH v8.1.
|
||||
#
|
||||
|
||||
name = "Hardened OpenSSH v8.1"
|
||||
version = 1
|
||||
|
||||
# Group exchange DH modulus sizes.
|
||||
dh_modulus_size_diffie-hellman-group-exchange-sha256 = 2048
|
||||
|
||||
# The host key types that must match exactly (order matters).
|
||||
host keys = ssh-ed25519
|
||||
|
||||
# Host key types that may optionally appear.
|
||||
optional host keys = sk-ssh-ed25519@openssh.com, ssh-ed25519-cert-v01@openssh.com, sk-ssh-ed25519-cert-v01@openssh.com, rsa-sha2-256-cert-v01@openssh.com, rsa-sha2-512-cert-v01@openssh.com
|
||||
|
||||
# The key exchange algorithms that must match exactly (order matters).
|
||||
key exchanges = curve25519-sha256, curve25519-sha256@libssh.org, diffie-hellman-group16-sha512, diffie-hellman-group18-sha512, diffie-hellman-group-exchange-sha256
|
||||
|
||||
# The ciphers that must match exactly (order matters).
|
||||
ciphers = chacha20-poly1305@openssh.com, aes256-gcm@openssh.com, aes128-gcm@openssh.com, aes256-ctr, aes192-ctr, aes128-ctr
|
||||
|
||||
# The MACs that must match exactly (order matters).
|
||||
macs = hmac-sha2-256-etm@openssh.com, hmac-sha2-512-etm@openssh.com, umac-128-etm@openssh.com
|
||||
@@ -1,28 +0,0 @@
|
||||
#
|
||||
# Official policy for hardened OpenSSH v8.2.
|
||||
#
|
||||
|
||||
name = "Hardened OpenSSH v8.2"
|
||||
version = 1
|
||||
|
||||
# RSA host key sizes.
|
||||
hostkey_size_rsa-sha2-256 = 4096
|
||||
hostkey_size_rsa-sha2-512 = 4096
|
||||
|
||||
# Group exchange DH modulus sizes.
|
||||
dh_modulus_size_diffie-hellman-group-exchange-sha256 = 2048
|
||||
|
||||
# The host key types that must match exactly (order matters).
|
||||
host keys = rsa-sha2-512, rsa-sha2-256, ssh-ed25519
|
||||
|
||||
# Host key types that may optionally appear.
|
||||
optional host keys = sk-ssh-ed25519@openssh.com, ssh-ed25519-cert-v01@openssh.com, sk-ssh-ed25519-cert-v01@openssh.com, rsa-sha2-256-cert-v01@openssh.com, rsa-sha2-512-cert-v01@openssh.com
|
||||
|
||||
# The key exchange algorithms that must match exactly (order matters).
|
||||
key exchanges = curve25519-sha256, curve25519-sha256@libssh.org, diffie-hellman-group16-sha512, diffie-hellman-group18-sha512, diffie-hellman-group-exchange-sha256
|
||||
|
||||
# The ciphers that must match exactly (order matters).
|
||||
ciphers = chacha20-poly1305@openssh.com, aes256-gcm@openssh.com, aes128-gcm@openssh.com, aes256-ctr, aes192-ctr, aes128-ctr
|
||||
|
||||
# The MACs that must match exactly (order matters).
|
||||
macs = hmac-sha2-256-etm@openssh.com, hmac-sha2-512-etm@openssh.com, umac-128-etm@openssh.com
|
||||
@@ -1,28 +0,0 @@
|
||||
#
|
||||
# Official policy for hardened OpenSSH v8.3.
|
||||
#
|
||||
|
||||
name = "Hardened OpenSSH v8.3"
|
||||
version = 1
|
||||
|
||||
# RSA host key sizes.
|
||||
hostkey_size_rsa-sha2-256 = 4096
|
||||
hostkey_size_rsa-sha2-512 = 4096
|
||||
|
||||
# Group exchange DH modulus sizes.
|
||||
dh_modulus_size_diffie-hellman-group-exchange-sha256 = 2048
|
||||
|
||||
# The host key types that must match exactly (order matters).
|
||||
host keys = rsa-sha2-512, rsa-sha2-256, ssh-ed25519
|
||||
|
||||
# Host key types that may optionally appear.
|
||||
optional host keys = sk-ssh-ed25519@openssh.com, ssh-ed25519-cert-v01@openssh.com, sk-ssh-ed25519-cert-v01@openssh.com, rsa-sha2-256-cert-v01@openssh.com, rsa-sha2-512-cert-v01@openssh.com
|
||||
|
||||
# The key exchange algorithms that must match exactly (order matters).
|
||||
key exchanges = curve25519-sha256, curve25519-sha256@libssh.org, diffie-hellman-group16-sha512, diffie-hellman-group18-sha512, diffie-hellman-group-exchange-sha256
|
||||
|
||||
# The ciphers that must match exactly (order matters).
|
||||
ciphers = chacha20-poly1305@openssh.com, aes256-gcm@openssh.com, aes128-gcm@openssh.com, aes256-ctr, aes192-ctr, aes128-ctr
|
||||
|
||||
# The MACs that must match exactly (order matters).
|
||||
macs = hmac-sha2-256-etm@openssh.com, hmac-sha2-512-etm@openssh.com, umac-128-etm@openssh.com
|
||||
@@ -1,28 +0,0 @@
|
||||
#
|
||||
# Official policy for hardened OpenSSH v8.4.
|
||||
#
|
||||
|
||||
name = "Hardened OpenSSH v8.4"
|
||||
version = 1
|
||||
|
||||
# RSA host key sizes.
|
||||
hostkey_size_rsa-sha2-256 = 4096
|
||||
hostkey_size_rsa-sha2-512 = 4096
|
||||
|
||||
# Group exchange DH modulus sizes.
|
||||
dh_modulus_size_diffie-hellman-group-exchange-sha256 = 2048
|
||||
|
||||
# The host key types that must match exactly (order matters).
|
||||
host keys = rsa-sha2-512, rsa-sha2-256, ssh-ed25519
|
||||
|
||||
# Host key types that may optionally appear.
|
||||
optional host keys = sk-ssh-ed25519@openssh.com, ssh-ed25519-cert-v01@openssh.com, sk-ssh-ed25519-cert-v01@openssh.com, rsa-sha2-256-cert-v01@openssh.com, rsa-sha2-512-cert-v01@openssh.com
|
||||
|
||||
# The key exchange algorithms that must match exactly (order matters).
|
||||
key exchanges = curve25519-sha256, curve25519-sha256@libssh.org, diffie-hellman-group16-sha512, diffie-hellman-group18-sha512, diffie-hellman-group-exchange-sha256
|
||||
|
||||
# The ciphers that must match exactly (order matters).
|
||||
ciphers = chacha20-poly1305@openssh.com, aes256-gcm@openssh.com, aes128-gcm@openssh.com, aes256-ctr, aes192-ctr, aes128-ctr
|
||||
|
||||
# The MACs that must match exactly (order matters).
|
||||
macs = hmac-sha2-256-etm@openssh.com, hmac-sha2-512-etm@openssh.com, umac-128-etm@openssh.com
|
||||
@@ -1,19 +0,0 @@
|
||||
#
|
||||
# Official policy for hardened OpenSSH on Ubuntu 16.04 LTS.
|
||||
#
|
||||
|
||||
client policy = true
|
||||
name = "Hardened Ubuntu Client 16.04 LTS"
|
||||
version = 1
|
||||
|
||||
# The host key types that must match exactly (order matters).
|
||||
host keys = ssh-ed25519, ssh-ed25519-cert-v01@openssh.com, rsa-sha2-256, rsa-sha2-512, ssh-rsa-cert-v01@openssh.com
|
||||
|
||||
# The key exchange algorithms that must match exactly (order matters).
|
||||
key exchanges = curve25519-sha256@libssh.org, diffie-hellman-group-exchange-sha256, ext-info-c
|
||||
|
||||
# The ciphers that must match exactly (order matters).
|
||||
ciphers = chacha20-poly1305@openssh.com, aes256-gcm@openssh.com, aes128-gcm@openssh.com, aes256-ctr, aes192-ctr, aes128-ctr
|
||||
|
||||
# The MACs that must match exactly (order matters).
|
||||
macs = hmac-sha2-256-etm@openssh.com, hmac-sha2-512-etm@openssh.com, umac-128-etm@openssh.com
|
||||
@@ -1,19 +0,0 @@
|
||||
#
|
||||
# Official policy for hardened OpenSSH on Ubuntu 18.04 LTS.
|
||||
#
|
||||
|
||||
client policy = true
|
||||
name = "Hardened Ubuntu Client 18.04 LTS"
|
||||
version = 1
|
||||
|
||||
# The host key types that must match exactly (order matters).
|
||||
host keys = ssh-ed25519, ssh-ed25519-cert-v01@openssh.com, rsa-sha2-256, rsa-sha2-512, ssh-rsa-cert-v01@openssh.com
|
||||
|
||||
# The key exchange algorithms that must match exactly (order matters).
|
||||
key exchanges = curve25519-sha256, curve25519-sha256@libssh.org, diffie-hellman-group16-sha512, diffie-hellman-group18-sha512, diffie-hellman-group-exchange-sha256, ext-info-c
|
||||
|
||||
# The ciphers that must match exactly (order matters).
|
||||
ciphers = chacha20-poly1305@openssh.com, aes256-gcm@openssh.com, aes128-gcm@openssh.com, aes256-ctr, aes192-ctr, aes128-ctr
|
||||
|
||||
# The MACs that must match exactly (order matters).
|
||||
macs = hmac-sha2-256-etm@openssh.com, hmac-sha2-512-etm@openssh.com, umac-128-etm@openssh.com
|
||||
@@ -1,19 +0,0 @@
|
||||
#
|
||||
# Official policy for hardened OpenSSH on Ubuntu 20.04 LTS.
|
||||
#
|
||||
|
||||
client policy = true
|
||||
name = "Hardened Ubuntu Client 20.04 LTS"
|
||||
version = 1
|
||||
|
||||
# The host key types that must match exactly (order matters).
|
||||
host keys = ssh-ed25519, ssh-ed25519-cert-v01@openssh.com, sk-ssh-ed25519@openssh.com, sk-ssh-ed25519-cert-v01@openssh.com, rsa-sha2-256, rsa-sha2-256-cert-v01@openssh.com, rsa-sha2-512, rsa-sha2-512-cert-v01@openssh.com, ssh-rsa-cert-v01@openssh.com
|
||||
|
||||
# The key exchange algorithms that must match exactly (order matters).
|
||||
key exchanges = curve25519-sha256, curve25519-sha256@libssh.org, diffie-hellman-group16-sha512, diffie-hellman-group18-sha512, diffie-hellman-group-exchange-sha256, ext-info-c
|
||||
|
||||
# The ciphers that must match exactly (order matters).
|
||||
ciphers = chacha20-poly1305@openssh.com, aes256-gcm@openssh.com, aes128-gcm@openssh.com, aes256-ctr, aes192-ctr, aes128-ctr
|
||||
|
||||
# The MACs that must match exactly (order matters).
|
||||
macs = hmac-sha2-256-etm@openssh.com, hmac-sha2-512-etm@openssh.com, umac-128-etm@openssh.com
|
||||
@@ -1,24 +0,0 @@
|
||||
#
|
||||
# Official policy for hardened OpenSSH on Ubuntu Server 16.04 LTS.
|
||||
#
|
||||
|
||||
name = "Hardened Ubuntu Server 16.04 LTS"
|
||||
version = 1
|
||||
|
||||
# Group exchange DH modulus sizes.
|
||||
dh_modulus_size_diffie-hellman-group-exchange-sha256 = 2048
|
||||
|
||||
# The host key types that must match exactly (order matters).
|
||||
host keys = ssh-ed25519
|
||||
|
||||
# Host key types that may optionally appear.
|
||||
optional host keys = ssh-ed25519-cert-v01@openssh.com, rsa-sha2-256-cert-v01@openssh.com, rsa-sha2-512-cert-v01@openssh.com
|
||||
|
||||
# The key exchange algorithms that must match exactly (order matters).
|
||||
key exchanges = curve25519-sha256@libssh.org, diffie-hellman-group-exchange-sha256
|
||||
|
||||
# The ciphers that must match exactly (order matters).
|
||||
ciphers = chacha20-poly1305@openssh.com, aes256-gcm@openssh.com, aes128-gcm@openssh.com, aes256-ctr, aes192-ctr, aes128-ctr
|
||||
|
||||
# The MACs that must match exactly (order matters).
|
||||
macs = hmac-sha2-256-etm@openssh.com, hmac-sha2-512-etm@openssh.com, umac-128-etm@openssh.com
|
||||
@@ -1,24 +0,0 @@
|
||||
#
|
||||
# Official policy for hardened OpenSSH on Ubuntu Server 18.04 LTS.
|
||||
#
|
||||
|
||||
name = "Hardened Ubuntu Server 18.04 LTS"
|
||||
version = 1
|
||||
|
||||
# Group exchange DH modulus sizes.
|
||||
dh_modulus_size_diffie-hellman-group-exchange-sha256 = 2048
|
||||
|
||||
# The host key types that must match exactly (order matters).
|
||||
host keys = ssh-ed25519
|
||||
|
||||
# Host key types that may optionally appear.
|
||||
optional host keys = ssh-ed25519-cert-v01@openssh.com, rsa-sha2-256-cert-v01@openssh.com, rsa-sha2-512-cert-v01@openssh.com
|
||||
|
||||
# The key exchange algorithms that must match exactly (order matters).
|
||||
key exchanges = curve25519-sha256, curve25519-sha256@libssh.org, diffie-hellman-group16-sha512, diffie-hellman-group18-sha512, diffie-hellman-group-exchange-sha256
|
||||
|
||||
# The ciphers that must match exactly (order matters).
|
||||
ciphers = chacha20-poly1305@openssh.com, aes256-gcm@openssh.com, aes128-gcm@openssh.com, aes256-ctr, aes192-ctr, aes128-ctr
|
||||
|
||||
# The MACs that must match exactly (order matters).
|
||||
macs = hmac-sha2-256-etm@openssh.com, hmac-sha2-512-etm@openssh.com, umac-128-etm@openssh.com
|
||||
@@ -1,28 +0,0 @@
|
||||
#
|
||||
# Official policy for hardened OpenSSH on Ubuntu Server 20.04 LTS.
|
||||
#
|
||||
|
||||
name = "Hardened Ubuntu Server 20.04 LTS"
|
||||
version = 1
|
||||
|
||||
# RSA host key sizes.
|
||||
hostkey_size_rsa-sha2-256 = 4096
|
||||
hostkey_size_rsa-sha2-512 = 4096
|
||||
|
||||
# Group exchange DH modulus sizes.
|
||||
dh_modulus_size_diffie-hellman-group-exchange-sha256 = 2048
|
||||
|
||||
# The host key types that must match exactly (order matters).
|
||||
host keys = rsa-sha2-512, rsa-sha2-256, ssh-ed25519
|
||||
|
||||
# Host key types that may optionally appear.
|
||||
optional host keys = sk-ssh-ed25519@openssh.com, ssh-ed25519-cert-v01@openssh.com, sk-ssh-ed25519-cert-v01@openssh.com, rsa-sha2-256-cert-v01@openssh.com, rsa-sha2-512-cert-v01@openssh.com
|
||||
|
||||
# The key exchange algorithms that must match exactly (order matters).
|
||||
key exchanges = curve25519-sha256, curve25519-sha256@libssh.org, diffie-hellman-group16-sha512, diffie-hellman-group18-sha512, diffie-hellman-group-exchange-sha256
|
||||
|
||||
# The ciphers that must match exactly (order matters).
|
||||
ciphers = chacha20-poly1305@openssh.com, aes256-gcm@openssh.com, aes128-gcm@openssh.com, aes256-ctr, aes192-ctr, aes128-ctr
|
||||
|
||||
# The MACs that must match exactly (order matters).
|
||||
macs = hmac-sha2-256-etm@openssh.com, hmac-sha2-512-etm@openssh.com, umac-128-etm@openssh.com
|
||||
+121
-8
@@ -22,7 +22,7 @@
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
from typing import Dict, List, Tuple
|
||||
from typing import Optional, Any
|
||||
from typing import Optional, Any, Union, cast
|
||||
from datetime import date
|
||||
|
||||
from ssh_audit.ssh2_kex import SSH2_Kex # pylint: disable=unused-import
|
||||
@@ -32,7 +32,49 @@ from ssh_audit.banner import Banner
|
||||
# Validates policy files and performs policy testing
|
||||
class Policy:
|
||||
|
||||
def __init__(self, policy_file: Optional[str] = None, policy_data: Optional[str] = None) -> None:
|
||||
# Each field maps directly to a private member variable of the Policy class.
|
||||
BUILTIN_POLICIES = {
|
||||
|
||||
# Ubuntu Server policies
|
||||
|
||||
'Hardened Ubuntu Server 16.04 LTS (version 1)': {'version': '1', 'banner': None, 'compressions': None, 'host_keys': ['ssh-ed25519'], 'optional_host_keys': ['ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com'], 'kex': ['curve25519-sha256@libssh.org', 'diffie-hellman-group-exchange-sha256'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes128-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@openssh.com'], 'hostkey_sizes': None, 'cakey_sizes': None, 'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 2048}, 'server_policy': True},
|
||||
|
||||
'Hardened Ubuntu Server 18.04 LTS (version 1)': {'version': '1', 'banner': None, 'compressions': None, 'host_keys': ['ssh-ed25519'], 'optional_host_keys': ['ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com'], 'kex': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes128-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@openssh.com'], 'hostkey_sizes': None, 'cakey_sizes': None, 'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 2048}, 'server_policy': True},
|
||||
|
||||
'Hardened Ubuntu Server 20.04 LTS (version 1)': {'version': '1', 'banner': None, 'compressions': None, 'host_keys': ['rsa-sha2-512', 'rsa-sha2-256', 'ssh-ed25519'], 'optional_host_keys': ['sk-ssh-ed25519@openssh.com', 'ssh-ed25519-cert-v01@openssh.com', 'sk-ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com'], 'kex': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes128-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@openssh.com'], 'hostkey_sizes': {'rsa-sha2-256': 4096, 'rsa-sha2-512': 4096}, 'cakey_sizes': None, 'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 2048}, 'server_policy': True},
|
||||
|
||||
|
||||
# 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-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com'], 'kex': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes128-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@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-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com'], 'kex': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes128-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@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-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com'], 'kex': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes128-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@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-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com'], 'kex': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes128-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@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-ed25519@openssh.com', 'ssh-ed25519-cert-v01@openssh.com', 'sk-ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com'], 'kex': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes128-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@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-ed25519@openssh.com', 'ssh-ed25519-cert-v01@openssh.com', 'sk-ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com'], 'kex': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes128-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@openssh.com'], 'hostkey_sizes': {'rsa-sha2-256': 4096, 'rsa-sha2-512': 4096}, 'cakey_sizes': None, 'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 2048}, 'server_policy': True},
|
||||
|
||||
'Hardened OpenSSH Server v8.3 (version 1)': {'version': '1', 'banner': None, 'compressions': None, 'host_keys': ['rsa-sha2-512', 'rsa-sha2-256', 'ssh-ed25519'], 'optional_host_keys': ['sk-ssh-ed25519@openssh.com', 'ssh-ed25519-cert-v01@openssh.com', 'sk-ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com'], 'kex': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes128-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@openssh.com'], 'hostkey_sizes': {'rsa-sha2-256': 4096, 'rsa-sha2-512': 4096}, 'cakey_sizes': None, 'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 2048}, 'server_policy': True},
|
||||
|
||||
'Hardened OpenSSH Server v8.4 (version 1)': {'version': '1', 'banner': None, 'compressions': None, 'host_keys': ['rsa-sha2-512', 'rsa-sha2-256', 'ssh-ed25519'], 'optional_host_keys': ['sk-ssh-ed25519@openssh.com', 'ssh-ed25519-cert-v01@openssh.com', 'sk-ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com'], 'kex': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes128-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@openssh.com'], 'hostkey_sizes': {'rsa-sha2-256': 4096, 'rsa-sha2-512': 4096}, 'cakey_sizes': None, 'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 2048}, 'server_policy': True},
|
||||
|
||||
|
||||
# Ubuntu Client policies
|
||||
|
||||
'Hardened Ubuntu Client 16.04 LTS (version 1)': {'version': '1', 'banner': None, 'compressions': None, 'host_keys': ['ssh-ed25519', 'ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256', 'rsa-sha2-512', 'ssh-rsa-cert-v01@openssh.com'], 'optional_host_keys': None, 'kex': ['curve25519-sha256@libssh.org', 'diffie-hellman-group-exchange-sha256', 'ext-info-c'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes128-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@openssh.com'], 'hostkey_sizes': None, 'cakey_sizes': None, 'dh_modulus_sizes': None, 'server_policy': False},
|
||||
|
||||
'Hardened Ubuntu Client 18.04 LTS (version 1)': {'version': '1', 'banner': None, 'compressions': None, 'host_keys': ['ssh-ed25519', 'ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256', 'rsa-sha2-512', 'ssh-rsa-cert-v01@openssh.com'], 'optional_host_keys': None, 'kex': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256', 'ext-info-c'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes128-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@openssh.com'], 'hostkey_sizes': None, 'cakey_sizes': None, 'dh_modulus_sizes': None, 'server_policy': False},
|
||||
|
||||
'Hardened Ubuntu Client 20.04 LTS (version 1)': {'version': '1', 'banner': None, 'compressions': None, 'host_keys': ['ssh-ed25519', 'ssh-ed25519-cert-v01@openssh.com', 'sk-ssh-ed25519@openssh.com', 'sk-ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512', 'rsa-sha2-512-cert-v01@openssh.com', 'ssh-rsa-cert-v01@openssh.com'], 'optional_host_keys': None, 'kex': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256', 'ext-info-c'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes128-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@openssh.com'], 'hostkey_sizes': None, 'cakey_sizes': None, 'dh_modulus_sizes': None, 'server_policy': False},
|
||||
|
||||
} # type: Dict[str, Dict[str, Union[Optional[str], Optional[List[str]], bool, Dict[str, int]]]]
|
||||
|
||||
|
||||
def __init__(self, policy_file: Optional[str] = None, policy_data: Optional[str] = None, manual_load: bool = False) -> None:
|
||||
self._name = None # type: Optional[str]
|
||||
self._version = None # type: Optional[str]
|
||||
self._banner = None # type: Optional[str]
|
||||
@@ -47,10 +89,22 @@ class Policy:
|
||||
self._dh_modulus_sizes = None # type: Optional[Dict[str, int]]
|
||||
self._server_policy = True
|
||||
|
||||
if (policy_file is None) and (policy_data is None):
|
||||
raise RuntimeError('policy_file and policy_data must not both be None.')
|
||||
elif (policy_file is not None) and (policy_data is not None):
|
||||
raise RuntimeError('policy_file and policy_data must not both be specified.')
|
||||
self._name_and_version = '' # type: str
|
||||
|
||||
# Ensure that only one mode was specified.
|
||||
num_modes = 0
|
||||
if policy_file is not None:
|
||||
num_modes += 1
|
||||
if policy_data is not None:
|
||||
num_modes += 1
|
||||
if manual_load is True:
|
||||
num_modes += 1
|
||||
|
||||
if num_modes != 1:
|
||||
raise RuntimeError('Exactly one of the following can be specified only: policy_file, policy_data, or manual_load')
|
||||
|
||||
if manual_load:
|
||||
return
|
||||
|
||||
if policy_file is not None:
|
||||
with open(policy_file, "r") as f:
|
||||
@@ -142,6 +196,8 @@ class Policy:
|
||||
if self._version is None:
|
||||
raise ValueError('The policy does not have a version field.')
|
||||
|
||||
self._name_and_version = "%s (version %s)" % (self._name, self._version)
|
||||
|
||||
|
||||
@staticmethod
|
||||
def _append_error(errors: List[Any], mismatched_field: str, expected_required: Optional[List[str]], expected_optional: Optional[List[str]], actual: List[str]) -> None:
|
||||
@@ -339,7 +395,7 @@ macs = %s
|
||||
|
||||
def get_name_and_version(self) -> str:
|
||||
'''Returns a string of this Policy's name and version.'''
|
||||
return '%s (version %s)' % (self._name, self._version)
|
||||
return self._name_and_version
|
||||
|
||||
|
||||
def is_server_policy(self) -> bool:
|
||||
@@ -347,6 +403,50 @@ macs = %s
|
||||
return self._server_policy
|
||||
|
||||
|
||||
@staticmethod
|
||||
def list_builtin_policies() -> Tuple[List[str], List[str]]:
|
||||
'''Returns two lists: a list of names of built-in server policies, and a list of names of built-in client policies, respectively.'''
|
||||
server_policy_names = []
|
||||
client_policy_names = []
|
||||
|
||||
for policy_name in Policy.BUILTIN_POLICIES:
|
||||
if Policy.BUILTIN_POLICIES[policy_name]['server_policy']:
|
||||
server_policy_names.append(policy_name)
|
||||
else:
|
||||
client_policy_names.append(policy_name)
|
||||
|
||||
server_policy_names.sort()
|
||||
client_policy_names.sort()
|
||||
return server_policy_names, client_policy_names
|
||||
|
||||
|
||||
@staticmethod
|
||||
def load_builtin_policy(policy_name: str) -> Optional['Policy']:
|
||||
'''Returns a Policy with the specified built-in policy name loaded, or None if no policy of that name exists.'''
|
||||
p = None
|
||||
if policy_name in Policy.BUILTIN_POLICIES:
|
||||
policy_struct = Policy.BUILTIN_POLICIES[policy_name]
|
||||
p = Policy(manual_load=True)
|
||||
policy_name_without_version = policy_name[0:policy_name.rfind(' (')]
|
||||
p._name = policy_name_without_version # pylint: disable=protected-access
|
||||
p._version = cast(str, policy_struct['version']) # pylint: disable=protected-access
|
||||
p._banner = cast(Optional[str], policy_struct['banner']) # pylint: disable=protected-access
|
||||
p._compressions = cast(Optional[List[str]], policy_struct['compressions']) # pylint: disable=protected-access
|
||||
p._host_keys = cast(Optional[List[str]], policy_struct['host_keys']) # pylint: disable=protected-access
|
||||
p._optional_host_keys = cast(Optional[List[str]], policy_struct['optional_host_keys']) # pylint: disable=protected-access
|
||||
p._kex = cast(Optional[List[str]], policy_struct['kex']) # pylint: disable=protected-access
|
||||
p._ciphers = cast(Optional[List[str]], policy_struct['ciphers']) # pylint: disable=protected-access
|
||||
p._macs = cast(Optional[List[str]], policy_struct['macs']) # pylint: disable=protected-access
|
||||
p._hostkey_sizes = cast(Optional[Dict[str, int]], policy_struct['hostkey_sizes']) # pylint: disable=protected-access
|
||||
p._cakey_sizes = cast(Optional[Dict[str, int]], policy_struct['cakey_sizes']) # pylint: disable=protected-access
|
||||
p._dh_modulus_sizes = cast(Optional[Dict[str, int]], policy_struct['dh_modulus_sizes']) # pylint: disable=protected-access
|
||||
p._server_policy = cast(bool, policy_struct['server_policy']) # pylint: disable=protected-access
|
||||
|
||||
p._name_and_version = "%s (version %s)" % (p._name, p._version) # pylint: disable=protected-access
|
||||
|
||||
return p
|
||||
|
||||
|
||||
@staticmethod
|
||||
def _normalize_error_field(field: List[str]) -> Any:
|
||||
'''If field is an array with a string parsable as an integer, return that integer. Otherwise, return the field unmodified.'''
|
||||
@@ -367,9 +467,14 @@ macs = %s
|
||||
banner = undefined
|
||||
compressions_str = undefined
|
||||
host_keys_str = undefined
|
||||
optional_host_keys_str = undefined
|
||||
kex_str = undefined
|
||||
ciphers_str = undefined
|
||||
macs_str = undefined
|
||||
hostkey_sizes_str = undefined
|
||||
cakey_sizes_str = undefined
|
||||
dh_modulus_sizes_str = undefined
|
||||
|
||||
|
||||
if self._name is not None:
|
||||
name = '[%s]' % self._name
|
||||
@@ -382,11 +487,19 @@ macs = %s
|
||||
compressions_str = ', '.join(self._compressions)
|
||||
if self._host_keys is not None:
|
||||
host_keys_str = ', '.join(self._host_keys)
|
||||
if self._optional_host_keys is not None:
|
||||
optional_host_keys_str = ', '.join(self._optional_host_keys)
|
||||
if self._kex is not None:
|
||||
kex_str = ', '.join(self._kex)
|
||||
if self._ciphers is not None:
|
||||
ciphers_str = ', '.join(self._ciphers)
|
||||
if self._macs is not None:
|
||||
macs_str = ', '.join(self._macs)
|
||||
if self._hostkey_sizes is not None:
|
||||
hostkey_sizes_str = str(self._hostkey_sizes)
|
||||
if self._cakey_sizes is not None:
|
||||
cakey_sizes_str = str(self._cakey_sizes)
|
||||
if self._dh_modulus_sizes is not None:
|
||||
dh_modulus_sizes_str = str(self._dh_modulus_sizes)
|
||||
|
||||
return "Name: %s\nVersion: %s\nBanner: %s\nCompressions: %s\nHost Keys: %s\nKey Exchanges: %s\nCiphers: %s\nMACs: %s" % (name, version, banner, compressions_str, host_keys_str, kex_str, ciphers_str, macs_str)
|
||||
return "Name: %s\nVersion: %s\nBanner: %s\nCompressions: %s\nHost Keys: %s\nOptional Host Keys: %s\nKey Exchanges: %s\nCiphers: %s\nMACs: %s\nHost Key Sizes: %s\nCA Key Sizes: %s\nDH Modulus Sizes: %s\nServer Policy: %r" % (name, version, banner, compressions_str, host_keys_str, optional_host_keys_str, kex_str, ciphers_str, macs_str, hostkey_sizes_str, cakey_sizes_str, dh_modulus_sizes_str, self._server_policy)
|
||||
+19
-48
@@ -33,7 +33,7 @@ import traceback
|
||||
from typing import Dict, List, Set, Sequence, Tuple, Iterable # noqa: F401
|
||||
from typing import Callable, Optional, Union, Any # noqa: F401
|
||||
|
||||
from ssh_audit.globals import GITHUB_ISSUES_URL, VERSION
|
||||
from ssh_audit.globals import VERSION
|
||||
from ssh_audit.algorithm import Algorithm
|
||||
from ssh_audit.algorithms import Algorithms
|
||||
from ssh_audit.auditconf import AuditConf
|
||||
@@ -508,55 +508,22 @@ def evaluate_policy(aconf: AuditConf, banner: Optional['Banner'], client_host: O
|
||||
|
||||
|
||||
def list_policies() -> None:
|
||||
'''Prints a list of server & client policies.'''
|
||||
|
||||
# Get a list of all the files in the policies sub-directory, relative to the path of this script.
|
||||
installed_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
policies_dir = os.path.join(installed_dir, 'policies')
|
||||
server_policy_names, client_policy_names = Policy.list_builtin_policies()
|
||||
|
||||
# If the path is not a directory, print a useful error and exit.
|
||||
if not os.path.isdir(policies_dir):
|
||||
print("Error: could not find policies directory. Please report this full output to <%s>:" % GITHUB_ISSUES_URL)
|
||||
print("\nsys.argv[0]: %s" % sys.argv[0])
|
||||
print("__file__: %s" % __file__)
|
||||
print("policies_dir: %s" % policies_dir)
|
||||
sys.exit(exitcodes.UNKNOWN_ERROR)
|
||||
|
||||
# Get a list of all the files in the policies sub-directory.
|
||||
files = []
|
||||
for f in os.listdir(policies_dir):
|
||||
files.append(f)
|
||||
|
||||
files.sort() # Now the files will be in order, like 'ubuntu_client_16_04.txt', 'ubuntu_client_18_04.txt', 'ubuntu_client_20_04.txt', ...
|
||||
|
||||
server_policies_summary = []
|
||||
client_policies_summary = []
|
||||
for f in files:
|
||||
|
||||
# Load each policy, and generate a short summary from its name and absolute file path.
|
||||
policy_file = os.path.join(policies_dir, f)
|
||||
policy = Policy(policy_file=policy_file)
|
||||
policy_summary = "Name: %s\nPolicy path: %s" % (policy.get_name_and_version(), policy_file)
|
||||
|
||||
# We will print the server policies separately from thee client policies...
|
||||
if policy.is_server_policy():
|
||||
server_policies_summary.append(policy_summary)
|
||||
else:
|
||||
client_policies_summary.append(policy_summary)
|
||||
|
||||
if len(server_policies_summary) > 0:
|
||||
if len(server_policy_names) > 0:
|
||||
out.head('\nServer policies:\n')
|
||||
print("\n\n".join(server_policies_summary))
|
||||
print()
|
||||
print(" * \"%s\"" % "\"\n * \"".join(server_policy_names))
|
||||
|
||||
if len(client_policies_summary) > 0:
|
||||
if len(client_policy_names) > 0:
|
||||
out.head('\nClient policies:\n')
|
||||
print("\n\n".join(client_policies_summary))
|
||||
print()
|
||||
print(" * \"%s\"" % "\"\n * \"".join(client_policy_names))
|
||||
|
||||
if len(server_policies_summary) == 0 and len(client_policies_summary) == 0:
|
||||
print("Error: no built-in policies found in %s." % policies_dir)
|
||||
if len(server_policy_names) == 0 and len(client_policy_names) == 0:
|
||||
print("Error: no built-in policies found!")
|
||||
else:
|
||||
print("\nHint: Use -P and provide the path to a policy to run a policy scan.\n")
|
||||
print("\nHint: Use -P and provide the full name of a policy to run a policy scan with.\n")
|
||||
|
||||
|
||||
def make_policy(aconf: AuditConf, banner: Optional['Banner'], kex: Optional['SSH2_Kex'], client_host: Optional[str]) -> None:
|
||||
@@ -685,11 +652,15 @@ def process_commandline(args: List[str], usage_cb: Callable[..., None]) -> 'Audi
|
||||
|
||||
# If a policy file was provided, validate it.
|
||||
if (aconf.policy_file is not None) and (aconf.make_policy is False):
|
||||
try:
|
||||
aconf.policy = Policy(policy_file=aconf.policy_file)
|
||||
except Exception as e:
|
||||
print("Error while loading policy file: %s: %s" % (str(e), traceback.format_exc()))
|
||||
sys.exit(exitcodes.UNKNOWN_ERROR)
|
||||
|
||||
# First, see if this is a built-in policy name. If not, assume a file path was provided, and try to load it from disk.
|
||||
aconf.policy = Policy.load_builtin_policy(aconf.policy_file)
|
||||
if aconf.policy is None:
|
||||
try:
|
||||
aconf.policy = Policy(policy_file=aconf.policy_file)
|
||||
except Exception as e:
|
||||
print("Error while loading policy file: %s: %s" % (str(e), traceback.format_exc()))
|
||||
sys.exit(exitcodes.UNKNOWN_ERROR)
|
||||
|
||||
# If the user wants to do a client audit, but provided a server policy, terminate.
|
||||
if aconf.client_audit and aconf.policy.is_server_policy():
|
||||
|
||||
+20
-11
@@ -1,4 +1,4 @@
|
||||
.TH SSH-AUDIT 1 "July 16, 2020"
|
||||
.TH SSH-AUDIT 1 "October 19, 2020"
|
||||
.SH NAME
|
||||
\fBssh-audit\fP \- SSH server & client configuration auditor
|
||||
.SH SYNOPSIS
|
||||
@@ -59,7 +59,7 @@ Specify the minimum output level. Default is info.
|
||||
.TP
|
||||
.B -L, \-\-list-policies
|
||||
.br
|
||||
List all official, built-in policies for common systems. Their file paths can then be provided using -P/--policy=<path/to/policy.txt>.
|
||||
List all official, built-in policies for common systems. Their full names can then be passed to -P/--policy.
|
||||
|
||||
.TP
|
||||
.B \-\-lookup=<alg1,alg2,...>
|
||||
@@ -67,7 +67,7 @@ List all official, built-in policies for common systems. Their file paths can t
|
||||
Look up the security information of an algorithm(s) in the internal database. Does not connect to a server.
|
||||
|
||||
.TP
|
||||
.B -M, \-\-make-policy=<policy.txt>
|
||||
.B -M, \-\-make-policy=<custom_policy.txt>
|
||||
.br
|
||||
Creates a policy based on the target server. Useful when other servers should be compared to the target server's custom configuration (i.e.: a cluster environment). Note that the resulting policy can be edited manually.
|
||||
|
||||
@@ -82,7 +82,7 @@ Disable color output.
|
||||
The TCP port to connect to when auditing a server, or the port to listen on when auditing a client.
|
||||
|
||||
.TP
|
||||
.B -P, \-\-policy=<policy.txt>
|
||||
.B -P, \-\-policy=<"built-in policy name" | path/to/custom_policy.txt>
|
||||
.br
|
||||
Runs a policy audit against a target using the specified policy (see \fBPOLICY AUDIT\fP section for detailed description of this mode of operation). Combine with -c/--client-audit to audit a client configuration instead of a server. Use -L/--list-policies to list all official, built-in policies for common systems.
|
||||
|
||||
@@ -109,7 +109,7 @@ By default, \fBssh-audit\fP performs a standard audit. That is, it enumerates a
|
||||
|
||||
.SH POLICY AUDIT
|
||||
.PP
|
||||
When the -P/--policy=<policy.txt> option is used, \fBssh-audit\fP performs a policy audit. The target's host key types, key exchanges, ciphers, MACs, and other information is compared to a set of expected values defined in the specified policy file. If everything matches, only a short message stating a passing result is reported. Otherwise, the field(s) that did not match are reported.
|
||||
When the -P/--policy option is used, \fBssh-audit\fP performs a policy audit. The target's host key types, key exchanges, ciphers, MACs, and other information is compared to a set of expected values defined in the specified policy file. If everything matches, only a short message stating a passing result is reported. Otherwise, the field(s) that did not match are reported.
|
||||
|
||||
.PP
|
||||
Policy auditing is helpful for ensuring a group of related servers are properly hardened to an exact specification.
|
||||
@@ -140,7 +140,7 @@ ssh-audit -T servers.txt
|
||||
.RE
|
||||
|
||||
.LP
|
||||
To audit a client configuration (listens on port 2222 by default; connect using "ssh anything@localhost"):
|
||||
To audit a client configuration (listens on port 2222 by default; connect using "ssh -p 2222 anything@localhost"):
|
||||
.RS
|
||||
.nf
|
||||
ssh-audit -c
|
||||
@@ -156,7 +156,7 @@ ssh-audit -c -p 4567
|
||||
.RE
|
||||
|
||||
.LP
|
||||
To list all official built-in policies (hint: use resulting file paths with -P/--policy):
|
||||
To list all official built-in policies (hint: use their full names with -P/--policy):
|
||||
.RS
|
||||
.nf
|
||||
ssh-audit -L
|
||||
@@ -164,10 +164,19 @@ ssh-audit -L
|
||||
.RE
|
||||
|
||||
.LP
|
||||
To run a policy audit against a server:
|
||||
To run a built-in policy audit against a server (hint: use -L to see list of built-in policies):
|
||||
.RS
|
||||
.nf
|
||||
ssh-audit -P path/to/server_policy targetserver
|
||||
ssh-audit -P "Hardened Ubuntu Server 20.04 LTS (version 1)" targetserver
|
||||
.fi
|
||||
.RE
|
||||
|
||||
|
||||
.LP
|
||||
To run a custom policy audit against a server (hint: use -M/--make-policy to create a custom policy file):
|
||||
.RS
|
||||
.nf
|
||||
ssh-audit -P path/to/server_policy.txt targetserver
|
||||
.fi
|
||||
.RE
|
||||
|
||||
@@ -175,7 +184,7 @@ ssh-audit -P path/to/server_policy targetserver
|
||||
To run a policy audit against a client:
|
||||
.RS
|
||||
.nf
|
||||
ssh-audit -c -P path/to/client_policy
|
||||
ssh-audit -c -P ["policy name" | path/to/client_policy.txt]
|
||||
.fi
|
||||
.RE
|
||||
|
||||
@@ -183,7 +192,7 @@ ssh-audit -c -P path/to/client_policy
|
||||
To run a policy audit against many servers:
|
||||
.RS
|
||||
.nf
|
||||
ssh-audit -T servers.txt -P path/to/server_policy
|
||||
ssh-audit -T servers.txt -P ["policy name" | path/to/server_policy.txt]
|
||||
.fi
|
||||
.RE
|
||||
|
||||
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1 @@
|
||||
{"errors": [], "host": "localhost", "passed": true, "policy": "Hardened OpenSSH Server v8.0 (version 1)"}
|
||||
@@ -0,0 +1,3 @@
|
||||
Host: localhost:2222
|
||||
Policy: Hardened OpenSSH Server v8.0 (version 1)
|
||||
Result: [0;32m✔ Passed[0m
|
||||
@@ -0,0 +1 @@
|
||||
{"errors": [{"actual": ["umac-64-etm@openssh.com", "umac-128-etm@openssh.com", "hmac-sha2-256-etm@openssh.com", "hmac-sha2-512-etm@openssh.com", "hmac-sha1-etm@openssh.com", "umac-64@openssh.com", "umac-128@openssh.com", "hmac-sha2-256", "hmac-sha2-512", "hmac-sha1"], "expected_optional": [""], "expected_required": ["hmac-sha2-256-etm@openssh.com", "hmac-sha2-512-etm@openssh.com", "umac-128-etm@openssh.com"], "mismatched_field": "MACs"}], "host": "localhost", "passed": false, "policy": "Hardened OpenSSH Server v8.0 (version 1)"}
|
||||
@@ -0,0 +1,6 @@
|
||||
Host: localhost:2222
|
||||
Policy: Hardened OpenSSH Server v8.0 (version 1)
|
||||
Result: [0;31m❌ Failed![0m
|
||||
[0;33m
|
||||
Errors:
|
||||
* MACs did not match. Expected: ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@openssh.com']; Actual: ['umac-64-etm@openssh.com', 'umac-128-etm@openssh.com', 'hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'hmac-sha1-etm@openssh.com', 'umac-64@openssh.com', 'umac-128@openssh.com', 'hmac-sha2-256', 'hmac-sha2-512', 'hmac-sha1'][0m
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+18
-1
@@ -35,6 +35,23 @@ class TestPolicy:
|
||||
return self.ssh2_kex.parse(w.write_flush())
|
||||
|
||||
|
||||
def test_builtin_policy_consistency(self):
|
||||
'''Ensure that the BUILTIN_POLICIES struct is consistent.'''
|
||||
|
||||
for policy_name in Policy.BUILTIN_POLICIES:
|
||||
# Ensure that the policy name ends with " (version X)", where X is the 'version' field.
|
||||
version_str = " (version %s)" % Policy.BUILTIN_POLICIES[policy_name]['version']
|
||||
assert(policy_name.endswith(version_str))
|
||||
|
||||
# Ensure that each built-in policy can be loaded with Policy.load_builtin_policy().
|
||||
assert(Policy.load_builtin_policy(policy_name) is not None)
|
||||
|
||||
# Ensure that both server and client policy names are returned.
|
||||
server_policy_names, client_policy_names = Policy.list_builtin_policies()
|
||||
assert(len(server_policy_names) > 0)
|
||||
assert(len(client_policy_names) > 0)
|
||||
|
||||
|
||||
def test_policy_basic(self):
|
||||
'''Ensure that a basic policy can be parsed correctly.'''
|
||||
|
||||
@@ -49,7 +66,7 @@ ciphers = cipher_alg1, cipher_alg2, cipher_alg3
|
||||
macs = mac_alg1, mac_alg2, mac_alg3'''
|
||||
|
||||
policy = self.Policy(policy_data=policy_data)
|
||||
assert str(policy) == "Name: [Test Policy]\nVersion: [1]\nBanner: {undefined}\nCompressions: comp_alg1\nHost Keys: key_alg1\nKey Exchanges: kex_alg1, kex_alg2\nCiphers: cipher_alg1, cipher_alg2, cipher_alg3\nMACs: mac_alg1, mac_alg2, mac_alg3"
|
||||
assert str(policy) == "Name: [Test Policy]\nVersion: [1]\nBanner: {undefined}\nCompressions: comp_alg1\nHost Keys: key_alg1\nOptional Host Keys: {undefined}\nKey Exchanges: kex_alg1, kex_alg2\nCiphers: cipher_alg1, cipher_alg2, cipher_alg3\nMACs: mac_alg1, mac_alg2, mac_alg3\nHost Key Sizes: {undefined}\nCA Key Sizes: {undefined}\nDH Modulus Sizes: {undefined}\nServer Policy: True"
|
||||
|
||||
|
||||
def test_policy_invalid_1(self):
|
||||
|
||||
Reference in new issue
Block a user