blob: 8259a12b2c91b4f6651a4966bf8175d3e49e8026 [file] [log] [blame]
// Copyright 2019 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CRYPTOHOME_USERDATAAUTH_H_
#define CRYPTOHOME_USERDATAAUTH_H_
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <base/threading/thread.h>
#include <brillo/secure_blob.h>
#include "cryptohome/crypto.h"
#include "cryptohome/homedirs.h"
#include "cryptohome/mount.h"
#include "cryptohome/platform.h"
namespace cryptohome {
class UserDataAuth {
public:
UserDataAuth();
~UserDataAuth();
// Note that this function must be called from the thread that created this
// object, so that |origin_task_runner_| is initialized correctly.
bool Initialize();
// =============== Mount Related Public API ===============
// If username is empty, returns true if any mount is mounted, otherwise,
// returns true if the mount associated with the given |username| is mounted.
// For |is_ephemeral_out|, if no username is given, then is_ephemeral_out is
// set to true when any mount is ephemeral. Otherwise, is_ephemeral_out is set
// to true when the mount associated with the given |username| is mounted in
// an ephemeral manner. If nullptr is passed in for is_ephemeral_out, then it
// won't be touched. Ephemeral mount means that the content of the mount is
// cleared once the user logs out.
bool IsMounted(const std::string& username = "",
bool* is_ephemeral_out = nullptr);
// Returns true if the mount that corresponds to the username is mounted,
// false otherwise. If that mount is ephemeral, then is_ephemeral_out is set
// to true, false otherwise. If nullptr is passed in for is_ephemeral_out,
// then it won't be touched. Ephemeral mount means that the content of the
// mount is cleared once the user logs out.
bool IsMountedForUser(const std::string& username,
bool* is_ephemeral_out = nullptr);
// ================= Threading Utilities ==================
// Returns true if we are currently running on the origin thread
bool IsOnOriginThread() {
// Note that this function should not rely on |origin_task_runner_| because
// it may be unavailable when this function is first called by
// UserDataAuth::Initialize()
return disable_threading_ ||
base::PlatformThread::CurrentId() == origin_thread_id_;
}
// Returns true if we are currently running on the mount thread
bool IsOnMountThread() {
// GetThreadId blocks if the thread is not started yet.
return disable_threading_ ||
(mount_thread_.IsRunning() &&
(base::PlatformThread::CurrentId() == mount_thread_.GetThreadId()));
}
// DCHECK if we are running on the origin thread. Will have no effect
// in production.
void AssertOnOriginThread() { DCHECK(IsOnOriginThread()); }
// DCHECK if we are running on the mount thread. Will have no effect
// in production.
void AssertOnMountThread() { DCHECK(IsOnMountThread()); }
// Post Task to origin thread. For the caller, from_here is usually FROM_HERE
// macro, while task is a callback function to be posted. Will return true if
// the task may be run sometime in the future, false if it will definitely not
// run.
bool PostTaskToOriginThread(const tracked_objects::Location& from_here,
base::OnceClosure task);
// Post Task to mount thread. For the caller, from_here is usually FROM_HERE
// macro, while task is a callback function to be posted. Will return true if
// the task may be run sometime in the future, false if it will definitely not
// run.
bool PostTaskToMountThread(const tracked_objects::Location& from_here,
base::OnceClosure task);
// ================= Testing Utilities ==================
// Note that all functions below in this section should only be used for unit
// testing purpose only.
// Override |crypto_| for testing purpose
void set_crypto(cryptohome::Crypto* crypto) { crypto_ = crypto; }
// Override |homedirs_| for testing purpose
void set_homedirs(cryptohome::HomeDirs* homedirs) { homedirs_ = homedirs; }
// Override |tpm_| for testing purpose
void set_tpm(Tpm* tpm) { tpm_ = tpm; }
// Override |tpm_init_| for testing purpose
void set_tpm_init(TpmInit* tpm_init) { tpm_init_ = tpm_init; }
// Override |platform_| for testing purpose
void set_platform(cryptohome::Platform* platform) { platform_ = platform; }
// Associate a particular mount object |mount| with the username |username|
// for testing purpose
void set_mount_for_user(const std::string& username,
cryptohome::Mount* mount) {
mounts_[username] = mount;
}
// Set |disable_threading_|, so that we can disable threading in this class
// for testing purpose. See comment of |disable_threading_| for more
// information.
void set_disable_threading(bool disable_threading) {
disable_threading_ = disable_threading;
}
private:
// Note: In Service class (the class that this class is refactored from),
// there is a use_tpm_ member variable, but it is almost unused and always set
// to true there, so in this class, if we are migrating any code from Service
// class and use_tpm_ is used there, then we'll just assume it's true and not
// have a use_tpm_ variable here.
// The same is true for initialize_tpm_ variable, it is assumed to be true.
// =============== Mount Related Utilities ===============
// Returns the mount object associated with the given username
scoped_refptr<cryptohome::Mount> GetMountForUser(const std::string& username);
// =============== Threading Related Variables ===============
// The task runner that belongs to the thread that created this UserDataAuth
// object. Currently, this is required to be the same as the dbus thread's
// task runner.
scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner_;
// The thread ID of the thread that created this UserDataAuth object.
// Currently, this is required to be th esame as the dbus thread's task
// runner.
base::PlatformThreadId origin_thread_id_;
// The thread for performing long running, or mount related operations
base::Thread mount_thread_;
// This variable is used only for unit testing purpose. If set to true, it'll
// disable the the threading mechanism in this class so that testing doesn't
// fail. When threading is disabled, posting to origin or mount thread will
// execute immediately, and all checks for whether we are on mount or origin
// thread will result in true.
bool disable_threading_;
// =============== Basic Utilities Related Variables ===============
// The system salt that is used for obfuscating the username
brillo::SecureBlob system_salt_;
// The object for accessing the TPM
// Note that TPM doesn't use the unique_ptr for default pattern, since the tpm
// is a singleton - we don't want it getting destroyed when we are.
Tpm* tpm_;
// The default TPM init object.
std::unique_ptr<TpmInit> default_tpm_init_;
// The TPM init object. Note that |tpm_init_| and |default_tpm_init_| will be
// removed at the end of the refactoring that's happening in cryptohome
// (b/123679223).
TpmInit* tpm_init_;
// The default platform object for accessing platform related functionalities
std::unique_ptr<cryptohome::Platform> default_platform_;
// The actual platform object used by this class, usually set to
// default_platform_, but can be overridden for testing
cryptohome::Platform* platform_;
// The default crypto object for performing cryptographic operations
std::unique_ptr<cryptohome::Crypto> default_crypto_;
// The actual crypto object used by this class, usually set to
// default_crypto_, but can be overridden for testing
cryptohome::Crypto* crypto_;
// =============== Mount Related Variables ===============
// Defines a type for tracking Mount objects for each user by username.
typedef std::map<const std::string, scoped_refptr<cryptohome::Mount>>
MountMap;
// Records the Mount objects associated with each username.
// This and its content should only be accessed from the mount thread.
MountMap mounts_;
// Note: In Service class (the class that this class is refactored from),
// there is a mounts_lock_ lock for inserting/removal of mounts_ map. However,
// in this class, all accesses to mounts_ should happen on the mount thread,
// so no lock is needed.
// The homedirs_ object in normal operation
std::unique_ptr<HomeDirs> default_homedirs_;
// This holds the object that records informations about the homedirs.
// This is usually set to default_homedirs_, but can be overridden for
// testing
HomeDirs* homedirs_;
// This holds a timestamp for each user that is the time that the user was
// active.
std::unique_ptr<UserOldestActivityTimestampCache> user_timestamp_cache_;
};
} // namespace cryptohome
#endif // CRYPTOHOME_USERDATAAUTH_H_