示例#1
0
        public void InfoTest()
        {
            SslLabsClient client = new SslLabsClient();

            Info info = client.GetInfo();

            Assert.IsNotNull(info);
        }
示例#2
0
        public void InfoTest()
        {
            SslLabsClient client = new SslLabsClient();

            Info info = client.GetInfo();

            Assert.IsNotNull(info);

            TestHelpers.EnsureAllPropertiesSet(info);
        }
示例#3
0
        static int Main(string[] args)
        {
            Options options = new Options();

            options.MaxConcurrentAssesments = DefaultMaxAssesments;
            options.MaxAge = DefaultMaxAge;

            OptionSet parser = new OptionSet();

            parser.Add("f|file=", "Input file, one host pr. line, required", s => options.Input = s);
            parser.Add("o|output=", "Output directory, will be created", s => options.Output    = s);
            parser.Add("n|new", "Forces new scans", s => options.ForceNew   = true);
            parser.Add("p|publish", "Published scans", s => options.Publish = true);
            parser.Add("w|overwrite", "Overwrite local scans, older than MaxAge", s => options.Overwrite = true);
            parser.Add <int>("a|maxage=", "Specify a MaxAge parameter, default: " + DefaultMaxAge, s => options.MaxAge = s);
            parser.Add <int>("m|max=", "Max concurrent scans, default: " + DefaultMaxAssesments, s => options.MaxConcurrentAssesments = s);
            parser.Add("e|endpoint=", "Endpoint. 'prod' or 'dev'", s => options.Endpoint = s);

            List <string> excessArgs = parser.Parse(args);

            if (string.IsNullOrEmpty(options.Input) || !File.Exists(options.Input))
            {
                Console.WriteLine("Missing input file");
                Console.WriteLine();
                Console.WriteLine("Help:");
                parser.WriteOptionDescriptions(Console.Out);

                return(1);
            }

            if (string.IsNullOrEmpty(options.Output))
            {
                Console.WriteLine("Missing output directory");
                Console.WriteLine();
                Console.WriteLine("Help:");
                parser.WriteOptionDescriptions(Console.Out);

                return(1);
            }

            if (!Directory.Exists(options.Output))
            {
                Directory.CreateDirectory(options.Output);
            }

            Queue <string> domains     = new Queue <string>();
            bool           anyBadInput = false;

            foreach (string line in File.ReadLines(options.Input))
            {
                if (Uri.CheckHostName(line) != UriHostNameType.Dns)
                {
                    Console.WriteLine("Bad input: " + line);
                    anyBadInput = true;
                }
                else
                {
                    domains.Enqueue(line);
                }
            }

            if (anyBadInput)
            {
                Console.WriteLine("One or more bad lines found - please correct");

                return(2);
            }

            Console.WriteLine("Beginning work on {0:N0} domains", domains.Count);

            Uri endpoint = new Uri("https://api.ssllabs.com/api/v2/");

            if (options.Endpoint == "dev")
            {
                endpoint = new Uri("https://api.dev.ssllabs.com/api/v2/");
            }

            int           completedTasks = 0;
            SslLabsClient client         = new SslLabsClient(endpoint);

            client.WaitTimePreScan = TimeSpan.FromSeconds(20);
            client.WaitTimeScan    = TimeSpan.FromSeconds(10);

            Info sslLabsInfo = client.GetInfo();

            int?maxAge = options.MaxAge;

            AnalyzeOptions startOptions = AnalyzeOptions.None;

            if (options.ForceNew)
            {
                startOptions |= AnalyzeOptions.StartNew;
                maxAge        = null;
            }
            else
            {
                startOptions = AnalyzeOptions.ReturnAllIfDone;
            }

            if (options.Publish)
            {
                startOptions |= AnalyzeOptions.Publish;
            }

            DateTime lastStatus     = DateTime.UtcNow;
            object   lastStatusLock = new object();
            Action   printStatus    = () =>
            {
                lock (lastStatusLock)
                {
                    if ((DateTime.UtcNow - lastStatus).TotalSeconds < 5)
                    {
                        return;
                    }

                    lastStatus = DateTime.UtcNow;

                    Console.WriteLine("Queue: {0:N0}, running: {1:N0} (cur.limit: {2:N0}), completed: {3:N0}", domains.Count, client.CurrentAssesments, client.MaxAssesments, completedTasks);
                }
            };

            AutoResetEvent limitChangedEvent = new AutoResetEvent(false);

            client.MaxAssesmentsChanged     += () => limitChangedEvent.Set();
            client.CurrentAssesmentsChanged += () => limitChangedEvent.Set();

            while (domains.Any())
            {
                string domain   = domains.Peek();
                string scanPath = Path.Combine(options.Output, domain + ".scan");

                // Is it done already?
                Analysis analysis;

                if (File.Exists(scanPath))
                {
                    if (options.Overwrite && maxAge.HasValue)
                    {
                        analysis = JsonConvert.DeserializeObject <Analysis>(File.ReadAllText(scanPath));

                        int age = (int)(DateTime.UtcNow - analysis.TestTime).TotalHours;
                        if (age > maxAge)
                        {
                            // Process this
                            analysis = null;
                        }
                        else
                        {
                            // Skip
                            domains.Dequeue();
                            continue;
                        }
                    }
                    else
                    {
                        // Skip
                        domains.Dequeue();
                        continue;
                    }
                }

                // Attempt to start the task
                while (true)
                {
                    TryStartResult didStart;
                    try
                    {
                        didStart = client.TryStartAnalysis(domain, maxAge, out analysis, startOptions);
                    }
                    catch (WebException ex)
                    {
                        Console.WriteLine("(Domain: " + domain + ") Webexception starting scan, waiting 3s: " + ex.Message);
                        limitChangedEvent.WaitOne(3000);
                        continue;
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("(Domain: " + domain + ") Exception while starting scan, waiting 30s: " + ex.Message);
                        Thread.Sleep(30000);
                        continue;
                    }

                    if (didStart == TryStartResult.RateLimit)
                    {
                        Thread.Sleep(sslLabsInfo.NewAssessmentCoolOff);
                        continue;
                    }

                    if (didStart == TryStartResult.Ok)
                    {
                        printStatus();
                        break;
                    }

                    // Wait for one to free up, fall back to trying every 30s
                    limitChangedEvent.WaitOne(30000);

                    printStatus();
                }

                // The task was started
                domains.Dequeue();
                //Console.WriteLine("Started " + domain);

                Task.Factory.StartNew(() =>
                {
                    Analysis innerAnalysis = null;
                    if (analysis != null && analysis.Status == AnalysisStatus.READY)
                    {
                        // Use the one we fetched immediately
                        innerAnalysis = analysis;
                    }

                    while (innerAnalysis == null)
                    {
                        try
                        {
                            // Block till we have an analysis
                            innerAnalysis = client.GetAnalysisBlocking(domain);
                        }
                        catch (WebException ex)
                        {
                            Console.WriteLine("(Domain: " + domain + ") Webexception waiting for scan, waiting 3s: " + ex.Message);
                            Thread.Sleep(3000);
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine("(Domain: " + domain + ") Exception while waiting for scan, waiting 30s: " + ex.Message);
                            Thread.Sleep(30000);
                        }
                    }

                    File.WriteAllText(scanPath, JsonConvert.SerializeObject(innerAnalysis));

                    Console.WriteLine("Completed " + domain);

                    Interlocked.Increment(ref completedTasks);

                    limitChangedEvent.Set();
                });
            }

            Timer timer = new Timer(2000);

            timer.Elapsed += (sender, eventArgs) => printStatus();
            timer.Start();

            while (true)
            {
                Info info = client.GetInfo();
                if (info.CurrentAssessments == 0)
                {
                    break;
                }

                // Wait for tasks to finish, fall back to checking every 15s
                limitChangedEvent.WaitOne(15000);
            }

            timer.Stop();

            return(0);
        }
示例#4
0
        static int Main(string[] args)
        {
            // SslLabsCli ssllabs.com --progress --new --nowait

            Options options = new Options();

            OptionSet parser = new OptionSet();

            parser.Add("p|progress", "Show progress while waiting", s => options.Progress = true);
            parser.Add("n|new", "Force a new scan", s => options.New = true);
            parser.Add("w|nowait", "Exit if no scan is available", s => options.NoWait = true);
            parser.Add("s|save", "Save the scan to a file", s => options.Save          = s);

            List <string> leftoverArgs = parser.Parse(args);

            options.Hostname = leftoverArgs.FirstOrDefault();

            if (string.IsNullOrEmpty(options.Hostname))
            {
                Console.WriteLine("Usage: ");
                Console.WriteLine("  SslLabsCli [options] ssllabs.com");
                Console.WriteLine();
                Console.WriteLine("Options");
                parser.WriteOptionDescriptions(Console.Out);
                Console.WriteLine();

                return(1);
            }

            Host analysis = HandleFetch(options);

            if (analysis.Status == AnalysisStatus.ERROR)
            {
                AwesomeConsole.WriteLine("An error occurred", ConsoleColor.Red);
                AwesomeConsole.Write("Status: ");
                AwesomeConsole.WriteLine(analysis.StatusMessage, ConsoleColor.Cyan);

                AwesomeConsole.WriteLine("Messages from SSLLabs");
                Info info = Client.GetInfo();

                foreach (string msg in info.Messages)
                {
                    AwesomeConsole.WriteLine("  " + msg, ConsoleColor.Yellow);
                }

                return(3);
            }

            if (analysis.Status != AnalysisStatus.READY)
            {
                AwesomeConsole.WriteLine("Analysis not available", ConsoleColor.DarkYellow);
                return(2);
            }

            PresentAnalysis(analysis);

            if (!string.IsNullOrEmpty(options.Save))
            {
                File.WriteAllText(options.Save, JsonConvert.SerializeObject(analysis, Formatting.Indented));
            }

            return(0);
        }