def decrypt_token(token, _from): ''' Decrypt a token. ''' try: token_key = '{0}{1}'.format(hashlib.sha256(token).hexdigest(), _from) except Exception: raise TokenDecryptionError('Authentication error.') if token_key not in TOKENS: try: token = base64.b64decode(token) with stats.timer('kms_decrypt_token'): data = kms.decrypt( CiphertextBlob=token, EncryptionContext={ # This key is sent to us. 'to': app.config['AUTH_CONTEXT'], # From a service. 'from': _from }) # Decrypt doesn't take KeyId as an argument. We need to verify the # correct key was used to do the decryption. # Annoyingly, the KeyId from the data is actually an arn. key_arn = data['KeyId'] if key_arn != get_key_arn(app.config['AUTH_KEY']): raise TokenDecryptionError('Authentication error.') plaintext = data['Plaintext'] payload = json.loads(plaintext) # We don't care what exception is thrown. For paranoia's sake, fail # here. except Exception: log.exception('Failed to validate token.') raise TokenDecryptionError('Authentication error.') else: payload = TOKENS[token_key] time_format = "%Y%m%dT%H%M%SZ" now = datetime.datetime.utcnow() try: not_before = datetime.datetime.strptime(payload['not_before'], time_format) not_after = datetime.datetime.strptime(payload['not_after'], time_format) except Exception: log.exception( 'Failed to get not_before and not_after from token payload.') raise TokenDecryptionError('Authentication error.') delta = (not_after - not_before).seconds / 60 if delta > app.config['AUTH_TOKEN_MAX_LIFETIME']: log.warning('Token used which exceeds max token lifetime.') raise TokenDecryptionError('Authentication error.') if not (now >= not_before) and (now <= not_after): log.warning('Expired token used.') raise TokenDecryptionError('Authentication error.') TOKENS[token_key] = payload return payload
def _get_credentials(credential_ids): credentials = [] with stats.timer('service_batch_get_credentials'): for cred in Credential.batch_get(credential_ids): data_key = keymanager.decrypt_key( cred.data_key, encryption_context={'id': cred.id}) cipher_version = cred.cipher_version cipher = CipherManager(data_key, cipher_version) _credential_pairs = cipher.decrypt(cred.credential_pairs) _credential_pairs = json.loads(_credential_pairs) credentials.append({ 'id': cred.id, 'name': cred.name, 'enabled': cred.enabled, 'revision': cred.revision, 'credential_pairs': _credential_pairs }) return credentials
def _get_credentials(credential_ids): credentials = [] with stats.timer('service_batch_get_credentials'): for cred in Credential.batch_get(credential_ids): data_key = keymanager.decrypt_key( cred.data_key, encryption_context={'id': cred.id} ) cipher_version = cred.cipher_version cipher = CipherManager(data_key, cipher_version) _credential_pairs = cipher.decrypt(cred.credential_pairs) _credential_pairs = json.loads(_credential_pairs) credentials.append({ 'id': cred.id, 'name': cred.name, 'enabled': cred.enabled, 'revision': cred.revision, 'credential_pairs': _credential_pairs }) return credentials
def decrypt_token(token, _from): ''' Decrypt a token. ''' try: token_key = '{0}{1}'.format( hashlib.sha256(token).hexdigest(), _from ) except Exception: raise TokenDecryptionError('Authentication error.') if token_key not in TOKENS: try: token = base64.b64decode(token) with stats.timer('kms_decrypt_token'): data = kms.decrypt( CiphertextBlob=token, EncryptionContext={ # This key is sent to us. 'to': app.config['AUTH_CONTEXT'], # From a service. 'from': _from } ) # Decrypt doesn't take KeyId as an argument. We need to verify the # correct key was used to do the decryption. # Annoyingly, the KeyId from the data is actually an arn. key_arn = data['KeyId'] if key_arn != get_key_arn(app.config['AUTH_KEY']): raise TokenDecryptionError('Authentication error.') plaintext = data['Plaintext'] payload = json.loads(plaintext) # We don't care what exception is thrown. For paranoia's sake, fail # here. except Exception: log.exception('Failed to validate token.') raise TokenDecryptionError('Authentication error.') else: payload = TOKENS[token_key] time_format = "%Y%m%dT%H%M%SZ" now = datetime.datetime.utcnow() try: not_before = datetime.datetime.strptime( payload['not_before'], time_format ) not_after = datetime.datetime.strptime( payload['not_after'], time_format ) except Exception: log.exception( 'Failed to get not_before and not_after from token payload.' ) raise TokenDecryptionError('Authentication error.') delta = (not_after - not_before).seconds / 60 if delta > app.config['AUTH_TOKEN_MAX_LIFETIME']: log.warning('Token used which exceeds max token lifetime.') raise TokenDecryptionError('Authentication error.') if not (now >= not_before) and (now <= not_after): log.warning('Expired token used.') raise TokenDecryptionError('Authentication error.') TOKENS[token_key] = payload return payload
def decorated(*args, **kwargs): if not app.config.get('USE_AUTH'): return f(*args, **kwargs) auth = request.authorization headers = request.headers using_basic_kms_auth = (auth and auth.get('username') and auth.get('password') != '') using_kms_auth = ('X-Auth-Token' in headers and 'X-Auth-From' in headers) # User suppplied basic auth info if using_basic_kms_auth or using_kms_auth: if using_basic_kms_auth: _from = auth['username'] token = auth['password'] else: _from = headers['X-Auth-From'] token = headers['X-Auth-Token'] try: with stats.timer('decrypt_token'): payload = keymanager.decrypt_token(token, _from) log.debug('Auth request had the following payload:' ' {0}'.format(payload)) role = 'service' msg = 'Authenticated {0} with role {1} via kms auth' msg = msg.format(_from, role) log.debug(msg) if role_has_privilege(role, f.func_name): g.auth_role = role g.username = _from return f(*args, **kwargs) else: msg = '{0} is not authorized to access {1}.' msg = msg.format(_from, f.func_name) log.warning(msg) return abort(403) except keymanager.TokenDecryptionError: msg = 'Access denied for {0}. Authentication Failed.' msg = msg.format(_from) log.warning(msg) return abort(403) # If not using kms auth, require google auth. else: role = 'user' if not role_has_privilege(role, f.func_name): return abort(403) if 'email' in session.get('google_oauth2', []): if (app.config['USERS_FILE'] and get_logged_in_user_email() not in users): msg = 'User not authorized: {0}' log.warning(msg.format(get_logged_in_user_email())) return abort(403) else: g.auth_role = role return f(*args, **kwargs) response = make_response() if request.is_secure: secure_cookie = True else: secure_cookie = False result = _authomatic.login( WerkzeugAdapter(request, response), 'google', session=session, session_saver=lambda: app.save_session(session, response), secure_cookie=secure_cookie) if result: if result.error: msg = 'Google auth failed with error: {0}' log.error(msg.format(result.error.message)) return abort(403) if result.user: result.user.update() user = result.user email_suffix = app.config['GOOGLE_AUTH_EMAIL_SUFFIX'] if email_suffix and not user.email.endswith(email_suffix): return abort(403) session['google_oauth2'] = {} session['google_oauth2']['email'] = user.email session['google_oauth2']['first_name'] = user.first_name session['google_oauth2']['last_name'] = user.last_name g.auth_role = role # TODO: find a way to save the angular args # authomatic adds url params google auth has stripped the # angular args anyway, so let's just redirect back to the # index. return redirect(url_for('index')) return response return abort(403)
def decorated(*args, **kwargs): if not app.config.get('USE_AUTH'): return f(*args, **kwargs) auth = request.authorization headers = request.headers using_basic_kms_auth = ( auth and auth.get('username') and auth.get('password') != '' ) using_kms_auth = ( 'X-Auth-Token' in headers and 'X-Auth-From' in headers ) # User suppplied basic auth info if using_basic_kms_auth or using_kms_auth: if using_basic_kms_auth: _from = auth['username'] token = auth['password'] else: _from = headers['X-Auth-From'] token = headers['X-Auth-Token'] try: with stats.timer('decrypt_token'): payload = keymanager.decrypt_token( token, _from ) logging.debug('Auth request had the following payload:' ' {0}'.format(payload)) role = 'service' msg = 'Authenticated {0} with role {1} via kms auth' msg = msg.format(_from, role) logging.debug(msg) if role_has_privilege(role, f.func_name): g.auth_role = role g.username = _from return f(*args, **kwargs) else: msg = '{0} is not authorized to access {1}.' msg = msg.format(_from, f.func_name) logging.warning(msg) return abort(403) except keymanager.TokenDecryptionError: msg = 'Access denied for {0}. Authentication Failed.' msg = msg.format(_from) logging.warning(msg) return abort(403) # If not using kms auth, require google auth. else: role = 'user' if not role_has_privilege(role, f.func_name): return abort(403) if 'email' in session.get('google_oauth2', []): if (app.config['USERS_FILE'] and get_logged_in_user_email() not in users): msg = 'User not authorized: {0}' logging.warning(msg.format(get_logged_in_user_email())) return abort(403) else: g.auth_role = role return f(*args, **kwargs) response = make_response() if request.is_secure: secure_cookie = True else: secure_cookie = False result = _authomatic.login( WerkzeugAdapter(request, response), 'google', session=session, session_saver=lambda: app.save_session(session, response), secure_cookie=secure_cookie ) if result: if result.error: msg = 'Google auth failed with error: {0}' logging.error(msg.format(result.error.message)) return abort(403) if result.user: result.user.update() user = result.user email_suffix = app.config['GOOGLE_AUTH_EMAIL_SUFFIX'] if email_suffix and not user.email.endswith(email_suffix): return abort(403) session['google_oauth2'] = {} session['google_oauth2']['email'] = user.email session['google_oauth2']['first_name'] = user.first_name session['google_oauth2']['last_name'] = user.last_name g.auth_role = role # TODO: find a way to save the angular args # authomatic adds url params google auth has stripped the # angular args anyway, so let's just redirect back to the # index. return redirect(url_for('index')) return response return abort(403)
def decorated(*args, **kwargs): if not app.config.get("USE_AUTH"): return f(*args, **kwargs) auth = request.authorization headers = request.headers using_basic_kms_auth = auth and auth.get("username") and auth.get("password") != "" using_kms_auth = "X-Auth-Token" in headers and "X-Auth-From" in headers # User suppplied basic auth info if using_basic_kms_auth or using_kms_auth: if using_basic_kms_auth: _from = auth["username"] token = auth["password"] else: _from = headers["X-Auth-From"] token = headers["X-Auth-Token"] try: with stats.timer("decrypt_token"): payload = keymanager.decrypt_token(token, _from) log.debug("Auth request had the following payload:" " {0}".format(payload)) role = "service" msg = "Authenticated {0} with role {1} via kms auth" msg = msg.format(_from, role) log.debug(msg) if role_has_privilege(role, f.func_name): g.auth_role = role g.username = _from return f(*args, **kwargs) else: msg = "{0} is not authorized to access {1}." msg = msg.format(_from, f.func_name) log.warning(msg) return abort(403) except keymanager.TokenDecryptionError: msg = "Access denied for {0}. Authentication Failed." msg = msg.format(_from) log.warning(msg) return abort(403) # If not using kms auth, require google auth. else: role = "user" if not role_has_privilege(role, f.func_name): return abort(403) if "email" in session.get("google_oauth2", []): if app.config["USERS_FILE"] and get_logged_in_user_email() not in users: msg = "User not authorized: {0}" log.warning(msg.format(get_logged_in_user_email())) return abort(403) else: g.auth_role = role return f(*args, **kwargs) response = make_response() if request.is_secure: secure_cookie = True else: secure_cookie = False result = _authomatic.login( WerkzeugAdapter(request, response), "google", session=session, session_saver=lambda: app.save_session(session, response), secure_cookie=secure_cookie, ) if result: if result.error: msg = "Google auth failed with error: {0}" log.error(msg.format(result.error.message)) return abort(403) if result.user: result.user.update() user = result.user email_suffix = app.config["GOOGLE_AUTH_EMAIL_SUFFIX"] if email_suffix and not user.email.endswith(email_suffix): return abort(403) session["google_oauth2"] = {} session["google_oauth2"]["email"] = user.email session["google_oauth2"]["first_name"] = user.first_name session["google_oauth2"]["last_name"] = user.last_name g.auth_role = role # TODO: find a way to save the angular args # authomatic adds url params google auth has stripped the # angular args anyway, so let's just redirect back to the # index. return redirect(url_for("index")) return response return abort(403)