Abstract
There have been recently quite a few publications on One-Time Password Authentication. This discussion is on TOTP authentication in OpenLDAP using a mobile smart device to generate a 6 digits token.
There have been recently quite a few publications on One-Time Pasword Authentication. It seems, it is an emerging topic. Michael Schwartzkopff has written a blog entry on MOTP, I myself have written on OTP, now I will discuss TOTP as authentication method for OpenLDAP, using an application on a smart mobile device, to generate a 6 digit token.
Note
I am not arguing on security issues of smart mobile devices!
The slapd module to enable OpenLDAP to manage TOTP can be found in the directory
contrib/slapd-modules/passwd/totp
of OpenLDAP's HEAD git repository and in forthcoming OpenLDAP-2.5 release. In order to compile and install this module, visit the directory, read carefully README file, which still contains some errors. Edit Makefile to your requirements and run:
make && make install
Next, some configuration has to be done, for this I will use old slapd.conf style.
moduleload pw-totp.la
security ssf=1
password-hash {TOTP1}
...
database mdb
...
overlay totp
Managing Passwords
There are some requirements for secrets,
- the minimum size has to be 128 bit, it is recommended to extend this to 160 bit,
- a seed, if applicable, has to have 20 bit.
Note
There are many ways to generate secrets, the following is just a proof of concept.
I created a string in random order 12456ABCD789ab which will be encoded into a base64 string.
echo "12456ABCD789ab" | base64
MTI0NTZBQkNENzg5YWIK
Now we have a nice 20 byte string, which is our secret. As there is a password hashing scheme defined in slapd.conf {TOTP1}, the attribute userPassword may now be modified by means of LDAP Password Modify Extended Operation.
ldappasswd -D cn=admin,o=example -W \
-s 'MTI0NTZBQkNENzg5YWIK' -H ldap://localhost \
"cn=test1 Example,ou=users,o=test"
This secret string will be internally converted into a base32 string, while the output of ldapsearch or slapcat will be additionally base64 encoded.
Creating a Base32 String
As we intend to use an application on a mobile device, the secret has to be encoded into a base32 string. Unfortunately the Linux core utils don't provide a tool to generate base32 code. I therefore have created a simple Perl script:
#!/usr/bin/env perl
# $Id: convert-base32.pl,v 1.3 2015/11/09 11:21:14 dieter Exp dieter $
use MIME::Base32 qw(RFC);
my $string;
my $encoded;
undef $\;
$string = <STDIN>;
$encoded = MIME::Base32::encode($string);
print "$encoded\n";
exit(0);
There are 2 Perl modules providing base32 encoding, Convert::Base32 and MIME::Base32, the latter provides uppercase characters, due to RFC-3548 compliance.
echo "MTI0NTZBQkNENzg5YWIK" | ./convert-base32.pl
JVKESMCOKRNEEULLJZCU46THGVMVOSKL
Note
There are quite a few online sites, which provide base32 encoding.
A masochist may now enter this string into a smart device application. I have tested the Android applications:
- Google Authenticator
- Sophos Authenticator
- FreeOTP
all in conjunction with QR Droid.
As most of us are not masochistic, a QR-Code would come handy. So here it is:
Creating QR-Code
In order to create a proper QR-Code, a TOTP secret should be supplied as URL type:
- otpauth://TYPE/LABEL?PARAMETERS
- types can be TOTP and HOTP
- label could be accountname, issuer
- parameters are secret, issuer, algorithm, digits, period (counter for HOTP)
otpauth://totp/testldap:test1@example.com?secret=JVKESMCOKRNEEULLJZCU46THGVMVOSKL&\
issuer=mycompany&period=30&digits=6&algorithm=SHA1
This string should be written on a single line into a file, in this example the file is called QR-ldap.txt.
To create and read QR-Code I rely on the tools qrencode(1) and xv(1). The option -s9 indicates a pixel number of 9, while default is -s3, -o indicates an output file, the manual page provides more options, but I am happy with default settings.
qrencode -s9 -o ldaptest2.png < QR-ldap.txt
xv ldaptest2.png
And this is the result and can be scanned with an authenticator application.

Authentication with OpenLDAP
This is just a short excerpt on interaction of ldap client and ldap server:
ldapwhoami -D "cn=test1 example,ou=user,o=test" -W -H ldap://localhost:9007
Enter LDAP Password: (6 digits from an authenticator)
cn=test1 example,ou=user,o=test
These are the interesting lines on the server side
...
mdb_modify: cn=test1 example,ou=user,o=test
mdb_modify_internal: delete authTimestamp
mdb_modify_internal: replace authTimestamp
send_ldap_result: err=0 matched="" text=""
...
The authTimestamp operational attribute indicates the last successful authentication. More info on this topic can be found in slapd-totp.c.