Esempio n. 1
0
def init_multiauth(app, servicetype='HTTP', hostname=gethostname()):
    """
    Configure the GSSAPI service name, and validate the principal in the kerberos keytab.

    @param app: a flask application
    @param servicetype: GSSAPI service type
    @param hostname: hostname service is running on
    """
    global _SERVICE_NAME
    _SERVICE_NAME = "{0}@{1}".format(servicetype, hostname)

    global _logger
    _logger = app.logger

    global _cfg
    _cfg = app.config

    if "KRB5_KTNAME" not in environ:
        _logger.warn("Please set KRB5_KTNAME to your fully quailified KRB5 ketab file name")
        return

    try:
        principal = kerberos.getServerPrincipalDetails(servicetype, hostname)
        app.logger.warn("flask_multiauth: server is %s" % principal)
    except kerberos.KrbError as exc:
        _logger.warn("flask_multiauth: %s" % exc.message[0])
Esempio n. 2
0
 def _check_hostname(hostname):
     try:
         principal = kerberos.getServerPrincipalDetails('HTTP', hostname)
     except kerberos.KrbError as exc:
         LOG.warning('kerberos.getServerPrincipalDetails("HTTP", %r) raised %s', hostname, exc)
     else:
         LOG.debug('KerberosAuthMiddleware is identifying as %s', principal)
Esempio n. 3
0
def testServicePrincipal(service, hostname):
    try:
        result = kerberos.getServerPrincipalDetails(service, hostname)
    except kerberos.KrbError as e:
        print("Kerberos service principal for %s/%s failed: %s" % (service, hostname, e[0]))
    else:
        print("Kerberos service principal for %s/%s succeeded: %s" % (service, hostname, result))
Esempio n. 4
0
    def __init__(self, principal=None, serviceType=None, hostname=None):
        """

        @param principal:  full Kerberos principal (e.g., 'HTTP/[email protected]'). If C{None}
            then the type and hostname arguments are used instead.
        @type principal:     str
        @param serviceType:       service type for Kerberos (e.g., 'HTTP'). Must be C{None} if principal used.
        @type serviceType:        str
        @param hostname:   hostname for this server. Must be C{None} if principal used.
        @type hostname:    str
        """

        # Only certain combinations of arguments allowed
        assert (principal and not serviceType
                and not hostname) or (not principal and serviceType
                                      and hostname)

        if not principal:
            # Look up the Kerberos principal given the service type and hostname, and extract
            # the realm and a service principal value for later use.
            try:
                principal = kerberos.getServerPrincipalDetails(
                    serviceType, hostname)
            except kerberos.KrbError, ex:
                self.log.error("getServerPrincipalDetails: %s" % (ex[0], ))
                raise ValueError('Authentication System Failure: %s' %
                                 (ex[0], ))
Esempio n. 5
0
def init_kerberos(app, service='HTTP', hostname=gethostname()):
    '''
    Configure the GSSAPI service name, and validate the presence of the
    appropriate principal in the kerberos keytab.

    :param app: a flask application
    :type app: flask.Flask
    :param service: GSSAPI service name
    :type service: str
    :param hostname: hostname the service runs under
    :type hostname: str
    '''
    if config['Authentication']['Enabled'] == 'False':
        return

    global _SERVICE_NAME
    _SERVICE_NAME = "%s@%s" % (service, hostname)

    if 'KRB5_KTNAME' not in environ:
        app.logger.warn("Kerberos: set KRB5_KTNAME to your keytab file")
    else:
        try:
            principal = kerberos.getServerPrincipalDetails(service, hostname)
        except kerberos.KrbError as exc:
            app.logger.warn("Kerberos: %s" % exc.message[0])
        else:
            app.logger.info("Kerberos: server is %s" % principal)
Esempio n. 6
0
    def check_ticket(self, ticket):

        init_context_res = chech_ticket_res = -1
        principal = realm = orig_service = target_name = service = ''

        try:
            principal = kerberos.getServerPrincipalDetails(
                self._service_type, self._hostname)
            orig_service, realm = self._split_principal(principal)
            init_context_res, context = kerberos.authGSSServerInit('')
            chech_ticket_res = kerberos.authGSSServerStep(context, ticket)
            target_name = kerberos.authGSSServerTargetName(context)
            service, _ = self._split_principal(target_name)
            response = kerberos.authGSSServerResponse(context)
            principal = kerberos.authGSSServerUserName(context)
            kerberos.authGSSServerClean(context)

        except kerberos.GSSError:
            if init_context_res != 1:
                ERROR("Error init kerberos context")
            elif chech_ticket_res == -1:
                ERROR("Ticket is not correct:" + ticket)
            elif service.lower() != orig_service.lower():
                ERROR('Bad credentials: wrong target name ' + target_name)
            return '', '', ''

        except kerberos.KrbError:
            ERROR("Internal kerberos error")
            return '', '', ''

        # del kerberos
        username, realm = principal.split('@')
        return response, username, realm
Esempio n. 7
0
def testServicePrincipal(service, hostname):
    try:
        result = kerberos.getServerPrincipalDetails(service, hostname)
    except kerberos.KrbError as e:
        print("Kerberos service principal for %s/%s failed: %s" % (service, hostname, e[0]))
    else:
        print("Kerberos service principal for %s/%s succeeded: %s" % (service, hostname, result))
Esempio n. 8
0
    def auth_basic(self, auth_header):
        """
        Manages the basic authorization process with kerberos.
        Returns a username or raises a BasicAuthError.
        """

        # The authorization header is base64 encoded, we need it decoded
        auth_decoded = base64.decodebytes(auth_header.encode('utf8')).decode()
        # Decoded format is <username>:<password> so we need to split it
        userstring, password = auth_decoded.split(':', maxsplit=1)
        try:
            # If the user specifies a realm in the username verify
            # it matches the configured SPNEGO realm so we
            # don't open ourselves up to KDC spoofing
            username, realm = userstring.split('@', maxsplit=1)
            if realm != settings.SPNEGO_REALM:
                raise NotAuthorized
        except ValueError:
            username = userstring

        kerberos.checkPassword(
            username, password,
            kerberos.getServerPrincipalDetails('HTTP',
                                               settings.SPNEGO_HOSTNAME),
            settings.SPNEGO_REALM)

        return username
Esempio n. 9
0
def init_kerberos(app, service='HTTP', hostname=gethostname(), principal=None):
    '''
    Configure the GSSAPI service name, and validate the presence of the
    appropriate principal in the kerberos keytab.

    :param app: a flask application
    :type app: flask.Flask
    :param service: GSSAPI service name
    :type service: str
    :param hostname: hostname the service runs under
    :type hostname: str
    '''
    global _SERVICE_NAME

    _SERVICE_NAME = "%s@%s" % (service, hostname)

    if 'KRB5_KTNAME' not in environ:
        app.logger.error("Kerberos: set KRB5_KTNAME to your keytab file")
        return False
    elif principal is None:
        try:
            principal = kerberos.getServerPrincipalDetails(service, hostname)
        except kerberos.KrbError as exc:
            app.logger.error("Kerberos: %s" % exc.message[0])
            app.logger.error("ServiceName: %s" % _SERVICE_NAME)
            return False
    app.logger.info("Kerberos: server is %s" % principal)
    return True
Esempio n. 10
0
    def init_config(self, config):
        service = config.setdefault('KRB5_SERVICE_NAME', b'HTTP')
        hostname = config.setdefault('KRB5_HOSTNAME', socket.gethostname())
        self._service_name = b'{}@{}'.format(service, hostname)

        try:
            principal = kerberos.getServerPrincipalDetails(service, hostname)
        except kerberos.KrbError:
            log.warn("Error initializing Kerberos for %s", self._service_name, exc_info=True)
        else:
            log.info("Server principal is %s", principal)
Esempio n. 11
0
    def init_config(self, config):
        service = config.setdefault('KRB5_SERVICE_NAME', b'HTTP')
        hostname = config.setdefault('KRB5_HOSTNAME', socket.gethostname())
        self._service_name = b'{}@{}'.format(service, hostname)

        try:
            principal = kerberos.getServerPrincipalDetails(service, hostname)
        except kerberos.KrbError:
            log.warn("Error initializing Kerberos for %s",
                     self._service_name,
                     exc_info=True)
        else:
            log.info("Server principal is %s", principal)
Esempio n. 12
0
    def __init__(self,
                 app,
                 hostname=None,
                 unauthorized=None,
                 forbidden=None,
                 auth_required_callback=None):
        if hostname is None:
            hostname = socket.gethostname()

        if unauthorized is None:
            unauthorized = (b'Unauthorized', 'text/plain')
        elif isinstance(unauthorized, basestring):
            unauthorized = (unauthorized, 'text/plain')
        unauthorized = (ensure_bytestring(unauthorized[0]), unauthorized[1])

        if forbidden is None:
            forbidden = (b'Forbidden', 'text/plain')
        elif isinstance(forbidden, basestring):
            forbidden = (forbidden, 'text/plain')
        forbidden = (ensure_bytestring(forbidden[0]), forbidden[1])

        if auth_required_callback is None:
            auth_required_callback = lambda x: True

        self.application = app  # WSGI Application
        self.service = 'HTTP@%s' % hostname  # GSS Service
        self.unauthorized = unauthorized  # 401 response text/content-type
        self.forbidden = forbidden  # 403 response text/content-type
        self.auth_required_callback = auth_required_callback

        if 'KRB5_KTNAME' in os.environ:
            try:
                principal = kerberos.getServerPrincipalDetails(
                    'HTTP', hostname)
            except kerberos.KrbError as exc:
                LOG.warning('KerberosAuthMiddleware: %s', exc)
            else:
                LOG.debug('KerberosAuthMiddleware is identifying as %s',
                          principal)
        else:
            LOG.warning(
                'KerberosAuthMiddleware: set KRB5_KTNAME to your keytab file')
Esempio n. 13
0
def init_app(app):
    """Initializes application with kerberos"""
    hostname = app.config.get('SERVER_NAME')
    if not hostname:
        hostname = getfqdn()
    log.info("Kerberos: hostname %s", hostname)

    service = 'airflow'

    _KERBEROS_SERVICE.service_name = "{}@{}".format(service, hostname)

    if 'KRB5_KTNAME' not in os.environ:
        os.environ['KRB5_KTNAME'] = conf.get('kerberos', 'keytab')

    try:
        log.info("Kerberos init: %s %s", service, hostname)
        principal = kerberos.getServerPrincipalDetails(service, hostname)
    except kerberos.KrbError as err:
        log.warning("Kerberos: %s", err)
    else:
        log.info("Kerberos API: server is %s", principal)
Esempio n. 14
0
def init_app(app):
    global _SERVICE_NAME

    hostname = app.config.get('SERVER_NAME')
    if not hostname:
        hostname = getfqdn()
    logging.info("Kerberos: hostname {}".format(hostname))

    service = 'airflow'

    _SERVICE_NAME = "{}@{}".format(service, hostname)

    if 'KRB5_KTNAME' not in os.environ:
        os.environ['KRB5_KTNAME'] = conf.get('kerberos', 'keytab')

    try:
        logging.info("Kerberos init: {} {}".format(service, hostname))
        principal = kerberos.getServerPrincipalDetails(service, hostname)
    except kerberos.KrbError as err:
        logging.warn("Kerberos: {}".format(err))
    else:
        logging.info("Kerberos API: server is {}".format(principal))
Esempio n. 15
0
def init_app(app):
    global _SERVICE_NAME

    hostname = app.config.get('SERVER_NAME')
    if not hostname:
        hostname = getfqdn()
    log.info("Kerberos: hostname %s", hostname)

    service = 'airflow'

    _SERVICE_NAME = "{}@{}".format(service, hostname)

    if 'KRB5_KTNAME' not in os.environ:
        os.environ['KRB5_KTNAME'] = conf.get('kerberos', 'keytab')

    try:
        log.info("Kerberos init: %s %s", service, hostname)
        principal = kerberos.getServerPrincipalDetails(service, hostname)
    except kerberos.KrbError as err:
        log.warning("Kerberos: %s", err)
    else:
        log.info("Kerberos API: server is %s", principal)
Esempio n. 16
0
    def __init__(self, principal=None, type=None, hostname=None):
        """
        
        @param principal:  full Kerberos principal (e.g., 'HTTP/[email protected]'). If C{None}
            then the type and hostname arguments are used instead.
        @type service:     str
        @param type:       service type for Kerberos (e.g., 'HTTP'). Must be C{None} if principal used.
        @type type:        str
        @param hostname:   hostname for this server. Must be C{None} if principal used.
        @type hostname:    str
        """

        # Only certain combinations of arguments allowed
        assert (principal and not type and not hostname) or (not principal and type and hostname)

        if not principal:
            # Look up the Kerberos principal given the service type and hostname, and extract
            # the realm and a service principal value for later use.
            try:
                principal = kerberos.getServerPrincipalDetails(type, hostname)
            except kerberos.KrbError, ex:
                self.log_error("getServerPrincipalDetails: %s" % (ex[0],))
                raise ValueError('Authentication System Failure: %s' % (ex[0],))
Esempio n. 17
0
    def __init__(self, app, hostname=None, unauthorized=None, forbidden=None,
                 auth_required_callback=None):
        if hostname is None:
            hostname = socket.gethostname()

        if unauthorized is None:
            unauthorized = (b'Unauthorized', 'text/plain')
        elif isinstance(unauthorized, basestring):
            unauthorized = (unauthorized, 'text/plain')
        unauthorized = (ensure_bytestring(unauthorized[0]), unauthorized[1])

        if forbidden is None:
            forbidden = (b'Forbidden', 'text/plain')
        elif isinstance(forbidden, basestring):
            forbidden = (forbidden, 'text/plain')
        forbidden = (ensure_bytestring(forbidden[0]), forbidden[1])

        if auth_required_callback is None:
            auth_required_callback = lambda x: True

        self.application = app               # WSGI Application
        self.service = 'HTTP@%s' % hostname  # GSS Service
        self.unauthorized = unauthorized     # 401 response text/content-type
        self.forbidden = forbidden           # 403 response text/content-type
        self.auth_required_callback = auth_required_callback

        if 'KRB5_KTNAME' in os.environ:
            try:
                principal = kerberos.getServerPrincipalDetails('HTTP',
                                                               hostname)
            except kerberos.KrbError as exc:
                LOG.warning('KerberosAuthMiddleware: %s', exc)
            else:
                LOG.debug('KerberosAuthMiddleware is identifying as %s', principal)
        else:
            LOG.warning('KerberosAuthMiddleware: set KRB5_KTNAME to your keytab file')
Esempio n. 18
0
# Vanilla Kerberos provides only username.
# AD also embeds PAC (Privilege Attribute Certificate), which
# is supposed to be sent via HTTP headers and it contains
# the groups user is part of.
# Even then we would have to manually look up the e-mail
# address eg via LDAP, hence to keep things simple
# we simply use Kerberos to authenticate.

FQDN = socket.getaddrinfo(socket.gethostname(), 0, flags=socket.AI_CANONNAME)[0][3]

if not os.getenv("KRB5_KTNAME"):
    click.echo("Kerberos keytab not specified, set environment variable 'KRB5_KTNAME'", err=True)
    exit(250)

try:
    principal = kerberos.getServerPrincipalDetails("HTTP", FQDN)
except kerberos.KrbError as exc:
    click.echo("Failed to initialize Kerberos, reason: %s" % exc, err=True)
    exit(249)
else:
    click.echo("Kerberos enabled, service principal is HTTP/%s" % FQDN)

def login_required(func):
    def wrapped(resource, req, resp, *args, **kwargs):
        authorization = req.get_header("Authorization")

        if not authorization:
            resp.append_header("WWW-Authenticate", "Negotiate")
            raise falcon.HTTPUnauthorized("Unauthorized", "No Kerberos ticket offered?")

        token = ''.join(authorization.split()[1:])
Esempio n. 19
0
 def _getKerberosDetails(self):
     self._kerberosPrincipal = kerberos.getServerPrincipalDetails("HTTP", config.kerberos_hostname)
     (self._kerberosServiceType, split1) = self._kerberosPrincipal.split("/", 1)
     (self._kerberosService, self._kerberosRealm) = split1.split("@", 1)
Esempio n. 20
0
def test_service_principal():
    expected = "HTTP/%s@%s" % (hostname, realm.upper())
    actual = kerberos.getServerPrincipalDetails("HTTP", hostname)

    assert actual == expected, "The returned SPN does not match with test expectations"
Esempio n. 21
0
# the groups user is part of.
# Even then we would have to manually look up the e-mail
# address eg via LDAP, hence to keep things simple
# we simply use Kerberos to authenticate.

FQDN = socket.getaddrinfo(socket.gethostname(), 0,
                          flags=socket.AI_CANONNAME)[0][3]

if not os.getenv("KRB5_KTNAME"):
    click.echo(
        "Kerberos keytab not specified, set environment variable 'KRB5_KTNAME'",
        err=True)
    exit(250)

try:
    principal = kerberos.getServerPrincipalDetails("HTTP", FQDN)
except kerberos.KrbError as exc:
    click.echo("Failed to initialize Kerberos, reason: %s" % exc, err=True)
    exit(249)
else:
    click.echo("Kerberos enabled, service principal is HTTP/%s" % FQDN)


def login_required(func):
    def wrapped(resource, req, resp, *args, **kwargs):
        authorization = req.get_header("Authorization")

        if not authorization:
            resp.append_header("WWW-Authenticate", "Negotiate")
            raise falcon.HTTPUnauthorized("Unauthorized",
                                          "No Kerberos ticket offered?")
def init_kerberos(
    app,
    service="HTTP",
    hostname=gethostname(),
    mongodb_uri="mongodb://*****:*****@%s" % (service, hostname)
    _MAX_CSRF_TIME = max_csrf_time
    _LOGIN_PAGE = login_page
    _LOGOUT_PAGE = logout_page
    _MAX_LOGIN_FAILURES = max_login_failures
    _PASS_MIN_LEN = pass_min_len
    _PASS_MAX_LEN = pass_max_len
    _MONGODB_URI = mongodb_uri

    logger = logging.getLogger(__name__)

    # Get mongodb connection
    try:
        _c = _auto_reconnect(pymongo.MongoClient(mongodb_uri))
        parsed_uri = pymongo.uri_parser.parse_uri(mongodb_uri)
        mongo_db = parsed_uri.get("database") or "logins"
        _db = _c[mongo_db]
        mongo_collection = parsed_uri.get("collection") or "logins"
        _LOGINS = _db[mongo_collection]
    except pymongo.errors.PyMongoError as e:
        logger.error("Error: %s - connecting to database %s!" % (e, mongodb_uri), exc_info=1)

    if "KRB5_KTNAME" not in environ:
        logger.warn("Kerberos: set KRB5_KTNAME to your keytab file")
    else:
        try:
            principal = kerberos.getServerPrincipalDetails(service, hostname)
        except kerberos.KrbError as exc:
            logger.warn("Kerberos: %s" % exc)
        else:
            logger.info("Kerberos: server is %s" % principal)
            _REALM = principal.split("@")[1]

    app.mount(_APP_PREFIX, login_app)
def init_kerberos(app,
                  service='HTTP',
                  hostname=gethostname(),
                  mongodb_uri='mongodb://*****:*****@%s" % (service, hostname)
    _MAX_CSRF_TIME = max_csrf_time
    _LOGIN_PAGE = login_page
    _LOGOUT_PAGE = logout_page
    _MAX_LOGIN_FAILURES = max_login_failures
    _PASS_MIN_LEN = pass_min_len
    _PASS_MAX_LEN = pass_max_len
    _MONGODB_URI = mongodb_uri

    logger = logging.getLogger(__name__)

    # Get mongodb connection
    try:
        _c = _auto_reconnect(pymongo.MongoClient(mongodb_uri))
        parsed_uri = pymongo.uri_parser.parse_uri(mongodb_uri)
        mongo_db = parsed_uri.get('database') or 'logins'
        _db = _c[mongo_db]
        mongo_collection = parsed_uri.get('collection') or 'logins'
        _LOGINS = _db[mongo_collection]
    except pymongo.errors.PyMongoError as e:
        logger.error('Error: %s - connecting to database %s!' %
                     (e, mongodb_uri),
                     exc_info=1)

    if 'KRB5_KTNAME' not in environ:
        logger.warn("Kerberos: set KRB5_KTNAME to your keytab file")
    else:
        try:
            principal = kerberos.getServerPrincipalDetails(service, hostname)
        except kerberos.KrbError as exc:
            logger.warn("Kerberos: %s" % exc)
        else:
            logger.info("Kerberos: server is %s" % principal)
            _REALM = principal.split('@')[1]

    app.mount(_APP_PREFIX, login_app)
Esempio n. 24
0
 def _getKerberosDetails(self):
     self._kerberosPrincipal = kerberos.getServerPrincipalDetails(
         "HTTP", config.kerberos_hostname)
     (self._kerberosServiceType,
      split1) = self._kerberosPrincipal.split("/", 1)
     (self._kerberosService, self._kerberosRealm) = split1.split("@", 1)