views.py 3.83 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE.  If not, see <http://www.gnu.org/licenses/>.

18
from __future__ import absolute_import, unicode_literals
19

20
from datetime import timedelta
21
from json import dumps
22 23 24
import logging

from netaddr import AddrFormatError, IPAddress
25 26
from requests import post
from requests.exceptions import RequestException
27 28

from django.core.exceptions import PermissionDenied
29
from django.http import HttpResponse
30
from django.utils import timezone
31 32 33 34
from django.utils.translation import ugettext_lazy as _
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST

35
from .models import BlacklistItem, Host
36

37
from django.conf import settings
38

39
logger = logging.getLogger(__name__)
40

41

42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
def send_request(obj):
    data = {"ip": obj.ipv4,
            "msg": obj.snort_message,
            "reason": obj.reason,
            "expires_at": str(obj.expires_at).split('.')[0],
            "object_kind": "ban"}
    if obj.host:
        data.update({"hostname": obj.host.hostname,
                     "username": obj.host.owner.username,
                     "fullname": obj.host.owner.get_full_name()})
    try:
        r = post(settings.BLACKLIST_HOOK_URL, data=dumps(data, indent=2),
                 timeout=3)
        r.raise_for_status()
    except RequestException as e:
        logger.warning("Error in HTTP POST: %s. url: %s params: %s",
                       str(e), settings.BLACKLIST_HOOK_URL, data)
    else:
        logger.info("Successful HTTP POST. url: %s params: %s",
                    settings.BLACKLIST_HOOK_URL, data)


64 65
@csrf_exempt
@require_POST
66 67 68 69 70 71 72 73
def add_blacklist_item(request):
    password = request.POST.get('password')
    if (not settings.BLACKLIST_PASSWORD or
            password != settings.BLACKLIST_PASSWORD):
        logger.warning("Tried invalid password. Password: %s IP: %s",
                       password, request.META["REMOTE_ADDR"])
        raise PermissionDenied()

74
    try:
75
        address = request.POST.get('address')
76
        address_object = IPAddress(address, version=4)
77 78 79 80 81 82 83
    except (AddrFormatError, TypeError) as e:
        logger.warning("Invalid IP address: %s (%s)", address, str(e))
        return HttpResponse(_("Invalid IP address."))

    obj, created = BlacklistItem.objects.get_or_create(ipv4=address)
    if created:
        try:
84 85
            db_format = '.'.join("%03d" % x for x in address_object.words)
            obj.host = Host.objects.get(ipv4=db_format)
86 87
        except Host.DoesNotExist:
            pass
88

89 90 91
    now = timezone.now()
    can_update = ((obj.whitelisted and now > obj.expires_at) or
                  not obj.whitelisted)
92
    is_new = created or (obj.expires_at and now > obj.expires_at)
93

94 95 96 97 98 99 100
    if created or can_update:
        obj.reason = request.POST.get('reason')
        obj.snort_message = request.POST.get('snort_message')
        obj.whitelisted = False
        obj.expires_at = now + timedelta(weeks=1)
        obj.full_clean()
        obj.save()
101

102 103 104 105
    if created:
        logger.info("Successfully created blacklist item %s.", address)
    elif can_update:
        logger.info("Successfully modified blacklist item %s.", address)
106

107 108 109
    if is_new and settings.BLACKLIST_HOOK_URL:
        send_request(obj)

110
    return HttpResponse(unicode(_("OK")))