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
@@ -1,431 +0,0 @@
1
- # encoding: utf-8
2
- #
3
- # Author:: Paweł Wilk (mailto:pw@gnu.org)
4
- # Copyright:: Copyright (c) 2009 Paweł Wilk
5
- # License:: This program is licensed under the terms of {GNU Lesser General Public License}[link:docs/LGPL-LICENSE.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.
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 'socket'
26
- require 'singleton'
27
- require 'ipaccess/ip_access_errors'
28
-
29
- class IPAccess
30
-
31
- # This is global access set, used by
32
- # default by all socket handling
33
- # classes with enabled IP access control.
34
-
35
- Global = IPAccess.new 'global'
36
-
37
- end
38
-
39
- # :stopdoc:
40
-
41
- # This modules contain patches for Ruby socket
42
- # classes in order to enable IP access control
43
- # for them.
44
- #
45
- # This module patches socket handling classes
46
- # to use IP access control. Each patched socket
47
- # class has acl member, which is an IPAccess object.
48
-
49
- module IPAccess::Patches
50
-
51
- # This class is a proxy that raises an exception when
52
- # any method other than defined in Object class is called.
53
- # It behaves like NilClass.
54
-
55
- class GlobalSet
56
-
57
- include Singleton
58
-
59
- def nil?; true end
60
-
61
- def method_missing(name, *args)
62
- return nil.method(name).call(*args) if nil.respond_to?(name)
63
- raise ArgumentError, "cannot access global set from object's scope, use IPAccess::Global"
64
- end
65
-
66
- end
67
-
68
-
69
- # The IPSocketAccess module contains methods
70
- # that are present in all classes handling
71
- # sockets with IP access control enabled.
72
-
73
- module IPSocketAccess
74
-
75
- # This method enables usage of internal IP access list for object.
76
- # If argument is IPAccess object then it is used.
77
- #
78
- # ==== Example
79
- #
80
- # socket.acl = :global # use global access set
81
- # socket.acl = :private # create and use individual access set
82
- # socket.acl = IPAccess.new # use external (shared) access set
83
-
84
- def acl=(obj)
85
- if obj.is_a?(Symbol)
86
- case obj
87
- when :global
88
- @acl = GlobalSet.instance
89
- when :private
90
- @acl = IPAccess.new
91
- else
92
- raise ArgumentError, "bad access list selector, use: :global or :private"
93
- end
94
- elsif obj.is_a?(IPAccess)
95
- @acl = obj
96
- else
97
- raise ArgumentError, "bad access list"
98
- end
99
- end
100
-
101
- attr_reader :acl
102
- alias_method :access=, :acl=
103
- alias_method :access, :acl
104
-
105
- end
106
-
107
- ###################################################################
108
- # Socket class with IP access control.
109
- # It uses input and output access lists.
110
-
111
- module Socket
112
-
113
- include IPSocketAccess
114
-
115
- def self.included(base)
116
-
117
- marker = (base.name =~ /IPAccess/) ? base.superclass : base
118
- return if marker.instance_variable_defined?(:@uses_ipaccess)
119
- base.instance_variable_set(:@uses_ipaccess, true)
120
-
121
- base.class_eval do
122
-
123
- orig_initialize = self.instance_method :initialize
124
- orig_accept = self.instance_method :accept
125
- orig_accept_nonblock = self.instance_method :accept_nonblock
126
- orig_connect = self.instance_method :connect
127
- orig_recvfrom = self.instance_method :recvfrom
128
- orig_recvfrom_nonblock = self.instance_method :recvfrom_nonblock
129
- orig_sysaccept = self.instance_method :sysaccept
130
-
131
- define_method :initialize do |*args|
132
- @acl = GlobalSet.instance
133
- orig_initialize.bind(self).call(*args)
134
- end
135
-
136
- # accept on steroids.
137
- define_method :accept do |*args|
138
- acl = @acl.nil? ? IPAccess::Global : @acl
139
- ret = orig_accept.bind(self).call(*args)
140
- acl.check_in_socket(ret.first)
141
- return ret
142
- end
143
-
144
- # accept_nonblock on steroids.
145
- define_method :accept_nonblock do |*args|
146
- acl = @acl.nil? ? IPAccess::Global : @acl
147
- ret = orig_accept_nonblock.bind(self).call(*args)
148
- acl.check_in_socket(ret.first)
149
- return ret
150
- end
151
-
152
- # sysaccept on steroids.
153
- define_method :sysaccept do |*args|
154
- acl = @acl.nil? ? IPAccess::Global : @acl
155
- ret = orig_accept.bind(self).call(*args)
156
- acl.check_in_sockaddr(ret.last)
157
- return ret
158
- end
159
-
160
- # connect on steroids.
161
- define_method :connect do |*args|
162
- acl = @acl.nil? ? IPAccess::Global : @acl
163
- acl.check_out_sockaddr(args.first)
164
- return orig_connect.bind(self).call(*args)
165
- end
166
-
167
- # recvfrom on steroids.
168
- define_method :recvfrom do |*args|
169
- acl = @acl.nil? ? IPAccess::Global : @acl
170
- ret = orig_recvfrom.bind(self).call(*args)
171
- peer_ip = ret[1][3]
172
- family = ret[1][0]
173
- if (family == "AF_INET" || family == "AF_INET6")
174
- acl.check_in_ipstring(peer_ip)
175
- end
176
- return ret
177
- end
178
-
179
- # recvfrom_nonblock on steroids.
180
- define_method :recvfrom_nonblock do |*args|
181
- acl = @acl.nil? ? IPAccess::Global : @acl
182
- ret = orig_recvfrom_nonblock.bind(self).call(*args)
183
- peer_ip = ret[1][3]
184
- family = ret[1][0]
185
- if (family == "AF_INET" || family == "AF_INET6")
186
- acl.check_in_ipstring(peer_ip)
187
- end
188
- return ret
189
- end
190
-
191
- end # base.class_eval
192
-
193
- end # self.included
194
-
195
- end # module Socket
196
-
197
- ###################################################################
198
- # UDPSocket class with IP access control.
199
- # It uses input and output access lists.
200
-
201
- module UDPSocket
202
-
203
- include IPSocketAccess
204
-
205
- def self.included(base)
206
-
207
- marker = (base.name =~ /IPAccess/) ? base.superclass : base
208
- return if marker.instance_variable_defined?(:@uses_ipaccess)
209
- base.instance_variable_set(:@uses_ipaccess, true)
210
-
211
- base.class_eval do
212
-
213
- orig_initialize = self.instance_method :initialize
214
- orig_connect = self.instance_method :connect
215
- orig_send = self.instance_method :send
216
- orig_recvfrom = self.instance_method :recvfrom
217
- orig_recvfrom_nonblock = self.instance_method :recvfrom_nonblock
218
-
219
- define_method :initialize do |*args|
220
- @acl = GlobalSet.instance
221
- orig_initialize.bind(self).call(*args)
222
- end
223
-
224
- # connect on steroids.
225
- define_method :connect do |*args|
226
- acl = @acl.nil? ? IPAccess::Global : @acl
227
- peer_ip = self.class.getaddress(args.shift)
228
- acl.check_out_sockaddr(peer_ip)
229
- return orig_connect.bind(self).call(peer_ip, *args)
230
- end
231
-
232
- # send on steroids.
233
- define_method :send do |*args|
234
- hostname = args[2]
235
- return orig_send.bind(self).call(*args) if hostname.nil?
236
- acl = @acl.nil? ? IPAccess::Global : @acl
237
- peer_ip = self.class.getaddress(hostname)
238
- acl.check_out_sockaddr(peer_ip)
239
- args[2] = peer_ip
240
- return orig_send.bind(self).call(*args)
241
- end
242
-
243
- # recvfrom on steroids.
244
- define_method :recvfrom do |*args|
245
- acl = @acl.nil? ? IPAccess::Global : @acl
246
- ret = orig_recvfrom.bind(self).call(*args)
247
- peer_ip = ret[1][3]
248
- family = ret[1][0]
249
- if (family == "AF_INET" || family == "AF_INET6")
250
- acl.check_in_ipstring(peer_ip)
251
- end
252
- return ret
253
- end
254
-
255
- # recvfrom_nonblock on steroids.
256
- define_method :recvfrom_nonblock do |*args|
257
- acl = @acl.nil? ? IPAccess::Global : @acl
258
- ret = orig_recvfrom_nonblock.bind(self).call(*args)
259
- peer_ip = ret[1][3]
260
- family = ret[1][0]
261
- if (family == "AF_INET" || family == "AF_INET6")
262
- acl.check_in_ipstring(peer_ip)
263
- end
264
- return ret
265
- end
266
-
267
- end # base.class_eval
268
-
269
- end # self.included
270
-
271
- end # module UDPSocket
272
-
273
- ###################################################################
274
- # SOCKSSocket class with IP access control.
275
- # It uses output access lists.
276
-
277
- module SOCKSocket
278
-
279
- include IPSocketAccess
280
-
281
- def self.included(base)
282
-
283
- marker = (base.name =~ /IPAccess/) ? base.superclass : base
284
- return if marker.instance_variable_defined?(:@uses_ipaccess)
285
- base.instance_variable_set(:@uses_ipaccess, true)
286
-
287
- base.class_eval do
288
-
289
- orig_initialize = self.instance_method :initialize
290
-
291
- # initialize on steroids.
292
- define_method :initialize do |*args|
293
- self.acl = (args.size > 2) ? args.pop : :global
294
- acl = @acl.nil? ? IPAccess::Global : @acl
295
- args[0] = self.class.getaddress(args[0])
296
- acl.check_out_ipstring args[0]
297
- orig_initialize.bind(self).call(*args)
298
- end
299
-
300
- end # base.class_eval
301
-
302
- end # self.included
303
-
304
- end # module SOCKSSocket
305
-
306
- ###################################################################
307
- # TCPSocket class with IP access control.
308
- # It uses output access lists.
309
-
310
- module TCPSocket
311
-
312
- include IPSocketAccess
313
-
314
- def self.included(base)
315
-
316
- marker = (base.name =~ /IPAccess/) ? base.superclass : base
317
- return if marker.instance_variable_defined?(:@uses_ipaccess)
318
- base.instance_variable_set(:@uses_ipaccess, true)
319
-
320
- base.class_eval do
321
-
322
- orig_initialize = self.instance_method :initialize
323
-
324
- # initialize on steroids.
325
- define_method :initialize do |*args|
326
- self.acl = (args.size > 2) ? args.pop : :global
327
- acl = @acl.nil? ? IPAccess::Global : @acl
328
- args[0] = self.class.getaddress(args[0])
329
- acl.check_out_ipstring args[0]
330
- orig_initialize.bind(self).call(*args)
331
- end
332
-
333
- end # base.class_eval
334
-
335
- end # self.included
336
-
337
- end # module TCPSocket
338
-
339
- ###################################################################
340
- # TCPServer class with IP access control.
341
- # It uses input access lists.
342
-
343
- module TCPServer
344
-
345
- include IPSocketAccess
346
-
347
- def self.included(base)
348
-
349
- marker = (base.name =~ /IPAccess/) ? base.superclass : base
350
- return if marker.instance_variable_defined?(:@uses_ipaccess)
351
- base.instance_variable_set(:@uses_ipaccess, true)
352
-
353
- base.class_eval do
354
-
355
- orig_initialize = self.instance_method :initialize
356
- orig_accept = self.instance_method :accept
357
- orig_accept_nonblock = self.instance_method :accept_nonblock
358
- orig_sysaccept = self.instance_method :sysaccept
359
-
360
- # initialize on steroids.
361
- define_method :initialize do |*args|
362
- @acl = GlobalSet.instance
363
- orig_initialize.bind(self).call(*args)
364
- end
365
-
366
- # accept on steroids.
367
- define_method :accept do |*args|
368
- acl = @acl.nil? ? IPAccess::Global : @acl
369
- acl.check_in_socket orig_accept.bind(self).call(*args)
370
- end
371
-
372
- # accept_nonblock on steroids.
373
- define_method :accept_nonblock do |*args|
374
- acl = @acl.nil? ? IPAccess::Global : @acl
375
- acl.check_in_socket orig_accept_nonblock.bind(self).call(*args)
376
- end
377
-
378
- # sysaccept on steroids.
379
- define_method :sysaccept do |*args|
380
- acl = @acl.nil? ? IPAccess::Global : @acl
381
- acl.check_in_fd orig_sysaccept.bind(self).call(*args)
382
- end
383
-
384
- end # base.class_eval
385
-
386
- end # self.included
387
-
388
- end # module TCPServer
389
-
390
- end # module IPAccess::Patches
391
-
392
- # :startdoc:
393
-
394
- class IPAccess
395
-
396
- # This special method patches Ruby's standard
397
- # library socket handling classes and enables
398
- # IP access control for them. Instances of
399
- # such altered classes will be equipped with
400
- # member called +acl+ which is a kind of
401
- # IPAccess and allows you to manipulate
402
- # access rules.
403
- #
404
- # Passed argument may be a class object,
405
- # a string representation of a class object
406
- # or a symbol representing a class object.
407
- #
408
- # Currently supported classes are:
409
- # +Socket+, +UDPSocket+, +SOCKSSocket+,
410
- # +TCPSocket+ and +TCPServer+.
411
- #
412
- # Example:
413
- #
414
- # IPAccess.arm TCPSocket # arm TCPSocket class
415
- # IPAccess::Global.output.blacklist 'randomseed.pl' # add host to black list of the global set
416
- # TCPSocket.new('randomseed.pl', 80) # try to connect
417
-
418
- def self.arm(klass)
419
- klass_name = klass.name if klass.is_a?(Class)
420
- klass_name = klass_name.to_s unless klass.is_a?(String)
421
- klass_name = klass_name.to_sym
422
- case klass_name
423
- when :Socket, :UDPSocket, :SOCKSSocket, :TCPSocket, :TCPServer
424
- klass.__send__(:include, Patches.const_get(klass_name))
425
- else
426
- raise ArgumentError, "cannot enable IP access control for class #{klass_name}"
427
- end
428
- end
429
-
430
- end
431
-
data/spec/core_spec.rb DELETED
@@ -1,5 +0,0 @@
1
- $:.unshift File.join(File.dirname(__FILE__), "..", "lib")
2
-
3
- ['ip_access_list_spec'].each do |spec|
4
- require File.join(File.dirname(__FILE__), spec)
5
- end