blob: 783eda940cae6b76b6571e57ccc8b54a2fc749e0 [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
42base::LazyInstance<Configuration> g_config = LAZY_INSTANCE_INITIALIZER;
43
44} // namespace
cfroussios3ea4c692016-07-18 19:15:1445
46// static
47void KeyStorageLinux::SetStore(const std::string& store_type) {
cfroussiosc51d7ae192016-08-19 12:01:1448 g_config.Get().store = store_type;
cfroussios3ea4c692016-07-18 19:15:1449 VLOG(1) << "OSCrypt store set to " << store_type;
50}
cfroussios3b5a4e42016-05-31 11:02:1851
52// static
cfroussios2e6729a42016-07-26 09:18:1253void KeyStorageLinux::SetProductName(const std::string& product_name) {
cfroussiosc51d7ae192016-08-19 12:01:1454 g_config.Get().product_name = product_name;
55}
56
57// static
58void KeyStorageLinux::SetMainThreadRunner(
59 scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner) {
60 g_config.Get().main_thread_runner = main_thread_runner;
cfroussios2e6729a42016-07-26 09:18:1261}
62
63// static
cfroussios3b5a4e42016-05-31 11:02:1864std::unique_ptr<KeyStorageLinux> KeyStorageLinux::CreateService() {
cfroussios2f05d7f2016-08-17 15:58:5065 // Select a backend.
66 std::unique_ptr<base::Environment> env(base::Environment::Create());
67 base::nix::DesktopEnvironment desktop_env =
68 base::nix::GetDesktopEnvironment(env.get());
69 os_crypt::SelectedLinuxBackend selected_backend =
cfroussiosc51d7ae192016-08-19 12:01:1470 os_crypt::SelectBackend(g_config.Get().store, desktop_env);
cfroussios3b5a4e42016-05-31 11:02:1871
cfroussios2f05d7f2016-08-17 15:58:5072 // Try initializing the selected backend.
cfroussiosb013c15b2016-09-03 01:10:1673 // In case of GNOME_ANY, prefer Libsecret
cfroussios3ea4c692016-07-18 19:15:1474 std::unique_ptr<KeyStorageLinux> key_storage;
cfroussiosb013c15b2016-09-03 01:10:1675
76#if defined(USE_LIBSECRET)
cfroussios2f05d7f2016-08-17 15:58:5077 if (selected_backend == os_crypt::SelectedLinuxBackend::GNOME_ANY ||
78 selected_backend == os_crypt::SelectedLinuxBackend::GNOME_LIBSECRET) {
cfroussios3ea4c692016-07-18 19:15:1479 key_storage.reset(new KeyStorageLibsecret());
80 if (key_storage->Init()) {
81 VLOG(1) << "OSCrypt using Libsecret as backend.";
82 return key_storage;
83 }
cfroussiosb013c15b2016-09-03 01:10:1684 }
cfroussios3ea4c692016-07-18 19:15:1485#endif
cfroussiosb013c15b2016-09-03 01:10:1686
87#if defined(USE_KEYRING)
88 if (selected_backend == os_crypt::SelectedLinuxBackend::GNOME_ANY ||
89 selected_backend == os_crypt::SelectedLinuxBackend::GNOME_KEYRING) {
90 key_storage.reset(new KeyStorageKeyring(g_config.Get().main_thread_runner));
91 if (key_storage->Init()) {
92 VLOG(1) << "OSCrypt using Keyring as backend.";
93 return key_storage;
94 }
95 }
96#endif
97
cfroussios2e6729a42016-07-26 09:18:1298#if defined(USE_KWALLET)
cfroussiosb013c15b2016-09-03 01:10:1699 if (selected_backend == os_crypt::SelectedLinuxBackend::KWALLET ||
100 selected_backend == os_crypt::SelectedLinuxBackend::KWALLET5) {
cfroussiosc51d7ae192016-08-19 12:01:14101 DCHECK(!g_config.Get().product_name.empty());
cfroussios2f05d7f2016-08-17 15:58:50102 base::nix::DesktopEnvironment used_desktop_env =
103 selected_backend == os_crypt::SelectedLinuxBackend::KWALLET
104 ? base::nix::DESKTOP_ENVIRONMENT_KDE4
105 : base::nix::DESKTOP_ENVIRONMENT_KDE5;
cfroussios2e6729a42016-07-26 09:18:12106 key_storage.reset(
cfroussiosc51d7ae192016-08-19 12:01:14107 new KeyStorageKWallet(used_desktop_env, g_config.Get().product_name));
cfroussios2e6729a42016-07-26 09:18:12108 if (key_storage->Init()) {
109 VLOG(1) << "OSCrypt using KWallet as backend.";
110 return key_storage;
111 }
cfroussios3ea4c692016-07-18 19:15:14112 }
cfroussiosb013c15b2016-09-03 01:10:16113#endif
cfroussios3b5a4e42016-05-31 11:02:18114
cfroussios3ea4c692016-07-18 19:15:14115 // The appropriate store was not available.
116 VLOG(1) << "OSCrypt could not initialize a backend.";
cfroussios3b5a4e42016-05-31 11:02:18117 return nullptr;
118}