Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'authhelper'

  • Loading branch information...
commit 0b9369b62fe8eb38d5b5e8fdff6fc5179a92eeb5 2 parents 3f92398 + acd3c9d
@andy10gen andy10gen authored
View
57 jstests/auth/auth_helpers.js
@@ -0,0 +1,57 @@
+// Test the db.auth() shell helper.
+
+var conn = MongoRunner.runMongod({ smallfiles: "", auth: "" });
+
+var mechanisms, hasMongoCR, hasCramMd5;
+
+// Find out if this build supports the authenticationMechanisms startup parameter. If it does,
+// restart with MONGO-CR and CRAM-MD5 mechanisms enabled.
+var cmdOut = conn.getDB('admin').runCommand({getParameter: 1, authenticationMechanisms: 1})
+if (cmdOut.ok) {
+ MongoRunner.stopMongod(conn);
+ conn = MongoRunner.runMongod({ restart: conn,
+ setParameter: "authenticationMechanisms=MONGO-CR,CRAM-MD5" });
+ mechanisms = [ "MONGO-CR", "CRAM-MD5" ];
+ hasMongoCR = true;
+ hasCramMd5 = true;
+ print("test info: Enabling non-default authentication mechanisms.");
+}
+else {
+ mechanisms = [ "MONGO-CR" ];
+ hasMongoCR = true;
+ hasCramMd5 = false;
+ print("test info: Using only default authentication mechanism, MONGO-CR.");
+}
+
+var admin = conn.getDB('admin');
+
+var testedSomething = false;
+
+admin.addUser('andy', 'a');
+
+// If the server supports them MONGO-CR, try all the ways to call db.auth that use MONGO-CR.
+if (hasMongoCR) {
+ testedSomething = true;
+ assert(admin.auth('andy', 'a'));
+ admin.logout();
+ assert(admin.auth({user: 'andy', pwd: 'a'}));
+ admin.logout();
+ assert(admin.auth({mechanism: 'MONGO-CR', user: 'andy', pwd: 'a'}));
+ admin.logout();
+}
+
+// If the server supports CRAM-MD5 and the shell supports sasl, try it out.
+if (hasCramMd5 && conn.saslAuthenticate) {
+ testedSomething = true;
+ assert(admin.auth({mechanism: 'CRAM-MD5', user: 'andy', pwd: 'a'}));
+ admin.logout();
+}
+
+// Sanity check that we tested at least one of MONGO-CR and CRAM-MD5.
+assert(testedSomething, "No candidate authentication mechanisms matched.");
+
+// If the shell doesn't support sasl authentication, it shouldn't be able to do CRAM-MD5,
+// but shouldn't crash.
+if (!conn.saslAuthenticate) {
+ assert(!admin.auth({mechanism: 'CRAM-MD5', user: 'andy', pwd: 'a'}));
+}
View
28 src/mongo/client/sasl_client_authenticate.cpp
@@ -38,10 +38,10 @@ namespace mongo {
const char* const saslCommandErrmsgFieldName = "errmsg";
const char* const saslCommandMechanismFieldName = "mechanism";
const char* const saslCommandMechanismListFieldName = "supportedMechanisms";
- const char* const saslCommandPasswordFieldName = "password";
+ const char* const saslCommandPasswordFieldName = "pwd";
const char* const saslCommandPayloadFieldName = "payload";
- const char* const saslCommandPrincipalFieldName = "principal";
- const char* const saslCommandPrincipalSourceFieldName = "principalSource";
+ const char* const saslCommandPrincipalFieldName = "user";
+ const char* const saslCommandPrincipalSourceFieldName = "userSource";
const char* const saslCommandServiceHostnameFieldName = "serviceHostname";
const char* const saslCommandServiceNameFieldName = "serviceName";
const char* const saslDefaultDBName = "$sasl";
@@ -127,22 +127,24 @@ namespace {
return status;
session->setProperty(GSASL_HOSTNAME, hostname);
- BSONElement element = saslParameters[saslCommandPrincipalFieldName];
- if (element.type() == String) {
- session->setProperty(GSASL_AUTHID, element.str());
+ BSONElement principalElement = saslParameters[saslCommandPrincipalFieldName];
+ if (principalElement.type() == String) {
+ session->setProperty(GSASL_AUTHID, principalElement.str());
}
- else if (!element.eoo()) {
+ else if (!principalElement.eoo()) {
return Status(ErrorCodes::TypeMismatch,
- str::stream() << "Expected string for " << element);
+ str::stream() << "Expected string for " << principalElement);
}
- element = saslParameters[saslCommandPasswordFieldName];
- if (element.type() == String) {
- session->setProperty(GSASL_PASSWORD, element.str());
+ BSONElement passwordElement = saslParameters[saslCommandPasswordFieldName];
+ if (passwordElement.type() == String) {
+ std::string passwordHash = client->createPasswordDigest(principalElement.str(),
+ passwordElement.str());
+ session->setProperty(GSASL_PASSWORD, passwordHash);
}
- else if (!element.eoo()) {
+ else if (!passwordElement.eoo()) {
return Status(ErrorCodes::TypeMismatch,
- str::stream() << "Expected string for " << element);
+ str::stream() << "Expected string for " << passwordElement);
}
return Status::OK();
View
6 src/mongo/client/sasl_client_authenticate.h
@@ -38,11 +38,11 @@ namespace mongo {
* "autoAuthorize": Truthy values tell the server to automatically acquire privileges on
* all resources after successful authentication, which is the default. Falsey values
* instruct the server to await separate privilege-acquisition commands.
- * "principal": The string name of the principal to authenticate, GSASL_AUTHID.
- * "principalSource": The database target of the auth command, which identifies the location
+ * "user": The string name of the principal to authenticate, GSASL_AUTHID.
+ * "userSource": The database target of the auth command, which identifies the location
* of the credential information for the principal. May be "$sasl" if credential
* information is stored outside of the mongo cluster.
- * "password": The password data, GSASL_PASSWORD.
+ * "pwd": The password data, GSASL_PASSWORD.
* "serviceName": The GSSAPI service name to use. Defaults to "mongodb".
* "serviceHostname": The GSSAPI hostname to use. Defaults to the name of the remote host.
*
View
2  src/mongo/db/security_commands.cpp
@@ -150,7 +150,7 @@ namespace mongo {
dbname, PrincipalName(user, dbname), &userObj);
if (!status.isOK()) {
log() << status.reason() << std::endl;
- errmsg = status.reason();
+ errmsg = "auth fails";
return false;
}
pwd = userObj["pwd"].String();
View
42 src/mongo/shell/db.js
@@ -137,13 +137,43 @@ DB.prototype.__pwHash = function( nonce, username, pass ) {
return hex_md5( nonce + username + hex_md5( username + ":mongo:" + pass ) );
}
-DB.prototype.auth = function( username , pass ){
- var result = 0;
- try {
- result = this.getMongo().auth(this.getName(), username, pass);
+DB.prototype._authOrThrow = function () {
+ var params;
+ if (arguments.length == 2) {
+ params = { user: arguments[0], pwd: arguments[1] };
}
- catch (e) {
- print(e);
+ else if (arguments.length == 1) {
+ if (typeof(arguments[0]) != "object")
+ throw Error("Single-argument form of auth expects a parameter object");
+ params = arguments[0];
+ }
+ else {
+ throw Error(
+ "auth expects either (username, password) or ({ user: username, pwd: password })");
+ }
+
+ if (params.mechanism === undefined)
+ params.mechanism = "MONGO-CR";
+
+ if (params.mechanism == "MONGO-CR") {
+ this.getMongo().auth(this.getName(), params.user, params.pwd);
+ }
+ else if (typeof(this.getMongo().saslAuthenticate == "function")) {
+ params.userSource = this.getName();
+ this.getMongo().saslAuthenticate(params);
+ }
+ else {
+ throw Error("This shell does not support sasl authentication");
+ }
+}
+
+
+DB.prototype.auth = function() {
+ var ex;
+ try {
+ this._authOrThrow.apply(this, arguments);
+ } catch (ex) {
+ print(ex);
return 0;
}
return 1;
Please sign in to comment.
Something went wrong with that request. Please try again.