Пример #1
0
        public void ParseInvalidLongName2()
        {
            SwitchArgument argument = new SwitchArgument("switch", "");

            int i = 1;
            var result = argument.Parse(new[] { "/switch1", "--switch:" }, ref i);
            Assert.IsNull(result);
            Assert.AreEqual(1, i);
        }
Пример #2
0
        static void Main(string[] args)
        {
            CommandLineParser.CommandLineParser parser = new CommandLineParser.CommandLineParser();

            SwitchArgument debugFlag = new SwitchArgument('d', "debug", "Enable debug mode", false);
            FileArgument definitionFile = new FileArgument('f', "file", "Path to skin definition file");
            definitionFile.Optional = false;
            DirectoryArgument steamDirectory = new DirectoryArgument('s', "steam", "Path to Steam directory");
            steamDirectory.Optional = false;
            DirectoryArgument baseDirectory = new DirectoryArgument('b', "base", "Path to directory containing skin bases. Defaults to %STEAM_FOLDER%/skins/");
            SwitchArgument nobackupFlag = new SwitchArgument('n', "nobackup", "Backup old skin folder before writing new one", false);
            SwitchArgument activateSkinFlag = new SwitchArgument('a', "activate", "Activate skin after compilation", false);

            //dumbResponse = Array.Exists(args, el => el == "--dumb") || Array.Exists(args, el => el == "-q");

            parser.Arguments.Add(debugFlag);
            parser.Arguments.Add(definitionFile);
            parser.Arguments.Add(steamDirectory);
            parser.Arguments.Add(baseDirectory);
            parser.Arguments.Add(nobackupFlag);
            parser.Arguments.Add(activateSkinFlag);

            #if !DEBUG
            try
            {
            #endif
                parser.ParseCommandLine(args);
            #if !DEBUG
                try
                {
            #endif
                    Core.backupEnabled = !nobackupFlag.Value;
                    Core.debugMode = debugFlag.Value;
                    Core.activateSkin = activateSkinFlag.Value;
                    Core.Compile(definitionFile.Value, steamDirectory.Value, baseDirectory.Value);
            #if !DEBUG
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                    Environment.Exit(2);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Environment.Exit(1);
            }
            #endif
            #if DEBUG
            Console.ReadKey();
            #endif
        }
Пример #3
0
        private static void Main(string[] args)
        {
            CommandLineParser.CommandLineParser parser = new CommandLineParser.CommandLineParser();

            ValueArgument <string> assembly = new ValueArgument <string>(
                'a', "assembly", "Specify the assembly file");

            assembly.Optional = false;

            SwitchArgument silent = new SwitchArgument(
                's', "silent", "Enable silent mode", false);

            EnumeratedValueArgument <string> output = new EnumeratedValueArgument <string>(
                'o', "output", new string[] { "none", "screen", "environment-machine", "environment-user", "environment-process" });

            output.DefaultValue = "none";

            ValueArgument <string> name = new ValueArgument <string>(
                'n', "name", "Name of environment to create");

            parser.Arguments.Add(assembly);
            parser.Arguments.Add(silent);
            parser.Arguments.Add(output);
            parser.Arguments.Add(name);

            if (args.Length == 0)
            {
                parser.ShowUsage();
            }
            else
            {
                try
                {
                    parser.ParseCommandLine(args);

                    if (!string.Equals(output.Value, "none", StringComparison.OrdinalIgnoreCase) && !string.Equals(output.Value, "screen", StringComparison.OrdinalIgnoreCase))
                    {
                        if (string.IsNullOrEmpty(name.Value))
                        {
                            throw new Exception("The name parameter must be informed");
                        }
                    }

                    var version = GetInfo.GetFileVersionFrom(assembly.Value);

                    switch (output.Value.ToLower())
                    {
                    case "screen":
                        Console.Write(version);
                        break;

                    case "environment-machine":
                        EnvironmentHelper.SetEnvironment(name.Value, version, EnvironmentVariableTarget.Machine);
                        break;

                    case "environment-user":
                        EnvironmentHelper.SetEnvironment(name.Value, version, EnvironmentVariableTarget.User);
                        break;

                    case "environment-process":
                        EnvironmentHelper.SetEnvironment(name.Value, version, EnvironmentVariableTarget.Process);
                        break;
                    }

                    if (!silent.Value)
                    {
                        Console.WriteLine($"Assembly File Version {version}");
                    }

                    Environment.Exit(0); // Exit with successful
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                    Environment.Exit(2); // Exit default error
                }
            }

            Environment.Exit(1); // Exit without execute
        }
Пример #4
0
        public bool Parse(string[] args)
        {
            Mq.Info("Parsing args...");
            var success = false;

            // define args
            var outFileArg = new ValueArgument <string>('o', "outfile",
                                                        "Path for output file. You probably want this if you're not using -s.");
            var verboseArg = new ValueArgument <string>('v', "verbosity",
                                                        "Controls verbosity level, options are Trace (most verbose), Debug (less verbose), Info (less verbose still, default), and Data (results only). e.g '-v debug' ");
            var helpArg = new SwitchArgument('h', "help", "Displays this help.", false);
            //var extMatchArg = new ValueArgument<string>('e', "extmatch",
            //    "Path to wordlist for searching by exact extension match.");
            //var nameMatchArg = new ValueArgument<string>('n', "namematch",
            //    "Path to wordlist for searching by exact filename match.");
            //var grepMatchArg = new ValueArgument<string>('g', "grepmatch",
            //    "Path to wordlist for searching by grepping the contents of files with \"interesting\" extensions.");
            //var partialMatchArg = new ValueArgument<string>('p', "partialmatch",
            //    "Path to wordlist for searching by partial filename match.");
            //var pathMatchArg = new ValueArgument<string>('a', "pathmatch",
            //    "Path to wordlist for searching by partial path match.");
            //var extSkipMatchArg = new ValueArgument<string>('x', "extskipmatch",
            //    "Path to wordlist for extensions that should be skipped.");
            var stdOutArg = new SwitchArgument('s', "stdout",
                                               "Enables outputting results to stdout as soon as they're found. You probably want this if you're not using -o.",
                                               false);
            var mirrorArg = new ValueArgument <string>('m', "mirror",
                                                       "Enables and assigns an output dir for snaffler to automatically take a copy of any found files.");
            var fileHuntArg = new SwitchArgument('f', "filehuntoff",
                                                 "Disables file discovery, will only perform computer and share discovery.", false);
            var dirTargetArg = new ValueArgument <string>('i', "dirtarget",
                                                          "Disables computer and share discovery, requires a path to a directory in which to perform file discovery.");
            var maxThreadsArg = new ValueArgument <int>('t', "threads", "Maximum number of threads. Default 30.");
            var domainArg     = new ValueArgument <string>('d', "domain",
                                                           "Domain to search for computers to search for shares on to search for files in. Easy.");
            var adminshareArg = new SwitchArgument('a', "cdolla",
                                                   "Enables scanning of C$ shares if found. Can be prone to false positives but more thorough.", false);
            var domainControllerArg = new ValueArgument <string>('c', "domaincontroller",
                                                                 "Domain controller to query for a list of domain computers.");
            var maxGrepSizeArg = new ValueArgument <long>('r', "maxgrepsize",
                                                          "The maximum size file (in bytes) to search inside for interesting strings. Defaults to 500k.");
            var grepContextArg = new ValueArgument <int>('j', "grepcontext",
                                                         "How many bytes of context either side of found strings in files to show, e.g. -j 200");

            // list of letters i haven't used yet: bklquwyz

            var parser = new CommandLineParser.CommandLineParser();

            parser.Arguments.Add(outFileArg);
            parser.Arguments.Add(helpArg);
            //parser.Arguments.Add(extMatchArg);
            //parser.Arguments.Add(nameMatchArg);
            //parser.Arguments.Add(grepMatchArg);
            //parser.Arguments.Add(extSkipMatchArg);
            //parser.Arguments.Add(partialMatchArg);
            parser.Arguments.Add(stdOutArg);
            parser.Arguments.Add(mirrorArg);
            parser.Arguments.Add(fileHuntArg);
            parser.Arguments.Add(dirTargetArg);
            parser.Arguments.Add(maxThreadsArg);
            parser.Arguments.Add(domainArg);
            parser.Arguments.Add(verboseArg);
            parser.Arguments.Add(adminshareArg);
            parser.Arguments.Add(domainControllerArg);
            parser.Arguments.Add(maxGrepSizeArg);
            parser.Arguments.Add(grepContextArg);

            // extra check to handle builtin behaviour from cmd line arg parser
            if ((args.Contains("--help") || args.Contains("/?") || args.Contains("help") || args.Contains("-h") || args.Length == 0))
            {
                parser.ShowUsage();
                Environment.Exit(0);
            }

            try
            {
                parser.ParseCommandLine(args);

                // get the args into our config


                // output args
                if (outFileArg.Parsed && (outFileArg.Value != null))
                {
                    LogToFile   = true;
                    LogFilePath = outFileArg.Value;
                    Mq.Degub("Logging to file at " + LogFilePath);
                }

                // Set loglevel.
                if (verboseArg.Parsed)
                {
                    var logLevelString = verboseArg.Value;
                    switch (logLevelString.ToLower())
                    {
                    case "debug":
                        LogLevel = LogLevel.Debug;
                        Mq.Degub("Set verbosity level to degub.");
                        break;

                    case "degub":
                        LogLevel = LogLevel.Debug;
                        Mq.Degub("Set verbosity level to degub.");
                        break;

                    case "trace":
                        LogLevel = LogLevel.Trace;
                        Mq.Degub("Set verbosity level to trace.");
                        break;

                    case "data":
                        LogLevel = LogLevel.Warn;
                        Mq.Degub("Set verbosity level to data.");
                        break;

                    default:
                        LogLevel = LogLevel.Info;
                        Mq.Error("Invalid verbosity level " + logLevelString +
                                 " falling back to default level (info).");
                        break;
                    }
                }

                // if enabled, display findings to the console
                LogToConsole = stdOutArg.Parsed;
                Mq.Degub("Enabled logging to stdout.");

                if (maxThreadsArg.Parsed)
                {
                    MaxThreads = maxThreadsArg.Value;
                    Mq.Degub("Max threads set to " + maxThreadsArg.Value);
                }

                // args that tell us about targeting
                if ((domainArg.Parsed) && (domainArg.Value != null))
                {
                    TargetDomain = domainArg.Value;
                    Mq.Degub("Target domain is " + domainArg.Value);
                }

                if ((domainControllerArg.Parsed) && (domainControllerArg.Value != null))
                {
                    TargetDc = domainControllerArg.Value;
                    Mq.Degub("Target DC is " + domainControllerArg.Value);
                }

                if (dirTargetArg.Parsed)
                {
                    ShareFinderEnabled = false;
                    DirTarget          = dirTargetArg.Value;
                    Mq.Degub("Disabled finding shares.");
                    Mq.Degub("Target path is " + dirTargetArg.Value);
                }

                if (adminshareArg.Parsed)
                {
                    ScanCDollarShares = true;
                    Mq.Degub("Scanning of C$ shares enabled.");
                }

                // if the user passes the various MatchArgs with no value, that disables them.
                // Otherwise load their wordlist into the appropriate config item.

                /*
                 * if (extMatchArg.Parsed)
                 * {
                 *  if (extMatchArg.Value.Length <= 0)
                 *  {
                 *      ExactExtensionCheck = false;
                 *      Mq.Degub("Disabled matching based on exact file extension match.");
                 *  }
                 *  else
                 *  {
                 *      ExtensionsToKeep = File.ReadAllLines(extMatchArg.Value);
                 *      Mq.Degub("Using file at " + extMatchArg.Value + " for exact file extension matching.");
                 *  }
                 * }
                 *
                 * if (pathMatchArg.Parsed)
                 * {
                 *  if (pathMatchArg.Value.Length <= 0)
                 *  {
                 *      PartialPathCheck = false;
                 *      Mq.Degub("Disabled matching based on partial file path.");
                 *  }
                 *  else
                 *  {
                 *      PathsToKeep = File.ReadAllLines(pathMatchArg.Value);
                 *      Mq.Degub("Using file at " + pathMatchArg.Value + " for partial file path matching.");
                 *  }
                 * }
                 *
                 * if (extSkipMatchArg.Parsed)
                 * {
                 *  if (extSkipMatchArg.Value.Length <= 0)
                 *  {
                 *      ExactExtensionSkipCheck = false;
                 *      Mq.Degub("Disabled skipping files with extensions on skip-list.");
                 *  }
                 *  else
                 *  {
                 *      ExtSkipList = File.ReadAllLines(extSkipMatchArg.Value);
                 *      Mq.Degub("Using file at " + extSkipMatchArg.Value + " for extension skip-list.");
                 *  }
                 * }
                 *
                 * if (nameMatchArg.Parsed)
                 * {
                 *  if (nameMatchArg.Value.Length <= 0)
                 *  {
                 *      ExactNameCheck = false;
                 *      Mq.Degub("Disabled matching based on exact file name");
                 *  }
                 *  else
                 *  {
                 *      FileNamesToKeep = File.ReadAllLines(nameMatchArg.Value);
                 *      Mq.Degub("Using file at " + nameMatchArg.Value + " for exact file name matching.");
                 *  }
                 * }
                 *
                 * if (grepMatchArg.Parsed)
                 * {
                 *  if (grepMatchArg.Value.Length <= 0)
                 *  {
                 *      GrepByExtensionCheck = false;
                 *      Mq.Degub("Disabled matching based on file contents.");
                 *  }
                 *  else
                 *  {
                 *      GrepStrings = File.ReadAllLines(grepMatchArg.Value);
                 *      Mq.Degub("Using file at " + grepMatchArg.Value + " for file contents matching.");
                 *  }
                 * }
                 *
                 * if (partialMatchArg.Parsed)
                 * {
                 *  if (partialMatchArg.Value.Length <= 0)
                 *  {
                 *      PartialNameCheck = false;
                 *      Mq.Degub("Disabled partial file name matching.");
                 *  }
                 *  else
                 *  {
                 *      NameStringsToKeep = File.ReadAllLines(partialMatchArg.Value);
                 *      Mq.Degub("Using file at " + partialMatchArg.Value + " for partial file name matching.");
                 *  }
                 * }
                 */
                if (maxGrepSizeArg.Parsed)
                {
                    MaxSizeToGrep = maxGrepSizeArg.Value;
                    Mq.Degub("We won't bother looking inside files if they're bigger than " + MaxSizeToGrep + " bytes");
                }

                // how many bytes
                if (grepContextArg.Parsed)
                {
                    GrepContextBytes = grepContextArg.Value;
                    Mq.Degub(
                        "We'll show you " + grepContextArg.Value + " bytes of context around matches inside files.");
                }

                // if enabled, grab a copy of files that we like.
                if (mirrorArg.Parsed)
                {
                    if (mirrorArg.Value.Length <= 0)
                    {
                        Mq.Error("-m or -mirror arg requires a path value.");
                        throw new ArgumentException("Invalid argument combination.");
                    }

                    EnableMirror = true;
                    MirrorPath   = mirrorArg.Value.TrimEnd('\\');
                    Mq.Degub("Mirroring matched files to path " + MirrorPath);
                }

                if (!LogToConsole && !LogToFile)
                {
                    Mq.Error(
                        "\nYou didn't enable output to file or to the console so you won't see any results or debugs or anything. Your l0ss.");
                    throw new ArgumentException("Pointless argument combination.");
                }
            }
            catch (Exception e)
            {
                Mq.Error(e.ToString());
                throw;
            }
            success = true;
            return(success);
        }
Пример #5
0
        private static CommandLineParser ConfigureCommandLine()
        {
            var parser = new CommandLineParser
            {
                AllowUnknownArguments = false,

                Description =
                    @"This command-line tool can be used to pack files and directories into a single
package. The resulting package file uses the ZIP format and can be read with
standard ZIP tools.",

                HelpHeader =
                    @"If no package exists at the target location, a new file is created.
When the package already exists, it is updated.The input files are compared
with the packaged files. New files are added, modified files are updated, and
missing files are removed from the package. Files are compared by checking the
""Last Modified"" time and the file size.",

                HelpFooter =
                    @"Credits
-------
Pack.exe - Copyright (C) 2014 DigitalRune GmbH. All rights reserved.
DotNetZip - Copyright (C) 2006-2011 Dino Chiesa. All rights reserved.
jzlib - Copyright (C) 2000-2003 ymnk, JCraft,Inc. All rights reserved.
zlib - Copyright (C) 1995-2004 Jean-loup Gailly and Mark Adler."
            };

            var categoryMandatory = "Mandatory";
            var categoryOptional  = "Optional";

            // ----- Mandatory arguments

            // Input files
            _inputArgument = new ValueArgument <string>(
                "files",
                @"Defines the files and directories to add to the package.
The specified files and directories are relative to the current working copy or the base directory, which can be specified with /directory.
Wildcards ('?', '*') are supported.")
            {
                Category      = categoryMandatory,
                AllowMultiple = true,
            };
            parser.Arguments.Add(_inputArgument);

            // --output, --out, -o
            _outputArgument = new SwitchValueArgument <string>(
                "output",
                new ValueArgument <string>("package", "The filename incl. path of package."),
                "Defines the package to create or update.",
                new[] { "out" },
                new[] { 'o' })
            {
                Category = categoryMandatory,
            };
            parser.Arguments.Add(_outputArgument);

            // ----- Optional arguments

            // --directory, --dir, -d
            _directoryArgument = new SwitchValueArgument <string>(
                "directory",
                new ValueArgument <string>("directory", "The base directory."),
                "Specifies the base directory where to search for files.",
                new[] { "dir" },
                new[] { 'd' })
            {
                Category   = categoryOptional,
                IsOptional = true,
            };
            parser.Arguments.Add(_directoryArgument);

            // --recursive, --rec, -r
            _recursiveArgument = new SwitchArgument(
                "recursive",
                "Adds subdirectories to package.",
                new[] { "rec" },
                new[] { 'r' })
            {
                Category   = categoryOptional,
                IsOptional = true,
            };
            parser.Arguments.Add(_recursiveArgument);

            // --password, --pwd, -p
            _passwordArgument = new SwitchValueArgument <string>(
                "password",
                new ValueArgument <string>("password", "The password to use."),
                "Encrypts the package with a password.",
                new[] { "pwd" },
                new[] { 'p' })
            {
                Category   = categoryOptional,
                IsOptional = true,
            };
            parser.Arguments.Add(_passwordArgument);

            // --encryption, --enc, -e
            _encryptionArgument = new SwitchValueArgument <PackageEncryption>(
                "encryption",
                new EnumArgument <PackageEncryption>("method", "The default encryption method is ZipCrypto."),
                "Defines the encryption method in case a password is set.",
                new[] { "enc" },
                new[] { 'e' })
            {
                Category   = categoryOptional,
                IsOptional = true,
            };
            parser.Arguments.Add(_encryptionArgument);

            // --test, -t
            _testArgument = new SwitchArgument(
                "test",
                "Makes a test run without creating/updating the actual package.",
                null,
                new[] { 't' })
            {
                Category   = categoryOptional,
                IsOptional = true,
            };
            parser.Arguments.Add(_testArgument);

            // --help, -h, -?
            _helpArgument = new SwitchArgument(
                "help",
                "Shows help information.",
                null,
                new[] { 'h', '?' })
            {
                Category   = "Help",
                IsOptional = true,
            };
            parser.Arguments.Add(_helpArgument);

            return(parser);
        }
Пример #6
0
        public void ParseLongName1()
        {
            SwitchArgument argument = new SwitchArgument("switch", "");
            Assert.IsFalse(string.IsNullOrEmpty(argument.GetSyntax()));
            Assert.IsTrue(string.IsNullOrEmpty(argument.GetHelp()));

            int i = 1;
            var result = argument.Parse(new[] { "--switch1", "--switch" }, ref i);
            Assert.IsNotNull(result);
            Assert.AreEqual(2, i);
        }
Пример #7
0
        private static Options ParseImpl(string[] args)
        {
            BlockingMq Mq = BlockingMq.GetMq();

            Mq.Info("Parsing args...");
            Options parsedConfig = new Options();

            // define args
            ValueArgument <string> configFileArg = new ValueArgument <string>('z', "config", "Path to a .toml config file. Run with \'generate\' to puke a sample config file into the working directory.");
            ValueArgument <string> outFileArg    = new ValueArgument <string>('o', "outfile",
                                                                              "Path for output file. You probably want this if you're not using -s.");
            ValueArgument <string> verboseArg = new ValueArgument <string>('v', "verbosity",
                                                                           "Controls verbosity level, options are Trace (most verbose), Debug (less verbose), Info (less verbose still, default), and Data (results only). e.g '-v debug' ");
            SwitchArgument helpArg   = new SwitchArgument('h', "help", "Displays this help.", false);
            SwitchArgument stdOutArg = new SwitchArgument('s', "stdout",
                                                          "Enables outputting results to stdout as soon as they're found. You probably want this if you're not using -o.",
                                                          false);
            ValueArgument <string> snaffleArg = new ValueArgument <string>('m', "snaffle",
                                                                           "Enables and assigns an output dir for Snaffler to automatically snaffle a copy of any found files.");
            ValueArgument <long> snaffleSizeArg = new ValueArgument <long>('l', "snafflesize", "Maximum size of file to snaffle, in bytes. Defaults to 10MB.");
            //var fileHuntArg = new SwitchArgument('f', "filehuntoff",
            //    "Disables file discovery, will only perform computer and share discovery.", false);
            ValueArgument <string> dirTargetArg = new ValueArgument <string>('i', "dirtarget",
                                                                             "Disables computer and share discovery, requires a path to a directory in which to perform file discovery.");
            ValueArgument <string> domainArg = new ValueArgument <string>('d', "domain",
                                                                          "Domain to search for computers to search for shares on to search for files in. Easy.");
            ValueArgument <string> domainControllerArg = new ValueArgument <string>('c', "domaincontroller",
                                                                                    "Domain controller to query for a list of domain computers.");
            ValueArgument <long> maxGrepSizeArg = new ValueArgument <long>('r', "maxgrepsize",
                                                                           "The maximum size file (in bytes) to search inside for interesting strings. Defaults to 500k.");
            ValueArgument <int> grepContextArg = new ValueArgument <int>('j', "grepcontext",
                                                                         "How many bytes of context either side of found strings in files to show, e.g. -j 200");
            SwitchArgument domainUserArg = new SwitchArgument('u', "domainusers", "Makes Snaffler grab a list of interesting-looking accounts from the domain and uses them in searches.", false);

            // list of letters i haven't used yet: abefgknpqwxy

            CommandLineParser.CommandLineParser parser = new CommandLineParser.CommandLineParser();
            parser.Arguments.Add(configFileArg);
            parser.Arguments.Add(outFileArg);
            parser.Arguments.Add(helpArg);
            parser.Arguments.Add(stdOutArg);
            parser.Arguments.Add(snaffleArg);
            parser.Arguments.Add(snaffleSizeArg);
            parser.Arguments.Add(dirTargetArg);
            parser.Arguments.Add(domainArg);
            parser.Arguments.Add(verboseArg);
            parser.Arguments.Add(domainControllerArg);
            parser.Arguments.Add(maxGrepSizeArg);
            parser.Arguments.Add(grepContextArg);
            parser.Arguments.Add(domainUserArg);

            // extra check to handle builtin behaviour from cmd line arg parser
            if ((args.Contains("--help") || args.Contains("/?") || args.Contains("help") || args.Contains("-h") || args.Length == 0))
            {
                parser.ShowUsage();
                Environment.Exit(0);
            }

            TomlSettings settings = TomlSettings.Create(cfg => cfg
                                                        .ConfigureType <LogLevel>(tc =>
                                                                                  tc.WithConversionFor <TomlString>(conv => conv
                                                                                                                    .FromToml(s => (LogLevel)Enum.Parse(typeof(LogLevel), s.Value, ignoreCase: true))
                                                                                                                    .ToToml(e => e.ToString()))));

            try
            {
                parser.ParseCommandLine(args);

                if (configFileArg.Parsed)
                {
                    if (!configFileArg.Value.Equals("generate"))
                    {
                        string configFile = configFileArg.Value;
                        parsedConfig = Toml.ReadFile <Options>(configFile, settings);
                        parsedConfig.PrepareClassifiers();
                        Mq.Info("Read config file from " + configFile);
                        return(parsedConfig);
                    }
                }

                if (parsedConfig.ClassifierRules.Count <= 0)
                {
                    parsedConfig.BuildDefaultClassifiers();
                }
                // get the args into our config

                // output args
                if (outFileArg.Parsed && (!String.IsNullOrEmpty(outFileArg.Value)))
                {
                    parsedConfig.LogToFile   = true;
                    parsedConfig.LogFilePath = outFileArg.Value;
                    Mq.Degub("Logging to file at " + parsedConfig.LogFilePath);
                }

                // Set loglevel.
                if (verboseArg.Parsed)
                {
                    parsedConfig.LogLevelString = verboseArg.Value;
                    Mq.Degub("Requested verbosity level: " + parsedConfig.LogLevelString);
                }

                // if enabled, display findings to the console
                parsedConfig.LogToConsole = stdOutArg.Parsed;
                Mq.Degub("Enabled logging to stdout.");

                // args that tell us about targeting
                if ((domainArg.Parsed) && (!String.IsNullOrEmpty(domainArg.Value)))
                {
                    parsedConfig.TargetDomain = domainArg.Value;
                    Mq.Degub("Target domain is " + domainArg.Value);
                }

                if ((domainControllerArg.Parsed) && (!String.IsNullOrEmpty(domainControllerArg.Value)))
                {
                    parsedConfig.TargetDc = domainControllerArg.Value;
                    Mq.Degub("Target DC is " + domainControllerArg.Value);
                }

                if (domainUserArg.Parsed)
                {
                    parsedConfig.DomainUserRules = true;
                    Mq.Degub("Enabled use of domain user accounts in rules.");
                }

                if (dirTargetArg.Parsed)
                {
                    parsedConfig.ShareFinderEnabled = false;
                    parsedConfig.PathTargets        = new string[] { dirTargetArg.Value };
                    Mq.Degub("Disabled finding shares.");
                    Mq.Degub("Target path is " + dirTargetArg.Value);
                }

                if (maxGrepSizeArg.Parsed)
                {
                    parsedConfig.MaxSizeToGrep = maxGrepSizeArg.Value;
                    Mq.Degub("We won't bother looking inside files if they're bigger than " + parsedConfig.MaxSizeToGrep +
                             " bytes");
                }

                if (snaffleArg.Parsed)
                {
                    parsedConfig.SnafflePath = snaffleArg.Value;
                }

                if (snaffleSizeArg.Parsed)
                {
                    parsedConfig.MaxSizeToSnaffle = snaffleSizeArg.Value;
                }

                // how many bytes
                if (grepContextArg.Parsed)
                {
                    parsedConfig.MatchContextBytes = grepContextArg.Value;
                    Mq.Degub(
                        "We'll show you " + grepContextArg.Value +
                        " bytes of context around matches inside files.");
                }

                // if enabled, grab a copy of files that we like.
                if (snaffleArg.Parsed)
                {
                    if (snaffleArg.Value.Length <= 0)
                    {
                        Mq.Error("-m or -mirror arg requires a path value.");
                        throw new ArgumentException("Invalid argument combination.");
                    }

                    parsedConfig.Snaffle     = true;
                    parsedConfig.SnafflePath = snaffleArg.Value.TrimEnd('\\');
                    Mq.Degub("Mirroring matched files to path " + parsedConfig.SnafflePath);
                }

                if (!parsedConfig.LogToConsole && !parsedConfig.LogToFile)
                {
                    Mq.Error(
                        "\nYou didn't enable output to file or to the console so you won't see any results or debugs or anything. Your l0ss.");
                    throw new ArgumentException("Pointless argument combination.");
                }

                if (configFileArg.Parsed)
                {
                    if (configFileArg.Value.Equals("generate"))
                    {
                        Toml.WriteFile(parsedConfig, ".\\default.toml", settings);
                        Mq.Info("Wrote default config values to .\\default.toml");
                        Mq.Terminate();
                    }
                }

                parsedConfig.PrepareClassifiers();
            }
            catch (Exception e)
            {
                Mq.Error(e.ToString());
                throw;
            }

            return(parsedConfig);
        }
Пример #8
0
        static int Main(string[] args)
        {
            CommandLineParser parser = new CommandLineParser
            {
                AllowUnknownArguments = true,
            };

            parser.Description = "This is just a test application that demonstrates the usage of the CommandLineParser.";

            parser.HelpHeader =
                @"DESCRIPTION
    Here is a very detailed description of this app. Yadda, yadda, yadda...
    Yadda, yadda, yadda...
    Yadda, yadda, yadda...";

            parser.HelpFooter =
                @"EXAMPLES
    Show the help text:
        CommandLineApp --help
    
    Do something else:
        CommandLineApp --Enum Value1 Foo";

            var helpArgument = new SwitchArgument("help", "Show help.", null, new[] { 'h', '?' })
            {
                Category   = "Help",
                IsOptional = true,
            };

            parser.Arguments.Add(helpArgument);

            var fileArgument = new ValueArgument <string>("file", "The file to load.")
            {
                IsOptional    = false,
                AllowMultiple = true,
            };

            parser.Arguments.Add(fileArgument);

            var recursiveArgument = new SwitchArgument(
                "Recursive",
                "Enables recursive mode. \n This is just a demo text to test the formatting capabilities of the CommandLineParser.",
                null,
                new[] { 'R' })
            {
                IsOptional = true,
            };

            parser.Arguments.Add(recursiveArgument);

            var switchArgument1 = new SwitchArgument(
                "Switch1",
                "Another test switch. This is just a demo text to test the formatting capabilities of the CommandLineParser.")
            {
                Category   = "Test Category",
                IsOptional = true,
            };

            parser.Arguments.Add(switchArgument1);

            var switchArgument2 = new SwitchArgument(
                "Switch2",
                "Yet another test switch. This is just a demo text to test the formatting capabilities of the CommandLineParser. abcdefghijklmnopqrstuvw0123456789ABCDEFRGHIJKLMNOPQRSTUVWXYZ0123456789",
                null,
                new[] { 'S' })
            {
                Category   = "Test Category",
                IsOptional = true,
            };

            parser.Arguments.Add(switchArgument2);

            SwitchArgument longArgument = new SwitchArgument(
                "extremelyLongCommandLineArgumentToTestFormatting",
                "Extremely long argument. This is just a demo text to test the formatting capabilities of the CommandLineParser.",
                null,
                new[] { 'e' })
            {
                Category   = "Test Category",
                IsOptional = true,
            };

            parser.Arguments.Add(longArgument);

            var echoArgument = new SwitchValueArgument <string>(
                "echo",
                new ValueArgument <string>("text", null),
                "Prints the given text.")
            {
                Category   = null,
                IsOptional = true,
            };

            parser.Arguments.Add(echoArgument);

            var valueArgument = new SwitchValueArgument <int>(
                "value",
                new ValueArgument <int>("value", null)
            {
                AllowMultiple = true
            },
                "This switch has an integer value.",
                null,
                new[] { 'v' })
            {
                Category   = "Test Category 2",
                IsOptional = true,
            };

            parser.Arguments.Add(valueArgument);

            var boundedArgument = new SwitchValueArgument <float>(
                "bounded",
                new BoundedValueArgument <float>("boundedValue", null, 1, 5)
            {
                AllowMultiple = true, IsOptional = true
            },
                "This is a bounded integer value.",
                null,
                new[] { 'b' })
            {
                Category   = "Test Category 2",
                IsOptional = true,
            };

            parser.Arguments.Add(boundedArgument);

            var enumArgument = new SwitchValueArgument <MyEnum>(
                "Enum",
                new EnumArgument <MyEnum>("MyEnum", null)
            {
                IsOptional = true
            },
                "This is an enumeration.",
                null,
                new[] { 'e' })
            {
                Category   = "Test Category 2",
                IsOptional = true,
            };

            parser.Arguments.Add(enumArgument);

            var flagsArgument = new SwitchValueArgument <MyFlags>(
                "Flags",
                new EnumArgument <MyFlags>("MyFlags", "The value."),
                "This is a combination of flags (= enumeration with FlagsAttribute).",
                null,
                new[] { 'f' })
            {
                Category   = "Test Category 2",
                IsOptional = true,
            };

            parser.Arguments.Add(flagsArgument);

            ParseResult parseResult;

            try
            {
                parseResult = parser.Parse(args);

                if (parseResult.ParsedArguments[helpArgument] != null)
                {
                    // Show help and exit.
                    Console.WriteLine(parser.GetHelp());
                    return(ERROR_SUCCESS);
                }

                parser.ThrowIfMandatoryArgumentIsMissing(parseResult);
            }
            catch (CommandLineParserException exception)
            {
                Console.Error.WriteLine("ERROR");
                Console.Error.WriteLineIndented(exception.Message, 4);
                Console.Error.WriteLine();
                Console.Out.WriteLine("SYNTAX");
                Console.Out.WriteLineIndented(parser.GetSyntax(), 4);
                Console.Out.WriteLine();
                Console.Out.WriteLine("Try 'CommandLineApp --help'�for�more�information.");
                return(ERROR_BAD_ARGUMENTS);
            }

            var echo = parseResult.ParsedArguments["echo"] as ArgumentResult <string>;

            if (echo != null)
            {
                Console.Out.WriteLineWrapped(echo.Values[0]);
                return(ERROR_SUCCESS);
            }

            Console.WriteLine("----- Raw arguments");
            foreach (var arg in parseResult.RawArguments)
            {
                Console.WriteLine(arg);
            }

            Console.WriteLine();

            Console.WriteLine("----- Unknown arguments");
            foreach (var arg in parseResult.UnknownArguments)
            {
                Console.WriteLine(arg);
            }

            Console.WriteLine();

            Console.WriteLine("----- Parsed arguments");
            foreach (var arg in parseResult.ParsedArguments)
            {
                Console.Write("--");
                Console.Write(arg.Argument.Name);

                var values = arg.Values.Cast <object>().ToArray();

                if (values.Length > 0)
                {
                    Console.WriteLine(":");
                    foreach (var value in values)
                    {
                        Console.Write("    ");
                        Console.WriteLine(value);
                    }
                }
                else
                {
                    Console.WriteLine();
                }
            }

            return(ERROR_SUCCESS);
        }
Пример #9
0
        static void Main(string[] args)
        {
            // process args
            CommandLineParser.CommandLineParser parser =
                new CommandLineParser.CommandLineParser();

            var helpArgument = new SwitchArgument(
                'h', "help", "Display usage help", false);
            var configArgument = new SwitchArgument(
                'c', "config", "Only generate config file.", false);
            var inputArgument = new DirectoryArgument(
                'i', "input", "Path to the input folder. The folder must contain ApiDefinitions.cs and StructsAndEnums.cs");
            var outputArgument = new DirectoryArgument(
                'o', "output", "Path to the output folder");

            outputArgument.DirectoryMustExist = false;
            var namespaceArgument = new ValueArgument <string>(
                'n', "namespace", "Namespace for the individual objects");

            parser.Arguments.Add(helpArgument);
            parser.Arguments.Add(configArgument);
            parser.Arguments.Add(inputArgument);
            parser.Arguments.Add(outputArgument);
            parser.Arguments.Add(namespaceArgument);

            try
            {
                parser.ParseCommandLine(args);

                if (helpArgument.Parsed && helpArgument.Value)
                {
                    parser.ShowUsage();
                    Console.WriteLine(@"First step is to generate a config file:
dotnet run -- -i ../Bindings/ -o ../MaterialComponents.Parsed/ -c

Second step is to edit the config file and set EnableBinding and EnableXFWrapper for desired components.

Third step is to generate separated ObjC wrappers and Xamarin Forms wrappers/renderers:
dotnet run -- -i ../Bindings/ -o ../MaterialComponents.Parsed/ -n MaterialComponents");
                }
            }
            catch (CommandLineException e)
            {
                Console.WriteLine(e.Message);
                return;
            }
            catch (System.IO.DirectoryNotFoundException e)
            {
                Console.WriteLine(e.Message);
                return;
            }

            // load input files - ApiDefinitions.cs StructsAndEnums.cs
            var sharpieParser = new SharpieParser();
            var inputFolder   = inputArgument.Parsed ? inputArgument.Value : new DirectoryInfo(DefaultInputFolder);

            try
            {
                sharpieParser.ParseInputFolder(inputFolder.FullName);
            }
            catch (ArgumentException e)
            {
                Console.WriteLine(e.Message);
                return;
            }

            // output each interface/delegate/enum into separate files, add usings, and namespace
            var outputFolder = outputArgument.Parsed ? outputArgument.Value : new DirectoryInfo(DefaultOutputFolder);
            var ns           = namespaceArgument.Parsed ? namespaceArgument.Value : DefaultNamespace;
            var cfgOnly      = configArgument.Parsed ? configArgument.Value : false;

            // Create or update JSON config file that lists all components we are interested in generating.
            sharpieParser.UpdateOrCreateConfig(outputFolder.FullName, DefaultConfigName);

            if (!cfgOnly)
            {
                // Using JSON config create bindings
                sharpieParser.WriteOutput(outputFolder.FullName + "/Components/", ns);
                sharpieParser.WriteProject(outputFolder.FullName + "/Components/", DefaultProject);

                // Using JSON config generates XF wrappers
                sharpieParser.WriteXFWrappers(outputFolder.FullName,
                                              DefaultConfigName,
                                              DefaultXfFolder,
                                              DefaultIOSFolder,
                                              DefaultAndroidFolder,
                                              DefaultNamespace);
            }
        }
Пример #10
0
        public void ParseInvalidShortName3()
        {
            SwitchArgument argument = new SwitchArgument("switch", "", null, new[] { 'S' });

            int i = 1;
            var result = argument.Parse(new[] { "--switch1", "--S" }, ref i);
            Assert.IsNull(result);
            Assert.AreEqual(1, i);
        }
Пример #11
0
        public void ParseShortNameAlias()
        {
            SwitchArgument argument = new SwitchArgument("switch", "", null, new[] { 'S', 'A' });

            int i = 1;
            var result = argument.Parse(new[] { "--switch1", "-A" }, ref i);
            Assert.IsNotNull(result);
            Assert.AreEqual(2, i);
        }
Пример #12
0
        public void ParseOther()
        {
            SwitchArgument argument = new SwitchArgument("switch", "", null, new[] { 'S' });

            int i = 0;
            var result = argument.Parse(new[] { "--switch1", "--switch" }, ref i);
            Assert.IsNull(result);
            Assert.AreEqual(0, i);
        }
Пример #13
0
        public void ParseLongNameAlias()
        {
            SwitchArgument argument = new SwitchArgument("switch", "", new[] { "Alias" }, null);

            int i = 1;
            var result = argument.Parse(new[] { "--switch1", "--alias" }, ref i);
            Assert.IsNotNull(result);
            Assert.AreEqual(2, i);
        }
Пример #14
0
        public void ParseLongName2()
        {
            SwitchArgument argument = new SwitchArgument("switch", "");

            int i = 1;
            var result = argument.Parse(new[] { "--switch1", "--SwItcH" }, ref i);
            Assert.IsNotNull(result);
            Assert.AreEqual(2, i);
        }
Пример #15
0
        private static void Main(string[] args)
        {
            DateTime grouper2StartTime = DateTime.Now;

            CommandLineParser.CommandLineParser parser = new CommandLineParser.CommandLineParser();
            ValueArgument <string> htmlArg             = new ValueArgument <string>('f', "html", "Path for html output file.");
            SwitchArgument         debugArg            = new SwitchArgument('v', "verbose", "Enables debug mode. Probably quite noisy and rarely necessary. Will also show you the names of any categories of policies" +
                                                                            " that Grouper saw but didn't have any means of processing. I eagerly await your pull request.", false);
            SwitchArgument offlineArg = new SwitchArgument('o', "offline",
                                                           "Disables checks that require LDAP comms with a DC or SMB comms with file shares found in policy settings. Requires that you define a value for -s.",
                                                           false);
            ValueArgument <string> sysvolArg =
                new ValueArgument <string>('s', "sysvol", "Set the path to a domain SYSVOL directory.");
            ValueArgument <int> intlevArg = new ValueArgument <int>('i', "interestlevel",
                                                                    "The minimum interest level to display. i.e. findings with an interest level lower than x will not be seen in output. Defaults to 1, i.e. show " +
                                                                    "everything except some extremely dull defaults. If you want to see those too, do -i 0.");
            ValueArgument <int>    threadsArg = new ValueArgument <int>('t', "threads", "Max number of threads. Defaults to 10.");
            ValueArgument <string> domainArg  =
                new ValueArgument <string>('d', "domain", "Domain to query for Group Policy Goodies.");
            ValueArgument <string> passwordArg = new ValueArgument <string>('p', "password", "Password to use for LDAP operations.");
            ValueArgument <string> usernameArg =
                new ValueArgument <string>('u', "username", "Username to use for LDAP operations.");
            SwitchArgument helpArg           = new SwitchArgument('h', "help", "Displays this help.", false);
            SwitchArgument prettyArg         = new SwitchArgument('g', "pretty", "Switches output from the raw Json to a prettier format.", false);
            SwitchArgument noMessArg         = new SwitchArgument('m', "nomess", "Avoids file writes at all costs. May find less stuff.", false);
            SwitchArgument currentPolOnlyArg = new SwitchArgument('c', "currentonly", "Only checks current policies, ignoring stuff in those " +
                                                                  "Policies_NTFRS_* directories that result from replication failures.", false);
            SwitchArgument noGrepScriptsArg = new SwitchArgument('n', "nogrepscripts", "Don't grep through the files in the \"Scripts\" subdirectory", false);

            parser.Arguments.Add(usernameArg);
            parser.Arguments.Add(passwordArg);
            parser.Arguments.Add(debugArg);
            parser.Arguments.Add(intlevArg);
            parser.Arguments.Add(sysvolArg);
            parser.Arguments.Add(offlineArg);
            parser.Arguments.Add(threadsArg);
            parser.Arguments.Add(helpArg);
            parser.Arguments.Add(prettyArg);
            parser.Arguments.Add(noMessArg);
            parser.Arguments.Add(currentPolOnlyArg);
            parser.Arguments.Add(noGrepScriptsArg);
            parser.Arguments.Add(domainArg);
            parser.Arguments.Add(htmlArg);

            // set a few defaults
            string sysvolDir = "";

            GlobalVar.OnlineChecks = true;
            int  maxThreads   = 10;
            bool prettyOutput = false;

            GlobalVar.NoMess = false;
            bool   noNtfrs           = false;
            bool   noGrepScripts     = false;
            string userDefinedDomain = "";
            bool   htmlOut           = false;
            string htmlOutPath       = "";

            try
            {
                parser.ParseCommandLine(args);
                if (helpArg.Parsed)
                {
                    foreach (Argument arg in parser.Arguments)
                    {
                        Console.Error.Write("-");
                        Console.Error.Write(arg.ShortName);
                        Console.Error.Write(" " + arg.LongName);
                        Console.Error.WriteLine(" - " + arg.Description);
                    }

                    Environment.Exit(0);
                }
                if (offlineArg.Parsed && offlineArg.Value && sysvolArg.Parsed)
                {
                    // args config for valid offline run.
                    GlobalVar.OnlineChecks = false;
                    sysvolDir = sysvolArg.Value;
                }

                if (offlineArg.Parsed && offlineArg.Value && !sysvolArg.Parsed)
                {
                    // handle someone trying to run in offline mode without giving a value for sysvol
                    Console.Error.WriteLine(
                        "\nOffline mode requires you to provide a value for -s, the path where Grouper2 can find the domain SYSVOL share, or a copy of it at least.");
                    Environment.Exit(1);
                }

                if (intlevArg.Parsed)
                {
                    // handle interest level parsing
                    Console.Error.WriteLine("\nRoger. Everything with an Interest Level lower than " +
                                            intlevArg.Value.ToString() + " is getting thrown on the floor.");
                    GlobalVar.IntLevelToShow = intlevArg.Value;
                }
                else
                {
                    GlobalVar.IntLevelToShow = 1;
                }

                if (htmlArg.Parsed)
                {
                    htmlOut     = true;
                    htmlOutPath = htmlArg.Value;
                }
                if (debugArg.Parsed)
                {
                    Console.Error.WriteLine("\nVerbose debug mode enabled. Hope you like yellow.");
                    GlobalVar.DebugMode = true;
                }

                if (threadsArg.Parsed)
                {
                    Console.Error.WriteLine("\nMaximum threads set to: " + threadsArg.Value);
                    maxThreads = threadsArg.Value;
                }

                if (sysvolArg.Parsed)
                {
                    Console.Error.WriteLine("\nYou specified that I should assume SYSVOL is here: " + sysvolArg.Value);
                    sysvolDir = sysvolArg.Value;
                }

                if (prettyArg.Parsed)
                {
                    Console.Error.WriteLine("\nSwitching output to pretty mode. Nice.");
                    prettyOutput = true;
                }

                if (noMessArg.Parsed)
                {
                    Console.Error.WriteLine("\nNo Mess mode enabled. Good for OPSEC, maybe bad for finding all the vulns? All \"Directory Is Writable\" checks will return false.");

                    GlobalVar.NoMess = true;
                }

                if (currentPolOnlyArg.Parsed)
                {
                    Console.Error.WriteLine("\nOnly looking at current policies and scripts, not checking any of those weird old NTFRS dirs.");
                    noNtfrs = true;
                }

                if (domainArg.Parsed)
                {
                    Console.Error.Write("\nYou told me to talk to domain " + domainArg.Value + " so I'm gonna do that.");
                    if (!(usernameArg.Parsed) || !(passwordArg.Parsed))
                    {
                        Console.Error.Write("\nIf you specify a domain you need to specify a username and password too using -u and -p.");
                    }

                    userDefinedDomain = domainArg.Value;
                    string[]      splitDomain = userDefinedDomain.Split('.');
                    StringBuilder sb          = new StringBuilder();
                    int           pi          = splitDomain.Length;
                    int           ind         = 1;
                    foreach (string piece in splitDomain)
                    {
                        sb.Append("DC=" + piece);
                        if (pi != ind)
                        {
                            sb.Append(",");
                        }
                        ind++;
                    }

                    GlobalVar.UserDefinedDomain   = userDefinedDomain;
                    GlobalVar.UserDefinedDomainDn = sb.ToString();
                    GlobalVar.UserDefinedPassword = passwordArg.Value;
                    GlobalVar.UserDefinedUsername = usernameArg.Value;
                }

                if (noGrepScriptsArg.Parsed)
                {
                    Console.Error.WriteLine("\nNot gonna look through scripts in SYSVOL for goodies.");
                    noGrepScripts = true;
                }
            }
            catch (CommandLineException e)
            {
                Console.WriteLine(e.Message);
            }

            if (GlobalVar.UserDefinedDomain != null)
            {
                Console.Error.WriteLine("\nRunning as user: "******"\\" + GlobalVar.UserDefinedUsername);
            }
            else
            {
                Console.Error.WriteLine("\nRunning as user: "******"\\" + Environment.UserName);
            }
            Console.Error.WriteLine("\nAll online checks will be performed in the context of this user.");


            if (!prettyOutput)
            {
                Output.PrintBanner();
            }

            // Ask the DC for GPO details
            string currentDomainString = "";

            if (GlobalVar.OnlineChecks)
            {
                if (userDefinedDomain != "")
                {
                    currentDomainString = userDefinedDomain;
                }
                else
                {
                    Console.Error.WriteLine("\nTrying to figure out what AD domain we're working with.");
                    try
                    {
                        currentDomainString = Domain.GetCurrentDomain().ToString();
                    }
                    catch (ActiveDirectoryOperationException e)
                    {
                        Console.Error.WriteLine("\nCouldn't talk to the domain properly. If you're trying to run offline you should use the -o switch. Failing that, try rerunning with -d to specify a domain or -v to get more information about the error.");
                        Utility.Output.DebugWrite(e.ToString());

                        Environment.Exit(1);
                    }
                }

                Console.WriteLine("\nCurrent AD Domain is: " + currentDomainString);

                // if we're online, get a bunch of metadata about the GPOs via LDAP
                JObject domainGpos = new JObject();

                if (GlobalVar.OnlineChecks)
                {
                    domainGpos = GetDomainGpoData.DomainGpoData;
                }

                Console.WriteLine("");

                if (sysvolDir == "")
                {
                    sysvolDir = @"\\" + currentDomainString + @"\sysvol\" + currentDomainString + @"\";
                    Console.Error.WriteLine("Targeting SYSVOL at: " + sysvolDir);
                }
            }
            else if ((GlobalVar.OnlineChecks == false) && sysvolDir.Length > 1)
            {
                Console.Error.WriteLine("\nTargeting SYSVOL at: " + sysvolDir);
            }
            else
            {
                Console.Error.WriteLine("\nSomething went wrong with parsing the path to sysvol and I gave up.");
                Environment.Exit(1);
            }

            // get all the dirs with Policies and scripts in an array.
            string[] sysvolDirs =
                Directory.GetDirectories(sysvolDir);

            Console.Error.WriteLine(
                "\nI found all these directories in SYSVOL...");
            Console.Error.WriteLine("#########################################");
            foreach (string line in sysvolDirs)
            {
                Console.Error.WriteLine(line);
            }
            Console.Error.WriteLine("#########################################");

            List <string> sysvolPolDirs    = new List <string>();
            List <string> sysvolScriptDirs = new List <string>();

            if (noNtfrs)
            {
                Console.Error.WriteLine("... but I'm not going to look in any of them except .\\Policies and .\\Scripts because you told me not to.");
                sysvolPolDirs.Add(sysvolDir + "Policies\\");
                sysvolScriptDirs.Add(sysvolDir + "Scripts\\");
            }
            else
            {
                Console.Error.WriteLine("... and I'm going to find all the goodies I can in all of them.");
                foreach (string dir in sysvolDirs)
                {
                    if (dir.ToLower().Contains("scripts"))
                    {
                        sysvolScriptDirs.Add(dir);
                    }

                    if (dir.ToLower().Contains("policies"))
                    {
                        sysvolPolDirs.Add(dir);
                    }
                }
            }

            // get all the policy dirs
            List <string> gpoPaths = new List <string>();

            foreach (string policyPath in sysvolPolDirs)
            {
                try
                {
                    gpoPaths = Directory.GetDirectories(policyPath).ToList();
                }
                catch (Exception e)
                {
                    Console.Error.WriteLine("I had a problem with " + policyPath +
                                            ". I guess you could try to fix it?");
                    Output.DebugWrite(e.ToString());
                }
            }

            JObject gpoPackageData = new JObject();

            // Grab Packages from LDAP
            if (GlobalVar.OnlineChecks)
            {
                gpoPackageData = LDAPstuff.GetGpoPackages(Environment.UserDomainName.ToString());
            }



            // create a JObject to put all our output goodies in.
            JObject grouper2Output = new JObject();
            // so for each uid directory (including ones with that dumb broken domain replication condition)
            // we're going to gather up all our goodies and put them into that dict we just created.
            // Create a TaskScheduler
            LimitedConcurrencyLevelTaskScheduler lcts = new LimitedConcurrencyLevelTaskScheduler(maxThreads);
            List <Task> gpoTasks = new List <Task>();

            // create a TaskFactory
            TaskFactory             gpoFactory = new TaskFactory(lcts);
            CancellationTokenSource gpocts     = new CancellationTokenSource();

            Console.Error.WriteLine("\n" + gpoPaths.Count.ToString() + " GPOs to process.");
            Console.Error.WriteLine("\nStarting processing GPOs with " + maxThreads.ToString() + " threads.");

            JObject taskErrors = new JObject();

            // Create a task for each GPO
            foreach (string gpoPath in gpoPaths)
            {
                Task t = gpoFactory.StartNew(() =>
                {
                    try
                    {
                        JObject matchedPackages = new JObject();
                        if (GlobalVar.OnlineChecks)
                        {
                            // figure out the gpo UID from the path so we can see which packages need to be processed here.
                            string[] gpoPathArr      = gpoPath.Split('{');
                            string gpoPathBackString = gpoPathArr[1];
                            string[] gpoPathBackArr  = gpoPathBackString.Split('}');
                            string gpoUid            = gpoPathBackArr[0].ToString().ToLower();

                            // see if we have any appropriate matching packages and construct a little bundle
                            foreach (KeyValuePair <string, JToken> gpoPackage in gpoPackageData)
                            {
                                string packageParentGpoUid = gpoPackage.Value["ParentGPO"].ToString().ToLower()
                                                             .Trim('{', '}');
                                if (packageParentGpoUid == gpoUid)
                                {
                                    JProperty assessedPackage = PackageAssess.AssessPackage(gpoPackage);
                                    if (assessedPackage != null)
                                    {
                                        matchedPackages.Add(assessedPackage);
                                    }
                                }
                            }
                        }


                        JObject gpoFindings = ProcessGpo(gpoPath, matchedPackages);

                        if (gpoFindings != null)
                        {
                            if (gpoFindings.HasValues)
                            {
                                lock (grouper2Output)
                                {
                                    if (!(gpoPath.Contains("NTFRS")))
                                    {
                                        grouper2Output.Add(("Current Policy - " + gpoPath), gpoFindings);
                                    }
                                    else
                                    {
                                        grouper2Output.Add(gpoPath, gpoFindings);
                                    }
                                }
                            }
                        }
                    }

                    catch (Exception e)
                    {
                        taskErrors.Add(gpoPath, e.ToString());
                    }
                }, gpocts.Token);
                gpoTasks.Add(t);
            }

            // put 'em all in a happy little array
            Task[] gpoTaskArray = gpoTasks.ToArray();

            // create a little counter to provide status updates
            int totalGpoTasksCount  = gpoTaskArray.Length;
            int incompleteTaskCount = gpoTaskArray.Length;
            int remainingTaskCount  = gpoTaskArray.Length;

            while (remainingTaskCount > 0)
            {
                Task[] incompleteTasks =
                    Array.FindAll(gpoTaskArray, element => element.Status != TaskStatus.RanToCompletion);
                incompleteTaskCount = incompleteTasks.Length;
                Task[] faultedTasks = Array.FindAll(gpoTaskArray,
                                                    element => element.Status == TaskStatus.Faulted);
                int    faultedTaskCount  = faultedTasks.Length;
                int    completeTaskCount = totalGpoTasksCount - incompleteTaskCount - faultedTaskCount;
                int    percentage        = (int)Math.Round((double)(100 * completeTaskCount) / totalGpoTasksCount);
                string percentageString  = percentage.ToString();
                Console.Error.Write("");

                Console.Error.Write("\r" + completeTaskCount.ToString() + "/" + totalGpoTasksCount.ToString() +
                                    " GPOs processed. " + percentageString + "% complete. ");
                if (faultedTaskCount > 0)
                {
                    Console.Error.Write(faultedTaskCount.ToString() + " GPOs failed to process.");
                }

                remainingTaskCount = incompleteTaskCount - faultedTaskCount;
            }

            // make double sure tasks all finished
            Task.WaitAll(gpoTasks.ToArray());
            gpocts.Dispose();

            // do the script grepping
            if (!(noGrepScripts))
            {
                Console.Error.Write("\n\nProcessing SYSVOL script dirs.\n\n");
                JObject processedScriptDirs = ProcessScripts(sysvolScriptDirs);
                if ((processedScriptDirs != null) && (processedScriptDirs.HasValues))
                {
                    grouper2Output.Add("Scripts", processedScriptDirs);
                }
            }

            Console.Error.WriteLine("Errors in processing GPOs:");
            Console.Error.WriteLine(taskErrors.ToString());

            // Final output is finally happening finally here:

            if (prettyOutput || htmlOut)
            {
                // gotta add a line feed to make sure we're clear to write the nice output.
                Console.Error.WriteLine("\n");

                if (htmlOut)
                {
                    try
                    {
                        // gotta add a line feed to make sure we're clear to write the nice output.

                        Document htmlDoc = new Document();

                        htmlDoc.Children.Add(Output.GetG2BannerDocument());

                        foreach (KeyValuePair <string, JToken> gpo in grouper2Output)
                        {
                            htmlDoc.Children.Add(Output.GetAssessedGpoOutput(gpo));
                        }
                        ConsoleRenderer.RenderDocument(htmlDoc,
                                                       new HtmlRenderTarget(File.Create(htmlOutPath), new UTF8Encoding(false)));
                    }
                    catch (UnauthorizedAccessException)
                    {
                        Console.Error.WriteLine("Tried to write html output file but I'm not allowed.");
                    }
                }

                if (prettyOutput)
                {
                    Document prettyDoc = new Document();

                    prettyDoc.Children.Add(Output.GetG2BannerDocument());

                    foreach (KeyValuePair <string, JToken> gpo in grouper2Output)
                    {
                        prettyDoc.Children.Add(Output.GetAssessedGpoOutput(gpo));
                    }
                    ConsoleRenderer.RenderDocument(prettyDoc);
                }
            }
            else
            {
                Console.WriteLine(grouper2Output);
                Console.Error.WriteLine("If you find yourself thinking 'wtf this is very ugly and hard to read', consider trying the -g argument.");
            }


            // get the time it took to do the thing and give to user
            DateTime grouper2EndTime       = DateTime.Now;
            TimeSpan grouper2RunTime       = grouper2EndTime.Subtract(grouper2StartTime);
            string   grouper2RunTimeString =
                $"{grouper2RunTime.Hours}:{grouper2RunTime.Minutes}:{grouper2RunTime.Seconds}:{grouper2RunTime.Milliseconds}";

            Console.WriteLine("Grouper2 took " + grouper2RunTimeString + " to run.");

            if (GlobalVar.CleanupList != null)
            {
                List <string> cleanupList = Util.DedupeList(GlobalVar.CleanupList);
                if (cleanupList.Count >= 1)
                {
                    Console.WriteLine("\n\nGrouper2 tried to create these files. It probably failed, but just in case it didn't, you might want to check and clean them up.\n");
                    foreach (string path in cleanupList)
                    {
                        Console.WriteLine(path);
                    }
                }
            }
            // FINISHED!
            bool isDebuggerAttached = System.Diagnostics.Debugger.IsAttached;

            if (isDebuggerAttached)
            {
                Console.Error.WriteLine("Press any key to Exit");
                Console.ReadKey();
            }
            Environment.Exit(0);
        }
Пример #16
0
        private static void Main(string[] args)
        {
            Utility.PrintBanner();

            CommandLineParser.CommandLineParser parser = new CommandLineParser.CommandLineParser();
            SwitchArgument         debugArg            = new SwitchArgument('d', "debug", "Enables debug mode. Will also show you the names of any categories of policies that Grouper saw but didn't have any means of processing. I eagerly await your pull request.", false);
            SwitchArgument         offlineArg          = new SwitchArgument('o', "offline", "Disables checks that require LDAP comms with a DC or SMB comms with file shares found in policy settings. Requires that you define a value for --sysvol.", false);
            ValueArgument <string> sysvolArg           = new ValueArgument <string>('s', "sysvol", "Set the path to a domain SYSVOL directory.");
            ValueArgument <int>    intlevArg           = new ValueArgument <int>('i', "interestlevel", "The minimum interest level to display. i.e. findings with an interest level lower than x will not be seen in output. Defaults to 1, i.e. show everything except some extremely dull defaults. If you want to see those too, do -i 0.");

            //ValueArgument<string> domainArg = new ValueArgument<string>('d', "domain", "The domain to connect to. If not specified, connects to current user context domain.");
            //ValueArgument<string> usernameArg = new ValueArgument<string>('u', "username", "Username to authenticate as. SMB permissions checks will be run from this user's perspective.");
            //ValueArgument<string> passwordArg = new ValueArgument<string>('p', "password", "Password to use for authentication.");
            //parser.Arguments.Add(domainArg);
            //parser.Arguments.Add(usernameArg);
            //parser.Arguments.Add(passwordArg);
            parser.Arguments.Add(debugArg);
            parser.Arguments.Add(intlevArg);
            parser.Arguments.Add(sysvolArg);
            parser.Arguments.Add(offlineArg);

            // set a couple of defaults
            string sysvolPolDir = "";

            GlobalVar.OnlineChecks = true;

            try
            {
                parser.ParseCommandLine(args);
                //parser.ShowParsedArguments();
                if (debugArg.Parsed && debugArg.Value)
                {
                    GlobalVar.DebugMode = true;
                }
                if (offlineArg.Parsed && offlineArg.Value && sysvolArg.Parsed)
                {
                    // args config for valid offline run.
                    GlobalVar.OnlineChecks = false;
                    sysvolPolDir           = sysvolArg.Value;
                }
                if (offlineArg.Parsed && offlineArg.Value && !sysvolArg.Parsed)
                {
                    // handle someone trying to run in offline mode without giving a value for sysvol
                    Console.WriteLine("Offline mode requires you to provide a value for -s, the path where Grouper2 can find the domain SYSVOL share, or a copy of it at least.");
                    Environment.Exit(1);
                }
                if (intlevArg.Parsed)
                {
                    // handle interest level parsing
                    Console.WriteLine("Roger. Everything with an Interest Level lower than " + intlevArg.Value.ToString() + " is getting thrown on the floor.");
                    GlobalVar.IntLevelToShow = intlevArg.Value;
                }
                else
                {
                    GlobalVar.IntLevelToShow = 1;
                }

                if (sysvolArg.Parsed)
                {
                    sysvolPolDir = sysvolArg.Value;
                }
                //if (domainArg.Parsed || usernameArg.Parsed || passwordArg.Parsed)
                //{
                //    Console.WriteLine("I haven't set up anything to handle the domain/password stuff yet, so it won't work");
                //    Environment.Exit(1);
                //}
            }
            catch (CommandLineException e)
            {
                Console.WriteLine(e.Message);
            }

            JObject domainGpos = new JObject();

            // Ask the DC for GPO details
            if (GlobalVar.OnlineChecks)
            {
                Console.WriteLine("Trying to figure out what AD domain we're working with.");
                string currentDomainString = Domain.GetCurrentDomain().ToString();
                Console.WriteLine("Current AD Domain is: " + currentDomainString);
                if (sysvolPolDir == "")
                {
                    sysvolPolDir = @"\\" + currentDomainString + @"\sysvol\" + currentDomainString + @"\Policies\";
                }
            }

            Console.WriteLine("Targeting SYSVOL at: " + sysvolPolDir);

            // if we're online, get a bunch of metadata about the GPOs via LDAP
            if (GlobalVar.OnlineChecks)
            {
                domainGpos = LDAPstuff.GetDomainGpos();
            }

            string[] gpoPaths = new string[0];
            try
            {
                gpoPaths = Directory.GetDirectories(sysvolPolDir);
            }
            catch
            {
                Console.WriteLine("Sysvol path is broken. You should fix it.");
                Environment.Exit(1);
            }

            // create a JObject to put all our output goodies in.
            JObject grouper2Output = new JObject();

            // so for each uid directory (including ones with that dumb broken domain replication condition)
            // we're going to gather up all our goodies and put them into that dict we just created.
            foreach (var gpoPath in gpoPaths)
            {
                // create a dict to put the stuff we find for this GPO into.
                JObject gpoResult = new JObject();
                // Get the UID of the GPO from the file path.
                string[] splitPath = gpoPath.Split(Path.DirectorySeparatorChar);
                string   gpoUid    = splitPath[splitPath.Length - 1];

                // Make a JObject for GPO metadata
                JObject gpoProps = new JObject();
                // If we're online and talking to the domain, just use that data
                if (GlobalVar.OnlineChecks)
                {
                    JToken domainGpo = domainGpos[gpoUid];
                    gpoProps = (JObject)JToken.FromObject(domainGpo);
                }
                // otherwise do what we can with what we have
                else
                {
                    gpoProps = new JObject()
                    {
                        { "gpoUID", gpoUid },
                        { "gpoPath", gpoPath }
                    };
                }

                // TODO (and put in GPOProps)
                // get the policy owner
                // get whether it's linked and where
                // get whether it's enabled

                // Add all this crap into a dict, if we found anything of interest.
                gpoResult.Add("GPOProps", gpoProps);
                // turn dict of data for this gpo into jobj
                JObject gpoResultJson = (JObject)JToken.FromObject(gpoResult);

                // if I were smarter I would have done this shit with the machine and user dirs inside the Process methods instead of calling each one twice out here.
                // @liamosaur you reckon you can see how to clean it up after the fact?
                // Get the paths for the machine policy and user policy dirs
                string machinePolPath = Path.Combine(gpoPath, "Machine");
                string userPolPath    = Path.Combine(gpoPath, "User");

                // Process Inf and Xml Policy data for machine and user
                JArray machinePolInfResults    = ProcessInf(machinePolPath);
                JArray userPolInfResults       = ProcessInf(userPolPath);
                JArray machinePolGppResults    = ProcessGpXml(machinePolPath);
                JArray userPolGppResults       = ProcessGpXml(userPolPath);
                JArray machinePolScriptResults = ProcessScriptsIni(machinePolPath);
                JArray userPolScriptResults    = ProcessScriptsIni(userPolPath);

                // add all our findings to a JArray in what seems a very inefficient manner.
                JArray userFindings    = new JArray();
                JArray machineFindings = new JArray();
                if (machinePolGppResults != null && machinePolGppResults.HasValues)
                {
                    foreach (JObject finding in machinePolGppResults)
                    {
                        machineFindings.Add(finding);
                    }
                }
                if (userPolGppResults != null && userPolGppResults.HasValues)
                {
                    foreach (JObject finding in userPolGppResults)
                    {
                        userFindings.Add(finding);
                    }
                }
                if (machinePolGppResults != null && machinePolInfResults.HasValues)
                {
                    foreach (JObject finding in machinePolInfResults)
                    {
                        machineFindings.Add(finding);
                    }
                }
                if (userPolInfResults != null && userPolInfResults.HasValues)
                {
                    foreach (JObject finding in userPolInfResults)
                    {
                        userFindings.Add(finding);
                    }
                }
                if (machinePolScriptResults != null && machinePolScriptResults.HasValues)
                {
                    foreach (JObject finding in machinePolScriptResults)
                    {
                        machineFindings.Add(finding);
                    }
                }
                if (userPolScriptResults != null && userPolScriptResults.HasValues)
                {
                    foreach (JObject finding in userPolScriptResults)
                    {
                        userFindings.Add(finding);
                    }
                }
                // if there are any Findings, add it to the final output.
                if (userFindings.HasValues)
                {
                    JProperty userFindingsJProp = new JProperty("Findings in User Policy", userFindings);
                    gpoResultJson.Add(userFindingsJProp);
                }

                if (machineFindings.HasValues)
                {
                    JProperty machineFindingsJProp = new JProperty("Findings in Machine Policy", machineFindings);
                    gpoResultJson.Add(machineFindingsJProp);
                }

                // put into final output
                if (userFindings.HasValues || machineFindings.HasValues)
                {
                    grouper2Output.Add(gpoPath, gpoResultJson);
                }
            }

            // Final output is finally happening finally here:
            Console.WriteLine("RESULT!");
            Console.WriteLine("");
            Console.WriteLine(grouper2Output);
            Console.WriteLine("");
            // wait for 'anykey'
            Console.ReadKey();
        }
Пример #17
0
        private void AddTestArguments(CommandLineParser parser)
        {
            SwitchArgument helpArgument = new SwitchArgument("help", "Show help.", null, new[] { 'h', '?' })
            {
                Category   = "Help",
                IsOptional = true,
            };

            parser.Arguments.Add(helpArgument);

            ValueArgument <string> fileArgument = new ValueArgument <string>("file", "The file to load.")
            {
                Category      = "",
                IsOptional    = true,
                AllowMultiple = true,
            };

            parser.Arguments.Add(fileArgument);

            SwitchArgument recursiveArgument = new SwitchArgument("Recursive", "Enables recursive mode.", null, new[] { 'R' })
            {
                Category   = null,
                IsOptional = true
            };

            parser.Arguments.Add(recursiveArgument);

            SwitchArgument switchArgument1 = new SwitchArgument("Switch", "Another test switch.", null, new[] { 'S' })
            {
                Category   = "Test Category",
                IsOptional = true,
            };

            parser.Arguments.Add(switchArgument1);

            SwitchValueArgument <int> valueArgument = new SwitchValueArgument <int>(
                "value",
                new ValueArgument <int>("value", "The value.")
            {
                AllowMultiple = true
            },
                "This switch has a value.",
                null,
                new[] { 'v' })
            {
                Category   = "Test Category 2",
                IsOptional = true,
            };

            parser.Arguments.Add(valueArgument);

            SwitchValueArgument <float> boundedArgument = new SwitchValueArgument <float>(
                "bounded",
                new BoundedValueArgument <float>("value", "The value.", 1, 5)
            {
                AllowMultiple = true
            },
                "This is a bounded value.",
                null,
                new[] { 'b' })
            {
                Category   = "Test Category 2",
                IsOptional = true,
            };

            parser.Arguments.Add(boundedArgument);

            SwitchValueArgument <MyEnum> enumArgument = new SwitchValueArgument <MyEnum>(
                "Enum",
                new EnumArgument <MyEnum>("MyEnum", "The value."),
                "This is an enumeration.",
                null,
                new[] { 'e' })
            {
                Category   = "Test Category 2",
                IsOptional = true,
            };

            parser.Arguments.Add(enumArgument);

            SwitchValueArgument <MyFlags> flagsArgument = new SwitchValueArgument <MyFlags>(
                "Flags",
                new EnumArgument <MyFlags>("MyFlags", "The value."),
                "This is a combination of flags (= enumeration with FlagsAttribute).",
                null,
                new[] { 'f' })
            {
                Category   = "Test Category 2",
                IsOptional = true,
            };

            parser.Arguments.Add(flagsArgument);
        }
Пример #18
0
        static void Main(string[] args)
        {
            var commandLineParser = new CommandLineParser.CommandLineParser();

            var compilerPath = new FileArgument('c', "compiler", "Path to compiler")
            {
                Optional = false
            };

            var testsDirectory = new DirectoryArgument('t', "test-dir", "Path to tests directory")
            {
                Optional = false
            };

            var testLexer     = new SwitchArgument('l', "lexer", "Test lexer", false);
            var testParser    = new SwitchArgument('p', "parser", "Test parser", false);
            var testSemantics = new SwitchArgument('s', "semantics", "Test parser with semantics", false);
            var testCodeGen   = new SwitchArgument('g', "codegen", "Test code generation", false);
            var testAll       = new SwitchArgument('a', "all", "Launch all tests", false);

            commandLineParser.Arguments.Add(compilerPath);
            commandLineParser.Arguments.Add(testsDirectory);

            commandLineParser.Arguments.Add(testLexer);
            commandLineParser.Arguments.Add(testParser);
            commandLineParser.Arguments.Add(testSemantics);
            commandLineParser.Arguments.Add(testCodeGen);
            commandLineParser.Arguments.Add(testAll);

            var testGroupCertification = new ArgumentGroupCertification("a,p,l,s,g", EArgumentGroupCondition.AtLeastOneUsed);

            commandLineParser.Certifications.Add(testGroupCertification);

            try {
                commandLineParser.ParseCommandLine(args);
            }
            catch (CommandLineException) {
                commandLineParser.ShowUsageHeader = "dotnet Tester.dll [pathToCompiler] [pathToTestsRoot]";
                commandLineParser.ShowUsage();
            }


            if (testLexer.Value || testAll.Value)
            {
                TestLexer(compilerPath.Value.FullName, testsDirectory.Value.FullName);
            }

            if (testParser.Value || testAll.Value)
            {
                TestParser(compilerPath.Value.FullName, testsDirectory.Value.FullName, "parser");
            }

            if (testSemantics.Value || testAll.Value)
            {
                TestParser(compilerPath.Value.FullName, testsDirectory.Value.FullName, "semantics", true);
            }

            if (testCodeGen.Value || testAll.Value)
            {
                string nasmPath;
                string gccPath;

                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    //todo: remove hardcode?
                    nasmPath = @"C:\Program Files\NASM\nasm.exe";
                    gccPath  = @"C:\Users\Alexey\dev\toolchains\mingw-w64\x86_64-8.1.0-win32-seh-rt_v6-rev0\mingw64\bin\gcc.exe";
                }
                else
                {
                    nasmPath = "nasm";
                    gccPath  = "gcc";
                }
                TestCodeGen(compilerPath.Value.FullName, nasmPath, gccPath, testsDirectory.Value.FullName, "codegen");
            }
        }
Пример #19
0
        static void Main(string[] args)
        {
            var parser = new CommandLineParser.CommandLineParser
            {
                ShowUsageOnEmptyCommandline = false,
                AcceptSlash = true
            };

            //Optional
            var wait = new SwitchArgument(
                'w', "wait",
                "Wait for console input after output is completed", false)
            {
                Optional = true
            };

            parser.Arguments.Add(wait);

            var searchPath = new ValueArgument <string>(
                'p', "searchPath",
                "Directory path to search for and list files")
            {
                Optional = true
            };

            parser.Arguments.Add(searchPath);

            try
            {
                parser.ParseCommandLine(args);

                var dirSearchPath = string.IsNullOrEmpty(searchPath.Value) ? Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) : searchPath.Value;

                Console.Write("Scanning...");
                var results = new ConcurrentBag <string>();
                if (dirSearchPath != null)
                {
                    var d     = new DirectoryInfo(dirSearchPath);
                    var files = d.GetFiles("*.*", SearchOption.AllDirectories);
                    Parallel.ForEach(files, file =>
                    {
                        var relativePath = file.FullName.Replace(dirSearchPath, "");

                        var assemblyFileVersionInfo = FileVersionInfo.GetVersionInfo(file.FullName);
                        var assemblyFileInfo        = new FileInfo(file.FullName);
                        var version = string.IsNullOrEmpty(assemblyFileVersionInfo.FileVersion)
                            ? "0.0.0.0"
                            : assemblyFileVersionInfo.FileVersion;
                        var lastModified = string.Format($"{assemblyFileInfo.LastWriteTime.ToShortDateString()} {assemblyFileInfo.LastWriteTime.ToShortTimeString()}");

                        results.Add($"{lastModified.PadRight(20)} {version.PadRight(20)} {relativePath} ");
                    });
                }

                Console.WriteLine("Done.");
                var counter = 0;
                foreach (var result in results)
                {
                    counter++;
                    Console.WriteLine($"{counter.ToString().PadRight(8)} {result}");
                }

                if (wait.Value)
                {
                    Console.WriteLine("Press any key to continue...");
                    Console.ReadKey();
                }

                Environment.ExitCode = 0; //Success
            }
            catch (CommandLineException e)
            {
                Console.WriteLine("Unknown CommandLineException error: " + e.Message);
            }
        }
Пример #20
0
        public static void Main(string[] args)
        {
            if (!Windows.IsAdministrator())
            {
                logger.Error("You must run this with Administrator permission");
                Environment.Exit(1);
            }

            var            parser = new CommandLineParser.CommandLineParser();
            SwitchArgument clear  = new SwitchArgument('c', "clear", "Clear the configuration", false);

            parser.Arguments.Add(clear);
            parser.ParseCommandLine(args);

            logger.Info("Getting profile");
            var userSettings = GettingProfileUserData();

            if (!clear.Value)
            {
                if (userSettings == null)
                {
                    logger.Error("You must set user data settings using any bellow methods:");
                    logger.Info("APP ARGUMENTS => aplication arguments");
                    logger.Info("APP SETTINGS => ProxyMySystem.exe.config");
                    logger.Info("INI FILE => ProxyMySystem.ini");
                    logger.Info("JSON FILE => ProxyMySystem.json");
                    logger.Info("VARIABLE => environment variables");
                    logger.Info("The most important parameter is: PROXY_HOST then the first data settings that there are this value will be used");
                    Environment.Exit(2);
                }
                else
                {
                    logger.Info("Starting process to configure proxy: " + userSettings.ProxyHost);
                }
            }
            else
            {
                logger.Info("Starting clearing process");
            }

            var urlTemplate = new UrlTemplate(userSettings, clear.Value);

            ConfigInternetSettings(urlTemplate);
            ConfigWindowsCredential(urlTemplate);
            ConfigEnvironmentVariable(urlTemplate);
            ConfigNpm(urlTemplate);
            ConfigGit(urlTemplate);
            ConfigChocolatey(urlTemplate);
            //ConfigYarn(urlTemplate);
            ConfigNuget(urlTemplate);
            ConfigBower(urlTemplate);
            ConfigAndroidSdk(urlTemplate);
            ConfigGradle(urlTemplate);

            // Configure cntlm on localhost
            //var cntlmPath = Path.Combine(Environment.CurrentDirectory, "Lib", "cntlm-0.92.3");
            //var cntlmFiles = Directory.GetFiles(cntlmPath);
            //if (cntlmFiles.Contains(Path.Combine(cntlmPath, "cygrunsrv.exe")) && cntlmFiles.Contains(Path.Combine(cntlmPath, "cntlm.exe")))
            //{
            //    logger.Info("Setting cntlm on localhost");

            //    var existService = Msdos.Run(Path.Combine(cntlmPath, "cygrunsrv"), $@"--query cntlm");
            //    if (!existService.StandardError.Contains("The specified service does not exist as an installed service"))
            //    {
            //        // remove cntlm
            //        var remove = Msdos.Run(Path.Combine(cntlmPath, "cygrunsrv"), $@"--remove cntlm");
            //    }

            //    // Install
            //    var result = Msdos.Run(Path.Combine(cntlmPath, "cygrunsrv"), $@"--install cntlm --path {Path.Combine(cntlmPath, "cntlm.exe")}");
            //    var start = Msdos.Run(Path.Combine(cntlmPath, "cygrunsrv"), $@"--start cntlm");
            //}

            if (clear.Value)
            {
                logger.Info("The system has been cleared");
            }
            else
            {
                logger.Info("The system has been configured");
            }

            var refreshEnv = Msdos.IsInstalled(@"C:\Windows\DEV\Github\proxy-at-work\src\RefreshEnv.cmd");

            if (refreshEnv)
            {
                logger.Info("The environment variables was updated and the new settings were applied.");
            }
            else
            {
                logger.Info("Please, close all instances of Command Prompt or any program that use proxy and open again to reload newest settings");
            }

            Environment.Exit(0);
        }
Пример #21
0
        private static void Main(string[] args)
        {
            AppDomain.CurrentDomain.UnhandledException
                += delegate(object sender, UnhandledExceptionEventArgs eargs)
                {
                Exception exception = (Exception)eargs.ExceptionObject;
                System.Console.WriteLine(@"Unhandled exception: " + exception);
                Environment.Exit(1);
                };

            CommandLineParser.CommandLineParser parser = new CommandLineParser.CommandLineParser();

            ValueArgument <string> userArgument     = new ValueArgument <string>('u', "user", "ptc username");
            ValueArgument <string> passwordArgument = new ValueArgument <string>('p', "password", "ptc password");

            SwitchArgument teleportArgument = new SwitchArgument('t', "teleport", "use teleport", false);

            parser.Arguments.Add(userArgument);
            parser.Arguments.Add(passwordArgument);
            parser.Arguments.Add(teleportArgument);

            try
            {
                /* parse command line arguments */
                parser.ParseCommandLine(args);
                /* this prints results to the console */
                //parser.ShowParsedArguments();
            }
            catch (CommandLineException e)
            {
                System.Console.WriteLine(e.Message);
                parser.ShowUsage();
                return;
            }

            var setting = new Settings();

            setting.PtcUsername = userArgument.Value;
            setting.PtcPassword = passwordArgument.Value;
            setting.UseTeleportInsteadOfWalking = teleportArgument.Value;

            string path = Path.Combine(Directory.GetCurrentDirectory(), setting.PtcUsername);

            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }


            ServicePointManager.ServerCertificateValidationCallback = Validator;
            Logger.SetLogger();

            Task.Run(() =>
            {
                try
                {
                    new Logic.Logic(setting).Execute().Wait();
                }
                catch (PtcOfflineException)
                {
                    Logger.Write("PTC Servers are probably down OR your credentials are wrong. Try google", LogLevel.Error);
                    Logger.Write("Trying again in 60 seconds...");
                    Thread.Sleep(60000);
                    new Logic.Logic(new Settings()).Execute().Wait();
                }
                catch (AccountNotVerifiedException)
                {
                    Logger.Write("Account not verified. - Exiting");
                    Environment.Exit(0);
                }
                catch (Exception ex)
                {
                    Logger.Write($"Unhandled exception: {ex}", LogLevel.Error);
                    new Logic.Logic(new Settings()).Execute().Wait();
                }
            });

            string input = System.Console.ReadLine();

            while (input != "q")
            {
                input = System.Console.ReadLine();
                if (input == "e")
                {
                    System.Console.WriteLine("export");
                }
            }
        }
Пример #22
0
        private static Options ParseImpl(string[] args)
        {
            BlockingMq Mq = BlockingMq.GetMq();

            Mq.Info("Parsing args...");
            Options parsedConfig = new Options();

            // define args
            ValueArgument <string> configFileArg = new ValueArgument <string>('z', "config", "Path to a .toml config file. Run with \'generate\' to puke a sample config file into the working directory.");
            ValueArgument <string> outFileArg    = new ValueArgument <string>('o', "outfile",
                                                                              "Path for output file. You probably want this if you're not using -s.");
            ValueArgument <string> verboseArg = new ValueArgument <string>('v', "verbosity",
                                                                           "Controls verbosity level, options are Trace (most verbose), Debug (less verbose), Info (less verbose still, default), and Data (results only). e.g '-v debug' ");
            SwitchArgument helpArg   = new SwitchArgument('h', "help", "Displays this help.", false);
            SwitchArgument stdOutArg = new SwitchArgument('s', "stdout",
                                                          "Enables outputting results to stdout as soon as they're found. You probably want this if you're not using -o.",
                                                          false);
            ValueArgument <int>    interestLevel = new ValueArgument <int>('b', "interest", "Interest level to report (0-3)");
            ValueArgument <string> snaffleArg    = new ValueArgument <string>('m', "snaffle",
                                                                              "Enables and assigns an output dir for Snaffler to automatically snaffle a copy of any found files.");
            ValueArgument <long> snaffleSizeArg = new ValueArgument <long>('l', "snafflesize", "Maximum size of file to snaffle, in bytes. Defaults to 10MB.");
            //var fileHuntArg = new SwitchArgument('f', "filehuntoff",
            //    "Disables file discovery, will only perform computer and share discovery.", false);
            ValueArgument <string> dirTargetArg = new ValueArgument <string>('i', "dirtarget",
                                                                             "Disables computer and share discovery, requires a path to a directory in which to perform file discovery.");
            ValueArgument <string> domainArg = new ValueArgument <string>('d', "domain",
                                                                          "Domain to search for computers to search for shares on to search for files in. Easy.");
            ValueArgument <string> domainControllerArg = new ValueArgument <string>('c', "domaincontroller",
                                                                                    "Domain controller to query for a list of domain computers.");
            ValueArgument <long> maxGrepSizeArg = new ValueArgument <long>('r', "maxgrepsize",
                                                                           "The maximum size file (in bytes) to search inside for interesting strings. Defaults to 500k.");
            ValueArgument <int> grepContextArg = new ValueArgument <int>('j', "grepcontext",
                                                                         "How many bytes of context either side of found strings in files to show, e.g. -j 200");
            SwitchArgument      domainUserArg     = new SwitchArgument('u', "domainusers", "Makes Snaffler grab a list of interesting-looking accounts from the domain and uses them in searches.", false);
            ValueArgument <int> maxThreadsArg     = new ValueArgument <int>('x', "maxthreads", "How many threads to be snaffling with. Any less than 4 and you're gonna have a bad time.");
            SwitchArgument      tsvArg            = new SwitchArgument('y', "tsv", "Makes Snaffler output as tsv.", false);
            SwitchArgument      dfsArg            = new SwitchArgument('f', "dfs", "Limits Snaffler to finding file shares via DFS, for \"OPSEC\" reasons.", false);
            SwitchArgument      findSharesOnlyArg = new SwitchArgument('a', "sharesonly",
                                                                       "Stops after finding shares, doesn't walk their filesystems.", false);
            ValueArgument <string> compTargetArg = new ValueArgument <string>('n', "comptarget", "Computer (or comma separated list) to target.");
            ValueArgument <string> ruleDirArg    = new ValueArgument <string>('p', "rulespath", "Path to a directory full of toml-formatted rules. Snaffler will load all of these in place of the default ruleset.");
            ValueArgument <string> logType       = new ValueArgument <string>('t', "logtype", "Type of log you would like to output. Currently supported options are plain and JSON. Defaults to plain.");

            // list of letters i haven't used yet: egknqw

            CommandLineParser.CommandLineParser parser = new CommandLineParser.CommandLineParser();
            parser.Arguments.Add(configFileArg);
            parser.Arguments.Add(outFileArg);
            parser.Arguments.Add(helpArg);
            parser.Arguments.Add(stdOutArg);
            parser.Arguments.Add(snaffleArg);
            parser.Arguments.Add(snaffleSizeArg);
            parser.Arguments.Add(dirTargetArg);
            parser.Arguments.Add(interestLevel);
            parser.Arguments.Add(domainArg);
            parser.Arguments.Add(verboseArg);
            parser.Arguments.Add(domainControllerArg);
            parser.Arguments.Add(maxGrepSizeArg);
            parser.Arguments.Add(grepContextArg);
            parser.Arguments.Add(domainUserArg);
            parser.Arguments.Add(tsvArg);
            parser.Arguments.Add(dfsArg);
            parser.Arguments.Add(findSharesOnlyArg);
            parser.Arguments.Add(maxThreadsArg);
            parser.Arguments.Add(compTargetArg);
            parser.Arguments.Add(ruleDirArg);
            parser.Arguments.Add(logType);

            // extra check to handle builtin behaviour from cmd line arg parser
            if ((args.Contains("--help") || args.Contains("/?") || args.Contains("help") || args.Contains("-h") || args.Length == 0))
            {
                parser.ShowUsage();
                Environment.Exit(0);
            }

            TomlSettings settings = TomlSettings.Create(cfg => cfg
                                                        .ConfigureType <LogLevel>(tc =>
                                                                                  tc.WithConversionFor <TomlString>(conv => conv
                                                                                                                    .FromToml(s => (LogLevel)Enum.Parse(typeof(LogLevel), s.Value, ignoreCase: true))
                                                                                                                    .ToToml(e => e.ToString()))));

            try
            {
                parser.ParseCommandLine(args);

                if (logType.Parsed && !String.IsNullOrWhiteSpace(logType.Value))
                {
                    //Set the default to plain
                    parsedConfig.LogType = LogType.Plain;
                    //if they set a different type then replace it with the new type.
                    if (logType.Value.ToLower() == "json")
                    {
                        parsedConfig.LogType = LogType.JSON;
                    }
                    else
                    {
                        Mq.Info("Invalid type argument passed (" + logType.Value + ") defaulting to plaintext");
                    }
                }

                if (ruleDirArg.Parsed && !String.IsNullOrWhiteSpace(ruleDirArg.Value))
                {
                    parsedConfig.RuleDir = ruleDirArg.Value;
                }

                // get the args into our config

                // output args
                if (outFileArg.Parsed && (!String.IsNullOrEmpty(outFileArg.Value)))
                {
                    parsedConfig.LogToFile   = true;
                    parsedConfig.LogFilePath = outFileArg.Value;
                    Mq.Degub("Logging to file at " + parsedConfig.LogFilePath);
                }

                if (dfsArg.Parsed)
                {
                    parsedConfig.DfsOnly = dfsArg.Value;
                }

                if (compTargetArg.Parsed)
                {
                    string[] compTargets = null;
                    if (compTargetArg.Value.Contains(","))
                    {
                        compTargets = compTargetArg.Value.Split(',');
                    }
                    else
                    {
                        compTargets = new string[] { compTargetArg.Value };
                    }
                    parsedConfig.ComputerTargets = compTargets;
                }

                if (findSharesOnlyArg.Parsed)
                {
                    parsedConfig.ScanFoundShares = false;
                }
                if (maxThreadsArg.Parsed)
                {
                    parsedConfig.MaxThreads = maxThreadsArg.Value;
                }

                parsedConfig.ShareThreads = parsedConfig.MaxThreads / 3;
                parsedConfig.FileThreads  = parsedConfig.MaxThreads / 3;
                parsedConfig.TreeThreads  = parsedConfig.MaxThreads / 3;

                if (tsvArg.Parsed)
                {
                    parsedConfig.LogTSV = true;
                    if (parsedConfig.Separator == ' ')
                    {
                        parsedConfig.Separator = '\t';
                    }
                }

                // Set loglevel.
                if (verboseArg.Parsed)
                {
                    parsedConfig.LogLevelString = verboseArg.Value;
                    Mq.Degub("Requested verbosity level: " + parsedConfig.LogLevelString);
                }

                // if enabled, display findings to the console
                parsedConfig.LogToConsole = stdOutArg.Parsed;
                Mq.Degub("Enabled logging to stdout.");

                // args that tell us about targeting
                if ((domainArg.Parsed) && (!String.IsNullOrEmpty(domainArg.Value)))
                {
                    parsedConfig.TargetDomain = domainArg.Value;
                    Mq.Degub("Target domain is " + domainArg.Value);
                }

                if ((domainControllerArg.Parsed) && (!String.IsNullOrEmpty(domainControllerArg.Value)))
                {
                    parsedConfig.TargetDc = domainControllerArg.Value;
                    Mq.Degub("Target DC is " + domainControllerArg.Value);
                }

                if (domainUserArg.Parsed)
                {
                    parsedConfig.DomainUserRules = true;
                    Mq.Degub("Enabled use of domain user accounts in rules.");
                }

                if (dirTargetArg.Parsed)
                {
                    parsedConfig.ShareFinderEnabled = false;
                    parsedConfig.PathTargets.Add(dirTargetArg.Value);
                    Mq.Degub("Disabled finding shares.");
                    Mq.Degub("Target path is " + dirTargetArg.Value);
                }

                if (maxGrepSizeArg.Parsed)
                {
                    parsedConfig.MaxSizeToGrep = maxGrepSizeArg.Value;
                    Mq.Degub("We won't bother looking inside files if they're bigger than " + parsedConfig.MaxSizeToGrep +
                             " bytes");
                }

                if (snaffleSizeArg.Parsed)
                {
                    parsedConfig.MaxSizeToSnaffle = snaffleSizeArg.Value;
                }

                if (interestLevel.Parsed)
                {
                    parsedConfig.InterestLevel = interestLevel.Value;
                    Mq.Degub("Requested interest level: " + parsedConfig.InterestLevel);
                }

                // how many bytes
                if (grepContextArg.Parsed)
                {
                    parsedConfig.MatchContextBytes = grepContextArg.Value;
                    Mq.Degub(
                        "We'll show you " + grepContextArg.Value +
                        " bytes of context around matches inside files.");
                }

                // if enabled, grab a copy of files that we like.
                if (snaffleArg.Parsed)
                {
                    if (snaffleArg.Value.Length <= 0)
                    {
                        Mq.Error("-m or -mirror arg requires a path value.");
                        throw new ArgumentException("Invalid argument combination.");
                    }

                    parsedConfig.Snaffle     = true;
                    parsedConfig.SnafflePath = snaffleArg.Value.TrimEnd('\\');
                    Mq.Degub("Mirroring matched files to path " + parsedConfig.SnafflePath);
                }

                if (configFileArg.Parsed)
                {
                    if (configFileArg.Value.Equals("generate"))
                    {
                        Toml.WriteFile(parsedConfig, ".\\default.toml", settings);
                        Console.WriteLine("Wrote config values to .\\default.toml");
                        parsedConfig.LogToConsole = true;
                        Mq.Degub("Enabled logging to stdout.");
                        Environment.Exit(0);
                    }
                    else
                    {
                        string configFile = configFileArg.Value;
                        parsedConfig = Toml.ReadFile <Options>(configFile, settings);
                        Mq.Info("Read config file from " + configFile);
                    }
                }

                if (!parsedConfig.LogToConsole && !parsedConfig.LogToFile)
                {
                    Mq.Error(
                        "\nYou didn't enable output to file or to the console so you won't see any results or debugs or anything. Your l0ss.");
                    throw new ArgumentException("Pointless argument combination.");
                }

                if (parsedConfig.ClassifierRules.Count <= 0)
                {
                    if (String.IsNullOrWhiteSpace(parsedConfig.RuleDir))
                    {
                        // get all the embedded toml file resources
                        string[]      resourceNames = Assembly.GetExecutingAssembly().GetManifestResourceNames();
                        StringBuilder sb            = new StringBuilder();

                        foreach (string resourceName in resourceNames)
                        {
                            if (!resourceName.EndsWith(".toml"))
                            {
                                // skip this one as it's just metadata
                                continue;
                            }
                            string ruleFile = ReadResource(resourceName);
                            sb.AppendLine(ruleFile);
                        }

                        string bulktoml = sb.ToString();

                        // deserialise the toml to an actual ruleset
                        RuleSet ruleSet = Toml.ReadString <RuleSet>(bulktoml, settings);

                        // stick the rules in our config!
                        parsedConfig.ClassifierRules = ruleSet.ClassifierRules;
                    }
                    else
                    {
                        string[]      tomlfiles = Directory.GetFiles(parsedConfig.RuleDir, "*.toml", SearchOption.AllDirectories);
                        StringBuilder sb        = new StringBuilder();
                        foreach (string tomlfile in tomlfiles)
                        {
                            string tomlstring = File.ReadAllText(tomlfile);
                            sb.AppendLine(tomlstring);
                        }
                        string bulktoml = sb.ToString();
                        // deserialise the toml to an actual ruleset
                        RuleSet ruleSet = Toml.ReadString <RuleSet>(bulktoml, settings);

                        // stick the rules in our config!
                        parsedConfig.ClassifierRules = ruleSet.ClassifierRules;
                    }
                }

                parsedConfig.PrepareClassifiers();
            }
            catch (Exception e)
            {
                Mq.Error(e.ToString());
                throw;
            }

            return(parsedConfig);
        }
        public CommandLineParser.CommandLineParser InitAdditionalArguments()
        {
            var commandLineParser = new CommandLineParser.CommandLineParser();

            commandLineParser.ShowUsageOnEmptyCommandline = true;

            SwitchArgument showArgument = new SwitchArgument('s', "show", "Set whether show or not", true);

            SwitchArgument hideArgument = new SwitchArgument('h', "hide", "Set whether hid or not", false);

            ValueArgument <string> level = new ValueArgument <string>('l', "level", "Set the level");

            ValueArgument <decimal> version = new ValueArgument <decimal>('v', "version", "Set desired version");

            ValueArgument <Point> point = new ValueArgument <Point>('p', "point", "specify the point");

            BoundedValueArgument <int> optimization = new BoundedValueArgument <int>('o', "optimization", 0, 3);

            EnumeratedValueArgument <string> color = new EnumeratedValueArgument <string>('c', "color", new[] { "red", "green", "blue" });

            FileArgument inputFile = new FileArgument('i', "input", "Input file");

            inputFile.FileMustExist = false;
            FileArgument outputFile = new FileArgument('x', "output", "Output file");

            outputFile.FileMustExist = false;

            DirectoryArgument inputDirectory = new DirectoryArgument('d', "directory", "Input directory");

            inputDirectory.DirectoryMustExist = false;

            point.ConvertValueHandler = delegate(string stringValue)
            {
                if (stringValue.StartsWith("[") && stringValue.EndsWith("]"))
                {
                    string[] parts = stringValue.Substring(1, stringValue.Length - 2).Split(';', ',');
                    Point    p     = new Point();
                    p.x = int.Parse(parts[0]);
                    p.y = int.Parse(parts[1]);
                    return(p);
                }

                throw new CommandLineArgumentException("Bad point format", "point");
            };


            commandLineParser.Arguments.Add(showArgument);
            commandLineParser.Arguments.Add(hideArgument);
            commandLineParser.Arguments.Add(level);
            commandLineParser.Arguments.Add(version);
            commandLineParser.Arguments.Add(point);
            commandLineParser.Arguments.Add(optimization);
            commandLineParser.Arguments.Add(color);
            commandLineParser.Arguments.Add(inputFile);
            commandLineParser.Arguments.Add(outputFile);
            commandLineParser.Arguments.Add(inputDirectory);

            /*
             * Example: requiring additional arguments of
             * certain type (1 file in this case)
             *
             */
            FileArgument additionalFileArgument1 = new FileArgument('_');

            additionalFileArgument1.FileMustExist = false;
            additionalFileArgument1.Optional      = false;
            FileArgument additionalFileArgument2 = new FileArgument('_');

            additionalFileArgument2.FileMustExist = false;
            additionalFileArgument2.Optional      = false;

            commandLineParser.AdditionalArgumentsSettings.TypedAdditionalArguments.Add(additionalFileArgument1);
            commandLineParser.AdditionalArgumentsSettings.TypedAdditionalArguments.Add(additionalFileArgument2);

            return(commandLineParser);
        }
Пример #24
0
        static void Main(string[] args)
        {
            var parser = new CommandLineParser.CommandLineParser
            {
                ShowUsageOnEmptyCommandline = true,
                AcceptSlash = true
            };

            /*
             * -p "C:\Users\paul.ikeda\source\Repos\SX_Core" -w
             *
             * -p "C:\Users\paul.ikeda\source\Repos\SX_Core" -b "master" -g "SX_Core" -w -c
             */

            //Required
            var projectFilesPath = new ValueArgument <string>(
                'p', "projectFilesPath",
                "Sets root search path for project files")
            {
                Optional = false
            };

            parser.Arguments.Add(projectFilesPath);

            //Optional
            var ruleFilePath = new ValueArgument <string>(
                'r', "ruleFilePath",
                "Sets file path for rule file (uses exe location otherwise)")
            {
                Optional = true
            };

            parser.Arguments.Add(ruleFilePath);
            var outputProjectsToSearch = new SwitchArgument(
                'o', "outputProjectsToSearch",
                "Output to console the list of projects to search through", false)
            {
                Optional = true
            };

            parser.Arguments.Add(outputProjectsToSearch);
            var waitOnCompletion = new SwitchArgument(
                'w', "waitOnCompletion",
                "Wait for user input key when done processing before exiting", false)
            {
                Optional = true
            };

            parser.Arguments.Add(waitOnCompletion);

            var repositoryName = new ValueArgument <string>(
                'g', "repositoryName",
                "Name of the repository for previous build comparison")
            {
                Optional = true
            };

            parser.Arguments.Add(repositoryName);
            var branchName = new ValueArgument <string>(
                'b', "branchName",
                "Name of the repository's branch for previous build comparison")
            {
                Optional = true
            };

            parser.Arguments.Add(branchName);
            var enableRunAndCompareMode = new SwitchArgument(
                'c', "enableRunAndCompareMode",
                "Process normally and compare against previous build. Return an error code if the number of warnings or errors has increased. Requires repository and branch names.", false)
            {
                Optional = true
            };

            parser.Arguments.Add(enableRunAndCompareMode);

            try
            {
                parser.ParseCommandLine(args);
                //parser.ShowParsedArguments();

                var processor = new Processor
                {
                    ProjectsDirectory      = projectFilesPath.Value,
                    RuleFilePath           = ruleFilePath.Value,
                    OutputProjectsToSearch = outputProjectsToSearch.Value,
                    PauseBeforeExit        = waitOnCompletion.Value,
                    RepositoryName         = repositoryName.Value,
                    BranchName             = branchName.Value,
                    RunAndCompareMode      = enableRunAndCompareMode.Value
                };

                processor.Process();

                Environment.ExitCode = 0; //Success
            }
            catch (CommandLineException e)
            {
                Console.WriteLine("Unknown CommandLineException error: " + e.Message);
                Environment.ExitCode = (int)ErrorCodes.UnknownCommandLineExceptionError;
            }

            if (waitOnCompletion.Value)
            {
                Console.WriteLine("Press any key to continue...");
                Console.ReadKey();
            }
        }