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

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

Issue 2838023: linux: work around gnome keyring memory corruption (Closed)
Patch Set: now with better defines 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
« 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/native_backend_gnome_x.h" 5 #include "chrome/browser/password_manager/native_backend_gnome_x.h"
6 6
7 #if defined(DLOPEN_GNOME_KEYRING)
8 #include <dlfcn.h>
9 #endif
10
11 #include <map> 7 #include <map>
12 #include <string> 8 #include <string>
13 9
10 #include <dbus/dbus-glib.h>
11 #include <dlfcn.h>
12
14 #include "base/logging.h" 13 #include "base/logging.h"
15 #include "base/string_util.h" 14 #include "base/string_util.h"
16 #include "base/time.h" 15 #include "base/time.h"
17 #include "base/utf_string_conversions.h" 16 #include "base/utf_string_conversions.h"
18 #include "chrome/browser/chrome_thread.h" 17 #include "chrome/browser/chrome_thread.h"
19 18
20 using webkit_glue::PasswordForm; 19 using webkit_glue::PasswordForm;
21 20
21 namespace {
22
22 /* Many of the gnome_keyring_* functions use variable arguments, which makes 23 /* Many of the gnome_keyring_* functions use variable arguments, which makes
23 * them difficult if not impossible to wrap in C. Therefore, we want the 24 * them difficult if not impossible to wrap in C. Therefore, we want the
24 * actual uses below to either call the functions directly (if we are linking 25 * actual uses below to either call the functions directly (if we are linking
25 * against libgnome-keyring), or call them via appropriately-typed function 26 * against libgnome-keyring), or call them via appropriately-typed function
26 * pointers (if we are dynamically loading libgnome-keyring). 27 * pointers (if we are dynamically loading libgnome-keyring).
27 * 28 *
28 * Thus, instead of making a wrapper class with two implementations, we use 29 * Thus, instead of making a wrapper class with two implementations, we use
29 * the preprocessor to rename the calls below in the dynamic load case, and 30 * the preprocessor to rename the calls below in the dynamic load case, and
30 * provide a function to initialize a set of function pointers that have the 31 * provide a function to initialize a set of function pointers that have the
31 * alternate names. We also make sure the types are correct, since otherwise 32 * alternate names. We also make sure the types are correct, since otherwise
32 * dynamic loading like this would leave us vulnerable to signature changes. */ 33 * dynamic loading like this would leave us vulnerable to signature changes. */
33 34
34 #if defined(DLOPEN_GNOME_KEYRING) 35 #if defined(DLOPEN_GNOME_KEYRING)
35 36
36 namespace { 37 // Call a given parameter with the name of each func we use from
38 // gnome keyring.
39 #define GNOME_KEYRING_FOR_EACH_FUNC(F) \
40 F(is_available) \
41 F(store_password_sync) \
42 F(delete_password_sync) \
43 F(find_itemsv_sync) \
44 F(result_to_message) \
45 F(found_list_free) \
46 F(list_item_ids_sync) \
47 F(item_get_attributes_sync) \
48 F(attribute_list_free) \
49 F(item_get_info_sync) \
50 F(item_info_get_secret) \
51 F(item_info_free)
37 52
38 gboolean (*wrap_gnome_keyring_is_available)(); 53 #define GNOME_KEYRING_DECLARE_TYPE(name) \
39 GnomeKeyringResult (*wrap_gnome_keyring_store_password_sync)( // NOLINT 54 typeof(&gnome_keyring_##name) wrap_gnome_keyring_##name;
40 const GnomeKeyringPasswordSchema* schema, const gchar* keyring, 55 GNOME_KEYRING_FOR_EACH_FUNC(GNOME_KEYRING_DECLARE_TYPE)
41 const gchar* display_name, const gchar* password, ...); 56 #undef GNOME_KEYRING_DECLARE_TYPE
42 GnomeKeyringResult (*wrap_gnome_keyring_delete_password_sync)( // NOLINT
43 const GnomeKeyringPasswordSchema* schema, ...);
44 GnomeKeyringResult (*wrap_gnome_keyring_find_itemsv_sync)( // NOLINT
45 GnomeKeyringItemType type, GList** found, ...);
46 const gchar* (*wrap_gnome_keyring_result_to_message)(GnomeKeyringResult res);
47 void (*wrap_gnome_keyring_found_list_free)(GList* found_list);
48 57
49 /* Cause the compiler to complain if the types of the above function pointers 58 // Make it easy to initialize the function pointers above with a loop below.
50 * do not correspond to the types of the actual gnome_keyring_* functions. */
51 #define GNOME_KEYRING_VERIFY_TYPE(name) \
52 typeof(&gnome_keyring_##name) name = wrap_gnome_keyring_##name; name = name
53
54 inline void VerifyGnomeKeyringTypes() {
55 GNOME_KEYRING_VERIFY_TYPE(is_available);
56 GNOME_KEYRING_VERIFY_TYPE(store_password_sync);
57 GNOME_KEYRING_VERIFY_TYPE(delete_password_sync);
58 GNOME_KEYRING_VERIFY_TYPE(find_itemsv_sync);
59 GNOME_KEYRING_VERIFY_TYPE(result_to_message);
60 GNOME_KEYRING_VERIFY_TYPE(found_list_free);
61 }
62 #undef GNOME_KEYRING_VERIFY_TYPE
63
64 /* Make it easy to initialize the function pointers above with a loop below. */
65 #define GNOME_KEYRING_FUNCTION(name) \ 59 #define GNOME_KEYRING_FUNCTION(name) \
66 {#name, reinterpret_cast<void**>(&wrap_##name)} 60 {"gnome_keyring_"#name, reinterpret_cast<void**>(&wrap_gnome_keyring_##name)},
67 const struct { 61 const struct {
68 const char* name; 62 const char* name;
69 void** pointer; 63 void** pointer;
70 } gnome_keyring_functions[] = { 64 } gnome_keyring_functions[] = {
71 GNOME_KEYRING_FUNCTION(gnome_keyring_is_available), 65 GNOME_KEYRING_FOR_EACH_FUNC(GNOME_KEYRING_FUNCTION)
72 GNOME_KEYRING_FUNCTION(gnome_keyring_store_password_sync), 66 {NULL, NULL}
73 GNOME_KEYRING_FUNCTION(gnome_keyring_delete_password_sync),
74 GNOME_KEYRING_FUNCTION(gnome_keyring_find_itemsv_sync),
75 GNOME_KEYRING_FUNCTION(gnome_keyring_result_to_message),
76 GNOME_KEYRING_FUNCTION(gnome_keyring_found_list_free),
77 {NULL, NULL}
78 }; 67 };
79 #undef GNOME_KEYRING_FUNCTION 68 #undef GNOME_KEYRING_FUNCTION
80 69
81 /* Allow application code below to use the normal function names, but actually 70 #undef GNOME_KEYRING_FOR_EACH_FUNC
82 * end up using the function pointers above instead. */ 71
72 // Allow application code below to use the normal function names, but actually
73 // end up using the function pointers above instead.
83 #define gnome_keyring_is_available \ 74 #define gnome_keyring_is_available \
84 wrap_gnome_keyring_is_available 75 wrap_gnome_keyring_is_available
85 #define gnome_keyring_store_password_sync \ 76 #define gnome_keyring_store_password_sync \
86 wrap_gnome_keyring_store_password_sync 77 wrap_gnome_keyring_store_password_sync
87 #define gnome_keyring_delete_password_sync \ 78 #define gnome_keyring_delete_password_sync \
88 wrap_gnome_keyring_delete_password_sync 79 wrap_gnome_keyring_delete_password_sync
89 #define gnome_keyring_find_itemsv_sync \ 80 #define gnome_keyring_find_itemsv_sync \
90 wrap_gnome_keyring_find_itemsv_sync 81 wrap_gnome_keyring_find_itemsv_sync
91 #define gnome_keyring_result_to_message \ 82 #define gnome_keyring_result_to_message \
92 wrap_gnome_keyring_result_to_message 83 wrap_gnome_keyring_result_to_message
93 #define gnome_keyring_found_list_free \ 84 #define gnome_keyring_found_list_free \
94 wrap_gnome_keyring_found_list_free 85 wrap_gnome_keyring_found_list_free
95 86 #define gnome_keyring_list_item_ids_sync \
96 // Older versions of GNOME Keyring have bugs that prevent them from working 87 wrap_gnome_keyring_list_item_ids_sync
97 // correctly with this code. (In particular, the non-pageable memory allocator 88 #define gnome_keyring_item_get_attributes_sync \
98 // is rather busted.) There is no official way to check the version, but newer 89 wrap_gnome_keyring_item_get_attributes_sync
99 // versions provide several symbols that older versions did not. It would be 90 #define gnome_keyring_attribute_list_free \
100 // best if we could check for a new official API, but the only new symbols are 91 wrap_gnome_keyring_attribute_list_free
101 // "private" symbols. Still, it is probable that they will not change, and it's 92 #define gnome_keyring_item_get_info_sync \
102 // the best we can do for now. (And eventually we won't care about the older 93 wrap_gnome_keyring_item_get_info_sync
103 // versions anyway so we can remove this version check some day.) 94 #define gnome_keyring_item_info_get_secret \
104 bool GnomeKeyringVersionOK(void* handle) { 95 wrap_gnome_keyring_item_info_get_secret
105 dlerror(); 96 #define gnome_keyring_item_info_free \
106 dlsym(handle, "gnome_keyring_socket_connect_daemon"); 97 wrap_gnome_keyring_item_info_free
107 return !dlerror();
108 }
109 98
110 /* Load the library and initialize the function pointers. */ 99 /* Load the library and initialize the function pointers. */
111 bool LoadGnomeKeyring() { 100 bool LoadGnomeKeyring() {
112 void* handle = dlopen("libgnome-keyring.so.0", RTLD_NOW | RTLD_GLOBAL); 101 void* handle = dlopen("libgnome-keyring.so.0", RTLD_NOW | RTLD_GLOBAL);
113 if (!handle) { 102 if (!handle) {
114 // We wanted to use GNOME Keyring, but we couldn't load it. Warn, because 103 // We wanted to use GNOME Keyring, but we couldn't load it. Warn, because
115 // either the user asked for this, or we autodetected it incorrectly. (Or 104 // either the user asked for this, or we autodetected it incorrectly. (Or
116 // the system has broken libraries, which is also good to warn about.) 105 // the system has broken libraries, which is also good to warn about.)
117 LOG(WARNING) << "Could not load libgnome-keyring.so.0: " << dlerror(); 106 LOG(WARNING) << "Could not load libgnome-keyring.so.0: " << dlerror();
118 return false; 107 return false;
119 } 108 }
120 if (!GnomeKeyringVersionOK(handle)) {
121 // GNOME Keyring is too old. Only info, not a warning, as this can happen
122 // on older systems without the user actually asking for it explicitly.
123 LOG(INFO) << "libgnome-keyring.so.0 is too old!";
124 dlclose(handle);
125 return false;
126 }
127 for (size_t i = 0; gnome_keyring_functions[i].name; ++i) { 109 for (size_t i = 0; gnome_keyring_functions[i].name; ++i) {
128 dlerror(); 110 dlerror();
129 *gnome_keyring_functions[i].pointer = 111 *gnome_keyring_functions[i].pointer =
130 dlsym(handle, gnome_keyring_functions[i].name); 112 dlsym(handle, gnome_keyring_functions[i].name);
131 const char* error = dlerror(); 113 const char* error = dlerror();
132 if (error) { 114 if (error) {
133 LOG(ERROR) << "Unable to load symbol " << 115 LOG(ERROR) << "Unable to load symbol " <<
134 gnome_keyring_functions[i].name << ": " << error; 116 gnome_keyring_functions[i].name << ": " << error;
135 dlclose(handle); 117 dlclose(handle);
136 return false; 118 return false;
137 } 119 }
138 } 120 }
139 // We leak the library handle. That's OK: this function is called only once. 121 // We leak the library handle. That's OK: this function is called only once.
140 return true; 122 return true;
141 } 123 }
142 124
143 } // namespace 125 // Older versions of GNOME Keyring have bugs that prevent them from
126 // working correctly with the find_itemsv API. (In particular, the
127 // non-pageable memory allocator is rather busted.) There is no
128 // official way to check the version, nor could we figure out any
129 // reasonable unofficial way to do it. So we work around it by using
130 // a much slower API.
131 #define GNOME_KEYRING_WORKAROUND_MEMORY_CORRUPTION
144 132
145 #else // !defined(DLOPEN_GNOME_KEYRING) 133 #else // !defined(DLOPEN_GNOME_KEYRING)
146 134
147 namespace {
148
149 bool LoadGnomeKeyring() { 135 bool LoadGnomeKeyring() {
150 // We don't do the hacky version check here. When linking directly, we assume 136 // We don't need to do anything here. When linking directly, we
151 // that whoever is compiling this code has checked that the version is OK. 137 // assume that whoever is compiling this code has checked that the
138 // version is OK.
152 return true; 139 return true;
153 } 140 }
154 141
155 } // namespace
156
157 #endif // !defined(DLOPEN_GNOME_KEYRING) 142 #endif // !defined(DLOPEN_GNOME_KEYRING)
158 143
159 #define GNOME_KEYRING_APPLICATION_CHROME "chrome" 144 #define GNOME_KEYRING_APPLICATION_CHROME "chrome"
160 145
146 // Convert the attributes of a given keyring entry into a new
147 // PasswordForm. Note: does *not* get the actual password, as that is
148 // not a key attribute! Returns NULL if the attributes are for the
149 // wrong application.
150 PasswordForm* FormFromAttributes(GnomeKeyringAttributeList* attrs) {
151 // Read the string and int attributes into the appropriate map.
152 std::map<std::string, std::string> string_attr_map;
153 std::map<std::string, uint32_t> uint_attr_map;
154 for (guint i = 0; i < attrs->len; ++i) {
155 GnomeKeyringAttribute attr = gnome_keyring_attribute_list_index(attrs, i);
156 if (attr.type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING) {
157 if (std::string(attr.name) == "application" &&
158 std::string(attr.value.string) != GNOME_KEYRING_APPLICATION_CHROME) {
159 // This is not a password we care about.
160 return NULL;
161 }
162 string_attr_map[attr.name] = attr.value.string;
163 } else if (attr.type == GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32) {
164 uint_attr_map[attr.name] = attr.value.integer;
165 }
166 }
167
168 PasswordForm* form = new PasswordForm();
169 form->origin = GURL(string_attr_map["origin_url"]);
170 form->action = GURL(string_attr_map["action_url"]);
171 form->username_element = UTF8ToUTF16(string_attr_map["username_element"]);
172 form->username_value = UTF8ToUTF16(string_attr_map["username_value"]);
173 form->password_element = UTF8ToUTF16(string_attr_map["password_element"]);
174 form->submit_element = UTF8ToUTF16(string_attr_map["submit_element"]);
175 form->signon_realm = string_attr_map["signon_realm"];
176 form->ssl_valid = uint_attr_map["ssl_valid"];
177 form->preferred = uint_attr_map["preferred"];
178 int64 date_created = 0;
179 bool date_ok = StringToInt64(string_attr_map["date_created"],
180 &date_created);
181 DCHECK(date_ok);
182 DCHECK_NE(date_created, 0);
183 form->date_created = base::Time::FromTimeT(date_created);
184 form->blacklisted_by_user = uint_attr_map["blacklisted_by_user"];
185 form->scheme = static_cast<PasswordForm::Scheme>(uint_attr_map["scheme"]);
186
187 return form;
188 }
189
190 } // namespace
191
161 // Schema is analagous to the fields in PasswordForm. 192 // Schema is analagous to the fields in PasswordForm.
162 const GnomeKeyringPasswordSchema NativeBackendGnome::kGnomeSchema = { 193 const GnomeKeyringPasswordSchema NativeBackendGnome::kGnomeSchema = {
163 GNOME_KEYRING_ITEM_GENERIC_SECRET, { 194 GNOME_KEYRING_ITEM_GENERIC_SECRET, {
164 { "origin_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 195 { "origin_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
165 { "action_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 196 { "action_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
166 { "username_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 197 { "username_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
167 { "username_value", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 198 { "username_value", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
168 { "password_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 199 { "password_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
169 { "submit_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 200 { "submit_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
170 { "signon_realm", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 201 { "signon_realm", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 return GetLoginsList(forms, true); 398 return GetLoginsList(forms, true);
368 } 399 }
369 400
370 bool NativeBackendGnome::GetBlacklistLogins(PasswordFormList* forms) { 401 bool NativeBackendGnome::GetBlacklistLogins(PasswordFormList* forms) {
371 return GetLoginsList(forms, false); 402 return GetLoginsList(forms, false);
372 } 403 }
373 404
374 bool NativeBackendGnome::GetLoginsList(PasswordFormList* forms, 405 bool NativeBackendGnome::GetLoginsList(PasswordFormList* forms,
375 bool autofillable) { 406 bool autofillable) {
376 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB)); 407 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB));
408
409 uint32_t blacklisted_by_user = !autofillable;
410
411 #if !defined(GNOME_KEYRING_WORKAROUND_MEMORY_CORRUPTION)
377 GList* found = NULL; 412 GList* found = NULL;
378 uint32_t blacklisted_by_user = !autofillable;
379 // Search gnome keyring for matching passwords. 413 // Search gnome keyring for matching passwords.
380 GnomeKeyringResult result = gnome_keyring_find_itemsv_sync( 414 GnomeKeyringResult result = gnome_keyring_find_itemsv_sync(
381 GNOME_KEYRING_ITEM_GENERIC_SECRET, 415 GNOME_KEYRING_ITEM_GENERIC_SECRET,
382 &found, 416 &found,
383 "blacklisted_by_user", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32, 417 "blacklisted_by_user", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32,
384 blacklisted_by_user, 418 blacklisted_by_user,
385 "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, 419 "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
386 GNOME_KEYRING_APPLICATION_CHROME, 420 GNOME_KEYRING_APPLICATION_CHROME,
387 NULL); 421 NULL);
388 if (result == GNOME_KEYRING_RESULT_NO_MATCH) 422 if (result == GNOME_KEYRING_RESULT_NO_MATCH)
389 return true; 423 return true;
390 if (result != GNOME_KEYRING_RESULT_OK) { 424 if (result != GNOME_KEYRING_RESULT_OK) {
391 LOG(ERROR) << "Keyring find failed: " 425 LOG(ERROR) << "Keyring find failed: "
392 << gnome_keyring_result_to_message(result); 426 << gnome_keyring_result_to_message(result);
393 return false; 427 return false;
394 } 428 }
395 ConvertFormList(found, forms); 429 ConvertFormList(found, forms);
396 return true; 430 return true;
431 #else
432 PasswordFormList all_forms;
433 if (!GetAllLogins(&all_forms))
434 return false;
435 // Now manually filter the result for the values we care about.
436 for (size_t i = 0; i < all_forms.size(); ++i) {
437 if (all_forms[i]->blacklisted_by_user == blacklisted_by_user)
438 forms->push_back(all_forms[i]);
439 else
440 delete all_forms[i];
441 }
442 return true;
443 #endif
397 } 444 }
398 445
399 bool NativeBackendGnome::GetAllLogins(PasswordFormList* forms) { 446 bool NativeBackendGnome::GetAllLogins(PasswordFormList* forms) {
447 // Older versions of GNOME Keyring have bugs that prevent them from
448 // working correctly with the find_itemsv API. (In particular, the
449 // non-pageable memory allocator is rather busted.) There is no
450 // official way to check the version, nor could we figure out any
451 // reasonable unofficial way to do it. So we work around it by
452 // using a much slower API.
453
454 #if !defined(GNOME_KEYRING_WORKAROUND_MEMORY_CORRUPTION)
400 GList* found = NULL; 455 GList* found = NULL;
401 // We need to search for something, otherwise we get no results - so we search 456 // We need to search for something, otherwise we get no results - so
402 // for the fixed application string. 457 // we search for the fixed application string.
403 GnomeKeyringResult result = gnome_keyring_find_itemsv_sync( 458 GnomeKeyringResult result = gnome_keyring_find_itemsv_sync(
404 GNOME_KEYRING_ITEM_GENERIC_SECRET, 459 GNOME_KEYRING_ITEM_GENERIC_SECRET,
405 &found, 460 &found,
406 "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, 461 "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
407 GNOME_KEYRING_APPLICATION_CHROME, 462 GNOME_KEYRING_APPLICATION_CHROME,
408 NULL); 463 NULL);
409 if (result == GNOME_KEYRING_RESULT_NO_MATCH) 464 if (result == GNOME_KEYRING_RESULT_NO_MATCH)
410 return true; 465 return true;
411 if (result != GNOME_KEYRING_RESULT_OK) { 466 if (result != GNOME_KEYRING_RESULT_OK) {
412 LOG(ERROR) << "Keyring find failed: " 467 LOG(ERROR) << "Keyring find failed: "
413 << gnome_keyring_result_to_message(result); 468 << gnome_keyring_result_to_message(result);
414 return false; 469 return false;
415 } 470 }
416 ConvertFormList(found, forms); 471 ConvertFormList(found, forms);
417 return true; 472 return true;
473 #else
474 GList* ids = NULL;
475 GnomeKeyringResult result = gnome_keyring_list_item_ids_sync(NULL, &ids);
476 if (result != GNOME_KEYRING_RESULT_OK) {
477 LOG(ERROR) << "Keyring itemid list failed: "
478 << gnome_keyring_result_to_message(result);
479 return false;
480 }
481
482 for (GList* i = ids; i; i = i->next) {
483 int id = GPOINTER_TO_INT(i->data);
484 GnomeKeyringAttributeList* attrs = NULL;
485 result = gnome_keyring_item_get_attributes_sync(NULL, id, &attrs);
486 if (result != GNOME_KEYRING_RESULT_OK) {
487 LOG(ERROR) << "Keyring get item attributes failed:"
488 << gnome_keyring_result_to_message(result);
489 gnome_keyring_attribute_list_free(attrs);
490 break;
491 }
492
493 PasswordForm* form = FormFromAttributes(attrs);
494 gnome_keyring_attribute_list_free(attrs);
495
496 if (form) {
497 GnomeKeyringItemInfo* info = NULL;
498 result = gnome_keyring_item_get_info_sync(NULL, id, &info);
499 if (result != GNOME_KEYRING_RESULT_OK) {
500 delete form;
501 break;
502 }
503 form->password_value = UTF8ToUTF16(
504 gnome_keyring_item_info_get_secret(info));
505
506 gnome_keyring_item_info_free(info);
507 forms->push_back(form);
508 }
509 }
510 g_list_free(ids);
511
512 return result == GNOME_KEYRING_RESULT_OK;
513 #endif
418 } 514 }
419 515
420 void NativeBackendGnome::ConvertFormList(GList* found, 516 void NativeBackendGnome::ConvertFormList(GList* found,
421 PasswordFormList* forms) { 517 PasswordFormList* forms) {
422 GList* element = g_list_first(found); 518 GList* element = g_list_first(found);
423 while (element != NULL) { 519 while (element != NULL) {
424 GnomeKeyringFound* data = static_cast<GnomeKeyringFound*>(element->data); 520 GnomeKeyringFound* data = static_cast<GnomeKeyringFound*>(element->data);
521 GnomeKeyringAttributeList* attrs = data->attributes;
425 522
426 GnomeKeyringAttributeList* attrs = data->attributes; 523 PasswordForm* form = FormFromAttributes(attrs);
427 // Read the string and int attributes into the appropriate map.
428 std::map<std::string, std::string> string_attr_map;
429 std::map<std::string, uint32_t> uint_attr_map;
430 for (guint i = 0; i < attrs->len; ++i) {
431 GnomeKeyringAttribute attr = gnome_keyring_attribute_list_index(attrs, i);
432 if (attr.type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING) {
433 string_attr_map[attr.name] = attr.value.string;
434 } else if (attr.type == GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32) {
435 uint_attr_map[attr.name] = attr.value.integer;
436 }
437 }
438
439 PasswordForm* form = new PasswordForm();
440 form->origin = GURL(string_attr_map["origin_url"]);
441 form->action = GURL(string_attr_map["action_url"]);
442 form->username_element = UTF8ToUTF16(string_attr_map["username_element"]);
443 form->username_value = UTF8ToUTF16(string_attr_map["username_value"]);
444 form->password_element = UTF8ToUTF16(string_attr_map["password_element"]);
445 form->password_value = UTF8ToUTF16(data->secret); 524 form->password_value = UTF8ToUTF16(data->secret);
446 form->submit_element = UTF8ToUTF16(string_attr_map["submit_element"]);
447 form->signon_realm = string_attr_map["signon_realm"];
448 form->ssl_valid = uint_attr_map["ssl_valid"];
449 form->preferred = uint_attr_map["preferred"];
450 int64 date_created = 0;
451 bool date_ok = StringToInt64(string_attr_map["date_created"],
452 &date_created);
453 DCHECK(date_ok);
454 DCHECK_NE(date_created, 0);
455 form->date_created = base::Time::FromTimeT(date_created);
456 form->blacklisted_by_user = uint_attr_map["blacklisted_by_user"];
457 form->scheme = static_cast<PasswordForm::Scheme>(uint_attr_map["scheme"]);
458
459 forms->push_back(form); 525 forms->push_back(form);
460 526
461 element = g_list_next(element); 527 element = g_list_next(element);
462 } 528 }
463 gnome_keyring_found_list_free(found); 529 gnome_keyring_found_list_free(found);
464 } 530 }
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