VirtualMailManager/password.py
branchv0.7.x
changeset 691 932cd76bf879
parent 676 2bc11dada296
child 711 2a75058fc064
equal deleted inserted replaced
690:06c0acf6c45d 691:932cd76bf879
   180 
   180 
   181 def _md5_hash(password, scheme, encoding, user=None):
   181 def _md5_hash(password, scheme, encoding, user=None):
   182     """Generates DIGEST-MD5 aka PLAIN-MD5 and LDAP-MD5 hashes."""
   182     """Generates DIGEST-MD5 aka PLAIN-MD5 and LDAP-MD5 hashes."""
   183     md5 = hashlib.md5()
   183     md5 = hashlib.md5()
   184     if scheme == 'DIGEST-MD5':
   184     if scheme == 'DIGEST-MD5':
   185         #  Prior to Dovecot v1.1.12/v1.2.beta2 there was a problem with a
   185         md5.update(user.localpart.encode() + b':' +
   186         #  empty auth_realms setting in dovecot.conf and user@domain.tld
   186                    user.domainname.encode() + b':')
   187         #  usernames. So we have to generate different hashes for different
       
   188         #  versions. See also:
       
   189         #       http://dovecot.org/list/dovecot-news/2009-March/000103.html
       
   190         #       http://hg.dovecot.org/dovecot-1.1/rev/2b0043ba89ae
       
   191         if cfg_dget('misc.dovecot_version') >= 0x1010cf00:
       
   192             md5.update(user.localpart.encode() + b':' +
       
   193                        user.domainname.encode() + b':')
       
   194         else:
       
   195             raise VMMError('You will need Dovecot >= v1.2.0 for proper '
       
   196                            'functioning digest-md5 authentication.', VMM_ERROR)
       
   197     md5.update(password)
   187     md5.update(password)
   198     if (scheme in ('PLAIN-MD5', 'DIGEST-MD5') and encoding in DEFAULT_HEX) or \
   188     if (scheme in ('PLAIN-MD5', 'DIGEST-MD5') and encoding in DEFAULT_HEX) or \
   199        (scheme == 'LDAP-MD5' and encoding == 'HEX'):
   189        (scheme == 'LDAP-MD5' and encoding == 'HEX'):
   200         digest = md5.hexdigest()
   190         digest = md5.hexdigest()
   201     else:
   191     else:
   327 def list_schemes():
   317 def list_schemes():
   328     """Returns the tuple (schemes, encodings).
   318     """Returns the tuple (schemes, encodings).
   329 
   319 
   330     `schemes` is an iterator for all supported password schemes (depends on
   320     `schemes` is an iterator for all supported password schemes (depends on
   331     the used Dovecot version and features of the libc).
   321     the used Dovecot version and features of the libc).
   332     `encodings` is a tuple with all usable encoding suffixes. The tuple may
   322     `encodings` is a tuple with all usable encoding suffixes.
   333     be empty.
       
   334     """
   323     """
   335     dcv = cfg_dget('misc.dovecot_version')
   324     dcv = cfg_dget('misc.dovecot_version')
   336     schemes = (k for (k, v) in _scheme_info.items() if v[1] <= dcv)
   325     schemes = (k for (k, v) in _scheme_info.items() if v[1] <= dcv)
   337     encodings = ('.B64', '.BASE64', '.HEX') if dcv >= 0x10100a01 else ()
   326     encodings = ('.B64', '.BASE64', '.HEX')
   338     return schemes, encodings
   327     return schemes, encodings
   339 
   328 
   340 
   329 
   341 def verify_scheme(scheme):
   330 def verify_scheme(scheme):
   342     """Checks if the password scheme *scheme* is known and supported by the
   331     """Checks if the password scheme *scheme* is known and supported by the
   363         raise VMMError(_("The password scheme '%(scheme)s' requires Dovecot "
   352         raise VMMError(_("The password scheme '%(scheme)s' requires Dovecot "
   364                          ">= v%(version)s.") % {'scheme': scheme,
   353                          ">= v%(version)s.") % {'scheme': scheme,
   365                        'version': version_str(_scheme_info[scheme][1])},
   354                        'version': version_str(_scheme_info[scheme][1])},
   366                        VMM_ERROR)
   355                        VMM_ERROR)
   367     if len(scheme_encoding) > 1:
   356     if len(scheme_encoding) > 1:
   368         if cfg_dget('misc.dovecot_version') < 0x10100a01:
       
   369             raise VMMError(_('Encoding suffixes for password schemes require '
       
   370                              'Dovecot >= v1.1.alpha1.'), VMM_ERROR)
       
   371         if scheme_encoding[1] not in ('B64', 'BASE64', 'HEX'):
   357         if scheme_encoding[1] not in ('B64', 'BASE64', 'HEX'):
   372             raise VMMError(_("Unsupported password encoding: '%s'") %
   358             raise VMMError(_("Unsupported password encoding: '%s'") %
   373                            scheme_encoding[1], VMM_ERROR)
   359                            scheme_encoding[1], VMM_ERROR)
   374         encoding = scheme_encoding[1]
   360         encoding = scheme_encoding[1]
   375     else:
   361     else: