Пример #1
0
def _initalGetRealms():
    '''
    initaly parse all config entries, and extract the realm definition

    :return : a dict with all realm definitions
    :rtype  : dict of definitions
    '''

    Realms = {}
    defRealmConf = "linotp.useridresolver"
    realmConf = "linotp.useridresolver.group."
    defaultRealmDef = "linotp.DefaultRealm"
    defaultRealm = None

    dc = getLinotpConfig()
    for entry in dc:

        if entry.startswith(realmConf):

            #the realm might contain dots "."
            # so take all after the 3rd dot for realm
            r = {}
            realm = entry.split(".", 3)
            theRealm = realm[3].lower()
            r["realmname"] = realm[3]
            r["entry"] = entry

            ##resids          = env.config[entry]
            resids = getFromConfig(entry)

            # we adjust here the *ee resolvers from the config
            # so we only have to deal with the un-ee resolvers in the server
            # which match the available resolver classes

            resids = resids.replace("useridresolveree.", "useridresolver.")
            r["useridresolver"] = resids.split(",")

            Realms[theRealm] = r

        if entry == defRealmConf:
            r = {}

            theRealm = "_default_"
            r["realmname"] = theRealm
            r["entry"] = defRealmConf

            #resids          = env.config[entry]
            resids = getFromConfig(entry)
            r["useridresolver"] = resids.split(",")

            defaultRealm = "_default_"
            Realms[theRealm] = r

        if entry == defaultRealmDef:
            defaultRealm = getFromConfig(defaultRealmDef)

    if defaultRealm is not None:
        _setDefaultRealm(Realms, defaultRealm)

    return Realms
Пример #2
0
def get_legacy_provider(provider_type):
    """
    return a dict with legacy email or sms providers

    :param provider_type: either sms or email
    :return: dict with the provider
    """

    provider = {}

    defintion = Legacy_Provider.get(provider_type, {})
    if not defintion:
        raise Exception('unknow provider type %r' % provider_type)

    # find out, which providers we have
    config = getLinotpConfig()

    for key, translation in defintion.items():
        if key in config:
            provider[translation] = config[key]
        if 'enc' + key in config:
            provider[translation] = config['enc' + key]

    # if Config is not avail then nothing has been defined before
    if 'Config' not in provider:
        provider = {}

    return provider
Пример #3
0
def getResolverList(filter_resolver_type=None):
    '''
    Gets the list of configured resolvers

    :param filter_resolver_type: Only resolvers of the given type are returned
    :type filter_resolver_type: string
    :rtype: Dictionary of the resolvers and their configuration
    '''
    Resolvers = {}
    resolvertypes = get_resolver_types()

    conf = getLinotpConfig()
    for entry in conf:

        for typ in resolvertypes:
            if entry.startswith("linotp." + typ):
                # the realm might contain dots "."
                # so take all after the 3rd dot for realm
                r = {}
                resolver = entry.split(".", 3)
                # An old entry without resolver name
                if len(resolver) <= 3:
                    break
                r["resolvername"] = resolver[3]
                r["entry"] = entry
                r["type"] = typ

                if (filter_resolver_type is None) or (filter_resolver_type and filter_resolver_type == typ):
                    Resolvers[resolver[3]] = r
                # Dont check the other resolver types
                break

    return Resolvers
Пример #4
0
def _initalGetRealms():
    '''
    initaly parse all config entries, and extract the realm definition

    :return : a dict with all realm definitions
    :rtype  : dict of definitions
    '''

    Realms = {}
    defRealmConf = "linotp.useridresolver"
    realmConf = "linotp.useridresolver.group."
    defaultRealmDef = "linotp.DefaultRealm"
    defaultRealm = None

    dc = getLinotpConfig()
    for entry in dc:

        if entry.startswith(realmConf):

            #the realm might contain dots "."
            # so take all after the 3rd dot for realm
            r = {}
            realm = entry.split(".", 3)
            theRealm = realm[3].lower()
            r["realmname"] = realm[3]
            r["entry"] = entry

            ##resids          = env.config[entry]
            resids = getFromConfig(entry)

            # we adjust here the *ee resolvers from the config
            # so we only have to deal with the un-ee resolvers in the server
            # which match the available resolver classes

            resids = resids.replace("useridresolveree.", "useridresolver.")
            r["useridresolver"] = resids.split(",")

            Realms[theRealm] = r

        if entry == defRealmConf:
            r = {}

            theRealm = "_default_"
            r["realmname"] = theRealm
            r["entry"] = defRealmConf

            #resids          = env.config[entry]
            resids = getFromConfig(entry)
            r["useridresolver"] = resids.split(",")

            defaultRealm = "_default_"
            Realms[theRealm] = r

        if entry == defaultRealmDef:
            defaultRealm = getFromConfig(defaultRealmDef)

    if defaultRealm is not None:
        _setDefaultRealm(Realms, defaultRealm)

    return Realms
Пример #5
0
def getResolverList(filter_resolver_type=None):
    '''
    Gets the list of configured resolvers

    :param filter_resolver_type: Only resolvers of the given type are returned
    :type filter_resolver_type: string
    :rtype: Dictionary of the resolvers and their configuration
    '''
    Resolvers = {}
    resolvertypes = get_resolver_types()

    conf = getLinotpConfig()
    for entry in conf:

        for typ in resolvertypes:
            if entry.startswith("linotp." + typ):
                #the realm might contain dots "."
                # so take all after the 3rd dot for realm
                r = {}
                resolver = entry.split(".", 3)
                # An old entry without resolver name
                if len(resolver) <= 3:
                    break
                r["resolvername"] = resolver[3]
                r["entry"] = entry
                r["type"] = typ

                if (filter_resolver_type is None) or (
                        filter_resolver_type and filter_resolver_type == typ):
                    Resolvers[resolver[3]] = r
                # Dont check the other resolver types
                break

    return Resolvers
Пример #6
0
def get_legacy_provider(provider_type):
    """
    return a dict with legacy email or sms providers

    :param provider_type: either sms or email
    :return: dict with the provider
    """

    provider = {}
    config = getLinotpConfig()

    defintion = Legacy_Provider.get(provider_type, {})
    if not defintion:
        raise Exception('unknown provider type %r' % provider_type)

    for key, translation in defintion.items():
        if key in config:
            provider[translation] = config[key]

    # prepare for return
    legacy_provider = {}
    if "Config" in provider:
        provider['Default'] = False
        legacy_provider[Legacy_Provider_Name] = provider

    return legacy_provider
Пример #7
0
def get_legacy_provider(provider_type):
    """
    return a dict with legacy email or sms providers

    :param provider_type: either sms or email
    :return: dict with the provider
    """

    provider = {}
    config = getLinotpConfig()

    defintion = Legacy_Provider.get(provider_type, {})
    if not defintion:
        raise Exception('unknown provider type %r' % provider_type)

    for key, translation in defintion.items():
        if key in config:
            provider[translation] = config[key]

    # prepare for return
    legacy_provider = {}
    if "Config" in provider:
        provider['Default'] = False
        legacy_provider[Legacy_Provider_Name] = provider

    return legacy_provider
Пример #8
0
def test_getuserlist_case_sensitive_resolver_names(fthsm, app, admin_res):

    g.request_context["Config"] = getLinotpConfig()  # This sucks.
    g.request_context["CacheManager"] = app.cache  # This sucks even worse.
    g.request_context["UserLookup"] = {}  # Don't get me started.

    admin_realm_name = app.config["ADMIN_REALM_NAME"]
    admin_resolvers_key = f"useridresolver.group.{admin_realm_name}"
    admin_resolvers = getFromConfig(admin_resolvers_key, "")
    _, _, aci = admin_resolvers.rpartition(".")

    # As before, if we make the RCI uppercase and the `getUserList()` function
    # still returns a user list, then the comparison must have been
    # case-insensitive. With a case-sensitive comparison, the result should
    # be empty.

    search_user = User(
        login="******",
        realm=admin_realm_name,
        resolver_config_identifier=aci.upper(),
    )
    user_list = getUserList({}, search_user)
    assert (
        not user_list
    ), "getUserList resolver name comparison is not case-sensitive"
Пример #9
0
def test_getsearchfields_case_sensitive_resolver_names(fthsm, app):

    g.request_context["Config"] = getLinotpConfig()  # This sucks.
    g.request_context["CacheManager"] = app.cache  # This sucks even worse.

    admin_realm_name = app.config["ADMIN_REALM_NAME"]
    admin_resolvers_key = f"useridresolver.group.{admin_realm_name}"
    admin_resolvers = getFromConfig(admin_resolvers_key, "")
    _, _, aci = admin_resolvers.rpartition(".")

    user = User(
        login="******", realm=admin_realm_name, resolver_config_identifier=aci
    )

    # If the user's resolver config identifier matches its resolver, then the
    # `getSearchFields` function should return a set of search fields. If there
    # is no match, the result should be empty. Hence if we tweak the RCI to be
    # the uppercase version, then if the comparison is case-sensitive the result
    # should be empty.

    user.resolver_config_identifier = user.resolver_config_identifier.upper()
    search_fields = getSearchFields(user)
    assert (
        not search_fields
    ), "getSearchFields resolver name comparison is not case-sensitive"
Пример #10
0
def getResolverInfo(resolvername):
    '''
    return the resolver info of the given resolvername

    :param resolvername: the requested resolver
    :type  resolvername: string

    :return : dict of resolver description
    '''
    resolver_dict = {}
    typ = ""
    resolvertypes = get_resolver_types()

    descr = {}

    conf = getLinotpConfig()

    for entry in conf:

        for typ in resolvertypes:

            # get the typed values of the descriptor!
            resolver_conf = get_resolver_classConfig(typ)
            if typ in resolver_conf:
                descr = resolver_conf.get(typ).get('config', {})
            else:
                descr = resolver_conf

            if entry.startswith("linotp." + typ) and entry.endswith(resolvername):
                # the realm might contain dots "."
                # so take all after the 3rd dot for realm
                resolver = entry.split(".", 3)
                # An old entry without resolver name
                if len(resolver) <= 3:
                    break

                value = conf.get(entry)
                if resolver[2] in descr:
                    configEntry = resolver[2]
                    if descr.get(configEntry) == 'password':

                        # do we already have the decrypted pass?
                        if 'enc' + entry in conf:
                            value = conf.get('enc' + entry)
                        else:
                            # if no, we take the encpass and decrypt it
                            value = conf.get(entry)
                            try:
                                en = decryptPassword(value)
                                value = en
                            except:
                                log.info("Decryption of resolver passwd failed: compatibility issue?")

                resolver_dict[ resolver[2] ] = value
                # Dont check the other resolver types

                break

    return { "type" : typ, "data" : resolver_dict, "resolver" : resolvername}
Пример #11
0
def loadProvider(provider_type, provider_name=None):
    """
    interface for the provider user like email token or sms token

    :param provider_type: 'email' or 'sms
    :param provider_name: the name of the provider configuration

    :return: the instantiated provider with already loaded configuration
    """
    # if no provider is given, we try to lookup the default
    if not provider_name:
        config = getLinotpConfig()
        default_provider_key = Default_Provider_Key[provider_type]
        if default_provider_key in config:
            provider_name = config[default_provider_key]

    if provider_name:
        providers = getProvider(provider_type, provider_name=provider_name)
        provider_info = providers.get(provider_name)
    else:
        # if no given provider and no default, try to fallback to the old one
        provider_info = get_legacy_provider(provider_type=provider_type)

    if not provider_info:
        raise Exception('Unable to load provider: %r' % provider_name)

    provider_class = provider_info.get('Class')
    try:
        provider_class_obi = _load_provider_class(provider_class)
        provider = provider_class_obi()
    except Exception as exc:
        log.exception("Failed to load provider: %r" % exc)
        raise exc

    provider_config = {}
    config = provider_info['Config']

    # backward compatibility hack: fix the handling of multiline config entries
    lconfig = []
    lines = config.splitlines()
    for line in lines:
        line = line.strip('\\')
        if len(line) > 0:
            lconfig.append(line)

    config = " ".join(lconfig)

    try:
        provider_config = json.loads(config)
    except ValueError as exx:
        log.exception('Failed to load provider config %r', config)
        raise ValueError('Failed to load provider config:%r %r'
                         % (config, exx))

    provider.loadConfig(provider_config)

    return provider
Пример #12
0
def getResolverObject(resolvername):
    """
    get the resolver instance from a resolver name spec
    - either take the class from the request context
    - or create one from the global object list + init with resolver config

    :remark: the resolver object is preserved in the request context, so that
              a resolver could preserve a connection durung a request

    :param resolvername: the resolver string as from the token including
                         the config as last part
    :return: instance of the resolver with the loaded config

    """
    r_obj = None

    ### this patch is a bit hacky:
    ## the normal request has a request context, where it retrieves
    ## the resolver info from and preserves the loaded resolvers for reusage
    ## But in case of a authentication request (by a redirect from a 401)
    ## the caller is no std request and the context object is missing :-(
    ## The solution is to deal with local references, either to the
    ## global context or to local data (where we have no reuse of the resolver)

    resolvers_loaded = {}
    try:
        if hasattr(context, 'resolvers_loaded') == False:
            setattr(context, 'resolvers_loaded', {})
        resolvers_loaded = context.resolvers_loaded
    except Exception as exx:
        resolvers_loaded = {}

    ## test if there is already a resolver of this kind loaded
    if resolvername in resolvers_loaded:
        return resolvers_loaded.get(resolvername)

    ## no resolver - so instatiate one
    else:
        parts = resolvername.split('.')
        if len(parts) > 2:
            re_name = '.'.join(parts[:-1])
            r_obj_class = get_resolver_class(re_name)

        if r_obj_class is None:
            log.error("unknown resolver class %s " % resolvername)
            return r_obj

        ## create the resolver instance and load the config
        r_obj = r_obj_class()
        conf = resolvername.split(".")[-1]

        if r_obj is not None:
            config = getLinotpConfig()
            r_obj.loadConfig(config, conf)
            resolvers_loaded[resolvername] = r_obj

    return r_obj
Пример #13
0
def getResolverObject(resolvername):
    """
    get the resolver instance from a resolver name spec
    - either take the class from the request context
    - or create one from the global object list + init with resolver config

    :remark: the resolver object is preserved in the request context, so that
              a resolver could preserve a connection durung a request

    :param resolvername: the resolver string as from the token including
                         the config as last part
    :return: instance of the resolver with the loaded config

    """
    r_obj = None

    ### this patch is a bit hacky:
    ## the normal request has a request context, where it retrieves
    ## the resolver info from and preserves the loaded resolvers for reusage
    ## But in case of a authentication request (by a redirect from a 401)
    ## the caller is no std request and the context object is missing :-(
    ## The solution is to deal with local references, either to the
    ## global context or to local data (where we have no reuse of the resolver)

    resolvers_loaded = {}
    try:
        if hasattr(context, 'resolvers_loaded') == False:
            setattr(context, 'resolvers_loaded', {})
        resolvers_loaded = context.resolvers_loaded
    except Exception as exx:
        resolvers_loaded = {}

    ## test if there is already a resolver of this kind loaded
    if resolvername in resolvers_loaded:
        return resolvers_loaded.get(resolvername)

    ## no resolver - so instatiate one
    else:
        parts = resolvername.split('.')
        if len(parts) > 2:
            re_name = '.'.join(parts[:-1])
            r_obj_class = get_resolver_class(re_name)

        if r_obj_class is None:
            log.error("unknown resolver class %s " % resolvername)
            return r_obj

        ## create the resolver instance and load the config
        r_obj = r_obj_class()
        conf = resolvername.split(".")[-1]

        if r_obj is not None:
            config = getLinotpConfig()
            r_obj.loadConfig(config, conf)
            resolvers_loaded[resolvername] = r_obj

    return r_obj
Пример #14
0
def delProvider(provider_type, provider_name):
    """
    delete a provider

    :param provider_type: the type of Provider: sms or email
    :param provider_name: the name of the provider

    :return: the number of deleted entries
    """
    detail = {}

    prefix = Provider_types.get(provider_type, {}).get('prefix')
    if not prefix:
        raise Exception('unknown provider type %r' % provider_type)

    # find out, which providers we have
    config = getLinotpConfig()

    # if the provider is the default one, we don't delete this one
    default_provider_key = Default_Provider_Key[provider_type]
    if default_provider_key in config:
        default_provider = config[default_provider_key]
        if provider_name == default_provider:
            detail = {'message': _('Default provider could not be deleted!')}
            ret = 0
            return ret, detail

    # check that there are no references left
    provider_policies = _lookup_provider_policies(provider_type)
    if provider_name in provider_policies:
        detail = {
          'message': (_('Unable to delete - provider used in policies!\n[%s]')
                      % ','.join(provider_policies[provider_name]))
            }
        ret = 0
        return ret, detail

    del_entries = set()
    provider = prefix + provider_name

    # first delete the provider root entry
    if provider in config:
        del_entries.add(provider)

    # now lookup the all decent entries
    provider_prefix = provider + '.'
    for key in config.keys():
        if key[:len(provider_prefix)] == provider_prefix:
            del_entries.add(key)

    # when all entries are gathered, we can now delete them all
    for del_entry in del_entries:
        removeFromConfig(del_entry)

    ret = len(del_entries)

    return ret, detail
Пример #15
0
def get_all_new_providers(provider_type, show_managed_config=False):
    """
    get all providers of the new format
    :param provider_type: the type of the provider
    :return: dict with all providers
    """

    providers = {}

    provider_names = {}

    # find out, which provider type we have, currently only push, sms or email
    prefix = Provider_types.get(provider_type, {}).get('prefix')
    if not prefix:
        raise Exception('unknown provider type %r' % provider_type)

    # find out, which providers we have
    config = getLinotpConfig()

    # first identify all providers by its name
    for key, value in config.items():
        if key[:len(prefix)] == prefix:
            parts = key.split('.')
            if len(parts) == 3:
                provider_names[key] = value

    for provider, provider_class in provider_names.items():

        defintion = {}
        defintion['Class'] = provider_class
        prefix = provider + '.'

        for key, value in config.items():
            if key[:len(prefix)] == prefix:

                if 'enc' + key in config:
                    value = config.get('enc' + key)

                entry = key.replace(prefix, '')
                defintion[entry] = value

        defintion['Default'] = False

        # in case of a managed provider, the configuration is not displayed
        if prefix + 'Managed' in config:

            defintion['Managed'] = config.get(prefix + 'Managed')

            if not show_managed_config:
                del defintion['Config']

        name = provider.split('.')[2]
        providers[name] = defintion

    return providers
Пример #16
0
def setProvider(params):
    """
    save the provider info in linotp config

    :param params: generic parameter dictionary to support later more complex
                   provider definitions
                   in the dictionary currently required keys are
                   :param type: sms or email
                   :param name: the provider name
                   :param config: the provider config
                   :param timeout: the provider timeout
                   :param: default: boolean

    :return: success - boolean
    """

    provider_type = params['type']
    provider_name = params['name']

    prefix = Provider_types.get(provider_type, {}).get('prefix')
    if not prefix:
        raise Exception('unknown provider type %r' % provider_type)

    provider_prefix = prefix + provider_name
    storeConfig(key=provider_prefix, val=params['class'])
    storeConfig(key=provider_prefix + '.Timeout', val=params['timeout'])

    # alternative to storing the whole config in encrypted way, we
    # might look if it's a json and store the next Config.  level
    # and look for the reserved additional appended type: password
    storeConfig(key=provider_prefix + '.Config', val=params['config'],
                typ='password')

    # finally we handle the default setting and the
    # ability to delete legacy entries
    drop_legacy = False
    config = getLinotpConfig()
    default_provider_key = Default_Provider_Key[provider_type]

    if 'default' in params:
        if params['default'] == True or params['default'].lower() == 'true':
            storeConfig(key=default_provider_key, val=provider_name)
            drop_legacy = True

    elif provider_name == config.get(default_provider_key, ''):
        drop_legacy = True

    if drop_legacy:
        # at this point we can drop the legacy definition
        entries = Legacy_Provider[provider_type]
        for entry in entries.keys():
            if entry in config:
                removeFromConfig(entry)

    return True, {}
Пример #17
0
def _initalGetRealms():
    '''
    initaly parse all config entries, and extract the realm definition

    :return : a dict with all realm definitions
    :rtype  : dict of definitions
    '''

    Realms = {}
    defRealmConf = "linotp.useridresolver"
    realmConf = "linotp.useridresolver.group."
    defaultRealmDef = "linotp.DefaultRealm"
    defaultRealm = None


    dc = getLinotpConfig()
    for entry in dc:

        if entry.startswith(realmConf):

            #the realm might contain dots "."
            # so take all after the 3rd dot for realm
            r = {}
            realm = entry.split(".", 3)
            theRealm = realm[3].lower()
            r["realmname"] = realm[3]
            r["entry"] = entry

            ##resids          = env.config[entry]
            resids = getFromConfig(entry)
            r["useridresolver"] = resids.split(",")

            Realms[theRealm] = r

        if entry == defRealmConf:
            r = {}

            theRealm = "_default_"
            r["realmname"] = theRealm
            r["entry"] = defRealmConf

            #resids          = env.config[entry]
            resids = getFromConfig(entry)
            r["useridresolver"] = resids.split(",")

            defaultRealm = "_default_"
            Realms[theRealm] = r

        if entry == defaultRealmDef:
            defaultRealm = getFromConfig(defaultRealmDef)

    if defaultRealm is not None:
        _setDefaultRealm(Realms, defaultRealm)

    return Realms
Пример #18
0
def get_all_new_providers(provider_type, show_managed_config=False):
    """
    get all providers of the new format
    :param provider_type: the type of the provider
    :return: dict with all providers
    """

    providers = {}

    provider_names = {}

    # find out, which provider type we have, currently only push, sms or email
    prefix = Provider_types.get(provider_type, {}).get('prefix')
    if not prefix:
        raise Exception('unknown provider type %r' % provider_type)

    # find out, which providers we have
    config = getLinotpConfig()

    # first identify all providers by its name
    for key, value in config.items():
        if key[:len(prefix)] == prefix:
            parts = key.split('.')
            if len(parts) == 3:
                provider_names[key] = value

    for provider, provider_class in provider_names.items():

        defintion = {}
        defintion['Class'] = provider_class
        prefix = provider + '.'

        for key, value in config.items():
            if key[:len(prefix)] == prefix:

                if 'enc' + key in config:
                    value = config.get('enc' + key)

                entry = key.replace(prefix, '')
                defintion[entry] = value

        defintion['Default'] = False

        # in case of a managed provider, the configuration is not displayed
        if prefix + 'Managed' in config:

            defintion['Managed'] = config.get(prefix + 'Managed')

            if not show_managed_config:
                del defintion['Config']

        name = provider.split('.')[2]
        providers[name] = defintion

    return providers
Пример #19
0
def _initalGetRealms():
    '''
    initaly parse all config entries, and extract the realm definition

    :return : a dict with all realm definitions
    :rtype  : dict of definitions
    '''

    Realms = {}
    defRealmConf = "linotp.useridresolver"
    realmConf = "linotp.useridresolver.group."
    defaultRealmDef = "linotp.DefaultRealm"
    defaultRealm = None

    dc = getLinotpConfig()
    for entry in dc:

        if entry.startswith(realmConf):

            #the realm might contain dots "."
            # so take all after the 3rd dot for realm
            r = {}
            realm = entry.split(".", 3)
            theRealm = realm[3].lower()
            r["realmname"] = realm[3]
            r["entry"] = entry

            ##resids          = env.config[entry]
            resids = getFromConfig(entry)
            r["useridresolver"] = resids.split(",")

            Realms[theRealm] = r

        if entry == defRealmConf:
            r = {}

            theRealm = "_default_"
            r["realmname"] = theRealm
            r["entry"] = defRealmConf

            #resids          = env.config[entry]
            resids = getFromConfig(entry)
            r["useridresolver"] = resids.split(",")

            defaultRealm = "_default_"
            Realms[theRealm] = r

        if entry == defaultRealmDef:
            defaultRealm = getFromConfig(defaultRealmDef)

    if defaultRealm is not None:
        _setDefaultRealm(Realms, defaultRealm)

    return Realms
Пример #20
0
def loadProvider(provider_type, provider_name=None):
    """
    interface for the provider user like email token or sms token

    :param provider_type: 'push', 'email' or 'sms
    :param provider_name: the name of the provider configuration

    :return: the instantiated provider with already loaded configuration
    """
    provider_info = {}
    config = getLinotpConfig()

    default_provider_key = Default_Provider_Key[provider_type]

    #
    # if no provider is given, we try to lookup the default
    #
    if default_provider_key in config and not provider_name:
        provider_name = config[default_provider_key]

    #
    # if there is no provider_name or the provider is a legacy one
    # try to load it the legacy way
    #
    if not provider_name or provider_name == Legacy_Provider_Name:
        provider_info = get_legacy_provider(provider_type=provider_type)
        provider_name = Legacy_Provider_Name

    #
    # in case of no provider_info the provider is
    # either a new one or or a legacy converted one
    #
    if not provider_info:
        providers = getProvider(provider_type, provider_name=provider_name)
        provider_info = providers.get(provider_name)

    if not provider_info:
        raise Exception('Unable to load provider: %r' % provider_name)

    provider_info = provider_info.get(provider_name, provider_info)
    provider_class = provider_info.get('Class')

    try:
        provider_class_obi = _load_provider_class(provider_class)
        provider = provider_class_obi()
    except Exception as exc:
        log.exception("Failed to load provider: %r", exc)
        raise exc

    provider_config = _build_provider_config(provider_info)
    provider.loadConfig(provider_config)

    return provider
Пример #21
0
def loadProvider(provider_type, provider_name=None):
    """
    interface for the provider user like email token or sms token

    :param provider_type: 'push', 'email' or 'sms
    :param provider_name: the name of the provider configuration

    :return: the instantiated provider with already loaded configuration
    """
    provider_info = {}
    config = getLinotpConfig()

    default_provider_key = Default_Provider_Key[provider_type]

    #
    # if no provider is given, we try to lookup the default
    #
    if default_provider_key in config and not provider_name:
        provider_name = config[default_provider_key]

    #
    # if there is no provider_name or the provider is a legacy one
    # try to load it the legacy way
    #
    if not provider_name or provider_name == Legacy_Provider_Name:
        provider_info = get_legacy_provider(provider_type=provider_type)
        provider_name = Legacy_Provider_Name

    #
    # in case of no provider_info the provider is
    # either a new one or or a legacy converted one
    #
    if not provider_info:
        providers = getProvider(provider_type, provider_name=provider_name)
        provider_info = providers.get(provider_name)

    if not provider_info:
        raise Exception('Unable to load provider: %r' % provider_name)

    provider_info = provider_info.get(provider_name, provider_info)
    provider_class = provider_info.get('Class')

    try:
        provider_class_obi = _load_provider_class(provider_class)
        provider = provider_class_obi()
    except Exception as exc:
        log.exception("Failed to load provider: %r", exc)
        raise exc

    provider_config = _build_provider_config(provider_info)
    provider.loadConfig(provider_config)

    return provider
Пример #22
0
def get_default_provider(provider_type):
    """
    find out, which provider is declared as default

    :param provider_type: push, sms or email
    :return: the name of the default provider
    """
    config = getLinotpConfig()

    # finally care for the default provider
    default_provider_key = Default_Provider_Key[provider_type]
    default_provider = config.get(default_provider_key, None)
    return default_provider
Пример #23
0
def get_default_provider(provider_type):
    """
    find out, which provider is declared as default

    :param provider_type: push, sms or email
    :return: the name of the default provider
    """
    config = getLinotpConfig()

    # finally care for the default provider
    default_provider_key = Default_Provider_Key[provider_type]
    default_provider = config.get(default_provider_key, None)
    return default_provider
Пример #24
0
    def authenticate(self, environ, identity):
        log.info("[authenticate] entering repoze authenticate function.")
        # log.debug( identity )
        username = None
        realm = None
        options = {}
        realmbox = "False"

        authenticate = True
        if isSelfTest():
            authenticate = False

        try:
            if isSelfTest():
                if ('login' not in identity
                        and 'repoze.who.plugins.auth_tkt.userid' in identity):
                    u = identity.get('repoze.who.plugins.auth_tkt.userid')
                    identity['login'] = u
                    identity['password'] = u

            username = identity['login']
            realm = identity['realm']
            password = identity['password']
            options.update(identity)
            realmbox = options.get("realmbox", "False")

        except KeyError as e:
            log.exception("[authenticate] Keyerror in identity: %r." % e)
            return None

        # convert string to boolean
        realm_mbox = False
        if realmbox.lower() == 'true':
            realm_mbox = True

        # check username/realm, password
        with request_context_safety():
            linotp_config = getLinotpConfig()
            request_context['Config'] = linotp_config
            user = get_authenticated_user(username,
                                          realm,
                                          password,
                                          realm_box=realm_mbox,
                                          authenticate=authenticate,
                                          options=options)
        if not user:
            return None

        authUser = "******" % (user.login, user.realm)
        return authUser
Пример #25
0
def getRealmBox():
    '''
    returns the config value of selfservice.realmbox.
    if True, the realmbox in the selfservice login will be displayed.
    if False, the realmbox will not be displayed and the user needs to login via user@realm
    '''
    rb_string = "linotp.selfservice.realmbox"
    log.debug("[getRealmBox] getting realmbox setting")
    conf = getLinotpConfig()
    if rb_string in conf:
        log.debug("[getRealmBox] read setting: %r" % conf[rb_string])
        return "True" == conf[rb_string]
    else:
        return False
Пример #26
0
def getRealmBox():
    '''
    returns the config value of selfservice.realmbox.
    if True, the realmbox in the selfservice login will be displayed.
    if False, the realmbox will not be displayed and the user needs to login via user@realm
    '''
    rb_string = "linotp.selfservice.realmbox"
    log.debug("[getRealmBox] getting realmbox setting")
    conf = getLinotpConfig()
    if rb_string in conf:
        log.debug("[getRealmBox] read setting: %r" % conf[rb_string])
        return "True" == conf[rb_string]
    else:
        return False
Пример #27
0
def setPolicy(param, context=None):
    '''
    Function to set a policy. It expects a dict of with the following keys:

      * name
      * action
      * scope
      * realm
      * user
      * time
      * client
    '''
    ret = {}

    name = param.get('name')
    action = param.get('action')
    scope = param.get('scope')
    realm = param.get('realm')
    user = param.get('user')
    time = param.get('time')
    client = param.get('client')
    active = param.get('active', "True")

    # before storing the policy, we have to check the impact:
    # if there is a problem, we will raise an exception with a warning
    if context and 'Policies' in context:
        policies = deepcopy(context['Policies'])
    else:
        Config = getLinotpConfig()
        policies = getPolicies(config=Config)

    _check_policy_impact(policies=policies, **param)

    ret["action"] = storeConfig("Policy.%s.action" % name, action, "",
                                "a policy definition")
    ret["scope"] = storeConfig("Policy.%s.scope" % name, scope, "",
                               "a policy definition")
    ret["realm"] = storeConfig("Policy.%s.realm" % name, realm, "",
                               "a policy definition")
    ret["user"] = storeConfig("Policy.%s.user" % name, user, "",
                              "a policy definition")
    ret["time"] = storeConfig("Policy.%s.time" % name, time, "",
                              "a policy definition")
    ret["client"] = storeConfig("Policy.%s.client" % name, client, "",
                                "a policy definition")
    ret["active"] = storeConfig("Policy.%s.active" % name, active, "",
                                "a policy definition")

    return ret
Пример #28
0
def setPolicy(param, context=None):
    '''
    Function to set a policy. It expects a dict of with the following keys:

      * name
      * action
      * scope
      * realm
      * user
      * time
      * client
    '''
    ret = {}

    name = param.get('name')
    action = param.get('action')
    scope = param.get('scope')
    realm = param.get('realm')
    user = param.get('user')
    time = param.get('time')
    client = param.get('client')
    active = param.get('active', "True")

    # before storing the policy, we have to check the impact:
    # if there is a problem, we will raise an exception with a warning
    if context and 'Policies' in context:
        policies = deepcopy(context['Policies'])
    else:
        Config = getLinotpConfig()
        policies = getPolicies(config=Config)

    _check_policy_impact(policies=policies, **param)

    ret["action"] = storeConfig("Policy.%s.action" % name,
                                action, "", "a policy definition")
    ret["scope"] = storeConfig("Policy.%s.scope" % name,
                               scope, "", "a policy definition")
    ret["realm"] = storeConfig("Policy.%s.realm" % name,
                               realm, "", "a policy definition")
    ret["user"] = storeConfig("Policy.%s.user" % name,
                              user, "", "a policy definition")
    ret["time"] = storeConfig("Policy.%s.time" % name,
                              time, "", "a policy definition")
    ret["client"] = storeConfig("Policy.%s.client" % name,
                                client, "", "a policy definition")
    ret["active"] = storeConfig("Policy.%s.active" % name,
                                active, "", "a policy definition")

    return ret
Пример #29
0
    def authenticate(self, environ, identity):
        log.info("[authenticate] entering repoze authenticate function.")
        # log.debug( identity )
        username = None
        realm = None
        options = {}
        realmbox = "False"

        authenticate = True
        if isSelfTest():
            authenticate = False

        try:
            if isSelfTest():
                if ('login' not in identity
                    and 'repoze.who.plugins.auth_tkt.userid' in identity):
                    u = identity.get('repoze.who.plugins.auth_tkt.userid')
                    identity['login'] = u
                    identity['password'] = u

            username = identity['login']
            realm = identity['realm']
            password = identity['password']
            options.update(identity)
            realmbox = options.get("realmbox", "False")

        except KeyError as e:
            log.exception("[authenticate] Keyerror in identity: %r." % e)
            return None

        # convert string to boolean
        realm_mbox = False
        if realmbox.lower() == 'true':
            realm_mbox = True

        # check username/realm, password
        with request_context_safety():
            linotp_config = getLinotpConfig()
            request_context['Config'] = linotp_config
            user = get_authenticated_user(username, realm, password,
                                              realm_box=realm_mbox,
                                              authenticate=authenticate,
                                              options=options)
        if not user:
            return None

        authUser = "******" % (user.login, user.realm)
        return authUser
Пример #30
0
def deletePolicy(name, enforce=False):
    '''
    Function to delete one named policy

    attributes:
        name:   (required) will only return the policy with the name
    '''
    res = {}
    if not re.match('^[a-zA-Z0-9_]*$', name):
        raise ServerError(
            "policy name may only contain the "
            "characters a-zA-Z0-9_",
            id=8888)

    if context and 'Config' in context:
        Config = context['Config']
    else:
        Config = getLinotpConfig()

    if context and 'Policies' in context:
        policies = context['Policies']
    else:
        policies = getPolicies()

    # check if due to delete of the policy a lockout could happen
    param = policies.get(name)
    # delete is same as inactive ;-)
    if param:
        param['active'] = "False"
        param['name'] = name
        param['enforce'] = enforce
        _check_policy_impact(**param)

    delEntries = []
    for entry in Config:
        if entry.startswith("linotp.Policy.%s." % name):
            delEntries.append(entry)

    for entry in delEntries:
        # delete this entry.
        log.debug("[deletePolicy] removing key: %s" % entry)
        ret = removeFromConfig(entry)
        res[entry] = ret

    return res
Пример #31
0
def deletePolicy(name, enforce=False):
    """
    Function to delete one named policy

    attributes:
        name:   (required) will only return the policy with the name
    """
    res = {}
    if not re.match("^[a-zA-Z0-9_]*$", name):
        raise ServerError(
            "policy name may only contain the " "characters a-zA-Z0-9_",
            id=8888,
        )

    if context and context.get("Config"):
        Config = context["Config"]
    else:
        Config = getLinotpConfig()

    #
    # we need the policies for a name lookup only

    policies = get_policies()

    # check if due to delete of the policy a lockout could happen
    param = policies.get(name)
    # delete is same as inactive ;-)
    if param:
        param["active"] = "False"
        param["name"] = name
        param["enforce"] = enforce
        _check_policy_impact(**param)

    delEntries = []
    for entry in Config:
        if entry.startswith("linotp.Policy.%s." % name):
            delEntries.append(entry)

    for entry in delEntries:
        # delete this entry.
        log.debug("[deletePolicy] removing key: %r", entry)
        ret = removeFromConfig(entry)
        res[entry] = ret

    return res
Пример #32
0
def getRealms(aRealmName="", context=None):
    '''
    lookup for a defined realm or all realms

    :note:  the realms dict is inserted into the LinOtp Config object
    so that a lookup has not to reparse the whole config again

    :param aRealmName: a realmname - the realm, that is of interestet, if =="" all realms are returned
    :type  aRealmName: string

    :return:  a dict with realm description like
    :rtype :  dict : {
                u'myotherrealm': {'realmname': u'myotherrealm',
                                'useridresolver': ['useridresolver.PasswdIdResolver.IdResolver.myOtherRes'],
                                'entry': u'linotp.useridresolver.group.myotherrealm'},
                u'mydefrealm': {'default': 'true',
                                'realmname': u'mydefrealm',
                                'useridresolver': ['useridresolver.PasswdIdResolver.IdResolver.myDefRes'],
                                'entry': u'linotp.useridresolver.group.mydefrealm'},
               u'mymixrealm': {'realmname': u'mymixrealm',
                               'useridresolver': ['useridresolver.PasswdIdResolver.IdResolver.myOtherRes', 'useridresolver.PasswdIdResolver.IdResolver.myDefRes'],
                               'entry': u'linotp.useridresolver.group.mymixrealm'}}

    '''
    ret = {}

    if not context:
        config = getLinotpConfig()
    else:
        config = context["Config"]
    realms = config.getRealms()

    # only parse once per session
    if realms is None:
        realms = _initalGetRealms()
        config.setRealms(realms)

    ''' check if only one realm is searched '''
    if aRealmName != "" :
        if aRealmName in realms:
            ret[aRealmName] = realms.get(aRealmName)
    else:
        ret.update(realms)
    return ret
Пример #33
0
def deletePolicy(name, enforce=False):
    '''
    Function to delete one named policy

    attributes:
        name:   (required) will only return the policy with the name
    '''
    res = {}
    if not re.match('^[a-zA-Z0-9_]*$', name):
        raise ServerError("policy name may only contain the "
                          "characters a-zA-Z0-9_", id=8888)

    if context and 'Config' in context:
        Config = context['Config']
    else:
        Config = getLinotpConfig()

    #
    # we need the policies for a name lookup only

    policies = get_policies()

    # check if due to delete of the policy a lockout could happen
    param = policies.get(name)
    # delete is same as inactive ;-)
    if param:
        param['active'] = "False"
        param['name'] = name
        param['enforce'] = enforce
        _check_policy_impact(**param)

    delEntries = []
    for entry in Config:
        if entry.startswith("linotp.Policy.%s." % name):
            delEntries.append(entry)

    for entry in delEntries:
        # delete this entry.
        log.debug("[deletePolicy] removing key: %s" % entry)
        ret = removeFromConfig(entry)
        res[entry] = ret

    return res
Пример #34
0
def deleteResolver(resolvername):
    '''
    delete a resolver and all related config entries

    :paramm resolvername: the name of the to be deleted resolver
    :type   resolvername: string
    :return: sucess or fail
    :rtype:  boelean

    '''
    res = False

    resolvertypes = get_resolver_types()
    conf = getLinotpConfig()

    delEntries = []

    for entry in conf:
        rest = entry.split(".", 3)
        lSplit = len(rest)
        if lSplit > 3:
            rConf = rest[lSplit - 1]
            if rConf == resolvername:
                if rest[0] == "linotp" or rest[0] == "enclinotp" :
                    typ = rest[1]
                    if typ in resolvertypes:
                        delEntries.append(entry)

    if len(delEntries) > 0 :
        try:
            for entry in delEntries:
                res = removeFromConfig(entry)
                log.debug("[deleteResolver] removing key: %s" % entry)
                res = True
        except Exception as e:
            log.error("deleteResolver: %r" % e)
            res = False


    return res
Пример #35
0
def deleteResolver(resolvername):
    '''
    delete a resolver and all related config entries

    :paramm resolvername: the name of the to be deleted resolver
    :type   resolvername: string
    :return: sucess or fail
    :rtype:  boelean

    '''
    res = False

    resolvertypes = get_resolver_types()
    conf = getLinotpConfig()

    delEntries = []

    for entry in conf:
        rest = entry.split(".", 3)
        lSplit = len(rest)
        if lSplit > 3:
            rConf = rest[lSplit - 1]
            if rConf == resolvername:
                if rest[0] == "linotp" or rest[0] == "enclinotp":
                    typ = rest[1]
                    if typ in resolvertypes:
                        delEntries.append(entry)

    if len(delEntries) > 0:
        try:
            for entry in delEntries:
                res = removeFromConfig(entry)
                log.debug("[deleteResolver] removing key: %s" % entry)
                res = True
        except Exception as e:
            log.error("deleteResolver: %r" % e)
            res = False

    return res
Пример #36
0
    def create_context(self, request):
        """
        create the request context for all controllers
        """

        linotp_config = getLinotpConfig()

        self.request_context = {}
        self.request_context['Config'] = linotp_config
        self.request_context['Policies'] = getPolicies(config=linotp_config)
        self.request_context['translate'] = translate

        request_params = {}

        try:
            request_params.update(request.params)
        except UnicodeDecodeError as exx:
            log.error("Faild to decode request parameters %r" % exx)

        self.request_context['Params'] = request_params

        authUser = None
        try:
            authUser = getUserFromRequest(request)
        except UnicodeDecodeError as exx:
            log.error("Faild to decode request parameters %r" % exx)

        self.request_context['AuthUser'] = authUser

        requestUser = None
        try:
            requestUser = getUserFromParam(request_params, True)
        except UnicodeDecodeError as exx:
            log.error("Faild to decode request parameters %r" % exx)
        self.request_context['RequestUser'] = requestUser

        client = None
        try:
            client = get_client(request=request)
        except UnicodeDecodeError as exx:
            log.error("Faild to decode request parameters %r" % exx)

        self.request_context['Client'] = client

        self.request_context['audit'] = {}

        defaultRealm = ""
        try:
            defaultRealm = getDefaultRealm(linotp_config)
        except UnicodeDecodeError as exx:
            log.error("Faild to decode request parameters %r" % exx)

        self.request_context['defaultRealm'] = defaultRealm

        realms = None
        try:
            realms = getRealms(context=self.request_context)
        except UnicodeDecodeError as exx:
            log.error("Faild to decode request parameters %r" % exx)

        self.request_context['Realms'] = realms

        return
Пример #37
0
def getResolverObject(resolver_spec, config=None, load_config=True):
    """
    get the resolver instance from a resolver specification.

    :remark: internally this function uses the request context for caching.

    :param resolver_spec: the resolver string as from the token including
                          the config identifier.

                          format:
                          <resolver class identifier>.<config identifier>

    :return: instance of the resolver with the loaded config (or None
             if specification was invalid or didn't match a resolver)

    """

    #  this patch is a bit hacky:
    # the normal request has a request context, where it retrieves
    # the resolver info from and preserves the loaded resolvers for reusage
    # But in case of a authentication request (by a redirect from a 401)
    # the caller is no std request and the context object is missing :-(
    # The solution is to deal with local references, either to the
    # global context or to local data (where we have no reuse of the resolver)

    resolvers_loaded = context.setdefault('resolvers_loaded', {})

    if not config:
        config = getLinotpConfig()

    # test if the resolver is in the cache
    if resolver_spec in resolvers_loaded:
        return resolvers_loaded.get(resolver_spec)

    # no resolver - so instantiate one
    else:

        cls_identifier, config_identifier = parse_resolver_spec(resolver_spec)

        if not cls_identifier or not config_identifier:
            log.error('Format error: resolver_spec must have the format '
                      '<resolver_class_identifier>.<config_identifier>, but '
                      'value was %s' % resolver_spec)
            return None

        resolver_cls = get_resolver_class(cls_identifier)

        if resolver_cls is None:
            log.error('Unknown resolver class: %s' % cls_identifier)
            return None

        resolver = resolver_cls()

        if load_config:

            try:

                resolver.loadConfig(config, config_identifier)

            except ResolverNotAvailable:
                log.error('Unable to connect to resolver %r', resolver_spec)
                return None

            except Exception as exx:
                # FIXME: Except clause is too general. resolver
                # should be ResolverLoadConfigError
                # exceptions in the useridresolver modules should
                # have their own type, so we can filter here
                log.error(
                    'Resolver config loading failed for resolver with '
                    'specification %s: %r', resolver_spec, exx)

                return None

            # in case of the replication there might by difference
            # in the used resolver config and the config from the LinOTP config
            _check_for_resolver_cache_flush(resolver_spec, config_identifier)

            resolvers_loaded[resolver_spec] = resolver

        return resolver
Пример #38
0
    def authenticate(self, environ, identity):
        log.debug("Authentication through repoze.")
        username = None
        realm = None
        options = {}
        realmbox = "False"

        authenticate = True
        if isSelfTest():
            authenticate = False

        try:
            if isSelfTest():
                if ('login' not in identity
                        and 'repoze.who.plugins.auth_tkt.userid' in identity):
                    u = identity.get('repoze.who.plugins.auth_tkt.userid')
                    identity['login'] = u
                    identity['password'] = u

            username = identity['login']
            realm = identity['realm']
            password = identity['password']
            options.update(identity)
            realmbox = options.get("realmbox", "False")

        except KeyError as e:
            log.exception("Keyerror in repoze identity: %r." % e)
            return None

        # convert string to boolean
        realm_mbox = False
        if realmbox.lower() == 'true':
            realm_mbox = True

        # check username/realm, password
        with request_context_safety():
            linotp_config = getLinotpConfig()
            request_context['Config'] = linotp_config

            # add the cache manager to the context
            glo = getGlobalObject()
            cache_manager = glo.cache_manager
            request_context['CacheManager'] = cache_manager

            # and also add the hsm - enables us to do otp validation :-)
            sep = glo.security_provider
            hsm = sep.getSecurityModule()
            request_context['hsm'] = hsm

            # initialize the base context
            # - copied for the dumb repoze middleware

            cache_dir = config.get("app_conf", {}).get("cache_dir", None)
            setupResolvers(config=linotp_config, cache_dir=cache_dir)
            resolver_context = initResolvers()
            request_context.update(resolver_context)

            # prepare the request local user cache
            if 'UserLookup' not in request_context:
                request_context['UserLookup'] = {}

            user = get_authenticated_user(username,
                                          realm,
                                          password,
                                          realm_box=realm_mbox,
                                          authenticate=authenticate,
                                          options=options)

        if not user:
            return None

        authUser = "******" % (user.login, user.realm)
        return authUser
Пример #39
0
    def create_context(self, request):
        """
        create the request context for all controllers
        """

        linotp_config = getLinotpConfig()

        self.request_context = {}
        self.request_context['Config'] = linotp_config
        self.request_context['Policies'] = getPolicies(config=linotp_config)
        self.request_context['translate'] = translate

        request_params = {}

        try:
            request_params.update(request.params)
        except UnicodeDecodeError as exx:
            log.error("Faild to decode request parameters %r" % exx)

        self.request_context['Params'] = request_params

        authUser = None
        try:
            authUser = getUserFromRequest(request)
        except UnicodeDecodeError as exx:
            log.error("Faild to decode request parameters %r" % exx)

        self.request_context['AuthUser'] = authUser

        requestUser = None
        try:
            requestUser = getUserFromParam(request_params, True)
        except UnicodeDecodeError as exx:
            log.error("Faild to decode request parameters %r" % exx)
        self.request_context['RequestUser'] = requestUser

        client = None
        try:
            client = get_client(request=request)
        except UnicodeDecodeError as exx:
            log.error("Faild to decode request parameters %r" % exx)

        self.request_context['Client'] = client

        self.request_context['audit'] = {}

        defaultRealm = ""
        try:
            defaultRealm = getDefaultRealm(linotp_config)
        except UnicodeDecodeError as exx:
            log.error("Faild to decode request parameters %r" % exx)

        self.request_context['defaultRealm'] = defaultRealm

        realms = None
        try:
            realms = getRealms(context=self.request_context)
        except UnicodeDecodeError as exx:
            log.error("Faild to decode request parameters %r" % exx)

        self.request_context['Realms'] = realms

        return
Пример #40
0
def getProvider(provider_type, provider_name=None):
    """
    return a dict with  providers, each with it's description as dict

    :param provider_type: either sms or email
    :param provider_name: name of the provider (optional)
    """
    providers = {}

    # find out, which provider type we have, currently only sms or email
    prefix = Provider_types.get(provider_type, {}).get('prefix')
    if not prefix:
        raise Exception('unknow provider type %r' % provider_type)

    default_provider_key = Default_Provider_Key[provider_type]

    # find out, which providers we have
    config = getLinotpConfig()

    provider_names = {}

    default_provider = None

    # if provider by name is given, we select only this one
    if provider_name:
        name = prefix + provider_name
        if name in config:
            provider_names[name] = config[name]
    else:
        # first identify all providers by its name
        for key, value in config.items():
            if key[:len(prefix)] == prefix:
                parts = key.split('.')
                if len(parts) == 3:
                    provider_names[key] = value

    for provider, provider_class in provider_names.items():

        defintion = {}
        defintion['Class'] = provider_class
        prefix = provider + '.'

        for key, value in config.items():
            if key[:len(prefix)] == prefix:
                if 'enc' + key in config:
                    value = config.get('enc' + key)
                entry = key.replace(prefix, '')
                defintion[entry] = value

        defintion['Default'] = False
        name = provider.split('.')[2]
        providers[name] = defintion

    # finally care for the default provider
    if default_provider_key in config:
        default_provider = config.get(default_provider_key)
        if default_provider in providers:
            providers[default_provider]['Default'] = True

    # if searched for a dedicated provider, ignore the legacy one
    if not provider_name:
        if Legacy_Provider_Name not in providers:
            defintion = get_legacy_provider(provider_type=provider_type)
            if defintion:
                if not default_provider:
                    defintion['Default'] = True

                providers[Legacy_Provider_Name] = defintion

    #
    # finally check that we preserve and show the default:
    #
    # if in the current definition, we have a different default defined (s.o.)
    # we trust this and overwrite the one of Config table (if any)
    # This will create a consistent way to bootstrap a default even
    # from import

    for provider in providers:
        provider_info = providers[provider]
        if provider_info.get('Default', False):
            if config.get(default_provider_key, '') != provider:
                storeConfig(default_provider_key, provider)

    # if there is only one defined, it must be the default :-)
    if len(providers.keys()) == 1:
        for provider, provider_info in providers.items():
            provider_info['Default'] = True
            storeConfig(default_provider_key, provider)

    return providers
Пример #41
0
    def authenticate(self, environ, identity):
        log.info("[authenticate] entering repoze authenticate function.")
        # log.debug( identity )
        username = None
        realm = None
        options = {}
        realmbox = "False"

        authenticate = True
        if isSelfTest():
            authenticate = False

        try:
            if isSelfTest():
                if ('login' not in identity
                        and 'repoze.who.plugins.auth_tkt.userid' in identity):
                    u = identity.get('repoze.who.plugins.auth_tkt.userid')
                    identity['login'] = u
                    identity['password'] = u

            username = identity['login']
            realm = identity['realm']
            password = identity['password']
            options.update(identity)
            realmbox = options.get("realmbox", "False")

        except KeyError as e:
            log.exception("[authenticate] Keyerror in identity: %r." % e)
            return None

        # convert string to boolean
        realm_mbox = False
        if realmbox.lower() == 'true':
            realm_mbox = True

        # check username/realm, password
        with request_context_safety():
            linotp_config = getLinotpConfig()
            request_context['Config'] = linotp_config

            # add the cache manager to the context
            glo = getGlobalObject()
            cache_manager = glo.cache_manager
            request_context['CacheManager'] = cache_manager

            # and also add the hsm - enables us to do otp validation :-)
            sep = glo.security_provider
            hsm = sep.getSecurityModule()
            request_context['hsm'] = hsm

            resolver_context = initResolvers()
            request_context.update(resolver_context)

            user = get_authenticated_user(username,
                                          realm,
                                          password,
                                          realm_box=realm_mbox,
                                          authenticate=authenticate,
                                          options=options)

        if not user:
            return None

        authUser = "******" % (user.login, user.realm)
        return authUser
Пример #42
0
def getResolverObject(resolver_spec):

    """
    get the resolver instance from a resolver specification.

    :remark: internally this function uses the request context for caching.

    :param resolver_spec: the resolver string as from the token including
                          the config identifier.

                          format:
                          <resolver class identifier>.<config identifier>

    :return: instance of the resolver with the loaded config (or None
             if specification was invalid or didn't match a resolver)

    """

    #  this patch is a bit hacky:
    # the normal request has a request context, where it retrieves
    # the resolver info from and preserves the loaded resolvers for reusage
    # But in case of a authentication request (by a redirect from a 401)
    # the caller is no std request and the context object is missing :-(
    # The solution is to deal with local references, either to the
    # global context or to local data (where we have no reuse of the resolver)

    resolvers_loaded = context.setdefault('resolvers_loaded', {})

    # test if the resolver is in the cache
    if resolver_spec in resolvers_loaded:
        return resolvers_loaded.get(resolver_spec)

    # no resolver - so instatiate one
    else:

        cls_identifier, config_identifier = parse_resolver_spec(resolver_spec)

        if not cls_identifier or not config_identifier:
            log.error('Format error: resolver_spec must have the format '
                      '<resolver_class_identifier>.<config_identifier>, but '
                      'value was %s' % resolver_spec)
            return None

        resolver_cls = get_resolver_class(cls_identifier)

        if resolver_cls is None:
            log.error('unknown resolver class: %s' % cls_identifier)
            return None

        resolver = resolver_cls()

        config = getLinotpConfig()
        try:
            resolver.loadConfig(config, config_identifier)
        except:
            # FIXME: Except clause is too general. resolver
            # exceptions in the useridresolver modules should
            # have their own type, so we can filter here
            log.error('resolver config loading failed for resolver with '
                      'specification %s' % resolver_spec)
            return None
        resolvers_loaded[resolver_spec] = resolver

        return resolver
Пример #43
0
def delProvider(provider_type, provider_name):
    """
    delete a provider

    :param provider_type: the type of Provider: push, sms or email
    :param provider_name: the name of the provider

    :return: the number of deleted entries
    """
    detail = {}

    prefix = Provider_types.get(provider_type, {}).get('prefix')
    if not prefix:
        raise Exception('unknown provider type %r' % provider_type)

    # find out, which providers we have
    config = getLinotpConfig()

    # if the provider is the default one, we don't delete this one
    default_provider_key = Default_Provider_Key[provider_type]
    if default_provider_key in config:
        default_provider = config[default_provider_key]

        if provider_name == default_provider:
            detail = {'message': _('Default provider could not be deleted!')}
            ret = 0
            return ret, detail

    # check that there are no references left
    provider_policies = _lookup_provider_policies(provider_type)
    if provider_name in provider_policies:
        detail = {
            'message':
            (_('Unable to delete - provider used in '
               'policies!\n[%s]') % ','.join(provider_policies[provider_name]))
        }
        ret = 0
        return ret, detail

    del_entries = set()
    provider = prefix + provider_name

    # treat backward default legacy case
    if provider_name == Legacy_Provider_Name:
        entries = Legacy_Provider.get(provider_type, {})
        for entry in entries.keys():
            if entry in config:
                del_entries.add(entry)

    if not del_entries:
        # first delete the provider root entry
        if provider in config:
            del_entries.add(provider)

        # now lookup the all decent entries
        provider_prefix = provider + '.'
        for key in config.keys():
            if key[:len(provider_prefix)] == provider_prefix:
                del_entries.add(key)

    # when all entries are gathered, we can now delete them all
    for del_entry in del_entries:
        removeFromConfig(del_entry)

    ret = len(del_entries)

    return ret, detail
Пример #44
0
def getResolverInfo(resolvername):
    '''
    return the resolver info of the given resolvername

    :param resolvername: the requested resolver
    :type  resolvername: string

    :return : dict of resolver description
    '''
    resolver_dict = {}
    typ = ""
    resolvertypes = get_resolver_types()

    descr = {}

    conf = getLinotpConfig()

    for entry in conf:

        for typ in resolvertypes:

            ## get the typed values of the descriptor!
            resolver_conf = get_resolver_classConfig(typ)
            if typ in resolver_conf:
                descr = resolver_conf.get(typ).get('config', {})
            else:
                descr = resolver_conf

            if entry.startswith("linotp." +
                                typ) and entry.endswith(resolvername):
                #the realm might contain dots "."
                # so take all after the 3rd dot for realm
                resolver = entry.split(".", 3)
                # An old entry without resolver name
                if len(resolver) <= 3:
                    break

                value = conf.get(entry)
                if resolver[2] in descr:
                    configEntry = resolver[2]
                    if descr.get(configEntry) == 'password':

                        ## do we already have the decrypted pass?
                        if 'enc' + entry in conf:
                            value = conf.get('enc' + entry)
                        else:
                            ## if no, we take the encpass and decrypt it
                            value = conf.get(entry)
                            try:
                                en = decryptPassword(value)
                                value = en
                            except:
                                log.info(
                                    "Decryption of resolver passwd failed: compatibility issue?"
                                )

                resolver_dict[resolver[2]] = value
                # Dont check the other resolver types

                break

    return {"type": typ, "data": resolver_dict, "resolver": resolvername}
Пример #45
0
    def create_context(self, request):
        """
        create the request context for all controllers
        """

        linotp_config = getLinotpConfig()

        request_context['Config'] = linotp_config
        request_context['Policies'] = getPolicies()
        request_context['translate'] = translate

        initResolvers()

        request_params = {}

        try:
            request_params.update(request.params)
        except UnicodeDecodeError as exx:
            log.error("Faild to decode request parameters %r" % exx)

        request_context['Params'] = request_params

        authUser = None
        try:
            authUser = getUserFromRequest(request)
        except UnicodeDecodeError as exx:
            log.error("Faild to decode request parameters %r" % exx)

        request_context['AuthUser'] = authUser

        requestUser = None
        try:
            requestUser = getUserFromParam(request_params, True)
        except UnicodeDecodeError as exx:
            log.error("Faild to decode request parameters %r" % exx)
        request_context['RequestUser'] = requestUser

        client = None
        try:
            client = get_client(request=request)
        except UnicodeDecodeError as exx:
            log.error("Faild to decode request parameters %r" % exx)

        request_context['Client'] = client

        request_context['Audit'] = Audit
        request_context['audit'] = Audit.initialize(request,
                                                         client=client)

        defaultRealm = ""
        try:
            defaultRealm = getDefaultRealm(linotp_config)
        except UnicodeDecodeError as exx:
            log.error("Faild to decode request parameters %r" % exx)

        request_context['defaultRealm'] = defaultRealm

        realms = None
        try:
            realms = getRealms()
        except UnicodeDecodeError as exx:
            log.error("Faild to decode request parameters %r" % exx)

        request_context['Realms'] = realms

        request_context['hsm'] = None
        if hasattr(self, "hsm"):
            request_context['hsm'] = self.hsm

        # copy some system entries from pylons
        syskeys = {
                   "radius.nas_identifier": "LinOTP",
                   "radius.dictfile": "/etc/linotp2/dictionary"
        }

        sysconfig = {}
        for key, default in syskeys.items():
            try:
                sysconfig[key] = config.get(key, default)
            except:
                log.info('no sytem config entry %s' % key)

        request_context['SystemConfig'] = sysconfig
Пример #46
0
    def create_context(self, request, environment):
        """
        create the request context for all controllers
        """

        linotp_config = getLinotpConfig()

        # make the request id available in the request context
        request_context['RequestId'] = environment['REQUEST_ID']

        # a request local cache to get the user info from the resolver
        request_context['UserLookup'] = {}

        # a request local cache to get the resolver from user and realm
        request_context['UserRealmLookup'] = {}

        request_context['Config'] = linotp_config
        request_context['Policies'] = parse_policies(linotp_config)
        request_context['translate'] = translate
        request_context['CacheManager'] = environment['beaker.cache']

        routes = environment.get('pylons.routes_dict', {})
        path = "/%s/%s" % (routes['controller'], routes['action'])
        request_context['Path'] = path

        request_context['hsm'] = self.hsm

        initResolvers()

        client = None
        try:
            client = get_client(request=request)
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r" % exx)

        request_context['Client'] = client

        request_context['Audit'] = Audit
        request_context['audit'] = Audit.initialize(request, client=client)

        authUser = None
        try:
            authUser = getUserFromRequest(request)
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r" % exx)

        request_context['AuthUser'] = authUser
        request_context['UserLookup'] = {}

        # ------------------------------------------------------------------ --
        # get the current resolvers

        resolvers = []
        try:
            resolvers = getResolverList(config=linotp_config)
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r" % exx)

        request_context['Resolvers'] = resolvers

        # ------------------------------------------------------------------ --
        # get the current realms

        realms = {}
        try:
            realms = getRealms()
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r" % exx)

        request_context['Realms'] = realms

        # ------------------------------------------------------------------ --

        defaultRealm = ""
        try:
            defaultRealm = getDefaultRealm(linotp_config)
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r" % exx)

        request_context['defaultRealm'] = defaultRealm

        # ------------------------------------------------------------------ --
        # load the requesting user

        from linotp.useridresolver.UserIdResolver import (
            ResolverNotAvailable)

        requestUser = None
        try:
            requestUser = getUserFromParam(self.request_params)
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r", exx)
        except (ResolverNotAvailable, NoResolverFound) as exx:
            log.error("Failed to connect to server %r", exx)

        request_context['RequestUser'] = requestUser

        # ------------------------------------------------------------------ --
        # load the providers

        from linotp.provider import Provider_types
        from linotp.provider import getProvider

        provider = {}
        for provider_type in Provider_types.keys():
            provider[provider_type] = getProvider(provider_type)

        request_context['Provider'] = provider

        # ------------------------------------------------------------------ --

        # for the setup of encrypted data, we require the hsm is instatiated
        # and available in the request context

        if not self.secret_key:
            init_key_partition(linotp_config, partition=0)

        # ------------------------------------------------------------------ --

        # copy some system entries from pylons
        syskeys = {
            "radius.nas_identifier": "LinOTP",
            "radius.dictfile": "/etc/linotp2/dictionary"
        }

        sysconfig = {}
        for key, default in syskeys.items():
            sysconfig[key] = config.get(key, default)

        request_context['SystemConfig'] = sysconfig
Пример #47
0
    def create_context(self, request, environment):
        """
        create the request context for all controllers
        """

        linotp_config = getLinotpConfig()

        request_context['Config'] = linotp_config
        request_context['Policies'] = parse_policies(linotp_config)
        request_context['translate'] = translate
        request_context['CacheManager'] = environment['beaker.cache']

        initResolvers()

        request_params = {}

        try:
            request_params.update(request.params)
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r" % exx)

        request_context['Params'] = request_params

        authUser = None
        try:
            authUser = getUserFromRequest(request)
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r" % exx)

        request_context['AuthUser'] = authUser
        request_context['UserLookup'] = {}

        requestUser = None
        try:
            requestUser = getUserFromParam(request_params)
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r" % exx)
        request_context['RequestUser'] = requestUser

        client = None
        try:
            client = get_client(request=request)
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r" % exx)

        request_context['Client'] = client

        request_context['Audit'] = Audit
        request_context['audit'] = Audit.initialize(request, client=client)

        defaultRealm = ""
        try:
            defaultRealm = getDefaultRealm(linotp_config)
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r" % exx)

        request_context['defaultRealm'] = defaultRealm

        realms = None
        try:
            realms = getRealms()
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r" % exx)

        request_context['Realms'] = realms

        request_context['hsm'] = None
        if hasattr(self, "hsm"):
            request_context['hsm'] = self.hsm

        # copy some system entries from pylons
        syskeys = {
            "radius.nas_identifier": "LinOTP",
            "radius.dictfile": "/etc/linotp2/dictionary"
        }

        sysconfig = {}
        for key, default in syskeys.items():
            sysconfig[key] = config.get(key, default)

        request_context['SystemConfig'] = sysconfig
Пример #48
0
    def __init__(self, *args, **kw):
        """
        base controller constructor

        :param *args: generic argument array
        :param **kw: generic argument dict
        :return: None

        """
        self.sep = None
        self.set_language(request.headers)
        self.base_auth_user = ''

        self.parent = super(WSGIController, self)
        self.parent.__init__(*args, **kw)

        # make the OpenID SQL Instance globally available
        openid_sql = config.get('openid_sql', None)
        if openid_sql is None:
            try:
                openid_storage = SQLStorage()
                config['openid_sql'] = openid_storage
            except Exception as exx:
                config['openid_sql'] = exx
                log.error("Failed to configure openid_sql: %r" % exx)

        first_run = False
        app_setup_done = config.get('app_setup_done', False)
        if app_setup_done is False:
            try:
                setup_app(config)
                config['app_setup_done'] = True
                first_run = True
            except Exception as exx:
                config['app_setup_done'] = False
                log.error("Failed to serve request: %r" % exx)
                raise exx

        # set the decryption device before loading linotp config,
        # so it contains the decrypted values as well
        glo = getGlobalObject()
        self.sep = glo.security_provider

        try:
            hsm = self.sep.getSecurityModule()
            self.hsm = hsm
            c.hsm = hsm
        except Exception as exx:
            log.exception('failed to assign hsm device: %r' % exx)
            raise exx

        l_config = getLinotpConfig()

        # initialize the elliptic curve secret + public key for the qrtoken
        secret_key = l_config.get('SecretKey.Partition.0', False)

        if not secret_key:
            init_key_partition(l_config, partition=0)

        resolver_setup_done = config.get('resolver_setup_done', False)
        if resolver_setup_done is False:
            try:
                cache_dir = config.get("app_conf", {}).get("cache_dir", None)
                setupResolvers(config=l_config, cache_dir=cache_dir)
                config['resolver_setup_done'] = True
            except Exception as exx:
                config['resolver_setup_done'] = False
                log.error("Failed to setup resolver: %r", exx)
                raise exx

        # TODO: verify merge dropped
        # initResolvers()

        # if we are in the setup cycle, we check for the linotpLicenseFile
        if first_run:
            if "linotpLicenseFile" in config and 'license' not in l_config:
                license_str = ''
                filename = config.get("linotpLicenseFile", '')
                try:
                    with open(filename) as f:
                        license_str = f.read()
                except IOError:
                    log.error("could not open licence file: %s", filename)

                if not license_str:
                    log.error("empty license file: %s", filename)
                else:
                    with request_context_safety():
                        request_context['translate'] = translate

                        import linotp.lib.support
                        res, msg = linotp.lib.support.setSupportLicense(
                            license_str)
                        if res is False:
                            log.error("failed to load license: %s: %s",
                                      license_str, msg)

                        else:
                            log.info("license successfully loaded")
            if 'provider.config_file' in config:
                from linotp.provider import load_provider_ini

                load_provider_ini(config['provider.config_file'])

        return
Пример #49
0
def loadProvider(provider_type, provider_name=None):
    """
    interface for the provider user like email token or sms token

    :param provider_type: 'email' or 'sms
    :param provider_name: the name of the provider configuration

    :return: the instantiated provider with already loaded configuration
    """
    provider_info = {}

    config = getLinotpConfig()
    default_provider_key = Default_Provider_Key[provider_type]

    #
    # if no provider is given, we try to lookup the default
    #
    if default_provider_key in config and not provider_name:
        provider_name = config[default_provider_key]

    #
    # if there is no provider_name or the provider is a legacy one
    # try to load it the legacy way
    #
    if not provider_name or provider_name == Legacy_Provider_Name:
        provider_info = get_legacy_provider(provider_type=provider_type)
        provider_name = Legacy_Provider_Name

    #
    # in case of no provider_info the provider is
    # either a new one or or a legacy converted one
    #
    if not provider_info:
        providers = getProvider(provider_type, provider_name=provider_name)
        provider_info = providers.get(provider_name)

    if not provider_info:
        raise Exception('Unable to load provider: %r' % provider_name)

    provider_info = provider_info.get(provider_name, provider_info)
    provider_class = provider_info.get('Class')

    try:
        provider_class_obi = _load_provider_class(provider_class)
        provider = provider_class_obi()
    except Exception as exc:
        log.exception("Failed to load provider: %r", exc)
        raise exc

    provider_config = {}
    config = provider_info['Config']

    #
    # backward compatibility hack: fix the handling of multiline config entries
    #
    lconfig = []
    lines = config.splitlines()
    for line in lines:
        line = line.strip('\\')
        if len(line) > 0:
            lconfig.append(line)

    config = " ".join(lconfig)

    try:
        provider_config = json.loads(config)
    except ValueError as exx:
        log.exception('Failed to load provider config %r', config)
        raise ValueError('Failed to load provider config:%r %r'
                         % (config, exx))

    provider.loadConfig(provider_config)

    return provider
Пример #50
0
    def create_context(self, request, environment):
        """
        create the request context for all controllers
        """

        linotp_config = getLinotpConfig()

        request_context['Config'] = linotp_config
        request_context['Policies'] = parse_policies(linotp_config)
        request_context['translate'] = translate
        request_context['CacheManager'] = environment['beaker.cache']
        request_context['Path'] = environment.get("PATH_INFO", "") or ""
        request_context['hsm'] = self.hsm

        request_params = {}

        try:
            request_params.update(request.params)
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r" % exx)

        request_context['Params'] = request_params

        initResolvers()

        client = None
        try:
            client = get_client(request=request)
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r" % exx)

        request_context['Client'] = client

        request_context['Audit'] = Audit
        request_context['audit'] = Audit.initialize(request, client=client)

        authUser = None
        try:
            authUser = getUserFromRequest(request)
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r" % exx)

        request_context['AuthUser'] = authUser
        request_context['UserLookup'] = {}

        requestUser = None
        try:
            requestUser = getUserFromParam(request_params)
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r" % exx)
        request_context['RequestUser'] = requestUser


        defaultRealm = ""
        try:
            defaultRealm = getDefaultRealm(linotp_config)
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r" % exx)

        request_context['defaultRealm'] = defaultRealm

        realms = None
        try:
            realms = getRealms()
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r" % exx)

        request_context['Realms'] = realms

        # ------------------------------------------------------------------ --

        # for the setup of encrypted data, we require the hsm is instatiated
        # and available in the request context

        if not self.secret_key:
            init_key_partition(linotp_config, partition=0)

        # ------------------------------------------------------------------ --

        # copy some system entries from pylons
        syskeys = {
                   "radius.nas_identifier": "LinOTP",
                   "radius.dictfile": "/etc/linotp2/dictionary"
        }

        sysconfig = {}
        for key, default in syskeys.items():
            sysconfig[key] = config.get(key, default)

        request_context['SystemConfig'] = sysconfig