Parses the DNS Rulefile, validates the rules, replaces keywords
(self, file_)
| 494 | |
| 495 | |
| 496 | def __init__(self, file_): |
| 497 | """ |
| 498 | Parses the DNS Rulefile, validates the rules, replaces keywords |
| 499 | """ |
| 500 | |
| 501 | # track DNS requests here |
| 502 | self.match_history = {} |
| 503 | |
| 504 | self.rule_list = [] |
| 505 | |
| 506 | # A lol.com IP1,IP2,IP3,IP4,IP5,IP6 rebind_threshold%Rebind_IP1,Rebind_IP2 |
| 507 | with open(file_, 'r') as rulefile: |
| 508 | rules = rulefile.readlines() |
| 509 | lineno = 0 # keep track of line number for errors |
| 510 | |
| 511 | for rule in rules: |
| 512 | |
| 513 | # ignore blank lines or lines starting with hashmark (coments) |
| 514 | if len(rule.strip()) == 0 or rule.lstrip()[0] == "#" or rule == '\n': |
| 515 | # thank you to github user cambid for the comments suggestion |
| 516 | continue |
| 517 | |
| 518 | # Confirm that the rule has at least three columns to it |
| 519 | if len(rule.split()) < 3: |
| 520 | raise RuleError_BadFormat(lineno) |
| 521 | |
| 522 | # break the rule out into its components |
| 523 | s_rule = rule.split() |
| 524 | rule_type = s_rule[0].upper() |
| 525 | domain = s_rule[1] |
| 526 | ips = s_rule[2].split(',') # allow multiple ip's thru commas |
| 527 | |
| 528 | # only try this if the rule is long enough |
| 529 | if len(s_rule) == 4: |
| 530 | rebinds = s_rule[3] |
| 531 | # handle old rule style (maybe someone updated) |
| 532 | if '%' in rebinds: |
| 533 | rebind_threshold,rebinds = rebinds.split('%') |
| 534 | rebinds = rebinds.split(',') |
| 535 | rebind_threshold = int(rebind_threshold) |
| 536 | else: |
| 537 | # in the old days we assumed a rebind thresh of 1 |
| 538 | rebind_threshold = 1 |
| 539 | else: |
| 540 | rebinds = None |
| 541 | rebind_threshold = None |
| 542 | |
| 543 | # Validate the rule |
| 544 | # make sure we understand this type of response |
| 545 | if rule_type not in TYPE.values(): |
| 546 | raise RuleError_BadRuleType(lineno) |
| 547 | # attempt to parse the regex (if any) in the domain field |
| 548 | try: |
| 549 | domain = re.compile(domain, flags=re.IGNORECASE) |
| 550 | except: |
| 551 | raise RuleError_BadRegularExpression(lineno) |
| 552 | |
| 553 | # replace self in the list of ips and list of rebinds (if any) |
nothing calls this directly
no test coverage detected