/389-directory-bcrypt

bcrypt support for 389 directory LDAP server with configurable work factor

Primary LanguageCThe UnlicenseUnlicense

*WARNING: This plugin is in very early stages of development. It works for us, but might not be robust enough for your purposes. Please test it thoroughly before using it in production environments.*

bcrypt 389 DS support
----------------------
pw-bcrypt.c provides support for bcrypt password hashes in 389 Directory server.

The original repository (for OpenLDAP) is [sistason/openldap-sha256-bcrypt], I just rewrite it as 389 DS plugin.

About bcrypt
------------
Bcrypt is a modern password hashing method, based on the Blowfish block cipher.
It is designed by Niels Provos and David Mazieres, and is used in OpenBSD.

From Wikipedia:
Besides incorporating a salt to protect against rainbow table attacks, bcrypt is
an adaptive function: over time, the iteration count can be increased to make it
slower, so it remains resistant to brute-force search attacks even with
increasing computation power. (See 'Choosing a work factor' below.)

A bcrypt hash in OpenLDAP looks like this:

{BCRYPT}$2b$08$eSLWg21V/YvYvHYoWXFaKutal4LcolDv6.K/zgGmPJhDdytkb4yOe

- {BCRYPT} is the name of the scheme
- $2b$ means it will always use the 'safe', modern version of the algorithm, as
  discussed in http://www.openwall.com/lists/announce/2011/07/17/1
  The original safe version had the $2y$ prefix. OpenBSD 5.5+ has a different
  prefix for the same thing, which is $2b$ so we prefer that.
  See also http://www.openwall.com/lists/announce/2014/08/31/1
- 08 is the work factor (this is the default)
- Next is 16 bytes of random salt
- The rest is the actual hash

The work factor defines the number of rounds, and is a base 2 logarithm. So going
from work factor 8 to 9 means the hash takes twice as much time to generate
(and crack).

Building
--------
I do not test this plugin to work with 389DS from RPMs package, only from custom source build.

I forked (https://pagure.io/forks/rangerx/389-ds-base) 389 DS original repo (https://pagure.io/389-ds-base) and integrate this plugin to some branches (master and 389-ds-base-1.3.9).

1) So, you could try to build your own 389 DS with Bcrypt support like this:

# clone fork
$ git clone -b 389-ds-base-1.3.9 --recurse-submodules --single-branch -- https://pagure.io/forks/rangerx/389-ds-base.git 389-ds-base
$ cd 389-ds-base/

# install some dependencies in CentOS 7
$ sudo yum install -y make epel-release @buildsys-build python3-argparse-manpage python3-argcomplete python3-ldap rpm-build redhat-rpm-config python3-devel cracklib-devel
$ sudo yum install -y --skip-broken `grep -E "^(Build)?Requires" ./rpm/389-ds-base.spec.in | grep -v -E '(name|MODULE)' | awk '{ print $2 }' | grep -v "^/" | grep -v pkgversion | sort | uniq|  tr '\n' ' '`

# or Ubuntu/Debian (not tested)
$ sudo apt-get install -y libcrack2-dev libpam0g-dev libevent-dev libnspr4-dev libnss3-dev libldap2-dev libdb-dev libsasl2-dev libsnmp-dev libkrb5-dev libcmocka-dev

# now configure and build
$ autoreconf -fiv
$ ./configure --enable-debug --with-openldap [other options you want]
$ make && make lib389 && make check && make install

2) Run 389 DS. Something like:
/usr/sbin/ns-slapd -D /etc/dirsrv/slapd-dir

3) Enable bcrypt plugin:
ldapadd -x -D 'cn=Directory Manager' -f ldap/servers/plugins/389-directory-bcrypt/bcrypt-conf.ldif -W

Make sure that all LDAP servers in your environment have the module
loaded before you do this, otherwise your users will not be able to authenticate.

Testing
-------

Use pwdhash to generate some hashes.

$ pwdhash -D /opt/dirsrv/etc/dirsrv/slapd-dir -s BCRYPT 12345
{BCRYPT}$2b$10$aSftQ1DXbBHwPCHObVLHOeOqdstI2Q5IjR.crFb8Srx4epuIRTIuK

Or compare passwords:
$ pwdhash -D /opt/dirsrv/etc/dirsrv/slapd-dir -c '{BCRYPT}$2a$10$/EvaHg4kmzMn2tTk5Ao48.4FLeZqiRMvKXB8V8GyNzKaLksUnDAf.' 12345
pwdhash: password ok.

Debugging
---------
To see what's going on, recompile with SLAPD_BCRYPT_DEBUG, and then run slapd from the console:

ns-slapd -D /etc/dirsrv/slapd-dir -d 65536

WARNING: With debugging enabled, all passwords will be logged in plaintext!

ACKNOWLEDGEMENT:
This work is based on crypt_blowfish version 1.3 developed by Solar Designer,
which is available at http://www.openwall.com/crypt/.