cisco_acl_intp 0.0.2 → 0.0.3
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 +4 -4
- data/Gemfile +1 -1
- data/README.md +64 -3
- data/cisco_acl_intp.gemspec +2 -2
- data/lib/cisco_acl_intp/ace.rb +9 -286
- data/lib/cisco_acl_intp/ace_ip.rb +24 -22
- data/lib/cisco_acl_intp/ace_other_qualifiers.rb +23 -6
- data/lib/cisco_acl_intp/ace_port.rb +37 -182
- data/lib/cisco_acl_intp/ace_port_opr.rb +251 -0
- data/lib/cisco_acl_intp/ace_port_opr_base.rb +138 -0
- data/lib/cisco_acl_intp/ace_proto.rb +133 -328
- data/lib/cisco_acl_intp/ace_proto_base.rb +163 -0
- data/lib/cisco_acl_intp/ace_srcdst.rb +30 -40
- data/lib/cisco_acl_intp/ace_tcp_flags.rb +9 -3
- data/lib/cisco_acl_intp/acl.rb +1 -251
- data/lib/cisco_acl_intp/acl_base.rb +1 -1
- data/lib/cisco_acl_intp/acl_utils.rb +120 -0
- data/lib/cisco_acl_intp/extended_ace.rb +149 -0
- data/lib/cisco_acl_intp/mono_function_acl.rb +161 -0
- data/lib/cisco_acl_intp/parser.rb +237 -395
- data/lib/cisco_acl_intp/parser.ry +85 -243
- data/lib/cisco_acl_intp/parser_api.rb +2 -2
- data/lib/cisco_acl_intp/single_acl_base.rb +137 -0
- data/lib/cisco_acl_intp/standard_ace.rb +105 -0
- data/lib/cisco_acl_intp/version.rb +1 -1
- data/spec/cisco_acl_intp/ace_ip_spec.rb +63 -0
- data/spec/cisco_acl_intp/ace_other_qualifier_spec.rb +52 -1
- data/spec/cisco_acl_intp/ace_port_operator_spec.rb +340 -0
- data/spec/cisco_acl_intp/ace_port_spec.rb +67 -217
- data/spec/cisco_acl_intp/ace_proto_spec.rb +118 -41
- data/spec/cisco_acl_intp/ace_spec.rb +38 -547
- data/spec/cisco_acl_intp/ace_srcdst_spec.rb +115 -226
- data/spec/cisco_acl_intp/ace_tcp_flags_spec.rb +36 -4
- data/spec/cisco_acl_intp/acl_base_spec.rb +2 -2
- data/spec/cisco_acl_intp/extended_ace_spec.rb +411 -0
- data/spec/cisco_acl_intp/extended_acl_spec.rb +265 -0
- data/spec/cisco_acl_intp/scanner_spec.rb +13 -12
- data/spec/cisco_acl_intp/standard_ace_spec.rb +77 -0
- data/spec/cisco_acl_intp/standard_acl_spec.rb +245 -0
- data/spec/conf/scanner_spec_data.yml +32 -0
- data/spec/spec_helper.rb +2 -2
- metadata +20 -4
- data/spec/cisco_acl_intp/acl_spec.rb +0 -525
@@ -0,0 +1,137 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'forwardable'
|
3
|
+
require 'cisco_acl_intp/extended_ace'
|
4
|
+
require 'cisco_acl_intp/acl_utils'
|
5
|
+
|
6
|
+
module CiscoAclIntp
|
7
|
+
# Single access-list container base
|
8
|
+
class SingleAclBase < AclContainerBase
|
9
|
+
extend Forwardable
|
10
|
+
include Enumerable
|
11
|
+
include AceSearchUtility
|
12
|
+
|
13
|
+
# @return [String] name ACL name,
|
14
|
+
# when numbered acl, /\d+/ string
|
15
|
+
attr_reader :name
|
16
|
+
# Some Enumerable included methods returns Array of ACE objects
|
17
|
+
# (e.g. sort),the returned Array was used as ACE object by
|
18
|
+
# overwrite accessor 'list'.
|
19
|
+
# @return [Array<AceBase>] list ACE object Array
|
20
|
+
attr_accessor :list
|
21
|
+
# @return [String, Symbol] acl_type ACL type
|
22
|
+
attr_reader :acl_type
|
23
|
+
# @return [String, Symbol] name_type ACL name type
|
24
|
+
attr_reader :name_type
|
25
|
+
|
26
|
+
def_delegators :@list, :each # for Enumerable
|
27
|
+
def_delegators :@list, :push, :pop, :shift, :unshift
|
28
|
+
def_delegators :@list, :size, :length
|
29
|
+
|
30
|
+
# Increment number of ACL sequence number
|
31
|
+
SEQ_NUM_DIV = 10
|
32
|
+
|
33
|
+
# Constructor
|
34
|
+
# @param [String] name ACL name
|
35
|
+
# @return [SingleAclBase]
|
36
|
+
def initialize(name)
|
37
|
+
@name = name
|
38
|
+
@list = []
|
39
|
+
@seq_number = 0
|
40
|
+
|
41
|
+
@acl_type = nil # :standard or :extended
|
42
|
+
@name_type = nil # :named or :numbered
|
43
|
+
end
|
44
|
+
|
45
|
+
# duplicate ACE list
|
46
|
+
# @param [Array<AceBase>] list List of ACE
|
47
|
+
# @return [SingleAclBase]
|
48
|
+
def dup_with_list(list)
|
49
|
+
acl = dup
|
50
|
+
acl.list = list.dup
|
51
|
+
acl
|
52
|
+
end
|
53
|
+
|
54
|
+
# Add ACE to ACL (push with sequence number)
|
55
|
+
# @param [AceBase] ace ACE object
|
56
|
+
def add_entry(ace)
|
57
|
+
# 'ace' is AceBase Object
|
58
|
+
# it will be ExtendedAce/StandardAce/RemarkAce/EvaluateAce
|
59
|
+
ace.seq_number? ||
|
60
|
+
ace.seq_number = (@list.length + 1) * SEQ_NUM_DIV
|
61
|
+
@list.push ace
|
62
|
+
end
|
63
|
+
|
64
|
+
# Renumber ACL by list sequence
|
65
|
+
def renumber
|
66
|
+
# re-numbering seq_number of each entry
|
67
|
+
@list.reduce(SEQ_NUM_DIV) do |number, each|
|
68
|
+
each.seq_number = number
|
69
|
+
number + SEQ_NUM_DIV
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Check equality
|
74
|
+
# @return [Boolean]
|
75
|
+
def ==(other)
|
76
|
+
if @acl_type &&
|
77
|
+
@name_type &&
|
78
|
+
@acl_type == other.acl_type &&
|
79
|
+
@name_type == other.name_type
|
80
|
+
@list == other.list
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Find lists of ACEs that contains flow by options
|
85
|
+
# @param [Hash] opts Options (target packet info)
|
86
|
+
# options are same as #find_aces_with
|
87
|
+
# @see #find_aces_with
|
88
|
+
# @return [Array<AceBase>] List of ACEs or nil(not found)
|
89
|
+
def find_aces_contains(opts)
|
90
|
+
find_aces_with(opts) { |ace, target_ace| ace.contains?(target_ace) }
|
91
|
+
end
|
92
|
+
|
93
|
+
# Find lists of ACEs that is contained flow by options
|
94
|
+
# @param [Hash] opts Options (target packet info)
|
95
|
+
# options are same as #find_aces_with
|
96
|
+
# @see #find_aces_with
|
97
|
+
# @return [Array<AceBase>] List of ACEs or nil(not found)
|
98
|
+
def find_aces_contained(opts)
|
99
|
+
find_aces_with(opts) { |ace, target_ace| target_ace.contains?(ace) }
|
100
|
+
end
|
101
|
+
|
102
|
+
# Find lists of ACEs
|
103
|
+
# @note In Standard ACL, only src_ip option is used and another
|
104
|
+
# conditions are ignored (if specified).
|
105
|
+
# @param [Hash] opts Options (target flow info),
|
106
|
+
# @option opts [Integer,String] protocol L3 protocol No./Name
|
107
|
+
# @option opts [String] src_ip Source IP Address
|
108
|
+
# @option opts [String] src_operator Source port operator.
|
109
|
+
# @option opts [Integer,String] src_begin_port Source Port No./Name
|
110
|
+
# @option opts [Integer,String] src_end_port Source Port No./Name
|
111
|
+
# @option opts [String] dst_ip Destination IP Address
|
112
|
+
# @option opts [Integer,String] dst_begin_port Destination Port No./Name
|
113
|
+
# @option opts [Integer,String] dst_end_port Destination Port No./Name
|
114
|
+
# @yield Find lists of ACEs
|
115
|
+
# @yieldparam [ExtendedAce] ace ACE
|
116
|
+
# @yieldparam [ExtendedAce] target_ace Target ACE
|
117
|
+
# @yieldreturn [Boolean] Condition to find
|
118
|
+
# @return [Array<AceBase>] List of ACEs or nil(not found)
|
119
|
+
def find_aces_with(opts)
|
120
|
+
target_ace = target_ace(opts)
|
121
|
+
@list.find { |ace| yield(ace, target_ace) }
|
122
|
+
end
|
123
|
+
|
124
|
+
# acl string clean-up (override)
|
125
|
+
# @param [String] str ACL string.
|
126
|
+
# @return [String]
|
127
|
+
def clean_acl_string(str)
|
128
|
+
str =~ /remark/ ? str : super
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end # module
|
132
|
+
|
133
|
+
### Local variables:
|
134
|
+
### mode: Ruby
|
135
|
+
### coding: utf-8-unix
|
136
|
+
### indent-tabs-mode: nil
|
137
|
+
### End:
|
@@ -0,0 +1,105 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'cisco_acl_intp/ace'
|
3
|
+
|
4
|
+
module CiscoAclIntp
|
5
|
+
# ACE for standard access list
|
6
|
+
class StandardAce < AceBase
|
7
|
+
# @param [String] value Action
|
8
|
+
# @return [String]
|
9
|
+
attr_accessor :action
|
10
|
+
|
11
|
+
# @param [AceSrcDstSpec] value Source spec object
|
12
|
+
# @return [AceSrcDstSpec]
|
13
|
+
attr_accessor :src_spec
|
14
|
+
|
15
|
+
# @param [AceLogSpec] value Log spec object
|
16
|
+
# @return [AceLogSpec]
|
17
|
+
attr_accessor :log_spec
|
18
|
+
|
19
|
+
# Constructor
|
20
|
+
# @param [Hash] opts Options
|
21
|
+
# @option opts [Integer] :number Sequence number
|
22
|
+
# @option opts [String] :action Action (permit/deny)
|
23
|
+
# @option opts [AceSrcDstSpec] :src Source spec object
|
24
|
+
# @option opts [Hash] :src Source spec parmeters
|
25
|
+
# @option opts [AceLogSpec] :log Log spec object
|
26
|
+
# @return [StandardAce]
|
27
|
+
# @raise [AclArgumentError]
|
28
|
+
def initialize(opts)
|
29
|
+
super
|
30
|
+
@options = opts
|
31
|
+
@action = define_action
|
32
|
+
@src_spec = define_src_spec
|
33
|
+
@log_spec = define_log_spec
|
34
|
+
end
|
35
|
+
|
36
|
+
# @return [Boolean]
|
37
|
+
def ==(other)
|
38
|
+
@action == other.action && @src_spec == other.src_spec
|
39
|
+
end
|
40
|
+
|
41
|
+
# Generate string for Cisco IOS access list
|
42
|
+
# @return [String]
|
43
|
+
def to_s
|
44
|
+
format(
|
45
|
+
'%s %s %s',
|
46
|
+
tag_action(@action.to_s),
|
47
|
+
@src_spec,
|
48
|
+
tag_other_qualifier(@log_spec ? @log_spec : '')
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Search matched ACE
|
53
|
+
# @param [StandardAce] other Target ACE
|
54
|
+
# @return [Boolean] Matched or not
|
55
|
+
def contains?(other)
|
56
|
+
other.kind_of?(StandardAce) &&
|
57
|
+
@src_spec.contains?(other.src_spec)
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
# Set instance variables
|
63
|
+
# @return [String] Action string
|
64
|
+
# @raise [AclArgumentError]
|
65
|
+
def define_action
|
66
|
+
if @options.key?(:action)
|
67
|
+
@options[:action]
|
68
|
+
else
|
69
|
+
fail AclArgumentError, 'Not specified action'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Set instance variables
|
74
|
+
# @return [AceSrcDstSpec] Source spec object
|
75
|
+
# @raise [AclArgumentError]
|
76
|
+
def define_src_spec
|
77
|
+
if @options.key?(:src)
|
78
|
+
src = @options[:src]
|
79
|
+
case src
|
80
|
+
when Hash
|
81
|
+
AceSrcDstSpec.new(src)
|
82
|
+
when AceSrcDstSpec
|
83
|
+
src
|
84
|
+
else
|
85
|
+
fail AclArgumentError, 'src spec: unknown class'
|
86
|
+
end
|
87
|
+
else
|
88
|
+
fail AclArgumentError, 'Not specified src spec'
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Set instance variables
|
93
|
+
# @return [String] Log spec object
|
94
|
+
# @raise [AclArgumentError]
|
95
|
+
def define_log_spec
|
96
|
+
@options[:log] || nil
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end # module
|
100
|
+
|
101
|
+
### Local variables:
|
102
|
+
### mode: Ruby
|
103
|
+
### coding: utf-8-unix
|
104
|
+
### indent-tabs-mode: nil
|
105
|
+
### End:
|
@@ -2,6 +2,64 @@
|
|
2
2
|
require 'spec_helper'
|
3
3
|
|
4
4
|
describe AceIpSpec do
|
5
|
+
describe '#==' do
|
6
|
+
before(:all) do
|
7
|
+
@ip = AceIpSpec.new(
|
8
|
+
ipaddr: '192.168.15.15',
|
9
|
+
wildcard: '0.0.3.255'
|
10
|
+
)
|
11
|
+
@ip1 = AceIpSpec.new(
|
12
|
+
ipaddr: '192.168.15.15',
|
13
|
+
wildcard: '0.0.3.255'
|
14
|
+
)
|
15
|
+
@ip2 = AceIpSpec.new(
|
16
|
+
ipaddr: '192.168.15.15',
|
17
|
+
netmask: 22
|
18
|
+
)
|
19
|
+
@ip3 = AceIpSpec.new(
|
20
|
+
ipaddr: '192.168.15.13',
|
21
|
+
netmask: 22
|
22
|
+
)
|
23
|
+
@ip4 = AceIpSpec.new(
|
24
|
+
ipaddr: '192.168.15.0',
|
25
|
+
wildcard: '0.0.3.255'
|
26
|
+
)
|
27
|
+
@ip5 = AceIpSpec.new(
|
28
|
+
ipaddr: '192.168.15.15',
|
29
|
+
wildcard: '0.0.1.255'
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should be true same ip and same wildcard' do
|
34
|
+
(@ip == @ip1).should be_true
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should be true same ip and same wildcard/netmask' do
|
38
|
+
(@ip1 == @ip2).should be_true
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should be false different ip and same netmask' do
|
42
|
+
(@ip2 == @ip3).should be_false
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should be false different ip and same wildcard' do
|
46
|
+
(@ip1 == @ip4).should be_false
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should be false same ip and different wildcard' do
|
50
|
+
(@ip1 == @ip5).should be_false
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should be true ANY object' do
|
54
|
+
ip1 = AceIpSpec.new(ipaddr: 'any')
|
55
|
+
ip2 = AceIpSpec.new(ipaddr: '0.0.0.0', wildcard: '255.255.255.255')
|
56
|
+
ip3 = AceIpSpec.new(ipaddr: '0.0.0.0', netmask: 0)
|
57
|
+
(ip1 == ip2).should be_true
|
58
|
+
(ip2 == ip3).should be_true
|
59
|
+
(ip3 == ip1).should be_true
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
5
63
|
describe '#netmask, #wildcard' do
|
6
64
|
it 'should be converted wildcard/netmask' do
|
7
65
|
ip = AceIpSpec.new(
|
@@ -56,6 +114,11 @@ describe AceIpSpec do
|
|
56
114
|
ip.to_s.should be_aclstr('192.168.8.9 0.0.7.6')
|
57
115
|
end
|
58
116
|
|
117
|
+
it 'should be "any" with any alias' do
|
118
|
+
ip = AceIpSpec.new(ipaddr: 'any')
|
119
|
+
ip.to_s.should be_aclstr('any')
|
120
|
+
end
|
121
|
+
|
59
122
|
it 'should be "any"' do
|
60
123
|
ip = AceIpSpec.new(
|
61
124
|
ipaddr: '0.0.0.0',
|
@@ -2,6 +2,22 @@
|
|
2
2
|
require 'spec_helper'
|
3
3
|
|
4
4
|
describe AceLogSpec do
|
5
|
+
describe '#==' do
|
6
|
+
before(:all) do
|
7
|
+
@log1 = AceLogSpec.new
|
8
|
+
@log2 = AceLogSpec.new('hoge')
|
9
|
+
@log3 = AceLogSpec.new('hoge')
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should be true when same cookie' do
|
13
|
+
(@log2 == @log3).should be_true
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should be false when different cookie' do
|
17
|
+
(@log2 == @log1).should be_false
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
5
21
|
describe '#to_s' do
|
6
22
|
it 'should be log without cookie' do
|
7
23
|
log = AceLogSpec.new
|
@@ -26,6 +42,22 @@ describe AceLogSpec do
|
|
26
42
|
end
|
27
43
|
|
28
44
|
describe AceRecursiveQualifier do
|
45
|
+
describe '#==' do
|
46
|
+
before(:all) do
|
47
|
+
@rcsv1 = AceLogSpec.new
|
48
|
+
@rcsv2 = AceLogSpec.new('hoge')
|
49
|
+
@rcsv3 = AceLogSpec.new('hoge')
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should be true when same recursive-name' do
|
53
|
+
(@rcsv2 == @rcsv3).should be_true
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should be false when different recursive-name' do
|
57
|
+
(@rcsv2 == @rcsv1).should be_false
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
29
61
|
describe '#to_s' do
|
30
62
|
it 'should be reflect spec string' do
|
31
63
|
rcsv = AceRecursiveQualifier.new('established')
|
@@ -42,7 +74,7 @@ end
|
|
42
74
|
|
43
75
|
describe AceOtherQualifierList do
|
44
76
|
describe '#to_s' do
|
45
|
-
before do
|
77
|
+
before(:all) do
|
46
78
|
@oq1 = AceLogSpec.new
|
47
79
|
@oq2 = AceRecursiveQualifier.new('iptraffic')
|
48
80
|
@list = AceOtherQualifierList.new
|
@@ -60,4 +92,23 @@ describe AceOtherQualifierList do
|
|
60
92
|
@list.to_s.should be_aclstr('log reflect iptraffic')
|
61
93
|
end
|
62
94
|
end
|
95
|
+
|
96
|
+
describe '#==' do
|
97
|
+
before(:all) do
|
98
|
+
log1 = AceLogSpec.new
|
99
|
+
log2 = AceLogSpec.new('hoge')
|
100
|
+
rcsv1 = AceRecursiveQualifier.new('iptraffic')
|
101
|
+
@list1 = AceOtherQualifierList.new([log1, rcsv1])
|
102
|
+
@list2 = AceOtherQualifierList.new([rcsv1, log1])
|
103
|
+
@list3 = AceOtherQualifierList.new([log2, rcsv1])
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should be true when same other qualifier elements' do
|
107
|
+
(@list1 == @list2).should be_true
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'should be false when different other qualifier elements' do
|
111
|
+
(@list1 == @list3).should be_false
|
112
|
+
end
|
113
|
+
end
|
63
114
|
end
|