19 from subprocess import Popen, PIPE |
19 from subprocess import Popen, PIPE |
20 |
20 |
21 from pyPgSQL import PgSQL # python-pgsql - http://pypgsql.sourceforge.net |
21 from pyPgSQL import PgSQL # python-pgsql - http://pypgsql.sourceforge.net |
22 |
22 |
23 import VirtualMailManager.constants.ERROR as ERR |
23 import VirtualMailManager.constants.ERROR as ERR |
24 from VirtualMailManager import ENCODING |
|
25 from VirtualMailManager.Account import Account |
24 from VirtualMailManager.Account import Account |
26 from VirtualMailManager.Alias import Alias |
25 from VirtualMailManager.Alias import Alias |
27 from VirtualMailManager.AliasDomain import AliasDomain |
26 from VirtualMailManager.AliasDomain import AliasDomain |
28 from VirtualMailManager.common import exec_ok |
27 from VirtualMailManager.common import exec_ok |
29 from VirtualMailManager.Config import Config as Cfg |
28 from VirtualMailManager.Config import Config as Cfg |
46 |
44 |
47 |
45 |
48 class Handler(object): |
46 class Handler(object): |
49 """Wrapper class to simplify the access on all the stuff from |
47 """Wrapper class to simplify the access on all the stuff from |
50 VirtualMailManager""" |
48 VirtualMailManager""" |
51 __slots__ = ('_Cfg', '_cfgFileName', '_dbh', '_scheme', '__warnings', |
49 __slots__ = ('_Cfg', '_cfgFileName', '_dbh', '_postconf', '__warnings') |
52 '_postconf') |
|
53 |
50 |
54 def __init__(self, skip_some_checks=False): |
51 def __init__(self, skip_some_checks=False): |
55 """Creates a new Handler instance. |
52 """Creates a new Handler instance. |
56 |
53 |
57 ``skip_some_checks`` : bool |
54 ``skip_some_checks`` : bool |
324 raise VMMError(_( |
320 raise VMMError(_( |
325 u'Detected group mismatch in domain directory.'), |
321 u'Detected group mismatch in domain directory.'), |
326 ERR.DOMAINDIR_GROUP_MISMATCH) |
322 ERR.DOMAINDIR_GROUP_MISMATCH) |
327 rmtree(domdirdirs[1], ignore_errors=True) |
323 rmtree(domdirdirs[1], ignore_errors=True) |
328 |
324 |
329 def __getSalt(self): |
|
330 from random import choice |
|
331 salt = None |
|
332 if self._scheme == 'CRYPT': |
|
333 salt = '%s%s' % (choice(SALTCHARS), choice(SALTCHARS)) |
|
334 elif self._scheme in ['MD5', 'MD5-CRYPT']: |
|
335 salt = '$1$%s$' % ''.join([choice(SALTCHARS) for x in xrange(8)]) |
|
336 return salt |
|
337 |
|
338 def __pwCrypt(self, password): |
|
339 # for: CRYPT, MD5 and MD5-CRYPT |
|
340 from crypt import crypt |
|
341 return crypt(password, self.__getSalt()) |
|
342 |
|
343 def __pwSHA1(self, password): |
|
344 # for: SHA/SHA1 |
|
345 import sha |
|
346 from base64 import standard_b64encode |
|
347 sha1 = sha.new(password) |
|
348 return standard_b64encode(sha1.digest()) |
|
349 |
|
350 def __pwMD5(self, password, emailaddress=None): |
|
351 import md5 |
|
352 _md5 = md5.new(password) |
|
353 if self._scheme == 'LDAP-MD5': |
|
354 from base64 import standard_b64encode |
|
355 return standard_b64encode(_md5.digest()) |
|
356 elif self._scheme == 'PLAIN-MD5': |
|
357 return _md5.hexdigest() |
|
358 elif self._scheme == 'DIGEST-MD5' and emailaddress is not None: |
|
359 # use an empty realm - works better with usenames like user@dom |
|
360 _md5 = md5.new('%s::%s' % (emailaddress, password)) |
|
361 return _md5.hexdigest() |
|
362 |
|
363 def __pwMD4(self, password): |
|
364 # for: PLAIN-MD4 |
|
365 from Crypto.Hash import MD4 |
|
366 _md4 = MD4.new(password) |
|
367 return _md4.hexdigest() |
|
368 |
|
369 def __pwhash(self, password, scheme=None, user=None): |
|
370 if scheme is not None: |
|
371 self._scheme = scheme |
|
372 if self._scheme in ['CRYPT', 'MD5', 'MD5-CRYPT']: |
|
373 return '{%s}%s' % (self._scheme, self.__pwCrypt(password)) |
|
374 elif self._scheme in ['SHA', 'SHA1']: |
|
375 return '{%s}%s' % (self._scheme, self.__pwSHA1(password)) |
|
376 elif self._scheme in ['PLAIN-MD5', 'LDAP-MD5', 'DIGEST-MD5']: |
|
377 return '{%s}%s' % (self._scheme, self.__pwMD5(password, user)) |
|
378 elif self._scheme == 'PLAIN-MD4': |
|
379 return '{%s}%s' % (self._scheme, self.__pwMD4(password)) |
|
380 elif self._scheme in ['SMD5', 'SSHA', 'CRAM-MD5', 'HMAC-MD5', |
|
381 'LANMAN', 'NTLM', 'RPA']: |
|
382 cmd_args = [self._Cfg.dget('bin.dovecotpw'), '-s', self._scheme, |
|
383 '-p', password] |
|
384 if self._Cfg.dget('misc.dovecot_version') >= 0x20000a01: |
|
385 cmd_args.insert(1, 'pw') |
|
386 return Popen(cmd_args, stdout=PIPE).communicate()[0][:-1] |
|
387 else: |
|
388 return '{%s}%s' % (self._scheme, password) |
|
389 |
|
390 def hasWarnings(self): |
325 def hasWarnings(self): |
391 """Checks if warnings are present, returns bool.""" |
326 """Checks if warnings are present, returns bool.""" |
392 return bool(len(self.__warnings)) |
327 return bool(len(self.__warnings)) |
393 |
328 |
394 def getWarnings(self): |
329 def getWarnings(self): |