watobo 0.9.9.pre3 → 0.9.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. data/.yardopts +24 -0
  2. data/CHANGELOG +17 -7
  3. data/README +4 -60
  4. data/bin/nfq_server.rb +191 -0
  5. data/config/interceptor.yml +2 -6
  6. data/lib/watobo/adapters/data_store.rb +1 -1
  7. data/lib/watobo/adapters/file/file_store.rb +50 -33
  8. data/lib/watobo/ca.rb +22 -0
  9. data/lib/watobo/config.rb +6 -0
  10. data/lib/watobo/core/ca.rb +411 -0
  11. data/lib/watobo/core/cert_store.rb +56 -0
  12. data/lib/watobo/core/forwarding_proxy.rb +38 -0
  13. data/lib/watobo/core/http_socket.rb +18 -0
  14. data/lib/watobo/core/intercept_carver.rb +179 -0
  15. data/lib/watobo/core/intercept_filter.rb +257 -0
  16. data/lib/watobo/core/interceptor.rb +342 -79
  17. data/lib/watobo/core/netfilter_queue.rb +191 -0
  18. data/lib/watobo/core/project.rb +84 -138
  19. data/lib/watobo/core/proxy.rb +61 -0
  20. data/lib/watobo/core/request.rb +40 -0
  21. data/lib/watobo/core/response.rb +30 -0
  22. data/lib/watobo/core/scanner.rb +64 -58
  23. data/lib/watobo/core/session.rb +70 -77
  24. data/lib/watobo/core.rb +1 -1
  25. data/lib/watobo/framework/create_project.rb +25 -10
  26. data/lib/watobo/framework/init.rb +13 -0
  27. data/lib/watobo/gui/browser_preview.rb +5 -4
  28. data/lib/watobo/gui/checks_policy_frame.rb +1 -0
  29. data/lib/watobo/gui/client_cert_dialog.rb +11 -6
  30. data/lib/watobo/gui/conversation_table.rb +7 -4
  31. data/lib/watobo/gui/fuzzer_gui.rb +9 -11
  32. data/lib/watobo/gui/intercept_filter_dialog.rb +210 -0
  33. data/lib/watobo/gui/interceptor_gui.rb +59 -21
  34. data/lib/watobo/gui/interceptor_settings_dialog.rb +39 -5
  35. data/lib/watobo/gui/list_box.rb +2 -1
  36. data/lib/watobo/gui/log_viewer.rb +79 -5
  37. data/lib/watobo/gui/main_window.rb +159 -113
  38. data/lib/watobo/gui/manual_request_editor.rb +11 -5
  39. data/lib/watobo/gui/mixins/subscriber.rb +47 -0
  40. data/lib/watobo/gui/project_wizzard.rb +3 -3
  41. data/lib/watobo/gui/proxy_dialog.rb +17 -18
  42. data/lib/watobo/gui/request_editor.rb +1 -1
  43. data/lib/watobo/gui/rewrite_filters_dialog.rb +416 -0
  44. data/lib/watobo/gui/rewrite_rules_dialog.rb +394 -0
  45. data/lib/watobo/gui/scanner_settings_dialog.rb +9 -6
  46. data/lib/watobo/gui/session_management_dialog.rb +33 -23
  47. data/lib/watobo/gui/sites_tree.rb +5 -6
  48. data/lib/watobo/gui/status_bar.rb +101 -49
  49. data/lib/watobo/gui/table_editor.rb +1 -1
  50. data/lib/watobo/gui/templates/plugin2.rb +23 -27
  51. data/lib/watobo/gui/utils/save_default_settings.rb +9 -9
  52. data/lib/watobo/gui/utils/save_proxy_settings.rb +25 -9
  53. data/lib/watobo/gui/utils/save_scanner_settings.rb +10 -7
  54. data/lib/watobo/gui/utils/session_history.rb +1 -1
  55. data/lib/watobo/gui/www_auth_dialog.rb +25 -21
  56. data/lib/watobo/gui.rb +3 -1
  57. data/lib/watobo/mixins/httpparser.rb +47 -40
  58. data/lib/watobo/mixins/request_parser.rb +126 -41
  59. data/lib/watobo/mixins/shapers.rb +124 -15
  60. data/lib/watobo/utils/hexprint.rb +31 -0
  61. data/lib/watobo/utils/load_chat.rb +2 -0
  62. data/lib/watobo/utils/response_builder.rb +111 -0
  63. data/lib/watobo.rb +4 -1
  64. data/modules/active/discovery/http_methods.rb +6 -4
  65. data/modules/active/fileinclusion/lfi_simple.rb +3 -3
  66. data/modules/active/sqlinjection/sqli_timing.rb +6 -6
  67. data/modules/passive/redirectionz.rb +5 -6
  68. data/plugins/catalog/catalog.rb +240 -56
  69. data/plugins/catalog/db_tests +1 -6483
  70. data/plugins/catalog/db_variables +2 -29
  71. data/plugins/crawler/gui/auth_frame.rb +15 -3
  72. data/plugins/crawler/gui/crawler_gui.rb +24 -0
  73. data/plugins/crawler/gui/hooks_frame.rb +7 -2
  74. data/plugins/crawler/gui/settings_tabbook.rb +4 -0
  75. data/plugins/crawler/gui.rb +3 -3
  76. data/plugins/crawler/lib/engine.rb +1 -1
  77. data/plugins/filefinder/filefinder.rb +21 -17
  78. data/plugins/sqlmap/bin/test.rb +100 -0
  79. data/plugins/sqlmap/gui/main.rb +227 -0
  80. data/plugins/sqlmap/gui/options_frame.rb +119 -0
  81. data/plugins/sqlmap/gui.rb +27 -0
  82. data/plugins/sqlmap/icons/sqlmap.ico +0 -0
  83. data/plugins/sqlmap/lib/sqlmap_ctrl.rb +116 -0
  84. data/plugins/sqlmap/sqlmap.rb +26 -0
  85. data/plugins/sslchecker/gui/gui.rb +45 -30
  86. metadata +32 -9
  87. data/certificates/cert.pem +0 -19
  88. data/certificates/privkey.pem +0 -15
  89. data/certificates/watobo_dh.key +0 -5
  90. data/lib/watobo/core/simple_ca.rb +0 -393
@@ -20,27 +20,124 @@
20
20
  # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
21
  # .
22
22
  module Watobo
23
- INTERCEPT_NONE = 0x00
24
- INTERCEPT_REQUEST = 0x01
25
- INTERCEPT_RESPONSE = 0x02
26
- INTERCEPT_BOTH = 0x03
23
+ module Interceptor
24
+ INTERCEPT_NONE = 0x00
25
+ INTERCEPT_REQUEST = 0x01
26
+ INTERCEPT_RESPONSE = 0x02
27
+ INTERCEPT_BOTH = 0x03
28
+
29
+ REWRITE_NONE = 0x00
30
+ REWRITE_REQUEST = 0x01
31
+ REWRITE_RESPONSE = 0x02
32
+ REWRITE_BOTH = 0x04
33
+
34
+ INTERCEPT_DEFAULT_PORT = 8081
35
+
36
+ MODE_REGULAR = 0x01
37
+ MODE_TRANSPARENT = 0x02
38
+
39
+ @proxy_mode ||= MODE_REGULAR
40
+ @intercept_mode ||= INTERCEPT_NONE
41
+ @rewrite_mode ||= REWRITE_NONE
42
+
43
+ @proxy = nil
44
+ #@proxy_mode = Watobo::Conf::Interceptor.proxy_mode if Watobo::Conf::Interceptor.respond_to? :proxy_mode
45
+ def self.proxy_mode
46
+ @proxy_mode
47
+ end
48
+
49
+ def self.proxy_mode=(mode)
50
+ @proxy_mode = mode
51
+ end
52
+
53
+ def self.rewrite_mode
54
+ @rewrite_mode
55
+ end
56
+
57
+ def self.rewrite_mode=(mode)
58
+ @rewrite_mode = mode
59
+ end
60
+
61
+ def self.intercept_mode
62
+ @intercept_mode
63
+ end
64
+
65
+ def self.intercept_mode=(mode)
66
+ @intercept_mode = mode
67
+ end
68
+
69
+ def self.transparent?
70
+ return true if ( @proxy_mode & MODE_TRANSPARENT ) > 0
71
+ return false
72
+ end
73
+
74
+ def self.intercept_requests?
75
+ return true if ( @intercept_mode & INTERCEPT_REQUEST ) > 0
76
+ return false
77
+ end
78
+
79
+ def self.intercept_responses?
80
+ return true if ( @intercept_mode & INTERCEPT_RESPONSE ) > 0
81
+ return false
82
+ end
83
+
84
+ def self.rewrite_requests?
85
+ return true if ( @rewrite_mode & REWRITE_REQUEST ) > 0
86
+ return false
87
+ end
88
+
89
+ def self.rewrite_responses?
90
+ return true if ( @rewrite_mode & REWRITE_RESPONSE ) > 0
91
+ return false
92
+ end
93
+
94
+ def self.active?
95
+ return false if @proxy.nil?
96
+ return true
97
+ end
98
+
99
+ def self.start
100
+ @proxy = Watobo::InterceptProxy.new()
101
+
102
+ @proxy.subscribe(:new_interception) { |chat|
103
+ Thread.new(chat) { |c|
104
+ Watobo.project.addChat(c) unless Watobo.project.nil?
105
+ }
106
+ }
107
+
108
+ @proxy.start()
109
+ puts "DEBUG: Proxy running" if $DEBUG
110
+ # puts "* set www_auth for interceptor"
111
+ # puts YAML.dump(@project.settings[:www_auth])
112
+ #@proxy.www_auth = Watobo.project.settings[:www_auth] unless Watobo.project.nil?
113
+ end
114
+
115
+ def self.proxy
116
+ @proxy
117
+ end
118
+
119
+ def self.stop
120
+ @proxy.stop
121
+ @proxy = nil
122
+ end
123
+
124
+ end
27
125
 
28
- INTERCEPT_DEFAULT_PORT = 8081
29
126
  # I N T E R C E P T P R O X Y
30
127
  #
31
128
  class InterceptProxy
32
129
 
33
130
  include Watobo::Constants
34
- # include Watobo::Conf::Interceptor
131
+ # include Watobo::Interceptor
35
132
 
36
133
  attr :port
37
134
 
38
- attr_accessor :mode
135
+ attr_accessor :proxy_mode
39
136
 
40
137
  attr_accessor :contentLength
41
138
  attr_accessor :contentTypes
42
139
  attr_accessor :target
43
- attr_accessor :www_auth
140
+ attr :www_auth
44
141
  attr_accessor :client_certificates
45
142
  def server
46
143
  @bind_addr
@@ -68,7 +165,16 @@ module Watobo
68
165
 
69
166
  def setRequestFilter(new_settings)
70
167
  @request_filter_settings.update new_settings unless new_settings.nil?
71
- puts @request_filter_settings.to_yaml
168
+ # puts @request_filter_settings.to_yaml
169
+ end
170
+
171
+ def clear_request_carvers
172
+ @request_carvers.clear unless @request_carvers.nil?
173
+
174
+ end
175
+
176
+ def clear_response_carvers
177
+ @response_carvers.clear unless @response_carvers.nil?
72
178
  end
73
179
 
74
180
  # def getRequestFilter
@@ -88,9 +194,11 @@ module Watobo
88
194
  def stop()
89
195
  begin
90
196
  puts "[#{self.class}] stop"
91
- puts @t_server.status
197
+ if @t_server.respond_to? :status
198
+ puts @t_server.status
92
199
  @t_server.kill
93
200
  @intercept_srv.close
201
+ end
94
202
  rescue IOError => bang
95
203
  puts bang
96
204
  puts bang.backtrace if $DEBUG
@@ -101,16 +209,16 @@ module Watobo
101
209
  # R U N
102
210
  #
103
211
 
104
- def run(settings={})
105
- begin
106
- # @server = '127.0.0.1'
107
- # @port = settings[:port] if settings[:port]
108
- # @server = settings[:server] if settings[:server]
109
- # @contentLength = settings[:content_length] if settings[:content_length]
110
- # @contentTypes = settings[:content_types] if settings[:content_types]
212
+ def start()
213
+
214
+ if transparent?
215
+ DRb.start_service
216
+ @connections = DRbObject.new nil, "druby://127.0.0.1:666"
217
+ end
111
218
 
219
+ begin
112
220
  @intercept_srv = TCPServer.new(@bind_addr, @port)
113
- @intercept_srv.setsockopt( Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1)
221
+ @intercept_srv.setsockopt( Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1 )
114
222
 
115
223
  rescue => bang
116
224
  puts "\n!!!Could not start InterceptProxy"
@@ -119,28 +227,32 @@ module Watobo
119
227
  end
120
228
  puts "\n* Intercepor started on #{@bind_addr}:#{@port}"
121
229
  session_list = []
230
+ puts "!!! TRANSPARENT MODE ENABLED !!!" if transparent?
122
231
 
123
232
  @t_server = Thread.new(@intercept_srv) { |server|
124
233
  while (new_session = server.accept)
125
234
  # new_session.sync = true
126
235
  Thread.new(new_session) { |session|
236
+ flags = []
127
237
  begin
238
+
128
239
  request, c_sock = read_request(session)
129
240
 
130
241
  if request.nil? or request.empty? then
131
242
  # puts "! empty request ? :("
132
- c_sock.close
243
+ closeSocket(c_sock)
133
244
  Thread.current.exit
134
245
  #return
135
246
  end
136
247
  puts "*[I] #{request.url}"
137
248
 
138
249
  rescue => bang
139
- # puts "!!! Error reading client request "
140
- # puts bang
250
+ puts "!!! Error reading client request "
251
+ puts bang
141
252
  # puts bang.backtrace
142
253
  # puts request
143
254
  # puts request
255
+ closeSocket(c_sock)
144
256
  Thread.current.exit
145
257
  #break
146
258
  end
@@ -160,17 +272,24 @@ module Watobo
160
272
  closeSocket(c_sock)
161
273
  end
162
274
  end
163
- next
275
+ #next
276
+ Thread.current.exit
164
277
  end
278
+
165
279
  request_intercepted = false
166
280
  # no preview, check if interception request is turned on
167
- if @target and @mode & INTERCEPT_REQUEST > 0 then
168
-
281
+ if Watobo::Interceptor.rewrite_requests? then
282
+ Interceptor::RequestCarver.shape(request, flags)
283
+ puts "FLAGS >>"
284
+ puts flags
285
+ end
286
+
287
+ if @target and Watobo::Interceptor.intercept_requests? then
169
288
  if matchRequestFilter(request)
170
289
  @awaiting_requests += 1
171
290
  request_intercepted = true
172
291
 
173
- if @target.respond_to? :modifyRequest
292
+ if @target.respond_to? :addRequest
174
293
  # puts "*INTERCEPT REQUEST"
175
294
  # puts @target
176
295
  #notify(:modify_request, request, Thread.current)
@@ -190,12 +309,14 @@ module Watobo
190
309
  #p "getHTTPHeader"
191
310
  #s_sock, req, resp = @sender.getHTTPHeader(request, :update_sids => true, :update_session => false, :update_contentlength => true)
192
311
  begin
312
+
193
313
  s_sock, req, resp = @sender.sendHTTPRequest(request, :update_sids => true, :update_session => false, :update_contentlength => true, :www_auth => @www_auth, :client_certificates => @client_certificates)
194
314
  if s_sock.nil? then
195
315
  c_sock.print resp.join unless resp.nil?
196
316
  closeSocket(c_sock)
197
317
  next
198
318
  end
319
+
199
320
  rescue => bang
200
321
  puts bang
201
322
  puts bang.backtrace if $DEBUG
@@ -245,7 +366,10 @@ module Watobo
245
366
 
246
367
  end
247
368
  else
369
+ # don't try to read body if request method is HEAD
370
+ unless req.method =~ /^head/i
248
371
  @sender.readHTTPBody(s_sock, resp, req, :update_sids => true)
372
+ end
249
373
  end
250
374
  rescue => bang
251
375
  puts "!!! could not send request !!!"
@@ -255,7 +379,17 @@ module Watobo
255
379
  end
256
380
 
257
381
  begin
258
- if @target and @mode & INTERCEPT_RESPONSE > 0 then
382
+ Watobo::Response.create resp
383
+ # puts "* unchunk response ..."
384
+ resp.unchunk
385
+ # puts "* unzip response ..."
386
+ resp.unzip
387
+
388
+ if Watobo::Interceptor.rewrite_responses? then
389
+ Interceptor::ResponseCarver.shape(resp, flags)
390
+ end
391
+
392
+ if @target and Watobo::Interceptor.intercept_responses? then
259
393
  if matchResponseFilter(resp)
260
394
  # if resp.content_type =~ /text/ or resp.content_type =~ /application\/javascript/ then
261
395
  if @target.respond_to? :modifyResponse
@@ -267,8 +401,12 @@ module Watobo
267
401
  end
268
402
  end
269
403
 
404
+ # puts ">> SEND TO CLIENT"
270
405
  c_sock.write resp.join
271
- closeSocket(c_sock)
406
+ # puts resp.join
407
+ # puts "-----"
408
+ # closeSocket(c_sock)
409
+
272
410
  rescue Errno::ECONNRESET
273
411
  print "x"
274
412
  # puts "!!! ERROR (Reset): reading body"
@@ -285,8 +423,12 @@ module Watobo
285
423
  #return
286
424
  end
287
425
  #if req then # when req == nil an error occured -> no chat necessary
288
- chat = Chat.new(request, resp, :source => CHAT_SOURCE_INTERCEPT)
426
+
427
+ rc = YAML.load(YAML.dump(request))
428
+ sc = YAML.load(YAML.dump(resp))
429
+ chat = Chat.new(rc, sc, :source => CHAT_SOURCE_INTERCEPT)
289
430
  notify(:new_interception, chat)
431
+ closeSocket(c_sock)
290
432
  # end
291
433
  #else
292
434
  # puts "* got no response"
@@ -295,6 +437,10 @@ module Watobo
295
437
  end
296
438
  }
297
439
  end
440
+
441
+ def refresh_www_auth
442
+ @www_auth = Watobo::Conf::Scanner.www_auth
443
+ end
298
444
 
299
445
  def initialize(settings=nil)
300
446
  @event_dispatcher_listeners = Hash.new
@@ -307,22 +453,11 @@ module Watobo
307
453
  # @port = @settings[:intercept_port]
308
454
  # puts settings.to_yaml
309
455
 
310
- @mode = INTERCEPT_NONE
311
- @www_auth = {}
312
- @client_certificates = {}
313
- @target = nil
314
- @sender = Watobo::Session.new(@target)
456
+ # @proxy_mode = Watobo::Interceptor.proxy_mode
315
457
 
316
- @bind_addr = Watobo::Conf::Interceptor.server
317
- puts "> Server: #{@bind_addr}"
318
- @port = Watobo::Conf::Interceptor.port
319
- puts "> Port: #{@port}"
458
+ #Watobo::Interceptor.proxy_mode = INTERCEPT_NONE
320
459
 
321
- pt = Watobo::Conf::Interceptor.pass_through
322
- @contentLength = pt[:content_length]
323
- puts "> PT-ContentLength: #{@contentLength}"
324
- @contentTypes = pt[:content_types]
325
- puts "> PT-ContentTypes: #{@contentTypes}"
460
+ init_instance_vars
326
461
 
327
462
  @awaiting_requests = 0
328
463
  @awaiting_responses = 0
@@ -358,28 +493,20 @@ module Watobo
358
493
  # p @settings[:certificate_path]
359
494
  # p @settings[:cert_file]
360
495
  # p @settings[:key_file]
361
- crt_path = Watobo::Conf::Interceptor.certificate_path
362
- crt_file = Watobo::Conf::Interceptor.cert_file
363
- key_file = Watobo::Conf::Interceptor.key_file
364
- dh_key_file = Watobo::Conf::Interceptor.dh_key_file
365
-
366
- crt_filename = File.join(Watobo.base_directory, crt_path, crt_file)
367
- key_filename = File.join(Watobo.base_directory, crt_path, key_file)
368
- dh_filename = File.join(Watobo.base_directory, crt_path, dh_key_file)
369
- unless File.exist? dh_filename
370
- #puts "* no dh key file found"
371
- File.open(dh_filename,"w") do |fh|
372
- puts "* creating SSL key (DH 1024) ... "
373
- fh.write OpenSSL::PKey::DH.new(1024).to_pem
374
- print " DONE\r\n"
375
- end
376
- end
496
+ # crt_path = Watobo::Conf::Interceptor.certificate_path
497
+ # crt_file = Watobo::Conf::Interceptor.cert_file
498
+ # key_file = Watobo::Conf::Interceptor.key_file
499
+ # dh_key_file = Watobo::Conf::Interceptor.dh_key_file
500
+
501
+ # crt_filename = File.join(Watobo.base_directory, crt_path, crt_file)
502
+ # key_filename = File.join(Watobo.base_directory, crt_path, key_file)
377
503
 
378
504
  # @ctx = OpenSSL::SSL::SSLContext.new('SSLv23_server')
379
- @cert = OpenSSL::X509::Certificate.new(File.read(crt_filename))
380
- @key = OpenSSL::PKey::RSA.new(File.read(key_filename))
505
+ # @cert = OpenSSL::X509::Certificate.new(File.read(crt_filename))
506
+ # @key = OpenSSL::PKey::RSA.new(File.read(key_filename))
381
507
 
382
- @dh_key = OpenSSL::PKey::DH.new(File.read(dh_filename))
508
+ #@dh_key = OpenSSL::PKey::DH.new(File.read(dh_filename))
509
+ @dh_key = Watobo::CA.dh_key
383
510
  # @ctx.ciphers = nil # ['TLSv1/SSLv3', 56, 56 ]
384
511
 
385
512
  rescue => bang
@@ -391,6 +518,57 @@ module Watobo
391
518
  end
392
519
 
393
520
  private
521
+
522
+ def init_instance_vars
523
+ @www_auth = Watobo::Conf::Scanner.www_auth
524
+ @fake_certs = {}
525
+ @client_certificates = {}
526
+ @target = nil
527
+ @sender = Watobo::Session.new(@target)
528
+
529
+ @bind_addr = Watobo::Conf::Interceptor.bind_addr
530
+ puts "> Server: #{@bind_addr}"
531
+ @port = Watobo::Conf::Interceptor.port
532
+ puts "> Port: #{@port}"
533
+ @proxy_mode = Watobo::Conf::Interceptor.proxy_mode
534
+
535
+ pt = Watobo::Conf::Interceptor.pass_through
536
+ @contentLength = pt[:content_length]
537
+ puts "> PT-ContentLength: #{@contentLength}"
538
+ @contentTypes = pt[:content_types]
539
+ puts "> PT-ContentTypes: #{@contentTypes}"
540
+ end
541
+
542
+ def get_ssl_cert_cn(host,port)
543
+ cn = ""
544
+ begin
545
+ tcp_socket = TCPSocket.new( host, port )
546
+ tcp_socket.setsockopt( Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1)
547
+ tcp_socket.sync = true
548
+ ctx = OpenSSL::SSL::SSLContext.new()
549
+
550
+ ctx.tmp_dh_callback = proc { |*args|
551
+ OpenSSL::PKey::DH.new(128)
552
+ }
553
+
554
+ socket = OpenSSL::SSL::SSLSocket.new(tcp_socket, ctx)
555
+
556
+ socket.connect
557
+ cert = socket.peer_cert
558
+
559
+ if cert.subject.to_s =~ /cn=([^\/]*)/i
560
+ cn = $1
561
+ end
562
+ puts "Peer-Cert CN: #{cn}"
563
+ socket.io.shutdown(2)
564
+ rescue => bang
565
+ puts bang
566
+ cn = host
567
+ ensure
568
+ socket.close if socket.respond_to? :close
569
+ end
570
+ cn
571
+ end
394
572
 
395
573
  #
396
574
  #
@@ -531,14 +709,15 @@ module Watobo
531
709
  #print "~]"
532
710
  return if buf.nil?
533
711
  rescue Errno::ECONNRESET
534
- puts "!!! ERROR (Reset): reading body"
535
- puts "* last data seen on socket: #{buf}"
712
+ # puts "!!! ERROR (Reset): reading body"
713
+ # puts "* last data seen on socket: #{buf}"
714
+ print "R"
536
715
  return if buf.nil?
537
716
  rescue Timeout::Error
538
- puts "!!! ERROR (Timeout): reading body"
539
- puts "* last data seen on socket:"
540
- #client.write buf if buf
541
- print "!~]"
717
+ #puts "!!! ERROR (Timeout): reading body"
718
+ #puts "* last data seen on socket:"
719
+ #client.write buf if buf
720
+ print "T"
542
721
  return if buf.nil?
543
722
  rescue => bang
544
723
  puts "!!! could not read body !!!"
@@ -583,16 +762,76 @@ module Watobo
583
762
  end
584
763
  end
585
764
 
765
+ def transparent?
766
+ return true if ( @proxy_mode & Watobo::Interceptor::MODE_TRANSPARENT ) > 0
767
+ return false
768
+ end
769
+
586
770
  def read_request(socket)
587
771
  request = []
588
772
  # read http header lines
589
773
  session = socket
590
- # puts "* read header ..."
591
- Watobo::HTTP.read_header(socket) do |line|
592
- # puts line
774
+
775
+ ra = socket.remote_address
776
+ cport = ra.ip_port
777
+ caddr = ra.ip_address
778
+
779
+ if transparent?
780
+
781
+ ci = @connections.info({ 'host' => caddr, 'port' => cport } )
782
+ unless ci['target'].empty? or ci['cn'].empty?
783
+ puts "SSL-REQUEST FROM #{caddr}:#{cport}"
784
+
785
+ ctx = Watobo::CertStore.acquire_ssl_ctx ci['target'], ci['cn']
786
+
787
+ begin
788
+ ssl_socket = OpenSSL::SSL::SSLSocket.new(socket, ctx)
789
+ ssl_socket.setsockopt( Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1)
790
+ # ssl_socket.sync_close = true
791
+ ssl_socket.sync = true
792
+ # puts ssl_socket.methods.sort
793
+ session = ssl_socket.accept
794
+ rescue OpenSSL::SSL::SSLError => e
795
+ puts ">> SSLError"
796
+ puts e
797
+ return nil, session
798
+ rescue => bang
799
+ puts bang
800
+ puts bang.backtrace
801
+ return nil, session
802
+ end
803
+ else
804
+ puts ci['host']
805
+ puts ci['cn']
806
+ end
807
+ end
808
+
809
+ Watobo::HTTP.read_header(session) do |line|
810
+ # puts line
593
811
  request.push line
594
812
  end
595
813
 
814
+ if transparent?
815
+ #puts "> get hostname ..."
816
+ thn = nil
817
+ request.each do |l|
818
+ if l =~ /^Host: (.*)/
819
+ thn = $1.strip
820
+ # puts ">> #{thn}"
821
+ end
822
+ end
823
+ # puts session.class
824
+ # puts "* fix request line ..."
825
+ # puts request.first
826
+ # puts ">>"
827
+ if session.is_a? OpenSSL::SSL::SSLSocket
828
+ request.first.gsub!(/(^[^[:space:]]{1,}) (.*) (HTTP.*)/i,"\\1 https://#{thn}\\2 \\3")
829
+ else
830
+ request.first.gsub!(/(^[^[:space:]]{1,}) (.*) (HTTP.*)/i,"\\1 http://#{thn}\\2 \\3")
831
+ end
832
+ #puts request.first
833
+ end
834
+
596
835
  if request.first =~ /^CONNECT (.*):(\d{1,5}) HTTP\/1\./ then
597
836
  target = $1
598
837
  tport = $2
@@ -606,13 +845,31 @@ module Watobo
606
845
  bscount = 0 # bad handshake counter
607
846
  # puts "* wait for ssl handshake ..."
608
847
  begin
609
-
848
+ dst = "#{target}:#{tport}"
849
+ unless @fake_certs.has_key? dst
850
+ puts "NEW CERTIFICATE FOR >> #{dst} <<"
851
+ cn = get_ssl_cert_cn(target, tport)
852
+ puts "CN=#{cn}"
853
+
854
+ cert = {
855
+ :hostname => cn,
856
+ :type => 'server',
857
+ :user => 'watobo',
858
+ :email => 'a.schmidt@siberas.de',
859
+ }
860
+ cert_file, key_file = Watobo::CA.create_cert cert
861
+ @fake_certs[dst] = {
862
+ :cert => OpenSSL::X509::Certificate.new(File.read(cert_file)),
863
+ :key => OpenSSL::PKey::RSA.new(File.read(key_file))
864
+ }
865
+ end
610
866
  ctx = OpenSSL::SSL::SSLContext.new()
611
867
 
612
- ctx.cert = @cert
868
+ #ctx.cert = @cert
869
+ ctx.cert = @fake_certs[dst][:cert]
613
870
  # @ctx.key = OpenSSL::PKey::DSA.new(File.read(key_file))
614
- ctx.key = @key
615
-
871
+ #ctx.key = @key
872
+ ctx.key = @fake_certs[dst][:key]
616
873
  ctx.tmp_dh_callback = proc { |*args|
617
874
  @dh_key
618
875
  }
@@ -622,7 +879,7 @@ module Watobo
622
879
 
623
880
  ssl_socket = OpenSSL::SSL::SSLSocket.new(socket, ctx)
624
881
  ssl_socket.setsockopt( Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1)
625
- #ssl_socket.sync_close = true
882
+ # ssl_socket.sync_close = true
626
883
  ssl_socket.sync = true
627
884
  # puts ssl_socket.methods.sort
628
885
 
@@ -652,9 +909,10 @@ module Watobo
652
909
  request.first.gsub!(/(^[^[:space:]]{1,})( )(\/.*)/, "\\1 https://#{target}:#{tport}\\3")
653
910
  end
654
911
  #puts request
655
- request.extend Watobo::Mixin::Parser::Url
656
- request.extend Watobo::Mixin::Parser::Web10
657
- request.extend Watobo::Mixin::Shaper::Web10
912
+ # request.extend Watobo::Mixin::Parser::Url
913
+ # request.extend Watobo::Mixin::Parser::Web10
914
+ # request.extend Watobo::Mixin::Shaper::Web10
915
+ Watobo::Request.create request
658
916
 
659
917
  clen = request.content_length
660
918
  if clen > 0 then
@@ -673,6 +931,8 @@ module Watobo
673
931
  begin
674
932
  reason = nil
675
933
  clen = response.content_length
934
+ # no pass-through necessary if request method is HEAD
935
+ return false if request.method =~ /^head/i
676
936
 
677
937
  if matchContentType?(response.content_type) then
678
938
  # first forward headers
@@ -718,17 +978,20 @@ module Watobo
718
978
 
719
979
  def closeSocket(socket)
720
980
  #puts socket.class
981
+ return false if socket.nil?
721
982
  begin
722
983
  #if socket.class.to_s =~ /SSLSocket/
723
984
  if socket.is_a? OpenSSL::SSL::SSLSocket
724
985
  socket.io.shutdown(2)
986
+ #socket.sysclose
725
987
  else
726
988
  socket.shutdown(2)
727
989
  end
728
- socket.close
990
+ socket.close if socket.respond_to? :close
729
991
  rescue => bang
730
992
  puts bang
731
993
  puts bang.backtrace if $DEBUG
994
+
732
995
  end
733
996
  end
734
997