Skip to content

Commit

Permalink
non.restful mode handling
Browse files Browse the repository at this point in the history
  • Loading branch information
greg-sk committed Mar 26, 2014
1 parent b1e251d commit 47bf22e
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 48 deletions.
22 changes: 14 additions & 8 deletions rfw/cmdparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,12 @@ def path_parts(path):

p = path_parts(path)

action = p[0]
# for path = '/' return 'help' action
if not p:
return 'help', None

# for path = '/' return empty tuple
if action == '':
if len(p) == 1:
return tuple()
else:
raise PathError(path)

action = p[0]

if action.upper() in iptables.RULE_TARGETS:
try:
return action, build_rule(p)
Expand Down Expand Up @@ -224,6 +221,15 @@ def parse_command_query(query):
ret['wait'] = wait
else:
raise ValueError('Incorrect wait parameter value')


modify = params.get('modify')
if modify:
modify = modify.lower()
if modify in ['insert', 'delete']:
ret['modify'] = modify
else:
raise ValueError('Incorrect modify parameter value')
return ret


Expand Down
78 changes: 38 additions & 40 deletions rfw/rfw.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,20 +72,37 @@ def check_whitelist_conflict(ip, whitelist):

def process(handler, modify, urlpath):
# modify should be 'D' for Delete or 'I' for Insert understood as -D and -I iptables flags
assert modify == 'D' or modify == 'I'
assert modify in ['D', 'I', 'L']
log.debug('process {} urlpath: {}'.format(modify, urlpath))

try:
action, rule, directives = cmdparse.parse_command(urlpath)
log.debug('\nAction: {}\nRule: {}\nDirectives: {}'.format(action, rule, directives))
if action == 'list':
chain = rule
rules = Iptables.read_simple_rules(chain)
log.debug('List rfw rules: %s', rules)
list_of_dict = map(iptables.Rule._asdict, rules)
resp = json.dumps(list_of_dict)
return handler.http_resp(200, resp)
elif action.upper() in iptables.RULE_TARGETS:
if modify == 'L':
if action == 'help':
resp = 'TODO usage'
return handler.http_resp(200, resp)
elif action == 'list':
chain = rule
rules = Iptables.read_simple_rules(chain)
log.debug('List rfw rules: %s', rules)
list_of_dict = map(iptables.Rule._asdict, rules)
resp = json.dumps(list_of_dict)
return handler.http_resp(200, resp)
elif rfwconf.is_non_restful():
mod = directives.get('modify')
if not mod:
raise Exception('Unrecognized command. Non-restful enabled, you need to provide modify parameter.'.format(action))
if mod == 'insert':
modify = 'I'
elif mod == 'delete':
modify = 'D'
else:
raise Exception('Unrecognized command. Modify parameter can be "insert" or "delete".')
else:
raise Exception('Unrecognized command. Non-restful disabled.')

if modify in ['D', 'I'] and action.upper() in iptables.RULE_TARGETS:
# eliminate ignored/whitelisted IP related commands early to prevent propagating them to expiry queue
check_whitelist_conflict(rule.source, rfwconf.whitelist())
check_whitelist_conflict(rule.destination, rfwconf.whitelist())
Expand All @@ -94,9 +111,9 @@ def process(handler, modify, urlpath):
cmd_queue.put_nowait(ctup)
return handler.http_resp(200, ctup)
else:
raise Exception('Unrecognized action: {}'.format(action))
raise Exception('Unrecognized command.')
except Exception, e:
msg = 'add_command error: {}'.format(e.message)
msg = 'ERROR: {}'.format(e.message)
# logging as error disabled - bad client request is not an error
# log.exception(msg)
log.info(msg)
Expand All @@ -114,24 +131,17 @@ def go(self, modify, urlpath, remote_addr):

def do_modify(self, modify):
self.go(modify, self.path, self.client_address[0])

def do_PUT(self):
self.do_modify('I')
self.go('I', self.path, self.client_address[0])

def do_DELETE(self):
self.do_modify('D')
self.go('D', self.path, self.client_address[0])

def do_GET(self):
if rfwconf.is_non_restful():
#TODO here it will be more complicated. The GET requests are valid in restful scenario for listing rfw status
self.do_POST()
else:
self.send_response(405) # Method Not Allowed
self.go('L', self.path, self.client_address[0])

def do_POST(self):
self.do_modify('I')




class OutwardRequestHandler(BasicAuthRequestHandler):

Expand All @@ -140,37 +150,25 @@ def version_string(self):

def creds_check(self, user, password):
return user == rfwconf.auth_username() and password == rfwconf.auth_password()


def go(self, modify, urlpath, remote_addr):

# authenticate by checking if client IP is in the whitelist - normally reqests from non-whitelisted IPs should be blocked by firewall beforehand
if not iputil.ip_in_list(remote_addr, rfwconf.whitelist()):
log.error('Request from client IP: {} which is not authorized in the whitelist. It should have been blocked by firewall.'.format(remote_addr))
return self.http_resp(403, '') # Forbidden

process(self, modify, urlpath)


def do_modify(self, modify):
self.go(modify, self.path, self.client_address[0])

def do_PUT(self):
self.do_modify('I')
self.go('I', self.path, self.client_address[0])

def do_DELETE(self):
self.do_modify('D')
self.go('D', self.path, self.client_address[0])

def do_GET(self):
if rfwconf.is_non_restful():
#TODO here it will be more complicated. The GET requests are valid in restful scenario for listing rfw status
self.do_POST()
else:
self.send_response(405) # Method Not Allowed
self.go('L', self.path, self.client_address[0])

def do_POST(self):
self.do_modify('I')


return LocalRequestHandler, OutwardRequestHandler


Expand Down

0 comments on commit 47bf22e

Please sign in to comment.