def main():
    print('Starting PfSense Parental Control App')

    print('Finding LAN devices')
    devices = find_devices()

    print('Finding Rule Overides')
    overrides = get_overrides()

    print('Finding blocked users')
    blocked = find_blocked(devices, overrides)

    print('Resolving IP addresses')
    blocked_ip = [[build_descr(b), devices.get(b['MAC'])] for b in blocked]

    print("Configuring Faux API")
    api = PfsenseFauxapi(PFSENSE_HOST, apikey, apisecret)
    api.proto = 'http'

    print("Requesting config")
    current_block_rules, default_rules = get_rules(api)
    current_block_ip = dict(
        (r['descr'], r['source']['address']) for r in current_block_rules)

    new_rules = build_new_rules(blocked_ip, current_block_ip)
    new_patch = create_filter_rule_patch(new_rules + default_rules)

    pprint.pprint(new_patch)
    print("patching")
    api.config_patch(new_patch)
    api.function_call({
        'function': 'filter_configure_sync',
        'args': [False],
        'includes': ['shaper.inc'],
    })
def test_config_patch(mock_requests_post):

    fauxapi = PfsenseFauxapi(host=None, apikey=None, apisecret=None)
    mock_requests_post.return_value.status_code = 200
    mock_requests_post.return_value.text = '{"callid": "5c8dbe47090f8", "action": "config_patch", "message": "ok", "data": {"do_backup": true, "do_reload": true, "previous_config_file": "/cf/conf/backup/config-1552793159.xml"}}'

    response = fauxapi.config_patch(config={})
    assert response['action'] == 'config_patch'
    assert response['message'] == 'ok'
    assert response['data'] is not None
예제 #3
0
config_aliases = FauxapiLib.config_get('aliases')
print(json.dumps(
    FauxapiLib.config_set(config_aliases, 'aliases'))
)

# config_patch
# =============================================================================
# in this example we patch a specific set of configuration parameters and then revert them back to what they were
config_patch = {
    'system': {
        'dnsserver': ['8.8.8.8', '8.8.4.4'],
        'hostname': 'testing'
    }
}
print(json.dumps(
    FauxapiLib.config_patch(config_patch)
))

# config_patch - set dnsserver to what it was originally
config_patch = {
    'system': {
        'dnsserver': config['system']['dnsserver'] if 'dnsserver' in config['system'] else [''],
        'hostname': config['system']['hostname'],
    }
}
print(json.dumps(
    FauxapiLib.config_patch(config_patch)
))

# config get the full configuration again so we can manually confirm it has been restored
config = FauxapiLib.config_get()
예제 #4
0
class UserGroupManagementFauxapi():

    fauxapi_host = None
    fauxapi_apikey = None
    fauxapi_apisecret = None

    system_config = None

    FauxapiLib = None

    def __init__(self,
                 fauxapi_host,
                 fauxapi_apikey,
                 fauxapi_apisecret,
                 debug=False):
        self.FauxapiLib = PfsenseFauxapi(fauxapi_host, fauxapi_apikey,
                                         fauxapi_apisecret, debug)

    # user functions
    # =========================================================================

    def get_users(self):
        self._reload_system_config()

        response_data = {}
        for user in self.system_config['system']['user']:
            response_data[user['name']] = user
            del (response_data[user['name']]['name'])
        return response_data

    def add_user(self, username):
        self._reload_system_config()

        user_index, user = self._get_entity('user', username)
        if user_index is not None:
            raise UserGroupManagementFauxapiException('user already exists',
                                                      username)

        user = {
            'scope': 'user',
            'bcrypt-hash': 'no-password-set',
            'descr': '',
            'name': username,
            'expires': '',
            'dashboardcolumns': '2',
            'authorizedkeys': '',
            'ipsecpsk': '',
            'webguicss': 'pfSense.css',
            'uid': self._get_next_id('uid'),
        }

        patch_system_user = {
            'system': {
                'user': self.system_config['system']['user']
            }
        }
        patch_system_user['system']['user'].append(user)

        response = self.FauxapiLib.config_patch(patch_system_user)
        if response['message'] != 'ok':
            raise UserGroupManagementFauxapiException('unable to add user',
                                                      response['message'])

        self._increment_next_id('uid')

        return user

    def manage_user(self, username, attributes):
        self._reload_system_config()

        valid_attributes = [
            'password', 'descr', 'expires', 'dashboardcolumns',
            'authorizedkeys', 'ipsecpsk', 'webguicss', 'disabled', 'priv'
        ]

        user_index, user = self._get_entity('user', username)
        if user_index is None:
            raise UserGroupManagementFauxapiException('user does not exist',
                                                      username)

        if type(attributes) != dict:
            raise UserGroupManagementFauxapiException(
                'attributes is incorrect type')

        for attribute, value in attributes.items():
            if attribute not in valid_attributes:
                raise UserGroupManagementFauxapiException(
                    'unsupported attribute type', attribute)

            if attribute == 'disabled':
                if value is True:
                    user[attribute] = ''
                else:
                    if attribute in user:
                        del (user[attribute])
            elif attribute == 'password':
                user['bcrypt-hash'] = bcrypt.hashpw(
                    value.encode('utf8'), bcrypt.gensalt()).decode('utf8')
            else:
                if len(value) == 0 and attribute in user:
                    del (user[attribute])
                elif len(value) > 0:
                    user[attribute] = value

        patch_system_user = {
            'system': {
                'user': self.system_config['system']['user']
            }
        }
        patch_system_user['system']['user'][user_index] = user

        response = self.FauxapiLib.config_patch(patch_system_user)
        if response['message'] != 'ok':
            raise UserGroupManagementFauxapiException('unable to manage user',
                                                      response['message'])

        return user

    def remove_user(self, username):
        self._reload_system_config()

        user_index, user = self._get_entity('user', username)
        if user_index is None:
            raise UserGroupManagementFauxapiException('user does not exist',
                                                      username)

        patch_system_user = {
            'system': {
                'user': self.system_config['system']['user']
            }
        }
        del (patch_system_user['system']['user'][user_index])

        response = self.FauxapiLib.config_patch(patch_system_user)
        if response['message'] != 'ok':
            raise UserGroupManagementFauxapiException('unable to remove user',
                                                      response['message'])

        return user

    # group functions
    # =========================================================================

    def get_groups(self):
        self._reload_system_config()

        response_data = {}
        for group in self.system_config['system']['group']:
            response_data[group['name']] = group
            del (response_data[group['name']]['name'])
        return response_data

    def add_group(self, groupname):
        self._reload_system_config()

        group_index, group = self._get_entity('group', groupname)
        if group_index is not None:
            raise UserGroupManagementFauxapiException('group already exists',
                                                      groupname)

        group = {
            'scope': 'local',
            'description': '',
            'name': groupname,
            'gid': self._get_next_id('gid'),
        }

        patch_system_group = {
            'system': {
                'group': self.system_config['system']['group']
            }
        }
        patch_system_group['system']['group'].append(group)

        response = self.FauxapiLib.config_patch(patch_system_group)
        if response['message'] != 'ok':
            raise UserGroupManagementFauxapiException('unable to add group',
                                                      response['message'])

        self._increment_next_id('gid')

        return group

    def manage_group(self, groupname, attributes):
        self._reload_system_config()

        valid_attributes = ['description', 'member', 'priv']

        group_index, group = self._get_entity('group', groupname)
        if group_index is None:
            raise UserGroupManagementFauxapiException('group does not exist',
                                                      groupname)

        if type(attributes) != dict:
            raise UserGroupManagementFauxapiException(
                'attributes is incorrect type')

        for attribute, value in attributes.items():
            if attribute not in valid_attributes:
                raise UserGroupManagementFauxapiException(
                    'unsupported attribute type', attribute)

            if attribute == 'member':
                if type(value) != list:
                    raise UserGroupManagementFauxapiException(
                        'member attribute is incorrect type')
            elif attribute == 'priv':
                if type(value) != list:
                    raise UserGroupManagementFauxapiException(
                        'priv attribute is incorrect type')

            if len(value) == 0 and attribute in group:
                del (group[attribute])
            elif len(value) > 0:
                group[attribute] = value

        patch_system_group = {
            'system': {
                'group': self.system_config['system']['group']
            }
        }
        patch_system_group['system']['group'][group_index] = group

        response = self.FauxapiLib.config_patch(patch_system_group)
        if response['message'] != 'ok':
            raise UserGroupManagementFauxapiException('unable to manage group',
                                                      response['message'])

        return group

    def remove_group(self, groupname):
        self._reload_system_config()

        group_index, group = self._get_entity('group', groupname)
        if group_index is None:
            raise UserGroupManagementFauxapiException('group does not exist',
                                                      groupname)

        patch_system_group = {
            'system': {
                'group': self.system_config['system']['group']
            }
        }
        del (patch_system_group['system']['group'][group_index])

        response = self.FauxapiLib.config_patch(patch_system_group)
        if response['message'] != 'ok':
            raise UserGroupManagementFauxapiException('unable to remove group',
                                                      response['message'])

        return group

    # internal helper functions
    # =========================================================================

    def _get_entity(self, entity_type, entity_name):

        entity = None
        entity_index = 0
        for entity_data in self.system_config['system'][entity_type]:
            if entity_data['name'] == entity_name:
                entity = entity_data
                break
            entity_index += 1

        if entity is None:
            return None, None

        return entity_index, entity

    def _get_next_id(self, id_type):
        id_name = 'next{}'.format(id_type)
        return self.system_config['system'][id_name]

    def _increment_next_id(self, id_type):
        id_name = 'next{}'.format(id_type)
        next_id = int(self._get_next_id(id_type)) + 1
        patch_system_nextid = {'system': {id_name: str(next_id)}}
        response = self.FauxapiLib.config_patch(patch_system_nextid)
        if response['message'] != 'ok':
            raise UserGroupManagementFauxapiException(
                'unable to increment the nextid', id_type)
        return next_id

    def _reload_system_config(self):
        self.system_config = self.FauxapiLib.config_get()
예제 #5
0
# NB: again, nothing amazing happening in this example, we are are again only writing back the same (section)
# configuration, the developer more likely wants to perform some kind of operation on `config_aliases` before calling
# the config_set function again.
config_aliases = FauxapiLib.config_get('aliases')
print(json.dumps(FauxapiLib.config_set(config_aliases, 'aliases')))

# config_patch
# =============================================================================
# in this example we patch a specific set of configuration parameters and then revert them back to what they were
config_patch = {
    'system': {
        'dnsserver': ['8.8.8.8', '8.8.4.4'],
        'hostname': 'testing'
    }
}
print(json.dumps(FauxapiLib.config_patch(config_patch)))

# config_patch - set dnsserver to what it was originally
config_patch = {
    'system': {
        'dnsserver':
        config['system']['dnsserver']
        if 'dnsserver' in config['system'] else [''],
        'hostname':
        config['system']['hostname'],
    }
}
print(json.dumps(FauxapiLib.config_patch(config_patch)))

# config get the full configuration again so we can manually confirm it has been restored
config = FauxapiLib.config_get()