ssl_scan 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|