1 from datetime import datetime, timedelta
 
   4 from django.contrib.auth.mixins import LoginRequiredMixin
 
   5 from django.contrib import messages
 
   6 from django.db import IntegrityError
 
   7 from django.db.models import Q
 
   8 from django import http
 
   9 from django.shortcuts import get_object_or_404
 
  10 from django.utils.timezone import now
 
  11 from django.utils.translation import ugettext as _
 
  12 from django.views.decorators.csrf import csrf_exempt
 
  13 from django.views.generic import ListView, CreateView, DeleteView
 
  14 from services.models import Service
 
  15 from .models import SSHKey
 
  16 from .utils import parse_log_line
 
  19 class SSHKeysView(LoginRequiredMixin, ListView):
 
  20     def get_queryset(self):
 
  21         return SSHKey.objects.filter(user=self.request.user)
 
  24 class AddSSHKeyView(LoginRequiredMixin, CreateView):
 
  28     template_name = 'ssh_keys/sshkey_add.html'
 
  30     def form_valid(self, form):
 
  31         form.instance.user = self.request.user
 
  33             return super().form_valid(form)
 
  34         except ValueError as e:
 
  35             messages.add_message(self.request, messages.ERROR, e)
 
  36         except IntegrityError:
 
  37             messages.add_message(self.request, messages.ERROR, _("Key already in the database."))
 
  38         return http.HttpResponseRedirect(self.success_url)
 
  42 class DeleteSSHKeyView(LoginRequiredMixin, DeleteView):
 
  45     def get_queryset(self):
 
  46         return SSHKey.objects.filter(user=self.request.user)
 
  50 def ssh_keys_seen(request):
 
  51     logger = logging.getLogger('django.request')
 
  52     key = request.GET.get('key')
 
  53     service = get_object_or_404(Service, key=key)
 
  56     logline_re = r'^(?P<time>\w{3}\s+\d+\s+\d\d:\d\d:\d\d).*: Accepted publickey for .* from .* port .* ssh2: (?P<algo>\w+) (?P<hash>[a-f0-9:]+)$'
 
  59     for line in request.body.decode('latin1').split('\n'):
 
  62         data = parse_log_line(line)
 
  64             logger.error('Unparsed: ' + line)
 
  70             hash_value = data['md5']
 
  73             hash_value = data['sha256']
 
  74         key = algo, hash_type, hash_value
 
  75         last_seen[key] = max(last_seen.get(key, dt), dt)
 
  77     for key, dt in last_seen.items():
 
  78         algo, hash_type, hash_value = key
 
  79         SSHKey.objects.filter(
 
  80             Q(last_seen_at=None) | Q(last_seen_at__lt=dt),
 
  82             **{f'{hash_type}_hash': hash_value}
 
  87     return http.HttpResponse('ok')