Commit 9800d81b authored by Rakesh Soma's avatar Rakesh Soma Committed by Commit Bot

Donot refresh login UI if auth enforcement was already performed on

that particular user sid.

Note: Tested the changes locally on a VM instance. It works great !

Bug: 1045080
Change-Id: I3e05cbd8d6448a601109787f3de2a9a36236709e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2135188
Commit-Queue: Rakesh Soma <rakeshsoma@google.com>
Reviewed-by: default avatarYusuf Sengul <yusufsn@google.com>
Cr-Commit-Position: refs/heads/master@{#756361}
parent 867fcd45
...@@ -603,25 +603,6 @@ bool AssociatedUserValidator::IsTokenHandleValidForUser( ...@@ -603,25 +603,6 @@ bool AssociatedUserValidator::IsTokenHandleValidForUser(
return validity_it->second->is_valid; return validity_it->second->is_valid;
} }
bool AssociatedUserValidator::IsAuthEnforcedOnAssociatedUsers() {
std::map<base::string16, UserTokenHandleInfo> sids_to_handle_info;
HRESULT hr = GetUserTokenHandles(&sids_to_handle_info);
if (FAILED(hr)) {
LOGFN(ERROR) << "GetUserTokenHandles hr=" << putHR(hr);
return hr;
}
for (const auto& sid_to_association : sids_to_handle_info) {
const base::string16& sid = sid_to_association.first;
// Return true even if one of the associated user sid
// has an auth enforced.
if (IsAuthEnforcedForUser(sid)) {
return true;
}
}
return false;
}
void AssociatedUserValidator::BlockDenyAccessUpdate() { void AssociatedUserValidator::BlockDenyAccessUpdate() {
base::AutoLock locker(validator_lock_); base::AutoLock locker(validator_lock_);
++block_deny_access_update_; ++block_deny_access_update_;
......
...@@ -144,7 +144,6 @@ TEST_F(AssociatedUserValidatorTest, CleanupStaleUsers) { ...@@ -144,7 +144,6 @@ TEST_F(AssociatedUserValidatorTest, CleanupStaleUsers) {
EXPECT_FALSE(validator.IsAuthEnforcedForUser(OLE2CW(sid_bad))); EXPECT_FALSE(validator.IsAuthEnforcedForUser(OLE2CW(sid_bad)));
EXPECT_FALSE(validator.IsAuthEnforcedForUser(OLE2CW(sid_no_gaia_id))); EXPECT_FALSE(validator.IsAuthEnforcedForUser(OLE2CW(sid_no_gaia_id)));
EXPECT_TRUE(validator.IsAuthEnforcedForUser(OLE2CW(sid_no_token_handle))); EXPECT_TRUE(validator.IsAuthEnforcedForUser(OLE2CW(sid_no_token_handle)));
EXPECT_TRUE(validator.IsAuthEnforcedOnAssociatedUsers());
// Expect deleted user and user with no gaia id to be deleted. // Expect deleted user and user with no gaia id to be deleted.
EXPECT_NE(ERROR_SUCCESS, key.OpenKey(OLE2CW(sid_bad), KEY_READ)); EXPECT_NE(ERROR_SUCCESS, key.OpenKey(OLE2CW(sid_bad), KEY_READ));
...@@ -165,7 +164,6 @@ TEST_F(AssociatedUserValidatorTest, NoTokenHandles) { ...@@ -165,7 +164,6 @@ TEST_F(AssociatedUserValidatorTest, NoTokenHandles) {
// If there is no associated user then all token handles are valid. // If there is no associated user then all token handles are valid.
EXPECT_FALSE( EXPECT_FALSE(
validator.IsAuthEnforcedForUser(GetNewSidString(fake_os_user_manager()))); validator.IsAuthEnforcedForUser(GetNewSidString(fake_os_user_manager())));
EXPECT_FALSE(validator.IsAuthEnforcedOnAssociatedUsers());
EXPECT_EQ(0u, fake_http_url_fetcher_factory()->requests_created()); EXPECT_EQ(0u, fake_http_url_fetcher_factory()->requests_created());
} }
...@@ -187,7 +185,6 @@ TEST_F(AssociatedUserValidatorTest, ValidTokenHandle) { ...@@ -187,7 +185,6 @@ TEST_F(AssociatedUserValidatorTest, ValidTokenHandle) {
validator.StartRefreshingTokenHandleValidity(); validator.StartRefreshingTokenHandleValidity();
EXPECT_FALSE(validator.IsAuthEnforcedForUser(OLE2W(sid))); EXPECT_FALSE(validator.IsAuthEnforcedForUser(OLE2W(sid)));
EXPECT_FALSE(validator.IsAuthEnforcedOnAssociatedUsers());
EXPECT_EQ(1u, fake_http_url_fetcher_factory()->requests_created()); EXPECT_EQ(1u, fake_http_url_fetcher_factory()->requests_created());
} }
...@@ -207,7 +204,6 @@ TEST_F(AssociatedUserValidatorTest, InvalidTokenHandle) { ...@@ -207,7 +204,6 @@ TEST_F(AssociatedUserValidatorTest, InvalidTokenHandle) {
validator.StartRefreshingTokenHandleValidity(); validator.StartRefreshingTokenHandleValidity();
EXPECT_TRUE(validator.IsAuthEnforcedForUser(OLE2W(sid))); EXPECT_TRUE(validator.IsAuthEnforcedForUser(OLE2W(sid)));
EXPECT_TRUE(validator.IsAuthEnforcedOnAssociatedUsers());
EXPECT_EQ(1u, fake_http_url_fetcher_factory()->requests_created()); EXPECT_EQ(1u, fake_http_url_fetcher_factory()->requests_created());
} }
...@@ -223,7 +219,6 @@ TEST_F(AssociatedUserValidatorTest, InvalidTokenHandleNoInternet) { ...@@ -223,7 +219,6 @@ TEST_F(AssociatedUserValidatorTest, InvalidTokenHandleNoInternet) {
validator.StartRefreshingTokenHandleValidity(); validator.StartRefreshingTokenHandleValidity();
EXPECT_FALSE(validator.IsAuthEnforcedForUser(OLE2W(sid))); EXPECT_FALSE(validator.IsAuthEnforcedForUser(OLE2W(sid)));
EXPECT_FALSE(validator.IsAuthEnforcedOnAssociatedUsers());
EXPECT_EQ(0u, fake_http_url_fetcher_factory()->requests_created()); EXPECT_EQ(0u, fake_http_url_fetcher_factory()->requests_created());
} }
...@@ -244,7 +239,6 @@ TEST_F(AssociatedUserValidatorTest, InvalidTokenHandleTimeout) { ...@@ -244,7 +239,6 @@ TEST_F(AssociatedUserValidatorTest, InvalidTokenHandleTimeout) {
validator.StartRefreshingTokenHandleValidity(); validator.StartRefreshingTokenHandleValidity();
EXPECT_FALSE(validator.IsAuthEnforcedForUser(OLE2W(sid))); EXPECT_FALSE(validator.IsAuthEnforcedForUser(OLE2W(sid)));
EXPECT_FALSE(validator.IsAuthEnforcedOnAssociatedUsers());
EXPECT_EQ(1u, fake_http_url_fetcher_factory()->requests_created()); EXPECT_EQ(1u, fake_http_url_fetcher_factory()->requests_created());
http_fetcher_event.Signal(); http_fetcher_event.Signal();
...@@ -269,7 +263,6 @@ TEST_F(AssociatedUserValidatorTest, TokenHandleValidityStillFresh) { ...@@ -269,7 +263,6 @@ TEST_F(AssociatedUserValidatorTest, TokenHandleValidityStillFresh) {
EXPECT_FALSE(validator.IsAuthEnforcedForUser(OLE2W(sid))); EXPECT_FALSE(validator.IsAuthEnforcedForUser(OLE2W(sid)));
EXPECT_FALSE(validator.IsAuthEnforcedForUser(OLE2W(sid))); EXPECT_FALSE(validator.IsAuthEnforcedForUser(OLE2W(sid)));
EXPECT_FALSE(validator.IsAuthEnforcedOnAssociatedUsers());
EXPECT_EQ(1u, fake_http_url_fetcher_factory()->requests_created()); EXPECT_EQ(1u, fake_http_url_fetcher_factory()->requests_created());
} }
...@@ -343,7 +336,6 @@ TEST_F(AssociatedUserValidatorTest, ...@@ -343,7 +336,6 @@ TEST_F(AssociatedUserValidatorTest,
EXPECT_TRUE(validator.IsAuthEnforcedForUser(OLE2W(sid))); EXPECT_TRUE(validator.IsAuthEnforcedForUser(OLE2W(sid)));
EXPECT_TRUE(validator.DenySigninForUsersWithInvalidTokenHandles(CPUS_LOGON, EXPECT_TRUE(validator.DenySigninForUsersWithInvalidTokenHandles(CPUS_LOGON,
reauth_sids)); reauth_sids));
EXPECT_TRUE(validator.IsAuthEnforcedOnAssociatedUsers());
} }
// Donot deny user access even when the gaia handle is invalidated for a // Donot deny user access even when the gaia handle is invalidated for a
...@@ -372,7 +364,6 @@ TEST_F(AssociatedUserValidatorTest, ...@@ -372,7 +364,6 @@ TEST_F(AssociatedUserValidatorTest,
EXPECT_TRUE(validator.IsAuthEnforcedForUser(OLE2W(sid))); EXPECT_TRUE(validator.IsAuthEnforcedForUser(OLE2W(sid)));
EXPECT_FALSE(validator.DenySigninForUsersWithInvalidTokenHandles( EXPECT_FALSE(validator.DenySigninForUsersWithInvalidTokenHandles(
CPUS_LOGON, reauth_sids)); CPUS_LOGON, reauth_sids));
EXPECT_TRUE(validator.IsAuthEnforcedOnAssociatedUsers());
} }
// Clear the UserProperty from registry for those sids which doesn't // Clear the UserProperty from registry for those sids which doesn't
...@@ -564,7 +555,6 @@ TEST_P(AssociatedUserValidatorUserAccessBlockingTest, BlockUserAccessAsNeeded) { ...@@ -564,7 +555,6 @@ TEST_P(AssociatedUserValidatorUserAccessBlockingTest, BlockUserAccessAsNeeded) {
EXPECT_EQ(should_user_be_blocked, EXPECT_EQ(should_user_be_blocked,
validator.IsUserAccessBlockedForTesting(OLE2W(sid))); validator.IsUserAccessBlockedForTesting(OLE2W(sid)));
EXPECT_EQ(is_get_auth_enforced, validator.IsAuthEnforcedForUser(OLE2W(sid))); EXPECT_EQ(is_get_auth_enforced, validator.IsAuthEnforcedForUser(OLE2W(sid)));
EXPECT_EQ(is_get_auth_enforced, validator.IsAuthEnforcedOnAssociatedUsers());
// Unlock the user. // Unlock the user.
validator.AllowSigninForUsersWithInvalidTokenHandles(); validator.AllowSigninForUsersWithInvalidTokenHandles();
...@@ -616,7 +606,6 @@ TEST_F(AssociatedUserValidatorTest, ValidTokenHandle_Refresh) { ...@@ -616,7 +606,6 @@ TEST_F(AssociatedUserValidatorTest, ValidTokenHandle_Refresh) {
validator.StartRefreshingTokenHandleValidity(); validator.StartRefreshingTokenHandleValidity();
EXPECT_FALSE(validator.IsAuthEnforcedForUser(OLE2W(sid))); EXPECT_FALSE(validator.IsAuthEnforcedForUser(OLE2W(sid)));
EXPECT_FALSE(validator.IsAuthEnforcedOnAssociatedUsers());
// Make the next token fetch result invalid. // Make the next token fetch result invalid.
fake_http_url_fetcher_factory()->SetFakeResponse( fake_http_url_fetcher_factory()->SetFakeResponse(
...@@ -626,7 +615,6 @@ TEST_F(AssociatedUserValidatorTest, ValidTokenHandle_Refresh) { ...@@ -626,7 +615,6 @@ TEST_F(AssociatedUserValidatorTest, ValidTokenHandle_Refresh) {
// If the lifetime of the validity has not expired, even if the token is // If the lifetime of the validity has not expired, even if the token is
// invalid, no new fetch will be performed yet. // invalid, no new fetch will be performed yet.
EXPECT_FALSE(validator.IsAuthEnforcedForUser(OLE2W(sid))); EXPECT_FALSE(validator.IsAuthEnforcedForUser(OLE2W(sid)));
EXPECT_FALSE(validator.IsAuthEnforcedOnAssociatedUsers());
EXPECT_EQ(1u, fake_http_url_fetcher_factory()->requests_created()); EXPECT_EQ(1u, fake_http_url_fetcher_factory()->requests_created());
// Advance the time so that a new fetch will be done and retrieve the // Advance the time so that a new fetch will be done and retrieve the
...@@ -635,7 +623,6 @@ TEST_F(AssociatedUserValidatorTest, ValidTokenHandle_Refresh) { ...@@ -635,7 +623,6 @@ TEST_F(AssociatedUserValidatorTest, ValidTokenHandle_Refresh) {
AssociatedUserValidator::kTokenHandleValidityLifetime + AssociatedUserValidator::kTokenHandleValidityLifetime +
base::TimeDelta::FromMilliseconds(1); base::TimeDelta::FromMilliseconds(1);
EXPECT_TRUE(validator.IsAuthEnforcedForUser(OLE2W(sid))); EXPECT_TRUE(validator.IsAuthEnforcedForUser(OLE2W(sid)));
EXPECT_TRUE(validator.IsAuthEnforcedOnAssociatedUsers());
EXPECT_EQ(2u, fake_http_url_fetcher_factory()->requests_created()); EXPECT_EQ(2u, fake_http_url_fetcher_factory()->requests_created());
} }
...@@ -664,7 +651,6 @@ TEST_F(AssociatedUserValidatorTest, InvalidTokenHandle_MissingPasswordLsaData) { ...@@ -664,7 +651,6 @@ TEST_F(AssociatedUserValidatorTest, InvalidTokenHandle_MissingPasswordLsaData) {
validator.StartRefreshingTokenHandleValidity(); validator.StartRefreshingTokenHandleValidity();
EXPECT_TRUE(validator.IsAuthEnforcedForUser(OLE2W(sid))); EXPECT_TRUE(validator.IsAuthEnforcedForUser(OLE2W(sid)));
EXPECT_TRUE(validator.IsAuthEnforcedOnAssociatedUsers());
} }
TEST_F(AssociatedUserValidatorTest, ValidTokenHandle_PresentPasswordLsaData) { TEST_F(AssociatedUserValidatorTest, ValidTokenHandle_PresentPasswordLsaData) {
...@@ -694,7 +680,6 @@ TEST_F(AssociatedUserValidatorTest, ValidTokenHandle_PresentPasswordLsaData) { ...@@ -694,7 +680,6 @@ TEST_F(AssociatedUserValidatorTest, ValidTokenHandle_PresentPasswordLsaData) {
validator.StartRefreshingTokenHandleValidity(); validator.StartRefreshingTokenHandleValidity();
EXPECT_FALSE(validator.IsAuthEnforcedForUser(OLE2W(sid))); EXPECT_FALSE(validator.IsAuthEnforcedForUser(OLE2W(sid)));
EXPECT_FALSE(validator.IsAuthEnforcedOnAssociatedUsers());
} }
} // namespace testing } // namespace testing
......
...@@ -120,25 +120,29 @@ HRESULT CreateCredentialObject( ...@@ -120,25 +120,29 @@ HRESULT CreateCredentialObject(
class BackgroundTokenHandleUpdater { class BackgroundTokenHandleUpdater {
public: public:
explicit BackgroundTokenHandleUpdater( explicit BackgroundTokenHandleUpdater(
ICredentialUpdateEventsHandler* event_handler); ICredentialUpdateEventsHandler* event_handler,
const std::vector<base::string16>* reauth_sids);
~BackgroundTokenHandleUpdater(); ~BackgroundTokenHandleUpdater();
private: private:
static unsigned __stdcall PeriodicTokenHandleUpdate(void* param); static unsigned __stdcall PeriodicTokenHandleUpdate(void* param);
bool IsAuthEnforcedOnAssociatedUsers();
// Raw pointer to the interface on CGaiaCredentialProvider that is used // Raw pointer to the interface on CGaiaCredentialProvider that is used
// to notify that token handle validity has changed. Any instance of this // to notify that token handle validity has changed. Any instance of this
// class should be owned by the CGaiaCredentialProvider to ensure that // class should be owned by the CGaiaCredentialProvider to ensure that
// this pointer outlives the updater. // this pointer outlives the updater.
ICredentialUpdateEventsHandler* event_handler_; ICredentialUpdateEventsHandler* event_handler_;
const std::vector<base::string16>* reauth_sids_;
base::win::ScopedHandle token_update_thread_; base::win::ScopedHandle token_update_thread_;
base::WaitableEvent token_update_quit_event_; base::WaitableEvent token_update_quit_event_;
}; };
BackgroundTokenHandleUpdater::BackgroundTokenHandleUpdater( BackgroundTokenHandleUpdater::BackgroundTokenHandleUpdater(
ICredentialUpdateEventsHandler* event_handler) ICredentialUpdateEventsHandler* event_handler,
: event_handler_(event_handler) { const std::vector<base::string16>* reauth_sids)
: event_handler_(event_handler), reauth_sids_(reauth_sids) {
unsigned wait_thread_id; unsigned wait_thread_id;
uintptr_t wait_thread = uintptr_t wait_thread =
_beginthreadex(nullptr, 0, PeriodicTokenHandleUpdate, _beginthreadex(nullptr, 0, PeriodicTokenHandleUpdate,
...@@ -158,6 +162,31 @@ BackgroundTokenHandleUpdater::~BackgroundTokenHandleUpdater() { ...@@ -158,6 +162,31 @@ BackgroundTokenHandleUpdater::~BackgroundTokenHandleUpdater() {
} }
} }
bool BackgroundTokenHandleUpdater::IsAuthEnforcedOnAssociatedUsers() {
std::map<base::string16, UserTokenHandleInfo> sids_to_handle_info;
HRESULT hr = GetUserTokenHandles(&sids_to_handle_info);
if (FAILED(hr)) {
LOGFN(ERROR) << "GetUserTokenHandles hr=" << putHR(hr);
return hr;
}
for (const auto& sid_to_association : sids_to_handle_info) {
const base::string16& sid = sid_to_association.first;
// Checks if the login UI was already refreshed due to
// auth enforcements on this sid.
if (reauth_sids_ != nullptr &&
(std::find(reauth_sids_->begin(), reauth_sids_->end(), sid) !=
reauth_sids_->end()))
continue;
// Return true if the associated user sid has auth enforced.
if (AssociatedUserValidator::Get()->IsAuthEnforcedForUser(sid)) {
return true;
}
}
return false;
}
unsigned __stdcall BackgroundTokenHandleUpdater::PeriodicTokenHandleUpdate( unsigned __stdcall BackgroundTokenHandleUpdater::PeriodicTokenHandleUpdate(
void* param) { void* param) {
BackgroundTokenHandleUpdater* updater = BackgroundTokenHandleUpdater* updater =
...@@ -173,8 +202,7 @@ unsigned __stdcall BackgroundTokenHandleUpdater::PeriodicTokenHandleUpdate( ...@@ -173,8 +202,7 @@ unsigned __stdcall BackgroundTokenHandleUpdater::PeriodicTokenHandleUpdate(
if (hr != WAIT_TIMEOUT) if (hr != WAIT_TIMEOUT)
break; break;
bool user_access_changed = bool user_access_changed = updater->IsAuthEnforcedOnAssociatedUsers();
AssociatedUserValidator::Get()->IsAuthEnforcedOnAssociatedUsers();
if (user_access_changed) { if (user_access_changed) {
LOGFN(VERBOSE) << "A user token handle has been invalidated. Refreshing " LOGFN(VERBOSE) << "A user token handle has been invalidated. Refreshing "
"credentials"; "credentials";
...@@ -381,8 +409,8 @@ HRESULT CGaiaCredentialProvider::CreateReauthCredentials( ...@@ -381,8 +409,8 @@ HRESULT CGaiaCredentialProvider::CreateReauthCredentials(
} }
LOGFN(VERBOSE) << "count=" << count; LOGFN(VERBOSE) << "count=" << count;
reauth_cred_sids_.clear();
std::vector<base::string16> reauth_cred_sids;
for (DWORD i = 0; i < count; ++i) { for (DWORD i = 0; i < count; ++i) {
Microsoft::WRL::ComPtr<ICredentialProviderUser> user; Microsoft::WRL::ComPtr<ICredentialProviderUser> user;
hr = users->GetAt(i, &user); hr = users->GetAt(i, &user);
...@@ -466,14 +494,14 @@ HRESULT CGaiaCredentialProvider::CreateReauthCredentials( ...@@ -466,14 +494,14 @@ HRESULT CGaiaCredentialProvider::CreateReauthCredentials(
// Add SID to the vector to keep track of all the users that have a reauth // Add SID to the vector to keep track of all the users that have a reauth
// credential created. // credential created.
reauth_cred_sids.push_back(sid); reauth_cred_sids_.push_back(sid);
LOGFN(VERBOSE) << "Reauth SID : " << sid; LOGFN(VERBOSE) << "Reauth SID : " << sid;
} }
// Deny sign in access for users that have a reauth credential added to them. // Deny sign in access for users that have a reauth credential added to them.
AssociatedUserValidator::Get()->DenySigninForUsersWithInvalidTokenHandles( AssociatedUserValidator::Get()->DenySigninForUsersWithInvalidTokenHandles(
cpus_, reauth_cred_sids); cpus_, reauth_cred_sids_);
return S_OK; return S_OK;
} }
...@@ -702,8 +730,8 @@ HRESULT CGaiaCredentialProvider::Advise(ICredentialProviderEvents* pcpe, ...@@ -702,8 +730,8 @@ HRESULT CGaiaCredentialProvider::Advise(ICredentialProviderEvents* pcpe,
advise_context_ = context; advise_context_ = context;
if (AssociatedUserValidator::Get()->IsUserAccessBlockingEnforced(cpus_)) { if (AssociatedUserValidator::Get()->IsUserAccessBlockingEnforced(cpus_)) {
token_handle_updater_ = token_handle_updater_ = std::make_unique<BackgroundTokenHandleUpdater>(
std::make_unique<BackgroundTokenHandleUpdater>(this); this, &reauth_cred_sids_);
} }
return S_OK; return S_OK;
......
...@@ -259,6 +259,7 @@ class ATL_NO_VTABLE CGaiaCredentialProvider ...@@ -259,6 +259,7 @@ class ATL_NO_VTABLE CGaiaCredentialProvider
CredentialCreatorFn anonymous_cred_creator_ = nullptr; CredentialCreatorFn anonymous_cred_creator_ = nullptr;
CredentialCreatorFn other_user_cred_creator_ = nullptr; CredentialCreatorFn other_user_cred_creator_ = nullptr;
CredentialCreatorFn reauth_cred_creator_ = nullptr; CredentialCreatorFn reauth_cred_creator_ = nullptr;
std::vector<base::string16> reauth_cred_sids_;
}; };
// OBJECT_ENTRY_AUTO() contains an extra semicolon. // OBJECT_ENTRY_AUTO() contains an extra semicolon.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment