bool LogAcceptCategory(const char* category) { if (category != NULL) { // Give each thread quick access to -debug settings. // This helps prevent issues debugging global destructors, // where mapMultiArgs might be deleted before another // global destructor calls LogPrint() static boost::thread_specific_ptr<set<string> > ptrCategory; if (!fDebug) { if (ptrCategory.get() != NULL) { LogPrintf("debug turned off: thread %s\n", GetThreadName()); ptrCategory.release(); } return false; } if (ptrCategory.get() == NULL) { std::string strThreadName = GetThreadName(); LogPrintf("debug turned on:\n"); for (int i = 0; i < (int)mapMultiArgs["-debug"].size(); ++i) LogPrintf(" thread %s category %s\n", strThreadName, mapMultiArgs["-debug"][i]); const vector<string>& categories = mapMultiArgs["-debug"]; ptrCategory.reset(new set<string>(categories.begin(), categories.end())); // thread_specific_ptr automatically deletes the set when the thread ends. // "dash" is a composite category enabling all Dash-related debug output if(ptrCategory->count(string("dash"))) { ptrCategory->insert(string("privatesend")); ptrCategory->insert(string("instantsend")); ptrCategory->insert(string("masternode")); ptrCategory->insert(string("spork")); ptrCategory->insert(string("keepass")); ptrCategory->insert(string("mnpayments")); ptrCategory->insert(string("gobject")); } } const set<string>& setCategories = *ptrCategory.get(); // if not debugging everything and not debugging specific category, LogPrint does nothing. if (setCategories.count(string("")) == 0 && setCategories.count(string("1")) == 0 && setCategories.count(string(category)) == 0) return false; } return true; }
bool run(const char *ns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl) { log(1) << " authenticate: " << cmdObj << endl; string user = cmdObj.getStringField("user"); string key = cmdObj.getStringField("key"); string received_nonce = cmdObj.getStringField("nonce"); if( user.empty() || key.empty() || received_nonce.empty() ) { log() << "field missing/wrong type in received authenticate command " << cc().database()->name << endl; errmsg = "auth fails"; sleepmillis(10); return false; } stringstream digestBuilder; { bool reject = false; nonce *ln = lastNonce.release(); if ( ln == 0 ) { reject = true; } else { digestBuilder << hex << *ln; reject = digestBuilder.str() != received_nonce; } if ( reject ) { log() << "auth: bad nonce received or getnonce not called. could be a driver bug or a security attack. db:" << cc().database()->name << endl; errmsg = "auth fails"; sleepmillis(30); return false; } } static BSONObj userPattern = fromjson("{\"user\":1}"); string systemUsers = cc().database()->name + ".system.users"; OCCASIONALLY Helpers::ensureIndex(systemUsers.c_str(), userPattern, false, "user_1"); BSONObj userObj; { BSONObjBuilder b; b << "user" << user; BSONObj query = b.done(); if( !Helpers::findOne(systemUsers.c_str(), query, userObj) ) { log() << "auth: couldn't find user " << user << ", " << systemUsers << endl; errmsg = "auth fails"; return false; } } md5digest d; { string pwd = userObj.getStringField("pwd"); digestBuilder << user << pwd; string done = digestBuilder.str(); md5_state_t st; md5_init(&st); md5_append(&st, (const md5_byte_t *) done.c_str(), done.size()); md5_finish(&st, d); } string computed = digestToString( d ); if ( key != computed ){ log() << "auth: key mismatch " << user << ", ns:" << ns << endl; errmsg = "auth fails"; return false; } AuthenticationInfo *ai = cc().getAuthenticationInfo(); if ( userObj[ "readOnly" ].isBoolean() && userObj[ "readOnly" ].boolean() ) { if ( readLockSupported() ){ ai->authorizeReadOnly( cc().database()->name.c_str() ); } else { log() << "warning: old version of boost, read-only users not supported" << endl; ai->authorize( cc().database()->name.c_str() ); } } else { ai->authorize( cc().database()->name.c_str() ); } return true; }
bool CmdAuthenticate::run(const string& dbname , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) { log() << " authenticate: " << cmdObj << endl; string user = cmdObj.getStringField("user"); string key = cmdObj.getStringField("key"); string received_nonce = cmdObj.getStringField("nonce"); if( user.empty() || key.empty() || received_nonce.empty() ) { log() << "field missing/wrong type in received authenticate command " << dbname << endl; errmsg = "auth fails"; sleepmillis(10); return false; } stringstream digestBuilder; { bool reject = false; nonce64 *ln = lastNonce.release(); if ( ln == 0 ) { reject = true; log(1) << "auth: no lastNonce" << endl; } else { digestBuilder << hex << *ln; reject = digestBuilder.str() != received_nonce; if ( reject ) log(1) << "auth: different lastNonce" << endl; } if ( reject ) { log() << "auth: bad nonce received or getnonce not called. could be a driver bug or a security attack. db:" << dbname << endl; errmsg = "auth fails"; sleepmillis(30); return false; } } BSONObj userObj; string pwd; if (!getUserObj(dbname, user, userObj, pwd)) { errmsg = "auth fails"; return false; } md5digest d; { digestBuilder << user << pwd; string done = digestBuilder.str(); md5_state_t st; md5_init(&st); md5_append(&st, (const md5_byte_t *) done.c_str(), done.size()); md5_finish(&st, d); } string computed = digestToString( d ); if ( key != computed ) { log() << "auth: key mismatch " << user << ", ns:" << dbname << endl; errmsg = "auth fails"; return false; } authenticate(dbname, user, userObj[ "readOnly" ].isBoolean() && userObj[ "readOnly" ].boolean()); return true; }
bool run(const char *ns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl) { log(1) << " authenticate: " << cmdObj << endl; string user = cmdObj.getStringField("user"); string key = cmdObj.getStringField("key"); string received_nonce = cmdObj.getStringField("nonce"); if( user.empty() || key.empty() || received_nonce.empty() ) { log() << "field missing/wrong type in received authenticate command " << database->name << '\n'; log() << "field missing/wrong type in received authenticate command " << database->name << '\n'; errmsg = "auth fails"; sleepmillis(10); return false; } stringstream digestBuilder; { nonce *ln = lastNonce.release(); digestBuilder << hex << *ln; if( ln == 0 || digestBuilder.str() != received_nonce ) { log() << "auth: bad nonce received. could be a driver bug or a security attack. db:" << database->name << '\n'; log() << "field missing/wr " << database->name << '\n'; errmsg = "auth fails"; sleepmillis(30); return false; } } static BSONObj userPattern = fromjson("{\"user\":1}"); string systemUsers = database->name + ".system.users"; OCCASIONALLY Helpers::ensureIndex(systemUsers.c_str(), userPattern, "user_1"); BSONObj userObj; { BSONObjBuilder b; b << "user" << user; BSONObj query = b.done(); if( !Helpers::findOne(systemUsers.c_str(), query, userObj) ) { log() << "auth: couldn't find user " << user << ", " << systemUsers << '\n'; errmsg = "auth fails"; return false; } } md5digest d; { string pwd = userObj.getStringField("pwd"); digestBuilder << user << pwd; string done = digestBuilder.str(); md5_state_t st; md5_init(&st); md5_append(&st, (const md5_byte_t *) done.c_str(), done.size()); md5_finish(&st, d); } string computed = digestToString( d ); if ( key != computed ){ log() << "auth: key mismatch " << user << ", ns:" << ns << '\n'; errmsg = "auth fails"; return false; } AuthenticationInfo *ai = authInfo.get(); assert( ai ); ai->authorize(database->name.c_str()); return true; }