Chromium Code Reviews| Index: service.cc |
| diff --git a/service.cc b/service.cc |
| index ed47224568e5c6a38f6111187bcefbf06fd759ed..09c6630a08444317e2ae43a1113f775b360c6f9f 100644 |
| --- a/service.cc |
| +++ b/service.cc |
| @@ -12,11 +12,14 @@ |
| #include <base/string_util.h> |
| #include <base/time.h> |
| #include <chromeos/dbus/dbus.h> |
| +#include <string> |
| +#include <vector> |
| #include "cryptohome/marshal.glibmarshal.h" |
| #include "cryptohome_event_source.h" |
| #include "interface.h" |
| #include "crypto.h" |
| +#include "lockbox.h" |
| #include "mount.h" |
| #include "secure_blob.h" |
| #include "tpm.h" |
| @@ -86,7 +89,9 @@ Service::Service() |
| async_complete_signal_(-1), |
| tpm_init_signal_(-1), |
| event_source_(), |
| - auto_cleanup_period_(kAutoCleanupPeriodMS) { |
| + auto_cleanup_period_(kAutoCleanupPeriodMS), |
| + default_lockbox_(new cryptohome::Lockbox()), |
| + lockbox_(default_lockbox_.get()) { |
| } |
| Service::~Service() { |
| @@ -103,15 +108,19 @@ bool Service::Initialize() { |
| bool result = true; |
| mount_->Init(); |
| + // If the TPM is unowned or doesn't exist, it's safe for |
| + // this function to be called again. However, it shouldn't |
| + // be called across multiple threads in parallel. |
|
gauravsh
2011/04/11 04:03:20
Is this comment for InitializeLockBox()? If so, ca
Will Drewry
2011/04/13 16:04:59
The part that is relevant (thread safety) is in th
|
| + InitializeLockbox(); |
| + |
| Tpm* tpm = const_cast<Tpm*>(mount_->get_crypto()->get_tpm()); |
| - if (tpm && initialize_tpm_) { |
| + if (tpm && initialize_tpm_) { |
| tpm_init_->set_tpm(tpm); |
| tpm_init_->Init(this); |
| if (!SeedUrandom()) { |
| LOG(ERROR) << "FAILED TO SEED /dev/urandom AT START"; |
| } |
| } |
| - |
| // Install the type-info for the service with dbus. |
| dbus_g_object_type_install_info(gobject::cryptohome_get_type(), |
| &gobject::dbus_glib_cryptohome_object_info); |
| @@ -156,6 +165,17 @@ bool Service::Initialize() { |
| return result; |
| } |
| +void Service::InitializeLockbox() { |
|
gauravsh
2011/04/11 04:03:20
Should this return true or false? Otherwise the ca
Will Drewry
2011/04/13 16:04:59
The caller doesn't matter as much unless we want c
|
| + Tpm* tpm = const_cast<Tpm*>(mount_->get_crypto()->get_tpm()); |
| + // Don't call this until the TPM is owned. |
| + if (tpm && !tpm->IsOwned()) |
| + return; |
| + // tpm will be NULL if the system lacks one. |
| + lockbox_->Init(tpm, |
| + Lockbox::kDefaultNvramIndex, |
| + Lockbox::kDefaultPath); |
| +} |
| + |
| bool Service::SeedUrandom() { |
| SecureBlob random; |
| if (!tpm_init_->GetRandomData(kDefaultRandomSeedLength, &random)) { |
| @@ -206,6 +226,7 @@ void Service::NotifyEvent(CryptohomeEventBase* event) { |
| TpmInitStatus* result = static_cast<TpmInitStatus*>(event); |
| g_signal_emit(cryptohome_, tpm_init_signal_, 0, tpm_init_->IsTpmReady(), |
| tpm_init_->IsTpmEnabled(), result->get_took_ownership()); |
| + // TODO(wad) should we package up a Lockbox status here too? |
| } |
| } |
| @@ -219,6 +240,9 @@ void Service::InitializeTpmComplete(bool status, bool took_ownership) { |
| mount_task->set_complete_event(&event); |
| mount_thread_.message_loop()->PostTask(FROM_HERE, mount_task); |
| event.Wait(); |
| + // Initialize the install-time locked attributes since we |
| + // can't do it prior to ownership. |
| + InitializeLockbox(); |
| } |
| // The event source will free this object |
| TpmInitStatus* tpm_init_status = new TpmInitStatus(); |
| @@ -567,6 +591,68 @@ gboolean Service::TpmClearStoredPassword(GError** error) { |
| return TRUE; |
| } |
| +gboolean Service::LockboxGet(gchar* name, |
| + GArray** OUT_value, |
| + gboolean* OUT_successful, |
| + GError** error) { |
| + chromeos::Blob value; |
| + *OUT_successful = lockbox_->Get(name, &value); |
| + *OUT_value = g_array_new(false, false, sizeof(char)); |
| + if (*OUT_successful) |
| + g_array_append_vals(*OUT_value, &value.front(), value.size()); |
| + return TRUE; |
| +} |
| + |
| +gboolean Service::LockboxSet(gchar* name, |
| + GArray* value, |
| + gboolean* OUT_successful, |
| + GError** error) { |
| + // Convert from GArray to vector |
| + chromeos::Blob value_blob; |
| + value_blob.assign(value->data, value->data + value->len); |
| + *OUT_successful = lockbox_->Set(name, value_blob); |
| + return TRUE; |
| +} |
| + |
| +gboolean Service::LockboxLock(gboolean* OUT_locked, GError** error) { |
| + *OUT_locked = lockbox_->Lock(); |
| + return TRUE; |
| +} |
| + |
| +gboolean Service::LockboxCount(gint* OUT_count, GError** error) { |
| + // TODO(wad) for all of these functions return error on uninit. |
| + // Follow the CHROMEOS_LOGIN_ERROR quark example in chromeos/dbus/ |
| + *OUT_count = lockbox_->Count(); |
| + return TRUE; |
| +} |
| + |
| +gboolean Service::LockboxIsReady(gboolean* OUT_ready, GError** error) { |
| + // Initialization is handled automatically when possible and async |
| + // notification implies readiness. This allows other code to poll. |
| + *OUT_ready = (lockbox_->initialized() == true); |
| + return TRUE; |
| +} |
| + |
| +gboolean Service::LockboxIsLocked(gboolean* OUT_locked, GError** error) { |
| + *OUT_locked = (lockbox_->locked() == true); |
| + return TRUE; |
| +} |
| + |
| +gboolean Service::LockboxIsSecure(gboolean* OUT_secure, GError** error) { |
| + *OUT_secure = (lockbox_->secure() == true); |
| + return TRUE; |
| +} |
| + |
| +gboolean Service::LockboxIsTampered(gboolean* OUT_tampered, GError** error) { |
| + *OUT_tampered = (lockbox_->tampered() == true); |
| + return TRUE; |
| +} |
| + |
| +gboolean Service::LockboxIsLegacy(gboolean* OUT_legacy, GError** error) { |
| + *OUT_legacy = (lockbox_->legacy() == true); |
| + return TRUE; |
| +} |
| + |
| gboolean Service::GetStatusString(gchar** OUT_status, GError** error) { |
| Tpm::TpmStatusInfo tpm_status; |
| mount_->get_crypto()->EnsureTpm(false); |
| @@ -627,6 +713,26 @@ gboolean Service::GetStatusString(gchar** OUT_status, GError** error) { |
| } while(false); |
| } |
| + int lockbox_size = lockbox_->Count(); |
| + std::string lockbox_data("Lockbox Contents:\n"); |
| + if (lockbox_->Count()) { |
| + std::string name; |
| + chromeos::Blob value; |
| + for (int pair = 0; pair < lockbox_size; ++pair) { |
| + lockbox_data += StringPrintf( |
|
gauravsh
2011/04/11 04:03:20
is using += as efficient as using append()? (not t
Will Drewry
2011/04/13 16:04:59
No idea. Done.
gauravsh
2011/04/14 07:39:52
Yeah, it seems either append or += is ok. What's n
|
| + " Index...........................: %d\n", pair); |
| + if (lockbox_->GetNameByIndex(pair, &name) && |
| + lockbox_->GetValueByIndex(pair, &value)) { |
| + std::string value_str(reinterpret_cast<const char*>(&value[0]), |
| + value.size()); |
| + lockbox_data += StringPrintf( |
| + " Name............................: %s\n" |
| + " Value...........................: %s\n", |
| + name.c_str(), |
| + value_str.c_str()); |
| + } |
| + } |
| + } |
| *OUT_status = g_strdup_printf( |
| "TPM Status:\n" |
| @@ -644,7 +750,15 @@ gboolean Service::GetStatusString(gchar** OUT_status, GError** error) { |
| " Last Error......................: %08x\n" |
| "%s" |
| "Mount Status:\n" |
| - " Vault Is Mounted................: %s\n", |
| + " Vault Is Mounted................: %s\n" |
| + "Lockbox Status:\n" |
| + " Initialized.....................: %s\n" |
| + " Secure..........................: %s\n" |
| + " Legacy..........................: %s\n" |
| + " Locked..........................: %s\n" |
| + " Tampered........................: %s\n" |
| + " Entries.........................: %d\n" |
| + "%s", |
| (tpm_status.Enabled ? "1" : "0"), |
| (tpm_status.Owned ? "1" : "0"), |
| (tpm_status.BeingOwned ? "1" : "0"), |
| @@ -658,7 +772,14 @@ gboolean Service::GetStatusString(gchar** OUT_status, GError** error) { |
| (tpm_status.ThisInstanceHasKeyHandle ? "1" : "0"), |
| tpm_status.LastTpmError, |
| user_data.c_str(), |
| - (mount_->IsCryptohomeMounted() ? "1" : "0")); |
| + (mount_->IsCryptohomeMounted() ? "1" : "0"), |
| + (lockbox_->initialized() ? "1" : "0"), |
| + (lockbox_->secure() ? "1" : "0"), |
| + (lockbox_->legacy() ? "1" : "0"), |
| + (lockbox_->locked() ? "1" : "0"), |
| + (lockbox_->tampered() ? "1" : "0"), |
| + lockbox_size, |
| + lockbox_data.c_str()); |
| return TRUE; |
| } |