monkey/chaos_monkey/network/firewall.py

179 lines
5.1 KiB
Python
Raw Normal View History

import subprocess
import sys
import platform
2015-11-30 16:56:20 +08:00
class FirewallApp(object):
def is_enabled(self, **kwargs):
return False
def add_firewall_rule(self, **kwargs):
return False
def remove_firewall_rule(self, **kwargs):
return False
def listen_allowed(self, **kwargs):
return True
2015-10-12 19:57:04 +08:00
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
self.close()
def close(self):
return
2015-11-30 16:56:20 +08:00
def _run_netsh_cmd(command, args):
2015-11-30 16:56:20 +08:00
cmd = subprocess.Popen("netsh %s %s" % (command, " ".join(['%s="%s"' % (key, value) for key, value in args.items()
if value])), stdout=subprocess.PIPE)
return cmd.stdout.read().strip().lower().endswith('ok.')
2015-10-12 19:57:04 +08:00
class WinAdvFirewall(FirewallApp):
def __init__(self):
self._rules = {}
def is_enabled(self):
try:
cmd = subprocess.Popen('netsh advfirewall show currentprofile', stdout=subprocess.PIPE)
out = cmd.stdout.readlines()
for l in out:
if l.startswith('State'):
state = l.split()[-1].strip()
return state == "ON"
except:
return None
def add_firewall_rule(self, name="Firewall", dir="in", action="allow", program=sys.executable, **kwargs):
netsh_args = {'name': name,
2016-08-20 22:58:59 +08:00
'dir': dir,
'action': action,
2016-08-20 22:58:59 +08:00
'program': program}
netsh_args.update(kwargs)
try:
if _run_netsh_cmd('advfirewall firewall add rule', netsh_args):
self._rules[name] = netsh_args
return True
else:
return False
except:
return None
def remove_firewall_rule(self, name="Firewall", **kwargs):
netsh_args = {'name': name}
netsh_args.update(kwargs)
try:
if _run_netsh_cmd('advfirewall firewall delete rule', netsh_args):
2016-08-20 22:58:59 +08:00
if name in self._rules:
del self._rules[name]
return True
else:
2015-10-12 19:57:04 +08:00
return False
except:
return None
def listen_allowed(self, **kwargs):
2015-11-30 16:56:20 +08:00
if not self.is_enabled():
return True
for rule in self._rules.values():
if rule.get('program') == sys.executable and \
2015-11-30 16:56:20 +08:00
'in' == rule.get('dir') and \
'allow' == rule.get('action') and \
4 == len(rule.keys()):
return True
return False
def close(self):
try:
for rule in self._rules.keys():
2016-08-20 22:58:59 +08:00
_run_netsh_cmd('advfirewall firewall delete rule', {'name': rule})
except:
pass
class WinFirewall(FirewallApp):
def __init__(self):
self._rules = {}
def is_enabled(self):
try:
cmd = subprocess.Popen('netsh firewall show state', stdout=subprocess.PIPE)
out = cmd.stdout.readlines()
for l in out:
if l.startswith('Operational mode'):
state = l.split('=')[-1].strip()
elif l.startswith('The service has not been started.'):
return False
return state == "Enable"
except:
return None
2016-08-20 22:58:59 +08:00
def add_firewall_rule(self, rule='allowedprogram', name="Firewall", mode="ENABLE", program=sys.executable,
**kwargs):
netsh_args = {'name': name,
2016-08-20 22:58:59 +08:00
'mode': mode,
'program': program}
netsh_args.update(kwargs)
try:
2015-10-12 19:57:04 +08:00
if _run_netsh_cmd('firewall add %s' % rule, netsh_args):
netsh_args['rule'] = rule
self._rules[name] = netsh_args
return True
else:
2016-08-20 22:58:59 +08:00
return False
except:
return None
2016-08-20 22:58:59 +08:00
def remove_firewall_rule(self, rule='allowedprogram', name="Firewall", mode="ENABLE", program=sys.executable,
**kwargs):
netsh_args = {'program': program}
netsh_args.update(kwargs)
try:
2015-10-12 19:57:04 +08:00
if _run_netsh_cmd('firewall delete %s' % rule, netsh_args):
2016-08-20 22:58:59 +08:00
if name in self._rules:
del self._rules[name]
return True
else:
2016-08-20 22:58:59 +08:00
return False
except:
return None
def listen_allowed(self, **kwargs):
2015-11-30 16:56:20 +08:00
if not self.is_enabled():
return True
for rule in self._rules.values():
2015-11-30 16:56:20 +08:00
if rule.get('program') == sys.executable and 'ENABLE' == rule.get('mode'):
return True
2016-08-20 22:58:59 +08:00
return False
def close(self):
try:
2015-10-12 19:57:04 +08:00
for rule in self._rules.values():
self.remove_firewall_rule(**rule)
except:
pass
2016-08-20 22:58:59 +08:00
if sys.platform == "win32":
try:
win_ver = int(platform.version().split('.')[0])
except:
win_ver = 0
if win_ver > 5:
app = WinAdvFirewall()
else:
app = WinFirewall()
else:
2015-11-30 16:56:20 +08:00
app = FirewallApp()