tlspretense 0.6.1
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.
- data/.document +6 -0
- data/.gitignore +7 -0
- data/.rspec +1 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +41 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +231 -0
- data/Rakefile +44 -0
- data/bin/makeder.sh +6 -0
- data/bin/tlspretense +7 -0
- data/bin/view.sh +3 -0
- data/doc/general_setup.rdoc +288 -0
- data/doc/linux_setup.rdoc +64 -0
- data/lib/certmaker.rb +61 -0
- data/lib/certmaker/certificate_factory.rb +106 -0
- data/lib/certmaker/certificate_suite_generator.rb +120 -0
- data/lib/certmaker/ext_core/hash_indifferent_fetch.rb +12 -0
- data/lib/certmaker/runner.rb +27 -0
- data/lib/certmaker/tasks.rb +20 -0
- data/lib/packetthief.rb +167 -0
- data/lib/packetthief/handlers.rb +14 -0
- data/lib/packetthief/handlers/abstract_ssl_handler.rb +249 -0
- data/lib/packetthief/handlers/proxy_redirector.rb +26 -0
- data/lib/packetthief/handlers/ssl_client.rb +87 -0
- data/lib/packetthief/handlers/ssl_server.rb +174 -0
- data/lib/packetthief/handlers/ssl_smart_proxy.rb +143 -0
- data/lib/packetthief/handlers/ssl_transparent_proxy.rb +225 -0
- data/lib/packetthief/handlers/transparent_proxy.rb +183 -0
- data/lib/packetthief/impl.rb +11 -0
- data/lib/packetthief/impl/ipfw.rb +140 -0
- data/lib/packetthief/impl/manual.rb +54 -0
- data/lib/packetthief/impl/netfilter.rb +109 -0
- data/lib/packetthief/impl/pf_divert.rb +168 -0
- data/lib/packetthief/impl/pf_rdr.rb +192 -0
- data/lib/packetthief/logging.rb +49 -0
- data/lib/packetthief/redirect_rule.rb +29 -0
- data/lib/packetthief/util.rb +36 -0
- data/lib/ssl_test.rb +21 -0
- data/lib/ssl_test/app_context.rb +17 -0
- data/lib/ssl_test/certificate_manager.rb +33 -0
- data/lib/ssl_test/config.rb +79 -0
- data/lib/ssl_test/ext_core/io_raw_input.rb +31 -0
- data/lib/ssl_test/input_handler.rb +35 -0
- data/lib/ssl_test/runner.rb +110 -0
- data/lib/ssl_test/runner_options.rb +68 -0
- data/lib/ssl_test/ssl_test_case.rb +46 -0
- data/lib/ssl_test/ssl_test_report.rb +24 -0
- data/lib/ssl_test/ssl_test_result.rb +30 -0
- data/lib/ssl_test/test_listener.rb +140 -0
- data/lib/ssl_test/test_manager.rb +116 -0
- data/lib/tlspretense.rb +13 -0
- data/lib/tlspretense/app.rb +52 -0
- data/lib/tlspretense/init_runner.rb +115 -0
- data/lib/tlspretense/skel/ca/goodcacert.pem +19 -0
- data/lib/tlspretense/skel/ca/goodcakey.pem +27 -0
- data/lib/tlspretense/skel/config.yml +523 -0
- data/lib/tlspretense/version.rb +3 -0
- data/packetthief_examples/em_ssl_test.rb +73 -0
- data/packetthief_examples/redirector.rb +29 -0
- data/packetthief_examples/setup_iptables.sh +24 -0
- data/packetthief_examples/ssl_client_simple.rb +27 -0
- data/packetthief_examples/ssl_server_simple.rb +44 -0
- data/packetthief_examples/ssl_smart_proxy.rb +115 -0
- data/packetthief_examples/ssl_transparent_proxy.rb +97 -0
- data/packetthief_examples/transparent_proxy.rb +56 -0
- data/spec/packetthief/impl/ipfw_spec.rb +98 -0
- data/spec/packetthief/impl/manual_spec.rb +65 -0
- data/spec/packetthief/impl/netfilter_spec.rb +66 -0
- data/spec/packetthief/impl/pf_divert_spec.rb +82 -0
- data/spec/packetthief/impl/pf_rdr_spec.rb +133 -0
- data/spec/packetthief/logging_spec.rb +78 -0
- data/spec/packetthief_spec.rb +47 -0
- data/spec/spec_helper.rb +53 -0
- data/spec/ssl_test/certificate_manager_spec.rb +222 -0
- data/spec/ssl_test/config_spec.rb +76 -0
- data/spec/ssl_test/runner_spec.rb +360 -0
- data/spec/ssl_test/ssl_test_case_spec.rb +113 -0
- data/spec/ssl_test/test_listener_spec.rb +199 -0
- data/spec/ssl_test/test_manager_spec.rb +324 -0
- data/tlspretense.gemspec +35 -0
- metadata +262 -0
@@ -0,0 +1,192 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module PacketThief
|
4
|
+
module Impl
|
5
|
+
# Implementation that uses PF's +rdr+ (old style rules) and parses pfctl's
|
6
|
+
# output to interoperate with Mac OS X 10.7 Lion.
|
7
|
+
#
|
8
|
+
# It assumes that the system running PacketThief is already set up to
|
9
|
+
# reroute traffic like a NAT (On Mac OS X, you can do this by enabling
|
10
|
+
# Internet Sharing).
|
11
|
+
#
|
12
|
+
# To use it, you need to add the following rule to your /etc/pf.conf file
|
13
|
+
# in the "Translation" section.
|
14
|
+
#
|
15
|
+
# rdr-anchor "packetthief"
|
16
|
+
#
|
17
|
+
# This rule probably should be inserted after any NAT rules, but before any
|
18
|
+
# other redirect rules (such as Apple's +rdr-anchor+ rule). Once you have
|
19
|
+
# added it, you can reload the core ruleset:
|
20
|
+
#
|
21
|
+
# pfctl -f /etc/pf.conf
|
22
|
+
#
|
23
|
+
# == Design
|
24
|
+
#
|
25
|
+
# Lion (and Mountain Lion) provide an older implementation of PF (circa
|
26
|
+
# OpenBSD 4.3 and earlier) that does not contain the +divert-to+ action.
|
27
|
+
# Furthermore, Apple has decided to not make pfvars.h a public header file,
|
28
|
+
# making it marginally difficult to compile C code that can look up the
|
29
|
+
# original destination. Instead, we use pfctl to look up the state table,
|
30
|
+
# and we parse its output to find the current connection and acquire its
|
31
|
+
# original destination.
|
32
|
+
#
|
33
|
+
# Redirect rules look like the following:
|
34
|
+
#
|
35
|
+
# rdr on en1 proto tcp from any to any port 443 -> 127.0.0.1 port 54321
|
36
|
+
#
|
37
|
+
# The pfctl state table output looks something like:
|
38
|
+
#
|
39
|
+
# $ sudo pfctl -s states
|
40
|
+
# No ALTQ support in kernel
|
41
|
+
# ALTQ related functions disabled
|
42
|
+
# ALL tcp 74.125.224.68:80 <- 192.168.2.2:52995 ESTABLISHED:ESTABLISHED
|
43
|
+
# ALL tcp 192.168.2.2:52995 -> 10.0.1.2:33596 -> 74.125.224.68:80 ESTABLISHED:ESTABLISHED
|
44
|
+
# ALL tcp 127.0.0.1:54321 <- 173.194.79.147:443 <- 192.168.2.2:52998 CLOSED:SYN_SENT
|
45
|
+
# ALL tcp 127.0.0.1:54321 <- 173.194.79.147:443 <- 192.168.2.2:52999 CLOSED:SYN_SENT
|
46
|
+
# ALL tcp 127.0.0.1:54321 <- 173.194.79.147:443 <- 192.168.2.2:53000 CLOSED:SYN_SENT
|
47
|
+
# ALL tcp 127.0.0.1:54321 <- 173.194.79.147:443 <- 192.168.2.2:53001 CLOSED:SYN_SENT
|
48
|
+
# ALL udp 192.168.2.1:53 <- 192.168.2.2:53690 SINGLE:MULTIPLE
|
49
|
+
# ALL tcp 74.125.224.105:80 <- 192.168.2.2:53002 ESTABLISHED:ESTABLISHED
|
50
|
+
# ALL tcp 192.168.2.2:53002 -> 10.0.1.2:38466 -> 74.125.224.105:80 ESTABLISHED:ESTABLISHED
|
51
|
+
# ALL udp 224.0.0.251:5353 <- 10.0.1.4:5353 NO_TRAFFIC:SINGLE
|
52
|
+
# ALL udp ff02::fb[5353] <- fe80::72de:e2ff:fe41:5ddd[5353] NO_TRAFFIC:SINGLE
|
53
|
+
#
|
54
|
+
# /^(?<iface>\S+)\s+(?<proto>\S+)\s+(?<dest>\S+)\s+<-\s+(?<origdest>\S+)\s+<-\s+(?<src>\S+)\s+(?<status>\S+)$/
|
55
|
+
#
|
56
|
+
class PFRdr
|
57
|
+
module PFRdrRuleHandler
|
58
|
+
include Logging
|
59
|
+
attr_accessor :active_rules
|
60
|
+
|
61
|
+
# Executes a rule and holds onto it for later removal.
|
62
|
+
def run(rule)
|
63
|
+
@active_rules ||= []
|
64
|
+
|
65
|
+
@active_rules << rule
|
66
|
+
rulestrs = @active_rules.map { |r| r.to_pf_command.join(" ") }
|
67
|
+
|
68
|
+
rulestrs.each { |rule| logdebug rule }
|
69
|
+
args = %W{pfctl -q -a packetthief -f -}
|
70
|
+
IO.popen(args, "w+") do |pfctlio|
|
71
|
+
rulestrs.each { |rule| pfctlio.puts rule }
|
72
|
+
end
|
73
|
+
unless $?.exitstatus == 0
|
74
|
+
raise "Command #{args.inspect} exited with error code #{$?.inspect}"
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
# Reverts all executed rules that this handler knows about.
|
80
|
+
def revert
|
81
|
+
return if @active_rules == nil or @active_rules.empty?
|
82
|
+
|
83
|
+
args = %W{pfctl -q -a packetthief -F all}
|
84
|
+
unless system(*args)
|
85
|
+
raise "Command #{args.inspect} exited with error code #{$?.inspect}"
|
86
|
+
end
|
87
|
+
# end
|
88
|
+
|
89
|
+
@active_rules = []
|
90
|
+
end
|
91
|
+
end
|
92
|
+
extend PFRdrRuleHandler
|
93
|
+
|
94
|
+
class PFRdrRule < RedirectRule
|
95
|
+
|
96
|
+
attr_accessor :rule_number
|
97
|
+
|
98
|
+
def initialize(handler, rule_number=nil)
|
99
|
+
super(handler)
|
100
|
+
@rule_number = rule_number
|
101
|
+
end
|
102
|
+
|
103
|
+
def to_pf_command
|
104
|
+
args = []
|
105
|
+
|
106
|
+
args << "rdr"
|
107
|
+
|
108
|
+
if self.rulespec
|
109
|
+
args << 'on' << self.rulespec[:in_interface].to_s if self.rulespec.has_key? :in_interface
|
110
|
+
|
111
|
+
args << "proto" << self.rulespec.fetch(:protocol,'ip').to_s
|
112
|
+
|
113
|
+
args << 'from'
|
114
|
+
args << self.rulespec.fetch(:source_address, 'any').to_s
|
115
|
+
args << 'port' << self.rulespec[:source_port].to_s if self.rulespec.has_key? :source_port
|
116
|
+
|
117
|
+
args << 'to'
|
118
|
+
args << self.rulespec.fetch(:dest_address, 'any').to_s
|
119
|
+
args << 'port' << self.rulespec[:dest_port].to_s if self.rulespec.has_key? :dest_port
|
120
|
+
end
|
121
|
+
|
122
|
+
if self.redirectspec
|
123
|
+
if self.redirectspec.has_key? :to_ports
|
124
|
+
args << '->'
|
125
|
+
args << "127.0.0.1"
|
126
|
+
args << 'port' << self.redirectspec[:to_ports].to_s if self.redirectspec.has_key? :to_ports
|
127
|
+
else
|
128
|
+
raise "Rule lacks a valid redirect: #{self.inspect}"
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
args
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def self.redirect(args={})
|
138
|
+
rule = PFRdrRule.new(self)
|
139
|
+
rule.redirect(args)
|
140
|
+
end
|
141
|
+
|
142
|
+
RDR_PAT = /^(?<iface>\S+)\s+(?<proto>\S+)\s+(?<dest>\S+)\s+<-\s+(?<origdest>\S+)\s+<-\s+(?<src>\S+)\s+(?<status>\S+)$/
|
143
|
+
|
144
|
+
# Returns the [port, host] for the original destination of +sock+.
|
145
|
+
#
|
146
|
+
# +Sock+ can be a Ruby socket or an EventMachine::Connection (including
|
147
|
+
# handler modules, which are mixed in to an anonymous descendent of
|
148
|
+
# EM::Connection).
|
149
|
+
#
|
150
|
+
# When PF uses a nat/rdr rule, it stores the original destination in a
|
151
|
+
# table that can be queried using an ioctl() call on the /dev/pf device.
|
152
|
+
# Unfortunately for Mac OS X 10.7 and 10.8, Apple does not provide the
|
153
|
+
# necessary pfvars.h header for querying pf, although it exists in the XNU
|
154
|
+
# kernel source, which marks it as a "private" header. Apple's version is
|
155
|
+
# also "different" from the version supported by most BSDs these days,
|
156
|
+
# creating additional headaches.
|
157
|
+
#
|
158
|
+
# To work around this, we instead use +pfctl -s states+ to get the nat
|
159
|
+
# state information.
|
160
|
+
def self.original_dest(sock)
|
161
|
+
if sock.respond_to? :getsockname
|
162
|
+
sockname = sock.getsockname
|
163
|
+
elsif sock.respond_to? :get_sockname
|
164
|
+
sockname = sock.get_sockname
|
165
|
+
else
|
166
|
+
raise ArgumentError, "#{sock.inspect} supports neither :getsockname nor :get_sockname!"
|
167
|
+
end
|
168
|
+
if sock.respond_to? :getpeername
|
169
|
+
peername = sock.getpeername
|
170
|
+
elsif sock.respond_to? :get_peername
|
171
|
+
peername = sock.get_peername
|
172
|
+
else
|
173
|
+
raise ArgumentError, "#{sock.inspect} supports neither :getpeername nor :get_peername!"
|
174
|
+
end
|
175
|
+
dest = Socket.unpack_sockaddr_in(sockname)
|
176
|
+
src = Socket.unpack_sockaddr_in(peername)
|
177
|
+
|
178
|
+
state_table = `pfctl -q -s state`
|
179
|
+
rdr_lines = state_table.split("\n").map { |l| l.match(RDR_PAT) }.compact
|
180
|
+
matched_conns = rdr_lines.select { |l| l[:dest] == "#{dest[1]}:#{dest[0]}" and l[:src] == "#{src[1]}:#{src[0]}" }
|
181
|
+
raise "multiple conns matched: #{matched_conns.inspect}" unless matched_conns.length == 1
|
182
|
+
host, port = matched_conns[0][:origdest].split(':', 2)
|
183
|
+
port = port.to_i
|
184
|
+
|
185
|
+
logdebug "original_dest:", :port => port, :host => host
|
186
|
+
[port, host]
|
187
|
+
end
|
188
|
+
|
189
|
+
end
|
190
|
+
|
191
|
+
end
|
192
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module PacketThief
|
2
|
+
# Mix-in that provides some private convenience logging functions. Uses the
|
3
|
+
# @logger instance variable.
|
4
|
+
module Logging
|
5
|
+
# An optional Ruby Logger for debugging output. If it is unset, the log
|
6
|
+
# methods will be silent.
|
7
|
+
attr_accessor :logger
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
# Print a message at the specified log severity (prefixed with the component),
|
12
|
+
# and display any additional arguments. For example:
|
13
|
+
#
|
14
|
+
# dlog(Logger::DEBUG, SomeClass, "hello", :somevalue => 'that value")
|
15
|
+
#
|
16
|
+
# Will print the message: "SomeClass: hello: somevalue=that value" at the
|
17
|
+
# debug log level.
|
18
|
+
def log(level, component, msg, args={})
|
19
|
+
if @logger
|
20
|
+
unless args.empty?
|
21
|
+
kvstr = args.map { |pair| pair[0].to_s + ': ' + pair[1].inspect }.sort.join(', ')
|
22
|
+
msg += ": " + kvstr
|
23
|
+
end
|
24
|
+
@logger.log(level, component.to_s + ': ' + msg)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def logdebug(msg, args={})
|
29
|
+
log(Logger::DEBUG, (([Module, Class].include? self.class) ? self.name : self.class), msg, args)
|
30
|
+
end
|
31
|
+
|
32
|
+
def loginfo(msg, args={})
|
33
|
+
log(Logger::INFO, self.class, msg, args)
|
34
|
+
end
|
35
|
+
|
36
|
+
def logwarn(msg, args={})
|
37
|
+
log(Logger::WARN, self.class, msg, args)
|
38
|
+
end
|
39
|
+
|
40
|
+
def logerror(msg, args={})
|
41
|
+
log(Logger::ERROR, self.class, msg, args)
|
42
|
+
end
|
43
|
+
|
44
|
+
def logfatal(msg, args={})
|
45
|
+
log(Logger::FATAL, self.class, msg, args)
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
module PacketThief
|
3
|
+
class RedirectRule
|
4
|
+
attr_accessor :handler
|
5
|
+
attr_accessor :rulespec
|
6
|
+
attr_accessor :redirectspec
|
7
|
+
|
8
|
+
def initialize(handler)
|
9
|
+
@handler = handler
|
10
|
+
end
|
11
|
+
|
12
|
+
# specify an original destination
|
13
|
+
def where(args)
|
14
|
+
rule = clone
|
15
|
+
rule.rulespec = args
|
16
|
+
rule
|
17
|
+
end
|
18
|
+
|
19
|
+
def redirect(args)
|
20
|
+
rule = clone
|
21
|
+
rule.redirectspec = args
|
22
|
+
rule
|
23
|
+
end
|
24
|
+
|
25
|
+
def run
|
26
|
+
@handler.run(self)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module PacketThief
|
2
|
+
# Some utility methods, currently just used by the examples.
|
3
|
+
module Util
|
4
|
+
class << self
|
5
|
+
# Extracts all PEM encoded certificates out of a raw string and returns
|
6
|
+
# each raw PEM encoded certificate in an array.
|
7
|
+
def split_chain(raw)
|
8
|
+
chain = []
|
9
|
+
remaining = raw
|
10
|
+
certpat = /-----BEGIN CERTIFICATE-----(.*?)-----END CERTIFICATE-----/m
|
11
|
+
while m = certpat.match(remaining)
|
12
|
+
remaining = m.post_match
|
13
|
+
chain << m[0].strip
|
14
|
+
end
|
15
|
+
chain
|
16
|
+
end
|
17
|
+
|
18
|
+
# Extracts all PEM encoded certs from a raw string and returns a list of
|
19
|
+
# X509 certificate objects in the order they appear in the file.
|
20
|
+
#
|
21
|
+
# This can be helpful for loading a chain of certificates, eg for a
|
22
|
+
# server.
|
23
|
+
#
|
24
|
+
# Usage:
|
25
|
+
#
|
26
|
+
# chain = cert_chain(File.read("chain.pem"))
|
27
|
+
# p chain # => [#<OpenSSL::X509::Certificate subject=/C=US/CN=my.hostname.com, issuer=/C=US/CN=Trusted CA...>,
|
28
|
+
# #<OpenSSL::X509::Certificate subject=/C=US/CN=Trusted CA ... >]
|
29
|
+
def cert_chain(raw)
|
30
|
+
rawchain = split_chain(raw)
|
31
|
+
rawchain.map { |rawcert| OpenSSL::X509::Certificate.new(rawcert) }
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/ssl_test.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'packetthief'
|
2
|
+
require 'eventmachine'
|
3
|
+
require 'optparse'
|
4
|
+
require 'termios'
|
5
|
+
require 'logger'
|
6
|
+
|
7
|
+
require 'ssl_test/ext_core/io_raw_input'
|
8
|
+
|
9
|
+
module SSLTest
|
10
|
+
autoload :AppContext, 'ssl_test/app_context'
|
11
|
+
autoload :CertificateManager, 'ssl_test/certificate_manager'
|
12
|
+
autoload :Config, 'ssl_test/config'
|
13
|
+
autoload :InputHandler, 'ssl_test/input_handler'
|
14
|
+
autoload :RunnerOptions, 'ssl_test/runner_options'
|
15
|
+
autoload :Runner, 'ssl_test/runner'
|
16
|
+
autoload :SSLTestCase, 'ssl_test/ssl_test_case'
|
17
|
+
autoload :SSLTestReport, 'ssl_test/ssl_test_report'
|
18
|
+
autoload :SSLTestResult, 'ssl_test/ssl_test_result'
|
19
|
+
autoload :TestListener, 'ssl_test/test_listener'
|
20
|
+
autoload :TestManager, 'ssl_test/test_manager'
|
21
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module SSLTest
|
2
|
+
|
3
|
+
# Class to hold onto application-wide values in a single place and to track
|
4
|
+
# application state.
|
5
|
+
class AppContext
|
6
|
+
|
7
|
+
attr_accessor :config
|
8
|
+
attr_accessor :cert_manager
|
9
|
+
attr_accessor :logger
|
10
|
+
|
11
|
+
def initialize(config, cert_manager, logger)
|
12
|
+
@config = config
|
13
|
+
@cert_manager = cert_manager
|
14
|
+
@logger = logger
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module SSLTest
|
2
|
+
# Handles the loading and caching of certificates and private keys.
|
3
|
+
class CertificateManager
|
4
|
+
|
5
|
+
def initialize(certinfo)
|
6
|
+
@certinfo = certinfo
|
7
|
+
end
|
8
|
+
|
9
|
+
def get_raw_cert(name)
|
10
|
+
File.read(File.join('certs',name+"cert.pem"))
|
11
|
+
end
|
12
|
+
|
13
|
+
def get_cert(name)
|
14
|
+
OpenSSL::X509::Certificate.new(get_raw_cert(name))
|
15
|
+
end
|
16
|
+
|
17
|
+
def get_raw_key(name)
|
18
|
+
File.read(File.join('certs',name+"key.pem"))
|
19
|
+
end
|
20
|
+
|
21
|
+
def get_key(name)
|
22
|
+
OpenSSL::PKey.read(get_raw_key(name))
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_chain(list)
|
26
|
+
list.map { |name| get_cert(name) }
|
27
|
+
end
|
28
|
+
|
29
|
+
def get_keychain(list)
|
30
|
+
list.map { |name| get_key(name) }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module SSLTest
|
2
|
+
# Loads and interprets the configuration file.
|
3
|
+
class Config
|
4
|
+
|
5
|
+
DEFAULT = "config.yml"
|
6
|
+
|
7
|
+
attr_reader :raw
|
8
|
+
attr_reader :certs
|
9
|
+
|
10
|
+
def self.load_conf(opts)
|
11
|
+
Config.new(opts)
|
12
|
+
end
|
13
|
+
|
14
|
+
# TODO: do some basic type validation on the config file.
|
15
|
+
def initialize(opts)
|
16
|
+
@opts = opts
|
17
|
+
|
18
|
+
@raw = YAML.load_file(@opts[:config])
|
19
|
+
@certs = @raw['certs']
|
20
|
+
end
|
21
|
+
|
22
|
+
def tests
|
23
|
+
@raw['tests']
|
24
|
+
end
|
25
|
+
|
26
|
+
def hosttotest
|
27
|
+
@raw['hostname']
|
28
|
+
end
|
29
|
+
|
30
|
+
def listener_port
|
31
|
+
@raw['listener_port']
|
32
|
+
end
|
33
|
+
|
34
|
+
def testing_method
|
35
|
+
@raw['testing_method']
|
36
|
+
end
|
37
|
+
|
38
|
+
def packetthief
|
39
|
+
pt = @raw['packetthief'].dup
|
40
|
+
newvals = {}
|
41
|
+
pt.each_pair do |k,v|
|
42
|
+
if k.kind_of? String
|
43
|
+
newvals[k.to_sym] = v
|
44
|
+
end
|
45
|
+
end
|
46
|
+
pt.merge! newvals
|
47
|
+
pt
|
48
|
+
end
|
49
|
+
|
50
|
+
def pause?
|
51
|
+
@opts[:pause]
|
52
|
+
end
|
53
|
+
|
54
|
+
def action
|
55
|
+
@opts[:action]
|
56
|
+
end
|
57
|
+
|
58
|
+
def loglevel
|
59
|
+
levelstr = if @opts.has_key? :loglevel
|
60
|
+
@opts[:loglevel].upcase
|
61
|
+
elsif @raw.has_key? 'log' and @raw['log'].has_key? 'level'
|
62
|
+
@raw['log']['level'].upcase
|
63
|
+
else
|
64
|
+
'INFO'
|
65
|
+
end
|
66
|
+
Logger.const_get(levelstr)
|
67
|
+
end
|
68
|
+
|
69
|
+
def logfile
|
70
|
+
if @opts[:logfile] == '-'
|
71
|
+
STDOUT
|
72
|
+
else
|
73
|
+
@opts[:logfile]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|