Hi to all,
I'm still testing TOPT with OpenLDAP 2.5. I got TOTP1 running. So a user
with an OTP can use the six-digit number from googleauthenticator (or
freeOTP+) to authenticate while using ldapsearch. Then I switch to
TOTP1ANDPW I generate a secretkey for the TOTP-part of userPassword.
Then I create a password with "slappasswd" and put both TOTP1|password
together in userPassword after decoding base64 I saw what I expected:
------------
dn: cn=u1,ou=users,dc=example,dc=net
objectClass: posixAccount
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: autoCAuser
loginShell: /bin/bash
homeDirectory: /home/u1
uid: u1
uidNumber: 10010
gidNumber: 10000
sn: u
givenName: 1
cn: u1
userPassword::
e1RPVFAxQU5EUFd9TUpBVk1UM0tNUlVXSVNDUEtKWEhJWVNaR1kzRE80Q0x8e1N
TSEF9RWlCcVIwUGR4SUluMSswZTNqRSs1MXlwb1p6dTFKVUc=
------------------
echo
"e1RPVFAxQU5EUFd9TUpBVk1UM0tNUlVXSVNDUEtKWEhJWVNaR1kzRE80Q0x8e1NTSEF9RWlCcVIwUGR4SUluMSswZTNqRSs1MXlwb1p6dTFKVUc="
| base64 -d
{TOTP1ANDPW}MJAVMT3KMRUWISCPKJXHIYSZGY3DO4CL|{SSHA}EiBqR0PdxIIn1+0e3jE+51ypoZzu1JUG
I then try to authenticate using ldapsearch with:
123456secret
where 123456 is the six-digit key from googleauthenticator and "secret"
is the password. But I always got an error 49 :-(
I read this to set up the password:
https://git.openldap.org/ondra/openldap/-/tree/dfe1f6494d69a885477e854944...
Any hint? Anyone who got this running?
I wrote a little bash-script to generate the shared-key, the password
and write it into the users object:
THIS SCRIPT IS FOR TESTING PURPOSE ONLY!
-----------------------------
#!/bin/bash
##########################################
# This script requires an OpenLDAP 2.5.x #
# with the overlay pw-totp and autoca #
# active and configured! #
##########################################
# This script generats a TOTP1ANDPW password for a user
# the script needs the full DN of the user
# and an email address for the user.
# The script will NOT check if the email address is valide
# Ther will be a random string generated for the user
# the user do not need the string. The string is only
# to generate the sharedkey for the user.
# At the end you will see the sharedkey, the user can enter
# in an authenticator app like googleauthentiicator or freeOTP
# and a png-file will be created with the QR-code for the sharedkey
#
# The script can be used via network or local only via the ldapi-socket
if [ $# -ne 2 ]
then
echo "User-DN and User-Mail is needed"
echo "usage: $0 userdn user@mail"
exit 1
fi
USER_DN=$1
USER_MAIL=$2
LDAP_SERVER=ldap://ldap25-p01.example.net
USE_LDAPI=1 # set to "0" if userlogin is prefered
USE_TLS=1 # if TLS should not be used set to "0"
#LDAP_ADMIN="uid=ldap-admin,ou=users,dc=example,dc=net"
LDAP_ADMIN="cn=admin,dc=example,dc=net"
LDAP_ADMIN_PW="secret"
TOPT_ISSUER=stka
USER_PW_TOTP_BASE64=""
USER_NAME=""
USER_SHARED_KEY=""
QR_TEXT=""
USER_PASSWORD=""
# Setting the varaible to use TLS if selected
if [ "$USE_TLS" -eq 1 ]
then
ACTIVATE_TLS="-ZZ"
else
ACTIVATE_TLS=""
fi
if [ ! -f "/usr/bin/qrencode" ]
then
echo "qrencode is not installed!"
exit 2
fi
#First part of DN is USER_MANE
USER_NAME=$(echo "$USER_DN" | cut -d "," -f 1)
# Let's get shure that there is exactly one user present in database
if [ $USE_LDAPI -eq 1 ]
then
USER_DN_IN_DB=$(ldapsearch -Q -Y EXTERNAL -LLL -H ldapi:///
$USER_NAME dn 2>/dev/null | cut -d " " -f 2)
else
USER_DN_IN_DB=$(ldapsearch -xLLL "$ACTIVATE_TLS" -D
"$LDAP_ADMIN" -w "$LDAP_ADMIN_PW" -H "$LDAP_SERVER"
"$USER_NAME" dn
2>/dev/null | cut -d " " -f 2)
fi
if [ "${USER_DN,,}" != "${USER_DN_IN_DB,,}" ]
then
echo "User $USER_DN not found in database"
exit 3
fi
#Create random 20 byte string: 160 bit is recommended (min 128 bit)
USER_PW=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 20 ; echo '')
#Create the password for 2fa
USER_PASSWORD=$(slappasswd)
#Set user password
if [ $USE_LDAPI -eq 1 ]
then
ldappasswd -Q -Y EXTERNAL -H ldapi:/// -s
"${USER_PW}|${USER_PASSWORD}" "$USER_DN"
else
ldappasswd -x "$ACTIVATE_TLS" -D "$LDAP_ADMIN" -w
"$LDAP_ADMIN_PW" -s "${USER_PW}|${USER_PASSWORD}"
"$USER_DN"
fi
#Read user password from LDAP in TOTP1-format
if [ $USE_LDAPI -eq 1 ]
then
PW_STEP_1=$(ldapsearch -Q -Y EXTERNAL -LLL -H ldapi:///
"$USER_NAME" userpassword | grep -A1 userPassword)
USER_PW_TOTP_BASE64=$(echo $PW_STEP_1 | awk '{print $2 $3}')
else
USER_PW_TOTP_BASE64=$(ldapsearch -x "$ACTIVATE_TLS" -D
"$LDAP_ADMIN" -w "$LDAP_ADMIN_PW" -LLL -H "$LDAP_SERVER"
"$USER_NAME"
userpassword | grep userPassword | cut -d " " -f 2 | cut -d '|' -f 1)
fi
#Create user shared key
USER_SHARED_KEY=$(echo $USER_PW_TOTP_BASE64 | base64 -d)
#cut the password hash type from shared key
USER_SHARED_KEY=$(echo $USER_SHARED_KEY | cut -d "|" -f 1 | cut -d "}"
-f 2)
#Create the QR-text for the user
QR_TEXT="otpauth://totp/$LDAP_SERVER:$USER_MAIL?secret=${USER_SHARED_KEY}a&issuer=${TOTP_ISSUER}&period=30&digits=6&algorithm=SHA1"
#Generate the QR-code
echo $QR_TEXT | qrencode -s9 -o ${USER_MAIL}.png
echo "Shared key for User $USER_DN is $USER_SHARED_KEY"
echo "You find the QR-code in file ${USER_MAIL}.png"
-----------------------------