Index: components/os_crypt/keyring_util_linux.cc |
diff --git a/components/os_crypt/keyring_util_linux.cc b/components/os_crypt/keyring_util_linux.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..300a344b985516953eea0d940a7592c5b15a8c37 |
--- /dev/null |
+++ b/components/os_crypt/keyring_util_linux.cc |
@@ -0,0 +1,82 @@ |
+// 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/keyring_util_linux.h" |
+ |
+#include <dlfcn.h> |
+ |
+#include "base/logging.h" |
+ |
+decltype(&::gnome_keyring_is_available) |
+ GnomeKeyringLoader::gnome_keyring_is_available_ptr; |
+decltype(&::gnome_keyring_store_password) |
+ GnomeKeyringLoader::gnome_keyring_store_password_ptr; |
+decltype(&::gnome_keyring_delete_password) |
+ GnomeKeyringLoader::gnome_keyring_delete_password_ptr; |
+decltype(&::gnome_keyring_find_items) |
+ GnomeKeyringLoader::gnome_keyring_find_items_ptr; |
+decltype(&::gnome_keyring_result_to_message) |
+ GnomeKeyringLoader::gnome_keyring_result_to_message_ptr; |
+decltype(&::gnome_keyring_attribute_list_free) |
+ GnomeKeyringLoader::gnome_keyring_attribute_list_free_ptr; |
+decltype(&::gnome_keyring_attribute_list_new) |
+ GnomeKeyringLoader::gnome_keyring_attribute_list_new_ptr; |
+decltype(&::gnome_keyring_attribute_list_append_string) |
+ GnomeKeyringLoader::gnome_keyring_attribute_list_append_string_ptr; |
+decltype(&::gnome_keyring_attribute_list_append_uint32) |
+ GnomeKeyringLoader::gnome_keyring_attribute_list_append_uint32_ptr; |
+ |
+bool GnomeKeyringLoader::keyring_loaded = false; |
+ |
+const GnomeKeyringLoader::FunctionInfo GnomeKeyringLoader::functions[] = { |
+ {"gnome_keyring_is_available", |
+ reinterpret_cast<void**>(&gnome_keyring_is_available_ptr)}, |
+ {"gnome_keyring_store_password", |
+ reinterpret_cast<void**>(&gnome_keyring_store_password_ptr)}, |
+ {"gnome_keyring_delete_password", |
+ reinterpret_cast<void**>(&gnome_keyring_delete_password_ptr)}, |
+ {"gnome_keyring_find_items", |
+ reinterpret_cast<void**>(&gnome_keyring_find_items_ptr)}, |
+ {"gnome_keyring_result_to_message", |
+ reinterpret_cast<void**>(&gnome_keyring_result_to_message_ptr)}, |
+ {"gnome_keyring_attribute_list_free", |
+ reinterpret_cast<void**>(&gnome_keyring_attribute_list_free_ptr)}, |
+ {"gnome_keyring_attribute_list_new", |
+ reinterpret_cast<void**>(&gnome_keyring_attribute_list_new_ptr)}, |
+ {"gnome_keyring_attribute_list_append_string", |
+ reinterpret_cast<void**>(&gnome_keyring_attribute_list_append_string_ptr)}, |
+ {"gnome_keyring_attribute_list_append_uint32", |
+ reinterpret_cast<void**>( |
+ &gnome_keyring_attribute_list_append_uint32_ptr)}}; |
+ |
+/* Load the library and initialize the function pointers. */ |
+bool GnomeKeyringLoader::LoadGnomeKeyring() { |
+ if (keyring_loaded) |
+ return true; |
+ |
+ void* handle = dlopen("libgnome-keyring.so.0", RTLD_NOW | RTLD_GLOBAL); |
+ if (!handle) { |
+ // We wanted to use GNOME Keyring, but we couldn't load it. Warn, because |
+ // either the user asked for this, or we autodetected it incorrectly. (Or |
+ // the system has broken libraries, which is also good to warn about.) |
+ LOG(WARNING) << "Could not load libgnome-keyring.so.0: " << dlerror(); |
+ return false; |
+ } |
+ |
+ for (size_t i = 0; i < arraysize(functions); ++i) { |
+ dlerror(); |
+ *functions[i].pointer = dlsym(handle, functions[i].name); |
+ const char* error = dlerror(); |
+ if (error) { |
+ LOG(ERROR) << "Unable to load symbol " << functions[i].name << ": " |
+ << error; |
+ dlclose(handle); |
+ return false; |
+ } |
+ } |
+ |
+ keyring_loaded = true; |
+ // We leak the library handle. That's OK: this function is called only once. |
+ return true; |
+} |