Exemplo n.º 1
0
    def test_01_config(self):
        self.assertEqual(get_app_config(), current_app.config)
        self.assertEqual(get_app_config()["SUPERUSER_REALM"], ["adminrealm"])

        self.assertEqual(get_app_config_value("SUPERUSER_REALM"), ["adminrealm"])
        self.assertEqual(get_app_config_value("DOES_NOT_EXIST"), None)
        self.assertEqual(get_app_config_value("DOES_NOT_EXIST", 1337), 1337)
Exemplo n.º 2
0
    def test_01_config(self):
        self.assertEqual(get_app_config(), current_app.config)
        self.assertEqual(get_app_config()["SUPERUSER_REALM"], ["adminrealm"])

        self.assertEqual(get_app_config_value("SUPERUSER_REALM"), ["adminrealm"])
        self.assertEqual(get_app_config_value("DOES_NOT_EXIST"), None)
        self.assertEqual(get_app_config_value("DOES_NOT_EXIST", 1337), 1337)
Exemplo n.º 3
0
def get_privacyidea_node():
    """
    This returns the node name of the privacyIDEA node as found in the pi.cfg
    file in PI_NODE.
    If it does not exist, the PI_AUDIT_SERVERNAME is used.
    :return: the destinct node name
    """
    node_name = get_app_config_value("PI_NODE", get_app_config_value("PI_AUDIT_SERVERNAME", "localnode"))
    return node_name
Exemplo n.º 4
0
def get_privacyidea_node():
    """
    This returns the node name of the privacyIDEA node as found in the pi.cfg
    file in PI_NODE.
    If it does not exist, the PI_AUDIT_SERVERNAME is used.
    :return: the destinct node name
    """
    node_name = get_app_config_value("PI_NODE", get_app_config_value("PI_AUDIT_SERVERNAME", "localnode"))
    return node_name
Exemplo n.º 5
0
def pass_hash(password):
    """
    Hash password with crypt context
    :param password: The password to hash
    :type password: str
    :return: The hash string of the password
    """
    DEFAULT_HASH_ALGO_PARAMS.update(
        get_app_config_value("PI_HASH_ALGO_PARAMS", default={}))
    pass_ctx = CryptContext(
        get_app_config_value("PI_HASH_ALGO_LIST",
                             default=DEFAULT_HASH_ALGO_LIST),
        **DEFAULT_HASH_ALGO_PARAMS)
    pw_dig = pass_ctx.hash(password)
    return pw_dig
Exemplo n.º 6
0
def get_registry():
    """
    Return the ``EngineRegistry`` object associated with the current application.
    If there is no such object yet, create one and write it to the app-local store.
    This respects the ``PI_ENGINE_REGISTRY_CLASS`` config option.
    :return: an ``EngineRegistry`` object
    """
    # This function will be called concurrently by multiple threads.
    # This is no problem when we already have an engine registry object.
    # However, if there is no registry object yet, two threads may concurrently
    # decide to create a new one. But as ``setdefault`` is atomic, only the
    # first one will be the written to ``app_store['config']``. The latter
    # one will not be referenced and will be garbage-collected at some point.
    app_store = get_app_local_store()
    try:
        return app_store["engine_registry"]
    except KeyError:
        # create a new engine registry of the appropriate class
        registry_class_name = get_app_config_value("PI_ENGINE_REGISTRY_CLASS", DEFAULT_REGISTRY_CLASS_NAME)
        if registry_class_name not in ENGINE_REGISTRY_CLASSES:
            log.warning(u"Unknown engine registry class: {!r}".format(registry_class_name))
            registry_class_name = DEFAULT_REGISTRY_CLASS_NAME
        registry = ENGINE_REGISTRY_CLASSES[registry_class_name]()
        log.info(u"Created a new engine registry: {!r}".format(registry))
        return app_store.setdefault("engine_registry", registry)
Exemplo n.º 7
0
    def __init__(self, config=None):
        self.name = "sqlaudit"
        self.config = config or {}
        self.audit_data = {}
        self.sign_data = not self.config.get("PI_AUDIT_NO_SIGN")
        self.sign_object = None
        self.verify_old_sig = get_app_config_value('PI_CHECK_OLD_SIGNATURES')
        if self.sign_data:
            self.read_keys(self.config.get("PI_AUDIT_KEY_PUBLIC"),
                           self.config.get("PI_AUDIT_KEY_PRIVATE"))
            self.sign_object = Sign(self.private, self.public)

        # We can use "sqlaudit" as the key because the SQLAudit connection
        # string is fixed for a running privacyIDEA instance.
        # In other words, we will not run into any problems with changing connect strings.
        self.engine = get_engine(self.name, self._create_engine)
        # create a configured "Session" class. ``scoped_session`` is not
        # necessary because we do not share session objects among threads.
        # We use it anyway as a safety measure.
        Session = scoped_session(sessionmaker(bind=self.engine))
        self.session = Session()
        # Ensure that the connection gets returned to the pool when the request has
        # been handled. This may close an already-closed session, but this is not a problem.
        register_finalizer(self.session.close)
        self.session._model_changes = {}
Exemplo n.º 8
0
    def __init__(self, config=None):
        self.name = "sqlaudit"
        self.config = config or {}
        self.audit_data = {}
        self.sign_data = not self.config.get("PI_AUDIT_NO_SIGN")
        self.sign_object = None
        self.verify_old_sig = get_app_config_value('PI_CHECK_OLD_SIGNATURES')
        if self.sign_data:
            self.read_keys(self.config.get("PI_AUDIT_KEY_PUBLIC"),
                           self.config.get("PI_AUDIT_KEY_PRIVATE"))
            self.sign_object = Sign(self.private, self.public)

        # We can use "sqlaudit" as the key because the SQLAudit connection
        # string is fixed for a running privacyIDEA instance.
        # In other words, we will not run into any problems with changing connect strings.
        self.engine = get_engine(self.name, self._create_engine)
        # create a configured "Session" class. ``scoped_session`` is not
        # necessary because we do not share session objects among threads.
        # We use it anyway as a safety measure.
        Session = scoped_session(sessionmaker(bind=self.engine))
        self.session = Session()
        # Ensure that the connection gets returned to the pool when the request has
        # been handled. This may close an already-closed session, but this is not a problem.
        register_finalizer(self.session.close)
        self.session._model_changes = {}
Exemplo n.º 9
0
def get_registry():
    """
    Return the ``EngineRegistry`` object associated with the current application.
    If there is no such object yet, create one and write it to the app-local store.
    This respects the ``PI_ENGINE_REGISTRY_CLASS`` config option.
    :return: an ``EngineRegistry`` object
    """
    # This function will be called concurrently by multiple threads.
    # This is no problem when we already have an engine registry object.
    # However, if there is no registry object yet, two threads may concurrently
    # decide to create a new one. But as ``setdefault`` is atomic, only the
    # first one will be the written to ``app_store['config']``. The latter
    # one will not be referenced and will be garbage-collected at some point.
    app_store = get_app_local_store()
    try:
        return app_store["engine_registry"]
    except KeyError:
        # create a new engine registry of the appropriate class
        registry_class_name = get_app_config_value(
            "PI_ENGINE_REGISTRY_CLASS", DEFAULT_REGISTRY_CLASS_NAME)
        if registry_class_name not in ENGINE_REGISTRY_CLASSES:
            log.warning(u"Unknown engine registry class: {!r}".format(
                registry_class_name))
            registry_class_name = DEFAULT_REGISTRY_CLASS_NAME
        registry = ENGINE_REGISTRY_CLASSES[registry_class_name]()
        log.info(u"Created a new engine registry: {!r}".format(registry))
        return app_store.setdefault("engine_registry", registry)
Exemplo n.º 10
0
    def reload_from_db(self):
        """
        Read the timestamp from the database. If the timestamp is newer than
        the internal timestamp, then read the complete data
        :return:
        """
        check_reload_config = get_app_config_value("PI_CHECK_RELOAD_CONFIG", 0)
        if not self.timestamp or \
            self.timestamp + datetime.timedelta(seconds=check_reload_config) < datetime.datetime.now():
            db_ts = Config.query.filter_by(Key=PRIVACYIDEA_TIMESTAMP).first()
            if reload_db(self.timestamp, db_ts):
                self.config = {}
                self.resolver = {}
                self.realm = {}
                self.default_realm = None
                for sysconf in Config.query.all():
                    self.config[sysconf.Key] = {
                        "Value": sysconf.Value,
                        "Type": sysconf.Type,
                        "Description": sysconf.Description
                    }
                for resolver in Resolver.query.all():
                    resolverdef = {
                        "type": resolver.rtype,
                        "resolvername": resolver.name,
                        "censor_keys": []
                    }
                    data = {}
                    for rconf in resolver.config_list:
                        if rconf.Type == "password":
                            value = decryptPassword(rconf.Value,
                                                    convert_unicode=True)
                            resolverdef["censor_keys"].append(rconf.Key)
                        else:
                            value = rconf.Value
                        data[rconf.Key] = value
                    resolverdef["data"] = data
                    self.resolver[resolver.name] = resolverdef

                for realm in Realm.query.all():
                    if realm.default:
                        self.default_realm = realm.name
                    realmdef = {
                        "option": realm.option,
                        "default": realm.default,
                        "resolver": []
                    }
                    for x in realm.resolver_list:
                        realmdef["resolver"].append({
                            "priority": x.priority,
                            "name": x.resolver.name,
                            "type": x.resolver.rtype
                        })
                    self.realm[realm.name] = realmdef

            self.timestamp = datetime.datetime.now()
Exemplo n.º 11
0
def get_privacyidea_nodes():
    """
    This returns the list of the nodes, including the own local node name
    :return: list of nodes
    """
    own_node_name = get_privacyidea_node()
    nodes = get_app_config_value("PI_NODES", [])[:]
    if own_node_name not in nodes:
        nodes.append(own_node_name)
    return nodes
Exemplo n.º 12
0
def get_privacyidea_nodes():
    """
    This returns the list of the nodes, including the own local node name
    :return: list of nodes
    """
    own_node_name = get_privacyidea_node()
    nodes = get_app_config_value("PI_NODES", [])[:]
    if own_node_name not in nodes:
        nodes.append(own_node_name)
    return nodes
Exemplo n.º 13
0
    def __init__(self, script_directory=None):
        if not script_directory:
            try:
                self.script_directory = get_app_config_value("PI_SCRIPT_HANDLER_DIRECTORY",
                                                       "/etc/privacyidea/scripts")
            except RuntimeError as e:
                # In case of the tests we are outside of the application context
                self.script_directory = "tests/testdata/scripts"

        else:
            self.script_directory = script_directory
Exemplo n.º 14
0
    def __init__(self, script_directory=None):
        if not script_directory:
            try:
                self.script_directory = get_app_config_value("PI_SCRIPT_HANDLER_DIRECTORY",
                                                       "/etc/privacyidea/scripts")
            except RuntimeError as e:
                # In case of the tests we are outside of the application context
                self.script_directory = "tests/testdata/scripts"

        else:
            self.script_directory = script_directory
Exemplo n.º 15
0
def hash_with_pepper(password, rounds=10023, salt_size=10):
    """
    Hash function to hash with salt and pepper. The pepper is read from
    "PI_PEPPER" from pi.cfg.

    Is used with admins and passwordReset

    :return: Hash string
    """
    key = get_app_config_value("PI_PEPPER", "missing")
    pw_dig = passlib.hash.pbkdf2_sha512.encrypt(key + password, rounds=rounds,
                                                salt_size=salt_size)
    return pw_dig
Exemplo n.º 16
0
def hash_with_pepper(password, rounds=10023, salt_size=10):
    """
    Hash function to hash with salt and pepper. The pepper is read from
    "PI_PEPPER" from pi.cfg.

    Is used with admins and passwordReset

    :return: Hash string
    """
    key = get_app_config_value("PI_PEPPER", "missing")
    pw_dig = passlib.hash.pbkdf2_sha512.encrypt(key + password,
                                                rounds=rounds,
                                                salt_size=salt_size)
    return pw_dig
Exemplo n.º 17
0
def hash_with_pepper(password):
    """
    Hash function to hash with salt and pepper. The pepper is read from
    "PI_PEPPER" from pi.cfg.

    Is used with admins and passwordReset

    :param password: the password to hash
    :type password: str
    :return: hashed password string
    :rtype: str
    """
    key = get_app_config_value("PI_PEPPER", "missing")
    return pass_hash(key + password)
Exemplo n.º 18
0
def verify_pass_hash(password, hvalue):
    """
    Verify the hashed password value
    :param password: The plaintext password to verify
    :type password: str
    :param hvalue: The hashed password
    :type hvalue: str
    :return: True if the password matches
    :rtype: bool
    """
    pass_ctx = CryptContext(
        get_app_config_value("PI_HASH_ALGO_LIST",
                             default=DEFAULT_HASH_ALGO_LIST))
    return pass_ctx.verify(password, hvalue)
Exemplo n.º 19
0
    def reload_from_db(self):
        """
        Read the timestamp from the database. If the timestamp is newer than
        the internal timestamp, then read the complete data
        :return:
        """
        check_reload_config = get_app_config_value("PI_CHECK_RELOAD_CONFIG", 0)
        if not self.timestamp or \
            self.timestamp + datetime.timedelta(seconds=check_reload_config) < datetime.datetime.now():
            db_ts = Config.query.filter_by(Key=PRIVACYIDEA_TIMESTAMP).first()
            if reload_db(self.timestamp, db_ts):
                self.config = {}
                self.resolver = {}
                self.realm = {}
                self.default_realm = None
                for sysconf in Config.query.all():
                    self.config[sysconf.Key] = {
                        "Value": sysconf.Value,
                        "Type": sysconf.Type,
                        "Description": sysconf.Description}
                for resolver in Resolver.query.all():
                    resolverdef = {"type": resolver.rtype,
                                   "resolvername": resolver.name,
                                   "censor_keys": []}
                    data = {}
                    for rconf in resolver.config_list:
                        if rconf.Type == "password":
                            value = decryptPassword(rconf.Value)
                            resolverdef["censor_keys"].append(rconf.Key)
                        else:
                            value = rconf.Value
                        data[rconf.Key] = value
                    resolverdef["data"] = data
                    self.resolver[resolver.name] = resolverdef

                for realm in Realm.query.all():
                    if realm.default:
                        self.default_realm = realm.name
                    realmdef = {"option": realm.option,
                                "default": realm.default,
                                "resolver": []}
                    for x in realm.resolver_list:
                        realmdef["resolver"].append({"priority": x.priority,
                                                     "name": x.resolver.name,
                                                     "type": x.resolver.rtype})
                    self.realm[realm.name] = realmdef

            self.timestamp = datetime.datetime.now()
Exemplo n.º 20
0
def verify_with_pepper(passwordhash, password):
    """
    verify the password hash with the given password and pepper

    :param passwordhash: the passwordhash
    :type passwordhash: str
    :param password: the password to verify
    :type password: str
    :return: whether the password matches the hash
    :rtype: bool
    """
    # get the password pepper
    password = password or ""
    key = get_app_config_value("PI_PEPPER", "missing")
    success = passlib.hash.pbkdf2_sha512.verify(key + password, passwordhash)
    return success
Exemplo n.º 21
0
def check_signature(subscription):
    """
    This function checks the signature of a subscription. If the signature
    checking fails, a SignatureError / Exception is raised.

    :param subscription: The dict of the subscription
    :return: True
    """
    vendor = subscription.get("by_name").split()[0]
    enckey = get_app_config_value("PI_ENCFILE", "/etc/privacyidea/enckey")
    dirname = os.path.dirname(enckey)
    # In dirname we are searching for <vendor>.pem
    filename = u"{0!s}/{1!s}.pem".format(dirname, vendor)
    with open(filename, "r") as file_handle:
        public = file_handle.read()

    r = False
    try:
        # remove the minutes 00:00:00
        subscription["date_from"] = subscription.get("date_from").strftime(
            SUBSCRIPTION_DATE_FORMAT)
        subscription["date_till"] = subscription.get("date_till").strftime(
            SUBSCRIPTION_DATE_FORMAT)
        sign_string = SIGN_FORMAT.format(**subscription)
        RSAkey = RSA.importKey(public)
        hashvalue = SHA256.new(sign_string.encode("utf-8")).digest()
        signature = long(subscription.get("signature") or "100")
        r = RSAkey.verify(hashvalue, (signature, ))
        subscription["date_from"] = datetime.datetime.strptime(
            subscription.get("date_from"), SUBSCRIPTION_DATE_FORMAT)
        subscription["date_till"] = datetime.datetime.strptime(
            subscription.get("date_till"), SUBSCRIPTION_DATE_FORMAT)
    except Exception as exx:
        log.debug(traceback.format_exc())
        raise SubscriptionError(
            "Verifying the signature of your subscription "
            "failed.",
            application=subscription.get("application"))

    if not r:
        raise SubscriptionError(
            "Signature of your subscription does not "
            "match.",
            application=subscription.get("application"))

    return r
Exemplo n.º 22
0
def check_signature(subscription):
    """
    This function checks the signature of a subscription. If the signature
    checking fails, a SignatureError / Exception is raised.

    :param subscription: The dict of the subscription
    :return: True
    """
    vendor = subscription.get("by_name").split()[0]
    enckey = get_app_config_value("PI_ENCFILE", "/etc/privacyidea/enckey")
    dirname = os.path.dirname(enckey)
    # In dirname we are searching for <vendor>.pem
    filename = "{0!s}/{1!s}.pem".format(dirname, vendor)
    with open(filename, "r") as file_handle:
        public = file_handle.read()

    r = False
    try:
        # remove the minutes 00:00:00
        subscription["date_from"] = subscription.get("date_from").strftime(SUBSCRIPTION_DATE_FORMAT)
        subscription["date_till"] = subscription.get("date_till").strftime(SUBSCRIPTION_DATE_FORMAT)
        sign_string = SIGN_FORMAT.format(**subscription)
        RSAkey = RSA.importKey(public)
        hashvalue = SHA256.new(sign_string).digest()
        signature = long(subscription.get("signature") or "100")
        r = RSAkey.verify(hashvalue, (signature,))
        subscription["date_from"] = datetime.datetime.strptime(
            subscription.get("date_from"),
            SUBSCRIPTION_DATE_FORMAT)
        subscription["date_till"] = datetime.datetime.strptime(
            subscription.get("date_till"),
            SUBSCRIPTION_DATE_FORMAT)
    except Exception as exx:
        log.debug(traceback.format_exc())
        raise SubscriptionError("Verifying the signature of your subscription "
                                "failed.",
                                application=subscription.get("application"))

    if not r:
        raise SubscriptionError("Signature of your subscription does not "
                                "match.",
                                application=subscription.get("application"))

    return r
Exemplo n.º 23
0
    def __init__(self,
                 db_smsprovider_object=None,
                 smsgateway=None,
                 directory=None):
        """
        Create a new SMS Provider object fom a DB SMS provider object

        :param db_smsprovider_object: The database object
        :param smsgateway: The SMS gateway object from the database table
            SMS gateway. The options can be accessed via
            self.smsgateway.option_dict
        :param directory: The directory where the SMS sending scripts are located.
        :type directory: str
        :return: An SMS provider object
        """
        self.config = db_smsprovider_object or {}
        self.smsgateway = smsgateway
        self.script_directory = directory or get_app_config_value(
            "PI_SCRIPT_SMSPROVIDER_DIRECTORY", "/etc/privacyidea/scripts")
Exemplo n.º 24
0
def check_signature(subscription):
    """
    This function checks the signature of a subscription. If the signature
    checking fails, a SignatureError / Exception is raised.

    :param subscription: The dict of the subscription
    :return: True
    """
    vendor = subscription.get("by_name").split()[0]
    enckey = get_app_config_value("PI_ENCFILE", "/etc/privacyidea/enckey")
    dirname = os.path.dirname(enckey)
    # In dirname we are searching for <vendor>.pem
    filename = u"{0!s}/{1!s}.pem".format(dirname, vendor)

    try:
        # remove the minutes 00:00:00
        subscription["date_from"] = subscription.get("date_from").strftime(SUBSCRIPTION_DATE_FORMAT)
        subscription["date_till"] = subscription.get("date_till").strftime(SUBSCRIPTION_DATE_FORMAT)
        sign_string = SIGN_FORMAT.format(**subscription)
        with open(filename, 'rb') as key_file:
            sign_obj = Sign(private_key=None, public_key=key_file.read())

        signature = subscription.get('signature', '100')
        r = sign_obj.verify(sign_string, signature, verify_old_sigs=True)
        subscription["date_from"] = datetime.datetime.strptime(
            subscription.get("date_from"),
            SUBSCRIPTION_DATE_FORMAT)
        subscription["date_till"] = datetime.datetime.strptime(
            subscription.get("date_till"),
            SUBSCRIPTION_DATE_FORMAT)
    except Exception as _e:
        log.debug(traceback.format_exc())
        raise SubscriptionError("Verifying the signature of your subscription "
                                "failed.",
                                application=subscription.get("application"))

    if not r:
        raise SubscriptionError("Signature of your subscription does not "
                                "match.",
                                application=subscription.get("application"))

    return r
Exemplo n.º 25
0
def check_signature(subscription):
    """
    This function checks the signature of a subscription. If the signature
    checking fails, a SignatureError / Exception is raised.

    :param subscription: The dict of the subscription
    :return: True
    """
    vendor = subscription.get("by_name").split()[0]
    enckey = get_app_config_value("PI_ENCFILE", "/etc/privacyidea/enckey")
    dirname = os.path.dirname(enckey)
    # In dirname we are searching for <vendor>.pem
    filename = u"{0!s}/{1!s}.pem".format(dirname, vendor)

    try:
        # remove the minutes 00:00:00
        subscription["date_from"] = subscription.get("date_from").strftime(SUBSCRIPTION_DATE_FORMAT)
        subscription["date_till"] = subscription.get("date_till").strftime(SUBSCRIPTION_DATE_FORMAT)
        sign_string = SIGN_FORMAT.format(**subscription)
        with open(filename, 'rb') as key_file:
            sign_obj = Sign(private_key=None, public_key=key_file.read())

        signature = subscription.get('signature', '100')
        r = sign_obj.verify(sign_string, signature, verify_old_sigs=True)
        subscription["date_from"] = datetime.datetime.strptime(
            subscription.get("date_from"),
            SUBSCRIPTION_DATE_FORMAT)
        subscription["date_till"] = datetime.datetime.strptime(
            subscription.get("date_till"),
            SUBSCRIPTION_DATE_FORMAT)
    except Exception as _e:
        log.debug(traceback.format_exc())
        raise SubscriptionError("Verifying the signature of your subscription "
                                "failed.",
                                application=subscription.get("application"))

    if not r:
        raise SubscriptionError("Signature of your subscription does not "
                                "match.",
                                application=subscription.get("application"))

    return r
Exemplo n.º 26
0
def get_token_list():
    """
    get the list of the tokens
    :return: list of token names from the config file
    """
    module_list = set()

    module_list.add("privacyidea.lib.tokens.daplugtoken")
    module_list.add("privacyidea.lib.tokens.hotptoken")
    module_list.add("privacyidea.lib.tokens.motptoken")
    module_list.add("privacyidea.lib.tokens.passwordtoken")
    module_list.add("privacyidea.lib.tokens.remotetoken")
    module_list.add("privacyidea.lib.tokens.spasstoken")
    module_list.add("privacyidea.lib.tokens.sshkeytoken")
    module_list.add("privacyidea.lib.tokens.totptoken")
    module_list.add("privacyidea.lib.tokens.yubicotoken")
    module_list.add("privacyidea.lib.tokens.yubikeytoken")
    module_list.add("privacyidea.lib.tokens.radiustoken")
    module_list.add("privacyidea.lib.tokens.smstoken")
    module_list.add("privacyidea.lib.tokens.emailtoken")
    module_list.add("privacyidea.lib.tokens.registrationtoken")
    module_list.add("privacyidea.lib.tokens.certificatetoken")
    module_list.add("privacyidea.lib.tokens.foureyestoken")
    module_list.add("privacyidea.lib.tokens.tiqrtoken")
    module_list.add("privacyidea.lib.tokens.ocratoken")
    module_list.add("privacyidea.lib.tokens.u2ftoken")
    module_list.add("privacyidea.lib.tokens.papertoken")
    module_list.add("privacyidea.lib.tokens.questionnairetoken")
    module_list.add("privacyidea.lib.tokens.vascotoken")
    module_list.add("privacyidea.lib.tokens.tantoken")
    module_list.add("privacyidea.lib.tokens.pushtoken")
    module_list.add("privacyidea.lib.tokens.indexedsecrettoken")
    module_list.add("privacyidea.lib.tokens.webauthntoken")

    # Dynamic token modules
    dynamic_token_modules = get_app_config_value("PI_TOKEN_MODULES")
    if dynamic_token_modules:
        # In the pi.cfg you can specify a list or set of 3rd party token modules like
        #    PI_TOKEN_MODULES = [ "myproj.tokens.tok1", "myproj.tokens.tok2" ]
        module_list.update(to_list(dynamic_token_modules))

    return module_list
Exemplo n.º 27
0
    def actions(cls):
        """
        This method returns a dictionary of allowed actions and possible
        options in this handler module.

        :return: dict with actions
        """
        smtpserver_objs = get_smtpservers()
        smsgateway_dicts = get_smsgateway()
        smsgateways = [sms.identifier for sms in smsgateway_dicts]
        smtpservers = [s.config.identifier for s in smtpserver_objs]
        actions = {"sendmail": {"emailconfig":
                                     {"type": "str",
                                      "required": True,
                                      "description": _("Send notification "
                                                       "email via this "
                                                       "email server."),
                                      "value": smtpservers},
                                "mimetype": {"type": "str",
                                             "description": _("Either send "
                                                              "email as plain text or HTML."),
                                             "value": ["plain", "html"]},
                                "subject": {"type": "str",
                                            "required": False,
                                            "description": _("The subject of "
                                                             "the mail that "
                                                             "is sent.")},
                                "reply_to": {"type": "str",
                                             "required": False,
                                             "description": _("The Reply-To "
                                                              "header in the "
                                                              "sent email.")},
                                "body": {"type": "text",
                                         "required": False,
                                         "description": _("The body of the "
                                                          "mail that is "
                                                          "sent.")},
                                "To": {"type": "str",
                                       "required": True,
                                       "description": _("Send notification to "
                                                        "this user."),
                                       "value": [
                                           NOTIFY_TYPE.TOKENOWNER,
                                           NOTIFY_TYPE.LOGGED_IN_USER,
                                           NOTIFY_TYPE.INTERNAL_ADMIN,
                                           NOTIFY_TYPE.ADMIN_REALM,
                                           NOTIFY_TYPE.EMAIL]},
                                "To "+NOTIFY_TYPE.ADMIN_REALM: {
                                    "type": "str",
                                    "value": get_app_config_value("SUPERUSER_REALM", []),
                                    "visibleIf": "To",
                                    "visibleValue": NOTIFY_TYPE.ADMIN_REALM},
                                "To "+NOTIFY_TYPE.INTERNAL_ADMIN: {
                                    "type": "str",
                                    "value": [a.username for a in
                                              get_db_admins()],
                                    "visibleIf": "To",
                                    "visibleValue":
                                         NOTIFY_TYPE.INTERNAL_ADMIN},
                                "To "+NOTIFY_TYPE.EMAIL: {
                                    "type": "str",
                                    "description": _("Any email address, to "
                                                     "which the notification "
                                                     "should be sent."),
                                    "visibleIf": "To",
                                    "visibleValue": NOTIFY_TYPE.EMAIL}
                                },
                   "sendsms": {"smsconfig":
                                   {"type": "str",
                                    "required": True,
                                    "description": _("Send the user "
                                                     "notification via a "
                                                     "predefined SMS "
                                                     "gateway."),
                                    "value": smsgateways},
                               "body": {"type": "text",
                                        "required": False,
                                        "description": _("The text of the "
                                                         "SMS.")},
                               "To": {"type": "str",
                                      "required": True,
                                      "description": _("Send notification to "
                                                       "this user."),
                                      "value": [NOTIFY_TYPE.TOKENOWNER]}
                               }
                   }
        return actions
Exemplo n.º 28
0
 def _reload_from_db(self):
     """
     Read the timestamp from the database. If the timestamp is newer than
     the internal timestamp, then read the complete data
     :return:
     """
     check_reload_config = get_app_config_value("PI_CHECK_RELOAD_CONFIG", 0)
     if not self.timestamp or \
         self.timestamp + datetime.timedelta(seconds=check_reload_config) < datetime.datetime.now():
         db_ts = Config.query.filter_by(Key=PRIVACYIDEA_TIMESTAMP).first()
         if reload_db(self.timestamp, db_ts):
             log.debug(u"Reloading shared config from database")
             config = {}
             resolverconfig = {}
             realmconfig = {}
             default_realm = None
             policies = []
             events = []
             # Load system configuration
             for sysconf in Config.query.all():
                 config[sysconf.Key] = {
                     "Value": sysconf.Value,
                     "Type": sysconf.Type,
                     "Description": sysconf.Description
                 }
             # Load resolver configuration
             for resolver in Resolver.query.all():
                 resolverdef = {
                     "type": resolver.rtype,
                     "resolvername": resolver.name,
                     "censor_keys": []
                 }
                 data = {}
                 for rconf in resolver.config_list:
                     if rconf.Type == "password":
                         value = decryptPassword(rconf.Value)
                         resolverdef["censor_keys"].append(rconf.Key)
                     else:
                         value = rconf.Value
                     data[rconf.Key] = value
                 resolverdef["data"] = data
                 resolverconfig[resolver.name] = resolverdef
             # Load realm configuration
             for realm in Realm.query.all():
                 if realm.default:
                     default_realm = realm.name
                 realmdef = {
                     "id": realm.id,
                     "option": realm.option,
                     "default": realm.default,
                     "resolver": []
                 }
                 for x in realm.resolver_list:
                     realmdef["resolver"].append({
                         "priority": x.priority,
                         "name": x.resolver.name,
                         "type": x.resolver.rtype
                     })
                 realmconfig[realm.name] = realmdef
             # Load all policies
             for pol in Policy.query.all():
                 policies.append(pol.get())
             # Load all events
             for event in EventHandler.query.order_by(
                     EventHandler.ordering):
                 events.append(event.get())
             # Finally, set the current timestamp
             timestamp = datetime.datetime.now()
             with self._config_lock:
                 self.config = config
                 self.resolver = resolverconfig
                 self.realm = realmconfig
                 self.default_realm = default_realm
                 self.policies = policies
                 self.events = events
                 self.timestamp = timestamp
Exemplo n.º 29
0
    def test_email(config, recipient, subject, body, sender=None,
                   reply_to=None, mimetype="plain"):
        """
        Sends an email via the configuration.

        :param config: The email configuration
        :type config: dict
        :param recipient: The recipients of the email
        :type recipient: list
        :param subject: The subject of the email
        :type subject: basestring
        :param body: The body of the email
        :type body: basestring
        :param sender: An optional sender of the email. The SMTP database
            object has its own sender. This parameter can be used to override
            the internal sender.
        :type sender: basestring
        :param reply_to: The Reply-To parameter
        :type reply_to: basestring
        :param mimetype: The type of the email to send. Can by plain or html
        :return: True or False
        """
        if type(recipient) != list:
            recipient = [recipient]
        mail_from = sender or config['sender']
        reply_to = reply_to or mail_from
        msg = MIMEText(body.encode('utf-8'), mimetype, 'utf-8')
        msg['Subject'] = subject
        msg['From'] = mail_from
        msg['To'] = ",".join(recipient)
        msg['Date'] = strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime())
        msg['Reply-To'] = reply_to

        mail = smtplib.SMTP(config['server'], port=int(config['port']),
                            timeout=config.get('timeout', TIMEOUT))
        log.debug(u"submitting message to {0!s}".format(msg["To"]))
        log.debug("Saying EHLO to mailserver {0!s}".format(config['server']))
        r = mail.ehlo()
        log.debug("mailserver responded with {0!s}".format(r))
        # Start TLS if required
        if config.get('tls', False):
            log.debug("Trying to STARTTLS: {0!s}".format(config['tls']))
            mail.starttls()
        # Authenticate, if a username is given.
        if config.get('username', ''):
            log.debug("Doing authentication with {0!s}".format(config['username']))
            password = decryptPassword(config['password'])
            if password == FAILED_TO_DECRYPT_PASSWORD:
                password = config['password']
            # Under Python 2, we pass passwords as bytestrings to get CRAM-MD5 to work.
            # We add a safeguard config option to disable the conversion.
            # Under Python 3, we pass passwords as unicode.
            if six.PY2 and get_app_config_value("PI_SMTP_PASSWORD_AS_BYTES", True):
                password = to_bytes(password)
            mail.login(config['username'], password)
        r = mail.sendmail(mail_from, recipient, msg.as_string())
        log.info("Mail sent: {0!s}".format(r))
        # r is a dictionary like {"*****@*****.**": (200, 'OK')}
        # we change this to True or False
        success = True
        for one_recipient in recipient:
            res_id, res_text = r.get(one_recipient, (200, "OK"))
            if res_id != 200 and res_text != "OK":
                success = False
                log.error("Failed to send email to {0!r}: {1!r}, {2!r}".format(one_recipient,
                                                                  res_id,
                                                                  res_text))
        mail.quit()
        log.debug("I am done sending your email.")
        return success
Exemplo n.º 30
0
def verify_with_pepper(passwordhash, password):
    # get the password pepper
    password = password or ""
    key = get_app_config_value("PI_PEPPER", "missing")
    success = passlib.hash.pbkdf2_sha512.verify(key + password, passwordhash)
    return success
Exemplo n.º 31
0
    def test_email(config,
                   recipient,
                   subject,
                   body,
                   sender=None,
                   reply_to=None,
                   mimetype="plain"):
        """
        Sends an email via the configuration.

        :param config: The email configuration
        :type config: dict
        :param recipient: The recipients of the email
        :type recipient: list
        :param subject: The subject of the email
        :type subject: basestring
        :param body: The body of the email
        :type body: basestring
        :param sender: An optional sender of the email. The SMTP database
            object has its own sender. This parameter can be used to override
            the internal sender.
        :type sender: basestring
        :param reply_to: The Reply-To parameter
        :type reply_to: basestring
        :param mimetype: The type of the email to send. Can by plain or html
        :return: True or False
        """
        if type(recipient) != list:
            recipient = [recipient]
        mail_from = sender or config['sender']
        reply_to = reply_to or mail_from
        msg = MIMEText(body.encode('utf-8'), mimetype, 'utf-8')
        msg['Subject'] = subject
        msg['From'] = mail_from
        msg['To'] = ",".join(recipient)
        msg['Date'] = strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime())
        msg['Reply-To'] = reply_to

        mail = smtplib.SMTP(config['server'],
                            port=int(config['port']),
                            timeout=config.get('timeout', TIMEOUT))
        log.debug(u"submitting message to {0!s}".format(msg["To"]))
        log.debug("Saying EHLO to mailserver {0!s}".format(config['server']))
        r = mail.ehlo()
        log.debug("mailserver responded with {0!s}".format(r))
        # Start TLS if required
        if config.get('tls', False):
            log.debug("Trying to STARTTLS: {0!s}".format(config['tls']))
            mail.starttls()
        # Authenticate, if a username is given.
        if config.get('username', ''):
            log.debug("Doing authentication with {0!s}".format(
                config['username']))
            password = decryptPassword(config['password'])
            if password == FAILED_TO_DECRYPT_PASSWORD:
                password = config['password']
            # Under Python 2, we pass passwords as bytestrings to get CRAM-MD5 to work.
            # We add a safeguard config option to disable the conversion.
            # Under Python 3, we pass passwords as unicode.
            if six.PY2 and get_app_config_value("PI_SMTP_PASSWORD_AS_BYTES",
                                                True):
                password = to_bytes(password)
            mail.login(config['username'], password)
        r = mail.sendmail(mail_from, recipient, msg.as_string())
        log.info("Mail sent: {0!s}".format(r))
        # r is a dictionary like {"*****@*****.**": (200, 'OK')}
        # we change this to True or False
        success = True
        for one_recipient in recipient:
            res_id, res_text = r.get(one_recipient, (200, "OK"))
            if res_id != 200 and res_text != "OK":
                success = False
                log.error("Failed to send email to {0!r}: {1!r}, {2!r}".format(
                    one_recipient, res_id, res_text))
        mail.quit()
        log.debug("I am done sending your email.")
        return success
Exemplo n.º 32
0
def verify_with_pepper(passwordhash, password):
    # get the password pepper
    password = password or ""
    key = get_app_config_value("PI_PEPPER", "missing")
    success = passlib.hash.pbkdf2_sha512.verify(key + password, passwordhash)
    return success
Exemplo n.º 33
0
from ctypes import c_ulong
from ctypes import c_char
from ctypes import c_byte

from privacyidea.lib.framework import get_app_config_value
from privacyidea.lib.error import ParameterError

__all__ = ["vasco_otp_check"]


log = logging.getLogger(__name__)

vasco_dll = None

try:
    vasco_library_path = get_app_config_value("PI_VASCO_LIBRARY")
    if vasco_library_path is not None: # pragma: no cover
        log.info(u"Loading VASCO library from {!s} ...".format(vasco_library_path))
        vasco_dll = CDLL(vasco_library_path)
    else:
        log.info(u"PI_VASCO_LIBRARY option is not set, functionality disabled")
except Exception as exx:
    log.warning(u"Could not load VASCO library: {!r}".format(exx))

def check_vasco(fn):
    '''
    This is a decorator:
    checks if vasco dll is defined,
    it then runs the function otherwise raises RuntimeError

    :param fn: function - the to be called function
Exemplo n.º 34
0
    def do(self, action, options=None):
        """
        This method executes the defined action in the given event.

        :param action:
        :param options: Contains the flask parameters g, request, response
            and the handler_def configuration
        :type options: dict
        :return:
        """
        ret = True
        g = options.get("g")
        request = options.get("request")
        response = options.get("response")
        content = self._get_response_content(response)
        handler_def = options.get("handler_def")
        handler_options = handler_def.get("options", {})
        notify_type = handler_options.get("To", NOTIFY_TYPE.TOKENOWNER)
        reply_to_type = handler_options.get("reply_to")
        try:
            logged_in_user = g.logged_in_user
        except Exception:
            logged_in_user = {}

        tokenowner = self._get_tokenowner(request)
        log.debug(u"Executing event for action {0!r}, user {1!r}, "
                  u"logged_in_user {2!r}".format(action, tokenowner,
                                                 logged_in_user))

        # Determine recipient
        recipient = None
        reply_to = None

        if reply_to_type == NOTIFY_TYPE.NO_REPLY_TO:
            reply_to = ""

        elif reply_to_type == NOTIFY_TYPE.TOKENOWNER and not tokenowner.is_empty(
        ):
            reply_to = tokenowner.info.get("email")

        elif reply_to_type == NOTIFY_TYPE.INTERNAL_ADMIN:
            username = handler_options.get("reply_to " +
                                           NOTIFY_TYPE.INTERNAL_ADMIN)
            internal_admin = get_db_admin(username)
            reply_to = internal_admin.email if internal_admin else ""

        elif reply_to_type == NOTIFY_TYPE.ADMIN_REALM:
            # Adds all email addresses from a specific admin realm to the reply-to-header
            admin_realm = handler_options.get("reply_to " +
                                              NOTIFY_TYPE.ADMIN_REALM)
            attr = is_attribute_at_all()
            ulist = get_user_list({"realm": admin_realm},
                                  custom_attributes=attr)
            # create a list of all user-emails, if the user has an email
            emails = [u.get("email") for u in ulist if u.get("email")]
            reply_to = ",".join(emails)

        elif reply_to_type == NOTIFY_TYPE.LOGGED_IN_USER:
            # Add email address from the logged in user into the reply-to header
            if logged_in_user.get(
                    "username") and not logged_in_user.get("realm"):
                # internal admins have no realm
                internal_admin = get_db_admin(logged_in_user.get("username"))
                if internal_admin:
                    reply_to = internal_admin.email if internal_admin else ""

            else:
                # Try to find the user in the specified realm
                user_obj = User(logged_in_user.get("username"),
                                logged_in_user.get("realm"))
                if user_obj:
                    reply_to = user_obj.info.get("email") if user_obj else ""

        elif reply_to_type == NOTIFY_TYPE.EMAIL:
            email = handler_options.get("reply_to " + NOTIFY_TYPE.EMAIL,
                                        "").split(",")
            reply_to = email[0]

        else:
            log.warning("Was not able to determine the email for the reply-to "
                        "header: {0!s}".format(handler_def))

        if notify_type == NOTIFY_TYPE.TOKENOWNER and not tokenowner.is_empty():
            recipient = {
                "givenname": tokenowner.info.get("givenname"),
                "surname": tokenowner.info.get("surname"),
                "username": tokenowner.login,
                "userrealm": tokenowner.realm,
                "email": tokenowner.info.get("email"),
                "mobile": tokenowner.info.get("mobile")
            }
        elif notify_type == NOTIFY_TYPE.INTERNAL_ADMIN:
            username = handler_options.get("To " + NOTIFY_TYPE.INTERNAL_ADMIN)
            internal_admin = get_db_admin(username)
            recipient = {
                "givenname": username,
                "email": internal_admin.email if internal_admin else ""
            }
        elif notify_type == NOTIFY_TYPE.ADMIN_REALM:
            # Send emails to all the users in the specified admin realm
            admin_realm = handler_options.get("To " + NOTIFY_TYPE.ADMIN_REALM)
            attr = is_attribute_at_all()
            ulist = get_user_list({"realm": admin_realm},
                                  custom_attributes=attr)
            # create a list of all user-emails, if the user has an email
            emails = [u.get("email") for u in ulist if u.get("email")]
            recipient = {
                "givenname": "admin of realm {0!s}".format(admin_realm),
                "email": emails
            }
        elif notify_type == NOTIFY_TYPE.LOGGED_IN_USER:
            # Send notification to the logged in user
            if logged_in_user.get(
                    "username") and not logged_in_user.get("realm"):
                # internal admins have no realm
                internal_admin = get_db_admin(logged_in_user.get("username"))
                if internal_admin:
                    recipient = {
                        "givenname": logged_in_user.get("username"),
                        "email": internal_admin.email if internal_admin else ""
                    }
            else:
                # Try to find the user in the specified realm
                user_obj = User(logged_in_user.get("username"),
                                logged_in_user.get("realm"))
                if user_obj:
                    recipient = {
                        "givenname": user_obj.info.get("givenname"),
                        "surname": user_obj.info.get("surname"),
                        "email": user_obj.info.get("email"),
                        "mobile": user_obj.info.get("mobile")
                    }

        elif notify_type == NOTIFY_TYPE.EMAIL:
            email = handler_options.get("To " + NOTIFY_TYPE.EMAIL,
                                        "").split(",")
            recipient = {"email": email}
        else:
            log.warning("Was not able to determine the recipient for the user "
                        "notification: {0!s}".format(handler_def))

        if recipient or action.lower() == "savefile":
            # In case of "savefile" we do not need a recipient
            # Collect all data
            body = handler_options.get("body") or DEFAULT_BODY
            if body.startswith("file:"):  # pragma no cover
                # We read the template from the file.
                filename = body[5:]
                try:
                    with open(filename, "r", encoding="utf-8") as f:
                        body = f.read()
                except Exception as e:
                    log.warning(
                        u"Failed to read email template from file {0!r}: {1!r}"
                        .format(filename, e))
                    log.debug(u"{0!s}".format(traceback.format_exc()))

            subject = handler_options.get("subject") or \
                      "An action was performed on your token."
            serial = request.all_data.get("serial") or \
                     content.get("detail", {}).get("serial") or \
                     g.audit_object.audit_data.get("serial")
            registrationcode = content.get("detail",
                                           {}).get("registrationcode")
            pin = content.get("detail", {}).get("pin")
            googleurl_value = content.get("detail", {}).get("googleurl",
                                                            {}).get("value")
            googleurl_img = content.get("detail", {}).get("googleurl",
                                                          {}).get("img")
            tokentype = None
            if serial:
                tokens = get_tokens(serial=serial)
                if tokens:
                    tokentype = tokens[0].get_tokentype()
            else:
                token_objects = get_tokens(user=tokenowner)
                serial = ','.join([tok.get_serial() for tok in token_objects])

            tags = create_tag_dict(
                logged_in_user=logged_in_user,
                request=request,
                client_ip=g.client_ip,
                pin=pin,
                googleurl_value=googleurl_value,
                recipient=recipient,
                tokenowner=tokenowner,
                serial=serial,
                tokentype=tokentype,
                registrationcode=registrationcode,
                escape_html=action.lower() == "sendmail"
                and handler_options.get("mimetype", "").lower() == "html")

            body = to_unicode(body).format(googleurl_img=googleurl_img, **tags)
            subject = subject.format(**tags)
            # Send notification
            if action.lower() == "sendmail":
                emailconfig = handler_options.get("emailconfig")
                mimetype = handler_options.get("mimetype", "plain")
                useremail = recipient.get("email")
                attach_qrcode = handler_options.get("attach_qrcode", False)

                if attach_qrcode and googleurl_img:
                    # get the image part of the googleurl
                    googleurl = urlopen(googleurl_img)
                    mail_body = MIMEMultipart('related')
                    mail_body.attach(MIMEText(body, mimetype))
                    mail_img = MIMEImage(googleurl.read())
                    mail_img.add_header('Content-ID', '<token_image>')
                    mail_img.add_header(
                        'Content-Disposition',
                        'inline; filename="{0!s}.png"'.format(serial))
                    mail_body.attach(mail_img)
                    body = mail_body
                try:
                    ret = send_email_identifier(emailconfig,
                                                recipient=useremail,
                                                subject=subject,
                                                body=body,
                                                reply_to=reply_to,
                                                mimetype=mimetype)
                except Exception as exx:
                    log.error("Failed to send email: {0!s}".format(exx))
                    ret = False
                if ret:
                    log.info("Sent a notification email to user {0}".format(
                        recipient))
                else:
                    log.warning("Failed to send a notification email to user "
                                "{0}".format(recipient))

            elif action.lower() == "savefile":
                spooldir = get_app_config_value(
                    "PI_NOTIFICATION_HANDLER_SPOOLDIRECTORY",
                    "/var/lib/privacyidea/notifications/")
                filename = handler_options.get("filename")
                random = get_alphanum_str(16)
                filename = filename.format(random=random,
                                           **tags).lstrip(os.path.sep)
                outfile = os.path.normpath(os.path.join(spooldir, filename))
                if not outfile.startswith(spooldir):
                    log.error(
                        u'Cannot write outside of spooldir {0!s}!'.format(
                            spooldir))
                else:
                    try:
                        with open(outfile, "w") as f:
                            f.write(body)
                    except Exception as err:
                        log.error(
                            u"Failed to write notification file: {0!s}".format(
                                err))

            elif action.lower() == "sendsms":
                smsconfig = handler_options.get("smsconfig")
                userphone = recipient.get("mobile")
                try:
                    ret = send_sms_identifier(smsconfig, userphone, body)
                except Exception as exx:
                    log.error("Failed to send sms: {0!s}".format(exx))
                    ret = False
                if ret:
                    log.info("Sent a notification sms to user {0}".format(
                        recipient))
                else:
                    log.warning("Failed to send a notification email to user "
                                "{0}".format(recipient))

        return ret
Exemplo n.º 35
0
    def actions(cls):
        """
        This method returns a dictionary of allowed actions and possible
        options in this handler module.

        :return: dict with actions
        """
        smtpserver_objs = get_smtpservers()
        smsgateway_dicts = get_smsgateway()
        smsgateways = [sms.identifier for sms in smsgateway_dicts]
        smtpservers = [s.config.identifier for s in smtpserver_objs]
        actions = {
            "sendmail": {
                "emailconfig": {
                    "type":
                    "str",
                    "required":
                    True,
                    "description":
                    _("Send notification email via this email server."),
                    "value":
                    smtpservers
                },
                "mimetype": {
                    "type": "str",
                    "description":
                    _("Either send email as plain text or HTML."),
                    "value": ["plain", "html"]
                },
                "attach_qrcode": {
                    "type":
                    "bool",
                    "description":
                    _("Send QR-Code image as an attachment "
                      "(cid URL: token_image)")
                },
                "subject": {
                    "type": "str",
                    "required": False,
                    "description": _("The subject of the mail that is sent.")
                },
                "reply_to": {
                    "type":
                    "str",
                    "required":
                    False,
                    "description":
                    _("The Reply-To header in the sent email."),
                    "value": [
                        NOTIFY_TYPE.NO_REPLY_TO, NOTIFY_TYPE.TOKENOWNER,
                        NOTIFY_TYPE.LOGGED_IN_USER, NOTIFY_TYPE.INTERNAL_ADMIN,
                        NOTIFY_TYPE.ADMIN_REALM, NOTIFY_TYPE.EMAIL
                    ]
                },
                "reply_to " + NOTIFY_TYPE.ADMIN_REALM: {
                    "type": "str",
                    "value": get_app_config_value("SUPERUSER_REALM", []),
                    "visibleIf": "reply_to",
                    "visibleValue": NOTIFY_TYPE.ADMIN_REALM
                },
                "reply_to " + NOTIFY_TYPE.INTERNAL_ADMIN: {
                    "type": "str",
                    "value": [a.username for a in get_db_admins()],
                    "visibleIf": "reply_to",
                    "visibleValue": NOTIFY_TYPE.INTERNAL_ADMIN
                },
                "reply_to " + NOTIFY_TYPE.EMAIL: {
                    "type":
                    "str",
                    "description":
                    _("Any email address, to which the notification "
                      "should be sent."),
                    "visibleIf":
                    "reply_to",
                    "visibleValue":
                    NOTIFY_TYPE.EMAIL
                },
                "body": {
                    "type": "text",
                    "required": False,
                    "description": _("The body of the mail that is sent.")
                },
                "To": {
                    "type":
                    "str",
                    "required":
                    True,
                    "description":
                    _("Send notification to this user."),
                    "value": [
                        NOTIFY_TYPE.TOKENOWNER, NOTIFY_TYPE.LOGGED_IN_USER,
                        NOTIFY_TYPE.INTERNAL_ADMIN, NOTIFY_TYPE.ADMIN_REALM,
                        NOTIFY_TYPE.EMAIL
                    ]
                },
                "To " + NOTIFY_TYPE.ADMIN_REALM: {
                    "type": "str",
                    "value": get_app_config_value("SUPERUSER_REALM", []),
                    "visibleIf": "To",
                    "visibleValue": NOTIFY_TYPE.ADMIN_REALM
                },
                "To " + NOTIFY_TYPE.INTERNAL_ADMIN: {
                    "type": "str",
                    "value": [a.username for a in get_db_admins()],
                    "visibleIf": "To",
                    "visibleValue": NOTIFY_TYPE.INTERNAL_ADMIN
                },
                "To " + NOTIFY_TYPE.EMAIL: {
                    "type":
                    "str",
                    "description":
                    _("Any email address, to which the notification "
                      "should be sent."),
                    "visibleIf":
                    "To",
                    "visibleValue":
                    NOTIFY_TYPE.EMAIL
                }
            },
            "sendsms": {
                "smsconfig": {
                    "type":
                    "str",
                    "required":
                    True,
                    "description":
                    _("Send the user notification via a "
                      "predefined SMS gateway."),
                    "value":
                    smsgateways
                },
                "body": {
                    "type": "text",
                    "required": False,
                    "description": _("The text of the SMS.")
                },
                "To": {
                    "type": "str",
                    "required": True,
                    "description": _("Send notification to this user."),
                    "value": [NOTIFY_TYPE.TOKENOWNER]
                }
            },
            "savefile": {
                "body": {
                    "type":
                    "text",
                    "required":
                    True,
                    "description":
                    _("This is the template content of "
                      "the new file. Can contain the tags "
                      "as specified in the documentation.")
                },
                "filename": {
                    "type":
                    "str",
                    "required":
                    True,
                    "description":
                    _("The filename of the notification. Existing files "
                      "are overwritten. The name can contain tags as specified "
                      "in the documentation and can also contain the tag {random}."
                      )
                }
            }
        }
        return actions
Exemplo n.º 36
0
    def actions(cls):
        """
        This method returns a dictionary of allowed actions and possible
        options in this handler module.

        :return: dict with actions
        """
        smtpserver_objs = get_smtpservers()
        smsgateway_dicts = get_smsgateway()
        smsgateways = [sms.identifier for sms in smsgateway_dicts]
        smtpservers = [s.config.identifier for s in smtpserver_objs]
        actions = {
            "sendmail": {
                "emailconfig": {
                    "type":
                    "str",
                    "required":
                    True,
                    "description":
                    _("Send notification "
                      "email via this "
                      "email server."),
                    "value":
                    smtpservers
                },
                "mimetype": {
                    "type": "str",
                    "description": _("Either send "
                                     "email as plain text or HTML."),
                    "value": ["plain", "html"]
                },
                "subject": {
                    "type": "str",
                    "required": False,
                    "description": _("The subject of "
                                     "the mail that "
                                     "is sent.")
                },
                "reply_to": {
                    "type":
                    "str",
                    "required":
                    False,
                    "description":
                    _("The Reply-To "
                      "header in the "
                      "sent email.")
                },
                "body": {
                    "type": "text",
                    "required": False,
                    "description": _("The body of the "
                                     "mail that is "
                                     "sent.")
                },
                "To": {
                    "type":
                    "str",
                    "required":
                    True,
                    "description":
                    _("Send notification to "
                      "this user."),
                    "value": [
                        NOTIFY_TYPE.TOKENOWNER, NOTIFY_TYPE.LOGGED_IN_USER,
                        NOTIFY_TYPE.INTERNAL_ADMIN, NOTIFY_TYPE.ADMIN_REALM,
                        NOTIFY_TYPE.EMAIL
                    ]
                },
                "To " + NOTIFY_TYPE.ADMIN_REALM: {
                    "type": "str",
                    "value": get_app_config_value("SUPERUSER_REALM", []),
                    "visibleIf": "To",
                    "visibleValue": NOTIFY_TYPE.ADMIN_REALM
                },
                "To " + NOTIFY_TYPE.INTERNAL_ADMIN: {
                    "type": "str",
                    "value": [a.username for a in get_db_admins()],
                    "visibleIf": "To",
                    "visibleValue": NOTIFY_TYPE.INTERNAL_ADMIN
                },
                "To " + NOTIFY_TYPE.EMAIL: {
                    "type":
                    "str",
                    "description":
                    _("Any email address, to "
                      "which the notification "
                      "should be sent."),
                    "visibleIf":
                    "To",
                    "visibleValue":
                    NOTIFY_TYPE.EMAIL
                }
            },
            "sendsms": {
                "smsconfig": {
                    "type":
                    "str",
                    "required":
                    True,
                    "description":
                    _("Send the user "
                      "notification via a "
                      "predefined SMS "
                      "gateway."),
                    "value":
                    smsgateways
                },
                "body": {
                    "type": "text",
                    "required": False,
                    "description": _("The text of the "
                                     "SMS.")
                },
                "To": {
                    "type": "str",
                    "required": True,
                    "description": _("Send notification to "
                                     "this user."),
                    "value": [NOTIFY_TYPE.TOKENOWNER]
                }
            }
        }
        return actions
Exemplo n.º 37
0
from ctypes import byref
from ctypes import c_ulong
from ctypes import c_char
from ctypes import c_byte

from privacyidea.lib.framework import get_app_config_value
from privacyidea.lib.error import ParameterError

__all__ = ["vasco_otp_check"]

log = logging.getLogger(__name__)

vasco_dll = None

try:
    vasco_library_path = get_app_config_value("PI_VASCO_LIBRARY")
    if vasco_library_path is not None:  # pragma: no cover
        log.info(
            u"Loading VASCO library from {!s} ...".format(vasco_library_path))
        vasco_dll = CDLL(vasco_library_path)
    else:
        log.info(u"PI_VASCO_LIBRARY option is not set, functionality disabled")
except Exception as exx:
    log.warning(u"Could not load VASCO library: {!r}".format(exx))


def check_vasco(fn):
    '''
    This is a decorator:
    checks if vasco dll is defined,
    it then runs the function otherwise raises RuntimeError