Chromium Code Reviews| Index: components/os_crypt/key_storage_keyring.cc |
| diff --git a/components/os_crypt/key_storage_keyring.cc b/components/os_crypt/key_storage_keyring.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..5104b52ffab46c1d50a20ec0121668be678c8e27 |
| --- /dev/null |
| +++ b/components/os_crypt/key_storage_keyring.cc |
| @@ -0,0 +1,106 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "components/os_crypt/key_storage_keyring.h" |
| + |
| +#include <gnome-keyring.h> |
| + |
| +#include "base/base64.h" |
| +#include "base/bind.h" |
| +#include "base/rand_util.h" |
| +#include "base/single_thread_task_runner.h" |
| +#include "base/strings/string_number_conversions.h" |
| +#include "base/synchronization/waitable_event.h" |
| +#include "base/threading/thread.h" |
| +#include "components/os_crypt/keyring_util_linux.h" |
| + |
| +namespace { |
| + |
| +#if defined(GOOGLE_CHROME_BUILD) |
| +const char kApplicationName[] = "chrome"; |
| +#else |
| +const char kApplicationName[] = "chromium"; |
| +#endif |
| + |
| +const GnomeKeyringPasswordSchema kSchema = { |
| + GNOME_KEYRING_ITEM_GENERIC_SECRET, |
| + {{"application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING}, {nullptr}}}; |
| + |
| +} // namespace |
| + |
| +KeyStorageKeyring::KeyStorageKeyring( |
| + scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner) |
| + : main_thread_runner_(main_thread_runner) { |
| + thread_checker_.DetachFromThread(); |
| +} |
| + |
| +KeyStorageKeyring::~KeyStorageKeyring() {} |
| + |
| +bool KeyStorageKeyring::Init() { |
| + return GnomeKeyringLoader::LoadGnomeKeyring(); |
| +} |
| + |
| +std::string KeyStorageKeyring::GetKey() { |
| + std::string password; |
| + |
| + // Ensure GetKeyDelegate() is executed on the main thread. |
| + if (main_thread_runner_->BelongsToCurrentThread()) { |
| + GetKeyDelegate(&password, nullptr); |
| + } else { |
| + base::WaitableEvent password_loaded( |
| + base::WaitableEvent::ResetPolicy::MANUAL, |
| + base::WaitableEvent::InitialState::NOT_SIGNALED); |
| + main_thread_runner_->PostTask( |
| + FROM_HERE, |
| + base::Bind(&KeyStorageKeyring::GetKeyDelegate, base::Unretained(this), |
| + &password, &password_loaded)); |
| + password_loaded.Wait(); |
| + } |
| + |
| + return password; |
| +} |
| + |
| +void KeyStorageKeyring::GetKeyDelegate( |
|
Lei Zhang
2016/09/01 07:56:31
Can these be inside an anonymous namespace, instea
cfroussios
2016/09/01 10:58:16
AddRandomPasswordInKeyring() needs access to prote
|
| + std::string* password_ptr, |
| + base::WaitableEvent* password_loaded_ptr) { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| + |
| + gchar* password = nullptr; |
| + GnomeKeyringResult result = |
| + GnomeKeyringLoader::gnome_keyring_find_password_sync_ptr( |
| + &kSchema, &password, "application", kApplicationName, nullptr); |
| + if (result == GNOME_KEYRING_RESULT_OK) { |
| + *password_ptr = password; |
| + GnomeKeyringLoader::gnome_keyring_free_password_ptr(password); |
| + } else if (result == GNOME_KEYRING_RESULT_NO_MATCH) { |
| + *password_ptr = KeyStorageKeyring::AddRandomPasswordInKeyring(); |
| + VLOG(1) << "OSCrypt generated a new password"; |
| + } else { |
| + password_ptr->clear(); |
| + VLOG(1) << "OSCrypt failed to use gnome-keyring"; |
| + } |
| + |
| + if (password_loaded_ptr) |
|
Lei Zhang
2016/09/01 07:56:31
Is this ever false?
cfroussios
2016/09/01 10:58:16
When GetKey() is called on the main thread.
Lei Zhang
2016/09/01 17:16:40
Right, that's what I get for doing late night revi
|
| + password_loaded_ptr->Signal(); |
| +} |
| + |
| +std::string KeyStorageKeyring::AddRandomPasswordInKeyring() { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| + |
| + // Generate password |
| + std::string password; |
| + base::Base64Encode(base::RandBytesAsString(16), &password); |
| + |
| + // Store generated password |
| + GnomeKeyringResult result = |
| + GnomeKeyringLoader::gnome_keyring_store_password_sync_ptr( |
| + &kSchema, nullptr /* default keyring */, KeyStorageLinux::kKey, |
| + password.c_str(), "application", kApplicationName, nullptr); |
| + if (result != GNOME_KEYRING_RESULT_OK) { |
| + VLOG(1) << "Failed to store generated password to gnome-keyring"; |
| + return std::string(); |
| + } |
| + |
| + return password; |
| +} |