0

UserDataAuth: use common AuthSessionProperties field for all operations

Note: this change might break some developer flows as it requires
ChromeOS version 15629.0.0. Be sure to update ChromeOS version.

Bug: b:301078137
Change-Id: If47b6b3385a2d986336110ab4a8d6e9151b4283a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4887207
Commit-Queue: Denis Kuznetsov <antrim@chromium.org>
Reviewed-by: Maksim Ivanov <emaxx@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1205956}
This commit is contained in:
Denis Kuznetsov
2023-10-05 18:39:38 +00:00
committed by Chromium LUCI CQ
parent f8dcaed5ca
commit 0966778f0f
8 changed files with 100 additions and 23 deletions

@ -1008,6 +1008,10 @@ void FakeUserDataAuthClient::PrepareEphemeralVault(
return; return;
} }
auth_session.authenticated = true; auth_session.authenticated = true;
auth_session.requested_auth_session_intent =
user_data_auth::AUTH_INTENT_DECRYPT;
auth_session.lifetime =
base::Time::Now() + cryptohome::kAuthsessionInitialLifetime;
const auto [_, was_inserted] = const auto [_, was_inserted] =
users_.insert({auth_session.account, UserCryptohomeState()}); users_.insert({auth_session.account, UserCryptohomeState()});
@ -1020,6 +1024,11 @@ void FakeUserDataAuthClient::PrepareEphemeralVault(
} }
reply.set_sanitized_username(GetStubSanitizedUsername(account)); reply.set_sanitized_username(GetStubSanitizedUsername(account));
reply.mutable_auth_properties()->add_authorized_for(
auth_session.requested_auth_session_intent);
reply.mutable_auth_properties()->set_seconds_left(
cryptohome::kAuthsessionInitialLifetime.InSeconds());
} }
void FakeUserDataAuthClient::CreatePersistentUser( void FakeUserDataAuthClient::CreatePersistentUser(
@ -1061,10 +1070,15 @@ void FakeUserDataAuthClient::CreatePersistentUser(
} }
auth_session.authenticated = true; auth_session.authenticated = true;
// TODO(b/301078137): once proto includes lifetime information, add it auth_session.requested_auth_session_intent =
// to the reply. user_data_auth::AUTH_INTENT_DECRYPT;
auth_session.lifetime = auth_session.lifetime =
base::Time::Now() + cryptohome::kAuthsessionInitialLifetime; base::Time::Now() + cryptohome::kAuthsessionInitialLifetime;
reply.mutable_auth_properties()->add_authorized_for(
auth_session.requested_auth_session_intent);
reply.mutable_auth_properties()->set_seconds_left(
cryptohome::kAuthsessionInitialLifetime.InSeconds());
} }
void FakeUserDataAuthClient::PreparePersistentVault( void FakeUserDataAuthClient::PreparePersistentVault(
@ -1319,6 +1333,12 @@ void FakeUserDataAuthClient::AuthenticateAuthFactor(
session.requested_auth_session_intent); session.requested_auth_session_intent);
session.lifetime = session.lifetime =
base::Time::Now() + cryptohome::kAuthsessionInitialLifetime; base::Time::Now() + cryptohome::kAuthsessionInitialLifetime;
reply.mutable_auth_properties()->add_authorized_for(
session.requested_auth_session_intent);
reply.mutable_auth_properties()->set_seconds_left(
cryptohome::kAuthsessionInitialLifetime.InSeconds());
// TODO(b/301078137): Remove usage of these fields in favor of
// auth_properties.
reply.add_authorized_for(session.requested_auth_session_intent); reply.add_authorized_for(session.requested_auth_session_intent);
reply.set_seconds_left(cryptohome::kAuthsessionInitialLifetime.InSeconds()); reply.set_seconds_left(cryptohome::kAuthsessionInitialLifetime.InSeconds());
} }
@ -1424,7 +1444,10 @@ void FakeUserDataAuthClient::GetAuthSessionStatus(
return; return;
} }
reply.set_status(::user_data_auth::AUTH_SESSION_STATUS_AUTHENTICATED); reply.set_status(::user_data_auth::AUTH_SESSION_STATUS_AUTHENTICATED);
// Use 5 minutes timeout - as if auth session has just started. reply.mutable_auth_properties()->add_authorized_for(
auth_session->second.requested_auth_session_intent);
reply.mutable_auth_properties()->set_seconds_left(time_left.InSeconds());
// TODO(b/301078137): Remove usage of these field in favor of auth_properties.
reply.set_time_left(time_left.InSeconds()); reply.set_time_left(time_left.InSeconds());
} }

@ -87,6 +87,23 @@ base::WeakPtr<AuthPerformer> AuthPerformer::AsWeakPtr() {
return weak_factory_.GetWeakPtr(); return weak_factory_.GetWeakPtr();
} }
// static
void AuthPerformer::FillAuthenticationData(
const user_data_auth::AuthSessionProperties& session_properties,
UserContext& out_context) {
DCHECK(session_properties.authorized_for_size() > 0);
out_context.ClearAuthorizedIntents();
for (const auto& authorized_for : session_properties.authorized_for()) {
auto intent = DeserializeIntent(
static_cast<user_data_auth::AuthIntent>(authorized_for));
if (intent.has_value()) {
out_context.AddAuthorizedIntent(intent.value());
}
}
out_context.SetSessionLifetime(
base::Time::Now() + base::Seconds(session_properties.seconds_left()));
}
void AuthPerformer::StartAuthSession(std::unique_ptr<UserContext> context, void AuthPerformer::StartAuthSession(std::unique_ptr<UserContext> context,
bool ephemeral, bool ephemeral,
AuthSessionIntent intent, AuthSessionIntent intent,
@ -571,16 +588,9 @@ void AuthPerformer::OnAuthenticateAuthFactor(
return; return;
} }
CHECK(reply.has_value()); CHECK(reply.has_value());
DCHECK(reply->authorized_for_size() > 0); CHECK(reply->has_auth_properties());
for (auto& authorized_for : reply->authorized_for()) { FillAuthenticationData(reply->auth_properties(), *context);
auto intent = DeserializeIntent(
static_cast<user_data_auth::AuthIntent>(authorized_for));
if (intent.has_value()) {
context->AddAuthorizedIntent(intent.value());
}
}
context->SetSessionLifetime(base::Time::Now() +
base::Seconds(reply->seconds_left()));
LOGIN_LOG(EVENT) << "Authenticated successfully"; LOGIN_LOG(EVENT) << "Authenticated successfully";
std::move(callback).Run(std::move(context), absl::nullopt); std::move(callback).Run(std::move(context), absl::nullopt);
} }
@ -606,6 +616,9 @@ void AuthPerformer::OnGetAuthSessionStatus(
return; return;
} }
CHECK(reply.has_value()); CHECK(reply.has_value());
CHECK(reply->has_auth_properties());
// TODO(b/301078137): As lifetime is now stored in UserContext,
// there is no need to pass it separately.
base::TimeDelta lifetime; base::TimeDelta lifetime;
AuthSessionStatus status; AuthSessionStatus status;
switch (reply->status()) { switch (reply->status()) {
@ -621,11 +634,12 @@ void AuthPerformer::OnGetAuthSessionStatus(
case ::user_data_auth::AUTH_SESSION_STATUS_AUTHENTICATED: case ::user_data_auth::AUTH_SESSION_STATUS_AUTHENTICATED:
status.Put(AuthSessionLevel::kSessionIsValid); status.Put(AuthSessionLevel::kSessionIsValid);
status.Put(AuthSessionLevel::kCryptohomeStrong); status.Put(AuthSessionLevel::kCryptohomeStrong);
lifetime = base::Seconds(reply->time_left()); lifetime = base::Seconds(reply->auth_properties().seconds_left());
break; break;
default: default:
NOTREACHED(); NOTREACHED();
} }
FillAuthenticationData(reply->auth_properties(), *context);
std::move(callback).Run(status, lifetime, std::move(context), std::move(callback).Run(status, lifetime, std::move(context),
/*cryptohome_error=*/absl::nullopt); /*cryptohome_error=*/absl::nullopt);
} }

@ -59,6 +59,12 @@ class COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_LOGIN_AUTH) AuthPerformer {
base::WeakPtr<AuthPerformer> AsWeakPtr(); base::WeakPtr<AuthPerformer> AsWeakPtr();
// Utility method, copies data relevant for authentidated session
// into UserContext: authenticated intents, remaining lifetime.
static void FillAuthenticationData(
const user_data_auth::AuthSessionProperties& session_properties,
UserContext& out_context);
// Starts new AuthSession using identity passed in `context`, // Starts new AuthSession using identity passed in `context`,
// fills information about supported (and configured if user exists) keys. // fills information about supported (and configured if user exists) keys.
// `Context` should not have associated auth session. // `Context` should not have associated auth session.

@ -50,7 +50,8 @@ void ReplyAsSuccess(
UserDataAuthClient::AuthenticateAuthFactorCallback callback) { UserDataAuthClient::AuthenticateAuthFactorCallback callback) {
::user_data_auth::AuthenticateAuthFactorReply reply; ::user_data_auth::AuthenticateAuthFactorReply reply;
reply.set_error(::user_data_auth::CRYPTOHOME_ERROR_NOT_SET); reply.set_error(::user_data_auth::CRYPTOHOME_ERROR_NOT_SET);
reply.add_authorized_for(user_data_auth::AUTH_INTENT_DECRYPT); reply.mutable_auth_properties()->add_authorized_for(
user_data_auth::AUTH_INTENT_DECRYPT);
std::move(callback).Run(reply); std::move(callback).Run(reply);
} }

@ -177,7 +177,9 @@ StartAuthSessionReply BuildStartReply(const std::string& auth_session_id,
AuthenticateAuthFactorReply BuildAuthenticateFactorSuccessReply() { AuthenticateAuthFactorReply BuildAuthenticateFactorSuccessReply() {
AuthenticateAuthFactorReply reply; AuthenticateAuthFactorReply reply;
reply.add_authorized_for(user_data_auth::AUTH_INTENT_DECRYPT); reply.mutable_auth_properties()->add_authorized_for(
user_data_auth::AUTH_INTENT_DECRYPT);
reply.mutable_auth_properties()->set_seconds_left(5 * 60);
return reply; return reply;
} }
@ -189,6 +191,22 @@ AuthenticateAuthFactorReply BuildAuthenticateFactorFailureReply() {
return reply; return reply;
} }
CreatePersistentUserReply BuildCreatePersistentUserReply() {
CreatePersistentUserReply reply;
reply.mutable_auth_properties()->add_authorized_for(
user_data_auth::AUTH_INTENT_DECRYPT);
reply.mutable_auth_properties()->set_seconds_left(5 * 60);
return reply;
}
PrepareEphemeralVaultReply BuildPrepareEphemeralVaultReply() {
PrepareEphemeralVaultReply reply;
reply.mutable_auth_properties()->add_authorized_for(
user_data_auth::AUTH_INTENT_DECRYPT);
reply.mutable_auth_properties()->set_seconds_left(5 * 60);
return reply;
}
AuthFactor PasswordFactor(const std::string& label) { AuthFactor PasswordFactor(const std::string& label) {
AuthFactor factor; AuthFactor factor;
factor.set_type(AUTH_FACTOR_TYPE_PASSWORD); factor.set_type(AUTH_FACTOR_TYPE_PASSWORD);
@ -321,7 +339,7 @@ TEST_F(AuthSessionAuthenticatorTest, CompleteLoginRegularNew) {
/*user_exists=*/false, /*user_exists=*/false,
/*factors=*/{}))); /*factors=*/{})));
EXPECT_CALL(userdataauth(), CreatePersistentUser(WithFirstAuthSessionId(), _)) EXPECT_CALL(userdataauth(), CreatePersistentUser(WithFirstAuthSessionId(), _))
.WillOnce(ReplyWith(CreatePersistentUserReply())); .WillOnce(ReplyWith(BuildCreatePersistentUserReply()));
EXPECT_CALL(userdataauth(), EXPECT_CALL(userdataauth(),
PreparePersistentVault(WithFirstAuthSessionId(), _)) PreparePersistentVault(WithFirstAuthSessionId(), _))
.WillOnce(ReplyWith(PreparePersistentVaultReply())); .WillOnce(ReplyWith(PreparePersistentVaultReply()));
@ -466,7 +484,7 @@ TEST_F(AuthSessionAuthenticatorTest, CompleteLoginEphemeral) {
/*factors=*/{}))); /*factors=*/{})));
EXPECT_CALL(userdataauth(), EXPECT_CALL(userdataauth(),
PrepareEphemeralVault(WithFirstAuthSessionId(), _)) PrepareEphemeralVault(WithFirstAuthSessionId(), _))
.WillOnce(ReplyWith(PrepareEphemeralVaultReply())); .WillOnce(ReplyWith(BuildPrepareEphemeralVaultReply()));
EXPECT_CALL( EXPECT_CALL(
userdataauth(), userdataauth(),
AddAuthFactor(AllOf(WithFirstAuthSessionId(), AddAuthFactor(AllOf(WithFirstAuthSessionId(),
@ -516,7 +534,7 @@ TEST_F(AuthSessionAuthenticatorTest, CompleteLoginEphemeralStaleData) {
/*factors=*/{}))); /*factors=*/{})));
EXPECT_CALL(userdataauth(), EXPECT_CALL(userdataauth(),
PrepareEphemeralVault(WithSecondAuthSessionId(), _)) PrepareEphemeralVault(WithSecondAuthSessionId(), _))
.WillOnce(ReplyWith(PrepareEphemeralVaultReply())); .WillOnce(ReplyWith(BuildPrepareEphemeralVaultReply()));
EXPECT_CALL( EXPECT_CALL(
userdataauth(), userdataauth(),
AddAuthFactor(AllOf(WithSecondAuthSessionId(), AddAuthFactor(AllOf(WithSecondAuthSessionId(),
@ -629,7 +647,7 @@ TEST_F(AuthSessionAuthenticatorTest, LoginAsPublicSession) {
/*factors=*/{}))); /*factors=*/{})));
EXPECT_CALL(userdataauth(), EXPECT_CALL(userdataauth(),
PrepareEphemeralVault(WithFirstAuthSessionId(), _)) PrepareEphemeralVault(WithFirstAuthSessionId(), _))
.WillOnce(ReplyWith(PrepareEphemeralVaultReply())); .WillOnce(ReplyWith(BuildPrepareEphemeralVaultReply()));
// Act. // Act.
authenticator().LoginAsPublicSession(user_context); authenticator().LoginAsPublicSession(user_context);
@ -653,7 +671,7 @@ TEST_F(AuthSessionAuthenticatorTest, LoginAsKioskAccountNew) {
ReplyWith(BuildStartReply(kFirstAuthSessionId, /*user_exists=*/false, ReplyWith(BuildStartReply(kFirstAuthSessionId, /*user_exists=*/false,
/*factors=*/{}))); /*factors=*/{})));
EXPECT_CALL(userdataauth(), CreatePersistentUser(WithFirstAuthSessionId(), _)) EXPECT_CALL(userdataauth(), CreatePersistentUser(WithFirstAuthSessionId(), _))
.WillOnce(ReplyWith(CreatePersistentUserReply())); .WillOnce(ReplyWith(BuildCreatePersistentUserReply()));
EXPECT_CALL(userdataauth(), EXPECT_CALL(userdataauth(),
PreparePersistentVault(WithFirstAuthSessionId(), _)) PreparePersistentVault(WithFirstAuthSessionId(), _))
.WillOnce(ReplyWith(PreparePersistentVaultReply())); .WillOnce(ReplyWith(PreparePersistentVaultReply()));
@ -718,7 +736,7 @@ TEST_F(AuthSessionAuthenticatorTest, LoginAsKioskAccountEphemeral) {
/*factors=*/{}))); /*factors=*/{})));
EXPECT_CALL(userdataauth(), EXPECT_CALL(userdataauth(),
PrepareEphemeralVault(WithFirstAuthSessionId(), _)) PrepareEphemeralVault(WithFirstAuthSessionId(), _))
.WillOnce(ReplyWith(PrepareEphemeralVaultReply())); .WillOnce(ReplyWith(BuildPrepareEphemeralVaultReply()));
// Act. // Act.
authenticator().LoginAsKioskAccount(kAccountId, /*ephemeral=*/true); authenticator().LoginAsKioskAccount(kAccountId, /*ephemeral=*/true);
@ -757,7 +775,7 @@ TEST_F(AuthSessionAuthenticatorTest, LoginAsKioskAccountEphemeralStaleData) {
/*factors=*/{}))); /*factors=*/{})));
EXPECT_CALL(userdataauth(), EXPECT_CALL(userdataauth(),
PrepareEphemeralVault(WithSecondAuthSessionId(), _)) PrepareEphemeralVault(WithSecondAuthSessionId(), _))
.WillOnce(ReplyWith(PrepareEphemeralVaultReply())); .WillOnce(ReplyWith(BuildPrepareEphemeralVaultReply()));
} }
// Act. // Act.

@ -11,6 +11,7 @@
#include "chromeos/ash/components/cryptohome/userdataauth_util.h" #include "chromeos/ash/components/cryptohome/userdataauth_util.h"
#include "chromeos/ash/components/dbus/userdataauth/userdataauth_client.h" #include "chromeos/ash/components/dbus/userdataauth/userdataauth_client.h"
#include "chromeos/ash/components/login/auth/auth_events_recorder.h" #include "chromeos/ash/components/login/auth/auth_events_recorder.h"
#include "chromeos/ash/components/login/auth/auth_performer.h"
#include "chromeos/ash/components/login/auth/public/user_context.h" #include "chromeos/ash/components/login/auth/public/user_context.h"
#include "components/device_event_log/device_event_log.h" #include "components/device_event_log/device_event_log.h"
@ -184,6 +185,8 @@ void MountPerformer::OnCreatePersistentUser(
return; return;
} }
CHECK(reply.has_value()); CHECK(reply.has_value());
CHECK(reply->has_auth_properties());
AuthPerformer::FillAuthenticationData(reply->auth_properties(), *context);
std::move(callback).Run(std::move(context), absl::nullopt); std::move(callback).Run(std::move(context), absl::nullopt);
} }
@ -219,6 +222,8 @@ void MountPerformer::OnPrepareEphemeralVault(
return; return;
} }
CHECK(reply.has_value()); CHECK(reply.has_value());
CHECK(reply->has_auth_properties());
AuthPerformer::FillAuthenticationData(reply->auth_properties(), *context);
context->SetUserIDHash(reply->sanitized_username()); context->SetUserIDHash(reply->sanitized_username());
std::move(callback).Run(std::move(context), absl::nullopt); std::move(callback).Run(std::move(context), absl::nullopt);
} }

@ -159,6 +159,10 @@ AuthSessionIntents UserContext::CryptohomeContext::GetAuthorizedIntents()
return authorized_for_; return authorized_for_;
} }
void UserContext::CryptohomeContext::ClearAuthorizedIntents() {
authorized_for_.Clear();
}
void UserContext::CryptohomeContext::AddAuthorizedIntent( void UserContext::CryptohomeContext::AddAuthorizedIntent(
const AuthSessionIntent auth_intent) { const AuthSessionIntent auth_intent) {
authorized_for_.Put(auth_intent); authorized_for_.Put(auth_intent);
@ -511,6 +515,10 @@ AuthSessionIntents UserContext::GetAuthorizedIntents() const {
return cryptohome_.GetAuthorizedIntents(); return cryptohome_.GetAuthorizedIntents();
} }
void UserContext::ClearAuthorizedIntents() {
cryptohome_.ClearAuthorizedIntents();
}
void UserContext::AddAuthorizedIntent(const AuthSessionIntent auth_intent) { void UserContext::AddAuthorizedIntent(const AuthSessionIntent auth_intent) {
cryptohome_.AddAuthorizedIntent(auth_intent); cryptohome_.AddAuthorizedIntent(auth_intent);
} }

@ -85,6 +85,7 @@ class COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_LOGIN_AUTH_PUBLIC) UserContext {
base::Time GetSessionLifetime() const; base::Time GetSessionLifetime() const;
void SetSessionLifetime(const base::Time& valid_until); void SetSessionLifetime(const base::Time& valid_until);
void ClearAuthorizedIntents();
void AddAuthorizedIntent(AuthSessionIntent auth_intent); void AddAuthorizedIntent(AuthSessionIntent auth_intent);
AuthSessionIntents GetAuthorizedIntents() const; AuthSessionIntents GetAuthorizedIntents() const;
@ -249,6 +250,7 @@ class COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_LOGIN_AUTH_PUBLIC) UserContext {
base::Time GetSessionLifetime() const; base::Time GetSessionLifetime() const;
void SetSessionLifetime(const base::Time& valid_until); void SetSessionLifetime(const base::Time& valid_until);
void ClearAuthorizedIntents();
void AddAuthorizedIntent(AuthSessionIntent auth_intent); void AddAuthorizedIntent(AuthSessionIntent auth_intent);
void ClearSecrets(); void ClearSecrets();