ipaccess 1.2.0 → 1.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.yardopts +2 -0
- data/ChangeLog +66 -0
- data/Manifest.txt +5 -10
- data/README.md +2 -2
- data/Rakefile +1 -1
- data/docs/HISTORY +11 -0
- data/docs/TODO +1 -1
- data/docs/yard-tpl/default/fulldoc/html/css/common.css +5 -0
- data/examples/open-uri.rb +14 -0
- data/examples/telnet.rb +1 -1
- data/ipaccess.gemspec +62 -0
- data/lib/ipaccess.rb +2 -566
- data/lib/ipaccess/arm_sockets.rb +0 -1
- data/lib/ipaccess/core.rb +523 -0
- data/lib/ipaccess/ghost_doc/ghost_doc.rb +1 -1
- data/lib/ipaccess/ghost_doc/ghost_doc_acl.rdoc +54 -0
- data/lib/ipaccess/ghost_doc/ghost_doc_net_ftp.rb +35 -19
- data/lib/ipaccess/ghost_doc/ghost_doc_net_http.rb +34 -18
- data/lib/ipaccess/ghost_doc/ghost_doc_net_smtp.rb +35 -19
- data/lib/ipaccess/ghost_doc/ghost_doc_net_telnet.rb +35 -19
- data/lib/ipaccess/ghost_doc/ghost_doc_patched_usage.rdoc +65 -0
- data/lib/ipaccess/ghost_doc/ghost_doc_sockets.rb +353 -125
- data/lib/ipaccess/ip_access_check.rb +2 -2
- data/lib/ipaccess/ip_access_errors.rb +2 -2
- data/lib/ipaccess/ip_access_list.rb +3 -3
- data/lib/ipaccess/patches/generic.rb +150 -183
- data/lib/ipaccess/patches/net_ftp.rb +1 -2
- data/lib/ipaccess/patches/net_http.rb +10 -14
- data/lib/ipaccess/patches/net_imap.rb +1 -2
- data/lib/ipaccess/patches/net_pop.rb +2 -4
- data/lib/ipaccess/patches/net_smtp.rb +2 -4
- data/lib/ipaccess/patches/net_telnet.rb +1 -2
- data/lib/ipaccess/patches/sockets.rb +67 -69
- data/lib/ipaccess/socket.rb +0 -17
- metadata +70 -100
- metadata.gz.sig +0 -0
- data/lib/ipaccess/ghost_doc/ghost_doc_acl.rb +0 -54
- data/lib/ipaccess/ghost_doc/ghost_doc_p_blacklist.rb +0 -36
- data/lib/ipaccess/ghost_doc/ghost_doc_p_blacklist_e.rb +0 -7
- data/lib/ipaccess/ghost_doc/ghost_doc_p_unblacklist.rb +0 -36
- data/lib/ipaccess/ghost_doc/ghost_doc_p_unblacklist_e.rb +0 -7
- data/lib/ipaccess/ghost_doc/ghost_doc_p_unwhitelist.rb +0 -36
- data/lib/ipaccess/ghost_doc/ghost_doc_p_unwhitelist_e.rb +0 -7
- data/lib/ipaccess/ghost_doc/ghost_doc_p_whitelist.rb +0 -36
- data/lib/ipaccess/ghost_doc/ghost_doc_p_whitelist_e.rb +0 -7
- data/lib/ipaccess/ghost_doc/ghost_doc_patched_usage.rb +0 -64
data/lib/ipaccess/arm_sockets.rb
CHANGED
@@ -0,0 +1,523 @@
|
|
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 library allow you to create
|
8
|
+
# and manage IP access lists in an easy way. You may use
|
9
|
+
# IPAccess::Set class to maintain inpu/output traffic control.
|
10
|
+
# You also may use IPAccess::List class directly to build
|
11
|
+
# your own access sets based on black lists and white lists.
|
12
|
+
|
13
|
+
require 'ipaccess/patches/netaddr'
|
14
|
+
require 'ipaccess/ip_access_list'
|
15
|
+
require 'ipaccess/ip_access_set'
|
16
|
+
|
17
|
+
# This module contains classes that are used to control IP access.
|
18
|
+
# There are three major components you may want to use:
|
19
|
+
#
|
20
|
+
# === IPAccess::List class
|
21
|
+
#
|
22
|
+
# This class lets you create IP access list with blacklisted
|
23
|
+
# and whitelisted elements. It also has methods for checking
|
24
|
+
# whether given IP matches the list.
|
25
|
+
#
|
26
|
+
# === IPAccess::Set class
|
27
|
+
#
|
28
|
+
# This class contains two objects that are instances
|
29
|
+
# of IPAccess::List class. It allows you to create so
|
30
|
+
# called access set. The access set contains members named
|
31
|
+
# +input+ and +output+. All methods that validate IP access do it
|
32
|
+
# against one of the lists. Input access list is for incomming
|
33
|
+
# and output for outgoing IP traffic. In case of connection-oriented
|
34
|
+
# sockets and other network objects the convention is to use output access
|
35
|
+
# list to validate connections that we initiate. The incomming traffic
|
36
|
+
# in that model means the connections initiated by a remote peer.
|
37
|
+
#
|
38
|
+
# === Patching engine
|
39
|
+
#
|
40
|
+
# IPAccess was initialy considered as a set of classes that you may use
|
41
|
+
# in your own programs to control IP access. That means your own classes
|
42
|
+
# used for communication should use access lists or sets before making any
|
43
|
+
# real connections or sending any datagrams.
|
44
|
+
#
|
45
|
+
# Fortunately there are many network classes, including sockets, that Ruby ships with.
|
46
|
+
# It would be waste of resources to not modify them to support IP access control
|
47
|
+
# and automagically throw exceptions when access should be denied.
|
48
|
+
#
|
49
|
+
# And here the special module method called +IPAccess.arm+
|
50
|
+
# comes in. It lets you patch most of Ruby's networking classes and objects. Besides
|
51
|
+
# equipping them in IPAccess::Set instance it also adds some methods for doing quick
|
52
|
+
# checks and changes in access lists.
|
53
|
+
#
|
54
|
+
# The patching engine can arm network classes and single network objects.
|
55
|
+
# It is not loaded by default since you may not want extra code attached to a
|
56
|
+
# program that uses access lists or sets with own access checking code.
|
57
|
+
#
|
58
|
+
# === Variants of popular classes
|
59
|
+
#
|
60
|
+
# Sometimes you want to write a code that uses standard Ruby's network objects
|
61
|
+
# but you find it dirty to alter classes or objects. In that case you may
|
62
|
+
# want to use static variants of Ruby's network classes that are not patches
|
63
|
+
# but derived classes.
|
64
|
+
#
|
65
|
+
# === Exceptions
|
66
|
+
#
|
67
|
+
# When you are dealing with patched (armed) versions of classes and objects
|
68
|
+
# or when you are using special variants of popular network classes, you have
|
69
|
+
# to rely on exceptions as the only way for access checking methods to tell
|
70
|
+
# your program that an event (like access denied) happened.
|
71
|
+
#
|
72
|
+
# Note that when exception is thrown the communication session is closed in case
|
73
|
+
# of connection-oriented network objects. You may change it by setting
|
74
|
+
# +opened_on_deny+ attribute to +true+.
|
75
|
+
#
|
76
|
+
# See IPAccess::Set#check_in to know more about tracking original network object
|
77
|
+
# that caused exception to happend. Note that in case of armed versions of network
|
78
|
+
# classes (or access-contolled variants) an information about original network
|
79
|
+
# object stored within an exception will be set to +nil+ if access had been denied before
|
80
|
+
# object was initialized. This shouldn't happend often, since access checks are lazy
|
81
|
+
# (they are performed only when connection is going to be made).
|
82
|
+
#
|
83
|
+
# See IPAccessDenied for more information about what you can do with exceptions.
|
84
|
+
#
|
85
|
+
# === Sockets in armed network objects
|
86
|
+
#
|
87
|
+
# Specialized Ruby's network classes, such as Net::HTTP or Net::Telnet
|
88
|
+
# and their variants created by this library, make use of socket objects.
|
89
|
+
# For example Net::HTTP class uses TCPSocket instance to
|
90
|
+
# create TCP connection. When versions of these <tt>Net::</tt> objects with
|
91
|
+
# enabled access control are used then the internal routines of IPAccess
|
92
|
+
# will also try to patch underlying sockets and assign to them the same
|
93
|
+
# access set that is used by main object. It is done to avoid access leaks.
|
94
|
+
# However, such armed internal sockets will have +opened_on_deny+ flag switched on
|
95
|
+
# since closing session (and an eventual connection) should be settled by main object.
|
96
|
+
#
|
97
|
+
# === Ordination of elements
|
98
|
+
#
|
99
|
+
# To properly understand what are the most important structures mentioned above it's worth
|
100
|
+
# to look at the diagram:
|
101
|
+
#
|
102
|
+
# link:images/ipaccess_view.png
|
103
|
+
#
|
104
|
+
# == Usage
|
105
|
+
#
|
106
|
+
# === Handling access sets and access lists
|
107
|
+
#
|
108
|
+
# If you need just IP access lists that you will handle in your own way
|
109
|
+
# you may want to use two classes:
|
110
|
+
#
|
111
|
+
# * IPAccess::Set to maintain access sets (containing input and output access lists),
|
112
|
+
# * IPAccess::List to maintain single access list.
|
113
|
+
#
|
114
|
+
# === Using socket classes
|
115
|
+
#
|
116
|
+
# If you want standard sockets to have access control enabled
|
117
|
+
# you may want to use:
|
118
|
+
#
|
119
|
+
# * IPAccess::Socket (or issue <tt>IPAccess.arm Socket</tt>)
|
120
|
+
# * IPAccess::TCPSocket (or issue <tt>IPAccess.arm TCPSocket</tt>)
|
121
|
+
# * IPAccess::UDPSocket (or issue <tt>IPAccess.arm UDPSocket</tt>)
|
122
|
+
# * IPAccess::SOCKSocket (or issue <tt>IPAccess.arm SOCKSocket</tt>)
|
123
|
+
# * IPAccess::TCPServer (or issue <tt>IPAccess.arm TCPServer</tt>)
|
124
|
+
#
|
125
|
+
# Before using any of them you must issue:
|
126
|
+
#
|
127
|
+
# * <tt>require 'ipaccess/socket'</tt>
|
128
|
+
#
|
129
|
+
# Using the IPAccess.arm causes standard socket class to be altered,
|
130
|
+
# while <tt>IPAccess::</tt> classes are just new variants of socket
|
131
|
+
# handling classes.
|
132
|
+
#
|
133
|
+
# ==== Using other supported network classes
|
134
|
+
#
|
135
|
+
# If you want some working objects to have access control enabled
|
136
|
+
# you may want to use:
|
137
|
+
#
|
138
|
+
# * IPAccess::Net::Telnet (or issue <tt>IPAccess.arm Net::Telnet</tt>)
|
139
|
+
# * IPAccess::Net::HTTP (or issue <tt>IPAccess.arm Net::HTTP</tt>)
|
140
|
+
# * IPAccess::Net::FTP (or issue <tt>IPAccess.arm Net::FTP</tt>)
|
141
|
+
# * IPAccess::Net::POP3 (or issue <tt>IPAccess.arm Net::POP3</tt>)
|
142
|
+
# * IPAccess::Net::IMAP (or issue <tt>IPAccess.arm Net::IMAP</tt>)
|
143
|
+
# * IPAccess::Net::SMTP (or issue <tt>IPAccess.arm Net::SMTP</tt>)
|
144
|
+
#
|
145
|
+
# ==== Using single network objects
|
146
|
+
#
|
147
|
+
# If you want to enable access control for single network
|
148
|
+
# object from the list shown above you may issue:
|
149
|
+
#
|
150
|
+
# require 'ipaccess/net/http'
|
151
|
+
# obj = Net::HTTP.new(host, port)
|
152
|
+
# IPAccess.arm obj
|
153
|
+
#
|
154
|
+
# or
|
155
|
+
#
|
156
|
+
# require 'ipaccess/socket'
|
157
|
+
# socket = IPAccess::TCPServer.new(31337)
|
158
|
+
# IPAccess.arm socket
|
159
|
+
#
|
160
|
+
# ..and so on.
|
161
|
+
#
|
162
|
+
# === Structures
|
163
|
+
#
|
164
|
+
# IP addresses used by the classes are internaly and interfacialy
|
165
|
+
# represented by NetAddr::CIDR[http://netaddr.rubyforge.org/classes/NetAddr/CIDR.html]
|
166
|
+
# objects (NetAddr::CIDRv4[http://netaddr.rubyforge.org/classes/NetAddr/CIDRv4.html] and
|
167
|
+
# NetAddr::CIDRv6[http://netaddr.rubyforge.org/classes/NetAddr/CIDRv6.html]). Due to
|
168
|
+
# performance reasons any access list internally is represented as a tree
|
169
|
+
# (slightly modified NetAddr::Tree[http://netaddr.rubyforge.org/classes/NetAddr/Tree.html])
|
170
|
+
# with special tags assigning rules to virtual lists.
|
171
|
+
#
|
172
|
+
# === Relations
|
173
|
+
#
|
174
|
+
# Here is a diagram which shows relations
|
175
|
+
# between the IPAccess::TCPSocket class
|
176
|
+
# and other classes from this module:
|
177
|
+
#
|
178
|
+
# link:images/ipaccess_relations.png
|
179
|
+
|
180
|
+
module IPAccess
|
181
|
+
|
182
|
+
# This method converts names to NetAddr::CIDR objects. It returns an array of CIDR objects.
|
183
|
+
#
|
184
|
+
# Allowed input are strings (DNS names or IP addresses optionally with masks),
|
185
|
+
# numbers (IP addresses representation), IPSocket objects, URI objects, IPAddr objects,
|
186
|
+
# Net::HTTP objects, IPAddrList objects, NetAddr::CIDR objects, NetAddr::Tree objects,
|
187
|
+
# IPAccess::List objects, symbols, objects that contain file descriptors bound to sockets
|
188
|
+
# (including OpenSSL sockets) and arrays of these.
|
189
|
+
#
|
190
|
+
# In case of resolving the IPv6 link-local addresses
|
191
|
+
# zone index is removed. In case of DNS names there may
|
192
|
+
# occur Resolv::ResolvError exception. If there is an
|
193
|
+
# object that cannot be converted the ArgumentError
|
194
|
+
# exception is raised.
|
195
|
+
#
|
196
|
+
# When an argument called +:include_origins+ is present then the method will attach
|
197
|
+
# original converted objects to results as the +:Origin+ tag of CIDR objects
|
198
|
+
# (<tt>tag[:Origin]</tt>). This rule applies only to single objects or objects
|
199
|
+
# inside of arrays or sets. Objects that are kind of NetAddr::CIDR, IPAccess::Set,
|
200
|
+
# NetAddr::Tree and arrays will never be set as originators.
|
201
|
+
#
|
202
|
+
# ==== Examples
|
203
|
+
#
|
204
|
+
# to_cidrs("127.0.0.1") # uses the IP address
|
205
|
+
# to_cidrs(2130706433) # uses numeric representation of 127.0.0.1
|
206
|
+
# to_cidrs(:private, "localhost") # uses special symbol and DNS hostname
|
207
|
+
# to_cidrs(:private, :localhost) # uses special symbols
|
208
|
+
# to_cidrs [:private, :auto] # other way to write the above
|
209
|
+
# to_cidrs "10.0.0.0/8" # uses masked IP address
|
210
|
+
# to_cidrs "10.0.0.0/255.0.0.0" # uses masked IP address
|
211
|
+
# to_cidrs IPSocket.new("www.pl", 80) # uses the socket
|
212
|
+
# to_cidrs IPAddr("10.0.0.1") # uses IPAddr object
|
213
|
+
# to_cidrs NetAddr::CIDR.create("10.0.0.1") # uses NetAddr object
|
214
|
+
# to_cidrs URI('http://www.pl/') # uses URI
|
215
|
+
# to_cidrs 'http://www.pl/' # uses the extracted host string
|
216
|
+
# to_cidrs 'somehost.xx' # uses the host string (fetches ALL addresses from DNS)
|
217
|
+
# to_cidrs 'somehost.xx/16' # uses the host string and a netmask
|
218
|
+
#
|
219
|
+
# ==== Special symbols
|
220
|
+
#
|
221
|
+
# When symbol is passed to this method it tries to find out if it has special meaning.
|
222
|
+
# That allows you to create access rules in an easy way. For most of them you may
|
223
|
+
# also specify IP protocol version using +ipv4_+ or +ipv6_+ prefix.
|
224
|
+
#
|
225
|
+
# Known symbols are:
|
226
|
+
#
|
227
|
+
# <b>+:all+</b> (+:any+, +:anyone+, +:world+, +:internet+, +:net+, +:everything+, +:everyone+, +:everybody+, +:anybody+)
|
228
|
+
#
|
229
|
+
# variants: +:ipv4_+ and +:ipv6_+
|
230
|
+
#
|
231
|
+
# Creates masked IP address that matches all networks:
|
232
|
+
# – 0.0.0.0/0
|
233
|
+
# – ::/0
|
234
|
+
#
|
235
|
+
# <b>+:broadcast+</b> (+:brd+)
|
236
|
+
#
|
237
|
+
# variants: +:ipv4_+ and +:ipv6_+
|
238
|
+
#
|
239
|
+
# Creates masked IP address that matches generic broadcast address:
|
240
|
+
# – 255.255.255.255/32
|
241
|
+
# – ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128
|
242
|
+
#
|
243
|
+
# <b>+:local+</b> (+:localhost+, +:localdomain+, +:loopback+, +:lo+)
|
244
|
+
#
|
245
|
+
# variants: +:ipv4_+ and +:ipv6_+
|
246
|
+
#
|
247
|
+
# Creates masked IP addresses that match localhost:
|
248
|
+
# – 127.0.0.1/8
|
249
|
+
# – ::1/128
|
250
|
+
#
|
251
|
+
# <b>+:auto+</b> (+:automatic+, +:linklocal+)
|
252
|
+
#
|
253
|
+
# variants: +:ipv4_+ and +:ipv6_+
|
254
|
+
#
|
255
|
+
# Creates masked IP addresses that match automatically assigned address ranges:
|
256
|
+
# – 169.254.0.0/16
|
257
|
+
# – fe80::/10
|
258
|
+
#
|
259
|
+
# <b>+:private+</b> (+:intra+, +:intranet+, +:internal+)
|
260
|
+
#
|
261
|
+
# variants: +:ipv4_+ and +:ipv6_+
|
262
|
+
#
|
263
|
+
# Creates masked IP addresses that match private ranges:
|
264
|
+
# – 10.0.0.0/8
|
265
|
+
# – 172.16.0.0/12
|
266
|
+
# – 192.168.0.0/16
|
267
|
+
# – 2001:10::/28
|
268
|
+
# – 2001:db8::/32
|
269
|
+
# – fc00::/7
|
270
|
+
# – fdde:9e1a:dc85:7374::/64
|
271
|
+
#
|
272
|
+
# <b>+:multicast+</b> (+:multi+, +:multiemission+)
|
273
|
+
#
|
274
|
+
# variants: +:ipv4_+ and +:ipv6_+
|
275
|
+
#
|
276
|
+
# Creates masked IP addresses that match multicast addresses ranges:
|
277
|
+
# – 224.0.0.0/4
|
278
|
+
# – ff00::/8
|
279
|
+
# – ff02::1:ff00:0/104
|
280
|
+
#
|
281
|
+
# <b>+:reserved+</b> (+:example+)
|
282
|
+
#
|
283
|
+
# variants: +:ipv4_+
|
284
|
+
#
|
285
|
+
# Creates masked IP addresses that match reserved addresses ranges:
|
286
|
+
# – 192.0.2.0/24
|
287
|
+
# – 128.0.0.0/16
|
288
|
+
# – 191.255.0.0/16
|
289
|
+
# – 192.0.0.0/24
|
290
|
+
# – 198.18.0.0/15
|
291
|
+
# – 223.255.255.0/24
|
292
|
+
# – 240.0.0.0/4
|
293
|
+
#
|
294
|
+
# <b>+:strange+</b> (+:unusual+, +:nonpublic+, +:unpublic+)
|
295
|
+
#
|
296
|
+
# Creates masked IP addressess that match the following sets (both IPv4 and IPv6):
|
297
|
+
# – :local
|
298
|
+
# – :auto
|
299
|
+
# – :private
|
300
|
+
# – :reserved
|
301
|
+
# – :multicast
|
302
|
+
|
303
|
+
def self.to_cidrs(*addresses)
|
304
|
+
obj = addresses.flatten
|
305
|
+
include_origins = !!obj.reject!{ |x| x.is_a?(Symbol) && x == :include_origins }
|
306
|
+
if obj.size == 1
|
307
|
+
obj = obj.first
|
308
|
+
else
|
309
|
+
ary = []
|
310
|
+
obj.each do |o|
|
311
|
+
ary += ( include_origins ? to_cidrs(o, :include_origins) : to_cidrs(o) )
|
312
|
+
end
|
313
|
+
ary.flatten!
|
314
|
+
return ary
|
315
|
+
end
|
316
|
+
|
317
|
+
ori_obj = obj
|
318
|
+
|
319
|
+
# NetAddr::CIDR - immediate generation
|
320
|
+
if obj.is_a?(NetAddr::CIDR)
|
321
|
+
r = obj.dup
|
322
|
+
r.tag[:Originator] = ori_obj if include_origins
|
323
|
+
return [r]
|
324
|
+
end
|
325
|
+
|
326
|
+
# IPAccess::List - immediate generation
|
327
|
+
return obj.to_a if obj.is_a?(IPAccess::List)
|
328
|
+
|
329
|
+
# NetAddr::Tree - immediate generation
|
330
|
+
return obj.dump.map { |addr| addr[:CIDR] } if obj.is_a?(NetAddr::Tree)
|
331
|
+
|
332
|
+
# number or nil - immediate generation or exception
|
333
|
+
if (obj.is_a?(Numeric) || obj.nil?)
|
334
|
+
r = NetAddr::CIDR.create(obj)
|
335
|
+
r.tag[:Originator] = ori_obj if include_origins
|
336
|
+
return [r]
|
337
|
+
end
|
338
|
+
|
339
|
+
# object containing socket member (e.g. Net::HTTP) - fetch socket
|
340
|
+
if obj.respond_to?(:socket)
|
341
|
+
obj = obj.socket
|
342
|
+
elsif obj.respond_to?(:sock)
|
343
|
+
obj = obj.sock
|
344
|
+
elsif obj.respond_to?(:client_socket)
|
345
|
+
obj = obj.client_socket
|
346
|
+
elsif obj.instance_variable_defined?(:@socket)
|
347
|
+
obj = obj.instance_variable_get(:@socket)
|
348
|
+
elsif obj.instance_variable_defined?(:@client_socket)
|
349
|
+
obj = obj.instance_variable_get(:@client_socket)
|
350
|
+
elsif obj.instance_variable_defined?(:@sock)
|
351
|
+
obj = obj.instance_variable_get(:@sock)
|
352
|
+
end
|
353
|
+
obj = obj.io if (obj.respond_to?(:io) && obj.io.respond_to?(:getpeername))
|
354
|
+
|
355
|
+
# some file descriptor but not socket - fetch socket
|
356
|
+
obj = ::Socket.for_fd(obj.fileno) if (!obj.respond_to?(:getpeername) && obj.respond_to?(:fileno))
|
357
|
+
|
358
|
+
# Socket - immediate generation
|
359
|
+
if obj.respond_to?(:getpeername)
|
360
|
+
peeraddr = ::Socket.unpack_sockaddr_in(obj.getpeername).last.split('%').first
|
361
|
+
r = NetAddr::CIDR.create(peeraddr)
|
362
|
+
r.tag[:Originator] = ori_obj if include_origins
|
363
|
+
return [r]
|
364
|
+
end
|
365
|
+
|
366
|
+
# symbol - immediate generation
|
367
|
+
r_args = nil
|
368
|
+
if obj.is_a?(Symbol)
|
369
|
+
case obj
|
370
|
+
when :ipv4_all, :ipv4_any, :ipv4_anyone, :ipv4_world, :ipv4_internet, :ipv4_net, :ipv4_everything, :ipv4_everyone, :ipv4_everybody, :ipv4_anybody
|
371
|
+
obj = [ "0.0.0.0/0" ]
|
372
|
+
when :ipv6_all, :ipv6_any, :ipv6_anyone, :ipv6_world, :ipv6_internet, :ipv6_net, :ipv6_everything, :ipv6_everyone, :ipv6_everybody, :ipv6_anybody
|
373
|
+
obj = [ "0.0.0.0/0", "::/0" ]
|
374
|
+
when :ipv4_broadcast, :ipv4_brd
|
375
|
+
obj = [ "255.255.255.255/32" ]
|
376
|
+
when :ipv6_broadcast, :ipv6_brd
|
377
|
+
obj = [ "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128" ]
|
378
|
+
when :ipv4_local, :ipv4_localhost, :ipv4_loopback, :ipv4_lo
|
379
|
+
obj = [ "127.0.0.1/8" ]
|
380
|
+
when :ipv6_local, :ipv6_localhost, :ipv6_loopback, :ipv6_lo
|
381
|
+
obj = [ "::1/128" ]
|
382
|
+
when :ipv4_auto, :ipv4_automatic, :ipv4_linklocal
|
383
|
+
obj = [ "169.254.0.0/16" ]
|
384
|
+
when :ipv6_auto, :ipv6_automatic, :ipv6_linklocal
|
385
|
+
obj = [ "fe80::/10" ]
|
386
|
+
when :ipv4_private, :ipv4_intra, :ipv4_intranet, :ipv4_internal
|
387
|
+
obj = [ "10.0.0.0/8",
|
388
|
+
"172.16.0.0/12",
|
389
|
+
"192.168.0.0/16" ]
|
390
|
+
when :ipv6_private, :ipv6_intra, :ipv6_intranet, :ipv6_internal, :ipv6_ula, :ipv6_unique
|
391
|
+
obj = [ "2001:10::/28",
|
392
|
+
"2001:db8::/32",
|
393
|
+
"fc00::/7",
|
394
|
+
"fdde:9e1a:dc85:7374::/64" ]
|
395
|
+
when :ipv4_multicast, :ipv4_multi, :ipv4_multiemission
|
396
|
+
obj = [ "224.0.0.0/4" ]
|
397
|
+
when :ipv6_multicast, :ipv6_multi, :ipv6_multiemission
|
398
|
+
obj = [ "ff00::/8",
|
399
|
+
"ff02::1:ff00:0/104" ]
|
400
|
+
when :ipv4_example, :ipv4_reserved
|
401
|
+
obj = [ "192.0.2.0/24",
|
402
|
+
"128.0.0.0/16",
|
403
|
+
"191.255.0.0/16",
|
404
|
+
"192.0.0.0/24",
|
405
|
+
"198.18.0.0/15",
|
406
|
+
"223.255.255.0/24",
|
407
|
+
"240.0.0.0/4" ]
|
408
|
+
when :all, :any, :anyone, :world, :internet, :net, :everything, :everyone, :everybody, :anybody
|
409
|
+
r_args = [ :ipv4_all,
|
410
|
+
:ipv6_all ]
|
411
|
+
when :broadcast, :brd
|
412
|
+
r_args = [ :ipv4_broadcast,
|
413
|
+
:ipv6_broadcast ]
|
414
|
+
when :local, :localhost, :localdomain, :loopback, :lo
|
415
|
+
r_args = [ :ipv4_local,
|
416
|
+
:ipv6_local ]
|
417
|
+
when :auto, :automatic, :linklocal
|
418
|
+
r_args = [ :ipv4_auto,
|
419
|
+
:ipv6_auto ]
|
420
|
+
when :private, :intra, :intranet, :internal
|
421
|
+
r_args = [ :ipv4_private,
|
422
|
+
:ipv6_private ]
|
423
|
+
when :multicast, :multi, :multiemission
|
424
|
+
r_args = [ :ipv4_multicast,
|
425
|
+
:ipv6_multicast ]
|
426
|
+
when :reserved, :example
|
427
|
+
r_args = [ :ipv4_example ]
|
428
|
+
when :strange, :unusual, :nonpublic, :unpublic
|
429
|
+
r_args = [ :local,
|
430
|
+
:auto,
|
431
|
+
:private,
|
432
|
+
:reserved,
|
433
|
+
:multicast ]
|
434
|
+
else
|
435
|
+
raise ArgumentError, "Provided symbol is unknown: #{obj.to_s}"
|
436
|
+
end
|
437
|
+
|
438
|
+
unless r_args.nil?
|
439
|
+
r_args.push :include_origins if include_origins
|
440
|
+
return to_cidrs(*r_args)
|
441
|
+
end
|
442
|
+
|
443
|
+
# strange types here
|
444
|
+
if obj.is_a?(Array)
|
445
|
+
return obj.map do |addr|
|
446
|
+
r = NetAddr::CIDR.create(addr)
|
447
|
+
r.tag[:Originator] = addr if include_origins
|
448
|
+
r
|
449
|
+
end
|
450
|
+
end
|
451
|
+
end
|
452
|
+
|
453
|
+
# URI or something that responds to host method - fetch string
|
454
|
+
obj = obj.host if obj.respond_to?(:host)
|
455
|
+
|
456
|
+
# objects of external classes
|
457
|
+
case obj.class.name.to_sym
|
458
|
+
when :IPAddr # IPAddr - fetch IP/mask string
|
459
|
+
obj = obj.native.inspect.split[1].chomp('>')[5..-1]
|
460
|
+
when :IPAddrList # IPAddrList - pass array to parse
|
461
|
+
return include_origins ? to_cidrs(obj.to_a, :include_origins) : to_cidrs(obj.to_a)
|
462
|
+
end
|
463
|
+
|
464
|
+
# string or similar - immediate generation
|
465
|
+
if obj.respond_to?(:to_s)
|
466
|
+
hostmask = ""
|
467
|
+
obj = obj.to_s
|
468
|
+
# URI
|
469
|
+
if obj =~ /^[^:]+:\/\/(.*)/
|
470
|
+
obj = $1.split('/').first
|
471
|
+
# IP in URI
|
472
|
+
if obj =~ /^\[([^\]]+)\]/
|
473
|
+
obj = $1
|
474
|
+
else
|
475
|
+
obj = obj.split(':').first
|
476
|
+
end
|
477
|
+
# host(s) and a mask
|
478
|
+
elsif obj =~ /^([^\/]+)(\/((\d{1,2}$)|(\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b$)))/
|
479
|
+
obj = $1
|
480
|
+
hostmask = $2
|
481
|
+
end
|
482
|
+
begin
|
483
|
+
ipa = obj.split('%').first.to_s
|
484
|
+
r = NetAddr::CIDR.create(ipa + hostmask)
|
485
|
+
rescue NetAddr::ValidationError
|
486
|
+
begin
|
487
|
+
addresses = Resolv::getaddresses(obj)
|
488
|
+
rescue NoMethodError # unhandled error
|
489
|
+
raise Resolv::ResolvError, "not connected or network error"
|
490
|
+
end
|
491
|
+
addresses.map! do |addr|
|
492
|
+
begin
|
493
|
+
r = NetAddr::CIDR.create(addr.split('%').first + hostmask)
|
494
|
+
r.tag[:Originator] = ori_obj
|
495
|
+
r
|
496
|
+
rescue ArgumentError
|
497
|
+
nil
|
498
|
+
end
|
499
|
+
end
|
500
|
+
addresses.flatten!
|
501
|
+
addresses.compact!
|
502
|
+
return addresses
|
503
|
+
end
|
504
|
+
r.tag[:Originator] = ori_obj
|
505
|
+
return [r]
|
506
|
+
end
|
507
|
+
|
508
|
+
# should never happend
|
509
|
+
r = obj.is_a?(NetAddr::CIDR) ? obj.dup : NetAddr::CIDR.create(obj.to_s)
|
510
|
+
r.tag[:Originator] = ori_obj
|
511
|
+
return [r]
|
512
|
+
end
|
513
|
+
|
514
|
+
# This method calls IPAccess.to_cidrs
|
515
|
+
# and returns first obtained entry containing
|
516
|
+
# single IP address with mask (NetAddr::CIDR).
|
517
|
+
|
518
|
+
def self.to_cidr(*addresses)
|
519
|
+
r = self.to_cidrs(*addresses)
|
520
|
+
return r.respond_to?(:first) ? first : r
|
521
|
+
end
|
522
|
+
|
523
|
+
end
|