<commit_before>#!/usr/bin/python
# The MIT License (MIT)
# 
# Copyright (C) 2015, <NAME> <<EMAIL>>
# 
# Permission is hereby granted, free of charge, to any person 
# obtaining a copy of this software and associated documentation 
# files (the "Software"), to deal in the Software without 
# restriction, including without limitation the rights to use, 
# copy, modify, merge, publish, distribute, sublicense, and/or sell 
# copies of the Software, and to permit persons to whom the 
# Software is furnished to do so, subject to the following 
# conditions: 
# 
# The above copyright notice and this permission notice shall be 
# included in all copies or substantial portions of the Software. 
# 
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
# NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
# OTHER DEALINGS IN THE SOFTWARE.

import flask, iptc

app = flask.Flask(__name__)

# do table names in uppercase, this is what we'll query iptc with
TABLES = ['FILTER']
FILTER_CHAINS = ['INPUT', 'OUTPUT', 'FORWARD']
TABLE_CHAINS = { 'FILTER' : FILTER_CHAINS }
TARGETS = ['ACCEPT', 'DROP']

class Rule:

    def __init__(self, num=None, in_interface=None, out_interface=None, src=None, dst=None, protocol=None, target=None):
        self.num = num
        self.in_interface = in_interface
        self.out_interface = out_interface
        self.src = src
        self.dst = dst
        self.protocol = protocol
        self.target = target

    @staticmethod
    def build_from_iptables(rule, rule_num):
        rule_dict = {}
        rule_dict['num'] = rule_num
        rule_dict['target'] = rule.target.name
        # handle logic for table/chain-specific stuff (can do this better
        # example: in_interface is only valid for INPUT chain in FILTER table
        if rule.in_interface:
            rule_dict['in_interface'] = rule.in_interface
        if rule.out_interface:
            rule_dict['out_interface'] = rule.out_interface
        rule_dict['protocol'] = rule.protocol
        rule_dict['src'] = rule.src
        rule_dict['dst'] = rule.dst
        # should return a Rule class
        return Rule(**rule_dict)

    def write_to_iptables(self, table_name, chain_name):
        table = iptc.Table(table_name.lower())
        table.refresh()
        chains_by_name = {chain.name : chain for chain in table.chains}
        chain = chains_by_name[chain_name.upper()]
        rule = iptc.Rule()
        if self.in_interface:
            rule.in_interface = self.in_interface
        if self.out_interface:
            rule.out_interface = self.out_interface
        if self.src:
            rule.src = self.src
        if self.dst:
            rule.dst = self.dst
        if self.protocol:
            rule.protocol = self.protocol
        else:
            rule.protocol = 'ip'
        rule.target = iptc.Target(rule, self.target)
        chain.insert_rule(rule)

def parse_iptc_rule_to_dict(rule, rule_num):
    rule_dict = {}
    rule_dict['num'] = rule_num
    rule_dict['target'] = rule.target.name
    # handle logic for table/chain-specific stuff (can do this better
    # example: in_interface is only valid for INPUT chain in FILTER table
    if rule.in_interface:
        rule_dict['in_interface'] = rule.in_interface
    if rule.out_interface:
        rule_dict['out_interface'] = rule.out_interface
    rule_dict['protocol'] = rule.protocol
    rule_dict['src'] = rule.src
    rule_dict['dst'] = rule.dst
    return rule_dict


def get_iptables_rules_from_chain(table_name, chain_name):
    table = iptc.Table(table_name.lower())
    table.refresh()
    chains_by_name = {chain.name : chain for chain in table.chains}
    chain = chains_by_name[chain_name.upper()]
    rules = [parse_iptc_rule_to_dict(rule, rule_num) for rule_num, rule in enumerate(chain.rules)]
    return rules

def add_iptables_rule_to_chain(table_name, chain_name, json_input):
    # it would be better to have a class for rules that does sanity checking...
    table = iptc.Table(table_name.lower())
    table.refresh()
    chains_by_name = {chain.name : chain for chain in table.chains}
    chain = chains_by_name[chain_name.upper()]
    rule = iptc.Rule()
    if 'in_interface' in json_input:
        rule.in_interface = json_input['in_interface']
    if 'out_interface' in json_input:
        rule.out_interface = json_input['out_interface']
    if 'src' in json_input:
        rule.src = json_input['src']
    if 'dst' in json_input:
        rule.src = json_input['dst']
    if 'protocol' in json_input:
        rule.protocol = json_input['protocol']
    else:
        rule.protocol = 'ip'
    rule.target = iptc.Target(rule, json_input['target'])
    chain.insert_rule(rule)

@app.route('/api/v1.0/table', methods=['GET'])
def show_tables():
    return flask.jsonify({'tables' : TABLES})

@app.route('/api/v1.0/table/<table_name>/chain', methods=['GET'])<commit_msg>mocking up classes to output nice RESTful responses<commit_after>#!/usr/bin/python
# The MIT License (MIT)
# 
# Copyright (C) 2015, <NAME> <<EMAIL>>
# 
# Permission is hereby granted, free of charge, to any person 
# obtaining a copy of this software and associated documentation 
# files (the "Software"), to deal in the Software without 
# restriction, including without limitation the rights to use, 
# copy, modify, merge, publish, distribute, sublicense, and/or sell 
# copies of the Software, and to permit persons to whom the 
# Software is furnished to do so, subject to the following 
# conditions: 
# 
# The above copyright notice and this permission notice shall be 
# included in all copies or substantial portions of the Software. 
# 
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
# NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
# OTHER DEALINGS IN THE SOFTWARE.

import flask, iptc

app = flask.Flask(__name__)

# do table names in uppercase, this is what we'll query iptc with
TABLES = ['FILTER']
FILTER_CHAINS = ['INPUT', 'OUTPUT', 'FORWARD']
TABLE_CHAINS = { 'FILTER' : FILTER_CHAINS }
TARGETS = ['ACCEPT', 'DROP']

class Rule:

    def __init__(self, num=None, in_interface=None, out_interface=None, src=None, dst=None, protocol=None, target=None):
        self.num = num
        self.in_interface = in_interface
        self.out_interface = out_interface
        self.src = src
        self.dst = dst
        self.protocol = protocol
        self.target = target

    @staticmethod
    def build_from_iptables(rule, rule_num):
        rule_dict = {}
        rule_dict['num'] = rule_num
        rule_dict['target'] = rule.target.name
        # handle logic for table/chain-specific stuff (can do this better
        # example: in_interface is only valid for INPUT chain in FILTER table
        if rule.in_interface:
            rule_dict['in_interface'] = rule.in_interface
        if rule.out_interface:
            rule_dict['out_interface'] = rule.out_interface
        rule_dict['protocol'] = rule.protocol
        rule_dict['src'] = rule.src
        rule_dict['dst'] = rule.dst
        # should return a Rule class
        return Rule(**rule_dict)

    def write_to_iptables(self, table_name, chain_name):
        table = iptc.Table(table_name.lower())
        table.refresh()
        chains_by_name = {chain.name : chain for chain in table.chains}
        chain = chains_by_name[chain_name.upper()]
        rule = iptc.Rule()
        if self.in_interface:
            rule.in_interface = self.in_interface
        if self.out_interface:
            rule.out_interface = self.out_interface
        if self.src:
            rule.src = self.src
        if self.dst:
            rule.dst = self.dst
        if self.protocol:
            rule.protocol = self.protocol
        else:
            rule.protocol = 'ip'
        rule.target = iptc.Target(rule, self.target)
        chain.insert_rule(rule)

def parse_iptc_rule_to_dict(rule, rule_num):
    rule_dict = {}
    rule_dict['num'] = rule_num
    rule_dict['target'] = rule.target.name
    # handle logic for table/chain-specific stuff (can do this better
    # example: in_interface is only valid for INPUT chain in FILTER table
    if rule.in_interface:
        rule_dict['in_interface'] = rule.in_interface
    if rule.out_interface:
        rule_dict['out_interface'] = rule.out_interface
    rule_dict['protocol'] = rule.protocol
    rule_dict['src'] = rule.src
    rule_dict['dst'] = rule.dst
    return rule_dict


def get_iptables_rules_from_chain(table_name, chain_name):
    table = iptc.Table(table_name.lower())
    table.refresh()
    chains_by_name = {chain.name : chain for chain in table.chains}
    chain = chains_by_name[chain_name.upper()]
    rules = [parse_iptc_rule_to_dict(rule, rule_num) for rule_num, rule in enumerate(chain.rules)]
    return rules

def add_iptables_rule_to_chain(table_name, chain_name, json_input):
    # it would be better to have a class for rules that does sanity checking...
    table = iptc.Table(table_name.lower())
    table.refresh()
    chains_by_name = {chain.name : chain for chain in table.chains}
    chain = chains_by_name[chain_name.upper()]
    rule = iptc.Rule()
    if 'in_interface' in json_input:
        rule.in_interface = json_input['in_interface']
    if 'out_interface' in json_input:
        rule.out_interface = json_input['out_interface']
    if 'src' in json_input:
        rule.src = json_input['src']
    if 'dst' in json_input:
        rule.src = json_input['dst']
    if 'protocol' in json_input:
        rule.protocol = json_input['protocol']
    else:
        rule.protocol = 'ip'
    rule.target = iptc.Target(rule, json_input['target'])
    chain.insert_rule(rule)

class RestfulObject:

    def __init__(self):
        pass

    def to_rest_response(self):
        output = {'data' : None,
                'links' : None,
                 }
        return output

class IptablesTable(RestfulObject):
    pass

class IptablesChain(RestfulObject):
    pass

@app.route('/api/v1.0/table', methods=['GET'])
def show_tables():
    return flask.jsonify({'tables' : TABLES})

@app.route('/api/v1.0/table/<table_name>/chain', methods=['GET'])
{'fraction_non_alphanumeric': 0.09921040408732001, 'fraction_numerical': 0.0014862981885740826, 'mean_word_length': 3.0966514459665144, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3273668', 'n_tokens_mistral': 3316, 'n_tokens_neox': 3233, 'n_words': 962}