nouveau module password
This commit is contained in:
		
							parent
							
								
									3611e0f9d8
								
							
						
					
					
						commit
						2841700f2d
					
				@ -22,6 +22,7 @@ except ImportError:
 | 
			
		||||
               'getopt', 'optparse', 'args', 'control',
 | 
			
		||||
               'functions', 'json', 'web',
 | 
			
		||||
               'flock',
 | 
			
		||||
               'password',
 | 
			
		||||
               )
 | 
			
		||||
MODULES = list(MODULES)
 | 
			
		||||
def __has_module_and_remove(m, remove=True):
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										141
									
								
								pyulib/src/ulib/base/password.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								pyulib/src/ulib/base/password.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,141 @@
 | 
			
		||||
# -*- coding: utf-8 -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
 | 
			
		||||
import i_need_py25
 | 
			
		||||
 | 
			
		||||
"""Des fonctions pour gérer les formes cryptées des mots de passe
 | 
			
		||||
 | 
			
		||||
Les scheme supportés sont {CRYPT}, {SSHA}, {SMD5}, {SHA}, {MD5}
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
__all__ = ()
 | 
			
		||||
 | 
			
		||||
import base64, random, hashlib
 | 
			
		||||
 | 
			
		||||
try: from crypt import crypt
 | 
			
		||||
except: crypt = None
 | 
			
		||||
 | 
			
		||||
from uio import Utf8IO
 | 
			
		||||
_utf8 = Utf8IO()
 | 
			
		||||
 | 
			
		||||
def is_crypt_scheme(pw):
 | 
			
		||||
    if pw is None: return False
 | 
			
		||||
    return pw[:7].lower() == '{crypt}' or pw.lower() == 'crypt'
 | 
			
		||||
 | 
			
		||||
def is_smd5_scheme(pw):
 | 
			
		||||
    if pw is None: return False
 | 
			
		||||
    return pw[:6].lower() == '{smd5}' or pw.lower() == 'smd5'
 | 
			
		||||
 | 
			
		||||
def is_ssha_scheme(pw):
 | 
			
		||||
    if pw is None: return False
 | 
			
		||||
    return pw[:6].lower() == '{ssha}' or pw.lower() == 'ssha'
 | 
			
		||||
 | 
			
		||||
def is_md5_scheme(pw):
 | 
			
		||||
    if pw is None: return False
 | 
			
		||||
    return pw[:5].lower() == '{md5}' or pw.lower() == 'md5'
 | 
			
		||||
 | 
			
		||||
def is_sha_scheme(pw):
 | 
			
		||||
    if pw is None: return False
 | 
			
		||||
    return pw[:5].lower() == '{sha}' or pw.lower() == 'sha'
 | 
			
		||||
 | 
			
		||||
def get_scheme(pw):
 | 
			
		||||
    if pw is None: return None
 | 
			
		||||
    if is_crypt_scheme(pw): return '{CRYPT}'
 | 
			
		||||
    elif is_smd5_scheme(pw): return '{SMD5}'
 | 
			
		||||
    elif is_ssha_scheme(pw): return '{SSHA}'
 | 
			
		||||
    elif is_md5_scheme(pw): return '{MD5}'
 | 
			
		||||
    elif is_sha_scheme(pw): return '{SHA}'
 | 
			
		||||
    else: return '{CRYPT}'
 | 
			
		||||
 | 
			
		||||
def get_crypt_salt(pw):
 | 
			
		||||
    if pw is None: return None
 | 
			
		||||
    if pw[:7].lower() == '{crypt}': pw = pw[7:]
 | 
			
		||||
    return pw[:2]
 | 
			
		||||
 | 
			
		||||
def get_smd5_salt(pw):
 | 
			
		||||
    if pw is None: return None
 | 
			
		||||
    if pw[:6].lower() == '{smd5}': pw = pw[6:]
 | 
			
		||||
    return base64.decodestring(pw)[16:]
 | 
			
		||||
 | 
			
		||||
def get_ssha_salt(pw):
 | 
			
		||||
    if pw is None: return None
 | 
			
		||||
    if pw[:6].lower() == '{ssha}': pw = pw[6:]
 | 
			
		||||
    return base64.decodestring(pw)[20:]
 | 
			
		||||
 | 
			
		||||
def get_salt(pw):
 | 
			
		||||
    if pw is None: return None
 | 
			
		||||
    if pw[:7].lower() == '{crypt}': return get_crypt_salt(pw)
 | 
			
		||||
    if pw[:6].lower() == '{smd5}': return get_smd5_salt(pw)
 | 
			
		||||
    if pw[:6].lower() == '{ssha}': return get_ssha_salt(pw)
 | 
			
		||||
    # pas de salt
 | 
			
		||||
    if pw[:5].lower() == '{md5}': return ''
 | 
			
		||||
    if pw[:5].lower() == '{sha}': return ''
 | 
			
		||||
    # par défaut, considérer le salt comme pour crypt
 | 
			
		||||
    return get_crypt_salt(pw)
 | 
			
		||||
 | 
			
		||||
CRYPT_SALT_CHARS = "./abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
 | 
			
		||||
def gen_crypt_salt():
 | 
			
		||||
    return random.choice(CRYPT_SALT_CHARS) + random.choice(CRYPT_SALT_CHARS)
 | 
			
		||||
 | 
			
		||||
def gen_binary_salt(length=20):
 | 
			
		||||
    salt = []
 | 
			
		||||
    for i in range(length):
 | 
			
		||||
        salt.append(chr(random.randint(0, 255)))
 | 
			
		||||
    return ''.join(salt)
 | 
			
		||||
 | 
			
		||||
def gen_salt(pw=None, length=20):
 | 
			
		||||
    if pw is not None:
 | 
			
		||||
        if pw[:7].lower() == '{crypt}' or pw.lower() == 'crypt': return gen_crypt_salt()
 | 
			
		||||
        if pw[:6].lower() == '{smd5}' or pw.lower() == 'smd5': return gen_binary_salt(length)
 | 
			
		||||
        if pw[:6].lower() == '{ssha}' or pw.lower() == 'ssha': return gen_binary_salt(length)
 | 
			
		||||
        # pas de salt pour MD5 et SHA
 | 
			
		||||
        if pw[:5].lower() == '{md5}' or pw.lower() == 'md5': return ''
 | 
			
		||||
        if pw[:5].lower() == '{sha}' or pw.lower() == 'sha': return ''
 | 
			
		||||
    # par défaut, générer un salt pour crypt
 | 
			
		||||
    return gen_crypt_salt()
 | 
			
		||||
 | 
			
		||||
def gen_crypt_hash(pw, salt=None):
 | 
			
		||||
    if salt is None: salt = gen_crypt_salt()
 | 
			
		||||
    if crypt is None: raise ValueError("crypt is unvailable")
 | 
			
		||||
    return crypt(pw, salt)
 | 
			
		||||
 | 
			
		||||
def gen_binary_hash(pw, scheme, salt=None):
 | 
			
		||||
    if is_md5_scheme(scheme):
 | 
			
		||||
        m = hashlib.md5()
 | 
			
		||||
    elif is_sha_scheme(scheme):
 | 
			
		||||
        m = hashlib.sha1()
 | 
			
		||||
    elif is_smd5_scheme(scheme):
 | 
			
		||||
        m = hashlib.md5()
 | 
			
		||||
        if salt is None: salt = gen_binary_salt()
 | 
			
		||||
    elif is_ssha_scheme(scheme):
 | 
			
		||||
        m = hashlib.sha1()
 | 
			
		||||
        if salt is None: salt = gen_binary_salt()
 | 
			
		||||
    else: raise ValueError("unsupported scheme: %s" % scheme)
 | 
			
		||||
 | 
			
		||||
    pw = _utf8.s(pw)
 | 
			
		||||
    m.update(pw)
 | 
			
		||||
    if salt is not None: m.update(salt)
 | 
			
		||||
 | 
			
		||||
    hash = m.digest()
 | 
			
		||||
    if salt is not None: hash += salt
 | 
			
		||||
 | 
			
		||||
    return base64.b64encode(hash)
 | 
			
		||||
    
 | 
			
		||||
def gen_hash(pw, scheme=None, ref=None, normalized=True):
 | 
			
		||||
    if ref is not None:
 | 
			
		||||
        scheme = get_scheme(ref)
 | 
			
		||||
        salt = get_salt(ref)
 | 
			
		||||
        if is_crypt_scheme(scheme):
 | 
			
		||||
            hash = gen_crypt_hash(pw, salt)
 | 
			
		||||
        else:
 | 
			
		||||
            hash = gen_binary_hash(pw, scheme, salt)
 | 
			
		||||
    elif scheme is not None:
 | 
			
		||||
        scheme = get_scheme(scheme)
 | 
			
		||||
        if is_crypt_scheme(scheme):
 | 
			
		||||
            hash = gen_crypt_hash(pw)
 | 
			
		||||
        else:
 | 
			
		||||
            hash = gen_binary_hash(pw, scheme)
 | 
			
		||||
    else:
 | 
			
		||||
        # Par défaut, hasher en crypt
 | 
			
		||||
        scheme = '{CRYPT}'
 | 
			
		||||
        hash = gen_crypt_hash(pw)
 | 
			
		||||
    if normalized: hash = scheme + hash
 | 
			
		||||
    return hash
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user