watobo 0.9.9.pre3 → 0.9.9

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 (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