Browse Source

Check for SMTP and XMPP too

master
Aeris 4 years ago
parent
commit
11c86006b7
38 changed files with 352 additions and 116 deletions
  1. 0
    2
      Gemfile
  2. 0
    0
      app/assets/javascripts/check.coffee
  3. 0
    0
      app/assets/javascripts/https.coffee
  4. 10
    3
      app/assets/javascripts/site.coffee.erb
  5. 3
    0
      app/assets/javascripts/smtp.coffee
  6. 3
    0
      app/assets/javascripts/xmpp.coffee
  7. 0
    0
      app/assets/stylesheets/check.scss
  8. 0
    0
      app/assets/stylesheets/https.scss
  9. 3
    0
      app/assets/stylesheets/smtp.scss
  10. 3
    0
      app/assets/stylesheets/xmpp.scss
  11. 39
    0
      app/controllers/check_controller.rb
  12. 10
    0
      app/controllers/https_controller.rb
  13. 1
    36
      app/controllers/site_controller.rb
  14. 10
    0
      app/controllers/smtp_controller.rb
  15. 10
    0
      app/controllers/xmpp_controller.rb
  16. 2
    0
      app/helpers/check_helper.rb
  17. 2
    0
      app/helpers/https_helper.rb
  18. 30
    11
      app/helpers/site_helper.rb
  19. 2
    0
      app/helpers/smtp_helper.rb
  20. 2
    0
      app/helpers/xmpp_helper.rb
  21. 3
    0
      app/views/application/_headers.erb
  22. 0
    0
      app/views/check/no_tls.html.erb
  23. 2
    2
      app/views/check/processing.html.erb
  24. 2
    2
      app/views/check/show.html.erb
  25. 35
    0
      app/views/site/ciphers.html.erb
  26. 11
    10
      app/views/site/index.html.erb
  27. 48
    0
      app/workers/check_worker.rb
  28. 10
    35
      app/workers/https_worker.rb
  29. 12
    0
      app/workers/smtp_worker.rb
  30. 12
    0
      app/workers/xmpp_worker.rb
  31. 15
    4
      config/application.rb
  32. 0
    6
      config/environments/development.rb
  33. 0
    3
      config/environments/production.rb
  34. 16
    2
      config/routes.rb
  35. 14
    0
      test/controllers/check_controller_test.rb
  36. 14
    0
      test/controllers/https_controller_test.rb
  37. 14
    0
      test/controllers/smtp_controller_test.rb
  38. 14
    0
      test/controllers/xmpp_controller_test.rb

+ 0
- 2
Gemfile View File

@@ -2,11 +2,9 @@ source 'https://rubygems.org'

gem 'rails', '4.2.1'

gem 'sqlite3'
gem 'cryptcheck', '~> 1.0.0', path: File.expand_path(File.join File.dirname(__FILE__), '../cryptcheck')
gem 'sidekiq', '~> 3.4.2'
gem 'stretcher', '~> 1.21.1'
#gem 'mongo', '~> 2.0.6'
gem 'faraday', '~> 0.8.9' # For stretcher compatibility
gem 'simpleidn', '~> 0.0.5'


+ 0
- 0
app/assets/javascripts/check.coffee View File


+ 0
- 0
app/assets/javascripts/https.coffee View File


+ 10
- 3
app/assets/javascripts/site.coffee.erb View File

@@ -1,5 +1,12 @@
$ ->
$('#check_form').submit ->
submit = ->
host = $('#check_host').val()
window.location.href = "<%= path :result, %i(host) %>"
false
type = $('#check_type').val()
window.location.href = "<%= Rails.configuration.relative_url_root %>/#{type}/#{host}"

$('#check_host').keypress (e) ->
submit() if e.which == 13
return
$('#check_submit').click ->
submit()
return

+ 3
- 0
app/assets/javascripts/smtp.coffee View File

@@ -0,0 +1,3 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/

+ 3
- 0
app/assets/javascripts/xmpp.coffee View File

@@ -0,0 +1,3 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/

+ 0
- 0
app/assets/stylesheets/check.scss View File


+ 0
- 0
app/assets/stylesheets/https.scss View File


+ 3
- 0
app/assets/stylesheets/smtp.scss View File

@@ -0,0 +1,3 @@
// Place all the styles related to the Smtp controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

+ 3
- 0
app/assets/stylesheets/xmpp.scss View File

@@ -0,0 +1,3 @@
// Place all the styles related to the Xmpp controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

+ 39
- 0
app/controllers/check_controller.rb View File

@@ -0,0 +1,39 @@
class CheckController < ApplicationController
before_action :check_host

def check_host
@host = params[:id]
@idn = SimpleIDN.to_ascii @host
if /[^a-zA-Z0-9.-]/.match @idn
flash[:danger] = "Hôte #{@host} invalide"
redirect_to :root
return false
end
@result = Datastore.host self.type, @idn
end

def show
enqueue_host unless @result
return render :processing if @result.pending
return render :no_tls if @result.no_tls
end

def refresh
unless @result.pending
refresh_allowed = @result.date + Rails.configuration.refresh_delay
if Time.now < refresh_allowed
flash[:warning] = "Merci d’attendre au moins #{l refresh_allowed} pour rafraîchir"
return redirect_to result_path @host
end
enqueue_host
end
redirect_to action: :show
end

protected
def enqueue_host
Datastore.pending self.type, @host
self.worker.perform_async @idn
@result = OpenStruct.new pending: true , date: Time.now
end
end

+ 10
- 0
app/controllers/https_controller.rb View File

@@ -0,0 +1,10 @@
class HttpsController < CheckController
protected
def type
:https
end

def worker
HTTPSWorker
end
end

+ 1
- 36
app/controllers/site_controller.rb View File

@@ -1,42 +1,7 @@
class SiteController < ApplicationController
before_action :check_host, only: %i(result refresh)

def check_host
@host = params[:id]
@idn = SimpleIDN.to_ascii @host
if /[^a-zA-Z0-9.-]/.match @idn
flash[:danger] = "Hôte #{@host} invalide"
redirect_to :root
return false
end
@result = Datastore.host :https, @idn
end

def index
end

def result
enqueue_host unless @result
return render :processing if @result.pending
return render :no_tls if @result.no_tls
end

def refresh
unless @result.pending
refresh_allowed = @result.date + Rails.configuration.refresh_delay
if Time.now < refresh_allowed
flash[:warning] = "Merci d’attendre au moins #{l refresh_allowed} pour rafraîchir"
return redirect_to result_path @host
end
enqueue_host
end
redirect_to :result
end

private
def enqueue_host
Datastore.pending :https, @host
HTTPSWorker.perform_async @idn
@result = OpenStruct.new pending: true , date: Time.now
def ciphers
end
end

+ 10
- 0
app/controllers/smtp_controller.rb View File

@@ -0,0 +1,10 @@
class SmtpController < CheckController
protected
def type
:smtp
end

def worker
SMTPWorker
end
end

+ 10
- 0
app/controllers/xmpp_controller.rb View File

@@ -0,0 +1,10 @@
class XmppController < CheckController
protected
def type
:xmpp
end

def worker
XMPPWorker
end
end

+ 2
- 0
app/helpers/check_helper.rb View File

@@ -0,0 +1,2 @@
module CheckHelper
end

+ 2
- 0
app/helpers/https_helper.rb View File

@@ -0,0 +1,2 @@
module HttpsHelper
end

+ 30
- 11
app/helpers/site_helper.rb View File

@@ -35,7 +35,7 @@ module SiteHelper
end

def protocol_label(protocol)
color = case protocol
color = case protocol.to_s
when 'TLSv1_2' then :success
when 'SSLv3', 'SSLv2' then :danger
else :default
@@ -57,8 +57,9 @@ module SiteHelper
keys.sort { |a, b| -1 * (a.rsa_size <=> b.rsa_size)} .collect { |k| key_label k }.join("\n").html_safe
end

def cipher_label(cipher)
"<span class=\"label label-#{cipher_color cipher['size']} %>\">#{cipher['size']} bits</span>".html_safe
def cipher_size_label(cipher)
size = cipher.kind_of?(CryptCheck::Tls::Cipher) ? cipher.size : cipher['size']
"<span class=\"label label-#{cipher_color size} %>\">#{size} bits</span>".html_safe
end

def color_key(key)
@@ -72,20 +73,38 @@ module SiteHelper

def cipher_color(key)
case key
when 0...112 then :error
when 0...112 then :danger
when 112...128 then :warning
when 128...256 then :success
else :primary
end
end

def cipher_name_label(cipher, state)
color = case
when !state[:danger].empty? then :danger
when !state[:warning].empty? then :warning
when !state[:success].empty? then :success
else :default
end
color = :primary if color == :success and cipher.size >= 256
"<span class=\"label label-#{color} %>\">#{cipher.name}</span>".html_safe
end

def cipher_labels(cipher)
{ success: %i(pfs),
warning: %i(des3 sha1),
danger: %i(md5 psk srp anonymous null export des rc2 rc4)
}.collect do |color, types|
types.select { |t| CryptCheck::Tls::Cipher.send "#{t}?", cipher.name }
.collect { |t| "<span class=\"label label-#{color}\">#{t.upcase}</span>" }
end.flatten(1).join("\n").html_safe
case cipher
when Hashie::Mash
{ success: %i(pfs),
warning: %i(des3 sha1),
danger: %i(md5 psk srp anonymous null export des rc2 rc4)
}.collect do |c, ts|
ts.select { |t| CryptCheck::Tls::Cipher.send "#{t}?", cipher.name }.collect { |t| [c, t] }
end
when Hash
cipher.collect { |c, ts| ts.collect { |t| [c, t] } }
end
.flatten(1)
.collect { |c, t| "<span class=\"label label-#{c}\">#{t.upcase}</span>" }
.join("\n").html_safe
end
end

+ 2
- 0
app/helpers/smtp_helper.rb View File

@@ -0,0 +1,2 @@
module SmtpHelper
end

+ 2
- 0
app/helpers/xmpp_helper.rb View File

@@ -0,0 +1,2 @@
module XmppHelper
end

+ 3
- 0
app/views/application/_headers.erb View File

@@ -4,6 +4,9 @@
<div class="navbar-header">
<%= link_to 'CryptCheck', root_path, class: %i(navbar-brand) %>
</div>
<ul class="nav navbar-nav">
<li><%= link_to 'Ciphers', ciphers_path %></li>
</ul>
<!--
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">

app/views/site/no_tls.html → app/views/check/no_tls.html.erb View File


app/views/site/processing.html.erb → app/views/check/processing.html.erb View File

@@ -1,5 +1,5 @@
<% content_for :head do %>
<meta http-equiv="refresh" content="60">
<meta http-equiv="refresh" content="10">
<% end %>
<div id="check" class="container">
<div class="row">
@@ -13,7 +13,7 @@
</p>
<p class="pull-right">
Merci de patienter…
<span class="small">(Cette page se rafraîchit automatiquement toutes les minutes)</span>
<span class="small">(Cette page se rafraîchit automatiquement toutes les 10 secondes)</span>
</p>
</div>
</div>

app/views/site/result.html.erb → app/views/check/show.html.erb View File

@@ -8,7 +8,7 @@
</div>
<% if Time.now - @result.date >= Rails.configuration.refresh_delay %>
<div class="col-sm-1">
<%= link_to 'Rafraîchir', refresh_path, class: %i(btn btn-default) %>
<%= link_to 'Rafraîchir', {action: :refresh}, class: %i(btn btn-default) %>
</div>
<% end %>
</div>
@@ -92,7 +92,7 @@
<% ciphers.each do |cipher| %>
<tr>
<td><%= cipher.name %></td>
<td><%= cipher_label cipher %></td>
<td><%= cipher_size_label cipher %></td>
<td><%= key_label cipher.dh if cipher.dh %></td>
<td><%= cipher_labels cipher %></td>
</tr>

+ 35
- 0
app/views/site/ciphers.html.erb View File

@@ -0,0 +1,35 @@
<div class="container">
<div class="row">
<table class="table-bordered table-condensed table-striped col-sm-12">
<thead>
<tr>
<th class="col-sm-4">Algorithme</th>
<th class="col-sm-1">Taille</th>
<td class="col-sm-7"></td>
</tr>
</thead>
<tbody>
<% %i(TLSv1_2).each do |protocol|
context = OpenSSL::SSL::SSLContext.new protocol rescue next
%>
<!--
<tr>
<th colspan="3"><h1><%= protocol %><h1></th>
</tr>
-->
<%
context.ciphers = 'ALL:COMPLEMENTOFALL'
context.ciphers.collect { |c| CryptCheck::Tls::Cipher.new protocol, c }
.sort { |a, b| -1 * (a.size <=> b.size)}.each do |cipher| %>
<tr>
<% state = cipher.state %>
<th><%= cipher_name_label cipher, state %></th>
<th><%= cipher_size_label cipher %></th>
<th><%= cipher_labels state %></th>
</tr>
<% end %>
<% end %>
</tbody>
</table>
</div>
</div>

+ 11
- 10
app/views/site/index.html.erb View File

@@ -1,17 +1,18 @@
<div id="check" class="container">
<div class="row">
<div class="col-sm-8 col-sm-offset-2">
<div class="col-sm-12">
<h1>Vérifier votre domaine</h1>
<form id="check_form" class="form form-horizontal">
<div class="form-group">
<div class="col-sm-9">
<%= text_field_tag :check_host, nil, class: %i(form-control input-lg), placeholder: 'your-site.com' %>
</div>
<div class="col-sm-3">
<%= submit_tag 'Test-moi !', class: %i(form-control btn btn-primary input-lg pull-right) %>
</div>
<div class="form-group">
<div class="col-sm-8">
<%= text_field_tag :check_host, nil, class: %i(form-control input-lg), placeholder: 'your-site.com' %>
</div>
</form>
<div class="col-sm-2">
<%= select_tag :check_type, options_for_select({'HTTPS' => :https, 'SMTP' => :smtp, 'XMPP' => :xmpp}), class: %i(form-control input-lg) %>
</div>
<div class="col-sm-2">
<%= submit_tag 'Test-moi !', id: 'check_submit', class: %i(form-control btn btn-primary input-lg pull-right) %>
</div>
</div>
</div>
</div>
</div>

+ 48
- 0
app/workers/check_worker.rb View File

@@ -0,0 +1,48 @@
require 'simpleidn'
require 'cryptcheck'

class CheckWorker
include Sidekiq::Worker
sidekiq_options retry: false

def key_to_json(key)
key.nil? ? nil : { type: key.type, size: key.size, rsa_size: key.rsa_equivalent_size }
end

def perform(host)
idn = SimpleIDN.to_ascii host
result = begin
server = self.module::Server.new idn
grade = self.module::Grade.new 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,
warning: grade.warning,
success: grade.success
}
}


self.result server, grade, result
rescue CryptCheck::Tls::Server::TLSNotAvailableException
{ no_tls: true }
end
Datastore.post self.type, host, result
end

protected
def result(_, _, result)
result
end
end

+ 10
- 35
app/workers/https_worker.rb View File

@@ -1,42 +1,17 @@
require 'simpleidn'
require 'cryptcheck'

class HTTPSWorker
include Sidekiq::Worker
class HTTPSWorker < CheckWorker
sidekiq_options retry: false

def key_to_json(key)
key.nil? ? nil : { type: key.type, size: key.size, rsa_size: key.rsa_equivalent_size }
protected
def module
CryptCheck::Tls::Https
end

def perform(host)
idn = SimpleIDN.to_ascii host
result = begin
server = CryptCheck::Tls::Https::Server.new idn
grade = CryptCheck::Tls::Https::Grade.new server
def type
:https
end

{
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) } },
hsts: server.hsts,
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,
warning: grade.warning,
success: grade.success
}
}
rescue CryptCheck::Tls::Server::TLSNotAvailableException
{ no_tls: true }
end
Datastore.post :https, host, result
def result(server, _, hash)
hash[:hsts] = server.hsts
hash
end
end

+ 12
- 0
app/workers/smtp_worker.rb View File

@@ -0,0 +1,12 @@
class SMTPWorker < CheckWorker
sidekiq_options retry: false

protected
def module
CryptCheck::Tls::Smtp
end

def type
:smtp
end
end

+ 12
- 0
app/workers/xmpp_worker.rb View File

@@ -0,0 +1,12 @@
class XMPPWorker < CheckWorker
sidekiq_options retry: false

protected
def module
CryptCheck::Tls::Xmpp
end

def type
:xmpp
end
end

+ 15
- 4
config/application.rb View File

@@ -1,6 +1,20 @@
require File.expand_path('../boot', __FILE__)

require 'rails/all'
%w(
action_controller
action_view
active_job
rails/test_unit
sprockets
).each do |framework|
begin
require "#{framework}/railtie"
rescue LoadError
end
end




# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
@@ -26,9 +40,6 @@ module CryptcheckRails
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
config.i18n.default_locale = :fr

# Do not swallow errors in after_commit/after_rollback callbacks.
config.active_record.raise_in_transactional_callbacks = true

config.refresh_delay = 1.hour
end
end

+ 0
- 6
config/environments/development.rb View File

@@ -13,15 +13,9 @@ Rails.application.configure do
config.consider_all_requests_local = true
config.action_controller.perform_caching = false

# Don't care if the mailer can't send.
config.action_mailer.raise_delivery_errors = false

# Print deprecation notices to the Rails logger.
config.active_support.deprecation = :log

# Raise an error on page load if there are pending migrations.
config.active_record.migration_error = :page_load

# Debug mode disables concatenation and preprocessing of assets.
# This option may cause significant delays in view rendering with a large
# number of complex assets.

+ 0
- 3
config/environments/production.rb View File

@@ -73,7 +73,4 @@ Rails.application.configure do

# Use default logging formatter so that PID and timestamp are not suppressed.
config.log_formatter = ::Logger::Formatter.new

# Do not dump schema after migrations.
config.active_record.dump_schema_after_migration = false
end

+ 16
- 2
config/routes.rb View File

@@ -1,5 +1,19 @@
Rails.application.routes.draw do
namespace :https, id: /[^\/]*/ do
get ':id/', action: :show
get ':id/refresh', action: :refresh, as: :refresh
end

namespace :smtp, id: /[^\/]*/ do
get ':id/', action: :show
get ':id/refresh', action: :refresh, as: :refresh
end

namespace :xmpp, id: /[^\/]*/ do
get ':id/', action: :show
get ':id/refresh', action: :refresh, as: :refresh
end

root 'site#index'
get '/:id/refresh' => 'site#refresh', as: :refresh, id: /.*/
get '/:id' => 'site#result', as: :result, id: /.*/
get '/ciphers' => 'site#ciphers'
end

+ 14
- 0
test/controllers/check_controller_test.rb View File

@@ -0,0 +1,14 @@
require 'test_helper'

class CheckControllerTest < ActionController::TestCase
test "should get result" do
get :show
assert_response :success
end

test "should get refresh" do
get :refresh
assert_response :success
end

end

+ 14
- 0
test/controllers/https_controller_test.rb View File

@@ -0,0 +1,14 @@
require 'test_helper'

class HttpsControllerTest < ActionController::TestCase
test "should get result" do
get :show
assert_response :success
end

test "should get refresh" do
get :refresh
assert_response :success
end

end

+ 14
- 0
test/controllers/smtp_controller_test.rb View File

@@ -0,0 +1,14 @@
require 'test_helper'

class SmtpControllerTest < ActionController::TestCase
test "should get show" do
get :show
assert_response :success
end

test "should get refresh" do
get :refresh
assert_response :success
end

end

+ 14
- 0
test/controllers/xmpp_controller_test.rb View File

@@ -0,0 +1,14 @@
require 'test_helper'

class XmppControllerTest < ActionController::TestCase
test "should get show" do
get :show
assert_response :success
end

test "should get refresh" do
get :refresh
assert_response :success
end

end

Loading…
Cancel
Save