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.
 
 
 
 
 
 
cryptcheck-rails/bin/stats

126 lines
3.3 KiB

#!./bin/rails runner
# Profit from open class to add stats methods only on this script
class Analysis
def grade
grades = self.result.collect { _1['grade'] }.compact
CryptCheck::Grade.worst grades
end
def tls
return unless (result = self.result)
protocols = result.collect { |r| r.dig('handshakes', 'protocols')
&.collect { |p| p['protocol'].to_sym } }
.compact.flatten.uniq
return :ssl unless (protocols & %i[SSLv2 SSLv3]).empty?
return :tls unless protocols.include? :TLSv1_2
return :tls1_2_only if protocols == %i[TLSv1_2]
:tls1_2
end
def ciphers
return unless (result = self.result)
status = result.collect do |r|
r.dig('handshakes', 'ciphers')&.collect do |c|
s = CryptCheck::Tls::Cipher
.new(nil, c.fetch('name')).status
CryptCheck::State.good_or_bad s
end
end.compact.flatten.uniq
return :bad if status.include? :bad
:good
end
def pfs
return unless (result = self.result)
ciphers = result.collect do |r|
r.dig('handshakes', 'ciphers')&.collect do |c|
CryptCheck::Tls::Cipher
.new(nil, c.fetch('name'))
.pfs?
end
end.compact.flatten.uniq
return :no_pfs unless ciphers.include? true
return :pfs_only unless ciphers.include? false
:pfs
end
end
# sites = YAML.load_file Rails.root.join 'config/sites.yml'
#
# workflows = []
# sites.each do |type, domains|
# domains.each do |domain|
# puts "Refreshing #{domain}"
# @analysis = Analysis.pending! :https, domain, 443
# workflows << CheckWorkflow.start!(:https, @analysis.host, *@analysis.args)
# end
# end
# workflows.each &:wait
#
# sites.each do |type, domains|
# domains = domains.collect do |domain|
# analysis = Analysis[:https, domain, 443]
# stats = {
# grade: analysis.grade,
# tls: analysis.tls,
# ciphers: analysis.ciphers,
# pfs: analysis.pfs
# }
# [domain, stats]
# end.to_h
#
# Stat.create! :"sites_#{type}", domains
# end
# general stat
services = Analysis.group(:service).order(service: :asc).count
Stat.create! :request_per_service, { labels: services.keys, dataset: services.values }
# grade per service for https, smtp, tls and xmpp
%i[https smtp tls xmpp].each do |name|
services = Analysis.where service: name, pending: false
grades = Hash.new 0
tls = %i[tls1_2_only tls1_2 tls ssl].to_h { [_1, 0] }
ciphers = %i[good bad].to_h { [_1, 0] }
pfs = %i[pfs_only pfs no_pfs].to_h { [_1, 0] }
progress = ProgressBar.create title: name, total: services.count,
format: '%t | %c/%u %W | %e'
services.find_in_batches do |batch|
batch.each do |service|
if (g = service.grade)
grades[g] += 1
end
if (t = service.tls)
tls[t] += 1
end
if (c = service.ciphers)
ciphers[c] += 1
end
if (p = service.pfs)
pfs[p] += 1
end
progress.increment
end
end
ap "grades_for_#{name}" => grades
Stat.create! "grades_for_#{name}", grades
ap "tls_for_#{name}" => tls
Stat.create! "tls_for_#{name}", tls
ap "ciphers_for_#{name}" => ciphers
Stat.create! "ciphers_for_#{name}", ciphers
ap "pfs_for_#{name}" => pfs
Stat.create! "pfs_for_#{name}", pfs
end