def get_by_username(username, remote_addr=None): username = utils.filter_str(username).lower() if remote_addr: doc = Administrator.limiter_collection.find_and_modify({ '_id': remote_addr, }, { '$inc': {'count': 1}, '$setOnInsert': {'timestamp': utils.now()}, }, new=True, upsert=True) if utils.now() > doc['timestamp'] + datetime.timedelta(minutes=1): doc = { 'count': 1, 'timestamp': utils.now(), } Administrator.limiter_collection.update({ '_id': remote_addr, }, doc, upsert=True) if doc['count'] > settings.app.auth_limiter_count_max: raise flask.abort(403) admin = find_user(username=username) if not admin: return return admin
def check_auth(username, password, remote_addr=None): username = utils.filter_str(username).lower() if remote_addr: doc = Administrator.limiter_collection.find_and_modify( { '_id': remote_addr, }, { '$inc': { 'count': 1 }, '$setOnInsert': { 'timestamp': utils.now() }, }, new=True, upsert=True) if utils.now() > doc['timestamp'] + datetime.timedelta(minutes=1): doc = { 'count': 1, 'timestamp': utils.now(), } Administrator.limiter_collection.update({ '_id': remote_addr, }, doc, upsert=True) if doc['count'] > settings.app.auth_limiter_count_max: raise flask.abort(403) administrator = find_user(username=username) if not administrator: return if not administrator.test_password(password): return sso_admin = settings.app.sso_admin if settings.app.sso and DUO_AUTH in settings.app.sso and sso_admin: allow, _ = sso.auth_duo(sso_admin, strong=True, ipaddr=remote_addr, type='Administrator') if not allow: return return administrator
def audit_event(self, event_type, event_msg, remote_addr=None): if settings.app.auditing != ALL: return timestamp = utils.now() self.audit_collection.insert({ 'user_id': self.id, 'timestamp': timestamp, 'type': event_type, 'remote_addr': remote_addr, 'message': event_msg, }) plugins.event( 'audit_event', host_id=settings.local.host_id, host_name=settings.local.host.name, user_id=self.id, org_id=None, timestamp=timestamp, type=event_type, remote_addr=remote_addr, message=event_msg, )
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 audit_event(self, event_type, event_msg, remote_addr=None): if settings.app.auditing != ALL: return self.audit_collection.insert({ 'user_id': self.id, 'timestamp': utils.now(), 'type': event_type, 'remote_addr': remote_addr, 'message': event_msg, })
def check_auth(username, password, remote_addr=None): username = utils.filter_str(username).lower() if remote_addr: doc = Administrator.limiter_collection.find_and_modify({ '_id': remote_addr, }, { '$inc': {'count': 1}, '$setOnInsert': {'timestamp': utils.now()}, }, new=True, upsert=True) if utils.now() > doc['timestamp'] + datetime.timedelta(minutes=1): doc = { 'count': 1, 'timestamp': utils.now(), } Administrator.limiter_collection.update({ '_id': remote_addr, }, doc, upsert=True) if doc['count'] > settings.app.auth_limiter_count_max: raise flask.abort(403) administrator = find_user(username=username) if not administrator: return if not administrator.test_password(password): return sso_admin = settings.app.sso_admin if settings.app.sso and DUO_AUTH in settings.app.sso and sso_admin: allow, _ = sso.auth_duo( sso_admin, strong=True, ipaddr=remote_addr, type='Administrator' ) if not allow: return return administrator
def audit_event(event_type, event_msg, remote_addr=None): if settings.app.auditing != ALL: return audit_collection = mongo.get_collection('users_audit') audit_collection.insert_one({ 'user_id': 'admin', 'org_id': 'admin', 'timestamp': utils.now(), 'type': event_type, 'remote_addr': remote_addr, 'message': event_msg, })
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