// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Cryptohome client that uses the dbus client interface

#include <inttypes.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/sha.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>

#include <memory>
#include <string>
#include <vector>

#include <attestation/proto_bindings/interface.pb.h>
#include <base/command_line.h>
#include <base/files/file_path.h>
#include <base/logging.h>
#include <base/stl_util.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_split.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <brillo/cryptohome.h>
#include <brillo/glib/dbus.h>
#include <brillo/secure_blob.h>
#include <brillo/syslog_logging.h>
#include <chromeos/constants/cryptohome.h>
#include <chromeos/dbus/service_constants.h>
#include <google/protobuf/message_lite.h>

#include "cryptohome/attestation.pb.h"
#include "cryptohome/crypto.h"
#include "cryptohome/cryptolib.h"
#include "cryptohome/filesystem_layout.h"
#include "cryptohome/key.pb.h"
#include "cryptohome/pkcs11_init.h"
#include "cryptohome/platform.h"
#include "cryptohome/rpc.pb.h"
#include "cryptohome/signed_secret.pb.h"
#include "cryptohome/storage/homedirs.h"
#include "cryptohome/vault_keyset.pb.h"

#include "bindings/cryptohome.dbusclient.h"

using base::FilePath;
using base::StringPrintf;
using brillo::SecureBlob;
using brillo::cryptohome::home::SanitizeUserNameWithSalt;

namespace {
// Number of days that the set_current_user_old action uses when updating the
// home directory timestamp.  ~3 months should be old enough for test purposes.
const int kSetCurrentUserOldOffsetInDays = 92;

// Five minutes is enough to wait for any TPM operations, sync() calls, etc.
const int kDefaultTimeoutMs = 300000;

// We've 100 seconds to wait for TakeOwnership(), should be rather generous.
constexpr int kWaitOwnershipTimeoutInSeconds = 100;

// Poll once every 0.2s.
constexpr int kWaitOwnershipPollIntervalInMs = 200;

}  // namespace

namespace switches {
static const char kSyslogSwitch[] = "syslog";
static const char kAttestationServerSwitch[] = "attestation-server";
static struct {
  const char* name;
  const int aca_type;
} kAttestationServers[] = {{"default", attestation::DEFAULT_ACA},
                           {"test", attestation::TEST_ACA},
                           {nullptr, attestation::ACAType_ARRAYSIZE}};
static const char kVaServerSwitch[] = "va-server";
static struct {
  const char* name;
  const int va_type;
} kVaServers[] = {{"default", attestation::DEFAULT_VA},
                  {"test", attestation::TEST_VA},
                  {nullptr, attestation::VAType_ARRAYSIZE}};
static const char kWaitOwnershipTimeoutSwitch[] = "wait-ownership-timeout";
static const char kActionSwitch[] = "action";
static const char* kActions[] = {"mount_ex",
                                 "mount_guest_ex",
                                 "unmount",
                                 "is_mounted",
                                 "check_key_ex",
                                 "remove_key_ex",
                                 "get_key_data_ex",
                                 "list_keys_ex",
                                 "migrate_key_ex",
                                 "add_key_ex",
                                 "add_data_restore_key",
                                 "mass_remove_keys",
                                 "update_key_ex",
                                 "remove",
                                 "obfuscate_user",
                                 "get_system_salt",
                                 "dump_keyset",
                                 "dump_last_activity",
                                 "tpm_status",
                                 "tpm_more_status",
                                 "status",
                                 "set_current_user_old",
                                 "tpm_take_ownership",
                                 "tpm_clear_stored_password",
                                 "tpm_wait_ownership",
                                 "install_attributes_set",
                                 "install_attributes_get",
                                 "install_attributes_finalize",
                                 "install_attributes_count",
                                 "install_attributes_is_ready",
                                 "install_attributes_is_secure",
                                 "install_attributes_is_invalid",
                                 "install_attributes_is_first_install",
                                 "pkcs11_get_user_token_info",
                                 "pkcs11_get_system_token_info",
                                 "pkcs11_is_user_token_ok",
                                 "pkcs11_terminate",
                                 "tpm_verify_attestation",
                                 "tpm_verify_ek",
                                 "tpm_attestation_status",
                                 "tpm_attestation_more_status",
                                 "tpm_attestation_start_enroll",
                                 "tpm_attestation_finish_enroll",
                                 "tpm_attestation_enroll",
                                 "tpm_attestation_start_cert_request",
                                 "tpm_attestation_finish_cert_request",
                                 "tpm_attestation_get_certificate",
                                 "tpm_attestation_key_status",
                                 "tpm_attestation_register_key",
                                 "tpm_attestation_enterprise_challenge",
                                 "tpm_attestation_simple_challenge",
                                 "tpm_attestation_get_key_payload",
                                 "tpm_attestation_set_key_payload",
                                 "tpm_attestation_delete_keys",
                                 "tpm_attestation_delete_key",
                                 "tpm_attestation_get_ek",
                                 "tpm_attestation_reset_identity",
                                 "tpm_attestation_reset_identity_result",
                                 "sign_lockbox",
                                 "verify_lockbox",
                                 "finalize_lockbox",
                                 "get_boot_attribute",
                                 "set_boot_attribute",
                                 "flush_and_sign_boot_attributes",
                                 "get_login_status",
                                 "initialize_cast_key",
                                 "get_firmware_management_parameters",
                                 "set_firmware_management_parameters",
                                 "remove_firmware_management_parameters",
                                 "migrate_to_dircrypto",
                                 "needs_dircrypto_migration",
                                 "get_enrollment_id",
                                 "get_supported_key_policies",
                                 "get_account_disk_usage",
                                 "lock_to_single_user_mount_until_reboot",
                                 "get_rsu_device_id",
                                 "check_health",
                                 "start_fingerprint_auth_session",
                                 "end_fingerprint_auth_session",
                                 "start_auth_session",
                                 NULL};
enum ActionEnum {
  ACTION_MOUNT_EX,
  ACTION_MOUNT_GUEST_EX,
  ACTION_UNMOUNT,
  ACTION_MOUNTED,
  ACTION_CHECK_KEY_EX,
  ACTION_REMOVE_KEY_EX,
  ACTION_GET_KEY_DATA_EX,
  ACTION_LIST_KEYS_EX,
  ACTION_MIGRATE_KEY_EX,
  ACTION_ADD_KEY_EX,
  ACTION_ADD_DATA_RESTORE_KEY,
  ACTION_MASS_REMOVE_KEYS,
  ACTION_UPDATE_KEY_EX,
  ACTION_REMOVE,
  ACTION_OBFUSCATE_USER,
  ACTION_GET_SYSTEM_SALT,
  ACTION_DUMP_KEYSET,
  ACTION_DUMP_LAST_ACTIVITY,
  ACTION_TPM_STATUS,
  ACTION_TPM_MORE_STATUS,
  ACTION_STATUS,
  ACTION_SET_CURRENT_USER_OLD,
  ACTION_TPM_TAKE_OWNERSHIP,
  ACTION_TPM_CLEAR_STORED_PASSWORD,
  ACTION_TPM_WAIT_OWNERSHIP,
  ACTION_INSTALL_ATTRIBUTES_SET,
  ACTION_INSTALL_ATTRIBUTES_GET,
  ACTION_INSTALL_ATTRIBUTES_FINALIZE,
  ACTION_INSTALL_ATTRIBUTES_COUNT,
  ACTION_INSTALL_ATTRIBUTES_IS_READY,
  ACTION_INSTALL_ATTRIBUTES_IS_SECURE,
  ACTION_INSTALL_ATTRIBUTES_IS_INVALID,
  ACTION_INSTALL_ATTRIBUTES_IS_FIRST_INSTALL,
  ACTION_PKCS11_GET_USER_TOKEN_INFO,
  ACTION_PKCS11_GET_SYSTEM_TOKEN_INFO,
  ACTION_PKCS11_IS_USER_TOKEN_OK,
  ACTION_PKCS11_TERMINATE,
  ACTION_TPM_VERIFY_ATTESTATION,
  ACTION_TPM_VERIFY_EK,
  ACTION_TPM_ATTESTATION_STATUS,
  ACTION_TPM_ATTESTATION_MORE_STATUS,
  ACTION_TPM_ATTESTATION_START_ENROLL,
  ACTION_TPM_ATTESTATION_FINISH_ENROLL,
  ACTION_TPM_ATTESTATION_ENROLL,
  ACTION_TPM_ATTESTATION_START_CERTREQ,
  ACTION_TPM_ATTESTATION_FINISH_CERTREQ,
  ACTION_TPM_ATTESTATION_GET_CERTIFICATE,
  ACTION_TPM_ATTESTATION_KEY_STATUS,
  ACTION_TPM_ATTESTATION_REGISTER_KEY,
  ACTION_TPM_ATTESTATION_ENTERPRISE_CHALLENGE,
  ACTION_TPM_ATTESTATION_SIMPLE_CHALLENGE,
  ACTION_TPM_ATTESTATION_GET_KEY_PAYLOAD,
  ACTION_TPM_ATTESTATION_SET_KEY_PAYLOAD,
  ACTION_TPM_ATTESTATION_DELETE_KEYS,
  ACTION_TPM_ATTESTATION_DELETE_KEY,
  ACTION_TPM_ATTESTATION_GET_EK,
  ACTION_TPM_ATTESTATION_RESET_IDENTITY,
  ACTION_TPM_ATTESTATION_RESET_IDENTITY_RESULT,
  ACTION_SIGN_LOCKBOX,
  ACTION_VERIFY_LOCKBOX,
  ACTION_FINALIZE_LOCKBOX,
  ACTION_GET_BOOT_ATTRIBUTE,
  ACTION_SET_BOOT_ATTRIBUTE,
  ACTION_FLUSH_AND_SIGN_BOOT_ATTRIBUTES,
  ACTION_GET_LOGIN_STATUS,
  ACTION_INITIALIZE_CAST_KEY,
  ACTION_GET_FIRMWARE_MANAGEMENT_PARAMETERS,
  ACTION_SET_FIRMWARE_MANAGEMENT_PARAMETERS,
  ACTION_REMOVE_FIRMWARE_MANAGEMENT_PARAMETERS,
  ACTION_MIGRATE_TO_DIRCRYPTO,
  ACTION_NEEDS_DIRCRYPTO_MIGRATION,
  ACTION_GET_ENROLLMENT_ID,
  ACTION_GET_SUPPORTED_KEY_POLICIES,
  ACTION_GET_ACCOUNT_DISK_USAGE,
  ACTION_LOCK_TO_SINGLE_USER_MOUNT_UNTIL_REBOOT,
  ACTION_GET_RSU_DEVICE_ID,
  ACTION_CHECK_HEALTH,
  ACTION_START_FINGERPRINT_AUTH_SESSION,
  ACTION_END_FINGERPRINT_AUTH_SESSION,
  ACTION_START_AUTH_SESSION,
};
static const char kUserSwitch[] = "user";
static const char kPasswordSwitch[] = "password";
static const char kFingerprintSwitch[] = "fingerprint";
static const char kKeyLabelSwitch[] = "key_label";
static const char kNewKeyLabelSwitch[] = "new_key_label";
static const char kRemoveKeyLabelSwitch[] = "remove_key_label";
static const char kOldPasswordSwitch[] = "old_password";
static const char kNewPasswordSwitch[] = "new_password";
static const char kForceSwitch[] = "force";
static const char kAsyncSwitch[] = "async";
static const char kCreateSwitch[] = "create";
static const char kAttrNameSwitch[] = "name";
static const char kAttrPrefixSwitch[] = "prefix";
static const char kAttrValueSwitch[] = "value";
static const char kFileSwitch[] = "file";
static const char kInputFileSwitch[] = "input";
static const char kOutputFileSwitch[] = "output";
static const char kEnsureEphemeralSwitch[] = "ensure_ephemeral";
static const char kCrosCoreSwitch[] = "cros_core";
static const char kProtobufSwitch[] = "protobuf";
static const char kFlagsSwitch[] = "flags";
static const char kDevKeyHashSwitch[] = "developer_key_hash";
static const char kEcryptfsSwitch[] = "ecryptfs";
static const char kToMigrateFromEcryptfsSwitch[] = "to_migrate_from_ecryptfs";
static const char kHiddenMount[] = "hidden_mount";
static const char kMinimalMigration[] = "minimal_migration";
static const char kPublicMount[] = "public_mount";
static const char kKeyPolicySwitch[] = "key_policy";
static const char kKeyPolicyLECredential[] = "le";
static const char kProfileSwitch[] = "profile";
static const char kIgnoreCache[] = "ignore_cache";
static const char kRestoreKeyInHexSwitch[] = "restore_key_in_hex";
static const char kMassRemoveExemptLabelsSwitch[] = "exempt_key_labels";
static const char kEnrollSwitch[] = "enroll";
static const char kUseDBus[] = "use_dbus";
}  // namespace switches

#define DBUS_METHOD(method_name) org_chromium_CryptohomeInterface_##method_name

typedef void (*ProtoDBusReplyMethod)(DBusGProxy*, GArray*, GError*, gpointer);
typedef gboolean (*ProtoDBusMethod)(DBusGProxy*,
                                    const GArray*,
                                    GArray**,
                                    GError**);
typedef DBusGProxyCall* (*ProtoDBusAsyncMethod)(DBusGProxy*,
                                                const GArray*,
                                                ProtoDBusReplyMethod,
                                                gpointer);

brillo::SecureBlob GetSystemSalt(const brillo::dbus::Proxy& proxy) {
  brillo::glib::ScopedError error;
  brillo::glib::ScopedArray salt;
  if (!org_chromium_CryptohomeInterface_get_system_salt(
          proxy.gproxy(), &brillo::Resetter(&salt).lvalue(),
          &brillo::Resetter(&error).lvalue())) {
    LOG(ERROR) << "GetSystemSalt failed: " << error->message;
    return brillo::SecureBlob();
  }

  brillo::SecureBlob system_salt;
  system_salt.resize(salt->len);
  if (system_salt.size() == salt->len) {
    memcpy(system_salt.data(), static_cast<const void*>(salt->data), salt->len);
  } else {
    system_salt.clear();
  }
  return system_salt;
}

bool GetAttrName(const base::CommandLine* cl, std::string* name_out) {
  *name_out = cl->GetSwitchValueASCII(switches::kAttrNameSwitch);

  if (name_out->length() == 0) {
    printf("No install attribute name specified (--name=<name>)\n");
    return false;
  }
  return true;
}

bool GetAttrValue(const base::CommandLine* cl, std::string* value_out) {
  *value_out = cl->GetSwitchValueASCII(switches::kAttrValueSwitch);

  if (value_out->length() == 0) {
    printf("No install attribute value specified (--value=<value>)\n");
    return false;
  }
  return true;
}

bool GetAccountId(const base::CommandLine* cl, std::string* user_out) {
  *user_out = cl->GetSwitchValueASCII(switches::kUserSwitch);

  if (user_out->length() == 0) {
    printf("No user specified (--user=<account_id>)\n");
    return false;
  }
  return true;
}

bool GetPassword(const brillo::dbus::Proxy& proxy,
                 const base::CommandLine* cl,
                 const std::string& cl_switch,
                 const std::string& prompt,
                 std::string* password_out) {
  std::string password = cl->GetSwitchValueASCII(cl_switch);

  if (password.length() == 0) {
    char buffer[256];
    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);
    printf("%s: ", prompt.c_str());
    fflush(stdout);
    if (fgets(buffer, base::size(buffer), stdin))
      password = buffer;
    printf("\n");
    tcsetattr(0, TCSANOW, &original_attr);
  }

  std::string trimmed_password;
  base::TrimString(password, "\r\n", &trimmed_password);
  SecureBlob passkey;
  cryptohome::Crypto::PasswordToPasskey(trimmed_password.c_str(),
                                        GetSystemSalt(proxy), &passkey);
  *password_out = passkey.to_string();

  return true;
}

bool IsMixingOldAndNewFileSwitches(const base::CommandLine* cl) {
  return cl->HasSwitch(switches::kFileSwitch) &&
         (cl->HasSwitch(switches::kInputFileSwitch) ||
          cl->HasSwitch(switches::kOutputFileSwitch));
}

FilePath GetFile(const base::CommandLine* cl) {
  const char kDefaultFilePath[] = "/tmp/__cryptohome";
  FilePath file_path(cl->GetSwitchValueASCII(switches::kFileSwitch));
  if (file_path.empty()) {
    return FilePath(kDefaultFilePath);
  }
  return file_path;
}

FilePath GetInputFile(const base::CommandLine* cl) {
  FilePath file_path(cl->GetSwitchValueASCII(switches::kInputFileSwitch));
  if (file_path.empty()) {
    return GetFile(cl);
  }
  return file_path;
}

FilePath GetOutputFile(const base::CommandLine* cl) {
  FilePath file_path(cl->GetSwitchValueASCII(switches::kOutputFileSwitch));
  if (file_path.empty()) {
    return GetFile(cl);
  }
  return file_path;
}

bool GetProfile(const base::CommandLine* cl,
                cryptohome::CertificateProfile* profile) {
  const std::string profile_str =
      cl->GetSwitchValueASCII(switches::kProfileSwitch);
  if (profile_str.empty() || profile_str == "enterprise_user" ||
      profile_str == "user" || profile_str == "u") {
    *profile = cryptohome::ENTERPRISE_USER_CERTIFICATE;
  } else if (profile_str == "enterprise_machine" || profile_str == "machine" ||
             profile_str == "m") {
    *profile = cryptohome::ENTERPRISE_MACHINE_CERTIFICATE;
  } else if (profile_str == "enterprise_enrollment" ||
             profile_str == "enrollment" || profile_str == "e") {
    *profile = cryptohome::ENTERPRISE_ENROLLMENT_CERTIFICATE;
  } else if (profile_str == "content_protection" || profile_str == "content" ||
             profile_str == "c") {
    *profile = cryptohome::CONTENT_PROTECTION_CERTIFICATE;
  } else if (profile_str == "content_protection_with_stable_id" ||
             profile_str == "cpsi") {
    *profile = cryptohome::CONTENT_PROTECTION_CERTIFICATE_WITH_STABLE_ID;
  } else if (profile_str == "cast") {
    *profile = cryptohome::CAST_CERTIFICATE;
  } else if (profile_str == "gfsc") {
    *profile = cryptohome::GFSC_CERTIFICATE;
  } else if (profile_str == "jetstream") {
    *profile = cryptohome::JETSTREAM_CERTIFICATE;
  } else {
    printf("Unknown certificate profile: %s.\n", profile_str.c_str());
    return false;
  }
  return true;
}

bool ConfirmRemove(const std::string& user) {
  printf("!!! Are you sure you want to remove the user's cryptohome?\n");
  printf("!!!\n");
  printf("!!! Re-enter the username at the prompt to remove the\n");
  printf("!!! cryptohome for the user.\n");
  printf("Enter the username <%s>: ", user.c_str());
  fflush(stdout);

  char buffer[256];
  if (!fgets(buffer, base::size(buffer), stdin)) {
    printf("Error while reading username.\n");
    return false;
  }
  std::string verification = buffer;
  // fgets will append the newline character, remove it.
  base::TrimWhitespaceASCII(verification, base::TRIM_ALL, &verification);
  if (user != verification) {
    printf("Usernames do not match.\n");
    return false;
  }
  return true;
}

GArray* GArrayFromProtoBuf(const google::protobuf::MessageLite& pb) {
  size_t len_raw = pb.ByteSizeLong();
  if (len_raw > G_MAXUINT) {
    printf("Protocol buffer too large.\n");
    return NULL;
  }

  guint len = len_raw;
  GArray* ary = g_array_sized_new(FALSE, FALSE, 1, len);
  g_array_set_size(ary, len);
  if (!pb.SerializeToArray(ary->data, len)) {
    printf("Failed to serialize protocol buffer.\n");
    return NULL;
  }
  return ary;
}

bool BuildAccountId(base::CommandLine* cl, cryptohome::AccountIdentifier* id) {
  std::string account_id;
  if (!GetAccountId(cl, &account_id)) {
    printf("No account_id specified.\n");
    return false;
  }
  id->set_account_id(account_id);
  return true;
}

bool BuildAuthorization(base::CommandLine* cl,
                        const brillo::dbus::Proxy& proxy,
                        bool need_password,
                        cryptohome::AuthorizationRequest* auth) {
  if (need_password) {
    // Check if restore key is provided
    if (cl->HasSwitch(switches::kRestoreKeyInHexSwitch)) {
      brillo::SecureBlob raw_byte(
          cl->GetSwitchValueASCII(switches::kRestoreKeyInHexSwitch));
      if (raw_byte.to_string().length() == 0) {
        printf("No hex string specified\n");
        return false;
      }
      SecureBlob::HexStringToSecureBlob(raw_byte.to_string(), &raw_byte);
      auth->mutable_key()->set_secret(raw_byte.to_string());
    } else {
      std::string password;
      GetPassword(proxy, cl, switches::kPasswordSwitch, "Enter the password",
                  &password);

      auth->mutable_key()->set_secret(password);
    }
  }

  if (cl->HasSwitch(switches::kKeyLabelSwitch)) {
    auth->mutable_key()->mutable_data()->set_label(
        cl->GetSwitchValueASCII(switches::kKeyLabelSwitch));
  }

  return true;
}

void ParseBaseReply(GArray* reply_ary,
                    cryptohome::BaseReply* reply,
                    bool print_reply) {
  if (!reply)
    return;
  if (!reply->ParseFromArray(reply_ary->data, reply_ary->len)) {
    printf("Failed to parse reply.\n");
    exit(1);
  }
  if (print_reply)
    reply->PrintDebugString();
}

class ClientLoop {
 public:
  ClientLoop()
      : loop_(NULL),
        async_call_id_(0),
        return_status_(false),
        return_code_(0) {}

  virtual ~ClientLoop() {
    if (loop_) {
      g_main_loop_unref(loop_);
    }
  }

  void Initialize(brillo::dbus::Proxy* proxy) {
    dbus_g_object_register_marshaller(g_cclosure_marshal_generic, G_TYPE_NONE,
                                      G_TYPE_INT, G_TYPE_BOOLEAN, G_TYPE_INT,
                                      G_TYPE_INVALID);
    dbus_g_proxy_add_signal(proxy->gproxy(), "AsyncCallStatus", G_TYPE_INT,
                            G_TYPE_BOOLEAN, G_TYPE_INT, G_TYPE_INVALID);
    dbus_g_proxy_connect_signal(proxy->gproxy(), "AsyncCallStatus",
                                G_CALLBACK(ClientLoop::CallbackThunk), this,
                                NULL);
    dbus_g_object_register_marshaller(g_cclosure_marshal_generic, G_TYPE_NONE,
                                      G_TYPE_INT, G_TYPE_BOOLEAN,
                                      DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_INVALID);
    dbus_g_proxy_add_signal(proxy->gproxy(), "AsyncCallStatusWithData",
                            G_TYPE_INT, G_TYPE_BOOLEAN, DBUS_TYPE_G_UCHAR_ARRAY,
                            G_TYPE_INVALID);
    dbus_g_proxy_connect_signal(proxy->gproxy(), "AsyncCallStatusWithData",
                                G_CALLBACK(ClientLoop::CallbackDataThunk), this,
                                NULL);
    loop_ = g_main_loop_new(NULL, TRUE);
  }

  void Run(int async_call_id) {
    async_call_id_ = async_call_id;
    g_main_loop_run(loop_);
  }

  void Run() { Run(0); }

  // This callback can be used with a ClientLoop instance as the |userdata| to
  // handle an asynchronous reply which emits a serialized BaseReply.
  static void ParseReplyThunk(DBusGProxy* proxy,
                              GArray* data,
                              GError* error,
                              gpointer userdata) {
    reinterpret_cast<ClientLoop*>(userdata)->ParseReply(data, error);
  }

  bool get_return_status() { return return_status_; }

  int get_return_code() { return return_code_; }

  std::string get_return_data() { return return_data_; }

  cryptohome::BaseReply reply() { return reply_; }

 private:
  void Callback(int async_call_id, bool return_status, int return_code) {
    if (async_call_id == async_call_id_) {
      return_status_ = return_status;
      return_code_ = return_code;
      g_main_loop_quit(loop_);
    }
  }

  void CallbackWithData(int async_call_id, bool return_status, GArray* data) {
    if (async_call_id == async_call_id_) {
      return_status_ = return_status;
      return_data_ = std::string(static_cast<char*>(data->data), data->len);
      g_main_loop_quit(loop_);
    }
  }

  void ParseReply(GArray* reply_ary, GError* error) {
    if (error && error->message) {
      printf("Call error: %s\n", error->message);
      exit(1);
    }
    ParseBaseReply(reply_ary, &reply_, true /* print_reply */);
    g_main_loop_quit(loop_);
  }

  static void CallbackThunk(DBusGProxy* proxy,
                            int async_call_id,
                            bool return_status,
                            int return_code,
                            gpointer userdata) {
    reinterpret_cast<ClientLoop*>(userdata)->Callback(
        async_call_id, return_status, return_code);
  }

  static void CallbackDataThunk(DBusGProxy* proxy,
                                int async_call_id,
                                bool return_status,
                                GArray* data,
                                gpointer userdata) {
    reinterpret_cast<ClientLoop*>(userdata)->CallbackWithData(
        async_call_id, return_status, data);
  }

  GMainLoop* loop_;
  int async_call_id_;
  bool return_status_;
  int return_code_;
  std::string return_data_;
  cryptohome::BaseReply reply_;
};

bool MakeProtoDBusCall(const std::string& name,
                       ProtoDBusMethod method,
                       ProtoDBusAsyncMethod async_method,
                       base::CommandLine* cl,
                       brillo::dbus::Proxy* proxy,
                       const google::protobuf::MessageLite& request,
                       cryptohome::BaseReply* reply,
                       bool print_reply) {
  brillo::glib::ScopedArray request_ary(GArrayFromProtoBuf(request));
  if (cl->HasSwitch(switches::kAsyncSwitch)) {
    ClientLoop loop;
    loop.Initialize(proxy);
    DBusGProxyCall* call = (*async_method)(proxy->gproxy(), request_ary.get(),
                                           &ClientLoop::ParseReplyThunk,
                                           static_cast<gpointer>(&loop));
    if (!call) {
      printf("Failed to call %s!\n", name.c_str());
      return false;
    }
    loop.Run();
    *reply = loop.reply();
  } else {
    brillo::glib::ScopedError error;
    brillo::glib::ScopedArray reply_ary;
    if (!(*method)(proxy->gproxy(), request_ary.get(),
                   &brillo::Resetter(&reply_ary).lvalue(),
                   &brillo::Resetter(&error).lvalue())) {
      printf("Failed to call %s: %s\n", name.c_str(), error->message);
      return false;
    }
    ParseBaseReply(reply_ary.get(), reply, print_reply);
  }
  if (reply->has_error()) {
    printf("%s error: %d\n", name.c_str(), reply->error());
    return false;
  }

  return true;
}

std::string GetPCAName(int pca_type) {
  switch (pca_type) {
    case attestation::DEFAULT_ACA:
      return "the default ACA";
    case attestation::TEST_ACA:
      return "the test ACA";
    default: {
      std::ostringstream stream;
      stream << "ACA " << pca_type;
      return stream.str();
    }
  }
}

int main(int argc, char** argv) {
  base::CommandLine::Init(argc, argv);
  base::CommandLine* cl = base::CommandLine::ForCurrentProcess();
  if (cl->HasSwitch(switches::kSyslogSwitch))
    brillo::InitLog(brillo::kLogToSyslog | brillo::kLogToStderr);
  else
    brillo::InitLog(brillo::kLogToStderr);

  int pca_type = attestation::ACAType_ARRAYSIZE;
  if (cl->HasSwitch(switches::kAttestationServerSwitch)) {
    std::string server =
        cl->GetSwitchValueASCII(switches::kAttestationServerSwitch);
    for (int i = 0; switches::kAttestationServers[i].name; ++i) {
      if (server == switches::kAttestationServers[i].name) {
        pca_type = switches::kAttestationServers[i].aca_type;
        break;
      }
    }
    if (pca_type == attestation::ACAType_ARRAYSIZE) {
      printf("Invalid attestation server: %s\n", server.c_str());
      return 1;
    }
  } else {
    pca_type = attestation::DEFAULT_ACA;
  }

  int va_type = attestation::VAType_ARRAYSIZE;
  std::string va_server(
      cl->HasSwitch(switches::kVaServerSwitch)
          ? cl->GetSwitchValueASCII(switches::kVaServerSwitch)
          : cl->GetSwitchValueASCII(switches::kAttestationServerSwitch));
  if (va_server.size()) {
    for (int i = 0; switches::kVaServers[i].name; ++i) {
      if (va_server == switches::kVaServers[i].name) {
        va_type = switches::kVaServers[i].va_type;
        break;
      }
    }
    if (va_type == attestation::VAType_ARRAYSIZE) {
      printf("Invalid Verified Access server: %s\n", va_server.c_str());
      return 1;
    }
  } else {
    va_type = attestation::DEFAULT_VA;
  }

  if (IsMixingOldAndNewFileSwitches(cl)) {
    printf("Use either --%s and --%s together, or --%s only.\n",
           switches::kInputFileSwitch, switches::kOutputFileSwitch,
           switches::kFileSwitch);
    return 1;
  }

  std::string action = cl->GetSwitchValueASCII(switches::kActionSwitch);
  brillo::dbus::BusConnection bus = brillo::dbus::GetSystemBusConnection();
  brillo::dbus::Proxy proxy(bus, cryptohome::kCryptohomeServiceName,
                            cryptohome::kCryptohomeServicePath,
                            cryptohome::kCryptohomeInterface);
  DCHECK(proxy.gproxy()) << "Failed to acquire proxy";
  dbus_g_proxy_set_default_timeout(proxy.gproxy(), kDefaultTimeoutMs);

  cryptohome::Platform platform;

  if (!strcmp(switches::kActions[switches::ACTION_MOUNT_EX], action.c_str())) {
    bool is_public_mount = cl->HasSwitch(switches::kPublicMount);

    cryptohome::AccountIdentifier id;
    if (!BuildAccountId(cl, &id))
      return 1;
    cryptohome::AuthorizationRequest auth;
    if (!BuildAuthorization(cl, proxy, !is_public_mount, &auth))
      return 1;

    cryptohome::MountRequest mount_req;
    mount_req.set_require_ephemeral(
        cl->HasSwitch(switches::kEnsureEphemeralSwitch));
    mount_req.set_to_migrate_from_ecryptfs(
        cl->HasSwitch(switches::kToMigrateFromEcryptfsSwitch));
    mount_req.set_hidden_mount(cl->HasSwitch(switches::kHiddenMount));
    mount_req.set_public_mount(is_public_mount);
    if (cl->HasSwitch(switches::kCreateSwitch)) {
      cryptohome::CreateRequest* create = mount_req.mutable_create();
      if (cl->HasSwitch(switches::kPublicMount)) {
        cryptohome::Key* key = create->add_keys();
        key->mutable_data()->set_label(auth.key().data().label());
      } else {
        create->set_copy_authorization_key(true);
      }
      if (cl->HasSwitch(switches::kEcryptfsSwitch)) {
        create->set_force_ecryptfs(true);
      }
    }

    brillo::glib::ScopedArray account_ary(GArrayFromProtoBuf(id));
    brillo::glib::ScopedArray auth_ary(GArrayFromProtoBuf(auth));
    brillo::glib::ScopedArray req_ary(GArrayFromProtoBuf(mount_req));
    if (!account_ary.get() || !auth_ary.get() || !req_ary.get())
      return 1;

    cryptohome::BaseReply reply;
    brillo::glib::ScopedError error;
    if (cl->HasSwitch(switches::kAsyncSwitch)) {
      ClientLoop loop;
      loop.Initialize(&proxy);
      DBusGProxyCall* call = org_chromium_CryptohomeInterface_mount_ex_async(
          proxy.gproxy(), account_ary.get(), auth_ary.get(), req_ary.get(),
          &ClientLoop::ParseReplyThunk, static_cast<gpointer>(&loop));
      if (!call)
        return 1;
      loop.Run();
      reply = loop.reply();
    } else {
      GArray* out_reply = NULL;
      if (!org_chromium_CryptohomeInterface_mount_ex(
              proxy.gproxy(), account_ary.get(), auth_ary.get(), req_ary.get(),
              &out_reply, &brillo::Resetter(&error).lvalue())) {
        printf("MountEx call failed: %s", error->message);
        return 1;
      }
      ParseBaseReply(out_reply, &reply, true /* print_reply */);
    }
    if (reply.has_error()) {
      printf("Mount failed.\n");
      return reply.error();
    }
    printf("Mount succeeded.\n");
  } else if (!strcmp(switches::kActions[switches::ACTION_MOUNT_GUEST_EX],
                     action.c_str())) {
    cryptohome::BaseReply reply;
    cryptohome::MountGuestRequest request;
    brillo::glib::ScopedError error;
    GArray* out_reply = NULL;

    brillo::glib::ScopedArray guest_request_ary(GArrayFromProtoBuf(request));
    if (!org_chromium_CryptohomeInterface_mount_guest_ex(
            proxy.gproxy(), guest_request_ary.get(), &out_reply,
            &brillo::Resetter(&error).lvalue())) {
      printf("Mount call failed: %s.\n", error->message);
      return 1;
    }

    ParseBaseReply(out_reply, &reply, true /* print_reply */);
    if (reply.has_error()) {
      printf("Mount failed.\n");
      return reply.error();
    }
    printf("Mount succeeded.\n");
  } else if (!strcmp(switches::kActions
                         [switches::ACTION_START_FINGERPRINT_AUTH_SESSION],
                     action.c_str())) {
    cryptohome::AccountIdentifier id;
    if (!BuildAccountId(cl, &id))
      return 1;

    cryptohome::StartFingerprintAuthSessionRequest req;

    brillo::glib::ScopedArray account_ary(GArrayFromProtoBuf(id));
    brillo::glib::ScopedArray req_ary(GArrayFromProtoBuf(req));
    if (!account_ary.get() || !req_ary.get())
      return 1;

    cryptohome::BaseReply reply;
    brillo::glib::ScopedError error;

    GArray* out_reply = NULL;
    if (!org_chromium_CryptohomeInterface_start_fingerprint_auth_session(
            proxy.gproxy(), account_ary.get(), req_ary.get(), &out_reply,
            &brillo::Resetter(&error).lvalue())) {
      printf("StartFingerprintAuthSession call failed: %s", error->message);
      return 1;
    }
    ParseBaseReply(out_reply, &reply, true /* print_reply */);
    if (reply.has_error()) {
      printf("Fingerprint auth session failed to start.\n");
      return reply.error();
    }
  } else if (!strcmp(switches::kActions
                         [switches::ACTION_END_FINGERPRINT_AUTH_SESSION],
                     action.c_str())) {
    cryptohome::EndFingerprintAuthSessionRequest req;
    brillo::glib::ScopedArray req_ary(GArrayFromProtoBuf(req));
    if (!req_ary.get())
      return 1;

    brillo::glib::ScopedError error;
    GArray* out_reply = NULL;
    if (!org_chromium_CryptohomeInterface_end_fingerprint_auth_session(
            proxy.gproxy(), req_ary.get(), &out_reply,
            &brillo::Resetter(&error).lvalue())) {
      printf("EndFingerprintAuthSession call failed: %s", error->message);
      return 1;
    }
    // EndFingerprintAuthSession always succeeds.
  } else if (!strcmp(switches::kActions[switches::ACTION_REMOVE_KEY_EX],
                     action.c_str())) {
    cryptohome::AccountIdentifier id;
    if (!BuildAccountId(cl, &id))
      return 1;
    cryptohome::AuthorizationRequest auth;
    if (!BuildAuthorization(cl, proxy, true /* need_password */, &auth))
      return 1;

    cryptohome::RemoveKeyRequest remove_req;
    cryptohome::KeyData* data = remove_req.mutable_key()->mutable_data();
    data->set_label(cl->GetSwitchValueASCII(switches::kRemoveKeyLabelSwitch));

    brillo::glib::ScopedArray account_ary(GArrayFromProtoBuf(id));
    brillo::glib::ScopedArray auth_ary(GArrayFromProtoBuf(auth));
    brillo::glib::ScopedArray req_ary(GArrayFromProtoBuf(remove_req));
    if (!account_ary.get() || !auth_ary.get() || !req_ary.get())
      return 1;

    cryptohome::BaseReply reply;
    brillo::glib::ScopedError error;
    if (cl->HasSwitch(switches::kAsyncSwitch)) {
      ClientLoop loop;
      loop.Initialize(&proxy);
      DBusGProxyCall* call =
          org_chromium_CryptohomeInterface_remove_key_ex_async(
              proxy.gproxy(), account_ary.get(), auth_ary.get(), req_ary.get(),
              &ClientLoop::ParseReplyThunk, static_cast<gpointer>(&loop));
      if (!call)
        return 1;
      loop.Run();
      reply = loop.reply();
    } else {
      GArray* out_reply = NULL;
      if (!org_chromium_CryptohomeInterface_remove_key_ex(
              proxy.gproxy(), account_ary.get(), auth_ary.get(), req_ary.get(),
              &out_reply, &brillo::Resetter(&error).lvalue())) {
        printf("RemoveKeyEx call failed: %s", error->message);
        return 1;
      }
      ParseBaseReply(out_reply, &reply, true /* print_reply */);
    }
    if (reply.has_error()) {
      printf("Key removal failed.\n");
      return reply.error();
    }
    printf("Key removed.\n");
  } else if (!strcmp(switches::kActions[switches::ACTION_GET_KEY_DATA_EX],
                     action.c_str())) {
    cryptohome::AccountIdentifier id;
    if (!BuildAccountId(cl, &id)) {
      return 1;
    }
    cryptohome::AuthorizationRequest auth;
    cryptohome::GetKeyDataRequest key_data_req;
    const std::string label =
        cl->GetSwitchValueASCII(switches::kKeyLabelSwitch);
    if (label.empty()) {
      printf("No key_label specified.\n");
      return 1;
    }
    key_data_req.mutable_key()->mutable_data()->set_label(label);

    brillo::glib::ScopedArray account_ary(GArrayFromProtoBuf(id));
    brillo::glib::ScopedArray auth_ary(GArrayFromProtoBuf(auth));
    brillo::glib::ScopedArray req_ary(GArrayFromProtoBuf(key_data_req));
    if (!account_ary.get() || !auth_ary.get() || !req_ary.get()) {
      return 1;
    }

    cryptohome::BaseReply reply;
    brillo::glib::ScopedError error;
    if (cl->HasSwitch(switches::kAsyncSwitch)) {
      ClientLoop loop;
      loop.Initialize(&proxy);
      DBusGProxyCall* call =
          org_chromium_CryptohomeInterface_get_key_data_ex_async(
              proxy.gproxy(), account_ary.get(), auth_ary.get(), req_ary.get(),
              &ClientLoop::ParseReplyThunk, static_cast<gpointer>(&loop));
      if (!call) {
        return 1;
      }
      loop.Run();
      reply = loop.reply();
    } else {
      GArray* out_reply = NULL;
      if (!org_chromium_CryptohomeInterface_get_key_data_ex(
              proxy.gproxy(), account_ary.get(), auth_ary.get(), req_ary.get(),
              &out_reply, &brillo::Resetter(&error).lvalue())) {
        printf("GetKeyDataEx call failed: %s", error->message);
        return 1;
      }
      ParseBaseReply(out_reply, &reply, true /* print_reply */);
    }
    if (reply.has_error()) {
      printf("Key retrieval failed.\n");
      return reply.error();
    }
  } else if (!strcmp(switches::kActions[switches::ACTION_LIST_KEYS_EX],
                     action.c_str())) {
    cryptohome::AccountIdentifier id;
    if (!BuildAccountId(cl, &id))
      return 1;
    cryptohome::AuthorizationRequest auth;

    cryptohome::ListKeysRequest list_keys_req;

    brillo::glib::ScopedArray account_ary(GArrayFromProtoBuf(id));
    brillo::glib::ScopedArray auth_ary(GArrayFromProtoBuf(auth));
    brillo::glib::ScopedArray req_ary(GArrayFromProtoBuf(list_keys_req));
    if (!account_ary.get() || !auth_ary.get() || !req_ary.get())
      return 1;

    cryptohome::BaseReply reply;
    brillo::glib::ScopedError error;
    if (cl->HasSwitch(switches::kAsyncSwitch)) {
      ClientLoop loop;
      loop.Initialize(&proxy);
      DBusGProxyCall* call =
          org_chromium_CryptohomeInterface_list_keys_ex_async(
              proxy.gproxy(), account_ary.get(), auth_ary.get(), req_ary.get(),
              &ClientLoop::ParseReplyThunk, static_cast<gpointer>(&loop));
      if (!call) {
        return 1;
      }
      loop.Run();
      reply = loop.reply();
    } else {
      GArray* out_reply = NULL;
      if (!org_chromium_CryptohomeInterface_list_keys_ex(
              proxy.gproxy(), account_ary.get(), auth_ary.get(), req_ary.get(),
              &out_reply, &brillo::Resetter(&error).lvalue())) {
        printf("ListKeysEx call failed: %s", error->message);
        return 1;
      }
      ParseBaseReply(out_reply, &reply, true /* print_reply */);
    }
    if (reply.has_error()) {
      printf("Failed to list keys.\n");
      return reply.error();
    }
    if (!reply.HasExtension(cryptohome::ListKeysReply::reply)) {
      printf("ListKeysReply missing.\n");
      return 1;
    }
    cryptohome::ListKeysReply list_keys_reply =
        reply.GetExtension(cryptohome::ListKeysReply::reply);
    for (int i = 0; i < list_keys_reply.labels_size(); ++i) {
      printf("Label: %s\n", list_keys_reply.labels(i).c_str());
    }
  } else if (!strcmp(switches::kActions[switches::ACTION_CHECK_KEY_EX],
                     action.c_str())) {
    cryptohome::AccountIdentifier id;
    if (!BuildAccountId(cl, &id))
      return 1;
    cryptohome::AuthorizationRequest auth;
    if (cl->HasSwitch(switches::kFingerprintSwitch)) {
      auth.mutable_key()->mutable_data()->set_type(
          cryptohome::KeyData::KEY_TYPE_FINGERPRINT);
    } else if (!BuildAuthorization(cl, proxy, true /* need_password */,
                                   &auth)) {
      return 1;
    }

    cryptohome::CheckKeyRequest check_req;
    // TODO(wad) Add a privileges cl interface

    brillo::glib::ScopedArray account_ary(GArrayFromProtoBuf(id));
    brillo::glib::ScopedArray auth_ary(GArrayFromProtoBuf(auth));
    brillo::glib::ScopedArray req_ary(GArrayFromProtoBuf(check_req));
    if (!account_ary.get() || !auth_ary.get() || !req_ary.get())
      return 1;

    cryptohome::BaseReply reply;
    brillo::glib::ScopedError error;
    if (cl->HasSwitch(switches::kAsyncSwitch)) {
      ClientLoop loop;
      loop.Initialize(&proxy);
      DBusGProxyCall* call =
          org_chromium_CryptohomeInterface_check_key_ex_async(
              proxy.gproxy(), account_ary.get(), auth_ary.get(), req_ary.get(),
              &ClientLoop::ParseReplyThunk, static_cast<gpointer>(&loop));
      if (!call)
        return 1;
      loop.Run();
      reply = loop.reply();
    } else {
      GArray* out_reply = NULL;
      if (!org_chromium_CryptohomeInterface_check_key_ex(
              proxy.gproxy(), account_ary.get(), auth_ary.get(), req_ary.get(),
              &out_reply, &brillo::Resetter(&error).lvalue())) {
        printf("CheckKeyEx call failed: %s", error->message);
        return 1;
      }
      ParseBaseReply(out_reply, &reply, true /* print_reply */);
    }
    if (reply.has_error()) {
      printf("Key authentication failed.\n");
      return reply.error();
    }
    printf("Key authenticated.\n");
  } else if (!strcmp(switches::kActions[switches::ACTION_ADD_DATA_RESTORE_KEY],
                     action.c_str())) {
    cryptohome::AccountIdentifier id;
    if (!BuildAccountId(cl, &id))
      return 1;
    cryptohome::AuthorizationRequest auth;
    if (!BuildAuthorization(cl, proxy, true /* need_password */, &auth))
      return 1;

    brillo::glib::ScopedArray account_ary(GArrayFromProtoBuf(id));
    brillo::glib::ScopedArray auth_ary(GArrayFromProtoBuf(auth));
    if (!account_ary.get() || !auth_ary.get())
      return 1;

    cryptohome::BaseReply reply;
    brillo::glib::ScopedError error;
    if (cl->HasSwitch(switches::kAsyncSwitch)) {
      ClientLoop loop;
      loop.Initialize(&proxy);
      DBusGProxyCall* call =
          org_chromium_CryptohomeInterface_add_data_restore_key_async(
              proxy.gproxy(), account_ary.get(), auth_ary.get(),
              &ClientLoop::ParseReplyThunk, static_cast<gpointer>(&loop));
      if (!call)
        return 1;
      loop.Run();
      reply = loop.reply();
    } else {
      GArray* out_reply = NULL;
      if (!org_chromium_CryptohomeInterface_add_data_restore_key(
              proxy.gproxy(), account_ary.get(), auth_ary.get(), &out_reply,
              &brillo::Resetter(&error).lvalue())) {
        printf("Restore key addition failed: %s", error->message);
        return 1;
      }
      ParseBaseReply(out_reply, &reply, true /* print_reply */);
    }
    if (reply.has_error()) {
      printf("Restore key addition failed.\n");
      return reply.error();
    }
    SecureBlob data_restore_key_raw(
        reply.GetExtension(cryptohome::AddDataRestoreKeyReply::reply)
            .data_restore_key());
    printf("Restore key addition succeeded.\n");
    printf("Here's the data restore key in hex: %s\n",
           brillo::SecureBlobToSecureHex(data_restore_key_raw)
               .to_string()
               .c_str());
  } else if (!strcmp(switches::kActions[switches::ACTION_MASS_REMOVE_KEYS],
                     action.c_str())) {
    cryptohome::AccountIdentifier id;
    if (!BuildAccountId(cl, &id))
      return 1;
    cryptohome::AuthorizationRequest auth;
    if (!BuildAuthorization(cl, proxy, true /* need_password */, &auth))
      return 1;

    cryptohome::MassRemoveKeysRequest mass_remove_keys_request;
    // Since it's unlikely to have comma in a label string,
    // exempt_key_labels are seperated by comma from command line input
    // ( e.g. --exempt_key_labels=label1,label2,label3 )
    std::vector<std::string> exempt_labels = SplitString(
        cl->GetSwitchValueASCII(switches::kMassRemoveExemptLabelsSwitch), ",",
        base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
    for (std::string label : exempt_labels) {
      cryptohome::KeyData* data =
          mass_remove_keys_request.add_exempt_key_data();
      data->set_label(label);
    }
    brillo::glib::ScopedArray account_ary(GArrayFromProtoBuf(id));
    brillo::glib::ScopedArray auth_ary(GArrayFromProtoBuf(auth));
    brillo::glib::ScopedArray req_ary(
        GArrayFromProtoBuf(mass_remove_keys_request));
    if (!account_ary.get() || !auth_ary.get() || !req_ary.get())
      return 1;

    cryptohome::BaseReply reply;
    brillo::glib::ScopedError error;
    if (cl->HasSwitch(switches::kAsyncSwitch)) {
      ClientLoop loop;
      loop.Initialize(&proxy);
      DBusGProxyCall* call =
          org_chromium_CryptohomeInterface_mass_remove_keys_async(
              proxy.gproxy(), account_ary.get(), auth_ary.get(), req_ary.get(),
              &ClientLoop::ParseReplyThunk, static_cast<gpointer>(&loop));
      if (!call)
        return 1;
      loop.Run();
      reply = loop.reply();
    } else {
      GArray* out_reply = NULL;
      if (!org_chromium_CryptohomeInterface_mass_remove_keys(
              proxy.gproxy(), account_ary.get(), auth_ary.get(), req_ary.get(),
              &out_reply, &brillo::Resetter(&error).lvalue())) {
        printf("MassRemoveKeys call failed: %s", error->message);
        return 1;
      }
      ParseBaseReply(out_reply, &reply, true /* print_reply */);
    }
    if (reply.has_error()) {
      printf("MassRemoveKeys failed.\n");
      return reply.error();
    }
    printf("MassRemoveKeys succeeded.\n");
  } else if (!strcmp(switches::kActions[switches::ACTION_MIGRATE_KEY_EX],
                     action.c_str())) {
    std::string account_id, password, old_password;

    if (!GetAccountId(cl, &account_id)) {
      return 1;
    }

    GetPassword(proxy, cl, switches::kPasswordSwitch,
                StringPrintf("Enter the password for <%s>", account_id.c_str()),
                &password);
    GetPassword(
        proxy, cl, switches::kOldPasswordSwitch,
        StringPrintf("Enter the old password for <%s>", account_id.c_str()),
        &old_password);

    cryptohome::AccountIdentifier account;
    cryptohome::AuthorizationRequest auth_request;
    cryptohome::MigrateKeyRequest migrate_request;
    account.set_account_id(account_id);
    auth_request.mutable_key()->set_secret(old_password);
    migrate_request.set_secret(password);

    brillo::glib::ScopedArray account_ary(GArrayFromProtoBuf(account));
    brillo::glib::ScopedArray auth_request_ary(
        GArrayFromProtoBuf(auth_request));
    brillo::glib::ScopedArray migrate_request_ary(
        GArrayFromProtoBuf(migrate_request));

    if (!account_ary.get() || !auth_request_ary.get() ||
        !migrate_request_ary.get()) {
      return 1;
    }

    cryptohome::BaseReply reply;
    brillo::glib::ScopedError error;
    GArray* out_reply = NULL;
    if (!org_chromium_CryptohomeInterface_migrate_key_ex(
            proxy.gproxy(), account_ary.get(), auth_request_ary.get(),
            migrate_request_ary.get(), &out_reply,
            &brillo::Resetter(&error).lvalue())) {
      printf("MigrateKeyEx call failed: %s", error->message);
      return 1;
    }
    ParseBaseReply(out_reply, &reply, true /* print_reply */);
    if (reply.has_error()) {
      printf("Key migration failed.\n");
      return reply.error();
    }
    printf("Key migration succeeded.\n");
  } else if (!strcmp(switches::kActions[switches::ACTION_ADD_KEY_EX],
                     action.c_str())) {
    std::string new_password;
    GetPassword(proxy, cl, switches::kNewPasswordSwitch,
                "Enter the new password", &new_password);
    cryptohome::AccountIdentifier id;
    if (!BuildAccountId(cl, &id))
      return 1;
    cryptohome::AuthorizationRequest auth;
    if (!BuildAuthorization(cl, proxy, true /* need_password */, &auth))
      return 1;

    cryptohome::AddKeyRequest key_req;
    key_req.set_clobber_if_exists(cl->HasSwitch(switches::kForceSwitch));

    cryptohome::Key* key = key_req.mutable_key();
    key->set_secret(new_password);
    cryptohome::KeyData* data = key->mutable_data();
    data->set_label(cl->GetSwitchValueASCII(switches::kNewKeyLabelSwitch));

    if (cl->HasSwitch(switches::kKeyPolicySwitch)) {
      if (cl->GetSwitchValueASCII(switches::kKeyPolicySwitch) ==
          switches::kKeyPolicyLECredential) {
        data->mutable_policy()->set_low_entropy_credential(true);
      } else {
        printf("Unknown key policy.\n");
        return 1;
      }
    }

    // TODO(wad) Add a privileges cl interface

    brillo::glib::ScopedArray account_ary(GArrayFromProtoBuf(id));
    brillo::glib::ScopedArray auth_ary(GArrayFromProtoBuf(auth));
    brillo::glib::ScopedArray req_ary(GArrayFromProtoBuf(key_req));
    if (!account_ary.get() || !auth_ary.get() || !req_ary.get())
      return 1;

    cryptohome::BaseReply reply;
    brillo::glib::ScopedError error;
    if (cl->HasSwitch(switches::kAsyncSwitch)) {
      ClientLoop loop;
      loop.Initialize(&proxy);
      DBusGProxyCall* call = org_chromium_CryptohomeInterface_add_key_ex_async(
          proxy.gproxy(), account_ary.get(), auth_ary.get(), req_ary.get(),
          &ClientLoop::ParseReplyThunk, static_cast<gpointer>(&loop));
      if (!call)
        return 1;
      loop.Run();
      reply = loop.reply();
    } else {
      GArray* out_reply = NULL;
      if (!org_chromium_CryptohomeInterface_add_key_ex(
              proxy.gproxy(), account_ary.get(), auth_ary.get(), req_ary.get(),
              &out_reply, &brillo::Resetter(&error).lvalue())) {
        printf("AddKeyEx call failed: %s", error->message);
        return 1;
      }
      ParseBaseReply(out_reply, &reply, true /* print_reply */);
    }
    if (reply.has_error()) {
      printf("Key addition failed.\n");
      return reply.error();
    }
    printf("Key added.\n");
  } else if (!strcmp(switches::kActions[switches::ACTION_REMOVE],
                     action.c_str())) {
    std::string account_id;

    if (!GetAccountId(cl, &account_id)) {
      return 1;
    }

    if (!cl->HasSwitch(switches::kForceSwitch) && !ConfirmRemove(account_id)) {
      return 1;
    }

    cryptohome::AccountIdentifier identifier;
    identifier.set_account_id(account_id);

    brillo::glib::ScopedArray account_ary(GArrayFromProtoBuf(identifier));
    if (!account_ary.get())
      return 1;

    GArray* out_reply = nullptr;
    brillo::glib::ScopedError error;
    if (!org_chromium_CryptohomeInterface_remove_ex(
            proxy.gproxy(), account_ary.get(), &out_reply,
            &brillo::Resetter(&error).lvalue())) {
      printf("Remove call failed: %s.\n", error->message);
      return 1;
    }

    cryptohome::BaseReply reply;
    ParseBaseReply(out_reply, &reply, true /* print_reply */);
    if (reply.has_error()) {
      printf("Remove failed.\n");
      return 1;
    }
    printf("Remove succeeded.\n");
  } else if (!strcmp(switches::kActions[switches::ACTION_UNMOUNT],
                     action.c_str())) {
    cryptohome::UnmountRequest request;
    brillo::glib::ScopedArray request_ary(GArrayFromProtoBuf(request));
    if (!request_ary.get())
      return 1;

    GArray* out_reply = nullptr;
    brillo::glib::ScopedError error;
    if (!org_chromium_CryptohomeInterface_unmount_ex(
            proxy.gproxy(), request_ary.get(), &out_reply,
            &brillo::Resetter(&error).lvalue())) {
      printf("Unmount call failed: %s.\n", error->message);
      return 1;
    }

    cryptohome::BaseReply reply;
    ParseBaseReply(out_reply, &reply, true /* print_reply */);
    if (reply.has_error()) {
      printf("Unmount failed.\n");
      return 1;
    }
    printf("Unmount succeeded.\n");
  } else if (!strcmp(switches::kActions[switches::ACTION_MOUNTED],
                     action.c_str())) {
    brillo::glib::ScopedError error;
    gboolean done = false;
    if (!org_chromium_CryptohomeInterface_is_mounted(
            proxy.gproxy(), &done, &brillo::Resetter(&error).lvalue())) {
      printf("IsMounted call failed: %s.\n", error->message);
    }
    if (done) {
      printf("true\n");
    } else {
      printf("false\n");
    }
  } else if (!strcmp(switches::kActions[switches::ACTION_OBFUSCATE_USER],
                     action.c_str())) {
    std::string account_id;

    if (!GetAccountId(cl, &account_id)) {
      return 1;
    }

    if (cl->HasSwitch(switches::kUseDBus)) {
      gchar* result;
      brillo::glib::ScopedError error;
      if (!org_chromium_CryptohomeInterface_get_sanitized_username(
              proxy.gproxy(), account_id.c_str(), &result,
              &brillo::Resetter(&error).lvalue())) {
        printf("GetSanitizedUserName call failed: %s.\n", error->message);
        return 1;
      }
      printf("%s\n", result);
    } else {
      // Use libbrillo directly instead of going through dbus/cryptohome.
      if (!brillo::cryptohome::home::EnsureSystemSaltIsLoaded()) {
        printf("Failed to load system salt\n");
        return 1;
      }

      std::string* salt_ptr = brillo::cryptohome::home::GetSystemSalt();
      brillo::SecureBlob system_salt = SecureBlob(*salt_ptr);
      printf("%s\n", SanitizeUserNameWithSalt(account_id, system_salt).c_str());
    }
  } else if (!strcmp(switches::kActions[switches::ACTION_GET_SYSTEM_SALT],
                     action.c_str())) {
    brillo::SecureBlob system_salt;
    if (cl->HasSwitch(switches::kUseDBus)) {
      system_salt = GetSystemSalt(proxy);
      if (system_salt.empty()) {
        printf("Failed to retrieve system salt\n");
      }
    } else {
      // Use libbrillo directly instead of going through dbus/cryptohome.
      if (!brillo::cryptohome::home::EnsureSystemSaltIsLoaded()) {
        printf("Failed to load system salt\n");
        return 1;
      }

      std::string* salt_ptr = brillo::cryptohome::home::GetSystemSalt();
      system_salt = SecureBlob(*salt_ptr);
    }
    std::string hex_salt =
        base::HexEncode(system_salt.data(), system_salt.size());
    // We want to follow the convention of having low case hex for output as in
    // GetSanitizedUsername().
    std::transform(hex_salt.begin(), hex_salt.end(), hex_salt.begin(),
                   ::tolower);
    printf("%s\n", hex_salt.c_str());
  } else if (!strcmp(switches::kActions[switches::ACTION_DUMP_KEYSET],
                     action.c_str())) {
    std::string account_id;

    if (!GetAccountId(cl, &account_id)) {
      return 1;
    }

    FilePath vault_path =
        FilePath("/home/.shadow")
            .Append(SanitizeUserNameWithSalt(account_id, GetSystemSalt(proxy)))
            .Append("master.0");
    brillo::Blob contents;
    if (!platform.ReadFile(vault_path, &contents)) {
      printf("Couldn't load keyset contents: %s.\n",
             vault_path.value().c_str());
      return 1;
    }
    cryptohome::SerializedVaultKeyset serialized;
    if (!serialized.ParseFromArray(contents.data(), contents.size())) {
      printf("Couldn't parse keyset contents: %s.\n",
             vault_path.value().c_str());
      return 1;
    }
    printf("For keyset: %s\n", vault_path.value().c_str());
    printf("  Flags:\n");
    if ((serialized.flags() & cryptohome::SerializedVaultKeyset::TPM_WRAPPED) &&
        serialized.has_tpm_key()) {
      printf("    TPM_WRAPPED\n");
    }
    if ((serialized.flags() & cryptohome::SerializedVaultKeyset::PCR_BOUND) &&
        serialized.has_tpm_key() && serialized.has_extended_tpm_key()) {
      printf("    PCR_BOUND\n");
    }
    if (serialized.flags() &
        cryptohome::SerializedVaultKeyset::SCRYPT_WRAPPED) {
      printf("    SCRYPT_WRAPPED\n");
    }
    SecureBlob blob(serialized.salt().length());
    serialized.salt().copy(blob.char_data(), serialized.salt().length(), 0);
    printf("  Salt:\n");
    printf("    %s\n", cryptohome::CryptoLib::SecureBlobToHex(blob).c_str());
    blob.resize(serialized.wrapped_keyset().length());
    serialized.wrapped_keyset().copy(blob.char_data(),
                                     serialized.wrapped_keyset().length(), 0);
    printf("  Wrapped (Encrypted) Keyset:\n");
    printf("    %s\n", cryptohome::CryptoLib::SecureBlobToHex(blob).c_str());
    if (serialized.has_tpm_key()) {
      blob.resize(serialized.tpm_key().length());
      serialized.tpm_key().copy(blob.char_data(), serialized.tpm_key().length(),
                                0);
      printf("  TPM-Bound (Encrypted) Vault Encryption Key:\n");
      printf("    %s\n", cryptohome::CryptoLib::SecureBlobToHex(blob).c_str());
    }
    if (serialized.has_extended_tpm_key()) {
      blob.resize(serialized.extended_tpm_key().length());
      serialized.extended_tpm_key().copy(
          blob.char_data(), serialized.extended_tpm_key().length(), 0);
      printf("  TPM-Bound (Encrypted) Vault Encryption Key, PCR extended:\n");
      printf("    %s\n", cryptohome::CryptoLib::SecureBlobToHex(blob).c_str());
    }
    if (serialized.has_tpm_public_key_hash()) {
      blob.resize(serialized.tpm_public_key_hash().length());
      serialized.tpm_public_key_hash().copy(blob.char_data(),
                                            serialized.tpm_key().length(), 0);
      printf("  TPM Public Key Hash:\n");
      printf("    %s\n", cryptohome::CryptoLib::SecureBlobToHex(blob).c_str());
    }
    if (serialized.has_password_rounds()) {
      printf("  Password rounds:\n");
      printf("    %d\n", serialized.password_rounds());
    }

    base::Time last_activity =
        base::Time::FromInternalValue(serialized.last_activity_timestamp());
    FilePath timestamp_path = vault_path.AddExtension("timestamp");
    brillo::Blob tcontents;
    if (platform.ReadFile(timestamp_path, &tcontents)) {
      cryptohome::Timestamp timestamp;
      if (!timestamp.ParseFromArray(tcontents.data(), tcontents.size())) {
        printf("Couldn't parse timestamp contents: %s.\n",
               timestamp_path.value().c_str());
      }
      last_activity = base::Time::FromInternalValue(timestamp.timestamp());
    } else {
      printf("Couldn't load timestamp contents: %s.\n",
             timestamp_path.value().c_str());
    }

    printf("  Last activity (days ago):\n");
    printf("    %d\n", (base::Time::Now() - last_activity).InDays());

  } else if (!strcmp(switches::kActions[switches::ACTION_DUMP_LAST_ACTIVITY],
                     action.c_str())) {
    std::vector<FilePath> user_dirs;
    if (!platform.EnumerateDirectoryEntries(FilePath("/home/.shadow/"), false,
                                            &user_dirs)) {
      LOG(ERROR) << "Can not list shadow root.";
      return 1;
    }
    for (std::vector<FilePath>::iterator it = user_dirs.begin();
         it != user_dirs.end(); ++it) {
      const std::string dir_name = it->BaseName().value();
      if (!brillo::cryptohome::home::IsSanitizedUserName(dir_name))
        continue;
      // TODO(wad): change it so that it uses GetVaultKeysets().
      std::unique_ptr<cryptohome::FileEnumerator> file_enumerator(
          platform.GetFileEnumerator(*it, false, base::FileEnumerator::FILES));
      base::Time max_activity = base::Time::UnixEpoch();
      FilePath next_path;
      while (!(next_path = file_enumerator->Next()).empty()) {
        FilePath file_name = next_path.BaseName().RemoveFinalExtension();
        // Scan for "master." files.
        if (file_name.value() != cryptohome::kKeyFile)
          continue;
        brillo::Blob contents;
        if (!platform.ReadFile(next_path, &contents)) {
          LOG(ERROR) << "Couldn't load keyset: " << next_path.value();
          continue;
        }
        cryptohome::SerializedVaultKeyset keyset;
        if (!keyset.ParseFromArray(contents.data(), contents.size())) {
          LOG(ERROR) << "Couldn't parse keyset: " << next_path.value();
          continue;
        }
        base::Time last_activity =
            base::Time::FromInternalValue(keyset.last_activity_timestamp());

        FilePath timestamp_path = next_path.AddExtension("timestamp");
        brillo::Blob tcontents;
        if (platform.ReadFile(timestamp_path, &tcontents)) {
          cryptohome::Timestamp timestamp;
          if (!timestamp.ParseFromArray(tcontents.data(), tcontents.size())) {
            printf("Couldn't parse timestamp contents: %s.\n",
                   timestamp_path.value().c_str());
          }
          last_activity = base::Time::FromInternalValue(timestamp.timestamp());
        } else {
          printf("Couldn't load timestamp contents: %s.\n",
                 timestamp_path.value().c_str());
        }

        if (last_activity > max_activity) {
          max_activity = last_activity;
        }
      }
      if (max_activity > base::Time::UnixEpoch()) {
        printf("%s %3d\n", dir_name.c_str(),
               (base::Time::Now() - max_activity).InDays());
      }
    }
  } else if (!strcmp(switches::kActions[switches::ACTION_TPM_STATUS],
                     action.c_str())) {
    brillo::glib::ScopedError error;
    gboolean result = false;
    if (!org_chromium_CryptohomeInterface_tpm_is_enabled(
            proxy.gproxy(), &result, &brillo::Resetter(&error).lvalue())) {
      printf("TpmIsEnabled call failed: %s.\n", error->message);
    } else {
      printf("TPM Enabled: %s\n", (result ? "true" : "false"));
    }
    result = false;
    if (!org_chromium_CryptohomeInterface_tpm_is_owned(
            proxy.gproxy(), &result, &brillo::Resetter(&error).lvalue())) {
      printf("TpmIsOwned call failed: %s.\n", error->message);
    } else {
      printf("TPM Owned: %s\n", (result ? "true" : "false"));
    }
    if (!org_chromium_CryptohomeInterface_tpm_is_being_owned(
            proxy.gproxy(), &result, &brillo::Resetter(&error).lvalue())) {
      printf("TpmIsBeingOwned call failed: %s.\n", error->message);
    } else {
      printf("TPM Being Owned: %s\n", (result ? "true" : "false"));
    }
    if (!org_chromium_CryptohomeInterface_tpm_is_ready(
            proxy.gproxy(), &result, &brillo::Resetter(&error).lvalue())) {
      printf("TpmIsReady call failed: %s.\n", error->message);
    } else {
      printf("TPM Ready: %s\n", (result ? "true" : "false"));
    }
    gchar* password;
    if (!org_chromium_CryptohomeInterface_tpm_get_password(
            proxy.gproxy(), &password, &brillo::Resetter(&error).lvalue())) {
      printf("TpmGetPassword call failed: %s.\n", error->message);
    } else {
      printf("TPM Password: %s\n", password);
      g_free(password);
    }
  } else if (!strcmp(switches::kActions[switches::ACTION_TPM_MORE_STATUS],
                     action.c_str())) {
    cryptohome::GetTpmStatusRequest request;
    cryptohome::BaseReply reply;
    if (!MakeProtoDBusCall(cryptohome::kCryptohomeGetTpmStatus,
                           DBUS_METHOD(get_tpm_status),
                           DBUS_METHOD(get_tpm_status_async), cl, &proxy,
                           request, &reply, true /* print_reply */)) {
      return 1;
    }
    if (!reply.HasExtension(cryptohome::GetTpmStatusReply::reply)) {
      printf("GetTpmStatusReply missing.\n");
      return 1;
    }
    printf("GetTpmStatus success.\n");
  } else if (!strcmp(switches::kActions[switches::ACTION_STATUS],
                     action.c_str())) {
    brillo::glib::ScopedError error;
    gchar* status;
    if (!org_chromium_CryptohomeInterface_get_status_string(
            proxy.gproxy(), &status, &brillo::Resetter(&error).lvalue())) {
      printf("GetStatusString call failed: %s.\n", error->message);
    } else {
      printf("%s\n", status);
      g_free(status);
    }
  } else if (!strcmp(switches::kActions[switches::ACTION_SET_CURRENT_USER_OLD],
                     action.c_str())) {
    brillo::glib::ScopedError error;
    ClientLoop client_loop;
    client_loop.Initialize(&proxy);
    if (!org_chromium_CryptohomeInterface_update_current_user_activity_timestamp(  // NOLINT
            proxy.gproxy(),
            base::TimeDelta::FromDays(kSetCurrentUserOldOffsetInDays)
                .InSeconds(),
            &brillo::Resetter(&error).lvalue())) {
      printf("UpdateCurrentUserActivityTimestamp call failed: %s.\n",
             error->message);
    } else {
      printf(
          "Timestamp successfully updated. You may verify it with "
          "--action=dump_keyset --user=...\n");
    }
  } else if (!strcmp(switches::kActions[switches::ACTION_TPM_TAKE_OWNERSHIP],
                     action.c_str())) {
    brillo::glib::ScopedError error;
    if (!org_chromium_CryptohomeInterface_tpm_can_attempt_ownership(
            proxy.gproxy(), &brillo::Resetter(&error).lvalue())) {
      printf("TpmCanAttemptOwnership call failed: %s.\n", error->message);
    }
  } else if (!strcmp(
                 switches::kActions[switches::ACTION_TPM_CLEAR_STORED_PASSWORD],
                 action.c_str())) {
    brillo::glib::ScopedError error;
    if (!org_chromium_CryptohomeInterface_tpm_clear_stored_password(
            proxy.gproxy(), &brillo::Resetter(&error).lvalue())) {
      printf("TpmClearStoredPassword call failed: %s.\n", error->message);
    }
  } else if (!strcmp(
                 switches::kActions[switches::ACTION_INSTALL_ATTRIBUTES_GET],
                 action.c_str())) {
    std::string name;
    if (!GetAttrName(cl, &name)) {
      printf("No attribute name specified.\n");
      return 1;
    }

    brillo::glib::ScopedError error;
    gboolean result;
    if (!org_chromium_CryptohomeInterface_install_attributes_is_ready(
            proxy.gproxy(), &result, &brillo::Resetter(&error).lvalue())) {
      printf("IsReady call failed: %s.\n", error->message);
      return 1;
    }
    if (result == FALSE) {
      printf("InstallAttributes() is not ready.\n");
      return 1;
    }

    brillo::glib::ScopedArray value;
    if (!org_chromium_CryptohomeInterface_install_attributes_get(
            proxy.gproxy(), name.c_str(), &brillo::Resetter(&value).lvalue(),
            &result, &brillo::Resetter(&error).lvalue())) {
      printf("Get() failed: %s.\n", error->message);
      return 1;
    }
    std::string value_str(value->data, value->len);
    if (result == TRUE) {
      printf("%s\n", value_str.c_str());
    } else {
      return 1;
    }
  } else if (!strcmp(
                 switches::kActions[switches::ACTION_INSTALL_ATTRIBUTES_SET],
                 action.c_str())) {
    std::string name;
    if (!GetAttrName(cl, &name)) {
      printf("No attribute name specified.\n");
      return 1;
    }
    std::string value;
    if (!GetAttrValue(cl, &value)) {
      printf("No attribute value specified.\n");
      return 1;
    }

    brillo::glib::ScopedError error;
    gboolean result;
    if (!org_chromium_CryptohomeInterface_install_attributes_is_ready(
            proxy.gproxy(), &result, &brillo::Resetter(&error).lvalue())) {
      printf("IsReady call failed: %s.\n", error->message);
      return 1;
    }

    if (result == FALSE) {
      printf("InstallAttributes() is not ready.\n");
      return 1;
    }

    brillo::glib::ScopedArray value_ary(g_array_new(FALSE, FALSE, 1));
    g_array_append_vals(value_ary.get(), value.c_str(), value.size() + 1);
    if (!org_chromium_CryptohomeInterface_install_attributes_set(
            proxy.gproxy(), name.c_str(), value_ary.get(), &result,
            &brillo::Resetter(&error).lvalue())) {
      printf("Set() failed: %s.\n", error->message);
      return 1;
    }
    if (result == FALSE)
      return 1;
  } else if (!strcmp(switches::kActions
                         [switches::ACTION_INSTALL_ATTRIBUTES_FINALIZE],
                     action.c_str())) {
    brillo::glib::ScopedError error;
    gboolean result;
    if (!org_chromium_CryptohomeInterface_install_attributes_is_ready(
            proxy.gproxy(), &result, &brillo::Resetter(&error).lvalue())) {
      printf("IsReady call failed: %s.\n", error->message);
      return 1;
    }
    if (result == FALSE) {
      printf("InstallAttributes is not ready.\n");
      return 1;
    }
    if (!org_chromium_CryptohomeInterface_install_attributes_finalize(
            proxy.gproxy(), &result, &brillo::Resetter(&error).lvalue())) {
      printf("Finalize() failed: %s.\n", error->message);
      return 1;
    }
    printf("InstallAttributesFinalize(): %d\n", result);
  } else if (!strcmp(
                 switches::kActions[switches::ACTION_INSTALL_ATTRIBUTES_COUNT],
                 action.c_str())) {
    brillo::glib::ScopedError error;
    gint result;
    if (!org_chromium_CryptohomeInterface_install_attributes_count(
            proxy.gproxy(), &result, &brillo::Resetter(&error).lvalue())) {
      printf("InstallAttributesCount() call failed: %s.\n", error->message);
      return 1;
    }
    printf("InstallAttributesCount(): %d\n", result);
  } else if (!strcmp(switches::kActions
                         [switches::ACTION_INSTALL_ATTRIBUTES_IS_READY],
                     action.c_str())) {
    brillo::glib::ScopedError error;
    gboolean result;
    if (!org_chromium_CryptohomeInterface_install_attributes_is_ready(
            proxy.gproxy(), &result, &brillo::Resetter(&error).lvalue())) {
      printf("InstallAttributesIsReady() call failed: %s.\n", error->message);
      return 1;
    }
    printf("InstallAttributesIsReady(): %d\n", static_cast<int>(result));
  } else if (!strcmp(switches::kActions
                         [switches::ACTION_INSTALL_ATTRIBUTES_IS_SECURE],
                     action.c_str())) {
    brillo::glib::ScopedError error;
    gboolean result;
    if (!org_chromium_CryptohomeInterface_install_attributes_is_secure(
            proxy.gproxy(), &result, &brillo::Resetter(&error).lvalue())) {
      printf("InstallAttributesIsSecure() call failed: %s.\n", error->message);
      return 1;
    }
    printf("InstallAttributesIsSecure(): %d\n", static_cast<int>(result));
  } else if (!strcmp(switches::kActions
                         [switches::ACTION_INSTALL_ATTRIBUTES_IS_INVALID],
                     action.c_str())) {
    brillo::glib::ScopedError error;
    gboolean result;
    if (!org_chromium_CryptohomeInterface_install_attributes_is_invalid(
            proxy.gproxy(), &result, &brillo::Resetter(&error).lvalue())) {
      printf("InstallAttributesIsInvalid() call failed: %s.\n", error->message);
      return 1;
    }
    printf("InstallAttributesIsInvalid(): %d\n", static_cast<int>(result));
  } else if (!strcmp(switches::kActions
                         [switches::ACTION_INSTALL_ATTRIBUTES_IS_FIRST_INSTALL],
                     action.c_str())) {
    brillo::glib::ScopedError error;
    gboolean result;
    if (!org_chromium_CryptohomeInterface_install_attributes_is_first_install(
            proxy.gproxy(), &result, &brillo::Resetter(&error).lvalue())) {
      printf("InstallAttributesIsFirstInstall() call failed: %s.\n",
             error->message);
      return 1;
    }
    printf("InstallAttributesIsFirstInstall(): %d\n", static_cast<int>(result));
  } else if (!strcmp(switches::kActions[switches::ACTION_TPM_WAIT_OWNERSHIP],
                     action.c_str())) {
    // Note that this is a rather hackish implementation that will be replaced
    // once the refactor to distributed mode is over. It'll be replaced with an
    // implementation that does one synchronous call to tpm_manager's
    // TakeOwnership(), then check if it's owned.
    int timeout = kWaitOwnershipTimeoutInSeconds;
    int timeout_in_switch;
    if (cl->HasSwitch(switches::kWaitOwnershipTimeoutSwitch) &&
        base::StringToInt(
            cl->GetSwitchValueASCII(switches::kWaitOwnershipTimeoutSwitch),
            &timeout_in_switch)) {
      timeout = timeout_in_switch;
    }

    brillo::glib::ScopedError error;
    auto deadline = base::Time::Now() + base::TimeDelta::FromSeconds(timeout);
    while (base::Time::Now() < deadline) {
      base::PlatformThread::Sleep(
          base::TimeDelta::FromMilliseconds(kWaitOwnershipPollIntervalInMs));
      gboolean is_owned = false;
      if (!org_chromium_CryptohomeInterface_tpm_is_owned(
              proxy.gproxy(), &is_owned, &brillo::Resetter(&error).lvalue())) {
        printf("TpmIsOwned call failed: %s.\n", error->message);
        return 1;
      }
      if (is_owned) {
        // This is the condition we are waiting for.
        printf("TPM is now owned.\n");
        return 0;
      }
    }
    printf("Fail to own TPM.\n");
    return 1;
  } else if (!strcmp(switches::kActions
                         [switches::ACTION_PKCS11_GET_USER_TOKEN_INFO],
                     action.c_str())) {
    // If no account_id is specified, proceed with the empty string.
    std::string account_id = cl->GetSwitchValueASCII(switches::kUserSwitch);
    if (!account_id.empty()) {
      brillo::glib::ScopedError error;
      gchar* label = NULL;
      gchar* pin = NULL;
      int slot = 0;
      if (!org_chromium_CryptohomeInterface_pkcs11_get_tpm_token_info_for_user(
              proxy.gproxy(), account_id.c_str(), &label, &pin, &slot,
              &brillo::Resetter(&error).lvalue())) {
        printf("PKCS #11 info call failed: %s.\n", error->message);
      } else {
        printf("Token properties for %s:\n", account_id.c_str());
        printf("Label = %s\n", label);
        printf("Pin = %s\n", pin);
        printf("Slot = %d\n", slot);
        g_free(label);
        g_free(pin);
      }
    } else {
      printf("Account ID/Username not specified.\n");
      return 1;
    }
  } else if (!strcmp(switches::kActions
                         [switches::ACTION_PKCS11_GET_SYSTEM_TOKEN_INFO],
                     action.c_str())) {
    brillo::glib::ScopedError error;
    gchar* label = NULL;
    gchar* pin = NULL;
    int slot = 0;
    if (!org_chromium_CryptohomeInterface_pkcs11_get_tpm_token_info(
            proxy.gproxy(), &label, &pin, &slot,
            &brillo::Resetter(&error).lvalue())) {
      printf("PKCS #11 info call failed: %s.\n", error->message);
    } else {
      printf("System token properties:\n");
      printf("Label = %s\n", label);
      printf("Pin = %s\n", pin);
      printf("Slot = %d\n", slot);
      g_free(label);
      g_free(pin);
    }
  } else if (!strcmp(
                 switches::kActions[switches::ACTION_PKCS11_IS_USER_TOKEN_OK],
                 action.c_str())) {
    cryptohome::Pkcs11Init init;
    if (!init.IsUserTokenOK()) {
      printf("User token looks broken!\n");
      return 1;
    }
    printf("User token looks OK!\n");
  } else if (!strcmp(switches::kActions[switches::ACTION_PKCS11_TERMINATE],
                     action.c_str())) {
    // If no account_id is specified, proceed with the empty string.
    std::string account_id;
    GetAccountId(cl, &account_id);
    brillo::glib::ScopedError error;
    if (!org_chromium_CryptohomeInterface_pkcs11_terminate(
            proxy.gproxy(), account_id.c_str(),
            &brillo::Resetter(&error).lvalue())) {
      printf("PKCS #11 terminate call failed: %s.\n", error->message);
    }
  } else if (!strcmp(
                 switches::kActions[switches::ACTION_TPM_VERIFY_ATTESTATION],
                 action.c_str())) {
    bool is_cros_core = cl->HasSwitch(switches::kCrosCoreSwitch);
    brillo::glib::ScopedError error;
    gboolean result = FALSE;
    if (!org_chromium_CryptohomeInterface_tpm_verify_attestation_data(
            proxy.gproxy(), is_cros_core, &result,
            &brillo::Resetter(&error).lvalue())) {
      printf("TpmVerifyAttestationData call failed: %s.\n", error->message);
      return 1;
    }
    if (result == FALSE) {
      printf("TPM attestation data is not valid or is not available.\n");
      return 1;
    }
  } else if (!strcmp(switches::kActions[switches::ACTION_TPM_VERIFY_EK],
                     action.c_str())) {
    bool is_cros_core = cl->HasSwitch(switches::kCrosCoreSwitch);
    brillo::glib::ScopedError error;
    gboolean result = FALSE;
    if (!org_chromium_CryptohomeInterface_tpm_verify_ek(
            proxy.gproxy(), is_cros_core, &result,
            &brillo::Resetter(&error).lvalue())) {
      printf("TpmVerifyEK call failed: %s.\n", error->message);
      return 1;
    }
    if (result == FALSE) {
      printf("TPM endorsement key is not valid or is not available.\n");
      return 1;
    }
  } else if (!strcmp(
                 switches::kActions[switches::ACTION_TPM_ATTESTATION_STATUS],
                 action.c_str())) {
    brillo::glib::ScopedError error;
    gboolean result = FALSE;
    if (!org_chromium_CryptohomeInterface_tpm_is_attestation_prepared(
            proxy.gproxy(), &result, &brillo::Resetter(&error).lvalue())) {
      printf("TpmIsAttestationPrepared call failed: %s.\n", error->message);
    } else {
      printf("Attestation Prepared: %s\n", (result ? "true" : "false"));
    }
    if (!org_chromium_CryptohomeInterface_tpm_is_attestation_enrolled(
            proxy.gproxy(), &result, &brillo::Resetter(&error).lvalue())) {
      printf("TpmIsAttestationEnrolled call failed: %s.\n", error->message);
    } else {
      printf("Attestation Enrolled: %s\n", (result ? "true" : "false"));
    }
  } else if (!strcmp(switches::kActions
                         [switches::ACTION_TPM_ATTESTATION_MORE_STATUS],
                     action.c_str())) {
    cryptohome::AttestationGetEnrollmentPreparationsRequest request;
    cryptohome::BaseReply reply;
    if (!MakeProtoDBusCall(
            cryptohome::kCryptohomeTpmAttestationGetEnrollmentPreparationsEx,
            DBUS_METHOD(tpm_attestation_get_enrollment_preparations_ex),
            DBUS_METHOD(tpm_attestation_get_enrollment_preparations_ex_async),
            cl, &proxy, request, &reply, false /* print_reply */)) {
      printf("TpmAttestationGetEnrollmentPreparationsEx call failed.\n");
    } else if (!reply.HasExtension(
                   cryptohome::AttestationGetEnrollmentPreparationsReply::
                       reply)) {
      printf("AttestationGetEnrollmentPreparationsReply missing.\n");
    } else {
      cryptohome::AttestationGetEnrollmentPreparationsReply* extension =
          reply.MutableExtension(
              cryptohome::AttestationGetEnrollmentPreparationsReply::reply);
      auto map = extension->enrollment_preparations();
      bool prepared = false;
      for (auto it = map.cbegin(), end = map.cend(); it != end; ++it) {
        prepared |= it->second;
      }
      printf("Attestation Prepared: %s\n", prepared ? "true" : "false");
      for (auto it = map.cbegin(), end = map.cend(); it != end; ++it) {
        printf("    Prepared for %s: %s\n", GetPCAName(it->first).c_str(),
               (it->second ? "true" : "false"));
      }
    }
    // TODO(crbug.com/922062): Replace with a call listing all identity certs.
    brillo::glib::ScopedError error;
    gboolean result = FALSE;
    if (!org_chromium_CryptohomeInterface_tpm_is_attestation_enrolled(
            proxy.gproxy(), &result, &brillo::Resetter(&error).lvalue())) {
      printf("TpmIsAttestationEnrolled call failed: %s.\n", error->message);
    } else {
      printf("Attestation Enrolled: %s\n", (result ? "true" : "false"));
    }
  } else if (!strcmp(switches::kActions
                         [switches::ACTION_TPM_ATTESTATION_START_ENROLL],
                     action.c_str())) {
    brillo::glib::ScopedError error;
    std::string response_data;
    if (!cl->HasSwitch(switches::kAsyncSwitch)) {
      brillo::glib::ScopedArray data;
      if (!org_chromium_CryptohomeInterface_tpm_attestation_create_enroll_request(  // NOLINT
              proxy.gproxy(), pca_type, &brillo::Resetter(&data).lvalue(),
              &brillo::Resetter(&error).lvalue())) {
        printf("TpmAttestationCreateEnrollRequest call failed: %s.\n",
               error->message);
        return 1;
      }
      response_data = std::string(static_cast<char*>(data->data), data->len);
    } else {
      ClientLoop client_loop;
      client_loop.Initialize(&proxy);
      gint async_id = -1;
      if (!org_chromium_CryptohomeInterface_async_tpm_attestation_create_enroll_request(  // NOLINT
              proxy.gproxy(), pca_type, &async_id,
              &brillo::Resetter(&error).lvalue())) {
        printf("AsyncTpmAttestationCreateEnrollRequest call failed: %s.\n",
               error->message);
        return 1;
      } else {
        client_loop.Run(async_id);
        if (!client_loop.get_return_status()) {
          printf("Attestation enrollment request failed.\n");
          return 1;
        }
        response_data = client_loop.get_return_data();
      }
    }
    base::WriteFile(GetOutputFile(cl), response_data.data(),
                    response_data.length());
  } else if (!strcmp(switches::kActions
                         [switches::ACTION_TPM_ATTESTATION_FINISH_ENROLL],
                     action.c_str())) {
    std::string contents;
    if (!base::ReadFileToString(GetInputFile(cl), &contents)) {
      printf("Failed to read input file.\n");
      return 1;
    }
    brillo::glib::ScopedArray data(g_array_new(FALSE, FALSE, 1));
    g_array_append_vals(data.get(), contents.data(), contents.length());
    gboolean success = FALSE;
    brillo::glib::ScopedError error;
    if (!cl->HasSwitch(switches::kAsyncSwitch)) {
      if (!org_chromium_CryptohomeInterface_tpm_attestation_enroll(
              proxy.gproxy(), pca_type, data.get(), &success,
              &brillo::Resetter(&error).lvalue())) {
        printf("TpmAttestationEnroll call failed: %s.\n", error->message);
        return 1;
      }
    } else {
      ClientLoop client_loop;
      client_loop.Initialize(&proxy);
      gint async_id = -1;
      if (!org_chromium_CryptohomeInterface_async_tpm_attestation_enroll(
              proxy.gproxy(), pca_type, data.get(), &async_id,
              &brillo::Resetter(&error).lvalue())) {
        printf("AsyncTpmAttestationEnroll call failed: %s.\n", error->message);
        return 1;
      } else {
        client_loop.Run(async_id);
        success = client_loop.get_return_status();
      }
    }
    if (!success) {
      printf("Attestation enrollment failed.\n");
      return 1;
    }
  } else if (!strcmp(
                 switches::kActions[switches::ACTION_TPM_ATTESTATION_ENROLL],
                 action.c_str())) {
    brillo::glib::ScopedError error;
    gboolean success = FALSE;
    const bool forced = cl->HasSwitch(switches::kForceSwitch);
    if (!cl->HasSwitch(switches::kAsyncSwitch)) {
      brillo::glib::ScopedArray data;
      if (!org_chromium_CryptohomeInterface_tpm_attestation_enroll_ex(
              proxy.gproxy(), pca_type, forced, &success,
              &brillo::Resetter(&error).lvalue())) {
        printf("TpmAttestationEnrollEx call failed: %s.\n", error->message);
        return 1;
      }
    } else {
      ClientLoop client_loop;
      client_loop.Initialize(&proxy);
      gint async_id = -1;
      if (!org_chromium_CryptohomeInterface_async_tpm_attestation_enroll_ex(
              proxy.gproxy(), pca_type, forced, &async_id,
              &brillo::Resetter(&error).lvalue())) {
        printf("AsyncTpmAttestationEnrollEx call failed: %s.\n",
               error->message);
        return 1;
      } else {
        client_loop.Run(async_id);
        success = client_loop.get_return_status();
      }
    }
    if (!success) {
      printf("Attestation enrollment failed.\n");
      return 1;
    }
  } else if (!strcmp(switches::kActions
                         [switches::ACTION_TPM_ATTESTATION_START_CERTREQ],
                     action.c_str())) {
    brillo::glib::ScopedError error;
    std::string response_data;
    cryptohome::CertificateProfile profile;
    if (!GetProfile(cl, &profile)) {
      return 1;
    }
    if (!cl->HasSwitch(switches::kAsyncSwitch)) {
      brillo::glib::ScopedArray data;
      if (!org_chromium_CryptohomeInterface_tpm_attestation_create_cert_request(
              proxy.gproxy(), pca_type, profile, "", "",
              &brillo::Resetter(&data).lvalue(),
              &brillo::Resetter(&error).lvalue())) {
        printf("TpmAttestationCreateCertRequest call failed: %s.\n",
               error->message);
        return 1;
      }
      response_data = std::string(static_cast<char*>(data->data), data->len);
    } else {
      ClientLoop client_loop;
      client_loop.Initialize(&proxy);
      gint async_id = -1;
      if (!org_chromium_CryptohomeInterface_async_tpm_attestation_create_cert_request(  // NOLINT
              proxy.gproxy(), pca_type, profile, "", "", &async_id,
              &brillo::Resetter(&error).lvalue())) {
        printf("AsyncTpmAttestationCreateCertRequest call failed: %s.\n",
               error->message);
        return 1;
      } else {
        client_loop.Run(async_id);
        if (!client_loop.get_return_status()) {
          printf("Attestation certificate request failed.\n");
          return 1;
        }
        response_data = client_loop.get_return_data();
      }
    }
    base::WriteFile(GetOutputFile(cl), response_data.data(),
                    response_data.length());
  } else if (!strcmp(switches::kActions
                         [switches::ACTION_TPM_ATTESTATION_FINISH_CERTREQ],
                     action.c_str())) {
    std::string account_id = cl->GetSwitchValueASCII(switches::kUserSwitch);
    std::string key_name = cl->GetSwitchValueASCII(switches::kAttrNameSwitch);
    if (key_name.length() == 0) {
      printf("No key name specified (--%s=<name>)\n",
             switches::kAttrNameSwitch);
      return 1;
    }
    std::string contents;
    if (!base::ReadFileToString(GetInputFile(cl), &contents)) {
      printf("Failed to read input file.\n");
      return 1;
    }
    gboolean is_user_specific = !account_id.empty();
    brillo::glib::ScopedArray data(g_array_new(FALSE, FALSE, 1));
    g_array_append_vals(data.get(), contents.data(), contents.length());
    gboolean success = FALSE;
    brillo::glib::ScopedError error;
    std::string cert_data;
    if (!cl->HasSwitch(switches::kAsyncSwitch)) {
      brillo::glib::ScopedArray cert;
      if (!org_chromium_CryptohomeInterface_tpm_attestation_finish_cert_request(
              proxy.gproxy(), data.get(), is_user_specific, account_id.c_str(),
              key_name.c_str(), &brillo::Resetter(&cert).lvalue(), &success,
              &brillo::Resetter(&error).lvalue())) {
        printf("TpmAttestationFinishCertRequest call failed: %s.\n",
               error->message);
        return 1;
      }
      cert_data = std::string(static_cast<char*>(cert->data), cert->len);
    } else {
      ClientLoop client_loop;
      client_loop.Initialize(&proxy);
      gint async_id = -1;
      if (!org_chromium_CryptohomeInterface_async_tpm_attestation_finish_cert_request(  // NOLINT
              proxy.gproxy(), data.get(), is_user_specific, account_id.c_str(),
              key_name.c_str(), &async_id,
              &brillo::Resetter(&error).lvalue())) {
        printf("AsyncTpmAttestationFinishCertRequest call failed: %s.\n",
               error->message);
        return 1;
      } else {
        client_loop.Run(async_id);
        success = client_loop.get_return_status();
        cert_data = client_loop.get_return_data();
      }
    }
    if (!success) {
      printf("Attestation certificate request failed.\n");
      return 1;
    }
    base::WriteFile(GetOutputFile(cl), cert_data.data(), cert_data.length());
  } else if (!strcmp(switches::kActions
                         [switches::ACTION_TPM_ATTESTATION_GET_CERTIFICATE],
                     action.c_str())) {
    brillo::glib::ScopedError error;
    cryptohome::CertificateProfile profile;
    const std::string account_id =
        cl->GetSwitchValueASCII(switches::kUserSwitch);
    const std::string key_name =
        cl->GetSwitchValueASCII(switches::kAttrNameSwitch);
    const bool forced = cl->HasSwitch(switches::kForceSwitch);
    const bool shall_trigger_enrollment =
        cl->HasSwitch(switches::kEnrollSwitch);

    gboolean success = FALSE;
    std::string cert;
    if (!GetProfile(cl, &profile)) {
      return 1;
    }
    if (!cl->HasSwitch(switches::kAsyncSwitch)) {
      brillo::glib::ScopedArray data;
      if (!org_chromium_CryptohomeInterface_tpm_attestation_get_certificate_ex(
              proxy.gproxy(), profile, account_id.c_str(),
              /*request_origin=*/"", pca_type,
              /*key_type=*/1, key_name.c_str(), forced,
              shall_trigger_enrollment, &brillo::Resetter(&data).lvalue(),
              &success, &brillo::Resetter(&error).lvalue())) {
        printf("TpmAttestationCreateCertRequest call failed: %s.\n",
               error->message);
        return 1;
      }
      cert = std::string(static_cast<char*>(data->data), data->len);
    } else {
      ClientLoop client_loop;
      client_loop.Initialize(&proxy);
      gint async_id = -1;
      if (!org_chromium_CryptohomeInterface_async_tpm_attestation_get_certificate_ex(  // NOLINT
              proxy.gproxy(), profile, account_id.c_str(),
              /*request_origin=*/"", pca_type,
              /*key_type=*/1, key_name.c_str(), forced,
              shall_trigger_enrollment, &async_id,
              &brillo::Resetter(&error).lvalue())) {
        printf("AsyncTpmAttestationCreateCertRequest call failed: %s.\n",
               error->message);
        return 1;
      } else {
        client_loop.Run(async_id);
        success = client_loop.get_return_status();
        cert = client_loop.get_return_data();
      }
    }
    if (!success) {
      printf("Attestation certificate request failed.\n");
      return 1;
    }
    base::WriteFile(GetOutputFile(cl), cert.data(), cert.length());
  } else if (!strcmp(switches::kActions
                         [switches::ACTION_TPM_ATTESTATION_KEY_STATUS],
                     action.c_str())) {
    std::string account_id = cl->GetSwitchValueASCII(switches::kUserSwitch);
    std::string key_name = cl->GetSwitchValueASCII(switches::kAttrNameSwitch);
    if (key_name.length() == 0) {
      printf("No key name specified (--%s=<name>)\n",
             switches::kAttrNameSwitch);
      return 1;
    }
    gboolean is_user_specific = !account_id.empty();
    brillo::glib::ScopedError error;
    gboolean exists = FALSE;
    if (!org_chromium_CryptohomeInterface_tpm_attestation_does_key_exist(
            proxy.gproxy(), is_user_specific, account_id.c_str(),
            key_name.c_str(), &exists, &brillo::Resetter(&error).lvalue())) {
      printf("TpmAttestationDoesKeyExist call failed: %s.\n", error->message);
      return 1;
    }
    if (!exists) {
      printf("Key does not exist.\n");
      return 0;
    }
    gboolean success = FALSE;
    brillo::glib::ScopedArray cert;
    if (!org_chromium_CryptohomeInterface_tpm_attestation_get_certificate(
            proxy.gproxy(), is_user_specific, account_id.c_str(),
            key_name.c_str(), &brillo::Resetter(&cert).lvalue(), &success,
            &brillo::Resetter(&error).lvalue())) {
      printf("TpmAttestationGetCertificate call failed: %s.\n", error->message);
      return 1;
    }
    brillo::glib::ScopedArray public_key;
    if (!org_chromium_CryptohomeInterface_tpm_attestation_get_public_key(
            proxy.gproxy(), is_user_specific, account_id.c_str(),
            key_name.c_str(), &brillo::Resetter(&public_key).lvalue(), &success,
            &brillo::Resetter(&error).lvalue())) {
      printf("TpmAttestationGetPublicKey call failed: %s.\n", error->message);
      return 1;
    }
    std::string cert_pem =
        std::string(static_cast<char*>(cert->data), cert->len);
    std::string public_key_hex =
        base::HexEncode(public_key->data, public_key->len);
    printf("Public Key:\n%s\n\nCertificate:\n%s\n", public_key_hex.c_str(),
           cert_pem.c_str());
  } else if (!strcmp(switches::kActions
                         [switches::ACTION_TPM_ATTESTATION_REGISTER_KEY],
                     action.c_str())) {
    std::string account_id = cl->GetSwitchValueASCII(switches::kUserSwitch);
    std::string key_name = cl->GetSwitchValueASCII(switches::kAttrNameSwitch);
    if (key_name.length() == 0) {
      printf("No key name specified (--%s=<name>)\n",
             switches::kAttrNameSwitch);
      return 1;
    }
    const gboolean is_user_specific = !account_id.empty();
    ClientLoop client_loop;
    client_loop.Initialize(&proxy);
    gint async_id = -1;
    brillo::glib::ScopedError error;
    if (!org_chromium_CryptohomeInterface_tpm_attestation_register_key(
            proxy.gproxy(), is_user_specific, account_id.c_str(),
            key_name.c_str(), &async_id, &brillo::Resetter(&error).lvalue())) {
      printf("TpmAttestationRegisterKey call failed: %s.\n", error->message);
      return 1;
    } else {
      client_loop.Run(async_id);
      gboolean result = client_loop.get_return_status();
      printf("Result: %s\n", result ? "Success" : "Failure");
    }
  } else if (!strcmp(
                 switches::kActions
                     [switches::ACTION_TPM_ATTESTATION_ENTERPRISE_CHALLENGE],
                 action.c_str())) {
    std::string account_id = cl->GetSwitchValueASCII(switches::kUserSwitch);
    std::string key_name = cl->GetSwitchValueASCII(switches::kAttrNameSwitch);
    if (key_name.length() == 0) {
      printf("No key name specified (--%s=<name>)\n",
             switches::kAttrNameSwitch);
      return 1;
    }
    gboolean is_user_specific = !account_id.empty();
    std::string contents;
    if (!base::ReadFileToString(GetInputFile(cl), &contents)) {
      printf("Failed to read input file: %s\n",
             GetInputFile(cl).value().c_str());
      return 1;
    }
    brillo::glib::ScopedArray challenge(g_array_new(FALSE, FALSE, 1));
    g_array_append_vals(challenge.get(), contents.data(), contents.length());
    brillo::glib::ScopedArray device_id(g_array_new(FALSE, FALSE, 1));
    std::string device_id_str = "fake_device_id";
    g_array_append_vals(device_id.get(), device_id_str.data(),
                        device_id_str.length());
    brillo::glib::ScopedError error;
    ClientLoop client_loop;
    client_loop.Initialize(&proxy);
    gint async_id = -1;
    if (!org_chromium_CryptohomeInterface_tpm_attestation_sign_enterprise_va_challenge(  // NOLINT
            proxy.gproxy(), va_type, is_user_specific, account_id.c_str(),
            key_name.c_str(), account_id.c_str(), device_id.get(), TRUE,
            challenge.get(), &async_id, &brillo::Resetter(&error).lvalue())) {
      printf("AsyncTpmAttestationSignEnterpriseVaChallenge call failed: %s.\n",
             error->message);
      return 1;
    }
    client_loop.Run(async_id);
    if (!client_loop.get_return_status()) {
      printf("Attestation challenge response failed.\n");
      return 1;
    }
    std::string response_data = client_loop.get_return_data();
    base::WriteFileDescriptor(STDOUT_FILENO, response_data.data(),
                              response_data.length());
  } else if (!strcmp(switches::kActions
                         [switches::ACTION_TPM_ATTESTATION_SIMPLE_CHALLENGE],
                     action.c_str())) {
    std::string account_id = cl->GetSwitchValueASCII(switches::kUserSwitch);
    std::string key_name = cl->GetSwitchValueASCII(switches::kAttrNameSwitch);
    if (key_name.length() == 0) {
      printf("No key name specified (--%s=<name>)\n",
             switches::kAttrNameSwitch);
      return 1;
    }
    gboolean is_user_specific = !account_id.empty();
    std::string contents = "challenge";
    brillo::glib::ScopedArray challenge(g_array_new(FALSE, FALSE, 1));
    g_array_append_vals(challenge.get(), contents.data(), contents.length());
    brillo::glib::ScopedError error;
    ClientLoop client_loop;
    client_loop.Initialize(&proxy);
    gint async_id = -1;
    if (!org_chromium_CryptohomeInterface_tpm_attestation_sign_simple_challenge(
            proxy.gproxy(), is_user_specific, account_id.c_str(),
            key_name.c_str(), challenge.get(), &async_id,
            &brillo::Resetter(&error).lvalue())) {
      printf("AsyncTpmAttestationSignSimpleChallenge call failed: %s.\n",
             error->message);
      return 1;
    }
    client_loop.Run(async_id);
    if (!client_loop.get_return_status()) {
      printf("Attestation challenge response failed.\n");
      return 1;
    }
    std::string response_data = client_loop.get_return_data();
    base::WriteFileDescriptor(STDOUT_FILENO, response_data.data(),
                              response_data.length());
  } else if (!strcmp(switches::kActions
                         [switches::ACTION_TPM_ATTESTATION_GET_KEY_PAYLOAD],
                     action.c_str())) {
    std::string account_id = cl->GetSwitchValueASCII(switches::kUserSwitch);
    std::string key_name = cl->GetSwitchValueASCII(switches::kAttrNameSwitch);
    if (key_name.length() == 0) {
      printf("No key name specified (--%s=<name>)\n",
             switches::kAttrNameSwitch);
      return 1;
    }
    brillo::glib::ScopedArray payload;
    gboolean is_user_specific = !account_id.empty();
    brillo::glib::ScopedError error;
    gboolean success = FALSE;
    if (!org_chromium_CryptohomeInterface_tpm_attestation_get_key_payload(
            proxy.gproxy(), is_user_specific, account_id.c_str(),
            key_name.c_str(), &brillo::Resetter(&payload).lvalue(), &success,
            &brillo::Resetter(&error).lvalue())) {
      printf("AsyncTpmAttestationGetKetPayload call failed: %s.\n",
             error->message);
      return 1;
    }
    if (!success) {
      printf("AsyncTpmAttestationGetKetPayload operation failed.\n");
      return 1;
    }
    base::WriteFile(GetOutputFile(cl), payload->data, payload->len);
    base::WriteFileDescriptor(STDOUT_FILENO, payload->data, payload->len);
  } else if (!strcmp(switches::kActions
                         [switches::ACTION_TPM_ATTESTATION_SET_KEY_PAYLOAD],
                     action.c_str())) {
    std::string account_id = cl->GetSwitchValueASCII(switches::kUserSwitch);
    std::string key_name = cl->GetSwitchValueASCII(switches::kAttrNameSwitch);
    std::string value = cl->GetSwitchValueASCII(switches::kAttrValueSwitch);
    if (key_name.length() == 0) {
      printf("No key name specified (--%s=<name>)\n",
             switches::kAttrNameSwitch);
      return 1;
    }
    if (value.length() == 0) {
      printf("No payload specified (--%s=<payload>)\n",
             switches::kAttrValueSwitch);
      return 1;
    }
    brillo::glib::ScopedArray payload(g_array_new(FALSE, FALSE, 1));
    g_array_append_vals(payload.get(), value.data(), value.length());
    gboolean is_user_specific = !account_id.empty();
    brillo::glib::ScopedError error;
    gboolean success = FALSE;
    if (!org_chromium_CryptohomeInterface_tpm_attestation_set_key_payload(
            proxy.gproxy(), is_user_specific, account_id.c_str(),
            key_name.c_str(), payload.get(), &success,
            &brillo::Resetter(&error).lvalue())) {
      printf("AsyncTpmAttestationSetKetPayload call failed: %s.\n",
             error->message);
      return 1;
    }
    if (!success) {
      printf("AsyncTpmAttestationSetKetPayload operation failed.\n");
      return 1;
    }
  } else if (!strcmp(switches::kActions
                         [switches::ACTION_TPM_ATTESTATION_DELETE_KEYS],
                     action.c_str())) {
    std::string account_id = cl->GetSwitchValueASCII(switches::kUserSwitch);
    std::string key_prefix =
        cl->GetSwitchValueASCII(switches::kAttrPrefixSwitch);
    if (key_prefix.empty()) {
      printf("No key prefix specified (--%s=<prefix>)\n",
             switches::kAttrPrefixSwitch);
      return 1;
    }
    gboolean is_user_specific = !account_id.empty();
    brillo::glib::ScopedError error;
    gboolean success = FALSE;
    if (!org_chromium_CryptohomeInterface_tpm_attestation_delete_keys(
            proxy.gproxy(), is_user_specific, account_id.c_str(),
            key_prefix.c_str(), &success, &brillo::Resetter(&error).lvalue())) {
      printf("AsyncTpmAttestationDeleteKeys call failed: %s.\n",
             error->message);
      return 1;
    }
    if (!success) {
      printf("Delete operation failed.\n");
      return 1;
    }
  } else if (!strcmp(switches::kActions
                         [switches::ACTION_TPM_ATTESTATION_DELETE_KEY],
                     action.c_str())) {
    std::string account_id = cl->GetSwitchValueASCII(switches::kUserSwitch);
    std::string key_name = cl->GetSwitchValueASCII(switches::kAttrNameSwitch);
    if (key_name.empty()) {
      printf("No key name specified (--%s=<name>)\n",
             switches::kAttrNameSwitch);
      return 1;
    }
    gboolean is_user_specific = !account_id.empty();
    brillo::glib::ScopedError error;
    gboolean success = FALSE;
    if (!org_chromium_CryptohomeInterface_tpm_attestation_delete_key(
            proxy.gproxy(), is_user_specific, account_id.c_str(),
            key_name.c_str(), &success, &brillo::Resetter(&error).lvalue())) {
      printf("AsyncTpmAttestationDeleteKeys call failed: %s.\n",
             error->message);
      return 1;
    }
    if (!success) {
      printf("Delete operation failed.\n");
      return 1;
    }
  } else if (!strcmp(
                 switches::kActions[switches::ACTION_TPM_ATTESTATION_GET_EK],
                 action.c_str())) {
    if (cl->HasSwitch(switches::kProtobufSwitch)) {
      // Get the EK info as a protobuf.
      cryptohome::GetEndorsementInfoRequest request;
      cryptohome::BaseReply reply;
      if (!MakeProtoDBusCall("GetEndorsementInfo",
                             DBUS_METHOD(get_endorsement_info),
                             DBUS_METHOD(get_endorsement_info_async), cl,
                             &proxy, request, &reply, true /* print_reply */)) {
        return 1;
      }
      if (!reply.HasExtension(cryptohome::GetEndorsementInfoReply::reply)) {
        printf("GetEndorsementInfoReply missing.\n");
        return 1;
      }
      printf("GetEndorsementInfo (protobuf) success.\n");
    } else {
      brillo::glib::ScopedError error;
      gboolean success = FALSE;
      gchar* ek_info = NULL;
      if (!org_chromium_CryptohomeInterface_tpm_attestation_get_ek(
              proxy.gproxy(), &ek_info, &success,
              &brillo::Resetter(&error).lvalue())) {
        printf("AsyncTpmAttestationGetEK call failed: %s.\n", error->message);
        return 1;
      }
      if (!success) {
        printf("Failed to get EK.\n");
        g_free(ek_info);
        return 1;
      }
      printf("%s\n", ek_info);
      g_free(ek_info);
    }
  } else if (!strcmp(switches::kActions
                         [switches::ACTION_TPM_ATTESTATION_RESET_IDENTITY],
                     action.c_str())) {
    brillo::glib::ScopedError error;
    gboolean success = FALSE;
    std::string token = cl->GetSwitchValueASCII(switches::kPasswordSwitch);
    brillo::glib::ScopedArray reset_request;
    if (!org_chromium_CryptohomeInterface_tpm_attestation_reset_identity(
            proxy.gproxy(), token.c_str(),
            &brillo::Resetter(&reset_request).lvalue(), &success,
            &brillo::Resetter(&error).lvalue())) {
      printf("TpmAttestationResetIdentity call failed: %s.\n", error->message);
      return 1;
    }
    if (!success) {
      printf("Failed to get identity reset request.\n");
      return 1;
    }
    base::WriteFile(GetOutputFile(cl), reset_request->data, reset_request->len);
  } else if (!strcmp(
                 switches::kActions
                     [switches::ACTION_TPM_ATTESTATION_RESET_IDENTITY_RESULT],
                 action.c_str())) {
    std::string contents;
    if (!base::ReadFileToString(GetInputFile(cl), &contents)) {
      printf("Failed to read input file: %s\n",
             GetInputFile(cl).value().c_str());
      return 1;
    }
    cryptohome::AttestationResetResponse response;
    if (!response.ParseFromString(contents)) {
      printf("Failed to parse response.\n");
      return 1;
    }
    switch (response.status()) {
      case cryptohome::OK:
        printf("Identity reset successful.\n");
        break;
      case cryptohome::SERVER_ERROR:
        printf("Identity reset server error: %s\n", response.detail().c_str());
        break;
      case cryptohome::BAD_REQUEST:
        printf("Identity reset data error: %s\n", response.detail().c_str());
        break;
      case cryptohome::REJECT:
        printf("Identity reset request denied: %s\n",
               response.detail().c_str());
        break;
      case cryptohome::QUOTA_LIMIT_EXCEEDED:
        printf("Identity reset quota exceeded: %s\n",
               response.detail().c_str());
        break;
      default:
        printf("Identity reset unknown error: %s\n", response.detail().c_str());
    }
  } else if (!strcmp(switches::kActions[switches::ACTION_SIGN_LOCKBOX],
                     action.c_str())) {
    std::string data;
    if (!base::ReadFileToString(GetInputFile(cl), &data)) {
      printf("Failed to read input file: %s\n",
             GetInputFile(cl).value().c_str());
      return 1;
    }

    cryptohome::SignBootLockboxRequest request;
    request.set_data(data);
    cryptohome::BaseReply reply;
    if (!MakeProtoDBusCall("SignBootLockbox", DBUS_METHOD(sign_boot_lockbox),
                           DBUS_METHOD(sign_boot_lockbox_async), cl, &proxy,
                           request, &reply, true /* print_reply */)) {
      return 1;
    }

    if (!reply.HasExtension(cryptohome::SignBootLockboxReply::reply)) {
      printf("SignBootLockboxReply missing.\n");
      return 1;
    }
    std::string signature =
        reply.GetExtension(cryptohome::SignBootLockboxReply::reply).signature();
    base::WriteFile(GetOutputFile(cl).AddExtension("signature"),
                    signature.data(), signature.size());
    printf("SignBootLockbox success.\n");
  } else if (!strcmp(switches::kActions[switches::ACTION_VERIFY_LOCKBOX],
                     action.c_str())) {
    std::string data;
    if (!base::ReadFileToString(GetInputFile(cl), &data)) {
      printf("Failed to read input file: %s\n",
             GetInputFile(cl).value().c_str());
      return 1;
    }
    std::string signature;
    FilePath signature_file = GetInputFile(cl).AddExtension("signature");
    if (!base::ReadFileToString(signature_file, &signature)) {
      printf("Failed to read input file: %s\n", signature_file.value().c_str());
      return 1;
    }

    cryptohome::VerifyBootLockboxRequest request;
    request.set_data(data);
    request.set_signature(signature);
    cryptohome::BaseReply reply;
    if (!MakeProtoDBusCall("VerifyBootLockbox",
                           DBUS_METHOD(verify_boot_lockbox),
                           DBUS_METHOD(verify_boot_lockbox_async), cl, &proxy,
                           request, &reply, true /* print_reply */)) {
      return 1;
    }
    printf("VerifyBootLockbox success.\n");
  } else if (!strcmp(switches::kActions[switches::ACTION_FINALIZE_LOCKBOX],
                     action.c_str())) {
    cryptohome::FinalizeBootLockboxRequest request;
    cryptohome::BaseReply reply;
    if (!MakeProtoDBusCall("FinalizeBootLockbox",
                           DBUS_METHOD(finalize_boot_lockbox),
                           DBUS_METHOD(finalize_boot_lockbox_async), cl, &proxy,
                           request, &reply, true /* print_reply */)) {
      return 1;
    }
    printf("FinalizeBootLockbox success.\n");
  } else if (!strcmp(switches::kActions[switches::ACTION_GET_BOOT_ATTRIBUTE],
                     action.c_str())) {
    std::string name;
    if (!GetAttrName(cl, &name)) {
      printf("No attribute name specified.\n");
      return 1;
    }

    cryptohome::GetBootAttributeRequest request;
    request.set_name(name);
    cryptohome::BaseReply reply;
    if (!MakeProtoDBusCall("GetBootAttribute", DBUS_METHOD(get_boot_attribute),
                           DBUS_METHOD(get_boot_attribute_async), cl, &proxy,
                           request, &reply, true /* print_reply */)) {
      return 1;
    }
    if (!reply.HasExtension(cryptohome::GetBootAttributeReply::reply)) {
      printf("GetBootAttributeReply missing.\n");
      return 1;
    }
    std::string value =
        reply.GetExtension(cryptohome::GetBootAttributeReply::reply).value();
    printf("%s\n", value.c_str());
  } else if (!strcmp(switches::kActions[switches::ACTION_SET_BOOT_ATTRIBUTE],
                     action.c_str())) {
    std::string name;
    if (!GetAttrName(cl, &name)) {
      printf("No attribute name specified.\n");
      return 1;
    }
    std::string value;
    if (!GetAttrValue(cl, &value)) {
      printf("No attribute value specified.\n");
      return 1;
    }

    cryptohome::SetBootAttributeRequest request;
    request.set_name(name);
    request.set_value(value);
    cryptohome::BaseReply reply;
    if (!MakeProtoDBusCall("SetBootAttribute", DBUS_METHOD(set_boot_attribute),
                           DBUS_METHOD(set_boot_attribute_async), cl, &proxy,
                           request, &reply, true /* print_reply */)) {
      return 1;
    }
    printf("SetBootAttribute success.\n");
  } else if (!strcmp(switches::kActions
                         [switches::ACTION_FLUSH_AND_SIGN_BOOT_ATTRIBUTES],
                     action.c_str())) {
    cryptohome::FlushAndSignBootAttributesRequest request;
    cryptohome::BaseReply reply;
    if (!MakeProtoDBusCall("FlushAndSignBootAttributes",
                           DBUS_METHOD(flush_and_sign_boot_attributes),
                           DBUS_METHOD(flush_and_sign_boot_attributes_async),
                           cl, &proxy, request, &reply,
                           true /* print_reply */)) {
      return 1;
    }
    printf("FlushAndSignBootAttributes success.\n");
  } else if (!strcmp(switches::kActions[switches::ACTION_GET_LOGIN_STATUS],
                     action.c_str())) {
    cryptohome::GetLoginStatusRequest request;
    cryptohome::BaseReply reply;
    if (!MakeProtoDBusCall("GetLoginStatus", DBUS_METHOD(get_login_status),
                           DBUS_METHOD(get_login_status_async), cl, &proxy,
                           request, &reply, true /* print_reply */)) {
      return 1;
    }
    if (!reply.HasExtension(cryptohome::GetLoginStatusReply::reply)) {
      printf("GetLoginStatusReply missing.\n");
      return 1;
    }
    printf("GetLoginStatus success.\n");
  } else if (!strcmp(switches::kActions[switches::ACTION_INITIALIZE_CAST_KEY],
                     action.c_str())) {
    cryptohome::InitializeCastKeyRequest request;
    cryptohome::BaseReply reply;
    if (!MakeProtoDBusCall("InitializeCastKey",
                           DBUS_METHOD(initialize_cast_key),
                           DBUS_METHOD(initialize_cast_key_async), cl, &proxy,
                           request, &reply, true /* print_reply */)) {
      return 1;
    }
    printf("InitializeCastKey success.\n");
  } else if (!strcmp(switches::kActions
                         [switches::ACTION_GET_FIRMWARE_MANAGEMENT_PARAMETERS],
                     action.c_str())) {
    cryptohome::GetFirmwareManagementParametersRequest request;
    cryptohome::BaseReply reply;
    if (!MakeProtoDBusCall(
            cryptohome::kCryptohomeGetFirmwareManagementParameters,
            DBUS_METHOD(get_firmware_management_parameters),
            DBUS_METHOD(get_firmware_management_parameters_async), cl, &proxy,
            request, &reply, true /* print_reply */)) {
      return 1;
    }
    if (!reply.HasExtension(
            cryptohome::GetFirmwareManagementParametersReply::reply)) {
      printf("GetFirmwareManagementParametersReply missing.\n");
      return 1;
    }
    cryptohome::GetFirmwareManagementParametersReply get_fwmp_reply =
        reply.GetExtension(
            cryptohome::GetFirmwareManagementParametersReply::reply);
    printf("flags=0x%08x\n", get_fwmp_reply.flags());
    brillo::Blob hash =
        brillo::BlobFromString(get_fwmp_reply.developer_key_hash());
    printf("hash=%s\n", cryptohome::CryptoLib::BlobToHex(hash).c_str());
    printf("GetFirmwareManagementParameters success.\n");
  } else if (!strcmp(switches::kActions
                         [switches::ACTION_SET_FIRMWARE_MANAGEMENT_PARAMETERS],
                     action.c_str())) {
    cryptohome::SetFirmwareManagementParametersRequest request;
    cryptohome::BaseReply reply;

    if (cl->HasSwitch(switches::kFlagsSwitch)) {
      std::string flags_str = cl->GetSwitchValueASCII(switches::kFlagsSwitch);
      char* end = NULL;
      int32_t flags = strtol(flags_str.c_str(), &end, 0);
      if (end && *end != '\0') {
        printf("Bad flags value.\n");
        return 1;
      }
      request.set_flags(flags);
    } else {
      printf("Use --flags (and optionally --developer_key_hash).\n");
      return 1;
    }

    if (cl->HasSwitch(switches::kDevKeyHashSwitch)) {
      std::string hash_str =
          cl->GetSwitchValueASCII(switches::kDevKeyHashSwitch);
      brillo::Blob hash;
      if (!base::HexStringToBytes(hash_str, &hash)) {
        printf("Bad hash value.\n");
        return 1;
      }
      if (hash.size() != SHA256_DIGEST_LENGTH) {
        printf("Bad hash size.\n");
        return 1;
      }

      request.set_developer_key_hash(brillo::BlobToString(hash));
    }

    if (!MakeProtoDBusCall(
            cryptohome::kCryptohomeSetFirmwareManagementParameters,
            DBUS_METHOD(set_firmware_management_parameters),
            DBUS_METHOD(set_firmware_management_parameters_async), cl, &proxy,
            request, &reply, true /* print_reply */)) {
      return 1;
    }
    printf("SetFirmwareManagementParameters success.\n");
  } else if (!strcmp(
                 switches::kActions
                     [switches::ACTION_REMOVE_FIRMWARE_MANAGEMENT_PARAMETERS],
                 action.c_str())) {
    cryptohome::RemoveFirmwareManagementParametersRequest request;
    cryptohome::BaseReply reply;

    if (!MakeProtoDBusCall(
            cryptohome::kCryptohomeRemoveFirmwareManagementParameters,
            DBUS_METHOD(remove_firmware_management_parameters),
            DBUS_METHOD(remove_firmware_management_parameters_async), cl,
            &proxy, request, &reply, true /* print_reply */)) {
      return 1;
    }
    printf("RemoveFirmwareManagementParameters success.\n");
  } else if (!strcmp(switches::kActions[switches::ACTION_MIGRATE_TO_DIRCRYPTO],
                     action.c_str())) {
    cryptohome::AccountIdentifier id;
    if (!BuildAccountId(cl, &id))
      return 1;

    brillo::glib::ScopedArray account_ary(GArrayFromProtoBuf(id));
    if (!account_ary.get())
      return 1;

    cryptohome::MigrateToDircryptoRequest request;
    request.set_minimal_migration(cl->HasSwitch(switches::kMinimalMigration));

    brillo::glib::ScopedArray request_ary(GArrayFromProtoBuf(request));
    if (!request_ary.get())
      return 1;

    brillo::glib::ScopedError error;
    if (!org_chromium_CryptohomeInterface_migrate_to_dircrypto(
            proxy.gproxy(), account_ary.get(), request_ary.get(),
            &brillo::Resetter(&error).lvalue())) {
      printf("MigrateToDircrypto call failed: %s\n", error->message);
      return 1;
    }
    printf("MigrateToDircrypto call succeeded.\n");
  } else if (!strcmp(
                 switches::kActions[switches::ACTION_NEEDS_DIRCRYPTO_MIGRATION],
                 action.c_str())) {
    cryptohome::AccountIdentifier id;
    if (!BuildAccountId(cl, &id)) {
      printf("No account_id specified.\n");
      return 1;
    }

    brillo::glib::ScopedArray account_ary(GArrayFromProtoBuf(id));
    if (!account_ary.get())
      return 1;

    brillo::glib::ScopedError error;
    gboolean needs_migration = false;
    if (!org_chromium_CryptohomeInterface_needs_dircrypto_migration(
            proxy.gproxy(), account_ary.get(), &needs_migration,
            &brillo::Resetter(&error).lvalue())) {
      printf("NeedsDirCryptoMigration call failed: %s.\n", error->message);
      return 1;
    }
    if (needs_migration)
      printf("Yes\n");
    else
      printf("No\n");
  } else if (!strcmp(switches::kActions[switches::ACTION_GET_ENROLLMENT_ID],
                     action.c_str())) {
    gboolean success = FALSE;
    brillo::glib::ScopedArray enrollment_id;
    brillo::glib::ScopedError error;
    if (!org_chromium_CryptohomeInterface_tpm_attestation_get_enrollment_id(
            proxy.gproxy(), cl->HasSwitch(switches::kIgnoreCache),
            &brillo::Resetter(&enrollment_id).lvalue(), &success,
            &brillo::Resetter(&error).lvalue())) {
      printf("GetEnrollmentId call failed: %s.\n", error->message);
      return 1;
    }
    std::string eid_str = base::ToLowerASCII(
        base::HexEncode(enrollment_id->data, enrollment_id->len));
    printf("%s\n", eid_str.c_str());
  } else if (!strcmp(switches::kActions
                         [switches::ACTION_GET_SUPPORTED_KEY_POLICIES],
                     action.c_str())) {
    cryptohome::GetSupportedKeyPoliciesRequest request;
    cryptohome::BaseReply reply;

    if (!MakeProtoDBusCall(cryptohome::kCryptohomeGetSupportedKeyPolicies,
                           DBUS_METHOD(get_supported_key_policies),
                           DBUS_METHOD(get_supported_key_policies_async), cl,
                           &proxy, request, &reply, true /* print_reply */)) {
      return 1;
    }
    if (!reply.HasExtension(cryptohome::GetSupportedKeyPoliciesReply::reply)) {
      printf("GetSupportedKeyPoliciesReply missing.\n");
      return 1;
    }
    printf("GetSupportedKeyPolicies success.\n");
  } else if (!strcmp(
                 switches::kActions[switches::ACTION_GET_ACCOUNT_DISK_USAGE],
                 action.c_str())) {
    cryptohome::AccountIdentifier id;
    if (!BuildAccountId(cl, &id))
      return 1;

    brillo::glib::ScopedArray id_ary(GArrayFromProtoBuf(id));
    brillo::glib::ScopedError error;
    GArray* out_reply = NULL;
    if (!org_chromium_CryptohomeInterface_get_account_disk_usage(
            proxy.gproxy(), id_ary.get(), &out_reply,
            &brillo::Resetter(&error).lvalue())) {
      printf("GetAccountDiskUsage call failed: %s", error->message);
      return 1;
    }
    cryptohome::BaseReply reply;
    ParseBaseReply(out_reply, &reply, true /* print_reply */);
    if (reply.has_error()) {
      printf("GetAccountDiskUsage failed with %d.\n", reply.error());
      return reply.error();
    }
    if (!reply.HasExtension(cryptohome::GetAccountDiskUsageReply::reply)) {
      printf("GetAccountDiskUsageReply missing.\n");
      return 1;
    }
    auto ext = reply.GetExtension(cryptohome::GetAccountDiskUsageReply::reply);
    printf("Account Disk Usage in bytes: %" PRId64 "\n", ext.size());
    return 0;
  } else if (!strcmp(
                 switches::kActions
                     [switches::ACTION_LOCK_TO_SINGLE_USER_MOUNT_UNTIL_REBOOT],
                 action.c_str())) {
    cryptohome::AccountIdentifier id;
    if (!BuildAccountId(cl, &id))
      return 1;

    cryptohome::LockToSingleUserMountUntilRebootRequest request;
    request.mutable_account_id()->CopyFrom(id);
    brillo::glib::ScopedArray req_ary(GArrayFromProtoBuf(request));
    cryptohome::BaseReply reply;
    brillo::glib::ScopedError error;
    GArray* out_reply = NULL;
    if (!org_chromium_CryptohomeInterface_lock_to_single_user_mount_until_reboot(  // NOLINT
            proxy.gproxy(), req_ary.get(), &out_reply,
            &brillo::Resetter(&error).lvalue())) {
      printf("LockToSingleUserMountUntilReboot call failed: %s",
             error->message);
      return 1;
    }
    ParseBaseReply(out_reply, &reply, true /* print_reply */);
    printf("Login disabled.\n");
  } else if (!strcmp(switches::kActions[switches::ACTION_GET_RSU_DEVICE_ID],
                     action.c_str())) {
    cryptohome::GetRsuDeviceIdRequest request;
    cryptohome::BaseReply reply;
    if (!MakeProtoDBusCall("GetRsuDeviceId", DBUS_METHOD(get_rsu_device_id),
                           DBUS_METHOD(get_rsu_device_id_async), cl, &proxy,
                           request, &reply, true /* print_reply */)) {
      return 1;
    }
    if (!reply.HasExtension(cryptohome::GetRsuDeviceIdReply::reply)) {
      printf("GetRsuDeviceIdReply missing.\n");
      return 1;
    }
  } else if (!strcmp(switches::kActions[switches::ACTION_CHECK_HEALTH],
                     action.c_str())) {
    cryptohome::CheckHealthRequest request;
    cryptohome::BaseReply reply;
    if (!MakeProtoDBusCall("CheckHealth", DBUS_METHOD(check_health),
                           DBUS_METHOD(check_health_async), cl, &proxy, request,
                           &reply, true /* print_reply */)) {
      return 1;
    }
    if (!reply.HasExtension(cryptohome::CheckHealthReply::reply)) {
      printf("CheckHealthReply missing.\n");
      return 1;
    }
  } else if (!strcmp(switches::kActions[switches::ACTION_START_AUTH_SESSION],
                     action.c_str())) {
    cryptohome::AccountIdentifier id;
    if (!BuildAccountId(cl, &id))
      return 1;

    cryptohome::StartAuthSessionRequest req;

    brillo::glib::ScopedArray account_ary(GArrayFromProtoBuf(id));
    brillo::glib::ScopedArray req_ary(GArrayFromProtoBuf(req));
    if (!account_ary.get() || !req_ary.get())
      return 1;

    cryptohome::BaseReply reply;
    brillo::glib::ScopedError error;

    GArray* out_reply = NULL;
    VLOG(1) << "Attempt to start auth session.";
    if (!org_chromium_CryptohomeInterface_start_auth_session(
            proxy.gproxy(), account_ary.get(), req_ary.get(), &out_reply,
            &brillo::Resetter(&error).lvalue())) {
      return 1;
    }
    // TODO(crbug.com/1152474): Print Auth Session token here for the developer
    // to easily access token.
    ParseBaseReply(out_reply, &reply, true /* print_reply */);
    if (reply.has_error()) {
      printf("Auth session failed to start.\n");
      return reply.error();
    }
    printf("Auth session start succeeded.\n");
  } else {
    printf("Unknown action or no action given.  Available actions:\n");
    for (int i = 0; switches::kActions[i]; i++)
      printf("  --action=%s\n", switches::kActions[i]);
  }
  return 0;
}  // NOLINT(readability/fn_size)
