119 lines
4.3 KiB
C#
119 lines
4.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Text.RegularExpressions;
|
|
using Seatbelt.Output.TextWriters;
|
|
using Seatbelt.Output.Formatters;
|
|
|
|
|
|
namespace Seatbelt.Commands.Browser
|
|
{
|
|
internal class FirefoxHistoryCommand : CommandBase
|
|
{
|
|
public override string Command => "FirefoxHistory";
|
|
public override string Description => "Parses any found FireFox history files";
|
|
public override CommandGroup[] Group => new[] { CommandGroup.Misc };
|
|
public override bool SupportRemote => true;
|
|
public Runtime ThisRunTime;
|
|
|
|
public FirefoxHistoryCommand(Runtime runtime) : base(runtime)
|
|
{
|
|
ThisRunTime = runtime;
|
|
}
|
|
|
|
public override IEnumerable<CommandDTOBase?> Execute(string[] args)
|
|
{
|
|
var dirs = ThisRunTime.GetDirectories("\\Users\\");
|
|
|
|
foreach (var dir in dirs)
|
|
{
|
|
var parts = dir.Split('\\');
|
|
var userName = parts[parts.Length - 1];
|
|
|
|
if (dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") ||
|
|
dir.EndsWith("All Users"))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var userFirefoxBasePath = $"{dir}\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\";
|
|
|
|
// parses a Firefox history file via regex
|
|
if (Directory.Exists(userFirefoxBasePath))
|
|
{
|
|
var history = new List<string>();
|
|
var directories = Directory.GetDirectories(userFirefoxBasePath);
|
|
|
|
foreach (var directory in directories)
|
|
{
|
|
var firefoxHistoryFile = $"{directory}\\places.sqlite";
|
|
var historyRegex = new Regex(@"(http|ftp|https|file)://([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?");
|
|
|
|
try
|
|
{
|
|
using (var r = new StreamReader(firefoxHistoryFile))
|
|
{
|
|
string line;
|
|
while ((line = r.ReadLine()) != null)
|
|
{
|
|
var m = historyRegex.Match(line);
|
|
if (m.Success)
|
|
{
|
|
// WriteHost(" " + m.Groups[0].ToString().Trim());
|
|
history.Add(m.Groups[0].ToString().Trim());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (IOException exception)
|
|
{
|
|
WriteError($"IO exception, places.sqlite file likely in use (i.e. Firefox is likely running). {exception.Message}");
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
WriteError(e.ToString());
|
|
}
|
|
}
|
|
|
|
yield return new FirefoxHistoryDTO(
|
|
userName,
|
|
history
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
internal class FirefoxHistoryDTO : CommandDTOBase
|
|
{
|
|
public FirefoxHistoryDTO(string userName, List<string> history)
|
|
{
|
|
UserName = userName;
|
|
History = history;
|
|
}
|
|
public string UserName { get; }
|
|
public List<string> History { get; }
|
|
}
|
|
|
|
[CommandOutputType(typeof(FirefoxHistoryDTO))]
|
|
internal class InternetExplorerFavoritesFormatter : TextFormatterBase
|
|
{
|
|
public InternetExplorerFavoritesFormatter(ITextWriter writer) : base(writer)
|
|
{
|
|
}
|
|
|
|
public override void FormatResult(CommandBase? command, CommandDTOBase result, bool filterResults)
|
|
{
|
|
var dto = (FirefoxHistoryDTO)result;
|
|
|
|
WriteLine($"\n History ({dto.UserName}):\n");
|
|
|
|
foreach (var history in dto.History)
|
|
{
|
|
WriteLine($" {history}");
|
|
}
|
|
WriteLine();
|
|
}
|
|
}
|
|
}
|
|
}
|