Browse Source

Better error handling

master
Aeris 2 years ago
parent
commit
2b134ba712

+ 1
- 0
Gemfile View File

@@ -22,6 +22,7 @@ end
22 22
 group :development, :test do
23 23
 	gem 'puma'
24 24
 	gem 'web-console'
25
+	gem 'awesome_print'
25 26
 
26 27
 	gem 'pry-rails'
27 28
 

+ 1
- 3
app/controllers/check_controller.rb View File

@@ -8,12 +8,10 @@ class CheckController < ApplicationController
8 8
 		respond_to do |format|
9 9
 			format.html do
10 10
 				return render :processing if @result.pending
11
-				return render :no_tls if @result.no_tls
12 11
 			end
13 12
 			format.json do
14 13
 				render json: case
15 14
 					when @result.pending then :pending
16
-					when @result.no_tls then :no_tls
17 15
 					else @result
18 16
 				end
19 17
 			end
@@ -34,7 +32,7 @@ class CheckController < ApplicationController
34 32
 
35 33
 	protected
36 34
 	def enqueue_host
37
-		Datastore.pending self.type, @id, @port
35
+		Datastore.pending self.type, @host, @port
38 36
 		self.worker.perform_async *(@port.blank? ? [@host] : [@host, @port])
39 37
 		@result = OpenStruct.new pending: true , date: Time.now
40 38
 	end

+ 5
- 4
app/lib/datastore.rb View File

@@ -3,19 +3,20 @@ class Datastore
3 3
 	@@index.create unless @@index.exists?
4 4
 
5 5
 	def self.host(type, host, port)
6
-		result = @@index.type(type).get self.key(host, port)
6
+		key = self.key host, port
7
+		result = @@index.type(type).get key
7 8
 		result.date = Time.parse result.date
8 9
 		result
9 10
 	rescue Stretcher::RequestError::NotFound
10 11
 	end
11 12
 
12 13
 	def self.pending(type, host, port)
13
-		self.post type, host, port, { pending: true }
14
+		self.post type, host, port, { pending: true, date: DateTime.now }
14 15
 	end
15 16
 
16 17
 	def self.post(type, host, port, data)
17
-		data[:date] = DateTime.now
18
-		@@index.type(type).put self.key(host, port), data
18
+		key = self.key host, port
19
+		@@index.type(type).put key, data
19 20
 	end
20 21
 
21 22
 	private

+ 0
- 12
app/views/check/no_tls.html.erb View File

@@ -1,12 +0,0 @@
1
-<div id="check" class="container">
2
-	<div class="row">
3
-		<div class="col-sm-8 col-sm-offset-2">
4
-			<h1>
5
-				[<%= self.type.to_s.upcase %>] <%= @host %> ne supporte pas <%= self.tls_type %>
6
-			</h1>
7
-			<% if Time.now - @result.date >= Rails.configuration.refresh_delay %>
8
-			<%= link_to 'Rafraîchir', {action: :refresh}, class: %i(btn btn-default pull-right) %>
9
-			<% end %>
10
-		</div>
11
-	</div>
12
-</div>

+ 31
- 11
app/views/check/show.html.erb View File

@@ -3,7 +3,6 @@
3 3
 		<div class="col-sm-11">
4 4
 			<h1>
5 5
 				[<%= self.type.to_s.upcase %>] <%= @host %> <span class="small">(<%= l @result.date %>)</span>
6
-				<%= rank_label @result.score.rank %>
7 6
 			</h1>
8 7
 		</div>
9 8
 		<% if Time.now - @result.date >= Rails.configuration.refresh_delay %>
@@ -12,16 +11,35 @@
12 11
 		</div>
13 12
 		<% end %>
14 13
 	</div>
15
-	<br/>
14
+	<%
15
+		@result.hosts.each do |host|
16
+			if host.error
17
+				error, host = host.error, host.host
18
+	%>
19
+	<div class="row">
20
+		<div class="col-sm-12">
21
+			<h2><%= host.name %> - <%= host.ip %> : <%= host.port %></h2>
22
+			Error during analysis :
23
+			<span class="label label-error"><%= error %></span>
24
+		</div>
25
+	</div>
26
+	<%
27
+			else
28
+				host, grade, handshake = host.host, host.grade, host.handshake
29
+	%>
30
+	<div class="row">
31
+		<div class="col-sm-12">
32
+			<h2><%= host.name %> - <%= host.ip %> : <%= host.port %></h2>
33
+		</div>
34
+	</div>
16 35
 	<div class="row">
17 36
 		<div class="col-sm-6">
18
-			<% scores = @result.score.details %>
19 37
 			<table class="table table-bordered table-condensed table-striped">
20 38
 				<thead>
21 39
 					<tr>
22 40
 						<th colspan="2">
23 41
 							Scores
24
-							<%= rank_label @result.score.rank %>
42
+							<%= rank_label grade.rank %>
25 43
 						</th>
26 44
 					</tr>
27 45
 				</thead>
@@ -33,7 +51,7 @@
33 51
 						 'Total' => 'score'}.each do |name, v| %>
34 52
 					<tr>
35 53
 						<th class="col-sm-4"><%= name %></th>
36
-						<td class="col-sm-8"><%= score_progress scores[v] %></td>
54
+						<td class="col-sm-8"><%= score_progress grade.details[v] %></td>
37 55
 					</tr>
38 56
 					<% end %>
39 57
 				</tbody>
@@ -44,20 +62,20 @@
44 62
 				<tbody>
45 63
 					<tr>
46 64
 						<th class="col-sm-4">Protocoles</th>
47
-						<td class="col-sm-8"><%= protocol_labels @result.protocols %></td>
65
+						<td class="col-sm-8"><%= protocol_labels handshake.protocols %></td>
48 66
 					</tr>
49 67
 					<tr>
50 68
 						<th>Clefs</th>
51 69
 						<td>
52
-							<p>Certificat : <%= key_label @result[:key] %></p>
53
-							<p>Diffie Hellman : <%= key_labels @result.dh %></p>
70
+							<p>Certificat : <%= key_label handshake[:key] %></p>
71
+							<p>Diffie Hellman : <%= key_labels handshake.dh %></p>
54 72
 						</td>
55 73
 					</tr>
56 74
 					<% { 'Bonnes pratiques' => :success,
57 75
 					 'Alertes' => :warning,
58 76
 					 'Dangers' => :danger,
59 77
 					 'Erreurs' => :error }.each do |name, color|
60
-						names = @result.score[color]
78
+						names = grade[color]
61 79
 						next if names.nil? or names.empty?
62 80
 					%>
63 81
 					<tr>
@@ -100,8 +118,8 @@
100 118
 				</thead>
101 119
 				<tbody>
102 120
 					<% CryptCheck::Tls::Server::EXISTING_METHODS.each do |protocol|
103
-						ciphers = CryptCheck::Tls::Cipher.sort(@result.ciphers.select { |c| c.protocol == protocol.to_s }
104
-								.collect { |c| CryptCheck::Tls::Cipher.new protocol, [c.name, nil, c[:size]], c.dh, @result[:key] })
121
+						ciphers = CryptCheck::Tls::Cipher.sort(handshake.ciphers.select { |c| c.protocol == protocol.to_s }
122
+								.collect { |c| CryptCheck::Tls::Cipher.new protocol, [c.name, nil, c[:size]], c.dh, handshake[:key] })
105 123
 						unless ciphers.empty? %>
106 124
 					<tr>
107 125
 						<th colspan="12"><%= protocol_label protocol %></th>
@@ -133,4 +151,6 @@
133 151
 			</table>
134 152
 		</div>
135 153
 	</div>
154
+	<% end
155
+	   end %>
136 156
 </div>

+ 28
- 6
app/views/ssh/show.html.erb View File

@@ -11,7 +11,27 @@
11 11
 		</div>
12 12
 		<% end %>
13 13
 	</div>
14
-	<br/>
14
+	<%
15
+		@result.hosts.each do |host|
16
+			if host.error
17
+				error, host = host.error, host.host
18
+	%>
19
+	<div class="row">
20
+		<div class="col-sm-12">
21
+			<h2><%= host.name %> - <%= host.ip %> : <%= host.port %></h2>
22
+			Error during analysis :
23
+			<span class="label label-error"><%= error %></span>
24
+		</div>
25
+	</div>
26
+	<%
27
+		else
28
+			host, server = host.host, host.handshake
29
+	%>
30
+	<div class="row">
31
+		<div class="col-sm-12">
32
+			<h2><%= host.name %> - <%= host.ip %> : <%= host.port %></h2>
33
+		</div>
34
+	</div>
15 35
 	<div class="row">
16 36
 		<div class="col-sm-12">
17 37
 			<table class="table table-bordered table-condensed table-striped">
@@ -19,7 +39,7 @@
19 39
 					<tr>
20 40
 						<th>Échange de clef</th>
21 41
 					</tr>
22
-					<% @result.kex.each do |kex| %>
42
+					<% server.kex.each do |kex| %>
23 43
 					<tr>
24 44
 						<td><%= kex_label kex %></td>
25 45
 					</tr>
@@ -28,7 +48,7 @@
28 48
 					<tr>
29 49
 						<th>Chiffrement</th>
30 50
 					</tr>
31
-					<% @result.encryption.each do |cipher| %>
51
+					<% server.encryption.each do |cipher| %>
32 52
 					<tr>
33 53
 						<td><%= cipher_label cipher %></td>
34 54
 					</tr>
@@ -37,7 +57,7 @@
37 57
 					<tr>
38 58
 						<th>HMAC</th>
39 59
 					</tr>
40
-					<% @result.hmac.each do |hmac| %>
60
+					<% server.hmac.each do |hmac| %>
41 61
 						<tr>
42 62
 							<td><%= hmac_label hmac %></td>
43 63
 						</tr>
@@ -46,7 +66,7 @@
46 66
 					<tr>
47 67
 						<th>Compression</th>
48 68
 					</tr>
49
-					<% @result.compression.each do |compression| %>
69
+					<% server.compression.each do |compression| %>
50 70
 						<tr>
51 71
 							<td><%= compression_label compression %></td>
52 72
 						</tr>
@@ -55,7 +75,7 @@
55 75
 					<tr>
56 76
 						<th>Clefs</th>
57 77
 					</tr>
58
-					<% @result['key'].each do |key| %>
78
+					<% server.key_.each do |key| %>
59 79
 					<tr>
60 80
 						<td><%= key_label key %></td>
61 81
 					</tr>
@@ -64,4 +84,6 @@
64 84
 			</table>
65 85
 		</div>
66 86
 	</div>
87
+	<% end
88
+	   end %>
67 89
 </div>

+ 44
- 28
app/workers/check_worker.rb View File

@@ -7,40 +7,56 @@ class CheckWorker
7 7
 	end
8 8
 
9 9
 	def perform(host, port=nil)
10
-		host    = SimpleIDN.to_ascii host.downcase
11
-		result = begin
12
-			grade  = self.analyze *(port ? [host, port] : [host])
13
-			raise CryptCheck::Tls::Server::TLSNotAvailableException if grade.is_a? CryptCheck::Tls::TlsNotSupportedGrade
10
+		host   = SimpleIDN.to_ascii host.downcase
11
+		hosts  = self.analyze *(port ? [host, port] : [host])
12
+		hosts  = hosts.collect do |host, result|
13
+			name, ip, p = host
14
+			host           = { name: name, ip: ip, port: p }
15
+
16
+			if result.is_a? CryptCheck::AnalysisFailure
17
+				next {
18
+						host:  host,
19
+						error: result.to_s
20
+				}
21
+			end
22
+
23
+			grade  = result
14 24
 			server = grade.server
15
-			result = {
16
-					key:       key_to_json(server.key),
17
-					dh:        server.dh.collect { |k| key_to_json k },
18
-					protocols: server.supported_protocols,
19
-					ciphers:   server.supported_ciphers.collect { |c| { protocol: c.protocol, name: c.name, size: c.size, dh: key_to_json(c.dh) } },
20
-					score:     {
21
-							rank:    grade.grade,
22
-							details: {
23
-									score:            grade.score,
24
-									protocol:         grade.protocol_score,
25
-									key_exchange:     grade.key_exchange_score,
26
-									cipher_strengths: grade.cipher_strengths_score
27
-							},
28
-							error:   grade.error,
29
-							danger:  grade.danger,
30
-							warning: grade.warning,
31
-							success: grade.success
32
-					}
25
+			{
26
+					host:      host,
27
+					handshake: to_json(server),
28
+					grade: grade_to_json(grade)
33 29
 			}
34
-
35
-			self.result server, grade, result
36
-		rescue CryptCheck::Tls::Server::TLSNotAvailableException
37
-			{ no_tls: true }
38 30
 		end
31
+		result = { date: DateTime.now, hosts: hosts }
39 32
 		Datastore.post self.type, host, port, result
40 33
 	end
41 34
 
42 35
 	protected
43
-	def result(_, _, result)
44
-		result
36
+	def to_json(server)
37
+		{
38
+				key:       key_to_json(server.key),
39
+				dh:        server.dh.collect { |k| key_to_json k },
40
+				protocols: server.supported_protocols,
41
+				ciphers:   server.supported_ciphers.collect { |c| { protocol: c.protocol, name: c.name, size: c.size, dh: key_to_json(c.dh) } },
42
+
43
+		}
44
+	end
45
+
46
+	private
47
+	def grade_to_json(grade)
48
+		{
49
+				rank:    grade.grade,
50
+				details: {
51
+						score:            grade.score,
52
+						protocol:         grade.protocol_score,
53
+						key_exchange:     grade.key_exchange_score,
54
+						cipher_strengths: grade.cipher_strengths_score
55
+				},
56
+				error:   grade.error,
57
+				danger:  grade.danger,
58
+				warning: grade.warning,
59
+				success: grade.success
60
+		}
45 61
 	end
46 62
 end

+ 4
- 3
app/workers/https_worker.rb View File

@@ -10,8 +10,9 @@ class HTTPSWorker < CheckWorker
10 10
 		:https
11 11
 	end
12 12
 
13
-	def result(server, _, hash)
14
-		hash[:hsts] = server.hsts
15
-		hash
13
+	def to_json(server)
14
+		result = super
15
+		result[:hsts] = server.hsts
16
+		result
16 17
 	end
17 18
 end

+ 2
- 2
app/workers/smtp_worker.rb View File

@@ -2,8 +2,8 @@ class SMTPWorker < CheckWorker
2 2
 	sidekiq_options retry: false
3 3
 
4 4
 	protected
5
-	def analyze(host, port=25)
6
-		CryptCheck::Tls::Smtp.analyze host, port
5
+	def analyze(host)
6
+		CryptCheck::Tls::Smtp.analyze_domain host
7 7
 	end
8 8
 
9 9
 	def type

+ 22
- 17
app/workers/ssh_worker.rb View File

@@ -1,21 +1,26 @@
1
-class SSHWorker
2
-	include Sidekiq::Worker
1
+class SSHWorker < CheckWorker
3 2
 	sidekiq_options retry: false
4 3
 
5
-	def perform(host, port=nil)
6
-		host    = SimpleIDN.to_ascii host.downcase
7
-		result = begin
8
-			server = CryptCheck::Ssh.analyze host, port
9
-			{
10
-					kex:         server.kex,
11
-					encryption:  server.encryption,
12
-					hmac:        server.hmac,
13
-					compression: server.compression,
14
-					key:         server.key
15
-			}
16
-		rescue CryptCheck::Ssh::Server::SshNotAvailableException
17
-			{ no_tls: true }
18
-		end
19
-		Datastore.post :ssh, host, port, result
4
+	protected
5
+	def analyze(host, port=22)
6
+		CryptCheck::Ssh.analyze host, port
7
+	end
8
+
9
+	def type
10
+		:ssh
11
+	end
12
+
13
+	def to_json(server)
14
+		{
15
+				kex:         server.kex,
16
+				encryption:  server.encryption,
17
+				hmac:        server.hmac,
18
+				compression: server.compression,
19
+				key_:         server.key
20
+		}
21
+	end
22
+
23
+	def grade_to_json(grade)
24
+		nil
20 25
 	end
21 26
 end

+ 7
- 1
app/workers/xmpp_worker.rb View File

@@ -3,10 +3,16 @@ class XMPPWorker < CheckWorker
3 3
 
4 4
 	protected
5 5
 	def analyze(host)
6
-		CryptCheck::Tls::Xmpp.analyze host
6
+		CryptCheck::Tls::Xmpp.analyze_domain host
7 7
 	end
8 8
 
9 9
 	def type
10 10
 		:xmpp
11 11
 	end
12
+
13
+	def to_json(server)
14
+		result = super
15
+		result[:required] = server.required?
16
+		result
17
+	end
12 18
 end

+ 1
- 0
bin/enqueue View File

@@ -6,4 +6,5 @@ options      = {
6 6
 }
7 7
 client       = Sidekiq::Client.new Sidekiq::RedisConnection.create options
8 8
 clazz, *args = ARGV
9
+clazz += 'Worker'
9 10
 client.push({ 'class' => clazz, 'args' => args })

Loading…
Cancel
Save