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,3 @@
1
+ module TLSPretense
2
+ VERSION = '0.6.1'
3
+ end
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $: << 'lib'
4
+
5
+ require 'rubygems'
6
+ require 'eventmachine'
7
+ require 'packetthief' # needs root
8
+
9
+
10
+ # Note that this does not forward the encrypted traffic at all, so it isn't a
11
+ # full proxy. It just demonstrates that we can terminate the SSL connection
12
+ # that we have redirected.
13
+ #
14
+ # Also, you will need to supply your own certificate chain and private key file.
15
+ #
16
+ # A single connection:
17
+ # Connected
18
+ # starting TLS
19
+ # Connection closed
20
+ #
21
+ # A second connection, where the client accepts the certificate:
22
+ # Connected
23
+ # starting TLS
24
+ # SSL handshake completed
25
+ # Received data
26
+ module SSLTester
27
+ def initialize(chainfile, keyfile)
28
+ puts "Connected"
29
+ @chainfile = chainfile
30
+ @keyfile = keyfile
31
+ end
32
+
33
+ def connection_completed
34
+ puts "Connection completed."
35
+ end
36
+
37
+ def post_init
38
+ puts "starting TLS"
39
+ start_tls(:private_key_file => @keyfile, :cert_chain_file => @chainfile, :verify_peer => false)
40
+ end
41
+
42
+ def ssl_handshake_completed
43
+ puts "SSL handshake completed"
44
+ end
45
+
46
+ def receive_data(data)
47
+ puts "Received data"
48
+ end
49
+
50
+ def unbind
51
+ puts "Connection closed"
52
+ end
53
+ end
54
+
55
+
56
+ PacketThief.redirect(:to_ports => 54321).where(:protocol => :tcp, :dest_port => 443).run
57
+ EM.run {
58
+ EM.start_server('', 54321, SSLTester, 'chain.pem', 'key.pem')
59
+
60
+ Signal.trap("TERM") do
61
+ puts "Received SIGTERM"
62
+ PacketThief.revert
63
+ exit
64
+ end
65
+
66
+ Signal.trap("INT") do
67
+ puts "Received SIGINT"
68
+ PacketThief.revert
69
+ exit
70
+ end
71
+
72
+ }
73
+ PacketThief.revert
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $: << 'lib'
4
+
5
+ require 'rubygems'
6
+ require 'eventmachine'
7
+ require 'packetthief' # needs root
8
+
9
+ PacketThief.redirect(:to_ports => 54321).where(:protocol => :tcp, :dest_port => 80, :in_interface => 'en1').run
10
+
11
+ at_exit { puts "Exiting"; PacketThief.revert }
12
+
13
+ Signal.trap("TERM") do
14
+ puts "Received SIGTERM"
15
+ exit
16
+ end
17
+
18
+ Signal.trap("INT") do
19
+ puts "Received SIGINT"
20
+ exit
21
+ end
22
+
23
+
24
+ EM.run do
25
+
26
+ EM.start_server('', 54321, PacketThief::Handlers::ProxyRedirector, 'localhost', 8080)
27
+
28
+ end
29
+ PacketThief.revert
@@ -0,0 +1,24 @@
1
+ #!/bin/sh
2
+ # Sample script for setting up iptables/netfilter for use with PacketThief. It
3
+ # creates a NAT on the external interface, and it manually configures the
4
+ # internal interface. A more advanced setup with a DHCP server could make it
5
+ # easier by auto-configuring clients.
6
+ external=eth0
7
+ internal=eth1
8
+
9
+ iptables --flush
10
+ iptables --table nat --flush
11
+ iptables --delete-chain
12
+ iptables --table nat --delete-chain
13
+
14
+
15
+ echo "Manually setup the internal network's nic"
16
+ ifconfig $internal 192.168.0.1 netmask 255.255.255.0
17
+
18
+ echo "enabling packet forwarding"
19
+ echo 1 > /proc/sys/net/ipv4/ip_forward
20
+
21
+ echo "applying basic iptables rules for NATing"
22
+ iptables -t nat -A POSTROUTING -o $external -j MASQUERADE
23
+
24
+ echo "Done! PacketThief will create and destroy the rules for redirecting traffic."
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ # This example just shows how to call the SSLServer class with PacketThief. All
3
+ # it does is receive data -- it does not attempt to send data on.
4
+ #
5
+ # TODO: Make the dest configurable
6
+ # TODO: Pull input form stdin
7
+
8
+ $: << 'lib'
9
+
10
+ require 'rubygems'
11
+ require 'eventmachine'
12
+ require 'packetthief' # needs root
13
+
14
+
15
+ EM.run do
16
+
17
+ PacketThief::Handlers::SSLClient.connect('www.isecpartners.com', 443) do |h|
18
+ h.ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE
19
+ # h.ctx.ssl_version = :TLSv1_client
20
+
21
+ def h.tls_successful_handshake
22
+ puts @sslsocket.peer_cert_chain.inspect
23
+ close_connection
24
+ end
25
+ end
26
+
27
+ end
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env ruby
2
+ # This example just shows how to call the SSLServer class with PacketThief. All
3
+ # it does is receive data -- it does not attempt to send data on.
4
+
5
+ $: << 'lib'
6
+
7
+ require 'rubygems'
8
+ require 'eventmachine'
9
+ require 'packetthief' # needs root
10
+
11
+ if ARGV.length != 2
12
+ puts "script chain.pem key.pem"
13
+ exit 1
14
+ end
15
+
16
+ chain = PacketThief::Util.cert_chain(File.read(ARGV[0]))
17
+ puts "Certificate chain:"
18
+ p chain
19
+ cert = chain.shift
20
+ key = OpenSSL::PKey.read(File.read(ARGV[1]))
21
+
22
+ PacketThief.redirect(:to_ports => 54321).where(:protocol => :tcp, :dest_port => 443, :in_interface => 'en1').run
23
+ at_exit { puts "Exiting"; PacketThief.revert }
24
+ Signal.trap("TERM") do
25
+ puts "Received SIGTERM"
26
+ exit
27
+ end
28
+ Signal.trap("INT") do
29
+ puts "Received SIGINT"
30
+ exit
31
+ end
32
+
33
+ EM.run do
34
+
35
+ PacketThief::Handlers::SSLServer.start('', 54321) do |h|
36
+ puts "extra block"
37
+ h.ctx.cert = cert
38
+ h.ctx.extra_chain_cert = chain
39
+ h.ctx.key = key
40
+ end
41
+
42
+
43
+ end
44
+ PacketThief.revert
@@ -0,0 +1,115 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $: << 'lib'
4
+
5
+ require 'rubygems'
6
+ require 'eventmachine'
7
+ require 'packetthief' # needs root
8
+
9
+ class VerboseProxy < PacketThief::Handlers::SSLSmartProxy
10
+
11
+ def client_desc
12
+ "Client #{client_host}:#{client_port}->#{dest_host}:#{dest_port} (#{dest_hostname})"
13
+ end
14
+
15
+ def dest_desc
16
+ "Dest #{dest_host}:#{dest_port}(#{dest_hostname})->#{client_host}:#{client_port}"
17
+ end
18
+
19
+ def servername_cb(sslsock, hostname)
20
+ puts "#{client_desc} request hostname: #{hostname}"
21
+ super(sslsock, hostname)
22
+ end
23
+
24
+ def client_connected
25
+ puts "#{client_desc} connected and TLS handshake succeeded"
26
+ super
27
+ end
28
+
29
+ def client_handshake_failed(e)
30
+ puts "TLS handshake from #{client_desc} failed: #{e}"
31
+ end
32
+
33
+ def client_recv(data)
34
+ puts "#{client_desc} says (#{data.length}): #{data.inspect}"
35
+ # @seenclientdata ||= false
36
+ # unless @seenclientdata
37
+ # puts "#{client_desc} says (#{data.length}): #{data.split("\r\n\r\n",2)[0]}"
38
+ # puts ""
39
+ # @seenclientdata = true
40
+ # else
41
+ # puts "#{client_desc} says (#{data.length}): #{data[0,20].inspect}"
42
+ # end
43
+ super(data)
44
+ end
45
+
46
+ def client_closed
47
+ puts "#{client_desc} closed"
48
+ end
49
+
50
+ def dest_connected
51
+ puts "#{dest_desc} connected"
52
+ puts "Remote certificates: #{dest_cert_chain.inspect}"
53
+ end
54
+
55
+ def dest_handshake_failed(e)
56
+ puts "TLS handshake to #{dest_desc} handshake failed: #{e}"
57
+ end
58
+
59
+ def dest_recv(data)
60
+ puts "#{dest_desc} says (#{data.length}): #{data.inspect}"
61
+ # @seendestdata ||= false
62
+ # unless @seendestdata
63
+ # puts "#{dest_desc} says (#{data.length}): #{data.split("\r\n\r\n",2)[0]}"
64
+ # puts ""
65
+ # @seendestdata = true
66
+ # else
67
+ # puts "#{dest_desc} says (#{data.length}): #{data[0,20].inspect}"
68
+ # end
69
+ super(data)
70
+ end
71
+
72
+ def dest_closed
73
+ puts "#{dest_desc} closed"
74
+ end
75
+
76
+ end
77
+
78
+ if ARGV.length != 2
79
+ puts "script cacert.pem key.pem"
80
+ exit 1
81
+ end
82
+ cacert = OpenSSL::X509::Certificate.new(File.read(ARGV[0]))
83
+ key = OpenSSL::PKey.read(File.read(ARGV[1]))
84
+
85
+
86
+ PacketThief.redirect(:to_ports => 54321).where(:protocol => :tcp, :dest_port => 443, :in_interface => 'en1').run
87
+ #PacketThief.redirect(:to_ports => 54321).where(:protocol => :tcp, :dest_port => 443, :in_interface => 'vmnet1').run
88
+ #PacketThief.redirect(:to_ports => 54321).where(:protocol => :tcp, :dest_port => 443, :in_interface => 'vmnet8').run
89
+ #PacketThief.redirect(:to_ports => 54322).where(:protocol => :tcp, :dest_port => 80, :in_interface => 'en1').run
90
+
91
+ at_exit { puts "Exiting"; PacketThief.revert }
92
+
93
+ Signal.trap("TERM") do
94
+ puts "Received SIGTERM"
95
+ exit
96
+ end
97
+
98
+ Signal.trap("INT") do
99
+ puts "Received SIGINT"
100
+ exit
101
+ end
102
+
103
+ EM.run do
104
+
105
+ VerboseProxy.start('', 54321, cacert, key) do |h|
106
+ # h.ctx.ssl_version = :TLSv1_server
107
+ end
108
+ EM.start_server('', 54322, PacketThief::Handlers::TransparentProxy) do |h|
109
+ def h.client_recv(data)
110
+ puts "HTTP: #{data}"
111
+ end
112
+ end
113
+
114
+ end
115
+ PacketThief.revert
@@ -0,0 +1,97 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $: << 'lib'
4
+
5
+ require 'rubygems'
6
+ require 'eventmachine'
7
+ require 'packetthief' # needs root
8
+
9
+ class VerboseProxy < PacketThief::Handlers::SSLTransparentProxy
10
+
11
+ def client_desc
12
+ "Client #{client_host}:#{client_port}->#{dest_host}:#{dest_port} (#{dest_hostname})"
13
+ end
14
+
15
+ def dest_desc
16
+ "Dest #{dest_host}:#{dest_port}(#{dest_hostname})->#{client_host}:#{client_port}"
17
+ end
18
+
19
+ def servername_cb(sslsock, hostname)
20
+ puts "#{client_desc} request hostname: #{hostname}"
21
+ super(sslsock, hostname)
22
+ end
23
+
24
+ def client_connected
25
+ puts "#{client_desc} connected and TLS handshake succeeded"
26
+ super
27
+ end
28
+
29
+ def client_handshake_failed(e)
30
+ puts "TLS handshake from #{client_desc} failed: #{e}"
31
+ end
32
+
33
+ def client_recv(data)
34
+ puts "#{client_desc} says: #{data[0,20].inspect}"
35
+ super(data)
36
+ end
37
+
38
+ def client_closed
39
+ puts "#{client_desc} closing"
40
+ end
41
+
42
+ def dest_connected
43
+ puts "#{dest_desc} connected"
44
+ puts "Remote certificates: #{dest_cert_chain.inspect}"
45
+ end
46
+
47
+ def dest_handshake_failed(e)
48
+ puts "TLS handshake to #{dest_desc} handshake failed: #{e}"
49
+ end
50
+
51
+ def dest_recv(data)
52
+ puts "#{dest_desc} says: #{data[0,20].inspect}"
53
+ super(data)
54
+ end
55
+
56
+ def dest_closed
57
+ puts "#{dest_desc} closing"
58
+ end
59
+
60
+ end
61
+
62
+
63
+ if ARGV.length != 2
64
+ puts "script chain.pem key.pem"
65
+ exit 1
66
+ end
67
+
68
+ chain = PacketThief::Util.cert_chain(File.read(ARGV[0]))
69
+ puts "Certificate chain:"
70
+ p chain
71
+ cert = chain.shift
72
+ key = OpenSSL::PKey.read(File.read(ARGV[1]))
73
+
74
+
75
+ #PacketThief.redirect(:to_ports => 54321).where(:protocol => :tcp, :dest_port => 80, :in_interface => 'en1').run
76
+ PacketThief.redirect(:to_ports => 54321).where(:protocol => :tcp, :dest_port => 443, :in_interface => 'en1').run
77
+ at_exit { puts "Exiting"; PacketThief.revert }
78
+ Signal.trap("TERM") do
79
+ puts "Received SIGTERM"
80
+ exit
81
+ end
82
+ Signal.trap("INT") do
83
+ puts "Received SIGINT"
84
+ exit
85
+ end
86
+
87
+ EM.run do
88
+
89
+ VerboseProxy.start('', 54321) do |h|
90
+ h.ctx.cert = cert
91
+ h.ctx.extra_chain_cert = chain
92
+ h.ctx.key = key
93
+ # h.ctx.ssl_version = :TLSv1_server
94
+ end
95
+
96
+ end
97
+ PacketThief.revert
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $: << 'lib'
4
+
5
+ require 'rubygems'
6
+ require 'eventmachine'
7
+ require 'packetthief' # needs root
8
+
9
+ PacketThief.redirect(:to_ports => 54321).where(:protocol => :tcp, :dest_port => 80, :in_interface => 'en1').run
10
+ PacketThief.redirect(:to_ports => 54321).where(:protocol => :tcp, :dest_port => 443, :in_interface => 'en1').run
11
+
12
+ at_exit { puts "Exiting"; PacketThief.revert }
13
+
14
+ Signal.trap("TERM") do
15
+ puts "Received SIGTERM"
16
+ exit
17
+ end
18
+
19
+ Signal.trap("INT") do
20
+ puts "Received SIGINT"
21
+ exit
22
+ end
23
+
24
+ class VerboseProxy < PacketThief::Handlers::TransparentProxy
25
+
26
+ def client_connected
27
+ puts "Client #{client_host}:#{client_port}->#{dest_host}:#{dest_port} connected"
28
+ connect_to_dest
29
+ end
30
+
31
+ def client_recv(data)
32
+ puts "Client #{client_host}:#{client_port}->#{dest_host}:#{dest_port} says: #{data[0,20].inspect}"
33
+ send_to_dest data
34
+ end
35
+
36
+ def dest_recv(data)
37
+ puts "Dest #{client_host}:#{client_port}->#{dest_host}:#{dest_port} says: #{data[0,20].inspect}"
38
+ send_to_client data
39
+ end
40
+
41
+ def client_closed
42
+ puts "Client #{client_host}:#{client_port}->#{dest_host}:#{dest_port} closing"
43
+ end
44
+
45
+ def dest_closed
46
+ puts "Dest #{client_host}:#{client_port}->#{dest_host}:#{dest_port} closing"
47
+ end
48
+
49
+ end
50
+
51
+ EM.run do
52
+
53
+ EM.start_server('', 54321, VerboseProxy)
54
+
55
+ end
56
+ PacketThief.revert