diff options
Diffstat (limited to 'chromium/chrome/browser/extensions/api/certificate_provider/certificate_provider_api.cc')
-rw-r--r-- | chromium/chrome/browser/extensions/api/certificate_provider/certificate_provider_api.cc | 70 |
1 files changed, 66 insertions, 4 deletions
diff --git a/chromium/chrome/browser/extensions/api/certificate_provider/certificate_provider_api.cc b/chromium/chrome/browser/extensions/api/certificate_provider/certificate_provider_api.cc index 533bdee1e87..4530f54ea05 100644 --- a/chromium/chrome/browser/extensions/api/certificate_provider/certificate_provider_api.cc +++ b/chromium/chrome/browser/extensions/api/certificate_provider/certificate_provider_api.cc @@ -12,6 +12,8 @@ #include "base/bind.h" #include "base/logging.h" +#include "base/macros.h" +#include "base/values.h" #include "chrome/browser/chromeos/certificate_provider/certificate_provider_service.h" #include "chrome/browser/chromeos/certificate_provider/certificate_provider_service_factory.h" #include "chrome/browser/chromeos/certificate_provider/pin_dialog_manager.h" @@ -19,6 +21,7 @@ #include "chrome/common/extensions/api/certificate_provider.h" #include "chrome/common/extensions/api/certificate_provider_internal.h" #include "chromeos/constants/security_token_pin_types.h" +#include "extensions/browser/quota_service.h" #include "net/cert/x509_certificate.h" #include "net/ssl/ssl_private_key.h" #include "third_party/blink/public/mojom/devtools/console_message.mojom.h" @@ -75,9 +78,55 @@ const char kCertificateProviderPreviousDialogActive[] = "Previous request not finished"; const char kCertificateProviderNoUserInput[] = "No user input received"; +// The BucketMapper implementation for the requestPin API that avoids using the +// quota when the current request uses the requestId that is strictly greater +// than all previous ones. +class RequestPinExceptFirstQuotaBucketMapper final + : public QuotaLimitHeuristic::BucketMapper { + public: + RequestPinExceptFirstQuotaBucketMapper() = default; + ~RequestPinExceptFirstQuotaBucketMapper() override = default; + + void GetBucketsForArgs(const base::ListValue* args, + QuotaLimitHeuristic::BucketList* buckets) override { + if (args->GetList().empty()) + return; + const base::Value& details = args->GetList()[0]; + if (!details.is_dict()) + return; + const base::Value* sign_request_id = + details.FindKeyOfType("signRequestId", base::Value::Type::INTEGER); + if (!sign_request_id) + return; + if (sign_request_id->GetInt() > biggest_request_id_) { + // Either it's the first request with the newly issued requestId, or it's + // an invalid requestId (bigger than the real one). Return a new bucket in + // order to apply no quota for the former case; for the latter case the + // quota doesn't matter much, except that we're maybe making it stricter + // for future requests (which is bearable). + biggest_request_id_ = sign_request_id->GetInt(); + new_request_bucket_ = std::make_unique<QuotaLimitHeuristic::Bucket>(); + buckets->push_back(new_request_bucket_.get()); + return; + } + // Either it's a repeatitive request for the given requestId, or the + // extension reordered the requests. Fall back to the default bucket (shared + // between all requests) in that case. + buckets->push_back(&default_bucket_); + } + + private: + int biggest_request_id_ = -1; + QuotaLimitHeuristic::Bucket default_bucket_; + std::unique_ptr<QuotaLimitHeuristic::Bucket> new_request_bucket_; + + DISALLOW_COPY_AND_ASSIGN(RequestPinExceptFirstQuotaBucketMapper); +}; + } // namespace -const int api::certificate_provider::kMaxClosedDialogsPer10Mins = 2; +const int api::certificate_provider::kMaxClosedDialogsPerMinute = 10; +const int api::certificate_provider::kMaxClosedDialogsPer10Minutes = 30; CertificateProviderInternalReportCertificatesFunction:: ~CertificateProviderInternalReportCertificatesFunction() {} @@ -256,12 +305,25 @@ bool CertificateProviderRequestPinFunction::ShouldSkipQuotaLimiting() const { } void CertificateProviderRequestPinFunction::GetQuotaLimitHeuristics( - extensions::QuotaLimitHeuristics* heuristics) const { + QuotaLimitHeuristics* heuristics) const { + // Apply a 1-minute and a 10-minute quotas. A special bucket mapper is used in + // order to, approximately, skip applying quotas to the first request for each + // requestId (such logic cannot be done in ShouldSkipQuotaLimiting(), since + // it's not called with the request's parameters). The limitation constants + // are decremented below to account the first request. + QuotaLimitHeuristic::Config short_limit_config = { - api::certificate_provider::kMaxClosedDialogsPer10Mins, + api::certificate_provider::kMaxClosedDialogsPerMinute - 1, + base::TimeDelta::FromMinutes(1)}; + heuristics->push_back(std::make_unique<QuotaService::TimedLimit>( + short_limit_config, new RequestPinExceptFirstQuotaBucketMapper, + "MAX_PIN_DIALOGS_CLOSED_PER_MINUTE")); + + QuotaLimitHeuristic::Config long_limit_config = { + api::certificate_provider::kMaxClosedDialogsPer10Minutes - 1, base::TimeDelta::FromMinutes(10)}; heuristics->push_back(std::make_unique<QuotaService::TimedLimit>( - short_limit_config, new QuotaLimitHeuristic::SingletonBucketMapper(), + long_limit_config, new RequestPinExceptFirstQuotaBucketMapper, "MAX_PIN_DIALOGS_CLOSED_PER_10_MINUTES")); } |