From ba3453a006f01afebc144d569d121e094bd041b3 Mon Sep 17 00:00:00 2001 From: Giovanni Lanzani Date: Wed, 7 Nov 2018 23:07:48 +0100 Subject: [PATCH] [AIRFLOW-2698] Simplify Kerberos code (#3563) Some functions were not used. On top of that, the `principal_from_username` function was getting the wrong config value ("security" instead of "kerberos"). Since the results were only used by `kerberos.checkPassword`, and the function can cope with needing a realm in the `username` when `realm` is provided, we removed the `principal_from_username` function altogether. --- .../contrib/auth/backends/kerberos_auth.py | 12 +++++-- airflow/security/utils.py | 33 ++++--------------- 2 files changed, 16 insertions(+), 29 deletions(-) diff --git a/airflow/contrib/auth/backends/kerberos_auth.py b/airflow/contrib/auth/backends/kerberos_auth.py index e3500c93170a5..08ae898737aab 100644 --- a/airflow/contrib/auth/backends/kerberos_auth.py +++ b/airflow/contrib/auth/backends/kerberos_auth.py @@ -19,6 +19,7 @@ import logging import flask_login +from airflow.exceptions import AirflowConfigException from flask_login import current_user from flask import flash from wtforms import Form, PasswordField, StringField @@ -56,7 +57,13 @@ def authenticate(username, password): utils.get_fqdn() ) realm = configuration.conf.get("kerberos", "default_realm") - user_principal = utils.principal_from_username(username) + + try: + user_realm = configuration.conf.get("security", "default_realm") + except AirflowConfigException: + user_realm = realm + + user_principal = utils.principal_from_username(username, user_realm) try: # this is pykerberos specific, verify = True is needed to prevent KDC spoofing @@ -66,7 +73,8 @@ def authenticate(username, password): raise AuthenticationError() except kerberos.KrbError as e: logging.error( - 'Password validation for principal %s failed %s', user_principal, e) + 'Password validation for user ' + '%s in realm %s failed %s', user_principal, realm, e) raise AuthenticationError(e) return diff --git a/airflow/security/utils.py b/airflow/security/utils.py index 8e4fcbd4bfc0e..cf8ade922b336 100644 --- a/airflow/security/utils.py +++ b/airflow/security/utils.py @@ -22,21 +22,6 @@ from airflow.utils.net import get_hostname -# Pattern to replace with hostname -HOSTNAME_PATTERN = '_HOST' - - -def get_kerberos_principal(principal, host): - components = get_components(principal) - if not components or len(components) != 3 or components[1] != HOSTNAME_PATTERN: - return principal - else: - if not host: - raise IOError("Can't replace %s pattern " - "since host is null." % HOSTNAME_PATTERN) - return replace_hostname_pattern(components, host) - - def get_components(principal): """ get_components(principal) -> (short name, instance (FQDN), realm) @@ -51,33 +36,27 @@ def get_components(principal): def replace_hostname_pattern(components, host=None): fqdn = host if not fqdn or fqdn == '0.0.0.0': - fqdn = get_localhost_name() + fqdn = get_hostname() return '%s/%s@%s' % (components[0], fqdn.lower(), components[2]) -def get_localhost_name(): - return get_hostname() - - def get_fqdn(hostname_or_ip=None): # Get hostname try: if hostname_or_ip: fqdn = socket.gethostbyaddr(hostname_or_ip)[0] + if fqdn == 'localhost': + fqdn = get_hostname() else: - fqdn = get_localhost_name() + fqdn = get_hostname() except IOError: fqdn = hostname_or_ip - if fqdn == 'localhost': - fqdn = get_localhost_name() - return fqdn -def principal_from_username(username): - realm = conf.get("security", "default_realm") - if '@' not in username and realm: +def principal_from_username(username, realm): + if ('@' not in username) and realm: username = "{}@{}".format(username, realm) return username