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,38 @@
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
+ # Classes contained in this file are subclasses
8
+ # of Ruby Telnet handling classes equipped
9
+ # with IP access control.
10
+ #
11
+ #--
12
+ #
13
+ # Copyright (C) 2009 by Paweł Wilk. All Rights Reserved.
14
+ #
15
+ # This program is free software; you can redistribute it and/or modify
16
+ # it under the terms of either: 1) the GNU Lesser General Public License
17
+ # as published by the Free Software Foundation; either version 3 of the
18
+ # License, or (at your option) any later version; or 2) Ruby's License.
19
+ #
20
+ # See the file COPYING for complete licensing information.
21
+ #
22
+ #
23
+ # See ipaccess/ghost_doc/ghost_doc.rb for documentation of this classes.
24
+ #
25
+ #++
26
+
27
+ require 'net/telnet'
28
+ require 'ipaccess/ip_access_set'
29
+ require 'ipaccess/patches/net_telnet'
30
+
31
+ module IPAccess::Net
32
+
33
+ class Telnet < ::Net::Telnet
34
+ include IPAccess::Patches::Net::Telnet
35
+ end
36
+
37
+ end
38
+
@@ -0,0 +1,807 @@
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 classes in order to add
9
+ # IP access control to them.
10
+ #
11
+ #--
12
+ #
13
+ # Copyright (C) 2009 by Paweł Wilk. All Rights Reserved.
14
+ #
15
+ # This program is free software; you can redistribute it and/or modify
16
+ # it under the terms of either: 1) the GNU Lesser General Public License
17
+ # as published by the Free Software Foundation; either version 3 of the
18
+ # License, or (at your option) any later version; or 2) Ruby's License.
19
+ #
20
+ # See the file COPYING for complete licensing information.
21
+ #
22
+ #++
23
+ #
24
+
25
+ require 'singleton'
26
+ require 'ipaccess/ip_access_errors'
27
+
28
+ module IPAccess
29
+
30
+ class Set
31
+
32
+ # This is global access set, used by
33
+ # default by all socket handling
34
+ # classes with enabled IP access control.
35
+ # It has just one instance called IPAccess::Set.Global.
36
+ # It is present only when patching engine is loaded.
37
+
38
+ class GlobalClass < Set
39
+
40
+ # :stopdoc:
41
+
42
+ include Singleton
43
+
44
+ def global?; true end
45
+
46
+ def ==(obj)
47
+ return true if obj.object_id == IPAccess::Set::GlobalSet.instance.object_id
48
+ super(obj)
49
+ end
50
+
51
+ def ===(obj)
52
+ return true if obj.object_id == IPAccess::Set::GlobalSet.instance.object_id
53
+ super(obj)
54
+ end
55
+
56
+ def to_s
57
+ "#<IPAccess::Set:Global>"
58
+ end
59
+
60
+ # :startdoc:
61
+
62
+ end
63
+
64
+ # This is global access set, used by
65
+ # default by all socket handling
66
+ # classes with enabled IP access control.
67
+ # It is present only when patching engine is loaded.
68
+
69
+ Global = GlobalClass.instance
70
+ Global.name = 'global'
71
+
72
+ # This method returns +true+ when
73
+ # the current instance is not regular IPAccess::Set object
74
+ # but a reference to the IPAccess::Set.Global,
75
+ # which should be reached by that name. It returns
76
+ # +false+ in case of regular IPAccess::Set objects.
77
+ #
78
+ # This method is present only if
79
+ # patching engine had been loaded.
80
+
81
+ def global?; false end
82
+
83
+ end # class Set
84
+
85
+ # :call-seq:
86
+ # arm(klass, acl=nil)<br />
87
+ # arm(klass, :opened_on_deny)<br />
88
+ # arm(klass, acl, :opened_on_deny)
89
+ #
90
+ # This special method patches Ruby's standard
91
+ # library classes and enables IP access control
92
+ # for them. Instances of such altered classes
93
+ # will be equipped with member called +acl+,
94
+ # which is a kind of IPAccess::Set and allows you
95
+ # to manipulate access rules. It is also
96
+ # able to patch single instance of supported
97
+ # classes.
98
+ #
99
+ # This method returns object that has
100
+ # been patched.
101
+ #
102
+ # ==== Supported classes
103
+ #
104
+ # Currently supported classes are:
105
+ #
106
+ # – Socket, UDPSocket, SOCKSSocket, TCPSocket, TCPServer,
107
+ # – Net::HTTP,
108
+ # – Net::Telnet,
109
+ # – Net::FTP,
110
+ # – Net::POP3,
111
+ # – Net::IMAP,
112
+ # – Net::SMTP.
113
+ #
114
+ # ==== Patching classes
115
+ #
116
+ # Passed argument may be a class object,
117
+ # a string representation of a class object
118
+ # or a symbol representing a class object.
119
+ #
120
+ # ==== Patching single instances
121
+ #
122
+ # Passed argument may be an instance of
123
+ # supported class. It's possible to
124
+ # pass second, optional argument, which
125
+ # should be an initial access set. If
126
+ # this argument is omited then IPAccess::Set.Global
127
+ # is used. If +:opened_on_deny+ is passed then
128
+ # any connection remains opened in case of IPAccessDenied
129
+ # exception during arming.
130
+ #
131
+ # ==== Patching Ruby's sockets
132
+ #
133
+ # To quickly patch all Ruby's socket classes
134
+ # you may pass symbol +:sockets+ as an
135
+ # argument.
136
+ #
137
+ # === Examples
138
+ #
139
+ # ==== Example 1 – sockets
140
+ #
141
+ # require 'ipaccess/socket' # load sockets subsystem and IPAccess.arm method
142
+ #
143
+ # IPAccess.arm TCPSocket # arm TCPSocket class
144
+ # IPAccess::Set::Global.output.blacklist 'randomseed.pl' # add host to black list of the global set
145
+ # TCPSocket.new('randomseed.pl', 80) # try to connect
146
+ #
147
+ # ==== Example 2 – HTTP
148
+ #
149
+ # require 'ipaccess/net/http' # load net/http subsystem and IPAccess.arm method
150
+ #
151
+ # IPAccess.arm Net::HTTP # arm TCPSocket class
152
+ # IPAccess::Set::Global.output.blacklist 'randomseed.pl' # add host to black list of the global set
153
+ # Net::HTTP.get_print('randomseed.pl', '/i.html') # try to connect
154
+ #
155
+ # ==== Example 3 – single network object
156
+ #
157
+ # require 'ipaccess/net/telnet' # load Net::Telnet version and IPAccess.arm method
158
+ #
159
+ # opts = {}
160
+ # opts["Host"] = 'randomseed.pl'
161
+ # opts["Port"] = '80'
162
+ #
163
+ # t = Net::Telnet.new(opts) # try to connect to remote host
164
+ #
165
+ # acl = IPAccess::Set.new # create custom access set
166
+ # acl.output.blacklist 'randomseed.pl' # blacklist host
167
+ # IPAccess.arm t, acl # arm Telnet object and pass optional ACL
168
+
169
+ def self.arm(*args)
170
+ cod = args.delete(:opened_on_deny).nil? ? true : false
171
+ klass, acl = *args
172
+ singleton_obj = nil
173
+ if klass.is_a?(Class) # regular class
174
+ klass_name = klass.name
175
+ elsif (klass.is_a?(Symbol) || klass.is_a?(String))
176
+ klass_name = klass.to_s
177
+ if klass.name.downcase == "sockets" # just a bunch of sockets
178
+ require 'ipaccess/arm_sockets'
179
+ return
180
+ else # regular class as a string or symbol
181
+ klass = Kernel
182
+ klass_name.to_s.split('::').each do |k|
183
+ klass = klass.const_get(k)
184
+ end
185
+ end
186
+ else # regular object (will patch singleton of this object)
187
+ klass_name = klass.class.name
188
+ singleton_obj = klass
189
+ klass = (class <<klass; self; end)
190
+ end
191
+ begin
192
+ patch_klass = IPAccess::Patches
193
+ klass_name.split('::').each do |k|
194
+ patch_klass = patch_klass.const_get(k)
195
+ end
196
+ rescue NameError
197
+ raise ArgumentError, "cannot enable IP access control for class #{klass_name}"
198
+ end
199
+ klass.__send__(:include, patch_klass)
200
+ singleton_obj.__send__(:__ipa_singleton_hook, acl, cod) unless singleton_obj.nil?
201
+ return klass
202
+ end
203
+
204
+ # :stopdoc:
205
+
206
+ # This module patches network classes
207
+ # to enforce IP access control for them. Each patched
208
+ # class has the acl member, which is an IPAccess::Set object.
209
+
210
+ module Patches
211
+
212
+ # This class is a proxy that raises an exception when
213
+ # any method other than defined in Object class is called.
214
+ # It behaves like NilClass. Do not use this class, use
215
+ # IPAccess::Set.Global constant instead.
216
+
217
+ class IPAccess::Set::GlobalSet
218
+
219
+ include Singleton
220
+
221
+ # imitate nil
222
+ def nil?; true end
223
+
224
+ # This method returns +true+ if current object is IPAccess::Set.Global.
225
+ # Otherwise it returns +false+.
226
+ def global?; true end
227
+
228
+ # return +true+ when compared to IPAccess::Set.Global
229
+ def ==(obj)
230
+ return true if obj.object_id == IPAccess::Set::Global.object_id
231
+ method_missing(:==, obj)
232
+ end
233
+
234
+ def ===(obj)
235
+ return true if obj.object_id == IPAccess::Set::Global.object_id
236
+ method_missing(:===, obj)
237
+ end
238
+
239
+ # imitate IPAccess::Set.Global when inspected
240
+ def inspect
241
+ IPAccess::Set::Global.inspect
242
+ end
243
+
244
+ # imitate nil even more and disallow direct ACL modifications
245
+ def method_missing(name, *args)
246
+ return nil.method(name).call(*args) if nil.respond_to?(name)
247
+ raise ArgumentError, "cannot access global set from object's scope, use IPAccess::Set::Global"
248
+ end
249
+
250
+ end # class IPAccess::Set.GlobalSet
251
+
252
+ # The ACL module contains methods
253
+ # that are present in all network
254
+ # objects with IP access control enabled.
255
+
256
+ module ACL
257
+
258
+ # This method is used to safely
259
+ # pass an eventual exception
260
+ # and fill its useables field with a current
261
+ # object.
262
+
263
+ def __ipa_wrap_socket_call(*args, &block)
264
+ IPAccess.take_care(self, *args, &block)
265
+ end
266
+ protected :__ipa_wrap_socket_call
267
+
268
+ # This method enables usage of internal IP access list for object.
269
+ # If argument is IPAccess::Set object then it is used.
270
+ #
271
+ # ==== Example
272
+ #
273
+ # socket.acl = :global # use global access set
274
+ # socket.acl = :private # create and use individual access set
275
+ # socket.acl = IPAccess::Set.new # use external (shared) access set
276
+
277
+ def acl=(access_set)
278
+ new_acl = nil
279
+ prev_acl = @acl
280
+ if access_set.is_a?(Symbol)
281
+ case access_set
282
+ when :global
283
+ new_acl = IPAccess::Set::GlobalSet.instance
284
+ when :private
285
+ new_acl = IPAccess::Set.new
286
+ else
287
+ raise ArgumentError, "bad access list selector, use: :global or :private"
288
+ end
289
+ elsif access_set.is_a?(IPAccess::Set)
290
+ if access_set == IPAccess::Set::Global
291
+ new_acl = IPAccess::Set::GlobalSet.instance
292
+ else
293
+ new_acl = access_set
294
+ end
295
+ elsif access_set.nil?
296
+ new_acl = IPAccess::Set::GlobalSet.instance
297
+ else
298
+ raise ArgumentError, "bad access list"
299
+ end
300
+ unless (new_acl.nil? || prev_acl.object_id == new_acl.object_id)
301
+ @acl = new_acl
302
+ self.acl_recheck if self.respond_to?(:acl_recheck)
303
+ end
304
+ end
305
+
306
+ # This method returns +true+ if the given object can be used to initialize ACL.
307
+ # Otherwise it returns +false+.
308
+
309
+ def IPAccess.valid_acl?(obj)
310
+ if obj.is_a?(Symbol)
311
+ return true if (obj == :global || obj == :private)
312
+ elsif obj.is_a?(IPAccess::Set)
313
+ return true
314
+ end
315
+ return false
316
+ end
317
+
318
+ # This method returns +true+ if the given object can be used to initialize ACL.
319
+ # Otherwise it returns +false+.
320
+
321
+ def valid_acl?(obj)
322
+ IPAccess.valid_acl?(obj)
323
+ end
324
+
325
+ # This method should be called each time the access set related to an object
326
+ # is changed and there is a need to validate remote peer again, since it might be
327
+ # blacklisted.
328
+ #
329
+ # Each class that patches Ruby's network class should redefine this method
330
+ # and call it in a proper place (e.g. from hook executed when singleton methods
331
+ # are added to network object).
332
+
333
+ def acl_recheck
334
+ ;
335
+ end
336
+
337
+ # This method return current access set for an object.
338
+ #
339
+ # Ifaccess set (@acl) is somehow set to +nil+
340
+ # (which should never happend) or to IPAccess::Set.GlobalSet
341
+ # (which is internal singleton used to mark that @acl should
342
+ # point to the global set) it will return a reference
343
+ # to the global access set IPAccess::Set.Global.
344
+
345
+ def real_acl
346
+ @acl.nil? ? IPAccess::Set::Global : @acl
347
+ end
348
+ private :real_acl
349
+
350
+ attr_reader :acl
351
+ alias_method :access=, :acl=
352
+ alias_method :access, :acl
353
+
354
+ # This method returns default access list indicator
355
+ # used by protected object; usually +:input+ or
356
+ # +:output+.
357
+
358
+ def default_list; :output end
359
+
360
+ # :call-seq:
361
+ # whitelist(list, *addresses)
362
+ # whitelist(*addresses)
363
+ #
364
+ # This method whitelists IP address(-es) in
365
+ # the input or output access list selected
366
+ # by the *list* argument (+:input+ or +:output+).
367
+ # If the access list selector is omited it
368
+ # operates on the default access list that certain
369
+ # kind of network object uses. The allowed format of address
370
+ # is the same as for IPAccess.to_cidrs.
371
+ # This method will not add nor remove any
372
+ # blacklisted item.
373
+ #
374
+ # It will return the result of calling
375
+ # IPAccess::List#whitelist on the list.
376
+ #
377
+ # This method won't allow you to modify the list if
378
+ # the global access set is associated with an object.
379
+ # You may operate on IPAccess::Set.Global or use
380
+ # whitelist! instead.
381
+ #
382
+ # === Revalidation
383
+ #
384
+ # After modyfing access set current connection
385
+ # is validated again to avoid access leaks.
386
+ #
387
+ # === DNS Warning
388
+ #
389
+ # You should avoid passing hostnames as arguments since
390
+ # DNS is not reliable and responses may change with time,
391
+ # which may cause security flaws.
392
+
393
+ def whitelist(*addresses)
394
+ aclist = ( addresses.first.is_a?(Symbol) && [:input,:output].include?(addresses.first) ) ? addresses.shift : self.default_list
395
+ r = @acl.send(aclist).whitelist(*addresses)
396
+ self.acl_recheck
397
+ return r
398
+ end
399
+
400
+ alias_method :add_white, :whitelist
401
+ alias_method :allow, :whitelist
402
+ alias_method :permit, :whitelist
403
+
404
+ # This method works like whitelist but allows
405
+ # to set reason.
406
+
407
+ def whitelist_reasonable(reason, *addresses)
408
+ aclist = ( addresses.first.is_a?(Symbol) && [:input,:output].include?(addresses.first) ) ? addresses.shift : self.default_list
409
+ r = @acl.send(aclist).whitelist_reasonable(reason, *addresses)
410
+ self.acl_recheck
411
+ return r
412
+ end
413
+
414
+ # :call-seq:
415
+ # whitelist!(list, *addresses)
416
+ # whitelist!(*addresses)
417
+ #
418
+ # This method whitelists IP address(-es) in
419
+ # the input or output access list selected
420
+ # by the *list* argument (+:input+ or +:output+).
421
+ # If the access list selector is omited it
422
+ # operates on the default access list that certain
423
+ # kind of network object uses. The allowed format of address
424
+ # is the same as for IPAccess.to_cidrs.
425
+ # This method will not add nor remove any
426
+ # blacklisted item.
427
+ #
428
+ # It will return the result of calling
429
+ # IPAccess::List#whitelist on the list.
430
+ #
431
+ # This method will allow you to modify the list
432
+ # even if the global access set is used by object.
433
+ #
434
+ # === Revalidation
435
+ #
436
+ # After modyfing access set current connection
437
+ # is validated again to avoid access leaks.
438
+ #
439
+ # === DNS Warning
440
+ #
441
+ # You should avoid passing hostnames as arguments since
442
+ # DNS is not reliable and responses may change with time,
443
+ # which may cause security flaws.
444
+
445
+ def whitelist!(*addresses)
446
+ aclist = ( addresses.first.is_a?(Symbol) && [:input,:output].include?(addresses.first) ) ? addresses.shift : self.default_list
447
+ r = real_acl.send(aclist).whitelist(*addresses)
448
+ self.acl_recheck
449
+ return r
450
+ end
451
+
452
+ alias_method :add_white!, :whitelist!
453
+ alias_method :allow!, :whitelist!
454
+ alias_method :permit!, :whitelist!
455
+
456
+ # This method works like whitelist! but
457
+ # allows to set reason.
458
+
459
+ def whitelist_reasonable!(*addresses)
460
+ aclist = ( addresses.first.is_a?(Symbol) && [:input,:output].include?(addresses.first) ) ? addresses.shift : self.default_list
461
+ r = real_acl.send(aclist).whitelist_reasonable(reason, *addresses)
462
+ self.acl_recheck
463
+ return r
464
+ end
465
+
466
+ # :call-seq:
467
+ # unwhitelist(list, *addresses)
468
+ # unwhitelist(*addresses)
469
+ #
470
+ # This method removes whitelisted IP address(-es)
471
+ # from the input or output access list selected
472
+ # by the *list* argument (+:input+ or +:output+).
473
+ # If the access list selector is omited it
474
+ # operates on the default access list that certain
475
+ # kind of network object uses. The allowed format of address
476
+ # is the same as for IPAccess.to_cidrs.
477
+ # This method will not add nor remove any
478
+ # blacklisted item.
479
+ #
480
+ # It will return the result of calling
481
+ # IPAccess::List#unwhitelist on the list.
482
+ #
483
+ # This method won't allow you to modify the list if
484
+ # the global access set is associated with an object.
485
+ # You may operate on IPAccess::Set.Global or use
486
+ # unwhitelist! instead.
487
+ #
488
+ # === Revalidation
489
+ #
490
+ # After modyfing access set current connection
491
+ # is validated again to avoid access leaks.
492
+ #
493
+ # === DNS Warning
494
+ #
495
+ # You should avoid passing hostnames as arguments since
496
+ # DNS is not reliable and responses may change with time,
497
+ # which may cause security flaws.
498
+
499
+ def unwhitelist(*addresses)
500
+ aclist = ( addresses.first.is_a?(Symbol) && [:input,:output].include?(addresses.first) ) ? addresses.shift : self.default_list
501
+ r = @acl.send(aclist).unwhitelist(*addresses)
502
+ self.acl_recheck
503
+ return r
504
+ end
505
+
506
+ alias_method :unwhite, :unwhitelist
507
+ alias_method :del_white, :unwhitelist
508
+ alias_method :unallow, :unwhitelist
509
+ alias_method :unpermit, :unwhitelist
510
+
511
+ # :call-seq:
512
+ # unwhitelist!(list, *addresses)
513
+ # unwhitelist!(*addresses)
514
+ #
515
+ # This method removes whitelisted IP address(-es)
516
+ # from the input or output access list selected
517
+ # by the *list* argument (+:input+ or +:output+).
518
+ # If the access list selector is omited it
519
+ # operates on the default access list that certain
520
+ # kind of network object uses. The allowed format of address
521
+ # is the same as for IPAccess.to_cidrs.
522
+ # This method will not add nor remove any
523
+ # blacklisted item.
524
+ #
525
+ # It will return the result of calling
526
+ # IPAccess::List#unwhitelist on the list.
527
+ #
528
+ # This method will allow you to modify the list
529
+ # even if the global access set is used by object.
530
+ #
531
+ # === Revalidation
532
+ #
533
+ # After modyfing access set current connection
534
+ # is validated again to avoid access leaks.
535
+ #
536
+ # === DNS Warning
537
+ #
538
+ # You should avoid passing hostnames as arguments since
539
+ # DNS is not reliable and responses may change with time,
540
+ # which may cause security flaws.
541
+
542
+ def unwhitelist!(*addresses)
543
+ aclist = ( addresses.first.is_a?(Symbol) && [:input,:output].include?(addresses.first) ) ? addresses.shift : self.default_list
544
+ r = real_acl.send(aclist).unwhitelist(*addresses)
545
+ self.acl_recheck
546
+ return r
547
+ end
548
+
549
+ alias_method :unwhite!, :unwhitelist!
550
+ alias_method :del_white!, :unwhitelist!
551
+ alias_method :unallow!, :unwhitelist!
552
+ alias_method :unpermit!, :unwhitelist!
553
+
554
+ # :call-seq:
555
+ # blacklist(list, *addresses)
556
+ # blacklist(*addresses)
557
+ #
558
+ # This method blacklists IP address(-es) in
559
+ # the input or output access list selected
560
+ # by the *list* argument (+:input+ or +:output+).
561
+ # If the access list selector is omited it
562
+ # operates on the default access list that certain
563
+ # kind of network object uses. The allowed format of address
564
+ # is the same as for IPAccess.to_cidrs.
565
+ # This method will not add nor remove any
566
+ # whitelisted item.
567
+ #
568
+ # It will return the result of calling
569
+ # IPAccess::List#blacklist on the list.
570
+ #
571
+ # This method won't allow you to modify the list if
572
+ # the global access set is associated with an object.
573
+ # You may operate on IPAccess::Set.Global or use
574
+ # blacklist! instead.
575
+ #
576
+ # === Revalidation
577
+ #
578
+ # After modyfing access set current connection
579
+ # is validated again to avoid access leaks.
580
+ #
581
+ # === DNS Warning
582
+ #
583
+ # You should avoid passing hostnames as arguments since
584
+ # DNS is not reliable and responses may change with time,
585
+ # which may cause security flaws.
586
+
587
+ def blacklist(*addresses)
588
+ aclist = ( addresses.first.is_a?(Symbol) && [:input,:output].include?(addresses.first) ) ? addresses.shift : self.default_list
589
+ r = @acl.send(aclist).blacklist(*addresses)
590
+ self.acl_recheck
591
+ return r
592
+ end
593
+
594
+ alias_method :add_black, :blacklist
595
+ alias_method :deny, :blacklist
596
+ alias_method :block, :blacklist
597
+
598
+ # This method works like blacklist but allows to
599
+ # set reason.
600
+
601
+ def blacklist_reasonable(reason, *addresses)
602
+ aclist = ( addresses.first.is_a?(Symbol) && [:input,:output].include?(addresses.first) ) ? addresses.shift : self.default_list
603
+ r = @acl.send(aclist).blacklist_reasonable(reason, *addresses)
604
+ self.acl_recheck
605
+ return r
606
+ end
607
+
608
+ # :call-seq:
609
+ # blacklist!(list, *addresses)
610
+ # blacklist!(*addresses)
611
+ #
612
+ # This method blacklists IP address(-es) in
613
+ # the input or output access list selected
614
+ # by the *list* argument (+:input+ or +:output+).
615
+ # If the access list selector is omited it
616
+ # operates on the default access list that certain
617
+ # kind of network object uses. The allowed format of address
618
+ # is the same as for IPAccess.to_cidrs.
619
+ # This method will not add nor remove any
620
+ # whitelisted item.
621
+ #
622
+ # It will return the result of calling
623
+ # IPAccess::List#blacklist on the list.
624
+ #
625
+ # This method will allow you to modify the list
626
+ # even if the global access set is used by object.
627
+ #
628
+ # === Revalidation
629
+ #
630
+ # After modyfing access set current connection
631
+ # is validated again to avoid access leaks.
632
+ #
633
+ # === DNS Warning
634
+ #
635
+ # You should avoid passing hostnames as arguments since
636
+ # DNS is not reliable and responses may change with time,
637
+ # which may cause security flaws.
638
+
639
+ def blacklist!(*addresses)
640
+ aclist = ( addresses.first.is_a?(Symbol) && [:input,:output].include?(addresses.first) ) ? addresses.shift : self.default_list
641
+ r = real_acl.send(aclist).blacklist(*addresses)
642
+ self.acl_recheck
643
+ return r
644
+ end
645
+
646
+ alias_method :add_black!, :blacklist!
647
+ alias_method :deny!, :blacklist!
648
+ alias_method :block!, :blacklist!
649
+
650
+ # This method works like blacklist! but allows
651
+ # to set reason.
652
+
653
+ def blacklist_reasonable!(reason, *addresses)
654
+ aclist = ( addresses.first.is_a?(Symbol) && [:input,:output].include?(addresses.first) ) ? addresses.shift : self.default_list
655
+ r = real_acl.send(aclist).blacklist(reason, *addresses)
656
+ self.acl_recheck
657
+ return r
658
+ end
659
+
660
+ # :call-seq:
661
+ # unblacklist(list, *addresses)
662
+ # unblacklist(*addresses)
663
+ #
664
+ # This method removes blacklisted IP address(-es)
665
+ # from the input or output access list selected
666
+ # by the *list* argument (+:input+ or +:output+).
667
+ # If the access list selector is omited it
668
+ # operates on the default access list that certain
669
+ # kind of network object uses. The allowed format of address
670
+ # is the same as for IPAccess.to_cidrs.
671
+ # This method will not add nor remove any
672
+ # whitelisted item.
673
+ #
674
+ # It will return the result of calling
675
+ # IPAccess::List#unblacklist on the list.
676
+ #
677
+ # This method won't allow you to modify the list if
678
+ # the global access set is associated with an object.
679
+ # You may operate on IPAccess::Set.Global or use
680
+ # unwhitelist! instead.
681
+ #
682
+ # === Revalidation
683
+ #
684
+ # After modyfing access set current connection
685
+ # is validated again to avoid access leaks.
686
+ #
687
+ # === DNS Warning
688
+ #
689
+ # You should avoid passing hostnames as arguments since
690
+ # DNS is not reliable and responses may change with time,
691
+ # which may cause security flaws.
692
+
693
+ def unblacklist(*addresses)
694
+ aclist = ( addresses.first.is_a?(Symbol) && [:input,:output].include?(addresses.first) ) ? addresses.shift : self.default_list
695
+ r = @acl.send(aclist).unblacklist(*addresses)
696
+ self.acl_recheck
697
+ return r
698
+ end
699
+
700
+ alias_method :unblack, :unblacklist
701
+ alias_method :undeny, :unblacklist
702
+ alias_method :unblock, :unblacklist
703
+ alias_method :del_black, :unblacklist
704
+
705
+ # :call-seq:
706
+ # unblacklist!(list, *addresses)
707
+ # unblacklist!(*addresses)
708
+ #
709
+ # This method removes blacklisted IP address(-es)
710
+ # from the input or output access list selected
711
+ # by the *list* argument (+:input+ or +:output+).
712
+ # If the access list selector is omited it
713
+ # operates on the default access list that certain
714
+ # kind of network object uses. The allowed format of address
715
+ # is the same as for IPAccess.to_cidrs.
716
+ # This method will not add nor remove any
717
+ # whitelisted item.
718
+ #
719
+ # It will return the result of calling
720
+ # IPAccess::List#unblacklist on the list.
721
+ #
722
+ # This method will allow you to modify the list
723
+ # even if the global access set is used by object.
724
+ #
725
+ # === Revalidation
726
+ #
727
+ # After modyfing access set current connection
728
+ # is validated again to avoid access leaks.
729
+ #
730
+ # === DNS Warning
731
+ #
732
+ # You should avoid passing hostnames as arguments since
733
+ # DNS is not reliable and responses may change with time,
734
+ # which may cause security flaws.
735
+
736
+ def unblacklist!(*addresses)
737
+ aclist = ( addresses.first.is_a?(Symbol) && [:input,:output].include?(addresses.first) ) ? addresses.shift : self.default_list
738
+ r = real_acl.send(aclist).unblacklist(*addresses)
739
+ self.acl_recheck
740
+ return r
741
+ end
742
+
743
+ alias_method :unblack!, :unblacklist!
744
+ alias_method :undeny!, :unblacklist!
745
+ alias_method :unblock!, :unblacklist!
746
+ alias_method :del_black!, :unblacklist!
747
+
748
+ # Setting it to +false+ disables closing connection
749
+ # when raising access denied exception
750
+
751
+ attr_accessor :opened_on_deny
752
+
753
+ # Setting it to +true+ disables closing connection
754
+ # when raising access denied exception
755
+
756
+ def close_on_deny=(x)
757
+ self.open_on_deny = !x
758
+ end
759
+
760
+ def close_on_deny
761
+ not self.open_on_deny
762
+ end
763
+
764
+ # This method is universal wrapper for
765
+ # closing connection. Classes should
766
+ # override it.
767
+
768
+ def terminate
769
+ self.close unless self.closed?
770
+ end
771
+
772
+ # This method will try to close
773
+ # session/connection for network object
774
+ # if +open_on_deny+ member is set to +false+
775
+
776
+ def try_terminate
777
+ terminate unless @opened_on_deny
778
+ return nil
779
+ end
780
+ private :try_terminate
781
+
782
+ # helper for dropping unwanted connections
783
+ def try_terminate_subsocket(sock)
784
+ sock.close unless (@opened_on_deny || sock.closed?)
785
+ return nil
786
+ end
787
+ private :try_terminate_subsocket
788
+
789
+ # This method will be called when
790
+ # instance is patched.
791
+
792
+ def __ipa_singleton_hook(acl=nil, open_on_deny=false)
793
+ @opened_on_deny = open_on_deny
794
+ acl = @options["ACL"] if (acl.nil? && instance_variable_defined?(:@options) && @options.respond_to?(:has_key?))
795
+ self.acl = acl
796
+ end
797
+ private :__ipa_singleton_hook
798
+
799
+ end # module ACL
800
+
801
+ end # module Patches
802
+
803
+ # :startdoc:
804
+
805
+ end # module IPAccess
806
+
807
+