X-Git-Url: https://code.grnet.gr/git/flowspy/blobdiff_plain/052c14aae9f075e11f6e055951fb4e8034e89ef0..00957db3ba41b14cf37217ee0e2db40bb9d6b3cf:/flowspec/forms.py?ds=sidebyside
diff --git a/flowspec/forms.py b/flowspec/forms.py
index 52b90ce..f5741c6 100644
--- a/flowspec/forms.py
+++ b/flowspec/forms.py
@@ -7,8 +7,9 @@ from flowspy.flowspec.models import *
from ipaddr import *
from django.core.urlresolvers import reverse
from django.contrib.auth.models import User
+from django.conf import settings
import datetime
-
+from django.core.mail import mail_admins, mail_managers, send_mail
class RouteForm(forms.ModelForm):
@@ -21,26 +22,68 @@ class RouteForm(forms.ModelForm):
# " e.g.10.10.0.1/32"), label=ugettext_lazy("Destination Address"), required=False)
# destination_ports = forms.ModelMultipleChoiceField(queryset=MatchPort.objects.all(), help_text=ugettext_lazy("A set of destination ports to block"), label=ugettext_lazy("Destination Ports"), required=False)
# ports = forms.ModelMultipleChoiceField(queryset=MatchPort.objects.all(), help_text=ugettext_lazy("A set of ports to block"), label=ugettext_lazy("Ports"), required=False)
+
class Meta:
model = Route
def clean_source(self):
+ user = User.objects.get(pk=self.data['applier'])
+ peer = user.get_profile().peer
data = self.cleaned_data['source']
+ private_error = False
+ protected_error = False
if data:
try:
address = IPNetwork(data)
- return self.cleaned_data["source"]
+ for net in settings.PROTECTED_SUBNETS:
+ if address in IPNetwork(net):
+ protected_error = True
+ mail_body = "User %s %s (%s) attempted to set %s as the source address in a firewall rule" %(user.username, user.email, peer.peer_name, data)
+ send_mail(settings.EMAIL_SUBJECT_PREFIX + "Caught an attempt to set a protected IP/network as a source address",
+ mail_body, settings.SERVER_EMAIL,
+ settings.NOTIFY_ADMIN_MAILS, fail_silently=True)
+ raise forms.ValidationError("Not allowed")
+ if address.is_private:
+ private_error = True
+ raise forms.ValidationError('Private addresses not allowed')
+ else:
+ return self.cleaned_data["source"]
except Exception:
- raise forms.ValidationError('Invalid network address format')
+ error_text = 'Invalid network address format'
+ if private_error:
+ error_text = 'Private addresses not allowed'
+ if protected_error:
+ error_text = 'You have no authority on this subnet'
+ raise forms.ValidationError(error_text)
def clean_destination(self):
+ user = User.objects.get(pk=self.data['applier'])
+ peer = user.get_profile().peer
data = self.cleaned_data['destination']
+ error = None
+ protected_error = False
if data:
try:
address = IPNetwork(data)
+ for net in settings.PROTECTED_SUBNETS:
+ if address in IPNetwork(net):
+ protected_error = True
+ mail_body = "User %s %s (%s) attempted to set %s as the destination address in a firewall rule" %(user.username, user.email, peer.peer_name, data)
+ send_mail(settings.EMAIL_SUBJECT_PREFIX + "Caught an attempt to set a protected IP/network as the destination address",
+ mail_body, settings.SERVER_EMAIL,
+ settings.NOTIFY_ADMIN_MAILS, fail_silently=True)
+ raise forms.ValidationError("Not allowed")
+ if address.prefixlen < settings.PREFIX_LENGTH:
+ error = "Currently no prefix lengths < %s are allowed" %settings.PREFIX_LENGTH
+ raise forms.ValidationError('error')
return self.cleaned_data["destination"]
except Exception:
- raise forms.ValidationError('Invalid network address format')
+ error_text = 'Invalid network address format'
+ if error:
+ error_text = error
+ if protected_error:
+ error_text = 'You have no authority on this subnet'
+ raise forms.ValidationError(error_text)
def clean_expires(self):
date = self.cleaned_data['expires']
@@ -64,7 +107,6 @@ class RouteForm(forms.ModelForm):
networks = peer.networks.all()
mynetwork = False
route_pk_list = []
-
if destination:
for network in networks:
net = IPNetwork(network.network)
@@ -81,7 +123,9 @@ class RouteForm(forms.ModelForm):
if destinationports and not destination:
raise forms.ValidationError('Once destination port is matched, destination has to be filled as well. Either deselect destination port or fill destination address')
if not (source or sourceports or ports or destination or destinationports):
- raise forms.ValidationError('Fill at least a Route Match Condition')
+ raise forms.ValidationError('Fill at least a Rule Match Condition')
+ if not user.is_superuser and then[0].action not in settings.UI_USER_THEN_ACTIONS:
+ raise forms.ValidationError('This action "%s" is not permitted' %(then[0].action))
existing_routes = Route.objects.exclude(status='EXPIRED').exclude(status='PENDING').exclude(status='ERROR').exclude(status='ADMININACTIVE')
existing_routes = existing_routes.filter(applier__userprofile__peer=peer)
if source:
@@ -111,12 +155,8 @@ class RouteForm(forms.ModelForm):
for route in existing_routes:
if name != route.name:
existing_url = reverse('edit-route', args=[route.name])
- if IPNetwork(destination) in IPNetwork(route.destination):
- raise forms.ValidationError('There is an exact %s rule, %s whose destination (%s) is supernet of (or the same as) network (%s).
To avoid overlapping try editing rule %s' %(route.status, route.name, route.destination, destination, existing_url, route.name))
- if IPNetwork(route.destination) in IPNetwork(destination):
- raise forms.ValidationError('There is an exact %s rule, %s whose destination network (%s) belongs to the destination network %s.
To avoid overlapping try editing rule %s' %(route.status, route.name, route.destination, destination, existing_url, route.name))
-
-
+ if IPNetwork(destination) in IPNetwork(route.destination) or IPNetwork(route.destination) in IPNetwork(destination):
+ raise forms.ValidationError('Found an exact %s rule, %s with destination prefix %s
To avoid overlapping try editing rule %s' %(route.status, route.name, route.destination, existing_url, route.name))
return self.cleaned_data
class ThenPlainForm(forms.ModelForm):
@@ -129,11 +169,11 @@ class ThenPlainForm(forms.ModelForm):
if action_value:
try:
assert(int(action_value))
+ if int(action_value) < 50:
+ raise forms.ValidationError('Rate-limiting cannot be < 50kbps')
return "%s" %self.cleaned_data["action_value"]
except:
- raise forms.ValidationError('Rate-limiting should be an integer')
- if int(action_value) < 50:
- raise forms.ValidationError('Rate-limiting cannot be < 50kbps')
+ raise forms.ValidationError('Rate-limiting should be an integer < 50')
else:
raise forms.ValidationError('Cannot be empty')
@@ -143,6 +183,7 @@ class ThenPlainForm(forms.ModelForm):
raise forms.ValidationError('Cannot select something other than rate-limit')
else:
return self.cleaned_data["action"]
+
class PortPlainForm(forms.ModelForm):
# action = forms.CharField(initial='rate-limit')