tlspretense 0.6.1

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