#!/usr/bin/env python # -*- coding: utf-8 -*- """ Copyright(C) 2007 INL Written by Damien Boucard <damien.boucard AT inl.fr> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, see <http://www.gnu.org/licenses/>. --- iptmodels.py contains all data structure to manage and generate iptables commands. """ class IptCommand(object): def __init__(self, *args, **kw): """ @param command: (optional) the unique non-keyword argument admitted. If given, the new object is a deep copy of the instance given in arguments. Keyword arguments are applied next, if they are given. @type command: IptCommand @keyword chain: (optional) indicates the chain concerned by the iptables command ('-A' option). @type chain: str @keyword target: (optional) indicates the decision resulting to the netfilter rule defined by the iptables command ('-j' option). @type target: str @keyword comment: (optional) add a commentary at the end of the rule line. @type comment: str """ if args : self.__copy(args[0], self) self.chain = kw.get("chain") self.target = kw.get("target") self.comment = kw.get("comment") self.modules = {} self.modules_order = [] self.postoptions = {} def __copy(cls, from_obj, to_obj): """ Class method doing a deep copy of an instance into anothor instance. """ import copy if not isinstance(from_obj, IptCommand): raise TypeError("Bad argument type: %s ; expected: %s"\ %(type(from_obj), type(cls))) if not isinstance(to_obj, IptCommand): raise TypeError("Bad argument type: %s ; expected: %s"\ %(type(to_obj), type(cls))) to_obj.chain = from_obj.chain to_obj.target = from_obj.target to_obj.modules = copy.deepcopy(from_obj.modules) to_obj.postoptions = from_obj.postoptions.copy() __copy = classmethod(__copy) def append_module(self, name, **options): """ Add a netfilter module, specify its options. Options are passed as variable-length keywords (i.e. option_name="option_value") to be converted into the related iptables option (i.e. '--option_name "option_value"'). @param name: Name of the module ('-m' option). @type name: str """ self.modules_order.append(name) self.modules[name] = options def add_postoption(self, name, value): """ Add an option which will be added post to the target option. For instance : >>> cmd = IptCommand(chain="FORWARD", target="LOG") >>> cmd.postoptions {} >>> cmd.add_postoption("log-prefix", "This is a logged string") >>> cmd.postoptions {'log-prefix': 'This is a logged string'} @type name: str @type value: str """ self.postoptions[name] = value def del_postoption(self, name): """ Delete a previously added postoption. >>> cmd = IptCommand(chain="FORWARD", target="LOG") >>> cmd.add_postoption("log-prefix", "This is a logged string") >>> cmd.postoptions {'log-prefix': 'This is a logged string'} >>> cmd.del_postoption("log-prefix") >>> cmd.postoptions {} @type name: str """ del self.postoptions[name] def __str__(self): cmd_list = [] if self.chain is not None: cmd_list.append("-A %s" %self.chain) for modname in self.modules_order: modopt = self.modules[modname] cmd_list.append("-m %s" %modname) for (optname, optval) in modopt.iteritems(): cmd_list.append("--%s %s" %(optname, optval)) if self.target is not None: cmd_list.append("-j %s" %self.target) for (optname, optval) in self.postoptions.iteritems(): cmd_list.append("--%s %s" %(optname, optval)) if self.comment is not None: cmd_list.append("# %s" %(self.comment)) return ' '.join(cmd_list)