antfarm-core 0.5.0.beta1

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.
@@ -0,0 +1,90 @@
1
+ ################################################################################
2
+ # #
3
+ # Copyright (2008-2010) Sandia Corporation. Under the terms of Contract #
4
+ # DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains #
5
+ # certain rights in this software. #
6
+ # #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy #
8
+ # of this software and associated documentation files (the "Software"), to #
9
+ # deal in the Software without restriction, including without limitation the #
10
+ # rights to use, copy, modify, merge, publish, distribute, distribute with #
11
+ # modifications, sublicense, and/or sell copies of the Software, and to permit #
12
+ # persons to whom the Software is furnished to do so, subject to the following #
13
+ # conditions: #
14
+ # #
15
+ # The above copyright notice and this permission notice shall be included in #
16
+ # all copies or substantial portions of the Software. #
17
+ # #
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #
21
+ # ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, #
22
+ # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR #
23
+ # IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE #
24
+ # SOFTWARE. #
25
+ # #
26
+ # Except as contained in this notice, the name(s) of the above copyright #
27
+ # holders shall not be used in advertising or otherwise to promote the sale, #
28
+ # use or other dealings in this Software without prior written authorization. #
29
+ # #
30
+ ################################################################################
31
+
32
+ module Antfarm
33
+ module Plugin
34
+ module Cisco
35
+ class FileDoesNotExistError < Antfarm::AntfarmError; end
36
+
37
+ class ParseArp
38
+ include Antfarm::Plugin
39
+
40
+ def initialize
41
+ super({ :name => 'Parse ARP',
42
+ :desc => 'Parse an ARP dump from a Cisco network device',
43
+ :author => 'Bryan T. Richardson <btricha>' },
44
+ [ { :name => :input,
45
+ :desc => 'Dump file or directory',
46
+ :type => String,
47
+ :required => true }
48
+ ])
49
+ end
50
+
51
+ def run(options)
52
+ input = options[:input]
53
+
54
+ if File.directory?(input)
55
+ Find.find(input) do |path|
56
+ if File.file?(path)
57
+ parse(path)
58
+ end
59
+ end
60
+ else
61
+ parse(input)
62
+ end
63
+ end
64
+
65
+ def parse(file)
66
+ print_message "Parsing file #{file}"
67
+
68
+ begin
69
+ File.open(file) do |list|
70
+ list.each do |line|
71
+ (junk, ip_addr, ethernet_addr) = line.split(' ')
72
+ ip_addr.strip!
73
+ ethernet_addr.strip!
74
+
75
+ Antfarm::Model::IpInterface.create(:address => ip_addr, :ethernet_address => ethernet_addr)
76
+ end
77
+ end
78
+
79
+ # TODO: merge by ethernet address
80
+
81
+ rescue Error::ENOENT
82
+ raise FileDoesNotExistError, "The file '#{file}' doesn't exist"
83
+ rescue Exception => e
84
+ raise Antfarm::AntfarmError, e.message
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,126 @@
1
+ ################################################################################
2
+ # #
3
+ # Copyright (2008-2010) Sandia Corporation. Under the terms of Contract #
4
+ # DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains #
5
+ # certain rights in this software. #
6
+ # #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy #
8
+ # of this software and associated documentation files (the "Software"), to #
9
+ # deal in the Software without restriction, including without limitation the #
10
+ # rights to use, copy, modify, merge, publish, distribute, distribute with #
11
+ # modifications, sublicense, and/or sell copies of the Software, and to permit #
12
+ # persons to whom the Software is furnished to do so, subject to the following #
13
+ # conditions: #
14
+ # #
15
+ # The above copyright notice and this permission notice shall be included in #
16
+ # all copies or substantial portions of the Software. #
17
+ # #
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #
21
+ # ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, #
22
+ # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR #
23
+ # IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE #
24
+ # SOFTWARE. #
25
+ # #
26
+ # Except as contained in this notice, the name(s) of the above copyright #
27
+ # holders shall not be used in advertising or otherwise to promote the sale, #
28
+ # use or other dealings in this Software without prior written authorization. #
29
+ # #
30
+ ################################################################################
31
+
32
+ module Antfarm
33
+ module Plugin
34
+ module Cisco
35
+ class FileDoesNotExistError < Antfarm::AntfarmError; end
36
+
37
+ class ParseInterfaces
38
+ include Antfarm::Plugin
39
+
40
+ def initialize
41
+ super({ :name => 'Parse Interfaces',
42
+ :desc => 'Parse Cisco IOS configuration file, looking for IP interfaces',
43
+ :author => 'Bryan T. Richardson <btricha>' },
44
+ [ { :name => :input_file,
45
+ :desc => 'Cisco IOS config file',
46
+ :type => String,
47
+ :required => true }
48
+ ])
49
+ end
50
+
51
+ def run(options)
52
+ print_message "Parsing file #{options[:input_file]}"
53
+
54
+ begin
55
+ pix_version_regexp = Regexp.new('^PIX Version ((\d+)\.(\d+)\((\d+)\))')
56
+ hostname_regexp = Regexp.new('^hostname (\S+)')
57
+ iface_regexp = Regexp.new('^interface')
58
+ ipv4_regexp = Regexp.new('((\d){1,3}\.(\d){1,3}\.(\d){1,3}\.(\d){1,3})')
59
+ ip_addr_regexp = Regexp.new('^ip address (\S+) %s %s' % [ipv4_regexp, ipv4_regexp])
60
+ iface_ip_addr_regexp = Regexp.new('^\s*ip address %s %s' % [ipv4_regexp, ipv4_regexp])
61
+
62
+ pix_version = nil
63
+ hostname = nil
64
+ iface_ips = Array.new
65
+ capture_iface = false
66
+
67
+ File.open(options[:input_file]) do |file|
68
+ file.each do |line|
69
+ # Get PIX IOS version
70
+ unless pix_version
71
+ if version = pix_version_regexp.match(line)
72
+ pix_version = version[2].to_i
73
+ end
74
+ end
75
+
76
+ # Get hostname
77
+ unless hostname
78
+ if name = hostname_regexp.match(line)
79
+ hostname = name[1]
80
+ end
81
+ end
82
+
83
+ # Get interface IP addresses
84
+ if pix_version == 6
85
+ if ip_addr = ip_addr_regexp.match(line)
86
+ iface_ips << "#{ip_addr[2]}/#{ip_addr[7]}"
87
+ end
88
+ elsif capture_iface
89
+ if line.strip! == "!"
90
+ capture_iface = false
91
+ else
92
+ if ip_addr = iface_ip_addr_regexp.match(line)
93
+ iface_ips << "#{ip_addr[1]}/#{ip_addr[6]}"
94
+ capture_iface = false
95
+ end
96
+ end
97
+ else
98
+ if iface = iface_regexp.match(line)
99
+ capture_iface = true
100
+ end
101
+ end
102
+ end
103
+ end
104
+
105
+ iface_ips.uniq!
106
+ iface_ips.each do |address|
107
+ ip_iface = Antfarm::Model::IpInterface.new :address => address
108
+ ip_iface.node_name = hostname if hostname
109
+ ip_iface.node_device_type = "Layer 3 Device"
110
+
111
+ unless ip_iface.save
112
+ ip_iface.errors.each_full do |msg|
113
+ print_error msg
114
+ end
115
+ end
116
+ end
117
+ rescue Errno::ENOENT
118
+ raise FileDoesNotExistError, "The file '#{options[:input_file]}' doesn't exist"
119
+ rescue Exception => e
120
+ raise Antfarm::AntfarmError, e.message
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,105 @@
1
+ ################################################################################
2
+ # #
3
+ # Copyright (2008-2010) Sandia Corporation. Under the terms of Contract #
4
+ # DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains #
5
+ # certain rights in this software. #
6
+ # #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy #
8
+ # of this software and associated documentation files (the "Software"), to #
9
+ # deal in the Software without restriction, including without limitation the #
10
+ # rights to use, copy, modify, merge, publish, distribute, distribute with #
11
+ # modifications, sublicense, and/or sell copies of the Software, and to permit #
12
+ # persons to whom the Software is furnished to do so, subject to the following #
13
+ # conditions: #
14
+ # #
15
+ # The above copyright notice and this permission notice shall be included in #
16
+ # all copies or substantial portions of the Software. #
17
+ # #
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #
21
+ # ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, #
22
+ # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR #
23
+ # IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE #
24
+ # SOFTWARE. #
25
+ # #
26
+ # Except as contained in this notice, the name(s) of the above copyright #
27
+ # holders shall not be used in advertising or otherwise to promote the sale, #
28
+ # use or other dealings in this Software without prior written authorization. #
29
+ # #
30
+ ################################################################################
31
+
32
+ module Antfarm
33
+ module Plugin
34
+ module Cisco
35
+ class FileDoesNotExistError < Antfarm::AntfarmError; end
36
+
37
+ class ParseNetworkObjects
38
+ include Antfarm::Plugin
39
+
40
+ def initialize
41
+ super({ :name => 'Parse Network Objects',
42
+ :desc => 'Parses a Cisco IOS config file and creates an IP Interface for each network object',
43
+ :author => 'Bryan T. Richardson <btricha>' },
44
+ [ { :name => :input,
45
+ :desc => 'Cisco IOS config file or directory',
46
+ :type => String,
47
+ :required => true }
48
+ ])
49
+ end
50
+
51
+ def run(options)
52
+ input = options[:input]
53
+
54
+ if File.directory?(input)
55
+ Find.find(input) do |path|
56
+ if File.file?(path)
57
+ parse(path)
58
+ end
59
+ end
60
+ else
61
+ parse(input)
62
+ end
63
+ end
64
+
65
+ def parse(file)
66
+ print_message "Parsing file #{file}"
67
+
68
+ begin
69
+ net_obj_host_regexp = Regexp.new('^\s*network-object host ((\d){1,3}\.(\d){1,3}\.(\d){1,3}\.(\d){1,3})')
70
+
71
+ net_obj_hosts = Array.new
72
+
73
+ File.open(file) do |list|
74
+ list.each do |line|
75
+ # Get network object hosts
76
+ if net_obj_host = net_obj_host_regexp.match(line)
77
+ net_obj_hosts << net_obj_host[1]
78
+ end
79
+ end
80
+ end
81
+
82
+ net_obj_hosts.uniq!
83
+ net_obj_hosts.each do |address|
84
+ if Antfarm::Model::LayerThreeNetwork.network_containing(address)
85
+ ip_iface = Antfarm::Model::IpInterface.new :address => address
86
+ ip_iface.node_name = address
87
+ ip_iface.node_device_type = "HOST"
88
+
89
+ unless ip_iface.save
90
+ ip_iface.errors.each_full do |msg|
91
+ print_error msg
92
+ end
93
+ end
94
+ end
95
+ end
96
+ rescue Errno::ENOENT
97
+ raise FileDoesNotExistError, "The file #{file} doesn't exist"
98
+ rescue Exception => e
99
+ raise Antfarm::AntfarmError, e.message
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,243 @@
1
+ ################################################################################
2
+ # #
3
+ # Copyright (2008-2010) Sandia Corporation. Under the terms of Contract #
4
+ # DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains #
5
+ # certain rights in this software. #
6
+ # #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy #
8
+ # of this software and associated documentation files (the "Software"), to #
9
+ # deal in the Software without restriction, including without limitation the #
10
+ # rights to use, copy, modify, merge, publish, distribute, distribute with #
11
+ # modifications, sublicense, and/or sell copies of the Software, and to permit #
12
+ # persons to whom the Software is furnished to do so, subject to the following #
13
+ # conditions: #
14
+ # #
15
+ # The above copyright notice and this permission notice shall be included in #
16
+ # all copies or substantial portions of the Software. #
17
+ # #
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #
21
+ # ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, #
22
+ # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR #
23
+ # IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE #
24
+ # SOFTWARE. #
25
+ # #
26
+ # Except as contained in this notice, the name(s) of the above copyright #
27
+ # holders shall not be used in advertising or otherwise to promote the sale, #
28
+ # use or other dealings in this Software without prior written authorization. #
29
+ # #
30
+ ################################################################################
31
+
32
+ module Antfarm
33
+ module Plugin
34
+ module Cisco
35
+ class FileDoesNotExistError < Antfarm::AntfarmError; end
36
+
37
+ class ParsePixConfig
38
+ include Antfarm::Plugin
39
+
40
+ def initialize
41
+ super({ :name => 'Parse PIX Firewall Config',
42
+ :desc => 'Parses a Cisco PIX IOS config file',
43
+ :author => 'Bryan T. Richardson <btricha>' },
44
+ [ { :name => :input,
45
+ :desc => 'Cisco PIX IOS config file or directory',
46
+ :type => String,
47
+ :required => true },
48
+ { :name => :tunnels,
49
+ :desc => 'Only parse IPSec Tunnels',
50
+ :required => false }
51
+ ])
52
+ end
53
+
54
+ def run(options)
55
+ input = options[:input]
56
+ tunnels = options[:tunnels]
57
+
58
+ if File.directory?(input)
59
+ Find.find(input) do |path|
60
+ if File.file?(path)
61
+ if tunnels
62
+ parse_tunnels(path)
63
+ else
64
+ parse(path)
65
+ end
66
+ end
67
+ end
68
+ else
69
+ if tunnels
70
+ parse_tunnels(input)
71
+ else
72
+ parse(input)
73
+ end
74
+ end
75
+ end
76
+
77
+ def parse(file)
78
+ print_message "Parsing file #{file}"
79
+
80
+ begin
81
+ hostname_regexp = %r{^hostname (\S+)}
82
+ ip_addr_regexp = %r{^\s*ip address[\s\S]* ((\d){1,3}\.(\d){1,3}\.(\d){1,3}\.(\d){1,3}) ((\d){1,3}\.(\d){1,3}\.(\d){1,3}\.(\d){1,3})}
83
+ obj_grp_net_regexp = %r{^\s*object-group network (\S+)}
84
+ net_obj_regexp = %r{^\s*network-object ((\d){1,3}\.(\d){1,3}\.(\d){1,3}\.(\d){1,3}) ((\d){1,3}\.(\d){1,3}\.(\d){1,3}\.(\d){1,3})}
85
+ net_obj_host_regexp = %r{^\s*network-object host ((\d){1,3}\.(\d){1,3}\.(\d){1,3}\.(\d){1,3})}
86
+ grp_obj_regexp = %r{^\s*group-object}
87
+
88
+ # TODO: how to fill this array from command-line?
89
+ obj_grp_nets_to_skip = Array.new
90
+
91
+ hostname = nil
92
+ fw_if_ips = Array.new
93
+ net_obj_ips = Array.new
94
+ net_obj_networks = Array.new
95
+
96
+ capture_host = false
97
+
98
+ File.open(file) do |list|
99
+ list.each do |line|
100
+ # Get hostname for PIX
101
+ if name = hostname_regexp.match(line)
102
+ hostname = name[1]
103
+ end
104
+
105
+ # Get IP addresses and netmasks for PIX interfaces
106
+ if ip_addr = ip_addr_regexp.match(line)
107
+ addr = ip_addr[1] + "/" + ip_addr[6]
108
+ fw_if_ips << addr
109
+ end
110
+ end
111
+ end
112
+
113
+ fw_if_ips.uniq!
114
+ fw_if_ips.each do |address|
115
+ ip_if = Antfarm::Model::IpInterface.new :address => address
116
+ ip_if.node_name = hostname
117
+ ip_if.node_device_type = 'FW'
118
+ unless ip_if.save
119
+ ip_if.errors.each_full do |msg|
120
+ print_error msg
121
+ end
122
+ end
123
+ end
124
+
125
+ net_obj_ips.uniq!
126
+ net_obj_ips.each do |address|
127
+ ip_if = Antfarm::Model::IpInterface.new :address => address
128
+ ip_if.node_device_type = 'FW NW OBJECT'
129
+ unless ip_if.save
130
+ ip_if.errors.each_full do |msg|
131
+ print_error msg
132
+ end
133
+ end
134
+ end
135
+
136
+ net_obj_networks.uniq!
137
+ net_obj_networks.each do |network|
138
+ ip_net = Antfarm::Model::IpNetwork.new :address => network
139
+ unless ip_net.save
140
+ ip_net.errors.each_full do |msg|
141
+ print_error msg
142
+ end
143
+ end
144
+ end
145
+ rescue Errno::ENOENT
146
+ raise FileDoesNotExistError, "The file #{file} doesn't exist"
147
+ rescue Exception => e
148
+ raise Antfarm::AntfarmError, e.message
149
+ end
150
+ end
151
+
152
+ def parse_tunnels(file)
153
+ print_message "Parsing file #{file}"
154
+
155
+ begin
156
+ version_regexp = %r{^PIX Version ((\d+).(\d+)\((\d+)\))}
157
+ nameif_ip_regexp = %r{^ip address (\S+) ((\d){1,3}\.(\d){1,3}\.(\d){1,3}\.(\d){1,3})}
158
+ interface_regexp = %r{^interface}
159
+ nameif_regexp = %r{^\s*nameif (\S+)}
160
+ ipaddr_regexp = %r{^\s*ip address ((\d){1,3}\.(\d){1,3}\.(\d){1,3}\.(\d){1,3})}
161
+ crmap_addr_regexp = %r{^crypto map (\S+) [\s\S]* ((\d){1,3}\.(\d){1,3}\.(\d){1,3}\.(\d){1,3})}
162
+ crmap_if_regexp = %r{^crypto map (\S+) interface (\S+)}
163
+ ip_addr_list = Array.new
164
+
165
+ v6 = false
166
+ v7 = false
167
+ cap_if = false
168
+ cap_crmap = false
169
+
170
+ if_map = Hash.new
171
+ if_name = nil
172
+
173
+ cr_addr_map = Hash.new
174
+ cr_if_map = Hash.new
175
+
176
+ File.open(file) do |list|
177
+ list.each do |line|
178
+ if v6 == false && v7 == false
179
+ if version = version_regexp.match(line)
180
+ if version[2].to_i == 6
181
+ v6 = true
182
+ elsif version[2].to_i == 7
183
+ v7 = true
184
+ end
185
+ end
186
+ elsif v6 == true
187
+ if nameif_ip = nameif_ip_regexp.match(line)
188
+ if_map[nameif_ip[1]] = nameif_ip[2]
189
+ end
190
+ elsif v7 == true
191
+ if cap_if == false
192
+ if interface = interface_regexp.match(line)
193
+ cap_if = true
194
+ end
195
+ else
196
+ if nameif = nameif_regexp.match(line)
197
+ cap_nameif = true
198
+ if_name = nameif[1]
199
+ elsif ipaddr = ipaddr_regexp.match(line)
200
+ if_map[if_name] = ipaddr[1]
201
+ cap_if = false
202
+ end
203
+ end
204
+ end
205
+
206
+ if crmap_addr = crmap_addr_regexp.match(line)
207
+ unless cr_addr_map[crmap_addr[1]]
208
+ cr_addr_map[crmap_addr[1]] = Array.new
209
+ end
210
+
211
+ cr_addr_map[crmap_addr[1]].push(crmap_addr[2])
212
+ elsif crmap_if = crmap_if_regexp.match(line)
213
+ cr_if_map[crmap_if[1]] = crmap_if[2]
214
+ end
215
+ end
216
+ end
217
+
218
+ cr_if_map.each do |key,value|
219
+ ip_addr_list = cr_addr_map[key]
220
+ ip_addr = if_map[value]
221
+
222
+ source_ip_if = Antfarm::Model::IpInterface.find_by_address(ip_addr)
223
+
224
+ if source_ip_if
225
+ ip_addr_list.each do |addr|
226
+ target_ip_if = Antfarm::Model::IpInterface.find_by_address(addr)
227
+
228
+ if target_ip_if
229
+ # Traffic.create(:source_layer3_interface => source_ip_if.layer3_interface, :target_layer3_interface => target_ip_if.layer3_interface, :description => 'TUNNEL')
230
+ end
231
+ end
232
+ end
233
+ end
234
+ rescue Errno::ENOENT
235
+ raise FileDoesNotExistError, "The file #{file} doesn't exist"
236
+ rescue Exception => e
237
+ raise Antfarm::AntfarmError, e.message
238
+ end
239
+ end
240
+ end
241
+ end
242
+ end
243
+ end