OLD | NEW |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |