27 from Config import VMMConfig as Cfg |
27 from Config import VMMConfig as Cfg |
28 from Account import Account |
28 from Account import Account |
29 from Alias import Alias |
29 from Alias import Alias |
30 from Domain import Domain |
30 from Domain import Domain |
31 |
31 |
|
32 SALTCHARS = './0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' |
32 RE_ASCII_CHARS = """^[\x20-\x7E]*$""" |
33 RE_ASCII_CHARS = """^[\x20-\x7E]*$""" |
33 RE_DOMAIN = """^(?:[a-z0-9-]{1,63}\.){1,}[a-z]{2,6}$""" |
34 RE_DOMAIN = """^(?:[a-z0-9-]{1,63}\.){1,}[a-z]{2,6}$""" |
34 RE_LOCALPART = """[^\w!#$%&'\*\+-\.\/=?^_`{\|}~]""" |
35 RE_LOCALPART = """[^\w!#$%&'\*\+-\.\/=?^_`{\|}~]""" |
35 RE_MAILLOCATION = """^[\w]{1,20}$""" |
36 RE_MAILLOCATION = """^[\w]{1,20}$""" |
36 re.compile(RE_ASCII_CHARS) |
37 re.compile(RE_ASCII_CHARS) |
305 raise VMMException( |
307 raise VMMException( |
306 ('FATAL: group mismatch in domain directory detected', |
308 ('FATAL: group mismatch in domain directory detected', |
307 ERR.DOMAINDIR_GROUP_MISMATCH)) |
309 ERR.DOMAINDIR_GROUP_MISMATCH)) |
308 rmtree(domdirdirs[1], ignore_errors=True) |
310 rmtree(domdirdirs[1], ignore_errors=True) |
309 |
311 |
|
312 def __getSalt(self): |
|
313 from random import choice |
|
314 salt = None |
|
315 if self.__scheme == 'CRYPT': |
|
316 salt = '%s%s' % (choice(SALTCHARS), choice(SALTCHARS)) |
|
317 elif self.__scheme in ['MD5', 'MD5-CRYPT']: |
|
318 salt = '$1$' |
|
319 for i in range(8): |
|
320 salt += choice(SALTCHARS) |
|
321 salt += '$' |
|
322 return salt |
|
323 |
|
324 def __pwCrypt(self, password): |
|
325 # for: CRYPT, MD5 and MD5-CRYPT |
|
326 from crypt import crypt |
|
327 return crypt(password, self.__getSalt()) |
|
328 |
|
329 def __pwSHA1(self, password): |
|
330 # for: SHA/SHA1 |
|
331 import sha |
|
332 from base64 import standard_b64encode |
|
333 sha1 = sha.new(password) |
|
334 return standard_b64encode(sha1.digest()) |
|
335 |
|
336 def __pwMD5(self, password, emailaddress=None): |
|
337 import md5 |
|
338 _md5 = md5.new(password) |
|
339 if self.__scheme == 'LDAP-MD5': |
|
340 from base64 import standard_b64encode |
|
341 return standard_b64encode(_md5.digest()) |
|
342 elif self.__scheme == 'PLAIN-MD5': |
|
343 return _md5.hexdigest() |
|
344 elif self.__scheme == 'DIGEST-MD5' and emailaddress is not None: |
|
345 _md5 = md5.new('%s:%s:' % tuple(emailaddress.split('@'))) |
|
346 _md5.update(password) |
|
347 return _md5.hexdigest() |
|
348 |
|
349 def __pwMD4(self, password): |
|
350 # for: PLAIN-MD4 |
|
351 from Crypto.Hash import MD4 |
|
352 _md4 = MD4.new(password) |
|
353 return _md4.hexdigest() |
|
354 |
310 def __pwhash(self, password, scheme=None, user=None): |
355 def __pwhash(self, password, scheme=None, user=None): |
311 # XXX alle Schemen berücksichtigen XXX |
356 if scheme is not None: |
312 if scheme is None: |
357 self.__scheme = scheme |
313 scheme = self.__Cfg.get('misc', 'passwdscheme') |
358 if self.__scheme in ['CRYPT', 'MD5', 'MD5-CRYPT']: |
314 return Popen([self.__Cfg.get('bin', 'dovecotpw'), '-s', scheme, '-p', |
359 return '{%s}%s' % (self.__scheme, self.__pwCrypt(password)) |
315 password], stdout=PIPE).communicate()[0][len(scheme)+2:-1] |
360 elif self.__scheme in ['SHA', 'SHA1']: |
|
361 return '{%s}%s' % (self.__scheme, self.__pwSHA1(password)) |
|
362 elif self.__scheme in ['PLAIN-MD5', 'LDAP-MD5', 'DIGEST-MD5']: |
|
363 return '{%s}%s' % (self.__scheme, self.__pwMD5(password, user)) |
|
364 elif self.__scheme == 'MD4': |
|
365 return '{%s}%s' % (self.__scheme, self.__pwMD4(password)) |
|
366 elif self.__scheme in ['SMD5', 'SSHA', 'CRAM-MD5', 'HMAC-MD5', |
|
367 'LANMAN', 'NTLM', 'RPA']: |
|
368 return Popen([self.__Cfg.get('bin', 'dovecotpw'), '-s', |
|
369 self.__scheme,'-p',password],stdout=PIPE).communicate()[0][:-1] |
|
370 else: |
|
371 return '{%s}%s' % (self.__scheme, password) |
316 |
372 |
317 def hasWarnings(self): |
373 def hasWarnings(self): |
318 """Checks if warnings are present, returns bool.""" |
374 """Checks if warnings are present, returns bool.""" |
319 return bool(len(self.__warnings)) |
375 return bool(len(self.__warnings)) |
320 |
376 |