mirror of
https://github.com/mongodb/mongo.git
synced 2024-11-30 17:10:48 +01:00
SERVER-36618 Write JS integration tests that validate whichever TLS suites are available on each Evergreen platform
This commit is contained in:
parent
82a07e2f04
commit
0169d181bd
@ -7014,6 +7014,20 @@ tasks:
|
||||
name: ssl
|
||||
commands:
|
||||
- func: "do setup"
|
||||
- command: shell.exec
|
||||
type: test
|
||||
params:
|
||||
working_dir: src
|
||||
script: |
|
||||
set -o errexit
|
||||
set -o verbose
|
||||
|
||||
${activate_virtualenv}
|
||||
if [ "Windows_NT" = "$OS" ]; then
|
||||
/cygdrive/c/python/python36/python.exe -m pip install -r etc/pip/evgtest-requirements.txt
|
||||
else
|
||||
python3 -m pip install -r etc/pip/evgtest-requirements.txt
|
||||
fi
|
||||
- func: "run tests"
|
||||
vars:
|
||||
resmoke_args: --suites=ssl --storageEngine=wiredTiger
|
||||
|
@ -2,5 +2,5 @@
|
||||
jira
|
||||
requests-oauth
|
||||
PyJWT # https://github.com/pycontribs/jira/issues/247
|
||||
cryptography # Needed for oauthlib to use RSAAlgorithm
|
||||
cryptography == 2.3 # Needed for oauthlib to use RSAAlgorithm # Version locked - see SERVER-36618
|
||||
# We are omitting pycrypto based on https://github.com/pycontribs/jira/pull/629
|
||||
|
@ -2,3 +2,5 @@
|
||||
pypiwin32==219; sys_platform == "win32" and python_version < "3"
|
||||
pypiwin32==223; sys_platform == "win32" and python_version > "3"
|
||||
subprocess32==3.5.2; os_name == "posix" and platform_release != "2.6.18-194.el5xen" and platform_release != "2.6.18-274.el5xen" and python_version < "3"
|
||||
# Needed for ssl_ECDHE_suites.js test - testing the TLS suites enabled on each platform
|
||||
sslyze==2.0.1; python_version >= "3.6" and sys_platform != "darwin"
|
||||
|
@ -6,12 +6,12 @@
|
||||
|
||||
# Common requirements
|
||||
asn1crypto==0.24.0
|
||||
boto3==1.9.14
|
||||
botocore==1.12.14
|
||||
boto3==1.9.16
|
||||
botocore==1.12.16
|
||||
certifi==2018.8.24
|
||||
cffi==1.11.5
|
||||
chardet==3.0.4
|
||||
cryptography==2.3.1
|
||||
cryptography==2.3
|
||||
defusedxml==0.5.0
|
||||
docutils==0.14
|
||||
idna==2.7
|
||||
@ -23,7 +23,7 @@ lazy-object-proxy==1.3.1
|
||||
MarkupSafe==1.0
|
||||
mccabe==0.6.1
|
||||
oauthlib==2.1.0
|
||||
pbr==4.2.0
|
||||
pbr==4.3.0
|
||||
psutil==5.4.7
|
||||
pycparser==2.19
|
||||
pydocstyle==2.1.1
|
||||
@ -68,3 +68,5 @@ typed-ast==1.1.0; python_version > "3"
|
||||
pypiwin32==219; sys_platform == "win32" and python_version < "3"
|
||||
pypiwin32==223; sys_platform == "win32" and python_version > "3"
|
||||
subprocess32==3.5.2; os_name == "posix" and platform_release != "2.6.18-194.el5xen" and platform_release != "2.6.18-274.el5xen" and python_version < "3"
|
||||
# Needed for ssl_ECDHE_suites.js test - testing the TLS suites enabled on each platform
|
||||
sslyze==2.0.1; python_version >= "3.6" and sys_platform != "darwin"
|
||||
|
93
jstests/ssl/ssl_ECDHE_suites.js
Normal file
93
jstests/ssl/ssl_ECDHE_suites.js
Normal file
@ -0,0 +1,93 @@
|
||||
// Test that a client can authenicate against the server with roles.
|
||||
// Also validates RFC2253
|
||||
load('jstests/ssl/libs/ssl_helpers.js');
|
||||
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
if (getBuildInfo().buildEnvironment.target_os === "macOS") {
|
||||
return;
|
||||
}
|
||||
|
||||
const suites = [
|
||||
"SSLV2 Cipher Suites",
|
||||
"SSLV3 Cipher Suites",
|
||||
"TLSV1_0 Cipher Suites",
|
||||
"TLSV1_1 Cipher Suites",
|
||||
"TLSV1_2 Cipher Suites",
|
||||
"TLSV1_3 Cipher Suites"
|
||||
];
|
||||
const SERVER_CERT = "jstests/libs/server.pem";
|
||||
|
||||
function runSSLYze(port) {
|
||||
let python = "/usr/bin/env python3";
|
||||
let sslyze = " jstests/ssl/sslyze_tester.py ";
|
||||
|
||||
if (_isWindows()) {
|
||||
const paths = ["c:\\python36\\python.exe", "c:\\python\\python36\\python.exe"];
|
||||
for (let p of paths) {
|
||||
if (fileExists(p)) {
|
||||
python = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const python_command = python + sslyze + "--port=" + port;
|
||||
let ret = 0;
|
||||
if (_isWindows()) {
|
||||
ret = runProgram('cmd.exe', '/c', python_command);
|
||||
} else {
|
||||
ret = runProgram('/bin/sh', '-c', python_command);
|
||||
}
|
||||
assert.eq(ret, 0);
|
||||
|
||||
try {
|
||||
let ciphers = cat("jstests/ssl/ciphers.json");
|
||||
let cipherDict = JSON.parse(ciphers);
|
||||
return cipherDict;
|
||||
} catch (e) {
|
||||
jsTestLog("Failed to parse: " + ciphers + "\n" + ciphers);
|
||||
throw e;
|
||||
} finally {
|
||||
const python_delete_command = python + sslyze + "--delete";
|
||||
if (_isWindows()) {
|
||||
ret = runProgram('cmd.exe', '/c', python_delete_command);
|
||||
} else {
|
||||
ret = runProgram('/bin/sh', '-c', python_delete_command);
|
||||
}
|
||||
assert.eq(ret, 0);
|
||||
}
|
||||
}
|
||||
|
||||
function testSSLYzeOutput(cipherDict) {
|
||||
// Checking that SSL 1.0, 2.0, 3.0 and TLS 1.0 are not accepted
|
||||
for (var i = 0; i < 3; i++) {
|
||||
assert.eq(cipherDict[suites[i]].length, 0);
|
||||
}
|
||||
|
||||
// Printing TLS 1.1, 1.2, and 1.3 suites that are accepted
|
||||
for (var i = 3; i < 6; i++) {
|
||||
const TLSVersion = cipherDict[suites[i]].toString().split(",");
|
||||
print('*************************\n' + suites[i] + ": ");
|
||||
for (var j = 0; j < TLSVersion.length; j++) {
|
||||
print(TLSVersion[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print("1. Testing x.509 auth to mongod");
|
||||
{
|
||||
const x509_options = {
|
||||
sslMode: "requireSSL",
|
||||
sslCAFile: CA_CERT,
|
||||
sslPEMKeyFile: SERVER_CERT,
|
||||
ipv6: "",
|
||||
bind_ip_all: ""
|
||||
};
|
||||
let mongod = MongoRunner.runMongod(x509_options);
|
||||
var cipherDict = runSSLYze(mongod.port);
|
||||
testSSLYzeOutput(cipherDict);
|
||||
|
||||
MongoRunner.stopMongod(mongod);
|
||||
}
|
||||
}());
|
52
jstests/ssl/sslyze_tester.py
Normal file
52
jstests/ssl/sslyze_tester.py
Normal file
@ -0,0 +1,52 @@
|
||||
#! /usr/bin/env python3
|
||||
|
||||
# This is a wrapper file around the SSLYze package
|
||||
# The SSLYze package is used for testing the TLS/SSL
|
||||
# suites that we allow for connections.
|
||||
import os, logging, json, argparse, urllib.parse
|
||||
from sslyze.synchronous_scanner import SynchronousScanner
|
||||
from sslyze.plugins import openssl_cipher_suites_plugin
|
||||
from sslyze.plugins.openssl_cipher_suites_plugin import *
|
||||
from sslyze.server_connectivity_tester import ServerConnectivityTester, ServerConnectivityError
|
||||
|
||||
path = str(os.path.dirname(os.path.abspath(__file__)))
|
||||
filename = f'{path}/ciphers.json'
|
||||
|
||||
def server_scanner(p):
|
||||
try:
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.info("Opening file")
|
||||
server_tester = ServerConnectivityTester(
|
||||
hostname = 'localhost',
|
||||
port=p
|
||||
)
|
||||
server_info = server_tester.perform()
|
||||
scanner = SynchronousScanner()
|
||||
|
||||
results = dict()
|
||||
suite_names = ['SSLV2 Cipher Suites', 'SSLV3 Cipher Suites', 'TLSV1_0 Cipher Suites', 'TLSV1_1 Cipher Suites', 'TLSV1_2 Cipher Suites', 'TLSV1_3 Cipher Suites']
|
||||
suites = [Sslv20ScanCommand, Sslv30ScanCommand, Tlsv10ScanCommand, Tlsv11ScanCommand, Tlsv12ScanCommand, Tlsv13ScanCommand]
|
||||
|
||||
logger.info("Scanning SSL/TLS suites, writing to ciphers.json")
|
||||
for suite_name, suite in zip(suite_names, suites):
|
||||
scan = scanner.run_scan_command(server_info, suite())
|
||||
results[suite_name] = [cipher.name for cipher in scan.accepted_cipher_list]
|
||||
|
||||
with open(filename, 'w') as outfile:
|
||||
json.dump(results, outfile)
|
||||
|
||||
except ServerConnectivityError as e:
|
||||
raise RuntimeError(f'Could not connect to {e.server_info.hostname}: {e.error_message}')
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='MongoDB SSL/TLS Suite Validation.')
|
||||
parser.add_argument('-p', '--port', type=int, default=27017, help="Port to listen on")
|
||||
parser.add_argument('-d', '--delete', action='store_true', help="Delete the ciphers.json file")
|
||||
args = parser.parse_args()
|
||||
if args.delete:
|
||||
os.remove(filename)
|
||||
else:
|
||||
return server_scanner(args.port)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Reference in New Issue
Block a user