| Index: cryptohome.cc
|
| diff --git a/cryptohome.cc b/cryptohome.cc
|
| index cdc9c5b768a41849716e4e1c2afd4f6c73a3bc36..74533f410ae955443342a906a93a01aa0eec8b6c 100644
|
| --- a/cryptohome.cc
|
| +++ b/cryptohome.cc
|
| @@ -4,6 +4,13 @@
|
| //
|
| // Cryptohome client that uses the dbus client interface
|
|
|
| +#include <openssl/err.h>
|
| +#include <openssl/evp.h>
|
| +#include <openssl/rand.h>
|
| +#include <openssl/sha.h>
|
| +#include <termios.h>
|
| +#include <unistd.h>
|
| +
|
| #include <base/basictypes.h>
|
| #include <base/command_line.h>
|
| #include <base/logging.h>
|
| @@ -11,35 +18,35 @@
|
| #include <chromeos/dbus/dbus.h>
|
| #include <chromeos/dbus/service_constants.h>
|
| #include <chromeos/utility.h>
|
| -
|
| #include <iostream>
|
| -#include <openssl/err.h>
|
| -#include <openssl/evp.h>
|
| -#include <openssl/rand.h>
|
| -#include <openssl/sha.h>
|
| -#include <termios.h>
|
| -#include <unistd.h>
|
|
|
| -#include "cryptohome/username_passkey.h"
|
| -#include "cryptohome/bindings/client.h"
|
| +#include "bindings/client.h"
|
| +#include "crypto.h"
|
| +#include "secure_blob.h"
|
| +#include "username_passkey.h"
|
| +
|
|
|
| namespace switches {
|
| static const char kActionSwitch[] = "action";
|
| static const char *kActions[] = {
|
| "mount",
|
| + "mount_guest",
|
| "unmount",
|
| "is_mounted",
|
| "test_auth",
|
| "migrate_key",
|
| "remove",
|
| + "obfuscate_user",
|
| NULL };
|
| enum ActionEnum {
|
| ACTION_MOUNT,
|
| + ACTION_MOUNT_GUEST,
|
| ACTION_UNMOUNT,
|
| ACTION_MOUNTED,
|
| ACTION_TEST_AUTH,
|
| ACTION_MIGRATE_KEY,
|
| - ACTION_REMOVE };
|
| + ACTION_REMOVE,
|
| + ACTION_OBFUSCATE_USER };
|
| static const char kUserSwitch[] = "user";
|
| static const char kPasswordSwitch[] = "password";
|
| static const char kOldPasswordSwitch[] = "old_password";
|
| @@ -77,31 +84,13 @@ bool GetUsername(const CommandLine* cl, std::string* user_out) {
|
| return true;
|
| }
|
|
|
| -bool GetUsernamePassword(const chromeos::dbus::Proxy& proxy,
|
| - const CommandLine* cl,
|
| - std::string* user_out,
|
| - std::string* password_out,
|
| - std::string* old_password_out = NULL) {
|
| - if(!GetUsername(cl, user_out)) {
|
| - return false;
|
| - }
|
| -
|
| - std::string password = cl->GetSwitchValueASCII(switches::kPasswordSwitch);
|
| - std::string old_password = cl->GetSwitchValueASCII(
|
| - switches::kOldPasswordSwitch);
|
| +bool GetPassword(const chromeos::dbus::Proxy& proxy,
|
| + const CommandLine* cl,
|
| + const std::string& cl_switch,
|
| + const std::string& prompt,
|
| + std::string* password_out) {
|
| + std::string password = cl->GetSwitchValueASCII(cl_switch);
|
|
|
| - if(old_password_out != NULL && old_password.length() == 0) {
|
| - struct termios original_attr;
|
| - struct termios new_attr;
|
| - tcgetattr(0, &original_attr);
|
| - memcpy(&new_attr, &original_attr, sizeof(new_attr));
|
| - new_attr.c_lflag &= ~(ECHO);
|
| - tcsetattr(0, TCSANOW, &new_attr);
|
| - std::cout << "Enter old password for <" << (*user_out) << ">: ";
|
| - std::cin >> old_password;
|
| - std::cout << std::endl;
|
| - tcsetattr(0, TCSANOW, &original_attr);
|
| - }
|
| if(password.length() == 0) {
|
| struct termios original_attr;
|
| struct termios new_attr;
|
| @@ -109,64 +98,23 @@ bool GetUsernamePassword(const chromeos::dbus::Proxy& proxy,
|
| memcpy(&new_attr, &original_attr, sizeof(new_attr));
|
| new_attr.c_lflag &= ~(ECHO);
|
| tcsetattr(0, TCSANOW, &new_attr);
|
| - std::cout << "Enter password for <" << (*user_out) << ">: ";
|
| + std::cout << prompt << ": ";
|
| std::cin >> password;
|
| - std::cout << std::endl
|
| - << "Re-enter password for <" << (*user_out) << ">: ";
|
| - std::string verification;
|
| - std::cin >> verification;
|
| std::cout << std::endl;
|
| tcsetattr(0, TCSANOW, &original_attr);
|
| - if(verification != password) {
|
| - LOG(ERROR) << "Passwords do not match.";
|
| - return false;
|
| - }
|
| }
|
|
|
| std::string trimmed_password;
|
| TrimString(password, "\r\n", &trimmed_password);
|
| - cryptohome::UsernamePasskey up(
|
| - cryptohome::UsernamePasskey::FromUsernamePassword((*user_out).c_str(),
|
| - trimmed_password.c_str(), GetSystemSalt(proxy)));
|
| - cryptohome::SecureBlob passkey = up.GetPasskey();
|
| - *password_out = std::string(reinterpret_cast<char*>(&passkey[0]),
|
| + cryptohome::SecureBlob passkey;
|
| + cryptohome::Crypto::PasswordToPasskey(trimmed_password.c_str(),
|
| + GetSystemSalt(proxy), &passkey);
|
| + *password_out = std::string(static_cast<char*>(passkey.data()),
|
| passkey.size());
|
| - if(old_password_out != NULL) {
|
| - TrimString(old_password, "\r\n", &trimmed_password);
|
| - cryptohome::UsernamePasskey old_up(
|
| - cryptohome::UsernamePasskey::FromUsernamePassword((*user_out).c_str(),
|
| - trimmed_password.c_str(), GetSystemSalt(proxy)));
|
| - passkey = old_up.GetPasskey();
|
| - *old_password_out = std::string(reinterpret_cast<char*>(&passkey[0]),
|
| - passkey.size());
|
| - }
|
|
|
| return true;
|
| }
|
|
|
| -bool AskHardQuestion(const std::string& user) {
|
| - std::cout << "!!! The password you entered did not unwrap the user's"
|
| - << std::endl
|
| - << "!!! vault key. If you proceed, the user's cryptohome"
|
| - << std::endl
|
| - << "!!! will be DELETED and RECREATED."
|
| - << std::endl
|
| - << "!!!"
|
| - << std::endl
|
| - << "!!! Re-enter the username at the prompt to create a new"
|
| - << std::endl
|
| - << "!!! cryptohome for the user."
|
| - << std::endl
|
| - << "Enter the username <" << user << ">: ";
|
| - std::string verification;
|
| - std::cin >> verification;
|
| - if(user != verification) {
|
| - LOG(ERROR) << "Usernames do not match.";
|
| - return false;
|
| - }
|
| - return true;
|
| -}
|
| -
|
| bool ConfirmRemove(const std::string& user) {
|
| std::cout << "!!! Are you sure you want to remove the user's cryptohome?"
|
| << std::endl
|
| @@ -206,44 +154,58 @@ int main(int argc, char **argv) {
|
| if (!strcmp(switches::kActions[switches::ACTION_MOUNT], action.c_str())) {
|
| std::string user, password;
|
|
|
| - if(!GetUsernamePassword(proxy, cl, &user, &password)) {
|
| + if (!GetUsername(cl, &user)) {
|
| + LOG(ERROR) << "No username specified";
|
| return 1;
|
| }
|
|
|
| + GetPassword(proxy, cl, switches::kPasswordSwitch,
|
| + StringPrintf("Enter the password for <%s>", user.c_str()),
|
| + &password);
|
| +
|
| gboolean done = false;
|
| + gint mount_error = 0;
|
| chromeos::glib::ScopedError error;
|
| GError **errptr = &chromeos::Resetter(&error).lvalue();
|
| - org_chromium_CryptohomeInterface_check_key(proxy.gproxy(),
|
| - user.c_str(),
|
| - password.c_str(),
|
| - &done,
|
| - errptr);
|
| - if(!done) {
|
| - // TODO(fes): Remove when Mount no longer automatically deletes cryptohome
|
| - // on passkey failure.
|
| - if(!AskHardQuestion(user)) {
|
| - return 1;
|
| - }
|
| - }
|
| -
|
| - errptr = &chromeos::Resetter(&error).lvalue();
|
| if (!org_chromium_CryptohomeInterface_mount(proxy.gproxy(),
|
| user.c_str(),
|
| password.c_str(),
|
| + &mount_error,
|
| &done,
|
| errptr)) {
|
| - LOG(ERROR) << "Mount call failed: " << error->message;
|
| + LOG(ERROR) << "Mount call failed: " << error->message
|
| + << ", with reason code: " << mount_error;
|
| }
|
| LOG_IF(ERROR, !done) << "Mount did not complete?";
|
| LOG_IF(INFO, done) << "Call completed";
|
| + } else if (!strcmp(switches::kActions[switches::ACTION_MOUNT_GUEST],
|
| + action.c_str())) {
|
| + gboolean done = false;
|
| + gint mount_error = 0;
|
| + chromeos::glib::ScopedError error;
|
| + GError **errptr = &chromeos::Resetter(&error).lvalue();
|
| + if (!org_chromium_CryptohomeInterface_mount_guest(proxy.gproxy(),
|
| + &mount_error,
|
| + &done,
|
| + errptr)) {
|
| + LOG(ERROR) << "MountGuest call failed: " << error->message
|
| + << ", with reason code: " << mount_error;
|
| + }
|
| + LOG_IF(ERROR, !done) << "MountGuest did not complete?";
|
| + LOG_IF(INFO, done) << "Call completed";
|
| } else if (!strcmp(switches::kActions[switches::ACTION_TEST_AUTH],
|
| action.c_str())) {
|
| std::string user, password;
|
|
|
| - if(!GetUsernamePassword(proxy, cl, &user, &password)) {
|
| + if (!GetUsername(cl, &user)) {
|
| + LOG(ERROR) << "No username specified";
|
| return 1;
|
| }
|
|
|
| + GetPassword(proxy, cl, switches::kPasswordSwitch,
|
| + StringPrintf("Enter the password for <%s>", user.c_str()),
|
| + &password);
|
| +
|
| gboolean done = false;
|
| chromeos::glib::ScopedError error;
|
| GError **errptr = &chromeos::Resetter(&error).lvalue();
|
| @@ -260,10 +222,18 @@ int main(int argc, char **argv) {
|
| action.c_str())) {
|
| std::string user, password, old_password;
|
|
|
| - if(!GetUsernamePassword(proxy, cl, &user, &password, &old_password)) {
|
| + if (!GetUsername(cl, &user)) {
|
| + LOG(ERROR) << "No username specified";
|
| return 1;
|
| }
|
|
|
| + GetPassword(proxy, cl, switches::kPasswordSwitch,
|
| + StringPrintf("Enter the password for <%s>", user.c_str()),
|
| + &password);
|
| + GetPassword(proxy, cl, switches::kOldPasswordSwitch,
|
| + StringPrintf("Enter the old password for <%s>", user.c_str()),
|
| + &old_password);
|
| +
|
| gboolean done = false;
|
| chromeos::glib::ScopedError error;
|
| GError **errptr = &chromeos::Resetter(&error).lvalue();
|
| @@ -324,6 +294,16 @@ int main(int argc, char **argv) {
|
| }
|
| std::cout << done << std::endl;
|
|
|
| + } else if (!strcmp(switches::kActions[switches::ACTION_OBFUSCATE_USER],
|
| + action.c_str())) {
|
| + std::string user;
|
| +
|
| + if(!GetUsername(cl, &user)) {
|
| + return 1;
|
| + }
|
| +
|
| + cryptohome::UsernamePasskey up(user.c_str(), cryptohome::SecureBlob());
|
| + LOG(INFO) << up.GetObfuscatedUsername(GetSystemSalt(proxy));
|
| } else {
|
| LOG(ERROR) << "Unknown action or no action given. Available actions: ";
|
| for(int i = 0; /* loop forever */; i++) {
|
|
|