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(); } }
public void InfoTest() { SslLabsClient client = new SslLabsClient(); Info info = client.GetInfo(); Assert.IsNotNull(info); }
public void StatusCodeTest() { SslLabsClient client = new SslLabsClient(); StatusCodes codes = client.GetStatusCodes(); Assert.IsNotNull(codes); }
public void InfoTest() { SslLabsClient client = new SslLabsClient(); Info info = client.GetInfo(); Assert.IsNotNull(info); TestHelpers.EnsureAllPropertiesSet(info); }
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); }
public void StatusCodeTest() { SslLabsClient client = new SslLabsClient(); StatusCodes codes = client.GetStatusCodes(); Assert.IsNotNull(codes); TestHelpers.EnsureAllPropertiesSet(codes); Assert.IsTrue(codes.StatusDetails.Any()); }
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()); }
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)); }
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")); }
/// <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; } }
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); }