diff --git a/gestion/ldap_passwd.py b/gestion/ldap_passwd.py new file mode 100644 index 00000000..bdbb8665 --- /dev/null +++ b/gestion/ldap_passwd.py @@ -0,0 +1,141 @@ +# -*- coding: iso8859-15 -*- +############################################################################### +# ldap_passwd.py : manipulation des mots de passes LDAP +# $Id: ldap_passwd.py,v 1.1 2006-04-27 23:53:03 chove Exp $ +############################################################################### +# The authors of this code are +# Bjorn Ove Grotan +# Etienne Chové +# +# Copyright (C) 2005 Bjorn Ove Grotan +# Copyright (C) 2006 Etienne Chové +# All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +############################################################################### + +# For extra strength passwords, we wanted SSHA in our LDAP-environment +# as the standard python-module 'sha' does not support ssha, but this can +# easily be implemented with a few extra functions. +# +# SSHA can be described as: +# the SHA1-digest of a password with a sequence of "salt" bytes, where +# the bytes are randomly chosen - followed by the same salt bytes +# For LDAP-use, the SHA1 and SSHA-digest has to be base64-encoded. +# +# Example-LDIF: +# {SSHA}oaEG3PJ10sHxGcSxsDRRooTifL55/2NOdN3nU1VEV+NFzc9Q +# +# This package should now support passwords compatible with [1] Samba using the [2] +# smbpasswd module for [3] Python. The samba compability is added for use with Samba +# as PDC with storing user and host-information in LDAP. +# +# [1] http://www.samba.org +# [2] http://barryp.org/software/py-smbpasswd/ +# [3] http://www.python.org + +import string,base64 +import random,sys +import exceptions +import md5,sha,crypt + +try: + import smbpasswd + smb = True +except: + smb = False + +def getsalt(chars=string.letters+string.digits, length=16): + ''' Generate a random salt. Default length is 16 ''' + salt = '' + for i in range(int(length)): + salt += random.choice(chars) + return salt + +def mkpasswd(pwd, sambaver=3, algo='SSHA', salt=getsalt()): + ''' Make a given password cryptated, possibly with different + crypt-algorihtms. This module was written for use with + LDAP - so default is seeded sha + ''' + + alg = { + 'SSHA':'Seeded SHA', + 'SHA':'Secure Hash Algorithm', + 'MD5':'MD5', + 'SMD5':'Seeded MD5', + 'CRYPT':'standard unix crypt' + } + + if smb: + alg['LMPassword'] = 'lan man hash' + alg['NTPassword'] = 'nt hash' + + if algo not in alg.keys(): + raise TypeError, 'Algorithm <%s> not supported in this version.' % algo + + if algo == 'SSHA': + pwdhash = "{SSHA}" + base64.encodestring(sha.new(str(pwd) + salt).digest() + salt) + elif algo =='SHA': + pwdhash = "{SHA}" + base64.encodestring(sha.new(str(pwd)).digest()) + elif algo =='MD5': + pwdhash = "{MD5}" + base64.encodestring(md5.new(str(pwd)).digest()) + elif algo == 'SMD5': + pwdhash = "{SMD5}" + base64.encodestring(md5.new(str(pwd) + salt).digest() + salt) + elif algo =='CRYPT': + pwdhash = "{CRYPT}" + crypt.crypt(str(pwd),getsalt(length=2)) # crypt only uses a salt of length 2 + elif algo == 'LMPassword': + if sambaver==3: + pwdhash = "{sambaLMPassword}" + smbpasswd.lmhash(pwd) + elif sambaver==2: + pwdhash = "{lmPassword}" + smbpasswd.lmhash(pwd) + elif algo == 'NTPassword': + if sambaver == 3: + pwdhash = "{sambaNTPassword}" + smbpasswd.lmhash(pwd) + elif sambaver == 2: + pwdhash = "{NTPassword}" + smbpasswd.lmhash(pwd) + return pwdhash.strip() + +def checkpwd(pwd, pwdhash): + ''' Check if the password matches the hash ''' + + alg = { + 'SSHA':'Seeded SHA', + 'SHA':'Secure Hash Algorithm', + 'MD5':'MD5', + 'SMD5':'Seeded MD5', + 'CRYPT':'standard unix crypt' + } + + if smb: + alg['LMPassword'] = 'lan man hash' + alg['NTPassword'] = 'nt hash' + + algo = pwdhash[1:].split('}')[0] + + if algo.startswith('samba'): + sambaver = 3 + algo = algo[5:] + else: + sambaver = 2 + + if not algo in alg.keys(): + raise TypeError, 'Algorithm <%s> not supported in this version.' % algo + + if alg[algo].startswith('Seeded '): + salt = base64.decodestring(pwdhash.split('}')[1])[-16:] + else: + salt = None + + return mkpasswd(pwd, sambaver=sambaver, algo=algo, salt=salt) == pwdhash