# HG changeset patch # User Pascal Volk # Date 1208139706 0 # Node ID 3388b96fd3ed27e1ccbaf6d2b090fd0d2a07e359 # Parent 1607f7b2dba9b16f01feeb6770149ec2b22eeb78 * '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 diff -r 1607f7b2dba9 -r 3388b96fd3ed ChangeLog --- 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 + + * 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 * update_tables_0.3.x-0.4.py: Replaced view dovecot_user diff -r 1607f7b2dba9 -r 3388b96fd3ed INSTALL --- 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://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 diff -r 1607f7b2dba9 -r 3388b96fd3ed VirtualMailManager/VirtualMailManager.py --- 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.""" diff -r 1607f7b2dba9 -r 3388b96fd3ed VirtualMailManager/constants/VERSION.py --- 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'