diff --git a/CHANGES b/CHANGES index dc387d7c065fbe833aa7b65683e9610baa86b7f9..ab09f147bb5c6dd34af63f489ce06181fda71b8b 100644 --- a/CHANGES +++ b/CHANGES @@ -19,7 +19,8 @@ OpenLDAP 2.4.22 Engineering Fixed slapo-rwm olcRwmMap handling (ITS#6436) Fixed slapo-rwm REP_ENTRY flag handling (ITS#5340,ITS#6423) Fixed slapo-syncprov memory leak (ITS#6459) - Fixed slapo-valsort REP_ENTRY flag handling (ITS#5340,ITS#6423) + Fixed slapo-valsort REP_ENTRY flag handling (ITS#5340,ITS#6423) + Fixed contrib/sha2 adds mechs for more hashes (ITS#6433) Documentation admin24 avoid explicity moduleload statements (ITS#6486) diff --git a/contrib/slapd-modules/passwd/sha2/README b/contrib/slapd-modules/passwd/sha2/README index 7d1ef3cca0b040268b689ac6da9ead4ddef9ad59..d6eebfb4baf13569c389456d53f878f95fd4673d 100644 --- a/contrib/slapd-modules/passwd/sha2/README +++ b/contrib/slapd-modules/passwd/sha2/README @@ -37,7 +37,18 @@ moduleload ...path/to/slapd-sha2.so 5) Restart slapd. -The {SHA512} scheme should now be recognised. + +Configuring +----------- + +The {SHA256}, {SHA384} and {SHA512} password schemes should now be recognised. + +You can also tell OpenLDAP to use one of these new schemes when processing LDAP +Password Modify Extended Operations, thanks to the password-hash option in +slapd.conf. For example: + +password-hash {SHA256} + Testing ------- diff --git a/contrib/slapd-modules/passwd/sha2/slapd-sha2.c b/contrib/slapd-modules/passwd/sha2/slapd-sha2.c index b06a301b29d9725a821ba274a7dff8d6b82c74a8..4d49b3c7181d3c374a6650f2568010b26aa90fd1 100644 --- a/contrib/slapd-modules/passwd/sha2/slapd-sha2.c +++ b/contrib/slapd-modules/passwd/sha2/slapd-sha2.c @@ -15,6 +15,8 @@ /* ACKNOWLEDGEMENT: * This work was initially developed by Jeff Turner for inclusion * in OpenLDAP Software. + * + * Hash methods for passwords generation added by Cédric Delfosse. */ #include <lber.h> @@ -30,6 +32,63 @@ #include <stdio.h> #endif +/* pw_string64 function taken from libraries/liblutil/passwd.c */ +static int pw_string64( + const struct berval *sc, + const struct berval *hash, + struct berval *b64, + const struct berval *salt ) +{ + int rc; + struct berval string; + size_t b64len; + + if( salt ) { + /* need to base64 combined string */ + string.bv_len = hash->bv_len + salt->bv_len; + string.bv_val = ber_memalloc( string.bv_len + 1 ); + + if( string.bv_val == NULL ) { + return LUTIL_PASSWD_ERR; + } + + AC_MEMCPY( string.bv_val, hash->bv_val, + hash->bv_len ); + AC_MEMCPY( &string.bv_val[hash->bv_len], salt->bv_val, + salt->bv_len ); + string.bv_val[string.bv_len] = '\0'; + + } else { + string = *hash; + } + + b64len = LUTIL_BASE64_ENCODE_LEN( string.bv_len ) + 1; + b64->bv_len = b64len + sc->bv_len; + b64->bv_val = ber_memalloc( b64->bv_len + 1 ); + + if( b64->bv_val == NULL ) { + if( salt ) ber_memfree( string.bv_val ); + return LUTIL_PASSWD_ERR; + } + + AC_MEMCPY(b64->bv_val, sc->bv_val, sc->bv_len); + + rc = lutil_b64_ntop( + (unsigned char *) string.bv_val, string.bv_len, + &b64->bv_val[sc->bv_len], b64len ); + + if( salt ) ber_memfree( string.bv_val ); + + if( rc < 0 ) { + return LUTIL_PASSWD_ERR; + } + + /* recompute length */ + b64->bv_len = sc->bv_len + rc; + assert( strlen(b64->bv_val) == b64->bv_len ); + return LUTIL_PASSWD_OK; +} + char * sha256_hex_hash(const char * passwd) { SHA256_CTX ct; @@ -94,6 +153,69 @@ char * sha512_hex_hash(const char * passwd) { return real_hash; } +static int hash_sha256( + const struct berval *scheme, + const struct berval *passwd, + struct berval *hash, + const char **text ) +{ + SHA256_CTX ct; + unsigned char hash256[SHA256_DIGEST_LENGTH]; + + SHA256_Init(&ct); + SHA256_Update(&ct, (const uint8_t*)passwd->bv_val, passwd->bv_len); + SHA256_Final(hash256, &ct); + + struct berval digest; + digest.bv_val = (char *) hash256; + digest.bv_len = sizeof(hash256); + + return pw_string64(scheme, &digest, hash, NULL); +} + +static int hash_sha384( + const struct berval *scheme, + const struct berval *passwd, + struct berval *hash, + const char **text ) +{ + SHA384_CTX ct; + unsigned char hash384[SHA384_DIGEST_LENGTH]; + +#ifdef SLAPD_SHA2_DEBUG + fprintf(stderr, "hashing password\n"); +#endif + SHA384_Init(&ct); + SHA384_Update(&ct, (const uint8_t*)passwd->bv_val, passwd->bv_len); + SHA384_Final(hash384, &ct); + + struct berval digest; + digest.bv_val = (char *) hash384; + digest.bv_len = sizeof(hash384); + + return pw_string64(scheme, &digest, hash, NULL); +} + +static int hash_sha512( + const struct berval *scheme, + const struct berval *passwd, + struct berval *hash, + const char **text ) +{ + SHA512_CTX ct; + unsigned char hash512[SHA512_DIGEST_LENGTH]; + + SHA512_Init(&ct); + SHA512_Update(&ct, (const uint8_t*)passwd->bv_val, passwd->bv_len); + SHA512_Final(hash512, &ct); + + struct berval digest; + digest.bv_val = (char *) hash512; + digest.bv_len = sizeof(hash512); + + return pw_string64(scheme, &digest, hash, NULL); +} + static int chk_sha256( const struct berval *scheme, // Scheme of hashed reference password const struct berval *passwd, // Hashed reference password to check against @@ -150,10 +272,10 @@ const struct berval sha512scheme = BER_BVC("{SHA512}"); int init_module(int argc, char *argv[]) { int result = 0; - result = lutil_passwd_add( (struct berval *)&sha256scheme, chk_sha256, NULL ); + result = lutil_passwd_add( (struct berval *)&sha256scheme, chk_sha256, hash_sha256 ); if (result != 0) return result; - result = lutil_passwd_add( (struct berval *)&sha384scheme, chk_sha384, NULL ); + result = lutil_passwd_add( (struct berval *)&sha384scheme, chk_sha384, hash_sha384 ); if (result != 0) return result; - result = lutil_passwd_add( (struct berval *)&sha512scheme, chk_sha512, NULL ); + result = lutil_passwd_add( (struct berval *)&sha512scheme, chk_sha512, hash_sha512 ); return result; }