diff --git a/Gemfile b/Gemfile index 8385a70..bf0c188 100644 --- a/Gemfile +++ b/Gemfile @@ -22,6 +22,7 @@ end group :development, :test do gem 'puma' gem 'web-console' + gem 'awesome_print' gem 'pry-rails' diff --git a/app/controllers/check_controller.rb b/app/controllers/check_controller.rb index bfe4d2d..35cca1f 100644 --- a/app/controllers/check_controller.rb +++ b/app/controllers/check_controller.rb @@ -8,12 +8,10 @@ class CheckController < ApplicationController respond_to do |format| format.html do return render :processing if @result.pending - return render :no_tls if @result.no_tls end format.json do render json: case when @result.pending then :pending - when @result.no_tls then :no_tls else @result end end @@ -34,7 +32,7 @@ class CheckController < ApplicationController protected def enqueue_host - Datastore.pending self.type, @id, @port + Datastore.pending self.type, @host, @port self.worker.perform_async *(@port.blank? ? [@host] : [@host, @port]) @result = OpenStruct.new pending: true , date: Time.now end diff --git a/app/lib/datastore.rb b/app/lib/datastore.rb index f10f64a..8f5fd29 100644 --- a/app/lib/datastore.rb +++ b/app/lib/datastore.rb @@ -3,19 +3,20 @@ class Datastore @@index.create unless @@index.exists? def self.host(type, host, port) - result = @@index.type(type).get self.key(host, port) + key = self.key host, port + result = @@index.type(type).get key result.date = Time.parse result.date result rescue Stretcher::RequestError::NotFound end def self.pending(type, host, port) - self.post type, host, port, { pending: true } + self.post type, host, port, { pending: true, date: DateTime.now } end def self.post(type, host, port, data) - data[:date] = DateTime.now - @@index.type(type).put self.key(host, port), data + key = self.key host, port + @@index.type(type).put key, data end private diff --git a/app/views/check/no_tls.html.erb b/app/views/check/no_tls.html.erb deleted file mode 100644 index dd4e33e..0000000 --- a/app/views/check/no_tls.html.erb +++ /dev/null @@ -1,12 +0,0 @@ -
-
-
-

- [<%= self.type.to_s.upcase %>] <%= @host %> ne supporte pas <%= self.tls_type %> -

- <% if Time.now - @result.date >= Rails.configuration.refresh_delay %> - <%= link_to 'Rafraîchir', {action: :refresh}, class: %i(btn btn-default pull-right) %> - <% end %> -
-
-
diff --git a/app/views/check/show.html.erb b/app/views/check/show.html.erb index 91d89eb..1c3d0fd 100644 --- a/app/views/check/show.html.erb +++ b/app/views/check/show.html.erb @@ -3,7 +3,6 @@

[<%= self.type.to_s.upcase %>] <%= @host %> (<%= l @result.date %>) - <%= rank_label @result.score.rank %>

<% if Time.now - @result.date >= Rails.configuration.refresh_delay %> @@ -12,16 +11,35 @@ <% end %> -
+ <% + @result.hosts.each do |host| + if host.error + error, host = host.error, host.host + %> +
+
+

<%= host.name %> - <%= host.ip %> : <%= host.port %>

+ Error during analysis : + <%= error %> +
+
+ <% + else + host, grade, handshake = host.host, host.grade, host.handshake + %> +
+
+

<%= host.name %> - <%= host.ip %> : <%= host.port %>

+
+
- <% scores = @result.score.details %> @@ -33,7 +51,7 @@ 'Total' => 'score'}.each do |name, v| %> - + <% end %> @@ -44,20 +62,20 @@ - + <% { 'Bonnes pratiques' => :success, 'Alertes' => :warning, 'Dangers' => :danger, 'Erreurs' => :error }.each do |name, color| - names = @result.score[color] + names = grade[color] next if names.nil? or names.empty? %> @@ -100,8 +118,8 @@ <% CryptCheck::Tls::Server::EXISTING_METHODS.each do |protocol| - ciphers = CryptCheck::Tls::Cipher.sort(@result.ciphers.select { |c| c.protocol == protocol.to_s } - .collect { |c| CryptCheck::Tls::Cipher.new protocol, [c.name, nil, c[:size]], c.dh, @result[:key] }) + ciphers = CryptCheck::Tls::Cipher.sort(handshake.ciphers.select { |c| c.protocol == protocol.to_s } + .collect { |c| CryptCheck::Tls::Cipher.new protocol, [c.name, nil, c[:size]], c.dh, handshake[:key] }) unless ciphers.empty? %> @@ -133,4 +151,6 @@
Scores - <%= rank_label @result.score.rank %> + <%= rank_label grade.rank %>
<%= name %><%= score_progress scores[v] %><%= score_progress grade.details[v] %>
Protocoles<%= protocol_labels @result.protocols %><%= protocol_labels handshake.protocols %>
Clefs -

Certificat : <%= key_label @result[:key] %>

-

Diffie Hellman : <%= key_labels @result.dh %>

+

Certificat : <%= key_label handshake[:key] %>

+

Diffie Hellman : <%= key_labels handshake.dh %>

<%= protocol_label protocol %>
+ <% end + end %> diff --git a/app/views/ssh/show.html.erb b/app/views/ssh/show.html.erb index 1537adb..e1d7ce3 100644 --- a/app/views/ssh/show.html.erb +++ b/app/views/ssh/show.html.erb @@ -11,7 +11,27 @@ <% end %> -
+ <% + @result.hosts.each do |host| + if host.error + error, host = host.error, host.host + %> +
+
+

<%= host.name %> - <%= host.ip %> : <%= host.port %>

+ Error during analysis : + <%= error %> +
+
+ <% + else + host, server = host.host, host.handshake + %> +
+
+

<%= host.name %> - <%= host.ip %> : <%= host.port %>

+
+
@@ -19,7 +39,7 @@ - <% @result.kex.each do |kex| %> + <% server.kex.each do |kex| %> @@ -28,7 +48,7 @@ - <% @result.encryption.each do |cipher| %> + <% server.encryption.each do |cipher| %> @@ -37,7 +57,7 @@ - <% @result.hmac.each do |hmac| %> + <% server.hmac.each do |hmac| %> @@ -46,7 +66,7 @@ - <% @result.compression.each do |compression| %> + <% server.compression.each do |compression| %> @@ -55,7 +75,7 @@ - <% @result['key'].each do |key| %> + <% server.key_.each do |key| %> @@ -64,4 +84,6 @@
Échange de clef
<%= kex_label kex %>
Chiffrement
<%= cipher_label cipher %>
HMAC
<%= hmac_label hmac %>
Compression
<%= compression_label compression %>
Clefs
<%= key_label key %>
+ <% end + end %> diff --git a/app/workers/check_worker.rb b/app/workers/check_worker.rb index ee9ff8a..31201e3 100644 --- a/app/workers/check_worker.rb +++ b/app/workers/check_worker.rb @@ -7,40 +7,56 @@ class CheckWorker end def perform(host, port=nil) - host = SimpleIDN.to_ascii host.downcase - result = begin - grade = self.analyze *(port ? [host, port] : [host]) - raise CryptCheck::Tls::Server::TLSNotAvailableException if grade.is_a? CryptCheck::Tls::TlsNotSupportedGrade + host = SimpleIDN.to_ascii host.downcase + hosts = self.analyze *(port ? [host, port] : [host]) + hosts = hosts.collect do |host, result| + name, ip, p = host + host = { name: name, ip: ip, port: p } + + if result.is_a? CryptCheck::AnalysisFailure + next { + host: host, + error: result.to_s + } + end + + grade = result server = grade.server - result = { - key: key_to_json(server.key), - dh: server.dh.collect { |k| key_to_json k }, - protocols: server.supported_protocols, - ciphers: server.supported_ciphers.collect { |c| { protocol: c.protocol, name: c.name, size: c.size, dh: key_to_json(c.dh) } }, - score: { - rank: grade.grade, - details: { - score: grade.score, - protocol: grade.protocol_score, - key_exchange: grade.key_exchange_score, - cipher_strengths: grade.cipher_strengths_score - }, - error: grade.error, - danger: grade.danger, - warning: grade.warning, - success: grade.success - } + { + host: host, + handshake: to_json(server), + grade: grade_to_json(grade) } - - self.result server, grade, result - rescue CryptCheck::Tls::Server::TLSNotAvailableException - { no_tls: true } end + result = { date: DateTime.now, hosts: hosts } Datastore.post self.type, host, port, result end protected - def result(_, _, result) - result + def to_json(server) + { + key: key_to_json(server.key), + dh: server.dh.collect { |k| key_to_json k }, + protocols: server.supported_protocols, + ciphers: server.supported_ciphers.collect { |c| { protocol: c.protocol, name: c.name, size: c.size, dh: key_to_json(c.dh) } }, + + } + end + + private + def grade_to_json(grade) + { + rank: grade.grade, + details: { + score: grade.score, + protocol: grade.protocol_score, + key_exchange: grade.key_exchange_score, + cipher_strengths: grade.cipher_strengths_score + }, + error: grade.error, + danger: grade.danger, + warning: grade.warning, + success: grade.success + } end end diff --git a/app/workers/https_worker.rb b/app/workers/https_worker.rb index 133a5b7..f50a7e5 100644 --- a/app/workers/https_worker.rb +++ b/app/workers/https_worker.rb @@ -10,8 +10,9 @@ class HTTPSWorker < CheckWorker :https end - def result(server, _, hash) - hash[:hsts] = server.hsts - hash + def to_json(server) + result = super + result[:hsts] = server.hsts + result end end diff --git a/app/workers/smtp_worker.rb b/app/workers/smtp_worker.rb index f667431..a716363 100644 --- a/app/workers/smtp_worker.rb +++ b/app/workers/smtp_worker.rb @@ -2,8 +2,8 @@ class SMTPWorker < CheckWorker sidekiq_options retry: false protected - def analyze(host, port=25) - CryptCheck::Tls::Smtp.analyze host, port + def analyze(host) + CryptCheck::Tls::Smtp.analyze_domain host end def type diff --git a/app/workers/ssh_worker.rb b/app/workers/ssh_worker.rb index 11ce68e..9579ca6 100644 --- a/app/workers/ssh_worker.rb +++ b/app/workers/ssh_worker.rb @@ -1,21 +1,26 @@ -class SSHWorker - include Sidekiq::Worker +class SSHWorker < CheckWorker sidekiq_options retry: false - def perform(host, port=nil) - host = SimpleIDN.to_ascii host.downcase - result = begin - server = CryptCheck::Ssh.analyze host, port - { - kex: server.kex, - encryption: server.encryption, - hmac: server.hmac, - compression: server.compression, - key: server.key - } - rescue CryptCheck::Ssh::Server::SshNotAvailableException - { no_tls: true } - end - Datastore.post :ssh, host, port, result + protected + def analyze(host, port=22) + CryptCheck::Ssh.analyze host, port + end + + def type + :ssh + end + + def to_json(server) + { + kex: server.kex, + encryption: server.encryption, + hmac: server.hmac, + compression: server.compression, + key_: server.key + } + end + + def grade_to_json(grade) + nil end end diff --git a/app/workers/xmpp_worker.rb b/app/workers/xmpp_worker.rb index 26580a4..b56c92b 100644 --- a/app/workers/xmpp_worker.rb +++ b/app/workers/xmpp_worker.rb @@ -3,10 +3,16 @@ class XMPPWorker < CheckWorker protected def analyze(host) - CryptCheck::Tls::Xmpp.analyze host + CryptCheck::Tls::Xmpp.analyze_domain host end def type :xmpp end + + def to_json(server) + result = super + result[:required] = server.required? + result + end end diff --git a/bin/enqueue b/bin/enqueue index 81ac621..cb4d3f3 100755 --- a/bin/enqueue +++ b/bin/enqueue @@ -6,4 +6,5 @@ options = { } client = Sidekiq::Client.new Sidekiq::RedisConnection.create options clazz, *args = ARGV +clazz += 'Worker' client.push({ 'class' => clazz, 'args' => args })