diff --git a/account/cbase_members.py b/account/cbase_members.py index b3fe08b..23e5489 100644 --- a/account/cbase_members.py +++ b/account/cbase_members.py @@ -5,6 +5,7 @@ import ldap import copy from django.conf import settings +from password_encryption import get_ldap_password """ Example configuration: @@ -14,8 +15,11 @@ CBASE_BASE_DN = 'ou=crew,dc=c-base,dc=org' """ def retrieve_member(request): - # TODO: Put password in encrypted session storage - return MemberValues(request.user.username, request.session['ldap_password']) + ldap_password = get_ldap_password(request) + session = dict(request.session) + print "session:", session + print "cookies:", request.COOKIES + return MemberValues(request.user.username, ldap_password) class MemberValues(object): @@ -80,7 +84,8 @@ class MemberValues(object): print "modattrs: ",mod_attrs result = l.modify_s(dn, mod_attrs) - print "result is: ", result + # + # print "result is: ", result l.unbind_s() def change_password(self, new_password): @@ -145,15 +150,26 @@ class MemberValues(object): l.passwd_s(self._get_bind_dn(username), None, new_password) l.unbind_s() + def get_number_of_members(self): + """ + Returns the total number of c-base members with active user accounts. + """ + return len(self.list_users()) + def list_users(self): + """ + Returns a list of strings with all usernames in the group 'crew'. + The list is sorted alphabetically. + """ l = ldap.initialize(settings.CBASE_LDAP_URL) user_dn = self._get_bind_dn() l.simple_bind_s(user_dn, self._password) try: - ldap_result_id = l.search(settings.CBASE_BASE_DN, ldap.SCOPE_SUBTREE, "memberOf=cn=crew,ou=groups,dc=c-base,dc=org", None) + result_id = l.search(settings.CBASE_BASE_DN, ldap.SCOPE_SUBTREE, + "memberOf=cn=crew,ou=groups,dc=c-base,dc=org", None) result_set = [] - while 1: - result_type, result_data = l.result(ldap_result_id, 0) + while True: + result_type, result_data = l.result(result_id, 0) if (result_data == []): break else: diff --git a/account/forms.py b/account/forms.py index 84f4fc1..6f957eb 100644 --- a/account/forms.py +++ b/account/forms.py @@ -10,7 +10,8 @@ from django.utils.translation import ugettext as _ class LoginForm(forms.Form): username = forms.CharField(max_length=255) - password = forms.CharField(max_length=255, widget=forms.PasswordInput) + password = forms.CharField(max_length=255, widget=forms.PasswordInput, + help_text=_('Cookies must be enabled.')) def clean(self): username = self.cleaned_data.get('username') diff --git a/account/password_encryption.py b/account/password_encryption.py new file mode 100644 index 0000000..0c4138c --- /dev/null +++ b/account/password_encryption.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import base64 + +from Crypto import Random +from Crypto.Cipher import AES + +ENCRYPTED_LDAP_PASSWORD = 'encrypted_ldap_password' + +def encrypt_ldap_password(cleartext_pw): + """ + Encrypts the cleartext_pw with a randomly generated key. + + Returns the key and the encrypted message containing the password. + The key is supposed to be stored into the 'session_key' cookie field we can + later use it to decrypt the password and connect to the LDAP server with it. + """ + # 16 bytes of key => AES-128 + random = Random.new() + key = random.read(16) + + # initialization vector + iv = random.read(16) + + # do the encryption + aes = AES.new(key, AES.MODE_CFB, iv) + message = iv + aes.encrypt(cleartext_pw) + return base64.b64encode(message), base64.b64encode(key) + +def decrypt_ldap_password(message, key): + """ + Takes an encrypted, base64 encoded password and the base64 encoded key. + Returns the cleartext password. + """ + decoded_message = base64.b64decode(message) + decoded_key = base64.b64decode(key) + + # first 16 bytes of the message are the initialization vector + iv = decoded_message[:16] + + # the rest is the encrypted password + ciphertext = decoded_message[16:] + + # decrypt it + aes = AES.new(decoded_key, AES.MODE_CFB, iv) + cleartext_pw = aes.decrypt(ciphertext) + return cleartext_pw + +def store_ldap_password(request, password): + """ + Stores the password in an encrypted session storage and returns the key. + """ + encrypted_pw, key = encrypt_ldap_password(password) + request.session[ENCRYPTED_LDAP_PASSWORD] = encrypted_pw + request.session.save() + return key + +def get_ldap_password(request): + cookies = request.COOKIES + key = cookies.get('sessionkey', None) + if not key: + raise Exception('sessionkey not found in cookies.') + return decrypt_ldap_password(request.session[ENCRYPTED_LDAP_PASSWORD], key) \ No newline at end of file diff --git a/account/templates/home.html b/account/templates/home.html index f8f2aaa..1532f92 100644 --- a/account/templates/home.html +++ b/account/templates/home.html @@ -5,7 +5,9 @@
{% blocktrans %}Here you can change +
You are one of currently {{ number_of_members }} + c-base members.
+{% blocktrans %}Here you can change some parameters of your c-base member account.{% endblocktrans %}