summaryrefslogtreecommitdiff
path: root/jstests/ssl/ssl_x509_roles.js
blob: a0097bb59786644087d1657ccf9aaf354962c942 (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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// Test that a client can authenicate against the server with roles.
// Also validates RFC2253
load('jstests/ssl/libs/ssl_helpers.js');

(function() {
"use strict";

const SERVER_CERT = "jstests/libs/server.pem";
const CA_CERT = "jstests/libs/ca.pem";
const CLIENT_CERT = "jstests/libs/client_roles.pem";
const CLIENT_ESCAPE_CERT = "jstests/libs/client_escape.pem";
const CLIENT_UTF8_CERT = "jstests/libs/client_utf8.pem";
const CLIENT_EMAIL_CERT = "jstests/libs/client_email.pem";
const CLIENT_TITLE_CERT = "jstests/libs/client_title.pem";
const CLIENT_CERT_NO_ROLES = "jstests/libs/client.pem";

const CLIENT_USER =
    "C=US,ST=New York,L=New York City,O=MongoDB,OU=Kernel Users,CN=Kernel Client Peer Role";

const CLIENT_USER_NO_ROLES = "CN=client,OU=KernelUser,O=MongoDB,L=New York City,ST=New York,C=US";
const smokeScript = 'assert(db.getSiblingDB(\'$external\').auth({ mechanism: \'MONGODB-X509\' }));';

function authAndTest(port, expectSuccess) {
    // First we run the shell with the "smoke" user that has no embedded roles to verify
    // that X509 auth works overall.
    const smoke = runMongoProgram("mongo",
                                  "--host",
                                  "localhost",
                                  "--port",
                                  port,
                                  "--ssl",
                                  "--sslCAFile",
                                  CA_CERT,
                                  "--sslPEMKeyFile",
                                  CLIENT_CERT_NO_ROLES,
                                  "--eval",
                                  smokeScript);
    assert.eq(smoke, 0, "Could not auth with smoke user");

    const runTest = function(cert, script) {
        const res = runMongoProgram("mongo",
                                    "--host",
                                    "localhost",
                                    "--port",
                                    port,
                                    "--ssl",
                                    "--sslCAFile",
                                    CA_CERT,
                                    "--sslPEMKeyFile",
                                    cert,
                                    script);

        let expectExitCode = 0;
        if (!expectSuccess) {
            if (_isWindows()) {
                expectExitCode = -3;
            } else {
                expectExitCode = 253;
            }
        }

        assert.eq(expectExitCode, res, "Connection attempt failed");
    };

    // Then we assert success or failure with each of the X509 certs with embedded roles.
    runTest(CLIENT_CERT, "jstests/ssl/libs/ssl_x509_role_auth.js");
    runTest(CLIENT_ESCAPE_CERT, "jstests/ssl/libs/ssl_x509_role_auth_escape.js");
    runTest(CLIENT_UTF8_CERT, "jstests/ssl/libs/ssl_x509_role_auth_utf8.js");
    runTest(CLIENT_EMAIL_CERT, "jstests/ssl/libs/ssl_x509_role_auth_email.js");
}

const prepConn = function(conn) {
    const admin = conn.getDB('admin');
    admin.createUser({user: "admin", pwd: "admin", roles: ["root"]});
    assert(admin.auth('admin', 'admin'));

    const external = conn.getDB('$external');
    external.createUser({user: CLIENT_USER_NO_ROLES, roles: [{'role': 'readWrite', 'db': 'test'}]});
};

const x509_options = {
    sslMode: "requireSSL",
    sslPEMKeyFile: SERVER_CERT,
    sslCAFile: CA_CERT
};

print("1. Testing x.509 auth to mongod");
{
    let mongo = MongoRunner.runMongod(Object.merge(x509_options, {auth: ""}));
    prepConn(mongo);

    authAndTest(mongo.port, true);

    MongoRunner.stopMongod(mongo);
}

jsTestLog("2. Testing disabling x.509 auth with roles");
{
    const mongo = MongoRunner.runMongod(Object.merge(
        x509_options, {auth: "", setParameter: "allowRolesFromX509Certificates=false"}));

    prepConn(mongo);

    authAndTest(mongo.port, false);

    MongoRunner.stopMongod(mongo);
}

print("3. Testing x.509 auth to mongos");
{
    let st = new ShardingTest({
        shards: 1,
        mongos: 1,
        other: {
            keyFile: 'jstests/libs/key1',
            configOptions: x509_options,
            mongosOptions: x509_options,
            shardOptions: x509_options,
            useHostname: false
        }
    });

    prepConn(st.s0);
    authAndTest(st.s0.port, true);
    st.stop();
}

print("4. Testing x.509 auth to mongos with x509 roles disabled");
{
    const localOptions =
        Object.merge(x509_options, {setParameter: "allowRolesFromX509Certificates=false"});
    let st = new ShardingTest({
        shards: 1,
        mongos: 1,
        other: {
            keyFile: 'jstests/libs/key1',
            configOptions: localOptions,
            mongosOptions: localOptions,
            shardOptions: localOptions,
            useHostname: false
        }
    });

    prepConn(st.s0);
    authAndTest(st.s0.port, false);
    st.stop();
}
}());