Migrate challenge-issuing rate limiters to the abusive message filter

This commit is contained in:
Jon Chambers
2021-11-18 15:39:46 -05:00
committed by Jon Chambers
parent 9628f147f1
commit 14cff958e9
26 changed files with 311 additions and 982 deletions

View File

@@ -40,9 +40,6 @@ import org.whispersystems.textsecuregcm.entities.PreKeyResponse;
import org.whispersystems.textsecuregcm.entities.PreKeyResponseItem;
import org.whispersystems.textsecuregcm.entities.PreKeyState;
import org.whispersystems.textsecuregcm.entities.SignedPreKey;
import org.whispersystems.textsecuregcm.limits.PreKeyRateLimiter;
import org.whispersystems.textsecuregcm.limits.RateLimitChallengeException;
import org.whispersystems.textsecuregcm.limits.RateLimitChallengeManager;
import org.whispersystems.textsecuregcm.limits.RateLimiters;
import org.whispersystems.textsecuregcm.storage.Account;
import org.whispersystems.textsecuregcm.storage.AccountsManager;
@@ -57,24 +54,16 @@ public class KeysController {
private final RateLimiters rateLimiters;
private final Keys keys;
private final AccountsManager accounts;
private final PreKeyRateLimiter preKeyRateLimiter;
private final RateLimitChallengeManager rateLimitChallengeManager;
private static final String PREKEY_REQUEST_COUNTER_NAME = name(KeysController.class, "preKeyGet");
private static final String RATE_LIMITED_GET_PREKEYS_COUNTER_NAME = name(KeysController.class, "rateLimitedGetPreKeys");
private static final String SOURCE_COUNTRY_TAG_NAME = "sourceCountry";
private static final String INTERNATIONAL_TAG_NAME = "international";
public KeysController(RateLimiters rateLimiters, Keys keys, AccountsManager accounts,
PreKeyRateLimiter preKeyRateLimiter,
RateLimitChallengeManager rateLimitChallengeManager) {
this.rateLimiters = rateLimiters;
public KeysController(RateLimiters rateLimiters, Keys keys, AccountsManager accounts) {
this.rateLimiters = rateLimiters;
this.keys = keys;
this.accounts = accounts;
this.preKeyRateLimiter = preKeyRateLimiter;
this.rateLimitChallengeManager = rateLimitChallengeManager;
this.accounts = accounts;
}
@GET
@@ -142,7 +131,7 @@ public class KeysController {
@PathParam("identifier") UUID targetUuid,
@PathParam("device_id") String deviceId,
@HeaderParam("User-Agent") String userAgent)
throws RateLimitExceededException, RateLimitChallengeException, ServerRejectedException {
throws RateLimitExceededException {
if (!auth.isPresent() && !accessKey.isPresent()) {
throw new WebApplicationException(Response.Status.UNAUTHORIZED);
@@ -174,23 +163,6 @@ public class KeysController {
rateLimiters.getPreKeysLimiter().validate(
account.get().getUuid() + "." + auth.get().getAuthenticatedDevice().getId() + "__" + targetUuid
+ "." + deviceId);
try {
preKeyRateLimiter.validate(account.get());
} catch (RateLimitExceededException e) {
final boolean legacyClient = rateLimitChallengeManager.isClientBelowMinimumVersion(userAgent);
Metrics.counter(RATE_LIMITED_GET_PREKEYS_COUNTER_NAME,
SOURCE_COUNTRY_TAG_NAME, Util.getCountryCode(account.get().getNumber()),
"legacyClient", String.valueOf(legacyClient))
.increment();
if (legacyClient) {
throw new ServerRejectedException();
}
throw new RateLimitChallengeException(account.get(), e.getRetryDuration());
}
}
final boolean usePhoneNumberIdentity = target.getPhoneNumberIdentifier().equals(targetUuid);

View File

@@ -75,9 +75,7 @@ import org.whispersystems.textsecuregcm.entities.SendMessageResponse;
import org.whispersystems.textsecuregcm.entities.SendMultiRecipientMessageResponse;
import org.whispersystems.textsecuregcm.entities.StaleDevices;
import org.whispersystems.textsecuregcm.limits.RateLimitChallengeException;
import org.whispersystems.textsecuregcm.limits.RateLimitChallengeManager;
import org.whispersystems.textsecuregcm.limits.RateLimiters;
import org.whispersystems.textsecuregcm.limits.UnsealedSenderRateLimiter;
import org.whispersystems.textsecuregcm.metrics.UserAgentTagUtil;
import org.whispersystems.textsecuregcm.providers.MultiRecipientMessageProvider;
import org.whispersystems.textsecuregcm.push.ApnFallbackManager;
@@ -109,9 +107,7 @@ public class MessageController {
private final ReceiptSender receiptSender;
private final AccountsManager accountsManager;
private final MessagesManager messagesManager;
private final UnsealedSenderRateLimiter unsealedSenderRateLimiter;
private final ApnFallbackManager apnFallbackManager;
private final RateLimitChallengeManager rateLimitChallengeManager;
private final ReportMessageManager reportMessageManager;
private final ExecutorService multiRecipientMessageExecutor;
@@ -145,9 +141,7 @@ public class MessageController {
ReceiptSender receiptSender,
AccountsManager accountsManager,
MessagesManager messagesManager,
UnsealedSenderRateLimiter unsealedSenderRateLimiter,
ApnFallbackManager apnFallbackManager,
RateLimitChallengeManager rateLimitChallengeManager,
ReportMessageManager reportMessageManager,
@Nonnull ExecutorService multiRecipientMessageExecutor) {
this.rateLimiters = rateLimiters;
@@ -155,9 +149,7 @@ public class MessageController {
this.receiptSender = receiptSender;
this.accountsManager = accountsManager;
this.messagesManager = messagesManager;
this.unsealedSenderRateLimiter = unsealedSenderRateLimiter;
this.apnFallbackManager = apnFallbackManager;
this.rateLimitChallengeManager = rateLimitChallengeManager;
this.reportMessageManager = reportMessageManager;
this.multiRecipientMessageExecutor = Objects.requireNonNull(multiRecipientMessageExecutor);
}
@@ -238,24 +230,6 @@ public class MessageController {
throw e;
}
try {
unsealedSenderRateLimiter.validate(source.get().getAccount(), destination.get());
} catch (final RateLimitExceededException e) {
final boolean legacyClient = rateLimitChallengeManager.isClientBelowMinimumVersion(userAgent);
final String rateLimitReason = legacyClient ? "unsealedSenderCardinality" : "challengeIssued";
Metrics.counter(RATE_LIMITED_MESSAGE_COUNTER_NAME,
SENDER_COUNTRY_TAG_NAME, senderCountryCode,
RATE_LIMIT_REASON_TAG_NAME, rateLimitReason).increment();
if (legacyClient) {
throw e;
}
throw new RateLimitChallengeException(source.get().getAccount(), e.getRetryDuration());
}
}
validateCompleteDeviceList(destination.get(), messages.getMessages(), isSyncMessage,