Example #1
0
        bool allowed( const char * rq , vector<string>& headers, const SockAddr &from ) {
            if ( from.isLocalHost() )
                return true;

            if ( ! _webUsers->haveAdminUsers() )
                return true;

            string auth = getHeader( rq , "Authorization" );

            if ( auth.size() > 0 && auth.find( "Digest " ) == 0 ) {
                auth = auth.substr( 7 ) + ", ";

                map<string,string> parms;
                pcrecpp::StringPiece input( auth );

                string name, val;
                pcrecpp::RE re("(\\w+)=\"?(.*?)\"?, ");
                while ( re.Consume( &input, &name, &val) ) {
                    parms[name] = val;
                }

                BSONObj user = _webUsers->getAdminUser( parms["username"] );
                if ( ! user.isEmpty() ) {
                    string ha1 = user["pwd"].str();
                    string ha2 = md5simpledigest( (string)"GET" + ":" + parms["uri"] );

                    stringstream r;
                    r << ha1 << ':' << parms["nonce"];
                    if ( parms["nc"].size() && parms["cnonce"].size() && parms["qop"].size() ) {
                        r << ':';
                        r << parms["nc"];
                        r << ':';
                        r << parms["cnonce"];
                        r << ':';
                        r << parms["qop"];
                    }
                    r << ':';
                    r << ha2;
                    string r1 = md5simpledigest( r.str() );

                    if ( r1 == parms["response"] )
                        return true;
                }
            }

            stringstream authHeader;
            authHeader
                    << "WWW-Authenticate: "
                    << "Digest realm=\"mongo\", "
                    << "nonce=\"abc\", "
                    << "algorithm=MD5, qop=\"auth\" "
                    ;

            headers.push_back( authHeader.str() );
            return 0;
        }
Example #2
0
        bool allowed( const char * rq , vector<string>& headers, const SockAddr &from ) {
            if ( from.isLocalHost() || !_webUsers->haveAdminUsers() ) {
                // TODO(spencer): should the above check use "&&" not "||"?  Currently this is much
                // more permissive than the server's localhost auth bypass.
                cc().getAuthorizationSession()->grantInternalAuthorization();
                return true;
            }

            string auth = getHeader( rq , "Authorization" );

            if ( auth.size() > 0 && auth.find( "Digest " ) == 0 ) {
                auth = auth.substr( 7 ) + ", ";

                map<string,string> parms;
                pcrecpp::StringPiece input( auth );

                string name, val;
                pcrecpp::RE re("(\\w+)=\"?(.*?)\"?,\\s*");
                while ( re.Consume( &input, &name, &val) ) {
                    parms[name] = val;
                }

                // Only users in the admin DB are visible by the webserver
                UserName userName(parms["username"], "admin");
                User* user;
                AuthorizationManager& authzManager =
                        cc().getAuthorizationSession()->getAuthorizationManager();
                Status status = authzManager.acquireUser(userName, &user);
                if (!status.isOK()) {
                    if (status.code() != ErrorCodes::UserNotFound) {
                        uasserted(17051, status.reason());
                    }
                } else {
                    uassert(17090,
                            "External users don't have a password",
                            !user->getCredentials().isExternal);
                    string ha1 = user->getCredentials().password;
                    authzManager.releaseUser(user);
                    string ha2 = md5simpledigest( (string)"GET" + ":" + parms["uri"] );

                    stringstream r;
                    r << ha1 << ':' << parms["nonce"];
                    if ( parms["nc"].size() && parms["cnonce"].size() && parms["qop"].size() ) {
                        r << ':';
                        r << parms["nc"];
                        r << ':';
                        r << parms["cnonce"];
                        r << ':';
                        r << parms["qop"];
                    }
                    r << ':';
                    r << ha2;
                    string r1 = md5simpledigest( r.str() );

                    if ( r1 == parms["response"] ) {
                        _authorizePrincipal(userName);
                        return true;
                    }
                }
            }

            stringstream authHeader;
            authHeader
                    << "WWW-Authenticate: "
                    << "Digest realm=\"mongo\", "
                    << "nonce=\"abc\", "
                    << "algorithm=MD5, qop=\"auth\" "
                    ;

            headers.push_back( authHeader.str() );
            return 0;
        }
Example #3
0
bool DbWebServer::_allowed(OperationContext* txn,
                           const char* rq,
                           vector<string>& headers,
                           const SockAddr& from) {
    AuthorizationSession* authSess = AuthorizationSession::get(txn->getClient());
    if (!authSess->getAuthorizationManager().isAuthEnabled()) {
        return true;
    }

    if (from.isLocalHost() && !_webUsers->haveAdminUsers(txn)) {
        authSess->grantInternalAuthorization();
        return true;
    }

    string auth = getHeader(rq, "Authorization");

    if (auth.size() > 0 && auth.find("Digest ") == 0) {
        auth = auth.substr(7) + ", ";

        map<string, string> parms;
        pcrecpp::StringPiece input(auth);

        string name, val;
        pcrecpp::RE re("(\\w+)=\"?(.*?)\"?,\\s*");
        while (re.Consume(&input, &name, &val)) {
            parms[name] = val;
        }

        // Only users in the admin DB are visible by the webserver
        UserName userName(parms["username"], "admin");
        User* user;
        AuthorizationManager& authzManager = authSess->getAuthorizationManager();
        Status status = authzManager.acquireUser(txn, userName, &user);
        if (!status.isOK()) {
            if (status.code() != ErrorCodes::UserNotFound) {
                uasserted(17051, status.reason());
            }
        } else {
            uassert(
                17090, "External users don't have a password", !user->getCredentials().isExternal);

            string ha1 = user->getCredentials().password;
            authzManager.releaseUser(user);
            if (ha1.empty()) {
                return false;
            }

            const string ha2 = md5simpledigest((string) "GET" + ":" + parms["uri"]);

            stringstream r;
            r << ha1 << ':' << parms["nonce"];
            if (parms["nc"].size() && parms["cnonce"].size() && parms["qop"].size()) {
                r << ':';
                r << parms["nc"];
                r << ':';
                r << parms["cnonce"];
                r << ':';
                r << parms["qop"];
            }
            r << ':';
            r << ha2;

            const string r1 = md5simpledigest(r.str());

            if (r1 == parms["response"]) {
                Status status = authSess->addAndAuthorizeUser(txn, userName);
                uassertStatusOK(status);
                return true;
            }
        }
    }

    stringstream authHeader;
    authHeader << "WWW-Authenticate: "
               << "Digest realm=\"mongo\", "
               << "nonce=\"abc\", "
               << "algorithm=MD5, qop=\"auth\" ";

    headers.push_back(authHeader.str());
    return 0;
}