Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(778)

Side by Side Diff: service.cc

Issue 6801020: service,cryptohome: wire up lockbox to dbus (Closed)
Patch Set: fix spaces Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« service.h ('K') | « service.h ('k') | service_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium OS Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "service.h" 5 #include "service.h"
6 6
7 #include <stdio.h> 7 #include <stdio.h>
8 #include <stdlib.h> 8 #include <stdlib.h>
9 9
10 #include <base/file_util.h> 10 #include <base/file_util.h>
11 #include <base/logging.h> 11 #include <base/logging.h>
12 #include <base/string_util.h> 12 #include <base/string_util.h>
13 #include <base/time.h> 13 #include <base/time.h>
14 #include <chromeos/dbus/dbus.h> 14 #include <chromeos/dbus/dbus.h>
15 #include <string>
16 #include <vector>
15 17
16 #include "cryptohome/marshal.glibmarshal.h" 18 #include "cryptohome/marshal.glibmarshal.h"
17 #include "cryptohome_event_source.h" 19 #include "cryptohome_event_source.h"
18 #include "interface.h" 20 #include "interface.h"
19 #include "crypto.h" 21 #include "crypto.h"
22 #include "lockbox.h"
20 #include "mount.h" 23 #include "mount.h"
21 #include "secure_blob.h" 24 #include "secure_blob.h"
22 #include "tpm.h" 25 #include "tpm.h"
23 #include "username_passkey.h" 26 #include "username_passkey.h"
24 #include "vault_keyset.pb.h" 27 #include "vault_keyset.pb.h"
25 28
26 // Forcibly namespace the dbus-bindings generated server bindings instead of 29 // Forcibly namespace the dbus-bindings generated server bindings instead of
27 // modifying the files afterward. 30 // modifying the files afterward.
28 namespace cryptohome { // NOLINT 31 namespace cryptohome { // NOLINT
29 namespace gobject { // NOLINT 32 namespace gobject { // NOLINT
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 system_salt_(), 82 system_salt_(),
80 default_mount_(new cryptohome::Mount()), 83 default_mount_(new cryptohome::Mount()),
81 mount_(default_mount_.get()), 84 mount_(default_mount_.get()),
82 default_tpm_init_(new TpmInit()), 85 default_tpm_init_(new TpmInit()),
83 tpm_init_(default_tpm_init_.get()), 86 tpm_init_(default_tpm_init_.get()),
84 initialize_tpm_(true), 87 initialize_tpm_(true),
85 mount_thread_(kMountThreadName), 88 mount_thread_(kMountThreadName),
86 async_complete_signal_(-1), 89 async_complete_signal_(-1),
87 tpm_init_signal_(-1), 90 tpm_init_signal_(-1),
88 event_source_(), 91 event_source_(),
89 auto_cleanup_period_(kAutoCleanupPeriodMS) { 92 auto_cleanup_period_(kAutoCleanupPeriodMS),
93 default_lockbox_(new cryptohome::Lockbox()),
94 lockbox_(default_lockbox_.get()) {
90 } 95 }
91 96
92 Service::~Service() { 97 Service::~Service() {
93 if (loop_) 98 if (loop_)
94 g_main_loop_unref(loop_); 99 g_main_loop_unref(loop_);
95 if (cryptohome_) 100 if (cryptohome_)
96 g_object_unref(cryptohome_); 101 g_object_unref(cryptohome_);
97 if (mount_thread_.IsRunning()) { 102 if (mount_thread_.IsRunning()) {
98 mount_thread_.Stop(); 103 mount_thread_.Stop();
99 } 104 }
100 } 105 }
101 106
102 bool Service::Initialize() { 107 bool Service::Initialize() {
103 bool result = true; 108 bool result = true;
104 109
105 mount_->Init(); 110 mount_->Init();
111 // If the TPM is unowned or doesn't exist, it's safe for
112 // this function to be called again. However, it shouldn't
113 // 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
114 InitializeLockbox();
115
106 Tpm* tpm = const_cast<Tpm*>(mount_->get_crypto()->get_tpm()); 116 Tpm* tpm = const_cast<Tpm*>(mount_->get_crypto()->get_tpm());
107 if (tpm && initialize_tpm_) { 117 if (tpm && initialize_tpm_) {
108 tpm_init_->set_tpm(tpm); 118 tpm_init_->set_tpm(tpm);
109 tpm_init_->Init(this); 119 tpm_init_->Init(this);
110 if (!SeedUrandom()) { 120 if (!SeedUrandom()) {
111 LOG(ERROR) << "FAILED TO SEED /dev/urandom AT START"; 121 LOG(ERROR) << "FAILED TO SEED /dev/urandom AT START";
112 } 122 }
113 } 123 }
114
115 // Install the type-info for the service with dbus. 124 // Install the type-info for the service with dbus.
116 dbus_g_object_type_install_info(gobject::cryptohome_get_type(), 125 dbus_g_object_type_install_info(gobject::cryptohome_get_type(),
117 &gobject::dbus_glib_cryptohome_object_info); 126 &gobject::dbus_glib_cryptohome_object_info);
118 if (!Reset()) { 127 if (!Reset()) {
119 result = false; 128 result = false;
120 } 129 }
121 130
122 async_complete_signal_ = g_signal_new("async_call_status", 131 async_complete_signal_ = g_signal_new("async_call_status",
123 gobject::cryptohome_get_type(), 132 gobject::cryptohome_get_type(),
124 G_SIGNAL_RUN_LAST, 133 G_SIGNAL_RUN_LAST,
(...skipping 24 matching lines...) Expand all
149 158
150 // Start scheduling periodic cleanup events. Note, that the first 159 // Start scheduling periodic cleanup events. Note, that the first
151 // event will be called by Chrome explicitly from the login screen. 160 // event will be called by Chrome explicitly from the login screen.
152 mount_thread_.message_loop()->PostDelayedTask( 161 mount_thread_.message_loop()->PostDelayedTask(
153 FROM_HERE, NewRunnableMethod(this, &Service::AutoCleanupCallback), 162 FROM_HERE, NewRunnableMethod(this, &Service::AutoCleanupCallback),
154 auto_cleanup_period_); 163 auto_cleanup_period_);
155 164
156 return result; 165 return result;
157 } 166 }
158 167
168 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
169 Tpm* tpm = const_cast<Tpm*>(mount_->get_crypto()->get_tpm());
170 // Don't call this until the TPM is owned.
171 if (tpm && !tpm->IsOwned())
172 return;
173 // tpm will be NULL if the system lacks one.
174 lockbox_->Init(tpm,
175 Lockbox::kDefaultNvramIndex,
176 Lockbox::kDefaultPath);
177 }
178
159 bool Service::SeedUrandom() { 179 bool Service::SeedUrandom() {
160 SecureBlob random; 180 SecureBlob random;
161 if (!tpm_init_->GetRandomData(kDefaultRandomSeedLength, &random)) { 181 if (!tpm_init_->GetRandomData(kDefaultRandomSeedLength, &random)) {
162 LOG(ERROR) << "Could not get random data from the TPM"; 182 LOG(ERROR) << "Could not get random data from the TPM";
163 return false; 183 return false;
164 } 184 }
165 size_t written = file_util::WriteFile(FilePath(kDefaultEntropySource), 185 size_t written = file_util::WriteFile(FilePath(kDefaultEntropySource),
166 static_cast<const char*>(random.const_data()), random.size()); 186 static_cast<const char*>(random.const_data()), random.size());
167 if (written != random.size()) { 187 if (written != random.size()) {
168 LOG(ERROR) << "Error writing data to /dev/urandom"; 188 LOG(ERROR) << "Error writing data to /dev/urandom";
(...skipping 30 matching lines...) Expand all
199 219
200 void Service::NotifyEvent(CryptohomeEventBase* event) { 220 void Service::NotifyEvent(CryptohomeEventBase* event) {
201 if (!strcmp(event->GetEventName(), kMountTaskResultEventType)) { 221 if (!strcmp(event->GetEventName(), kMountTaskResultEventType)) {
202 MountTaskResult* result = static_cast<MountTaskResult*>(event); 222 MountTaskResult* result = static_cast<MountTaskResult*>(event);
203 g_signal_emit(cryptohome_, async_complete_signal_, 0, result->sequence_id(), 223 g_signal_emit(cryptohome_, async_complete_signal_, 0, result->sequence_id(),
204 result->return_status(), result->return_code()); 224 result->return_status(), result->return_code());
205 } else if (!strcmp(event->GetEventName(), kTpmInitStatusEventType)) { 225 } else if (!strcmp(event->GetEventName(), kTpmInitStatusEventType)) {
206 TpmInitStatus* result = static_cast<TpmInitStatus*>(event); 226 TpmInitStatus* result = static_cast<TpmInitStatus*>(event);
207 g_signal_emit(cryptohome_, tpm_init_signal_, 0, tpm_init_->IsTpmReady(), 227 g_signal_emit(cryptohome_, tpm_init_signal_, 0, tpm_init_->IsTpmReady(),
208 tpm_init_->IsTpmEnabled(), result->get_took_ownership()); 228 tpm_init_->IsTpmEnabled(), result->get_took_ownership());
229 // TODO(wad) should we package up a Lockbox status here too?
209 } 230 }
210 } 231 }
211 232
212 void Service::InitializeTpmComplete(bool status, bool took_ownership) { 233 void Service::InitializeTpmComplete(bool status, bool took_ownership) {
213 if (took_ownership) { 234 if (took_ownership) {
214 MountTaskResult ignored_result; 235 MountTaskResult ignored_result;
215 base::WaitableEvent event(true, false); 236 base::WaitableEvent event(true, false);
216 MountTaskResetTpmContext* mount_task = 237 MountTaskResetTpmContext* mount_task =
217 new MountTaskResetTpmContext(NULL, mount_); 238 new MountTaskResetTpmContext(NULL, mount_);
218 mount_task->set_result(&ignored_result); 239 mount_task->set_result(&ignored_result);
219 mount_task->set_complete_event(&event); 240 mount_task->set_complete_event(&event);
220 mount_thread_.message_loop()->PostTask(FROM_HERE, mount_task); 241 mount_thread_.message_loop()->PostTask(FROM_HERE, mount_task);
221 event.Wait(); 242 event.Wait();
243 // Initialize the install-time locked attributes since we
244 // can't do it prior to ownership.
245 InitializeLockbox();
222 } 246 }
223 // The event source will free this object 247 // The event source will free this object
224 TpmInitStatus* tpm_init_status = new TpmInitStatus(); 248 TpmInitStatus* tpm_init_status = new TpmInitStatus();
225 tpm_init_status->set_status(status); 249 tpm_init_status->set_status(status);
226 tpm_init_status->set_took_ownership(took_ownership); 250 tpm_init_status->set_took_ownership(took_ownership);
227 event_source_.AddEvent(tpm_init_status); 251 event_source_.AddEvent(tpm_init_status);
228 } 252 }
229 253
230 gboolean Service::CheckKey(gchar *userid, 254 gboolean Service::CheckKey(gchar *userid,
231 gchar *key, 255 gchar *key,
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 tpm_init_->StartInitializeTpm(); 584 tpm_init_->StartInitializeTpm();
561 } 585 }
562 return TRUE; 586 return TRUE;
563 } 587 }
564 588
565 gboolean Service::TpmClearStoredPassword(GError** error) { 589 gboolean Service::TpmClearStoredPassword(GError** error) {
566 tpm_init_->ClearStoredTpmPassword(); 590 tpm_init_->ClearStoredTpmPassword();
567 return TRUE; 591 return TRUE;
568 } 592 }
569 593
594 gboolean Service::LockboxGet(gchar* name,
595 GArray** OUT_value,
596 gboolean* OUT_successful,
597 GError** error) {
598 chromeos::Blob value;
599 *OUT_successful = lockbox_->Get(name, &value);
600 *OUT_value = g_array_new(false, false, sizeof(char));
601 if (*OUT_successful)
602 g_array_append_vals(*OUT_value, &value.front(), value.size());
603 return TRUE;
604 }
605
606 gboolean Service::LockboxSet(gchar* name,
607 GArray* value,
608 gboolean* OUT_successful,
609 GError** error) {
610 // Convert from GArray to vector
611 chromeos::Blob value_blob;
612 value_blob.assign(value->data, value->data + value->len);
613 *OUT_successful = lockbox_->Set(name, value_blob);
614 return TRUE;
615 }
616
617 gboolean Service::LockboxLock(gboolean* OUT_locked, GError** error) {
618 *OUT_locked = lockbox_->Lock();
619 return TRUE;
620 }
621
622 gboolean Service::LockboxCount(gint* OUT_count, GError** error) {
623 // TODO(wad) for all of these functions return error on uninit.
624 // Follow the CHROMEOS_LOGIN_ERROR quark example in chromeos/dbus/
625 *OUT_count = lockbox_->Count();
626 return TRUE;
627 }
628
629 gboolean Service::LockboxIsReady(gboolean* OUT_ready, GError** error) {
630 // Initialization is handled automatically when possible and async
631 // notification implies readiness. This allows other code to poll.
632 *OUT_ready = (lockbox_->initialized() == true);
633 return TRUE;
634 }
635
636 gboolean Service::LockboxIsLocked(gboolean* OUT_locked, GError** error) {
637 *OUT_locked = (lockbox_->locked() == true);
638 return TRUE;
639 }
640
641 gboolean Service::LockboxIsSecure(gboolean* OUT_secure, GError** error) {
642 *OUT_secure = (lockbox_->secure() == true);
643 return TRUE;
644 }
645
646 gboolean Service::LockboxIsTampered(gboolean* OUT_tampered, GError** error) {
647 *OUT_tampered = (lockbox_->tampered() == true);
648 return TRUE;
649 }
650
651 gboolean Service::LockboxIsLegacy(gboolean* OUT_legacy, GError** error) {
652 *OUT_legacy = (lockbox_->legacy() == true);
653 return TRUE;
654 }
655
570 gboolean Service::GetStatusString(gchar** OUT_status, GError** error) { 656 gboolean Service::GetStatusString(gchar** OUT_status, GError** error) {
571 Tpm::TpmStatusInfo tpm_status; 657 Tpm::TpmStatusInfo tpm_status;
572 mount_->get_crypto()->EnsureTpm(false); 658 mount_->get_crypto()->EnsureTpm(false);
573 Tpm* tpm = const_cast<Tpm*>(mount_->get_crypto()->get_tpm()); 659 Tpm* tpm = const_cast<Tpm*>(mount_->get_crypto()->get_tpm());
574 660
575 if (tpm) { 661 if (tpm) {
576 tpm->GetStatus(true, &tpm_status); 662 tpm->GetStatus(true, &tpm_status);
577 } else { 663 } else {
578 Tpm::GetSingleton()->GetStatus(true, &tpm_status); 664 Tpm::GetSingleton()->GetStatus(true, &tpm_status);
579 } 665 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 " (UTC)\n", 706 " (UTC)\n",
621 ((serialized.flags() & 707 ((serialized.flags() &
622 cryptohome::SerializedVaultKeyset::TPM_WRAPPED) ? "1" : "0"), 708 cryptohome::SerializedVaultKeyset::TPM_WRAPPED) ? "1" : "0"),
623 ((serialized.flags() & 709 ((serialized.flags() &
624 cryptohome::SerializedVaultKeyset::SCRYPT_WRAPPED) ? "1" : "0"), 710 cryptohome::SerializedVaultKeyset::SCRYPT_WRAPPED) ? "1" : "0"),
625 exploded.month, exploded.day_of_month, exploded.year, 711 exploded.month, exploded.day_of_month, exploded.year,
626 exploded.hour, exploded.minute, exploded.second); 712 exploded.hour, exploded.minute, exploded.second);
627 713
628 } while(false); 714 } while(false);
629 } 715 }
716 int lockbox_size = lockbox_->Count();
717 std::string lockbox_data("Lockbox Contents:\n");
718 if (lockbox_->Count()) {
719 std::string name;
720 chromeos::Blob value;
721 for (int pair = 0; pair < lockbox_size; ++pair) {
722 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
723 " Index...........................: %d\n", pair);
724 if (lockbox_->GetNameByIndex(pair, &name) &&
725 lockbox_->GetValueByIndex(pair, &value)) {
726 std::string value_str(reinterpret_cast<const char*>(&value[0]),
727 value.size());
728 lockbox_data += StringPrintf(
729 " Name............................: %s\n"
730 " Value...........................: %s\n",
731 name.c_str(),
732 value_str.c_str());
733 }
734 }
735 }
630 736
631 *OUT_status = g_strdup_printf( 737 *OUT_status = g_strdup_printf(
632 "TPM Status:\n" 738 "TPM Status:\n"
633 " Enabled.........................: %s\n" 739 " Enabled.........................: %s\n"
634 " Owned...........................: %s\n" 740 " Owned...........................: %s\n"
635 " Being Owned.....................: %s\n" 741 " Being Owned.....................: %s\n"
636 " Can Connect.....................: %s\n" 742 " Can Connect.....................: %s\n"
637 " Can Load SRK....................: %s\n" 743 " Can Load SRK....................: %s\n"
638 " Can Load SRK Public.............: %s\n" 744 " Can Load SRK Public.............: %s\n"
639 " Has Cryptohome Key..............: %s\n" 745 " Has Cryptohome Key..............: %s\n"
640 " Can Encrypt.....................: %s\n" 746 " Can Encrypt.....................: %s\n"
641 " Can Decrypt.....................: %s\n" 747 " Can Decrypt.....................: %s\n"
642 " Instance Context................: %s\n" 748 " Instance Context................: %s\n"
643 " Instance Key Handle.............: %s\n" 749 " Instance Key Handle.............: %s\n"
644 " Last Error......................: %08x\n" 750 " Last Error......................: %08x\n"
645 "%s" 751 "%s"
646 "Mount Status:\n" 752 "Mount Status:\n"
647 " Vault Is Mounted................: %s\n", 753 " Vault Is Mounted................: %s\n"
754 "Lockbox Status:\n"
755 " Initialized.....................: %s\n"
756 " Secure..........................: %s\n"
757 " Legacy..........................: %s\n"
758 " Locked..........................: %s\n"
759 " Tampered........................: %s\n"
760 " Entries.........................: %d\n"
761 "%s",
648 (tpm_status.Enabled ? "1" : "0"), 762 (tpm_status.Enabled ? "1" : "0"),
649 (tpm_status.Owned ? "1" : "0"), 763 (tpm_status.Owned ? "1" : "0"),
650 (tpm_status.BeingOwned ? "1" : "0"), 764 (tpm_status.BeingOwned ? "1" : "0"),
651 (tpm_status.CanConnect ? "1" : "0"), 765 (tpm_status.CanConnect ? "1" : "0"),
652 (tpm_status.CanLoadSrk ? "1" : "0"), 766 (tpm_status.CanLoadSrk ? "1" : "0"),
653 (tpm_status.CanLoadSrkPublicKey ? "1" : "0"), 767 (tpm_status.CanLoadSrkPublicKey ? "1" : "0"),
654 (tpm_status.HasCryptohomeKey ? "1" : "0"), 768 (tpm_status.HasCryptohomeKey ? "1" : "0"),
655 (tpm_status.CanEncrypt ? "1" : "0"), 769 (tpm_status.CanEncrypt ? "1" : "0"),
656 (tpm_status.CanDecrypt ? "1" : "0"), 770 (tpm_status.CanDecrypt ? "1" : "0"),
657 (tpm_status.ThisInstanceHasContext ? "1" : "0"), 771 (tpm_status.ThisInstanceHasContext ? "1" : "0"),
658 (tpm_status.ThisInstanceHasKeyHandle ? "1" : "0"), 772 (tpm_status.ThisInstanceHasKeyHandle ? "1" : "0"),
659 tpm_status.LastTpmError, 773 tpm_status.LastTpmError,
660 user_data.c_str(), 774 user_data.c_str(),
661 (mount_->IsCryptohomeMounted() ? "1" : "0")); 775 (mount_->IsCryptohomeMounted() ? "1" : "0"),
776 (lockbox_->initialized() ? "1" : "0"),
777 (lockbox_->secure() ? "1" : "0"),
778 (lockbox_->legacy() ? "1" : "0"),
779 (lockbox_->locked() ? "1" : "0"),
780 (lockbox_->tampered() ? "1" : "0"),
781 lockbox_size,
782 lockbox_data.c_str());
662 return TRUE; 783 return TRUE;
663 } 784 }
664 785
665 // Called on Mount thread. 786 // Called on Mount thread.
666 void Service::AutoCleanupCallback() { 787 void Service::AutoCleanupCallback() {
667 mount_->DoAutomaticFreeDiskSpaceControl(); 788 mount_->DoAutomaticFreeDiskSpaceControl();
668 789
669 // Schedule our next call. If the thread is terminating, we would 790 // Schedule our next call. If the thread is terminating, we would
670 // not be called. 791 // not be called.
671 mount_thread_.message_loop()->PostDelayedTask( 792 mount_thread_.message_loop()->PostDelayedTask(
672 FROM_HERE, NewRunnableMethod(this, &Service::AutoCleanupCallback), 793 FROM_HERE, NewRunnableMethod(this, &Service::AutoCleanupCallback),
673 auto_cleanup_period_); 794 auto_cleanup_period_);
674 } 795 }
675 796
676 } // namespace cryptohome 797 } // namespace cryptohome
677 798
678 // We do not want AutoCleanupCallback() to refer the class and make it 799 // We do not want AutoCleanupCallback() to refer the class and make it
679 // wait for its execution. If Mount thread terminates, it will delete 800 // wait for its execution. If Mount thread terminates, it will delete
680 // our pending task or wait for it to finish. 801 // our pending task or wait for it to finish.
681 DISABLE_RUNNABLE_METHOD_REFCOUNT(cryptohome::Service); 802 DISABLE_RUNNABLE_METHOD_REFCOUNT(cryptohome::Service);
OLDNEW
« service.h ('K') | « service.h ('k') | service_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698