Esempio n. 1
0
    def getActivationCode(self):
        '''
        method:
            orcra/getActivationCode

        description:
            returns an valid example activcation code

        arguments:
            ./.

        returns:
            JSON with     "activationcode": "JZXW4ZI=2A"
        '''

        from linotp.lib.crypt import createActivationCode

        res = {}
        #description = 'ocra/getActivationCode'

        try:
            params = getLowerParams(request.params)
            log.debug("[getActivationCode]: %r" % params)

            checkPolicyPre('ocra', "activationcode")

            ac = str(params.get('activationcode'))
            activationCode = createActivationCode(acode=ac)
            res = {'activationcode': activationCode}

            Session.commit()
            return sendResult(response, res, 1)

        except PolicyException as pe:
            log.error("[getActivationCode] policy failed: %r" % pe)
            log.error("[getActivationCode] %s" % traceback.format_exc())
            Session.rollback()
            return sendError(response, unicode(pe))

        except Exception as exx:
            log.error("[getActivationCode] failed: %r" % exx)
            log.error("[getActivationCode] %s" % traceback.format_exc())
            Session.rollback()
            return sendError(response, unicode(exx), 0)

        finally:
            Session.close()
            log.debug('[getActivationCode] done')
Esempio n. 2
0
File: ocra.py Progetto: ukris/LinOTP
    def getActivationCode(self):
        '''
        method:
            ocra/getActivationCode

        description:
            returns an valid example activcation code

        arguments:
            ./.

        returns:
            JSON with     "activationcode": "JZXW4ZI=2A"
        '''

        from linotp.lib.crypt import createActivationCode

        res = {}
        #description = 'ocra/getActivationCode'

        try:
            params = getLowerParams(request.params)
            log.debug("[getActivationCode]: %r" % params)

            checkPolicyPre('ocra', "activationcode")

            ac = str(params.get('activationcode'))
            activationCode = createActivationCode(acode=ac)
            res = {'activationcode':activationCode}

            Session.commit()
            return sendResult(response, res, 1)

        except PolicyException as pe:
            log.error("[getActivationCode] policy failed: %r" % pe)
            log.error("[getActivationCode] %s" % traceback.format_exc())
            Session.rollback()
            return sendError(response, unicode(pe))

        except Exception as exx:
            log.error("[getActivationCode] failed: %r" % exx)
            log.error("[getActivationCode] %s" % traceback.format_exc())
            Session.rollback()
            return sendError(response, unicode(exx), 0)

        finally:
            Session.close()
            log.debug('[getActivationCode] done')
Esempio n. 3
0
    def tokeninfo(self):
        """
        this returns the contents of /admin/show?serial=xyz in a html format
        """
        param = request.params

        try:
            serial = getParam(param, "serial", required)

            filterRealm = ""
            # check admin authorization
            res = checkPolicyPre("admin", "show", param)

            filterRealm = res["realms"]
            # check if policies are active at all
            # If they are not active, we are allowed to SHOW any tokens.
            pol = getAdminPolicies("show")
            if not pol["active"]:
                filterRealm = ["*"]

            log.info("[tokeninfo] admin >%s< may display the following realms: %s" % (res["admin"], filterRealm))
            log.info("[tokeninfo] displaying tokens: serial: %s", serial)

            toks = TokenIterator(User("", "", ""), serial, filterRealm=filterRealm)

            ### now row by row
            lines = []
            for tok in toks:
                lines.append(tok)
            if len(lines) > 0:

                c.tokeninfo = lines[0]
            else:
                c.tokeninfo = {}

            for k in c.tokeninfo:
                if "LinOtp.TokenInfo" == k:
                    try:
                        # Try to convert string to Dictionary
                        c.tokeninfo["LinOtp.TokenInfo"] = json.loads(c.tokeninfo["LinOtp.TokenInfo"])
                    except:
                        pass

            return render("/manage/tokeninfo.mako")

        except PolicyException as pe:
            log.error("[tokeninfo] Error during checking policies: %r" % pe)
            log.error("[tokeninfo] %s" % traceback.format_exc())
            Session.rollback()
            return sendError(response, unicode(pe), 1)

        except Exception as e:
            log.error("[tokeninfo] failed! %r" % e)
            log.error("[tokeninfo] %s" % traceback.format_exc())
            Session.rollback()
            return sendError(response, e)

        finally:
            Session.close()
            log.debug("[tokeninfo] done")
Esempio n. 4
0
    def tokeninfo(self):
        '''
        this returns the contents of /admin/show?serial=xyz in an html format
        '''
        param = self.request_params

        try:
            try:
                serial = param['serial']
            except KeyError:
                raise ParameterError("Missing parameter: 'serial'")

            filterRealm = ""
            # check admin authorization
            res = checkPolicyPre('admin', 'show', param)

            # check if policies are active at all
            # If they are not active, we are allowed to SHOW any tokens.
            filterRealm = ["*"]
            if res['active'] and res['realms']:
                filterRealm = res['realms']

            log.info("[tokeninfo] admin >%s< may display the following realms:"
                     " %s" % (res['admin'], filterRealm))
            log.info("[tokeninfo] displaying tokens: serial: %s", serial)

            toks = TokenIterator(User("", "", ""),
                                 serial,
                                 filterRealm=filterRealm)

            # now row by row
            lines = []
            for tok in toks:
                lines.append(tok)
            if len(lines) > 0:
                c.tokeninfo = lines[0]
            else:
                c.tokeninfo = {}

            for k in c.tokeninfo:
                if "LinOtp.TokenInfo" == k:
                    try:
                        # Try to convert string to Dictionary
                        c.tokeninfo['LinOtp.TokenInfo'] = json.loads(
                            c.tokeninfo['LinOtp.TokenInfo'])
                    except:
                        pass

            return render('/manage/tokeninfo.mako').decode('utf-8')

        except PolicyException as pe:
            log.exception("[tokeninfo] Error during checking policies: %r" %
                          pe)
            db.session.rollback()
            return sendError(response, str(pe), 1)

        except Exception as e:
            log.exception("[tokeninfo] failed! %r" % e)
            db.session.rollback()
            return sendError(response, e)
Esempio n. 5
0
    def tokeninfo(self):
        '''
        this returns the contents of /admin/show?serial=xyz in a html format
        '''
        param = request.params

        try:
            serial = getParam(param, 'serial', required)

            filterRealm = ""
            # check admin authorization
            res = checkPolicyPre('admin', 'show', param)

            filterRealm = res['realms']
            # check if policies are active at all
            # If they are not active, we are allowed to SHOW any tokens.
            pol = getAdminPolicies("show")
            if not pol['active']:
                filterRealm = ["*"]

            log.info("[tokeninfo] admin >%s< may display the following realms: %s" % (res['admin'], filterRealm))
            log.info("[tokeninfo] displaying tokens: serial: %s", serial)

            toks = TokenIterator(User("", "", ""), serial, filterRealm=filterRealm)

            ### now row by row
            lines = []
            for tok in toks:
                lines.append(tok)
            if len(lines) > 0:

                c.tokeninfo = lines[0]
            else:
                c.tokeninfo = {}

            for k in c.tokeninfo:
                if "LinOtp.TokenInfo" == k:
                    try:
                        # Try to convert string to Dictionary
                        c.tokeninfo['LinOtp.TokenInfo'] = json.loads(c.tokeninfo['LinOtp.TokenInfo'])
                    except:
                        pass

            return render('/manage/tokeninfo.mako')

        except PolicyException as pe:
            log.error("[tokeninfo] Error during checking policies: %r" % pe)
            log.error("[tokeninfo] %s" % traceback.format_exc())
            Session.rollback()
            return sendError(response, unicode(pe), 1)

        except Exception as e:
            log.error("[tokeninfo] failed! %r" % e)
            log.error("[tokeninfo] %s" % traceback.format_exc())
            Session.rollback()
            return sendError(response, e)

        finally:
            Session.close()
            log.debug('[tokeninfo] done')
Esempio n. 6
0
    def tokeninfo(self):
        '''
        this returns the contents of /admin/show?serial=xyz in an html format
        '''
        param = request.params

        try:
            serial = getParam(param, 'serial', required)

            filterRealm = ""
            # check admin authorization
            res = checkPolicyPre('admin', 'show', param)

            # check if policies are active at all
            # If they are not active, we are allowed to SHOW any tokens.
            filterRealm = ["*"]
            if res['active'] and res['realms']:
                filterRealm = res['realms']

            log.info("[tokeninfo] admin >%s< may display the following realms:"
                     " %s" % (res['admin'], filterRealm))
            log.info("[tokeninfo] displaying tokens: serial: %s", serial)

            toks = TokenIterator(User("", "", ""), serial,
                                 filterRealm=filterRealm)

            # now row by row
            lines = []
            for tok in toks:
                lines.append(tok)
            if len(lines) > 0:
                c.tokeninfo = lines[0]
            else:
                c.tokeninfo = {}

            for k in c.tokeninfo:
                if "LinOtp.TokenInfo" == k:
                    try:
                        # Try to convert string to Dictionary
                        c.tokeninfo['LinOtp.TokenInfo'] = json.loads(
                                            c.tokeninfo['LinOtp.TokenInfo'])
                    except:
                        pass

            return render('/manage/tokeninfo.mako')

        except PolicyException as pe:
            log.exception("[tokeninfo] Error during checking policies: %r" % pe)
            Session.rollback()
            return sendError(response, unicode(pe), 1)

        except Exception as e:
            log.exception("[tokeninfo] failed! %r" % e)
            Session.rollback()
            return sendError(response, e)

        finally:
            Session.close()
            log.debug('[tokeninfo] done')
Esempio n. 7
0
    def getActivationCode(self):
        """
        method:
            ocra/getActivationCode

        description:
            returns an valid example activcation code

        arguments:
            ./.

        returns:
            JSON with     "activationcode": "JZXW4ZI=2A"
        """

        from linotp.lib.crypt import createActivationCode

        res = {}
        # description = 'ocra/getActivationCode'

        try:
            params = getLowerParams(request.params)
            log.debug("[getActivationCode]: %r" % params)

            checkPolicyPre("ocra", "activationcode", context=self.request_context)

            ac = str(params.get("activationcode"))
            activationCode = createActivationCode(acode=ac)
            res = {"activationcode": activationCode}

            Session.commit()
            return sendResult(response, res, 1)

        except PolicyException as pe:
            log.exception("[getActivationCode] policy failed: %r" % pe)
            Session.rollback()
            return sendError(response, unicode(pe))

        except Exception as exx:
            log.exception("[getActivationCode] failed: %r" % exx)
            Session.rollback()
            return sendError(response, unicode(exx), 0)

        finally:
            Session.close()
            log.debug("[getActivationCode] done")
Esempio n. 8
0
def getAdminRealms(username):
    results = []
    if username is None:
		return results

    from linotp.lib.policy import checkPolicyPre

    try:
        res = checkPolicyPre('admin', 'show', {}, user = User(username, '', ""))
        results = res['realms']
    finally:
        pass

    return results
Esempio n. 9
0
def getAdminRealms(username):
    results = []
    if username is None:
        return results

    from linotp.lib.policy import checkPolicyPre

    try:
        res = checkPolicyPre("admin", "show", {}, user=User(username, "", ""))
        results = res["realms"]
    finally:
        pass

    return results
Esempio n. 10
0
    def users(self):
        '''
        This function is used to fill the flexigrid.
        Unlike the complex /admin/userlist function, it only returns a
        simple array of the tokens.
        '''
        param = self.request_params

        try:

            page = param.get("page", 1)
            qfilter = param.get("query", '*') or '*'
            qtype = param.get("qtype", 'username')
            sort = param.get("sortname", 'username')
            direction = param.get("sortorder", 'asc')
            psize = param.get("rp", 20)

            user = getUserFromParam(param)

            realms = get_realms_from_params(
                param, getAdminPolicies('userlist', scope='admin'))

            uniqueUsers = {}
            for realm in realms:

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

                # check admin authorization: checkPolicyPre('admin',...

                # admin policies are special as they are acl which define
                # - for user (policy entry)
                # - the actions (policy entry)
                # - in the realm (policy entry)
                # is allowed. while the user.login is not evaluated, the
                # user.realm is.
                #
                # the admin policies are acls and are defined in contradiction
                # to the other policy scopes where actions are either defiend
                # for user or realm!!

                # so we have to check for every user.realm

                if isinstance(user, User):
                    user.realm = realm

                checkPolicyPre('admin', 'userlist', param=param, user=user)

                users_list = getUserList(
                    {qtype: qfilter, 'realm': realm}, user)

                # now create a unique list of users with the unique key of
                # userid + useridresolver

                for u in users_list:
                    pkey = u['userid'] + ':' + u['useridresolver']
                    user_realms = uniqueUsers.get(pkey, {}).get('realms', [])
                    user_realms.append(realm)
                    u['realms'] = user_realms
                    uniqueUsers[pkey] = u

            userNum = len(uniqueUsers)

            lines = []
            for u in uniqueUsers.values():
                # shorten the useridresolver, to get a better display value
                resolver_display = ""
                if "useridresolver" in u:
                    if len(u['useridresolver'].split(".")) > 3:
                        resolver_display = u['useridresolver'].split(
                            ".")[3] + " (" + u['useridresolver'].split(".")[1] + ")"
                    else:
                        resolver_display = u['useridresolver']
                lines.append(
                    {'id': u['username'],
                        'cell': [
                            (u['username']) if u.has_key('username') else (""),
                            (resolver_display),
                            (u['surname']) if u.has_key('surname') else (""),
                            (u['givenname']) if u.has_key(
                                'givenname') else (""),
                            (u['email']) if u.has_key('email') else (""),
                            (u['mobile']) if u.has_key('mobile') else (""),
                            (u['phone']) if u.has_key('phone') else (""),
                            (u['userid']) if u.has_key('userid') else (""),
                            (u['realms']),
                    ]
                    }
                )

            # sorting
            reverse = False
            sortnames = {
                'username': 0,
                'useridresolver': 1,
                'surname': 2,
                'givenname': 3,
                'email': 4,
                'mobile': 5,
                'phone': 6,
                'userid': 7
            }
            if direction == "desc":
                reverse = True

            lines = sorted(lines,
                           key=lambda user: user['cell'][sortnames[sort]],
                           reverse=reverse,
                           cmp=unicode_compare)

            # end: sorting

            # reducing the page
            if page and psize:
                page = int(page)
                psize = int(psize)
                start = psize * (page - 1)
                end = start + psize
                lines = lines[start:end]

            # We need to return 'page', 'total', 'rows'
            res = {
                "page": int(page),
                "total": userNum,
                "rows": lines
            }

            c.audit['success'] = True

            Session.commit()
            return sendResult(response, res)

        except PolicyException as pe:
            log.exception(
                "[userview_flexi] Error during checking policies: %r" % pe)
            Session.rollback()
            return sendError(response, unicode(pe), 1)

        except Exception as e:
            log.exception("[userview_flexi] failed: %r" % e)
            Session.rollback()
            return sendError(response, e)

        finally:
            Session.close()
Esempio n. 11
0
    def getotp(self):
        '''
        This function is used to retrieve the current otp value for a given user or a given serial
        If the user has more than one token, the list of the tokens is returend.

        method:
            gettoken/getotp

        arguments:
            user    - username / loginname
            realm   - additional realm to match the user to a useridresolver
            serial  - the serial number of the token
            curTime - used ONY for internal testing: datetime.datetime object

        returns:
            JSON response
        '''

        getotp_active = config.get("linotpGetotp.active")
        if "True" != getotp_active:
            return sendError(response, "getotp is not activated.", 0)

        param = request.params
        ret = {}
        res = -1
        otpval = ""
        passw = ""
        serials = []

        try:

            serial = getParam(param, "serial", optional)
            user = getUserFromParam(param, optional)
            curTime = getParam(param, "curTime", optional)

            c.audit['user'] = user.login
            if "" != user.login:
                c.audit['realm'] = user.realm or getDefaultRealm()

            if serial:
                log.debug("[getotp] retrieving OTP value for token %s" %
                          serial)
            elif user.login:
                log.debug(
                    "[getotp] retrieving OTP value for token for user %s@%s" %
                    (user.login, user.realm))
                toks = getTokens4UserOrSerial(user, serial)
                tokennum = len(toks)
                if tokennum > 1:
                    log.debug(
                        "[getotp] The user has more than one token. Returning the list of serials"
                    )
                    res = -3
                    for token in toks:
                        serials.append(token.getSerial())
                elif 1 == tokennum:
                    serial = toks[0].getSerial()
                    log.debug(
                        "[getotp] retrieving OTP for token %s for user %s@%s" %
                        (serial, user.login, user.realm))
                else:
                    log.debug("[getotp] no token found for user %s@%s" %
                              (user.login, user.realm))
                    res = -4
            else:
                res = -5

            # if a serial was given or a unique serial could be received from the given user.
            if serial:
                max_count = checkPolicyPre('gettoken', 'max_count', param)
                log.debug("[getmultiotp] checkpolicypre returned %s" %
                          max_count)
                if max_count <= 0:
                    return sendError(
                        response,
                        "The policy forbids receiving OTP values for the token %s in this realm"
                        % serial, 1)

                (res, pin, otpval, passw) = getOtp(serial, curTime=curTime)

            c.audit['success'] = True

            if int(res) < 0:
                ret['result'] = False
                if -1 == otpval:
                    ret['description'] = "No Token with this serial number"
                if -2 == otpval:
                    ret['description'] = "This Token does not support the getOtp function"
                if -3 == otpval:
                    ret['description'] = "The user has more than one token"
                    ret['serials'] = serials
                if -4 == otpval:
                    ret['description'] = "No Token found for this user"
                if -5 == otpval:
                    ret['description'] = "you need to provide a user or a serial"
            else:
                ret['result'] = True
                ret['otpval'] = otpval
                ret['pin'] = pin
                ret['pass'] = passw

            Session.commit()
            return sendResult(response, ret, 0)

        except PolicyException as pe:
            log.error("[getotp] gettoken/getotp policy failed: %r" % pe)
            log.error("[getotp] %s" % traceback.format_exc())
            Session.rollback()
            return sendError(response, unicode(pe), 1)

        except Exception as e:
            log.error("[getotp] gettoken/getotp failed: %r" % e)
            log.error("[getotp] %s" % traceback.format_exc())
            Session.rollback()
            return sendError(response,
                             "gettoken/getotp failed: %s" % unicode(e), 0)

        finally:
            Session.close()
            log.debug('[getotp] done')
Esempio n. 12
0
    def checkstatus(self):
        """
        method:
            ocra/checkstatus

        description:
            Methode zur assynchronen Ueberpruefungen eines Challenge Response Valiadation requests

        arguments:

            * transactionid:  (required one of  - string - (hex))
                    Dies ist eine Transaktions-ID, die bei der Challenge ausgegeben wurde.

            * serial: (required one of  - string)
                    die Serien Nummer des OCRA Token

            * user: (required one of  - string)
                    die Benutzer eines Tokens

            required is one of (user,serial,transactionid)

        returns:

            A JSON response::

                {
                 "version": "LinOTP 2.4",
                 "jsonrpc": "2.0",
                 "result": {
                     "status": true,
                     "value": [
                             {
                             "serial": SERIENNUMMER1,
                             "transactionid": TRANSACTIONID1,
                             "received_tan": true,
                             "valid_tan": true,
                             "failcount": 0
                             },
                             {
                             "serial": SERIENNUMMER1,
                             "transactionid": TRANSACTIONID2,
                             "received_tan": false,
                             "valid_tan": false,
                             "failcount": 0
                             },
                             {
                             "serial": SERIENNUMMER2,
                             "transactionid": TRANSACTIONID3,
                             "received_tan": true,
                             "valid_tan": false,
                             "failcount": 2
                             },
                         ]
                     },
                 "id": 0
                 }

        exception:

        """
        res = {}
        description = 'ocra/checkstatus: check the token status - for assynchronous verification. Missing parameter: You need to provide one of the parameters "transactionid", "user" or "serial"'

        try:
            param = getLowerParams(request.params)
            log.debug("[checkstatus] check OCRA token status: %r" % param)

            checkPolicyPre('ocra', "status")

            transid = getParam(param, 'transactionid'   , optional)
            user = getUserFromParam(param, optional)
            #user   = getParam(param, 'user'          ,optional)
            serial = getParam(param, 'serial'          , optional)

            if transid is None and user.isEmpty() and serial is None:
                ## raise exception
                log.exception("[ocra/checkstatus] : missing transactionid, user or serial number for token")
                raise ParameterError("Usage: %s" % description, id=77)

            tokens = []
            serials = set()
            status = []

            if serial is not None:
                serials.add(serial)

            ## if we have a transaction, get serial from this challenge
            if transid is not None :
                ocraChallenge = None
                try:
                    ocraChallenge = OcraTokenClass.getTransaction(transid)
                except:
                    pass
                if ocraChallenge is not None:
                    serials.add(ocraChallenge.tokenserial)

            ## if we have a serial number of  token
            if len(serials) > 0:
                for serial in serials:
                    tokens.extend(getTokens4UserOrSerial(serial=serial))

            ## if we have a user
            if user.isEmpty() == False:
                try:
                    tokens.extend(getTokens4UserOrSerial(user=user))
                except:
                    log.warning("no token or user %r found!" % user)

            for token in tokens:
                if token.getType() == 'ocra':
                    challenges = []
                    if transid is None:
                        serial = token.getSerial()
                        challenges = OcraTokenClass.getTransactions4serial(serial)
                    else:
                        challenges.append(OcraTokenClass.getTransaction(transid))

                    for challenge in challenges:
                        stat = token.getStatus(challenge.transid)
                        if stat is not None and len(stat) > 0:
                            status.append(stat)

            res['values'] = status
            c.audit['success'] = res

            Session.commit()
            return sendResult(response, res, 1)

        except PolicyException as pe:
            log.exception("[checkstatus] policy failed: %r" % pe)
            Session.rollback()
            return sendError(response, unicode(pe))

        except Exception as exx:
            log.exception("[checkstatus] failed: %r" % exx)
            Session.rollback()
            return sendResult(response, unicode(exx), 0)

        finally:
            Session.close()
            log.debug('[ocra/checkstatus] done')
Esempio n. 13
0
    def import_users(self):
        """
        import users from a csv file into an dedicated sql resolver
        """

        try:

            params = self.request_params

            # -------------------------------------------------------------- --
            # processing required arguments
            try:

                data_file = request.files["file"]
                resolver_name = params["resolver"]

            except KeyError as exx:

                log.error("Missing parameter: %r", exx)
                raise ParameterError("Missing parameter: %r" % exx)

            if resolver_name == current_app.config["ADMIN_RESOLVER_NAME"]:
                raise DeleteForbiddenError(
                    f"default admin resolver {resolver_name} is not allowed "
                    "to be overwritten!")

            groupid = resolver_name

            # process file upload data

            data = data_file

            # -- ----------------------------------------------------------- --
            # In case of form post requests, it is a "instance" of FileStorage
            # i.e. the Filename is selected in the browser and the data is
            # transferred in an iframe.
            #     see: http://jquery.malsup.com/form/#sample4
            # -- ----------------------------------------------------------- --

            if isinstance(data_file, FileStorage):
                data = data_file.read()

            data = data.decode()

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

            # process the other arguments
            dryrun = boolean(params.get("dryrun", False))

            passwords_in_plaintext = boolean(
                params.get("passwords_in_plaintext", False))

            file_format = params.get("format", "csv")

            if file_format in ("password", "passwd"):

                column_mapping = {
                    "userid": 2,
                    "username": 0,
                    "phone": 8,
                    "mobile": 7,
                    "email": 9,
                    "surname": 5,
                    "givenname": 4,
                    "password": 1,
                }

                format_reader = PasswdFormatReader()

            elif file_format in ("csv"):

                skip_header = boolean(params.get("skip_header", False))
                if skip_header:
                    data = "\n".join(data.split("\n")[1:])

                column_mapping = {
                    "username": 0,
                    "userid": 1,
                    "surname": 2,
                    "givenname": 3,
                    "email": 4,
                    "phone": 5,
                    "mobile": 6,
                    "password": 7,
                }

                delimiter = str(params.get("delimiter", ","))
                quotechar = str(params.get("quotechar", '"'))

                format_reader = DefaultFormatReader()
                format_reader.delimiter = delimiter
                format_reader.quotechar = quotechar

                column_mapping = params.get("column_mapping", column_mapping)

            else:

                raise Exception("unspecified file foramt")

            # we have to convert the column_mapping back into an dict

            if isinstance(column_mapping, str):
                column_mapping = json.loads(column_mapping)

            # prevent overwrite of existing unmanaged resolver

            checkPolicyPre("system", "setResolver")

            resolvers = getResolverList()
            if resolver_name in resolvers:
                if not resolvers[resolver_name].get("readonly", False):
                    raise Exception("Unmanged resolver with same name: %r"
                                    " already exists!" % resolver_name)
            # -------------------------------------------------------------- --

            # feed the engine :)

            # use a LinOTP Database context for Sessions and Engine

            db_context = LinOTP_DatabaseContext(SqlSession=db.session,
                                                SqlEngine=db.engine)

            # define the import into an SQL database + resolver

            import_handler = SQLImportHandler(
                groupid=groupid,
                resolver_name=resolver_name,
                database_context=db_context,
            )

            # create the UserImporter with the required mapping

            user_import = UserImport(import_handler)

            user_import.set_mapping(column_mapping)

            # and run the data processing

            result = user_import.import_csv_users(
                data,
                dryrun=dryrun,
                format_reader=format_reader,
                passwords_in_plaintext=passwords_in_plaintext,
            )

            if dryrun:

                return sendResult(response, result)

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

            # create / extend target realm for the resolver

            resolver_spec = import_handler.get_resolver_spec()

            db.session.commit()

            return sendResult(response, result)

        except PolicyException as pexx:

            log.error("Error during user import: %r", pexx)

            db.session.rollback()

            return sendError(response, "%r" % pexx, 1)

        except Exception as exx:

            log.error("Error during user import: %r", exx)

            db.session.rollback()

            return sendError(response, exx)

        finally:
            log.debug("done")
Esempio n. 14
0
    def tokenview_flexi(self):
        """
        This function is used to fill the flexigrid.
        Unlike the complex /admin/show function, it only returns a
        simple array of the tokens.
        """
        param = request.params

        try:
            # serial  = getParam(param,"serial",optional)
            c.page = getParam(param, "page", optional)
            c.filter = getParam(param, "query", optional)
            c.qtype = getParam(param, "qtype", optional)
            c.sort = getParam(param, "sortname", optional)
            c.dir = getParam(param, "sortorder", optional)
            c.psize = getParam(param, "rp", optional)

            filter_all = None
            filter_realm = None
            user = User()

            if c.qtype == "loginname":
                if "@" in c.filter:
                    (login, realm) = c.filter.split("@")
                    user = User(login, realm)
                else:
                    user = User(c.filter)

            elif c.qtype == "all":
                filter_all = c.filter
            elif c.qtype == "realm":
                filter_realm = c.filter

            # check admin authorization
            res = checkPolicyPre("admin", "show", param, user=user)

            filterRealm = res["realms"]
            # check if policies are active at all
            # If they are not active, we are allowed to SHOW any tokens.
            pol = getAdminPolicies("show")
            # If there are no admin policies, we are allowed to see all realms
            if not pol["active"]:
                filterRealm = ["*"]

            # check if we only want to see ONE realm or see all realms we are allowerd to see.
            if filter_realm:
                if filter_realm in filterRealm or "*" in filterRealm:
                    filterRealm = [filter_realm]

            log.debug(
                "[tokenview_flexi] admin >%s< may display the following realms: %s" % (pol["admin"], pol["realms"])
            )
            log.debug("[tokenview_flexi] page: %s, filter: %s, sort: %s, dir: %s" % (c.page, c.filter, c.sort, c.dir))

            if c.page is None:
                c.page = 1
            if c.psize is None:
                c.psize = 20

            log.debug(
                "[tokenview_flexi] calling TokenIterator for user=%s@%s, filter=%s, filterRealm=%s"
                % (user.login, user.realm, filter_all, filterRealm)
            )
            c.tokenArray = TokenIterator(
                user, None, c.page, c.psize, filter_all, c.sort, c.dir, filterRealm=filterRealm
            )
            c.resultset = c.tokenArray.getResultSetInfo()
            # If we have chosen a page to big!
            lines = []
            for tok in c.tokenArray:
                lines.append(
                    {
                        "id": tok["LinOtp.TokenSerialnumber"],
                        "cell": [
                            tok["LinOtp.TokenSerialnumber"],
                            tok["LinOtp.Isactive"],
                            tok["User.username"],
                            tok["LinOtp.RealmNames"],
                            tok["LinOtp.TokenType"],
                            tok["LinOtp.FailCount"],
                            tok["LinOtp.TokenDesc"],
                            tok["LinOtp.MaxFail"],
                            tok["LinOtp.OtpLen"],
                            tok["LinOtp.CountWindow"],
                            tok["LinOtp.SyncWindow"],
                            tok["LinOtp.Userid"],
                            tok["LinOtp.IdResolver"],
                        ],
                    }
                )

            # We need to return 'page', 'total', 'rows'
            response.content_type = "application/json"
            res = {"page": int(c.page), "total": c.resultset["tokens"], "rows": lines}

            c.audit["success"] = True

            Session.commit()
            return json.dumps(res, indent=3)

        except PolicyException as pe:
            log.error("[tokenview_flexi] Error during checking policies: %r" % pe)
            log.error("[tokenview_flexi] %s" % traceback.format_exc())
            Session.rollback()
            return sendError(response, unicode(pe), 1)

        except Exception as e:
            log.error("[tokenview_flexi] failed: %r" % e)
            log.error("[tokenview_flexi] %s" % traceback.format_exc())
            Session.rollback()
            return sendError(response, e)

        finally:
            Session.close()
            log.debug("[tokenview_flexi] done")
Esempio n. 15
0
    def tokenview_flexi(self):
        '''
        This function is used to fill the flexigrid.
        Unlike the complex /admin/show function, it only returns a
        simple array of the tokens.
        '''
        param = request.params

        try:
            #serial  = getParam(param,"serial",optional)
            c.page = getParam(param, "page", optional)
            c.filter = getParam(param, "query", optional)
            c.qtype = getParam(param, "qtype", optional)
            c.sort = getParam(param, "sortname", optional)
            c.dir = getParam(param, "sortorder", optional)
            c.psize = getParam(param, "rp", optional)

            filter_all = None
            filter_realm = None
            user = User()

            if c.qtype == "loginname":
                if "@" in c.filter:
                    (login, realm) = c.filter.split("@")
                    user = User(login, realm)
                else:
                    user = User(c.filter)

            elif c.qtype == "all":
                filter_all = c.filter
            elif c.qtype == "realm":
                filter_realm = c.filter

            # check admin authorization
            res = checkPolicyPre('admin', 'show', param, user=user)

            filterRealm = res['realms']
            # check if policies are active at all
            # If they are not active, we are allowed to SHOW any tokens.
            pol = getAdminPolicies("show")
            # If there are no admin policies, we are allowed to see all realms
            if not pol['active']:
                filterRealm = ["*"]

            # check if we only want to see ONE realm or see all realms we are allowerd to see.
            if filter_realm:
                if filter_realm in filterRealm or '*' in filterRealm:
                    filterRealm = [filter_realm]

            log.debug(
                "[tokenview_flexi] admin >%s< may display the following realms: %s"
                % (pol['admin'], pol['realms']))
            log.debug(
                "[tokenview_flexi] page: %s, filter: %s, sort: %s, dir: %s" %
                (c.page, c.filter, c.sort, c.dir))

            if c.page is None:
                c.page = 1
            if c.psize is None:
                c.psize = 20

            log.debug(
                "[tokenview_flexi] calling TokenIterator for user=%s@%s, filter=%s, filterRealm=%s"
                % (user.login, user.realm, filter_all, filterRealm))
            c.tokenArray = TokenIterator(user,
                                         None,
                                         c.page,
                                         c.psize,
                                         filter_all,
                                         c.sort,
                                         c.dir,
                                         filterRealm=filterRealm)
            c.resultset = c.tokenArray.getResultSetInfo()
            # If we have chosen a page to big!
            lines = []
            for tok in c.tokenArray:
                # Arrange the table more helpfully.
                lines.append({
                    'id':
                    tok['LinOtp.TokenSerialnumber'],
                    'cell': [
                        tok['LinOtp.TokenSerialnumber'],
                        tok['LinOtp.TokenType'],
                        tok['LinOtp.TokenDesc'],
                        tok['LinOtp.Isactive'],
                        tok['User.username'],
                        tok['LinOtp.Userid'],
                        tok['LinOtp.FailCount'],
                        tok['LinOtp.MaxFail'],
                        tok['LinOtp.OtpLen'],
                        tok['LinOtp.CountWindow'],
                        tok['LinOtp.SyncWindow'],
                    ]
                })

            # We need to return 'page', 'total', 'rows'
            response.content_type = 'application/json'
            res = {
                "page": int(c.page),
                "total": c.resultset['tokens'],
                "rows": lines
            }

            c.audit['success'] = True

            Session.commit()
            return json.dumps(res, indent=3)

        except PolicyException as pe:
            log.error("[tokenview_flexi] Error during checking policies: %r" %
                      pe)
            log.error("[tokenview_flexi] %s" % traceback.format_exc())
            Session.rollback()
            return sendError(response, unicode(pe), 1)

        except Exception as e:
            log.error("[tokenview_flexi] failed: %r" % e)
            log.error("[tokenview_flexi] %s" % traceback.format_exc())
            Session.rollback()
            return sendError(response, e)

        finally:
            Session.close()
            log.debug("[tokenview_flexi] done")
Esempio n. 16
0
    def getotp(self):
        '''
        This function is used to retrieve the current otp value for a given user or a given serial
        If the user has more than one token, the list of the tokens is returend.

        method:
            gettoken/getotp

        arguments:
            user    - username / loginname
            realm   - additional realm to match the user to a useridresolver
            serial  - the serial number of the token
            curTime - used ONLY for internal testing: datetime.datetime object

        returns:
            JSON response
        '''

        getotp_active = config.get("linotpGetotp.active")
        if "True" != getotp_active:
            return sendError(response, "getotp is not activated.", 0)

        param = request.params
        ret = {}
        res = -1
        otpval = ""
        passw = ""
        serials = []

        try:

            serial = getParam(param, "serial", optional)
            user = getUserFromParam(param, optional)
            curTime = getParam(param, "curTime", optional)

            c.audit['user'] = user.login
            if "" != user.login:
                c.audit['realm'] = user.realm or getDefaultRealm()

            if serial:
                log.debug("[getotp] retrieving OTP value for token %s" % serial)
            elif user.login:
                log.debug("[getotp] retrieving OTP value for token for user %s@%s" % (user.login, user.realm))
                toks = getTokens4UserOrSerial(user, serial)
                tokennum = len(toks)
                if tokennum > 1:
                    log.debug("[getotp] The user has more than one token. Returning the list of serials")
                    res = -3
                    for token in toks:
                        serials.append(token.getSerial())
                elif 1 == tokennum:
                    serial = toks[0].getSerial()
                    log.debug("[getotp] retrieving OTP for token %s for user %s@%s" %
                                (serial, user.login, user.realm))
                else:
                    log.debug("[getotp] no token found for user %s@%s" % (user.login, user.realm))
                    res = -4
            else:
                res = -5

            # if a serial was given or a unique serial could be received from the given user.
            if serial:
                max_count = checkPolicyPre('gettoken', 'max_count', param)
                log.debug("[getmultiotp] checkpolicypre returned %s" % max_count)
                if max_count <= 0:
                    return sendError(response, "The policy forbids receiving OTP values for the token %s in this realm" % serial , 1)

                (res, pin, otpval, passw) = getOtp(serial, curTime=curTime)

            c.audit['success'] = True

            if int(res) < 0:
                ret['result'] = False
                if -1 == otpval:
                    ret['description'] = "No Token with this serial number"
                if -2 == otpval:
                    ret['description'] = "This Token does not support the getOtp function"
                if -3 == otpval:
                    ret['description'] = "The user has more than one token"
                    ret['serials'] = serials
                if -4 == otpval:
                    ret['description'] = "No Token found for this user"
                if -5 == otpval:
                    ret['description'] = "you need to provide a user or a serial"
            else:
                ret['result'] = True
                ret['otpval'] = otpval
                ret['pin'] = pin
                ret['pass'] = passw

            Session.commit()
            return sendResult(response, ret , 0)

        except PolicyException as pe:
            log.exception("[getotp] gettoken/getotp policy failed: %r" % pe)
            Session.rollback()
            return sendError(response, unicode(pe), 1)

        except Exception as e:
            log.exception("[getotp] gettoken/getotp failed: %r" % e)
            Session.rollback()
            return sendError(response, "gettoken/getotp failed: %s" % unicode(e), 0)

        finally:
            Session.close()
            log.debug('[getotp] done')
Esempio n. 17
0
    def tokeninfo(self):
        """
        this returns the contents of /admin/show?serial=xyz in an html format
        """
        param = self.request_params

        try:
            try:
                serial = param["serial"]
            except KeyError:
                raise ParameterError("Missing parameter: 'serial'")

            filterRealm = ""
            # check admin authorization
            res = checkPolicyPre("admin", "show", param)

            # check if policies are active at all
            # If they are not active, we are allowed to SHOW any tokens.
            filterRealm = ["*"]
            if res["active"] and res["realms"]:
                filterRealm = res["realms"]

            log.info(
                "[tokeninfo] admin >%s< may display the following realms:"
                " %s",
                res["admin"],
                filterRealm,
            )
            log.info("[tokeninfo] displaying tokens: serial: %s", serial)

            toks = TokenIterator(
                User("", "", ""), serial, filterRealm=filterRealm
            )

            # now row by row
            lines = []
            for tok in toks:
                lines.append(tok)
            if len(lines) > 0:
                c.tokeninfo = lines[0]
            else:
                c.tokeninfo = {}

            for k in c.tokeninfo:
                if "LinOtp.TokenInfo" == k:
                    try:
                        # Try to convert string to Dictionary
                        c.tokeninfo["LinOtp.TokenInfo"] = json.loads(
                            c.tokeninfo["LinOtp.TokenInfo"]
                        )
                    except BaseException:
                        pass

            return render("/manage/tokeninfo.mako").decode("utf-8")

        except PolicyException as pe:
            log.error("[tokeninfo] Error during checking policies: %r", pe)
            db.session.rollback()
            return sendError(response, pe, 1)

        except Exception as exx:
            log.error("[tokeninfo] failed! %r", exx)
            db.session.rollback()
            return sendError(response, exx)
Esempio n. 18
0
    def getmultiotp(self):
        '''
        This function is used to retrieve multiple otp values for a given user or a given serial
        If the user has more than one token, the list of the tokens is returend.

        method:
            gettoken/getmultiotp

        arguments:
            serial  - the serial number of the token
            count   - number of otp values to return
            curTime - used ONLY for internal testing: datetime.datetime object

        returns:
            JSON response
        '''

        getotp_active = config.get("linotpGetotp.active")
        if "True" != getotp_active:
            return sendError(response, "getotp is not activated.", 0)

        param = request.params
        ret = {}

        try:
            serial = getParam(param, "serial", required)
            count = int(getParam(param, "count", required))
            curTime = getParam(param, "curTime", optional)
            view = getParam(param, "view", optional)

            r1 = checkPolicyPre('admin', 'getotp', param)
            log.debug("[getmultiotp] admin-getotp returned %s" % r1)

            max_count = checkPolicyPre('gettoken', 'max_count', param)
            log.debug("[getmultiotp] checkpolicypre returned %s" % max_count)
            if count > max_count:
                count = max_count

            log.debug("[getmultiotp] retrieving OTP value for token %s" % serial)
            ret = get_multi_otp(serial, count=int(count), curTime=curTime)
            ret["serial"] = serial

            c.audit['success'] = True
            Session.commit()

            if view:
                c.ret = ret
                return render('/manage/multiotp_view.mako')
            else:
                return sendResult(response, ret , 0)

        except PolicyException as pe:
            log.exception("[getotp] gettoken/getotp policy failed: %r" % pe)
            Session.rollback()
            return sendError(response, unicode(pe), 1)

        except Exception as e:
            log.exception("[getmultiotp] gettoken/getmultiotp failed: %r" % e)
            Session.rollback()
            return sendError(response, "gettoken/getmultiotp failed: %s"
                             % unicode(e), 0)

        finally:
            Session.close()
            log.debug("[getmultiotp] done")
Esempio n. 19
0
    def userview_flexi(self):
        """
        This function is used to fill the flexigrid.
        Unlike the complex /admin/userlist function, it only returns a
        simple array of the tokens.
        """
        param = self.request_params

        try:

            c.page = param.get("page")
            c.filter = param.get("query")
            qtype = param.get("qtype")
            c.sort = param.get("sortname")
            c.dir = param.get("sortorder")
            c.psize = param.get("rp")
            c.realm = param.get("realm")

            user = getUserFromParam(param)
            # check admin authorization
            # check if we got a realm or resolver, that is ok!
            checkPolicyPre(
                "admin", "userlist", {"user": user.login, "realm": c.realm}
            )

            if c.filter == "":
                c.filter = "*"

            log.debug(
                "[userview_flexi] page: %s, filter: %s, sort: %s, dir: %s",
                c.page,
                c.filter,
                c.sort,
                c.dir,
            )

            if c.page is None:
                c.page = 1
            if c.psize is None:
                c.psize = 20

            c.userArray = getUserList(
                {qtype: c.filter, "realm": c.realm}, user
            )
            c.userNum = len(c.userArray)

            lines = []
            for u in c.userArray:
                # shorten the useridresolver, to get a better display value
                resolver_display = ""
                if "useridresolver" in u:
                    if len(u["useridresolver"].split(".")) > 3:
                        resolver_display = (
                            u["useridresolver"].split(".")[3]
                            + " ("
                            + u["useridresolver"].split(".")[1]
                            + ")"
                        )
                    else:
                        resolver_display = u["useridresolver"]
                lines.append(
                    {
                        "id": u["username"],
                        "cell": [
                            (u["username"]) if "username" in u else (""),
                            (resolver_display),
                            (u["surname"]) if "surname" in u else (""),
                            (u["givenname"]) if "givenname" in u else (""),
                            (u["email"]) if "email" in u else (""),
                            (u["mobile"]) if "mobile" in u else (""),
                            (u["phone"]) if "phone" in u else (""),
                            (u["userid"]) if "userid" in u else (""),
                        ],
                    }
                )

            # sorting
            reverse = False
            sortnames = {
                "username": 0,
                "useridresolver": 1,
                "surname": 2,
                "givenname": 3,
                "email": 4,
                "mobile": 5,
                "phone": 6,
                "userid": 7,
            }
            if c.dir == "desc":
                reverse = True

            lines = sorted(
                lines,
                key=lambda user: user["cell"][sortnames[c.sort]],
                reverse=reverse,
            )
            # end: sorting

            # reducing the page
            if c.page and c.psize:
                page = int(c.page)
                psize = int(c.psize)
                start = psize * (page - 1)
                end = start + psize
                lines = lines[start:end]

            # We need to return 'page', 'total', 'rows'
            res = {"page": int(c.page), "total": c.userNum, "rows": lines}

            g.audit["success"] = True

            db.session.commit()
            return sendResult(response, res)

        except PolicyException as pe:
            log.error(
                "[userview_flexi] Error during checking policies: %r", pe
            )
            db.session.rollback()
            return sendError(response, pe, 1)

        except Exception as exx:
            log.error("[userview_flexi] failed: %r", exx)
            db.session.rollback()
            return sendError(response, exx)
Esempio n. 20
0
    def setPin(self):
        """
        method:
            api/helpdesk/setPin

        description:
            This function sets the PIN of the token

        arguments:
            * serial     - required
            * pin        - optional - uses random pin instead

        returns:
            an array with the list of affected serial numbers

        """
        res = {}

        try:
            params = self.request_params

            serial = params.get("serial")
            if not serial:
                raise ParameterError("Missing parameter: 'serial'")

            tokens = getTokens4UserOrSerial(serial=serial)

            result = []

            for token in tokens:
                owner = get_token_owner(token)
                current_serial = token.getSerial()

                pin = params.get(
                    'pin', createRandomPin(owner, min_pin_length=6))

                # as the parameter pin in the params is evaluated by
                # the checkPolicyPre and checkPolicyPost we need to put the
                # parameter pin and current_serial into the params
                params['pin'] = pin
                params['serial'] = current_serial

                # set pin is done by the admin/set with the parameter pin
                checkPolicyPre(
                    'admin', method='set', param=params, user=owner)

                token.setPin(pin)

                # while in the pre checks for method='set' the post checks
                # for 'setPin' which is used to determin if a new pin has to
                # be generated

                res = checkPolicyPost(
                    'admin', 'setPin', param=params, user=owner)
                pin = res.get('new_pin', pin)

                info = {
                    'message': ('A new pin ${Pin} has been set for your '
                                'token: ${serial}'),
                    'Subject': 'new pin set for token ${serial}',
                    'Pin': pin,
                    'serial': current_serial,
                }

                notify_user(owner, 'setPin', info, required=True)

                result.append(serial)

            c.audit['success'] = True
            c.audit['info'] = result

            Session.commit()
            return sendResult(response, result)

        except PolicyException as pex:
            log.exception('[setPin] policy failed %r')
            Session.rollback()
            return sendError(response, pex, 1)

        except Exception as exx:
            log.exception('[setPin] error while setting pin')
            Session.rollback()
            return sendError(response, exx, 0)

        finally:
            Session.close()
Esempio n. 21
0
    def enroll(self):
        """
        method:
            api/helpdesk/enroll

        description:
            method to enroll a token as helpdesk

        arguments:
            * type: the token type, currently only 'email'
            * user: the new token owner
            * realm: (optional) the realm the user belongs to - used to identify the user

        returns:
            success as boolean

        """

        ret = False
        response_detail = {}

        params = self.request_params

        try:

            if 'user' not in params:
                raise ParameterError('missing parameter: user!')

            if 'type' not in params:
                raise ParameterError('missing parameter: type!')

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

            # determine token class

            token_cls_alias = params.get("type")
            lower_alias = token_cls_alias.lower()

            if lower_alias not in tokenclass_registry:
                raise TokenAdminError('admin/init failed: unknown token '
                                      'type %r' % token_cls_alias, id=1610)

            token_cls = tokenclass_registry.get(lower_alias)

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

            # call the token class hook in order to enrich/overwrite the
            # parameters

            helper_params = token_cls.get_helper_params_pre(params)
            params.update(helper_params)

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

            # fetch user from parameters.

            user = getUserFromParam(params)

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

            # create a new pin according to the policies

            if 'pin' not in params:
                params['pin'] = createRandomPin(user, min_pin_length=6)

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

            if 'otpkey' not in params:
                params['genkey'] = '1'

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

            # check admin authorization

            res = checkPolicyPre('admin', 'init', params, user=user)

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

            helper_params = token_cls.get_helper_params_post(params, user=user)
            params.update(helper_params)

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

            # create new serial

            th = TokenHandler()

            serial = th.genSerial(token_cls_alias)
            params['serial'] = serial

            log.info("[init] initialize token. user: %s, serial: %s"
                     % (user.login, serial))

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

            # scope_extension: we are in scope helpdesk
            # this is eg required to notify the emailtoken to use the
            # email from user if none is given as param

            params['::scope::'] = {
                'helpdesk': True,
                'user': user
            }

            (ret, token) = th.initToken(params, user)

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

            # different token types return different information on
            # initialization (e.g. otpkey, pairing_url, etc)

            initDetail = token.getInitDetail(params, user)
            response_detail.update(initDetail)

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

            # prepare data for audit

            if token is not None and ret is True:
                c.audit['serial'] = token.getSerial()
                c.audit['token_type'] = token.type

            c.audit['success'] = ret
            c.audit['user'] = user.login
            c.audit['realm'] = user.realm

            c.audit['action_detail'] += get_token_num_info()

            res = checkPolicyPost('admin', 'init', params, user=user)
            pin = res.get('new_pin', params['pin'])

            message = ("A new ${tokentype} token (${serial}) "
                       "with pin '${Pin}' "
                       "for ${givenname} ${surname} has been enrolled.")
            info = {
                'message': message,
                'Subject': 'New %s token enrolled' % token.type,
                'Pin': pin,
                'tokentype': token.type
            }
            info.update(response_detail)

            notify_user(user, 'enrollment', info, required=True)

            c.audit['action_detail'] += get_token_num_info()

            c.audit['success'] = ret

            return sendResult(response, ret)

        except PolicyException as pex:
            log.exception("Policy Exception while enrolling token")
            Session.rollback()
            return sendError(response, pex, 1)

        except Exception as exx:
            log.exception("Exception while enrolling token")
            Session.rollback()
            return sendError(response, exx, 1)
Esempio n. 22
0
    def getmultiotp(self):
        """
        This function is used to retrieve multiple otp values for a given user
        or a given serial. If the user has more than one token, the list of
        the tokens is returend.

        method:
            gettoken/getmultiotp

        arguments:
            serial  - the serial number of the token
            count   - number of otp values to return
            curTime - used ONLY for internal testing: datetime.datetime object

        returns:
            JSON response
        """

        getotp_active = boolean(getFromConfig("linotpGetotp.active", False))
        if not getotp_active:
            return sendError(response, "getotp is not activated.", 0)

        param = self.request_params
        ret = {}

        try:
            serial = getParam(param, "serial", required)
            count = int(getParam(param, "count", required))
            curTime = getParam(param, "curTime", optional)
            view = getParam(param, "view", optional)

            r1 = checkPolicyPre("admin", "getotp", param)
            log.debug("[getmultiotp] admin-getotp policy: %s", r1)

            max_count = checkPolicyPre("gettoken", "max_count", param)
            log.debug("[getmultiotp] maxcount policy: %s", max_count)
            if count > max_count:
                count = max_count

            log.debug("[getmultiotp] retrieving OTP value for token %s",
                      serial)
            ret = get_multi_otp(serial, count=int(count), curTime=curTime)
            ret["serial"] = serial

            g.audit["success"] = True
            db.session.commit()

            if view:
                c.ret = ret
                return render("/selfservice/multiotp_view.mako").decode(
                    "utf-8")
            else:
                return sendResult(response, ret, 0)

        except PolicyException as pe:
            log.error("[getotp] gettoken/getotp policy failed: %r", pe)
            db.session.rollback()
            return sendError(response, pe, 1)

        except Exception as exx:
            log.error("[getmultiotp] gettoken/getmultiotp failed: %r", exx)
            db.session.rollback()
            return sendError(response, "gettoken/getmultiotp failed: %r" % exx,
                             0)
Esempio n. 23
0
    def tokenview_flexi(self):
        '''
        This function is used to fill the flexigrid.
        Unlike the complex /admin/show function, it only returns a
        simple array of the tokens.
        '''
        param = self.request_params

        try:
            c.page = param.get("page")
            c.filter = param.get("query")
            c.qtype = param.get("qtype")
            c.sort = param.get("sortname")
            c.dir = param.get("sortorder")
            c.psize = param.get("rp")

            filter_all = None
            filter_realm = None
            user = User()

            if c.qtype == "loginname":

                # we take by default the given expression as a loginname,
                # especially if it contains a "*" wildcard.
                # it only might be more, a user and a realm, if there
                # is an '@' sign in the loginname and the part after the
                # last '@' sign is matching an existing realm

                user = User(login=c.filter)

                if "*" not in c.filter and "@" in c.filter:

                    login, _ , realm = c.filter.rpartition("@")

                    if realm.lower() in getRealms():
                        user = User(login, realm)
                        if not user.exists():
                            user = User(login=c.filter)

            elif c.qtype == "all":
                filter_all = c.filter

            elif c.qtype == "realm":
                filter_realm = c.filter

            # check admin authorization
            res = checkPolicyPre('admin', 'show', param , user=user)

            filterRealm = res['realms']
            # check if policies are active at all
            # If they are not active, we are allowed to SHOW any tokens.
            pol = getAdminPolicies("show")
            # If there are no admin policies, we are allowed to see all realms
            if not pol['active']:
                filterRealm = ["*"]

            # check if we only want to see ONE realm or see all realms we are allowerd to see.
            if filter_realm:
                if filter_realm in filterRealm or '*' in filterRealm:
                    filterRealm = [filter_realm]

            log.debug("[tokenview_flexi] admin >%s< may display the following realms: %s" % (pol['admin'], pol['realms']))
            log.debug("[tokenview_flexi] page: %s, filter: %s, sort: %s, dir: %s" % (c.page, c.filter, c.sort, c.dir))

            if c.page is None:
                c.page = 1
            if c.psize is None:
                c.psize = 20

            log.debug("[tokenview_flexi] calling TokenIterator for user=%s@%s, filter=%s, filterRealm=%s"
                        % (user.login, user.realm, filter_all, filterRealm))
            c.tokenArray = TokenIterator(user, None, c.page , c.psize, filter_all, c.sort, c.dir, filterRealm=filterRealm)
            c.resultset = c.tokenArray.getResultSetInfo()
            # If we have chosen a page to big!
            lines = []
            for tok in c.tokenArray:
                lines.append(
                    {'id' : tok['LinOtp.TokenSerialnumber'],
                     'cell': [
                            tok['LinOtp.TokenSerialnumber'],
                            tok['LinOtp.Isactive'],
                            tok['User.username'],
                            tok['LinOtp.RealmNames'],
                            tok['LinOtp.TokenType'],
                            tok['LinOtp.FailCount'],
                            tok['LinOtp.TokenDesc'],
                            tok['LinOtp.MaxFail'],
                            tok['LinOtp.OtpLen'],
                            tok['LinOtp.CountWindow'],
                            tok['LinOtp.SyncWindow'],
                            tok['LinOtp.Userid'],
                            tok['LinOtp.IdResClass'].split('.')[-1],
                            ]
                    }
                    )

            # We need to return 'page', 'total', 'rows'
            res = { "page": int(c.page),
                "total": c.resultset['tokens'],
                "rows": lines }

            c.audit['success'] = True

            Session.commit()
            # The flexi handler should support std LinOTP output
            return sendResult(response, res)

        except PolicyException as pe:
            log.exception("[tokenview_flexi] Error during checking policies: %r" % pe)
            Session.rollback()
            return sendError(response, unicode(pe), 1)

        except Exception as e:
            log.exception("[tokenview_flexi] failed: %r" % e)
            Session.rollback()
            return sendError(response, e)

        finally:
            Session.close()
Esempio n. 24
0
    def userview_flexi(self):
        '''
        This function is used to fill the flexigrid.
        Unlike the complex /admin/userlist function, it only returns a
        simple array of the tokens.
        '''
        param = request.params

        try:
            #serial  = getParam(param,"serial",optional)
            c.page = getParam(param, "page", optional)
            c.filter = getParam(param, "query", optional)
            qtype = getParam(param, "qtype", optional)
            c.sort = getParam(param, "sortname", optional)
            c.dir = getParam(param, "sortorder", optional)
            c.psize = getParam(param, "rp", optional)
            c.realm = getParam(param, "realm", optional)

            user = getUserFromParam(param, optional)
            # check admin authorization
            # check if we got a realm or resolver, that is ok!
            checkPolicyPre('admin', 'userlist', { 'user': user.login,
                                                 'realm' : c.realm },
                           context=self.request_context)

            if c.filter == "":
                c.filter = "*"

            log.debug("[userview_flexi] page: %s, filter: %s, sort: %s, dir: %s"
                      % (c.page, c.filter, c.sort, c.dir))

            if c.page is None:
                c.page = 1
            if c.psize is None:
                c.psize = 20

            c.userArray = getUserList({ qtype:c.filter,
                                       'realm':c.realm }, user)
            c.userNum = len(c.userArray)

            lines = []
            for u in c.userArray:
                # shorten the useridresolver, to get a better display value
                resolver_display = ""
                if "useridresolver" in u:
                    if len(u['useridresolver'].split(".")) > 3:
                        resolver_display = u['useridresolver'].split(".")[3] + " (" + u['useridresolver'].split(".")[1] + ")"
                    else:
                        resolver_display = u['useridresolver']
                lines.append(
                    { 'id' : u['username'],
                        'cell': [
                            (u['username']) if u.has_key('username') else (""),
                            (resolver_display),
                            (u['surname']) if u.has_key('surname') else (""),
                            (u['givenname']) if u.has_key('givenname') else (""),
                            (u['email']) if u.has_key('email') else (""),
                            (u['mobile']) if u.has_key('mobile') else (""),
                            (u['phone']) if u.has_key('phone') else (""),
                            (u['userid']) if u.has_key('userid') else (""),
                             ]
                    }
                    )

            # sorting
            reverse = False
            sortnames = { 'username' : 0, 'useridresolver' : 1,
                    'surname' : 2, 'givenname' : 3, 'email' : 4,
                    'mobile' :5, 'phone' : 6, 'userid' : 7 }
            if c.dir == "desc":
                reverse = True

            lines = sorted(lines,
                           key=lambda user: user['cell'][sortnames[c.sort]],
                           reverse=reverse,
                           cmp=unicode_compare)
            # end: sorting

            # reducing the page
            if c.page and c.psize:
                page = int(c.page)
                psize = int(c.psize)
                start = psize * (page - 1)
                end = start + psize
                lines = lines[start:end]

            # We need to return 'page', 'total', 'rows'
            response.content_type = 'application/json'
            res = { "page": int(c.page),
                "total": c.userNum,
                "rows": lines }

            c.audit['success'] = True

            Session.commit()
            return sendResult(response, res)

        except PolicyException as pe:
            log.exception("[userview_flexi] Error during checking policies: %r" % pe)
            Session.rollback()
            return sendError(response, unicode(pe), 1)

        except Exception as e:
            log.exception("[userview_flexi] failed: %r" % e)
            Session.rollback()
            return sendError(response, e)

        finally:
            Session.close()
            log.debug('[userview_flexi] done')
Esempio n. 25
0
File: audit.py Progetto: ae-m/LinOTP
    def search(self):

        '''
        This functions searches within the audit trail
        It returns the audit information for the given search pattern

        method:
            audit/search

        arguments:
            key, value pairs as search patterns.

            * outform - optional: if set to "csv", than the token list will be
                        given in CSV


            or: Usually the key=values will be locally AND concatenated.
                it a parameter or=true is passed, the filters will
                be OR concatenated.

            The Flexigrid provides us the following parameters:
                ('page', u'1'), ('rp', u'25'),
                ('sortname', u'number'),
                ('sortorder', u'asc'),
                ('query', u''), ('qtype', u'serial')]
        returns:
            JSON response or csv format
        '''

        param = {}
        try:
            param.update(request.params)

            log.debug("[search] params: %s" % param)


            checkPolicyPre('audit', 'view', {})

            log.debug("[search] params %r" % param)

            # remove the param outform (and other parameters that should not
            # be used for search!
            search_params = {}
            search_params.update(param)
            for key in ["outform", 'delimiter']: 
                if key in search_params:
                    del search_params[key]

            output_format = param.get("outform", 'json') or 'json'
            delimiter = param.get('delimiter', ',') or ','

            audit_iterator = None

            log.debug("[search] search params %r" % search_params)
            audit_query = AuditQuery(search_params, audit)

            if output_format == "csv":
                filename = "linotp-audit.csv"
                response.content_type = "application/force-download"
                response.headers['Content-disposition'] = (
                                        'attachment; filename=%s' % filename)

                audit_iterator = CSVAuditIterator(audit_query, delimiter)
            else:
                response.content_type = 'application/json'
                audit_iterator = JSONAuditIterator(audit_query)

            c.audit['success'] = True
            Session.commit()
            return audit_iterator

        except PolicyException as pe:
            log.error("[getotp] gettoken/getotp policy failed: %r" % pe)
            log.error("[getotp] %s" % traceback.format_exc())
            Session.rollback()
            return sendError(response, unicode(pe), 1)

        except Exception as e:
            log.error("[search] audit/search failed: %r" % e)
            log.error("[search] %s" % traceback.format_exc())
            Session.rollback()
            return sendError(response, "audit/search failed: %s" % unicode(e), 0)

        finally:
            Session.close()
            log.debug('[search] done')
Esempio n. 26
0
    def userview_flexi(self):
        '''
        This function is used to fill the flexigrid.
        Unlike the complex /admin/userlist function, it only returns a
        simple array of the tokens.
        '''
        param = request.params

        try:
            #serial  = getParam(param,"serial",optional)
            c.page = getParam(param, "page", optional)
            c.filter = getParam(param, "query", optional)
            qtype = getParam(param, "qtype", optional)
            c.sort = getParam(param, "sortname", optional)
            c.dir = getParam(param, "sortorder", optional)
            c.psize = getParam(param, "rp", optional)
            c.realm = getParam(param, "realm", optional)

            user = getUserFromParam(param, optional)
            # check admin authorization
            # check if we got a realm or resolver, that is ok!
            checkPolicyPre('admin', 'userlist', {
                'user': user.login,
                'realm': c.realm
            })

            if c.filter == "":
                c.filter = "*"

            log.debug(
                "[userview_flexi] page: %s, filter: %s, sort: %s, dir: %s" %
                (c.page, c.filter, c.sort, c.dir))

            if c.page is None:
                c.page = 1
            if c.psize is None:
                c.psize = 20

            c.userArray = getUserList({
                qtype: c.filter,
                'realm': c.realm
            }, user)
            c.userNum = len(c.userArray)

            lines = []
            for u in c.userArray:
                # shorten the useridresolver, to get a better display value
                resolver_display = ""
                if "useridresolver" in u:
                    if len(u['useridresolver'].split(".")) > 3:
                        resolver_display = u['useridresolver'].split(".")[
                            3] + " (" + u['useridresolver'].split(".")[1] + ")"
                    else:
                        resolver_display = u['useridresolver']
                # Arrange the table more helpfully.
                lines.append({
                    'id':
                    u['username'],
                    'cell': [
                        (u['username']) if u.has_key('username') else (""),
                        (u['givenname']) if u.has_key('givenname') else (""),
                        (u['surname']) if u.has_key('surname') else (""),
                        (u['email']) if u.has_key('email') else (""),
                        (u['userid']) if u.has_key('userid') else (""),
                    ]
                })

            log.debug("[userview_flexi] Elements in c.userArray: %s" %
                      len(c.userArray))
            # sorting
            reverse = False
            sortnames = {
                'username': 0,
                'givenname': 1,
                'surname': 2,
                'email': 3,
                'userid': 4
            }
            if c.dir == "desc":
                reverse = True

            lines = sorted(lines,
                           key=lambda user: user['cell'][sortnames[c.sort]],
                           reverse=reverse,
                           cmp=unicode_compare)
            # end: sorting

            # reducing the page
            if c.page and c.psize:
                page = int(c.page)
                psize = int(c.psize)
                start = psize * (page - 1)
                end = start + psize
                lines = lines[start:end]

            # We need to return 'page', 'total', 'rows'
            response.content_type = 'application/json'
            res = {"page": int(c.page), "total": c.userNum, "rows": lines}

            c.audit['success'] = True

            Session.commit()
            return json.dumps(res, indent=3)

        except PolicyException as pe:
            log.error("[userview_flexi] Error during checking policies: %r" %
                      pe)
            log.error("[userview_flexi] %s" % traceback.format_exc())
            Session.rollback()
            return sendError(response, unicode(pe), 1)

        except Exception as e:
            log.error("[userview_flexi] failed: %r" % e)
            log.error("[userview_flexi] %s" % traceback.format_exc())
            Session.rollback()
            return sendError(response, e)

        finally:
            Session.close()
            log.debug('[userview_flexi] done')
Esempio n. 27
0
    def getotp(self):
        '''
        This function is used to retrieve the current otp value for a given
        user or a given serial. If the user has more than one token, the list
        of the tokens is returend.

        method:
            gettoken/getotp

        arguments:
            user    - username / loginname
            realm   - additional realm to match the user to a useridresolver
            serial  - the serial number of the token
            curTime - used ONLY for internal testing: datetime.datetime object

        returns:
            JSON response
        '''

        getotp_active = config.get("GETOTP_ENABLED")
        if not getotp_active:
            return sendError(response, "getotp is not activated.", 0)

        param = self.request_params
        ret = {}
        res = -1
        otpval = ""
        passw = ""
        serials = []

        try:

            serial = getParam(param, "serial", optional)
            user = getUserFromParam(param)
            curTime = getParam(param, "curTime", optional)

            g.audit['user'] = user.login
            if "" != user.login:
                g.audit['realm'] = user.realm or getDefaultRealm()

            if serial:
                log.debug("[getotp] retrieving OTP value for token %s", serial)

            elif user.login:
                log.debug(
                    "[getotp] retrieving OTP value for token for user "
                    "%s@%s", user.login, user.realm)

                toks = getTokens4UserOrSerial(user, serial)
                tokennum = len(toks)

                if tokennum > 1:
                    log.debug("[getotp] The user has more than one token."
                              "Returning the list of serials")
                    res = -3
                    for token in toks:
                        serials.append(token.getSerial())
                elif 1 == tokennum:
                    serial = toks[0].getSerial()
                    log.debug(
                        "[getotp] retrieving OTP for token %s for user"
                        " %s@%s", serial, user.login, user.realm)
                else:
                    log.debug("[getotp] no token found for user %s@%s",
                              user.login, user.realm)
                    res = -4
            else:
                res = -5

            # if a serial was given or a unique serial could be
            # received from the given user.

            if serial:
                max_count = checkPolicyPre('gettoken', 'max_count', param)
                log.debug("[getmultiotp] max_count policy: %s", max_count)
                if max_count <= 0:
                    return sendError(
                        response, "The policy forbids receiving"
                        " OTP values for the token %s in "
                        "this realm" % serial, 1)

                (res, pin, otpval, passw) = getOtp(serial, curTime=curTime)

            g.audit['success'] = True

            if int(res) < 0:
                ret['result'] = False
                if -1 == otpval:
                    ret['description'] = "No Token with this serial number"
                if -2 == otpval:
                    ret['description'] = ("This Token does not support the"
                                          " getOtp function")
                if -3 == otpval:
                    ret['description'] = "The user has more than one token"
                    ret['serials'] = serials
                if -4 == otpval:
                    ret['description'] = "No Token found for this user"
                if -5 == otpval:
                    ret['description'] = ("you need to provide a user or "
                                          "a serial")
            else:
                ret['result'] = True
                ret['otpval'] = otpval
                ret['pin'] = pin
                ret['pass'] = passw

            db.session.commit()
            return sendResult(response, ret, 0)

        except PolicyException as pe:
            log.exception("[getotp] gettoken/getotp policy failed: %r", pe)
            db.session.rollback()
            return sendError(response, str(pe), 1)

        except Exception as exx:
            log.exception("[getotp] gettoken/getotp failed: %r", exx)
            db.session.rollback()
            return sendError(response, "gettoken/getotp failed: %s" % exx, 0)
Esempio n. 28
0
    def userview_flexi(self):
        """
        This function is used to fill the flexigrid.
        Unlike the complex /admin/userlist function, it only returns a
        simple array of the tokens.
        """
        param = request.params

        try:
            # serial  = getParam(param,"serial",optional)
            c.page = getParam(param, "page", optional)
            c.filter = getParam(param, "query", optional)
            qtype = getParam(param, "qtype", optional)
            c.sort = getParam(param, "sortname", optional)
            c.dir = getParam(param, "sortorder", optional)
            c.psize = getParam(param, "rp", optional)
            c.realm = getParam(param, "realm", optional)

            user = getUserFromParam(param, optional)
            # check admin authorization
            # check if we got a realm or resolver, that is ok!
            checkPolicyPre("admin", "userlist", {"user": user.login, "realm": c.realm})

            if c.filter == "":
                c.filter = "*"

            log.debug("[userview_flexi] page: %s, filter: %s, sort: %s, dir: %s" % (c.page, c.filter, c.sort, c.dir))

            if c.page is None:
                c.page = 1
            if c.psize is None:
                c.psize = 20

            c.userArray = getUserList({qtype: c.filter, "realm": c.realm}, user)
            c.userNum = len(c.userArray)

            lines = []
            for u in c.userArray:
                # shorten the useridresolver, to get a better display value
                resolver_display = ""
                if "useridresolver" in u:
                    if len(u["useridresolver"].split(".")) > 3:
                        resolver_display = (
                            u["useridresolver"].split(".")[3] + " (" + u["useridresolver"].split(".")[1] + ")"
                        )
                    else:
                        resolver_display = u["useridresolver"]
                lines.append(
                    {
                        "id": u["username"],
                        "cell": [
                            (u["username"]) if u.has_key("username") else (""),
                            (resolver_display),
                            (u["surname"]) if u.has_key("surname") else (""),
                            (u["givenname"]) if u.has_key("givenname") else (""),
                            (u["email"]) if u.has_key("email") else (""),
                            (u["mobile"]) if u.has_key("mobile") else (""),
                            (u["phone"]) if u.has_key("phone") else (""),
                            (u["userid"]) if u.has_key("userid") else (""),
                        ],
                    }
                )

            # sorting
            reverse = False
            sortnames = {
                "username": 0,
                "useridresolver": 1,
                "surname": 2,
                "givenname": 3,
                "email": 4,
                "mobile": 5,
                "phone": 6,
                "userid": 7,
            }
            if c.dir == "desc":
                reverse = True

            lines = sorted(
                lines, key=lambda user: user["cell"][sortnames[c.sort]], reverse=reverse, cmp=unicode_compare
            )
            # end: sorting

            # reducing the page
            if c.page and c.psize:
                page = int(c.page)
                psize = int(c.psize)
                start = psize * (page - 1)
                end = start + psize
                lines = lines[start:end]

            # We need to return 'page', 'total', 'rows'
            response.content_type = "application/json"
            res = {"page": int(c.page), "total": c.userNum, "rows": lines}

            c.audit["success"] = True

            Session.commit()
            return json.dumps(res, indent=3)

        except PolicyException as pe:
            log.error("[userview_flexi] Error during checking policies: %r" % pe)
            log.error("[userview_flexi] %s" % traceback.format_exc())
            Session.rollback()
            return sendError(response, unicode(pe), 1)

        except Exception as e:
            log.error("[userview_flexi] failed: %r" % e)
            log.error("[userview_flexi] %s" % traceback.format_exc())
            Session.rollback()
            return sendError(response, e)

        finally:
            Session.close()
            log.debug("[userview_flexi] done")
Esempio n. 29
0
    def userview_flexi(self):
        '''
        This function is used to fill the flexigrid.
        Unlike the complex /admin/userlist function, it only returns a
        simple array of the tokens.
        '''
        param = self.request_params

        try:

            c.page = param.get("page")
            c.filter = param.get("query")
            qtype = param.get("qtype")
            c.sort = param.get("sortname")
            c.dir = param.get("sortorder")
            c.psize = param.get("rp")
            c.realm = param.get("realm")

            user = getUserFromParam(param)
            # check admin authorization
            # check if we got a realm or resolver, that is ok!
            checkPolicyPre('admin', 'userlist', {
                'user': user.login,
                'realm': c.realm
            })

            if c.filter == "":
                c.filter = "*"

            log.debug(
                "[userview_flexi] page: %s, filter: %s, sort: %s, dir: %s" %
                (c.page, c.filter, c.sort, c.dir))

            if c.page is None:
                c.page = 1
            if c.psize is None:
                c.psize = 20

            c.userArray = getUserList({
                qtype: c.filter,
                'realm': c.realm
            }, user)
            c.userNum = len(c.userArray)

            lines = []
            for u in c.userArray:
                # shorten the useridresolver, to get a better display value
                resolver_display = ""
                if "useridresolver" in u:
                    if len(u['useridresolver'].split(".")) > 3:
                        resolver_display = u['useridresolver'].split(".")[
                            3] + " (" + u['useridresolver'].split(".")[1] + ")"
                    else:
                        resolver_display = u['useridresolver']
                lines.append({
                    'id':
                    u['username'],
                    'cell': [
                        (u['username']) if 'username' in u else (""),
                        (resolver_display),
                        (u['surname']) if 'surname' in u else (""),
                        (u['givenname']) if 'givenname' in u else (""),
                        (u['email']) if 'email' in u else (""),
                        (u['mobile']) if 'mobile' in u else (""),
                        (u['phone']) if 'phone' in u else (""),
                        (u['userid']) if 'userid' in u else (""),
                    ]
                })

            # sorting
            reverse = False
            sortnames = {
                'username': 0,
                'useridresolver': 1,
                'surname': 2,
                'givenname': 3,
                'email': 4,
                'mobile': 5,
                'phone': 6,
                'userid': 7
            }
            if c.dir == "desc":
                reverse = True

            lines = sorted(lines,
                           key=lambda user: user['cell'][sortnames[c.sort]],
                           reverse=reverse)
            # end: sorting

            # reducing the page
            if c.page and c.psize:
                page = int(c.page)
                psize = int(c.psize)
                start = psize * (page - 1)
                end = start + psize
                lines = lines[start:end]

            # We need to return 'page', 'total', 'rows'
            res = {"page": int(c.page), "total": c.userNum, "rows": lines}

            c.audit['success'] = True

            Session.commit()
            return sendResult(response, res)

        except PolicyException as pe:
            log.exception(
                "[userview_flexi] Error during checking policies: %r" % pe)
            Session.rollback()
            return sendError(response, str(pe), 1)

        except Exception as e:
            log.exception("[userview_flexi] failed: %r" % e)
            Session.rollback()
            return sendError(response, e)

        finally:
            Session.close()
Esempio n. 30
0
    def request(self):
        """
        method:
            ocra/request

        description:
            request a challenge for a user or for a serial number (token).

        arguments:
            * serial: (required - string)
              Serial number of the token, for which a challenge should
              be generated (either serial or user is required)

            * user: (required  - string)
              The user for whose token a challenge should be generated
              If the user has more than one token, an error is returend.
              (either serial or user is required)

            * data: (required - String: URLendoced)
              These are the display data, that can be used to generate the challenge

        remark:
            the app will report a wrong qrcode, if the policy::

                {'authentication' : qrtanurl=https://localhost }

            is not defined !!

        returns:

            A JSON respone::

                        {
                            "version": "LinOTP 2.4",
                            "jsonrpc": "2.0",
                            "result": {
                                "status": true,
                                "value": false,
                            },
                            "detail": {
                                    "transactionid" : TRANSAKTIONSID,
                                    "data" : DATAOBJECT,
                            }
                        }

            * transactionid:
              This is the transaction ID, that is used later for
              verifying the Return code /TAN.

            * data:
              This is an object (URL) which can be used to generate a
              QR-Code to be displayed to the QRTAN App
        """
        res = {}
        description = 'ocra/request: request a challenge for a given user or token (serial). You must either provide a parameter "user" or a parameter "serial".'
        dataobj = ""

        try:
            param = getLowerParams(request.params)
            log.info("[request] saving default configuration: %r" % param)

            checkPolicyPre('ocra', "request")

            serial = getParam(param, 'serial', optional)
            user = getUserFromParam(param, optional)

            if user.isEmpty() and serial is None:
                ## raise exception
                log.exception("[request] user or serial is required")
                raise ParameterError("Usage: %s" % description, id=77)

            message = getParam(param, 'data'  , optional)
            if message is None:
                message = ''

            ## ocra token
            tokens = getTokens4UserOrSerial(user, serial)

            if len(tokens) > 1 :
                error = ('More than one token found: unable to create challenge '
                        'for (u:%r,s:%r)!' % (user, serial))
                log.error(error)
                raise Exception(error)

            if len(tokens) == 0:
                error = ('No token found: unable to create challenge for'
                          ' (u:%r,s:%r)!' % (user, serial))
                log.error(error)
                raise Exception(error)

            ocra = tokens[0]
            (transId, challenge, res, url) = ocra.challenge(message)

            u = urlencode({'u':str(url.encode("utf-8"))})

            uInfo = {'tr': transId, 'ch' : challenge,
                      'me': str(message.encode("utf-8")), 'u': u[2:]}
            detail = {"transactionid"   : transId,
                      'challenge'       : challenge,
                      'message'         : str(message.encode("utf-8")),
                      'url'             : str(url.encode("utf-8")),
                     }

            ## create the app_url from the data'''
            dataobj = 'lseqr://req?%s' % (str(urlencode(uInfo)))

            ## append the signature to the url '''
            signature = {'si' : ocra.signData(dataobj)}
            uInfo['si'] = signature
            dataobj = '%s&%s' % (dataobj, str(urlencode(signature)))

            detail["data"] = dataobj

            c.audit['success'] = res
            #c.audit['info'] += "%s=%s, " % (k, value)

            Session.commit()
            qr = getParam(param, 'qr', optional)
            if qr is not None:
                param['alt'] = detail
                return sendQRImageResult(response, dataobj, param)
            else:
                return sendResult(response, res, 1, opt=detail)

        except PolicyException as pe:
            log.exception("[request] policy failed: %r" % pe)
            Session.rollback()
            return sendError(response, unicode(pe))

        except Exception as exx:
            log.exception("[request] failed: %r" % exx)
            Session.rollback()
            return sendError(response, unicode(exx))

        finally:
            Session.close()
            log.debug("[request] done")
Esempio n. 31
0
    def search(self):
        '''
        This functions searches within the audit trail
        It returns the audit information for the given search pattern

        method:
            audit/search

        arguments:
            key, value pairs as search patterns.

            * outform - optional: if set to "csv", than the token list will be
                        given in CSV


            or: Usually the key=values will be locally AND concatenated.
                it a parameter or=true is passed, the filters will
                be OR concatenated.

            The Flexigrid provides us the following parameters:
                ('page', u'1'), ('rp', u'25'),
                ('sortname', u'number'),
                ('sortorder', u'asc'),
                ('query', u''), ('qtype', u'serial')]
        returns:
            JSON response or csv format
        '''

        try:
            log.debug("[search] params: %s" % self.request_params)

            checkPolicyPre('audit', 'view', {})

            # remove the param outform (and other parameters that should not
            # be used for search!
            search_params = self.request_params.copy()
            for key in ["outform", 'delimiter']:
                if key in search_params:
                    del search_params[key]

            output_format = self.request_params.get("outform",
                                                    'json') or 'json'

            streamed_response = None

            audit_obj = current_app.audit_obj
            audit_query = AuditQuery(search_params, audit_obj)

            if output_format == "csv":
                delimiter = self.request_params.get('delimiter', ',') or ','

                streamed_response = Response(stream_with_context(
                    CSVAuditIterator(audit_query, delimiter)),
                                             mimetype='text/csv')
                streamed_response.headers.set('Content-disposition',
                                              'attachment',
                                              filename='linotp-audit.csv')

            else:
                streamed_response = Response(stream_with_context(
                    JSONAuditIterator(audit_query)),
                                             mimetype='application/json')

            g.audit['success'] = True
            db.session.commit()

            return streamed_response

        except PolicyException as pe:
            log.exception("[getotp] gettoken/getotp policy failed: %r" % pe)
            db.session.rollback()
            return sendError(response, str(pe), 1)

        except Exception as e:
            log.exception("[search] audit/search failed: %r" % e)
            db.session.rollback()
            return sendError(response, "audit/search failed", 0)
Esempio n. 32
0
    def calculateOtp(self):
        '''

        '''
        from linotp.lib.crypt import kdf2
        from linotp.lib.ocra import OcraSuite
        from datetime import datetime

        from urlparse import urlparse
        from urlparse import parse_qs

        res = {}
        #description = 'ocra/calculateOtp: calculate the first otp from the given init2 response '

        try:
            params = getLowerParams(request.params)
            log.debug("[calculateOtp]: %r" % params)

            checkPolicyPre('ocra', "calcOTP")

            sharedsecret = params.get('sharedsecret')
            activationcode = params.get('activationcode')
            nonce = params.get('nonce')
            ocrasuite = params.get('ocrasuite')
            challenge = params.get('challenge')
            counter = params.get('counter')
            ocrapin = params.get('ocrapin')

            nonce3 = params.get('no')
            ocrasuite3 = params.get('os')
            #serial3         = params.get('se')

            challenge = params.get('challenge')
            counter = params.get('counter')
            ocrapin = params.get('ocrapin')
            init1 = params.get('init1')
            init2 = params.get('init2')

            ## parse init1 '''
            if init1 is not None:
                ## now parse the appurl for the ocrasuite '''
                uri = urlparse(init1.replace('lseqr://', 'http://'))
                qs = uri.query
                qdict = parse_qs(qs)

                ocrasuite2 = qdict.get('os', None)
                if ocrasuite2 is not None and len(ocrasuite2) > 0:
                    ocrasuite2 = ocrasuite2[0]

                if ocrasuite is None:
                    ocrasuite = ocrasuite2

                sharedsecret2 = qdict.get('sh', None)
                if sharedsecret2 is not None and len(sharedsecret2) > 0:
                    sharedsecret2 = sharedsecret2[0]

                if sharedsecret is None:
                    sharedsecret = sharedsecret2

            ## parse init1
            if init2 is not None:
                ## now parse the appurl for the ocrasuite
                uri = urlparse(init2.replace('lseqr://', 'http://'))
                qs = uri.query
                qdict = parse_qs(qs)

                challenge2 = qdict.get('ch', None)
                if challenge2 is not None and len(challenge2) > 0:
                    challenge2 = challenge2[0]
                if challenge is None:
                    challenge = challenge2

                nonce2 = qdict.get('no', None)
                if nonce2 is not None and len(nonce2) > 0:
                    nonce2 = nonce2[0]
                if nonce is None:
                    nonce = nonce2

            if ocrapin is None:
                ocrapin = ''
            if counter is None:
                counter = 0

            if nonce3 is not None:
                nonce = unicode(nonce3)

            if ocrasuite3 is not None:
                ocrasuite = unicode(ocrasuite3)

            ##  now we have all in place for the key derivation to create the new key
            ##     sharedsecret, activationcode and nonce
            key_len = 20
            if ocrasuite.find('-SHA256'):
                key_len = 32
            elif ocrasuite.find('-SHA512'):
                key_len = 64

            if sharedsecret is not None:
                sharedsecret = unicode(sharedsecret)
            if nonce is not None:
                nonce = unicode(nonce)
            if activationcode is not None:
                activationcode = unicode(activationcode)

            newkey = kdf2(sharedsecret, nonce, activationcode, len=key_len)
            ## hnewkey = binascii.hexlify(newkey)
            ocra = OcraSuite(ocrasuite)

            param = {}
            param['C'] = int(counter)
            param['Q'] = unicode(challenge)
            param['P'] = unicode(ocrapin)
            param['S'] = ''
            if ocra.T is not None:
                ## Default value for G is 1M, i.e., time-step size is one minute and the
                ##  T represents the number of minutes since epoch time [UT].
                now = datetime.now()
                stime = now.strftime("%s")
                itime = int(stime)
                param['T'] = itime

            data = ocra.combineData(**param)
            otp = ocra.compute(data, newkey)

            res = {'otp':otp}

            Session.commit()
            return sendResult(response, res, 1)

        except PolicyException as pe:
            log.exception("[ocra/calculateOtp] policy failed: %r" % pe)
            Session.rollback()
            return sendError(response, pe)

        except Exception as e:
            log.exception("[ocra/calculateOtp] failed: %r" % e)
            Session.rollback()
            return sendError(response, unicode(e), 0)

        finally:
            Session.close()
            log.debug('[ocra/calculateOtp] done')
Esempio n. 33
0
    def calculateOtp(self):
        '''

        '''
        from linotp.lib.crypto import kdf2
        from linotp.tokens.ocra import OcraSuite
        from datetime import datetime

        from urlparse import urlparse
        from urlparse import parse_qs

        res = {}

        # description = 'ocra/calculateOtp: calculate the first
        # otp from the given init2 response '

        try:
            params = getLowerParams(request.params)
            log.debug("[calculateOtp]: %r" % params)

            checkPolicyPre('ocra', "calcOTP")

            sharedsecret = params.get('sharedsecret')
            activationcode = params.get('activationcode')
            nonce = params.get('nonce')
            ocrasuite = params.get('ocrasuite')
            challenge = params.get('challenge')
            counter = params.get('counter')
            ocrapin = params.get('ocrapin')

            nonce3 = params.get('no')
            ocrasuite3 = params.get('os')

            challenge = params.get('challenge')
            counter = params.get('counter')
            ocrapin = params.get('ocrapin')
            init1 = params.get('init1')
            init2 = params.get('init2')

            if init1 is not None:

                # now parse the appurl for the ocrasuite

                uri = urlparse(init1.replace('lseqr://', 'http://'))
                qs = uri.query
                qdict = parse_qs(qs)

                ocrasuite2 = qdict.get('os', None)
                if ocrasuite2 is not None and len(ocrasuite2) > 0:
                    ocrasuite2 = ocrasuite2[0]

                if ocrasuite is None:
                    ocrasuite = ocrasuite2

                sharedsecret2 = qdict.get('sh', None)
                if sharedsecret2 is not None and len(sharedsecret2) > 0:
                    sharedsecret2 = sharedsecret2[0]

                if sharedsecret is None:
                    sharedsecret = sharedsecret2

            # parse init1

            if init2 is not None:

                # now parse the appurl for the ocrasuite

                uri = urlparse(init2.replace('lseqr://', 'http://'))
                qs = uri.query
                qdict = parse_qs(qs)

                challenge2 = qdict.get('ch', None)
                if challenge2 is not None and len(challenge2) > 0:
                    challenge2 = challenge2[0]
                if challenge is None:
                    challenge = challenge2

                nonce2 = qdict.get('no', None)
                if nonce2 is not None and len(nonce2) > 0:
                    nonce2 = nonce2[0]
                if nonce is None:
                    nonce = nonce2

            if ocrapin is None:
                ocrapin = ''
            if counter is None:
                counter = 0

            if nonce3 is not None:
                nonce = unicode(nonce3)

            if ocrasuite3 is not None:
                ocrasuite = unicode(ocrasuite3)

            #  now we have all in place for the key derivation to create
            # the new key sharedsecret, activationcode and nonce

            key_len = 20
            if ocrasuite.find('-SHA256'):
                key_len = 32
            elif ocrasuite.find('-SHA512'):
                key_len = 64

            if sharedsecret is not None:
                sharedsecret = unicode(sharedsecret)
            if nonce is not None:
                nonce = unicode(nonce)
            if activationcode is not None:
                activationcode = unicode(activationcode)

            newkey = kdf2(sharedsecret, nonce, activationcode, len=key_len)
            ocra = OcraSuite(ocrasuite)

            param = {}
            param['C'] = int(counter)
            param['Q'] = unicode(challenge)
            param['P'] = unicode(ocrapin)
            param['S'] = ''

            if ocra.T is not None:

                # Default value for G is 1M, i.e., time-step size is
                # one minute and the T represents the number of minutes
                # since epoch time [UT].

                now = datetime.now()
                stime = now.strftime("%s")
                itime = int(stime)
                param['T'] = itime

            data = ocra.combineData(**param)
            otp = ocra.compute(data, newkey)

            res = {'otp': otp}

            Session.commit()
            return sendResult(response, res, 1)

        except PolicyException as pe:
            log.exception("[ocra/calculateOtp] policy failed: %r" % pe)
            Session.rollback()
            return sendError(response, pe)

        except Exception as e:
            log.exception("[ocra/calculateOtp] failed: %r" % e)
            Session.rollback()
            return sendError(response, unicode(e), 0)

        finally:
            Session.close()
Esempio n. 34
0
    def getmultiotp(self):
        '''
        This function is used to retrieve multiple otp values for a given user or a given serial
        If the user has more than one token, the list of the tokens is returend.

        method:
            gettoken/getmultiotp

        arguments:
            serial  - the serial number of the token
            count   - number of otp values to return
            curTime - used ONLY for internal testing: datetime.datetime object

        returns:
            JSON response
        '''

        getotp_active = config.get("linotpGetotp.active")
        if "True" != getotp_active:
            return sendError(response, "getotp is not activated.", 0)

        param = request.params
        ret = {}

        try:
            serial = getParam(param, "serial", required)
            count = int(getParam(param, "count", required))
            curTime = getParam(param, "curTime", optional)
            view = getParam(param, "view", optional)

            r1 = checkPolicyPre('admin', 'getotp', param)
            log.debug("[getmultiotp] admin-getotp returned %s" % r1)

            max_count = checkPolicyPre('gettoken', 'max_count', param)
            log.debug("[getmultiotp] checkpolicypre returned %s" % max_count)
            if count > max_count:
                count = max_count

            log.debug("[getmultiotp] retrieving OTP value for token %s" %
                      serial)
            ret = get_multi_otp(serial, count=int(count), curTime=curTime)
            ret["serial"] = serial

            c.audit['success'] = True
            Session.commit()

            if view:
                c.ret = ret
                return render('/manage/multiotp_view.mako')
            else:
                return sendResult(response, ret, 0)

        except PolicyException as pe:
            log.error("[getotp] gettoken/getotp policy failed: %r" % pe)
            log.error("[getotp] %s" % traceback.format_exc())
            Session.rollback()
            return sendError(response, unicode(pe), 1)

        except Exception as e:
            log.error("[getmultiotp] gettoken/getmultiotp failed: %r" % e)
            log.error("[getmultiotp] %s" % traceback.format_exc())
            Session.rollback()
            return sendError(response,
                             "gettoken/getmultiotp failed: %s" % unicode(e), 0)

        finally:
            Session.close()
            log.debug("[getmultiotp] done")
Esempio n. 35
0
    def tokens(self):
        '''
        This function is used to fill the flexigrid.
        Unlike the complex /admin/show function, it only returns a
        simple array of the tokens.
        '''
        param = self.request_params

        try:
            page = param.get("page", 1)
            qfilter = param.get("query")
            qtype = param.get("qtype", 'all')
            sort = param.get("sortname", )
            direction = param.get("sortorder", "desc")
            psize = param.get("rp", 20)

            filter_all = None
            filter_realm = None
            user = User()

            if qtype == "loginname":

                # we take by default the given expression as a loginname,
                # especially if it contains a "*" wildcard.
                # it only might be more, a user and a realm, if there
                # is an '@' sign in the loginname and the part after the
                # last '@' sign is matching an existing realm

                user = User(login=qfilter)

                if "*" not in qfilter and "@" in qfilter:

                    login, _, realm = qfilter.rpartition("@")

                    if realm.lower() in getRealms():
                        user = User(login, realm)
                        if not user.exists():
                            user = User(login=qfilter)

            elif qtype == "all":
                filter_all = qfilter

            elif qtype == "realm":
                filter_realm = qfilter

            # check admin authorization
            res = checkPolicyPre('admin', 'show', param, user=user)

            filterRealm = res['realms']
            # check if policies are active at all
            # If they are not active, we are allowed to SHOW any tokens.
            pol = getAdminPolicies("show")

            # If there are no admin policies, we are allowed to see all realms
            if not pol['active']:
                filterRealm = ["*"]

            # check if we only want to see ONE realm or see all realms
            # we are allowerd to see.
            if filter_realm:
                if filter_realm in filterRealm or '*' in filterRealm:
                    filterRealm = [filter_realm]

            tokenArray = TokenIterator(
                user, None, page, psize, filter_all, sort,
                direction, filterRealm=filterRealm)

            resultset = tokenArray.getResultSetInfo()
            # If we have chosen a page to big!
            lines = []
            for tok in tokenArray:
                lines.append({
                    'id': tok['LinOtp.TokenSerialnumber'],
                    'cell': [
                        tok['LinOtp.TokenSerialnumber'],
                        tok['LinOtp.Isactive'],
                        tok['User.username'],
                        tok['LinOtp.RealmNames'],
                        tok['LinOtp.TokenType'],
                        tok['LinOtp.FailCount'],
                        tok['LinOtp.TokenDesc'],
                        tok['LinOtp.MaxFail'],
                        tok['LinOtp.OtpLen'],
                        tok['LinOtp.CountWindow'],
                        tok['LinOtp.SyncWindow'],
                        tok['LinOtp.Userid'],
                        tok['LinOtp.IdResClass'].split('.')[-1],
                    ]
                })

            # We need to return 'page', 'total', 'rows'
            res = {
                "page": int(page),
                "total": resultset['tokens'],
                "rows": lines
            }

            c.audit['success'] = True
            Session.commit()
            return sendResult(response, res)

        except PolicyException as pex:
            log.exception("Error during checking policies")
            Session.rollback()
            return sendError(response, pex, 1)

        except Exception as exx:
            log.exception("tokens lookup failed!")
            Session.rollback()
            return sendError(response, exx)

        finally:
            Session.close()
Esempio n. 36
0
    def getmultiotp(self):
        '''
        This function is used to retrieve multiple otp values for a given user
        or a given serial. If the user has more than one token, the list of
        the tokens is returend.

        method:
            gettoken/getmultiotp

        arguments:
            serial  - the serial number of the token
            count   - number of otp values to return
            curTime - used ONLY for internal testing: datetime.datetime object

        returns:
            JSON response
        '''

        getotp_active = config.get("GETOTP_ENABLED")
        if not getotp_active:
            return sendError(response, "getotp is not activated.", 0)

        param = self.request_params
        ret = {}

        try:
            serial = getParam(param, "serial", required)
            count = int(getParam(param, "count", required))
            curTime = getParam(param, "curTime", optional)
            view = getParam(param, "view", optional)

            r1 = checkPolicyPre('admin', 'getotp', param)
            log.debug("[getmultiotp] admin-getotp policy: %s", r1)

            max_count = checkPolicyPre('gettoken', 'max_count', param)
            log.debug("[getmultiotp] maxcount policy: %s", max_count)
            if count > max_count:
                count = max_count

            log.debug("[getmultiotp] retrieving OTP value for token %s",
                      serial)
            ret = get_multi_otp(serial, count=int(count), curTime=curTime)
            ret["serial"] = serial

            g.audit['success'] = True
            db.session.commit()

            if view:
                c.ret = ret
                return render('/manage/multiotp_view.mako').decode('utf-8')
            else:
                return sendResult(response, ret, 0)

        except PolicyException as pe:
            log.exception("[getotp] gettoken/getotp policy failed: %r", pe)
            db.session.rollback()
            return sendError(response, str(pe), 1)

        except Exception as exx:
            log.exception("[getmultiotp] gettoken/getmultiotp failed: %r", exx)
            db.session.rollback()
            return sendError(response, "gettoken/getmultiotp failed: %r" % exx,
                             0)
Esempio n. 37
0
    def search(self):
        """
        This functions searches within the audit trail
        It returns the audit information for the given search pattern

        method:
            audit/search

        arguments:
            key, value pairs as search patterns.

            * outform - optional: if set to "csv", than the token list will be
                        given in CSV


            or: Usually the key=values will be locally AND concatenated.
                it a parameter or=true is passed, the filters will
                be OR concatenated.

            The Flexigrid provides us the following parameters:
                ('page', u'1'), ('rp', u'25'),
                ('sortname', u'number'),
                ('sortorder', u'asc'),
                ('query', u''), ('qtype', u'serial')]
        returns:
            JSON response or csv format
        """

        try:
            log.debug("[search] params: %r", self.request_params)

            checkPolicyPre("audit", "view", {})

            # remove the param outform (and other parameters that should not
            # be used for search!
            search_params = self.request_params.copy()
            for key in ["outform", "delimiter"]:
                if key in search_params:
                    del search_params[key]

            output_format = (
                self.request_params.get("outform", "json") or "json"
            )

            delimiter = self.request_params.get("delimiter", ",") or ","

            audit_obj = current_app.audit_obj
            audit_query = AuditQuery(search_params, audit_obj)

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

            # check if we are running with sqlite which does not support
            # streaming responses

            stream_output = True

            db_uri = current_app.config["SQLALCHEMY_BINDS"]["auditdb"]
            if db_uri.startswith("sqlite"):
                stream_output = False

            if output_format == "csv":
                audit_iterator = CSVAuditIterator(audit_query, delimiter)
                mimetype = "text/csv"
                reponse_headers_args = {
                    "_key": "Content-disposition",
                    "_value": "attachment",
                    "filename": "linotp-audit.csv",
                }
            else:
                audit_iterator = JSONAuditIterator(audit_query)
                mimetype = "application/json"
                reponse_headers_args = {}

            if stream_output:
                audit_output = stream_with_context(audit_iterator)
            else:
                audit_output = ""
                try:
                    while True:
                        audit_output = audit_output + next(audit_iterator)
                except StopIteration:
                    # continue if all data is joined
                    pass

            streamed_response = Response(audit_output, mimetype=mimetype)

            if reponse_headers_args:
                streamed_response.headers.set(**reponse_headers_args)

            g.audit["success"] = True
            db.session.commit()

            return streamed_response

        except PolicyException as pe:
            log.error("[getotp] gettoken/getotp policy failedi: %r", pe)
            db.session.rollback()
            return sendError(response, pe, 1)

        except Exception as exx:
            log.error("[search] audit/search failed: %r", exx)
            db.session.rollback()
            return sendError(response, "audit/search failed", 0)
Esempio n. 38
0
    def tokenview_flexi(self):
        '''
        This function is used to fill the flexigrid.
        Unlike the complex /admin/show function, it only returns a
        simple array of the tokens.
        '''
        param = self.request_params

        try:
            c.page = param.get("page")
            c.filter = param.get("query")
            c.qtype = param.get("qtype")
            c.sort = param.get("sortname")
            c.dir = param.get("sortorder")
            c.psize = param.get("rp")

            filter_all = None
            filter_realm = None
            user = User()

            if c.qtype == "loginname":

                # we take by default the given expression as a loginname,
                # especially if it contains a "*" wildcard.
                # it only might be more, a user and a realm, if there
                # is an '@' sign in the loginname and the part after the
                # last '@' sign is matching an existing realm

                user = User(login=c.filter)

                if "*" not in c.filter and "@" in c.filter:

                    login, _, realm = c.filter.rpartition("@")

                    if realm.lower() in getRealms():
                        user = User(login, realm)
                        if not user.exists():
                            user = User(login=c.filter)

            elif c.qtype == "all":
                filter_all = c.filter

            elif c.qtype == "realm":
                filter_realm = c.filter

            # check admin authorization
            res = checkPolicyPre('admin', 'show', param, user=user)

            filterRealm = res['realms']
            # check if policies are active at all
            # If they are not active, we are allowed to SHOW any tokens.
            pol = getAdminPolicies("show")
            # If there are no admin policies, we are allowed to see all realms
            if not pol['active']:
                filterRealm = ["*"]

            # check if we only want to see ONE realm or see all realms we are allowerd to see.
            if filter_realm:
                if filter_realm in filterRealm or '*' in filterRealm:
                    filterRealm = [filter_realm]

            log.debug(
                "[tokenview_flexi] admin >%s< may display the following realms: %s"
                % (pol['admin'], pol['realms']))
            log.debug(
                "[tokenview_flexi] page: %s, filter: %s, sort: %s, dir: %s" %
                (c.page, c.filter, c.sort, c.dir))

            if c.page is None:
                c.page = 1
            if c.psize is None:
                c.psize = 20

            log.debug(
                "[tokenview_flexi] calling TokenIterator for user=%s@%s, filter=%s, filterRealm=%s"
                % (user.login, user.realm, filter_all, filterRealm))
            c.tokenArray = TokenIterator(user,
                                         None,
                                         c.page,
                                         c.psize,
                                         filter_all,
                                         c.sort,
                                         c.dir,
                                         filterRealm=filterRealm)
            c.resultset = c.tokenArray.getResultSetInfo()
            # If we have chosen a page to big!
            lines = []
            for tok in c.tokenArray:
                uid = tok['LinOtp.Userid']
                uid = uid.decode('utf-8') if isinstance(uid, bytes) else uid
                lines.append({
                    'id':
                    tok['LinOtp.TokenSerialnumber'],
                    'cell': [
                        tok['LinOtp.TokenSerialnumber'],
                        tok['LinOtp.Isactive'],
                        tok['User.username'],
                        tok['LinOtp.RealmNames'],
                        tok['LinOtp.TokenType'],
                        tok['LinOtp.FailCount'],
                        tok['LinOtp.TokenDesc'],
                        tok['LinOtp.MaxFail'],
                        tok['LinOtp.OtpLen'],
                        tok['LinOtp.CountWindow'],
                        tok['LinOtp.SyncWindow'],
                        uid,
                        tok['LinOtp.IdResClass'].split('.')[-1],
                    ]
                })

            # We need to return 'page', 'total', 'rows'
            res = {
                "page": int(c.page),
                "total": c.resultset['tokens'],
                "rows": lines
            }

            c.audit['success'] = True

            Session.commit()
            # The flexi handler should support std LinOTP output
            return sendResult(response, res)

        except PolicyException as pe:
            log.exception(
                "[tokenview_flexi] Error during checking policies: %r" % pe)
            Session.rollback()
            return sendError(response, str(pe), 1)

        except Exception as e:
            log.exception("[tokenview_flexi] failed: %r" % e)
            Session.rollback()
            return sendError(response, e)

        finally:
            Session.close()
Esempio n. 39
0
    def request(self):
        """
        method:
            ocra/request

        description:
            request a challenge for a user or for a serial number (token).

        arguments:
            * serial: (required - string)
              Serial number of the token, for which a challenge should
              be generated (either serial or user is required)

            * user: (required  - string)
              The user for whose token a challenge should be generated
              If the user has more than one token, an error is returend.
              (either serial or user is required)

            * data: (required - String: URLendoced)
              These are the display data, that can be used to generate the
              challenge

        remark:
            the app will report a wrong qrcode, if the policy::

                {'authentication' : qrtanurl=https://localhost }

            is not defined !!

        returns:

            A JSON respone::

                        {
                            "version": "LinOTP 2.4",
                            "jsonrpc": "2.0",
                            "result": {
                                "status": true,
                                "value": false,
                            },
                            "detail": {
                                    "transactionid" : TRANSAKTIONSID,
                                    "data" : DATAOBJECT,
                            }
                        }

            * transactionid:
              This is the transaction ID, that is used later for
              verifying the Return code /TAN.

            * data:
              This is an object (URL) which can be used to generate a
              QR-Code to be displayed to the QRTAN App
        """
        res = {}
        description = ('ocra/request: request a challenge for a given user or'
                       ' token (serial). You must either provide a parameter '
                       '"user" or a parameter "serial".')
        dataobj = ""

        try:
            param = getLowerParams(request.params)
            log.info("[request] saving default configuration: %r" % param)

            checkPolicyPre('ocra', "request")

            serial = param.get('serial')
            user = getUserFromParam(param)

            if user.is_empty and serial is None:

                log.exception("[request] user or serial is required")
                raise ParameterError("Usage: %s" % description, id=77)

            if not serial:
                if not user.exists():
                    raise UserError("getUserId failed: no user >%s< found!"
                                    % user.login, id=1205)

            message = param.get('data')
            if message is None:
                message = ''

            # ocra token

            tokens = getTokens4UserOrSerial(user, serial)

            if len(tokens) > 1:
                error = ('More than one token found: unable to create '
                         'challenge for (u:%r,s:%r)!' % (user, serial))
                raise Exception(error)

            if len(tokens) == 0:
                error = ('No token found: unable to create challenge for'
                         ' (u:%r,s:%r)!' % (user, serial))
                raise Exception(error)

            ocra = tokens[0]
            (transId, challenge, res, url) = ocra.challenge(message)

            u = urlencode({'u': str(url.encode("utf-8"))})

            uInfo = {'tr': transId,
                     'ch': challenge,
                     'me': str(message.encode("utf-8")),
                     'u': u[2:]}

            detail = {"transactionid": transId,
                      'challenge': challenge,
                      'message': str(message.encode("utf-8")),
                      'url': str(url.encode("utf-8")), }

            # create the app_url from the data

            dataobj = 'lseqr://req?%s' % (str(urlencode(uInfo)))

            # append the signature to the url

            signature = {'si': ocra.signData(dataobj)}
            uInfo['si'] = signature
            dataobj = '%s&%s' % (dataobj, str(urlencode(signature)))

            detail["data"] = dataobj

            c.audit['success'] = res

            Session.commit()
            qr = param.get('qr')
            if qr is not None:
                param['alt'] = detail
                return sendQRImageResult(response, dataobj, param)
            else:
                return sendResult(response, res, 1, opt=detail)

        except PolicyException as pe:
            log.exception("[request] policy failed: %r" % pe)
            Session.rollback()
            return sendError(response, unicode(pe))

        except Exception as exx:
            log.exception("[request] failed: %r" % exx)
            Session.rollback()
            return sendError(response, unicode(exx))

        finally:
            Session.close()
Esempio n. 40
0
    def search(self):
        '''
        This functions searches within the audit trail
        It returns the audit information for the given search pattern

        method:
            audit/search

        arguments:
            key, value pairs as search patterns.

            * outform - optional: if set to "csv", than the token list will be
                        given in CSV


            or: Usually the key=values will be locally AND concatenated.
                it a parameter or=true is passed, the filters will
                be OR concatenated.

            The Flexigrid provides us the following parameters:
                ('page', u'1'), ('rp', u'25'),
                ('sortname', u'number'),
                ('sortorder', u'asc'),
                ('query', u''), ('qtype', u'serial')]
        returns:
            JSON response or csv format
        '''

        param = {}
        try:
            param.update(request.params)

            log.debug("[search] params: %s" % param)

            checkPolicyPre('audit', 'view', {})

            # remove the param outform (and other parameters that should not
            # be used for search!
            search_params = {}
            search_params.update(param)
            for key in ["outform", 'delimiter']:
                if key in search_params:
                    del search_params[key]

            output_format = param.get("outform", 'json') or 'json'
            delimiter = param.get('delimiter', ',') or ','

            audit_iterator = None

            audit_query = AuditQuery(search_params, audit)

            if output_format == "csv":
                filename = "linotp-audit.csv"
                response.content_type = "application/force-download"
                response.headers['Content-disposition'] = (
                    'attachment; filename=%s' % filename)

                audit_iterator = CSVAuditIterator(audit_query, delimiter)
            else:
                response.content_type = 'application/json'
                audit_iterator = JSONAuditIterator(audit_query)

            c.audit['success'] = True
            Session.commit()
            return audit_iterator

        except PolicyException as pe:
            log.exception("[getotp] gettoken/getotp policy failed: %r" % pe)
            Session.rollback()
            return sendError(response, unicode(pe), 1)

        except Exception as e:
            log.exception("[search] audit/search failed: %r" % e)
            Session.rollback()
            return sendError(response, "audit/search failed", 0)

        finally:
            Session.close()
Esempio n. 41
0
    def checkstatus(self):
        """
        method:
            ocra/checkstatus

        description:
            Methode zur assynchronen Ueberpruefungen eines Challenge
            Response Valiadation requests

        arguments:

            * transactionid:  (required one of  - string - (hex))
                    Dies ist eine Transaktions-ID, die bei der Challenge
                    ausgegeben wurde.

            * serial: (required one of  - string)
                    die Serien Nummer des OCRA Token

            * user: (required one of  - string)
                    die Benutzer eines Tokens

            required is one of (user,serial,transactionid)

        returns:

            A JSON response::

                {
                 "version": "LinOTP 2.4",
                 "jsonrpc": "2.0",
                 "result": {
                     "status": true,
                     "value": [
                             {
                             "serial": SERIENNUMMER1,
                             "transactionid": TRANSACTIONID1,
                             "received_tan": true,
                             "valid_tan": true,
                             "failcount": 0
                             },
                             {
                             "serial": SERIENNUMMER1,
                             "transactionid": TRANSACTIONID2,
                             "received_tan": false,
                             "valid_tan": false,
                             "failcount": 0
                             },
                             {
                             "serial": SERIENNUMMER2,
                             "transactionid": TRANSACTIONID3,
                             "received_tan": true,
                             "valid_tan": false,
                             "failcount": 2
                             },
                         ]
                     },
                 "id": 0
                 }

        exception:

        """
        res = {}
        description = ('ocra/checkstatus: check the token status - '
                       'for assynchronous verification. Missing parameter: '
                       'You need to provide one of the parameters '
                       '"transactionid", "user" or "serial"')

        try:
            param = getLowerParams(request.params)
            log.debug("[checkstatus] check OCRA token status: %r" % param)

            checkPolicyPre('ocra', "status")

            transid = param.get('transactionid')
            user = getUserFromParam(param)
            serial = param.get('serial')

            if transid is None and user.is_empty and serial is None:
                # raise exception
                log.exception("[ocra/checkstatus] : missing transactionid, user or serial number for token")
                raise ParameterError("Usage: %s" % description, id=77)

            tokens = []
            serials = set()
            status = []

            if serial is not None:
                serials.add(serial)

            # if we have a transaction, get serial from this challenge

            if transid is not None:
                ocraChallenge = None
                try:
                    ocraChallenge = OcraTokenClass.getTransaction(transid)
                except:
                    pass
                if ocraChallenge is not None:
                    serials.add(ocraChallenge.tokenserial)

            # if we have a serial number of  token

            if len(serials) > 0:
                for serial in serials:
                    tokens.extend(getTokens4UserOrSerial(serial=serial))

            # if we have a user

            if not user.is_empty:
                try:
                    tokens.extend(getTokens4UserOrSerial(user=user))
                except:
                    log.warning("no token or user %r found!" % user)

            for token in tokens:
                if token.getType() == 'ocra':
                    challenges = []
                    if transid is None:
                        serial = token.getSerial()
                        challenges = OcraTokenClass.getTransactions4serial(
                                                                        serial)
                    else:
                        challenges.append(OcraTokenClass.getTransaction(
                                                                    transid))

                    for challenge in challenges:
                        stat = token.getStatus(challenge.transid)
                        if stat is not None and len(stat) > 0:
                            status.append(stat)

            res['values'] = status
            c.audit['success'] = res

            Session.commit()
            return sendResult(response, res, 1)

        except PolicyException as pe:
            log.exception("[checkstatus] policy failed: %r" % pe)
            Session.rollback()
            return sendError(response, unicode(pe))

        except Exception as exx:
            log.exception("[checkstatus] failed: %r" % exx)
            Session.rollback()
            return sendResult(response, unicode(exx), 0)

        finally:
            Session.close()