def password_is(self, password, upgrade_hash=False): """Test if the candidate password matches saved hash.""" if self.pw_hash is None: return False # Passwords may use the current Argon2 scheme or the older Bcrypt scheme. # Bcrypt passwords are transparently upgraded if requested. if argon2.identify(self.pw_hash): return argon2.verify(password, self.pw_hash) elif bcrypt.identify(self.pw_hash): verified = bcrypt.verify(password, self.pw_hash) if verified and upgrade_hash: self.pw_hash = argon2.hash(password) return verified return False
def check_auth(username, password): """This function is called to check if a username / password combination is valid. """ def any_(l): """Check if any element in the list is true, in constant time. """ ret = False for e in l: if e: ret = True return ret user_ok = False pass_sha1_ok = pbkdf2_sha256_ok = pass_sha512_ok = pass_sha512_crypt_ok = pass_bcrypt_crypt_ok = False user_ok = app.conf['wapt_user'] == username pass_sha1_ok = app.conf['wapt_password'] == hashlib.sha1( password.encode('utf8')).hexdigest() pass_sha512_ok = app.conf['wapt_password'] == hashlib.sha512( password.encode('utf8')).hexdigest() if '$pbkdf2-sha256$' in app.conf['wapt_password']: pbkdf2_sha256_ok = pbkdf2_sha256.verify(password, app.conf['wapt_password']) elif sha512_crypt.identify(app.conf['wapt_password']): pass_sha512_crypt_ok = sha512_crypt.verify(password, app.conf['wapt_password']) else: try: if bcrypt.identify(app.conf['wapt_password']): pass_bcrypt_crypt_ok = bcrypt.verify(password, app.conf['wapt_password']) except Exception: pass basic_auth = any_([ pbkdf2_sha256_ok, pass_sha1_ok, pass_sha512_ok, pass_sha512_crypt_ok, pass_bcrypt_crypt_ok ]) and user_ok return basic_auth or (auth_module_ad is not None and auth_module_ad.check_credentials_ad( app.conf, username, password))
def check_auth(username, password): """This function is called to check if a username / password combination is valid. """ def any_(l): """Check if any element in the list is true, in constant time. """ ret = False for e in l: if e: ret = True return ret user_ok = False pass_sha1_ok = pbkdf2_sha256_ok = pass_sha512_ok = pass_sha512_crypt_ok = pass_bcrypt_crypt_ok = False user_ok = app.conf['wapt_user'] == username pass_sha1_ok = app.conf['wapt_password'] == hashlib.sha1( password.encode('utf8')).hexdigest() pass_sha512_ok = app.conf['wapt_password'] == hashlib.sha512( password.encode('utf8')).hexdigest() if '$pbkdf2-sha256$' in app.conf['wapt_password']: pbkdf2_sha256_ok = pbkdf2_sha256.verify(password, app.conf['wapt_password']) elif sha512_crypt.identify(app.conf['wapt_password']): pass_sha512_crypt_ok = sha512_crypt.verify( password, app.conf['wapt_password']) else: try: if bcrypt.identify(app.conf['wapt_password']): pass_bcrypt_crypt_ok = bcrypt.verify( password, app.conf['wapt_password']) except Exception: pass basic_auth = any_([pbkdf2_sha256_ok, pass_sha1_ok, pass_sha512_ok, pass_sha512_crypt_ok, pass_bcrypt_crypt_ok]) and user_ok return basic_auth or (auth_module_ad is not None and auth_module_ad.check_credentials_ad(app.conf, username, password))
def verify(self, password, hashed, algorithm=None): """ Validates a password against a provided hash. This is a wrapper around various hash algorithms supported by this library. This function will try to guess the algorithm based on the hash. :param password: :param hashed: :param algorithm: :return: """ if algorithm is None: if argon2.identify(hashed): results = yield self.argon2_verify(password, hashed) return results if bcrypt.identify(hashed): results = yield self.bcrypt_verify(password, hashed) return results if algorithm is None: logger.warn("Unable to detect password hash algorithm") return False
def identify(hash): return bcrypt.identify(hash)
def checkPass(self, uid, password): ''' checkPass - checks the password for a given uid. :param uid: userid to be checked :type uid: string :param password: user password :type password: string :return : true in case of success, false if password does not match :rtype : boolean :todo: extend to support htpasswd passwords: http://httpd.apache.org/docs/2.2/misc/password_encryptions.html ''' log.info("[checkPass] checking password for user %s" % uid) userInfo = self.getUserInfo(uid, suppress_password=False) # adapt the encoding of the password to the encoding of the database if len(self.sqlEncoding) > 0: # FIXME: this fails at the moment #password = password.encode(self.sqlEncoding) pass # get the crypted password and the salt from the database # for doing crypt.crypt( "password", "salt" ) if "password" not in userInfo: log.error("[checkPass] password is not defined in SQL mapping!") return False # check if we have something like SHA or salted SHA m = re.match("^\{(.*)\}(.*)", userInfo["password"]) if m: # The password field contains something like # {SHA256}abcdfef123456 hash_type = m.group(1) hash_value = m.group(2) # Check for salt field in case the db splits salt from hash: salt = None if 'salt' in userInfo: salt = userInfo['salt'] return _check_hash_type(password, hash_type, hash_value, salt=salt) elif passlib_phpass.identify(userInfo["password"]): # The Password field contains something like # '$P$BPC00gOTHbTWl6RH6ZyfYVGWkX3Wec.' return check_php_password(password, userInfo["password"]) elif passlib_bcrypt.identify(userInfo["password"]): # password starts with $2$, $2a$, $2b$, $2b$, $2x$ or $2y$ return check_bcypt_password(password, userInfo["password"]) elif userInfo["password"][0] == '$': # ----------------------------------------------------------- -- # check the Modular Crypt Format (MCF): # # $<id>[$<param>=<value>(,<param>=<value>)*][$<salt>[$<hash>]] # # s. https://en.wikipedia.org/wiki/Crypt_%28C%29 if crypt.crypt(password, userInfo["password"]) == userInfo["password"]: log.info( "[checkPass] successfully authenticated " "user uid %s", uid) return True else: log.warning("[checkPass] user %s failed to authenticate.", uid) return False else: # ------------------------------------------------------------- -- # old style with dedicated salt from the database for doing # crypt.crypt( "password", "salt" ) salt = userInfo["password"][0:2] if "salt" in userInfo: salt = userInfo["salt"] npw = crypt.crypt(password, salt) if npw == userInfo["password"]: log.info("[checkPass] user %s authenticated successfully.", uid) return True log.warning("[checkPass] user %s failed to authenticate.", uid) return False
def save(self, *args, **kwargs): if self.pk is None: self.password = bcrypt.encrypt(self.password) elif bcrypt.identify(self.password) is False: self.password = bcrypt.encrypt(self.password) super(OAuthCredentials, self).save(*args, **kwargs)
def check_auth( username=None, password = None, request = None, session=None, methods=['admin','ldap','session']): """This function is called to check if a username / password combination is valid or to get already authenticated username from session argument. If no username or password, use session.authorization header if available. Args: username (str): password (str): request (Flask.Request) : request where to lookup authrization basic header session (Flask.Session) where to lookup session user methods (list of str) : list of auth method to try until one is successfull 'session': use current session user if it matches username 'admin': 'ldap': 'kerb': 'ssl': 'passwd': Returns: dict (auth_method = auth_method,user=auth_user,auth_date=auth_date) None if auth is not successfull """ if username is None and password is None and request is not None and request.authorization: username = request.authorization.username password = request.authorization.password auth_method = None auth_user = None auth_date = None assert(isinstance(methods,list)) for method in methods: if method == 'session' and session: session_user = session.get('user',None) if session_user and (username is None or username == session_user): auth_user = session_user auth_date = session.get('auth_date',None) auth_method = method logger.debug(u'User %s authenticated using session cookie' % (username,)) elif method == 'passwd' and valid_username(username) and username != app.conf['wapt_user'] and password is not None: # local htpasswd user/passwd file for add_host registration action if app.conf.get('htpasswd_path'): htpasswd_users = HtpasswdFile(app.conf.get('htpasswd_path')) if htpasswd_users.verify(username,password): auth_method = method auth_user = username auth_date = datetime.datetime.utcnow().isoformat() logger.debug(u'User %s authenticated using htpasswd %s' % (username,htpasswd_users)) else: logger.debug(u'user %s htpasswd %s verification failed' % (username,htpasswd_users)) elif method == 'admin' and valid_username(username) and app.conf['wapt_user'] == username and password is not None: pbkdf2_sha256_ok = False pass_sha512_crypt_ok = False pass_bcrypt_crypt_ok = False if '$pbkdf2-sha256$' in app.conf['wapt_password']: pbkdf2_sha256_ok = pbkdf2_sha256.verify(password, app.conf['wapt_password']) elif sha512_crypt.identify(app.conf['wapt_password']): pass_sha512_crypt_ok = sha512_crypt.verify( password, app.conf['wapt_password']) else: try: if bcrypt.identify(app.conf['wapt_password']): pass_bcrypt_crypt_ok = bcrypt.verify( password, app.conf['wapt_password']) except Exception: pass if pbkdf2_sha256_ok or pass_sha512_crypt_ok or pass_bcrypt_crypt_ok: auth_method = method auth_user = username auth_date = datetime.datetime.utcnow().isoformat() else: logger.debug(u'wapt admin passwd verification failed') elif method == 'token': # token auth token_secret_key = app.conf['secret_key'] if token_secret_key: # check if there is a valid token in the password try: token_gen = get_secured_token_generator(token_secret_key) # check if there is a Bearer, else use Basic / password authorization = request.headers.get('Authorization') if authorization and authorization.startswith('Bearer '): token_data = token_gen.loads(authorization.split(' ',1)[1]) elif password is not None: token_data = token_gen.loads(password) else: raise EWaptAuthenticationFailure('No token') uuid = token_data.get('uuid', token_data.get('user',None)) if not uuid: raise EWaptAuthenticationFailure('Bad token UUID') if token_data['server_uuid'] != get_server_uuid(): raise EWaptAuthenticationFailure('Bad server UUID') auth_method = method auth_user = uuid auth_date = datetime.datetime.fromtimestamp(token_data['iat']).isoformat() logger.debug(u'User %s authenticated using token' % (uuid,)) except Exception as e: logger.debug(u'Token verification failed : %s' % repr(e)) pass elif method == 'kerb' and app.conf['use_kerberos']: # with nginx kerberos module, auth user name is stored as Basic auth in the # 'Authorisation' header with password 'bogus_auth_gss_passwd' # Kerberos auth negociated by nginx if username != '' and password == 'bogus_auth_gss_passwd': authenticated_user = username.lower().replace('$', '') auth_method = method auth_user = authenticated_user auth_date = datetime.datetime.utcnow().isoformat() logger.debug(u'User %s authenticated using kerberos' % (authenticated_user,)) elif method == 'ldap' and valid_username(username) and password is not None: if auth_module_ad is not None and (app.conf['wapt_user'] != username and auth_module_ad.check_credentials_ad(app.conf, username, password)): auth_method = method auth_user = username auth_date = datetime.datetime.utcnow().isoformat() logger.debug(u'User %s authenticated using LDAP' % (username,)) # nginx ssl auth. elif method == 'ssl' and request and app.conf['use_ssl_client_auth'] and request.headers.get('X-Ssl-Authenticated', None) == 'SUCCESS': dn = request.headers.get('X-Ssl-Client-Dn', None) if dn: auth_method = method # strip CN= if no other suffix. if dn.upper().startswith('CN='): auth_user = dn.split('=',1)[1] else: auth_user = dn auth_date = datetime.datetime.utcnow().isoformat() logger.debug(u'User %s authenticated using SSL client certificate' % (dn,)) if auth_method and auth_user: break #only session and admin methods are ok for the embedded wapt admin password based account. if auth_method and auth_user and (auth_user != app.conf['wapt_user'] or auth_method in ('session','admin')): return dict(auth_method = auth_method,user=auth_user,auth_date=auth_date) else: return None