Example #1
0
    def authenticate(self, email, username, password, options):
        pam_username = None
        auto_register_username = None
        auto_register_email = None
        force_fail = False
        log.debug("use username: {} use email {} email {} username {}".format(
            options.get('login-use-username'),
            options.get('login-use-email', False), email, username))
        # check email based login first because if email exists in Galaxy DB
        # we will be given the "public name" as username
        if _get_bool(options, 'login-use-email', False) and email is not None:
            if '@' in email:
                (email_user, email_domain) = email.split('@')
                pam_username = email_user
                if email_domain == options.get('maildomain', None):
                    auto_register_email = email
                    if username is not None:
                        auto_register_username = username
                    else:
                        auto_register_username = email_user
                else:
                    log.debug(
                        'PAM authenticate: warning: email does not match configured PAM maildomain'
                    )
                    # no need to fail: if auto-register is not enabled, this
                    # might still be a valid user
            else:
                log.debug(
                    'PAM authenticate: email must be used to login, but no valid email found'
                )
                force_fail = True
        elif _get_bool(options, 'login-use-username', False):
            # if we get here via authenticate_user then
            # user will be "public name" and
            # email address will be as per registered user
            if username is not None:
                pam_username = username
                if email is not None:
                    auto_register_email = email
                elif options.get('maildomain', None) is not None:
                    # we can register a user with this username and mail domain
                    # if auto registration is enabled
                    auto_register_email = '{}@{}'.format(
                        username, options['maildomain'])
                auto_register_username = username
            else:
                log.debug(
                    'PAM authenticate: username login selected but no username provided'
                )
                force_fail = True
        else:
            log.debug('PAM authenticate: could not find username for PAM')
            force_fail = True

        if force_fail:
            return None, '', ''

        pam_service = options.get('pam-service', 'galaxy')
        use_helper = _get_bool(options, 'use-external-helper', False)
        log.debug("PAM auth: will use external helper: {}".format(use_helper))
        authenticated = False
        if use_helper:
            authentication_helper = options.get('authentication-helper-script',
                                                '/bin/false').strip()
            log.debug("PAM auth: external helper script: {}".format(
                authentication_helper))
            if not authentication_helper.startswith('/'):
                # don't accept relative path
                authenticated = False
            else:
                auth_cmd = shlex.split(
                    '/usr/bin/sudo -n {}'.format(authentication_helper))
                log.debug("PAM auth: external helper cmd: {}".format(auth_cmd))
                proc = Popen(auth_cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)
                message = '{}\n{}\n{}\n'.format(pam_service, pam_username,
                                                password)
                (output, error) = proc.communicate(message)
                status = proc.wait()
                if status != 0 and error != '':
                    log.debug(
                        "PAM auth: external authentication script had errors: status {} error {}"
                        .format(status, error))
                if output.strip() == 'True':
                    authenticated = True
                else:
                    authenticated = False
        else:
            try:
                import pam
            except ImportError:
                log.debug(
                    'PAM authenticate: could not load pam module, PAM authentication disabled'
                )
                return None, '', ''

            p_auth = pam.pam()
            authenticated = p_auth.authenticate(pam_username,
                                                password,
                                                service=pam_service)

        if authenticated:
            log.debug(
                'PAM authentication successful for {}'.format(pam_username))
            return True, auto_register_email, auto_register_username
        else:
            log.debug('PAM authentication failed for {}'.format(pam_username))
            return False, '', ''
    def authenticate(self, email, username, password, options):
        """
        See abstract method documentation.
        """
        log.debug("LDAP authenticate: email is %s" % email)
        log.debug("LDAP authenticate: username is %s" % username)
        log.debug("LDAP authenticate: options are %s" % options)

        failure_mode = False  # reject but continue
        if options.get('continue-on-failure', 'False') == 'False':
            failure_mode = None  # reject and do not continue

        if _get_bool(options, 'login-use-username', False):
            if username is None:
                log.debug('LDAP authenticate: username must be used to login, cannot be None')
                return (failure_mode, '', '')
        else:
            if email is None:
                log.debug('LDAP authenticate: email must be used to login, cannot be None')
                return (failure_mode, '', '')

        try:
            import ldap
        except:
            log.debug('LDAP authenticate: could not load ldap module')
            return (failure_mode, '', '')

        # do LDAP search (if required)
        params = {'email': email, 'username': username, 'password': password}

        try:
            ldap_options_raw = _get_subs(options, 'ldap-options', params)
        except ConfigurationError:
            ldap_options = ()
        else:
            ldap_options = _parse_ldap_options(ldap, ldap_options_raw)

        if 'search-fields' in options:
            try:
                # setup connection
                ldap.set_option(ldap.OPT_REFERRALS, 0)

                for opt in ldap_options:
                    ldap.set_option(*opt)

                l = ldap.initialize(_get_subs(options, 'server', params))
                l.protocol_version = 3

                if 'search-user' in options:
                    l.simple_bind_s(_get_subs(options, 'search-user', params),
                                    _get_subs(options, 'search-password', params))
                else:
                    l.simple_bind_s()

                # setup search
                attributes = [_.strip().format(**params)
                              for _ in options['search-fields'].split(',')]
                suser = l.search_ext_s(_get_subs(options, 'search-base', params),
                    ldap.SCOPE_SUBTREE,
                    _get_subs(options, 'search-filter', params), attributes,
                    timeout=60, sizelimit=1)

                # parse results
                if suser is None or len(suser) == 0:
                    log.warning('LDAP authenticate: search returned no results')
                    return (failure_mode, '', '')
                dn, attrs = suser[0]
                log.debug(("LDAP authenticate: dn is %s" % dn))
                log.debug(("LDAP authenticate: search attributes are %s" % attrs))
                if hasattr(attrs, 'has_key'):
                    for attr in attributes:
                        if attr in attrs:
                            params[attr] = str(attrs[attr][0])
                        else:
                            params[attr] = ""
                params['dn'] = dn
            except Exception:
                log.exception('LDAP authenticate: search exception')
                return (failure_mode, '', '')
        # end search

        # bind as user to check their credentials
        try:
            # setup connection
            ldap.set_option(ldap.OPT_REFERRALS, 0)

            for opt in ldap_options:
                ldap.set_option(*opt)

            l = ldap.initialize(_get_subs(options, 'server', params))
            l.protocol_version = 3
            l.simple_bind_s(_get_subs(
                options, 'bind-user', params), _get_subs(options, 'bind-password', params))
            whoami = l.whoami_s()
            log.debug("LDAP authenticate: whoami is %s", whoami)
            if whoami is None:
                raise RuntimeError('LDAP authenticate: anonymous bind')
        except Exception:
            log.warning('LDAP authenticate: bind exception', exc_info=True)
            return (failure_mode, '', '')

        log.debug('LDAP authentication successful')
        return (True,
                _get_subs(options, 'auto-register-email', params),
                _get_subs(options, 'auto-register-username', params))
Example #3
0
    def authenticate(self, email, username, password, options):
        """
        See abstract method documentation.
        """
        log.debug("LDAP authenticate: email is %s" % email)
        log.debug("LDAP authenticate: username is %s" % username)
        log.debug("LDAP authenticate: options are %s" % options)

        failure_mode = False  # reject but continue
        if options.get('continue-on-failure', 'False') == 'False':
            failure_mode = None  # reject and do not continue

        if _get_bool(options, 'login-use-username', False):
            if username is None:
                log.debug('LDAP authenticate: username must be used to login, cannot be None')
                return (failure_mode, '', '')
        else:
            if email is None:
                log.debug('LDAP authenticate: email must be used to login, cannot be None')
                return (failure_mode, '', '')

        try:
            import ldap
        except:
            log.debug('LDAP authenticate: could not load ldap module')
            return (failure_mode, '', '')

        # do LDAP search (if required)
        params = {'email': email, 'username': username, 'password': password}
        if 'search-fields' in options:
            try:
                # setup connection
                ldap.set_option(ldap.OPT_REFERRALS, 0)
                l = ldap.initialize(_get_subs(options, 'server', params))
                l.protocol_version = 3

                if 'search-user' in options:
                    l.simple_bind_s(_get_subs(options, 'search-user', params),
                                    _get_subs(options, 'search-password', params))
                else:
                    l.simple_bind_s()

                scope = ldap.SCOPE_SUBTREE

                # setup search
                attributes = [_.strip().format(**params)
                              for _ in options['search-fields'].split(',')]
                result = l.search(_get_subs(options, 'search-base', params), scope,
                                  _get_subs(options, 'search-filter', params), attributes)

                # parse results
                _, suser = l.result(result, 60)
                dn, attrs = suser[0]
                log.debug(("LDAP authenticate: dn is %s" % dn))
                log.debug(("LDAP authenticate: search attributes are %s" % attrs))
                if hasattr(attrs, 'has_key'):
                    for attr in attributes:
                        if attr in attrs:
                            params[attr] = str(attrs[attr][0])
                        else:
                            params[attr] = ""
                params['dn'] = dn
            except Exception:
                log.exception('LDAP authenticate: search exception')
                return (failure_mode, '', '')
        # end search

        # bind as user to check their credentials
        try:
            # setup connection
            ldap.set_option(ldap.OPT_REFERRALS, 0)
            l = ldap.initialize(_get_subs(options, 'server', params))
            l.protocol_version = 3
            l.simple_bind_s(_get_subs(
                options, 'bind-user', params), _get_subs(options, 'bind-password', params))
        except Exception:
            log.exception('LDAP authenticate: bind exception')
            return (failure_mode, '', '')

        log.debug('LDAP authentication successful')
        return (True,
                _get_subs(options, 'auto-register-email', params),
                _get_subs(options, 'auto-register-username', params))
Example #4
0
    def authenticate(self, email, username, password, options):
        pam_username = None
        auto_register_username = None
        auto_register_email = None
        force_fail = False
        log.debug(
            "use username: {} use email {} email {} username {}".format(
                options.get("login-use-username"), options.get("login-use-email", False), email, username
            )
        )
        # check email based login first because if email exists in Galaxy DB
        # we will be given the "public name" as username
        if _get_bool(options, "login-use-email", False) and email is not None:
            if "@" in email:
                (email_user, email_domain) = email.split("@")
                pam_username = email_user
                if email_domain == options.get("maildomain", None):
                    auto_register_email = email
                    if username is not None:
                        auto_register_username = username
                    else:
                        auto_register_username = email_user
                else:
                    log.debug("PAM authenticate: warning: email does not match configured PAM maildomain")
                    # no need to fail: if auto-register is not enabled, this
                    # might still be a valid user
            else:
                log.debug("PAM authenticate: email must be used to login, but no valid email found")
                force_fail = True
        elif _get_bool(options, "login-use-username", False):
            # if we get here via authenticate_user then
            # user will be "public name" and
            # email address will be as per registered user
            if username is not None:
                pam_username = username
                if email is not None:
                    auto_register_email = email
                elif options.get("maildomain", None) is not None:
                    # we can register a user with this username and mail domain
                    # if auto registration is enabled
                    auto_register_email = "{}@{}".format(username, options["maildomain"])
                auto_register_username = username
            else:
                log.debug("PAM authenticate: username login selected but no username provided")
                force_fail = True
        else:
            log.debug("PAM authenticate: could not find username for PAM")
            force_fail = True

        if force_fail:
            return None, "", ""

        pam_service = options.get("pam-service", "galaxy")
        use_helper = _get_bool(options, "use-external-helper", False)
        log.debug("PAM auth: will use external helper: {}".format(use_helper))
        authenticated = False
        if use_helper:
            authentication_helper = options.get("authentication-helper-script", "/bin/false").strip()
            log.debug("PAM auth: external helper script: {}".format(authentication_helper))
            if not authentication_helper.startswith("/"):
                # don't accept relative path
                authenticated = False
            else:
                auth_cmd = shlex.split("/usr/bin/sudo -n {}".format(authentication_helper))
                log.debug("PAM auth: external helper cmd: {}".format(auth_cmd))
                proc = Popen(auth_cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)
                message = "{}\n{}\n{}\n".format(pam_service, pam_username, password)
                (output, error) = proc.communicate(message)
                status = proc.wait()
                if status != 0 and error != "":
                    log.debug(
                        "PAM auth: external authentication script had errors: status {} error {}".format(status, error)
                    )
                if output.strip() == "True":
                    authenticated = True
                else:
                    authenticated = False
        else:
            try:
                import pam
            except ImportError:
                log.debug("PAM authenticate: could not load pam module, PAM authentication disabled")
                return None, "", ""

            p_auth = pam.pam()
            authenticated = p_auth.authenticate(pam_username, password, service=pam_service)

        if authenticated:
            log.debug("PAM authentication successful for {}".format(pam_username))
            return True, auto_register_email, auto_register_username
        else:
            log.debug("PAM authentication failed for {}".format(pam_username))
            return False, "", ""
Example #5
0
    def authenticate(self, email, username, password, options):
        """
        See abstract method documentation.
        """
        log.debug("LDAP authenticate: email is %s" % email)
        log.debug("LDAP authenticate: username is %s" % username)
        log.debug("LDAP authenticate: options are %s" % options)

        failure_mode = False  # reject but continue
        if options.get('continue-on-failure', 'False') == 'False':
            failure_mode = None  # reject and do not continue

        if _get_bool(options, 'login-use-username', False):
            if username is None:
                log.debug(
                    'LDAP authenticate: username must be used to login, cannot be None'
                )
                return (failure_mode, '', '')
        else:
            if email is None:
                log.debug(
                    'LDAP authenticate: email must be used to login, cannot be None'
                )
                return (failure_mode, '', '')

        try:
            import ldap
        except:
            log.debug('LDAP authenticate: could not load ldap module')
            return (failure_mode, '', '')

        # do LDAP search (if required)
        params = {'email': email, 'username': username, 'password': password}
        if 'search-fields' in options:
            try:
                # setup connection
                ldap.set_option(ldap.OPT_REFERRALS, 0)
                l = ldap.initialize(_get_subs(options, 'server', params))
                l.protocol_version = 3

                if 'search-user' in options:
                    l.simple_bind_s(
                        _get_subs(options, 'search-user', params),
                        _get_subs(options, 'search-password', params))
                else:
                    l.simple_bind_s()

                scope = ldap.SCOPE_SUBTREE

                # setup search
                attributes = [
                    _.strip().format(**params)
                    for _ in options['search-fields'].split(',')
                ]
                result = l.search(_get_subs(options, 'search-base',
                                            params), scope,
                                  _get_subs(options, 'search-filter', params),
                                  attributes)

                # parse results
                _, suser = l.result(result, 60)
                dn, attrs = suser[0]
                log.debug(("LDAP authenticate: dn is %s" % dn))
                log.debug(
                    ("LDAP authenticate: search attributes are %s" % attrs))
                if hasattr(attrs, 'has_key'):
                    for attr in attributes:
                        if attr in attrs:
                            params[attr] = str(attrs[attr][0])
                        else:
                            params[attr] = ""
                params['dn'] = dn
            except Exception:
                log.exception('LDAP authenticate: search exception')
                return (failure_mode, '', '')
        # end search

        # bind as user to check their credentials
        try:
            # setup connection
            ldap.set_option(ldap.OPT_REFERRALS, 0)
            l = ldap.initialize(_get_subs(options, 'server', params))
            l.protocol_version = 3
            l.simple_bind_s(_get_subs(options, 'bind-user', params),
                            _get_subs(options, 'bind-password', params))
        except Exception:
            log.exception('LDAP authenticate: bind exception')
            return (failure_mode, '', '')

        log.debug('LDAP authentication successful')
        return (True, _get_subs(options, 'auto-register-email', params),
                _get_subs(options, 'auto-register-username', params))
Example #6
0
    def authenticate(self, email, username, password, options):
        """
        See abstract method documentation.
        """
        log.debug("LDAP authenticate: email is %s" % email)
        log.debug("LDAP authenticate: username is %s" % username)
        log.debug("LDAP authenticate: options are %s" % options)

        failure_mode = False  # reject but continue
        if options.get("continue-on-failure", "False") == "False":
            failure_mode = None  # reject and do not continue

        if _get_bool(options, "login-use-username", False):
            if username is None:
                log.debug("LDAP authenticate: username must be used to login, cannot be None")
                return (failure_mode, "", "")
        else:
            if email is None:
                log.debug("LDAP authenticate: email must be used to login, cannot be None")
                return (failure_mode, "", "")

        try:
            import ldap
        except:
            log.debug("LDAP authenticate: could not load ldap module")
            return (failure_mode, "", "")

        # do LDAP search (if required)
        params = {"email": email, "username": username, "password": password}

        try:
            ldap_options_raw = _get_subs(options, "ldap-options", params)
        except ConfigurationError:
            ldap_options = ()
        else:
            ldap_options = _parse_ldap_options(ldap, ldap_options_raw)

        if "search-fields" in options:
            try:
                # setup connection
                ldap.set_option(ldap.OPT_REFERRALS, 0)

                for opt in ldap_options:
                    ldap.set_option(*opt)

                l = ldap.initialize(_get_subs(options, "server", params))
                l.protocol_version = 3

                if "search-user" in options:
                    l.simple_bind_s(
                        _get_subs(options, "search-user", params), _get_subs(options, "search-password", params)
                    )
                else:
                    l.simple_bind_s()

                # setup search
                attributes = [_.strip().format(**params) for _ in options["search-fields"].split(",")]
                suser = l.search_ext_s(
                    _get_subs(options, "search-base", params),
                    ldap.SCOPE_SUBTREE,
                    _get_subs(options, "search-filter", params),
                    attributes,
                    timeout=60,
                    sizelimit=1,
                )

                # parse results
                if suser is None or len(suser) == 0:
                    log.warn("LDAP authenticate: search returned no results")
                    return (failure_mode, "", "")
                dn, attrs = suser[0]
                log.debug(("LDAP authenticate: dn is %s" % dn))
                log.debug(("LDAP authenticate: search attributes are %s" % attrs))
                if hasattr(attrs, "has_key"):
                    for attr in attributes:
                        if attr in attrs:
                            params[attr] = str(attrs[attr][0])
                        else:
                            params[attr] = ""
                params["dn"] = dn
            except Exception:
                log.exception("LDAP authenticate: search exception")
                return (failure_mode, "", "")
        # end search

        # bind as user to check their credentials
        try:
            # setup connection
            ldap.set_option(ldap.OPT_REFERRALS, 0)

            for opt in ldap_options:
                ldap.set_option(*opt)

            l = ldap.initialize(_get_subs(options, "server", params))
            l.protocol_version = 3
            l.simple_bind_s(_get_subs(options, "bind-user", params), _get_subs(options, "bind-password", params))
            whoami = l.whoami_s()
            log.debug("LDAP authenticate: whoami is %s", whoami)

            p = re.compile(ur"[^\\]*$")

            username_from_whoami = re.search(p, whoami).group()
            params["usernameFromWhoami"] = username_from_whoami

            if whoami is None:
                raise RuntimeError("LDAP authenticate: anonymous bind")
        except Exception:
            log.warn("LDAP authenticate: bind exception", exc_info=True)
            return (failure_mode, "", "")

        log.debug("LDAP authentication successful")

        log.debug("We got the username from the whoami address: %s", username_from_whoami)

        return (
            True,
            _get_subs(options, "auto-register-email", params),
            _get_subs(options, "auto-register-username", params),
        )