ssl_scan 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Rakefile +32 -0
- data/data/cacert.pem +3866 -0
- data/lib/ssl_scan.rb +1 -0
- data/lib/ssl_scan/commands/command.rb +4 -5
- data/lib/ssl_scan/commands/host.rb +8 -3
- data/lib/ssl_scan/compat.rb +4 -0
- data/lib/ssl_scan/main.rb +74 -16
- data/lib/ssl_scan/result.rb +2 -0
- data/lib/ssl_scan/scanner.rb +37 -2
- data/lib/ssl_scan/util.rb +7 -0
- data/lib/ssl_scan/version.rb +1 -1
- data/locale/de/LC_MESSAGES/ssl_scan.mo +0 -0
- data/locale/de/ssl_scan.po +46 -0
- data/locale/en/LC_MESSAGES/ssl_scan.mo +0 -0
- data/locale/en/ssl_scan.po +34 -0
- data/sslscan.gemspec +4 -1
- metadata +37 -3
data/lib/ssl_scan.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
|
-
require "stringio"
|
2
|
-
|
3
1
|
module SSLScan
|
4
2
|
module Commands
|
5
3
|
class Command
|
6
4
|
attr_accessor :results, :options, :stream, :errors
|
5
|
+
include FastGettext::Translation
|
7
6
|
|
8
7
|
def initialize(results=[], stream=nil)
|
9
8
|
@results = results
|
@@ -17,11 +16,11 @@ module SSLScan
|
|
17
16
|
|
18
17
|
# Display Methods
|
19
18
|
def write_header(host, port=443)
|
20
|
-
stream.printf "\nTesting SSL server
|
19
|
+
stream.printf _("\nTesting SSL server %{host} on port %{port}\n") % { host: host, port: port }
|
21
20
|
end
|
22
21
|
|
23
22
|
def write_preferred_ciphers(scanner)
|
24
|
-
stream.printf("\nServer Preferred Cipher(s)\n")
|
23
|
+
stream.printf _("\nServer Preferred Cipher(s)\n")
|
25
24
|
ciphers = scanner.get_preferred_ciphers
|
26
25
|
ciphers.each do |c|
|
27
26
|
if c.length > 1 && !c[1].empty?
|
@@ -32,7 +31,7 @@ module SSLScan
|
|
32
31
|
end
|
33
32
|
|
34
33
|
def write_ciphers(scanner=nil)
|
35
|
-
stream.printf "\nSupported Server Cipher(s):\n"
|
34
|
+
stream.printf _("\nSupported Server Cipher(s):\n")
|
36
35
|
|
37
36
|
sslv = options.only_ssl2 || options.only_ssl3 || options.only_tls1 || false
|
38
37
|
|
@@ -29,9 +29,14 @@ module SSLScan
|
|
29
29
|
write_header(parts[0])
|
30
30
|
end
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
if options.only_cert
|
33
|
+
scanner.get_first_valid_cert
|
34
|
+
@results << scanner.results
|
35
|
+
else
|
36
|
+
write_ciphers(scanner)
|
37
|
+
write_preferred_ciphers(scanner)
|
38
|
+
@results << scanner.results
|
39
|
+
end
|
35
40
|
end
|
36
41
|
|
37
42
|
end # Host
|
data/lib/ssl_scan/compat.rb
CHANGED
@@ -56,6 +56,10 @@ def self.is_linux
|
|
56
56
|
@@is_linux = (RUBY_PLATFORM =~ /linux/) ? true : false
|
57
57
|
end
|
58
58
|
|
59
|
+
def self.is_debian
|
60
|
+
return self.is_linux && File.exists?('/etc/debian_version')
|
61
|
+
end
|
62
|
+
|
59
63
|
def self.is_bsdi
|
60
64
|
return @@is_bsdi if @@is_bsdi
|
61
65
|
@@is_bsdi = (RUBY_PLATFORM =~ /bsdi/i) ? true : false
|
data/lib/ssl_scan/main.rb
CHANGED
@@ -1,11 +1,7 @@
|
|
1
|
-
# require "ssl_scan/compat"
|
2
|
-
# require "ssl_scan/version"
|
3
|
-
# require "ssl_scan/scanner"
|
4
|
-
# require "ssl_scan/result"
|
5
|
-
|
6
1
|
require "ssl_scan/version"
|
7
2
|
require "ssl_scan/compat"
|
8
3
|
require "ssl_scan/result"
|
4
|
+
require "ssl_scan/util"
|
9
5
|
require "timeout"
|
10
6
|
require "thread"
|
11
7
|
require "ssl_scan/sync/thread_safe"
|
@@ -18,19 +14,42 @@ require "ssl_scan/scanner"
|
|
18
14
|
require "openssl"
|
19
15
|
require "optparse"
|
20
16
|
require "ostruct"
|
17
|
+
require "fast_gettext"
|
21
18
|
|
22
19
|
require "ssl_scan/commands/command"
|
23
20
|
require "ssl_scan/commands/host"
|
24
21
|
|
22
|
+
#
|
23
|
+
# Setup Translations
|
24
|
+
#
|
25
|
+
FastGettext.add_text_domain('ssl_scan', path: File.join(SSLScan::Util::ROOT, 'locale'))
|
26
|
+
FastGettext.text_domain = 'ssl_scan'
|
27
|
+
FastGettext.available_locales = ['en', 'de']
|
28
|
+
active_locale = "en"
|
29
|
+
['LC_ALL', 'LANG', 'LANGUAGE'].each do |env_lang|
|
30
|
+
lang = ENV[env_lang]
|
31
|
+
if lang
|
32
|
+
lang = lang[0..1]
|
33
|
+
if FastGettext.available_locales.include?(lang)
|
34
|
+
active_locale = lang
|
35
|
+
break
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
FastGettext.locale = active_locale
|
40
|
+
|
41
|
+
|
25
42
|
module SSLScan
|
26
43
|
class Main
|
27
44
|
|
45
|
+
include FastGettext::Translation
|
46
|
+
|
28
47
|
EXIT_SUCCESS = 0
|
29
48
|
EXIT_FAILURE = 1
|
30
49
|
|
31
|
-
SYNTAX = "ssl_scan [Options] [host:port | host]"
|
50
|
+
SYNTAX = _("ssl_scan [Options] [host:port | host]")
|
32
51
|
WEBSITE = "https://www.testcloud.de"
|
33
|
-
COPYRIGHT = "Copyright (C) John Faucett
|
52
|
+
COPYRIGHT = _("Copyright (C) John Faucett %{year}") % { year: Time.now.year }
|
34
53
|
|
35
54
|
BANNER =<<EOH
|
36
55
|
_
|
@@ -47,10 +66,10 @@ EOH
|
|
47
66
|
def check_host(host, die_on_fail=true)
|
48
67
|
valid = true
|
49
68
|
port = 443
|
50
|
-
error_msg = "Host invalid"
|
69
|
+
error_msg = _("Host invalid")
|
51
70
|
begin
|
52
71
|
if !host
|
53
|
-
error_msg = "Host not given"
|
72
|
+
error_msg = _("Host not given")
|
54
73
|
valid = false
|
55
74
|
else
|
56
75
|
host_parts = host.split(":")
|
@@ -64,7 +83,7 @@ EOH
|
|
64
83
|
end
|
65
84
|
|
66
85
|
unless valid
|
67
|
-
printf("Error: %
|
86
|
+
printf _("Error: %{error}\n") % { error: error_msg }
|
68
87
|
exit(EXIT_FAILURE) unless !die_on_fail
|
69
88
|
end
|
70
89
|
return valid
|
@@ -106,7 +125,7 @@ EOH
|
|
106
125
|
alias_method :run, :main
|
107
126
|
|
108
127
|
def self.version_info
|
109
|
-
|
128
|
+
_("ssl_scan version %{version}\n%{web}\n%{copy}\n") % { version: VERSION::STRING, web: WEBSITE, copy: COPYRIGHT}
|
110
129
|
end
|
111
130
|
|
112
131
|
def show_results(host, results)
|
@@ -114,13 +133,18 @@ EOH
|
|
114
133
|
unless result_set.empty?
|
115
134
|
result_set.each do |result|
|
116
135
|
show_certificate(result.cert)
|
136
|
+
|
137
|
+
# TODO: Implement certificate verification
|
138
|
+
printf _("Verify Certificate:")
|
139
|
+
printf _(" NOT IMPLEMENTED")
|
140
|
+
printf("\n")
|
117
141
|
end
|
118
142
|
end
|
119
143
|
end
|
120
144
|
|
121
145
|
def show_certificate(cert)
|
122
|
-
printf("SSL Certificate:\n")
|
123
|
-
printf(" Version: %
|
146
|
+
printf _("SSL Certificate:\n")
|
147
|
+
printf _(" Version: %{version}\n") % { version: cert.version }
|
124
148
|
printf(" Serial Number: %s\n", cert.serial.to_s(16))
|
125
149
|
printf(" Signature Algorithm: %s\n", cert.signature_algorithm)
|
126
150
|
printf(" Issuer: %s\n", cert.issuer.to_s)
|
@@ -129,7 +153,34 @@ EOH
|
|
129
153
|
printf(" Subject: %s\n", cert.subject.to_s)
|
130
154
|
printf(" %s", cert.public_key.to_text)
|
131
155
|
|
132
|
-
|
156
|
+
unless cert.extensions.empty?
|
157
|
+
puts _("X509v3 Extensions:")
|
158
|
+
cert.extensions.each do |extension|
|
159
|
+
case extension.oid
|
160
|
+
when 'keyUsage'
|
161
|
+
puts _(" X509v3 Key Usage: critical") if extension.critical?
|
162
|
+
when 'certificatePolicies'
|
163
|
+
puts _(" X509v3 Certificate Policies:")
|
164
|
+
when 'subjectAltName'
|
165
|
+
puts _(" X509v3 Subject Alternative Name:")
|
166
|
+
when 'basicConstraints'
|
167
|
+
puts _(" X509v3 Basic Constraints:")
|
168
|
+
when 'extendedKeyUsage'
|
169
|
+
puts _(" X509v3 Extended Key Usage:")
|
170
|
+
when 'crlDistributionPoints'
|
171
|
+
puts _(" X509v3 CRL Distribution Points:")
|
172
|
+
when 'authorityInfoAccess'
|
173
|
+
puts _(" Authority Information Access:")
|
174
|
+
when 'subjectKeyIdentifier'
|
175
|
+
puts _(" X509v3 Subject Key Identifier:")
|
176
|
+
when 'authorityKeyIdentifier'
|
177
|
+
puts _(" X509v3 Authority Key Identifier:")
|
178
|
+
else
|
179
|
+
puts extension.oid
|
180
|
+
end
|
181
|
+
puts _(" %{value}") % { value: extension.value }
|
182
|
+
end
|
183
|
+
end
|
133
184
|
end
|
134
185
|
|
135
186
|
def show_command_errors(host, errors)
|
@@ -143,6 +194,7 @@ EOH
|
|
143
194
|
options.only_ssl2 = false
|
144
195
|
options.only_ssl3 = false
|
145
196
|
options.only_tls1 = false
|
197
|
+
options.only_cert = false
|
146
198
|
|
147
199
|
opts = OptionParser.new do |opts|
|
148
200
|
opts.banner = sprintf("%s%s", BANNER, version_info)
|
@@ -155,8 +207,8 @@ EOH
|
|
155
207
|
|
156
208
|
# File containing list of hosts to check
|
157
209
|
opts.on( "-t",
|
158
|
-
"--targets FILE",
|
159
|
-
"A file containing a list of hosts to check with syntax ( host | host:port).") do |filename|
|
210
|
+
_("--targets FILE"),
|
211
|
+
_("A file containing a list of hosts to check with syntax ( host | host:port).")) do |filename|
|
160
212
|
options.file = filename
|
161
213
|
end
|
162
214
|
|
@@ -181,6 +233,12 @@ EOH
|
|
181
233
|
options.only_tls1 = :TLSv1
|
182
234
|
end
|
183
235
|
|
236
|
+
opts.on( "-c",
|
237
|
+
"--cert",
|
238
|
+
"Only get the server certificate") do
|
239
|
+
options.only_cert = true
|
240
|
+
end
|
241
|
+
|
184
242
|
opts.on( "-d",
|
185
243
|
"--debug",
|
186
244
|
"Print any SSL errors to stderr.") do
|
data/lib/ssl_scan/result.rb
CHANGED
data/lib/ssl_scan/scanner.rb
CHANGED
@@ -88,8 +88,9 @@ class Scanner
|
|
88
88
|
return scan_result
|
89
89
|
end
|
90
90
|
|
91
|
-
|
92
|
-
|
91
|
+
sslctx = OpenSSL::SSL::SSLContext.new(ssl_version)
|
92
|
+
sslctx.ciphers.each do |cipher_name, ssl_ver, key_length, alg_length|
|
93
|
+
|
93
94
|
status = test_cipher(ssl_version, cipher_name)
|
94
95
|
scan_result.add_cipher(ssl_version, cipher_name, key_length, status)
|
95
96
|
if status == :accepted and scan_result.cert.nil?
|
@@ -121,6 +122,10 @@ class Scanner
|
|
121
122
|
'Timeout' => @timeout
|
122
123
|
)
|
123
124
|
ssl_versions[ssl_version] = scan_client.cipher
|
125
|
+
|
126
|
+
if scan_client
|
127
|
+
scan_client.close
|
128
|
+
end
|
124
129
|
rescue => ex
|
125
130
|
ssl_versions.delete(ssl_version)
|
126
131
|
end
|
@@ -128,6 +133,36 @@ class Scanner
|
|
128
133
|
ssl_versions
|
129
134
|
end
|
130
135
|
|
136
|
+
|
137
|
+
def get_first_valid_cert
|
138
|
+
scan_result = SSLScan::Result.new
|
139
|
+
scan_result.openssl_sslv2 = sslv2
|
140
|
+
@supported_versions.each do |ssl_version|
|
141
|
+
begin
|
142
|
+
scan_client = SSLScan::Socket::Tcp.create(
|
143
|
+
'Context' => @context,
|
144
|
+
'PeerHost' => @host,
|
145
|
+
'PeerPort' => @port,
|
146
|
+
'SSL' => true,
|
147
|
+
'SSLVersion' => ssl_version,
|
148
|
+
'Timeout' => @timeout
|
149
|
+
)
|
150
|
+
cipher_name = scan_client.cipher[0]
|
151
|
+
key_length = scan_client.cipher[3]
|
152
|
+
status = test_cipher(ssl_version, cipher_name)
|
153
|
+
scan_result.add_cipher(ssl_version, cipher_name, key_length, status)
|
154
|
+
if status == :accepted and scan_result.cert.nil?
|
155
|
+
scan_result.cert = get_cert(ssl_version, cipher_name)
|
156
|
+
break
|
157
|
+
end
|
158
|
+
rescue => ex
|
159
|
+
# noop
|
160
|
+
end
|
161
|
+
end
|
162
|
+
@results = scan_result
|
163
|
+
scan_result
|
164
|
+
end
|
165
|
+
|
131
166
|
def test_ssl
|
132
167
|
begin
|
133
168
|
scan_client = SSLScan::Socket::Tcp.create(
|
data/lib/ssl_scan/version.rb
CHANGED
Binary file
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# SOME DESCRIPTIVE TITLE.
|
2
|
+
# Copyright (C) 2014 John Faucett
|
3
|
+
# This file is distributed under the same license as the app package.
|
4
|
+
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
5
|
+
#
|
6
|
+
#, fuzzy
|
7
|
+
msgid ""
|
8
|
+
msgstr ""
|
9
|
+
"Project-Id-Version: ssl_scan 0.0.5\n"
|
10
|
+
"Report-Msgid-Bugs-To: \n"
|
11
|
+
"POT-Creation-Date: 2013-09-29 17:49-0700\n"
|
12
|
+
"PO-Revision-Date: 2013-09-29 17:49-0700\n"
|
13
|
+
"Last-Translator: John Faucett <jwaterfaucett@gmail.com>\n"
|
14
|
+
"Language-Team: LANGUAGE <LL@li.org>\n"
|
15
|
+
"Language: \n"
|
16
|
+
"MIME-Version: 1.0\n"
|
17
|
+
"Content-Type: text/plain; charset=UTF-8\n"
|
18
|
+
"Content-Transfer-Encoding: 8bit\n"
|
19
|
+
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
|
20
|
+
|
21
|
+
msgid "Host invalid"
|
22
|
+
msgstr "Host ungültig"
|
23
|
+
|
24
|
+
msgid "Error: %{error}\n"
|
25
|
+
msgstr "Fehler: %{error}\n"
|
26
|
+
|
27
|
+
msgid "Host not given"
|
28
|
+
msgstr "Host wurde nicht angegeben"
|
29
|
+
|
30
|
+
msgid "ssl_scan [Options] [host:port | host]"
|
31
|
+
msgstr "ssl_scan [Optionen] [host:port | host]"
|
32
|
+
|
33
|
+
msgid "Copyright (C) John Faucett %{year}"
|
34
|
+
msgstr "Copyright (C) John Faucett %{year}"
|
35
|
+
|
36
|
+
msgid "SSL Certificate:\n"
|
37
|
+
msgstr "SSL Zertifikat:\n"
|
38
|
+
|
39
|
+
msgid " Version: %{version}\n"
|
40
|
+
msgstr " Version: %{version}\n"
|
41
|
+
|
42
|
+
msgid "A file containing a list of hosts to check with syntax ( host | host:port)."
|
43
|
+
msgstr "Eine Datei die eine Liste der zu überprüfenden Hosts enthält ( host | host:port)."
|
44
|
+
|
45
|
+
msgid "--targets FILE"
|
46
|
+
msgstr "--targets DATEI"
|
Binary file
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# SOME DESCRIPTIVE TITLE.
|
2
|
+
# Copyright (C) 2014 John Faucett
|
3
|
+
# This file is distributed under the same license as the app package.
|
4
|
+
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
5
|
+
#
|
6
|
+
#, fuzzy
|
7
|
+
msgid ""
|
8
|
+
msgstr ""
|
9
|
+
"Project-Id-Version: ssl_scan 0.0.5\n"
|
10
|
+
"Report-Msgid-Bugs-To: \n"
|
11
|
+
"POT-Creation-Date: 2013-09-29 17:49-0700\n"
|
12
|
+
"PO-Revision-Date: 2013-09-29 17:49-0700\n"
|
13
|
+
"Last-Translator: John Faucett <jwaterfaucett@gmail.com>\n"
|
14
|
+
"Language-Team: LANGUAGE <LL@li.org>\n"
|
15
|
+
"Language: \n"
|
16
|
+
"MIME-Version: 1.0\n"
|
17
|
+
"Content-Type: text/plain; charset=UTF-8\n"
|
18
|
+
"Content-Transfer-Encoding: 8bit\n"
|
19
|
+
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
|
20
|
+
|
21
|
+
msgid "Host invalid"
|
22
|
+
msgstr "Host invalid"
|
23
|
+
|
24
|
+
msgid "Error: %{error}\n"
|
25
|
+
msgstr "Error: %{error}\n"
|
26
|
+
|
27
|
+
msgid "Host not given"
|
28
|
+
msgstr "Host not given"
|
29
|
+
|
30
|
+
msgid "ssl_scan [Options] [host:port | host]"
|
31
|
+
msgstr "ssl_scan [Options] [host:port | host]"
|
32
|
+
|
33
|
+
msgid "Copyright (C) John Faucett %{year}"
|
34
|
+
msgstr "Copyright (C) John Faucett %{year}"
|
data/sslscan.gemspec
CHANGED
@@ -18,7 +18,10 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
+
spec.add_runtime_dependency "fast_gettext", "~> 0.8"
|
22
|
+
|
21
23
|
spec.add_development_dependency "bundler", "~> 1.5"
|
22
24
|
spec.add_development_dependency "rake"
|
23
|
-
spec.add_development_dependency "rspec", "~> 3.0
|
25
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
26
|
+
spec.add_development_dependency "gettext"
|
24
27
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ssl_scan
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Faucett
|
@@ -10,6 +10,20 @@ bindir: bin
|
|
10
10
|
cert_chain: []
|
11
11
|
date: 2014-06-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: fast_gettext
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.8'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.8'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: bundler
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -44,14 +58,28 @@ dependencies:
|
|
44
58
|
requirements:
|
45
59
|
- - ~>
|
46
60
|
- !ruby/object:Gem::Version
|
47
|
-
version: 3.0
|
61
|
+
version: '3.0'
|
48
62
|
type: :development
|
49
63
|
prerelease: false
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
51
65
|
requirements:
|
52
66
|
- - ~>
|
53
67
|
- !ruby/object:Gem::Version
|
54
|
-
version: 3.0
|
68
|
+
version: '3.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: gettext
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
55
83
|
description: An SSL Scanner Library and Utility in pure Ruby
|
56
84
|
email:
|
57
85
|
- jwaterfaucett@gmail.com
|
@@ -67,6 +95,7 @@ files:
|
|
67
95
|
- README.md
|
68
96
|
- Rakefile
|
69
97
|
- bin/ssl_scan
|
98
|
+
- data/cacert.pem
|
70
99
|
- lib/ssl_scan.rb
|
71
100
|
- lib/ssl_scan/commands/command.rb
|
72
101
|
- lib/ssl_scan/commands/host.rb
|
@@ -95,7 +124,12 @@ files:
|
|
95
124
|
- lib/ssl_scan/socket/tcp_server.rb
|
96
125
|
- lib/ssl_scan/socket/udp.rb
|
97
126
|
- lib/ssl_scan/sync/thread_safe.rb
|
127
|
+
- lib/ssl_scan/util.rb
|
98
128
|
- lib/ssl_scan/version.rb
|
129
|
+
- locale/de/LC_MESSAGES/ssl_scan.mo
|
130
|
+
- locale/de/ssl_scan.po
|
131
|
+
- locale/en/LC_MESSAGES/ssl_scan.mo
|
132
|
+
- locale/en/ssl_scan.po
|
99
133
|
- spec/lib/ssl_scan/scanner_spec.rb
|
100
134
|
- spec/spec_helper.rb
|
101
135
|
- sslscan.gemspec
|