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

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

Issue 2696002: Linux: make GNOME keyring password store able to use libgnome-keyring via dlopen. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 6 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/password_store_gnome.h" 5 #include "chrome/browser/password_manager/password_store_gnome.h"
6 6
7 #if defined(DLOPEN_GNOME_KEYRING)
8 #include <dlfcn.h>
9 #endif
10
11 #include <map>
7 #include <string> 12 #include <string>
8 13
9 #include "base/logging.h" 14 #include "base/logging.h"
10 #include "base/string_util.h" 15 #include "base/string_util.h"
11 #include "base/task.h" 16 #include "base/task.h"
12 #include "base/time.h" 17 #include "base/time.h"
13 #include "base/utf_string_conversions.h" 18 #include "base/utf_string_conversions.h"
14 19
15 using std::map; 20 using std::map;
16 using std::string; 21 using std::string;
17 using std::vector; 22 using std::vector;
18 using webkit_glue::PasswordForm; 23 using webkit_glue::PasswordForm;
19 24
25 /* Many of the gnome_keyring_* functions use variable arguments, which makes
26 * them difficult if not impossible to wrap in C. Therefore, we want the
27 * actual uses below to either call the functions directly (if we are linking
28 * against libgnome-keyring), or call them via appropriately-typed function
29 * pointers (if we are dynamically loading libgnome-keyring).
30 *
31 * Thus, instead of making a wrapper class with two implementations, we use
32 * the preprocessor to rename the calls below in the dynamic load case, and
33 * provide a function to initialize a set of function pointers that have the
34 * alternate names. We also make sure the types are correct, since otherwise
35 * dynamic loading like this would leave us vulnerable to signature changes. */
36
37 #if defined(DLOPEN_GNOME_KEYRING)
38
39 namespace {
40
41 gboolean (*wrap_gnome_keyring_is_available)();
42 GnomeKeyringResult (*wrap_gnome_keyring_store_password_sync)( // NOLINT
43 const GnomeKeyringPasswordSchema* schema, const gchar* keyring,
44 const gchar* display_name, const gchar* password, ...);
45 GnomeKeyringResult (*wrap_gnome_keyring_delete_password_sync)( // NOLINT
46 const GnomeKeyringPasswordSchema* schema, ...);
47 GnomeKeyringResult (*wrap_gnome_keyring_find_itemsv_sync)( // NOLINT
48 GnomeKeyringItemType type, GList** found, ...);
49 const gchar* (*wrap_gnome_keyring_result_to_message)(GnomeKeyringResult res);
50 void (*wrap_gnome_keyring_found_list_free)(GList* found_list);
51
52 /* Cause the compiler to complain if the types of the above function pointers
53 * do not correspond to the types of the actual gnome_keyring_* functions. */
54 #define GNOME_KEYRING_VERIFY_TYPE(name) \
55 typeof(&gnome_keyring_##name) name = wrap_gnome_keyring_##name; name = name
56
57 inline void VerifyGnomeKeyringTypes() {
58 GNOME_KEYRING_VERIFY_TYPE(is_available);
59 GNOME_KEYRING_VERIFY_TYPE(store_password_sync);
60 GNOME_KEYRING_VERIFY_TYPE(delete_password_sync);
61 GNOME_KEYRING_VERIFY_TYPE(find_itemsv_sync);
62 GNOME_KEYRING_VERIFY_TYPE(result_to_message);
63 GNOME_KEYRING_VERIFY_TYPE(found_list_free);
64 }
65 #undef GNOME_KEYRING_VERIFY_TYPE
66
67 /* Make it easy to initialize the function pointers above with a loop below. */
68 #define GNOME_KEYRING_FUNCTION(name) \
69 {#name, reinterpret_cast<void**>(&wrap_##name)}
70 const struct {
71 const char* name;
72 void** pointer;
73 } gnome_keyring_functions[] = {
74 GNOME_KEYRING_FUNCTION(gnome_keyring_is_available),
75 GNOME_KEYRING_FUNCTION(gnome_keyring_store_password_sync),
76 GNOME_KEYRING_FUNCTION(gnome_keyring_delete_password_sync),
77 GNOME_KEYRING_FUNCTION(gnome_keyring_find_itemsv_sync),
78 GNOME_KEYRING_FUNCTION(gnome_keyring_result_to_message),
79 GNOME_KEYRING_FUNCTION(gnome_keyring_found_list_free),
80 {NULL, NULL}
81 };
82 #undef GNOME_KEYRING_FUNCTION
83
84 /* Allow application code below to use the normal function names, but actually
85 * end up using the function pointers above instead. */
86 #define gnome_keyring_is_available \
87 wrap_gnome_keyring_is_available
88 #define gnome_keyring_store_password_sync \
89 wrap_gnome_keyring_store_password_sync
90 #define gnome_keyring_delete_password_sync \
91 wrap_gnome_keyring_delete_password_sync
92 #define gnome_keyring_find_itemsv_sync \
93 wrap_gnome_keyring_find_itemsv_sync
94 #define gnome_keyring_result_to_message \
95 wrap_gnome_keyring_result_to_message
96 #define gnome_keyring_found_list_free \
97 wrap_gnome_keyring_found_list_free
98
99 /* Load the library and initialize the function pointers. */
100 bool LoadGnomeKeyring() {
101 void* handle = dlopen("libgnome-keyring.so.0", RTLD_NOW | RTLD_GLOBAL);
102 if (!handle) {
103 LOG(INFO) << "Could not find libgnome-keyring.so.0";
104 return false;
105 }
106 for (size_t i = 0; gnome_keyring_functions[i].name; ++i) {
107 dlerror();
108 *gnome_keyring_functions[i].pointer =
109 dlsym(handle, gnome_keyring_functions[i].name);
110 const char* error = dlerror();
111 if (error) {
112 LOG(ERROR) << "Unable to load symbol " <<
113 gnome_keyring_functions[i].name << ": " << error;
114 dlclose(handle);
115 return false;
116 }
117 }
118 // We leak the library handle. That's OK: this function is called only once.
119 return true;
120 }
121
122 } // namespace
123
124 #else // DLOPEN_GNOME_KEYRING
125
126 namespace {
127
128 bool LoadGnomeKeyring() {
129 return true;
130 }
131
132 } // namespace
133
134 #endif // DLOPEN_GNOME_KEYRING
135
20 #define GNOME_KEYRING_APPLICATION_CHROME "chrome" 136 #define GNOME_KEYRING_APPLICATION_CHROME "chrome"
21 137
22 // Schema is analagous to the fields in PasswordForm. 138 // Schema is analagous to the fields in PasswordForm.
23 const GnomeKeyringPasswordSchema PasswordStoreGnome::kGnomeSchema = { 139 const GnomeKeyringPasswordSchema PasswordStoreGnome::kGnomeSchema = {
24 GNOME_KEYRING_ITEM_GENERIC_SECRET, { 140 GNOME_KEYRING_ITEM_GENERIC_SECRET, {
25 { "origin_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 141 { "origin_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
26 { "action_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 142 { "action_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
27 { "username_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 143 { "username_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
28 { "username_value", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 144 { "username_value", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
29 { "password_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 145 { "password_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
(...skipping 12 matching lines...) Expand all
42 158
43 PasswordStoreGnome::PasswordStoreGnome(LoginDatabase* login_db, 159 PasswordStoreGnome::PasswordStoreGnome(LoginDatabase* login_db,
44 Profile* profile, 160 Profile* profile,
45 WebDataService* web_data_service) { 161 WebDataService* web_data_service) {
46 } 162 }
47 163
48 PasswordStoreGnome::~PasswordStoreGnome() { 164 PasswordStoreGnome::~PasswordStoreGnome() {
49 } 165 }
50 166
51 bool PasswordStoreGnome::Init() { 167 bool PasswordStoreGnome::Init() {
52 return PasswordStore::Init() && gnome_keyring_is_available(); 168 return PasswordStore::Init() &&
169 LoadGnomeKeyring() &&
170 gnome_keyring_is_available();
53 } 171 }
54 172
55 void PasswordStoreGnome::AddLoginImpl(const PasswordForm& form) { 173 void PasswordStoreGnome::AddLoginImpl(const PasswordForm& form) {
56 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB)); 174 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB));
57 AddLoginHelper(form, base::Time::Now()); 175 AddLoginHelper(form, base::Time::Now());
58 } 176 }
59 177
60 void PasswordStoreGnome::UpdateLoginImpl(const PasswordForm& form) { 178 void PasswordStoreGnome::UpdateLoginImpl(const PasswordForm& form) {
61 // Based on LoginDatabase::UpdateLogin(), we search for forms to update by 179 // Based on LoginDatabase::UpdateLogin(), we search for forms to update by
62 // origin_url, username_element, username_value, password_element, and 180 // origin_url, username_element, username_value, password_element, and
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 form->password_value = UTF8ToUTF16(string(password)); 412 form->password_value = UTF8ToUTF16(string(password));
295 form->submit_element = 413 form->submit_element =
296 UTF8ToUTF16(string(string_attribute_map["submit_element"])); 414 UTF8ToUTF16(string(string_attribute_map["submit_element"]));
297 form->signon_realm = string_attribute_map["signon_realm"]; 415 form->signon_realm = string_attribute_map["signon_realm"];
298 form->ssl_valid = uint_attribute_map["ssl_valid"]; 416 form->ssl_valid = uint_attribute_map["ssl_valid"];
299 form->preferred = uint_attribute_map["preferred"]; 417 form->preferred = uint_attribute_map["preferred"];
300 string date = string_attribute_map["date_created"]; 418 string date = string_attribute_map["date_created"];
301 int64 date_created = 0; 419 int64 date_created = 0;
302 bool date_ok = StringToInt64(date, &date_created); 420 bool date_ok = StringToInt64(date, &date_created);
303 DCHECK(date_ok); 421 DCHECK(date_ok);
304 DCHECK(date_created != 0); 422 DCHECK_NE(date_created, 0);
305 form->date_created = base::Time::FromTimeT(date_created); 423 form->date_created = base::Time::FromTimeT(date_created);
306 form->blacklisted_by_user = uint_attribute_map["blacklisted_by_user"]; 424 form->blacklisted_by_user = uint_attribute_map["blacklisted_by_user"];
307 form->scheme = static_cast<PasswordForm::Scheme>( 425 form->scheme = static_cast<PasswordForm::Scheme>(
308 uint_attribute_map["scheme"]); 426 uint_attribute_map["scheme"]);
309 427
310 forms->push_back(form); 428 forms->push_back(form);
311 429
312 element = g_list_next(element); 430 element = g_list_next(element);
313 } 431 }
314 gnome_keyring_found_list_free(found); 432 gnome_keyring_found_list_free(found);
315 } 433 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698