Ejemplo n.º 1
0
 def deleteToken(self):
     # some DBs (eg. DB2) run 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.privacyIDEATokenId).delete()
     Session.delete(self)
     return True
Ejemplo n.º 2
0
def delete(name):
    '''
    Delete the machine with the name and return the number of deleted machines
    
    Should always be 1
    Should be 0 if such a machine did not exist.
    '''
    mid = _get_machine_id(name)
    _assigns = Session.query(MachineToken)\
        .filter(MachineToken.machine_id == mid).delete()
    num = Session.query(Machine).filter(Machine.cm_name == name).delete()
    Session.commit()
    # 1 -> success
    return num == 1
Ejemplo n.º 3
0
def get_options(machine_id=None,
                token_id=None,
                application=None,
                machinetoken_id=None):
    """
    returns a dictionary of the options for a given tuple
    of machine, token and application from the table
    MachineTokenOptions.
    
    :param machine_id: id of the machine
    :param token_id: id ot the token
    :param application: name of the application
    :param machinetoken_id: id of the machineToken-entry
    
    :return: option dictionary
     
    You either need to specify (machine_ind, token_id, application) or
    the machinetoken_id.
    """
    options = {}
    if machinetoken_id:
        sqlquery = Session.query(MachineTokenOptions).\
            filter(MachineTokenOptions.machinetoken_id == machinetoken_id)
        for option in sqlquery:
            options[option.mt_key] = option.mt_value
    elif (machine_id and token_id and application):
        raise NotImplementedError("the tuple machine_id, token_id, "
                                  "application is not implemented, yet.")
    else:
        raise Exception("You either need to specify the machinetoken_id"
                        "or the tuple token_id, machine_id, application.")
    return options
Ejemplo n.º 4
0
def get_token_in_realm(realm, active=True):
    '''
    This returns the number of tokens in one realm.

    You can either query only active token or also disabled tokens.
    '''
    if active:
        sqlQuery = Session.query(TokenRealm, Realm, Token).filter(and_(
                            TokenRealm.realm_id == Realm.id,
                            Realm.name == u'' + realm,
                            Token.privacyIDEAIsactive == True,
                            TokenRealm.token_id == Token.privacyIDEATokenId)).count()
    else:
        sqlQuery = Session.query(TokenRealm, Realm).filter(and_(
                            TokenRealm.realm_id == Realm.id,
                            Realm.name == realm)).count()
    return sqlQuery
Ejemplo n.º 5
0
def _get_machinetoken_id(machine_id, token_id, application):
    r = None
    sqlquery = Session.query(MachineToken.id)\
                .filter(and_(MachineToken.token_id == token_id,
                             MachineToken.machine_id == machine_id,
                             MachineToken.application == application))
    for row in sqlquery:
        r = row.id
    return r
Ejemplo n.º 6
0
def deltoken(machine_name, serial, application):
    """
    Delete a machine token.
    Also deletes the corresponding MachineTokenOptions
    """
    machine_id = _get_machine_id(machine_name)
    token_id = _get_token_id(serial)
    mtid = _get_machinetoken_id(machine_id, token_id, application)
    
    num = Session.query(MachineToken).\
        filter(and_(MachineToken.token_id == token_id,
                    MachineToken.machine_id == machine_id,
                    MachineToken.application == application)).delete()
    Session.query(MachineTokenOptions).\
        filter(MachineTokenOptions.machinetoken_id == mtid).delete()
    Session.commit()
    # 1 -> success
    return num == 1
Ejemplo n.º 7
0
def deltoken(machine_name, serial, application):
    machine_id = _get_machine_id(machine_name)
    token_id = _get_token_id(serial)
    
    num = Session.query(MachineToken).\
        filter(and_(MachineToken.token_id == token_id,
                    MachineToken.machine_id == machine_id,
                    MachineToken.application == application)).delete()
    Session.commit()
    # 1 -> success
    return num == 1
Ejemplo n.º 8
0
def _retrieveConfigDB(Key):
    ## prepend "lonotp." if required
    key = Key
    if (not key.startswith("privacyidea.")):
        if (not key.startswith("encprivacyidea.")):
            key = "privacyidea." + Key

    myVal = None
    key = u'' + key
    for theConf in Session.query(Config).filter(Config.Key == key):
        myVal = theConf.Value
        myVal = _expandHere(myVal)
    return myVal
Ejemplo n.º 9
0
def show(name=None, client_ip=None):
    res = {}
    cond_list = []
    if name:
        cond_list.append(Machine.cm_name == name)
    if client_ip:
        cond_list.append(Machine.cm_ip == client_ip)
                  
    condition = and_(*cond_list)
    sqlquery = Session.query(Machine).filter(condition)
    for machine in sqlquery:
        res[machine.cm_name] = machine.to_json()
    return res
Ejemplo n.º 10
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
Ejemplo n.º 11
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
    '''
    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)
    return challenges
Ejemplo n.º 12
0
def set_config(key, value, typ, description=None):
    '''
    create an intial config entry, if it does not exist

    :param key: the key
    :param value: the value
    :param description: the description of the key

    :return: nothing
    '''

    count = Session.query(model.Config).filter(
                        model.Config.Key == "privacyidea." + key).count()

    if count == 0:
        config_entry = model.Config(key, value, Type=typ, Description=description)
        Session.add(config_entry)

    return
Ejemplo n.º 13
0
def _removeConfigDB(key):
    if (not key.startswith("privacyidea.")):
        if not key.startswith('encprivacyidea.'):
            key = u"privacyidea." + 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.error('failed')
            raise ConfigAdminError("remove Config failed for %r: %r"
                                   % (key, e), id=1133)

    return num
Ejemplo n.º 14
0
    def delete_challenges(self, challenges):
        '''
        delete challenges, which match those listed ones

        :param challenges: list of (dict|int|str) challenges
        :return: result of the delete operation
        '''

        challenge_ids = []
        for challenge in challenges:
            if type(challenge) == dict:
                if challenge.has_key('id'):
                    challenge_id = challenge.get('id')
            elif type(challenge) == Challenge:
                challenge_id = challenge.get('id')
            elif type(challenge) in (unicode , str , int):
                challenge_id = challenge

            try:
                challenge_ids.append(int(challenge_id))
            except ValueError:
                ## ignore
                LOG.warning("failed to concert the challengeId %r to int()" %
                            challenge_id)

        res = 1

        # 1. get all challeges which are to be deleted
        # 2. self.token.select_challenges()

        if len(challenge_ids) > 0:

            del_challes = Session.query(Challenge).\
                filter(Challenge.tokenserial == u'' + self.token.getSerial()).\
                filter(Challenge.id.in_(challenge_ids)).all()

            for dell in del_challes:
                Session.delete(dell)
                #pass

        return res
Ejemplo n.º 15
0
def deloption(mtid=None,
              name=None,
              serial=None,
              application=None,
              key=None):
    """
    delete option from a machine token definition
    :param mtid: id of the machinetoken
    :param name: the machine name
    :param serial: the serial number of the token
    :param app: the application
    """
    if not mtid:
        mtid = _get_machinetoken_id(_get_machine_id(name),
                                    _get_token_id(serial),
                                    application)
    num = Session.query(MachineTokenOptions).\
                        filter(and_(MachineTokenOptions.machinetoken_id == mtid,
                                    MachineTokenOptions.mt_key == key)).delete()
    Session.commit()
    return num == 1
Ejemplo n.º 16
0
def _retrieveAllConfigDB():

    config = {}
    delay = False
    for conf in Session.query(Config).all():
        log.debug("key %r:%r" % (conf.Key, conf.Value))
        key = conf.Key
        if (not key.startswith("privacyidea.")):
            key = "privacyidea." + conf.Key
        nVal = _expandHere(conf.Value)
        config[key] = nVal
        myTyp = conf.Type
        if myTyp is not None:
            if myTyp == 'password':
                if hasattr(c, 'hsm') == True and isinstance(c.hsm, dict):
                    hsm = c.hsm.get('obj')
                    if hsm is not None and hsm.isReady() == True:
                        config['enc' + key] = decryptPassword(conf.Value)
                else:
                    delay = True

    return (config, delay)
Ejemplo n.º 17
0
def show(name=None, client_ip=None):
    '''
    Returns a dictionaries of machines matching name and client_ip
    
    :param name: the name of the machine
    :type name: string
    :param client_ip: the IP of the machine
    :type client_ip: sting
    :return: dictionary of machines, where the key is the machine name
             and the value is a dictionary with machine information.
    '''
    res = {}
    cond_list = []
    if name:
        cond_list.append(Machine.cm_name == name)
    if client_ip:
        cond_list.append(Machine.cm_ip == client_ip)
                  
    condition = and_(*cond_list)
    sqlquery = Session.query(Machine).filter(condition)
    for machine in sqlquery:
        res[machine.cm_name] = machine.to_json()
    return res
Ejemplo n.º 18
0
def _storeConfigDB(key, val, typ=None, desc=None):
    value = val

    if (not key.startswith("privacyidea.")):
        key = "privacyidea." + key

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

    if typ is not None and typ == 'password':
        value = encryptPassword(val)
        en = decryptPassword(value)
        if (en != val):
            raise Exception("StoreConfig: Error during encoding password type!")

    ## 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
Ejemplo n.º 19
0
def showtoken(machine_name=None,
              serial=None,
              application=None,
              client_ip=None,
              flexi=None,
              params=None):
    '''
    Returns a dictionary of tokens assigned to machines.
    
    :param flexi: If set, the output will be in flexigrid format and
            we will output all machines, even if they have no token assigned
    :type flexi: boolean
    :return: JSON of all tokens connected to machines with the corresponding
             application.
    '''
    res = {}
    machine_id = None
    token_id = None
    cond_list = []
    # default
    order = Machine.cm_name
    page = 1
    page_size = 15

    if machine_name or client_ip:
        machine_id = _get_machine_id(machine_name, client_ip)
    if serial:
        token_id = _get_token_id(serial)
    
    if machine_id:
        cond_list.append(MachineToken.machine_id == machine_id)
    if token_id:
        cond_list.append(MachineToken.token_id == token_id)
    if application:
        cond_list.append(MachineToken.application == application)
    
    machines = {}
     
    # For flexigrid we use addtional parameter
    if flexi:
        if params:
            # Filtering
            qtype = params.get("qtype")
            query = params.get("query")
            if qtype == "machine":
                cond_list.append(Machine.cm_name.like("%" + query + "%"))
            elif qtype == "IP":
                cond_list.append(Machine.cm_ip.like("%" + query + "%"))
            elif qtype == "description":
                cond_list.append(Machine.cm_desc.like("%" + query + "%"))
            elif qtype == "serial":
                cond_list.append(Token.privacyIDEATokenSerialnumber.
                                 like("%" + query + "%"))
            elif qtype == "application":
                cond_list.append(MachineToken.application.like("%" 
                                                               + query + "%"))

            condition = and_(*cond_list)

            # Flexigrid sorting
            sort = params.get("sortname")
            sort_order = params.get("sortorder")
            if sort == "machine_id":
                order = MachineToken.machine_id
            elif sort == "machine":
                order = Machine.cm_name
            elif sort == "IP":
                order = Machine.cm_ip
            elif sort == "description":
                order = Machine.cm_desc
            elif sort == "serial":
                order = Token.privacyIDEATokenSerialnumber
            elif sort == "application":
                order = MachineToken.application
            
            if sort_order is not None and sort_order == "desc":
                order = order.desc()
            else:
                order = order.asc()
                
            # pagination
            page = int(params.get("page", 1))
            page_size = int(params.get("rp", 15))

        sqlquery = Session.query(Machine,
                                 MachineToken.id,
                                 MachineToken.application,
                                 Token.privacyIDEATokenSerialnumber,
                                 Token.privacyIDEAIsactive)\
                                        .outerjoin(MachineToken)\
                                        .outerjoin(Token)\
                                        .filter(condition)\
                                        .order_by(order)\
                                        .limit(page_size)\
                                        .offset(page_size*(page - 1))
        # Fixme: This is not best way to determine the total count.
        sql_total = Session.query(Machine,
                                  MachineToken.application,
                                  Token.privacyIDEATokenSerialnumber)\
                                        .outerjoin(MachineToken)\
                                        .outerjoin(Token)\
                                        .filter(condition)
        total = 0
        for _i in sql_total:
            total += 1
        rows = []
        m_id = 0
        for row in sqlquery:
            machine, _mtid, application, serial, is_active = row
            m_id += 1
            rows.append({'id': m_id,
                         'cell': [(m_id),
                                  (machine.id),
                                  (machine.cm_name),
                                  (machine.cm_ip),
                                  (machine.cm_desc),
                                  (serial) or "",
                                  (is_active),
                                  (application) or ""]})
        
        res = {"page": page,
               "total": total}
        res["rows"] = rows
    else:
        condition = and_(*cond_list)
        sqlquery = Session.query(MachineToken).filter(condition)
        for row in sqlquery:
            machines[row.id] = row.to_json()
            # add options
            if application:
                machine_options = get_options(machinetoken_id=row.id)
                machines[row.id]["options"] = machine_options

        res["total"] = len(machines)
        res["machines"] = machines

    Session.commit()
    return res
Ejemplo n.º 20
0
def create_challenge(token, options=None):
    """
    dedicated method to create a challenge to support the implementation
    of challenge policies in future

    :param options: optional parameters for token specific tokens
                    eg. request a signed challenge
    :return: a tuple of  (boolean, and a dict, which contains the
             {'challenge' : challenge} description)
    """

    ## response dict, describing the challenge reply
    challenge = {}
    ## the allocated db challenge object
    challenge_obj = None
    retry_counter = 0
    reason = None

    id_length = int(getFromConfig('TransactionIdLength', 12))

    while True:
        try:

            transactionid = Challenge.createTransactionId(length=id_length)
            num_challenges = Session.query(Challenge).\
                    filter(Challenge.transid == transactionid).count()

            if num_challenges == 0:
                challenge_obj = Challenge(transid=transactionid,
                                                tokenserial=token.getSerial())
            if challenge_obj is not None:
                break

        except Exception as exce:
            LOG.info("Failed to create Challenge: %r", exce)
            reason = exce

        ## prevent an unlimited loop
        retry_counter = retry_counter + 1
        if retry_counter > 100:
            LOG.info("Failed to create Challenge for %d times: %r -quiting!",
                     retry_counter, reason)
            raise Exception('Failed to create challenge %r' % reason)

    challenges = get_challenges(serial=token.getSerial())

    ## carefully create a new challenge
    try:

        ## we got a challenge object allocated and initialize the challenge
        (res, open_transactionid, message, attributes) = \
                             token.initChallenge(transactionid,
                                                 challenges=challenges,
                                                 options=options)

        if res == False:
            ## if a different transid is returned, this indicates, that there
            ## is already an outstanding challenge we can refere to
            if open_transactionid != transactionid:
                transactionid = open_transactionid

        else:
            ## in case the init was successfull, we preserve no the challenge data
            ## to support the implementation of a blocking based on the previous
            ## stored data
            challenge_obj.setChallenge(message)
            challenge_obj.save()

            (res, message, data, attributes) = \
                        token.createChallenge(transactionid, options=options)

            if res == True:
                ## persist the final challenge data + message
                challenge_obj.setChallenge(message)
                challenge_obj.setData(data)
                challenge_obj.save()
            else:
                transactionid = ''

    except Exception as exce:
        reason = exce
        res = False


    ## if something goes wrong with the challenge, remove it
    if res == False and challenge_obj is not None:
        try:
            LOG.debug("deleting session")
            Session.delete(challenge_obj)
            Session.commit()
        except Exception as exx:
            LOG.debug("deleting session failed: %r" % exx)
            try:
                Session.expunge(challenge_obj)
                Session.commit()
            except Exception as exx:
                LOG.debug("expunge session failed: %r" % exx)

    ## in case that create challenge fails, we must raise this reason
    if reason is not None:
        message = "%r" % reason
        LOG.error("Failed to create or init challenge %r " % reason)
        raise reason

    ## prepare the response for the user
    if transactionid is not None:
        challenge['transactionid'] = transactionid

    if message is not None:
        challenge['message'] = message

    if attributes is not None and type(attributes) == dict:
        challenge.update(attributes)

    return (res, challenge)