OLD | NEW |
| (Empty) |
1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/password_manager/password_store_gnome.h" | |
6 | |
7 #include <string> | |
8 | |
9 #include "base/logging.h" | |
10 #include "base/string_util.h" | |
11 #include "base/task.h" | |
12 #include "base/time.h" | |
13 | |
14 using std::map; | |
15 using std::string; | |
16 using std::vector; | |
17 | |
18 // Schema is analagous to the fields in PasswordForm. | |
19 const GnomeKeyringPasswordSchema PasswordStoreGnome::kGnomeSchema = { | |
20 GNOME_KEYRING_ITEM_GENERIC_SECRET, { | |
21 { "origin_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | |
22 { "action_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | |
23 { "username_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | |
24 { "username_value", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | |
25 { "password_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | |
26 { "submit_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | |
27 { "signon_realm", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | |
28 { "ssl_valid", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, | |
29 { "preferred", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, | |
30 { "date_created", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | |
31 { "blacklisted_by_user", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, | |
32 { "scheme", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, | |
33 { NULL } | |
34 } | |
35 }; | |
36 | |
37 PasswordStoreGnome::PasswordStoreGnome() { | |
38 } | |
39 | |
40 PasswordStoreGnome::~PasswordStoreGnome() { | |
41 } | |
42 | |
43 bool PasswordStoreGnome::Init() { | |
44 return PasswordStore::Init() && gnome_keyring_is_available(); | |
45 } | |
46 | |
47 void PasswordStoreGnome::AddLoginImpl(const PasswordForm& form) { | |
48 AutoLock l(gnome_keyring_lock_); | |
49 GnomeKeyringResult result = gnome_keyring_store_password_sync( | |
50 &kGnomeSchema, | |
51 NULL, // Default keyring. | |
52 // TODO(johnmaguire@google.com): Localise this. | |
53 "Form password stored by Chrome", | |
54 WideToASCII(form.password_value).c_str(), | |
55 "origin_url", form.origin.spec().c_str(), | |
56 "action_url", form.action.spec().c_str(), | |
57 "username_element", form.username_element.c_str(), | |
58 "username_value", form.username_value.c_str(), | |
59 "password_element", form.password_element.c_str(), | |
60 "submit_element", form.submit_element.c_str(), | |
61 "signon_realm", form.signon_realm.c_str(), | |
62 "ssl_valid", form.ssl_valid, | |
63 "preferred", form.preferred, | |
64 "date_created", Int64ToString(base::Time::Now().ToTimeT()).c_str(), | |
65 "blacklisted_by_user", form.blacklisted_by_user, | |
66 "scheme", form.scheme, | |
67 NULL); | |
68 | |
69 if (result != GNOME_KEYRING_RESULT_OK) { | |
70 LOG(ERROR) << "Keyring save failed: " | |
71 << gnome_keyring_result_to_message(result); | |
72 } | |
73 } | |
74 | |
75 void PasswordStoreGnome::UpdateLoginImpl(const PasswordForm& form) { | |
76 AddLoginImpl(form); // Add & Update are the same in gnome keyring. | |
77 } | |
78 | |
79 void PasswordStoreGnome::RemoveLoginImpl(const PasswordForm& form) { | |
80 AutoLock l(gnome_keyring_lock_); | |
81 GnomeKeyringResult result = gnome_keyring_delete_password_sync( | |
82 &kGnomeSchema, | |
83 "origin_url", form.origin.spec().c_str(), | |
84 "action_url", form.action.spec().c_str(), | |
85 "username_element", form.username_element.c_str(), | |
86 "username_value", form.username_value.c_str(), | |
87 "password_element", form.password_element.c_str(), | |
88 "submit_element", form.submit_element.c_str(), | |
89 "signon_realm", form.signon_realm.c_str(), | |
90 "ssl_valid", form.ssl_valid, | |
91 "preferred", form.preferred, | |
92 "date_created", Int64ToString(form.date_created.ToTimeT()).c_str(), | |
93 "blacklisted_by_user", form.blacklisted_by_user, | |
94 "scheme", form.scheme, | |
95 NULL); | |
96 if (result != GNOME_KEYRING_RESULT_OK) { | |
97 LOG(ERROR) << "Keyring delete failed: " | |
98 << gnome_keyring_result_to_message(result); | |
99 } | |
100 } | |
101 | |
102 void PasswordStoreGnome::GetLoginsImpl(GetLoginsRequest* request) { | |
103 AutoLock l(gnome_keyring_lock_); | |
104 GList* found = NULL; | |
105 // Search gnome keyring for matching passwords. | |
106 GnomeKeyringResult result = gnome_keyring_find_itemsv_sync( | |
107 GNOME_KEYRING_ITEM_GENERIC_SECRET, | |
108 &found, | |
109 "signon_realm", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, | |
110 request->form.signon_realm.c_str(), | |
111 NULL); | |
112 vector<PasswordForm*> forms; | |
113 if (result == GNOME_KEYRING_RESULT_NO_MATCH) { | |
114 NotifyConsumer(request, forms); | |
115 return; | |
116 } else if (result != GNOME_KEYRING_RESULT_OK) { | |
117 LOG(ERROR) << "Keyring find failed: " | |
118 << gnome_keyring_result_to_message(result); | |
119 NotifyConsumer(request, forms); | |
120 return; | |
121 } | |
122 | |
123 // Parse all the results from the returned GList into a | |
124 // vector<PasswordForm*>. PasswordForms are allocated on the heap. These | |
125 // will be deleted by the consumer. | |
126 GList* element = g_list_first(found); | |
127 while (element != NULL) { | |
128 GnomeKeyringFound* data = static_cast<GnomeKeyringFound*>(element->data); | |
129 char* password = data->secret; | |
130 | |
131 GnomeKeyringAttributeList* attributes = data->attributes; | |
132 // Read the string & int attributes into the appropriate map. | |
133 map<string, string> string_attribute_map; | |
134 map<string, uint32> uint_attribute_map; | |
135 for (unsigned int i = 0; i < attributes->len; ++i) { | |
136 GnomeKeyringAttribute attribute = | |
137 gnome_keyring_attribute_list_index(attributes, i); | |
138 if (attribute.type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING) { | |
139 string_attribute_map[string(attribute.name)] = | |
140 string(attribute.value.string); | |
141 } else if (attribute.type == GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32) { | |
142 uint_attribute_map[string(attribute.name)] = attribute.value.integer; | |
143 } | |
144 } | |
145 | |
146 PasswordForm* form = new PasswordForm(); | |
147 form->origin = GURL(string_attribute_map["origin_url"]); | |
148 form->action = GURL(string_attribute_map["action_url"]); | |
149 form->username_element = | |
150 ASCIIToWide(string(string_attribute_map["username_element"])); | |
151 form->username_value = | |
152 ASCIIToWide(string(string_attribute_map["username_value"])); | |
153 form->password_element = | |
154 ASCIIToWide(string(string_attribute_map["password_element"])); | |
155 form->password_value = ASCIIToWide(string(password)); | |
156 form->submit_element = | |
157 ASCIIToWide(string(string_attribute_map["submit_element"])); | |
158 form->signon_realm = uint_attribute_map["signon_realm"]; | |
159 form->ssl_valid = uint_attribute_map["ssl_valid"]; | |
160 form->preferred = uint_attribute_map["preferred"]; | |
161 string date = string_attribute_map["date_created"]; | |
162 int64 date_created = 0; | |
163 DCHECK(StringToInt64(date, &date_created) && date_created != 0); | |
164 form->date_created = base::Time::FromTimeT(date_created); | |
165 form->blacklisted_by_user = uint_attribute_map["blacklisted_by_user"]; | |
166 form->scheme = | |
167 static_cast<PasswordForm::Scheme>(uint_attribute_map["scheme"]); | |
168 | |
169 forms.push_back(form); | |
170 | |
171 element = g_list_next(element); | |
172 } | |
173 gnome_keyring_found_list_free(found); | |
174 found = NULL; | |
175 | |
176 NotifyConsumer(request, forms); | |
177 } | |
OLD | NEW |