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 <krkurapati@google.com>
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 <yusufsn@google.com>
Commit-Queue: Krishna Kurapati <krkurapati@google.com>
Reviewed-by: Tien Mai <tienmai@chromium.org>
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"user@company.com", 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"user@company.com", 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"foo@gmail.com", 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"foo@gmail.com", 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"foo@gmail.com", 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"foo@gmail.com", 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"foo@gmail.com", 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"foo@gmail.com", 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"foo@gmail.com", 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"foo@gmail.com", 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"foo@gmail.com", 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"foo@gmail.com", 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"foo@gmail.com", 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"foo@gmail.com", 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"foo@gmail.com", 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"foo@gmail.com", 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"foo@gmail.com", 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"foo@gmail.com", 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"user@company.com", 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"user@company.com", 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"foo@gmail.com", 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"foo@gmail.com", 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"foo@gmail.com", 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"foo@gmail.com", 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"foo@gmail.com", 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"foo@gmail.com", 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"foo@gmail.com", 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"foo@gmail.com", 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"foo@gmail.com", 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"foo@gmail.com", 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"foo@gmail.com", 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"foo@gmail.com", 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"foo@gmail.com", 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"foo@gmail.com", 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"foo@gmail.com", 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"foo@gmail.com", 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"foo@gmail.com", 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"foo@gmail.com", 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"user@gmail.com";
+ 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"other@gmail.com", 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"user@gmail.com";
+ 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