Esempio n. 1
0
def get_challenges(serial=None, transid=None):
    '''
    get_challenges - give all challenges for a given token

    :param serial:   serial of the token
    :param transid:  transaction id, if None, all will be retrieved
    :return:         return a list of challenge dict
    '''
    LOG.debug('[get_challenges] %r' % (serial))

    challenges = []
    if transid is None and serial is None:
        return challenges

    if transid is None:
        db_challenges = Session.query(Challenge)\
            .filter(Challenge.tokenserial == u'' + serial)\
            .order_by(desc(Challenge.id))\
            .all()
    else:
        db_challenges = Session.query(Challenge)\
            .filter(Challenge.transid == transid)\
            .all()

    challenges.extend(db_challenges)

    LOG.debug('[getTransactions4serial] %r' % challenges)
    return challenges
Esempio n. 2
0
def deleteRealm(realmname):
    '''
    delete the realm from the Database Table with the given name

    :param realmname: the to be deleted realm
    :type  realmname: string
    '''

    log.debug("[delete] delete Realm object with name=%s" % realmname)
    r = getRealmObject(name=realmname)
    if r is None:
        ''' if no realm is found, we re-try the lowercase name for backward compatibility '''
        r = getRealmObject(name=realmname.lower())
    realmId = 0
    if r is not None:
        realmId = r.id

        if realmId != 0:
            log.debug("[deleteRealm] Now deleting all realations with realm_id=%i" % realmId)
            Session.query(TokenRealm).filter(TokenRealm.realm_id == realmId).delete()
        Session.delete(r)

    else:
        log.warning("[deleteRealm] There is no realm object with the name %s to be deleted." % realmname)
        return False
    # now delete all relations, i.e. remove all Tokens from this realm.

    return True
Esempio n. 3
0
    def test_updateExisting(self):
        # Test the following conditions:
        # - An entry is created with chunklength > 1
        # - The type and description are not set
        # - The entry is reduced to one chunk
        # Verify that the resulting config entry has
        # correctly set the type and description

        key = 'linotp.testupdate'
        longvalue = '*' * 2000
        value = 'value'
        typ = None
        description = None

        _storeConfigDB(key, longvalue, typ, description)
        assert Session.query(Config).count() == 2
        oldentries = Session.query(Config).all()
        assert len(oldentries) == 2

        _storeConfigDB(key, value, typ, description)
        entries = Session.query(Config).all()
        assert len(entries) == 1

        entry = entries[0]
        assert entry.Key == key
        assert entry.Value == value
        assert entry.Description == description
        assert entry.Type == typ
Esempio n. 4
0
def deleteRealm(realmname):
    '''
    delete the realm from the Database Table with the given name

    :param realmname: the to be deleted realm
    :type  realmname: string
    '''

    log.debug("[delete] delete Realm object with name=%s" % realmname)
    r = getRealmObject(name=realmname)
    if r is None:
        ''' if no realm is found, we re-try the lowercase name for backward compatibility '''
        r = getRealmObject(name=realmname.lower())
    realmId = 0
    if r is not None:
        realmId = r.id

        if realmId != 0:
            log.debug(
                "[deleteRealm] Now deleting all realations with realm_id=%i" %
                realmId)
            Session.query(TokenRealm).filter(
                TokenRealm.realm_id == realmId).delete()
        Session.delete(r)

    else:
        log.warning(
            "[deleteRealm] There is no realm object with the name %s to be deleted."
            % realmname)
        return False
    # now delete all relations, i.e. remove all Tokens from this realm.

    return True
Esempio n. 5
0
def deleteRealm(realmname):
    '''
    delete the realm from the Database Table with the given name

    :param realmname: the to be deleted realm
    :type  realmname: string
    '''

    log.debug("deleting realm object with name=%s" % realmname)
    r = getRealmObject(name=realmname)
    if r is None:
        ''' if no realm is found, we re-try the lowercase name for backward compatibility '''
        r = getRealmObject(name=realmname.lower())
    realmId = 0
    if r is not None:
        realmId = r.id

        if realmId != 0:
            log.debug("Deleting token relations for realm with id %i" % realmId)
            Session.query(TokenRealm).filter(TokenRealm.realm_id == realmId).delete()
        Session.delete(r)

    else:
        log.warning("Realm with name %s was not found." % realmname)
        return False
    # now delete all relations, i.e. remove all Tokens from this realm.

    # finally we delete the 'realmname' cache
    from linotp.lib.user import delete_realm_resolver_cache
    delete_realm_resolver_cache(realmname)

    return True
Esempio n. 6
0
    def test_updateExisting(self):
        # Test the following conditions:
        # - An entry is created with chunklength > 1
        # - The type and description are not set
        # - The entry is reduced to one chunk
        # Verify that the resulting config entry has
        # correctly set the type and description

        key = 'linotp.testupdate'
        longvalue = '*' * 2000
        value = 'value'
        typ = None
        description = None

        _storeConfigDB(key, longvalue, typ, description)
        self.assertEqual(Session.query(Config).count(), 2)
        oldentries = Session.query(Config).all()
        self.assertEqual(len(oldentries), 2)

        _storeConfigDB(key, value, typ, description)
        entries = Session.query(Config).all()
        self.assertEqual(len(entries), 1)

        entry = entries[0]
        self.assertEqual(entry.Key, key)
        self.assertEqual(entry.Value, value)
        self.assertEqual(entry.Description, '')  # None is converted to ''
        self.assertEqual(entry.Type, typ)
Esempio n. 7
0
def get_challenges(serial=None, transid=None):
    '''
    get_challenges - give all challenges for a given token

    :param serial:   serial of the token
    :param transid:  transaction id, if None, all will be retrieved
    :return:         return a list of challenge dict
    '''
    log.debug('[get_challenges] %r' % (serial))

    challenges = []
    if transid is None and serial is None:
        return challenges

    if transid is None:
        db_challenges = Session.query(Challenge)\
            .filter(Challenge.tokenserial == u'' + serial)\
            .order_by(desc(Challenge.id))\
            .all()
    else:
        transid_len = int(getFromConfig('TransactionIdLength', 12))
        if len(transid) == transid_len:
            db_challenges = Session.query(Challenge)\
                .filter(Challenge.transid == transid)\
                .all()
        else:
            db_challenges = Session.query(Challenge)\
                .filter(Challenge.transid.startswith(transid))\
                .all()

    challenges.extend(db_challenges)

    log.debug('[getTransactions4serial] %r' % challenges)
    return challenges
Esempio n. 8
0
def deleteRealm(realmname):
    '''
    delete the realm from the Database Table with the given name

    :param realmname: the to be deleted realm
    :type  realmname: string
    '''

    log.debug("deleting realm object with name=%s" % realmname)
    r = getRealmObject(name=realmname)
    if r is None:
        ''' if no realm is found, we re-try the lowercase name for backward compatibility '''
        r = getRealmObject(name=realmname.lower())
    realmId = 0
    if r is not None:
        realmId = r.id

        if realmId != 0:
            log.debug("Deleting token relations for realm with id %i" % realmId)
            Session.query(TokenRealm).filter(TokenRealm.realm_id == realmId).delete()
        Session.delete(r)

    else:
        log.warning("Realm with name %s was not found." % realmname)
        return False
    # now delete all relations, i.e. remove all Tokens from this realm.

    # finally we delete the 'realmname' cache
    from linotp.lib.user import delete_realm_resolver_cache
    delete_realm_resolver_cache(realmname)

    return True
Esempio n. 9
0
def get_challenges(serial=None, transid=None):
    """
    get_challenges - give all challenges for a given token

    :param serial:   serial of the token
    :param transid:  transaction id, if None, all will be retrieved
    :return:         return a list of challenge dict
    """
    LOG.debug("[get_challenges] %r" % (serial))

    challenges = []
    if transid is None and serial is None:
        return challenges

    if transid is None:
        db_challenges = (
            Session.query(Challenge).filter(Challenge.tokenserial == u"" + serial).order_by(desc(Challenge.id)).all()
        )
    else:
        db_challenges = Session.query(Challenge).filter(Challenge.transid == transid).all()

    challenges.extend(db_challenges)

    LOG.debug("[getTransactions4serial] %r" % challenges)
    return challenges
Esempio n. 10
0
def get_challenges(serial=None, transid=None):
    '''
    get_challenges - give all challenges for a given token

    :param serial:   serial of the token
    :param transid:  transaction id, if None, all will be retrieved
    :return:         return a list of challenge dict
    '''
    log.debug('[get_challenges] %r' % (serial))

    challenges = []
    if transid is None and serial is None:
        return challenges

    if transid is None:
        db_challenges = Session.query(Challenge)\
            .filter(Challenge.tokenserial == u'' + serial)\
            .order_by(desc(Challenge.id))\
            .all()
    else:
        transid_len = int(getFromConfig('TransactionIdLength', 12))
        if len(transid) == transid_len:
            db_challenges = Session.query(Challenge)\
                .filter(Challenge.transid == transid)\
                .all()
        else:
            db_challenges = Session.query(Challenge)\
                .filter(Challenge.transid.startswith(transid))\
                .all()

    challenges.extend(db_challenges)

    log.debug('[getTransactions4serial] %r' % challenges)
    return challenges
Esempio n. 11
0
    def test_updateExisting(self):
        # Test the following conditions:
        # - An entry is created with chunklength > 1
        # - The type and description are not set
        # - The entry is reduced to one chunk
        # Verify that the resulting config entry has
        # correctly set the type and description

        key = 'linotp.testupdate'
        longvalue = '*' * 2000
        value = 'value'
        typ = None
        description = None

        _storeConfigDB(key, longvalue, typ, description)
        self.assertEqual(Session.query(Config).count(), 2)
        oldentries = Session.query(Config).all()
        self.assertEqual(len(oldentries), 2)

        _storeConfigDB(key, value, typ, description)
        entries = Session.query(Config).all()
        self.assertEqual(len(entries), 1)

        entry = entries[0]
        self.assertEqual(entry.Key, key)
        self.assertEqual(entry.Value, value)
        self.assertEqual(entry.Description, '')  # None is converted to ''
        self.assertEqual(entry.Type, typ)
Esempio n. 12
0
 def deleteToken(self):
     # # some dbs (eg. DB2) runs in deadlock, if the TokenRealm entry
     # # is deleteted via foreign key relation
     # # so we delete it explicitly
     Session.query(TokenRealm).filter(
         TokenRealm.token_id == self.LinOtpTokenId).delete()
     Session.delete(self)
     return True
Esempio n. 13
0
 def deleteToken(self):
     log.debug('deleteToken()')
     ## some dbs (eg. DB2) runs in deadlock, if the TokenRealm entry
     ## is deleteted via foreign key relation
     ## so we delete it explicit
     Session.query(TokenRealm).filter(TokenRealm.token_id == self.LinOtpTokenId).delete()
     Session.delete(self)
     log.debug('delete token success')
     return True
Esempio n. 14
0
    def test_set_loglevel(self, app, client):
        name = 'linotp.lib.user'
        config_entry = Session.query(LoggingConfig).get(name)
        assert not config_entry

        params = dict(
            loggerName=name,
            level=10,
        )
        client.post('/maintenance/setLogLevel', json=params)

        config_entry = Session.query(LoggingConfig).get(name)
        assert config_entry.level == 10
Esempio n. 15
0
    def _get_tokens_in_realm(self, valid_realms):
        ## get all matching realms
        realm_id_tuples = Session.query(Realm.id).\
                            filter(Realm.name.in_(valid_realms)).all()
        realm_ids = set()
        for realm_tuple in realm_id_tuples:
            realm_ids.add(realm_tuple[0])
        ## get all tokenrealm ids
        token_id_tuples = Session.query(TokenRealm.token_id).\
                    filter(TokenRealm.realm_id.in_(realm_ids)).all()
        token_ids = set()
        for token_tuple in token_id_tuples:
            token_ids.add(token_tuple[0])

        return token_ids
Esempio n. 16
0
    def _get_tokens_in_realm(self, valid_realms):
        ## get all matching realms
        realm_id_tuples = Session.query(Realm.id).\
                            filter(Realm.name.in_(valid_realms)).all()
        realm_ids = set()
        for realm_tuple in realm_id_tuples:
            realm_ids.add(realm_tuple[0])
        ## get all tokenrealm ids
        token_id_tuples = Session.query(TokenRealm.token_id).\
                    filter(TokenRealm.realm_id.in_(realm_ids)).all()
        token_ids = set()
        for token_tuple in token_id_tuples:
            token_ids.add(token_tuple[0])

        return token_ids
Esempio n. 17
0
    def get_token_data(self):
        # get all tokens
        tokens = Session.query(model_token).all()

        for token in tokens:
            token_data = {}
            serial = token.LinOtpTokenSerialnumber
            token_data['Serial'] = serial

            if token.isPinEncrypted():
                pin = token.getPin()
                enc_value = self.crypter.encrypt(input_data=pin,
                                        just_mac=serial + token.LinOtpPinHash)
                token_data['TokenPin'] = enc_value

            # the userpin is used in motp and ocra/ocra2 token
            if token.LinOtpTokenPinUser:
                user_pin_obj = token.getUserPin()
                user_pin = user_pin_obj.getKey()
                enc_value = self.crypter.encrypt(input_data=user_pin,
                                    just_mac=serial + token.LinOtpTokenPinUser)
                token_data['TokenUserPin'] = enc_value

            # then we retrieve as well the original value,
            # to identify changes
            encKey = token.LinOtpKeyEnc

            secObj = token.getHOtpKey()
            seed = secObj.getKey()
            enc_value = self.crypter.encrypt(input_data=seed,
                                            just_mac=serial + encKey)
            token_data['TokenSeed'] = enc_value
            # next we look for tokens, where the pin is encrypted
            yield token_data
Esempio n. 18
0
    def set_token_data(self, token_data):

        serial = token_data["Serial"]
        tokens = Session.query(model_token).\
            filter(model_token.LinOtpTokenSerialnumber == serial).all()
        token = tokens[0]

        if 'TokenPin' in token_data:
            enc_pin = token_data['TokenPin']
            token_pin = self.crypter.decrypt(enc_pin,
                                just_mac=serial + token.LinOtpPinHash)
            # prove, we can write
            token.setPin(token_pin, hashed=False)

        if 'TokenUserPin' in token_data:
            enc_user_pin = token_data['TokenUserPin']
            user_pin = self.crypter.decrypt(enc_user_pin,
                               just_mac=serial + token.LinOtpTokenPinUser)
            # prove, we can write
            token.setUserPin(user_pin)

        # we put the current crypted seed in the mac to check if
        # something changed in meantime
        encKey = token.LinOtpKeyEnc
        enc_seed = token_data['TokenSeed']
        token_seed = self.crypter.decrypt(enc_seed,
                                          just_mac=serial + encKey)
        token.setHKey(token_seed, reset_failcount=False)
Esempio n. 19
0
def getRealmObject(name="", id=0):
    '''
    returns the Realm Object for a given realm name.
    If the given realm name is not found, it returns "None"

    :param name: realmname to be searched
    :type  name: string

    TODO: search by id not implemented, yet
    :param id:   id of the realm object
    :type  id:   integer

    :return : realmObject - the database object
    :rtype  : the sql db object
    '''

    log.debug("Getting realm object for name=%s, id=%i", name, id)
    realmObj = None

    name = '' + str(name)
    if (0 == id):
        realmObjects = Session.query(Realm).filter(func.lower(Realm.name) == name.lower())
        if realmObjects.count() > 0:
            realmObj = realmObjects[0]

    return realmObj
Esempio n. 20
0
    def webkdc_userinfo(self):
        # Called by WebAuth via the Elm remctld scripts.
        # Returns information about whether the user owns any tokens.

        # TODO: Require some sort of session token.
        param = {}

        try:
            param.update(request.params)
            user = getUserFromParam(param, optionalOrRequired = True)
            if (user is not None and user.isEmpty() == False):
                (userid, idResolver, idResolverClass) = getUserId(user)

                sqlQuery = Session.query(model.Token).with_lockmode("update").filter(
                   model.Token.LinOtpUserid == userid).filter(
                    model.Token.LinOtpIdResClass == idResolverClass).filter(
                     model.Token.LinOtpIsactive == 1)

                tokenList = []
                for token in sqlQuery:
                    tokenList.append(token.LinOtpTokenSerialnumber)

            Session.commit()

            return sendResult(response, tokenList, 0)

        except Exception as exx:
            log.error("[webkdc_userinfo] validate/webkdc_userinfo failed: %r" % exx)
            log.error("[webkdc_userinfo] %s" % traceback.format_exc())

            Session.rollback()
            return sendError(response, u"validate/webkdc_userinfo failed: %s" % unicode(exx), 0)
        finally:
            Session.close()
Esempio n. 21
0
def _storeConfigEntryDB(key, value, typ=None, desc=None):
    """
    lowest level for storing database entries in the config table
    """

    confEntries = Session.query(Config).filter(Config.Key == unicode(key))
    theConf = None

    # update
    if confEntries.count() == 1:
        theConf = confEntries[0]
        theConf.Value = unicode(value)
        if (typ is not None):
            theConf.Type = unicode(typ)
        if (desc is not None):
            theConf.Description = unicode(desc)

    # insert
    elif confEntries.count() == 0:
        theConf = Config(
                        Key=unicode(key),
                        Value=unicode(value),
                        Type=unicode(typ),
                        Description=unicode(desc)
                        )
    if theConf is not None:
        Session.add(theConf)

    return 101
Esempio n. 22
0
    def get_config_items(self):
        """
        iterator function, to return a config entry in the migration format

        it reads all config entries from the config table, which have the type
        password. The decrypted value is taken from the linotp config

        :return: dictionary with the config entry: key, type, description
                 and the value, which is a dict with the encryption relevant
                 data like: encrypted_data, iv, mac
        """

        config_entries = Session.query(model_config).\
                         filter(model_config.Type == 'password').all()
        for entry in config_entries:

            key = 'enc%s' % entry.Key
            value = getFromConfig(key)

            # calculate encryption and add mac from mac_data
            enc_value = self.crypter.encrypt(input_data=value,
                                             just_mac=key + entry.Value)

            config_item = {
                "Key": entry.Key,
                "Value": enc_value,
                "Type": entry.Type,
                "Description": entry.Description
            }

            yield config_item
Esempio n. 23
0
def getRealmObject(name=u"", id=0):
    '''
    returns the Realm Object for a given realm name.
    If the given realm name is not found, it returns "None"

    :param name: realmname to be searched
    :type  name: string

    TODO: search by id not implemented, yet
    :param id:   id of the realm object
    :type  id:   integer

    :return : realmObject - the database object
    :rtype  : the sql db object
    '''

    log.debug("Getting realm object for name=%s, id=%i", name, id)
    realmObj = None

    name = u'' + str(name)
    if (0 == id):
        realmObjects = Session.query(Realm).filter(func.lower(Realm.name) == name.lower())
        if realmObjects.count() > 0:
            realmObj = realmObjects[0]

    return realmObj
Esempio n. 24
0
    def active_users_total(self, realmlist):
        """
        get the total number of users of active tokens
        for all resolvers which are in allowed realms

        users are counted per resolver, so if resolver is in more than one
        realm, its uers will only be counted once

        :param realmlist: list of (existing and allowed) realms
        :return: number of users in allowed realms who own an active token
        """
        realm_cond = tuple()
        for realm in realmlist:
            realm_cond += (or_(Realm.name == realm),)

        user_and_resolver = Session.query(Token.LinOtpUserid,
                                          Token.LinOtpIdResolver,
                                          Token.LinOtpIdResClass,
                                          Token.LinOtpIsactive)\
            .join(TokenRealm)\
            .join(Realm)\
            .filter(or_(*realm_cond),
                    and_(Token.LinOtpIsactive == True,
                         Token.LinOtpIdResolver != ''))\
            .group_by(Token.LinOtpUserid, Token.LinOtpIdResolver,
                      Token.LinOtpIsactive, Token.LinOtpIdResClass)

        all_server_total = user_and_resolver.count()
        return all_server_total
Esempio n. 25
0
    def active_users_per_realm(self, realm=None):
        """
        get the number of users which are assigned to an active token in total
            or per realm and resolver
        :param realm: name of realm
        :return: dict with
                keys: resolvernames
                values: number of active token users
        """
        realminfo = context.get('Config').getRealms().get(realm)
        resolver_specs = realminfo.get('useridresolver', '')
        realmdict = {}

        for resolver_spec in resolver_specs:
            __, config_identifier = parse_resolver_spec(resolver_spec)
            act_users_per_resolver = Session.query(Token.LinOtpUserid,
                                                   Token.LinOtpIdResolver,
                                                   Token.LinOtpIdResClass,
                                                   Token.LinOtpIsactive)\
                .join(TokenRealm)\
                .join(Realm)\
                .filter(and_(
                            Token.LinOtpIsactive == True,
                            Token.LinOtpIdResClass == resolver_spec,
                            Realm.name == realm
                ))\
                .group_by(Token.LinOtpUserid, Token.LinOtpIdResolver,
                          Token.LinOtpIsactive, Token.LinOtpIdResClass)

            realmdict[config_identifier] = act_users_per_resolver.count()

        return realmdict
Esempio n. 26
0
def set_logging_level(name, level):

    """
    sets the logging level in the database as well as
    in the current running logger

    :param name: Name of the logger
    :param level: New level (must be integer)
    """

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

    logger = logging.getLogger(name)
    logger.setLevel(level)

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

    config_entry = Session.query(LoggingConfig).get(name)

    if config_entry is None:
        new_config_entry = LoggingConfig(name, level)
        Session.add(new_config_entry)
        return

    config_entry.level = level
Esempio n. 27
0
    def get_token_data(self):
        """
        get all tokens
        """
        tokens = Session.query(model_token).all()

        for token in tokens:
            token_data = {}
            serial = token.LinOtpTokenSerialnumber
            token_data["Serial"] = serial

            if token.isPinEncrypted():
                iv, enc_pin = token.get_encrypted_pin()
                pin = SecretObj.decrypt_pin(enc_pin, hsm=self.hsm)
                enc_value = self.crypter.encrypt(input_data=pin, just_mac=serial + token.LinOtpPinHash)
                token_data["TokenPin"] = enc_value

            # the userpin is used in motp and ocra/ocra2 token
            if token.LinOtpTokenPinUser:
                key, iv = token.getUserPin()
                user_pin = SecretObj.decrypt(key, iv, hsm=self.hsm)
                enc_value = self.crypter.encrypt(input_data=user_pin, just_mac=serial + token.LinOtpTokenPinUser)
                token_data["TokenUserPin"] = enc_value

            # then we retrieve as well the original value,
            # to identify changes
            encKey = token.LinOtpKeyEnc

            key, iv = token.get_encrypted_seed()
            secObj = SecretObj(key, iv, hsm=self.hsm)
            seed = secObj.getKey()
            enc_value = self.crypter.encrypt(input_data=seed, just_mac=serial + encKey)
            token_data["TokenSeed"] = enc_value
            # next we look for tokens, where the pin is encrypted
            yield token_data
Esempio n. 28
0
    def get_sync_status(self):
        """
        check if cache and config db are synced

        if sync is True, the synctime is returned
        else, the difference (cache-time - database_time) is given
        :return: dict with keys 'sync' and 'synctime'
        """
        result = {'sync': False}

        linotp_conf = LinOtpConfig()
        linotp_time = linotp_conf.get('linotp.Config')

        # get db entry for config
        entry = Session.query(config_model).filter(
            config_model.Key == 'linotp.Config').one()
        db_time = entry.Value

        # if the times are not in syc, LinOTP keeps its status
        # cached but does not update its timestamp of sync
        if db_time == linotp_time:
            result['sync'] = True
            result['synctime'] = db_time
            now = datetime.datetime.now()
            result['now'] = unicode(now)

        else:
            format_string = '%Y-%m-%d %H:%M:%S.%f'
            linotp_t = datetime.datetime.strptime(str(linotp_time), format_string)
            db_t = datetime.datetime.strptime(str(db_time), format_string)
            result['cache_to_db_diff'] = unicode(linotp_t - db_t)
            result['db_time'] = db_time

        return result
Esempio n. 29
0
    def set_config_entry(self, config_entry):
        """
        set the config entry - using the standard way, so that the new value
        will be encrypted using the new encryption key and potetialy as well an
        new iv.

        before storing the new entry, the old value in its encryted form is
        read. The


        :param config_entry: the config entry, as a dict
        :return: - nothing -
        """

        key = config_entry['Key']
        typ = config_entry['Type']
        desc = config_entry['Description']
        if desc == 'None':
            desc = None

        config_entries = Session.query(model_config).\
                         filter(model_config.Key == key).all()
        entry = config_entries[0]

        # decypt the real value
        enc_value = config_entry['Value']
        value = self.crypter.decrypt(enc_value,
                                     just_mac='enc%s' % key + entry.Value)

        _storeConfigDB(key, value, typ=typ, desc=desc)
Esempio n. 30
0
    def test_storeConfigDB_encoding(self):
        # Test round trip of _storeConfigDB with entries that require
        # encoding of special characters
        conf = {
            'Key': 'linotp.TËST',
            'Value': 'VALUEÄ',
            'Type': 'TYPEß',
            'Description': 'DESCRIPTIÖN',
        }

        _storeConfigDB(conf['Key'], conf['Value'], conf['Type'],
                       conf['Description'])

        # Check value is correctly returned
        stored_value = _retrieveConfigDB(conf['Key'])
        assert conf['Value'] == stored_value

        # Check type, description in database
        entries = Session.query(Config).all()

        assert (len(entries) == 1)
        stored_conf = entries[0]

        for key in list(conf.keys()):
            assert conf[key] == getattr(stored_conf, key), \
                             "Key should match key:%s - expected %r, recevied %r" % (key, conf[key], getattr(stored_conf, key))
Esempio n. 31
0
def init_logging_config():

    """
    Loads the persistent logging configuration from the database,
    sets the appropriate mappers (to enrich results with request
    ids, remote addresses, etc) and adds the handler defined in
    the global configuration.

    Should be called ONCE at the start of the server
    """

    root_logger = logging.getLogger()

    for handler in root_logger.handlers:
        filter_ = RequestContextFilter()
        handler.addFilter(filter_)

    stderr_handler = logging.StreamHandler()
    formatter = ColorFormatter('%(asctime)s %(levelname)s - %(message)s')
    stderr_handler.setFormatter(formatter)

    root_logger.addHandler(stderr_handler)

    config_entries = Session.query(LoggingConfig).all()

    for config_entry in config_entries:
        logger = logging.getLogger(config_entry.name)
        logger.setLevel(config_entry.level)
Esempio n. 32
0
    def active_users_per_realm(self, realm=None):
        """
        get the number of users which are assigned to an active token in total
            or per realm and resolver
        :param realm: name of realm
        :return: dict with
                keys: resolvernames
                values: number of active token users
        """
        realminfo = context.get('Config').getRealms().get(realm)
        resolver_specs = realminfo.get('useridresolver', '')
        realmdict = {}

        for resolver_spec in resolver_specs:
            __, config_identifier = parse_resolver_spec(resolver_spec)
            act_users_per_resolver = Session.query(Token.LinOtpUserid,
                                                   Token.LinOtpIdResolver,
                                                   Token.LinOtpIdResClass,
                                                   Token.LinOtpIsactive)\
                .join(TokenRealm)\
                .join(Realm)\
                .filter(and_(
                            Token.LinOtpIsactive == True,
                            Token.LinOtpIdResClass == resolver_spec,
                            Realm.name == realm
                ))\
                .group_by(Token.LinOtpUserid, Token.LinOtpIdResolver,
                          Token.LinOtpIsactive, Token.LinOtpIdResClass)

            realmdict[config_identifier] = act_users_per_resolver.count()

        return realmdict
Esempio n. 33
0
    def set_token_data(self, token_data):

        serial = token_data["Serial"]
        tokens = Session.query(model_token).\
            filter(model_token.LinOtpTokenSerialnumber == serial).all()
        token = tokens[0]

        if 'TokenPin' in token_data:
            enc_pin = token_data['TokenPin']
            token_pin = self.crypter.decrypt(enc_pin,
                                just_mac=serial + token.LinOtpPinHash)
            # prove, we can write
            enc_pin = SecretObj.encrypt_pin(token_pin)
            iv = enc_pin.split(':')[0]
            token.set_encrypted_pin(enc_pin, binascii.unhexlify(iv))

        if 'TokenUserPin' in token_data:
            token_enc_user_pin = token_data['TokenUserPin']
            user_pin = self.crypter.decrypt(token_enc_user_pin,
                               just_mac=serial + token.LinOtpTokenPinUser)
            # prove, we can write
            iv, enc_user_pin = SecretObj.encrypt(user_pin, hsm=self.hsm)
            token.setUserPin(enc_user_pin, iv)

        # we put the current crypted seed in the mac to check if
        # something changed in meantime
        encKey = token.LinOtpKeyEnc
        enc_seed = token_data['TokenSeed']
        token_seed = self.crypter.decrypt(enc_seed,
                                          just_mac=serial + encKey)

        # the encryption of the token seed is not part of the model anymore
        iv, enc_token_seed = SecretObj.encrypt(token_seed)
        token.set_encrypted_seed(enc_token_seed, iv, reset_failcount=False)
Esempio n. 34
0
    def test_storeConfigDB_encoding(self):
        # Test round trip of _storeConfigDB with entries that require
        # encoding of special characters
        conf = {
            'Key': u'linotp.TËST',
            'Value': u'VALUEÄ',
            'Type': u'TYPEß',
            'Description': u'DESCRIPTIÖN',
        }

        _storeConfigDB(conf['Key'], conf['Value'],
                       conf['Type'], conf['Description'])

        # Check value is correctly returned
        stored_value = _retrieveConfigDB(conf['Key'])
        self.assertEqual(conf['Value'], stored_value)

        # Check type, description in database
        entries = Session.query(Config).all()

        assert(len(entries) == 1)
        stored_conf = entries[0]

        for key in conf.keys():
            self.assertEqual(conf[key], getattr(stored_conf, key),
                             "Key should match key:%s - expected %r, recevied %r" % (key, conf[key], getattr(stored_conf, key)))
Esempio n. 35
0
def _storeConfigEntryDB(key, value, typ=None, desc=None):
    """
    lowest level for storing database entries in the config table
    """

    confEntries = Session.query(Config).filter(Config.Key == unicode(key))
    theConf = None

    # update
    if confEntries.count() == 1:
        theConf = confEntries[0]
        theConf.Value = unicode(value)
        if (typ is not None):
            theConf.Type = unicode(typ)
        if (desc is not None):
            theConf.Description = unicode(desc)

    # insert
    elif confEntries.count() == 0:
        theConf = Config(
                        Key=unicode(key),
                        Value=unicode(value),
                        Type=unicode(typ),
                        Description=unicode(desc)
                        )
    if theConf is not None:
        Session.add(theConf)

    return 101
Esempio n. 36
0
def _removeConfigDB(key):
    log.debug('removeConfigDB %r' % key)
    num = 0

    if (not key.startswith("linotp.")):
        if not key.startswith('enclinotp.'):
            key = u"linotp." + key

    confEntries = Session.query(Config).filter(Config.Key == unicode(key))

    num = confEntries.count()
    if num == 1:
        theConf = confEntries[0]

        try:
            # Session.add(theConf)
            Session.delete(theConf)

        except Exception as e:
            log.exception('[removeConfigDB] failed')
            raise ConfigAdminError("remove Config failed for %r: %r" %
                                   (key, e),
                                   id=1133)

    return num
Esempio n. 37
0
def delete(realms, status, date=None):
    """
    delete all rows in reporting database before a given date

    :param date: (optional)day until which all rows will be deleted
    :type date: string in format: 'yyyy-mm-dd'

    :return: number of deleted rows
    """

    if not isinstance(realms, (list, tuple)):
        realms = realms.split(',')

    realm_cond = tuple()
    for realm in realms:
       realm_cond += (or_(Reporting.realm == realm),)

    status_cond = tuple()
    for stat in status:
        status_cond += (or_(Reporting.parameter == stat),)

    date_cond = tuple()
    if date:
        date_cond += (and_(Reporting.timestamp < date),)

    conds = (and_(*date_cond), or_(*realm_cond), or_(*status_cond),)

    rows = Session.query(Reporting).filter(*conds)
    row_num = rows.count()

    for row in rows:
        Session.delete(row)
    return row_num
Esempio n. 38
0
    def get_sync_status(self):
        """
        check if cache and config db are synced

        if sync is True, the synctime is returned
        else, the difference (cache-time - database_time) is given
        :return: dict with keys 'sync' and 'synctime'
        """
        result = {'sync': False}

        linotp_conf = LinOtpConfig()
        linotp_time = linotp_conf.get('linotp.Config')

        # get db entry for config
        entry = Session.query(config_model).filter(
            config_model.Key == 'linotp.Config').one()
        db_time = entry.Value

        # if the times are not in syc, LinOTP keeps its status
        # cached but does not update its timestamp of sync
        if db_time == linotp_time:
            result['sync'] = True
            result['synctime'] = db_time
            now = datetime.datetime.now()
            result['now'] = unicode(now)

        else:
            format_string = '%Y-%m-%d %H:%M:%S.%f'
            linotp_t = datetime.datetime.strptime(str(linotp_time),
                                                  format_string)
            db_t = datetime.datetime.strptime(str(db_time), format_string)
            result['cache_to_db_diff'] = unicode(linotp_t - db_t)
            result['db_time'] = db_time

        return result
Esempio n. 39
0
    def active_users_total(self, realmlist):
        """
        get the total number of users of active tokens
        for all resolvers which are in allowed realms

        users are counted per resolver, so if resolver is in more than one
        realm, its uers will only be counted once

        :param realmlist: list of (existing and allowed) realms
        :return: number of users in allowed realms who own an active token
        """
        realm_cond = tuple()
        for realm in realmlist:
            realm_cond += (or_(Realm.name == realm), )

        user_and_resolver = Session.query(Token.LinOtpUserid,
                                          Token.LinOtpIdResolver,
                                          Token.LinOtpIdResClass,
                                          Token.LinOtpIsactive)\
            .join(TokenRealm)\
            .join(Realm)\
            .filter(or_(*realm_cond),
                    and_(Token.LinOtpIsactive == True,
                         Token.LinOtpIdResolver != ''))\
            .group_by(Token.LinOtpUserid, Token.LinOtpIdResolver,
                      Token.LinOtpIsactive, Token.LinOtpIdResClass)

        all_server_total = user_and_resolver.count()
        return all_server_total
Esempio n. 40
0
    def get_active_tokencount(self):
        """
        get the number of active tokens from all realms (including norealm)

        :return: number of active tokens
        """
        active = Token.LinOtpIsactive == True
        token_active = Session.query(Token).filter(active).count()
        return token_active
Esempio n. 41
0
    def get_active_tokencount(self):
        """
        get the number of active tokens from all realms (including norealm)

        :return: number of active tokens
        """
        active = Token.LinOtpIsactive == True
        token_active = Session.query(Token).filter(active).count()
        return token_active
Esempio n. 42
0
def _removeConfigDB(key):
    """
    remove entry from config table

    :param key: the name of the entry
    :return: number of deleted entries
    """
    log.debug('removeConfigDB %r' % key)

    if (not key.startswith("linotp.")):
        if not key.startswith('enclinotp.'):
            key = u"linotp." + key

    confEntries = Session.query(Config).filter(
        Config.Key == unicode(key)).all()

    if not confEntries:
        return 0

    theConf = confEntries[0]

    to_be_deleted = []
    to_be_deleted.append(theConf)

    # if entry is a contious type, delete all of this kind
    if theConf.Type == 'C' and theConf.Description[:len('0:')] == '0:':
        _start, end = theConf.Description.split(':')
        search_key = "%s__[%%:%s]" % (key, end)
        cont_entries = Session.query(Config).filter(
            Config.Key.like(search_key)).all()
        to_be_deleted.extend(cont_entries)

    try:
        for entry in to_be_deleted:
            # Session.add(theConf)
            Session.delete(entry)

    except Exception as e:
        log.exception('[removeConfigDB] failed')
        raise ConfigAdminError("remove Config failed for %r: %r" % (key, e),
                               id=1133)

    return len(to_be_deleted)
Esempio n. 43
0
def delete_reporting():
    """
    delete all rows in reporting database

    :return: number of deleted rows
    """
    rows = Session.query(Reporting)
    row_num = rows.count()
    for row in rows.all():
        Session.delete(row)
    return row_num
Esempio n. 44
0
def _removeConfigDB(key):
    """
    remove entry from config table

    :param key: the name of the entry
    :return: number of deleted entries
    """
    log.debug('removeConfigDB %r' % key)

    if (not key.startswith("linotp.")):
        if not key.startswith('enclinotp.'):
            key = u"linotp." + key

    confEntries = Session.query(Config).filter(Config.Key == unicode(key)).all()

    if not confEntries:
        return 0

    theConf = confEntries[0]

    to_be_deleted = []
    to_be_deleted.append(theConf)

    # if entry is a contious type, delete all of this kind
    if theConf.Type == 'C' and theConf.Description[:len('0:')] == '0:':
        _start, end = theConf.Description.split(':')
        search_key = "%s__[%%:%s]" % (key, end)
        cont_entries = Session.query(Config).filter(Config.Key.like(search_key)).all()
        to_be_deleted.extend(cont_entries)

    try:
        for entry in to_be_deleted:
            # Session.add(theConf)
            Session.delete(entry)

    except Exception as e:
        log.exception('[removeConfigDB] failed')
        raise ConfigAdminError("remove Config failed for %r: %r"
                               % (key, e), id=1133)

    return len(to_be_deleted)
Esempio n. 45
0
    def deleteToken(self):
        # some dbs (eg. DB2) runs in deadlock, if the TokenRealm entry
        # is deleteted via foreign key relation
        # so we delete it explicitly
        token_realm_entries = Session.query(TokenRealm).filter(
            TokenRealm.token_id == self.LinOtpTokenId).all()

        for token_realm_entry in token_realm_entries:
            Session.delete(token_realm_entry)

        Session.delete(self)
        return True
Esempio n. 46
0
    def deleteToken(self):
        # some dbs (eg. DB2) runs in deadlock, if the TokenRealm entry
        # is deleteted via foreign key relation
        # so we delete it explicitly
        token_realm_entries = Session.query(TokenRealm).filter(
                            TokenRealm.token_id == self.LinOtpTokenId).all()

        for token_realm_entry in token_realm_entries:
            Session.delete(token_realm_entry)

        Session.delete(self)
        return True
Esempio n. 47
0
def init_logging_config():
    """
    Loads the persistent logging configuration from the database

    Should be called ONCE at the start of the server
    """

    config_entries = Session.query(LoggingConfig).all()

    for config_entry in config_entries:
        logger = logging.getLogger(config_entry.name)
        logger.setLevel(config_entry.level)
Esempio n. 48
0
    def get_config_info(self):
        """
        get some counts from config db
        :return: dict with keys 'total', 'ldapresolver', 'sqlresolver',
            'passwdresolver', 'policies', 'realms'
        """
        result = {}
        # the number of config entries
        result['total'] = Session.query(config_model).count()

        # the number of resolver defintions
        ldap = Session.query(config_model).filter(
            config_model.Key.like('linotp.ldapresolver.%')).count()
        result['ldapresolver'] = ldap / 13

        sql = Session.query(config_model).filter(
            config_model.Key.like('linotp.sqlresolver.%')).count()
        result['sqlresolver'] = sql / 12

        passwd = Session.query(config_model).filter(
            config_model.Key.like('linotp.passwdresolver.%')).count()
        result['passwdresolver'] = passwd

        # the number of policy definitions
        policies = Session.query(config_model).filter(
            config_model.Key.like('linotp.Policy.%')).count()
        result['policies'] = policies / 7

        # the number of realm definition (?)
        realms = Session.query(config_model).filter(
            config_model.Key.like('linotp.useridresolver.group.%')).count()
        result['realms'] = realms

        return result
Esempio n. 49
0
    def get_config_info(self):
        """
        get some counts from config db
        :return: dict with keys 'total', 'ldapresolver', 'sqlresolver',
            'passwdresolver', 'policies', 'realms'
        """
        result = {}
        # the number of config entries
        result['total'] = Session.query(config_model).count()

        # the number of resolver defintions
        ldap = Session.query(config_model).filter(
            config_model.Key.like('linotp.ldapresolver.%')).count()
        result['ldapresolver'] = ldap / 13

        sql = Session.query(config_model).filter(
            config_model.Key.like('linotp.sqlresolver.%')).count()
        result['sqlresolver'] = sql / 12

        passwd = Session.query(config_model).filter(
            config_model.Key.like('linotp.passwdresolver.%')).count()
        result['passwdresolver'] = passwd

        # the number of policy definitions
        policies = Session.query(config_model).filter(
            config_model.Key.like('linotp.Policy.%')).count()
        result['policies'] = policies / 7

        # the number of realm definition (?)
        realms = Session.query(config_model).filter(
            config_model.Key.like('linotp.useridresolver.group.%')).count()
        result['realms'] = realms

        return result
Esempio n. 50
0
    def _get_realm_condition(self, valid_realms, filterRealm):
        """
         create the condition for only getting certain realms!
        """
        rcondition = None
        if '*' in valid_realms:
            log.debug("[TokenIterator::init] wildcard for realm '*' found."
                      " Tokens of all realms will be displayed")
            return rcondition

        if len(valid_realms) > 0:
            log.debug("[TokenIterator::init] adding filter condition"
                      " for realm %r" % valid_realms)

            # get all matching realms
            token_ids = self._get_tokens_in_realm(valid_realms)
            rcondition = and_(Token.LinOtpTokenId.in_(token_ids))
            return rcondition

        if ("''" in filterRealm or '""' in filterRealm
                or "/:no realm:/" in filterRealm):
            log.debug("[TokenIterator::init] search for all tokens, which are"
                      " in no realm")

            # get all tokenrealm ids
            token_id_tuples = Session.query(TokenRealm.token_id).all()
            token_ids = set()
            for token_tuple in token_id_tuples:
                token_ids.add(token_tuple[0])

            ## define the token id not condition
            rcondition = and_(not_(Token.LinOtpTokenId.in_(token_ids)))
            return rcondition

        if filterRealm:
            # get all matching realms
            search_realms = set()

            realms = getRealms()
            for realm in realms:
                for frealm in filterRealm:
                    if fnmatch.fnmatch(realm, frealm):
                        search_realms.add(realm)

            search_realms = list(search_realms)

            # define the token id condition
            token_ids = self._get_tokens_in_realm(search_realms)
            rcondition = and_(Token.LinOtpTokenId.in_(token_ids))
            return rcondition

        return rcondition
Esempio n. 51
0
    def _get_realm_condition(self, valid_realms, filterRealm):
        """
         create the condition for only getting certain realms!
        """
        rcondition = None
        if '*' in valid_realms:
            log.debug("[TokenIterator::init] wildcard for realm '*' found."
                      " Tokens of all realms will be displayed")
            return rcondition

        if len(valid_realms) > 0:
            log.debug("[TokenIterator::init] adding filter condition"
                      " for realm %r" % valid_realms)

            # get all matching realms
            token_ids = self._get_tokens_in_realm(valid_realms)
            rcondition = and_(Token.LinOtpTokenId.in_(token_ids))
            return rcondition

        if ("''" in filterRealm or '""' in filterRealm or
              "/:no realm:/" in filterRealm):
            log.debug("[TokenIterator::init] search for all tokens, which are"
                      " in no realm")

            # get all tokenrealm ids
            token_id_tuples = Session.query(TokenRealm.token_id).all()
            token_ids = set()
            for token_tuple in token_id_tuples:
                token_ids.add(token_tuple[0])

            ## define the token id not condition
            rcondition = and_(not_(Token.LinOtpTokenId.in_(token_ids)))
            return rcondition

        if filterRealm:
            # get all matching realms
            search_realms = set()

            realms = getRealms()
            for realm in realms:
                for frealm in filterRealm:
                    if fnmatch.fnmatch(realm, frealm):
                        search_realms.add(realm)

            search_realms = list(search_realms)

            # define the token id condition
            token_ids = self._get_tokens_in_realm(search_realms)
            rcondition = and_(Token.LinOtpTokenId.in_(token_ids))
            return rcondition

        return rcondition
Esempio n. 52
0
def init_logging_config():

    """
    Loads the persistent logging configuration from the database

    Should be called ONCE at the start of the server
    """

    config_entries = Session.query(LoggingConfig).all()

    for config_entry in config_entries:
        logger = logging.getLogger(config_entry.name)
        logger.setLevel(config_entry.level)
Esempio n. 53
0
def _retrieveConfigDB(Key):
    log.debug('[retrieveConfigDB] key: %r' % Key)

    # prepend "lonotp." if required
    key = Key
    if (not key.startswith("linotp.")):
        if (not key.startswith("enclinotp.")):
            key = "linotp." + Key

    myVal = None
    key = u'' + key
    entries = Session.query(Config).filter(Config.Key == key).all()

    if not entries:
        return None

    theConf = entries[0]

    # other types than continous: we are done
    if theConf.Type != 'C':
        myVal = theConf.Value
        myVal = _expandHere(myVal)
        return myVal

    # else we have the continue type: we iterate over all entries where the
    # number of entries is stored in the description as range end
    _start, end = theConf.Description.split(':')

    # start accumulating the value
    value = theConf.Value

    for i in range(int(end)):
        search_key = "%s__[%d:%d]" % (key, i, int(end))
        cont_entries = Session.query(Config).filter(
            Config.Key == search_key).all()
        if cont_entries:
            value = value + cont_entries[0].Value

    return value
Esempio n. 54
0
def _retrieveConfigDB(Key):
    log.debug('[retrieveConfigDB] key: %r' % Key)

    # prepend "lonotp." if required
    key = Key
    if (not key.startswith("linotp.")):
        if (not key.startswith("enclinotp.")):
            key = "linotp." + Key

    myVal = None
    key = u'' + key
    entries = Session.query(Config).filter(Config.Key == key).all()

    if not entries:
        return None

    theConf = entries[0]

    # other types than continous: we are done
    if theConf.Type != 'C':
        myVal = theConf.Value
        myVal = _expandHere(myVal)
        return myVal

    # else we have the continue type: we iterate over all entries where the
    # number of entries is stored in the description as range end
    _start, end = theConf.Description.split(':')

    # start accumulating the value
    value = theConf.Value

    for i in range(int(end)):
        search_key = "%s__[%d:%d]" % (key, i, int(end))
        cont_entries = Session.query(Config).filter(Config.Key == search_key).all()
        if cont_entries:
            value = value + cont_entries[0].Value

    return value
Esempio n. 55
0
    def lookup_challenge(self, state=0):
        '''
        database lookup to find all challenges belonging to a token and or
        if exist with a transaction state

        :param state: the optional parameter identified the state/transactionId

        :return: the list of challenges
        '''

        challenges = []

        if state == 0:
            challenges = Session.query(Challenge).\
              filter(Challenge.tokenserial == self.token.getSerial()).\
              all()
        else:
            challenges = Session.query(Challenge).\
              filter(Challenge.tokenserial == self.token.getSerial()).\
              filter(Challenge.transid == state).\
              all()

        return challenges
Esempio n. 56
0
def _retrieveConfigDB(Key):
    log.debug('[retrieveConfigDB] key: %r' % Key)

    # # prepend "lonotp." if required
    key = Key
    if (not key.startswith("linotp.")):
        if (not key.startswith("enclinotp.")):
            key = "linotp." + Key

    myVal = None
    key = u'' + key
    for theConf in Session.query(Config).filter(Config.Key == key):
        myVal = theConf.Value
        myVal = _expandHere(myVal)
    return myVal