static bool mongoc_uri_finalize_auth (mongoc_uri_t *uri) { bson_iter_t iter; const char *source = NULL; const char *mechanism = mongoc_uri_get_auth_mechanism(uri); if (bson_iter_init_find_case(&iter, &uri->credentials, "authSource")) { source = bson_iter_utf8(&iter, NULL); } /* authSource with GSSAPI or X509 should always be external */ if (mechanism) { if (!strcasecmp(mechanism, "GSSAPI") || !strcasecmp(mechanism, "MONGODB-X509")) { if (source) { if (strcasecmp(source, "$external")) { return false; } } else { bson_append_utf8(&uri->credentials, "authsource", -1, "$external", -1); } } } return true; }
bool _mongoc_cyrus_new_from_cluster (mongoc_cyrus_t *sasl, mongoc_cluster_t *cluster, mongoc_stream_t *stream, const char *hostname, bson_error_t *error) { const char *mechanism; char real_name[BSON_HOST_NAME_MAX + 1]; _mongoc_cyrus_init (sasl); mechanism = mongoc_uri_get_auth_mechanism (cluster->uri); if (!mechanism) { mechanism = "GSSAPI"; } if (!_mongoc_cyrus_set_mechanism (sasl, mechanism, error)) { _mongoc_cyrus_destroy (sasl); return false; } _mongoc_sasl_set_pass ((mongoc_sasl_t *) sasl, mongoc_uri_get_password (cluster->uri)); _mongoc_sasl_set_user ((mongoc_sasl_t *) sasl, mongoc_uri_get_username (cluster->uri)); _mongoc_sasl_set_properties ((mongoc_sasl_t *) sasl, cluster->uri); /* * If the URI requested canonicalizeHostname, we need to resolve the real * hostname for the IP Address and pass that to the SASL layer. Some * underlying GSSAPI layers will do this for us, but can be disabled in * their config (krb.conf). * * This allows the consumer to specify canonicalizeHostname=true in the URI * and have us do that for them. * * See CDRIVER-323 for more information. */ if (sasl->credentials.canonicalize_host_name && _mongoc_sasl_get_canonicalized_name ( stream, real_name, sizeof real_name)) { _mongoc_sasl_set_service_host ((mongoc_sasl_t *) sasl, real_name); } else { _mongoc_sasl_set_service_host ((mongoc_sasl_t *) sasl, hostname); } return true; }
static mongoc_stream_t * mongoc_client_default_stream_initiator (const mongoc_uri_t *uri, const mongoc_host_list_t *host, void *user_data, bson_error_t *error) { mongoc_stream_t *base_stream = NULL; #ifdef MONGOC_ENABLE_SSL mongoc_client_t *client = user_data; const bson_t *options; bson_iter_t iter; const char *mechanism; #endif bson_return_val_if_fail (uri, NULL); bson_return_val_if_fail (host, NULL); #ifndef MONGOC_ENABLE_SSL if (mongoc_uri_get_ssl (uri)) { bson_set_error (error, MONGOC_ERROR_CLIENT, MONGOC_ERROR_CLIENT_NO_ACCEPTABLE_PEER, "SSL is not enabled in this build of mongo-c-driver."); return NULL; } #endif switch (host->family) { #if defined(AF_INET6) case AF_INET6: #endif case AF_INET: base_stream = mongoc_client_connect_tcp (uri, host, error); break; case AF_UNIX: base_stream = mongoc_client_connect_unix (uri, host, error); break; default: bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_INVALID_TYPE, "Invalid address family: 0x%02x", host->family); break; } #ifdef MONGOC_ENABLE_SSL if (base_stream) { options = mongoc_uri_get_options (uri); mechanism = mongoc_uri_get_auth_mechanism (uri); if ((bson_iter_init_find_case (&iter, options, "ssl") && bson_iter_as_bool (&iter)) || (mechanism && (0 == strcmp (mechanism, "MONGODB-X509")))) { base_stream = mongoc_stream_tls_new (base_stream, &client->ssl_opts, true); if (!base_stream) { bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "Failed initialize TLS state."); return NULL; } if (!mongoc_stream_tls_do_handshake (base_stream, -1) || !mongoc_stream_tls_check_cert (base_stream, host->host)) { bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "Failed to handshake and validate TLS certificate."); mongoc_stream_destroy (base_stream); base_stream = NULL; return NULL; } } } #endif return base_stream ? mongoc_stream_buffered_new (base_stream, 1024) : NULL; }
mongoc_stream_t * mongoc_client_default_stream_initiator (const mongoc_uri_t *uri, const mongoc_host_list_t *host, void *user_data, bson_error_t *error) { mongoc_stream_t *base_stream = NULL; #ifdef MONGOC_ENABLE_SSL mongoc_client_t *client = (mongoc_client_t *)user_data; const char *mechanism; int32_t connecttimeoutms; #endif BSON_ASSERT (uri); BSON_ASSERT (host); #ifndef MONGOC_ENABLE_SSL if (mongoc_uri_get_ssl (uri)) { bson_set_error (error, MONGOC_ERROR_CLIENT, MONGOC_ERROR_CLIENT_NO_ACCEPTABLE_PEER, "SSL is not enabled in this build of mongo-c-driver."); return NULL; } #endif switch (host->family) { #if defined(AF_INET6) case AF_INET6: #endif case AF_INET: base_stream = mongoc_client_connect_tcp (uri, host, error); break; case AF_UNIX: base_stream = mongoc_client_connect_unix (uri, host, error); break; default: bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_INVALID_TYPE, "Invalid address family: 0x%02x", host->family); break; } #ifdef MONGOC_ENABLE_SSL if (base_stream) { mechanism = mongoc_uri_get_auth_mechanism (uri); if (client->use_ssl || (mechanism && (0 == strcmp (mechanism, "MONGODB-X509")))) { base_stream = mongoc_stream_tls_new (base_stream, &client->ssl_opts, true); if (!base_stream) { bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "Failed initialize TLS state."); return NULL; } connecttimeoutms = mongoc_uri_get_option_as_int32 ( uri, "connecttimeoutms", MONGOC_DEFAULT_CONNECTTIMEOUTMS); if (!mongoc_stream_tls_do_handshake (base_stream, connecttimeoutms) || !mongoc_stream_tls_check_cert (base_stream, host->host)) { bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "Failed to handshake and validate TLS certificate."); mongoc_stream_destroy (base_stream); return NULL; } } } #endif return base_stream ? mongoc_stream_buffered_new (base_stream, 1024) : NULL; }
std::string uri::auth_mechanism() const { return mongoc_uri_get_auth_mechanism(_impl->uri_t); }
static void test_mongoc_uri_new (void) { const mongoc_host_list_t *hosts; const bson_t *options; const bson_t *credentials; bson_t properties; mongoc_uri_t *uri; bson_iter_t iter; bson_iter_t child; /* bad uris */ ASSERT(!mongoc_uri_new("mongodb://")); ASSERT(!mongoc_uri_new("mongodb://::")); ASSERT(!mongoc_uri_new("mongodb://*****:*****@localhost:27017/foo/?authSource=abcd"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_username(uri), "christian"); ASSERT_CMPSTR(mongoc_uri_get_password(uri), "secret"); ASSERT_CMPSTR(mongoc_uri_get_auth_source(uri), "abcd"); mongoc_uri_destroy(uri); /* should use the default auth source and mechanism */ uri = mongoc_uri_new("mongodb://*****:*****@localhost:27017"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_auth_source(uri), "admin"); ASSERT(!mongoc_uri_get_auth_mechanism(uri)); mongoc_uri_destroy(uri); /* should use the db when no authSource is specified */ uri = mongoc_uri_new("mongodb://*****:*****@localhost/foo"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_auth_source(uri), "foo"); mongoc_uri_destroy(uri); /* should recognize an empty password */ uri = mongoc_uri_new("mongodb://samantha:@localhost"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_username(uri), "samantha"); ASSERT_CMPSTR(mongoc_uri_get_password(uri), ""); mongoc_uri_destroy(uri); /* should recognize no password */ uri = mongoc_uri_new("mongodb://christian@localhost:27017"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_username(uri), "christian"); ASSERT(!mongoc_uri_get_password(uri)); mongoc_uri_destroy(uri); /* should recognize a url escaped character in the username */ uri = mongoc_uri_new("mongodb://christian%40realm:pwd@localhost:27017"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_username(uri), "christian@realm"); mongoc_uri_destroy(uri); /* while you shouldn't do this, lets test for it */ uri = mongoc_uri_new("mongodb://christian%40realm@localhost:27017/db%2ename"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_database(uri), "db.name"); mongoc_uri_destroy(uri); uri = mongoc_uri_new("mongodb://christian%40realm@localhost:27017/db%2Ename"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_database(uri), "db.name"); mongoc_uri_destroy(uri); uri = mongoc_uri_new("mongodb://christian%40realm@localhost:27017/?abcd=%20"); ASSERT(uri); options = mongoc_uri_get_options(uri); ASSERT(options); ASSERT(bson_iter_init_find(&iter, options, "abcd")); ASSERT(BSON_ITER_HOLDS_UTF8(&iter)); ASSERT_CMPSTR(bson_iter_utf8(&iter, NULL), " "); mongoc_uri_destroy(uri); uri = mongoc_uri_new("mongodb://christian%40realm@[::6]:27017/?abcd=%20"); ASSERT(uri); options = mongoc_uri_get_options(uri); ASSERT(options); ASSERT(bson_iter_init_find(&iter, options, "abcd")); ASSERT(BSON_ITER_HOLDS_UTF8(&iter)); ASSERT_CMPSTR(bson_iter_utf8(&iter, NULL), " "); mongoc_uri_destroy(uri); /* GSSAPI-specific options */ /* should recognize the GSSAPI mechanism, and use $external as source */ uri = mongoc_uri_new("mongodb://user%40DOMAIN.COM:password@localhost/?authMechanism=GSSAPI"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_auth_mechanism(uri), "GSSAPI"); /*ASSERT_CMPSTR(mongoc_uri_get_auth_source(uri), "$external");*/ mongoc_uri_destroy(uri); /* use $external as source when db is specified */ uri = mongoc_uri_new("mongodb://user%40DOMAIN.COM:password@localhost/foo/?authMechanism=GSSAPI"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_auth_source(uri), "$external"); mongoc_uri_destroy(uri); /* should not accept authSource other than $external */ ASSERT(!mongoc_uri_new("mongodb://user%40DOMAIN.COM:password@localhost/foo/?authMechanism=GSSAPI&authSource=bar")); /* should accept authMechanismProperties */ uri = mongoc_uri_new("mongodb://user%40DOMAIN.COM:password@localhost/?authMechanism=GSSAPI" "&authMechanismProperties=SERVICE_NAME:other,CANONICALIZE_HOST_NAME:true"); ASSERT(uri); credentials = mongoc_uri_get_credentials(uri); ASSERT(credentials); ASSERT(mongoc_uri_get_mechanism_properties(uri, &properties)); assert (bson_iter_init_find_case (&iter, &properties, "SERVICE_NAME") && BSON_ITER_HOLDS_UTF8 (&iter) && (0 == strcmp (bson_iter_utf8 (&iter, NULL), "other"))); assert (bson_iter_init_find_case (&iter, &properties, "CANONICALIZE_HOST_NAME") && BSON_ITER_HOLDS_UTF8 (&iter) && (0 == strcmp (bson_iter_utf8 (&iter, NULL), "true"))); mongoc_uri_destroy(uri); /* reverse order of arguments to ensure parsing still succeeds */ uri = mongoc_uri_new("mongodb://user@localhost/" "?authMechanismProperties=SERVICE_NAME:other" "&authMechanism=GSSAPI"); ASSERT(uri); mongoc_uri_destroy(uri); /* deprecated gssapiServiceName option */ uri = mongoc_uri_new("mongodb://christian%40realm.cc@localhost:27017/?authMechanism=GSSAPI&gssapiServiceName=blah"); ASSERT(uri); options = mongoc_uri_get_options(uri); ASSERT(options); assert (0 == strcmp (mongoc_uri_get_auth_mechanism (uri), "GSSAPI")); assert (0 == strcmp (mongoc_uri_get_username (uri), "*****@*****.**")); assert (bson_iter_init_find_case (&iter, options, "gssapiServiceName") && BSON_ITER_HOLDS_UTF8 (&iter) && (0 == strcmp (bson_iter_utf8 (&iter, NULL), "blah"))); mongoc_uri_destroy(uri); /* MONGODB-CR */ /* should recognize this mechanism */ uri = mongoc_uri_new("mongodb://user@localhost/?authMechanism=MONGODB-CR"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_auth_mechanism(uri), "MONGODB-CR"); mongoc_uri_destroy(uri); /* X509 */ /* should recognize this mechanism, and use $external as the source */ uri = mongoc_uri_new("mongodb://user@localhost/?authMechanism=MONGODB-X509"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_auth_mechanism(uri), "MONGODB-X509"); /*ASSERT_CMPSTR(mongoc_uri_get_auth_source(uri), "$external");*/ mongoc_uri_destroy(uri); /* use $external as source when db is specified */ uri = mongoc_uri_new("mongodb://CN%3DmyName%2COU%3DmyOrgUnit%2CO%3DmyOrg%2CL%3DmyLocality" "%2CST%3DmyState%2CC%3DmyCountry@localhost/foo/?authMechanism=MONGODB-X509"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_auth_source(uri), "$external"); mongoc_uri_destroy(uri); /* should not accept authSource other than $external */ ASSERT(!mongoc_uri_new("mongodb://CN%3DmyName%2COU%3DmyOrgUnit%2CO%3DmyOrg%2CL%3DmyLocality" "%2CST%3DmyState%2CC%3DmyCountry@localhost/foo/?authMechanism=MONGODB-X509&authSource=bar")); /* should recognize the encoded username */ uri = mongoc_uri_new("mongodb://CN%3DmyName%2COU%3DmyOrgUnit%2CO%3DmyOrg%2CL%3DmyLocality" "%2CST%3DmyState%2CC%3DmyCountry@localhost/?authMechanism=MONGODB-X509"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_username(uri), "CN=myName,OU=myOrgUnit,O=myOrg,L=myLocality,ST=myState,C=myCountry"); mongoc_uri_destroy(uri); /* PLAIN */ /* should recognize this mechanism */ uri = mongoc_uri_new("mongodb://user@localhost/?authMechanism=PLAIN"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_auth_mechanism(uri), "PLAIN"); mongoc_uri_destroy(uri); /* SCRAM-SHA1 */ /* should recognize this mechanism */ uri = mongoc_uri_new("mongodb://user@localhost/?authMechanism=SCRAM-SHA1"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_auth_mechanism(uri), "SCRAM-SHA1"); mongoc_uri_destroy(uri); }
static void test_mongoc_uri_new (void) { const mongoc_host_list_t *hosts; const bson_t *options; mongoc_uri_t *uri; bson_iter_t iter; bson_iter_t child; ASSERT(!mongoc_uri_new("mongodb://")); ASSERT(!mongoc_uri_new("mongodb://::")); ASSERT(!mongoc_uri_new("mongodb://*****:*****@localhost:27017?authSource=abcd"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_username(uri), "christian"); ASSERT_CMPSTR(mongoc_uri_get_password(uri), "secret"); ASSERT_CMPSTR(mongoc_uri_get_auth_source(uri), "abcd"); mongoc_uri_destroy(uri); uri = mongoc_uri_new("mongodb://*****:*****@localhost:27017"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_auth_source(uri), "admin"); mongoc_uri_destroy(uri); uri = mongoc_uri_new("mongodb://christian@localhost:27017"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_username(uri), "christian"); mongoc_uri_destroy(uri); uri = mongoc_uri_new("mongodb://christian%40realm@localhost:27017"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_username(uri), "christian@realm"); mongoc_uri_destroy(uri); /* while you shouldn't do this, lets test for it */ uri = mongoc_uri_new("mongodb://christian%40realm@localhost:27017/db%2ename"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_database(uri), "db.name"); mongoc_uri_destroy(uri); uri = mongoc_uri_new("mongodb://christian%40realm@localhost:27017/db%2Ename"); ASSERT(uri); ASSERT_CMPSTR(mongoc_uri_get_database(uri), "db.name"); mongoc_uri_destroy(uri); uri = mongoc_uri_new("mongodb://christian%40realm@localhost:27017/?abcd=%20"); ASSERT(uri); options = mongoc_uri_get_options(uri); ASSERT(options); ASSERT(bson_iter_init_find(&iter, options, "abcd")); ASSERT(BSON_ITER_HOLDS_UTF8(&iter)); ASSERT_CMPSTR(bson_iter_utf8(&iter, NULL), " "); mongoc_uri_destroy(uri); uri = mongoc_uri_new("mongodb://christian%40realm.cc@localhost:27017/?authmechanism=GSSAPI&gssapiservicename=blah"); ASSERT(uri); options = mongoc_uri_get_options(uri); ASSERT(options); assert (0 == strcmp (mongoc_uri_get_auth_mechanism (uri), "GSSAPI")); assert (0 == strcmp (mongoc_uri_get_username (uri), "*****@*****.**")); assert (bson_iter_init_find_case (&iter, options, "gssapiservicename") && BSON_ITER_HOLDS_UTF8 (&iter) && (0 == strcmp (bson_iter_utf8 (&iter, NULL), "blah"))); mongoc_uri_destroy(uri); uri = mongoc_uri_new("mongodb://christian%40realm@[::6]:27017/?abcd=%20"); ASSERT(uri); options = mongoc_uri_get_options(uri); ASSERT(options); ASSERT(bson_iter_init_find(&iter, options, "abcd")); ASSERT(BSON_ITER_HOLDS_UTF8(&iter)); ASSERT_CMPSTR(bson_iter_utf8(&iter, NULL), " "); mongoc_uri_destroy(uri); }