Changeset 114
- Timestamp:
- 05/12/05 04:17:19 (4 years ago)
- Files:
-
- fwc/trunk/Firewall.py (modified) (2 diffs)
- fwc/trunk/fwc (modified) (26 diffs)
- fwc/trunk/Object.py (modified) (2 diffs)
- fwc/trunk/Resolver.py (added)
- fwc/trunk/util.py (added)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
fwc/trunk/Firewall.py
r112 r114 3 3 4 4 class Firewall: 5 def __init__(self, name): 6 self.rules = [] 5 """ 6 The Firewall class contains all 7 """ 8 class Error(Exception): pass 9 class InvalidIndex(Error): pass 10 class InvalidObject(Error): pass 11 class InvalidRule(Error): pass 12 13 def __init__(self, name, resolver): 14 self.__rules = [] 7 15 self.name = name 8 self.ip = {} 9 self.network = {} 10 self.port = {} 11 # Set up default objects 12 self.add_object(Object(Object.NETWORK, 'any', '0.0.0.0/0', 'Any network address')) 13 self.add_object(Object(Object.IP, 'any', '0.0.0.0', 'Any IP address')) 14 self.add_object(Object(Object.PORT, 'any', '0-65535', 'Any port')) 15 16 def resolve_object(self, type, name): 17 map = getattr(self, type) 18 if map and name in map: 19 return map[name] 20 return Object(type, name, name) 21 22 def resolve_network(self, network): 23 return self.resolve_object('network', network) 24 25 def resolve_ip(self, ip): 26 return self.resolve_ip('ip', ip) 27 28 def resolve_port(self, port): 29 return self.resolve_port('port', port) 16 self.resolver = resolver 30 17 31 18 def resolve_rule(self, rule): 32 19 try: 33 20 rule = int(rule) 34 if rule >= 0 and rule < len(self. rules):21 if rule >= 0 and rule < len(self.__rules): 35 22 return int(rule) 36 23 except TypeError: … … 40 27 try: 41 28 if where == 'top': 42 self. rules.insert(0, rule)29 self.__rules.insert(0, rule) 43 30 return 0 44 31 elif where == 'bottom' : 45 self. rules.append(rule)46 return len(self. rules) - 132 self.__rules.append(rule) 33 return len(self.__rules) - 1 47 34 elif where == 'before': 48 self. rules.insert(index, rule)35 self.__rules.insert(index, rule) 49 36 return index 50 37 elif where == 'after': 51 self. rules.insert(index + 1, rule)38 self.__rules.insert(index + 1, rule) 52 39 return index + 1 53 40 elif where == 'replace' : 54 self. rules[index] = rule41 self.__rules[index] = rule 55 42 return index 56 43 else: 57 raise IndexError("invalid location '%s' for rule addition" % where)44 raise Firewall.InvalidIndex("invalid location '%s' for rule addition" % where) 58 45 except IndexError: 59 error("Invalid ruleset index %s" % index) 60 return None 46 raise Firewall.InvalidIndex("Invalid ruleset index %s" % index) 61 47 62 48 def move(self, old, new): 49 """ Move rule from index old to before index new """ 63 50 if old == new: return 64 51 try: 65 rule = self. rules.pop(old)52 rule = self.__rules.pop(old) 66 53 try: 67 54 if new > old: 68 self. rules.insert(new - 1, rule)55 self.__rules.insert(new - 1, rule) 69 56 else: 70 self. rules.insert(new, rule)57 self.__rules.insert(new, rule) 71 58 except: 72 self. rules.insert(old, rule)59 self.__rules.insert(old, rule) 73 60 raise 74 61 except IndexError: 75 error("Invalid ruleset index %s or %s" % (old, new))62 raise InvalidRule("Invalid ruleset index %s or %s" % (old, new)) 76 63 77 64 def remove(self, index): 65 """ Remove a set of rules. Indices are guaranteed to be valid across 66 the entire remove operation. """ 78 67 if type(index) is not list: index = [ index ] 79 68 try: 80 69 for i in index: 81 self. rules[i] = None70 self.__rules[i] = None 82 71 newrules = [] 83 for i in self. rules:72 for i in self.__rules: 84 73 if i: newrules.append(i) 85 self. rules = newrules74 self.__rules = newrules 86 75 except IndexError: 87 error("Invalid rule index %s" % index)76 raise InvalidRule("Invalid rule index %s" % index) 88 77 89 def add_object(self, object): 90 map = getattr(self, object.type) 91 if object.name in map: 92 error("%s object '%s' already exists" % (object.type.title(), object.name)) 93 else: 94 map[object.name] = object 95 96 def remove_object(self, object): 97 try: 98 del(getattr(self, object.type)[object.name]) 99 except IndexError: 100 error("Object '%s' not in ruleset" % object.name) 78 def get_rule(self, rule): 79 return self.__rules[rule] 101 80 81 def get_rules(self): 82 return self.__rules 83 84 def __iter__(self): 85 return iter(self.__rules) fwc/trunk/fwc
r112 r114 1 1 #!/usr/bin/python 2 2 3 from CLI import *3 from CLI.CLI import * 4 4 import types 5 5 import re … … 10 10 from Object import Object 11 11 from Firewall import Firewall 12 from Resolver import Resolver 13 from util import * 12 14 13 15 CONF_DIR = "/etc/fwcrc" … … 15 17 # Globally useful stuff 16 18 19 resolver = Resolver() 17 20 firewalls = {} 18 firewall = firewalls['DEFAULT'] = Firewall() 21 firewall = None 22 firewall = Firewall("localhost", resolver) 19 23 20 24 def to_list(value): … … 22 26 return value 23 27 24 def info(message):25 print "[32m[1mOK [22m%s[0m" % message26 27 def warning(message):28 print "[33m[1mWRN %s[0m" % message29 30 def error(message):31 print "[31m[1mERR %s[0m" % message32 33 def fatal(message):34 print "[31m[1mFTL %s[0m" % message35 sys.exit(1)36 37 28 def check_port_protocol(context): 38 29 return 'protocol' in context and context['protocol'] in [ 'tcp', 'udp' ] 39 30 31 def have_firewall(context): 32 """ Return true if the current firewall is have_firewall. """ 33 return firewall 34 35 def have_modifiable_firewall(context): 36 return firewall 37 40 38 # Help extractors 41 39 42 def help_ip(context):43 help = { '<ip>' : 'IP address.'}44 for o in firewall.ip.values():45 text = o.description or "IP address object %s" % o.name46 help[o.name] = text + " (%s)" % o.value47 return help48 49 40 def help_network(context): 50 41 help = { '<network>' : 'Network address.'} 51 for o in firewall.network.values():42 for o in resolver.get_objects('network'): 52 43 text = o.description or "Network object %s" % o.name 53 44 help[o.name] = text + " (%s)" % o.value 54 45 return help 55 46 56 def help_network_ip(context):57 help = {}58 help.update(help_ip(context))59 help.update(help_network(context))60 return help61 62 47 def help_port(context): 63 48 help = { '<port>' : 'Port.'} 64 for o in firewall.port.values():49 for o in resolver.get_objects('port'): 65 50 text = o.description or "Port object %s" % o.name 66 51 help[o.name] = text + " (%s)" % o.value … … 76 61 77 62 def NETWORK(context, str): 78 return re.match( r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/\d{1,2}', str) \63 return re.match(Object.NETWORK_PATTERN, str) \ 79 64 or str in help_network(context) 80 65 81 def NETWORK_IP(context, str):82 return re.match(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(?:/\d{1,2})?', str) \83 or str in help_network(context) \84 or str in help_ip(context)85 86 def IP(context, str):87 return re.match(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', str) \88 or str in help_ip(context)89 90 66 def PORT(context, str): 91 return re.match( r'\d{1,5}', str) \67 return re.match(Object.PORT_PATTERN, str) \ 92 68 or str in help_port(context) 93 69 … … 98 74 def RULE(context, str): 99 75 try: 100 return int(str) >= 0 and int(str) < len(firewall. rules)76 return int(str) >= 0 and int(str) < len(firewall.get_rules()) 101 77 except: 102 78 return False 103 79 104 80 def FIREWALL(context, str): 105 print help_firewall(context)106 81 return str in help_firewall(context) 107 82 … … 124 99 try: 125 100 old = int(old) 126 new = firewall.add(firewall. rules[old], where, index and int(index) or None)101 new = firewall.add(firewall.get_rule(old), where, index and int(index) or None) 127 102 if new < old: old += 1 128 103 firewall.remove(old) … … 132 107 133 108 def list_ruleset(context): 134 for ruleno, rule in enumerate(firewall. rules):135 cmd = " [1m%s[22m" % rule.action109 for ruleno, rule in enumerate(firewall.get_rules()): 110 cmd = "^B%s^B" % rule.action 136 111 if rule.state != 'new': 137 cmd += " state [1m" + rule.state + "[22m"112 cmd += " state ^B" + rule.state + "^B" 138 113 if rule.protocol: 139 cmd += " [1m" + rule.protocol + "[22m"114 cmd += " ^B" + rule.protocol + "^B" 140 115 if rule.source or rule.sport: 141 116 cmd += " from" 142 117 if rule.source: 143 cmd += " [1m" + ' '.join(rule.source) + "[22m"118 cmd += " ^B" + ' '.join(rule.source) + "^B" 144 119 if rule.sport: 145 cmd += " port [1m" + ' '.join(rule.sport) + "[22m"120 cmd += " port ^B" + ' '.join(rule.sport) + "^B" 146 121 if rule.destination or rule.dport: 147 122 cmd += " to" 148 123 if rule.destination: 149 cmd += " [1m" + ' '.join(rule.destination) + "[22m"124 cmd += " ^B" + ' '.join(rule.destination) + "^B" 150 125 if rule.dport: 151 cmd += " port [1m" + ' '.join(rule.dport) + "[22m"126 cmd += " port ^B" + ' '.join(rule.dport) + "^B" 152 127 if rule.log: 153 128 cmd += " log" 154 129 if type(rule.log) is str: 155 cmd += " [1m'%s'[22m" % rule.log130 cmd += " ^B'%s'^B" % rule.log 156 131 if rule.description: 157 cmd += " description [1m'%s'[22m" % rule.description158 print "[1m%3i:[0m %s" % (ruleno, cmd)132 cmd += " description ^B'%s'^B" % rule.description 133 cprint("^B%3i:^B %s" % (ruleno, cmd)) 159 134 160 135 def create_object(context, type, name, value, description = None): 161 firewall.add_object(Object(type, name, value, description)) 162 163 def list_objects(context, type = ['network', 'ip', 'port']): 136 try: 137 resolver.add_object(Object(type, name, value, description)) 138 except Resolver.Error, e: 139 error(e) 140 141 142 def list_objects(context, type = Resolver.get_object_types()): 164 143 for t in to_list(type): 165 objects = getattr(firewall, t) 166 print "[4m[1m%s objects[0m" % t.title() 167 for k in sorted(objects): 168 o = objects[k] 169 str = " %s %s" % (o.name, o.value) 144 objects = resolver.get_objects(t) 145 for o in sorted(objects): 146 str = "%s %s %s" % (o.type, o.name, o.value) 170 147 if o.description: str += " '%s'" % o.description 171 148 print str … … 234 211 cli = CLI({ 235 212 'accept|drop|reject' : { 213 IF : have_modifiable_firewall, 236 214 GLOBAL_LABEL : 'commands', 237 215 'state' : { … … 267 245 HELP : 'Match source network or port.', 268 246 IF : lambda ctx: ('protocol' in ctx and ctx['protocol'] in ['tcp', 'udp'] and not 'sport' in ctx) or not 'source' in ctx, 269 NETWORK _IP: {247 NETWORK : { 270 248 VAR : 'source', 271 249 LABEL : 'source', … … 284 262 IF : check_port_protocol, 285 263 }, 286 HELP : help_network _ip,264 HELP : help_network, 287 265 }, 288 266 'port' : { … … 312 290 IF : lambda ctx: ('protocol' in ctx and ctx['protocol'] in ['tcp', 'udp'] and not 'dport' in ctx) or not 'destination' in ctx, 313 291 UNLESS_VAR : [ 'dport', 'destination' ], 314 NETWORK _IP: {292 NETWORK : { 315 293 LABEL : 'destination', 316 294 VAR : 'destination', … … 328 306 HELP : 'Match destination port.', 329 307 }, 330 HELP : help_network _ip,308 HELP : help_network, 331 309 }, 332 310 'port' : { … … 363 341 'object' : { 364 342 HELP : 'Manage ruleset objects.', 343 'import' : { 344 HELP : 'Import system default objects.', 345 ACTION : lambda x: resolver.populate_defaults(), 346 }, 365 347 'create' : { 366 348 HELP : 'Create a ruleset object.', … … 368 350 VAR : 'type', 369 351 HELP : 'Create network object.', 370 '\w+': {352 Object.NAME_PATTERN : { 371 353 VAR : 'name', 372 354 HELP : { '<name>' : 'Name of object to create.' }, 373 '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/\d{1,2}': {355 Object.NETWORK_PATTERN : { 374 356 VAR : 'value', 375 357 HELP : { '<network>' : 'Network.' }, … … 383 365 }, 384 366 }, 385 'default' : {386 HELP : 'Create objects from system defaults.',387 },388 Object.IP : {389 VAR : 'type',390 HELP : 'Create IP address object.',391 '\w+' : {392 VAR : 'name',393 HELP : { '<name>' : 'Name of object to create.' },394 '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}' : {395 VAR : 'value',396 HELP : { '<ip>' : 'IP address.' },397 ACTION : create_object,398 '.+' : {399 VAR : 'description',400 HELP : { '<description>' : 'Description of object.' },401 ACTION : create_object,402 },403 },404 },405 },406 367 Object.PORT : { 407 368 VAR : 'type', 408 369 HELP : 'Create port object.', 409 '\w+': {370 Object.NAME_PATTERN : { 410 371 VAR : 'name', 411 372 HELP : { '<name>' : 'Name of object to create.' }, 412 '\d{1,5}': {373 Object.PORT_PATTERN : { 413 374 VAR : 'value', 414 375 HELP : { '<port>' : 'Port.' }, … … 424 385 }, 425 386 'delete' : { 426 HELP : ' Create a newruleset object.',427 'network| ip|port' : {387 HELP : 'Delete a ruleset object.', 388 'network|port' : { 428 389 VAR : 'type', 429 390 HELP : { 430 391 'network' : 'Remove network object.', 431 'ip' : 'Remove IP address object.',432 392 'port' : 'Remove port object.', 433 393 }, … … 440 400 ACTION : list_objects, 441 401 }, 442 'network| ip|port' : {402 'network|port' : { 443 403 VAR : 'type', 444 404 HELP : { 445 405 'network' : 'List network objects.', 446 'ip' : 'List IP address objects.',447 406 'port' : 'List port objects.', 448 407 }, … … 452 411 }, 453 412 'delete' : { 413 IF : have_modifiable_firewall, 454 414 HELP : 'Remove rule(s) from the ruleset.', 455 415 LABEL : 'rule', … … 462 422 }, 463 423 'list' : { 424 IF : have_firewall, 464 425 HELP : 'List ruleset.', 465 426 ACTION : list_ruleset, … … 467 428 HELP : "Commands to manage the ruleset.", 468 429 'move' : { 430 IF : have_modifiable_firewall, 469 431 HELP : 'Move rule.', 470 432 RULE : { … … 483 445 'acquire' : { 484 446 HELP : 'Acquire a firewall for management.', 447 '\w+' : { 448 }, 485 449 }, 486 450 'list' : { … … 498 462 499 463 cli_inject_text = '' 464 bind_key = hasattr(readline, 'bind_key') and readline.bind_key or None 465 force_redisplay = hasattr(readline, 'force_redisplay') and readline.force_redisplay or None 466 set_input_hook = hasattr(readline, 'set_input_hook') and readline.set_input_hook or None 467 cursor = hasattr(readline, 'cursor') and readline.cursor or None 500 468 501 469 def cli_completion(text, state): … … 530 498 readline.insert_text("?") 531 499 return 532 if hasattr(readline, 'bind_key'):533 if result.context.parsed_tokens and result.context.parsed_tokens[-1].start() >= readline.cursor():500 if cursor: 501 if result.context.parsed_tokens and result.context.parsed_tokens[-1].start() >= cursor(): 534 502 return 535 503 if need_linefeed: 536 504 print 537 505 format_help(result.help()) 538 if hasattr(readline, 'bind_key'):539 readline.force_redisplay()506 if force_redisplay: 507 force_redisplay() 540 508 541 509 def cli_help(key, count): … … 548 516 length = len(h[0]) 549 517 for h in help: 550 print " [1m%s[0m %s" % (h[0] + (length - len(h[0])) * ' ', h[1])518 cprint(" ^B%s^B %s" % (h[0] + (length - len(h[0])) * ' ', h[1])) 551 519 552 520 readline.set_completer(cli_completion) 553 521 readline.set_startup_hook(cli_injector) 554 if hasattr(readline, 'bind_key'): 555 readline.bind_key(ord('?'), cli_help) 556 557 print \ 558 """Welcome to the [1mFireWall Console[22m ([1mFWC[22m)[0m 559 560 Press [1m?[22m at any time for help.""" 522 # Use custom readline extensions not in 2.4 523 if bind_key and set_input_hook: 524 bind_key(ord('?'), cli_help) 525 #set_input_hook(timeout) 526 527 cprint(\ 528 """Welcome to the ^BFireWall Console^B (^BFWC^B) 529 530 Press ^B?^B at any time for help.""" 531 ) 561 532 while True: 562 533 command = '' 563 534 try: 564 535 command = raw_input("fwc> ") 536 except KeyboardInterrupt: 537 print 565 538 except EOFError: 566 539 print … … 584 557 585 558 if result.state == Result.OK: 586 result() 559 try: 560 result() 561 except Firewall.Error, e: 562 error(e) 587 563 else: 588 564 if not result.token: fwc/trunk/Object.py
r112 r114 1 1 class Object: 2 # Types 2 3 NETWORK = 'network' 3 IP = 'ip'4 4 PORT = 'port' 5 6 NETWORK_PATTERN = r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(?:/\d{1,2})?' 7 PORT_PATTERN = r'\d{1,5}' 8 9 # Regex matching a valid object name 10 NAME_PATTERN = '[\w.-]+' 5 11 6 12 def __init__(self, type, name, value, description = ""): … … 10 16 self.description = description 11 17 18 def __repr__(self): 19 return "%s(%s, %s, %s)" % (self.type, repr(self.name), repr(self.value), repr(self.description))
