Changeset 128

Show
Ignore:
Timestamp:
07/19/05 06:29:58 (3 years ago)
Author:
athomas
Message:
  • Removed all tabs
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • fwc/trunk/Config.py

    r127 r128  
    11import string 
    22import re 
     3from util import abstract 
     4from copy import deepcopy 
    35 
    46class Config(object): 
    5         class Error(Exception): pass 
    6         class ReadOnly(Error): pass 
    7         class InvalidValue(Error): pass 
     7    class Error(Exception): pass 
     8    class ReadOnly(Error): pass 
     9    class InvalidValue(Error): pass 
     10    class KeyRequired(Error): pass 
     11    class KeyError(Error): pass 
    812 
    9         class Template(string.Template): 
    10                 idpattern = '[_a-z][-_a-z0-9]*' 
     13    class Serialiser: 
     14        @abstract 
     15        def serialise(self, out): 
     16            """ Serialise this object in a form that can be parsed by FWC. 
     17                "out" is an I/O object. """ 
    1118 
    12         class Value: 
    13                 def __init__(self, name, value, help = 'No help available', readonly = None, constraint = '.*'): 
    14                         self.name, self.value, self.help, self.readonly, self.constraint = name, value, help, readonly, constraint 
     19    class __Template(string.Template): 
     20        idpattern = '[_a-z][-_a-z0-9]*' 
    1521 
    16        class Iterator
    17                def __init__(self, config): 
    18                         self.__config = config 
    19                         self.__iter = iter(config) 
     22    class Value
     23        def __init__(self, name, value, help = ('<value>', 'No help available'), immutable = False, constraint = '.*', required = True): 
     24            if type(help) is str: help = ('<value>', help) 
     25            self.name, self.value, self.help, self.immutable, self.constraint, required = name, value, help, immutable, constraint, required 
    2026 
    21                 def next(self): 
    22                         n = self.__iter.next() 
    23                         return (n, self.__config[n].value) 
     27    class Iterator: 
     28        def __init__(self, config): 
     29            self.__config = config 
     30            self.__iter = iter(config) 
    2431 
    25         def __init__(self): 
    26                 object.__setattr__(self, '_Config__store', {}) 
     32        def next(self): 
     33            n = self.__iter.next() 
     34            return (n, self.__config[n].value) 
    2735 
    28        def define(self, key, value, help = None, readonly = False): 
    29                key = key.replace('-', '_'
    30                self.__store[key] = Config.Value(key, value, help, readonly
     36    def __init__(self, config = ()): 
     37        object.__setattr__(self, '_Config__store', {}
     38        self.merge(config
    3139 
    32         def __contains__(self, key): 
    33                 return key in self.__store 
     40    def merge(self, config): 
     41        for v in config: 
     42            assert isinstance(v, Config.Value) 
     43            self.define(v.name, deepcopy(v)) 
    3444 
    35         def __getattr__(self, name): 
    36                 return self.__store[name].value 
    37         __getitem__ = __getattr__ 
     45    def define(self, key, value, **argd): 
     46        key = key.replace('-', '_') 
     47        if isinstance(value, Config.Value): 
     48            self.__store[key] = value 
     49        else: 
     50            self.__store[key] = Config.Value(key, value, **argd) 
    3851 
    39         def __setattr__(self, name, value): 
    40                 if name not in self.__store: 
    41                         raise KeyError(name) 
    42                 v = self.__store[name] 
    43                 if v.readonly: raise Config.ReadOnly('"%s" is read only' % name) 
    44                 if not re.match(v.constraint, value): raise Config.InvalidValue('Invalid value "%s" for "%s"' % (value, name)) 
    45                 v.value = value 
    46         __setitem__ = __setattr__ 
     52    def __contains__(self, key): 
     53        return key in self.__store 
    4754 
    48         def __iter__(self): 
    49                 return iter(self.__store) 
     55    def __getattr__(self, name): 
     56        return self.__store[name].value 
     57    __getitem__ = __getattr__ 
    5058 
    51         def __delattr__(self, key): 
    52                 del(self.__store[key]) 
    53         __delitem__ = __delattr__ 
     59    def __setattr__(self, name, value): 
     60        if name not in self.__store: 
     61            raise Config.KeyError("unknown configuration key '%s'" % name) 
     62        v = self.__store[name] 
     63        if v.immutable: 
     64            raise Config.ReadOnly("Key '%s' is read only" % name) 
     65        if not re.match(v.constraint, value): 
     66            raise Config.InvalidValue("Invalid value '%s' for '%s'" % (value, name)) 
     67        v.value = value 
     68    __setitem__ = __setattr__ 
    5469 
    55         def iteritems(self): 
    56                 """ Iterate over (k, v) pairs """ 
    57                 return Config.Iterator(self.__store) 
     70    def __iter__(self): 
     71        return iter(self.__store) 
    5872 
    59         def __len__(self): 
    60                 return len(self.__store) 
     73    def __delattr__(self, key): 
     74        if key not in self.__store: 
     75            raise Config.KeyError("can't delete non-existent configuration key '%s'" % name) 
     76        if self.__store[key].required: 
     77            raise Config.KeyRequired("Key '%s' is required and can not be removed" % key) 
     78        del(self.__store[key]) 
     79    __delitem__ = __delattr__ 
    6180 
    62         def keys(self): 
    63                 return self.__store.keys() 
     81    def iteritems(self): 
     82        """ Iterate over (k, v) pairs """ 
     83        return Config.Iterator(self.__store) 
    6484 
    65        def values(self): 
    66                 return [x.value for x in self.__store.values()] 
     85    def __len__(self): 
     86        return len(self.__store) 
    6787 
    68        def help(self, key): 
    69                 return self.__store[key].help 
     88    def keys(self): 
     89        return self.__store.keys() 
    7090 
    71         def readonly(self, key): 
    72                 return self.__store[key].readonly 
     91    def raw(self, key): 
     92        """ Fetch raw Config.Value object """ 
     93        return self.__store[key] 
    7394 
    74        def validate(self, key, value): 
    75                 return re.match(self.__store[key].constraint, value) 
     95    def values(self): 
     96        return [x.value for x in self.__store.values()] 
    7697 
    77         def expand(self, text): 
    78                 vars = dict([(v.name.replace('_', '-'), v.value) for v in self.__store.values()]) 
    79                 lasttext = '' 
    80                 while '$' in text and lasttext != text: 
    81                         lasttext = text[:] 
    82                         text = Config.Template(text).safe_substitute(vars) 
    83                 return text 
     98    def help(self, key): 
     99        return self.__store[key].help 
     100 
     101    def immutable(self, key): 
     102        return self.__store[key].immutable 
     103 
     104    def validate(self, key, value): 
     105        return re.match(self.__store[key].constraint, value) 
     106 
     107    def expand(self, text): 
     108        vars = dict([(v.name.replace('_', '-'), v.value) for v in self.__store.values()]) 
     109        lasttext = '' 
     110        while '$' in text and lasttext != text: 
     111            lasttext = text[:] 
     112            text = Config.__Template(text).safe_substitute(vars) 
     113        return text 
  • fwc/trunk/DynamicLoader.py

    r123 r128  
    22 
    33def loadModule(modulePath): 
    4        try: 
    5                aMod = sys.modules[modulePath] 
    6                if not isinstance(aMod, types.ModuleType): 
    7                        raise KeyError 
    8        except KeyError: 
    9                # The last [''] is very important! 
    10                aMod = __import__(modulePath, globals(), locals(), ['']) 
    11                sys.modules[modulePath] = aMod 
    12        return aMod 
     4    try: 
     5        aMod = sys.modules[modulePath] 
     6        if not isinstance(aMod, types.ModuleType): 
     7            raise KeyError 
     8    except KeyError: 
     9        # The last [''] is very important! 
     10        aMod = __import__(modulePath, globals(), locals(), ['']) 
     11        sys.modules[modulePath] = aMod 
     12    return aMod 
    1313 
    1414def loadFunction(fullFuncName): 
    15        """Retrieve a function object from a full dotted-package name.""" 
    16          
    17        # Parse out the path, module, and function 
    18        lastDot = fullFuncName.rfind(u".") 
    19        funcName = fullFuncName[lastDot + 1:] 
    20        modPath = fullFuncName[:lastDot] 
    21          
    22        aMod = loadModule(modPath) 
    23        try: 
    24                aFunc = getattr(aMod, funcName) 
    25        except AttributeError: 
    26                raise ImportError("no such function '" + funcName + "'") 
    27          
    28        # Assert that the function is a *callable* attribute. 
    29        assert callable(aFunc), u"%s is not callable." % fullFuncName 
    30          
    31        # Return a reference to the function itself, 
    32        # not the results of the function. 
    33        return aFunc 
     15    """Retrieve a function object from a full dotted-package name.""" 
     16     
     17    # Parse out the path, module, and function 
     18    lastDot = fullFuncName.rfind(u".") 
     19    funcName = fullFuncName[lastDot + 1:] 
     20    modPath = fullFuncName[:lastDot] 
     21     
     22    aMod = loadModule(modPath) 
     23    try: 
     24        aFunc = getattr(aMod, funcName) 
     25    except AttributeError: 
     26        raise ImportError("no such function '" + funcName + "'") 
     27     
     28    # Assert that the function is a *callable* attribute. 
     29    assert callable(aFunc), u"%s is not callable." % fullFuncName 
     30     
     31    # Return a reference to the function itself, 
     32    # not the results of the function. 
     33    return aFunc 
    3434 
    3535def loadClass(fullClassName, parentClass=None): 
    36        """Load a module and retrieve a class (NOT an instance). 
    37          
    38        If the parentClass is supplied, className must be of parentClass 
    39        or a subclass of parentClass (or None is returned). 
    40        """ 
    41        aClass = loadFunction(fullClassName) 
    42          
    43        # Assert that the class is a subclass of parentClass. 
    44        if parentClass is not None: 
    45                if not issubclass(aClass, parentClass): 
    46                        raise TypeError(u"%s is not a subclass of %s" % 
    47                                                        (fullClassName, parentClass)) 
    48          
    49        # Return a reference to the class itself, not an instantiated object. 
    50        return aClass 
     36    """Load a module and retrieve a class (NOT an instance). 
     37     
     38    If the parentClass is supplied, className must be of parentClass 
     39    or a subclass of parentClass (or None is returned). 
     40    """ 
     41    aClass = loadFunction(fullClassName) 
     42     
     43    # Assert that the class is a subclass of parentClass. 
     44    if parentClass is not None: 
     45        if not issubclass(aClass, parentClass): 
     46            raise TypeError(u"%s is not a subclass of %s" % 
     47                            (fullClassName, parentClass)) 
     48     
     49    # Return a reference to the class itself, not an instantiated object. 
     50    return aClass 
  • fwc/trunk/Engine.py

    r127 r128  
     1import os 
    12import re 
    23import sys 
     
    45import readline 
    56import textwrap 
     7from copy import copy, deepcopy 
     8from fnmatch import fnmatch 
    69from ConfigParser import RawConfigParser 
    710from Config import Config 
     
    912from CLY.Parser import Parser 
    1013from CLY.Symbols import * 
    11 from util import * 
    1214from Resolver import Resolver 
    1315from Firewall import Firewall 
    14 from LinuxIPTables import LinuxIPTables 
    1516from Object import Object 
    1617from Singleton import Singleton 
    17 from fnmatch import fnmatch 
    18  
    19 class Engine(Singleton): 
    20         version = '0.1' 
    21         firewall_types = {'linux' : 'LinuxIPTables'} 
    22  
    23         class Error(Exception): pass 
    24  
    25         def __init__(self): 
    26                 self.__config = RawConfigParser() 
    27                 self.__config.read(['/etc/fwcrc', os.path.expanduser('~/.fwcrc')]) 
    28                 self.config = Config() 
    29                 self.config.define('prompt', 'fwc> ', 'FWC prompt') 
    30                 # TODO: Merge loaded config into self.config 
    31                 self.__firewalls = {} 
    32                 # Grammar hooks. 
    33                 self.__hooks = { 
    34                         'match' : [], 
    35                         'nat-to' : [], 
    36                         'nat-from' : [], 
    37                         'nat' : [], 
    38                         'from' : [], 
    39                         'to' : [], 
    40                 } 
    41                 self.existing_input = '' 
    42  
    43                 # Currently active firewall 
    44                 self.firewall = None 
    45                 self.__placement_rules = { 
    46                         'replace' : { 
    47                                 GROUP : 10, 
    48                                 UNLESS_VAR : [ 'old', 'where' ], 
    49                                 VAR : 'where', 
    50                                 HELP : 'Replace an existing rule.', 
    51                                 RULE : { 
    52                                         HELP : ('<rule>', 'Rule to replace.'), 
    53                                         VAR : 'index', 
    54                                         JUMP : RETURN, 
    55                                 }, 
    56                         }, 
    57                         'top|bottom' : { 
    58                                 GROUP : 10, 
    59                                 UNLESS_VAR : 'where', 
    60                                 VAR : 'where', 
    61                                 HELP : { 
    62                                         'top' : 'Insert rule at top of policy.', 
    63                                         'bottom' : 'Insert rule at bottom of policy (default).', 
    64                                 }, 
    65                                 JUMP : RETURN, 
    66                         }, 
    67                         'before|after' : { 
    68                                 GROUP : 10, 
    69                                 UNLESS_VAR : 'where', 
    70                                 VAR : 'where', 
    71                                 HELP : { 
    72                                         'before' : 'Insert rule before another.', 
    73                                         'after' : 'Insert rule after another.', 
    74                                 }, 
    75                                 RULE : { 
    76                                         HELP : ('<rule>', 'Rule to insert relative to.'), 
    77                                         VAR : 'index', 
    78                                         JUMP : RETURN, 
    79                                 }, 
    80                         }, 
    81                 } 
    82  
    83                 self.__protocol_rules = { 
    84                         lambda ctx, token: self.resolver.have_object(Object.PROTOCOL, token) : { 
    85                                 GROUP : 30, 
    86                                 UNLESS_VAR : 'protocol', 
    87                                 VAR : 'protocol', 
    88                                 HELP : lambda x: [(x.name, x.description or 'Protocol %s' % x.value) for x in self.resolver.get_objects('protocol')], 
    89                                 JUMP : RETURN, 
    90                         }, 
    91                         'protocol' : { 
    92                                 GROUP : 30, 
    93                                 HELP : 'Arbitrary IP protocol number.', 
    94                                 UNLESS_VAR : 'protocol', 
    95                                 '\d+' : { 
    96                                         HELP : ('<protocol>', 'IP protocol number.'), 
    97                                         JUMP : RETURN, 
    98                                         VAR : 'protocol', 
    99                                 }, 
    100                         }, 
    101                 } 
    102  
    103                 self.hook('nat', self.__placement_rules) 
    104                 self.hook('nat', self.__protocol_rules) 
    105  
    106                 self.__grammar = { 
    107                         'nat' : { 
    108                                 IF : have_firewall, 
    109                                 MERGE : self.__hooks['nat'], 
    110                                 GROUP : 10, 
    111                                 HELP : 'NAT matching packets.', 
    112                                 VAR : 'action', 
    113                                 'to' : { 
    114                                         MERGE : self.__hooks['nat-to'], 
    115                                         HELP : 'Specify destination to NAT to.', 
    116                                         NETWORK : { 
    117                                                 VAR : 'nat_ip', 
    118                                                 HELP : ('<ip>', 'NAT to IP address.'), 
    119                                                 'if' : { 
    120                                                         HELP : 'NAT on the following conditions.', 
    121                                                         JUMP : 'commands', 
    122                                                 }, 
    123                                         }, 
    124                                 }, 
    125                         }, 
    126                         'accept|drop|reject' : { 
    127                                 GROUP : 10, 
    128                                 IF : have_firewall, 
    129                                 GLOBAL_LABEL : 'commands', 
    130                                 MERGE : [ self.__placement_rules, self.__protocol_rules, self.__hooks['match'] ], 
    131                                 VAR : 'action', 
    132                                 ACTION : { 
    133                                         HELP : 'Add rule to firewall.', 
    134                                         ACTION : self.__insert_rule, 
    135                                 }, 
    136                                 HELP : { 
    137                                         'accept' : 'Add rule accepting matching packets.', 
    138                                         'drop' : 'Add rule dropping matching packets.', 
    139                                         'reject' : 'Add rule rejecting matching packets.', 
    140                                 }, 
    141                                 'with' : { 
    142                                         IF : lambda ctx: 'reject_type' not in ctx and ctx['action'] == 'reject', 
    143                                         HELP : 'Reject with the specified packet type.', 
    144                                         'tcp' : { 
    145                                                 VAR : 'reject_type', 
    146                                                 IF : lambda ctx: 'protocol' in ctx and ctx['protocol'] == 'tcp', 
    147                                                 HELP : 'Reject with tcp... packet.', 
    148                                                 'reset' : { 
    149                                                         VAR : 'reject_subtype', 
    150                                                         HELP : 'Reject with TCP reset.', 
    151                                                         JUMP : 'commands', 
    152                                                 }, 
    153                                         }, 
    154                                         'network|host|protocol|admin' : { 
    155                                                 VAR : 'reject_type', 
    156                                                 HELP : { 
    157                                                         'network' : 'Reject with icmp-network... packet.', 
    158                                                         'host' : 'Reject with icmp-host... packet.', 
    159                                                         'protocol' : 'Reject with icmp-protocol... packet.', 
    160                                                         'admin' : 'Reject with icmp-admin... packet.', 
    161                                                 }, 
    162                                                 'unreachable' : { 
    163                                                         HELP : lambda ctx: { 'unreachable' : 'Reject with icmp-%s-unreachable.' % ctx['reject_type'] }, 
    164                                                         IF : lambda ctx: ctx['reject_type'] != 'admin', 
    165                                                         VAR : 'reject_subtype', 
    166                                                         JUMP : 'commands', 
    167                                                 }, 
    168                                                 'prohibited' : { 
    169                                                         HELP : lambda ctx: { 'prohibited' : 'Reject with icmp-%s-prohibited.' % ctx['reject_type'] }, 
    170                                                         IF : lambda ctx: ctx['reject_type'] in ('network', 'host', 'admin'), 
    171                                                         VAR : 'reject_subtype', 
    172                                                         JUMP : 'commands', 
    173                                                 }, 
    174                                         }, 
    175  
    176                                 }, 
    177                                 'in' : { 
    178                                         GROUP : 20, 
    179                                         HELP : 'Match packets coming in an interface.', 
    180                                         lambda ctx, arg: INTERFACE(ctx, arg) and 'in_if' not in ctx or arg not in ctx['in_if'] : { 
    181                                                 HELP : lambda ctx: [(k, v) for k, v in help_interface(ctx).iteritems() if 'in_if' not in ctx or k not in ctx['in_if']], 
    182                                                 VAR : 'in_if', 
    183                                                 LABEL : 'in-if', 
    184                                                 JUMP_TO : 'in-if', 
    185                                                 JUMP : 'commands', 
    186                                         }, 
    187                                 }, 
    188                                 'out' : { 
    189                                         GROUP : 20, 
    190                                         HELP : 'Match packets going out an interface.', 
    191                                         INTERFACE : { 
    192                                                 HELP : help_interface, 
    193                                                 VAR : 'out_if', 
    194                                                 LABEL : 'out-if', 
    195                                                 JUMP_TO : 'out-if', 
    196                                                 JUMP : 'commands', 
    197                                         }, 
    198                                 }, 
    199                                 'from' : { 
    200                                         GROUP : 20, 
    201                                         HELP : 'Match source network or port.', 
    202                                         IF : lambda ctx: ('protocol' in ctx and ctx['protocol'] in ['tcp', 'udp'] and not 'sport' in ctx) or not 'source' in ctx, 
    203                                         NETWORK : { 
    204                                                 VAR : 'source', 
    205                                                 LABEL : 'source', 
    206                                                 JUMP : 'commands', 
    207                                                 JUMP_TO : 'source', 
    208                                                 GROUP : 5, 
    209                                                 'port' : { 
    210                                                         GROUP : 20, 
    211                                                         RANGE : 1, 
    212                                                         HELP : 'Match source port.', 
    213                                                         PORT : { 
    214                                                                 LABEL : 'sport', 
    215                                                                 VAR : 'sport', 
    216                                                                 JUMP : 'commands', 
    217                                                                 JUMP_TO : 'sport', 
    218                                                                 HELP : lambda ctx: help_object(ctx, 'port'), 
    219                                                         }, 
    220                                                         IF : check_port_protocol, 
    221                                                 }, 
    222                                                 HELP : help_network, 
    223                                         }, 
    224                                         'port' : { 
    225                                                 HELP : 'Match source port.', 
    226                                                 GROUP : 20, 
    227                                                 PORT : { 
    228                                                         GROUP : 5, 
    229                                                         HELP : help_port, 
    230                                                         LABEL : 'sports', 
    231                                                         VAR : 'sport', 
    232                                                         JUMP : 'commands', 
    233                                                         # This allows syntax like: accept from port 22 23 25 to anywhere 
    234                                                         JUMP_TO : 'sports', 
    235                                                 }, 
    236                                                 IF : check_port_protocol, 
    237                                         }, 
    238                                 }, 
    239                                 'description' : { 
    240                                         '.+' : { 
    241                                                 VAR : 'description', 
    242                                                 JUMP : 'commands', 
    243                                                 HELP : ('<description>', 'Rule description.'), 
    244                                         }, 
    245                                         RANGE : 1, 
    246                                         HELP : 'Set rule description.' 
    247                                 }, 
    248                                 'to' : { 
    249                                         GROUP : 20, 
    250                                         IF : lambda ctx: ('protocol' in ctx and ctx['protocol'] in ['tcp', 'udp'] and not 'dport' in ctx) or not 'destination' in ctx, 
    251                                         UNLESS_VAR : [ 'dport', 'destination' ], 
    252                                         NETWORK : { 
    253                                                 GROUP : 5, 
    254                                                 LABEL : 'destination', 
    255                                                 VAR : 'destination', 
    256                                                 JUMP : 'commands', 
    257                                                 JUMP_TO : 'destination', 
    258                                                 'port' : { 
    259                                                         GROUP : 20, 
    260                                                         PORT : { 
    261                                                                 GROUP : 5, 
    262                                                                 LABEL : 'dport', 
    263                                                                 VAR : 'dport', 
    264                                                                 JUMP : 'commands', 
    265                                                                 JUMP_TO : 'dport', 
    266                                                                 HELP : help_port, 
    267                                                         }, 
    268                                                         IF : check_port_protocol, 
    269                                                         HELP : 'Match destination port.', 
    270                                                 }, 
    271                                                 HELP : help_network, 
    272                                         }, 
    273                                         'port' : { 
    274                                                 GROUP : 20, 
    275                                                 PORT : { 
    276                                                         GROUP : 5, 
    277                                                         LABEL : 'dports', 
    278                                                         VAR : 'dport', 
    279                                                         JUMP : 'commands', 
    280                                                         JUMP_TO : 'dports', 
    281                                                         HELP : help_port, 
    282                                                 }, 
    283                                                 IF : check_port_protocol, 
    284                                                 HELP : 'Match destination port.', 
    285                                         }, 
    286                                         HELP : 'Match destination network or port.', 
    287                                 }, 
    288                                 'log' : { 
    289                                         VAR : 'log', 
    290                                         UNLESS_VAR : 'log', 
    291                                         HELP : "Log a message when this rule matches.", 
    292                                         'message' : { 
    293                                                 HELP : 'Log with custom message.', 
    294                                                 '.+' : { 
    295                                                         HELP : ('<message>', 'Custom log message.'), 
    296                                                         JUMP : 'commands', 
    297                                                         VAR : 'log', 
    298                                                 }, 
    299                                         }, 
    300                                         JUMP : 'commands', 
    301                                 }, 
    302                         }, 
    303                         'quit|exit' : { 
    304                                 GROUP : 20000, 
    305                                 HELP : [ 'quit', 'Exit.' ], 
    306                                 ACTION : { 
    307                                         HELP : 'Exit.', 
    308                                         ACTION : self.quit, 
    309                                 }, 
    310                         }, 
    311                         '!\d+' : { 
    312                                 VAR : 'index', 
    313                                 ACTION : lambda ctx, index: self.__set_history(ctx, index[1:]), 
    314                         }, 
    315                         'history' : { 
    316                                 GROUP : 20000, 
    317                                 HELP : 'Command history management.', 
    318                                 ACTION : { 
    319                                         HELP : 'Show history.', 
    320                                         ACTION : self.__list_history, 
    321                                 }, 
    322                                 'clear' : { 
    323                                         HELP : 'Clear history.', 
    324                                         ACTION : self.__clear_history, 
    325                                 }, 
    326                                 '\d+' : { 
    327                                         VAR : 'index', 
    328                                         HELP : ('<index>', 'History item index.'), 
    329                                         ACTION : self.__set_history, 
    330                                 }, 
    331                         }, 
    332                         'object' : { 
    333                                 IF : have_firewall, 
    334                                 HELP : 'Firewall object manipulation.', 
    335                                 'import' : { 
    336                                         LABEL : 'import', 
    337                                         'all' : { 
    338                                                 RANGE : 1, 
    339                                                 GROUP : 10, 
    340                                                 HELP : 'Also import aliases.', 
    341                                                 VAR : 'aliases', 
    342                                                 JUMP : 'import', 
    343                                         }, 
    344                                         's|'.join(Resolver.get_object_types()) + 's' : { 
    345                                                 GROUP : 20, 
    346                                                 VAR : 'import_types', 
    347                                                 HELP : lambda ctx: [(x + 's', 'Import system %s objects' % x) for x in Resolver.get_object_types()], 
    348                                                 ACTION : lambda ctx, import_types, **args: self.resolver.populate_defaults(tolist(import_types), with_aliases = 'aliases' in ctx), 
    349                                         }, 
    350                                         HELP : 'Import system objects.', 
    351                                         ACTION : lambda ctx, **args: self.resolver.populate_defaults(with_aliases = 'aliases' in ctx), 
    352                                 }, 
    353                                 'create' : { 
    354                                         HELP : 'Create a policy object.', 
    355                                         '|'.join(Resolver.get_object_types()) : { 
    356                                                 VAR : 'type', 
    357                                                 HELP : lambda ctx: [(x, 'Create %s object' % x) for x in Resolver.get_object_types()], 
    358                                                 Object.NAME_PATTERN : { 
    359                                                         VAR : 'name', 
    360                                                         HELP : { '<name>' : 'Name of object to create.' }, 
    361                                                         LABEL : 'create', 
    362                                                         'description' : { 
    363                                                                 UNLESS_VAR : 'description', 
    364                                                                 ORDER : 10, 
    365                                                                 GROUP : 20, 
    366                                                                 '.+' : { 
    367                                                                         VAR : 'description', 
    368                                                                         HELP : { '<description>' : 'Description of object.' }, 
    369                                                                         JUMP : 'create', 
    370                                                                         ACTION : { 
    371                                                                                 IF_VAR : 'value', 
    372                                                                                 ACTION : self.__create_object, 
    373                                                                         }, 
    374                                                                 }, 
    375                                                                 HELP : 'Optional description of object.' 
    376                                                         }, 
    377                                                         lambda ctx, token: re.match(Object.TYPE_PATTERNS[ctx['type']], token) or token in help_object(ctx, ctx['type']) : { 
    378                                                                 ORDER : 20, 
    379                                                                 GROUP : (10, 'Add ...'), 
    380                                                                 VAR : 'value', 
    381                                                                 HELP : lambda ctx: [(k, v) for k, v in help_object(ctx, ctx['type']).iteritems() if 'value' in ctx and k not in tolist(ctx['value']) or 'va