From 0ce2f0f249e0b0868056d3ce00a2db5ebe270605 Mon Sep 17 00:00:00 2001 From: ausiv4 Date: Thu, 6 Aug 2009 23:54:46 +0000 Subject: Changes were made to improve database efficiency and to use the django authentication backend framework. --- django/srpproject/settings.py | 4 ++++ django/srpproject/srp/backends.py | 24 ++++++++++++++++++++++++ django/srpproject/srp/models.py | 13 ++++++------- django/srpproject/srp/views.py | 34 ++++++++++++++++------------------ 4 files changed, 50 insertions(+), 25 deletions(-) create mode 100644 django/srpproject/srp/backends.py diff --git a/django/srpproject/settings.py b/django/srpproject/settings.py index 804c81d..7daaf66 100644 --- a/django/srpproject/settings.py +++ b/django/srpproject/settings.py @@ -78,3 +78,7 @@ INSTALLED_APPS = ( 'django.contrib.sites', 'srpproject.srp' ) + +AUTHENTICATION_BACKENDS = ( + 'srp.backends.SRPBackend', +) diff --git a/django/srpproject/srp/backends.py b/django/srpproject/srp/backends.py new file mode 100644 index 0000000..1f13173 --- /dev/null +++ b/django/srpproject/srp/backends.py @@ -0,0 +1,24 @@ +from srp.models import SRPUser + +class SRPBackend: + """ + Authenticate against srp.models.SRPUser + """ + # TODO: Model, login attribute name and password attribute name should be + # configurable. + def authenticate(self, username=None, M=None): + try: + user = SRPUser.objects.get(username=username) + if user.check_password(M): + return user + except SRPUser.DoesNotExist: + return None + + def get_user(self, user_id): + try: + return SRPUser.objects.get(pk=user_id) + except SRPUser.DoesNotExist: + return None + + + diff --git a/django/srpproject/srp/models.py b/django/srpproject/srp/models.py index 62d4c3e..ce30c95 100644 --- a/django/srpproject/srp/models.py +++ b/django/srpproject/srp/models.py @@ -1,12 +1,11 @@ from django.db import models -from django.contrib import auth +from django.contrib.auth.models import User # Create your models here. -class User(models.Model): +class SRPUser(User): salt = models.CharField(max_length=16) - name = models.CharField(max_length=20, unique=True) verifier = models.CharField(max_length=65, null=True) - - def delete(self): - auth.models.objects.filter(username=self.name).delete() - super(User, self).delete() + + def check_password(self, M): + return M[0] == M[1] + diff --git a/django/srpproject/srp/views.py b/django/srpproject/srp/views.py index 4200e8c..ffc5679 100644 --- a/django/srpproject/srp/views.py +++ b/django/srpproject/srp/views.py @@ -41,7 +41,7 @@ def register_page(request): # Step 1. A client submits a username. If the username is available, we generate a salt, store it, and return it. # Otherwise, we return an error. def register_salt(request): - if models.User.objects.filter(name=request.POST["I"]).count() > 0: + if models.SRPUser.objects.filter(username=request.POST["I"]).count() > 0: return HttpResponse("Username already in use", mimetype="text/xml") request.session["srp_name"] = request.POST["I"] request.session["srp_salt"] = generate_salt() @@ -50,8 +50,8 @@ def register_salt(request): # Step 2. The client creates the password verifier and sends it to the server, along with a username. def register_user(request): from django.contrib import auth - models.User(salt=request.session["srp_salt"], name=request.session["srp_name"], verifier=request.POST["v"]).save() - auth.models.User.objects.create_user(request.session["srp_name"],'', str(request.POST["v"])) + models.SRPUser(salt=request.session["srp_salt"], username=request.session["srp_name"], verifier=request.POST["v"]).save() + # auth.models.SRPUser.objects.create_user(request.session["srp_name"],'', str(request.POST["v"])) del request.session["srp_salt"] del request.session["srp_name"] return HttpResponse("", mimetype="text/xml"); @@ -77,15 +77,13 @@ def handshake(request): return HttpResponse("Invalid ephemeral key.", mimetype="text/xml") else: try: - user = models.User.objects.get(name=request.session["srp_I"]) + user = models.SRPUser.objects.get(username=request.session["srp_I"]) salt = user.salt v = int(user.verifier, 16) # We don't want to leak that the username doesn't exist. Make up a fake salt and verifier. - except models.User.DoesNotExist: + except models.SRPUser.DoesNotExist: salt, x = generate_fake_salt(request.POST["I"]) v = pow(g, x, N) - - request.session["srp_v"] = hex(v)[2:-1] # Ensure that B%N != 0 while True: @@ -108,21 +106,21 @@ def handshake(request): # Step 2: The client sends its proof of S. The server confirms, and sends its proof of S. def verify(request): import hashlib - from django.contrib import auth - if request.POST["M"] == request.session["srp_M"]: - # H(A, M, K) - user = auth.authenticate(username=request.session["srp_I"], password=str(request.session["srp_v"])) - if user != None: + from django.contrib.auth import login, authenticate + # H(A, M, K) + try: + user = authenticate(username=request.session["srp_I"], M=(request.POST["M"], request.session["srp_M"])) + if user: response = "%s" % hashlib.sha256("%s%s%s" % (request.session["srp_A"], request.session["srp_M"], request.session["srp_S"])).hexdigest() - auth.login(request, user) + login(request, user) else: - # This should only happen when authentication is successful with SRP, but the user isn't in the auth table. - response = "Authentication failed. This is likely a server problem." - else: - response = "Invalid username or password." + response = "Invalid username or password." + except models.SRPUser.DoesNotExist: + # This should only happen when authentication is successful with SRP, but the user isn't in the auth table. + response = "Authentication failed. This is likely a server problem." + try: del request.session["srp_I"] - del request.session["srp_v"] del request.session["srp_M"] del request.session["srp_S"] del request.session["srp_A"] -- cgit v1.2.3