trigger 2.0.0__py3-none-any.whl
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.
- trigger/__init__.py +7 -0
- trigger/acl/__init__.py +32 -0
- trigger/acl/autoacl.py +70 -0
- trigger/acl/db.py +324 -0
- trigger/acl/dicts.py +357 -0
- trigger/acl/grammar.py +112 -0
- trigger/acl/ios.py +222 -0
- trigger/acl/junos.py +422 -0
- trigger/acl/models.py +118 -0
- trigger/acl/parser.py +168 -0
- trigger/acl/queue.py +296 -0
- trigger/acl/support.py +1431 -0
- trigger/acl/tools.py +746 -0
- trigger/bin/__init__.py +0 -0
- trigger/bin/acl.py +233 -0
- trigger/bin/acl_script.py +574 -0
- trigger/bin/aclconv.py +82 -0
- trigger/bin/check_access.py +93 -0
- trigger/bin/check_syntax.py +66 -0
- trigger/bin/fe.py +197 -0
- trigger/bin/find_access.py +191 -0
- trigger/bin/gnng.py +434 -0
- trigger/bin/gong.py +86 -0
- trigger/bin/load_acl.py +841 -0
- trigger/bin/load_config.py +18 -0
- trigger/bin/netdev.py +317 -0
- trigger/bin/optimizer.py +638 -0
- trigger/bin/run_cmds.py +18 -0
- trigger/changemgmt/__init__.py +352 -0
- trigger/changemgmt/bounce.py +57 -0
- trigger/cmds.py +1217 -0
- trigger/conf/__init__.py +94 -0
- trigger/conf/global_settings.py +674 -0
- trigger/contrib/__init__.py +7 -0
- trigger/exceptions.py +307 -0
- trigger/gorc.py +172 -0
- trigger/netdevices/__init__.py +1288 -0
- trigger/netdevices/loader.py +174 -0
- trigger/netscreen.py +1030 -0
- trigger/packages/__init__.py +6 -0
- trigger/packages/peewee.py +8084 -0
- trigger/rancid.py +463 -0
- trigger/tacacsrc.py +584 -0
- trigger/twister.py +2203 -0
- trigger/twister2.py +745 -0
- trigger/utils/__init__.py +88 -0
- trigger/utils/cli.py +349 -0
- trigger/utils/importlib.py +77 -0
- trigger/utils/network.py +157 -0
- trigger/utils/rcs.py +178 -0
- trigger/utils/templates.py +81 -0
- trigger/utils/url.py +78 -0
- trigger/utils/xmltodict.py +298 -0
- trigger-2.0.0.dist-info/METADATA +146 -0
- trigger-2.0.0.dist-info/RECORD +61 -0
- trigger-2.0.0.dist-info/WHEEL +5 -0
- trigger-2.0.0.dist-info/entry_points.txt +15 -0
- trigger-2.0.0.dist-info/licenses/AUTHORS.md +20 -0
- trigger-2.0.0.dist-info/licenses/LICENSE.md +28 -0
- trigger-2.0.0.dist-info/top_level.txt +2 -0
- twisted/plugins/trigger_xmlrpc.py +124 -0
trigger/netscreen.py
ADDED
|
@@ -0,0 +1,1030 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Parses and manipulates firewall policy for Juniper NetScreen firewall devices.
|
|
3
|
+
Broken apart from acl.parser because the approaches are vastly different from each
|
|
4
|
+
other.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
__author__ = "Jathan McCollum, Mark Thomas"
|
|
8
|
+
__maintainer__ = "Jathan McCollum"
|
|
9
|
+
__email__ = "jathan.mccollum@teamaol.com"
|
|
10
|
+
__copyright__ = "Copyright 2007-2012, AOL Inc."
|
|
11
|
+
__version__ = "1.2.2"
|
|
12
|
+
|
|
13
|
+
import IPy
|
|
14
|
+
|
|
15
|
+
from trigger import exceptions
|
|
16
|
+
from trigger.acl.parser import (
|
|
17
|
+
TIP,
|
|
18
|
+
ACLParser,
|
|
19
|
+
ACLProcessor,
|
|
20
|
+
Protocol,
|
|
21
|
+
S,
|
|
22
|
+
check_range,
|
|
23
|
+
default_processor,
|
|
24
|
+
do_protocol_lookup,
|
|
25
|
+
literals,
|
|
26
|
+
make_nondefault_processor,
|
|
27
|
+
)
|
|
28
|
+
from trigger.acl.tools import create_trigger_term
|
|
29
|
+
|
|
30
|
+
# TODO (jathan): Implement __all__
|
|
31
|
+
__all__ = (
|
|
32
|
+
"NSRawPolicy",
|
|
33
|
+
"NSRawGroup",
|
|
34
|
+
"NetScreen",
|
|
35
|
+
"NSGroup",
|
|
36
|
+
"NSServiceBook",
|
|
37
|
+
"NSAddressBook",
|
|
38
|
+
"NSAddress",
|
|
39
|
+
"NSService",
|
|
40
|
+
"NSPolicy",
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
# Classes
|
|
45
|
+
class NetScreen:
|
|
46
|
+
"""
|
|
47
|
+
Parses and generates NetScreen firewall policy.
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
def __init__(self):
|
|
51
|
+
self.service_book = NSServiceBook()
|
|
52
|
+
self.address_book = NSAddressBook()
|
|
53
|
+
self.interfaces = []
|
|
54
|
+
self.address_groups = []
|
|
55
|
+
self.service_groups = []
|
|
56
|
+
self.policies = []
|
|
57
|
+
self.grammar = []
|
|
58
|
+
|
|
59
|
+
rules = {
|
|
60
|
+
#
|
|
61
|
+
# normal shiznitches.
|
|
62
|
+
#
|
|
63
|
+
"digits": "[0-9]+",
|
|
64
|
+
"<ts>": "[ \\t]+",
|
|
65
|
+
"<ws>": "[ \\t\\n]+",
|
|
66
|
+
"<EOL>": "('\r'?,'\n')/EOF",
|
|
67
|
+
"alphanums": "[a-zA-z0-9]+",
|
|
68
|
+
"word": "[a-zA-Z0-9_:./-]+",
|
|
69
|
+
"anychar": "[ a-zA-Z0-9.$:()&,/'_-]",
|
|
70
|
+
"nonspace": "[a-zA-Z0-9.$:()&,/'_-]+",
|
|
71
|
+
"ipv4": ('digits, (".", digits)*', TIP),
|
|
72
|
+
"cidr": ('ipv4, "/", digits', TIP),
|
|
73
|
+
"macaddr": "[0-9a-fA-F:]+",
|
|
74
|
+
"protocol": (literals(Protocol.name2num) + " / digits", do_protocol_lookup),
|
|
75
|
+
"tcp": ('"tcp" / "6"', Protocol("tcp")),
|
|
76
|
+
"udp": ('"udp" / "17"', Protocol("udp")),
|
|
77
|
+
"icmp": ('"icmp" / "1"', Protocol("icmp")),
|
|
78
|
+
"root": "ws?, netscreen, ws?",
|
|
79
|
+
#
|
|
80
|
+
# netscreen shiznit
|
|
81
|
+
#
|
|
82
|
+
"kw_address": ('"address"'),
|
|
83
|
+
"kw_service": ('"service"'),
|
|
84
|
+
"ns_word": ('"\\""?, word, "\\""?'),
|
|
85
|
+
"ns_nonspace": ('"\\""?, nonspace, "\\""?'),
|
|
86
|
+
"ns_quoted_word": ('"\\"",(word,ws?)+,"\\""', lambda x: "".join(x)[1:-1]),
|
|
87
|
+
"ns_quoted_nonspace": (
|
|
88
|
+
'"\\"",(nonspace,ws?)+,"\\""',
|
|
89
|
+
lambda x: "".join(x)[1:-1],
|
|
90
|
+
),
|
|
91
|
+
S("netmask_conv"): ("(ipv4, ws, ipv4) / cidr", self.netmask2cidr),
|
|
92
|
+
S("portrange"): ('digits,"-",digits', lambda xy: (int(xy[0]), int(xy[1]))),
|
|
93
|
+
S("service"): (
|
|
94
|
+
'"set", ws, "service", ws, ns_word, ws,'
|
|
95
|
+
'"protocol", ws, protocol, ws, "src-port", ws, portrange, ws,'
|
|
96
|
+
'"dst-port", ws, portrange',
|
|
97
|
+
lambda x: NSService(
|
|
98
|
+
name=x[0], protocol=x[1], source_port=x[2], destination_port=x[3]
|
|
99
|
+
),
|
|
100
|
+
),
|
|
101
|
+
S("address"): (
|
|
102
|
+
'"set", ws, "address", ws, ns_nonspace, ws, '
|
|
103
|
+
"ns_word, ws, netmask_conv, (ws, ns_quoted_word)?",
|
|
104
|
+
lambda x: NSAddress(zone=x[0], name=x[1], addr=x[2]),
|
|
105
|
+
),
|
|
106
|
+
"kw_log": ('"log"'),
|
|
107
|
+
"kw_count": ('"count"'),
|
|
108
|
+
"kw_reject": ('"reject"'),
|
|
109
|
+
"kw_permit": ('"permit"'),
|
|
110
|
+
"modifiers": (
|
|
111
|
+
'("deny"/"nat"/"permit"/"reject"/"tunnel"/"log"/"count"),ws?'
|
|
112
|
+
),
|
|
113
|
+
S("policy_rule"): (
|
|
114
|
+
'"from", ws, ns_word, ws, "to", ws, ns_word, ws, '
|
|
115
|
+
"ns_word, ws, ns_word, ws, ns_word, ws, modifiers+",
|
|
116
|
+
lambda x: {
|
|
117
|
+
"src-zone": x[0],
|
|
118
|
+
"dst-zone": x[1],
|
|
119
|
+
"src-address": [x[2]],
|
|
120
|
+
"dst-address": [x[3]],
|
|
121
|
+
"service": [x[4]],
|
|
122
|
+
},
|
|
123
|
+
),
|
|
124
|
+
S("src_address"): (
|
|
125
|
+
'"src-address", ws, ns_word',
|
|
126
|
+
lambda x: {"src-address": x[0]},
|
|
127
|
+
),
|
|
128
|
+
S("dst_address"): (
|
|
129
|
+
'"dst-address", ws, ns_word',
|
|
130
|
+
lambda x: {"dst-address": x[0]},
|
|
131
|
+
),
|
|
132
|
+
S("service_short"): ('"service", ws, ns_word', lambda x: {"service": x[0]}),
|
|
133
|
+
# S('name'): ('"name", ws, ns_quoted_word',
|
|
134
|
+
S("name"): ('"name", ws, ns_quoted_nonspace', lambda x: {"name": x[0]}),
|
|
135
|
+
"global": ('"global" / "Global"', lambda x: {"global": 1}),
|
|
136
|
+
S("policy_set_id"): (
|
|
137
|
+
'"set", ws, src_address / service_short / dst_address'
|
|
138
|
+
),
|
|
139
|
+
# the thing inside a policy set id 0 stuff.
|
|
140
|
+
S("policy_set_id_grp"): (
|
|
141
|
+
'(policy_set_id, ws?)+, "exit", ws',
|
|
142
|
+
self.concatenate_grp,
|
|
143
|
+
),
|
|
144
|
+
S("policy_id"): ('"id", ws, digits', lambda x: {"id": int(x[0])}),
|
|
145
|
+
"policy_id_null": ('"id", ws, digits, ws, "exit"', lambda x: {}),
|
|
146
|
+
# our main policy definition.
|
|
147
|
+
S("policy"): (
|
|
148
|
+
'"set", ws, "policy", ws,'
|
|
149
|
+
"((global, ws)?, (policy_id, ws)?, (name, ws)?)?,"
|
|
150
|
+
'policy_set_id_grp / policy_rule / "exit"',
|
|
151
|
+
lambda x: NSRawPolicy(x),
|
|
152
|
+
),
|
|
153
|
+
"address_group": (
|
|
154
|
+
'kw_address, ws, ns_word, ws, ns_word, (ws, "add", ws, ns_word)?'
|
|
155
|
+
),
|
|
156
|
+
"service_group": ('kw_service, ws, ns_word, (ws, "add", ws, ns_word)?'),
|
|
157
|
+
S("group"): (
|
|
158
|
+
'"set", ws, "group", ws, address_group / service_group',
|
|
159
|
+
lambda x: NSRawGroup(x[0]),
|
|
160
|
+
),
|
|
161
|
+
">line<": ("ws?, service / address / group / policy, ws?"),
|
|
162
|
+
S("netscreen"): ("(line)+", self.handle_raw_netscreen),
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
for (
|
|
166
|
+
production,
|
|
167
|
+
rule,
|
|
168
|
+
) in rules.items():
|
|
169
|
+
if isinstance(rule, tuple):
|
|
170
|
+
assert len(rule) == 2
|
|
171
|
+
setattr(ACLProcessor, production, make_nondefault_processor(rule[1]))
|
|
172
|
+
self.grammar.append(f"{production} := {rule[0]}")
|
|
173
|
+
else:
|
|
174
|
+
setattr(ACLProcessor, production, default_processor)
|
|
175
|
+
self.grammar.append(f"{production} := {rule}")
|
|
176
|
+
|
|
177
|
+
self.grammar = "\n".join(self.grammar)
|
|
178
|
+
|
|
179
|
+
def parse(self, data):
|
|
180
|
+
"""Parse policy into list of NSPolicy objects."""
|
|
181
|
+
parser = ACLParser(self.grammar)
|
|
182
|
+
try:
|
|
183
|
+
string = data.read()
|
|
184
|
+
except AttributeError:
|
|
185
|
+
string = data
|
|
186
|
+
|
|
187
|
+
success, children, nextchar = parser.parse(string)
|
|
188
|
+
|
|
189
|
+
if success and nextchar == len(string):
|
|
190
|
+
assert len(children) == 1
|
|
191
|
+
return children[0]
|
|
192
|
+
else:
|
|
193
|
+
line = string[:nextchar].count("\n") + 1
|
|
194
|
+
column = len(string[string[nextchar].rfind("\n") : nextchar]) + 2
|
|
195
|
+
print("Error at: ", string[nextchar:])
|
|
196
|
+
raise exceptions.ParseError(
|
|
197
|
+
"Could not match syntax. Please report as a bug.", line, column
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
def concatenate_grp(self, x):
|
|
201
|
+
"""Used by NetScreen class when grouping policy members."""
|
|
202
|
+
ret = {}
|
|
203
|
+
for entry in x:
|
|
204
|
+
for key, val in entry.items():
|
|
205
|
+
if key in ret:
|
|
206
|
+
ret[key].append(val)
|
|
207
|
+
else:
|
|
208
|
+
ret[key] = [val]
|
|
209
|
+
return ret
|
|
210
|
+
|
|
211
|
+
def netmask2cidr(self, iptuple):
|
|
212
|
+
"""Converts dotted-quad netmask to cidr notation"""
|
|
213
|
+
if len(iptuple) == 2:
|
|
214
|
+
addr, mask = iptuple
|
|
215
|
+
ipstr = addr.strNormal() + "/" + mask.strNormal()
|
|
216
|
+
return TIP(ipstr)
|
|
217
|
+
return TIP(iptuple[0].strNormal())
|
|
218
|
+
|
|
219
|
+
def handle_raw_netscreen(self, rows):
|
|
220
|
+
"""
|
|
221
|
+
The parser will hand it's final output to this function, which decodes
|
|
222
|
+
and puts everything in the right place.
|
|
223
|
+
"""
|
|
224
|
+
for node in rows:
|
|
225
|
+
if isinstance(node, NSAddress):
|
|
226
|
+
self.address_book.append(node)
|
|
227
|
+
elif isinstance(node, NSService):
|
|
228
|
+
self.service_book.append(node)
|
|
229
|
+
elif isinstance(node, NSGroup):
|
|
230
|
+
if node.type == "address":
|
|
231
|
+
self.address_book.append(node)
|
|
232
|
+
elif node.type == "service":
|
|
233
|
+
self.service_book.append(node)
|
|
234
|
+
else:
|
|
235
|
+
raise f"Unknown NSGroup type: {node.type}"
|
|
236
|
+
elif isinstance(node, NSRawGroup):
|
|
237
|
+
# take a raw parsed group entry,
|
|
238
|
+
# try to find it's entry in either the addressbook,
|
|
239
|
+
# or the service book. update and append to the group
|
|
240
|
+
# with the proper addresses/services
|
|
241
|
+
zone = None
|
|
242
|
+
type = None
|
|
243
|
+
name = None
|
|
244
|
+
entry = None
|
|
245
|
+
|
|
246
|
+
if len(node) == 4:
|
|
247
|
+
type, zone, name, entry = node
|
|
248
|
+
else:
|
|
249
|
+
type, name, entry = node
|
|
250
|
+
|
|
251
|
+
if entry is None:
|
|
252
|
+
continue
|
|
253
|
+
|
|
254
|
+
if type == "address":
|
|
255
|
+
address_find = self.address_book.find(entry, zone)
|
|
256
|
+
group_find = self.address_book.find(name, zone)
|
|
257
|
+
# does the thing being added have an entry?
|
|
258
|
+
if not address_find:
|
|
259
|
+
raise f"GROUP ADD: no address book entry for {entry}"
|
|
260
|
+
|
|
261
|
+
if group_find:
|
|
262
|
+
# we already have an entry for this group? if so
|
|
263
|
+
# just append.
|
|
264
|
+
group_find.append(address_find)
|
|
265
|
+
else:
|
|
266
|
+
# else we have to create a new group
|
|
267
|
+
new_group = NSGroup(name=name, type="address", zone=zone)
|
|
268
|
+
# insert the address entry into the group
|
|
269
|
+
new_group.append(address_find)
|
|
270
|
+
# insert the new group into the address book
|
|
271
|
+
self.address_book.append(new_group)
|
|
272
|
+
|
|
273
|
+
elif type == "service":
|
|
274
|
+
# do the same for service groups.
|
|
275
|
+
if not self.service_book.has_key(entry):
|
|
276
|
+
raise f"GROUP ADD: no service entry for {entry}"
|
|
277
|
+
found = None
|
|
278
|
+
if self.service_book.has_key(name):
|
|
279
|
+
found = self.service_book[name]
|
|
280
|
+
if not found:
|
|
281
|
+
new_grp = NSGroup(name=name, type="service")
|
|
282
|
+
new_grp.append(self.service_book[entry])
|
|
283
|
+
self.service_book.append(new_grp)
|
|
284
|
+
else:
|
|
285
|
+
found.append(self.service_book[entry])
|
|
286
|
+
else:
|
|
287
|
+
raise "Unknown group type"
|
|
288
|
+
|
|
289
|
+
elif isinstance(node, NSRawPolicy):
|
|
290
|
+
policy_id = node.data.get("id", 0)
|
|
291
|
+
node.data.get("rules", {})
|
|
292
|
+
isglobal = node.data.get("global", 0)
|
|
293
|
+
|
|
294
|
+
source_zone = node.data.get("src-zone", None)
|
|
295
|
+
dest_zone = node.data.get("dst-zone", None)
|
|
296
|
+
source_addr = node.data.get("src-address", [])
|
|
297
|
+
dest_addr = node.data.get("dst-address", [])
|
|
298
|
+
service = node.data.get("service", [])
|
|
299
|
+
name = node.data.get("name", None)
|
|
300
|
+
|
|
301
|
+
found = None
|
|
302
|
+
subset = False
|
|
303
|
+
|
|
304
|
+
if policy_id and not source_zone and not dest_zone:
|
|
305
|
+
# we have an sub-addition to a policy..
|
|
306
|
+
subset = True
|
|
307
|
+
for i in self.policies:
|
|
308
|
+
if i.id == policy_id:
|
|
309
|
+
found = i
|
|
310
|
+
break
|
|
311
|
+
if not found:
|
|
312
|
+
raise "Sub policy before policy defined"
|
|
313
|
+
else:
|
|
314
|
+
# create a new policy
|
|
315
|
+
found = NSPolicy(id=policy_id, isglobal=isglobal, name=name)
|
|
316
|
+
|
|
317
|
+
if source_zone:
|
|
318
|
+
found.source_zone = source_zone
|
|
319
|
+
|
|
320
|
+
if dest_zone:
|
|
321
|
+
found.destination_zone = dest_zone
|
|
322
|
+
|
|
323
|
+
if source_addr:
|
|
324
|
+
for entry in source_addr:
|
|
325
|
+
t = self.address_book.find(entry, found.source_zone)
|
|
326
|
+
if t is None:
|
|
327
|
+
msg = f"No address entry: {entry}, zone: {found.source_zone}, policy: {found.id}"
|
|
328
|
+
raise exceptions.NetScreenParseError(msg)
|
|
329
|
+
|
|
330
|
+
if (
|
|
331
|
+
t.zone and found.source_zone
|
|
332
|
+
) and t.zone != found.source_zone:
|
|
333
|
+
raise (
|
|
334
|
+
f"{t.name} has a zone of {t.zone}, while the source zone"
|
|
335
|
+
f" of the policy is {found.source_zone}"
|
|
336
|
+
)
|
|
337
|
+
found["src-address"].append(t)
|
|
338
|
+
|
|
339
|
+
if dest_addr:
|
|
340
|
+
for entry in dest_addr:
|
|
341
|
+
t = self.address_book.find(entry, found.destination_zone)
|
|
342
|
+
if t is None:
|
|
343
|
+
msg = f"No address entry: {entry}, zone: {found.destination_zone}, policy: {found.id}"
|
|
344
|
+
raise exceptions.NetScreenParseError(msg)
|
|
345
|
+
|
|
346
|
+
if (
|
|
347
|
+
t.zone and found.destination_zone
|
|
348
|
+
) and t.zone != found.destination_zone:
|
|
349
|
+
raise (
|
|
350
|
+
f"{t.name} has a zone of {t.zone}, while the destination zone"
|
|
351
|
+
f" of the policy is {found.destination_zone}"
|
|
352
|
+
)
|
|
353
|
+
|
|
354
|
+
found["dst-address"].append(t)
|
|
355
|
+
|
|
356
|
+
if service:
|
|
357
|
+
for entry in service:
|
|
358
|
+
found["service"].append(self.service_book[entry])
|
|
359
|
+
|
|
360
|
+
if not subset:
|
|
361
|
+
self.policies.append(found)
|
|
362
|
+
else:
|
|
363
|
+
raise f"Unknown node type {str(type(node))}"
|
|
364
|
+
|
|
365
|
+
def output(self):
|
|
366
|
+
ret = []
|
|
367
|
+
for ent in self.address_book.output():
|
|
368
|
+
ret.append(ent)
|
|
369
|
+
for ent in self.service_book.output():
|
|
370
|
+
ret.append(ent)
|
|
371
|
+
for ent in self.policies:
|
|
372
|
+
for line in ent.output():
|
|
373
|
+
ret.append(line)
|
|
374
|
+
return ret
|
|
375
|
+
|
|
376
|
+
def output_terms(self):
|
|
377
|
+
ret = []
|
|
378
|
+
for ent in self.policies:
|
|
379
|
+
for term in ent.output_terms():
|
|
380
|
+
ret.append(term)
|
|
381
|
+
return ret
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
############################
|
|
385
|
+
# Policy/Service/Group stuff
|
|
386
|
+
############################
|
|
387
|
+
class NSRawGroup:
|
|
388
|
+
"""
|
|
389
|
+
Container for group definitions.
|
|
390
|
+
"""
|
|
391
|
+
|
|
392
|
+
def __init__(self, data):
|
|
393
|
+
if data[0] == "address" and len(data) == 3:
|
|
394
|
+
data.append(None)
|
|
395
|
+
if data[0] == "service" and len(data) == 2:
|
|
396
|
+
data.append(None)
|
|
397
|
+
|
|
398
|
+
self.data = data
|
|
399
|
+
|
|
400
|
+
def __iter__(self):
|
|
401
|
+
return self.data.__iter__()
|
|
402
|
+
|
|
403
|
+
def __len__(self):
|
|
404
|
+
return self.data.__len__()
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
class NSGroup(NetScreen):
|
|
408
|
+
"""
|
|
409
|
+
Container for address/service groups.
|
|
410
|
+
"""
|
|
411
|
+
|
|
412
|
+
def __init__(self, name=None, group_type="address", zone=None):
|
|
413
|
+
self.nodes = []
|
|
414
|
+
self.name = name
|
|
415
|
+
self.type = group_type
|
|
416
|
+
self.zone = zone
|
|
417
|
+
|
|
418
|
+
def append(self, item):
|
|
419
|
+
return getattr(self, "add_" + self.type)(item)
|
|
420
|
+
|
|
421
|
+
def add_address(self, addr):
|
|
422
|
+
assert self.type == "address"
|
|
423
|
+
if not isinstance(addr, NSAddress):
|
|
424
|
+
raise "add_address requires NSAddress object"
|
|
425
|
+
# make sure the entry hasn't already been added, and
|
|
426
|
+
# that all the zones are in the same zone
|
|
427
|
+
for i in self.nodes:
|
|
428
|
+
if i.zone != addr.zone:
|
|
429
|
+
raise f"zone {addr.zone} did not equal others in group"
|
|
430
|
+
if i.name == addr.name:
|
|
431
|
+
return
|
|
432
|
+
self.nodes.append(addr)
|
|
433
|
+
|
|
434
|
+
def add_service(self, svc):
|
|
435
|
+
assert self.type == "service"
|
|
436
|
+
if not isinstance(svc, NSService):
|
|
437
|
+
raise "add_service requires NSService object"
|
|
438
|
+
for i in self.nodes:
|
|
439
|
+
if i.name == svc.name:
|
|
440
|
+
return
|
|
441
|
+
self.nodes.append(svc)
|
|
442
|
+
|
|
443
|
+
def set_name(self, name):
|
|
444
|
+
self.name = name
|
|
445
|
+
|
|
446
|
+
def __getitem__(self, key):
|
|
447
|
+
# allow people to find things in groups via a dict style
|
|
448
|
+
for i in self.nodes:
|
|
449
|
+
if i.name == key:
|
|
450
|
+
return i
|
|
451
|
+
raise KeyError
|
|
452
|
+
|
|
453
|
+
def __iter__(self):
|
|
454
|
+
return self.nodes.__iter__()
|
|
455
|
+
|
|
456
|
+
def output_crap(self):
|
|
457
|
+
ret = ""
|
|
458
|
+
for i in self.nodes:
|
|
459
|
+
ret += i.output_crap()
|
|
460
|
+
return ret
|
|
461
|
+
|
|
462
|
+
def get_real(self):
|
|
463
|
+
ret = []
|
|
464
|
+
for i in self.nodes:
|
|
465
|
+
for real in i.get_real():
|
|
466
|
+
ret.append(real)
|
|
467
|
+
return ret
|
|
468
|
+
|
|
469
|
+
def output(self):
|
|
470
|
+
ret = []
|
|
471
|
+
for i in self.nodes:
|
|
472
|
+
zone = ""
|
|
473
|
+
if self.zone:
|
|
474
|
+
zone = f'"{self.zone}"'
|
|
475
|
+
ret.append(f'set group {self.type} {zone} "{self.name}" add "{i.name}"')
|
|
476
|
+
return ret
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
class NSServiceBook(NetScreen):
|
|
480
|
+
"""
|
|
481
|
+
Container for built-in service entries and their defaults.
|
|
482
|
+
|
|
483
|
+
Example:
|
|
484
|
+
service = NSService(name="stupid_http")
|
|
485
|
+
service.set_source_port((1,65535))
|
|
486
|
+
service.set_destination_port(80)
|
|
487
|
+
service.set_protocol('tcp')
|
|
488
|
+
print(service.output())
|
|
489
|
+
"""
|
|
490
|
+
|
|
491
|
+
def __init__(self, entries=None):
|
|
492
|
+
self.entries = entries or []
|
|
493
|
+
if entries:
|
|
494
|
+
self.entries = entries
|
|
495
|
+
|
|
496
|
+
defaults = [
|
|
497
|
+
("HTTP", "tcp", (0, 65535), (80, 80)),
|
|
498
|
+
("HTTPS", "tcp", (0, 65535), (443, 443)),
|
|
499
|
+
("FTP", "tcp", (0, 65535), (21, 21)),
|
|
500
|
+
("SSH", "tcp", (0, 65535), (22, 22)),
|
|
501
|
+
("SNMP", "udp", (0, 65535), (161, 162)),
|
|
502
|
+
("DNS", "udp", (0, 65535), (53, 53)),
|
|
503
|
+
("NTP", "udp", (0, 65535), (123, 123)),
|
|
504
|
+
("PING", "icmp", 0, 8),
|
|
505
|
+
("SYSLOG", "udp", (0, 65535), (514, 514)),
|
|
506
|
+
("MAIL", "tcp", (0, 65535), (25, 25)),
|
|
507
|
+
("SMTP", "tcp", (0, 65535), (25, 25)),
|
|
508
|
+
("LDAP", "tcp", (0, 65535), (389, 389)),
|
|
509
|
+
("TFTP", "udp", (0, 65535), (69, 69)),
|
|
510
|
+
("TRACEROUTE", "udp", (0, 65535), (33400, 34000)),
|
|
511
|
+
("DHCP-Relay", "udp", (0, 65535), (67, 68)),
|
|
512
|
+
("ANY", 0, (0, 65535), (0, 65535)),
|
|
513
|
+
("TCP-ANY", "tcp", (0, 65535), (0, 65535)),
|
|
514
|
+
("UDP-ANY", "udp", (0, 65535), (0, 65535)),
|
|
515
|
+
("ICMP-ANY", "icmp", (0, 65535), (0, 65535)),
|
|
516
|
+
]
|
|
517
|
+
|
|
518
|
+
for name, proto, src, dst in defaults:
|
|
519
|
+
self.entries.append(
|
|
520
|
+
NSService(
|
|
521
|
+
name=name,
|
|
522
|
+
protocol=proto,
|
|
523
|
+
source_port=src,
|
|
524
|
+
destination_port=dst,
|
|
525
|
+
predefined=True,
|
|
526
|
+
)
|
|
527
|
+
)
|
|
528
|
+
|
|
529
|
+
def has_key(self, key):
|
|
530
|
+
for entry in self.entries:
|
|
531
|
+
if key == entry.name:
|
|
532
|
+
return True
|
|
533
|
+
return False
|
|
534
|
+
|
|
535
|
+
def __iter__(self):
|
|
536
|
+
return self.entries.__iter__()
|
|
537
|
+
|
|
538
|
+
def __getitem__(self, item):
|
|
539
|
+
for entry in self.entries:
|
|
540
|
+
if item == entry.name:
|
|
541
|
+
return entry
|
|
542
|
+
|
|
543
|
+
raise KeyError("%s", item)
|
|
544
|
+
|
|
545
|
+
def append(self, item):
|
|
546
|
+
if isinstance(item, NSService):
|
|
547
|
+
return self.entries.append(item)
|
|
548
|
+
if isinstance(item, NSGroup) and item.type == "service":
|
|
549
|
+
return self.entries.append(item)
|
|
550
|
+
raise (
|
|
551
|
+
"item inserted into NSServiceBook, not an NSService or "
|
|
552
|
+
"NSGroup.type='service' object"
|
|
553
|
+
)
|
|
554
|
+
|
|
555
|
+
def output(self):
|
|
556
|
+
ret = []
|
|
557
|
+
for ent in self.entries:
|
|
558
|
+
for line in ent.output():
|
|
559
|
+
ret.append(line)
|
|
560
|
+
return ret
|
|
561
|
+
|
|
562
|
+
|
|
563
|
+
class NSAddressBook(NetScreen):
|
|
564
|
+
"""
|
|
565
|
+
Container for address book entries.
|
|
566
|
+
"""
|
|
567
|
+
|
|
568
|
+
def __init__(self, name="ANY", zone=None):
|
|
569
|
+
self.entries = {}
|
|
570
|
+
self.any = NSAddress(name="ANY")
|
|
571
|
+
|
|
572
|
+
def find(self, address, zone):
|
|
573
|
+
if not self.entries.has_key(zone):
|
|
574
|
+
return None
|
|
575
|
+
|
|
576
|
+
for nsaddr in self.entries[zone]:
|
|
577
|
+
if isinstance(address, IPy.IP):
|
|
578
|
+
if nsaddr.addr == address:
|
|
579
|
+
return nsaddr
|
|
580
|
+
elif isinstance(address, str):
|
|
581
|
+
isany = address.lower()
|
|
582
|
+
if isany == "any":
|
|
583
|
+
return self.any
|
|
584
|
+
if nsaddr.name == address:
|
|
585
|
+
return nsaddr
|
|
586
|
+
|
|
587
|
+
return None
|
|
588
|
+
|
|
589
|
+
def append(self, item):
|
|
590
|
+
if not isinstance(item, NSAddress) and (
|
|
591
|
+
(not isinstance(item, NSGroup)) and item.type != "address"
|
|
592
|
+
):
|
|
593
|
+
raise "Item inserted int NSAddress not correct type"
|
|
594
|
+
|
|
595
|
+
if not self.entries.has_key(item.zone):
|
|
596
|
+
self.entries[item.zone] = []
|
|
597
|
+
|
|
598
|
+
return self.entries[item.zone].append(item)
|
|
599
|
+
|
|
600
|
+
def name2ips(self, name, zone):
|
|
601
|
+
for entry in self.entries:
|
|
602
|
+
if entry.name == name:
|
|
603
|
+
if isinstance(entry, NSAddress):
|
|
604
|
+
return [entry.addr]
|
|
605
|
+
if isinstance(entry, NSGroup):
|
|
606
|
+
ret = []
|
|
607
|
+
for ent in entry:
|
|
608
|
+
ret.append(ent.addr)
|
|
609
|
+
return ret
|
|
610
|
+
|
|
611
|
+
def output(self):
|
|
612
|
+
ret = []
|
|
613
|
+
for zone, addrs in self.entries.items():
|
|
614
|
+
for addr in addrs:
|
|
615
|
+
for x in addr.output():
|
|
616
|
+
ret.append(x)
|
|
617
|
+
return ret
|
|
618
|
+
|
|
619
|
+
|
|
620
|
+
class NSAddress(NetScreen):
|
|
621
|
+
"""
|
|
622
|
+
Container for individual address items.
|
|
623
|
+
"""
|
|
624
|
+
|
|
625
|
+
def __init__(self, name=None, zone=None, addr=None, comment=None):
|
|
626
|
+
self.name = None
|
|
627
|
+
self.zone = None
|
|
628
|
+
self.addr = TIP("0.0.0.0/0")
|
|
629
|
+
self.comment = ""
|
|
630
|
+
if name:
|
|
631
|
+
self.set_name(name)
|
|
632
|
+
if zone:
|
|
633
|
+
self.set_zone(zone)
|
|
634
|
+
if addr:
|
|
635
|
+
self.set_address(addr)
|
|
636
|
+
if comment:
|
|
637
|
+
self.set_comment(comment)
|
|
638
|
+
|
|
639
|
+
def set_address(self, addr):
|
|
640
|
+
try:
|
|
641
|
+
a = TIP(addr)
|
|
642
|
+
except Exception as e:
|
|
643
|
+
raise e
|
|
644
|
+
self.addr = a
|
|
645
|
+
|
|
646
|
+
def set_zone(self, zone):
|
|
647
|
+
self.zone = zone
|
|
648
|
+
|
|
649
|
+
def set_name(self, name):
|
|
650
|
+
self.name = name
|
|
651
|
+
|
|
652
|
+
def set_comment(self, comment):
|
|
653
|
+
comment = f'"{comment}"'
|
|
654
|
+
self.comment = comment
|
|
655
|
+
|
|
656
|
+
def get_real(self):
|
|
657
|
+
return [self.addr]
|
|
658
|
+
|
|
659
|
+
def output_crap(self):
|
|
660
|
+
return f"[(Z:{self.zone}){self.addr.strNormal()}]"
|
|
661
|
+
|
|
662
|
+
def output(self):
|
|
663
|
+
tmpl = 'set address "%s" "%s" %s %s %s'
|
|
664
|
+
output = tmpl % (
|
|
665
|
+
self.zone,
|
|
666
|
+
self.name,
|
|
667
|
+
self.addr.strNormal(0),
|
|
668
|
+
self.addr.netmask(),
|
|
669
|
+
self.comment,
|
|
670
|
+
)
|
|
671
|
+
return [output]
|
|
672
|
+
|
|
673
|
+
|
|
674
|
+
class NSService(NetScreen):
|
|
675
|
+
"""
|
|
676
|
+
Container for individual service items.
|
|
677
|
+
"""
|
|
678
|
+
|
|
679
|
+
def __init__(
|
|
680
|
+
self,
|
|
681
|
+
name=None,
|
|
682
|
+
protocol=None,
|
|
683
|
+
source_port=(1, 65535),
|
|
684
|
+
destination_port=(1, 65535),
|
|
685
|
+
timeout=0,
|
|
686
|
+
predefined=False,
|
|
687
|
+
):
|
|
688
|
+
self.protocol = protocol
|
|
689
|
+
self.source_port = source_port
|
|
690
|
+
self.destination_port = destination_port
|
|
691
|
+
self.timeout = timeout
|
|
692
|
+
self.name = name
|
|
693
|
+
self.predefined = predefined
|
|
694
|
+
self.initialize()
|
|
695
|
+
|
|
696
|
+
def initialize(self):
|
|
697
|
+
self.set_name(self.name)
|
|
698
|
+
self.set_protocol(self.protocol)
|
|
699
|
+
self.set_source_port(self.source_port)
|
|
700
|
+
self.set_destination_port(self.destination_port)
|
|
701
|
+
self.set_timeout(self.timeout)
|
|
702
|
+
|
|
703
|
+
def __cmp__(self, other):
|
|
704
|
+
if not isinstance(other, NSService):
|
|
705
|
+
return -1
|
|
706
|
+
|
|
707
|
+
for a, b in {
|
|
708
|
+
self.protocol: other.protocol,
|
|
709
|
+
self.source_port: other.source_port,
|
|
710
|
+
self.destination_port: other.destination_port,
|
|
711
|
+
}.items():
|
|
712
|
+
if a < b:
|
|
713
|
+
return -1
|
|
714
|
+
if a > b:
|
|
715
|
+
return 1
|
|
716
|
+
|
|
717
|
+
return 0
|
|
718
|
+
|
|
719
|
+
def set_name(self, arg):
|
|
720
|
+
self.name = arg
|
|
721
|
+
|
|
722
|
+
def set_source_port(self, ports):
|
|
723
|
+
if isinstance(ports, int):
|
|
724
|
+
check_range([ports], 0, 65535)
|
|
725
|
+
self.source_port = (ports, ports)
|
|
726
|
+
elif isinstance(ports, tuple):
|
|
727
|
+
check_range(ports, 0, 65535)
|
|
728
|
+
self.source_port = ports
|
|
729
|
+
else:
|
|
730
|
+
raise "add_source_port needs int or tuple argument"
|
|
731
|
+
|
|
732
|
+
def set_destination_port(self, ports):
|
|
733
|
+
if isinstance(ports, int):
|
|
734
|
+
check_range([ports], 0, 65535)
|
|
735
|
+
self.destination_port = (ports, ports)
|
|
736
|
+
elif isinstance(ports, tuple):
|
|
737
|
+
check_range(ports, 0, 65535)
|
|
738
|
+
self.destination_port = ports
|
|
739
|
+
else:
|
|
740
|
+
raise "add_destination_port needs int or tuple argument"
|
|
741
|
+
|
|
742
|
+
def set_timeout(self, timeout):
|
|
743
|
+
self.timeout = timeout
|
|
744
|
+
|
|
745
|
+
def set_protocol(self, protocol):
|
|
746
|
+
if isinstance(protocol, str) or isinstance(protocol, int):
|
|
747
|
+
self.protocol = Protocol(protocol)
|
|
748
|
+
if isinstance(protocol, Protocol):
|
|
749
|
+
self.protocol = protocol
|
|
750
|
+
|
|
751
|
+
def output_crap(self):
|
|
752
|
+
return "[Service: %s (%d-%d):(%d-%d)]" % (
|
|
753
|
+
self.protocol,
|
|
754
|
+
self.source_port[0],
|
|
755
|
+
self.source_port[1],
|
|
756
|
+
self.destination_port[0],
|
|
757
|
+
self.destination_port[1],
|
|
758
|
+
)
|
|
759
|
+
|
|
760
|
+
def get_real(self):
|
|
761
|
+
return [(self.source_port, self.destination_port, self.protocol)]
|
|
762
|
+
|
|
763
|
+
def output(self):
|
|
764
|
+
if self.predefined:
|
|
765
|
+
return []
|
|
766
|
+
ret = 'set service "%s" protocol %s src-port %d-%d dst-port %d-%d' % (
|
|
767
|
+
self.name,
|
|
768
|
+
self.protocol,
|
|
769
|
+
self.source_port[0],
|
|
770
|
+
self.source_port[1],
|
|
771
|
+
self.destination_port[0],
|
|
772
|
+
self.destination_port[1],
|
|
773
|
+
)
|
|
774
|
+
if self.timeout:
|
|
775
|
+
ret += " timeout %d" % (self.timeout)
|
|
776
|
+
return [ret]
|
|
777
|
+
|
|
778
|
+
|
|
779
|
+
class NSRawPolicy:
|
|
780
|
+
"""
|
|
781
|
+
Container for policy definitions.
|
|
782
|
+
"""
|
|
783
|
+
|
|
784
|
+
def __init__(self, data, isglobal=0):
|
|
785
|
+
self.isglobal = isglobal
|
|
786
|
+
self.data = {}
|
|
787
|
+
|
|
788
|
+
for entry in data:
|
|
789
|
+
for key, val in entry.items():
|
|
790
|
+
self.data[key] = val
|
|
791
|
+
|
|
792
|
+
|
|
793
|
+
class NSPolicy(NetScreen):
|
|
794
|
+
"""
|
|
795
|
+
Container for individual policy definitions.
|
|
796
|
+
"""
|
|
797
|
+
|
|
798
|
+
def __init__(
|
|
799
|
+
self,
|
|
800
|
+
name=None,
|
|
801
|
+
address_book=NSAddressBook(),
|
|
802
|
+
service_book=NSServiceBook(),
|
|
803
|
+
address_groups=None,
|
|
804
|
+
service_groups=None,
|
|
805
|
+
source_zone="Untrust",
|
|
806
|
+
destination_zone="Trust",
|
|
807
|
+
id=0,
|
|
808
|
+
action="permit",
|
|
809
|
+
isglobal=False,
|
|
810
|
+
):
|
|
811
|
+
self.service_book = service_book
|
|
812
|
+
self.address_book = address_book
|
|
813
|
+
self.service_groups = service_groups or []
|
|
814
|
+
self.address_groups = address_groups or []
|
|
815
|
+
self.source_zone = source_zone
|
|
816
|
+
self.destination_zone = destination_zone
|
|
817
|
+
self.source_addresses = []
|
|
818
|
+
self.destination_addresses = []
|
|
819
|
+
self.services = []
|
|
820
|
+
self.action = action
|
|
821
|
+
|
|
822
|
+
self.id = id
|
|
823
|
+
self.name = name
|
|
824
|
+
self.isglobal = isglobal
|
|
825
|
+
|
|
826
|
+
def add_address(self, address, zone, address_book, addresses):
|
|
827
|
+
addr = TIP(address)
|
|
828
|
+
found = address_book.find(addr, zone)
|
|
829
|
+
if not found:
|
|
830
|
+
if addr.prefixlen() == 32:
|
|
831
|
+
name = f"h{addr.strNormal(0)}"
|
|
832
|
+
else:
|
|
833
|
+
name = f"n{addr.strNormal()}"
|
|
834
|
+
|
|
835
|
+
found = NSAddress(name=name, zone=zone, addr=addr.strNormal())
|
|
836
|
+
|
|
837
|
+
address_book.append(found)
|
|
838
|
+
addresses.append(found)
|
|
839
|
+
|
|
840
|
+
def add_source_address(self, address):
|
|
841
|
+
self.add_address(
|
|
842
|
+
address, self.source_zone, self.address_book, self.source_addresses
|
|
843
|
+
)
|
|
844
|
+
|
|
845
|
+
def add_destination_address(self, address):
|
|
846
|
+
self.add_address(
|
|
847
|
+
address,
|
|
848
|
+
self.destination_zone,
|
|
849
|
+
self.address_book,
|
|
850
|
+
self.destination_addresses,
|
|
851
|
+
)
|
|
852
|
+
|
|
853
|
+
def add_service(
|
|
854
|
+
self, protocol, source_port=(1, 65535), destination_port=(1, 65535)
|
|
855
|
+
):
|
|
856
|
+
found = None
|
|
857
|
+
if not protocol:
|
|
858
|
+
raise "no protocol defined in add_service"
|
|
859
|
+
|
|
860
|
+
if isinstance(destination_port, tuple):
|
|
861
|
+
sname = "%s%d-%d" % (protocol, destination_port[0], destination_port[1])
|
|
862
|
+
else:
|
|
863
|
+
sname = "%s%d" % (protocol, destination_port)
|
|
864
|
+
|
|
865
|
+
test_service = NSService(
|
|
866
|
+
name=sname,
|
|
867
|
+
source_port=source_port,
|
|
868
|
+
destination_port=destination_port,
|
|
869
|
+
protocol=protocol,
|
|
870
|
+
)
|
|
871
|
+
|
|
872
|
+
for svc in self.service_book:
|
|
873
|
+
if svc == test_service:
|
|
874
|
+
found = svc
|
|
875
|
+
break
|
|
876
|
+
|
|
877
|
+
if not found:
|
|
878
|
+
self.service_book.append(test_service)
|
|
879
|
+
found = test_service
|
|
880
|
+
self.services.append(found)
|
|
881
|
+
|
|
882
|
+
def __getitem__(self, key):
|
|
883
|
+
if key == "dst-address":
|
|
884
|
+
return self.destination_addresses
|
|
885
|
+
if key == "src-address":
|
|
886
|
+
return self.source_addresses
|
|
887
|
+
if key == "service":
|
|
888
|
+
return self.services
|
|
889
|
+
raise KeyError
|
|
890
|
+
|
|
891
|
+
def output_crap(self):
|
|
892
|
+
for service in self.services:
|
|
893
|
+
for src in self.source_addresses:
|
|
894
|
+
for dst in self.destination_addresses:
|
|
895
|
+
print(
|
|
896
|
+
src.output_crap(),
|
|
897
|
+
"->",
|
|
898
|
+
dst.output_crap(),
|
|
899
|
+
":",
|
|
900
|
+
service.output_crap(),
|
|
901
|
+
)
|
|
902
|
+
|
|
903
|
+
def output_human(self):
|
|
904
|
+
source_addrs = []
|
|
905
|
+
dest_addrs = []
|
|
906
|
+
dest_serv = []
|
|
907
|
+
serv_hash = {}
|
|
908
|
+
|
|
909
|
+
for i in self.source_addresses:
|
|
910
|
+
for addr in i.get_real():
|
|
911
|
+
source_addrs.append(addr)
|
|
912
|
+
|
|
913
|
+
for i in self.destination_addresses:
|
|
914
|
+
for addr in i.get_real():
|
|
915
|
+
dest_addrs.append(addr)
|
|
916
|
+
|
|
917
|
+
for i in self.services:
|
|
918
|
+
for serv in i.get_real():
|
|
919
|
+
# (1, 65535), (80, 80), <Protocol: tcp>
|
|
920
|
+
s, d, p = serv
|
|
921
|
+
|
|
922
|
+
if not serv_hash.has_key(p):
|
|
923
|
+
serv_hash[p] = {s: [d]}
|
|
924
|
+
|
|
925
|
+
else:
|
|
926
|
+
if not serv_hash[p].has_key(s):
|
|
927
|
+
serv_hash[p][s] = [d]
|
|
928
|
+
else:
|
|
929
|
+
serv_hash[p][s].append(d)
|
|
930
|
+
|
|
931
|
+
dest_serv.append(serv)
|
|
932
|
+
|
|
933
|
+
for protocol in serv_hash:
|
|
934
|
+
print(f"protocol {protocol}")
|
|
935
|
+
for source_ports in serv_hash[protocol]:
|
|
936
|
+
print(" source ports", source_ports)
|
|
937
|
+
dest_ports = serv_hash[protocol][source_ports]
|
|
938
|
+
# for dest_ports in serv_hash[protocol][source_ports]:
|
|
939
|
+
print(" dest ports", dest_ports)
|
|
940
|
+
term = create_trigger_term(
|
|
941
|
+
source_ips=source_addrs,
|
|
942
|
+
dest_ips=dest_addrs,
|
|
943
|
+
source_ports=[source_ports],
|
|
944
|
+
dest_ports=dest_ports,
|
|
945
|
+
protocols=[protocol],
|
|
946
|
+
)
|
|
947
|
+
for line in term.output(format="junos"):
|
|
948
|
+
print(line)
|
|
949
|
+
|
|
950
|
+
print("SOURCES", source_addrs)
|
|
951
|
+
print("DESTINATIONS", dest_addrs)
|
|
952
|
+
print("SERVICES", serv_hash)
|
|
953
|
+
|
|
954
|
+
def output_terms(self):
|
|
955
|
+
source_addrs = []
|
|
956
|
+
dest_addrs = []
|
|
957
|
+
dest_serv = []
|
|
958
|
+
terms = []
|
|
959
|
+
serv_hash = {}
|
|
960
|
+
|
|
961
|
+
for i in self.source_addresses:
|
|
962
|
+
for addr in i.get_real():
|
|
963
|
+
source_addrs.append(addr)
|
|
964
|
+
|
|
965
|
+
for i in self.destination_addresses:
|
|
966
|
+
for addr in i.get_real():
|
|
967
|
+
dest_addrs.append(addr)
|
|
968
|
+
|
|
969
|
+
for i in self.services:
|
|
970
|
+
for serv in i.get_real():
|
|
971
|
+
s, d, p = serv
|
|
972
|
+
if not serv_hash.has_key(p):
|
|
973
|
+
serv_hash[p] = {s: [d]}
|
|
974
|
+
else:
|
|
975
|
+
if not serv_hash[p].has_key(s):
|
|
976
|
+
serv_hash[p] = {s: [d]}
|
|
977
|
+
else:
|
|
978
|
+
serv_hash[p][s].append(d)
|
|
979
|
+
|
|
980
|
+
dest_serv.append(serv)
|
|
981
|
+
|
|
982
|
+
for protocol in serv_hash:
|
|
983
|
+
for source_ports in serv_hash[protocol]:
|
|
984
|
+
dest_ports = serv_hash[protocol][source_ports]
|
|
985
|
+
term = create_trigger_term(
|
|
986
|
+
source_ips=source_addrs,
|
|
987
|
+
dest_ips=dest_addrs,
|
|
988
|
+
source_ports=[source_ports],
|
|
989
|
+
dest_ports=dest_ports,
|
|
990
|
+
protocols=[protocol],
|
|
991
|
+
)
|
|
992
|
+
terms.append(term)
|
|
993
|
+
return terms
|
|
994
|
+
|
|
995
|
+
def output(self):
|
|
996
|
+
toret = []
|
|
997
|
+
num_saddrs = len(self.source_addresses)
|
|
998
|
+
num_daddrs = len(self.destination_addresses)
|
|
999
|
+
num_services = len(self.services)
|
|
1000
|
+
ret = "set policy "
|
|
1001
|
+
if self.isglobal:
|
|
1002
|
+
ret += "global "
|
|
1003
|
+
if self.id:
|
|
1004
|
+
ret += "id %d " % (self.id)
|
|
1005
|
+
if self.name:
|
|
1006
|
+
ret += f'name "{self.name}" '
|
|
1007
|
+
ret += f'from "{self.source_zone}" to "{self.destination_zone}" '
|
|
1008
|
+
for setter in [
|
|
1009
|
+
self.source_addresses,
|
|
1010
|
+
self.destination_addresses,
|
|
1011
|
+
self.services,
|
|
1012
|
+
]:
|
|
1013
|
+
if not len(setter):
|
|
1014
|
+
ret += '"ANY" '
|
|
1015
|
+
else:
|
|
1016
|
+
ret += f'"{setter[0].name}" '
|
|
1017
|
+
ret += f"{self.action}"
|
|
1018
|
+
toret.append(ret)
|
|
1019
|
+
|
|
1020
|
+
if num_saddrs > 1 or num_daddrs > 1 or num_services > 1:
|
|
1021
|
+
toret.append("set policy id %d" % (self.id))
|
|
1022
|
+
for k, v in {
|
|
1023
|
+
"src-address": self.source_addresses[1:],
|
|
1024
|
+
"dst-address": self.destination_addresses[1:],
|
|
1025
|
+
"service": self.services[1:],
|
|
1026
|
+
}.items():
|
|
1027
|
+
for item in v:
|
|
1028
|
+
toret.append(f' set {k} "{item.name}"')
|
|
1029
|
+
toret.append("exit")
|
|
1030
|
+
return toret
|