scripts/gestion/ldap_passwd.py
Nicolas Dandrimont 273a1c29fa [ldap_passwd] Utilisation de la hashlib en lieu et place de md5 et sha
darcs-hash:20110227125935-ffbb2-bc18e97a03b502e327e917fe3613f908f5c89d85.gz
2011-02-27 13:59:35 +01:00

147 lines
4.9 KiB
Python

# -*- coding: utf-8 -*-
###############################################################################
# ldap_passwd.py : manipulation des mots de passes LDAP
# $Id: ldap_passwd.py,v 1.7 2006-05-04 17:46:58 chove Exp $
###############################################################################
# The authors of this code are
# Bjorn Ove Grotan <bgrotan@grotan.com>
# Etienne Chové <etienne.chove@crans.org>
#
# 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 crypt
import hashlib
try:
import smbpasswd
smb = True
except:
smb = False
algos={}
algos = {
'ssha':'Seeded SHA',
'sha':'Secure Hash Algorithm',
'md5':'MD5',
'smd5':'Seeded MD5',
'crypt':'standard unix crypt',
'cleartext':'clear text'
}
if smb:
algos['lmpassword'] = 'lan man hash'
algos['ntpassword'] = 'nt hash'
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=None):
''' Make a given password cryptated, possibly with different
crypt-algorihtms. This module was written for use with
LDAP - so default is seeded sha
'''
if salt == None:
salt = getsalt()
algo = algo.lower()
if algo not in algos.keys():
raise TypeError, 'Algorithm <%s> not supported in this version.' % algo
if algo == 'ssha':
h = hashlib.sha1()
h.update(str(pwd) + salt)
pwdhash = "{SSHA}" + base64.encodestring(h.digest() + salt)
elif algo =='sha':
h = hashlib.sha1()
h.update(str(pwd))
pwdhash = "{SHA}" + base64.encodestring(h.digest())
elif algo =='md5':
h = hashlib.md5()
h.update(str(pwd))
pwdhash = "{MD5}" + base64.encodestring(h.digest())
elif algo == 'smd5':
h = hashlib.md5()
h.update(str(pwd) + salt)
pwdhash = "{SMD5}" + base64.encodestring(h.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)
elif algo == 'cleartext':
pwdhash = "{CLEARTEXT}" + pwd
return pwdhash.strip()
def checkpwd(pwd, pwdhash):
''' Check if the password matches the hash '''
algo = pwdhash[1:].split('}')[0]
algo = algo.lower()
if algo.startswith('samba'):
sambaver = 3
algo = algo[5:]
else:
sambaver = 2
if not algo in algos.keys():
raise TypeError, 'Algorithm <%s> not supported in this version.' % algo
if algos[algo].startswith('Seeded '):
salt = base64.decodestring(pwdhash.split('}')[1])[20:]
else:
salt = None
return mkpasswd(pwd, sambaver=sambaver, algo=algo, salt=salt) == pwdhash