From b62ef5192bd9bc0d4145e3fec20036eec88ff1d8 Mon Sep 17 00:00:00 2001 From: Nicolas Vinot Date: Sat, 13 Dec 2014 22:20:54 +0100 Subject: [PATCH] Handle SSL/TLS timeout --- .gitignore | 6 +- Gemfile | 2 + Makefile | 38 +++++++ hosts.yml | 10 +- lib/sslcheck.rb | 55 +++++++++- lib/sslcheck/grade.rb | 12 ++- lib/sslcheck/server.rb | 167 ++++++++++++++++++------------ index2.erb => output/sslcheck.erb | 78 +++++++++----- index.erb => output/ssllabs.erb | 0 patch | 10 ++ sslcheck | 8 +- sslcheck-alexa | 19 ++++ sslcheck-all | 62 ++--------- test.rb | 79 -------------- 14 files changed, 311 insertions(+), 235 deletions(-) create mode 100644 Makefile rename index2.erb => output/sslcheck.erb (64%) rename index.erb => output/ssllabs.erb (100%) create mode 100644 patch create mode 100755 sslcheck-alexa delete mode 100755 test.rb diff --git a/.gitignore b/.gitignore index bf9b0f0..da369d0 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,8 @@ Gemfile.lock /html/ /.rspec /rakefile -/output/index.html +/output/*.html +/db/*.sqlite3 +/db/schema.rb +/lib/*.so +/lib/*.so.1.0.0 diff --git a/Gemfile b/Gemfile index 675fde8..14585f4 100644 --- a/Gemfile +++ b/Gemfile @@ -7,6 +7,8 @@ gem 'tcp_timeout' gem 'parallel' gem 'ruby-progressbar' gem 'logging' +gem 'activerecord' +gem 'sqlite3' group :test do gem 'rspec' diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b767823 --- /dev/null +++ b/Makefile @@ -0,0 +1,38 @@ +PWD = $(shell pwd) +export CPATH = $(PWD)/openssl/include +export LIBRARY_PATH = $(PWD)/openssl +OPENSSL_VERSION = OpenSSL_1_0_1j +RUBY_VERSION = 2.1.5 +RUBY_OPENSSL_EXT_DIR = ruby-$(RUBY_VERSION)/ext/openssl + +all: lib/libssl.so.1.0.0 lib/libcrypto.so.1.0.0 lib/openssl.so + +clean: + rm -rf ruby-$(RUBY_VERSION) openssl + +openssl: + git clone https://github.com/openssl/openssl -b $(OPENSSL_VERSION) + +openssl/Makefile: openssl + cd openssl; ./config shared + +openssl/libssl.so: openssl/Makefile + cd openssl; $(MAKE) depend all + +lib/%.so.1.0.0: openssl/%.so + cp $^ $@ + +ruby-$(RUBY_VERSION): + wget http://cache.ruby-lang.org/pub/ruby/2.1/ruby-$(RUBY_VERSION).tar.gz + tar xf ruby-$(RUBY_VERSION).tar.gz + rm -f ruby-$(RUBY_VERSION).tar.gz + +$(RUBY_OPENSSL_EXT_DIR)/Makefile: ruby-$(RUBY_VERSION) + cd $(RUBY_OPENSSL_EXT_DIR); ruby extconf.rb + patch $@ patch + +$(RUBY_OPENSSL_EXT_DIR)/openssl.so: $(RUBY_OPENSSL_EXT_DIR)/Makefile + cd $(RUBY_OPENSSL_EXT_DIR); $(MAKE); $(MAKE) install + +lib/openssl.so: $(RUBY_OPENSSL_EXT_DIR)/openssl.so + cp $< $@ diff --git a/hosts.yml b/hosts.yml index 0d830b9..0d043db 100644 --- a/hosts.yml +++ b/hosts.yml @@ -15,11 +15,13 @@ - description: Banques en ligne hostnames: - www.labanquepostale.fr + - www.labanquepostale-cartesprepayees.fr - www.secure.bnpparibas.net - www.axabanque.fr - www.fortuneo.fr - www.ca-paris.fr - www.credit-cooperatif.coop + - www.coopanet.com - www.cic.fr - particuliers.societegenerale.fr - espaceclient.groupama.fr @@ -36,7 +38,7 @@ - www.ca-paris.fr - www.ca-cotesdarmor.fr - secure.ingdirect.fr - - banque-accord.fr + - www.banque-accord.fr - espace-client-secure.banque-casino.fr - bforbank.com - hellobank.fr @@ -46,9 +48,9 @@ - zimbra.free.fr - webmail.numericable.fr - webmail.orange-business.com + - messagerie.orange.fr - webmail.gandi.net - messagerie.sfr.fr - - webmail.aliceadsl.fr - webmail.online.net - wmail.amen.fr - webmail.ovh.com @@ -67,6 +69,10 @@ - mon.service-public.fr - www.correspondants.cnil.fr - sso.quechoisir.org + - connexion.mon.service-public.fr + - mon.rsi.fr + - jedeclare.com + - net-entreprises.fr - description: Sites de commerce en ligne hostnames: - signin.ebay.fr diff --git a/lib/sslcheck.rb b/lib/sslcheck.rb index 9f5872f..28aab2c 100644 --- a/lib/sslcheck.rb +++ b/lib/sslcheck.rb @@ -1,6 +1,59 @@ -require 'sslcheck/ssllabs/api' +require 'erb' +require 'logging' +require 'parallel' +require 'thread' module SSLCheck + module SSLLabs + autoload :API, 'sslcheck/ssllabs/api' + end autoload :Server, 'sslcheck/server' autoload :Grade, 'sslcheck/grade' + + @@log = Logging.logger[SSLCheck] + + def self.grade(hostname, port=443) + timeout 600 do + Grade.new Server.new hostname, port + end + rescue Exception => e + @@log.error { "Error during #{hostname}:#{port} analysis : #{e}" } + NoSslTlsGrade.new NoSslTlsServer.new hostname, port + end + + def self.analyze(hosts, output) + results = {} + semaphore = Mutex.new + Parallel.each hosts, progress: 'Testing', in_threads: 10 do |description, host| + result = SSLCheck.grade host.strip + semaphore.synchronize do + if results.include? description + results[description] << result + else + results[description] = [result] + end + end + end + + results.each do |d, _| + results[d].sort! do |a, b| + cmp = score(a) <=> score(b) + if cmp == 0 + cmp = a.score <=> b.score + if cmp == 0 + cmp = a.server.hostname <=> b.server.hostname + end + end + cmp + end + end + + File.write "output/#{output}.html", ERB.new(File.read('output/sslcheck.erb')).result(binding) + end + + private + SCORES = %w(A+ A A- B C D E F T M X) + def self.score(a) + SCORES.index a.grade + end end diff --git a/lib/sslcheck/grade.rb b/lib/sslcheck/grade.rb index b2b667a..65d2b21 100644 --- a/lib/sslcheck/grade.rb +++ b/lib/sslcheck/grade.rb @@ -1,6 +1,16 @@ +require 'timeout' + module SSLCheck + class NoSslTlsGrade + attr_reader :server, :score, :grade + + def initialize(server) + @server, @score, @grade = server, -1, 'X' + end + end + class Grade - attr_reader :server, :score, :grade, :warning, :good + attr_reader :server, :score, :grade, :warning, :success def initialize(server) @server = server diff --git a/lib/sslcheck/server.rb b/lib/sslcheck/server.rb index 988c874..a5f9526 100644 --- a/lib/sslcheck/server.rb +++ b/lib/sslcheck/server.rb @@ -5,12 +5,23 @@ require 'parallel' require 'tcp_timeout' module SSLCheck + class NoSslTlsServer + attr_reader :hostname, :port + + def initialize(hostname, port=443) + @hostname, @port = hostname, port + end + end + class Server + TCP_TIMEOUT = 60 + SSL_TIMEOUT = 2*TCP_TIMEOUT EXISTING_METHODS = %i(TLSv1_2 TLSv1_1 TLSv1 SSLv3 SSLv2) SUPPORTED_METHODS = OpenSSL::SSL::SSLContext::METHODS - TIMEOUT = 5 class TLSNotAvailableException < Exception; end class CipherNotAvailable < Exception; end + class Timeout < Exception; end + class ConnectionError < Exception; end attr_reader :hostname, :port, :prefered_ciphers, :cert, :hsts @@ -19,12 +30,12 @@ module SSLCheck @hostname = hostname @port = port @methods = methods - @log.error { "Check for #{hostname} (#{port})"} - + @log.error { "Begin analysis" } extract_cert fetch_prefered_ciphers check_supported_cipher fetch_hsts + @log.error { "End analysis" } end def supported_methods @@ -33,18 +44,32 @@ module SSLCheck {worst: worst, best: best} end - def key_size + def key key = @cert.public_key case key when OpenSSL::PKey::RSA then - key.n.num_bits + [:rsa, key.n.num_bits] when OpenSSL::PKey::DSA then - key.p.num_bits + [:dsa, key.p.num_bits] when OpenSSL::PKey::EC then - key.group.degree + [:ecc, key.group.degree] end end + def key_size + type, size = self.key + if type == :ecc + size = case size + when 160 then 1024 + when 224 then 2048 + when 256 then 3072 + when 384 then 7680 + when 521 then 15360 + end + end + size + end + def cipher_size cipher_strengths = supported_ciphers.collect { |c| c[2] }.uniq.sort worst, best = cipher_strengths.first, cipher_strengths.last @@ -60,9 +85,9 @@ module SSLCheck end { - md2: %w(md2WithRSAEncryption), - md5: %w(md5WithRSAEncryption md5WithRSA), - sha1: %w(sha1WithRSAEncryption sha1WithRSA dsaWithSHA1 dsaWithSHA1_2 ecdsa_with_SHA1) + md2: %w(md2WithRSAEncryption), + md5: %w(md5WithRSAEncryption md5WithRSA), + sha1: %w(sha1WithRSAEncryption sha1WithRSA dsaWithSHA1 dsaWithSHA1_2 ecdsa_with_SHA1) }.each do |name, signature| class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 def #{name}_sig? @@ -72,12 +97,12 @@ module SSLCheck end { - md5: %w(MD5), - sha1: %w(SHA), + md5: %w(MD5), + sha1: %w(SHA), - rc4: %w(RC4), - des3: %w(3DES DES-CBC3), - des: %w(DES-CBC) + rc4: %w(RC4), + des3: %w(3DES DES-CBC3), + des: %w(DES-CBC) }.each do |name, ciphers| class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 def #{name}? @@ -129,8 +154,52 @@ module SSLCheck end private - def ssl_client(method = nil, ciphers = nil, &block) - ssl_context = method.nil? ? OpenSSL::SSL::SSLContext.new : OpenSSL::SSL::SSLContext.new(method) + def connect(family, host, port, &block) + socket = Socket.new family, Socket::SOCK_STREAM + sockaddr = Socket.sockaddr_in port, host + @log.debug { "Connecting to #{host}:#{port}" } + begin + status = socket.connect_nonblock sockaddr + @log.debug { "Connecting to #{host}:#{port} status : #{status}" } + raise ConnectionError.new status unless status == 0 + @log.debug { "Connected to #{host}:#{port}" } + block_given? ? block.call(socket) : nil + rescue IO::WaitReadable + @log.debug { "Waiting for read to #{host}:#{port}" } + raise Timeout.new unless IO.select [socket], nil, nil, TCP_TIMEOUT + retry + rescue IO::WaitWritable + @log.debug { "Waiting for write to #{host}:#{port}" } + raise Timeout.new unless IO.select nil, [socket], nil, TCP_TIMEOUT + retry + ensure + socket.close + end + end + + def ssl_connect(socket, context, method, &block) + ssl_socket = OpenSSL::SSL::SSLSocket.new socket, context + ssl_socket.hostname = @hostname unless method == :SSLv2 + @log.debug { "SSL connecting to #{@hostname}:#{@port}" } + begin + ssl_socket.connect_nonblock + @log.debug { "SSL connected to #{@hostname}:#{@port}" } + return block_given? ? block.call(ssl_socket) : nil + rescue IO::WaitReadable + @log.debug { "Waiting for SSL read to #{@hostname}:#{@port}" } + raise Timeout.new unless IO.select [socket], nil, nil, SSL_TIMEOUT + retry + rescue IO::WaitWritable + @log.debug { "Waiting for SSL write to #{@hostname}:#{@port}" } + raise Timeout.new unless IO.select nil, [socket], nil, SSL_TIMEOUT + retry + ensure + ssl_socket.close + end + end + + def ssl_client(method, ciphers = nil, &block) + ssl_context = OpenSSL::SSL::SSLContext.new method ssl_context.ciphers = ciphers if ciphers @log.debug { "Try #{method} connection with #{ciphers}" } @@ -144,47 +213,15 @@ module SSLCheck end addrs.each do |addr| - addr = addr[3] - sockaddr = Socket.sockaddr_in @port, addr - socket = Socket.new family, Socket::SOCK_STREAM - begin - @log.debug { "Connecting to #{addr}:#{@port}" } - socket.connect_nonblock sockaddr - rescue IO::WaitWritable - @log.debug { "Waiting for connection to #{addr}:#{@port}" } - if IO.select nil, [socket], nil, TIMEOUT - begin - if socket.connect_nonblock(sockaddr) == 0 - @log.debug { "Connected to #{addr}:#{@port}" } - - ssl_socket = OpenSSL::SSL::SSLSocket.new socket, ssl_context - ssl_socket.hostname = @hostname - begin - @log.debug { "TLS connection to #{addr}:#{@port}" } - ssl_socket.connect - return block_given? ? block.call(ssl_socket) : nil - rescue OpenSSL::SSL::SSLError => e - @log.debug { "Cipher not supported #{addr}:#{@port} : #{e}" } - raise CipherNotAvailable.new e - ensure - @log.debug { "Closing TLS connection to #{addr}:#{@port}" } - ssl_socket.close - end - end - rescue Errno::ECONNRESET, Errno::ECONNREFUSED, Errno::EHOSTUNREACH => e - @log.debug { "Connection failure to #{addr}:#{@port} : #{e}" } - end - else - @log.debug { "Connection timeout to #{addr}:#{@port}" } + connect family, addr[3], @port do |socket| + ssl_connect socket, ssl_context, method do |ssl_socket| + return block_given? ? block.call(ssl_socket) : nil end - ensure - @log.debug { "Closing connection to #{addr}:#{@port}" } - socket.close end end end - @log.debug { "No TLS available on #{@hostname}" } + @log.debug { "No SSL available on #{@hostname}" } raise CipherNotAvailable.new end @@ -193,9 +230,10 @@ module SSLCheck next unless SUPPORTED_METHODS.include? method begin @cert = ssl_client(method) { |s| s.peer_cert } - @log.warn { "Certificate #{@cert.subject}"} + @log.warn { "Certificate #{@cert.subject}" } break - rescue CipherNotAvailable + rescue Exception => e + @log.info { "Method #{method} not supported : #{e}" } end end raise TLSNotAvailableException.new unless @cert @@ -203,10 +241,10 @@ module SSLCheck def prefered_cipher(method) cipher = ssl_client(method, %w(ALL:COMPLEMENTOFALL)) { |s| s.cipher } - @log.warn { "Prefered cipher for #{method} : #{cipher[0]}"} + @log.warn { "Prefered cipher for #{method} : #{cipher[0]}" } cipher - rescue CipherNotAvailable => e - @log.info { "Method #{method} not supported : #{e}"} + rescue Exception => e + @log.info { "Method #{method} not supported : #{e}" } nil end @@ -216,6 +254,7 @@ module SSLCheck next unless SUPPORTED_METHODS.include? method @prefered_ciphers[method] = prefered_cipher method end + raise TLSNotAvailableException.new unless @prefered_ciphers.any? { |_, c| !c.nil? } end def available_ciphers(method) @@ -224,10 +263,10 @@ module SSLCheck def supported_cipher?(method, cipher) ssl_client method, [cipher] - @log.warn { "Verify #{method} / #{cipher[0]} : OK"} + @log.warn { "Verify #{method} / #{cipher[0]} : OK" } true - rescue TLSNotAvailableException, CipherNotAvailable => e - @log.debug { "Verify #{method} / #{cipher[0]} : NOK (#{e}"} + rescue Exception => e + @log.info { "Verify #{method} / #{cipher[0]} : NOK (#{e})" } false end @@ -247,10 +286,10 @@ module SSLCheck begin next unless SUPPORTED_METHODS.include? method @log.debug { "Check HSTS with #{method}" } - response = HTTParty.head "https://#{@hostname}#{port}/", {follow_redirects: false, verify: false, ssl_version: method, timeout: TIMEOUT} + response = HTTParty.head "https://#{@hostname}#{port}/", {follow_redirects: false, verify: false, ssl_version: method, timeout: SSL_TIMEOUT} break - rescue - @log.debug { "#{method} not supported" } + rescue Exception => e + @log.debug { "#{method} not supported : #{e}" } end end diff --git a/index2.erb b/output/sslcheck.erb similarity index 64% rename from index2.erb rename to output/sslcheck.erb index 7932b14..665ccf7 100644 --- a/index2.erb +++ b/output/sslcheck.erb @@ -14,6 +14,15 @@ td { text-align: center; } + + .critical { + background-color: #000; + color: #fff; + } + + td.critical:hover { + background-color: #333 !important; + } @@ -28,21 +37,22 @@ unless first %> -   +   <% end first = false %> - <%= r[0] %> + <%= r[0] %> Site (IP) Rang Clef (bits) Chiff. (bits) - SSL + SSL v2 + SSL v3 TLS TLS 1.2 TLS only @@ -57,12 +67,6 @@ <% r[1].each do |n| s = n.server - rank_color = case n.grade - when 'A+' then :info - when 'A', 'A-' then :success - when 'B', 'C' then :warning - else :danger - end %> @@ -70,66 +74,85 @@ <%= s.hostname %> + <% if s.is_a? SSLCheck::NoSslTlsServer %> + + No SSL/TLS + + <% + else + rank_color = case n.grade + when 'A+' then :info + when 'A', 'A-' then :success + when 'B', 'C' then :warning + else :danger + end + %> <%= n.grade %> - <%= s.key_size %> - (<%= s.key_size < 2048 ? '☹' : '☺' %>) + <% type, size = s.key %> + <%= "#{size} (#{type.to_s.upcase})" %> + (<%= s.key_size < 2048 ? '☹' : '☺' %>) <% cipher_size = s.cipher_size[:worst] %> <%= cipher_size %> - (<%= cipher_size < 128 ? '☹' : '☺' %>) + (<%= cipher_size < 128 ? '☹' : '☺' %>) + + + <%= s.sslv2? ? '✓' : '✗' %> + (<%= s.sslv2? ? '☹' : '☺' %>) - - <%= s.ssl? ? '✓' : '✗' %> - (<%= s.ssl? ? '☹' : '☺' %>) + + <%= s.sslv3? ? '✓' : '✗' %> + (<%= s.sslv3? ? '☹' : '☺' %>) <%= s.tls? ? '✓' : '✗' %> - (<%= s.tls? ? '☺' : '☹' %>) + (<%= s.tls? ? '☺' : '☹' %>) <%= s.tlsv1_2? ? '✓' : '✗' %> - (<%= s.tlsv1_2? ? '☺' : '☹' %>) + (<%= s.tlsv1_2? ? '☺' : '☹' %>) <%= s.tls_only? ? '✓' : '✗' %> - (<%= s.tls_only? ? '☺' : '☹' %>) + (<%= s.tls_only? ? '☺' : '☹' %>) <%= s.sha1_sig? ? '✓' : '✗' %> - (<%= s.sha1_sig? ? '☹' : '☺' %>) + (<%= s.sha1_sig? ? '☹' : '☺' %>) <%= s.rc4? ? '✓' : '✗' %> - (<%= s.rc4? ? '☹' : '☺' %>) + (<%= s.rc4? ? '☹' : '☺' %>) <%= s.any_des? ? '✓' : '✗' %> - (<%= s.any_des? ? '☹' : '☺' %>) + (<%= s.any_des? ? '☹' : '☺' %>) <%= s.md5? ? '✓' : '✗' %> - (<%= s.md5? ? '☹' : '☺' %>) + (<%= s.md5? ? '☹' : '☺' %>) <%= s.pfs? ? '✓' : '✗' %> - (<%= s.pfs? ? '☺' : '☹' %>) + (<%= s.pfs? ? '☺' : '☹' %>) <%= s.pfs_only? ? '✓' : '✗' %> - (<%= s.pfs_only? ? '☺' : '☹' %>) + (<%= s.pfs_only? ? '☺' : '☹' %>) <%= s.hsts? ? '✓' : '✗' %> - (<%= s.hsts? ? '☺' : '☹' %>) + (<%= s.hsts? ? '☺' : '☹' %>) <%= s.hsts_long? ? '✓' : '✗' %> - (<%= s.hsts_long? ? '☺' : '☹' %>) + (<%= s.hsts_long? ? '☺' : '☹' %>) + <% end %> <% end %> @@ -137,7 +160,8 @@ Rang Clef (bits) Chiff. (bits) - SSL + SSL v2 + SSL v3 TLS TLS 1.2 TLS only diff --git a/index.erb b/output/ssllabs.erb similarity index 100% rename from index.erb rename to output/ssllabs.erb diff --git a/patch b/patch new file mode 100644 index 0000000..97169be --- /dev/null +++ b/patch @@ -0,0 +1,10 @@ +--- Makefile 2014-12-13 01:20:15.025576957 +0100 ++++ Makefile 2014-12-13 01:26:44.801203932 +0100 +@@ -60,6 +60,7 @@ + sbindir = $(exec_prefix)/sbin + bindir = $(exec_prefix)/bin + archdir = $(rubyarchdir) ++top_srcdir = ../.. + + + CC = gcc diff --git a/sslcheck b/sslcheck index 96eb2b6..8fc3e26 100755 --- a/sslcheck +++ b/sslcheck @@ -1,11 +1,11 @@ #!/usr/bin/env ruby -#ENV['LD_LIBRARY_PATH'] = '/home/aeris/Workspace/external/sslscan/openssl' +ENV['LD_LIBRARY_PATH'] = '/home/aeris/Workspace/external/sslscan/openssl' require 'logging' $:.unshift 'lib' require 'sslcheck' Logging.logger.root.appenders = Logging.appenders.stdout -Logging.logger.root.level = :info +Logging.logger.root.level = :warn -server = SSLCheck::Server.new ARGV[0] -p SSLCheck::Grade.new server +p server = SSLCheck::Server.new(ARGV[0]) +p grade = SSLCheck::Grade.new(server) diff --git a/sslcheck-alexa b/sslcheck-alexa new file mode 100755 index 0000000..e5e9f62 --- /dev/null +++ b/sslcheck-alexa @@ -0,0 +1,19 @@ +#!/usr/bin/env ruby +require 'yaml' +$:.unshift 'lib' +require 'sslcheck' + +Logging.logger.root.appenders = Logging.appenders.stdout +Logging.logger.root.level = :error + +hosts = [] +File.open('top-1m.csv', 'r') do |file| + i = 0 + while line = file.gets + hosts << ['Top 100 Alexa', line.strip.split(',')[1]] + i += 1 + break if i == 100 + end +end + +SSLCheck.analyze hosts, 'alexa' diff --git a/sslcheck-all b/sslcheck-all index f3fca22..268a62b 100755 --- a/sslcheck-all +++ b/sslcheck-all @@ -1,66 +1,16 @@ #!/usr/bin/env ruby -require 'erb' require 'yaml' -require 'thread' -require 'parallel' -require 'logging' $:.unshift 'lib' require 'sslcheck' -#Logging.logger.root.appenders = Logging.appenders.stdout -#Logging.logger.root.level = :info - -SCORES = %w(A+ A A- B C D E F T M) -def score(a); SCORES.index a.grade; end - -def check(hostname) - hostname.strip! - #print ' ', hostname, ' : ' - begin - server = SSLCheck::Server.new hostname - note = SSLCheck::Grade.new server - #puts note.grade - note - rescue => e - puts e - raise - end -end +Logging.logger.root.appenders = Logging.appenders.stdout +Logging.logger.root.level = :error config = YAML.load_file 'hosts.yml' -results = Hash[config.collect { |c| [c['description'], []] }] - - -tests = [] +hosts = [] config.each do |c| - description, hosts = c['description'], c['hostnames'] - hosts.each { |host| tests << [description, host] } -end - -# tests.each do |description, host| -# results[description] << check(host) -# end - -semaphore = Mutex.new -Parallel.each tests, progress: 'Testing', in_threads: 8 do |description, host| - begin - result = check host - semaphore.synchronize do - results[description] << result - end - rescue SSLCheck::Server::TLSNotAvailableException - rescue Exception => e - p host, e - raise - end -end - -results.each do |d, _| - results[d].sort! do |a, b| - cmp = score(a) <=> score(b) - cmp != 0 ? cmp : a.server.hostname <=> b.server.hostname - end + d, hs = c['description'], c['hostnames'] + hs.each { |host| hosts << [d, host] } end -puts 'Generate results' -File.write 'output/index.html', ERB.new(File.read('index2.erb')).result(binding) +SSLCheck.analyze hosts, 'results' diff --git a/test.rb b/test.rb deleted file mode 100755 index b2095d7..0000000 --- a/test.rb +++ /dev/null @@ -1,79 +0,0 @@ -#!/usr/bin/env ruby -#ENV['LD_LIBRARY_PATH'] = '/home/aeris/Workspace/external/sslscan/openssl' -require 'logging' -$:.unshift 'lib' -require 'sslcheck' - -Logging.logger.root.appenders = Logging.appenders.stdout -Logging.logger.root.level = :debug - -# Server = Class.new SSLCheck::Server do -# def initialize -# @key = OpenSSL::PKey::RSA.new 2048 -# name = OpenSSL::X509::Name.parse 'CN=nobody/DC=example' -# @cert = OpenSSL::X509::Certificate.new -# @cert.version = 3 -# @cert.serial = 0 -# @cert.not_before = Time.now -# @cert.not_after = Time.now + 3600 -# @cert.public_key = @key.public_key -# @cert.subject = name -# -# @supported_ciphers = -# {SSLv3: [], TLSv1: [['ECDHE-RSA-AES256-SHA', 'TLSv1/SSLv3', 256, 256], ['DHE-RSA-AES256-SHA', 'TLSv1/SSLv3', 256, 256], ['ECDHE-RSA-AES128-SHA', 'TLSv1/SSLv3', 128, 128], ['DHE-RSA-AES128-SHA', 'TLSv1/SSLv3', 128, 128]], TLSv1_1: [['ECDHE-RSA-AES256-SHA', 'TLSv1/SSLv3', 256, 256], ['DHE-RSA-AES256-SHA', 'TLSv1/SSLv3', 256, 256], ['ECDHE-RSA-AES128-SHA', 'TLSv1/SSLv3', 128, 128], ['DHE-RSA-AES128-SHA', 'TLSv1/SSLv3', 128, 128]], TLSv1_2: [['ECDHE-RSA-AES256-GCM-SHA384', 'TLSv1/SSLv3', 256, 256], ['ECDHE-RSA-AES256-SHA384', 'TLSv1/SSLv3', 256, 256], ['ECDHE-RSA-AES256-SHA', 'TLSv1/SSLv3', 256, 256], ['DHE-RSA-AES256-GCM-SHA384', 'TLSv1/SSLv3', 256, 256], ['DHE-RSA-AES256-SHA256', 'TLSv1/SSLv3', 256, 256], ['DHE-RSA-AES256-SHA', 'TLSv1/SSLv3', 256, 256], ['ECDHE-RSA-AES128-GCM-SHA256', 'TLSv1/SSLv3', 128, 128], ['ECDHE-RSA-AES128-SHA256', 'TLSv1/SSLv3', 128, 128], ['ECDHE-RSA-AES128-SHA', 'TLSv1/SSLv3', 128, 128], ['DHE-RSA-AES128-GCM-SHA256', 'TLSv1/SSLv3', 128, 128], ['DHE-RSA-AES128-SHA256', 'TLSv1/SSLv3', 128, 128], ['DHE-RSA-AES128-SHA', 'TLSv1/SSLv3', 128, 128]]} -# @prefered_ciphers = {SSLv3: nil, TLSv1: ['ECDHE-RSA-AES128-SHA', 'TLSv1/SSLv3', 128, 128], TLSv1_1: ['ECDHE-RSA-AES128-SHA', 'TLSv1/SSLv3', 128, 128], TLSv1_2: ['ECDHE-RSA-AES128-GCM-SHA256', 'TLSv1/SSLv3', 128, 128]} -# -# @hsts = 31536000 -# end -# end -#server = Server.new -#server = SSLCheck::Server.new 'www.cjn.justice.gouv.fr' -#server = SSLCheck::Server.new 'www.capitainetrain.com' -server = SSLCheck::Server.new 'matlink.fr' -p SSLCheck::Grade.new server -exit - -hostname, port = ['www.cjn.justice.gouv.fr', 443] -tcp_client = TCPSocket.new hostname, port -ssl_client = OpenSSL::SSL::SSLSocket.new tcp_client -ssl_client.hostname = hostname -p ssl_client.connect - - -#hostname = 'provaping.com' -#compressions = {} -# existing_methods.each do |method| -# next unless supported_methods.include? method -# socket_context = OpenSSL::SSL::SSLContext.new method -# socket_context.ciphers = %w(ALL:COMPLEMENTOFALL) -# tcp_client = TCPSocket.new hostname, port -# ssl_client = OpenSSL::SSL::SSLSocket.new tcp_client, socket_context -# ssl_client.hostname = hostname -# begin -# ssl = ssl_client.connect -# data = OpenSSL::ASN1.decode(ssl.session.to_der).value.find { |a| a.tag == 11 } -# compression = !data.nil? -# compressions[method] = compression -# rescue OpenSSL::SSL::SSLError => e -# end -# end -#p "Compressions", compressions - -#hostname = 'espaceclient.groupama.fr' # not supported -# hostname = 'ameli.moncompte.mobi' -# renegociations = {} -# existing_methods.each do |method| -# next unless supported_methods.include? method -# socket_context = OpenSSL::SSL::SSLContext.new method -# socket_context.ciphers = %w(ALL:COMPLEMENTOFALL) -# tcp_client = TCPSocket.new hostname, port -# ssl_client = OpenSSL::SSL::SSLSocket.new tcp_client, socket_context -# ssl_client.hostname = hostname -# begin -# ssl = ssl_client.connect -# p ssl -# #data = OpenSSL::ASN1.decode(ssl.session.to_der).value.find { |a| a.tag == 11 } -# rescue OpenSSL::SSL::SSLError => e -# end -# end -# p "Renegociations", renegociations