antfarm-core 0.5.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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