in Cli/AttackSurfaceAnalyzerClient.cs [891:1007]
private static ASA_ERROR RunMonitorCommand(MonitorCommandOptions opts)
{
if (DatabaseManager is null)
{
Log.Error("Err_DatabaseManagerNull", "RunMonitorCommand");
return ASA_ERROR.DATABASE_NULL;
}
if (opts.RunId is string)
{
opts.RunId = opts.RunId.Trim();
}
else
{
opts.RunId = DateTime.Now.ToString("o", CultureInfo.InvariantCulture);
}
if (opts.Overwrite)
{
DatabaseManager.DeleteRun(opts.RunId);
}
else
{
if (DatabaseManager.GetRun(opts.RunId) != null)
{
Log.Error(Strings.Get("Err_RunIdAlreadyUsed"));
return ASA_ERROR.UNIQUE_ID;
}
}
var run = new AsaRun(RunId: opts.RunId, Timestamp: DateTime.Now, Version: AsaHelpers.GetVersionString(), Platform: AsaHelpers.GetPlatform(), new List<RESULT_TYPE>() { RESULT_TYPE.FILEMONITOR }, RUN_TYPE.MONITOR);
DatabaseManager.InsertRun(run);
var returnValue = ASA_ERROR.NONE;
if (opts.EnableFileSystemMonitor)
{
monitors.Add(new FileSystemMonitor(opts, x => DatabaseManager.Write(x, opts.RunId)));
}
if (monitors.Count == 0)
{
Log.Warning(Strings.Get("Err_NoMonitors"));
returnValue = ASA_ERROR.NO_COLLECTORS;
}
using var exitEvent = new ManualResetEvent(false);
// If duration is set, we use the secondary timer.
if (opts.Duration > 0)
{
Log.Information("{0} {1} {2}.", Strings.Get("MonitorStartedFor"), opts.Duration, Strings.Get("Minutes"));
using var aTimer = new System.Timers.Timer
{
Interval = opts.Duration * 60 * 1000, //lgtm [cs/loss-of-precision]
AutoReset = false,
};
aTimer.Elapsed += (source, e) => { exitEvent.Set(); };
// Start the timer
aTimer.Enabled = true;
}
foreach (FileSystemMonitor c in monitors)
{
Log.Information(Strings.Get("Begin"), c.GetType().Name);
try
{
c.StartRun();
}
catch (Exception ex)
{
Log.Error(Strings.Get("Err_CollectingFrom"), c.GetType().Name, ex.Message, ex.StackTrace);
returnValue = ASA_ERROR.UNKNOWN;
}
}
void consoleCancelDelegate(object? sender, ConsoleCancelEventArgs args)
{
args.Cancel = true;
exitEvent.Set();
};
// Set up the event to capture CTRL+C
Console.CancelKeyPress += consoleCancelDelegate;
Console.Write(Strings.Get("MonitoringPressC"));
// Write a spinner and wait until CTRL+C
WriteSpinner(exitEvent);
Log.Information("");
foreach (var c in monitors)
{
Log.Information(Strings.Get("End"), c.GetType().Name);
try
{
c.StopRun();
if (c is FileSystemMonitor)
{
((FileSystemMonitor)c).Dispose();
}
}
catch (Exception ex)
{
Log.Error(ex, " {0}: {1}", c.GetType().Name, ex.Message, Strings.Get("Err_Stopping"));
}
}
FlushResults();
DatabaseManager.Commit();
Console.CancelKeyPress -= consoleCancelDelegate;
return returnValue;
}