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.
Files changed (81) hide show
  1. data/.document +6 -0
  2. data/.gitignore +7 -0
  3. data/.rspec +1 -0
  4. data/Gemfile +2 -0
  5. data/Gemfile.lock +41 -0
  6. data/LICENSE.txt +20 -0
  7. data/README.rdoc +231 -0
  8. data/Rakefile +44 -0
  9. data/bin/makeder.sh +6 -0
  10. data/bin/tlspretense +7 -0
  11. data/bin/view.sh +3 -0
  12. data/doc/general_setup.rdoc +288 -0
  13. data/doc/linux_setup.rdoc +64 -0
  14. data/lib/certmaker.rb +61 -0
  15. data/lib/certmaker/certificate_factory.rb +106 -0
  16. data/lib/certmaker/certificate_suite_generator.rb +120 -0
  17. data/lib/certmaker/ext_core/hash_indifferent_fetch.rb +12 -0
  18. data/lib/certmaker/runner.rb +27 -0
  19. data/lib/certmaker/tasks.rb +20 -0
  20. data/lib/packetthief.rb +167 -0
  21. data/lib/packetthief/handlers.rb +14 -0
  22. data/lib/packetthief/handlers/abstract_ssl_handler.rb +249 -0
  23. data/lib/packetthief/handlers/proxy_redirector.rb +26 -0
  24. data/lib/packetthief/handlers/ssl_client.rb +87 -0
  25. data/lib/packetthief/handlers/ssl_server.rb +174 -0
  26. data/lib/packetthief/handlers/ssl_smart_proxy.rb +143 -0
  27. data/lib/packetthief/handlers/ssl_transparent_proxy.rb +225 -0
  28. data/lib/packetthief/handlers/transparent_proxy.rb +183 -0
  29. data/lib/packetthief/impl.rb +11 -0
  30. data/lib/packetthief/impl/ipfw.rb +140 -0
  31. data/lib/packetthief/impl/manual.rb +54 -0
  32. data/lib/packetthief/impl/netfilter.rb +109 -0
  33. data/lib/packetthief/impl/pf_divert.rb +168 -0
  34. data/lib/packetthief/impl/pf_rdr.rb +192 -0
  35. data/lib/packetthief/logging.rb +49 -0
  36. data/lib/packetthief/redirect_rule.rb +29 -0
  37. data/lib/packetthief/util.rb +36 -0
  38. data/lib/ssl_test.rb +21 -0
  39. data/lib/ssl_test/app_context.rb +17 -0
  40. data/lib/ssl_test/certificate_manager.rb +33 -0
  41. data/lib/ssl_test/config.rb +79 -0
  42. data/lib/ssl_test/ext_core/io_raw_input.rb +31 -0
  43. data/lib/ssl_test/input_handler.rb +35 -0
  44. data/lib/ssl_test/runner.rb +110 -0
  45. data/lib/ssl_test/runner_options.rb +68 -0
  46. data/lib/ssl_test/ssl_test_case.rb +46 -0
  47. data/lib/ssl_test/ssl_test_report.rb +24 -0
  48. data/lib/ssl_test/ssl_test_result.rb +30 -0
  49. data/lib/ssl_test/test_listener.rb +140 -0
  50. data/lib/ssl_test/test_manager.rb +116 -0
  51. data/lib/tlspretense.rb +13 -0
  52. data/lib/tlspretense/app.rb +52 -0
  53. data/lib/tlspretense/init_runner.rb +115 -0
  54. data/lib/tlspretense/skel/ca/goodcacert.pem +19 -0
  55. data/lib/tlspretense/skel/ca/goodcakey.pem +27 -0
  56. data/lib/tlspretense/skel/config.yml +523 -0
  57. data/lib/tlspretense/version.rb +3 -0
  58. data/packetthief_examples/em_ssl_test.rb +73 -0
  59. data/packetthief_examples/redirector.rb +29 -0
  60. data/packetthief_examples/setup_iptables.sh +24 -0
  61. data/packetthief_examples/ssl_client_simple.rb +27 -0
  62. data/packetthief_examples/ssl_server_simple.rb +44 -0
  63. data/packetthief_examples/ssl_smart_proxy.rb +115 -0
  64. data/packetthief_examples/ssl_transparent_proxy.rb +97 -0
  65. data/packetthief_examples/transparent_proxy.rb +56 -0
  66. data/spec/packetthief/impl/ipfw_spec.rb +98 -0
  67. data/spec/packetthief/impl/manual_spec.rb +65 -0
  68. data/spec/packetthief/impl/netfilter_spec.rb +66 -0
  69. data/spec/packetthief/impl/pf_divert_spec.rb +82 -0
  70. data/spec/packetthief/impl/pf_rdr_spec.rb +133 -0
  71. data/spec/packetthief/logging_spec.rb +78 -0
  72. data/spec/packetthief_spec.rb +47 -0
  73. data/spec/spec_helper.rb +53 -0
  74. data/spec/ssl_test/certificate_manager_spec.rb +222 -0
  75. data/spec/ssl_test/config_spec.rb +76 -0
  76. data/spec/ssl_test/runner_spec.rb +360 -0
  77. data/spec/ssl_test/ssl_test_case_spec.rb +113 -0
  78. data/spec/ssl_test/test_listener_spec.rb +199 -0
  79. data/spec/ssl_test/test_manager_spec.rb +324 -0
  80. data/tlspretense.gemspec +35 -0
  81. metadata +262 -0
@@ -0,0 +1,78 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),'..','spec_helper'))
2
+
3
+ module PacketThief
4
+ describe Logging do
5
+ class LoggingObj
6
+ include Logging
7
+ end
8
+
9
+ subject { LoggingObj.new }
10
+
11
+ let(:logger) { Logger.new(nil) }
12
+
13
+ it "does not expose its log methods" do
14
+ expect { subject.logdebug("some message") }.to raise_error NoMethodError
15
+ end
16
+
17
+ context "when logger is unset" do
18
+ before(:each) { subject.logger = nil }
19
+
20
+ it { expect { subject.send(:logdebug, "some message")}.to_not raise_error }
21
+ end
22
+
23
+ context "when logger is set" do
24
+ before(:each) { subject.logger = logger }
25
+
26
+ it "sends a message with the classname to the logger" do
27
+ logger.should_receive(:log).with(Logger::DEBUG, subject.class.to_s + ": hello world!")
28
+
29
+ subject.send(:logdebug, 'hello world!')
30
+ end
31
+ it "prints an optional argument to the logger" do
32
+ logger.should_receive(:log).with(Logger::DEBUG, subject.class.to_s + ": a message: data: 12345")
33
+
34
+ subject.send(:logdebug, 'a message', :data => 12345)
35
+ end
36
+ it "prints multiple optional arguments to the logger in sorted order" do
37
+ logger.should_receive(:log).with(Logger::DEBUG, /#{subject.class.to_s}: a message: astring: ['"]inspect this['"], data: 12345/)
38
+
39
+ subject.send(:logdebug, 'a message', :data => 12345, :astring => "inspect this")
40
+ end
41
+ end
42
+
43
+ context "when added to a class" do
44
+ class ClassToTest
45
+ class << self
46
+ include Logging
47
+ end
48
+ end
49
+
50
+ subject { ClassToTest }
51
+
52
+ before(:each) { subject.logger = logger }
53
+
54
+ it "sets component to the class name" do
55
+ logger.should_receive(:log).with(Logger::DEBUG, "#{subject.name}: a message")
56
+
57
+ subject.send(:logdebug , "a message")
58
+ end
59
+ end
60
+ context "when added to a module" do
61
+ module ModToTest
62
+ class << self
63
+ include Logging
64
+ end
65
+ end
66
+
67
+ subject { ModToTest }
68
+
69
+ before(:each) { subject.logger = logger }
70
+
71
+ it "sets component to the module name" do
72
+ logger.should_receive(:log).with(Logger::DEBUG, "#{subject.name}: a message")
73
+
74
+ subject.send(:logdebug , "a message")
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,47 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe PacketThief do
4
+ describe "setting an implementation" do
5
+ context "when no implementation has been previously set" do
6
+ before(:each) { PacketThief.implementation = nil }
7
+ after(:each) { PacketThief.implementation = nil }
8
+
9
+ it "guesses an implementation when an unknown method is called" do
10
+ @mod = Class.new
11
+ PacketThief.should_receive(:guess_implementation).and_return(@mod)
12
+ @mod.should_receive(:foo)
13
+
14
+ PacketThief.implementation.should == nil
15
+ PacketThief.foo
16
+ PacketThief.implementation.should == @mod
17
+ end
18
+
19
+ end
20
+
21
+ context "when the implementation is set to PacketThief::Impl::Netfilter" do
22
+ before(:each) { PacketThief.implementation = PacketThief::Impl::Netfilter }
23
+ after(:each) { PacketThief.implementation = nil }
24
+ it "reports that it uses the Netfilter implementation" do
25
+ PacketThief.implementation.should == PacketThief::Impl::Netfilter
26
+ end
27
+ it "forwards method calls Netfilter" do
28
+ PacketThief::Impl::Netfilter.should_receive(:foo)
29
+
30
+ PacketThief.foo
31
+ end
32
+ end
33
+
34
+ context "when the implementation is set to :netfilter" do
35
+ before(:each) { PacketThief.implementation = :netfilter }
36
+ after(:each) { PacketThief.implementation = nil }
37
+ it "reports that it uses the Netfilter implementation" do
38
+ PacketThief.implementation.should == PacketThief::Impl::Netfilter
39
+ end
40
+ it "forwards method calls Netfilter" do
41
+ PacketThief::Impl::Netfilter.should_receive(:foo)
42
+
43
+ PacketThief.foo
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,53 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+
4
+ if ENV["COVERAGE"]
5
+ require 'simplecov'
6
+ SimpleCov.start do
7
+ add_group 'Source', '/lib/'
8
+ add_group 'RSpec', '/spec/'
9
+ end
10
+ end
11
+
12
+ require 'rspec'
13
+ require 'tlspretense'
14
+
15
+ # Requires supporting files with custom matchers and macros, etc,
16
+ # in ./support/ and its subdirectories.
17
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
18
+
19
+ RSpec.configure do |config|
20
+ config.backtrace_clean_patterns = [
21
+ /\/lib\d*\/ruby\//,
22
+ /bin\//,
23
+ # /gems/,
24
+ /spec\/spec_helper\.rb/,
25
+ /lib\/rspec\/(core|expectations|matchers|mocks)/
26
+ ]
27
+
28
+ end
29
+
30
+ def with_constants(constants, &block)
31
+ saved_constants = {}
32
+ constants.each do |constant, val|
33
+ saved_constants[ constant ] = Object.const_get( constant )
34
+ # Kernel::silence_warnings { Object.const_set( constant, val ) }
35
+ old_verbose = $VERBOSE
36
+ $VERBOSE = nil
37
+ Object.const_set( constant, val )
38
+ $VERBOSE = old_verbose
39
+ end
40
+
41
+ begin
42
+ block.call
43
+ ensure
44
+ constants.each do |constant, val|
45
+ # Kernel::silence_warnings { Object.const_set( constant, saved_constants[ constant ] ) }
46
+ old_verbose = $VERBOSE
47
+ $VERBOSE = nil
48
+ Object.const_set( constant, saved_constants[ constant ] )
49
+ $VERBOSE = old_verbose
50
+ end
51
+ end
52
+ end
53
+
@@ -0,0 +1,222 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),'..','spec_helper'))
2
+
3
+ module SSLTest
4
+ describe CertificateManager do
5
+ let(:rawfoocert) do (<<-EOF).gsub(/^\s*/,'')
6
+ -----BEGIN CERTIFICATE-----
7
+ MIIDJTCCAg2gAwIBAgIEHokN5TANBgkqhkiG9w0BAQUFADAiMQswCQYDVQQGEwJV
8
+ UzETMBEGA1UEAwwKVHJ1c3RlZCBDQTAeFw0xMjEwMDUxODUxNDRaFw0xMzEwMDUx
9
+ ODUxNDRaMCIxCzAJBgNVBAYTAlVTMRMwEQYDVQQDDApUcnVzdGVkIENBMIIBIjAN
10
+ BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzRehpS5qO9LuW2dqm/Pc2YyPTOE3
11
+ LMzoZSukguefwFuZqi8KVWpn+4Tk5xACaZYnAKMQEHb3F9aC4REU3p3L6WiuEmar
12
+ xvnfxAFahEIlsmJSSiE6TaAxg3mXL3C5QiQxK/N9zjPGXW8QPlCCCs7CKQQ4RIQT
13
+ IkoOn4OvSDbpRWrPZ1H4ZBiCrAfqDQOSqzmHMTchUfhvezSWwDcFUQCfYGBdBkjz
14
+ FEcrtEG6lFjx3aVHZfZmuTKfki0fCEQCRsSd2l+/ZFJHIIphL0M2L/6VvCCDiazi
15
+ HMwxVitnsQ5JURvje7QRAXTKjArIgUl9h/IdfrIT9pbLKDNsDQMx2txfkQIDAQAB
16
+ o2MwYTAOBgNVHQ8BAf8EBAMCAgQwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
17
+ J8S9VAFA5sv9uRix79JE2chwrWkwHwYDVR0jBBgwFoAUJ8S9VAFA5sv9uRix79JE
18
+ 2chwrWkwDQYJKoZIhvcNAQEFBQADggEBADuWNwZW9//eN3bdXOBEIcvOQabsa4lF
19
+ YpniO1yjMw4EAN9bA6CgVvaRO2q3p/HgCKbOfXhGrxvqNIv8ifjQeDJts4HG6/cX
20
+ 3/luVw8KN94wLqllB2tE0bVdCoZXJ+glycZzdRLjnaPbUuuSP5StRunBAPP59dm5
21
+ lMKv5KhxJGBVHw7VHtM8rJ0KDsZmK9UCZ7Ztis2yZc5dH/uUlEtBs3HuHM7JddXD
22
+ h07Iwq9FhFsr7dszYHV4AbiA8/VObtnOU+GkAGGWD8EZZtYy035op2xGbDkmPSWU
23
+ SQDk71k6l730oJQtHh2ucrGxTWsWHk07X4lWrvxApydHRYIJElv1uqI=
24
+ -----END CERTIFICATE-----
25
+ EOF
26
+ end
27
+ let(:rawfookey) do (<<-QUOTE).gsub(/^\s*/,'')
28
+ -----BEGIN RSA PRIVATE KEY-----
29
+ MIIEpAIBAAKCAQEAzRehpS5qO9LuW2dqm/Pc2YyPTOE3LMzoZSukguefwFuZqi8K
30
+ VWpn+4Tk5xACaZYnAKMQEHb3F9aC4REU3p3L6WiuEmarxvnfxAFahEIlsmJSSiE6
31
+ TaAxg3mXL3C5QiQxK/N9zjPGXW8QPlCCCs7CKQQ4RIQTIkoOn4OvSDbpRWrPZ1H4
32
+ ZBiCrAfqDQOSqzmHMTchUfhvezSWwDcFUQCfYGBdBkjzFEcrtEG6lFjx3aVHZfZm
33
+ uTKfki0fCEQCRsSd2l+/ZFJHIIphL0M2L/6VvCCDiaziHMwxVitnsQ5JURvje7QR
34
+ AXTKjArIgUl9h/IdfrIT9pbLKDNsDQMx2txfkQIDAQABAoIBAQC49fbx4Uotaa1N
35
+ AZdDzkn+aKVT0EjSPnnXw+Q5qmqIMBQFRycqoSvlyZQmTmnej2vdRzHVp3RwKyUd
36
+ lSodGnIrrhxOvAlvCSqkuhPH81/L4KAV+qF6IF6HE8ElJ6Pr4nf2C0IKFOdwnBkq
37
+ GbEtzgmMtCGKqRIYenF1qm0J03vM/Ugn3Xvq9qIUJjLEoX32z0m1x3+QQKmG4k2U
38
+ AZK2Ngs3J3dHNmCjAOzWhJ7yeIEiPPAznP6MV9JCvv3+dAZGMZmQUbNkrXuEy+LG
39
+ tQh7C5GMSj1wrB3q7o+1V2MGdZUu8uNkxaPlCnc3MnjbCHw3WydAJHW1lgurqlv5
40
+ cwDd2BgBAoGBAPh4IdffVxlIRx2CR7++9O1D2UED+zXJjMFHok3sPhrONb/qOzaQ
41
+ ectQFxzznObz4zUEnb9TLCVhkfMyFQ3L/CabLHPa21+ucMigObk8HdZ7nPtf7Xo0
42
+ v54vISFhH7rlpBi73fOf69+bzd7ECEPOvfI639ltfJRv8LgSW6GdoaR5AoGBANNO
43
+ 8DbvicZ7+Qq6U05QJLhl4HyLziCS+Rr0Arz5KnbKxjPYoiV3Ujpzec3DAazTCRho
44
+ OCRgzNMO2dEQCp7ZEYK+HK/J6UA2DYExYHcPyfYskrxwQVo5N20oiLa6jLisk5Jf
45
+ vsq6Lbuq5PgYcykXfcX3ZnB6XAt32nC9dzcu2F3ZAoGAbYa/HGKWCU4EEyzvpcVu
46
+ P/yNkwxHOzGKO1TxZboCslw980g0K9xJ4+Z9GcUFYAUYHbHYO5NVPXEiHfrwrvFB
47
+ SF9UnAlYdHf3vWhrqYyndnls/J4Pl7QS147c4tLmYsOBr2l48ECJgDs058KwBfvn
48
+ XRS4wiZyKRijGvD0tWw/6bkCgYEAv1crjZM6XtDDokM2TCOmHJOjwyOVc0mi6BUs
49
+ pZG6MfdLoob3zJVPkD4gfYGncqdmBQPaUpaU4kkAU58C/vPwN0OPFl7vJ4XKlMHx
50
+ Z96UMqYJ+Ths9RX6ao3Zvh0Ob+tVdaXdThVodBc7XqxFG2B6M1jjGdayom/VDWGD
51
+ IiT5J4ECgYBhEHnaEepaK+Z++yMdGD4oZCtrKkY+2FiR3yK4scldzkKp+FLLBSD0
52
+ nD0rF9hlhvpzlWa8HASrHHt2IB+rhKkljNpBuHSk1pK1q2KVYLCePOIunai9O/Mo
53
+ JWJnWLSeS/Fd3rXB9jnNhiudElJRXzkof0jKSm0xnDbxWvWztBUnkA==
54
+ -----END RSA PRIVATE KEY-----
55
+ QUOTE
56
+ end
57
+ let(:rawbarcert) do (<<-EOF).gsub(/^\s*/,'')
58
+ -----BEGIN CERTIFICATE-----
59
+ MIIDLDCCAhSgAwIBAgIEKGSFPzANBgkqhkiG9w0BAQUFADAiMQswCQYDVQQGEwJV
60
+ UzETMBEGA1UEAwwKVHJ1c3RlZCBDQTAeFw0xMjEwMDUxODUyMzlaFw0xMzEwMDUx
61
+ ODUyMzlaMCkxCzAJBgNVBAYTAlVTMRowGAYDVQQDDBFJbnRlcm1lZGlhdGUgQ2Vy
62
+ dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANVqXbGIFUnjzXuOLLzD
63
+ G57ZqWvRK17hkL17cmhvbK1JgdWo7CJ20lCc/MhMbYT7ZTQ52CvGIhZlhbrf8sFV
64
+ wFtBv99ioULGltvBCL3neuyf3LvWDAU6JgNwVxL+//sv4/Whj5yrBEfFMPxjozDq
65
+ z9cOx6jQGHpn0ttQqgDIxmFPKu81DbDMtwQD8pJV+dqZ/Mlu3awWyzTKZpLJpJsH
66
+ 8mM4FO9lgdUcO433tK+7hu6VFPOzeItW047Wep6/mQnG8VzPMp1WamKSje+gbeNe
67
+ zUau4rV8ZjO92sSlCf2NOIvZSi1uJbTFkqpguEyCCWxBgBfzylWBAPOzaeXZs+5b
68
+ 090CAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgIEMA8GA1UdEwEB/wQFMAMBAf8wHQYD
69
+ VR0OBBYEFM+4kO4HcjypiiVD1TDDoG53yJlNMB8GA1UdIwQYMBaAFCfEvVQBQObL
70
+ /bkYse/SRNnIcK1pMA0GCSqGSIb3DQEBBQUAA4IBAQBprnU1g5nz8ecovTmo3vzy
71
+ 5Cq+O18l9GSX4T+6v8LEF30/AsSFe/FYM/KRbTUPLEhvZzX3oJM02e//w+drZTCR
72
+ Sv5mdQZZJTleeYwcf5QDz4o6E+sP7PorUK/YNSD4FQMRnV6aGTDDkeemNKncvNE6
73
+ cPP9mPdR7l1bf88QUy+L6wSWXY77qC7n/dL/PsddypvL5QVZL7G98sds7tU7y82s
74
+ i8j7nF9FFjmbE4+2aVjNTQVgUkn0irCZO50LiYU55jHPCOlsg9K8VBH7fZKghMSe
75
+ soLkjxuB/8Vg27ESlXvnp4sU7a4QcaULXJL1kpdfZxl62VoJU9oWBpy57/ZHPA6U
76
+ -----END CERTIFICATE-----
77
+ EOF
78
+ end
79
+ let(:rawbarkey) do (<<-QUOTE).gsub(/^\s*/,'')
80
+ -----BEGIN RSA PRIVATE KEY-----
81
+ MIIEowIBAAKCAQEA1WpdsYgVSePNe44svMMbntmpa9ErXuGQvXtyaG9srUmB1ajs
82
+ InbSUJz8yExthPtlNDnYK8YiFmWFut/ywVXAW0G/32KhQsaW28EIved67J/cu9YM
83
+ BTomA3BXEv7/+y/j9aGPnKsER8Uw/GOjMOrP1w7HqNAYemfS21CqAMjGYU8q7zUN
84
+ sMy3BAPyklX52pn8yW7drBbLNMpmksmkmwfyYzgU72WB1Rw7jfe0r7uG7pUU87N4
85
+ i1bTjtZ6nr+ZCcbxXM8ynVZqYpKN76Bt417NRq7itXxmM73axKUJ/Y04i9lKLW4l
86
+ tMWSqmC4TIIJbEGAF/PKVYEA87Np5dmz7lvT3QIDAQABAoIBAQCUyD+jeeSli6wA
87
+ XEDyI+9IkiQb50oeLpESmFJNXojcUieyxb5B1KaQzrEoDqg3km+etkjvU4UGKibN
88
+ /jyl7ltZA4B5grA79mjLsUqf4hX/iv9+8B2XM0+3DAWYV7Ar9Nour0CIj20/f8jD
89
+ 2860Vq8pFcO5+8Fk7KbCgPzT6STsRtf+2ehgY7gRNkR/o3337qMYumhcdID5orm3
90
+ OCfbX1zSJdzcZmkvtczGUncpf8Bbj/ygFZ+FVX9+Sjt8/RcZ1df8IEKNs1Z98GrO
91
+ WtcZsecZjuZYAATZ2e0K9ykAUEyXJZu3gMWiMd4PH66yT3DNWdIGbkBbfdPVHSgc
92
+ FfuECb/hAoGBAO9b36GG7Z7Ce0BmWBXSpm8xGobSOk4a6H+altAgajEJJH/Gqv97
93
+ 0aOOHJD/gQe60Pom2kLZDI+raIpCMLefH6Zf6nKmJPAHsZbhOvYyikmVNrZI9oTd
94
+ Qz8I85L9TZZCW7SFbyHhNslHGqOrcv9EEEz0Sy+yZDI8nZyw6L8vG5fFAoGBAORA
95
+ wAl5eWJ96T0vbS/zX5eG/Csbv7bftnWdEJsYPFxyybYalbXYoKNIjJ1nm3K3fMPV
96
+ hrqOsBo8c/mFeWz+7yjGh+n2B0ephj25Svk5zbDlfoRMQh9unNxU+HCCipZOHhvJ
97
+ x7S7tUos0ZT6uAGQIb0bzTAYfaZOUva5cssVEnU5AoGABtZI/QQtpWtIuf4yZe0u
98
+ c96jM1at860xFvQDes5yOhRYxo2WNNYElvdoOXwS43WiooKZmW85vKDYy5o4agZR
99
+ kR8MQ1obk/+kQvsMBBxNduycM3jCEemAEjzfOEOkA7bBh9aH5h/YwMcXK7WqA0Ce
100
+ dpRD0Yj287hniCJFg7CEyUECgYAgOfgjHlCCFG7q4ZhT7dOwTDGsUHWn9zwGrQ9c
101
+ JnbXQqmyGVzL2PMNOsAHtUogT0HBUJN+IYlBmwlw0GSNfAz+P9GOudrbRlcavd+V
102
+ ApFFCZHsUewADhj9js2o7PVuNUdQ+xNENEBrYZqRozh5mAT7c0JsKPkMkwBpr1NC
103
+ 0w3RGQKBgF3VDeZQjCSagMGaS+j1mg0vtwM8H9FJKdKnI0HFb0ffeNiAStb9AATZ
104
+ TTEbmX6Sm9s/SzIgBVgSpVlkmEc0BRuHv+40+UCWd3As6mHxEV8udbtTAJmhcm1W
105
+ Gq8Xuh8WelT7Z5Cqks9mMWnnmJ0ye8RlvmM3Cn09oeVRN8IOCTrX
106
+ -----END RSA PRIVATE KEY-----
107
+ QUOTE
108
+ end
109
+ let(:rawbazcert) do (<<-EOF).gsub(/^\s*/,'')
110
+ -----BEGIN CERTIFICATE-----
111
+ MIIDWTCCAkGgAwIBAgIEBZwKfDANBgkqhkiG9w0BAQUFADAiMQswCQYDVQQGEwJV
112
+ UzETMBEGA1UEAwwKVHJ1c3RlZCBDQTAeFw0xMjEwMDUxODUyNDJaFw0xMzEwMDUx
113
+ ODUyNDJaMD0xCzAJBgNVBAYTAlVTMS4wLAYDVQQDDCVJbnRlcm1lZGlhdGUgd2l0
114
+ aCBubyBiYXNpY0NvbnN0cmFpbnRzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
115
+ CgKCAQEAtqFVxhTBS+MvZFu/KdSB2w2GoF6fahsGkP7B8j3cIARmNJrGovjTWxnR
116
+ YuM7dhXyIf+XsHyV9KSu+LZ/sSUnGL/2jx7mxqk2aFNpSY6idQR/ihlyEYgIGr7+
117
+ VShsmLAJ7dH3z5NxLCabQf5814xWngeqh1P0W6VpJNKgx5ml84JiOswQl9oodpvg
118
+ neSCSqgbLE8iH0j0gofPAfceWVJQAVT3bEw6+qM3REx36Jqee3OYYwSUHPxGqcZb
119
+ VhHI2ZYZ4g09GwqiCC/30aTs0JuhNihPsv0C+e7pmXXcEurMYxwAOK8ugyRjQoP2
120
+ pBnNbV7hJiM+QryG+gmtvWkQgT2jlQIDAQABo3wwejALBgNVHQ8EBAMCBaAwHQYD
121
+ VR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB8GA1UdIwQYMBaAFCfEvVQBQObL
122
+ /bkYse/SRNnIcK1pMB0GA1UdDgQWBBR4hKt1JMRlRTO59Wr39RgN+yeIMDAMBgNV
123
+ HRMBAf8EAjAAMA0GCSqGSIb3DQEBBQUAA4IBAQB/SDwRip410niqqPYFizQuwcpJ
124
+ v/bWFuejycAIFjl+0T6m6B4VqiN5/KkWL+hdJUaK1lbVqI8eByEYP4vg/pyH23u4
125
+ bvKtAiJLPrqhgqlHoYll0xh4r3o8VkH1yiiK/LYIKNxIMKkRwe6/5RzG9b7kSRt1
126
+ XPMu2112cFIo/jrJ7gk/bGivQ42cDpHs7GZ3U1vvnltKIKkcHAYSnqVd0JWllDCg
127
+ S4pcOJjSUr2YLjy8+qWqIC5XKj1RsZwW3BZKy8tCRnD+gDxfoPq37suDTWF1yncA
128
+ MWHZuq3LeG3jD/5WlLKQjaxtV3an09iwAcG6ByLlDnutORP1+nY9Pn46uDjM
129
+ -----END CERTIFICATE-----
130
+ EOF
131
+ end
132
+ let(:rawbazkey) do (<<-QUOTE).gsub(/^\s*/,'')
133
+ -----BEGIN RSA PRIVATE KEY-----
134
+ MIIEogIBAAKCAQEAtqFVxhTBS+MvZFu/KdSB2w2GoF6fahsGkP7B8j3cIARmNJrG
135
+ ovjTWxnRYuM7dhXyIf+XsHyV9KSu+LZ/sSUnGL/2jx7mxqk2aFNpSY6idQR/ihly
136
+ EYgIGr7+VShsmLAJ7dH3z5NxLCabQf5814xWngeqh1P0W6VpJNKgx5ml84JiOswQ
137
+ l9oodpvgneSCSqgbLE8iH0j0gofPAfceWVJQAVT3bEw6+qM3REx36Jqee3OYYwSU
138
+ HPxGqcZbVhHI2ZYZ4g09GwqiCC/30aTs0JuhNihPsv0C+e7pmXXcEurMYxwAOK8u
139
+ gyRjQoP2pBnNbV7hJiM+QryG+gmtvWkQgT2jlQIDAQABAoIBADTOtcSO382XpW55
140
+ cO8heWLjqFfaxHGj2uQ2JdJrvKitXPg9AM7C8CpZbsgPOHROqDLYev4XKC0TKVzV
141
+ OFr6iTGI4DxGDSjIaOkFpV4VljgL0u0VqnwTP3SsYVIyXCRSUqynl+Y3lfPUPfR5
142
+ J5QUCj+rq81xoyiUzbBODxtn/CpKvhdLcYwKnn5T0lz1qb1qoSXNjtUc0r11a9wq
143
+ Nxj2xNZGsxpphicz7wYsUguDivxl5jpnXuHgIAgggQ3aDj3bC66YrKbQ99Uq5ToD
144
+ OrUSyZsiQsqXtZdwPGqrOFQlkggmjS0gNE1aqqR0dLJVemo1vhhrMhqIo5M6bbBc
145
+ VkRV6YkCgYEA3GEgUkkMdxW27L6KxujUojkHOqqO37ybf6dQTredBKeKwIQ4OwCJ
146
+ 2L4pL91lVL9b1Dznq5tLVts0SSSuM6mLTKDjXyvlSsy8X94X0qsxbCPzx36uF6lK
147
+ d4Gyd1D/OmzLWqnQSgEdNqXFohFMtL0l7UzBnfhzg+QiRFBaWlzGJ+8CgYEA1CY4
148
+ cbeo8McumHxF/8BU6QtKb25NFzN0KwUVRcR7lehYeaCNQExQrEgcvXD3HJ1cYnkX
149
+ kXaZmBMVCmgj8/g7TmFyH925Xb3p9MZKAWuPx+P6eGn8uf2k2lhJzAfYaWJaoCik
150
+ IpoyS7jvmLQO+/+8Vte3PZhpnzM4DLAd8QGxCLsCgYB5y8QNNgoJlpquZPBV1kAO
151
+ F+6C4dhsltRpzJJ5rsi81cu9clWRZk7I1u/0YCuslsWtmqt/ECinLCbNddRBASbX
152
+ huOiqaPjnxtM8HXCHJMH7SbBzqVwtkNNoQR9JOqp447P4KIZBFyc4ylC1MTL7u2T
153
+ JKStJa7R6bd2geItprBtSQKBgFHS8ABEQv+jA0DC5civqNA9j5cM5uTk7pBNJJhF
154
+ IRl/hOhcWT6McK0SHyud72F0/BXq+IEdSj5SVdIuunc1rcIcaYUK4pzaS+shs5d6
155
+ ofkJ4CgjUNt3jea9GLF98SUsTyHoqu3BpVZ5XMf74q+lQkIIb19tcod5nMuf/dxf
156
+ t6VTAoGAOxmC70VKaymxS9WF34EIsQKOI4IA/gcVgXlT1p5ULxAjQ+Z//9MmlUsR
157
+ nbK5OUOFN52d9Q9d1bAWrIXPOok1T+dUEePQdXlyoxnct1xtfNOqhrdGp07nGDg3
158
+ qx4mU2NiPm1793+rb9uJ38h4dGApaJ91z3QB7eDYvTBBJFWqSYQ=
159
+ -----END RSA PRIVATE KEY-----
160
+ QUOTE
161
+ end
162
+
163
+ before(:each) do
164
+ File.stub(:read).with('certs/foocert.pem').and_return(rawfoocert)
165
+ File.stub(:read).with('certs/barcert.pem').and_return(rawbarcert)
166
+ File.stub(:read).with('certs/bazcert.pem').and_return(rawbazcert)
167
+ File.stub(:read).with('certs/fookey.pem').and_return(rawfookey)
168
+ File.stub(:read).with('certs/barkey.pem').and_return(rawbarkey)
169
+ File.stub(:read).with('certs/bazkey.pem').and_return(rawbazkey)
170
+ end
171
+
172
+ describe "#get_chain" do
173
+
174
+ it "attempts to load the certificates from disk" do
175
+ File.should_receive(:read).with('certs/foocert.pem').and_return(rawfoocert)
176
+ File.should_receive(:read).with('certs/barcert.pem').and_return(rawbarcert)
177
+ File.should_receive(:read).with('certs/bazcert.pem').and_return(rawbazcert)
178
+
179
+ CertificateManager.new({}).get_chain(['foo', 'bar', 'baz'])
180
+ end
181
+
182
+ it "returns a list of X509 certs that correspond to the aliases given to it" do
183
+ certlist = CertificateManager.new({}).get_chain(['foo', 'bar', 'baz'])
184
+
185
+ certlist.length.should == 3
186
+ certlist.each { |cert| cert.should be_kind_of OpenSSL::X509::Certificate }
187
+ # this might conceivably fail of the PEM data is output at a different width.
188
+ certlist[0].to_pem.should == rawfoocert
189
+ certlist[1].to_pem.should == rawbarcert
190
+ certlist[2].to_pem.should == rawbazcert
191
+ end
192
+ end
193
+
194
+ describe "#get_keychain" do
195
+ it "attempts to load the keys from disk" do
196
+ File.should_receive(:read).with('certs/fookey.pem').and_return(rawfookey)
197
+ File.should_receive(:read).with('certs/barkey.pem').and_return(rawbarkey)
198
+ File.should_receive(:read).with('certs/bazkey.pem').and_return(rawbazkey)
199
+
200
+ CertificateManager.new({}).get_keychain(['foo', 'bar', 'baz'])
201
+ end
202
+
203
+ it "returns a list of keys that correspond to the certificates." do
204
+ certchain = CertificateManager.new({}).get_chain(['foo', 'bar', 'baz'])
205
+
206
+ keychain = CertificateManager.new({}).get_keychain(['foo', 'bar', 'baz'])
207
+
208
+ keychain.length.should == 3
209
+ keychain.each { |key| key.should be_kind_of OpenSSL::PKey::PKey }
210
+
211
+ pairs = certchain.zip keychain
212
+ pairs.each do |pair|
213
+ cert, key = pair
214
+ cert.public_key.to_pem.should == key.public_key.to_pem
215
+ end
216
+ end
217
+
218
+ end
219
+
220
+ end
221
+ end
222
+
@@ -0,0 +1,76 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),'..','spec_helper'))
2
+
3
+ module SSLTest
4
+ describe Config do
5
+ let(:foo_test) do
6
+ {
7
+ 'alias' => 'foo',
8
+ 'name' => 'test foo',
9
+ 'certchain' => [ 'a', 'b' ]
10
+ }
11
+ end
12
+ let(:bar_test) do
13
+ {
14
+ 'alias' => 'bar',
15
+ 'name' => 'test bar',
16
+ 'certchain' => [ 'c', 'd' ]
17
+ }
18
+ end
19
+ let(:conf_tests) { [ foo_test, bar_test ] }
20
+ let(:pt_data) do
21
+ {
22
+ 'dest_port' => 1234,
23
+ 'protocol' => 'tcp',
24
+ 'in_interface' => 'foo'
25
+ }
26
+ end
27
+ let(:conf_data) do
28
+ {
29
+ 'packetthief' => pt_data,
30
+ 'certs' => {},
31
+ 'tests' => conf_tests
32
+ }
33
+ end
34
+
35
+ let(:opts) do
36
+ {
37
+ :config => 'foo.yml',
38
+ }
39
+ end
40
+
41
+ before(:each) { YAML.stub(:load_file).and_return(conf_data) }
42
+
43
+ subject { Config.new(opts) }
44
+
45
+ describe "#initialize" do
46
+ it "loads yaml data from the specified file" do
47
+ YAML.should_receive(:load_file).with('foo.yml').and_return(conf_data)
48
+
49
+ subject
50
+ end
51
+
52
+ it "exposes the raw config through #raw" do
53
+ YAML.stub(:load_file).and_return(conf_data)
54
+
55
+ subject.raw.should == conf_data
56
+ end
57
+ # TODO: some basic schema validation on the config file?
58
+ end
59
+
60
+ describe "#packetthief" do
61
+ context "when a conf_data['packetthief']'s keys are strings" do
62
+ it "adds symbol versions" do
63
+ @pt = subject.packetthief
64
+ @pt.each_key do |k|
65
+ if k.kind_of? String
66
+ @pt.should have_key k.to_sym
67
+ @pt[k.to_sym].should == @pt[k]
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ end
75
+ end
76
+