cisco_acl_intp 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.rubocop.yml +13 -0
- data/.travis.yml +3 -0
- data/.yardopts +4 -0
- data/Gemfile +19 -0
- data/LICENSE.txt +22 -0
- data/README.md +132 -0
- data/Rakefile +78 -0
- data/acl_examples/err-acl.txt +49 -0
- data/acl_examples/named-ext-acl.txt +12 -0
- data/acl_examples/named-std-acl.txt +6 -0
- data/acl_examples/numd-acl.txt +21 -0
- data/cisco_acl_intp.gemspec +31 -0
- data/lib/cisco_acl_intp/ace.rb +432 -0
- data/lib/cisco_acl_intp/ace_ip.rb +136 -0
- data/lib/cisco_acl_intp/ace_other_qualifiers.rb +102 -0
- data/lib/cisco_acl_intp/ace_port.rb +146 -0
- data/lib/cisco_acl_intp/ace_proto.rb +319 -0
- data/lib/cisco_acl_intp/ace_srcdst.rb +114 -0
- data/lib/cisco_acl_intp/ace_tcp_flags.rb +65 -0
- data/lib/cisco_acl_intp/acl.rb +272 -0
- data/lib/cisco_acl_intp/acl_base.rb +111 -0
- data/lib/cisco_acl_intp/parser.rb +3509 -0
- data/lib/cisco_acl_intp/parser.ry +1397 -0
- data/lib/cisco_acl_intp/scanner.rb +176 -0
- data/lib/cisco_acl_intp/scanner_special_token_handler.rb +66 -0
- data/lib/cisco_acl_intp/version.rb +5 -0
- data/lib/cisco_acl_intp.rb +9 -0
- data/spec/cisco_acl_intp/ace_ip_spec.rb +111 -0
- data/spec/cisco_acl_intp/ace_other_qualifier_spec.rb +63 -0
- data/spec/cisco_acl_intp/ace_port_spec.rb +214 -0
- data/spec/cisco_acl_intp/ace_proto_spec.rb +200 -0
- data/spec/cisco_acl_intp/ace_spec.rb +605 -0
- data/spec/cisco_acl_intp/ace_srcdst_spec.rb +296 -0
- data/spec/cisco_acl_intp/ace_tcp_flags_spec.rb +38 -0
- data/spec/cisco_acl_intp/acl_spec.rb +523 -0
- data/spec/cisco_acl_intp/cisco_acl_intp_spec.rb +7 -0
- data/spec/cisco_acl_intp/parser_spec.rb +53 -0
- data/spec/cisco_acl_intp/scanner_spec.rb +122 -0
- data/spec/conf/extacl_objgrp_token_seq.yml +36 -0
- data/spec/conf/extacl_token_seq.yml +88 -0
- data/spec/conf/extended_acl.yml +226 -0
- data/spec/conf/scanner_spec_data.yml +120 -0
- data/spec/conf/single_tokens.yml +235 -0
- data/spec/conf/stdacl_token_seq.yml +8 -0
- data/spec/conf/tokens1.yml +158 -0
- data/spec/conf/tokens2.yml +206 -0
- data/spec/parser_fullfill_patterns.rb +145 -0
- data/spec/spec_helper.rb +54 -0
- data/tools/check_acl.rb +48 -0
- metadata +159 -0
@@ -0,0 +1,272 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
require 'cisco_acl_intp/ace'
|
5
|
+
|
6
|
+
module CiscoAclIntp
|
7
|
+
# Single access-list container base
|
8
|
+
class SingleAclBase < AclContainerBase
|
9
|
+
extend Forwardable
|
10
|
+
include Enumerable
|
11
|
+
|
12
|
+
# @return [String] name ACL name,
|
13
|
+
# when numbered acl, /\d+/ string
|
14
|
+
attr_reader :name
|
15
|
+
# Some Enumerable included methods returns Array of ACE objects
|
16
|
+
# (e.g. sort),the returned Array was used as ACE object by
|
17
|
+
# overwrite accessor 'list'.
|
18
|
+
# @return [Array] list ACE object Array
|
19
|
+
attr_accessor :list
|
20
|
+
# @return [String, Symbol] acl_type ACL type
|
21
|
+
attr_reader :acl_type
|
22
|
+
# @return [String, Symbol] name_type ACL name type
|
23
|
+
attr_reader :name_type
|
24
|
+
|
25
|
+
def_delegators :@list, :each # for Enumerable
|
26
|
+
def_delegators :@list, :push, :pop, :shift, :unshift
|
27
|
+
def_delegators :@list, :size, :length
|
28
|
+
|
29
|
+
# Increment number of ACL sequence number
|
30
|
+
SEQ_NUM_DIV = 10
|
31
|
+
|
32
|
+
# Constructor
|
33
|
+
# @param [String] name ACL name
|
34
|
+
# @return [SingleAclBase]
|
35
|
+
def initialize(name)
|
36
|
+
@name = name
|
37
|
+
@list = []
|
38
|
+
@seq_number = 0
|
39
|
+
|
40
|
+
@acl_type = nil # :standard or :extended
|
41
|
+
@name_type = nil # :named or :numbered
|
42
|
+
end
|
43
|
+
|
44
|
+
# duplicate with list
|
45
|
+
# @param [Array<SingleAclBase>]
|
46
|
+
# @return [SingleAclBase]
|
47
|
+
def dup_with_list(list)
|
48
|
+
acl = dup
|
49
|
+
acl.list = list.dup
|
50
|
+
acl
|
51
|
+
end
|
52
|
+
|
53
|
+
# Add ACE to ACL (push with sequence number)
|
54
|
+
# @param [AceBase] ace ACE object
|
55
|
+
def add_entry(ace)
|
56
|
+
# 'ace' is AceBase Object
|
57
|
+
# it will be ExtendedAce/StandardAce/RemarkAce/EvaluateAce
|
58
|
+
ace.seq_number? ||
|
59
|
+
ace.seq_number = (@list.length + 1) * SEQ_NUM_DIV
|
60
|
+
@list.push ace
|
61
|
+
end
|
62
|
+
|
63
|
+
# Renumber ACL by list sequence
|
64
|
+
def renumber
|
65
|
+
# re-numbering seq_number of each entry
|
66
|
+
@list.reduce(SEQ_NUM_DIV) do |number, each|
|
67
|
+
each.seq_number = number
|
68
|
+
number + SEQ_NUM_DIV
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# @return [Boolean]
|
73
|
+
def ==(other)
|
74
|
+
if @acl_type &&
|
75
|
+
@name_type &&
|
76
|
+
@acl_type == other.acl_type &&
|
77
|
+
@name_type == other.name_type
|
78
|
+
@list == other.list
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# Search matched ACE from list
|
83
|
+
# @param [Hash] opts Options (target packet info)
|
84
|
+
# @option [String, Symbol] protocol L3/L4 protocol name
|
85
|
+
# (allows :tcp, :udp and :icmp)
|
86
|
+
# @option [String] src_ip Source IP Address
|
87
|
+
# @option [String] src_port Source Port
|
88
|
+
# @option [String] dst_ip Destination IP Address
|
89
|
+
# @option [String] dst_port Destination Port
|
90
|
+
# @return [AceBase] Matched ACE object or nil(not found)
|
91
|
+
# @raise [AclArgumentError]
|
92
|
+
def search_ace(opts)
|
93
|
+
@list.find { |each| each.matches?(opts) }
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
############################################################
|
98
|
+
|
99
|
+
# Features for Extended ACL
|
100
|
+
module ExtAcl
|
101
|
+
## TBD
|
102
|
+
## does it have to raise error
|
103
|
+
## if add_entry called with StandardAce?
|
104
|
+
|
105
|
+
# Generate a Extended ACE by parameters
|
106
|
+
# and Add it to ACL
|
107
|
+
# @param [Hash] opts Options to create {ExtendedAce}
|
108
|
+
def add_entry_by_params(opts)
|
109
|
+
ace = ExtendedAce.new opts
|
110
|
+
add_entry ace
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# Features for Standard ACL
|
115
|
+
module StdAcl
|
116
|
+
## TBD
|
117
|
+
## does it have to raise error
|
118
|
+
## if add_entry called with ExtendedAce?
|
119
|
+
|
120
|
+
# Generate a Standard ACE by parameters
|
121
|
+
# and Add it to ACL
|
122
|
+
# @param [Hash] opts Options to create {StandardAce}
|
123
|
+
def add_entry_by_params(opts)
|
124
|
+
ace = StandardAce.new opts
|
125
|
+
add_entry ace
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
############################################################
|
130
|
+
|
131
|
+
# Named ACL container base
|
132
|
+
class NamedAcl < SingleAclBase
|
133
|
+
# Generate string for Cisco IOS access list
|
134
|
+
# @return [String]
|
135
|
+
def to_s
|
136
|
+
strings = [
|
137
|
+
sprintf(
|
138
|
+
'%s %s %s',
|
139
|
+
c_hdr('ip access-list'),
|
140
|
+
c_type(@acl_type),
|
141
|
+
c_name(@name)
|
142
|
+
)
|
143
|
+
]
|
144
|
+
@list.each { | entry | strings.push entry.to_s }
|
145
|
+
strings.join("\n")
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
# Numbered ACL container base
|
150
|
+
class NumberedAcl < SingleAclBase
|
151
|
+
# @return [Integer] Access list number
|
152
|
+
attr_reader :number
|
153
|
+
|
154
|
+
# Constructor
|
155
|
+
# @param [String, Integer] name ACL number
|
156
|
+
# @raise [AclArgumentError]
|
157
|
+
# @return [NumberedAcl]
|
158
|
+
def initialize(name)
|
159
|
+
super
|
160
|
+
|
161
|
+
## TBD
|
162
|
+
## it ought to do something about assignment operator...
|
163
|
+
## (attr_reader)
|
164
|
+
|
165
|
+
case name
|
166
|
+
when Fixnum
|
167
|
+
set_name_and_number(name.to_s, name)
|
168
|
+
when String
|
169
|
+
validate_name_by_string(name)
|
170
|
+
else
|
171
|
+
fail AclArgumentError, 'acl number error'
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
# Generate string for Cisco IOS access list
|
176
|
+
# @return [String]
|
177
|
+
def to_s
|
178
|
+
strings = []
|
179
|
+
@list.each do | entry |
|
180
|
+
strings.push sprintf(
|
181
|
+
'%s %s %s',
|
182
|
+
c_hdr('access-list'),
|
183
|
+
c_name(@name),
|
184
|
+
entry
|
185
|
+
)
|
186
|
+
end
|
187
|
+
strings.join("\n")
|
188
|
+
end
|
189
|
+
|
190
|
+
private
|
191
|
+
|
192
|
+
# validate instance variables
|
193
|
+
# @param [String] name ACL Name
|
194
|
+
def validate_name_by_string(name)
|
195
|
+
if name =~ /\A\d+\Z/
|
196
|
+
set_name_and_number(name, name.to_i)
|
197
|
+
else
|
198
|
+
fail AclArgumentError, 'acl number string is not integer'
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
# Set instance variables
|
203
|
+
def set_name_and_number(name, number)
|
204
|
+
@name = name
|
205
|
+
@number = number
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
############################################################
|
210
|
+
|
211
|
+
# Named extended ACL container
|
212
|
+
class NamedExtAcl < NamedAcl
|
213
|
+
include ExtAcl
|
214
|
+
|
215
|
+
# Constructor
|
216
|
+
# @param [String] name ACL name
|
217
|
+
# @return [NamedExtAcl]
|
218
|
+
def initialize(name)
|
219
|
+
super
|
220
|
+
@name_type = :named
|
221
|
+
@acl_type = :extended
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
# Numbered extended ACL container
|
226
|
+
class NumberedExtAcl < NumberedAcl
|
227
|
+
include ExtAcl
|
228
|
+
|
229
|
+
# Constructor
|
230
|
+
# @param [String, Integer] name ACL name
|
231
|
+
# @return [NumberedExtAcl]
|
232
|
+
def initialize(name)
|
233
|
+
super
|
234
|
+
@name_type = :numbered
|
235
|
+
@acl_type = :extended
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
# Named standard ACL container
|
240
|
+
class NamedStdAcl < NamedAcl
|
241
|
+
include StdAcl
|
242
|
+
|
243
|
+
# Constructor
|
244
|
+
# @param [String] name ACL name
|
245
|
+
# @return [NamedStdAcl]
|
246
|
+
def initialize(name)
|
247
|
+
super
|
248
|
+
@name_type = :named
|
249
|
+
@acl_type = :standard
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
# Numbered standard ACL container
|
254
|
+
class NumberedStdAcl < NumberedAcl
|
255
|
+
include StdAcl
|
256
|
+
|
257
|
+
# Constructor
|
258
|
+
# @param [String, Integer] name ACL name
|
259
|
+
# @return [NumberedStdAcl]
|
260
|
+
def initialize(name)
|
261
|
+
super
|
262
|
+
@name_type = :numbered
|
263
|
+
@acl_type = :standard
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end # module
|
267
|
+
|
268
|
+
### Local variables:
|
269
|
+
### mode: Ruby
|
270
|
+
### coding: utf-8-unix
|
271
|
+
### indent-tabs-mode: nil
|
272
|
+
### End:
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'term/ansicolor'
|
2
|
+
|
3
|
+
module CiscoAclIntp
|
4
|
+
# Standard Error Handler of CiscoAclParser
|
5
|
+
class AclError < StandardError; end
|
6
|
+
|
7
|
+
# Argument Error Handler of CiscoAclParser
|
8
|
+
class AclArgumentError < AclError; end
|
9
|
+
|
10
|
+
# Acl container common utility and status management
|
11
|
+
class AclContainerBase
|
12
|
+
include Term::ANSIColor
|
13
|
+
|
14
|
+
# color mode
|
15
|
+
@color = false ## as class-instance variable
|
16
|
+
|
17
|
+
# Enables coloring
|
18
|
+
def self.enable_color
|
19
|
+
@color = true
|
20
|
+
end
|
21
|
+
|
22
|
+
# Disables coloring
|
23
|
+
def self.disable_color
|
24
|
+
@color = false
|
25
|
+
end
|
26
|
+
|
27
|
+
# Generate string for Cisco IOS access list
|
28
|
+
# @abstract
|
29
|
+
# @return [String]
|
30
|
+
def to_s
|
31
|
+
fail AclError, 'Not overridden AclContainerBase::to_s'
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
# Generate string using colors
|
37
|
+
# @param [String] str String
|
38
|
+
# @param [Array<String>] pre_c Color attribute(s) (put before 'str')
|
39
|
+
# @return [String] Colored string (if enabled [@@color])
|
40
|
+
def self.c_str(str, *pre_c)
|
41
|
+
if pre_c && @color
|
42
|
+
pre_c.concat [str, Term::ANSIColor.clear]
|
43
|
+
pre_c.join
|
44
|
+
else
|
45
|
+
str
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Access list header
|
50
|
+
# @param [String] str String
|
51
|
+
# @return [String] Colored string
|
52
|
+
def c_hdr(str)
|
53
|
+
AclContainerBase.c_str str, on_blue
|
54
|
+
end
|
55
|
+
|
56
|
+
# Named access list type
|
57
|
+
# @param [String] str String
|
58
|
+
# @return [String] Colored string
|
59
|
+
def c_type(str)
|
60
|
+
AclContainerBase.c_str str, underline
|
61
|
+
end
|
62
|
+
|
63
|
+
# Action
|
64
|
+
# @param [String] str String
|
65
|
+
# @return [String] Colored string
|
66
|
+
def c_act(str)
|
67
|
+
AclContainerBase.c_str str, intense_magenta
|
68
|
+
end
|
69
|
+
|
70
|
+
# User defined name/number
|
71
|
+
# @param [String] str String
|
72
|
+
# @return [String] Colored string
|
73
|
+
def c_name(str)
|
74
|
+
AclContainerBase.c_str str, bold
|
75
|
+
end
|
76
|
+
|
77
|
+
# Remark
|
78
|
+
# @param [String] str String
|
79
|
+
# @return [String] Colored string
|
80
|
+
def c_rmk(str)
|
81
|
+
AclContainerBase.c_str str, blink
|
82
|
+
end
|
83
|
+
|
84
|
+
# IP address
|
85
|
+
# @param [String] str String
|
86
|
+
# @return [String] Colored string
|
87
|
+
def c_ip(str)
|
88
|
+
AclContainerBase.c_str str, green, underline
|
89
|
+
end
|
90
|
+
|
91
|
+
# Wildcard mask
|
92
|
+
# @param [String] str String
|
93
|
+
# @return [String] Colored string
|
94
|
+
def c_mask(str)
|
95
|
+
AclContainerBase.c_str str, yellow
|
96
|
+
end
|
97
|
+
|
98
|
+
# Protocol and port
|
99
|
+
# @param [String] str String
|
100
|
+
# @return [String] Colored string
|
101
|
+
def c_pp(str)
|
102
|
+
AclContainerBase.c_str str, cyan
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
### Local variables:
|
108
|
+
### mode: Ruby
|
109
|
+
### coding: utf-8-unix
|
110
|
+
### indent-tabs-mode: nil
|
111
|
+
### End:
|