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
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
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
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
def data(): """ Fixture to return an instance of encryptedData The unencrypted string is TEST_STRING """ instance = EncryptedData(TEST_STRING) return instance
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)
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