예제 #1
0
    def testDigest(self):
        self.getPage('/digest/')
        self.assertStatus(401)
        value = None
        for k, v in self.headers:
            if k.lower() == 'www-authenticate':
                if v.startswith('Digest'):
                    value = v
                    break

        if value is None:
            self._handlewebError(
                'Digest authentification scheme was not found')
        value = value[7:]
        items = value.split(', ')
        tokens = {}
        for item in items:
            key, value = item.split('=')
            tokens[key.lower()] = value

        missing_msg = '%s is missing'
        bad_value_msg = "'%s' was expecting '%s' but found '%s'"
        nonce = None
        if 'realm' not in tokens:
            self._handlewebError(missing_msg % 'realm')
        elif tokens['realm'] != '"localhost"':
            self._handlewebError(bad_value_msg %
                                 ('realm', '"localhost"', tokens['realm']))
        if 'nonce' not in tokens:
            self._handlewebError(missing_msg % 'nonce')
        else:
            nonce = tokens['nonce'].strip('"')
        if 'algorithm' not in tokens:
            self._handlewebError(missing_msg % 'algorithm')
        elif tokens['algorithm'] != '"MD5"':
            self._handlewebError(bad_value_msg %
                                 ('algorithm', '"MD5"', tokens['algorithm']))
        if 'qop' not in tokens:
            self._handlewebError(missing_msg % 'qop')
        elif tokens['qop'] != '"auth"':
            self._handlewebError(bad_value_msg %
                                 ('qop', '"auth"', tokens['qop']))
        base_auth = 'Digest username="******", realm="wrong realm", nonce="%s", uri="/digest/", algorithm=MD5, response="%s", qop=auth, nc=%s, cnonce="1522e61005789929"'
        auth = base_auth % (nonce, '', '00000001')
        params = httpauth.parseAuthorization(auth)
        response = httpauth._computeDigestResponse(params, 'test')
        auth = base_auth % (nonce, response, '00000001')
        self.getPage('/digest/', [('Authorization', auth)])
        self.assertStatus(401)
        base_auth = 'Digest username="******", realm="localhost", nonce="%s", uri="/digest/", algorithm=MD5, response="%s", qop=auth, nc=%s, cnonce="1522e61005789929"'
        auth = base_auth % (nonce, '', '00000001')
        params = httpauth.parseAuthorization(auth)
        response = httpauth._computeDigestResponse(params, 'test')
        auth = base_auth % (nonce, response, '00000001')
        self.getPage('/digest/', [('Authorization', auth)])
        self.assertStatus('200 OK')
        self.assertBody("Hello test, you've been authorized.")
예제 #2
0
    def testDigest(self):
        self.getPage('/digest/')
        self.assertStatus(401)
        value = None
        for k, v in self.headers:
            if k.lower() == 'www-authenticate':
                if v.startswith('Digest'):
                    value = v
                    break

        if value is None:
            self._handlewebError('Digest authentification scheme was not found')
        value = value[7:]
        items = value.split(', ')
        tokens = {}
        for item in items:
            key, value = item.split('=')
            tokens[key.lower()] = value

        missing_msg = '%s is missing'
        bad_value_msg = "'%s' was expecting '%s' but found '%s'"
        nonce = None
        if 'realm' not in tokens:
            self._handlewebError(missing_msg % 'realm')
        elif tokens['realm'] != '"localhost"':
            self._handlewebError(bad_value_msg % ('realm', '"localhost"', tokens['realm']))
        if 'nonce' not in tokens:
            self._handlewebError(missing_msg % 'nonce')
        else:
            nonce = tokens['nonce'].strip('"')
        if 'algorithm' not in tokens:
            self._handlewebError(missing_msg % 'algorithm')
        elif tokens['algorithm'] != '"MD5"':
            self._handlewebError(bad_value_msg % ('algorithm', '"MD5"', tokens['algorithm']))
        if 'qop' not in tokens:
            self._handlewebError(missing_msg % 'qop')
        elif tokens['qop'] != '"auth"':
            self._handlewebError(bad_value_msg % ('qop', '"auth"', tokens['qop']))
        base_auth = 'Digest username="******", realm="wrong realm", nonce="%s", uri="/digest/", algorithm=MD5, response="%s", qop=auth, nc=%s, cnonce="1522e61005789929"'
        auth = base_auth % (nonce, '', '00000001')
        params = httpauth.parseAuthorization(auth)
        response = httpauth._computeDigestResponse(params, 'test')
        auth = base_auth % (nonce, response, '00000001')
        self.getPage('/digest/', [('Authorization', auth)])
        self.assertStatus(401)
        base_auth = 'Digest username="******", realm="localhost", nonce="%s", uri="/digest/", algorithm=MD5, response="%s", qop=auth, nc=%s, cnonce="1522e61005789929"'
        auth = base_auth % (nonce, '', '00000001')
        params = httpauth.parseAuthorization(auth)
        response = httpauth._computeDigestResponse(params, 'test')
        auth = base_auth % (nonce, response, '00000001')
        self.getPage('/digest/', [('Authorization', auth)])
        self.assertStatus('200 OK')
        self.assertBody("Hello test, you've been authorized.")
예제 #3
0
파일: auth.py 프로젝트: ddimmich/Cubulus
def check_auth(users, encrypt=None):
    """If an authorization header contains credentials, return True, else False."""
    if 'authorization' in cherrypy.request.headers:
        # make sure the provided credentials are correctly set
        ah = httpauth.parseAuthorization(cherrypy.request.headers['authorization'])
        if ah is None:
            raise cherrypy.HTTPError(400, 'Bad Request')
        
        if not encrypt:
            encrypt = httpauth.DIGEST_AUTH_ENCODERS[httpauth.MD5]
        
        if callable(users):
            users = users() # expect it to return a dictionary
        
        if not isinstance(users, dict):
            raise ValueError, "Authentication users must be a dictionary"
        
        # fetch the user password
        password = users.get(ah["username"], None)
        
        # validate the authorization by re-computing it here
        # and compare it with what the user-agent provided
        if httpauth.checkResponse(ah, password, method=cherrypy.request.method,
                                  encrypt=encrypt):
            return True
    
    return False
예제 #4
0
def check_auth(users, encrypt=None, realm=None):
    """If an authorization header contains credentials, return True, else False."""
    request = cherrypy.serving.request
    if 'authorization' in request.headers:
        ah = httpauth.parseAuthorization(request.headers['authorization'])
        if ah is None:
            raise cherrypy.HTTPError(400, 'Bad Request')
        if not encrypt:
            encrypt = httpauth.DIGEST_AUTH_ENCODERS[httpauth.MD5]
        if hasattr(users, '__call__'):
            try:
                users = users()
                if not isinstance(users, dict):
                    raise ValueError(
                        'Authentication users must be a dictionary')
                password = users.get(ah['username'], None)
            except TypeError:
                password = users(ah['username'])

        else:
            if not isinstance(users, dict):
                raise ValueError('Authentication users must be a dictionary')
            password = users.get(ah['username'], None)
        if httpauth.checkResponse(ah,
                                  password,
                                  method=request.method,
                                  encrypt=encrypt,
                                  realm=realm):
            request.login = ah['username']
            return True
        request.login = False
    return False
예제 #5
0
def check_auth(users, encrypt = None, realm = None):
    request = cherrypy.serving.request
    if 'authorization' in request.headers:
        ah = httpauth.parseAuthorization(request.headers['authorization'])
        if ah is None:
            raise cherrypy.HTTPError(400, 'Bad Request')
        if not encrypt:
            encrypt = httpauth.DIGEST_AUTH_ENCODERS[httpauth.MD5]
        if hasattr(users, '__call__'):
            try:
                users = users()
                if not isinstance(users, dict):
                    raise ValueError('Authentication users must be a dictionary')
                password = users.get(ah['username'], None)
            except TypeError:
                password = users(ah['username'])

        else:
            if not isinstance(users, dict):
                raise ValueError('Authentication users must be a dictionary')
            password = users.get(ah['username'], None)
        if httpauth.checkResponse(ah, password, method=request.method, encrypt=encrypt, realm=realm):
            request.login = ah['username']
            return True
        request.login = False
    return False
예제 #6
0
    def login(self):
        """Validate user credentials"""
        if cherrypy.request.method != "POST":
            return {'_status': 'ERR', '_issues': ['You must only POST on this endpoint.']}

        username = cherrypy.request.json.get('username', None)
        password = cherrypy.request.json.get('password', None)

        # Get HTTP authentication
        authorization = cherrypy.request.headers.get('Authorization', None)
        if authorization:
            ah = httpauth.parseAuthorization(authorization)
            username = ah['username']
            password = ah['password']
        else:
            if cherrypy.request and not cherrypy.request.json:
                return {'_status': 'ERR', '_issues': ['You must POST parameters on this endpoint.']}

            if username is None:
                return {'_status': 'ERR', '_issues': ['Missing username parameter.']}

        token = self.app.backend_token(username, password)
        if not token:
            return {'_status': 'ERR', '_issues': ['Access denied.']}

        cherrypy.session[SESSION_KEY] = cherrypy.request.login = token
        return {'_status': 'OK', '_result': [token]}
예제 #7
0
파일: users.py 프로젝트: MusikPolice/musik
def check_password():
    """If the supplied username and password are valid, returns False, indicating that the request has not been 
    handled, and other request handlers should be allowed to execute.
    
    If the supplied username and password are not valid, returns True, indicating that the request has been 
    handled, and other request handlers should not be allowed to execute. An HTTP 401/403 error will also be
    thrown in this case.
    
    The password argument is first treated as a session token. If this check fails, then it is treated as a 
    password. If either test passes, the cherrypy.request.authorized member is set to True and the 
    cherrypy.request.user member is set to the authenticated user."""
    db = DatabaseWrapper()
    session = db.get_session()

    if 'authorization' in cherrypy.request.headers:
        auth = httpauth.parseAuthorization(cherrypy.request.headers['authorization'])
        if auth is None:
            raise cherrypy.HTTPError(400, 'Invalid Authorization Header.')

        username = auth['username']
        password = auth['password']
        user = None

        # try to treat username as a session token
        if username is not None:
            user = session.query(User).filter(User.username == username and User.token == password and User.token_expires > datetime.datetime.utcnow()).first()
            if user is not None:
                user.update_token_expiry()
                session.commit()
                cherrypy.request.user = user

        # try to look up username and password in the database
        if user is None and username is not None and password is not None:
            user = session.query(User).filter(User.username == username).first()
            if user is not None and user.passhash == user.password_hash(username, password):
                cherrypy.request.user = user

        if user is not None:
            cherrypy.request.authorized = True
            # if the user was authorized, allow other page handlers to run
            return False
        else:
            cherrypy.request.authorized = False
            if cherrypy.request.headers['X-Requested-With'] == 'XMLHttpRequest':
                # if the request came from a browser, don't send a 401 because that will
                # trigger a shitty looking popup. Use a 403 instead.
                raise cherrypy.HTTPError(403, 'Invalid Credentials.')
            else:
                raise cherrypy.HTTPError(401, 'Invalid Credentials.')

            # the user was not authorized, suppress other page handlers from running
            return True
    else:
        raise cherrypy.HTTPError(400, 'Missing Authorization Header.')
예제 #8
0
 def parseBasicAuthorizationHeaders(cls):
     try:
         username = None
         password = None
         authorization = cherrypy.request.headers['authorization']
         authorizationHeader = httpauth.parseAuthorization(authorization)
         if authorizationHeader['auth_scheme'] == 'basic':
             username = authorizationHeader['username']
             password = authorizationHeader['password']
         if username and password:
             return (username, password)
         else:
             raise AuthorizationError(
                 'Username and/or password not supplied.')
     except Exception as ex:
         errorMsg = 'Could not extract username/password from authorization header: %s' % ex
         raise AuthorizationError(errorMsg)
예제 #9
0
def check_auth(users, encrypt=None, realm=None):
    """If an authorization header contains credentials, return True or False.
    """
    request = cherrypy.serving.request
    if 'authorization' in request.headers:
        # make sure the provided credentials are correctly set
        ah = httpauth.parseAuthorization(request.headers['authorization'])
        if ah is None:
            raise cherrypy.HTTPError(400, 'Bad Request')

        if not encrypt:
            encrypt = httpauth.DIGEST_AUTH_ENCODERS[httpauth.MD5]

        if hasattr(users, '__call__'):
            try:
                # backward compatibility
                users = users()  # expect it to return a dictionary

                if not isinstance(users, dict):
                    raise ValueError(
                        'Authentication users must be a dictionary')

                # fetch the user password
                password = users.get(ah['username'], None)
            except TypeError:
                # returns a password (encrypted or clear text)
                password = users(ah['username'])
        else:
            if not isinstance(users, dict):
                raise ValueError('Authentication users must be a dictionary')

            # fetch the user password
            password = users.get(ah['username'], None)

        # validate the authorization by re-computing it here
        # and compare it with what the user-agent provided
        if httpauth.checkResponse(ah,
                                  password,
                                  method=request.method,
                                  encrypt=encrypt,
                                  realm=realm):
            request.login = ah['username']
            return True

        request.login = False
    return False
예제 #10
0
    def login(self, username=None, password=None, fromPage='/'):         \
            # pylint: disable=unused-argument

        if int(cherrypy.request.headers['Content-Length']):
            postdata = cherrypy.request.json
        else:
            postdata = {}

        username = postdata['username'] if 'username' in postdata else None
        password = postdata['password'] if 'password' in postdata else None

        if username is None or password is None:
            logger = logging.getLogger('tortuga.login')
            logger.addHandler(logging.NullHandler())

            logger.debug('Going for Basic Authentication')

            authorization = cherrypy.request.headers['Authorization']

            logger.debug('Authorization: %s' % (authorization))

            ah = httpauth.parseAuthorization(authorization)

            if ah['auth_scheme'] == 'basic':
                username = ah['username']
                password = ah['password']

        if username is None or password is None:
            logger.debug('Either username and/or password unspecified')

            return ''

        errorMsg = checkCredentials(username, password)

        if errorMsg:
            self.addTortugaResponseHeaders(
                tortugaStatus.TORTUGA_USER_NOT_AUTHORIZED_ERROR, errorMsg)

            cherrypy.response.status = 401

            return ''

        cherrypy.session[SESSION_KEY] = cherrypy.request.login = username

        self.addTortugaResponseHeaders(tortugaStatus.TORTUGA_OK)
예제 #11
0
def checkAuth(*args):  # pylint: disable=unused-argument
    """
    A tool that looks in config for 'auth.require'. If found and it
    is not None, a login is required and the entry is evaluated as a list
    of conditions that the user must fulfill.
    """

    logger = logging.getLogger('tortuga.checkAuth')
    logger.addHandler(logging.NullHandler())

    conditions = cherrypy.request.config.get('auth.require', None)

    if conditions is not None:
        username = cherrypy.session.get(SESSION_KEY)

        if username:
            cherrypy.request.login = username
            for condition in conditions:
                # A condition is just a callable that returns true or false
                if not condition():
                    # Send old page as fromPage parameter
                    logger.debug('Authorization failed for: %s ' % (username))

                    raise TortugaHTTPAuthError()
        else:
            username = None
            password = None

            if 'authorization' not in cherrypy.request.headers:
                raise TortugaHTTPAuthError()

            authorization = cherrypy.request.headers['authorization']

            ah = httpauth.parseAuthorization(authorization)

            if ah['auth_scheme'] == 'basic':
                username = ah['username']
                password = ah['password']

            if username and password and \
                    not checkCredentials(username, password):
                return

            raise TortugaHTTPAuthError()
예제 #12
0
파일: auth.py 프로젝트: 7924102/cherrypy
def check_auth(users, encrypt=None, realm=None):
    """If an authorization header contains credentials, return True or False.
    """
    request = cherrypy.serving.request
    if 'authorization' in request.headers:
        # make sure the provided credentials are correctly set
        ah = httpauth.parseAuthorization(request.headers['authorization'])
        if ah is None:
            raise cherrypy.HTTPError(400, 'Bad Request')

        if not encrypt:
            encrypt = httpauth.DIGEST_AUTH_ENCODERS[httpauth.MD5]

        if hasattr(users, '__call__'):
            try:
                # backward compatibility
                users = users()  # expect it to return a dictionary

                if not isinstance(users, dict):
                    raise ValueError(
                        "Authentication users must be a dictionary")

                # fetch the user password
                password = users.get(ah["username"], None)
            except TypeError:
                # returns a password (encrypted or clear text)
                password = users(ah["username"])
        else:
            if not isinstance(users, dict):
                raise ValueError("Authentication users must be a dictionary")

            # fetch the user password
            password = users.get(ah["username"], None)

        # validate the authorization by re-computing it here
        # and compare it with what the user-agent provided
        if httpauth.checkResponse(ah, password, method=request.method,
                                  encrypt=encrypt, realm=realm):
            request.login = ah["username"]
            return True

        request.login = False
    return False
예제 #13
0
def check_auth(users, encrypt=None, realm=None):
    """If an authorization header contains credentials, return True, else False."""
    if 'authorization' in cherrypy.request.headers:
        # make sure the provided credentials are correctly set
        ah = httpauth.parseAuthorization(cherrypy.request.headers['authorization'])
        if ah is None:
            raise cherrypy.HTTPError(400, 'Bad Request')

        if not encrypt:
            encrypt = httpauth.DIGEST_AUTH_ENCODERS[httpauth.MD5]

        if callable(users):
            try:
                # backward compatibility
                users = users() # expect it to return a dictionary

                if not isinstance(users, dict):
                    raise ValueError, "Authentication users must be a dictionary"

                # fetch the user password
                password = users.get(ah["username"], None)
            except TypeError:
                # returns a password (encrypted or clear text)
                password = users(ah["username"])
        else:
            if not isinstance(users, dict):
                raise ValueError, "Authentication users must be a dictionary"

            # fetch the user password
            password = users.get(ah["username"], None)

        # validate the authorization by re-computing it here
        # and compare it with what the user-agent provided
        if httpauth.checkResponse(ah, password, method=cherrypy.request.method,
                                  encrypt=encrypt, realm=realm):
            cherrypy.request.login = ah["username"]
            return True

        if ah.get('username') or ah.get('password'):
            logging.info('Attempt to login with wrong credentials from %s',
                         cherrypy.request.headers['Remote-Addr'])
        cherrypy.request.login = False
    return False
예제 #14
0
def parseBasicAuthorizationHeaders():
    try:
        logger = loggingManager.getLogger('parseBasicAuthorizationHeader')
        username = None
        password = None
        authorization = cherrypy.request.headers['authorization']
        authorizationHeader = httpauth.parseAuthorization(authorization)
        logger.debug('Authorization header: %s' % authorizationHeader)
        if authorizationHeader['auth_scheme'] == 'basic':
            username = authorizationHeader['username']
            password = authorizationHeader['password']
            logger.debug('Got username/password from headers: %s/%s' %
                         (username, password))
        if username and password:
            return (username, password)
        else:
            raise AuthorizationError('Username and/or password not supplied.')
    except Exception, ex:
        errorMsg = 'Could not extract username/password from authorization header: %s' % ex
        raise AuthorizationError(errorMsg)
예제 #15
0
def protect(*args, **kwargs):
    # pylint: disable=unused-argument
    """
    Check user credentials from HTTP Authorization request header
    """

    authenticated = False

    # A condition is just a callable that returns true or false
    conditions = cherrypy.request.config.get('auth.require', None)
    if conditions is not None:
        app = cherrypy.request.app.root.app

        try:
            logger.debug("Checking session: %s", SESSION_KEY)
            cherrypy.log("Checking session: %s" % SESSION_KEY)
            # check if there is an active session
            # sessions are turned on so we just have to know if there is
            # something inside of cherrypy.session[SESSION_KEY]:
            session_token = cherrypy.session[SESSION_KEY]
            logger.debug("Session: %s", session_token)
            cherrypy.log("Session: %s" % session_token)

            # Not sure if I need to do this myself or what
            cherrypy.session.regenerate()
            cherrypy.request.login = cherrypy.session[SESSION_KEY]

            authenticated = True
        except KeyError:
            # If the session isn't set, it either was not existing or valid.
            # Now check if the request includes HTTP Authorization?
            authorization = cherrypy.request.headers.get('Authorization')
            if authorization:
                logger.debug("Got authorization header: %s", authorization)
                ah = httpauth.parseAuthorization(authorization)

                # Get module application from cherrypy request
                logger.debug("Requesting login for %s@%s...",
                             ah['username'], cherrypy.request.remote.ip)
                cherrypy.log("Requesting login for %s@%s..."
                             % (ah['username'], cherrypy.request.remote.ip))
                token = app.backend_token(username=ah['username'], password=ah['password'])
                if token:
                    cherrypy.session.regenerate()
                    # This line of code is discussed in doc/sessions-and-auth.markdown
                    cherrypy.session[SESSION_KEY] = token
                    authenticated = True
                    logger.debug("Authenticated with backend")
                    cherrypy.log("Authenticated with backend")
                else:
                    logger.warning("Failed attempt to log in with authorization header for %s..",
                                   cherrypy.request.remote.ip)
                    cherrypy.session[SESSION_KEY] = ''
            else:
                logger.debug("No authorization header for %s.", cherrypy.request.remote.ip)
                cherrypy.session[SESSION_KEY] = ''

        except Exception as exp:  # pylint: disable=bare-except
            cherrypy.log("Exception: %s" % exp)
            cherrypy.log("Back trace of the error:\n%s" % traceback.format_exc())
            logger.warning("Client %s has no valid session and did not provided "
                           "HTTP Authorization credentials.", cherrypy.request.remote.ip)
            cherrypy.log("Client %s has no valid session and did not provided "
                         "HTTP Authorization credentials." % cherrypy.request.remote.ip)
            cherrypy.session[SESSION_KEY] = ''

        if authenticated:
            for condition in conditions:
                if not condition():
                    logger.warning("Authentication succeeded but authorization failed.")
                    raise cherrypy.HTTPError("403 Forbidden")
        else:
            raise cherrypy.HTTPError("401 Unauthorized")
    def testDigest(self):
        self.getPage("/digest/")
        self.assertStatus(401)

        value = None
        for k, v in self.headers:
            if k.lower() == "www-authenticate":
                if v.startswith("Digest"):
                    value = v
                    break

        if value is None:
            self._handlewebError("Digest authentification scheme was not found")

        value = value[7:]
        items = value.split(", ")
        tokens = {}
        for item in items:
            key, value = item.split("=")
            tokens[key.lower()] = value

        missing_msg = "%s is missing"
        bad_value_msg = "'%s' was expecting '%s' but found '%s'"
        nonce = None
        if "realm" not in tokens:
            self._handlewebError(missing_msg % "realm")
        elif tokens["realm"] != '"localhost"':
            self._handlewebError(bad_value_msg % ("realm", '"localhost"', tokens["realm"]))
        if "nonce" not in tokens:
            self._handlewebError(missing_msg % "nonce")
        else:
            nonce = tokens["nonce"].strip('"')
        if "algorithm" not in tokens:
            self._handlewebError(missing_msg % "algorithm")
        elif tokens["algorithm"] != '"MD5"':
            self._handlewebError(bad_value_msg % ("algorithm", '"MD5"', tokens["algorithm"]))
        if "qop" not in tokens:
            self._handlewebError(missing_msg % "qop")
        elif tokens["qop"] != '"auth"':
            self._handlewebError(bad_value_msg % ("qop", '"auth"', tokens["qop"]))

        # Test a wrong 'realm' value
        base_auth = (
            "Digest "
            'username="******", '
            'realm="wrong realm", '
            'nonce="%s", '
            'uri="/digest/", '
            "algorithm=MD5, "
            'response="%s", '
            "qop=auth, "
            "nc=%s, "
            'cnonce="1522e61005789929"'
        )

        auth = base_auth % (nonce, "", "00000001")
        params = httpauth.parseAuthorization(auth)
        response = httpauth._computeDigestResponse(params, "test")

        auth = base_auth % (nonce, response, "00000001")
        self.getPage("/digest/", [("Authorization", auth)])
        self.assertStatus(401)

        # Test that must pass
        base_auth = (
            "Digest "
            'username="******", '
            'realm="localhost", '
            'nonce="%s", '
            'uri="/digest/", '
            "algorithm=MD5, "
            'response="%s", '
            "qop=auth, "
            "nc=%s, "
            'cnonce="1522e61005789929"'
        )

        auth = base_auth % (nonce, "", "00000001")
        params = httpauth.parseAuthorization(auth)
        response = httpauth._computeDigestResponse(params, "test")

        auth = base_auth % (nonce, response, "00000001")
        self.getPage("/digest/", [("Authorization", auth)])
        self.assertStatus("200 OK")
        self.assertBody("Hello test, you've been authorized.")