Chrome · CredentialProvider
CVE-2026-106340
Authorization Error in CredentialProvider
Overview
Low
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifchrome/credential_provider/gaiacp/reg_utils.cc |
modified | |
ExperimentsManagerTestchrome/credential_provider/gaiacp/experiments_manager_unittest.cc |
modified | |
TEST_Fchrome/credential_provider/gaiacp/experiments_manager_unittest.cc |
modified |
Files Changed
chrome/credential_provider/gaiacp/gaia_credential_base.ccchrome/credential_provider/gaiacp/reauth_credential_unittest.ccchrome/credential_provider/gaiacp/experiments_manager_unittest.ccchrome/credential_provider/test/gcp_setup_unittest.ccchrome/credential_provider/test/gls_runner_test_base.ccchrome/credential_provider/gaiacp/reg_utils.ccchrome/credential_provider/gaiacp/gaia_credential_base_unittest.ccchrome/credential_provider/gaiacp/gcp_utils_unittest.ccchrome/credential_provider/gaiacp/associated_user_validator.ccchrome/credential_provider/gaiacp/reg_utils.h
Patch
From f91fec5484683b7bcdd4f1732cc0e3fd790800f1 Mon Sep 17 00:00:00 2001 From: Krishna Kurapati <[email protected]> Date: Mon, 31 Aug 2026 18:41:55 -0700 Subject: [PATCH] Update matching logic of finding existing GCPW user to check both gaia id and email address Bug: 503794852 Change-Id: Ic5efde56ffaee757880a6e594cf1df7d3fd20960 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8207682 Reviewed-by: Yusuf Sengul <[email protected]> Commit-Queue: Krishna Kurapati <[email protected]> Reviewed-by: Tien Mai <[email protected]> Cr-Commit-Position: refs/heads/main@{#1689506} --- diff --git a/chrome/credential_provider/gaiacp/associated_user_validator.cc b/chrome/credential_provider/gaiacp/associated_user_validator.cc index 80b2cc4..ae7dd84 100644 --- a/chrome/credential_provider/gaiacp/associated_user_validator.cc +++ b/chrome/credential_provider/gaiacp/associated_user_validator.cc @@ -180,7 +180,11 @@ } // namespace AssociatedUserValidator::TokenHandleInfo::TokenHandleInfo() = default; -AssociatedUserValidator::TokenHandleInfo::~TokenHandleInfo() = default; +AssociatedUserValidator::TokenHandleInfo::~TokenHandleInfo() { + if (pending_query_thread.is_valid()) { + ::WaitForSingleObject(pending_query_thread.get(), INFINITE); + } +} AssociatedUserValidator::TokenHandleInfo::TokenHandleInfo( const std::wstring& token_handle) diff --git a/chrome/credential_provider/gaiacp/gaia_credential_base.cc b/chrome/credential_provider/gaiacp/gaia_credential_base.cc index 8e21738..b13744e 100644 --- a/chrome/credential_provider/gaiacp/gaia_credential_base.cc +++ b/chrome/credential_provider/gaiacp/gaia_credential_base.cc @@ -497,14 +497,9 @@ // First try to detect if this gaia account has been used to create an OS // user already. If so, return the OS username of that user. - HRESULT hr = GetSidFromId(*gaia_id, sid, sid_length); + HRESULT hr = GetSidFromIdAndEmail(*gaia_id, email, sid, sid_length); if (FAILED(hr)) { - LOGFN(VERBOSE) << "Failed fetching Sid from Id : " << putHR(hr); - // If there is no gaia id user property available in the registry, - // fallback to email address mapping. - hr = GetSidFromEmail(email, sid, sid_length); - if (FAILED(hr)) - LOGFN(VERBOSE) << "Failed fetching Sid from email : " << putHR(hr); + LOGFN(VERBOSE) << "Failed fetching Sid from Id and email: " << putHR(hr); } // Check if the machine is domain joined and get the domain name if domain diff --git a/chrome/credential_provider/gaiacp/reg_utils.cc b/chrome/credential_provider/gaiacp/reg_utils.cc index 749f8a0..ef29c32 100644 --- a/chrome/credential_provider/gaiacp/reg_utils.cc +++ b/chrome/credential_provider/gaiacp/reg_utils.cc @@ -432,22 +432,30 @@ return S_OK; } -HRESULT GetSidFromKey(const wchar_t* key, - const std::wstring& value, - wchar_t* sid, - ULONG length) { +HRESULT GetSidFromIdAndEmail(const std::wstring& id, + const std::wstring& email, + wchar_t* sid, + ULONG length) { DCHECK(sid); bool result_found = false; base::win::RegistryKeyIterator iter(HKEY_LOCAL_MACHINE, kGcpUsersRootKeyName); for (; iter.Valid(); ++iter) { const wchar_t* user_sid = iter.Name(); - wchar_t result[256]; - ULONG result_length = std::size(result); - HRESULT hr = GetUserProperty(user_sid, key, result, &result_length); - if (SUCCEEDED(hr) && value == result) { + wchar_t user_id[256]; + ULONG user_id_length = std::size(user_id); + wchar_t user_email[256]; + ULONG user_email_length = std::size(user_email); + + if (SUCCEEDED( + GetUserProperty(user_sid, kUserId, user_id, &user_id_length)) && + id == user_id && + SUCCEEDED(GetUserProperty(user_sid, kUserEmail, user_email, + &user_email_length)) && + email == user_email) { // Make sure there are not 2 users with the same SID. - if (result_found) + if (result_found) { return HRESULT_FROM_WIN32(ERROR_USER_EXISTS); + } UNSAFE_TODO(wcsncpy_s(sid, length, user_sid, wcslen(user_sid))); result_found = true; @@ -457,33 +465,39 @@ return result_found ? S_OK : HRESULT_FROM_WIN32(ERROR_NONE_MAPPED); } -HRESULT GetSidFromEmail(const std::wstring& email, wchar_t* sid, ULONG length) { - return GetSidFromKey(kUserEmail, email, sid, length); -} - -HRESULT GetSidFromId(const std::wstring& id, wchar_t* sid, ULONG length) { - return GetSidFromKey(kUserId, id, sid, length); -} - HRESULT GetSidFromDomainAccountInfo(const std::wstring& domain, const std::wstring& username, wchar_t* sid, ULONG length) { - // Max SID length is 256 characters. - // https://docs.microsoft.com/en-us/windows-hardware/customize/desktop/unattend/microsoft-windows-shell-setup-offlineuseraccounts-offlinedomainaccounts-offlinedomainaccount-sid - wchar_t sid1[256]; - wchar_t sid2[256]; + DCHECK(sid); + bool result_found = false; + base::win::RegistryKeyIterator iter(HKEY_LOCAL_MACHINE, kGcpUsersRootKeyName); + for (; iter.Valid(); ++iter) { + const wchar_t* user_sid = iter.Name(); + wchar_t user_domain[256]; + ULONG user_domain_length = std::size(user_domain); + wchar_t user_username[256]; + ULONG user_username_length = std::size(user_username); - if (SUCCEEDED(GetSidFromKey(base::UTF8ToWide(kKeyDomain).c_str(), domain, - sid1, length)) && - SUCCEEDED(GetSidFromKey(base::UTF8ToWide(kKeyUsername).c_str(), username, - sid2, length)) && - UNSAFE_TODO(wcsicmp(sid1, sid2) == 0)) { - UNSAFE_TODO(wcscpy_s(sid, length, sid1)); - return S_OK; - } else { - return E_FAIL; + if (SUCCEEDED(GetUserProperty(user_sid, + base::UTF8ToWide(kKeyDomain).c_str(), + user_domain, &user_domain_length)) && + domain == user_domain && + SUCCEEDED(GetUserProperty(user_sid, + base::UTF8ToWide(kKeyUsername).c_str(), + user_username, &user_username_length)) && + username == user_username) { + // Make sure there are not 2 users with the same SID. + if (result_found) { + return HRESULT_FROM_WIN32(ERROR_USER_EXISTS); + } + + UNSAFE_TODO(wcsncpy_s(sid, length, user_sid, wcslen(user_sid))); + result_found = true; + } } + + return result_found ? S_OK : E_FAIL; } HRESULT GetIdFromSid(const wchar_t* sid, std::wstring* id) { diff --git a/chrome/credential_provider/gaiacp/reg_utils.h b/chrome/credential_provider/gaiacp/reg_utils.h index 4905a117..6d385a8 100644 --- a/chrome/credential_provider/gaiacp/reg_utils.h +++ b/chrome/credential_provider/gaiacp/reg_utils.h @@ -214,20 +214,12 @@ HRESULT GetUserTokenHandles( std::map<std::wstring, UserTokenHandleInfo>* sid_to_handle_info); -// Gets the SID associated with the given gaia id. If none exists, returns -// HRESULT_FROM_WIN32(ERROR_NONE_MAPPED). -HRESULT GetSidFromId(const std::wstring& id, wchar_t* sid, ULONG length); - -// Gets the SID associated with the given email. If none exists, returns -// HRESULT_FROM_WIN32(ERROR_NONE_MAPPED). -HRESULT GetSidFromEmail(const std::wstring& email, wchar_t* sid, ULONG length); - -// Gets the SID associated with the given input key. If none exists, returns -// HRESULT_FROM_WIN32(ERROR_NONE_MAPPED). -HRESULT GetSidFromKey(const wchar_t* key, - const std::wstring& value, - wchar_t* sid, - ULONG length); +// Gets the SID associated with the given gaia id and email. If none exists, +// returns HRESULT_FROM_WIN32(ERROR_NONE_MAPPED). +HRESULT GetSidFromIdAndEmail(const std::wstring& id, + const std::wstring& email, + wchar_t* sid, + ULONG length); // Returns the SID corresponding to given domain user from the user properties. HRESULT GetSidFromDomainAccountInfo(const std::wstring& domain, diff --git a/chrome/credential_provider/gaiacp/experiments_manager_unittest.cc b/chrome/credential_provider/gaiacp/experiments_manager_unittest.cc index 8b439189..889d3adf 100644 --- a/chrome/credential_provider/gaiacp/experiments_manager_unittest.cc +++ b/chrome/credential_provider/gaiacp/experiments_manager_unittest.cc @@ -23,6 +23,7 @@ class ExperimentsManagerTest : public GlsRunnerTestBase { protected: void SetUp() override; + void TearDown() override; }; void ExperimentsManagerTest::SetUp() { @@ -30,10 +31,12 @@ ASSERT_EQ(S_OK, SetGlobalFlagForTesting(L"experiments_enabled", 1)); FakesForTesting fakes; + fakes.os_user_manager_for_testing = fake_os_user_manager(); fakes.fake_win_http_url_fetcher_creator = fake_http_url_fetcher_factory()->GetCreatorCallback(); WinHttpUrlFetcher::SetCreatorForTesting( fakes.fake_win_http_url_fetcher_creator); + UserPoliciesManager::Get()->SetFakesForTesting(&fakes); // Set token result a valid access token. fake_http_url_fetcher_factory()->SetFakeResponse( @@ -41,6 +44,10 @@ FakeWinHttpUrlFetcher::Headers(), "{\"access_token\": \"dummy_token\"}"); } +void ExperimentsManagerTest::TearDown() { + GlsRunnerTestBase::TearDown(); +} + TEST_F(ExperimentsManagerTest, DefaultValues) { EXPECT_EQ("false", ExperimentsManager::Get()->GetExperimentForUser( "test_sid", Experiment::TEST_CLIENT_FLAG)); @@ -70,9 +77,10 @@ // Create a fake user that has the same gaia id as the test gaia id. base::win::ScopedBstr sid; - ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser( - L"foo", L"password", L"Full Name", L"comment", - kDefaultGaiaId, L"[email protected]", sid.Receive())); + ASSERT_EQ(S_OK, + fake_os_user_manager()->CreateTestOSUser( + L"foo", L"password", L"Full Name", L"comment", kDefaultGaiaId, + base::UTF8ToWide(kDefaultEmail), sid.Receive())); std::wstring device_resource_id = L"foo_resource_id"; ASSERT_EQ(S_OK, SetUserProperty(sid.Get(), L"device_resource_id", @@ -149,9 +157,10 @@ // Create a fake user that has the same gaia id as the test gaia id. base::win::ScopedBstr sid; - ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser( - L"foo", L"password", L"Full Name", L"comment", - kDefaultGaiaId, L"[email protected]", sid.Receive())); + ASSERT_EQ(S_OK, + fake_os_user_manager()->CreateTestOSUser( + L"foo", L"password", L"Full Name", L"comment", kDefaultGaiaId, + base::UTF8ToWide(kDefaultEmail), sid.Receive())); ASSERT_EQ(S_OK, GenerateGCPWDmToken(sid.Get())); diff --git a/chrome/credential_provider/gaiacp/gaia_credential_base_unittest.cc b/chrome/credential_provider/gaiacp/gaia_credential_base_unittest.cc index b418d264c..ced1c9c 100644 --- a/chrome/credential_provider/gaiacp/gaia_credential_base_unittest.cc +++ b/chrome/credential_provider/gaiacp/gaia_credential_base_unittest.cc @@ -469,7 +469,7 @@ std::wstring username(L"foo"); ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser( username, L"password", L"name", L"comment", - kDefaultGaiaId, std::wstring(), first_sid.Receive())); + kDefaultGaiaId, L"[email protected]", first_sid.Receive())); ASSERT_EQ(2ul, fake_os_user_manager()->GetUserCount()); // Create provider and start logon. Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; @@ -555,7 +555,7 @@ base::win::ScopedBstr windows_password(L"password2"); ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser( L"foo", windows_password.Get(), L"Full Name", L"comment", - kDefaultGaiaId, std::wstring(), sid.Receive())); + kDefaultGaiaId, L"[email protected]", sid.Receive())); // Create provider and start logon. Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; @@ -610,7 +610,7 @@ base::win::ScopedBstr windows_password(L"password2"); ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser( L"foo", windows_password.Get(), L"Full Name", L"comment", - kDefaultGaiaId, std::wstring(), sid.Receive())); + kDefaultGaiaId, L"[email protected]", sid.Receive())); // Create provider and start logon. Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; @@ -679,7 +679,7 @@ base::win::ScopedBstr windows_password(L"password2"); ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser( L"foo", windows_password.Get(), L"Full Name", L"comment", - kDefaultGaiaId, std::wstring(), sid.Receive())); + kDefaultGaiaId, L"[email protected]", sid.Receive())); // Create provider and start logon. Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; @@ -724,7 +724,7 @@ base::win::ScopedBstr windows_password(L"password2"); ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser( L"foo", windows_password.Get(), L"Full Name", L"comment", - kDefaultGaiaId, std::wstring(), sid.Receive())); + kDefaultGaiaId, L"[email protected]", sid.Receive())); // Create provider and start logon. Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; @@ -1112,7 +1112,7 @@ ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser( L"foo_registered", L"password", L"name", L"comment", - GaiaId("gaia-id-registered"), std::wstring(), sid.Receive())); + GaiaId("gaia-id-registered"), L"[email protected]", sid.Receive())); // Populate the associated users list. The created user's token handle // should be valid so that no reauth credential is created. @@ -1146,7 +1146,7 @@ std::wstring username(L"foo"); ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser( username, L"password", L"name", L"comment", - kDefaultGaiaId, std::wstring(), sid.Receive())); + kDefaultGaiaId, L"[email protected]", sid.Receive())); ASSERT_EQ(2ul, fake_os_user_manager()->GetUserCount()); // Create provider and start logon. @@ -1200,7 +1200,7 @@ std::wstring username(L"foo"); ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser( username, L"password", L"name", L"comment", - kDefaultGaiaId, std::wstring(), sid.Receive())); + kDefaultGaiaId, L"[email protected]", sid.Receive())); ASSERT_EQ(2ul, fake_os_user_manager()->GetUserCount()); // Create provider and start logon. @@ -1225,7 +1225,7 @@ std::wstring username(L"foo"); ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser( username, L"password", L"name", L"comment", - kDefaultGaiaId, std::wstring(), first_sid.Receive())); + kDefaultGaiaId, L"[email protected]", first_sid.Receive())); ASSERT_EQ(2ul, fake_os_user_manager()->GetUserCount()); UserPolicies user_policies; @@ -1313,7 +1313,7 @@ std::wstring username(L"foo"); ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser( username, L"password", L"name", L"comment", - kDefaultGaiaId, std::wstring(), first_sid.Receive())); + kDefaultGaiaId, L"[email protected]", first_sid.Receive())); ASSERT_EQ(2ul, fake_os_user_manager()->GetUserCount()); std::vector<std::wstring> reauth_sids; @@ -3066,7 +3066,7 @@ constexpr wchar_t kOldPassword[] = L"password"; ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser( kDefaultUsername, kOldPassword, L"Full Name", L"comment", - kDefaultGaiaId, std::wstring(), sid.Receive())); + kDefaultGaiaId, L"[email protected]", sid.Receive())); // Change token response to an invalid one. SetDefaultTokenHandleResponse(kDefaultInvalidTokenHandleResponse); @@ -3298,7 +3298,7 @@ constexpr wchar_t kOldPassword[] = L"password"; ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser( kDefaultUsername, kOldPassword, L"Full Name", L"comment", - kDefaultGaiaId, std::wstring(), sid.Receive())); + kDefaultGaiaId, L"[email protected]", sid.Receive())); // Change token response to an invalid one. SetDefaultTokenHandleResponse(kDefaultInvalidTokenHandleResponse); @@ -3451,7 +3451,7 @@ constexpr wchar_t kOldPassword[] = L"password"; ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser( kDefaultUsername, kOldPassword, L"Full Name", L"comment", - kDefaultGaiaId, std::wstring(), sid.Receive())); + kDefaultGaiaId, L"[email protected]", sid.Receive())); // Change token response to an invalid one. SetDefaultTokenHandleResponse(kDefaultInvalidTokenHandleResponse); @@ -3587,7 +3587,7 @@ base::win::ScopedBstr sid; ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser( kDefaultUsername, L"password", L"Full Name", L"comment", - kDefaultGaiaId, std::wstring(), domain, sid.Receive())); + kDefaultGaiaId, L"[email protected]", domain, sid.Receive())); std::string dm_token = base::Uuid::GenerateRandomV4().AsLowercaseString(); FakeTokenGenerator fake_token_generator; @@ -3835,7 +3835,7 @@ base::win::ScopedBstr sid; ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser( kDefaultUsername, L"password", L"Full Name", L"comment", - kDefaultGaiaId, std::wstring(), sid.Receive())); + kDefaultGaiaId, L"[email protected]", sid.Receive())); // Change token response to an valid one. SetDefaultTokenHandleResponse(kDefaultValidTokenHandleResponse); @@ -3917,7 +3917,7 @@ std::wstring username(L"foo"); ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser( username, L"password", L"name", L"comment", - kDefaultGaiaId, std::wstring(), sid.Receive())); + kDefaultGaiaId, L"[email protected]", sid.Receive())); ASSERT_EQ(2ul, fake_os_user_manager()->GetUserCount()); // Create provider. @@ -3973,7 +3973,7 @@ ... (file diff truncated)
Loading diff…
Regression Test / PoC
shipped with the fix
diff --git a/chrome/credential_provider/gaiacp/experiments_manager_unittest.cc b/chrome/credential_provider/gaiacp/experiments_manager_unittest.cc
index 8b439189..889d3adf 100644
--- a/chrome/credential_provider/gaiacp/experiments_manager_unittest.cc
+++ b/chrome/credential_provider/gaiacp/experiments_manager_unittest.cc
@@ -23,6 +23,7 @@
class ExperimentsManagerTest : public GlsRunnerTestBase {
protected:
void SetUp() override;
+ void TearDown() override;
};
void ExperimentsManagerTest::SetUp() {
@@ -30,10 +31,12 @@
ASSERT_EQ(S_OK, SetGlobalFlagForTesting(L"experiments_enabled", 1));
FakesForTesting fakes;
+ fakes.os_user_manager_for_testing = fake_os_user_manager();
fakes.fake_win_http_url_fetcher_creator =
fake_http_url_fetcher_factory()->GetCreatorCallback();
WinHttpUrlFetcher::SetCreatorForTesting(
fakes.fake_win_http_url_fetcher_creator);
+ UserPoliciesManager::Get()->SetFakesForTesting(&fakes);
// Set token result a valid access token.
fake_http_url_fetcher_factory()->SetFakeResponse(
@@ -41,6 +44,10 @@
FakeWinHttpUrlFetcher::Headers(), "{\"access_token\": \"dummy_token\"}");
}
+void ExperimentsManagerTest::TearDown() {
+ GlsRunnerTestBase::TearDown();
+}
+
TEST_F(ExperimentsManagerTest, DefaultValues) {
EXPECT_EQ("false", ExperimentsManager::Get()->GetExperimentForUser(
"test_sid", Experiment::TEST_CLIENT_FLAG));
@@ -70,9 +77,10 @@
// Create a fake user that has the same gaia id as the test gaia id.
base::win::ScopedBstr sid;
- ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser(
- L"foo", L"password", L"Full Name", L"comment",
- kDefaultGaiaId, L"[email protected]", sid.Receive()));
+ ASSERT_EQ(S_OK,
+ fake_os_user_manager()->CreateTestOSUser(
+ L"foo", L"password", L"Full Name", L"comment", kDefaultGaiaId,
+ base::UTF8ToWide(kDefaultEmail), sid.Receive()));
std::wstring device_resource_id = L"foo_resource_id";
ASSERT_EQ(S_OK, SetUserProperty(sid.Get(), L"device_resource_id",
@@ -149,9 +157,10 @@
// Create a fake user that has the same gaia id as the test gaia id.
base::win::ScopedBstr sid;
- ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser(
- L"foo", L"password", L"Full Name", L"comment",
- kDefaultGaiaId, L"[email protected]", sid.Receive()));
+ ASSERT_EQ(S_OK,
+ fake_os_user_manager()->CreateTestOSUser(
+ L"foo", L"password", L"Full Name", L"comment", kDefaultGaiaId,
+ base::UTF8ToWide(kDefaultEmail), sid.Receive()));
ASSERT_EQ(S_OK, GenerateGCPWDmToken(sid.Get()));
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_base_unittest.cc b/chrome/credential_provider/gaiacp/gaia_credential_base_unittest.cc
index b418d264c..ced1c9c 100644
--- a/chrome/credential_provider/gaiacp/gaia_credential_base_unittest.cc
+++ b/chrome/credential_provider/gaiacp/gaia_credential_base_unittest.cc
@@ -469,7 +469,7 @@
std::wstring username(L"foo");
ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser(
username, L"password", L"name", L"comment",
- kDefaultGaiaId, std::wstring(), first_sid.Receive()));
+ kDefaultGaiaId, L"[email protected]", first_sid.Receive()));
ASSERT_EQ(2ul, fake_os_user_manager()->GetUserCount());
// Create provider and start logon.
Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
@@ -555,7 +555,7 @@
base::win::ScopedBstr windows_password(L"password2");
ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser(
L"foo", windows_password.Get(), L"Full Name", L"comment",
- kDefaultGaiaId, std::wstring(), sid.Receive()));
+ kDefaultGaiaId, L"[email protected]", sid.Receive()));
// Create provider and start logon.
Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
@@ -610,7 +610,7 @@
base::win::ScopedBstr windows_password(L"password2");
ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser(
L"foo", windows_password.Get(), L"Full Name", L"comment",
- kDefaultGaiaId, std::wstring(), sid.Receive()));
+ kDefaultGaiaId, L"[email protected]", sid.Receive()));
// Create provider and start logon.
Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
@@ -679,7 +679,7 @@
base::win::ScopedBstr windows_password(L"password2");
ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser(
L"foo", windows_password.Get(), L"Full Name", L"comment",
- kDefaultGaiaId, std::wstring(), sid.Receive()));
+ kDefaultGaiaId, L"[email protected]", sid.Receive()));
// Create provider and start logon.
Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
@@ -724,7 +724,7 @@
base::win::ScopedBstr windows_password(L"password2");
ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser(
L"foo", windows_password.Get(), L"Full Name", L"comment",
- kDefaultGaiaId, std::wstring(), sid.Receive()));
+ kDefaultGaiaId, L"[email protected]", sid.Receive()));
// Create provider and start logon.
Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred;
@@ -1112,7 +1112,7 @@
ASSERT_EQ(S_OK,
fake_os_user_manager()->CreateTestOSUser(
L"foo_registered", L"password", L"name", L"comment",
- GaiaId("gaia-id-registered"), std::wstring(), sid.Receive()));
+ GaiaId("gaia-id-registered"), L"[email protected]", sid.Receive()));
// Populate the associated users list. The created user's token handle
// should be valid so that no reauth credential is created.
@@ -1146,7 +1146,7 @@
std::wstring username(L"foo");
ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser(
username, L"password", L"name", L"comment",
- kDefaultGaiaId, std::wstring(), sid.Receive()));
+ kDefaultGaiaId, L"[email protected]", sid.Receive()));
ASSERT_EQ(2ul, fake_os_user_manager()->GetUserCount());
// Create provider and start logon.
@@ -1200,7 +1200,7 @@
std::wstring username(L"foo");
ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser(
username, L"password", L"name", L"comment",
- kDefaultGaiaId, std::wstring(), sid.Receive()));
+ kDefaultGaiaId, L"[email protected]", sid.Receive()));
ASSERT_EQ(2ul, fake_os_user_manager()->GetUserCount());
// Create provider and start logon.
@@ -1225,7 +1225,7 @@
std::wstring username(L"foo");
ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser(
username, L"password", L"name", L"comment",
- kDefaultGaiaId, std::wstring(), first_sid.Receive()));
+ kDefaultGaiaId, L"[email protected]", first_sid.Receive()));
ASSERT_EQ(2ul, fake_os_user_manager()->GetUserCount());
UserPolicies user_policies;
@@ -1313,7 +1313,7 @@
std::wstring username(L"foo");
ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser(
username, L"password", L"name", L"comment",
- kDefaultGaiaId, std::wstring(), first_sid.Receive()));
+ kDefaultGaiaId, L"[email protected]", first_sid.Receive()));
ASSERT_EQ(2ul, fake_os_user_manager()->GetUserCount());
std::vector<std::wstring> reauth_sids;
@@ -3066,7 +3066,7 @@
constexpr wchar_t kOldPassword[] = L"password";
ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser(
kDefaultUsername, kOldPassword, L"Full Name", L"comment",
- kDefaultGaiaId, std::wstring(), sid.Receive()));
+ kDefaultGaiaId, L"[email protected]", sid.Receive()));
// Change token response to an invalid one.
SetDefaultTokenHandleResponse(kDefaultInvalidTokenHandleResponse);
@@ -3298,7 +3298,7 @@
constexpr wchar_t kOldPassword[] = L"password";
ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser(
kDefaultUsername, kOldPassword, L"Full Name", L"comment",
- kDefaultGaiaId, std::wstring(), sid.Receive()));
+ kDefaultGaiaId, L"[email protected]", sid.Receive()));
// Change token response to an invalid one.
SetDefaultTokenHandleResponse(kDefaultInvalidTokenHandleResponse);
@@ -3451,7 +3451,7 @@
constexpr wchar_t kOldPassword[] = L"password";
ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser(
kDefaultUsername, kOldPassword, L"Full Name", L"comment",
- kDefaultGaiaId, std::wstring(), sid.Receive()));
+ kDefaultGaiaId, L"[email protected]", sid.Receive()));
// Change token response to an invalid one.
SetDefaultTokenHandleResponse(kDefaultInvalidTokenHandleResponse);
@@ -3587,7 +3587,7 @@
base::win::ScopedBstr sid;
ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser(
kDefaultUsername, L"password", L"Full Name", L"comment",
- kDefaultGaiaId, std::wstring(), domain, sid.Receive()));
+ kDefaultGaiaId, L"[email protected]", domain, sid.Receive()));
std::string dm_token = base::Uuid::GenerateRandomV4().AsLowercaseString();
FakeTokenGenerator fake_token_generator;
@@ -3835,7 +3835,7 @@
base::win::ScopedBstr sid;
ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser(
kDefaultUsername, L"password", L"Full Name", L"comment",
- kDefaultGaiaId, std::wstring(), sid.Receive()));
+ kDefaultGaiaId, L"[email protected]", sid.Receive()));
// Change token response to an valid one.
SetDefaultTokenHandleResponse(kDefaultValidTokenHandleResponse);
@@ -3917,7 +3917,7 @@
std::wstring username(L"foo");
ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser(
username, L"password", L"name", L"comment",
- kDefaultGaiaId, std::wstring(), sid.Receive()));
+ kDefaultGaiaId, L"[email protected]", sid.Receive()));
ASSERT_EQ(2ul, fake_os_user_manager()->GetUserCount());
// Create provider.
@@ -3973,7 +3973,7 @@
base::win::ScopedBstr sid_str;
ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser(
kDefaultUsername, L"password", L"Full Name", L"comment",
- kDefaultGaiaId, std::wstring(), sid_str.Receive()));
+ kDefaultGaiaId, L"[email protected]", sid_str.Receive()));
std::wstring sid = sid_str.Get();
if (cloud_policies_enabled) {
@@ -4117,7 +4117,7 @@
base::win::ScopedBstr sid;
ASSERT_EQ(S_OK, fake_os_user_manager()->CreateTestOSUser(
kDefaultUsername, L"password", L"Full Name", L"comment",
- kDefaultGaiaId, std::wstring(), sid.Receive()));
+ kDefaultGaiaId, L"[email protected]", sid.Receive()));
// Change token response to an valid one.
SetDefaultTokenHandleResponse(kDefaultValidTokenHandleResponse);
diff --git a/chrome/credential_provider/gaiacp/gcp_utils_unittest.cc b/chrome/credential_provider/gaiacp/gcp_utils_unittest.cc
index 64269494..db6aabf 100644
--- a/chrome/credential_provider/gaiacp/gcp_utils_unittest.cc
+++ b/chrome/credential_provider/gaiacp/gcp_utils_unittest.cc
@@ -26,6 +26,7 @@
#include "base/test/test_reg_util_win.h"
#include "base/values.h"
#include "base/win/access_token.h"
+#include "base/win/scoped_bstr.h"
#include "base/win/scoped_handle.h"
#include "base/win/security_descriptor.h"
#include "base/win/security_util.h"
@@ -35,6 +36,7 @@
#include "chrome/credential_provider/gaiacp/mdm_utils.h"
#include "chrome/credential_provider/gaiacp/reg_utils.h"
#include "chrome/credential_provider/test/gcp_fakes.h"
+#include "google_apis/gaia/gaia_id.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -716,4 +718,126 @@
}
}
+class GcpRegUtilsTest : public ::testing::Test {
+ protected:
+ void SetUp() override {
+ InitializeRegistryOverrideForTesting(®istry_override_);
+ }
+
+ registry_util::RegistryOverrideManager registry_override_;
+ FakeOSUserManager fake_os_user_manager_;
+};
+
+TEST_F(GcpRegUtilsTest, GetSidFromIdAndEmail) {
+ const std::wstring gaia_id = L"gaia_id";
+ const std::wstring email = L"[email protected]";
+ const std::wstring username = L"username";
+ const std::wstring password = L"password";
+ base::win::ScopedBstr sid;
+
+ ASSERT_EQ(S_OK, fake_os_user_manager_.CreateTestOSUser(
+ username, password, L"Full Name", L"Comment",
+ GaiaId(base::WideToUTF8(gaia_id)), email, sid.Receive()));
+
+ wchar_t found_sid[256];
+ ASSERT_EQ(S_OK, GetSidFromIdAndEmail(gaia_id, email, found_sid,
+ std::size(found_sid)));
+ EXPECT_EQ(std::wstring(sid.Get()), std::wstring(found_sid));
+
+ // Different email should fail.
+ ASSERT_EQ(HRESULT_FROM_WIN32(ERROR_NONE_MAPPED),
+ GetSidFromIdAndEmail(gaia_id, L"[email protected]", found_sid,
+ std::size(found_sid)));
+
+ // Different id should fail.
+ ASSERT_EQ(HRESULT_FROM_WIN32(ERROR_NONE_MAPPED),
+ GetSidFromIdAndEmail(L"other_id", email, found_sid,
+ std::size(found_sid)));
+}
+
+TEST_F(GcpRegUtilsTest, GetSidFromIdAndEmail_Duplicate) {
+ const std::wstring gaia_id = L"gaia_id";
+ const std::wstring email = L"[email protected]";
+ base::win::ScopedBstr sid1;
+ base::win::ScopedBstr sid2;
+
+ ASSERT_EQ(S_OK,
+ fake_os_user_manager_.CreateTestOSUser(
+ L"user1", L"pass1", L"Full Name 1", L"Comment 1",
+ GaiaId(base::WideToUTF8(gaia_id)), email, sid1.Receive()));
... (truncated)
Loading diff…
Original Bug Report
The reporter's bug is still restricted on the tracker. Chrome de-restricts security bugs ~30–90 days after the fix ships; a later run will backfill it here.
References
On This Page