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.
Files changed (61) hide show
  1. trigger/__init__.py +7 -0
  2. trigger/acl/__init__.py +32 -0
  3. trigger/acl/autoacl.py +70 -0
  4. trigger/acl/db.py +324 -0
  5. trigger/acl/dicts.py +357 -0
  6. trigger/acl/grammar.py +112 -0
  7. trigger/acl/ios.py +222 -0
  8. trigger/acl/junos.py +422 -0
  9. trigger/acl/models.py +118 -0
  10. trigger/acl/parser.py +168 -0
  11. trigger/acl/queue.py +296 -0
  12. trigger/acl/support.py +1431 -0
  13. trigger/acl/tools.py +746 -0
  14. trigger/bin/__init__.py +0 -0
  15. trigger/bin/acl.py +233 -0
  16. trigger/bin/acl_script.py +574 -0
  17. trigger/bin/aclconv.py +82 -0
  18. trigger/bin/check_access.py +93 -0
  19. trigger/bin/check_syntax.py +66 -0
  20. trigger/bin/fe.py +197 -0
  21. trigger/bin/find_access.py +191 -0
  22. trigger/bin/gnng.py +434 -0
  23. trigger/bin/gong.py +86 -0
  24. trigger/bin/load_acl.py +841 -0
  25. trigger/bin/load_config.py +18 -0
  26. trigger/bin/netdev.py +317 -0
  27. trigger/bin/optimizer.py +638 -0
  28. trigger/bin/run_cmds.py +18 -0
  29. trigger/changemgmt/__init__.py +352 -0
  30. trigger/changemgmt/bounce.py +57 -0
  31. trigger/cmds.py +1217 -0
  32. trigger/conf/__init__.py +94 -0
  33. trigger/conf/global_settings.py +674 -0
  34. trigger/contrib/__init__.py +7 -0
  35. trigger/exceptions.py +307 -0
  36. trigger/gorc.py +172 -0
  37. trigger/netdevices/__init__.py +1288 -0
  38. trigger/netdevices/loader.py +174 -0
  39. trigger/netscreen.py +1030 -0
  40. trigger/packages/__init__.py +6 -0
  41. trigger/packages/peewee.py +8084 -0
  42. trigger/rancid.py +463 -0
  43. trigger/tacacsrc.py +584 -0
  44. trigger/twister.py +2203 -0
  45. trigger/twister2.py +745 -0
  46. trigger/utils/__init__.py +88 -0
  47. trigger/utils/cli.py +349 -0
  48. trigger/utils/importlib.py +77 -0
  49. trigger/utils/network.py +157 -0
  50. trigger/utils/rcs.py +178 -0
  51. trigger/utils/templates.py +81 -0
  52. trigger/utils/url.py +78 -0
  53. trigger/utils/xmltodict.py +298 -0
  54. trigger-2.0.0.dist-info/METADATA +146 -0
  55. trigger-2.0.0.dist-info/RECORD +61 -0
  56. trigger-2.0.0.dist-info/WHEEL +5 -0
  57. trigger-2.0.0.dist-info/entry_points.txt +15 -0
  58. trigger-2.0.0.dist-info/licenses/AUTHORS.md +20 -0
  59. trigger-2.0.0.dist-info/licenses/LICENSE.md +28 -0
  60. trigger-2.0.0.dist-info/top_level.txt +2 -0
  61. 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