Пример #1
0
def getUserId(user, check_existance=False):
    """
    getUserId (userObject)

    :param user: user object
    :return: (uid,resId,resIdC)
    """

    uid = None
    resId = ''

    uids = set()
    resolvers = getResolversOfUser(user)

    for resolver_spec in resolvers:
        _login, uid, _user_info = lookup_user_in_resolver(
            user.login, None, resolver_spec)
        if not uid:
            continue

        y = getResolverObject(resolver_spec)
        resId = y.getResolverId()
        if check_existance:
            uinfo = y.getUserInfo(uid)
            if not uinfo:
                uid = None

        if not uid:
            continue

        uids.add(uid)
        user.resolverUid[resolver_spec] = uid

    if not uid:
        log.warning("No uid found for the user >%r< in realm %r" %
                    (user.login, user.realm))
        raise UserError("getUserId failed: no user >%s< found!" % user.login,
                        id=1205)

    if len(uids) > 1:
        log.warning("multiple uid s found for the user >%r< in realm %r" %
                    (user.login, user.realm))
        raise UserError(
            "getUserId failed: multiple uids for user >%s< found!" %
            user.login,
            id=1205)

    log.debug("we are done!")
    return (uid, resId, resolver_spec)
Пример #2
0
def getUserResolverId(user, report=False):
    # here we call the userid resolver!!"
    log.debug('getUserResolverId for %r', user)

    (uuserid, uidResolver, uidResolverClass) = (u'', u'', u'')

    if (user is not None and user.isEmpty() is not True):
        try:
            (uuserid, uidResolver, uidResolverClass) = getUserId(user)
        except Exception as e:
            log.exception('[getUserResolverId] for %r@%r failed: %r' % (user.login, user.realm, e))
            if report is True:
                raise UserError("getUserResolverId failed: %r" % e, id=1112)

    return (uuserid, uidResolver, uidResolverClass)
Пример #3
0
def getUserId(user, resolvers=None):
    """
    getUserId (userObject)

    return (uid,resId,resIdC)
    """

    uid = ''
    loginUser = user.login

    if not resolvers:
        resolvers = getResolversOfUser(user)

    for resolver_spec in resolvers:
        resId = ""
        resIdC = ""
        uid = user.getResolverUId(resolver_spec)
        if uid != '':
            (resId, resIdC, _conf) = user.getResolverConf(resolver_spec)
            break

        cls_identifier, config_identifier = parse_resolver_spec(resolver_spec)

        if user.resolver_config_identifier:
            lower_config_id = user.resolver_config_identifier.lower()
            if config_identifier.lower() != lower_config_id:
                continue

        # try to load the UserIdResolver Class
        try:
            log.debug('[getUserId] Getting resolver class: [%s]',
                      cls_identifier)
            y = getResolverObject(resolver_spec)
            log.debug("[getUserId] Getting UserID for user %r", loginUser)
            uid = y.getUserId(loginUser)
            log.debug("[getUserId] Got UserId for user %r: %r",
                      loginUser, uid)

            log.debug("[getUserId] Retrieving ResolverID...")
            resId = y.getResolverId()

            resIdC = resolver_spec
            log.debug("[getUserId] Got ResolverID: %r, Loginuser: %r, "
                      "Uid: %r ]", resId, loginUser, uid)

            if uid != "":
                break

        except Exception as exx:
            log.exception("[getUserId] resolver class identifier %s: %r ]",
                          cls_identifier, exx)
            continue

    if (uid == ''):
        log.warning("[getUserId] No uid found for the user >%r< in realm %r"
                    % (loginUser, user.realm))
        raise UserError("getUserId failed: no user >%s< found!"
                        % unicode(loginUser), id=1205)

    log.debug("[getUserId] we are done!")
    return (unicode(uid), unicode(resId), unicode(resIdC))
Пример #4
0
    def finish_valid_tokens(self):
        """
        processing of the valid tokens
        """
        valid_tokens = self.valid_tokens
        validation_results = self.validation_results
        user = self.user

        if len(valid_tokens) == 1:
            token = valid_tokens[0]
            if user:
                action_detail = ("user %r@%r successfully authenticated." %
                                 (user.login, user.realm))
            else:
                action_detail = ("serial %r successfully authenticated." %
                                 token.getSerial())

            log.info(action_detail)

            # there could be a match in the window ahead,
            # so we need the last valid counter here
            (counter, _reply) = validation_results[token.getSerial()]
            token.setOtpCount(counter + 1)
            token.statusValidationSuccess()
            # finish as well related open challenges
            Challenges.finish_challenges(token, success=True)

            if token.getFromTokenInfo('count_auth_success_max', default=None):
                auth_count = token.get_count_auth_success()
                token.set_count_auth_success(auth_count + 1)

            detail = None
            auth_info = self.options.get('auth_info', 'False')
            if auth_info.lower() == "true":
                detail = token.getAuthDetail()

            # 1. check if token supports offline at all
            supports_offline_at_all = token.supports_offline_mode

            # 2. check if policy allows to use offline authentication
            if user is not None and user.login and user.realm:
                realms = [user.realm]
            else:
                realms = token.getRealms()

            offline_is_allowed = supports_offline(realms, token)

            # 3. check if parameter 'use_offline' is provided
            use_offline_param = self.options.get('use_offline', 'False')
            use_offline = use_offline_param.lower() == 'true'

            if supports_offline_at_all and \
               offline_is_allowed and \
               use_offline:

                offline_info = token.getOfflineInfo()
                if detail is None:
                    detail = {}

                offline = {'serial': token.getSerial(), 'type': token.type}
                offline['offline_info'] = offline_info

                detail.update({'offline': offline})

            return (True, detail, action_detail)

        else:
            # we have to set the matching counter to prevent replay one one
            # single token
            for token in valid_tokens:
                (res, _reply) = validation_results[token.getSerial()]
                token.setOtpCount(res)

            context['audit']['action_detail'] = "Multiple valid tokens found!"
            if user:
                log.error(
                    "[__checkTokenList] multiple token match error: "
                    "Several Tokens matching with the same OTP PIN "
                    "and OTP for user %r. Not sure how to auth", user.login)
            raise UserError("multiple token match error", id=-33)
Пример #5
0
def getUserId(user):
    """
    getUserId (userObject)

    return (uid,resId,resIdC)
    """

    uid = ''
    loginUser = u''
    loginUser = user.login;

    resolvers = '';
    realms = getRealms();

    # Get the first resolver they're present in, because UID is independent of realm.
    for key, v in realms.items():
        resolvers = getResolversOfUser(User(user.login, v['realmname'], ""))
        if (resolvers):
            break;

    for reso in resolvers:
        resId = ""
        resIdC = ""
        conf = ""
        uid = user.getResolverUId(reso)
        if uid != '':
            (resId, resIdC, conf) = user.getResolverConf(reso)
            break

        (package, module, class_, conf) = splitResolver(reso)

        if len(user.conf) > 0:
            if conf.lower() != user.conf.lower():
                continue

        ## try to load the UserIdResolver Class
        try:
            module = package + "." + module
            log.debug("[getUserId] Getting resolver class: [%r] [%r]"
                       % (module, class_))
            y = getResolverObject(reso)
            log.debug("[getUserId] Getting UserID for user %r"
                        % loginUser)
            uid = y.getUserId(loginUser)
            log.debug("[getUserId] Got UserId for user %r: %r"
                        % (loginUser, uid))

            log.debug("[getUserId] Retrieving ResolverID...")
            resId = y.getResolverId()

            resIdC = reso
            log.debug("[getUserId] Got ResolverID: %r, Loginuser: %r, "
                      "Uid: %r ]" % (resId, loginUser, uid))

            if uid != "":
                break;

        except Exception as e:
            log.error("[getUserId] module %r: %r ]" % (module, e))
            continue

    if (uid == ''):
        log.warning("[getUserId] No uid found for the user >%r< in realm %r"
                    % (loginUser, user.realm))
        raise UserError(u"getUserId failed: no user >%s< found!"
                         % unicode(loginUser), id=1205)

    log.debug("[getUserId] we are done!")
    return (unicode(uid), unicode(resId), unicode(resIdC))
Пример #6
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()
Пример #7
0
    def finish_valid_tokens(self):
        """
        processing of the valid tokens
        """
        valid_tokens = self.valid_tokens
        validation_results = self.validation_results
        user = self.user

        if len(valid_tokens) == 1:
            token = valid_tokens[0]
            if user:
                action_detail = "user %r@%r successfully authenticated." % (
                    user.login,
                    user.realm,
                )
            else:
                action_detail = ("serial %r successfully authenticated." %
                                 token.getSerial())

            log.info(action_detail)

            # there could be a match in the window ahead,
            # so we need the last valid counter here

            (counter, _reply) = validation_results[token.getSerial()]
            token.setOtpCount(counter + 1)
            token.statusValidationSuccess()

            # finish as well related open challenges
            Challenges.finish_challenges(token, success=True)

            if token.count_auth_success_max > 0:
                token.inc_count_auth_success()

            if token.count_auth_max > 0:
                token.inc_count_auth()

            detail = None
            auth_info = self.options.get("auth_info", "False")
            if auth_info.lower() == "true":
                detail = token.getAuthDetail()

            # 1. check if token supports offline at all
            supports_offline_at_all = token.supports_offline_mode

            # 2. check if policy allows to use offline authentication
            if user is not None and user.login and user.realm:
                realms = [user.realm]
            else:
                realms = token.getRealms()

            offline_is_allowed = supports_offline(realms, token)

            # 3. check if parameter 'use_offline' is provided
            use_offline_param = self.options.get("use_offline", "False")
            use_offline = use_offline_param.lower() == "true"

            if supports_offline_at_all and offline_is_allowed and use_offline:

                offline_info = token.getOfflineInfo()
                if detail is None:
                    detail = {}

                offline = {"serial": token.getSerial(), "type": token.type}
                offline["offline_info"] = offline_info

                detail.update({"offline": offline})

            janitor_to_remove_enrollment_token(valid_tokens=[token])

            return (True, detail, action_detail)

        else:
            # we have to set the matching counter to prevent replay one one
            # single token

            for token in valid_tokens:

                (res, _reply) = validation_results[token.getSerial()]

                token.setOtpCount(res)

                # in case of multiple matches the tokens were accessed
                # so we count them as well
                if token.count_auth_max > 0:
                    token.inc_count_auth()

            janitor_to_remove_enrollment_token(valid_tokens=valid_tokens)

            g.audit["action_detail"] = "Multiple valid tokens found!"
            if user:
                log.error(
                    "multiple token match error: "
                    "Several Tokens matching with the same OTP PIN "
                    "and OTP for user %r. Not sure how to auth",
                    user.login,
                )

            raise UserError("multiple token match error", id=-33)