Exemplo n.º 1
0
    def api_endpoint(request, g):
        """
        This provides a function to be plugged into the API endpoint
        /ttype/<tokentype> which is defined in api/ttype.py
        See :ref:`rest_ttype`.

        :param request: The Flask request
        :param g: The Flask global object g
        :return: Flask Response or text
        """
        params = request.all_data
        action = getParam(params, "action", optional) or \
                 API_ACTIONS.AUTHENTICATION
        if action not in API_ACTIONS.ALLOWED_ACTIONS:
            raise ParameterError("Allowed actions are {0!s}".format(
                                 API_ACTIONS.ALLOWED_ACTIONS))

        if action == API_ACTIONS.METADATA:
            session = getParam(params, "session", required)
            serial = getParam(params, "serial", required)
            # The user identifier is displayed in the App
            # We need to set the user ID
            tokens = get_tokens(serial=serial)
            if not tokens:  # pragma: no cover
                raise ParameterError("No token with serial {0!s}".format(serial))
            user_identifier, user_displayname = tokens[0].get_user_displayname()

            service_identifier = get_from_config("tiqr.serviceIdentifier") or\
                                 "org.privacyidea"
            ocrasuite = get_from_config("tiqr.ocrasuite") or OCRA_DEFAULT_SUITE
            service_displayname = get_from_config("tiqr.serviceDisplayname") or \
                                  "privacyIDEA"
            reg_server = get_from_config("tiqr.regServer")
            auth_server = get_from_config("tiqr.authServer") or reg_server
            logo_url = get_from_config("tiqr.logoUrl")

            service = {"displayName": service_displayname,
                       "identifier": service_identifier,
                       "logoUrl": logo_url,
                       "infoUrl": "https://www.privacyidea.org",
                       "authenticationUrl":
                           "{0!s}".format(auth_server),
                       "ocraSuite": ocrasuite,
                       "enrollmentUrl":
                           "{0!s}?action={1!s}&session={2!s}&serial={3!s}".format(
                               reg_server,
                               API_ACTIONS.ENROLLMENT,
                               session, serial)
                       }
            identity = {"identifier": user_identifier,
                        "displayName": user_displayname
                        }

            res = {"service": service,
                   "identity": identity
                   }

            return "json", res

        elif action == API_ACTIONS.ENROLLMENT:
            """
            operation: register
            secret: HEX
            notificationType: GCM
            notificationAddress: ...
            language: de
            session:
            serial:
            """
            res = "Fail"
            serial = getParam(params, "serial", required)
            session = getParam(params, "session", required)
            secret = getParam(params, "secret", required)
            # The secret needs to be stored in the token object.
            # We take the token "serial" and check, if it contains the "session"
            # in the tokeninfo.
            enroll_tokens = get_tokens(serial=serial)
            if len(enroll_tokens) == 1:
                if enroll_tokens[0].get_tokeninfo("session") == session:
                    # save the secret
                    enroll_tokens[0].set_otpkey(secret)
                    # delete the session
                    enroll_tokens[0].del_tokeninfo("session")
                    res = "OK"
                else:
                    raise ParameterError("Invalid Session")

            return "plain", res
        elif action == API_ACTIONS.AUTHENTICATION:
            res = "FAIL"
            userId = getParam(params, "userId", required)
            session = getParam(params, "sessionKey", required)
            passw = getParam(params, "response", required)
            operation = getParam(params, "operation", required)
            res = "INVALID_CHALLENGE"
            # The sessionKey is stored in the db_challenge.transaction_id
            # We need to get the token serial for this sessionKey
            challenges = get_challenges(transaction_id=session)
            # We found exactly one challenge
            if (len(challenges) == 1 and challenges[0].is_valid() and
                        challenges[0].otp_valid is False):
                # Challenge is still valid (time has not passed) and no
                    # correct response was given.
                    serial = challenges[0].serial
                    tokens = get_tokens(serial=serial)
                    if len(tokens) == 1:
                        # We found exactly the one token
                        res = "INVALID_RESPONSE"
                        r = tokens[0].verify_response(
                            challenge=challenges[0].challenge, passw=passw)
                        if r > 0:
                            res = "OK"
                            # Mark the challenge as answered successfully.
                            challenges[0].set_otp_status(True)

            cleanup_challenges()

            return "plain", res
Exemplo n.º 2
0
    def api_endpoint(cls, request, g):
        """
        This provides a function to be plugged into the API endpoint
        /ttype/<tokentype> which is defined in api/ttype.py
        See :ref:`rest_ttype`.

        :param request: The Flask request
        :param g: The Flask global object g
        :return: Flask Response or text
        """
        params = request.all_data
        action = getParam(params, "action", optional) or \
                 API_ACTIONS.AUTHENTICATION
        if action not in API_ACTIONS.ALLOWED_ACTIONS:
            raise ParameterError("Allowed actions are {0!s}".format(
                                 API_ACTIONS.ALLOWED_ACTIONS))

        if action == API_ACTIONS.METADATA:
            session = getParam(params, "session", required)
            serial = getParam(params, "serial", required)
            # The user identifier is displayed in the App
            # We need to set the user ID
            token = get_one_token(serial=serial, tokentype="tiqr")
            user_identifier, user_displayname = token.get_user_displayname()

            service_identifier = get_from_config("tiqr.serviceIdentifier") or\
                                 "org.privacyidea"
            ocrasuite = get_from_config("tiqr.ocrasuite") or OCRA_DEFAULT_SUITE
            service_displayname = get_from_config("tiqr.serviceDisplayname") or \
                                  "privacyIDEA"
            reg_server = get_from_config("tiqr.regServer")
            auth_server = get_from_config("tiqr.authServer") or reg_server
            logo_url = get_from_config("tiqr.logoUrl")
            info_url = get_from_config("tiqr.infoUrl") or \
                    "https://www.privacyidea.org"

            service = {"displayName": service_displayname,
                       "identifier": service_identifier,
                       "logoUrl": logo_url,
                       "infoUrl": info_url,
                       "authenticationUrl":
                           "{0!s}".format(auth_server),
                       "ocraSuite": ocrasuite,
                       "enrollmentUrl":
                           "{0!s}?action={1!s}&session={2!s}&serial={3!s}".format(
                               reg_server,
                               API_ACTIONS.ENROLLMENT,
                               session, serial)
                       }
            identity = {"identifier": user_identifier,
                        "displayName": user_displayname
                        }

            res = {"service": service,
                   "identity": identity
                   }

            return "json", res

        elif action == API_ACTIONS.ENROLLMENT:
            """
            operation: register
            secret: HEX
            notificationType: GCM
            notificationAddress: ...
            language: de
            session:
            serial:
            """
            res = "Fail"
            serial = getParam(params, "serial", required)
            session = getParam(params, "session", required)
            secret = getParam(params, "secret", required)
            # The secret needs to be stored in the token object.
            # We take the token "serial" and check, if it contains the "session"
            # in the tokeninfo.
            enroll_token = get_one_token(serial=serial, tokentype="tiqr")
            tokeninfo_session = enroll_token.get_tokeninfo("session")
            if tokeninfo_session and tokeninfo_session == session:
                # save the secret
                enroll_token.set_otpkey(secret)
                # delete the session
                enroll_token.del_tokeninfo("session")
                res = "OK"
            else:
                raise ParameterError("Invalid Session")

            return "plain", res
        elif action == API_ACTIONS.AUTHENTICATION:
            res = "FAIL"
            userId = getParam(params, "userId", required)
            session = getParam(params, "sessionKey", required)
            passw = getParam(params, "response", required)
            operation = getParam(params, "operation", required)
            res = "INVALID_CHALLENGE"
            # The sessionKey is stored in the db_challenge.transaction_id
            # We need to get the token serial for this sessionKey
            challenges = get_challenges(transaction_id=session)
            # We found several challenges with the given transaction ID,
            # and some of the challenges may belong to other tokens.
            # We only handle the TiQR tokens.
            for challenge in challenges:
                if challenge.is_valid() and challenge.otp_valid is False:
                    # Challenge is still valid (time has not passed) and no
                    # correct response was given.
                    token = get_one_token(serial=challenge.serial)
                    if token.type.lower() == "tiqr":
                        # We found a TiQR token with a valid challenge with the given transaction ID
                        r = token.verify_response(
                            challenge=challenge.challenge, passw=passw)
                        if r > 0:
                            res = "OK"
                            # Mark the challenge as answered successfully.
                            challenge.set_otp_status(True)
                            # We have found a valid TiQR token transaction, we break out of the loop
                            break
                        else:
                            # Send back how may retries there are left for the token is blocked
                            token.inc_failcount()
                            fail = token.get_failcount()
                            maxfail = token.get_max_failcount()
                            res = "INVALID_RESPONSE:{0!s}".format(maxfail - fail)
                            break

            cleanup_challenges()

            return "plain", res