| OLD | NEW |
| 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 #include "cryptohome/service.h" | 4 |
| 5 #include "service.h" |
| 6 |
| 7 #include <stdio.h> |
| 8 #include <stdlib.h> |
| 5 | 9 |
| 6 #include <base/logging.h> | 10 #include <base/logging.h> |
| 7 #include <chromeos/dbus/dbus.h> | 11 #include <chromeos/dbus/dbus.h> |
| 8 #include <stdio.h> | |
| 9 #include <stdlib.h> | |
| 10 | 12 |
| 11 #include "cryptohome/interface.h" | 13 #include "interface.h" |
| 12 #include "cryptohome/mount.h" | 14 #include "mount.h" |
| 13 #include "cryptohome/secure_blob.h" | 15 #include "secure_blob.h" |
| 14 #include "cryptohome/username_passkey.h" | 16 #include "username_passkey.h" |
| 15 | 17 |
| 16 // Forcibly namespace the dbus-bindings generated server bindings instead of | 18 // Forcibly namespace the dbus-bindings generated server bindings instead of |
| 17 // modifying the files afterward. | 19 // modifying the files afterward. |
| 18 namespace cryptohome { // NOLINT | 20 namespace cryptohome { // NOLINT |
| 19 namespace gobject { // NOLINT | 21 namespace gobject { // NOLINT |
| 20 #include "cryptohome/bindings/server.h" | 22 #include "cryptohome/bindings/server.h" |
| 21 } // namespace gobject | 23 } // namespace gobject |
| 22 } // namespace cryptohome | 24 } // namespace cryptohome |
| 23 | 25 |
| 24 namespace cryptohome { | 26 namespace cryptohome { |
| 25 | 27 |
| 26 Service::Service() : loop_(NULL), | 28 Service::Service() : loop_(NULL), |
| 27 cryptohome_(NULL), | 29 cryptohome_(NULL), |
| 28 system_salt_(), | 30 system_salt_(), |
| 29 mount_(NULL) { } | 31 default_mount_(new cryptohome::Mount()), |
| 32 mount_(default_mount_.get()) { } |
| 30 | 33 |
| 31 Service::~Service() { | 34 Service::~Service() { |
| 32 if (loop_) | 35 if (loop_) |
| 33 g_main_loop_unref(loop_); | 36 g_main_loop_unref(loop_); |
| 34 if (cryptohome_) | 37 if (cryptohome_) |
| 35 g_object_unref(cryptohome_); | 38 g_object_unref(cryptohome_); |
| 36 if (mount_) | |
| 37 delete mount_; | |
| 38 } | 39 } |
| 39 | 40 |
| 40 bool Service::Initialize() { | 41 bool Service::Initialize() { |
| 41 if(mount_ == NULL) { | 42 mount_->Init(); |
| 42 mount_ = new cryptohome::Mount(); | 43 |
| 43 mount_->Init(); | |
| 44 } | |
| 45 // Install the type-info for the service with dbus. | 44 // Install the type-info for the service with dbus. |
| 46 dbus_g_object_type_install_info(gobject::cryptohome_get_type(), | 45 dbus_g_object_type_install_info(gobject::cryptohome_get_type(), |
| 47 &gobject::dbus_glib_cryptohome_object_info); | 46 &gobject::dbus_glib_cryptohome_object_info); |
| 48 return Reset(); | 47 return Reset(); |
| 49 } | 48 } |
| 50 | 49 |
| 51 bool Service::Reset() { | 50 bool Service::Reset() { |
| 52 if (cryptohome_) | 51 if (cryptohome_) |
| 53 g_object_unref(cryptohome_); | 52 g_object_unref(cryptohome_); |
| 54 cryptohome_ = reinterpret_cast<gobject::Cryptohome*>( | 53 cryptohome_ = reinterpret_cast<gobject::Cryptohome*>( |
| 55 g_object_new(gobject::cryptohome_get_type(), NULL)); | 54 g_object_new(gobject::cryptohome_get_type(), NULL)); |
| 56 // Allow references to this instance. | 55 // Allow references to this instance. |
| 57 cryptohome_->service = this; | 56 cryptohome_->service = this; |
| 58 | 57 |
| 59 if (loop_) { | 58 if (loop_) { |
| 60 ::g_main_loop_unref(loop_); | 59 ::g_main_loop_unref(loop_); |
| 61 } | 60 } |
| 62 loop_ = g_main_loop_new(NULL, false); | 61 loop_ = g_main_loop_new(NULL, false); |
| 63 if (!loop_) { | 62 if (!loop_) { |
| 64 LOG(ERROR) << "Failed to create main loop"; | 63 LOG(ERROR) << "Failed to create main loop"; |
| 65 return false; | 64 return false; |
| 66 } | 65 } |
| 67 return true; | 66 return true; |
| 68 } | 67 } |
| 69 | 68 |
| 70 gboolean Service::CheckKey(gchar *userid, | 69 gboolean Service::CheckKey(gchar *userid, |
| 71 gchar *key, | 70 gchar *key, |
| 72 gboolean *OUT_success, | 71 gboolean *OUT_success, |
| 73 GError **error) { | 72 GError **error) { |
| 74 UsernamePasskey credentials(userid, strlen(userid), | 73 UsernamePasskey credentials(userid, SecureBlob(key, strlen(key))); |
| 75 chromeos::Blob(key, key + strlen(key))); | |
| 76 | 74 |
| 77 // TODO(fes): Handle CHROMEOS_PAM_LOCALACCOUNT | 75 // TODO(fes): Handle CHROMEOS_PAM_LOCALACCOUNT |
| 78 *OUT_success = mount_->TestCredentials(credentials); | 76 *OUT_success = mount_->TestCredentials(credentials); |
| 79 return TRUE; | 77 return TRUE; |
| 80 } | 78 } |
| 81 | 79 |
| 82 gboolean Service::MigrateKey(gchar *userid, | 80 gboolean Service::MigrateKey(gchar *userid, |
| 83 gchar *from_key, | 81 gchar *from_key, |
| 84 gchar *to_key, | 82 gchar *to_key, |
| 85 gboolean *OUT_success, | 83 gboolean *OUT_success, |
| 86 GError **error) { | 84 GError **error) { |
| 87 UsernamePasskey credentials(userid, strlen(userid), | 85 UsernamePasskey credentials(userid, SecureBlob(to_key, strlen(to_key))); |
| 88 chromeos::Blob(to_key, to_key + strlen(to_key))); | |
| 89 | 86 |
| 90 *OUT_success = mount_->MigratePasskey(credentials, from_key); | 87 *OUT_success = mount_->MigratePasskey(credentials, from_key); |
| 91 return TRUE; | 88 return TRUE; |
| 92 } | 89 } |
| 93 | 90 |
| 94 gboolean Service::Remove(gchar *userid, | 91 gboolean Service::Remove(gchar *userid, |
| 95 gboolean *OUT_success, | 92 gboolean *OUT_success, |
| 96 GError **error) { | 93 GError **error) { |
| 97 UsernamePasskey credentials(userid, strlen(userid), | 94 UsernamePasskey credentials(userid, chromeos::Blob()); |
| 98 chromeos::Blob()); | |
| 99 | 95 |
| 100 *OUT_success = mount_->RemoveCryptohome(credentials); | 96 *OUT_success = mount_->RemoveCryptohome(credentials); |
| 101 return TRUE; | 97 return TRUE; |
| 102 } | 98 } |
| 103 | 99 |
| 104 gboolean Service::GetSystemSalt(GArray **OUT_salt, GError **error) { | 100 gboolean Service::GetSystemSalt(GArray **OUT_salt, GError **error) { |
| 105 if(system_salt_.size() == 0) { | 101 if (system_salt_.size() == 0) { |
| 106 system_salt_ = mount_->GetSystemSalt(); | 102 mount_->GetSystemSalt(&system_salt_); |
| 107 } | 103 } |
| 108 *OUT_salt = g_array_new(false, false, 1); | 104 *OUT_salt = g_array_new(false, false, 1); |
| 109 g_array_append_vals(*OUT_salt, &system_salt_.front(), system_salt_.size()); | 105 g_array_append_vals(*OUT_salt, &system_salt_.front(), system_salt_.size()); |
| 110 | 106 |
| 111 return TRUE; | 107 return TRUE; |
| 112 } | 108 } |
| 113 | 109 |
| 114 gboolean Service::IsMounted(gboolean *OUT_is_mounted, GError **error) { | 110 gboolean Service::IsMounted(gboolean *OUT_is_mounted, GError **error) { |
| 115 *OUT_is_mounted = mount_->IsCryptohomeMounted(); | 111 *OUT_is_mounted = mount_->IsCryptohomeMounted(); |
| 116 return TRUE; | 112 return TRUE; |
| 117 } | 113 } |
| 118 | 114 |
| 119 gboolean Service::Mount(gchar *userid, | 115 gboolean Service::Mount(gchar *userid, |
| 120 gchar *key, | 116 gchar *key, |
| 117 gint *OUT_error, |
| 121 gboolean *OUT_done, | 118 gboolean *OUT_done, |
| 122 GError **error) { | 119 GError **error) { |
| 123 UsernamePasskey credentials(userid, strlen(userid), | 120 UsernamePasskey credentials(userid, SecureBlob(key, strlen(key))); |
| 124 chromeos::Blob(key, key + strlen(key))); | |
| 125 | 121 |
| 126 if(mount_->IsCryptohomeMounted()) { | 122 if (mount_->IsCryptohomeMounted()) { |
| 127 if(mount_->IsCryptohomeMountedForUser(credentials)) { | 123 if (mount_->IsCryptohomeMountedForUser(credentials)) { |
| 128 LOG(INFO) << "Cryptohome already mounted for this user"; | 124 LOG(INFO) << "Cryptohome already mounted for this user"; |
| 125 *OUT_error = Mount::MOUNT_ERROR_NONE; |
| 129 *OUT_done = TRUE; | 126 *OUT_done = TRUE; |
| 130 return TRUE; | 127 return TRUE; |
| 131 } else { | 128 } else { |
| 132 if(!mount_->UnmountCryptohome()) { | 129 if (!mount_->UnmountCryptohome()) { |
| 133 LOG(ERROR) << "Could not unmount cryptohome from previous user"; | 130 LOG(ERROR) << "Could not unmount cryptohome from previous user"; |
| 131 *OUT_error = Mount::MOUNT_ERROR_MOUNT_POINT_BUSY; |
| 134 *OUT_done = FALSE; | 132 *OUT_done = FALSE; |
| 135 return TRUE; | 133 return TRUE; |
| 136 } | 134 } |
| 137 } | 135 } |
| 138 } | 136 } |
| 139 | 137 |
| 140 // TODO(fes): Iterate keys if we change how cryptohome keeps track of key | 138 // We only check key 0 because it is the only key that we use. Other indexes |
| 141 // indexes. Right now, 0 is always the current, and 0+n should only be used | 139 // are only used in password migration. |
| 142 // temporarily during password migration. | 140 Mount::MountError local_error = Mount::MOUNT_ERROR_NONE; |
| 143 Mount::MountError mount_error = Mount::MOUNT_ERROR_NONE; | 141 *OUT_done = mount_->MountCryptohome(credentials, 0, &local_error); |
| 144 *OUT_done = mount_->MountCryptohome(credentials, 0, &mount_error); | 142 *OUT_error = local_error; |
| 145 if(!(*OUT_done) && (mount_error == Mount::MOUNT_ERROR_KEY_FAILURE)) { | 143 return TRUE; |
| 146 // If there is a key failure, create cryptohome from scratch. | 144 } |
| 147 // TODO(fes): remove this when Chrome is no longer expecting this behavior. | 145 |
| 148 if(mount_->RemoveCryptohome(credentials)) { | 146 gboolean Service::MountGuest(gint *OUT_error, |
| 149 *OUT_done = mount_->MountCryptohome(credentials, 0, &mount_error); | 147 gboolean *OUT_done, |
| 148 GError **error) { |
| 149 if (mount_->IsCryptohomeMounted()) { |
| 150 if (!mount_->UnmountCryptohome()) { |
| 151 LOG(ERROR) << "Could not unmount cryptohome from previous user"; |
| 152 *OUT_error = Mount::MOUNT_ERROR_MOUNT_POINT_BUSY; |
| 153 *OUT_done = FALSE; |
| 154 return TRUE; |
| 150 } | 155 } |
| 151 } | 156 } |
| 157 |
| 158 *OUT_error = Mount::MOUNT_ERROR_NONE; |
| 159 *OUT_done = mount_->MountGuestCryptohome(); |
| 152 return TRUE; | 160 return TRUE; |
| 153 } | 161 } |
| 154 | 162 |
| 155 gboolean Service::Unmount(gboolean *OUT_done, GError **error) { | 163 gboolean Service::Unmount(gboolean *OUT_done, GError **error) { |
| 156 if(mount_->IsCryptohomeMounted()) { | 164 if (mount_->IsCryptohomeMounted()) { |
| 157 *OUT_done = mount_->UnmountCryptohome(); | 165 *OUT_done = mount_->UnmountCryptohome(); |
| 158 } else { | 166 } else { |
| 159 *OUT_done = true; | 167 *OUT_done = true; |
| 160 } | 168 } |
| 161 return TRUE; | 169 return TRUE; |
| 162 } | 170 } |
| 163 | 171 |
| 164 } // namespace cryptohome | 172 } // namespace cryptohome |
| OLD | NEW |