Exemple #1
0
def storeConfig(key, val, typ=None, desc=None):
    """
    storing the config entry into the db and in the global config

    - external interface for storing config entries, which implies
      the conversion of the encrypted data to an encrypted data object

    :param key: name of the entry
    :param val: the value
    :param typ: -optional- the type
    :param desc: -optional- the description

    """
    if not typ and key in type_definitions:
        typ, converter = type_definitions[key]
        val = converter(val)

    if typ and typ.lower() in ['password', 'encrypted_data']:
        typ = 'encrypted_data'
        if not isinstance(val, EncryptedData):
            val = EncryptedData.from_unencrypted(val)

    if isinstance(val, EncryptedData):
        typ = 'encrypted_data'

    log.debug('Changing config entry %r: New value is %r', key, val)
    conf = getLinotpConfig()

    conf.addEntry(key, val, typ, desc)

    return True
Exemple #2
0
def storeConfig(key, val, typ=None, desc=None):
    """
    storing the config entry into the db and in the global config

    - external interface for storing config entries, which implies
      the conversion of the encrypted data to an encrypted data object

    :param key: name of the entry
    :param val: the value
    :param typ: -optional- the type
    :param desc: -optional- the description

    """
    if not typ and key in type_definitions:
        typ, converter = type_definitions[key]
        val = converter(val)

    if typ and typ.lower() in ["password", "encrypted_data"]:
        typ = "encrypted_data"
        if not isinstance(val, EncryptedData):
            val = EncryptedData.from_unencrypted(val)

    if isinstance(val, EncryptedData):
        typ = "encrypted_data"

    log.debug("Changing config entry %r: New value is %r", key, val)
    conf = getLinotpConfig()

    conf.addEntry(key, val, typ, desc)

    return True
Exemple #3
0
def set_duration(lic_dict, raiseException=False):
    """
    set the duration value in linotp config and thus in config database

    :param lic_dict: the license info object
    :param raiseException: switch to control if an exception should be thrown
           in case of a problem
    """
    # if there is no expiration in the license we just can go on
    if not (
        lic_dict.license_expiration and "days" in lic_dict.license_expiration
    ):
        return True

    lic_sign = lic_dict.signature
    days = lic_dict.license_expiration.replace("days", "").strip()
    try:
        days = int(days)
    except ValueError as _val:
        raise LicenseException(
            "Unable to interpret duration in license description"
        )

    # we have a timely limited version, so we have to check if there is
    # already a license like this installed by comparing the signatures
    date_format = "%d%m%y"

    # get the decrypted value from the config, if there is one
    expiration = _get_license_duration()

    if expiration:
        # fetch config and split the signature and the expiration date
        signature, _sep, _date_str = expiration.rpartition(":")

        # here we only verify that the license signature is not the same
        # - we only take a slice as the stored signature will be
        #   stored in an encrypted way and then will become too long
        if base64.b64encode(lic_sign)[:500] == signature:
            error = _("License already installed!")
            if raiseException:
                raise LicenseException(error)
            else:
                log.error(error)
                return False

    # so we calculate the expiration and store this together
    # with the license signature
    expires = datetime.datetime.now() + datetime.timedelta(days=days)
    expires_str = expires.strftime(date_format)

    # we take only some bytes as it is encrypted afterwards
    signature = base64.b64encode(lic_sign)[:500].decode()
    license_expire = "%s:%s" % (signature, expires_str)

    enc_license_expire = EncryptedData.from_unencrypted(license_expire)
    storeConfig("license_duration", enc_license_expire)
    log.info("Set license expiration to %s", license_expire)

    return True
Exemple #4
0
def test_round_trip(app):
    orig_string = TEST_STRING

    with app.test_request_context():
        instance = EncryptedData.from_unencrypted(orig_string)
        unencrypted = instance.get_unencrypted()

        assert orig_string == unencrypted
Exemple #5
0
def data():
    """
    Fixture to return an instance of encryptedData

    The unencrypted string is TEST_STRING
    """

    instance = EncryptedData(TEST_STRING)

    return instance
Exemple #6
0
def encrypted_data(value):
    """
    type converter for config entries -

    similar to int(bla) it will try to conveert the given value into
    an object of EncryptedData

    :return: EncyptedData object
    """

    # anything other than string will raise an error

    if not isinstance(value, str) and not isinstance(value, unicode):

        raise Exception('Unable to encode non textual data')

    # if value is already encrypted we can just return

    if isinstance(value, EncryptedData):

        return value

    return EncryptedData.from_unencrypted(value)
Exemple #7
0
def encrypted_data(value):
    """
    type converter for config entries -

    similar to int(bla) it will try to conveert the given value into
    an object of EncryptedData

    :return: EncyptedData object
    """

    # anything other than string will raise an error

    if not isinstance(value, str) and not isinstance(value, unicode):

        raise Exception('Unable to encode non textual data')

    # if value is already encrypted we can just return

    if isinstance(value, EncryptedData):

        return value

    return EncryptedData.from_unencrypted(value)
Exemple #8
0
def _retrieveAllConfigDB():
    """
    get the server config from database with one call

    remark: for support for continous entries dedicated dicts for
            description and type are used for interim processing

    :return: config dict
    """

    config = {}
    delay = False

    conf_dict = {}
    type_dict = {}
    desc_dict = {}
    cont_dict = {}

    db_config = Session.query(Config).all()

    # put all information in the dicts for later processing

    for conf in db_config:
        log.debug("[retrieveAllConfigDB] key %r:%r" % (conf.Key, conf.Value))

        conf_dict[conf.Key] = conf.Value
        type_dict[conf.Key] = conf.Type
        desc_dict[conf.Key] = conf.Description

        # a continuous entry is indicated by the type 'C' and the description
        # search for the entry which starts with '0:' as it will provide the
        # number of continuous entries

        if conf.Type == 'C' and conf.Description[:len('0:')] == '0:':
            _start, num = conf.Description.split(':')
            cont_dict[conf.Key] = int(num)

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

    # cleanup the config from continuous entries

    for key, number in cont_dict.items():

        value = conf_dict[key]

        for i in range(number + 1):

            search_key = u"%s__[%d:%d]" % (key, i, number)

            if search_key in conf_dict:
                value = value + conf_dict[search_key]
                del conf_dict[search_key]

        conf_dict[key] = value

        search_key = u"%s__[%d:%d]" % (key, number, number)
        # allow the reading of none existing entries
        type_dict[key] = type_dict.get(search_key)
        desc_dict[key] = desc_dict.get(search_key)

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

    # normal processing as before continous here

    for key, value in conf_dict.items():

        if key.startswith("linotp.") is False:
            key = u"linotp." + key

        if isinstance(key, str):
            key = u'' + key

        nVal = expand_here(value)
        config[key] = nVal

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

    # special treatment of encrypted_data / password:
    # instead of decrypting the data during the loading of the config, the
    # encrypted data is provided EncryptedData object, which allows to only
    # decrypt the data when needed.
    # This allows to drop the delayed loading handling
    #

    for key, value in config.items():

        myTyp = type_dict.get(key)

        if myTyp and myTyp in ['password', 'encrypted_data']:
            config[key] = EncryptedData(value)

    return config, False