ipaccess 0.0.4 → 1.2.0

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 (88) hide show
  1. checksums.yaml +15 -0
  2. checksums.yaml.gz.sig +1 -0
  3. data.tar.gz.sig +0 -0
  4. data/.gemtest +0 -0
  5. data/.rspec +1 -0
  6. data/.yardopts +12 -0
  7. data/ChangeLog +1495 -0
  8. data/{docs/LGPL-LICENSE → LGPL-LICENSE} +0 -0
  9. data/Manifest.txt +76 -0
  10. data/README.md +96 -0
  11. data/Rakefile +65 -42
  12. data/docs/COPYING +41 -45
  13. data/docs/FAQ +12 -0
  14. data/docs/HISTORY +17 -0
  15. data/docs/LEGAL +1 -1
  16. data/docs/LGPL +166 -0
  17. data/docs/TODO +150 -7
  18. data/docs/images/ipaccess.png +0 -0
  19. data/docs/images/ipaccess_ac_for_args.png +0 -0
  20. data/docs/images/ipaccess_ac_for_socket.png +0 -0
  21. data/docs/images/ipaccess_logo.png +0 -0
  22. data/docs/images/ipaccess_relations.png +0 -0
  23. data/docs/images/ipaccess_setup_origin.png +0 -0
  24. data/docs/images/ipaccess_setup_origin_tab.png +0 -0
  25. data/docs/images/ipaccess_view.png +0 -0
  26. data/docs/rdoc.css +22 -0
  27. data/examples/ftp.rb +62 -0
  28. data/examples/http.rb +81 -0
  29. data/examples/imap.rb +37 -0
  30. data/examples/pop.rb +31 -0
  31. data/examples/smtp.rb +26 -0
  32. data/examples/tcp_server.rb +32 -0
  33. data/examples/tcp_socket.rb +7 -3
  34. data/examples/telnet.rb +32 -0
  35. data/examples/text_message.rb +45 -0
  36. data/lib/ipaccess.rb +557 -7
  37. data/lib/ipaccess/arm_sockets.rb +7 -4
  38. data/lib/ipaccess/ghost_doc/ghost_doc.rb +23 -0
  39. data/lib/ipaccess/ghost_doc/ghost_doc_acl.rb +54 -0
  40. data/lib/ipaccess/ghost_doc/ghost_doc_net_ftp.rb +213 -0
  41. data/lib/ipaccess/ghost_doc/ghost_doc_net_http.rb +272 -0
  42. data/lib/ipaccess/ghost_doc/ghost_doc_net_smtp.rb +186 -0
  43. data/lib/ipaccess/ghost_doc/ghost_doc_net_telnet.rb +227 -0
  44. data/lib/ipaccess/ghost_doc/ghost_doc_p_blacklist.rb +36 -0
  45. data/lib/ipaccess/ghost_doc/ghost_doc_p_blacklist_e.rb +7 -0
  46. data/lib/ipaccess/ghost_doc/ghost_doc_p_unblacklist.rb +36 -0
  47. data/lib/ipaccess/ghost_doc/ghost_doc_p_unblacklist_e.rb +7 -0
  48. data/lib/ipaccess/ghost_doc/ghost_doc_p_unwhitelist.rb +36 -0
  49. data/lib/ipaccess/ghost_doc/ghost_doc_p_unwhitelist_e.rb +7 -0
  50. data/lib/ipaccess/ghost_doc/ghost_doc_p_whitelist.rb +36 -0
  51. data/lib/ipaccess/ghost_doc/ghost_doc_p_whitelist_e.rb +7 -0
  52. data/lib/ipaccess/ghost_doc/ghost_doc_patched_usage.rb +64 -0
  53. data/lib/ipaccess/ghost_doc/ghost_doc_sockets.rb +571 -0
  54. data/lib/ipaccess/ip_access_check.rb +508 -0
  55. data/lib/ipaccess/ip_access_errors.rb +186 -40
  56. data/lib/ipaccess/ip_access_list.rb +955 -1122
  57. data/lib/ipaccess/ip_access_set.rb +212 -0
  58. data/lib/ipaccess/net/ftp.rb +39 -0
  59. data/lib/ipaccess/net/http.rb +39 -0
  60. data/lib/ipaccess/net/https.rb +30 -0
  61. data/lib/ipaccess/net/imap.rb +39 -0
  62. data/lib/ipaccess/net/pop.rb +46 -0
  63. data/lib/ipaccess/net/smtp.rb +39 -0
  64. data/lib/ipaccess/net/telnet.rb +38 -0
  65. data/lib/ipaccess/patches/generic.rb +807 -0
  66. data/lib/ipaccess/patches/net_ftp.rb +165 -0
  67. data/lib/ipaccess/patches/net_http.rb +175 -0
  68. data/lib/ipaccess/patches/net_https.rb +29 -0
  69. data/lib/ipaccess/patches/net_imap.rb +117 -0
  70. data/lib/ipaccess/patches/net_pop.rb +171 -0
  71. data/lib/ipaccess/patches/net_smtp.rb +130 -0
  72. data/lib/ipaccess/patches/net_telnet.rb +103 -0
  73. data/lib/ipaccess/{netaddr_patch.rb → patches/netaddr.rb} +20 -11
  74. data/lib/ipaccess/patches/sockets.rb +586 -0
  75. data/lib/ipaccess/socket.rb +52 -1
  76. data/lib/ipaccess/sockets.rb +4 -30
  77. data/spec/ip_access_list_spec.rb +33 -21
  78. data/spec/spec.opts +2 -2
  79. metadata +289 -63
  80. metadata.gz.sig +0 -0
  81. data/docs/DOWNLOAD +0 -17
  82. data/docs/README +0 -95
  83. data/docs/WELCOME +0 -8
  84. data/lib/ipaccess/ghost_doc.rb +0 -206
  85. data/lib/ipaccess/ghost_doc_acl.rb +0 -31
  86. data/lib/ipaccess/ip_access.rb +0 -456
  87. data/lib/ipaccess/ip_access_patches.rb +0 -431
  88. data/spec/core_spec.rb +0 -5
@@ -0,0 +1,586 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Author:: Paweł Wilk (mailto:pw@gnu.org)
4
+ # Copyright:: Copyright (c) 2009-2014 by Paweł Wilk
5
+ # License:: This program is licensed under the terms of {GNU Lesser General Public License}[link:docs/LGPL.html] or {Ruby License}[link:docs/COPYING.html].
6
+ #
7
+ # Modules contained in this file are meant for
8
+ # patching Ruby socket classes in order to add
9
+ # IP access control to them. It is also used
10
+ # to create variants of socket handling classes
11
+ # with IP access control.
12
+ #
13
+ #--
14
+ #
15
+ # Copyright (C) 2009 by Paweł Wilk. All Rights Reserved.
16
+ #
17
+ # This program is free software; you can redistribute it and/or modify
18
+ # it under the terms of either: 1) the GNU Lesser General Public License
19
+ # as published by the Free Software Foundation; either version 3 of the
20
+ # License, or (at your option) any later version; or 2) Ruby's License.
21
+ #
22
+ # See the file COPYING for complete licensing information.
23
+ #
24
+ #++
25
+ #
26
+
27
+ require 'socket'
28
+ require 'ipaccess/ip_access_errors'
29
+ require 'ipaccess/patches/generic'
30
+
31
+ # :stopdoc:
32
+
33
+ # This modules contain patches for Ruby socket
34
+ # classes in order to enable IP access control
35
+ # for them.
36
+ #
37
+ # This module patches socket handling classes
38
+ # to use IP access control. Each patched socket
39
+ # class has acl member, which is an IPAccess::Set object.
40
+
41
+ module IPAccess::Patches
42
+
43
+ ###################################################################
44
+ # Socket class with IP access control.
45
+ # It uses input and output access lists.
46
+ # Default access list for management operations is output.
47
+
48
+ module Socket
49
+
50
+ include IPAccess::Patches::ACL
51
+
52
+ def self.included(base)
53
+
54
+ marker = (base.name =~ /IPAccess/) ? base.superclass : base
55
+ return if marker.instance_variable_defined?(:@uses_ipaccess)
56
+ base.instance_variable_set(:@uses_ipaccess, true)
57
+
58
+ base.class_eval do
59
+
60
+ orig_initialize = self.instance_method :initialize
61
+ orig_accept = self.instance_method :accept
62
+ orig_accept_nonblock = self.instance_method :accept_nonblock
63
+ orig_connect = self.instance_method :connect
64
+ orig_recvfrom = self.instance_method :recvfrom
65
+ orig_recvfrom_nonblock = self.instance_method :recvfrom_nonblock
66
+ orig_sysaccept = self.instance_method :sysaccept
67
+
68
+ define_method :__ipacall__initialize do |block, *args|
69
+ @opened_on_deny = false
70
+ args.delete_if { |x| @opened_on_deny = true if (x.is_a?(Symbol) && x == :opened_on_deny) }
71
+ args.pop if args.last.nil?
72
+ self.acl = valid_acl?(args.last) ? args.pop : :global
73
+ @useables = IPAccess::ObjectsReferences
74
+ orig_initialize.bind(self).call(*args, &block)
75
+ return self
76
+ end
77
+
78
+ # block passing wrapper for Ruby 1.8
79
+ def initialize(*args, &block)
80
+ __ipacall__initialize(block, *args)
81
+ end
82
+
83
+ # accept on steroids.
84
+ define_method :accept do |*args|
85
+ ret = orig_accept.bind(self).call(*args)
86
+ real_acl.input.check_socket(ret.first, ret.first) { try_terminate_subsocket(ret.first) }
87
+ return ret
88
+ end
89
+
90
+ # accept_nonblock on steroids.
91
+ define_method :accept_nonblock do |*args|
92
+ ret = orig_accept_nonblock.bind(self).call(*args)
93
+ real_acl.input.check_socket(ret.first, ret.first) { try_terminate_subsocket(ret.first) }
94
+ return ret
95
+ end
96
+
97
+ # sysaccept on steroids.
98
+ define_method :sysaccept do |*args|
99
+ ret = orig_accept.bind(self).call(*args)
100
+ real_acl.input.check_sockaddr(ret.last, ret.last) { try_terminate_subsocket(::Socket.for_fd(ret.first)) }
101
+ return ret
102
+ end
103
+
104
+ # connect on steroids.
105
+ define_method :connect do |*args|
106
+ unless @opened_on_deny
107
+ real_acl.output.check_sockaddr(args.first)
108
+ return orig_connect.bind(self).call(*args)
109
+ else
110
+ ret = orig_connect.bind(self).call(*args)
111
+ real_acl.output.check_socket(ret, self)
112
+ end
113
+ return ret
114
+ end
115
+
116
+ # this hook will be called each time @acl is reassigned
117
+ define_method :acl_recheck do
118
+ return nil if self.closed?
119
+ real_acl.output.check_socket(self, self) { try_terminate }
120
+ return nil
121
+ end
122
+
123
+ # recvfrom on steroids.
124
+ define_method :recvfrom do |*args|
125
+ ret = orig_recvfrom.bind(self).call(*args)
126
+ peer_ip = ret[1][3]
127
+ family = ret[1][0]
128
+ if (family == "AF_INET" || family == "AF_INET6")
129
+ real_acl.input.check_ipstring(peer_ip, self) { try_terminate }
130
+ end
131
+ return ret
132
+ end
133
+
134
+ # recvfrom_nonblock on steroids.
135
+ define_method :recvfrom_nonblock do |*args|
136
+ ret = orig_recvfrom_nonblock.bind(self).call(*args)
137
+ peer_ip = ret[1][3]
138
+ family = ret[1][0]
139
+ if (family == "AF_INET" || family == "AF_INET6")
140
+ real_acl.input.check_ipstring(peer_ip, self) { try_terminate }
141
+ end
142
+ return ret
143
+ end
144
+
145
+ # This method returns default access list indicator
146
+ # used by protected object; in this case it's +:output+.
147
+ define_method :default_list do
148
+ :output
149
+ end
150
+
151
+ define_method :useables do
152
+ @useables
153
+ end
154
+
155
+ end # base.class_eval
156
+
157
+ end # self.included
158
+
159
+ end # module Socket
160
+
161
+ ###################################################################
162
+ # UDPSocket class with IP access control.
163
+ # It uses input and output access lists.
164
+ # Default access list for management operations is input.
165
+
166
+ module UDPSocket
167
+
168
+ include IPAccess::Patches::ACL
169
+
170
+ def self.included(base)
171
+
172
+ marker = (base.name =~ /IPAccess/) ? base.superclass : base
173
+ return if marker.instance_variable_defined?(:@uses_ipaccess)
174
+ base.instance_variable_set(:@uses_ipaccess, true)
175
+
176
+ base.class_eval do
177
+
178
+ orig_initialize = self.instance_method :initialize
179
+ orig_connect = self.instance_method :connect
180
+ orig_send = self.instance_method :send
181
+ orig_recvfrom = self.instance_method :recvfrom
182
+ orig_recvfrom_nonblock = self.instance_method :recvfrom_nonblock
183
+
184
+ define_method :__ipacall__initialize do |block, *args|
185
+ self.acl = valid_acl?(args.last) ? args.pop : :global
186
+ @opened_on_deny = true
187
+ orig_initialize.bind(self).call(*args, &block)
188
+ return self
189
+ end
190
+
191
+ # block passing wrapper for Ruby 1.8
192
+ def initialize(*args, &block)
193
+ __ipacall__initialize(block, *args)
194
+ end
195
+
196
+ # connect on steroids.
197
+ define_method :connect do |*args|
198
+ peer_ip = self.class.getaddress(args.shift)
199
+ real_acl.output.check_sockaddr(peer_ip, self)
200
+ return orig_connect.bind(self).call(peer_ip, *args)
201
+ end
202
+
203
+ # send on steroids.
204
+ define_method :send do |*args|
205
+ hostname = args[2]
206
+ return orig_send.bind(self).call(*args) if hostname.nil?
207
+ peer_ip = self.class.getaddress(hostname)
208
+ real_acl.output.check_sockaddr(peer_ip, self)
209
+ args[2] = peer_ip
210
+ return orig_send.bind(self).call(*args)
211
+ end
212
+
213
+ # recvfrom on steroids.
214
+ define_method :recvfrom do |*args|
215
+ ret = orig_recvfrom.bind(self).call(*args)
216
+ peer_ip = ret[1][3]
217
+ family = ret[1][0]
218
+ if (family == "AF_INET" || family == "AF_INET6")
219
+ real_acl.input.check_ipstring(peer_ip, self)
220
+ end
221
+ return ret
222
+ end
223
+
224
+ # recvfrom_nonblock on steroids.
225
+ define_method :recvfrom_nonblock do |*args|
226
+ ret = orig_recvfrom_nonblock.bind(self).call(*args)
227
+ peer_ip = ret[1][3]
228
+ family = ret[1][0]
229
+ if (family == "AF_INET" || family == "AF_INET6")
230
+ real_acl.input.check_ipstring(peer_ip, self)
231
+ end
232
+ return ret
233
+ end
234
+
235
+ # This method returns default access list indicator
236
+ # used by protected object; in this case it's +:input+.
237
+ define_method :default_list do
238
+ :intput
239
+ end
240
+
241
+ # this kind of socket is not connection-oriented.
242
+ define_method :connection_close do
243
+ return nil
244
+ end
245
+
246
+ # this hook will be called each time @acl is reassigned
247
+ define_method :acl_recheck do
248
+ return nil if self.closed?
249
+ real_acl.output.check_socket(self, self) { try_terminate }
250
+ return nil
251
+ end
252
+
253
+ end # base.class_eval
254
+
255
+ end # self.included
256
+
257
+ end # module UDPSocket
258
+
259
+ ###################################################################
260
+ # SOCKSSocket class with IP access control.
261
+ # It uses output access lists.
262
+
263
+ module SOCKSocket
264
+
265
+ include IPAccess::Patches::ACL
266
+
267
+ def self.included(base)
268
+
269
+ marker = (base.name =~ /IPAccess/) ? base.superclass : base
270
+ return if marker.instance_variable_defined?(:@uses_ipaccess)
271
+ base.instance_variable_set(:@uses_ipaccess, true)
272
+
273
+ base.class_eval do
274
+
275
+ orig_initialize = self.instance_method :initialize
276
+
277
+ # initialize on steroids.
278
+ define_method :__pacall__initialize do |block, *args|
279
+ @opened_on_deny = false
280
+ args.delete_if { |x| @opened_on_deny = true if (x.is_a?(Symbol) && x == :opened_on_deny) }
281
+ args.pop if args.last.nil?
282
+ self.acl = valid_acl?(args.last) ? args.pop : :global
283
+ args[0] = self.class.getaddress(args[0])
284
+ unless @opened_on_deny
285
+ real_acl.output.check_ipstring args[0]
286
+ orig_initialize.bind(self).call(*args, &block)
287
+ else
288
+ orig_initialize.bind(self).call(*args, &block)
289
+ real_acl.output.check_socket(self)
290
+ end
291
+ @useables = IPAccess::ObjectsReferences
292
+ return self
293
+ end
294
+
295
+ # block passing wrapper for Ruby 1.8
296
+ def initialize(*args, &block)
297
+ __ipacall__initialize(block, *args)
298
+ end
299
+
300
+ # this hook will be called each time @acl is reassigned
301
+ define_method :acl_recheck do
302
+ return nil if self.closed?
303
+ real_acl.output.check_socket(self, self) { try_terminate }
304
+ return nil
305
+ end
306
+
307
+ # This method returns default access list indicator
308
+ # used by protected object; in this case it's +:output+.
309
+ define_method :default_list do
310
+ :output
311
+ end
312
+
313
+ end # base.class_eval
314
+
315
+ end # self.included
316
+
317
+ end # module SOCKSSocket
318
+
319
+ ###################################################################
320
+ # TCPSocket class with IP access control.
321
+ # It uses output access lists.
322
+
323
+ module TCPSocket
324
+
325
+ include IPAccess::Patches::ACL
326
+
327
+ def self.included(base)
328
+
329
+ marker = (base.name =~ /IPAccess/) ? base.superclass : base
330
+ return if marker.instance_variable_defined?(:@uses_ipaccess)
331
+ base.instance_variable_set(:@uses_ipaccess, true)
332
+
333
+ base.class_eval do
334
+
335
+ orig_initialize = self.instance_method :initialize
336
+
337
+ # initialize on steroids.
338
+ define_method :__ipacall__initialize do |block, *args|
339
+ @opened_on_deny = false
340
+ args.delete_if { |x| @opened_on_deny = true if (x.is_a?(Symbol) && x == :opened_on_deny) }
341
+ args.pop if args.last.nil?
342
+ self.acl = valid_acl?(args.last) ? args.pop : :global
343
+ args[0] = self.class.getaddress(args[0])
344
+ @useables = IPAccess::ObjectsReferences
345
+ unless @opened_on_deny
346
+ real_acl.output.check_ipstring(args[0], :none)
347
+ orig_initialize.bind(self).call(*args, &block)
348
+ else
349
+ orig_initialize.bind(self).call(*args, &block)
350
+ real_acl.output.check_socket(self)
351
+ end
352
+ return self
353
+ end
354
+
355
+ # block passing wrapper for Ruby 1.8
356
+ def initialize(*args, &block)
357
+ __ipacall__initialize(block, *args)
358
+ end
359
+
360
+ # this hook will be called each time @acl is reassigned
361
+ define_method :acl_recheck do
362
+ return nil if self.closed?
363
+ real_acl.output.check_socket(self, self) { try_terminate }
364
+ return nil
365
+ end
366
+
367
+ # This method returns default access list indicator
368
+ # used by protected object; in this case it's +:output+.
369
+ define_method :default_list do
370
+ :output
371
+ end
372
+
373
+ end # base.class_eval
374
+
375
+ end # self.included
376
+
377
+ end # module TCPSocket
378
+
379
+ ###################################################################
380
+ # TCPServer class with IP access control.
381
+ # It uses input access lists.
382
+
383
+ module TCPServer
384
+
385
+ include IPAccess::Patches::ACL
386
+
387
+ def self.included(base)
388
+
389
+ marker = (base.name =~ /IPAccess/) ? base.superclass : base
390
+ return if marker.instance_variable_defined?(:@uses_ipaccess)
391
+ base.instance_variable_set(:@uses_ipaccess, true)
392
+
393
+ base.class_eval do
394
+
395
+ orig_initialize = self.instance_method :initialize
396
+ orig_accept = self.instance_method :accept
397
+ orig_accept_nonblock = self.instance_method :accept_nonblock
398
+ orig_sysaccept = self.instance_method :sysaccept
399
+
400
+ # initialize on steroids.
401
+ define_method :__ipacall__initialize do |block, *args|
402
+ @opened_on_deny = false
403
+ args.delete_if { |x| @opened_on_deny = true if (x.is_a?(Symbol) && x == :opened_on_deny) }
404
+ args.pop if args.last.nil?
405
+ self.acl = valid_acl?(args.last) ? args.pop : :global
406
+ return orig_initialize.bind(self).call(*args, &block)
407
+ end
408
+
409
+ # block passing wrapper for Ruby 1.8
410
+ def initialize(*args, &block)
411
+ __ipacall__initialize(block, *args)
412
+ end
413
+
414
+ # accept on steroids.
415
+ define_method :accept do |*args|
416
+ r = orig_accept.bind(self).call(*args)
417
+ real_acl.input.check_socket(r, r) { try_terminate_subsocket(r) }
418
+ return r
419
+ end
420
+
421
+ # accept_nonblock on steroids.
422
+ define_method :accept_nonblock do |*args|
423
+ r = orig_accept_nonblock.bind(self).call(*args)
424
+ real_acl.input.check_socket(r, r) { try_terminate_subsocket(r) }
425
+ return r
426
+ end
427
+
428
+ # sysaccept on steroids.
429
+ define_method :sysaccept do |*args|
430
+ r = orig_sysaccept.bind(self).call(*args)
431
+ real_acl.input.check_fd(r, r) { try_terminate_subsocket(::Socket.for_fd(r)) }
432
+ return r
433
+ end
434
+
435
+ # this hook will be called each time @acl is reassigned
436
+ define_method :acl_recheck do
437
+ return nil if self.closed?
438
+ real_acl.output.check_socket(self, self) { try_terminate }
439
+ return nil
440
+ end
441
+
442
+ # This method returns default access list indicator
443
+ # used by protected object; in this case it's +:input+.
444
+ define_method :default_list do
445
+ :input
446
+ end
447
+
448
+ end # base.class_eval
449
+
450
+ end # self.included
451
+
452
+ end # module TCPServer
453
+
454
+ ###################################################################
455
+ # Helper methods for easy checking and arming sockets.
456
+
457
+ module ACL
458
+
459
+ # This method helps to obtain real socket object.
460
+ # It check whether object is SOCKSSocket or SSLSocket
461
+ # and calls the right method if needed.
462
+ #
463
+ # It returns socket object or +nil+ if something went wrong.
464
+
465
+ def real_socket(obj)
466
+ obj = obj.io if (obj.respond_to?(:io) && obj.io.respond_to?(:getpeername))
467
+ case obj.class.name.to_sym
468
+ when :TCPSocket, :UDPSocket, :TCPServer, :SOCKSSocket, :Socket
469
+ return obj
470
+ else
471
+ return nil
472
+ end
473
+ end
474
+ private :real_socket
475
+
476
+ # This method is used to safely
477
+ # re-raise an eventual exception
478
+ # and add current object's reference
479
+ # to its useables field and to useables
480
+ # of a socket object.
481
+ #
482
+ # The passed block should contain
483
+ # code that should be wrapped and
484
+ # the given object should point to
485
+ # useable.
486
+ #
487
+ # The block should return new socket
488
+ # object.
489
+ #
490
+ # This method is present only when
491
+ # patching/arming engine had been loaded.
492
+
493
+ def take_care
494
+ begin
495
+ ipa_socket = nil
496
+ ipa_socket = yield
497
+ rescue IPAccessDenied => e
498
+ e.originator = self
499
+ try_terminate
500
+ raise
501
+ ensure
502
+ ipa_socket.useables.add(useable) if ipa_socket.respond_to?(:useables)
503
+ end
504
+ end
505
+ private :take_care
506
+
507
+ # This method tries to arm socket object.
508
+ # If a wanted access set and an object's access
509
+ # set is no different then acl_recheck is called
510
+ # by force. It sets armed socket's +opened_on_deny+
511
+ # flag to +true+.
512
+
513
+ def try_arm_socket(obj, initial_acl=nil)
514
+ late_sock = real_socket(obj)
515
+ unless late_sock.nil?
516
+ take_care do
517
+ initial_acl = real_acl if initial_acl.nil?
518
+ IPAccess.arm(late_sock, acl, :opened_on_deny) unless late_sock.respond_to?(:acl)
519
+ late_sock.acl = initial_acl if late_sock.acl != initial_acl
520
+ late_sock
521
+ end
522
+ end
523
+ return obj
524
+ end
525
+ private :try_arm_socket
526
+
527
+ # This method tries to arm socket object and then
528
+ # tries to set up correct ACL for it. If the ACL
529
+ # had changed then it assumes that underlying routines
530
+ # took care about rechecking socket's IP against
531
+ # correct access list (input or output). By taking
532
+ # care we mean automatic triggering of acl_recheck
533
+ # when object's acl= method had been called.
534
+ # The acl_recheck will be called without any conditions.
535
+ # This method sets armed socket's +opened_on_deny+
536
+ # flag to +true+. When exception will happen during check
537
+ # it will fill up +originator+ attribute of IPAccessDenied
538
+ # kind of object. The originator will be set to
539
+ # +self+.
540
+ #
541
+ # This method returns the given object.
542
+
543
+ def try_arm_and_check_socket(obj, initial_acl=nil)
544
+ late_sock = real_socket(obj)
545
+ unless late_sock.nil?
546
+ take_care do
547
+ initial_acl = real_acl if initial_acl.nil?
548
+ IPAccess.arm(late_sock, acl, :opened_on_deny) unless late_sock.respond_to?(:acl)
549
+ if late_sock.acl != initial_acl
550
+ late_sock.acl = initial_acl
551
+ else
552
+ late_sock.acl_recheck
553
+ end
554
+ late_sock
555
+ end
556
+ end
557
+ return obj
558
+ end
559
+ private :try_arm_and_check_socket
560
+
561
+ def try_check_out_socket_acl(obj, used_acl)
562
+ take_care do
563
+ late_sock = real_socket(obj)
564
+ used_acl.output.check_socket(late_sock, self) { try_terminate } unless late_sock.nil?
565
+ late_sock
566
+ end
567
+ return obj
568
+ end
569
+ private :try_check_out_socket_acl
570
+
571
+ def try_check_in_socket_acl(obj, used_acl)
572
+ take_care do
573
+ late_sock = real_socket(obj)
574
+ used_acl.input.check_socket(late_sock, self) { try_terminate } unless late_sock.nil?
575
+ late_sock
576
+ end
577
+ return obj
578
+ end
579
+ private :try_check_in_socket_acl
580
+
581
+ end # module ACL
582
+
583
+ end # module IPAccess::Patches
584
+
585
+ # :startdoc:
586
+