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

Unified Diff: session_manager_service.cc

Issue 6469072: [login_manager] Use keygen helper to generate owner key (Closed) Base URL: http://git.chromium.org/git/login_manager.git@master
Patch Set: Add a few constants Created 9 years, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « session_manager_service.h ('k') | session_manager_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: session_manager_service.cc
diff --git a/session_manager_service.cc b/session_manager_service.cc
index f4bfd8bef7e0a6e2c7b133bba7c968b0d691d532..57245eb6da3bdef89e47dc29eef313a9a86e78eb 100644
--- a/session_manager_service.cc
+++ b/session_manager_service.cc
@@ -130,6 +130,10 @@ const char SessionManagerService::kTestingChannelFlag[] =
"--testing-channel=NamedTestingInterface:";
// static
const char SessionManagerService::kIOThreadName[] = "ThreadForIO";
+// static
+const char SessionManagerService::kKeygenExecutable[] = "/sbin/keygen";
+// static
+const char SessionManagerService::kTemporaryKeyFilename[] = "key.pub";
namespace {
@@ -145,6 +149,7 @@ SessionManagerService::SessionManagerService(
: child_jobs_(child_jobs.begin(), child_jobs.end()),
child_pids_(child_jobs.size(), -1),
exit_on_child_done_(false),
+ keygen_job_(NULL),
session_manager_(NULL),
main_loop_(g_main_loop_new(NULL, FALSE)),
system_(new SystemUtils),
@@ -479,20 +484,11 @@ gboolean SessionManagerService::StartSession(gchar* email_address,
return FALSE;
}
- if (set_uid_) {
- *OUT_done =
- upstart_signal_emitter_->EmitSignal(
- "start-user-session",
- StringPrintf("CHROMEOS_USER=%s USER_ID=%d",
- current_user_.c_str(), uid_),
- error);
- } else {
- *OUT_done =
- upstart_signal_emitter_->EmitSignal(
- "start-user-session",
- StringPrintf("CHROMEOS_USER=%s", current_user_.c_str()),
- error);
- }
+ *OUT_done =
+ upstart_signal_emitter_->EmitSignal(
+ "start-user-session",
+ StringPrintf("CHROMEOS_USER=%s", current_user_.c_str()),
+ error);
if (*OUT_done) {
for (size_t i_child = 0; i_child < child_jobs_.size(); ++i_child) {
@@ -506,11 +502,75 @@ gboolean SessionManagerService::StartSession(gchar* email_address,
signals_[kSignalSessionStateChanged],
0, "started", current_user_.c_str());
}
+ if (key_->HaveCheckedDisk() && !key_->IsPopulated())
+ StartKeyGeneration();
}
return *OUT_done;
}
+void SessionManagerService::HandleKeygenExit(GPid pid,
+ gint status,
+ gpointer data) {
+ SessionManagerService* manager = static_cast<SessionManagerService*>(data);
+ int i_child = manager->FindChildByPid(pid);
+ manager->child_pids_[i_child] = -1;
+ delete *(manager->child_jobs_.erase(manager->child_jobs_.begin() + i_child));
+
+ if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
+ std::string key;
+ file_util::ReadFileToString(
+ FilePath(file_util::GetHomeDir().AppendASCII(kTemporaryKeyFilename)),
+ &key);
+ manager->ValidateAndStoreOwnerKey(key);
+ } else {
+ if (WIFSIGNALED(status))
+ LOG(ERROR) << "keygen exited on signal " << WTERMSIG(status);
+ else
+ LOG(ERROR) << "keygen exited with exit code " << WEXITSTATUS(status);
+ }
+}
+
+void SessionManagerService::ValidateAndStoreOwnerKey(const std::string& buf) {
+ std::vector<uint8> pub_key;
+ NssUtil::KeyFromBuffer(buf, &pub_key);
+
+ if (!CurrentUserHasOwnerKey(pub_key, NULL)) {
+ SendSignal(chromium::kOwnerKeySetSignal, false);
+ return;
+ }
+
+ if (!key_->PopulateFromBuffer(pub_key)) {
+ SendSignal(chromium::kOwnerKeySetSignal, false);
+ return;
+ }
+ io_thread_.message_loop()->PostTask(
+ FROM_HERE, NewRunnableMethod(this, &SessionManagerService::PersistKey));
+ StoreOwnerProperties(NULL);
+}
+
+void SessionManagerService::StartKeyGeneration() {
+ if (!keygen_job_.get()) {
+ LOG(INFO) << "Creating keygen job";
+ std::vector<std::string> keygen_argv;
+ keygen_argv.push_back(kKeygenExecutable);
+ keygen_argv.push_back(
+ file_util::GetHomeDir().AppendASCII(kTemporaryKeyFilename).value());
Will Drewry 2011/02/23 03:30:16 I was going to suggest a random location, but sinc
+ keygen_job_.reset(new ChildJob(keygen_argv));
+ }
+
+ if (set_uid_)
+ keygen_job_->SetDesiredUid(uid_);
+ int pid = key_->StartGeneration(keygen_job_.get());
+ g_child_watch_add_full(G_PRIORITY_HIGH_IDLE,
+ pid,
+ HandleKeygenExit,
+ this,
+ NULL);
+ child_jobs_.push_back(keygen_job_.release());
+ child_pids_.push_back(pid);
+}
+
gboolean SessionManagerService::StopSession(gchar* unique_identifier,
gboolean* OUT_done,
GError** error) {
@@ -531,31 +591,12 @@ gboolean SessionManagerService::StopSession(gchar* unique_identifier,
gboolean SessionManagerService::SetOwnerKey(GArray* public_key_der,
GError** error) {
- LOG(INFO) << "key size is " << public_key_der->len;
-
- if (!session_started_) {
- SetGError(error,
- CHROMEOS_LOGIN_ERROR_ILLEGAL_PUBKEY,
- "Cannot set the owner's public key outside of a session.");
- return FALSE;
- }
-
- std::vector<uint8> pub_key;
- NssUtil::KeyFromBuffer(public_key_der, &pub_key);
-
- if (!CurrentUserHasOwnerKey(pub_key, error)) {
- return FALSE; // error set by CurrentUserHasOwnerKey()
- }
-
- if (!key_->PopulateFromBuffer(pub_key)) {
- SetGError(error,
- CHROMEOS_LOGIN_ERROR_ILLEGAL_PUBKEY,
- "Attempted to set invalid key as owner's public key.");
- return FALSE;
- }
- io_thread_.message_loop()->PostTask(
- FROM_HERE, NewRunnableMethod(this, &SessionManagerService::PersistKey));
- return StoreOwnerProperties(error);
+ SetGError(error,
+ CHROMEOS_LOGIN_ERROR_ILLEGAL_PUBKEY,
+ "The session_manager now sets the Owner's public key.");
+ // Just to be safe, send back a nACK in addition to returning an error.
+ SendSignal(chromium::kOwnerKeySetSignal, false);
+ return FALSE;
}
gboolean SessionManagerService::Unwhitelist(gchar* email_address,
@@ -784,19 +825,13 @@ void SessionManagerService::HandleChildExit(GPid pid,
if (manager->shutting_down_)
return;
- int i_child = -1;
- for (int i = 0; i < manager->child_pids_.size(); ++i) {
- if (manager->child_pids_[i] == pid) {
- i_child = i;
- manager->child_pids_[i] = -1;
- break;
- }
+ ChildJobInterface* child_job = NULL;
+ int i_child = manager->FindChildByPid(pid);
+ if (i_child >= 0) {
+ child_job = manager->child_jobs_[i_child];
+ manager->child_pids_[i_child] = -1;
}
- ChildJobInterface* child_job = i_child >= 0
- ? manager->child_jobs_[i_child]
- : NULL;
-
LOG(ERROR) << StringPrintf(
"Process %s(%d) exited.",
child_job ? child_job->GetName().c_str() : "",
@@ -1028,6 +1063,14 @@ gboolean SessionManagerService::ValidateAndCacheUserEmail(
return TRUE;
}
+int SessionManagerService::FindChildByPid(int pid) {
+ for (int i = 0; i < child_pids_.size(); ++i) {
+ if (child_pids_[i] == pid)
+ return i;
+ }
+ return -1;
+}
+
void SessionManagerService::CleanupChildren(int timeout) {
vector<pair<int, uid_t> > pids_to_kill;
« no previous file with comments | « session_manager_service.h ('k') | session_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698