示例#1
0
        static void Main(string[] args)
        {
            JsonConvert.DefaultSettings = () => new JsonSerializerSettings
            {
                MissingMemberHandling = MissingMemberHandling.Error,
                ContractResolver      = new FailingContractResolver(),
                Error = Error
            };

            SslLabsClient client = new SslLabsClient();

            // Run a method call

            //client.GetInfo();
            var analysis = client.GetAnalysis("ssllabs.com", null, AnalyzeOptions.FromCache | AnalyzeOptions.ReturnAll);

            //var res2 = File.ReadAllText("out_control.txt");
            //var analysis = JsonConvert.DeserializeObject<Host>(res2);

            //var res1 = JsonConvert.SerializeObject(analysis, Formatting.Indented);
            //File.WriteAllText("out_res.txt", res1);

            // Examine JSON errors
            Console.WriteLine($"There were {Errors.Count} JSON errors");

            foreach (ErrorEventArgs error in Errors)
            {
                Console.WriteLine($"Message : {error.ErrorContext.Error.Message}");
                Console.WriteLine($"  Path  : {error.ErrorContext.Path}");
                Console.WriteLine($"  Member: {error.ErrorContext.Member}");

                Console.WriteLine();
            }
        }
示例#2
0
        public void InfoTest()
        {
            SslLabsClient client = new SslLabsClient();

            Info info = client.GetInfo();

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

            StatusCodes codes = client.GetStatusCodes();

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

            Info info = client.GetInfo();

            Assert.IsNotNull(info);

            TestHelpers.EnsureAllPropertiesSet(info);
        }
示例#5
0
        static void Main(string[] args)
        {
            SslLabsClient client = new SslLabsClient();

            Analysis analysis = client.GetAnalysisBlocking("mbwarez.dk", null, AnalyzeOptions.StartNew, analysis1 =>
            {
                Console.WriteLine("Status: " + analysis1.Status + " (" + analysis1.StatusMessage + ")");
            });

            Console.WriteLine(analysis);
        }
示例#6
0
        public void StatusCodeTest()
        {
            SslLabsClient client = new SslLabsClient();

            StatusCodes codes = client.GetStatusCodes();

            Assert.IsNotNull(codes);

            TestHelpers.EnsureAllPropertiesSet(codes);

            Assert.IsTrue(codes.StatusDetails.Any());
        }
示例#7
0
        public void HpkpTest()
        {
            SslLabsClient client   = new SslLabsClient();
            Host          analysis = client.GetAnalysisBlocking("scotthelme.co.uk", options: AnalyzeOptions.ReturnAll);

            Assert.IsNotNull(analysis);
            Assert.AreEqual(AnalysisStatus.READY, analysis.Status, "scotthelme.co.uk analysis was not ready. Wait for the analysis to complete.");

            Endpoint endpoint = analysis.Endpoints.First();

            HpkpPolicy hpkpPolicy = endpoint.Details.HpkpPolicy;

            TestHelpers.EnsureAllPropertiesSet(hpkpPolicy, nameof(HpkpPolicy.Error));
            Assert.IsTrue(hpkpPolicy.MaxAge > 0);
            Assert.IsTrue(hpkpPolicy.IncludeSubDomains);
            Assert.AreEqual(HpkpStatus.Valid, hpkpPolicy.Status);

            Assert.IsTrue(hpkpPolicy.Pins.Any());
            Assert.IsTrue(hpkpPolicy.MatchedPins.Any());
        }
示例#8
0
        public void GeneralTest()
        {
            SslLabsClient client   = new SslLabsClient();
            Host          analysis = client.GetAnalysisBlocking("scotthelme.co.uk", options: AnalyzeOptions.ReturnAll);

            Assert.IsNotNull(analysis);
            Assert.AreEqual(AnalysisStatus.READY, analysis.Status, "scotthelme.co.uk analysis was not ready. Wait for the analysis to complete.");

            TestHelpers.EnsureAllPropertiesSet(analysis, nameof(Host.StatusMessage));

            Assert.IsTrue(analysis.Endpoints.Any());

            Endpoint endpoint = analysis.Endpoints.First();

            TestHelpers.EnsureAllPropertiesSet(endpoint, nameof(Endpoint.StatusDetails), nameof(Endpoint.StatusDetailsMessage));

            EndpointDetails details = endpoint.Details;

            TestHelpers.EnsureAllPropertiesSet(details, nameof(EndpointDetails.StaplingRevocationErrorMessage), nameof(EndpointDetails.HttpForwarding));
        }
示例#9
0
        public void HstsTest()
        {
            SslLabsClient client   = new SslLabsClient();
            Host          analysis = client.GetAnalysisBlocking("scotthelme.co.uk", options: AnalyzeOptions.ReturnAll);

            Assert.IsNotNull(analysis);
            Assert.AreEqual(AnalysisStatus.READY, analysis.Status, "scotthelme.co.uk analysis was not ready. Wait for the analysis to complete.");

            Endpoint endpoint = analysis.Endpoints.First();

            HstsPolicy hstsPolicy = endpoint.Details.HstsPolicy;

            Assert.IsTrue(hstsPolicy.MaxAge > 0);
            Assert.IsTrue(hstsPolicy.Preload);
            Assert.IsTrue(hstsPolicy.IncludeSubDomains);
            Assert.AreEqual(HstsStatus.Present, hstsPolicy.Status);

            List <HstsPreload> hstsPreloads = endpoint.Details.HstsPreloads;

            Assert.IsTrue(hstsPreloads.Any(s => s.Source == "Chrome"));
        }
示例#10
0
        /// <summary>
        /// Takes in host URL and returns Qualys SSL Labs API result
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public Task <Analysis> QualysReport(string domainUrl)
        {
            try
            {
                if (string.IsNullOrEmpty(domainUrl))
                {
                    throw new ArgumentNullException("Host URL was null or empty.");
                }

                var client = new SslLabsClient();
                var result = client.GetAnalysisBlocking(domainUrl, 24, AnalyzeOptions.FromCache | AnalyzeOptions.ReturnAll);

                return(Task.FromResult(result));
            }
            catch (HttpRequestException ex)
            {
                throw ex;
            }
            catch (Exception ex)
            {
                // TODO: log this exception
                throw ex;
            }
        }
示例#11
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);
        }