Exemplo n.º 1
0
    def check_totp_value(self, user_id, totp_value, *, tags=None):
        """
        Returns True if the given TOTP is valid against the user's secret.

        If the user doesn't have a TOTP secret, returns False.
        """
        tags = tags if tags is not None else []
        self._metrics.increment("warehouse.authentication.two_factor.start", tags=tags)

        totp_secret = self.get_totp_secret(user_id)

        if totp_secret is None:
            self._metrics.increment(
                "warehouse.authentication.two_factor.failure",
                tags=tags + ["failure_reason:no_totp"],
            )
            return False

        valid = otp.verify_totp(totp_secret, totp_value)

        if valid:
            self._metrics.increment("warehouse.authentication.two_factor.ok", tags=tags)
        else:
            self._metrics.increment(
                "warehouse.authentication.two_factor.failure",
                tags=tags + ["failure_reason:invalid_totp"],
            )

        return valid
Exemplo n.º 2
0
def test_verify_totp_failure(skew):
    secret = generate_totp_secret()
    totp = TOTP(secret,
                TOTP_LENGTH,
                SHA1(),
                TOTP_INTERVAL,
                backend=default_backend())
    value = totp.generate(time.time() + skew)
    assert not verify_totp(secret, value)
Exemplo n.º 3
0
    def check_totp_value(self, user_id, totp_value, *, tags=None):
        """
        Returns True if the given TOTP is valid against the user's secret.

        If the user doesn't have a TOTP secret or isn't allowed
        to use second factor methods, returns False.
        """
        tags = tags if tags is not None else []
        self._metrics.increment("warehouse.authentication.two_factor.start",
                                tags=tags)

        # The very first thing we want to do is check to see if we've hit our
        # global rate limit or not, assuming that we've been configured with a
        # global rate limiter anyways.
        if not self.ratelimiters["global"].test():
            logger.warning("Global failed login threshold reached.")
            self._metrics.increment(
                "warehouse.authentication.two_factor.ratelimited",
                tags=tags + ["ratelimiter:global"],
            )
            raise TooManyFailedLogins(
                resets_in=self.ratelimiters["global"].resets_in())

        # Now, check to make sure that we haven't hitten a rate limit on a
        # per user basis.
        if not self.ratelimiters["user"].test(user_id):
            self._metrics.increment(
                "warehouse.authentication.two_factor.ratelimited",
                tags=tags + ["ratelimiter:user"],
            )
            raise TooManyFailedLogins(
                resets_in=self.ratelimiters["user"].resets_in(user_id))

        totp_secret = self.get_totp_secret(user_id)

        if totp_secret is None:
            self._metrics.increment(
                "warehouse.authentication.two_factor.failure",
                tags=tags + ["failure_reason:no_totp"],
            )
            return False

        valid = otp.verify_totp(totp_secret, totp_value)

        if valid:
            self._metrics.increment("warehouse.authentication.two_factor.ok",
                                    tags=tags)
        else:
            self._metrics.increment(
                "warehouse.authentication.two_factor.failure",
                tags=tags + ["failure_reason:invalid_totp"],
            )

        return valid
Exemplo n.º 4
0
    def check_totp_value(self, user_id, totp_value, ip_address, *, tags=None):
        """
        Returns True if the given TOTP is valid against the user's secret.

        If the user doesn't have a TOTP secret or isn't allowed
        to use second factor methods, returns False.
        """
        tags = tags if tags is not None else []
        tags.append("mechanism:check_totp_value")
        self._metrics.increment("warehouse.authentication.two_factor.start",
                                tags=tags)

        self._check_ratelimits(userid=user_id,
                               ip_address=ip_address,
                               tags=tags)

        totp_secret = self.get_totp_secret(user_id)

        if totp_secret is None:
            self._metrics.increment(
                "warehouse.authentication.two_factor.failure",
                tags=tags + ["failure_reason:no_totp"],
            )
            # If we've gotten here, then we'll want to record a failed attempt in our
            # rate limiting before returning False to indicate a failed totp
            # verification.
            self._hit_ratelimits(ip_address, userid=user_id)
            return False

        last_totp_value = self.get_last_totp_value(user_id)

        if last_totp_value is not None and totp_value == last_totp_value.encode(
        ):
            return False

        valid = otp.verify_totp(totp_secret, totp_value)

        if valid:
            self._metrics.increment("warehouse.authentication.two_factor.ok",
                                    tags=tags)
        else:
            self._metrics.increment(
                "warehouse.authentication.two_factor.failure",
                tags=tags + ["failure_reason:invalid_totp"],
            )
            # If we've gotten here, then we'll want to record a failed attempt in our
            # rate limiting before returning False to indicate a failed totp
            # verification.
            self._hit_ratelimits(ip_address, userid=user_id)

        return valid
Exemplo n.º 5
0
 def validate_totp_value(self, field):
     totp_value = field.data.encode("utf8")
     if not otp.verify_totp(self.totp_secret, totp_value):
         raise wtforms.validators.ValidationError(
             "Invalid TOTP code. Try again?")
Exemplo n.º 6
0
def test_verify_totp_failure(skew):
    secret = generate_totp_secret()
    totp = TOTP(secret, TOTP_LENGTH, SHA1(), TOTP_INTERVAL, backend=default_backend())
    value = totp.generate(time.time() + skew)
    assert not verify_totp(secret, value)
Exemplo n.º 7
0
 def validate_totp_value(self, field):
     totp_value = field.data.encode("utf8")
     if not otp.verify_totp(self.totp_secret, totp_value):
         raise wtforms.validators.ValidationError("Invalid TOTP code. Try again?")