#!/usr/bin/python

"""FIBN (Firewall Ipset Blacklist Network): Networked (master/slave'd) blacklist generator and ipset builder."""

from firewall.client import FirewallClient, FirewallClientIPSetSettings
from zlib import decompress
from syslog import syslog
from urllib2 import urlopen, HTTPError

__author__ = 'LEVEL6'
__version__ = '0.5'

def get_config():
     with open('/etc/fibn/fibn.conf','r') as f:
        for line in f:
            variable_name = line.split("=")[0]
            if (variable_name == "MASTERURL"):
                master_url = line.split("=")[1]
                return master_url

def get_ips(url):
    try:
        response = urlopen(url)
    except HTTPError as e:
        syslog('Download failed: HTTP Error %i' % e.code)
        return []
    except:
        syslog('Download failed.')
        return []
    try:
        ip_list_txt = response.read()
    except:
         syslog('An error has occured.')
         return []
    ip_list = []

    with open('/etc/fibn/local.txt','r') as f:
        for line in f:
            line_nonl = line.rstrip();
            if (len(line_nonl) > 0 and line_nonl[0] != '#' and line_nonl.count('.') == 3):
                ip_list.append(line_nonl)
        
    for entry in ip_list_txt.split('\n'):
        if (len(entry) > 0 and entry[0] != '#' and entry.count('.') == 3):
            ip_list.append(entry)

    return sorted(set(ip_list))

def mk_ipset(name, type, client):
    settings = FirewallClientIPSetSettings()
    settings.setType(type)
    config = client.config()
    return config.addIPSet(name, settings)

def main():
    ipset_name = 'blacklist'
    ipset_type = 'hash:ip'
    rules = ['rule family=\"ipv4\" source ipset=\"' + ipset_name + '\" drop']
    listurl = get_config()
    fw_client = FirewallClient()
    zone_name = fw_client.getDefaultZone()

    iplist = get_ips(listurl)

    if (fw_client.connected and len(iplist) > 0):
        if (ipset_name in fw_client.config().getIPSetNames()):
            ipset = fw_client.config().getIPSetByName(ipset_name)
        else:
            ipset = mk_ipset(ipset_name, ipset_type, fw_client)
        fw_client.reload()

        for ip in iplist:
            fw_client.addEntry(ipset_name, ip)
        for rule in rules:
            fw_client.addRichRule(zone_name, rule)
    else:
        syslog('An error occurred.')



if (__name__ == '__main__'):
    main()
