Skip to content

Commit 1040823

Browse files
authored
CDRIVER-5985 remove username derivation for MONGODB-X509 (#2000)
* add x509 Atlas auth test * remove no-longer-needed internal `mongoc_ssl_extract_subject` * add x509 tests with test certs * set up Kerberos config and keytab files in script ** Avoid persisting keytab file in `/tmp` directory. Avoid modifying system-shared `/etc/krb5.conf` * remove `prepare-kerberos` Evergreen function * update user and password in docs to match what is used in Evergreen
1 parent e22ab0c commit 1040823

19 files changed

+252
-393
lines changed

.evergreen/config_generator/components/funcs/prepare_kerberos.py

-36
This file was deleted.

.evergreen/generated_configs/functions.yml

-21
Original file line numberDiff line numberDiff line change
@@ -327,27 +327,6 @@ functions:
327327
args:
328328
- -c
329329
- .evergreen/scripts/compile-openssl-static.sh
330-
prepare-kerberos:
331-
- command: subprocess.exec
332-
type: setup
333-
params:
334-
binary: bash
335-
working_dir: mongoc
336-
silent: true
337-
args:
338-
- -c
339-
- |
340-
if test "${keytab|}" && command -v kinit >/dev/null; then
341-
echo "${keytab}" > /tmp/drivers.keytab.base64
342-
cat /tmp/drivers.keytab.base64 | base64 -d > /tmp/drivers.keytab
343-
if touch /etc/krb5.conf 2>/dev/null; then
344-
cat .evergreen/etc/kerberos.realm | tee -a /etc/krb5.conf
345-
elif command sudo true 2>/dev/null; then
346-
cat .evergreen/etc/kerberos.realm | sudo tee -a /etc/krb5.conf
347-
else
348-
echo "Cannot append kerberos.realm to /etc/krb5.conf; skipping." 1>&2
349-
fi
350-
fi
351330
restore-instance-profile:
352331
- command: subprocess.exec
353332
params:

.evergreen/generated_configs/legacy-config.yml

-5
Original file line numberDiff line numberDiff line change
@@ -1193,7 +1193,6 @@ tasks:
11931193
- func: fetch-build
11941194
vars:
11951195
BUILD_NAME: debug-compile-sasl-openssl
1196-
- func: prepare-kerberos
11971196
- func: run auth tests
11981197
- name: authentication-tests-darwinssl
11991198
tags:
@@ -1206,7 +1205,6 @@ tasks:
12061205
- func: fetch-build
12071206
vars:
12081207
BUILD_NAME: debug-compile-sasl-darwinssl
1209-
- func: prepare-kerberos
12101208
- func: run auth tests
12111209
- name: authentication-tests-winssl
12121210
tags:
@@ -1219,7 +1217,6 @@ tasks:
12191217
- func: fetch-build
12201218
vars:
12211219
BUILD_NAME: debug-compile-sspi-winssl
1222-
- func: prepare-kerberos
12231220
- func: run auth tests
12241221
- name: authentication-tests-openssl-nosasl
12251222
tags:
@@ -1232,7 +1229,6 @@ tasks:
12321229
- func: fetch-build
12331230
vars:
12341231
BUILD_NAME: debug-compile-nosasl-openssl
1235-
- func: prepare-kerberos
12361232
- func: run auth tests
12371233
- name: test-mongohouse
12381234
depends_on:
@@ -1260,7 +1256,6 @@ tasks:
12601256
script: |-
12611257
set -o errexit
12621258
env SANITIZE=address SASL=AUTO SSL=OPENSSL .evergreen/scripts/compile.sh
1263-
- func: prepare-kerberos
12641259
- func: run auth tests
12651260
vars:
12661261
ASAN: 'on'

.evergreen/legacy_config_generator/evergreen_config_lib/tasks.py

-2
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,6 @@ def additional_dependencies(self) -> Iterable[DependencySpec]:
612612

613613
def post_commands(self) -> Iterable[Value]:
614614
yield func("fetch-build", BUILD_NAME=self.build_task_name)
615-
yield func("prepare-kerberos")
616615
yield func("run auth tests")
617616

618617
@property
@@ -664,7 +663,6 @@ def pre_commands(self) -> Iterable[Value]:
664663
""",
665664
add_expansions_to_env=True,
666665
),
667-
func("prepare-kerberos"),
668666
func("run auth tests", ASAN="on"),
669667
],
670668
)

.evergreen/scripts/run-auth-tests.sh

+38-4
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,40 @@ mongoc_dir="$(to_absolute "${script_dir}/../..")"
1818
declare install_dir="${mongoc_dir}/install-dir"
1919
declare openssl_install_dir="${mongoc_dir}/openssl-install-dir"
2020

21+
# Create directory for secrets within Evergreen task directory. Task directory is cleaned up between tasks.
22+
declare secrets_dir
23+
secrets_dir="$(to_absolute "${mongoc_dir}/../secrets")"
24+
mkdir -p "${secrets_dir}"
25+
chmod 700 "${secrets_dir}"
26+
27+
# Create certificate to test X509 auth with Atlas:
28+
atlas_x509_path="${secrets_dir:?}/atlas_x509.pem"
29+
echo "${atlas_x509_cert_base64:?}" | base64 --decode > "${secrets_dir:?}/atlas_x509.pem"
30+
# On Windows, convert certificate to PKCS#1 to work around CDRIVER-4269:
31+
if $IS_WINDOWS; then
32+
openssl pkey -in "${secrets_dir:?}/atlas_x509.pem" -traditional > "${secrets_dir:?}/atlas_x509_pkcs1.pem"
33+
openssl x509 -in "${secrets_dir:?}/atlas_x509.pem" >> "${secrets_dir:?}/atlas_x509_pkcs1.pem"
34+
atlas_x509_path="$(cygpath -m "${secrets_dir:?}/atlas_x509_pkcs1.pem")"
35+
fi
36+
37+
# Create Kerberos config and keytab files.
38+
echo "Setting up Kerberos ... begin"
39+
if command -v kinit >/dev/null; then
40+
# Copy host config and append realm:
41+
if [ -e /etc/krb5.conf ]; then
42+
cat /etc/krb5.conf > "${secrets_dir:?}/krb5.conf"
43+
fi
44+
cat "${mongoc_dir}/.evergreen/etc/kerberos.realm" >> "${secrets_dir:?}/krb5.conf"
45+
# Set up keytab:
46+
echo "${keytab:?}" | base64 --decode > "${secrets_dir:?}/drivers.keytab"
47+
# Initialize kerberos:
48+
KRB5_CONFIG="${secrets_dir:?}/krb5.conf" kinit -k -t "${secrets_dir:?}/drivers.keytab" -p [email protected]
49+
echo "Setting up Kerberos ... done"
50+
else
51+
echo "No 'kinit' detected"
52+
echo "Setting up Kerberos ... skipping"
53+
fi
54+
2155
declare c_timeout="connectTimeoutMS=30000&serverSelectionTryOnce=false"
2256

2357
declare sasl="OFF"
@@ -62,10 +96,6 @@ esac
6296
: "${test_gssapi:?}"
6397
: "${ip_addr:?}"
6498

65-
if command -v kinit >/dev/null && [[ -f /tmp/drivers.keytab ]]; then
66-
kinit -k -t /tmp/drivers.keytab -p [email protected] || true
67-
fi
68-
6999
# Archlinux (which we use for testing various self-installed OpenSSL versions)
70100
# stores their trust list under /etc/ca-certificates/extracted/.
71101
# We need to copy it to our custom installed OpenSSL trust store.
@@ -158,6 +188,10 @@ if [[ "${ssl}" != "OFF" ]]; then
158188
echo "Connecting to Atlas Serverless"
159189
LD_LIBRARY_PATH="${openssl_lib_prefix}" "${ping}" "${atlas_serverless:?}&${c_timeout}"
160190
fi
191+
192+
echo "Connecting to Atlas with X509"
193+
LD_LIBRARY_PATH="${openssl_lib_prefix}" "${ping}" "${atlas_x509:?}&tlsCertificateKeyFile=${atlas_x509_path}&${c_timeout}"
194+
161195
fi
162196

163197
echo "Authenticating using PLAIN"

CONTRIBUTING.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ $ mongod --auth --setParameter enableTestCommands=1 --dbpath db/
148148
In another terminal, use the `mongosh` shell to create a user:
149149

150150
```
151-
$ mongosh --eval "db.createUser({user: 'admin', pwd: 'pass', roles: ['root']})" admin
151+
$ mongosh --eval "db.createUser({user: 'bob', pwd: 'pwd123', roles: ['root']})" admin
152152
```
153153

154154
Authentication in MongoDB 3.0 and later uses SCRAM-SHA-1, which in turn
@@ -157,8 +157,8 @@ requires a driver built with SSL.
157157
Set the user and password environment variables, then build and run the tests:
158158

159159
```
160-
$ export MONGOC_TEST_USER=admin
161-
$ export MONGOC_TEST_PASSWORD=pass
160+
$ export MONGOC_TEST_USER=bob
161+
$ export MONGOC_TEST_PASSWORD=pwd123
162162
$ ./test-libmongoc
163163
```
164164

src/libmongoc/src/mongoc/mongoc-cluster-private.h

+1-4
Original file line numberDiff line numberDiff line change
@@ -235,10 +235,7 @@ _mongoc_cluster_create_server_stream (const mongoc_topology_description_t *td,
235235
mongoc_stream_t *stream);
236236

237237
bool
238-
_mongoc_cluster_get_auth_cmd_x509 (const mongoc_uri_t *uri,
239-
const mongoc_ssl_opt_t *ssl_opts,
240-
bson_t *cmd /* OUT */,
241-
bson_error_t *error /* OUT */);
238+
_mongoc_cluster_get_auth_cmd_x509 (const mongoc_uri_t *uri, bson_t *cmd /* OUT */, bson_error_t *error /* OUT */);
242239

243240
/* Returns true if a versioned server API has been selected, otherwise returns
244241
* false. */

src/libmongoc/src/mongoc/mongoc-cluster.c

+7-35
Original file line numberDiff line numberDiff line change
@@ -804,12 +804,7 @@ _stream_run_hello (mongoc_cluster_t *cluster,
804804
_mongoc_topology_dup_handshake_cmd (cluster->client->topology, &handshake_command);
805805

806806
if (cluster->requires_auth && speculative_auth_response) {
807-
mongoc_ssl_opt_t *ssl_opts = NULL;
808-
#ifdef MONGOC_ENABLE_SSL
809-
ssl_opts = &cluster->client->ssl_opts;
810-
#endif
811-
812-
_mongoc_topology_scanner_add_speculative_authentication (&handshake_command, cluster->uri, ssl_opts, scram);
807+
_mongoc_topology_scanner_add_speculative_authentication (&handshake_command, cluster->uri, scram);
813808
}
814809

815810
if (negotiate_sasl_supported_mechs) {
@@ -1053,10 +1048,7 @@ _mongoc_cluster_auth_node_plain (mongoc_cluster_t *cluster,
10531048
}
10541049

10551050
bool
1056-
_mongoc_cluster_get_auth_cmd_x509 (const mongoc_uri_t *uri,
1057-
const mongoc_ssl_opt_t *ssl_opts,
1058-
bson_t *cmd /* OUT */,
1059-
bson_error_t *error /* OUT */)
1051+
_mongoc_cluster_get_auth_cmd_x509 (const mongoc_uri_t *uri, bson_t *cmd /* OUT */, bson_error_t *error /* OUT */)
10601052
{
10611053
#ifndef MONGOC_ENABLE_SSL
10621054
_mongoc_set_error (error,
@@ -1067,41 +1059,21 @@ _mongoc_cluster_get_auth_cmd_x509 (const mongoc_uri_t *uri,
10671059
return false;
10681060
#else
10691061
const char *username_from_uri = NULL;
1070-
char *username_from_subject = NULL;
10711062

10721063
BSON_ASSERT (uri);
1064+
BSON_UNUSED (error);
10731065

10741066
username_from_uri = mongoc_uri_get_username (uri);
10751067
if (username_from_uri) {
10761068
TRACE ("%s", "X509: got username from URI");
1077-
} else {
1078-
if (!ssl_opts || !ssl_opts->pem_file) {
1079-
_mongoc_set_error (error,
1080-
MONGOC_ERROR_CLIENT,
1081-
MONGOC_ERROR_CLIENT_AUTHENTICATE,
1082-
"cannot determine username for "
1083-
"X-509 authentication.");
1084-
return false;
1085-
}
1086-
1087-
username_from_subject = mongoc_ssl_extract_subject (ssl_opts->pem_file, ssl_opts->pem_pwd);
1088-
if (!username_from_subject) {
1089-
_mongoc_set_error (error,
1090-
MONGOC_ERROR_CLIENT,
1091-
MONGOC_ERROR_CLIENT_AUTHENTICATE,
1092-
"No username provided for X509 authentication.");
1093-
return false;
1094-
}
1095-
1096-
TRACE ("%s", "X509: got username from certificate");
10971069
}
10981070

10991071
bson_init (cmd);
11001072
BSON_APPEND_INT32 (cmd, "authenticate", 1);
11011073
BSON_APPEND_UTF8 (cmd, "mechanism", "MONGODB-X509");
1102-
BSON_APPEND_UTF8 (cmd, "user", username_from_uri ? username_from_uri : username_from_subject);
1103-
1104-
bson_free (username_from_subject);
1074+
if (username_from_uri) {
1075+
BSON_APPEND_UTF8 (cmd, "user", username_from_uri);
1076+
}
11051077

11061078
return true;
11071079
#endif
@@ -1132,7 +1104,7 @@ _mongoc_cluster_auth_node_x509 (mongoc_cluster_t *cluster,
11321104
BSON_ASSERT (cluster);
11331105
BSON_ASSERT (stream);
11341106

1135-
if (!_mongoc_cluster_get_auth_cmd_x509 (cluster->uri, &cluster->client->ssl_opts, &cmd, error)) {
1107+
if (!_mongoc_cluster_get_auth_cmd_x509 (cluster->uri, &cmd, error)) {
11361108
return false;
11371109
}
11381110

src/libmongoc/src/mongoc/mongoc-openssl-private.h

-2
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ bool
3838
_mongoc_openssl_check_peer_hostname (SSL *ssl, const char *host, bool allow_invalid_hostname);
3939
SSL_CTX *
4040
_mongoc_openssl_ctx_new (mongoc_ssl_opt_t *opt);
41-
char *
42-
_mongoc_openssl_extract_subject (const char *filename, const char *passphrase);
4341
void
4442
_mongoc_openssl_init (void);
4543
void

src/libmongoc/src/mongoc/mongoc-openssl.c

-51
Original file line numberDiff line numberDiff line change
@@ -1012,57 +1012,6 @@ _mongoc_openssl_ctx_new (mongoc_ssl_opt_t *opt)
10121012
return ctx;
10131013
}
10141014

1015-
1016-
char *
1017-
_mongoc_openssl_extract_subject (const char *filename, const char *passphrase)
1018-
{
1019-
X509_NAME *subject = NULL;
1020-
X509 *cert = NULL;
1021-
BIO *certbio = NULL;
1022-
BIO *strbio = NULL;
1023-
char *str = NULL;
1024-
int ret;
1025-
1026-
BSON_UNUSED (passphrase);
1027-
1028-
if (!filename) {
1029-
return NULL;
1030-
}
1031-
1032-
certbio = BIO_new (BIO_s_file ());
1033-
strbio = BIO_new (BIO_s_mem ());
1034-
1035-
BSON_ASSERT (certbio);
1036-
BSON_ASSERT (strbio);
1037-
1038-
1039-
if (BIO_read_filename (certbio, filename) && (cert = PEM_read_bio_X509 (certbio, NULL, 0, NULL))) {
1040-
if ((subject = X509_get_subject_name (cert))) {
1041-
ret = X509_NAME_print_ex (strbio, subject, 0, XN_FLAG_RFC2253);
1042-
1043-
if ((ret > 0) && (ret < INT_MAX)) {
1044-
str = (char *) bson_malloc (ret + 2);
1045-
BIO_gets (strbio, str, ret + 1);
1046-
str[ret] = '\0';
1047-
}
1048-
}
1049-
}
1050-
1051-
if (cert) {
1052-
X509_free (cert);
1053-
}
1054-
1055-
if (certbio) {
1056-
BIO_free (certbio);
1057-
}
1058-
1059-
if (strbio) {
1060-
BIO_free (strbio);
1061-
}
1062-
1063-
return str;
1064-
}
1065-
10661015
#if OPENSSL_VERSION_NUMBER < 0x10100000L
10671016
#ifdef _WIN32
10681017

src/libmongoc/src/mongoc/mongoc-secure-channel-private.h

-4
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,6 @@
3232

3333
BSON_BEGIN_DECLS
3434

35-
36-
char *
37-
_mongoc_secure_channel_extract_subject (const char *filename, const char *passphrase);
38-
3935
bool
4036
mongoc_secure_channel_setup_ca (mongoc_stream_tls_secure_channel_t *secure_channel, mongoc_ssl_opt_t *opt);
4137

0 commit comments

Comments
 (0)