#!/usr/bin/env python
# -*- coding: utf-8 -*-
import utils
import base
import pwd

from utils import pretty_print, OK, anim
from base import dev

class firewall(base.firewall):
    """Pare-feu de zamok, le serveur des adhérents"""
    def __init__(self):
        super(self.__class__, self).__init__()

        self.reloadable.update({
            'admin_vlan' : self.admin_vlan,
            'blacklist_output' : self.blacklist_output,
        })

        self.use_ipset.extend([])
        self.use_tc.extend([])


    def raw_table(self):
        table = 'raw'

        super(self.__class__, self).raw_table()

        return

    def mangle_table(self):
        table = 'mangle'

        super(self.__class__, self).mangle_table()

        return

    def filter_table(self):
        table = 'filter'

        super(self.__class__, self).filter_table()

        chain = 'OUTPUT'
        self.add(table, chain , '-d 224.0.0.0/4 -j DROP')
        admin_vlan_chain = self.admin_vlan(table)
        self.add(table, chain, '-m state --state RELATED,ESTABLISHED -j ACCEPT')
        for net in base.config.NETs['adm']:
            self.add(table, chain, '-d %s -j %s' % (net, admin_vlan_chain))
        self.add(table, chain, '-o lo -j ACCEPT')
        self.add(table, chain, '-j %s' % self.blacklist_output(table))

        return

    def nat_table(self):
        table = 'nat'

        super(self.__class__, self).raw_table()
        return

    def admin_vlan(self, table=None, apply=False):
        chain='ADMIN-VLAN'

        if table == 'filter':
            pretty_print(table, chain)
            # ldap et dns toujours joinable
            self.add(table, chain, '-p tcp --dport ldap -j ACCEPT')
            self.add(table, chain, '-p tcp --dport domain -j ACCEPT')
            self.add(table, chain, '-p udp --dport domain -j ACCEPT')

            # Pour le nfs (le paquet à laisser passer n'a pas d'owner)
            self.add(table, chain, '-d nfs.adm.crans.org -j ACCEPT')

            for user in base.config.adm_users:
                try: self.add(table, chain, '-m owner --uid-owner %d -j ACCEPT' % pwd.getpwnam(user)[2])
                except KeyError: print "Utilisateur %s inconnu" % user

            for adh in self.conn.search(u"(|(droits=%s)(droits=%s))" % (utils.lc_ldap.attributs.nounou, utils.lc_ldap.attributs.apprenti)):
                self.add(table, chain, '-m owner --uid-owner %s -j RETURN' % adh['uidNumber'][0])

            # Rien d'autre ne passe
            self.add(table, chain, '-j REJECT --reject-with icmp-net-prohibited')
            print OK

        if apply:
            self.apply(table, chain)
        return chain

    def blacklist_maj(self, ips):
        self.blacklist_output('filter', apply=True)
        self.blacklist_hard_maj(ips)

    def blacklists(self, table=None, fill_ipset=False, apply=False):
        self.blacklist_hard(table=table, fill_ipset=fill_ipset, apply=apply)
        self.blacklist_output(table=table, apply=apply)

    def blacklist_output(self, table=None, apply=False):
        """Empêche les gens blacklisté d'utiliser zamok comme relaie"""
        chain='BLACKLIST-OUTPUT'

        if table == 'filter':
            pretty_print(table, chain)
            self.add(table, chain, '-d 127.0.0.1/8 -j RETURN')
            for net in base.config.NETs['all']:
                        self.add(table, chain, '-d %s -j RETURN' % net)
            for adh in self.blacklisted_adherents():
                if 'uidNumber' in adh:
                    self.add(table, chain, '-m owner --uid-owner %s -j REJECT' % adh['uidNumber'][0])
            print OK

        if apply:
            self.apply(table, chain)
        return chain

