You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. require 'erb'
  2. require 'logging'
  3. require 'parallel'
  4. require 'thread'
  5. require 'yaml'
  6. module SSLCheck
  7. module SSLLabs
  8. autoload :API, 'sslcheck/ssllabs/api'
  9. end
  10. autoload :Server, 'sslcheck/server'
  11. autoload :Grade, 'sslcheck/grade'
  12. PARALLEL_ANALYSIS = 20
  13. SYN_TIMEOUT = 600
  14. @@log = Logging.logger[SSLCheck]
  15. def self.grade(hostname, port=443)
  16. timeout SYN_TIMEOUT do
  17. Grade.new Server.new hostname, port
  18. end
  19. rescue Exception => e
  20. @@log.error { "Error during #{hostname}:#{port} analysis : #{e}" }
  21. NoSslTlsGrade.new NoSslTlsServer.new hostname, port
  22. end
  23. def self.analyze(hosts, output, groups = nil)
  24. results = {}
  25. semaphore = Mutex.new
  26. Parallel.each hosts, progress: 'Analysing', in_threads: PARALLEL_ANALYSIS,
  27. finish: lambda { |item, _, _| puts item[1] } do |description, host|
  28. result = SSLCheck.grade host.strip
  29. semaphore.synchronize do
  30. if results.include? description
  31. results[description] << result
  32. else
  33. results[description] = [result]
  34. end
  35. end
  36. end
  37. results = Hash[groups.collect { |g| [g, results[g]] }] if groups
  38. results.each do |d, _|
  39. results[d].sort! do |a, b|
  40. cmp = score(a) <=> score(b)
  41. if cmp == 0
  42. cmp = a.score <=> b.score
  43. if cmp == 0
  44. cmp = a.server.hostname <=> b.server.hostname
  45. end
  46. end
  47. cmp
  48. end
  49. end
  50. File.write output, ERB.new(File.read('output/sslcheck.erb')).result(binding)
  51. end
  52. def self.analyze_from_file(file, output)
  53. config = YAML.load_file file
  54. hosts = []
  55. groups = []
  56. config.each do |c|
  57. d, hs = c['description'], c['hostnames']
  58. groups << d
  59. hs.each { |host| hosts << [d, host] }
  60. end
  61. self.analyze hosts, output, groups
  62. end
  63. private
  64. SCORES = %w(A+ A A- B C D E F T M X)
  65. def self.score(a)
  66. SCORES.index a.grade
  67. end
  68. end