summaryrefslogtreecommitdiff
path: root/jstests/libs/ssl_test.js
blob: 11874ebc01ee2aee7963a42da79def7b0fd0c607 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// The SSLTest class is used to check if a shell with a certain SSL configuration
// can be used to connect to a server with a given SSL configuration.
// This is necessary because SSL settings are currently process global - so if the mongo shell
// started by resmoke.py has an SSL configuration that's incompatible with a server created with
// MongoRunner, it will not be able to connect to it.

/**
 * A utility for checking if a shell configured with the specified command line options can
 * connect to a server with the specified command line options.
 *
 * The 'serverOpts' and 'clientOpts' objects are in the form of
 * {'cmdLineParam': 'value', ...}. For flag arguments, the empty string is used as the value.
 *
 * For serverOpts a few defaults are set if values are not provided: specifically 'sslMode'
 * (preferSSL), sslPEMKeyFile ("jstests/libs/server.pem"), and sslCAFile
 * "jstests/libs/ca.pem").
 */
function SSLTest(serverOpts, clientOpts) {
    var canonicalServerOpts = function(userProvidedOpts) {
        var canonical = Object.extend({}, userProvidedOpts || {});

        if (!canonical.hasOwnProperty("sslMode")) {
            canonical.sslMode = "preferSSL";
        } else if (canonical.sslMode === "disabled") {
            // should not add further options if SSL is disabled
            return canonical;
        }

        if (!canonical.hasOwnProperty("sslPEMKeyFile")) {
            canonical.sslPEMKeyFile = "jstests/libs/server.pem";
        }
        if (!canonical.hasOwnProperty("sslCAFile")) {
            canonical.sslCAFile = "jstests/libs/ca.pem";
        }
        return canonical;
    };

    this.serverOpts = MongoRunner.mongodOptions(canonicalServerOpts(serverOpts));
    this.port = this.serverOpts.port;
    resetDbpath(this.serverOpts.dbpath);

    this.clientOpts = Object.extend({}, clientOpts || this.defaultSSLClientOptions);
    this.clientOpts.port = this.port;
}

/**
 * The default shell arguments for a shell with SSL enabled.
 */
SSLTest.prototype.defaultSSLClientOptions = {
    "ssl": "",
    "sslPEMKeyFile": "jstests/libs/client.pem",
    "sslAllowInvalidCertificates": "",
    "eval": ";"  // prevent the shell from entering interactive mode
};

/**
 * The default shell arguments for a shell without SSL enabled.
 */
SSLTest.prototype.noSSLClientOptions = {
    eval: ";"  // prevent the shell from entering interactive mode
};

/**
 * Starts a server with the parameters passed to the fixture constructor and then attempts to
 * connect with a shell created with the configured options. Returns whether a connection
 * was successfully established.
 */
SSLTest.prototype.connectWorked = function() {
    var connectTimeoutMillis = 30000;

    var serverArgv = MongoRunner.arrOptions("mongod", this.serverOpts);
    var clientArgv = MongoRunner.arrOptions("mongo", this.clientOpts);

    var serverPID = _startMongoProgram.apply(null, serverArgv);
    try {
        assert.soon(function() {
            return checkProgram(serverPID) && (0 === _runMongoProgram.apply(null, clientArgv));
        }, "connect failed", connectTimeoutMillis);
    } catch (ex) {
        return false;
    } finally {
        _stopMongoProgram(this.port);
    }
    return true;
};