tlspretense 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|