public static ASA_ERROR RunCollectCommand()

in Cli/AttackSurfaceAnalyzerClient.cs [1196:1422]


        public static ASA_ERROR RunCollectCommand(CollectCommandOptions opts)
        {
            if (DatabaseManager is null)
            {
                Log.Error("Err_DatabaseManagerNull", "RunCollectCommand");
                return ASA_ERROR.DATABASE_NULL;
            }
            if (opts == null) { return ASA_ERROR.NO_COLLECTORS; }
            collectors.Clear();
            AdminOrWarn();

            opts.RunId = opts.RunId?.Trim() ?? DateTime.Now.ToString("o", CultureInfo.InvariantCulture);

            if (opts.MatchedCollectorId != null)
            {
                var matchedRun = DatabaseManager.GetRun(opts.MatchedCollectorId);
                if (matchedRun is AsaRun)
                {
                    foreach (var resultType in matchedRun.ResultTypes)
                    {
                        switch (resultType)
                        {
                            case RESULT_TYPE.FILE:
                                opts.EnableFileSystemCollector = true;
                                break;

                            case RESULT_TYPE.PORT:
                                opts.EnableNetworkPortCollector = true;
                                break;

                            case RESULT_TYPE.CERTIFICATE:
                                opts.EnableCertificateCollector = true;
                                break;

                            case RESULT_TYPE.COM:
                                opts.EnableComObjectCollector = true;
                                break;

                            case RESULT_TYPE.FIREWALL:
                                opts.EnableFirewallCollector = true;
                                break;

                            case RESULT_TYPE.LOG:
                                opts.EnableEventLogCollector = true;
                                break;

                            case RESULT_TYPE.SERVICE:
                                opts.EnableServiceCollector = true;
                                break;

                            case RESULT_TYPE.USER:
                                opts.EnableUserCollector = true;
                                break;

                            case RESULT_TYPE.KEY:
                                opts.EnableKeyCollector = true;
                                break;

                            case RESULT_TYPE.TPM:
                                opts.EnableTpmCollector = true;
                                break;

                            case RESULT_TYPE.PROCESS:
                                opts.EnableProcessCollector = true;
                                break;

                            case RESULT_TYPE.DRIVER:
                                opts.EnableDriverCollector = true;
                                break;

                            case RESULT_TYPE.WIFI:
                                opts.EnableWifiCollector = true;
                                break;
                        }
                    }
                }
            }

            Action<CollectObject> defaultChangeHandler = x => DatabaseManager.Write(x, opts.RunId);

            var dict = new List<RESULT_TYPE>();

            if (opts.EnableFileSystemCollector || opts.EnableAllCollectors)
            {
                collectors.Add(new FileSystemCollector(opts, defaultChangeHandler));
                dict.Add(RESULT_TYPE.FILE);
            }
            if (opts.EnableNetworkPortCollector || opts.EnableAllCollectors)
            {
                collectors.Add(new OpenPortCollector(opts, defaultChangeHandler));
                dict.Add(RESULT_TYPE.PORT);
            }
            if (opts.EnableServiceCollector || opts.EnableAllCollectors)
            {
                collectors.Add(new ServiceCollector(opts, defaultChangeHandler));
                dict.Add(RESULT_TYPE.SERVICE);
            }
            if (opts.EnableUserCollector || opts.EnableAllCollectors)
            {
                collectors.Add(new UserAccountCollector(opts, defaultChangeHandler));
                dict.Add(RESULT_TYPE.USER);
            }
            if (opts.EnableRegistryCollector || (opts.EnableAllCollectors && RuntimeInformation.IsOSPlatform(OSPlatform.Windows)))
            {
                collectors.Add(new RegistryCollector(opts, defaultChangeHandler));
                dict.Add(RESULT_TYPE.REGISTRY);
            }
            if (opts.EnableCertificateCollector || opts.EnableAllCollectors)
            {
                collectors.Add(new CertificateCollector(opts, defaultChangeHandler));
                dict.Add(RESULT_TYPE.CERTIFICATE);
            }
            if (opts.EnableFirewallCollector || opts.EnableAllCollectors)
            {
                collectors.Add(new FirewallCollector(opts, defaultChangeHandler));
                dict.Add(RESULT_TYPE.FIREWALL);
            }
            if (opts.EnableComObjectCollector || (opts.EnableAllCollectors && RuntimeInformation.IsOSPlatform(OSPlatform.Windows)))
            {
                collectors.Add(new ComObjectCollector(opts, defaultChangeHandler));
                dict.Add(RESULT_TYPE.COM);
            }
            if (opts.EnableEventLogCollector || opts.EnableAllCollectors)
            {
                collectors.Add(new EventLogCollector(opts, defaultChangeHandler));
                dict.Add(RESULT_TYPE.LOG);
            }
            if (opts.EnableTpmCollector || (opts.EnableAllCollectors && (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || RuntimeInformation.IsOSPlatform(OSPlatform.Linux))))
            {
                collectors.Add(new TpmCollector(opts, defaultChangeHandler));
                dict.Add(RESULT_TYPE.TPM);
            }
            if (opts.EnableKeyCollector || opts.EnableAllCollectors && (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)))
            {
                collectors.Add(new CryptographicKeyCollector(opts, defaultChangeHandler));
                dict.Add(RESULT_TYPE.KEY);
            }
            if (opts.EnableProcessCollector || opts.EnableAllCollectors)
            {
                collectors.Add(new ProcessCollector(opts, defaultChangeHandler));
                dict.Add(RESULT_TYPE.PROCESS);
            }
            if (opts.EnableDriverCollector || opts.EnableAllCollectors)
            {
                collectors.Add(new DriverCollector(opts, defaultChangeHandler));
                dict.Add(RESULT_TYPE.DRIVER);
            }
            if (opts.EnableWifiCollector || opts.EnableAllCollectors)
            {
                collectors.Add(new WifiCollector(opts, defaultChangeHandler));
                dict.Add(RESULT_TYPE.WIFI);
            }

            if (collectors.Count == 0)
            {
                Log.Warning(Strings.Get("Err_NoCollectors"));
                return ASA_ERROR.NO_COLLECTORS;
            }

            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;
                }
            }
            Log.Information(Strings.Get("Begin"), opts.RunId);

            var run = new AsaRun(RunId: opts.RunId, Timestamp: DateTime.Now, Version: AsaHelpers.GetVersionString(), Platform: AsaHelpers.GetPlatform(), ResultTypes: dict, Type: RUN_TYPE.COLLECT);

            DatabaseManager.InsertRun(run);

            Log.Information(Strings.Get("StartingN"), collectors.Count.ToString(CultureInfo.InvariantCulture), Strings.Get("Collectors"));

            using CancellationTokenSource source = new CancellationTokenSource();
            CancellationToken token = source.Token;

            void cancelKeyDelegate(object? sender, ConsoleCancelEventArgs args)
            {
                Log.Information("Cancelling collection. Rolling back transaction. Please wait to avoid corrupting database.");
                source.Cancel();

                if (DatabaseManager is null)
                {
                    Log.Error("Err_DatabaseManagerNull", "InsertCompareResults");
                }
                else
                {
                    DatabaseManager.CloseDatabase();
                }
                Environment.Exit((int)ASA_ERROR.CANCELLED);
            }
            Console.CancelKeyPress += cancelKeyDelegate;

            Dictionary<string, string> EndEvent = new Dictionary<string, string>();
            foreach (BaseCollector c in collectors)
            {
                try
                {
                    DatabaseManager.BeginTransaction();

                    c.TryExecute(token);

                    FlushResults();

                    DatabaseManager.Commit();
                }
                catch (Exception e)
                {
                    Log.Error(Strings.Get("Err_CollectingFrom"), c.GetType().Name, e.Message, e.StackTrace);

                    Console.CancelKeyPress -= cancelKeyDelegate;

                    return ASA_ERROR.FAILED_TO_COMMIT;
                }
            }

            DatabaseManager.Commit();
            Console.CancelKeyPress -= cancelKeyDelegate;

            return ASA_ERROR.NONE;
        }