def verify_otp_code(self, code): otp_secret = self.otp_secret padding = 8 - len(otp_secret) % 8 if padding != 8: otp_secret = otp_secret.ljust(len(otp_secret) + padding, '=') otp_secret = base64.b32decode(otp_secret.upper()) valid_codes = [] epoch = int(utils.time_now() / 30) for epoch_offset in range(-1, 2): value = struct.pack('>q', epoch + epoch_offset) hmac_hash = hmac.new(otp_secret, value, hashlib.sha1).digest() offset = ord(hmac_hash[-1]) & 0x0F truncated_hash = hmac_hash[offset:offset + 4] truncated_hash = struct.unpack('>L', truncated_hash)[0] truncated_hash &= 0x7FFFFFFF truncated_hash %= 1000000 valid_codes.append('%06d' % truncated_hash) if code not in valid_codes: return False response = self.otp_collection.update({ '_id': { 'user_id': self.id, 'code': code, }, }, {'$set': { 'timestamp': utils.now(), }}, upsert=True) if response['updatedExisting']: return False return True
def check_session(csrf_check): auth_token = flask.request.headers.get('Auth-Token', None) if auth_token: auth_timestamp = flask.request.headers.get('Auth-Timestamp', None) auth_nonce = flask.request.headers.get('Auth-Nonce', None) auth_signature = flask.request.headers.get('Auth-Signature', None) if not auth_token or not auth_timestamp or not auth_nonce or \ not auth_signature: return False auth_nonce = auth_nonce[:32] try: if abs(int(auth_timestamp) - int(utils.time_now())) > \ settings.app.auth_time_window: return False except ValueError: return False administrator = find_user(token=auth_token) if not administrator: return False if not administrator.auth_api: return False auth_string = '&'.join([ auth_token, auth_timestamp, auth_nonce, flask.request.method, flask.request.path]) if len(auth_string) > AUTH_SIG_STRING_MAX_LEN or len(auth_nonce) < 8: return False if not administrator.secret or len(administrator.secret) < 8: return False auth_test_signature = base64.b64encode(hmac.new( administrator.secret.encode(), auth_string, hashlib.sha256).digest()) if auth_signature != auth_test_signature: return False try: Administrator.nonces_collection.insert({ 'token': auth_token, 'nonce': auth_nonce, 'timestamp': utils.now(), }) except pymongo.errors.DuplicateKeyError: return False else: if not flask.session: return False admin_id = utils.session_opt_str('admin_id') if not admin_id: return False admin_id = utils.ObjectId(admin_id) session_id = utils.session_opt_str('session_id') signature = utils.session_opt_str('signature') if not signature: return False if not utils.check_flask_sig(): return False if csrf_check: csrf_token = flask.request.headers.get('Csrf-Token', None) if not validate_token(csrf_token): logger.error('CSRF token check failed', 'auth', method=flask.request.method, path=flask.request.path, ) return False administrator = get_user(admin_id, session_id) if not administrator: return False if not settings.app.reverse_proxy and \ not settings.app.allow_insecure_session and \ not settings.app.server_ssl and \ utils.session_opt_str('source') != utils.get_remote_addr(): flask.session.clear() clear_session(admin_id, session_id) return False session_timeout = settings.app.session_timeout if session_timeout and int(utils.time_now()) - \ utils.session_int('timestamp') > session_timeout: flask.session.clear() clear_session(admin_id, session_id) return False flask.session['timestamp'] = int(utils.time_now()) utils.set_flask_sig() if administrator.disabled: return False flask.g.administrator = administrator return True
def check_session(): auth_token = flask.request.headers.get('Auth-Token', None) if auth_token: auth_timestamp = flask.request.headers.get('Auth-Timestamp', None) auth_nonce = flask.request.headers.get('Auth-Nonce', None) auth_signature = flask.request.headers.get('Auth-Signature', None) if not auth_token or not auth_timestamp or not auth_nonce or \ not auth_signature: return False auth_nonce = auth_nonce[:32] try: if abs(int(auth_timestamp) - int(utils.time_now())) > \ settings.app.auth_time_window: return False except ValueError: return False administrator = find_user(token=auth_token) if not administrator: return False if not administrator.auth_api: return False auth_string = '&'.join([ auth_token, auth_timestamp, auth_nonce, flask.request.method, flask.request.path] + ([flask.request.data] if flask.request.data else [])) if len(auth_string) > AUTH_SIG_STRING_MAX_LEN: return False if not administrator.secret or len(administrator.secret) < 8: return False auth_test_signature = base64.b64encode(hmac.new( administrator.secret.encode(), auth_string, hashlib.sha256).digest()) if auth_signature != auth_test_signature: return False try: Administrator.nonces_collection.insert({ 'token': auth_token, 'nonce': auth_nonce, 'timestamp': utils.now(), }) except pymongo.errors.DuplicateKeyError: return False else: if not flask.session: return False admin_id = flask.session.get('admin_id') if not admin_id: return False admin_id = utils.ObjectId(admin_id) session_id = flask.session.get('session_id') administrator = get_user(admin_id, session_id) if not administrator: return False if not settings.app.allow_insecure_session and \ not settings.conf.ssl and flask.session.get( 'source') != utils.get_remote_addr(): flask.session.clear() return False session_timeout = settings.app.session_timeout if session_timeout and int(utils.time_now()) - \ flask.session['timestamp'] > session_timeout: flask.session.clear() return False flask.session['timestamp'] = int(utils.time_now()) if administrator.disabled: return False flask.g.administrator = administrator return True