1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/importer/nss_decryptor.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string> 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector> 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "app/sql/connection.h" 11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "app/sql/statement.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/base64.h" 13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_split.h" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h" 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h" 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/password_form.h" 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(USE_NSS) 20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include <pk11pub.h> 21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include <pk11sdr.h> 22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif // defined(USE_NSS) 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This method is based on some Firefox code in 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// security/manager/ssl/src/nsSDR.cpp 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The license block is: 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch/* ***** BEGIN LICENSE BLOCK ***** 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch* Version: MPL 1.1/GPL 2.0/LGPL 2.1 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch* 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch* The contents of this file are subject to the Mozilla Public License Version 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch* 1.1 (the "License"); you may not use this file except in compliance with 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch* the License. You may obtain a copy of the License at 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch* http://www.mozilla.org/MPL/ 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch* 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch* Software distributed under the License is distributed on an "AS IS" basis, 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch* for the specific language governing rights and limitations under the 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch* License. 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch* 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch* The Original Code is the Netscape security libraries. 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch* 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch* The Initial Developer of the Original Code is 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch* Netscape Communications Corporation. 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch* Portions created by the Initial Developer are Copyright (C) 1994-2000 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch* the Initial Developer. All Rights Reserved. 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch* 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch* Contributor(s): 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch* 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch* Alternatively, the contents of this file may be used under the terms of 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch* either the GNU General Public License Version 2 or later (the "GPL"), or 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch* in which case the provisions of the GPL or the LGPL are applicable instead 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch* of those above. If you wish to allow use of your version of this file only 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch* under the terms of either the GPL or the LGPL, and not to allow others to 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch* use your version of this file under the terms of the MPL, indicate your 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch* decision by deleting the provisions above and replace them with the notice 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch* and other provisions required by the GPL or the LGPL. If you do not delete 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch* the provisions above, a recipient may use your version of this file under 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch* the terms of any one of the MPL, the GPL or the LGPL. 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch* 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch* ***** END LICENSE BLOCK ***** */ 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstring16 NSSDecryptor::Decrypt(const std::string& crypt) const { 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Do nothing if NSS is not loaded. 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!is_nss_initialized_) 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return string16(); 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The old style password is encoded in base64. They are identified 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // by a leading '~'. Otherwise, we should decrypt the text. 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string plain; 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (crypt[0] != '~') { 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string decoded_data; 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Base64Decode(crypt, &decoded_data); 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PK11SlotInfo* slot = GetKeySlotForDB(); 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SECStatus result = PK11_Authenticate(slot, PR_TRUE, NULL); 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (result != SECSuccess) { 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FreeSlot(slot); 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return string16(); 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SECItem request; 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.data = reinterpret_cast<unsigned char*>( 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const_cast<char*>(decoded_data.data())); 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.len = static_cast<unsigned int>(decoded_data.size()); 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SECItem reply; 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch reply.data = NULL; 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch reply.len = 0; 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(USE_NSS) 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch result = PK11SDR_DecryptWithSlot(slot, &request, &reply, NULL); 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch result = PK11SDR_Decrypt(&request, &reply, NULL); 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif // defined(USE_NSS) 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (result == SECSuccess) 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch plain.assign(reinterpret_cast<char*>(reply.data), reply.len); 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SECITEM_FreeItem(&reply, PR_FALSE); 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FreeSlot(slot); 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Deletes the leading '~' before decoding. 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Base64Decode(crypt.substr(1), &plain); 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return UTF8ToUTF16(plain); 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// There are three versions of password files. They store saved user 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// names and passwords. 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// References: 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// http://kb.mozillazine.org/Signons.txt 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// http://kb.mozillazine.org/Signons2.txt 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// http://kb.mozillazine.org/Signons3.txt 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NSSDecryptor::ParseSignons(const std::string& content, 114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::vector<webkit_glue::PasswordForm>* forms) { 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch forms->clear(); 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Splits the file content into lines. 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<std::string> lines; 119731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick base::SplitString(content, '\n', &lines); 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The first line is the file version. We skip the unknown versions. 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (lines.empty()) 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int version; 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (lines[0] == "#2c") 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch version = 1; 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else if (lines[0] == "#2d") 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch version = 2; 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else if (lines[0] == "#2e") 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch version = 3; 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL::Replacements rep; 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rep.ClearQuery(); 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rep.ClearRef(); 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rep.ClearUsername(); 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rep.ClearPassword(); 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Reads never-saved list. Domains are stored one per line. 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t i; 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (i = 1; i < lines.size() && lines[i].compare(".") != 0; ++i) { 143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen webkit_glue::PasswordForm form; 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.origin = GURL(lines[i]).ReplaceComponents(rep); 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.signon_realm = form.origin.GetOrigin().spec(); 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.blacklisted_by_user = true; 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch forms->push_back(form); 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++i; 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Reads saved passwords. The information is stored in blocks 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // seperated by lines that only contain a dot. We find a block 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // by the seperator and parse them one by one. 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (i < lines.size()) { 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t begin = i; 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t end = i + 1; 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (end < lines.size() && lines[end].compare(".") != 0) 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++end; 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch i = end + 1; 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // A block has at least five lines. 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (end - begin < 5) 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch continue; 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen webkit_glue::PasswordForm form; 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The first line is the site URL. 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // For HTTP authentication logins, the URL may contain http realm, 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // which will be in bracket: 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // sitename:8080 (realm) 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL url; 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string realm; 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char kRealmBracketBegin[] = " ("; 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char kRealmBracketEnd[] = ")"; 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (lines[begin].find(kRealmBracketBegin) != std::string::npos) { 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // In this case, the scheme may not exsit. We assume that the 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // scheme is HTTP. 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (lines[begin].find("://") == std::string::npos) 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch lines[begin] = "http://" + lines[begin]; 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t start = lines[begin].find(kRealmBracketBegin); 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url = GURL(lines[begin].substr(0, start)); 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch start += std::string(kRealmBracketBegin).size(); 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t end = lines[begin].rfind(kRealmBracketEnd); 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch realm = lines[begin].substr(start, end - start); 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Don't have http realm. It is the URL that the following passwords 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // belong to. 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url = GURL(lines[begin]); 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Skips this block if the URL is not valid. 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!url.is_valid()) 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch continue; 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.origin = url.ReplaceComponents(rep); 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.signon_realm = form.origin.GetOrigin().spec(); 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!realm.empty()) 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.signon_realm += realm; 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.ssl_valid = form.origin.SchemeIsSecure(); 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++begin; 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // There may be multiple username/password pairs for this site. 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // In this case, they are saved in one block without a seperated 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // line (contains a dot). 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (begin + 4 < end) { 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The user name. 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.username_element = UTF8ToUTF16(lines[begin++]); 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.username_value = Decrypt(lines[begin++]); 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The element name has a leading '*'. 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (lines[begin].at(0) == '*') { 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.password_element = UTF8ToUTF16(lines[begin++].substr(1)); 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.password_value = Decrypt(lines[begin++]); 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Maybe the file is bad, we skip to next block. 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The action attribute from the form element. This line exists 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // in versin 2 or above. 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (version >= 2) { 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (begin < end) 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.action = GURL(lines[begin]).ReplaceComponents(rep); 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++begin; 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Version 3 has an extra line for further use. 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (version == 3) { 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++begin; 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch forms->push_back(form); 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool NSSDecryptor::ReadAndParseSignons(const FilePath& sqlite_file, 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<webkit_glue::PasswordForm>* forms) { 236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen sql::Connection db; 237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!db.Open(sqlite_file)) 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 240ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const char* query = "SELECT hostname FROM moz_disabledHosts"; 241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen sql::Statement s(db.GetUniqueStatement(query)); 242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!s) 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL::Replacements rep; 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rep.ClearQuery(); 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rep.ClearRef(); 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rep.ClearUsername(); 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rep.ClearPassword(); 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Read domains for which passwords are never saved. 251ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen while (s.Step()) { 252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen webkit_glue::PasswordForm form; 253ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen form.origin = GURL(s.ColumnString(0)).ReplaceComponents(rep); 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.signon_realm = form.origin.GetOrigin().spec(); 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.blacklisted_by_user = true; 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch forms->push_back(form); 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 259ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const char* query2 = "SELECT hostname, httpRealm, formSubmitURL, " 260ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "usernameField, passwordField, encryptedUsername, " 261ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "encryptedPassword FROM moz_logins"; 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 263ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen sql::Statement s2(db.GetUniqueStatement(query2)); 264ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!s2) 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 267ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen while (s2.Step()) { 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL url; 269ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string realm(s2.ColumnString(1)); 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!realm.empty()) { 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // In this case, the scheme may not exsit. Assume HTTP. 272ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string host(s2.ColumnString(0)); 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (host.find("://") == std::string::npos) 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch host = "http://" + host; 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url = GURL(host); 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen url = GURL(s2.ColumnString(0)); 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Skip this row if the URL is not valid. 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!url.is_valid()) 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch continue; 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 283ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen webkit_glue::PasswordForm form; 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.origin = url.ReplaceComponents(rep); 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.signon_realm = form.origin.GetOrigin().spec(); 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!realm.empty()) 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.signon_realm += realm; 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.ssl_valid = form.origin.SchemeIsSecure(); 289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The user name, password and action. 290ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen form.username_element = s2.ColumnString16(3); 291ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen form.username_value = Decrypt(s2.ColumnString(5)); 292ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen form.password_element = s2.ColumnString16(4); 293ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen form.password_value = Decrypt(s2.ColumnString(6)); 294ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen form.action = GURL(s2.ColumnString(2)).ReplaceComponents(rep); 295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch forms->push_back(form); 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 299