blob: e244bdde509c6162bb5d53b8569987263aded954 [file] [log] [blame]
// Copyright 2016 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.
#ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_REUSE_DETECTOR_H_
#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_REUSE_DETECTOR_H_
#include <stdint.h>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>
#include "base/macros.h"
#include "base/optional.h"
#include "base/strings/string16.h"
#include "components/password_manager/core/browser/hash_password_manager.h"
#include "components/password_manager/core/browser/password_store_change.h"
#include "components/password_manager/core/browser/password_store_consumer.h"
namespace password_manager {
class PasswordReuseDetectorConsumer;
// Comparator that compares reversed strings.
struct ReverseStringLess {
bool operator()(const base::string16& lhs, const base::string16& rhs) const;
};
// Per-profile class responsible for detection of password reuse, i.e. that the
// user input on some site contains the password saved on another site.
// It receives saved passwords through PasswordStoreConsumer interface.
// It stores passwords in memory and CheckReuse() can be used for finding
// a password reuse.
class PasswordReuseDetector : public PasswordStoreConsumer {
public:
PasswordReuseDetector();
~PasswordReuseDetector() override;
// PasswordStoreConsumer
void OnGetPasswordStoreResults(
std::vector<std::unique_ptr<autofill::PasswordForm>> results) override;
// Add new or updated passwords from |changes| to internal password index.
void OnLoginsChanged(const PasswordStoreChangeList& changes);
// Checks that some suffix of |input| equals to a password saved on another
// registry controlled domain than |domain| or to a sync password.
// If such suffix is found, |consumer|->OnReuseFound() is called on the same
// thread on which this method is called.
// |consumer| should not be null.
void CheckReuse(const base::string16& input,
const std::string& domain,
PasswordReuseDetectorConsumer* consumer);
// Stores internal |sync_password_data| for password reuse checking.
void UseSyncPasswordHash(base::Optional<PasswordHashData> sync_password_data);
// Stores a vector of PasswordHashData for Gaia password reuse checking.
void UseGaiaPasswordHash(
base::Optional<std::vector<PasswordHashData>> password_hash_data_list);
// Stores a vector of PasswordHashData for enterprise password reuse checking.
void UseNonGaiaEnterprisePasswordHash(
base::Optional<std::vector<PasswordHashData>> password_hash_data_list);
// Stores enterprise login URLs and change password URL.
// These URLs should be skipped in enterprise password reuse checking.
void UseEnterprisePasswordURLs(
base::Optional<std::vector<GURL>> enterprise_login_urls,
base::Optional<GURL> enterprise_change_password_url);
void ClearGaiaPasswordHash(const std::string& username);
void ClearAllGaiaPasswordHash();
void ClearAllEnterprisePasswordHash();
private:
using passwords_iterator = std::map<base::string16,
std::set<std::string>,
ReverseStringLess>::const_iterator;
// Add password from |form| to |passwords_|.
void AddPassword(const autofill::PasswordForm& form);
// If Gaia password reuse is found, return the PasswordHashData of the reused
// password. If no reuse is found, return |base::nullopt|.
base::Optional<PasswordHashData> CheckGaiaPasswordReuse(
const base::string16& input,
const std::string& domain);
// If Non-Gaia enterprise password reuse is found, return the PasswordHashData
// of the the reused password. If no reuse is found, return |base::nullopt|.
base::Optional<PasswordHashData> CheckNonGaiaEnterprisePasswordReuse(
const base::string16& input,
const std::string& domain);
// If saved-password reuse is found, fill in the registry-controlled
// domains that match any reused password, and return the length of the
// longest password matched. If no reuse is found, return 0.
size_t CheckSavedPasswordReuse(
const base::string16& input,
const std::string& domain,
std::vector<std::string>* matching_domains_out);
// Returns the iterator to |passwords_| that corresponds to the longest key in
// |passwords_| that is a suffix of |input|. Returns passwords_.end() in case
// when no key in |passwords_| is a prefix of |input|.
passwords_iterator FindFirstSavedPassword(const base::string16& input);
// Call this repeatedly with iterator from |FindFirstSavedPassword| to
// find other matching passwords. This returns the iterator to |passwords_|
// that is the next previous matching entry that's a suffix of |input|, or
// passwords_.end() if there are no more.
passwords_iterator FindNextSavedPassword(const base::string16& input,
passwords_iterator it);
// Contains all passwords.
// A key is a password.
// A value is a set of registry controlled domains on which the password
// saved.
std::map<base::string16, std::set<std::string>, ReverseStringLess> passwords_;
// Number of passwords in |passwords_|, each password is calculated the number
// of times how many different sites it's saved on.
int saved_passwords_ = 0;
base::Optional<std::vector<PasswordHashData>> gaia_password_hash_data_list_;
base::Optional<std::vector<PasswordHashData>>
enterprise_password_hash_data_list_;
base::Optional<std::vector<GURL>> enterprise_password_urls_;
DISALLOW_COPY_AND_ASSIGN(PasswordReuseDetector);
};
} // namespace password_manager
#endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_REUSE_DETECTOR_H_