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;
}
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] =
users_.insert({auth_session.account, UserCryptohomeState()});
@ -1020,6 +1024,11 @@ void FakeUserDataAuthClient::PrepareEphemeralVault(
}
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(
@ -1061,10 +1070,15 @@ void FakeUserDataAuthClient::CreatePersistentUser(
}
auth_session.authenticated = true;
// TODO(b/301078137): once proto includes lifetime information, add it
// to the reply.
auth_session.requested_auth_session_intent =
user_data_auth::AUTH_INTENT_DECRYPT;
auth_session.lifetime =
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(
@ -1319,6 +1333,12 @@ void FakeUserDataAuthClient::AuthenticateAuthFactor(
session.requested_auth_session_intent);
session.lifetime =
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.set_seconds_left(cryptohome::kAuthsessionInitialLifetime.InSeconds());
}
@ -1424,7 +1444,10 @@ void FakeUserDataAuthClient::GetAuthSessionStatus(
return;
}
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());
}

@ -87,6 +87,23 @@ base::WeakPtr<AuthPerformer> AuthPerformer::AsWeakPtr() {
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,
bool ephemeral,
AuthSessionIntent intent,
@ -571,16 +588,9 @@ void AuthPerformer::OnAuthenticateAuthFactor(
return;
}
CHECK(reply.has_value());
DCHECK(reply->authorized_for_size() > 0);
for (auto& authorized_for : reply->authorized_for()) {
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()));
CHECK(reply->has_auth_properties());
FillAuthenticationData(reply->auth_properties(), *context);
LOGIN_LOG(EVENT) << "Authenticated successfully";
std::move(callback).Run(std::move(context), absl::nullopt);
}
@ -606,6 +616,9 @@ void AuthPerformer::OnGetAuthSessionStatus(
return;
}
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;
AuthSessionStatus status;
switch (reply->status()) {
@ -621,11 +634,12 @@ void AuthPerformer::OnGetAuthSessionStatus(
case ::user_data_auth::AUTH_SESSION_STATUS_AUTHENTICATED:
status.Put(AuthSessionLevel::kSessionIsValid);
status.Put(AuthSessionLevel::kCryptohomeStrong);
lifetime = base::Seconds(reply->time_left());
lifetime = base::Seconds(reply->auth_properties().seconds_left());
break;
default:
NOTREACHED();
}
FillAuthenticationData(reply->auth_properties(), *context);
std::move(callback).Run(status, lifetime, std::move(context),
/*cryptohome_error=*/absl::nullopt);
}

@ -59,6 +59,12 @@ class COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_LOGIN_AUTH) AuthPerformer {
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`,
// fills information about supported (and configured if user exists) keys.
// `Context` should not have associated auth session.

@ -50,7 +50,8 @@ void ReplyAsSuccess(
UserDataAuthClient::AuthenticateAuthFactorCallback callback) {
::user_data_auth::AuthenticateAuthFactorReply reply;
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);
}

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

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

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

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