blob: c8b18324ce7551d3df017f7bb26cd5b732ae8614 [file] [log] [blame]
cfroussios3b5a4e42016-05-31 11:02:181// Copyright 2016 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "components/os_crypt/key_storage_linux.h"
6
cfroussios3ea4c692016-07-18 19:15:147#include "base/environment.h"
8#include "base/lazy_instance.h"
9#include "base/logging.h"
10#include "base/nix/xdg_util.h"
cfroussiosb013c15b2016-09-03 01:10:1611#include "base/single_thread_task_runner.h"
cfroussios2f05d7f2016-08-17 15:58:5012#include "components/os_crypt/key_storage_util_linux.h"
cfroussios3ea4c692016-07-18 19:15:1413
14#if defined(USE_LIBSECRET)
cfroussios3b5a4e42016-05-31 11:02:1815#include "components/os_crypt/key_storage_libsecret.h"
cfroussios3ea4c692016-07-18 19:15:1416#endif
cfroussiosb013c15b2016-09-03 01:10:1617#if defined(USE_KEYRING)
18#include "components/os_crypt/key_storage_keyring.h"
19#endif
cfroussios2e6729a42016-07-26 09:18:1220#if defined(USE_KWALLET)
21#include "components/os_crypt/key_storage_kwallet.h"
22#endif
23
thestigc0bfd642016-08-22 18:10:3524#if defined(GOOGLE_CHROME_BUILD)
cfroussios2e6729a42016-07-26 09:18:1225const char KeyStorageLinux::kFolderName[] = "Chrome Keys";
26const char KeyStorageLinux::kKey[] = "Chrome Safe Storage";
27#else
28const char KeyStorageLinux::kFolderName[] = "Chromium Keys";
29const char KeyStorageLinux::kKey[] = "Chromium Safe Storage";
30#endif
31
cfroussiosc51d7ae192016-08-19 12:01:1432namespace {
33
34// Parameters to OSCrypt, which are set before the first call to OSCrypt, are
35// stored here.
36struct Configuration {
37 std::string store;
38 std::string product_name;
39 scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner;
40};
41
scottmg5e65e3a2017-03-08 08:48:4642base::LazyInstance<Configuration>::DestructorAtExit g_config =
43 LAZY_INSTANCE_INITIALIZER;
cfroussiosc51d7ae192016-08-19 12:01:1444
45} // namespace
cfroussios3ea4c692016-07-18 19:15:1446
47// static
48void KeyStorageLinux::SetStore(const std::string& store_type) {
cfroussiosc51d7ae192016-08-19 12:01:1449 g_config.Get().store = store_type;
cfroussios3ea4c692016-07-18 19:15:1450 VLOG(1) << "OSCrypt store set to " << store_type;
51}
cfroussios3b5a4e42016-05-31 11:02:1852
53// static
cfroussios2e6729a42016-07-26 09:18:1254void KeyStorageLinux::SetProductName(const std::string& product_name) {
cfroussiosc51d7ae192016-08-19 12:01:1455 g_config.Get().product_name = product_name;
56}
57
58// static
59void KeyStorageLinux::SetMainThreadRunner(
60 scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner) {
61 g_config.Get().main_thread_runner = main_thread_runner;
cfroussios2e6729a42016-07-26 09:18:1262}
63
64// static
cfroussios3b5a4e42016-05-31 11:02:1865std::unique_ptr<KeyStorageLinux> KeyStorageLinux::CreateService() {
slana881a862016-09-09 21:36:0766#if defined(USE_LIBSECRET) || defined(USE_KEYRING) || defined(USE_KWALLET)
cfroussios2f05d7f2016-08-17 15:58:5067 // Select a backend.
68 std::unique_ptr<base::Environment> env(base::Environment::Create());
69 base::nix::DesktopEnvironment desktop_env =
70 base::nix::GetDesktopEnvironment(env.get());
71 os_crypt::SelectedLinuxBackend selected_backend =
cfroussiosc51d7ae192016-08-19 12:01:1472 os_crypt::SelectBackend(g_config.Get().store, desktop_env);
cfroussios3b5a4e42016-05-31 11:02:1873
cfroussios2f05d7f2016-08-17 15:58:5074 // Try initializing the selected backend.
cfroussiosb013c15b2016-09-03 01:10:1675 // In case of GNOME_ANY, prefer Libsecret
cfroussios3ea4c692016-07-18 19:15:1476 std::unique_ptr<KeyStorageLinux> key_storage;
cfroussiosb013c15b2016-09-03 01:10:1677
78#if defined(USE_LIBSECRET)
cfroussios2f05d7f2016-08-17 15:58:5079 if (selected_backend == os_crypt::SelectedLinuxBackend::GNOME_ANY ||
80 selected_backend == os_crypt::SelectedLinuxBackend::GNOME_LIBSECRET) {
cfroussios3ea4c692016-07-18 19:15:1481 key_storage.reset(new KeyStorageLibsecret());
82 if (key_storage->Init()) {
83 VLOG(1) << "OSCrypt using Libsecret as backend.";
84 return key_storage;
85 }
cfroussiosb013c15b2016-09-03 01:10:1686 }
slana881a862016-09-09 21:36:0787#endif // defined(USE_LIBSECRET)
cfroussiosb013c15b2016-09-03 01:10:1688
89#if defined(USE_KEYRING)
90 if (selected_backend == os_crypt::SelectedLinuxBackend::GNOME_ANY ||
91 selected_backend == os_crypt::SelectedLinuxBackend::GNOME_KEYRING) {
92 key_storage.reset(new KeyStorageKeyring(g_config.Get().main_thread_runner));
93 if (key_storage->Init()) {
94 VLOG(1) << "OSCrypt using Keyring as backend.";
95 return key_storage;
96 }
97 }
slana881a862016-09-09 21:36:0798#endif // defined(USE_KEYRING)
cfroussiosb013c15b2016-09-03 01:10:1699
cfroussios2e6729a42016-07-26 09:18:12100#if defined(USE_KWALLET)
cfroussiosb013c15b2016-09-03 01:10:16101 if (selected_backend == os_crypt::SelectedLinuxBackend::KWALLET ||
102 selected_backend == os_crypt::SelectedLinuxBackend::KWALLET5) {
cfroussiosc51d7ae192016-08-19 12:01:14103 DCHECK(!g_config.Get().product_name.empty());
cfroussios2f05d7f2016-08-17 15:58:50104 base::nix::DesktopEnvironment used_desktop_env =
105 selected_backend == os_crypt::SelectedLinuxBackend::KWALLET
106 ? base::nix::DESKTOP_ENVIRONMENT_KDE4
107 : base::nix::DESKTOP_ENVIRONMENT_KDE5;
cfroussios2e6729a42016-07-26 09:18:12108 key_storage.reset(
cfroussiosc51d7ae192016-08-19 12:01:14109 new KeyStorageKWallet(used_desktop_env, g_config.Get().product_name));
cfroussios2e6729a42016-07-26 09:18:12110 if (key_storage->Init()) {
111 VLOG(1) << "OSCrypt using KWallet as backend.";
112 return key_storage;
113 }
cfroussios3ea4c692016-07-18 19:15:14114 }
slana881a862016-09-09 21:36:07115#endif // defined(USE_KWALLET)
116#endif // defined(USE_LIBSECRET) || defined(USE_KEYRING) ||
117 // defined(USE_KWALLET)
cfroussios3b5a4e42016-05-31 11:02:18118
cfroussios3ea4c692016-07-18 19:15:14119 // The appropriate store was not available.
120 VLOG(1) << "OSCrypt could not initialize a backend.";
cfroussios3b5a4e42016-05-31 11:02:18121 return nullptr;
122}