Пример #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;
        }
Пример #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;
        }