Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(550)

Side by Side Diff: chrome/browser/password_manager/native_backend_gnome_x.cc

Issue 7396013: Linux: revive a mysteriously disabled test and add tests for the GNOME Keyring native backend. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/password_manager/native_backend_gnome_x.h" 5 #include "chrome/browser/password_manager/native_backend_gnome_x.h"
6 6
7 #include <dlfcn.h> 7 #include <dlfcn.h>
8 #include <gnome-keyring.h> 8 #include <gnome-keyring.h>
9 9
10 #include <map> 10 #include <map>
11 #include <string> 11 #include <string>
12 #include <vector> 12 #include <vector>
13 13
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/string_number_conversions.h" 15 #include "base/string_number_conversions.h"
16 #include "base/string_piece.h" 16 #include "base/string_piece.h"
17 #include "base/string_util.h" 17 #include "base/string_util.h"
18 #include "base/stringprintf.h" 18 #include "base/stringprintf.h"
19 #include "base/time.h" 19 #include "base/time.h"
20 #include "base/utf_string_conversions.h" 20 #include "base/utf_string_conversions.h"
21 #include "base/synchronization/waitable_event.h" 21 #include "base/synchronization/waitable_event.h"
22 #include "content/browser/browser_thread.h" 22 #include "content/browser/browser_thread.h"
23 23
24 using webkit_glue::PasswordForm; 24 using webkit_glue::PasswordForm;
25 25
26 namespace { 26 #define GNOME_KEYRING_DEFINE_POINTER(name) \
27 typeof(&::gnome_keyring_##name) GnomeKeyringLoader::gnome_keyring_##name;
28 GNOME_KEYRING_FOR_EACH_FUNC(GNOME_KEYRING_DEFINE_POINTER)
29 #undef GNOME_KEYRING_DEFINE_POINTER
27 30
28 // Many of the gnome_keyring_* functions use variable arguments, which makes 31 bool GnomeKeyringLoader::keyring_loaded = false;
29 // them difficult if not impossible to wrap in C. Therefore, we want the
30 // actual uses below to either call the functions directly (if we are linking
31 // against libgnome-keyring), or call them via appropriately-typed function
32 // pointers (if we are dynamically loading libgnome-keyring).
33
34 // Thus, instead of making a wrapper class with two implementations, we use
35 // the preprocessor to rename the calls below in the dynamic load case, and
36 // provide a function to initialize a set of function pointers that have the
37 // alternate names. We also make sure the types are correct, since otherwise
38 // dynamic loading like this would leave us vulnerable to signature changes.
39 32
40 #if defined(DLOPEN_GNOME_KEYRING) 33 #if defined(DLOPEN_GNOME_KEYRING)
41 34
42 // Call a given parameter with the name of each function we use from GNOME 35 #define GNOME_KEYRING_FUNCTION_INFO(name) \
43 // Keyring. 36 {"gnome_keyring_"#name, reinterpret_cast<void**>(&gnome_keyring_##name)},
44 #define GNOME_KEYRING_FOR_EACH_FUNC(F) \ 37 const GnomeKeyringLoader::FunctionInfo GnomeKeyringLoader::functions[] = {
45 F(is_available) \ 38 GNOME_KEYRING_FOR_EACH_FUNC(GNOME_KEYRING_FUNCTION_INFO)
46 F(store_password) \
47 F(delete_password) \
48 F(find_itemsv) \
49 F(result_to_message)
50
51 // Define the actual function pointers that we'll use in application code.
52 #define GNOME_KEYRING_DEFINE_WRAPPER(name) \
53 typeof(&gnome_keyring_##name) wrap_gnome_keyring_##name;
54 GNOME_KEYRING_FOR_EACH_FUNC(GNOME_KEYRING_DEFINE_WRAPPER)
55 #undef GNOME_KEYRING_DEFINE_WRAPPER
56
57 // Make it easy to initialize the function pointers above with a loop below.
58 #define GNOME_KEYRING_FUNCTION(name) \
59 {"gnome_keyring_"#name, reinterpret_cast<void**>(&wrap_gnome_keyring_##name)},
60 const struct {
61 const char* name;
62 void** pointer;
63 } gnome_keyring_functions[] = {
64 GNOME_KEYRING_FOR_EACH_FUNC(GNOME_KEYRING_FUNCTION)
65 {NULL, NULL} 39 {NULL, NULL}
66 }; 40 };
67 #undef GNOME_KEYRING_FUNCTION 41 #undef GNOME_KEYRING_FUNCTION_INFO
68
69 #undef GNOME_KEYRING_FOR_EACH_FUNC
70
71 // Allow application code below to use the normal function names, but actually
72 // end up using the function pointers above instead.
73 #define gnome_keyring_is_available \
74 wrap_gnome_keyring_is_available
75 #define gnome_keyring_store_password \
76 wrap_gnome_keyring_store_password
77 #define gnome_keyring_delete_password \
78 wrap_gnome_keyring_delete_password
79 #define gnome_keyring_find_itemsv \
80 wrap_gnome_keyring_find_itemsv
81 #define gnome_keyring_result_to_message \
82 wrap_gnome_keyring_result_to_message
83 42
84 /* Load the library and initialize the function pointers. */ 43 /* Load the library and initialize the function pointers. */
85 bool LoadGnomeKeyring() { 44 bool GnomeKeyringLoader::LoadGnomeKeyring() {
45 if (keyring_loaded)
46 return true;
47
86 void* handle = dlopen("libgnome-keyring.so.0", RTLD_NOW | RTLD_GLOBAL); 48 void* handle = dlopen("libgnome-keyring.so.0", RTLD_NOW | RTLD_GLOBAL);
87 if (!handle) { 49 if (!handle) {
88 // We wanted to use GNOME Keyring, but we couldn't load it. Warn, because 50 // We wanted to use GNOME Keyring, but we couldn't load it. Warn, because
89 // either the user asked for this, or we autodetected it incorrectly. (Or 51 // either the user asked for this, or we autodetected it incorrectly. (Or
90 // the system has broken libraries, which is also good to warn about.) 52 // the system has broken libraries, which is also good to warn about.)
91 LOG(WARNING) << "Could not load libgnome-keyring.so.0: " << dlerror(); 53 LOG(WARNING) << "Could not load libgnome-keyring.so.0: " << dlerror();
92 return false; 54 return false;
93 } 55 }
94 for (size_t i = 0; gnome_keyring_functions[i].name; ++i) { 56
57 for (size_t i = 0; functions[i].name; ++i) {
95 dlerror(); 58 dlerror();
96 *gnome_keyring_functions[i].pointer = 59 *functions[i].pointer = dlsym(handle, functions[i].name);
97 dlsym(handle, gnome_keyring_functions[i].name);
98 const char* error = dlerror(); 60 const char* error = dlerror();
99 if (error) { 61 if (error) {
100 LOG(ERROR) << "Unable to load symbol " 62 LOG(ERROR) << "Unable to load symbol "
101 << gnome_keyring_functions[i].name << ": " << error; 63 << functions[i].name << ": " << error;
102 dlclose(handle); 64 dlclose(handle);
103 return false; 65 return false;
104 } 66 }
105 } 67 }
68
69 keyring_loaded = true;
106 // We leak the library handle. That's OK: this function is called only once. 70 // We leak the library handle. That's OK: this function is called only once.
107 return true; 71 return true;
108 } 72 }
109 73
110 #else // !defined(DLOPEN_GNOME_KEYRING) 74 #else // defined(DLOPEN_GNOME_KEYRING)
111 75
112 bool LoadGnomeKeyring() { 76 bool GnomeKeyringLoader::LoadGnomeKeyring() {
113 // We don't need to do anything here. 77 if (keyring_loaded)
78 return true;
79 #define GNOME_KEYRING_ASSIGN_POINTER(name) \
80 gnome_keyring_##name = &::gnome_keyring_##name;
81 GNOME_KEYRING_FOR_EACH_FUNC(GNOME_KEYRING_ASSIGN_POINTER)
82 #undef GNOME_KEYRING_ASSIGN_POINTER
83 keyring_loaded = true;
114 return true; 84 return true;
115 } 85 }
116 86
117 #endif // !defined(DLOPEN_GNOME_KEYRING) 87 #endif // defined(DLOPEN_GNOME_KEYRING)
88
89 namespace {
118 90
119 const char kGnomeKeyringAppString[] = "chrome"; 91 const char kGnomeKeyringAppString[] = "chrome";
120 92
121 // Convert the attributes of a given keyring entry into a new PasswordForm. 93 // Convert the attributes of a given keyring entry into a new PasswordForm.
122 // Note: does *not* get the actual password, as that is not a key attribute! 94 // Note: does *not* get the actual password, as that is not a key attribute!
123 // Returns NULL if the attributes are for the wrong application. 95 // Returns NULL if the attributes are for the wrong application.
124 PasswordForm* FormFromAttributes(GnomeKeyringAttributeList* attrs) { 96 PasswordForm* FormFromAttributes(GnomeKeyringAttributeList* attrs) {
125 // Read the string and int attributes into the appropriate map. 97 // Read the string and int attributes into the appropriate map.
126 std::map<std::string, std::string> string_attr_map; 98 std::map<std::string, std::string> string_attr_map;
127 std::map<std::string, uint32_t> uint_attr_map; 99 std::map<std::string, uint32_t> uint_attr_map;
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 // caller, e.g. in the password management UI), and *block* the DB thread 186 // caller, e.g. in the password management UI), and *block* the DB thread
215 // waiting for a response from the UI thread to provide the synchronous API 187 // waiting for a response from the UI thread to provide the synchronous API
216 // PasswordStore expects of us. (It will then in turn switch back to the 188 // PasswordStore expects of us. (It will then in turn switch back to the
217 // original caller to send the asynchronous reply to the original request.) 189 // original caller to send the asynchronous reply to the original request.)
218 190
219 // This class represents a call to a GNOME Keyring method. A RunnableMethod 191 // This class represents a call to a GNOME Keyring method. A RunnableMethod
220 // should be posted to the UI thread to call one of its action methods, and then 192 // should be posted to the UI thread to call one of its action methods, and then
221 // a WaitResult() method should be called to wait for the result. Each instance 193 // a WaitResult() method should be called to wait for the result. Each instance
222 // supports only one outstanding method at a time, though multiple instances may 194 // supports only one outstanding method at a time, though multiple instances may
223 // be used in parallel. 195 // be used in parallel.
224 class GKRMethod { 196 class GKRMethod : public GnomeKeyringLoader {
225 public: 197 public:
226 typedef NativeBackendGnome::PasswordFormList PasswordFormList; 198 typedef NativeBackendGnome::PasswordFormList PasswordFormList;
227 199
228 GKRMethod() : event_(false, false), result_(GNOME_KEYRING_RESULT_CANCELLED) {} 200 GKRMethod() : event_(false, false), result_(GNOME_KEYRING_RESULT_CANCELLED) {}
229 201
230 // Action methods. These call gnome_keyring_* functions. Call from UI thread. 202 // Action methods. These call gnome_keyring_* functions. Call from UI thread.
231 // See GetProfileSpecificAppString() for more information on the app string. 203 // See GetProfileSpecificAppString() for more information on the app string.
232 void AddLogin(const PasswordForm& form, const char* app_string); 204 void AddLogin(const PasswordForm& form, const char* app_string);
233 void AddLoginSearch(const PasswordForm& form, const char* app_string); 205 void AddLoginSearch(const PasswordForm& form, const char* app_string);
234 void UpdateLoginSearch(const PasswordForm& form, const char* app_string); 206 void UpdateLoginSearch(const PasswordForm& form, const char* app_string);
(...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after
754 // Each other profile must be able to migrate the shared data as well, 726 // Each other profile must be able to migrate the shared data as well,
755 // so we must leave it alone. After a few releases, we'll add code to 727 // so we must leave it alone. After a few releases, we'll add code to
756 // delete them, and eventually remove this migration code. 728 // delete them, and eventually remove this migration code.
757 // TODO(mdm): follow through with the plan above. 729 // TODO(mdm): follow through with the plan above.
758 PasswordStoreX::SetPasswordsUseLocalProfileId(prefs_); 730 PasswordStoreX::SetPasswordsUseLocalProfileId(prefs_);
759 } else { 731 } else {
760 // We failed to migrate for some reason. Use the old app string. 732 // We failed to migrate for some reason. Use the old app string.
761 app_string_ = kGnomeKeyringAppString; 733 app_string_ = kGnomeKeyringAppString;
762 } 734 }
763 } 735 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698