| Index: components/password_manager/core/browser/android_affiliation/affiliation_utils.cc
|
| diff --git a/components/password_manager/core/browser/android_affiliation/affiliation_utils.cc b/components/password_manager/core/browser/android_affiliation/affiliation_utils.cc
|
| deleted file mode 100644
|
| index 9583702e700fe04cacf6850b96517d7bff4158a3..0000000000000000000000000000000000000000
|
| --- a/components/password_manager/core/browser/android_affiliation/affiliation_utils.cc
|
| +++ /dev/null
|
| @@ -1,314 +0,0 @@
|
| -// Copyright 2014 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "components/password_manager/core/browser/android_affiliation/affiliation_utils.h"
|
| -
|
| -#include <algorithm>
|
| -#include <ostream>
|
| -
|
| -#include "base/base64.h"
|
| -#include "base/strings/string_piece.h"
|
| -#include "base/strings/string_util.h"
|
| -#include "components/autofill/core/common/password_form.h"
|
| -#include "components/url_formatter/elide_url.h"
|
| -#include "components/variations/variations_associated_data.h"
|
| -#include "net/base/escape.h"
|
| -#include "url/third_party/mozilla/url_parse.h"
|
| -#include "url/url_canon_stdstring.h"
|
| -
|
| -namespace password_manager {
|
| -
|
| -namespace {
|
| -
|
| -// The scheme used for identifying Android applications.
|
| -const char kAndroidAppScheme[] = "android";
|
| -
|
| -// Returns a StringPiece corresponding to |component| in |uri|, or the empty
|
| -// string in case there is no such component.
|
| -base::StringPiece ComponentString(const std::string& uri,
|
| - const url::Component& component) {
|
| - if (!component.is_valid())
|
| - return base::StringPiece();
|
| - return base::StringPiece(uri.c_str() + component.begin, component.len);
|
| -}
|
| -
|
| -// Returns true if the passed ASCII |input| string contains nothing else than
|
| -// alphanumeric characters and those in |other_characters|.
|
| -bool ContainsOnlyAlphanumericAnd(const base::StringPiece& input,
|
| - const base::StringPiece& other_characters) {
|
| - for (char c : input) {
|
| - if (!base::IsAsciiAlpha(c) && !base::IsAsciiDigit(c) &&
|
| - other_characters.find(c) == base::StringPiece::npos)
|
| - return false;
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -// Canonicalizes a Web facet URI, and returns true if canonicalization was
|
| -// successful and produced a valid URI.
|
| -bool CanonicalizeWebFacetURI(const std::string& input_uri,
|
| - const url::Parsed& input_parsed,
|
| - std::string* canonical_uri) {
|
| - url::Parsed canonical_parsed;
|
| - url::StdStringCanonOutput canonical_output(canonical_uri);
|
| -
|
| - bool canonicalization_succeeded = url::CanonicalizeStandardURL(
|
| - input_uri.c_str(), input_uri.size(), input_parsed, nullptr,
|
| - &canonical_output, &canonical_parsed);
|
| - canonical_output.Complete();
|
| -
|
| - if (canonicalization_succeeded && canonical_parsed.host.is_nonempty() &&
|
| - !canonical_parsed.username.is_valid() &&
|
| - !canonical_parsed.password.is_valid() &&
|
| - ComponentString(*canonical_uri, canonical_parsed.path) == "/" &&
|
| - !canonical_parsed.query.is_valid() && !canonical_parsed.ref.is_valid()) {
|
| - // Get rid of the trailing slash added by url::CanonicalizeStandardURL().
|
| - DCHECK_EQ((size_t)canonical_parsed.path.begin, canonical_uri->size() - 1);
|
| - canonical_uri->erase(canonical_parsed.path.begin,
|
| - canonical_parsed.path.len);
|
| - return true;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -// Adds padding until the length of the base64-encoded |data| becomes a multiple
|
| -// of 4, and returns true if the thusly obtained |data| is now correctly padded,
|
| -// i.e., there are at most 2 padding characters ('=') at the very end.
|
| -bool CanonicalizeBase64Padding(std::string* data) {
|
| - while (data->size() % 4u != 0u)
|
| - data->push_back('=');
|
| -
|
| - size_t first_padding = data->find_first_of('=');
|
| - return first_padding == std::string::npos ||
|
| - (data->size() - first_padding <= 2u &&
|
| - data->find_first_not_of('=', first_padding) == std::string::npos);
|
| -}
|
| -
|
| -// Canonicalizes the username component in an Android facet URI (containing the
|
| -// certificate hash), and returns true if canonicalization was successful and
|
| -// produced a valid non-empty component.
|
| -bool CanonicalizeHashComponent(const base::StringPiece& input_hash,
|
| - url::CanonOutput* canonical_output) {
|
| - // Characters other than alphanumeric that are used in the "URL and filename
|
| - // safe" base64 alphabet; plus the padding ('=').
|
| - const char kBase64NonAlphanumericChars[] = "-_=";
|
| -
|
| - // We need net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS to
|
| - // unescape the padding ('=').
|
| - std::string base64_encoded_hash = net::UnescapeURLComponent(
|
| - input_hash.as_string(),
|
| - net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS);
|
| -
|
| - if (!base64_encoded_hash.empty() &&
|
| - CanonicalizeBase64Padding(&base64_encoded_hash) &&
|
| - ContainsOnlyAlphanumericAnd(base64_encoded_hash,
|
| - kBase64NonAlphanumericChars)) {
|
| - canonical_output->Append(base64_encoded_hash.data(),
|
| - base64_encoded_hash.size());
|
| - canonical_output->push_back('@');
|
| - return true;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -// Canonicalizes the host component in an Android facet URI (containing the
|
| -// package name), and returns true if canonicalization was successful and
|
| -// produced a valid non-empty component.
|
| -bool CanonicalizePackageNameComponent(
|
| - const base::StringPiece& input_package_name,
|
| - url::CanonOutput* canonical_output) {
|
| - // Characters other than alphanumeric that are permitted in the package names.
|
| - const char kPackageNameNonAlphanumericChars[] = "._";
|
| -
|
| - std::string package_name = net::UnescapeURLComponent(
|
| - input_package_name.as_string(), net::UnescapeRule::NORMAL);
|
| -
|
| - // TODO(engedy): We might want to use a regex to check this more throughly.
|
| - if (!package_name.empty() &&
|
| - ContainsOnlyAlphanumericAnd(package_name,
|
| - kPackageNameNonAlphanumericChars)) {
|
| - canonical_output->Append(package_name.data(), package_name.size());
|
| - return true;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -// Canonicalizes an Android facet URI, and returns true if canonicalization was
|
| -// successful and produced a valid URI.
|
| -bool CanonicalizeAndroidFacetURI(const std::string& input_uri,
|
| - const url::Parsed& input_parsed,
|
| - std::string* canonical_uri) {
|
| - url::StdStringCanonOutput canonical_output(canonical_uri);
|
| -
|
| - url::Component unused;
|
| - bool success = url::CanonicalizeScheme(
|
| - input_uri.c_str(), input_parsed.scheme, &canonical_output, &unused);
|
| -
|
| - canonical_output.push_back('/');
|
| - canonical_output.push_back('/');
|
| -
|
| - // We cannot use url::CanonicalizeUserInfo as that would percent encode the
|
| - // base64 padding characters ('=').
|
| - success &= CanonicalizeHashComponent(
|
| - ComponentString(input_uri, input_parsed.username), &canonical_output);
|
| -
|
| - // We cannot use url::CanonicalizeHost as that would convert the package name
|
| - // to lower case, but the package name is case sensitive.
|
| - success &= CanonicalizePackageNameComponent(
|
| - ComponentString(input_uri.data(), input_parsed.host), &canonical_output);
|
| -
|
| - canonical_output.Complete();
|
| -
|
| - return success && !input_parsed.password.is_nonempty() &&
|
| - (!input_parsed.path.is_nonempty() ||
|
| - ComponentString(input_uri, input_parsed.path) == "/") &&
|
| - !input_parsed.port.is_nonempty() && !input_parsed.query.is_valid() &&
|
| - !input_parsed.ref.is_valid();
|
| -}
|
| -
|
| -// Computes the canonicalized form of |uri| into |canonical_uri|, and returns
|
| -// true if canonicalization was successful and produced a valid URI.
|
| -bool ParseAndCanonicalizeFacetURI(const std::string& input_uri,
|
| - std::string* canonical_uri) {
|
| - DCHECK(canonical_uri);
|
| - canonical_uri->clear();
|
| - canonical_uri->reserve(input_uri.size() + 32);
|
| -
|
| - url::Parsed input_parsed;
|
| - url::ParseStandardURL(input_uri.c_str(), input_uri.size(), &input_parsed);
|
| -
|
| - base::StringPiece scheme = ComponentString(input_uri, input_parsed.scheme);
|
| - if (base::LowerCaseEqualsASCII(scheme, url::kHttpsScheme)) {
|
| - return CanonicalizeWebFacetURI(input_uri, input_parsed, canonical_uri);
|
| - } else if (base::LowerCaseEqualsASCII(scheme, kAndroidAppScheme)) {
|
| - return CanonicalizeAndroidFacetURI(input_uri, input_parsed, canonical_uri);
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -
|
| -// FacetURI -------------------------------------------------------------------
|
| -
|
| -FacetURI::FacetURI() : is_valid_(false) {
|
| -}
|
| -
|
| -// static
|
| -FacetURI FacetURI::FromPotentiallyInvalidSpec(const std::string& spec) {
|
| - std::string canonical_spec;
|
| - bool is_valid = ParseAndCanonicalizeFacetURI(spec, &canonical_spec);
|
| - return FacetURI(canonical_spec, is_valid);
|
| -}
|
| -
|
| -// static
|
| -FacetURI FacetURI::FromCanonicalSpec(const std::string& canonical_spec) {
|
| - return FacetURI(canonical_spec, true);
|
| -}
|
| -
|
| -bool FacetURI::operator==(const FacetURI& other) const {
|
| - DCHECK(is_empty() || is_valid());
|
| - DCHECK(other.is_empty() || other.is_valid());
|
| - return canonical_spec_ == other.canonical_spec_;
|
| -}
|
| -
|
| -bool FacetURI::operator!=(const FacetURI& other) const {
|
| - DCHECK(is_empty() || is_valid());
|
| - DCHECK(other.is_empty() || other.is_valid());
|
| - return canonical_spec_ != other.canonical_spec_;
|
| -}
|
| -
|
| -bool FacetURI::operator<(const FacetURI& other) const {
|
| - DCHECK(is_empty() || is_valid());
|
| - DCHECK(other.is_empty() || other.is_valid());
|
| - return canonical_spec_ < other.canonical_spec_;
|
| -}
|
| -
|
| -bool FacetURI::operator>(const FacetURI& other) const {
|
| - DCHECK(is_empty() || is_valid());
|
| - DCHECK(other.is_empty() || other.is_valid());
|
| - return canonical_spec_ > other.canonical_spec_;
|
| -}
|
| -
|
| -bool FacetURI::IsValidWebFacetURI() const {
|
| - return scheme() == url::kHttpsScheme;
|
| -}
|
| -
|
| -bool FacetURI::IsValidAndroidFacetURI() const {
|
| - return scheme() == kAndroidAppScheme;
|
| -}
|
| -
|
| -std::string FacetURI::scheme() const {
|
| - return is_valid()
|
| - ? ComponentString(canonical_spec_, parsed_.scheme).as_string()
|
| - : "";
|
| -}
|
| -
|
| -std::string FacetURI::android_package_name() const {
|
| - if (!IsValidAndroidFacetURI())
|
| - return "";
|
| - return ComponentString(canonical_spec_, parsed_.host).as_string();
|
| -}
|
| -
|
| -FacetURI::FacetURI(const std::string& canonical_spec, bool is_valid)
|
| - : is_valid_(is_valid), canonical_spec_(canonical_spec) {
|
| - // TODO(engedy): Refactor code in order to avoid to avoid parsing the URL
|
| - // twice.
|
| - url::ParseStandardURL(canonical_spec_.c_str(), canonical_spec_.size(),
|
| - &parsed_);
|
| -}
|
| -
|
| -
|
| -// AffiliatedFacetsWithUpdateTime ---------------------------------------------
|
| -
|
| -AffiliatedFacetsWithUpdateTime::AffiliatedFacetsWithUpdateTime() {
|
| -}
|
| -
|
| -AffiliatedFacetsWithUpdateTime::AffiliatedFacetsWithUpdateTime(
|
| - const AffiliatedFacetsWithUpdateTime& other) = default;
|
| -
|
| -AffiliatedFacetsWithUpdateTime::~AffiliatedFacetsWithUpdateTime() {
|
| -}
|
| -
|
| -
|
| -// Helpers --------------------------------------------------------------------
|
| -
|
| -std::ostream& operator<<(std::ostream& os, const FacetURI& facet_uri) {
|
| - return os << facet_uri.potentially_invalid_spec();
|
| -}
|
| -
|
| -bool AreEquivalenceClassesEqual(const AffiliatedFacets& a,
|
| - const AffiliatedFacets& b) {
|
| - if (a.size() != b.size())
|
| - return false;
|
| -
|
| - std::vector<FacetURI> a_sorted(a.begin(), a.end());
|
| - std::vector<FacetURI> b_sorted(b.begin(), b.end());
|
| - std::sort(a_sorted.begin(), a_sorted.end());
|
| - std::sort(b_sorted.begin(), b_sorted.end());
|
| - return std::equal(a_sorted.begin(), a_sorted.end(), b_sorted.begin());
|
| -}
|
| -
|
| -bool IsValidAndroidFacetURI(const std::string& url) {
|
| - FacetURI facet = FacetURI::FromPotentiallyInvalidSpec(url);
|
| - return facet.IsValidAndroidFacetURI();
|
| -}
|
| -
|
| -std::string GetHumanReadableOrigin(
|
| - const autofill::PasswordForm& password_form) {
|
| - FacetURI facet_uri =
|
| - FacetURI::FromPotentiallyInvalidSpec(password_form.signon_realm);
|
| - if (facet_uri.IsValidAndroidFacetURI())
|
| - return GetHumanReadableOriginForAndroidUri(facet_uri);
|
| -
|
| - return base::UTF16ToUTF8(
|
| - url_formatter::FormatUrlForSecurityDisplay(password_form.origin));
|
| -}
|
| -
|
| -std::string GetHumanReadableOriginForAndroidUri(const FacetURI facet_uri) {
|
| - DCHECK(facet_uri.IsValidAndroidFacetURI());
|
| - return facet_uri.scheme() + "://" + facet_uri.android_package_name();
|
| -}
|
| -
|
| -} // namespace password_manager
|
|
|