| OLD | NEW |
| 1 // Copyright (c) 2010 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/importer/nss_decryptor.h" | 5 #include "chrome/browser/importer/nss_decryptor.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/base64.h" |
| 10 #include "base/scoped_ptr.h" | 11 #include "base/scoped_ptr.h" |
| 12 #include "base/string_split.h" |
| 13 #include "base/string_util.h" |
| 14 #include "base/utf_string_conversions.h" |
| 11 #include "build/build_config.h" | 15 #include "build/build_config.h" |
| 12 #include "chrome/common/sqlite_utils.h" | 16 #include "chrome/common/sqlite_utils.h" |
| 17 #include "webkit/glue/password_form.h" |
| 13 | 18 |
| 14 #if defined(USE_NSS) | 19 #if defined(USE_NSS) |
| 15 #include <pk11pub.h> | 20 #include <pk11pub.h> |
| 16 #include <pk11sdr.h> | 21 #include <pk11sdr.h> |
| 17 #endif // defined(USE_NSS) | 22 #endif // defined(USE_NSS) |
| 18 | 23 |
| 19 #include "base/base64.h" | |
| 20 #include "base/string_split.h" | |
| 21 #include "base/string_util.h" | |
| 22 #include "base/utf_string_conversions.h" | |
| 23 #include "webkit/glue/password_form.h" | |
| 24 | |
| 25 using webkit_glue::PasswordForm; | |
| 26 | |
| 27 // This method is based on some Firefox code in | 24 // This method is based on some Firefox code in |
| 28 // security/manager/ssl/src/nsSDR.cpp | 25 // security/manager/ssl/src/nsSDR.cpp |
| 29 // The license block is: | 26 // The license block is: |
| 30 | 27 |
| 31 /* ***** BEGIN LICENSE BLOCK ***** | 28 /* ***** BEGIN LICENSE BLOCK ***** |
| 32 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 | 29 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
| 33 * | 30 * |
| 34 * The contents of this file are subject to the Mozilla Public License Version | 31 * The contents of this file are subject to the Mozilla Public License Version |
| 35 * 1.1 (the "License"); you may not use this file except in compliance with | 32 * 1.1 (the "License"); you may not use this file except in compliance with |
| 36 * the License. You may obtain a copy of the License at | 33 * the License. You may obtain a copy of the License at |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 return UTF8ToUTF16(plain); | 104 return UTF8ToUTF16(plain); |
| 108 } | 105 } |
| 109 | 106 |
| 110 // There are three versions of password files. They store saved user | 107 // There are three versions of password files. They store saved user |
| 111 // names and passwords. | 108 // names and passwords. |
| 112 // References: | 109 // References: |
| 113 // http://kb.mozillazine.org/Signons.txt | 110 // http://kb.mozillazine.org/Signons.txt |
| 114 // http://kb.mozillazine.org/Signons2.txt | 111 // http://kb.mozillazine.org/Signons2.txt |
| 115 // http://kb.mozillazine.org/Signons3.txt | 112 // http://kb.mozillazine.org/Signons3.txt |
| 116 void NSSDecryptor::ParseSignons(const std::string& content, | 113 void NSSDecryptor::ParseSignons(const std::string& content, |
| 117 std::vector<PasswordForm>* forms) { | 114 std::vector<webkit_glue::PasswordForm>* forms) { |
| 118 forms->clear(); | 115 forms->clear(); |
| 119 | 116 |
| 120 // Splits the file content into lines. | 117 // Splits the file content into lines. |
| 121 std::vector<std::string> lines; | 118 std::vector<std::string> lines; |
| 122 base::SplitString(content, '\n', &lines); | 119 base::SplitString(content, '\n', &lines); |
| 123 | 120 |
| 124 // The first line is the file version. We skip the unknown versions. | 121 // The first line is the file version. We skip the unknown versions. |
| 125 if (lines.empty()) | 122 if (lines.empty()) |
| 126 return; | 123 return; |
| 127 int version; | 124 int version; |
| 128 if (lines[0] == "#2c") | 125 if (lines[0] == "#2c") |
| 129 version = 1; | 126 version = 1; |
| 130 else if (lines[0] == "#2d") | 127 else if (lines[0] == "#2d") |
| 131 version = 2; | 128 version = 2; |
| 132 else if (lines[0] == "#2e") | 129 else if (lines[0] == "#2e") |
| 133 version = 3; | 130 version = 3; |
| 134 else | 131 else |
| 135 return; | 132 return; |
| 136 | 133 |
| 137 GURL::Replacements rep; | 134 GURL::Replacements rep; |
| 138 rep.ClearQuery(); | 135 rep.ClearQuery(); |
| 139 rep.ClearRef(); | 136 rep.ClearRef(); |
| 140 rep.ClearUsername(); | 137 rep.ClearUsername(); |
| 141 rep.ClearPassword(); | 138 rep.ClearPassword(); |
| 142 | 139 |
| 143 // Reads never-saved list. Domains are stored one per line. | 140 // Reads never-saved list. Domains are stored one per line. |
| 144 size_t i; | 141 size_t i; |
| 145 for (i = 1; i < lines.size() && lines[i].compare(".") != 0; ++i) { | 142 for (i = 1; i < lines.size() && lines[i].compare(".") != 0; ++i) { |
| 146 PasswordForm form; | 143 webkit_glue::PasswordForm form; |
| 147 form.origin = GURL(lines[i]).ReplaceComponents(rep); | 144 form.origin = GURL(lines[i]).ReplaceComponents(rep); |
| 148 form.signon_realm = form.origin.GetOrigin().spec(); | 145 form.signon_realm = form.origin.GetOrigin().spec(); |
| 149 form.blacklisted_by_user = true; | 146 form.blacklisted_by_user = true; |
| 150 forms->push_back(form); | 147 forms->push_back(form); |
| 151 } | 148 } |
| 152 ++i; | 149 ++i; |
| 153 | 150 |
| 154 // Reads saved passwords. The information is stored in blocks | 151 // Reads saved passwords. The information is stored in blocks |
| 155 // seperated by lines that only contain a dot. We find a block | 152 // seperated by lines that only contain a dot. We find a block |
| 156 // by the seperator and parse them one by one. | 153 // by the seperator and parse them one by one. |
| 157 while (i < lines.size()) { | 154 while (i < lines.size()) { |
| 158 size_t begin = i; | 155 size_t begin = i; |
| 159 size_t end = i + 1; | 156 size_t end = i + 1; |
| 160 while (end < lines.size() && lines[end].compare(".") != 0) | 157 while (end < lines.size() && lines[end].compare(".") != 0) |
| 161 ++end; | 158 ++end; |
| 162 i = end + 1; | 159 i = end + 1; |
| 163 | 160 |
| 164 // A block has at least five lines. | 161 // A block has at least five lines. |
| 165 if (end - begin < 5) | 162 if (end - begin < 5) |
| 166 continue; | 163 continue; |
| 167 | 164 |
| 168 PasswordForm form; | 165 webkit_glue::PasswordForm form; |
| 169 | 166 |
| 170 // The first line is the site URL. | 167 // The first line is the site URL. |
| 171 // For HTTP authentication logins, the URL may contain http realm, | 168 // For HTTP authentication logins, the URL may contain http realm, |
| 172 // which will be in bracket: | 169 // which will be in bracket: |
| 173 // sitename:8080 (realm) | 170 // sitename:8080 (realm) |
| 174 GURL url; | 171 GURL url; |
| 175 std::string realm; | 172 std::string realm; |
| 176 const char kRealmBracketBegin[] = " ("; | 173 const char kRealmBracketBegin[] = " ("; |
| 177 const char kRealmBracketEnd[] = ")"; | 174 const char kRealmBracketEnd[] = ")"; |
| 178 if (lines[begin].find(kRealmBracketBegin) != std::string::npos) { | 175 if (lines[begin].find(kRealmBracketBegin) != std::string::npos) { |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 if (s.prepare(db.get(), stmt) != SQLITE_OK) | 243 if (s.prepare(db.get(), stmt) != SQLITE_OK) |
| 247 return false; | 244 return false; |
| 248 | 245 |
| 249 GURL::Replacements rep; | 246 GURL::Replacements rep; |
| 250 rep.ClearQuery(); | 247 rep.ClearQuery(); |
| 251 rep.ClearRef(); | 248 rep.ClearRef(); |
| 252 rep.ClearUsername(); | 249 rep.ClearUsername(); |
| 253 rep.ClearPassword(); | 250 rep.ClearPassword(); |
| 254 // Read domains for which passwords are never saved. | 251 // Read domains for which passwords are never saved. |
| 255 while (s.step() == SQLITE_ROW) { | 252 while (s.step() == SQLITE_ROW) { |
| 256 PasswordForm form; | 253 webkit_glue::PasswordForm form; |
| 257 form.origin = GURL(s.column_string(0)).ReplaceComponents(rep); | 254 form.origin = GURL(s.column_string(0)).ReplaceComponents(rep); |
| 258 form.signon_realm = form.origin.GetOrigin().spec(); | 255 form.signon_realm = form.origin.GetOrigin().spec(); |
| 259 form.blacklisted_by_user = true; | 256 form.blacklisted_by_user = true; |
| 260 forms->push_back(form); | 257 forms->push_back(form); |
| 261 } | 258 } |
| 262 | 259 |
| 263 SQLStatement s2; | 260 SQLStatement s2; |
| 264 const char* stmt2 = "SELECT hostname, httpRealm, formSubmitURL, " | 261 const char* stmt2 = "SELECT hostname, httpRealm, formSubmitURL, " |
| 265 "usernameField, passwordField, encryptedUsername, " | 262 "usernameField, passwordField, encryptedUsername, " |
| 266 "encryptedPassword FROM moz_logins"; | 263 "encryptedPassword FROM moz_logins"; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 277 if (host.find("://") == std::string::npos) | 274 if (host.find("://") == std::string::npos) |
| 278 host = "http://" + host; | 275 host = "http://" + host; |
| 279 url = GURL(host); | 276 url = GURL(host); |
| 280 } else { | 277 } else { |
| 281 url = GURL(s2.column_string(0)); | 278 url = GURL(s2.column_string(0)); |
| 282 } | 279 } |
| 283 // Skip this row if the URL is not valid. | 280 // Skip this row if the URL is not valid. |
| 284 if (!url.is_valid()) | 281 if (!url.is_valid()) |
| 285 continue; | 282 continue; |
| 286 | 283 |
| 287 PasswordForm form; | 284 webkit_glue::PasswordForm form; |
| 288 form.origin = url.ReplaceComponents(rep); | 285 form.origin = url.ReplaceComponents(rep); |
| 289 form.signon_realm = form.origin.GetOrigin().spec(); | 286 form.signon_realm = form.origin.GetOrigin().spec(); |
| 290 if (!realm.empty()) | 287 if (!realm.empty()) |
| 291 form.signon_realm += realm; | 288 form.signon_realm += realm; |
| 292 form.ssl_valid = form.origin.SchemeIsSecure(); | 289 form.ssl_valid = form.origin.SchemeIsSecure(); |
| 293 // The user name, password and action. | 290 // The user name, password and action. |
| 294 form.username_element = UTF8ToUTF16(s2.column_string(3)); | 291 form.username_element = UTF8ToUTF16(s2.column_string(3)); |
| 295 form.username_value = Decrypt(s2.column_string(5)); | 292 form.username_value = Decrypt(s2.column_string(5)); |
| 296 form.password_element = UTF8ToUTF16(s2.column_string(4)); | 293 form.password_element = UTF8ToUTF16(s2.column_string(4)); |
| 297 form.password_value = Decrypt(s2.column_string(6)); | 294 form.password_value = Decrypt(s2.column_string(6)); |
| 298 form.action = GURL(s2.column_string(2)).ReplaceComponents(rep); | 295 form.action = GURL(s2.column_string(2)).ReplaceComponents(rep); |
| 299 forms->push_back(form); | 296 forms->push_back(form); |
| 300 } | 297 } |
| 301 return true; | 298 return true; |
| 302 } | 299 } |
| OLD | NEW |