changeset 6045:f029e42ecdec

add logging for login to detect potential abuse
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Fri, 06 Jun 2014 13:33:16 +0200
parents c30de53bd126
children f7175dbb081e
files MoinMoin/auth/__init__.py MoinMoin/util/abuse.py wikiserverlogging.conf
diffstat 3 files changed, 63 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/auth/__init__.py	Tue Apr 29 10:42:46 2014 +0200
+++ b/MoinMoin/auth/__init__.py	Fri Jun 06 13:33:16 2014 +0200
@@ -140,6 +140,7 @@
 from werkzeug import redirect, abort, url_quote, url_quote_plus
 
 from MoinMoin import user, wikiutil
+from MoinMoin.util.abuse import log_attempt
 
 
 def get_multistage_continuation_url(request, auth_name, extra_fields={}):
@@ -245,9 +246,11 @@
         u = user.User(request, name=username, password=password, auth_method=self.name)
         if u.valid:
             logging.debug("%s: successfully authenticated user %r (valid)" % (self.name, u.name))
+            log_attempt("auth: login (moin)", True, request, username)
             return ContinueLogin(u)
         else:
             logging.debug("%s: could not authenticate user %r (not valid)" % (self.name, username))
+            log_attempt("auth: login (moin)", False, request, username)
             return ContinueLogin(user_obj, _("Invalid username or password."))
 
     def login_hint(self, request):
@@ -370,9 +373,12 @@
             u.create_or_update()
         if u and u.valid:
             logging.debug("returning valid user %r" % u)
+            log_attempt("auth: request (given)", True, request, auth_username)
             return u, True # True to get other methods called, too
         else:
             logging.debug("returning %r" % user_obj)
+            if u and not u.valid:
+                log_attempt("auth: request (given)", False, request, auth_username)
             return user_obj, True
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/util/abuse.py	Fri Jun 06 13:33:16 2014 +0200
@@ -0,0 +1,36 @@
+# -*- coding: iso-8859-1 -*-
+"""
+    MoinMoin - (ab)use logging
+    Log some data that can be used for usage analysis and abuse detection.
+
+    This logging functionality is kept in this separate module so we can
+    easily redirect the output to a separate log using logging configuration.
+
+    @copyright: 2013 MoinMoin:ThomasWaldmann
+    @license: GNU GPL, see COPYING for details.
+"""
+
+from MoinMoin import log
+logging = log.getLogger(__name__)
+
+
+def log_attempt(system, success, request=None, username=None):
+    """
+    log attempts to use <system>, log success / failure / username / ip
+
+    @param system: some string telling about the system that was used, e.g.
+                   "auth: login" or "textcha"
+    @param success: whether the attempt was successful
+    @param request: request object (optional, to determine remote's ip address)
+    @param username: user's name (optional, if None: determined from request)
+    """
+    if username is None:
+        if request and request.user.valid:
+            username = request.user.name
+        else:
+            username = u'anonymous'
+    level = (logging.WARNING, logging.INFO)[success]
+    msg = """%s status: %s username: "%s" ip: %s"""
+    status = ("failure", "success")[success]
+    ip = request and request.remote_addr or 'unknown'
+    logging.log(level, msg, system, status, username, ip)
--- a/wikiserverlogging.conf	Tue Apr 29 10:42:46 2014 +0200
+++ b/wikiserverlogging.conf	Fri Jun 06 13:33:16 2014 +0200
@@ -6,7 +6,7 @@
 logfile=moin.log
 
 [loggers]
-keys=root,moin_debug
+keys=root,moin_debug,moin_abuse
 
 [logger_root]
 level=INFO
@@ -19,9 +19,16 @@
 qualname=MoinMoin.auth
 propagate=0
 
+[logger_moin_abuse]
+# adapt the next lines to your abuse logging needs:
+level=INFO
+handlers=abuse
+qualname=MoinMoin.util.abuse
+propagate=0
+
 [handlers]
 #keys=logfile,stderr
-keys=stderr
+keys=stderr,abuse
 
 [handler_logfile]
 class=FileHandler
@@ -35,11 +42,22 @@
 level=DEBUG
 args=(sys.stderr, )
 
+[handler_abuse]
+class=StreamHandler
+formatter=abuse
+level=DEBUG
+args=(sys.stderr, )
+
 [formatters]
-keys=default
+keys=default,abuse
 
 [formatter_default]
 format=%(asctime)s %(levelname)s %(name)s:%(lineno)d %(message)s
 datefmt=
 class=logging.Formatter
 
+[formatter_abuse]
+format=%(asctime)s %(levelname)s %(message)s
+datefmt=
+class=logging.Formatter
+