|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- from salt.exceptions import CommandExecutionError, CommandNotFoundError
- import re
- import socket
-
-
- def _unchanged(name, msg):
- return {'name': name, 'result': True, 'comment': msg, 'changes': {}}
-
-
- def _test(name, msg):
- return {'name': name, 'result': None, 'comment': msg, 'changes': {}}
-
-
- def _error(name, msg):
- return {'name': name, 'result': False, 'comment': msg, 'changes': {}}
-
-
- def _changed(name, msg, **changes):
- return {'name': name, 'result': True, 'comment': msg, 'changes': changes}
-
-
- def _resolve(host):
- # let's just see if it starts with a number or a colon, for simplicity
- if re.match(r'^[0-9:]', host):
- return host
-
- return socket.gethostbyname(host)
-
-
- def _as_rule(method, app, interface, protocol, from_addr, from_port, to_addr, to_port, comment):
- cmd = [method]
- if app is not None:
- cmd.append("from")
- if from_addr is not None:
- cmd.append(from_addr)
- else:
- cmd.append("any")
-
- cmd.append("to")
- if to_addr is not None:
- cmd.append(to_addr)
- else:
- cmd.append("any")
-
- cmd.append("app")
- cmd.append(app)
- elif interface is not None:
- cmd.append("in")
- cmd.append("on")
- cmd.append(interface)
- else:
- if protocol is not None:
- cmd.append("proto")
- cmd.append(protocol)
-
- cmd.append("from")
- if from_addr is not None:
- cmd.append(_resolve(from_addr))
- else:
- cmd.append("any")
-
- if from_port is not None:
- cmd.append("port")
- cmd.append(_resolve(from_port))
-
- cmd.append("to")
- if to_addr is not None:
- cmd.append(to_addr)
- else:
- cmd.append("any")
-
- if to_port is not None:
- cmd.append("port")
- cmd.append(to_port)
-
- if comment is not None:
- cmd.append("comment")
- cmd.append(comment)
- real_cmd = ' '.join(cmd)
- return real_cmd
-
-
- def _add_rule(method, name, app=None, interface=None, protocol=None,
- from_addr=None, from_port=None, to_addr=None, to_port=None, comment=None):
-
- if app and app.strip('"\' ') == '*':
- app = None
- if to_port and to_port.strip('"\' ') == '*':
- to_port = None
-
- rule = _as_rule(method, app=app, interface=interface, protocol=protocol,
- from_addr=from_addr, from_port=from_port, to_addr=to_addr, to_port=to_port, comment=comment)
-
- try:
- out = __salt__['ufw.add_rule'](rule)
- except (CommandExecutionError, CommandNotFoundError) as e:
- if method.startswith('insert 1 deny') and "Invalid position '1'" in e.message:
- # This is probably the first rule to be added, so try again without "insert 1"
- return _add_rule('deny', name, app, interface, protocol, from_addr, from_port, to_addr, to_port, comment)
- return _error(name, e.message)
-
- adds = False
- inserts = False
- updates = False
- for line in out.split('\n'):
- if re.match('^Skipping', line):
- return _unchanged(name, "{0} is already configured".format(name))
- break
- if re.match('^Rule(s)? added', line):
- adds = True
- break
- if re.match('^Rule(s)? inserted', line):
- inserts = True
- break
- if re.match('^Rule(s)? updated', line):
- updates = True
- break
- if __opts__['test']:
- return _test(name, "{0} would have been configured".format(name))
- break
-
- if method.startswith('insert 1 deny') and "Invalid position '1'" in line:
- # This is probably the first rule to be added, so try again without "insert 1"
- return _add_rule('deny', name, app, interface, protocol, from_addr, from_port, to_addr, to_port, comment)
- return _error(name, line)
-
- if adds:
- return _changed(name, "{0} added".format(name), rule=rule)
- elif inserts:
- return _changed(name, "{0} inserted".format(name), rule=rule)
- elif updates:
- return _changed(name, "{0} updated".format(name), rule=rule)
- else:
- return _unchanged(name, "{0} was already configured".format(name))
-
-
- def enabled(name, **kwargs):
- if __salt__['ufw.is_enabled']():
- return _unchanged(name, "UFW is already enabled")
-
- try:
- __salt__['ufw.set_enabled'](True)
- except (CommandExecutionError, CommandNotFoundError) as e:
- return _error(name, e.message)
-
- if __opts__['test']:
- return _test(name, "UFW would have been enabled")
- else:
- return _changed(name, "UFW is enabled", enabled=True)
-
-
- def default_incoming(name, default):
- rule = "default {0} incoming".format(default)
- if __opts__['test']:
- return _test(name, "{0}: {1}".format(name, rule))
-
- current = __salt__['ufw.get_default_incoming']()
-
- if default != current:
- try:
- out = __salt__['ufw.add_rule'](rule)
- except (CommandExecutionError, CommandNotFoundError) as e:
- return _error(name, e.message)
-
- for line in out.split('\n'):
- if line.startswith("Default incoming policy changed to"):
- return _changed(name, "{0} set to {1}".format(name, default), rule=rule)
- return _error(name, line)
-
- return _unchanged(name, "{0} was already set to {1}".format(name, default))
-
-
- def default_outgoing(name, default):
- rule = "default {0} outgoing".format(default)
- if __opts__['test']:
- return _test(name, "{0}: {1}".format(name, rule))
-
- current = __salt__['ufw.get_default_outgoing']()
-
- if default != current:
- try:
- out = __salt__['ufw.add_rule'](rule)
- except (CommandExecutionError, CommandNotFoundError) as e:
- return _error(name, e.message)
-
- for line in out.split('\n'):
- if line.startswith("Default outgoing policy changed to"):
- return _changed(name, "{0} set to {1}".format(name, default), rule=rule)
- return _error(name, line)
-
- return _unchanged(name, "{0} was already set to {1}".format(name, default))
-
-
- def deny(name, app=None, interface=None, protocol=None,
- from_addr=None, from_port=None, to_addr=None, to_port=None, comment=None):
-
- return _add_rule('insert 1 deny', name, app, interface, protocol, from_addr, from_port, to_addr, to_port, comment)
-
-
- def limit(name, app=None, interface=None, protocol=None,
- from_addr=None, from_port=None, to_addr=None, to_port=None, comment=None):
-
- return _add_rule('limit', name, app, interface, protocol, from_addr, from_port, to_addr, to_port, comment)
-
-
- def allow(name, app=None, interface=None, protocol=None,
- from_addr=None, from_port=None, to_addr=None, to_port=None, comment=None):
-
- return _add_rule('allow', name, app, interface, protocol, from_addr, from_port, to_addr, to_port, comment)
-
-
- def allowed(name, app=None, interface=None, protocol=None,
- from_addr=None, from_port=None, to_addr=None, to_port=None, comment=None):
-
- """
- allow() is aliased to allowed() to maintain backwards compatibility.
- """
- return allow(name, app, interface, protocol, from_addr, from_port, to_addr, to_port, comment)
|