* 'VirtualMailManager/VirtualMailManager.py'
authorPascal Volk <neverseen@users.sourceforge.net>
Mon, 14 Apr 2008 02:21:46 +0000
changeset 16 3388b96fd3ed
parent 15 1607f7b2dba9
child 17 fe9be0081e5f
* 'VirtualMailManager/VirtualMailManager.py' - implemented: * VirtualMailManager.__getSalt() * VirtualMailManager.__pwCrypt() * VirtualMailManager.__pwSHA1() * VirtualMailManager.__pwMD5() * VirtualMailManager.__pwMD4() - updated VirtualMailManager.__pwhash() * 'VirtualMailManager/constants/VERSION.py' - set version to 0.4-dev * 'INSTALL' - added hint for python-crypto - updated user_query
ChangeLog
INSTALL
VirtualMailManager/VirtualMailManager.py
VirtualMailManager/constants/VERSION.py
--- a/ChangeLog	Thu Apr 10 03:24:12 2008 +0000
+++ b/ChangeLog	Mon Apr 14 02:21:46 2008 +0000
@@ -1,4 +1,15 @@
 === 0.0.0 ===
+2008-04-14  Pascal Volk  <neverseen@users.sourceforge.net>
+
+	* VirtualMailManager/VirtualMailManager.py: Implemented:
+	VirtualMailManager.__getSalt(), VirtualMailManager.__pwCrypt(),
+	VirtualMailManager.__pwSHA1(), VirtualMailManager.__pwMD5() and
+	VirtualMailManager.__pwMD4()
+	updated VirtualMailManager.__pwhash()
+	* VirtualMailManager/constants/VERSION.py: Set Version to 0.4-dev
+	* INSTALL: Added hint for python-crypto, fixed user_query
+
+
 2008-04-10  Pascal Volk  <neverseen@users.sourceforge.net>
 
 	* update_tables_0.3.x-0.4.py: Replaced view dovecot_user
--- a/INSTALL	Thu Apr 10 03:24:12 2008 +0000
+++ b/INSTALL	Mon Apr 14 02:21:46 2008 +0000
@@ -2,6 +2,8 @@
 You should already have installed and configured Postfix, Dovecot and
 PostgreSQL.
 You have to install Python and pyPgSQL* to use the Virtual Mail Manager.
+If you want to store the passwords as PLAIN-MD4 digest you have also to install
+python-crypto <http://www.amk.ca/python/code/crypto.html>.
 
 * = http://pypgsql.sourceforge.net/ (Debian: python-pgsql)
 
@@ -91,8 +93,8 @@
     driver = pgsql
     connect = host=localhost dbname=mailsys user=dovecot password=$Dovecot_PASS
     default_pass_scheme = HMAC-MD5
-    password_query = SELECT "user", password FROM dovecot_password WHERE "user"= '%u'
-    user_query = SELECT home, uid, gid, mail FROM dovecot_user WHERE userid='%u'
+    password_query = SELECT "user", password FROM dovecot_password WHERE "user"='%u'
+    user_query = SELECT home, uid, gid, 'maildir:'||mail AS mail FROM dovecot_user WHERE userid = '%u'
 
 Provide a root SETUID copy of Dovecot's deliver agent for Postfix
 
--- a/VirtualMailManager/VirtualMailManager.py	Thu Apr 10 03:24:12 2008 +0000
+++ b/VirtualMailManager/VirtualMailManager.py	Mon Apr 14 02:21:46 2008 +0000
@@ -29,6 +29,7 @@
 from Alias import Alias
 from Domain import Domain
 
+SALTCHARS = './0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
 RE_ASCII_CHARS = """^[\x20-\x7E]*$"""
 RE_DOMAIN = """^(?:[a-z0-9-]{1,63}\.){1,}[a-z]{2,6}$"""
 RE_LOCALPART = """[^\w!#$%&'\*\+-\.\/=?^_`{\|}~]"""
@@ -60,6 +61,7 @@
             self.__Cfg.load()
             self.__Cfg.check()
             self.__cfgSections = self.__Cfg.getsections()
+            self.__scheme = self.__Cfg.get('misc', 'passwdscheme')
         if not sys.argv[1] in ['cf', 'configure']:
             self.__chkenv()
 
@@ -307,12 +309,66 @@
                         ERR.DOMAINDIR_GROUP_MISMATCH))
                 rmtree(domdirdirs[1], ignore_errors=True)
 
+    def __getSalt(self):
+        from random import choice
+        salt = None
+        if self.__scheme == 'CRYPT':
+            salt = '%s%s' % (choice(SALTCHARS), choice(SALTCHARS))
+        elif self.__scheme in ['MD5', 'MD5-CRYPT']:
+            salt = '$1$'
+            for i in range(8):
+                salt += choice(SALTCHARS)
+            salt += '$'
+        return salt
+
+    def __pwCrypt(self, password):
+        # for: CRYPT, MD5 and MD5-CRYPT
+        from crypt import crypt
+        return crypt(password, self.__getSalt())
+
+    def __pwSHA1(self, password):
+        # for: SHA/SHA1
+        import sha
+        from base64 import standard_b64encode
+        sha1 = sha.new(password)
+        return standard_b64encode(sha1.digest())
+
+    def __pwMD5(self, password, emailaddress=None):
+        import md5
+        _md5 = md5.new(password)
+        if self.__scheme == 'LDAP-MD5':
+            from base64 import standard_b64encode
+            return standard_b64encode(_md5.digest())
+        elif self.__scheme == 'PLAIN-MD5':
+            return _md5.hexdigest()
+        elif self.__scheme == 'DIGEST-MD5' and emailaddress is not None:
+            _md5 = md5.new('%s:%s:' % tuple(emailaddress.split('@')))
+            _md5.update(password)
+            return _md5.hexdigest()
+
+    def __pwMD4(self, password):
+        # for: PLAIN-MD4
+        from Crypto.Hash import MD4
+        _md4 = MD4.new(password)
+        return _md4.hexdigest()
+
     def __pwhash(self, password, scheme=None, user=None):
-        # XXX alle Schemen berücksichtigen XXX
-        if scheme is None:
-            scheme = self.__Cfg.get('misc', 'passwdscheme')
-        return Popen([self.__Cfg.get('bin', 'dovecotpw'), '-s', scheme, '-p',
-            password], stdout=PIPE).communicate()[0][len(scheme)+2:-1]
+        if scheme is not None:
+            self.__scheme = scheme
+        if self.__scheme in ['CRYPT', 'MD5', 'MD5-CRYPT']:
+            return '{%s}%s' % (self.__scheme, self.__pwCrypt(password))
+        elif self.__scheme in ['SHA', 'SHA1']:
+            return '{%s}%s' % (self.__scheme, self.__pwSHA1(password))
+        elif self.__scheme in ['PLAIN-MD5', 'LDAP-MD5', 'DIGEST-MD5']:
+            return '{%s}%s' % (self.__scheme, self.__pwMD5(password, user))
+        elif self.__scheme == 'MD4':
+            return '{%s}%s' % (self.__scheme, self.__pwMD4(password))
+        elif self.__scheme in ['SMD5', 'SSHA', 'CRAM-MD5', 'HMAC-MD5',
+                'LANMAN', 'NTLM', 'RPA']:
+            return Popen([self.__Cfg.get('bin', 'dovecotpw'), '-s',
+                self.__scheme,'-p',password],stdout=PIPE).communicate()[0][:-1]
+        else:
+            return '{%s}%s' % (self.__scheme, password)
 
     def hasWarnings(self):
         """Checks if warnings are present, returns bool."""
--- a/VirtualMailManager/constants/VERSION.py	Thu Apr 10 03:24:12 2008 +0000
+++ b/VirtualMailManager/constants/VERSION.py	Mon Apr 14 02:21:46 2008 +0000
@@ -4,4 +4,4 @@
 # See COPYING for distribution information.
 # $Id$
 
-VERSION = '0.3.1'
+VERSION = '0.4-dev'