mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-20 22:59:34 -05:00
ITS#8639 remove LANMAN hashed passwords
This commit is contained in:
parent
1c05dce379
commit
6f5cc45f93
2 changed files with 3 additions and 347 deletions
16
configure.in
16
configure.in
|
|
@ -271,7 +271,6 @@ OL_ARG_ENABLE(dynacl,[ --enable-dynacl enable run-time loadable ACL support
|
|||
OL_ARG_ENABLE(aci,[ --enable-aci enable per-object ACIs (experimental)], no, [no yes mod])dnl
|
||||
OL_ARG_ENABLE(cleartext,[ --enable-cleartext enable cleartext passwords], yes)dnl
|
||||
OL_ARG_ENABLE(crypt,[ --enable-crypt enable crypt(3) passwords], no)dnl
|
||||
OL_ARG_ENABLE(lmpasswd,[ --enable-lmpasswd enable LAN Manager passwords], no)dnl
|
||||
OL_ARG_ENABLE(spasswd,[ --enable-spasswd enable (Cyrus) SASL password verification], no)dnl
|
||||
OL_ARG_ENABLE(modules,[ --enable-modules enable dynamic module support], no)dnl
|
||||
OL_ARG_ENABLE(rewrite,[ --enable-rewrite enable DN rewriting in back-ldap and rwm overlay], auto)dnl
|
||||
|
|
@ -507,12 +506,6 @@ if test $ol_enable_asyncmeta/$ol_enable_ldap = yes/no ; then
|
|||
AC_MSG_ERROR([--enable-asyncmeta requires --enable-ldap])
|
||||
fi
|
||||
|
||||
if test $ol_enable_lmpasswd = yes ; then
|
||||
if test $ol_with_tls = no ; then
|
||||
AC_MSG_ERROR([LAN Manager passwords require OpenSSL])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test $ol_enable_spasswd = yes ; then
|
||||
if test $ol_with_cyrus_sasl = no ; then
|
||||
AC_MSG_ERROR([options require --with-cyrus-sasl])
|
||||
|
|
@ -1293,15 +1286,6 @@ else
|
|||
AC_MSG_WARN([TLS data protection not supported!])
|
||||
fi
|
||||
|
||||
dnl ----------------------------------------------------------------
|
||||
dnl LAN Manger password checking requires DES from OpenSSL
|
||||
if test $ol_enable_lmpasswd != no; then
|
||||
if test $ol_link_tls != yes ; then
|
||||
AC_MSG_ERROR([LAN Manager passwords require OpenSSL])
|
||||
fi
|
||||
|
||||
AC_DEFINE(SLAPD_LMHASH, 1, [define to support LAN Manager passwords])
|
||||
fi
|
||||
|
||||
dnl ----------------------------------------------------------------
|
||||
dnl Threads?
|
||||
|
|
|
|||
|
|
@ -32,36 +32,6 @@
|
|||
#include <ac/stdlib.h>
|
||||
#include <ac/string.h>
|
||||
#include <ac/unistd.h>
|
||||
|
||||
#if defined(SLAPD_LMHASH)
|
||||
#if defined(HAVE_OPENSSL)
|
||||
# include <openssl/des.h>
|
||||
|
||||
|
||||
typedef DES_cblock des_key;
|
||||
typedef DES_cblock des_data_block;
|
||||
typedef DES_key_schedule des_context[1];
|
||||
#define des_failed(encrypted) 0
|
||||
#define des_finish(key, schedule)
|
||||
|
||||
#elif defined(HAVE_MOZNSS)
|
||||
/*
|
||||
hack hack hack
|
||||
We need to define this here so that nspr/obsolete/protypes.h will not be included
|
||||
if that file is included, it will create a uint32 typedef that will cause the
|
||||
one in lutil_sha1.h to blow up
|
||||
*/
|
||||
#define PROTYPES_H 1
|
||||
# include <nss/pk11pub.h>
|
||||
typedef PK11SymKey *des_key;
|
||||
typedef unsigned char des_data_block[8];
|
||||
typedef PK11Context *des_context[1];
|
||||
#define DES_ENCRYPT CKA_ENCRYPT
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* SLAPD_LMHASH */
|
||||
|
||||
#include <ac/param.h>
|
||||
|
||||
#ifdef SLAPD_CRYPT
|
||||
|
|
@ -130,10 +100,6 @@ static LUTIL_PASSWD_HASH_FUNC hash_sha1;
|
|||
static LUTIL_PASSWD_HASH_FUNC hash_ssha1;
|
||||
#endif
|
||||
|
||||
#ifdef SLAPD_LMHASH
|
||||
static LUTIL_PASSWD_CHK_FUNC chk_lanman;
|
||||
static LUTIL_PASSWD_HASH_FUNC hash_lanman;
|
||||
#endif
|
||||
|
||||
#ifdef SLAPD_CRYPT
|
||||
static LUTIL_PASSWD_CHK_FUNC chk_crypt;
|
||||
|
|
@ -163,10 +129,6 @@ static const struct pw_scheme pw_schemes_default[] =
|
|||
{ BER_BVC("{SMD5}"), chk_smd5, hash_smd5 },
|
||||
{ BER_BVC("{MD5}"), chk_md5, hash_md5 },
|
||||
|
||||
#ifdef SLAPD_LMHASH
|
||||
{ BER_BVC("{LANMAN}"), chk_lanman, hash_lanman },
|
||||
#endif /* SLAPD_LMHASH */
|
||||
|
||||
#ifdef SLAPD_CRYPT
|
||||
{ BER_BVC("{CRYPT}"), chk_crypt, hash_crypt },
|
||||
# if defined( HAVE_GETPWNAM ) && defined( HAVE_STRUCT_PASSWD_PW_PASSWD )
|
||||
|
|
@ -399,8 +361,8 @@ int lutil_passwd_hash(
|
|||
return (sc->hash_fn)( &sc->name, passwd, hash, text );
|
||||
}
|
||||
|
||||
/* pw_string is only called when SLAPD_LMHASH or SLAPD_CRYPT is defined */
|
||||
#if defined(SLAPD_LMHASH) || defined(SLAPD_CRYPT)
|
||||
/* pw_string is only called when SLAPD_CRYPT is defined */
|
||||
#if defined(SLAPD_CRYPT)
|
||||
static int pw_string(
|
||||
const struct berval *sc,
|
||||
struct berval *passwd )
|
||||
|
|
@ -422,7 +384,7 @@ static int pw_string(
|
|||
|
||||
return LUTIL_PASSWD_OK;
|
||||
}
|
||||
#endif /* SLAPD_LMHASH || SLAPD_CRYPT */
|
||||
#endif /* SLAPD_CRYPT */
|
||||
|
||||
int lutil_passwd_string64(
|
||||
const struct berval *sc,
|
||||
|
|
@ -656,245 +618,6 @@ static int chk_md5(
|
|||
return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
|
||||
}
|
||||
|
||||
#ifdef SLAPD_LMHASH
|
||||
|
||||
#if defined(HAVE_OPENSSL)
|
||||
|
||||
/*
|
||||
* abstract away setting the parity.
|
||||
*/
|
||||
static void
|
||||
des_set_key_and_parity( des_key *key, unsigned char *keyData)
|
||||
{
|
||||
memcpy(key, keyData, 8);
|
||||
DES_set_odd_parity( key );
|
||||
}
|
||||
|
||||
|
||||
#elif defined(HAVE_MOZNSS)
|
||||
|
||||
/*
|
||||
* implement MozNSS wrappers for the openSSL calls
|
||||
*/
|
||||
static void
|
||||
des_set_key_and_parity( des_key *key, unsigned char *keyData)
|
||||
{
|
||||
SECItem keyDataItem;
|
||||
PK11SlotInfo *slot;
|
||||
*key = NULL;
|
||||
|
||||
keyDataItem.data = keyData;
|
||||
keyDataItem.len = 8;
|
||||
|
||||
slot = PK11_GetBestSlot(CKM_DES_ECB, NULL);
|
||||
if (slot == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* NOTE: this will not work in FIPS mode. In order to make lmhash
|
||||
* work in fips mode we need to define a LMHASH pbe mechanism and
|
||||
* do the fulll key derivation inside the token */
|
||||
*key = PK11_ImportSymKey(slot, CKM_DES_ECB, PK11_OriginGenerated,
|
||||
CKA_ENCRYPT, &keyDataItem, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
DES_set_key_unchecked( des_key *key, des_context ctxt )
|
||||
{
|
||||
ctxt[0] = NULL;
|
||||
|
||||
/* handle error conditions from previous call */
|
||||
if (!*key) {
|
||||
return;
|
||||
}
|
||||
|
||||
ctxt[0] = PK11_CreateContextBySymKey(CKM_DES_ECB, CKA_ENCRYPT, *key, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
DES_ecb_encrypt( des_data_block *plain, des_data_block *encrypted,
|
||||
des_context ctxt, int op)
|
||||
{
|
||||
SECStatus rv;
|
||||
int size;
|
||||
|
||||
if (ctxt[0] == NULL) {
|
||||
/* need to fail here... */
|
||||
memset(encrypted, 0, sizeof(des_data_block));
|
||||
return;
|
||||
}
|
||||
rv = PK11_CipherOp(ctxt[0], (unsigned char *)&encrypted[0],
|
||||
&size, sizeof(des_data_block),
|
||||
(unsigned char *)&plain[0], sizeof(des_data_block));
|
||||
if (rv != SECSuccess) {
|
||||
/* signal failure */
|
||||
memset(encrypted, 0, sizeof(des_data_block));
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
des_failed(des_data_block *encrypted)
|
||||
{
|
||||
static const des_data_block zero = { 0 };
|
||||
return memcmp(encrypted, zero, sizeof(zero)) == 0;
|
||||
}
|
||||
|
||||
static void
|
||||
des_finish(des_key *key, des_context ctxt)
|
||||
{
|
||||
if (*key) {
|
||||
PK11_FreeSymKey(*key);
|
||||
*key = NULL;
|
||||
}
|
||||
if (ctxt[0]) {
|
||||
PK11_Finalize(ctxt[0]);
|
||||
PK11_DestroyContext(ctxt[0], PR_TRUE);
|
||||
ctxt[0] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* pseudocode from RFC2433
|
||||
* A.2 LmPasswordHash()
|
||||
*
|
||||
* LmPasswordHash(
|
||||
* IN 0-to-14-oem-char Password,
|
||||
* OUT 16-octet PasswordHash )
|
||||
* {
|
||||
* Set UcasePassword to the uppercased Password
|
||||
* Zero pad UcasePassword to 14 characters
|
||||
*
|
||||
* DesHash( 1st 7-octets of UcasePassword,
|
||||
* giving 1st 8-octets of PasswordHash )
|
||||
*
|
||||
* DesHash( 2nd 7-octets of UcasePassword,
|
||||
* giving 2nd 8-octets of PasswordHash )
|
||||
* }
|
||||
*
|
||||
*
|
||||
* A.3 DesHash()
|
||||
*
|
||||
* DesHash(
|
||||
* IN 7-octet Clear,
|
||||
* OUT 8-octet Cypher )
|
||||
* {
|
||||
* *
|
||||
* * Make Cypher an irreversibly encrypted form of Clear by
|
||||
* * encrypting known text using Clear as the secret key.
|
||||
* * The known text consists of the string
|
||||
* *
|
||||
* * KGS!@#$%
|
||||
* *
|
||||
*
|
||||
* Set StdText to "KGS!@#$%"
|
||||
* DesEncrypt( StdText, Clear, giving Cypher )
|
||||
* }
|
||||
*
|
||||
*
|
||||
* A.4 DesEncrypt()
|
||||
*
|
||||
* DesEncrypt(
|
||||
* IN 8-octet Clear,
|
||||
* IN 7-octet Key,
|
||||
* OUT 8-octet Cypher )
|
||||
* {
|
||||
* *
|
||||
* * Use the DES encryption algorithm [4] in ECB mode [9]
|
||||
* * to encrypt Clear into Cypher such that Cypher can
|
||||
* * only be decrypted back to Clear by providing Key.
|
||||
* * Note that the DES algorithm takes as input a 64-bit
|
||||
* * stream where the 8th, 16th, 24th, etc. bits are
|
||||
* * parity bits ignored by the encrypting algorithm.
|
||||
* * Unless you write your own DES to accept 56-bit input
|
||||
* * without parity, you will need to insert the parity bits
|
||||
* * yourself.
|
||||
* *
|
||||
* }
|
||||
*/
|
||||
|
||||
static void lmPasswd_to_key(
|
||||
const char *lmPasswd,
|
||||
des_key *key)
|
||||
{
|
||||
const unsigned char *lpw = (const unsigned char *) lmPasswd;
|
||||
unsigned char k[8];
|
||||
|
||||
/* make room for parity bits */
|
||||
k[0] = lpw[0];
|
||||
k[1] = ((lpw[0] & 0x01) << 7) | (lpw[1] >> 1);
|
||||
k[2] = ((lpw[1] & 0x03) << 6) | (lpw[2] >> 2);
|
||||
k[3] = ((lpw[2] & 0x07) << 5) | (lpw[3] >> 3);
|
||||
k[4] = ((lpw[3] & 0x0F) << 4) | (lpw[4] >> 4);
|
||||
k[5] = ((lpw[4] & 0x1F) << 3) | (lpw[5] >> 5);
|
||||
k[6] = ((lpw[5] & 0x3F) << 2) | (lpw[6] >> 6);
|
||||
k[7] = ((lpw[6] & 0x7F) << 1);
|
||||
|
||||
des_set_key_and_parity( key, k );
|
||||
}
|
||||
|
||||
static int chk_lanman(
|
||||
const struct berval *scheme,
|
||||
const struct berval *passwd,
|
||||
const struct berval *cred,
|
||||
const char **text )
|
||||
{
|
||||
ber_len_t i;
|
||||
char UcasePassword[15];
|
||||
des_key key;
|
||||
des_context schedule;
|
||||
des_data_block StdText = "KGS!@#$%";
|
||||
des_data_block PasswordHash1, PasswordHash2;
|
||||
char PasswordHash[33], storedPasswordHash[33];
|
||||
|
||||
for( i=0; i<cred->bv_len; i++) {
|
||||
if(cred->bv_val[i] == '\0') {
|
||||
return LUTIL_PASSWD_ERR; /* NUL character in password */
|
||||
}
|
||||
}
|
||||
|
||||
if( cred->bv_val[i] != '\0' ) {
|
||||
return LUTIL_PASSWD_ERR; /* passwd must behave like a string */
|
||||
}
|
||||
|
||||
strncpy( UcasePassword, cred->bv_val, 14 );
|
||||
UcasePassword[14] = '\0';
|
||||
ldap_pvt_str2upper( UcasePassword );
|
||||
|
||||
lmPasswd_to_key( UcasePassword, &key );
|
||||
DES_set_key_unchecked( &key, schedule );
|
||||
DES_ecb_encrypt( &StdText, &PasswordHash1, schedule , DES_ENCRYPT );
|
||||
|
||||
if (des_failed(&PasswordHash1)) {
|
||||
return LUTIL_PASSWD_ERR;
|
||||
}
|
||||
|
||||
lmPasswd_to_key( &UcasePassword[7], &key );
|
||||
DES_set_key_unchecked( &key, schedule );
|
||||
DES_ecb_encrypt( &StdText, &PasswordHash2, schedule , DES_ENCRYPT );
|
||||
if (des_failed(&PasswordHash2)) {
|
||||
return LUTIL_PASSWD_ERR;
|
||||
}
|
||||
|
||||
des_finish( &key, schedule );
|
||||
|
||||
sprintf( PasswordHash, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||
PasswordHash1[0],PasswordHash1[1],PasswordHash1[2],PasswordHash1[3],
|
||||
PasswordHash1[4],PasswordHash1[5],PasswordHash1[6],PasswordHash1[7],
|
||||
PasswordHash2[0],PasswordHash2[1],PasswordHash2[2],PasswordHash2[3],
|
||||
PasswordHash2[4],PasswordHash2[5],PasswordHash2[6],PasswordHash2[7] );
|
||||
|
||||
/* as a precaution convert stored password hash to lower case */
|
||||
strncpy( storedPasswordHash, passwd->bv_val, 32 );
|
||||
storedPasswordHash[32] = '\0';
|
||||
ldap_pvt_str2lower( storedPasswordHash );
|
||||
|
||||
return memcmp( PasswordHash, storedPasswordHash, 32) ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
|
||||
}
|
||||
#endif /* SLAPD_LMHASH */
|
||||
|
||||
#ifdef SLAPD_CRYPT
|
||||
static int lutil_crypt(
|
||||
const char *key,
|
||||
|
|
@ -1129,57 +852,6 @@ static int hash_md5(
|
|||
;
|
||||
}
|
||||
|
||||
#ifdef SLAPD_LMHASH
|
||||
static int hash_lanman(
|
||||
const struct berval *scheme,
|
||||
const struct berval *passwd,
|
||||
struct berval *hash,
|
||||
const char **text )
|
||||
{
|
||||
|
||||
ber_len_t i;
|
||||
char UcasePassword[15];
|
||||
des_key key;
|
||||
des_context schedule;
|
||||
des_data_block StdText = "KGS!@#$%";
|
||||
des_data_block PasswordHash1, PasswordHash2;
|
||||
char PasswordHash[33];
|
||||
|
||||
for( i=0; i<passwd->bv_len; i++) {
|
||||
if(passwd->bv_val[i] == '\0') {
|
||||
return LUTIL_PASSWD_ERR; /* NUL character in password */
|
||||
}
|
||||
}
|
||||
|
||||
if( passwd->bv_val[i] != '\0' ) {
|
||||
return LUTIL_PASSWD_ERR; /* passwd must behave like a string */
|
||||
}
|
||||
|
||||
strncpy( UcasePassword, passwd->bv_val, 14 );
|
||||
UcasePassword[14] = '\0';
|
||||
ldap_pvt_str2upper( UcasePassword );
|
||||
|
||||
lmPasswd_to_key( UcasePassword, &key );
|
||||
DES_set_key_unchecked( &key, schedule );
|
||||
DES_ecb_encrypt( &StdText, &PasswordHash1, schedule , DES_ENCRYPT );
|
||||
|
||||
lmPasswd_to_key( &UcasePassword[7], &key );
|
||||
DES_set_key_unchecked( &key, schedule );
|
||||
DES_ecb_encrypt( &StdText, &PasswordHash2, schedule , DES_ENCRYPT );
|
||||
|
||||
sprintf( PasswordHash, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||
PasswordHash1[0],PasswordHash1[1],PasswordHash1[2],PasswordHash1[3],
|
||||
PasswordHash1[4],PasswordHash1[5],PasswordHash1[6],PasswordHash1[7],
|
||||
PasswordHash2[0],PasswordHash2[1],PasswordHash2[2],PasswordHash2[3],
|
||||
PasswordHash2[4],PasswordHash2[5],PasswordHash2[6],PasswordHash2[7] );
|
||||
|
||||
hash->bv_val = PasswordHash;
|
||||
hash->bv_len = 32;
|
||||
|
||||
return pw_string( scheme, hash );
|
||||
}
|
||||
#endif /* SLAPD_LMHASH */
|
||||
|
||||
#ifdef SLAPD_CRYPT
|
||||
static int hash_crypt(
|
||||
const struct berval *scheme,
|
||||
|
|
|
|||
Loading…
Reference in a new issue