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

Side by Side Diff: src/platform/cryptohome/service.cc

Issue 2051003: Initial patch from Will. (Closed) Base URL: ssh://git@chromiumos-git/chromiumos
Patch Set: Address style nits. Created 10 years, 6 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
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 #include "cryptohome/service.h" 4 #include "cryptohome/service.h"
5 5
6 #include <base/logging.h> 6 #include <base/logging.h>
7 #include <chromeos/dbus/dbus.h> 7 #include <chromeos/dbus/dbus.h>
8 #include <stdio.h> 8 #include <stdio.h>
9 #include <stdlib.h> 9 #include <stdlib.h>
10 10
11 #include "cryptohome/authenticator.h"
12 #include "cryptohome/interface.h" 11 #include "cryptohome/interface.h"
13 #include "cryptohome/username_passhash.h" 12 #include "cryptohome/mount.h"
13 #include "cryptohome/secure_blob.h"
14 #include "cryptohome/username_passkey.h"
14 15
15 // Forcibly namespace the dbus-bindings generated server bindings instead of 16 // Forcibly namespace the dbus-bindings generated server bindings instead of
16 // modifying the files afterward. 17 // modifying the files afterward.
17 namespace cryptohome { // NOLINT 18 namespace cryptohome { // NOLINT
18 namespace gobject { // NOLINT 19 namespace gobject { // NOLINT
19 #include "cryptohome/bindings/server.h" 20 #include "cryptohome/bindings/server.h"
20 } // namespace gobject 21 } // namespace gobject
21 } // namespace cryptohome 22 } // namespace cryptohome
22 23
23 namespace cryptohome { 24 namespace cryptohome {
24 25
25 const char *Service::kDefaultMountCommand = "/usr/sbin/mount.cryptohome"; 26 Service::Service() : loop_(NULL),
26 const char *Service::kDefaultUnmountCommand = "/usr/sbin/umount.cryptohome"; 27 cryptohome_(NULL),
27 const char *Service::kDefaultIsMountedCommand = 28 system_salt_(),
28 "/bin/mount | /bin/grep -q ' /home/chronos/user '"; 29 mount_(NULL) { }
29 30
30 Service::Service() : loop_(NULL),
31 auth_(new Authenticator),
32 cryptohome_(NULL),
33 mount_command_(kDefaultMountCommand),
34 unmount_command_(kDefaultUnmountCommand),
35 is_mounted_command_(kDefaultIsMountedCommand) { }
36 Service::~Service() { 31 Service::~Service() {
37 if (loop_) 32 if (loop_)
38 g_main_loop_unref(loop_); 33 g_main_loop_unref(loop_);
39 if (cryptohome_) 34 if (cryptohome_)
40 g_object_unref(cryptohome_); 35 g_object_unref(cryptohome_);
36 if (mount_)
37 delete mount_;
41 } 38 }
42 39
43 bool Service::Initialize() { 40 bool Service::Initialize() {
41 if(mount_ == NULL) {
42 mount_ = new cryptohome::Mount();
43 mount_->Init();
44 }
44 // Install the type-info for the service with dbus. 45 // Install the type-info for the service with dbus.
45 dbus_g_object_type_install_info(gobject::cryptohome_get_type(), 46 dbus_g_object_type_install_info(gobject::cryptohome_get_type(),
46 &gobject::dbus_glib_cryptohome_object_info); 47 &gobject::dbus_glib_cryptohome_object_info);
47 return Reset(); 48 return Reset();
48 } 49 }
49 50
50 bool Service::Reset() { 51 bool Service::Reset() {
51 if (cryptohome_) 52 if (cryptohome_)
52 g_object_unref(cryptohome_); 53 g_object_unref(cryptohome_);
53 cryptohome_ = reinterpret_cast<gobject::Cryptohome*>( 54 cryptohome_ = reinterpret_cast<gobject::Cryptohome*>(
54 g_object_new(gobject::cryptohome_get_type(), NULL)); 55 g_object_new(gobject::cryptohome_get_type(), NULL));
55 // Allow references to this instance. 56 // Allow references to this instance.
56 cryptohome_->service = this; 57 cryptohome_->service = this;
57 58
58 if (loop_) { 59 if (loop_) {
59 ::g_main_loop_unref(loop_); 60 ::g_main_loop_unref(loop_);
60 } 61 }
61 loop_ = g_main_loop_new(NULL, false); 62 loop_ = g_main_loop_new(NULL, false);
62 if (!loop_) { 63 if (!loop_) {
63 LOG(ERROR) << "Failed to create main loop"; 64 LOG(ERROR) << "Failed to create main loop";
64 return false; 65 return false;
65 } 66 }
66 return true; 67 return true;
67 } 68 }
68 69
69 gboolean Service::CheckKey(gchar *userid, 70 gboolean Service::CheckKey(gchar *userid,
70 gchar *key, 71 gchar *key,
71 gboolean *OUT_success, 72 gboolean *OUT_success,
72 GError **error) { 73 GError **error) {
73 UsernamePasshash creds(userid, strlen(userid), key, strlen(key)); 74 UsernamePasskey credentials(userid, strlen(userid),
74 if (!auth_->Init()) { 75 chromeos::Blob(key, key + strlen(key)));
75 *OUT_success = FALSE; 76
76 return TRUE; 77 // TODO(fes): Handle CHROMEOS_PAM_LOCALACCOUNT
78 *OUT_success = mount_->TestCredentials(credentials);
79 return TRUE;
80 }
81
82 gboolean Service::MigrateKey(gchar *userid,
83 gchar *from_key,
84 gchar *to_key,
85 gboolean *OUT_success,
86 GError **error) {
87 UsernamePasskey credentials(userid, strlen(userid),
88 chromeos::Blob(to_key, to_key + strlen(to_key)));
89
90 *OUT_success = mount_->MigratePasskey(credentials, from_key);
91 return TRUE;
92 }
93
94 gboolean Service::Remove(gchar *userid,
95 gboolean *OUT_success,
96 GError **error) {
97 UsernamePasskey credentials(userid, strlen(userid),
98 chromeos::Blob());
99
100 *OUT_success = mount_->RemoveCryptohome(credentials);
101 return TRUE;
102 }
103
104 gboolean Service::GetSystemSalt(GArray **OUT_salt, GError **error) {
105 if(system_salt_.size() == 0) {
106 system_salt_ = mount_->GetSystemSalt();
77 } 107 }
78 *OUT_success = auth_->TestAllMasterKeys(creds); 108 *OUT_salt = g_array_new(false, false, 1);
109 g_array_append_vals(*OUT_salt, &system_salt_.front(), system_salt_.size());
110
79 return TRUE; 111 return TRUE;
80 } 112 }
81 113
82 gboolean Service::IsMounted(gboolean *OUT_is_mounted, GError **error) { 114 gboolean Service::IsMounted(gboolean *OUT_is_mounted, GError **error) {
83 int status = system(is_mounted_command()); 115 *OUT_is_mounted = mount_->IsCryptohomeMounted();
84 *OUT_is_mounted = !status;
85 return TRUE; 116 return TRUE;
86 } 117 }
87 118
88 gboolean Service::Mount(gchar *userid, 119 gboolean Service::Mount(gchar *userid,
89 gchar *key, 120 gchar *key,
90 gboolean *OUT_done, 121 gboolean *OUT_done,
91 GError **error) { 122 GError **error) {
92 // Never double mount. 123 UsernamePasskey credentials(userid, strlen(userid),
93 // This will mean we don't mount over existing mounts, 124 chromeos::Blob(key, key + strlen(key)));
94 // but at present, we reboot on user change so it is ok. 125
95 // Later, this can be more intelligent. 126 if(mount_->IsCryptohomeMounted()) {
96 if (IsMounted(OUT_done, error) && *OUT_done) { 127 if(mount_->IsCryptohomeMountedForUser(credentials)) {
97 *OUT_done = FALSE; 128 LOG(INFO) << "Cryptohome already mounted for this user";
98 return TRUE; 129 *OUT_done = TRUE;
130 return TRUE;
131 } else {
132 if(!mount_->UnmountCryptohome()) {
133 LOG(ERROR) << "Could not unmount cryptohome from previous user";
134 *OUT_done = FALSE;
135 return TRUE;
136 }
137 }
99 } 138 }
100 // Note, by doing this we allow any chronos caller to 139
101 // send a variable for use in the scripts. Bad idea. 140 // TODO(fes): Iterate keys if we change how cryptohome keeps track of key
102 // Thankfully, this will go away with the scripts. 141 // indexes. Right now, 0 is always the current, and 0+n should only be used
103 setenv("CHROMEOS_USER", userid, 1); 142 // temporarily during password migration.
104 FILE *mount = popen(mount_command(), "w"); 143 Mount::MountError mount_error = Mount::MOUNT_ERROR_NONE;
105 if (!mount) { 144 *OUT_done = mount_->MountCryptohome(credentials, 0, &mount_error);
106 // TODO(wad) *error = 145 if(!(*OUT_done) && (mount_error == Mount::MOUNT_ERROR_KEY_FAILURE)) {
107 return FALSE; 146 // If there is a key failure, create cryptohome from scratch.
108 } 147 // TODO(fes): remove this when Chrome is no longer expecting this behavior.
109 fprintf(mount, "%s", key); 148 if(mount_->RemoveCryptohome(credentials)) {
110 int status = pclose(mount); 149 *OUT_done = mount_->MountCryptohome(credentials, 0, &mount_error);
111 if (status != 0) { 150 }
112 *OUT_done = FALSE;
113 } else {
114 *OUT_done = TRUE;
115 } 151 }
116 return TRUE; 152 return TRUE;
117 } 153 }
118 154
119 gboolean Service::Unmount(gboolean *OUT_done, GError **error) { 155 gboolean Service::Unmount(gboolean *OUT_done, GError **error) {
120 // Check for a mount first. 156 if(mount_->IsCryptohomeMounted()) {
121 if (IsMounted(OUT_done, error) && !*OUT_done) { 157 *OUT_done = mount_->UnmountCryptohome();
122 *OUT_done = TRUE; // unmounting nothing works fine. 158 } else {
123 return TRUE; 159 *OUT_done = true;
124 } 160 }
125
126 int status = system(unmount_command());
127 *OUT_done = !status;
128 return TRUE; 161 return TRUE;
129 } 162 }
130 163
131 } // namespace cryptohome 164 } // namespace cryptohome
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698