self-service-password
self-service-password copied to clipboard
Added TOTP feature
Now there's a new option (disabled by default) to create a new password, based on the TOTP module for openldap, that the user must have installed and configured https://github.com/openldap/openldap/tree/master/contrib/slapd-modules/passwd/totp
To get the new password, the user must reset it by "resetbytoken" in the new menu option, and after click the link, the user will obtain a QR code that must scan with an app (freeOTP, for example) before submit the form.
I haven't seen that there were some tests :-/ I have tested the option I have added and it's working. I have added two needed git submodules (for base32, needed for TOTP module in openldap) and the one to create QRcode.
Indeed, you must set the translation strings in all lang files. Put the english translation string everywhere you are not able to translate.
I will need some time to test this PR. I let also @plewin review the code.
Added the translations. The errors from Codacy tests are from twig section, but not sure how to solve it.
Hi @yuki,
Thank you a lot for the PR. Do not worry about Codacy, it is not well configured.
There is something I do not understand, after you used your changetotp feature, do you have 2 entries of userPassword in your ldap ? I think I misunderstand something, is the code in ssp replacing your password by the totp secret, making it impossible to connect to ldap with a password but only the totp token ?
Hi @plewin
I'll try to answer all your questions.
I choose this base32 library because I see that was very simple, and solved what I need. I didn't want to take a big project that has more functionalities that base32 (for base64 PHP has its own functions).
I copy the file sendtoken.php to create changetotp.php. The basic functionality is the same, but because of the code, I didn't see any function to be reused, so I decided to copy the file and make minor changes. We could delete the file changetotp.php and use sendtoken.php and make inside the changes using an URL variable (similar to the resetbytoken.php).
About "type" variable in resetbytoken.php, you're right. I wasn't sure how to make it in the right way. We could take care about the global variables.
About the menu, I saw that there were 2 highlighted links, not sure why (the sms and mail ones). I wasn't sure if it was a bug, so I added to highlight the TOTP. I can change that.
The TOTP plugin in LDAP (right now is in beta mode) does the magic with the "{TOTP1}base32hash" in the password field. As you can see, I forced to be a clear password, so with a "slapcat" an administrator can see the base32hash of the user. With this base32 in your app (freetotp, for example) it generates the "one time password", so when you try to authenticate against the LDAP, the LDAP plugin does the same algorithm to be sure that the digits you introduce and what the plugin returns are the same.
If a user has 2 different passwords (one based on SSHA and othe in TOTP modes), if the user tries to authenticate, it can use any of both passwords, the TOTP one or the SSHA. I'm not sure if we can force to authenticate against one password and not the other :-/ So, my idea is that my users will have a new user (or the same user, but in other branch of the LDAP tree) with only TOTP password, and my app will only use this branch in the authentication, to be sure that they must use TOTP password.
I have done this modifications because I need them for my users, and because I didn't see nothing to make it. If you're working hard in the new branch for 2.0 to refactor code and so on, we can put this pull-request in "sleep" mode and put it in your new branch in the future. If you need some help, I'll try to help you in the new branch if you want. If you have some ideas of how the project will evolve (in the wiki, for example), please let me know and I'll try to help.
By the way, if you're ok, I'll try to make the modifications this night with your suggestions, and I'll check if there's another base32 library with "composer" mode.
Thanks for this project! :D
I choose this base32 library because I see that was very simple, and solved what I need. I didn't want to take a big project that has more functionalities that base32 (for base64 PHP has its own functions).
Okay, I think we can keep it for now.
I copy the file sendtoken.php to create changetotp.php. The basic functionality is the same, but because of the code, I didn't see any function to be reused, so I decided to copy the file and make minor changes. We could delete the file changetotp.php and use sendtoken.php and make inside the changes using an URL variable (similar to the resetbytoken.php).
I believe keeping the file changetotp.php it is fine so we don't have to change how url -> action -> pages are handled. sendtoken.php yes will need to detect if it was included by changetotp.php and change its url variable.
About "type" variable in resetbytoken.php, you're right. I wasn't sure how to make it in the right way. We could take care about the global variables.
I think it is okay to call die() at the top of resetbytoken.php if available_actions does not contain sendtoken and does not contain also sendsms and type is not present.
About the menu, I saw that there were 2 highlighted links, not sure why (the sms and mail ones). I wasn't sure if it was a bug, so I added to highlight the TOTP. I can change that.
Now that you mention it, yes it is a visual bug I introduced when the templates got extracted and converted to twig. You do not have to handle it. I have a fix in a other branch so it will be solved if it gets merged, if it is not merged, i will port the fix for master.
The TOTP plugin in LDAP (right now is in beta mode) does the magic with the "{TOTP1}base32hash" in the password field. As you can see, I forced to be a clear password, so with a "slapcat" an administrator can see the base32hash of the user. With this base32 in your app (freetotp, for example) it generates the "one time password", so when you try to authenticate against the LDAP, the LDAP plugin does the same algorithm to be sure that the digits you introduce and what the plugin returns are the same.
I understand this but I am suprised that the php ldap code in change_password does not overwrite the normal password. I guess I have to test the topt module myself and make some experiments.
If a user has 2 different passwords (one based on SSHA and othe in TOTP modes), if the user tries to authenticate, it can use any of both passwords, the TOTP one or the SSHA. I'm not sure if we can force to authenticate against one password and not the other :-/
My understanding is that is it not possible to test against one or another with a bind. Applications that want to use totp should add a new textfield in the login page and bind test both password and totp code.
I guess applications should also assert password input != totp code to avoid tricking the system. I hope there is a way to specifically test the TOTP otherwise php applications won't be able to use totp in two steps forms.
So, my idea is that my users will have a new user (or the same user, but in other branch of the LDAP tree) with only TOTP password, and my app will only use this branch in the authentication, to be sure that they must use TOTP password.
This sounds strange to me, "only use this branch in the authentication" " with only TOTP password", so you want a 1FA with totp ? 6 digits pin code is only 10**6 = 1000000 possibilities.
I have done this modifications because I need them for my users, and because I didn't see nothing to make it. If you're working hard in the new branch for 2.0 to refactor code and so on, we can put this pull-request in "sleep" mode and put it in your new branch in the future. If you need some help, I'll try to help you in the new branch if you want. If you have some ideas of how the project will evolve (in the wiki, for example), please let me know and I'll try to help.
Do not worry about the 2.0 proposal. If this PR gets in master i will port it to 2.0 proposal too.
By the way, if you're ok, I'll try to make the modifications this night with your suggestions, and I'll check if there's another base32 library with "composer" mode.
The library is okay do not worry, there is no rush.
I understand this but I am suprised that the php ldap code in change_password does not overwrite the normal password. I guess I have to test the topt module myself and make some experiments.
I don't understand what you mean with this, sorry. The function I used "change_password" is the one of your code. I only force to set "$hash" as "clear" and add the header based of the totp algorithm ("{TOTP256}" if sha256, or "{TOTP512}" if sha512), and it overwrites my previous password (doesn't care if it was SSHA, clear, TOTP, or MD5). Here you have a slapcat of my test user, so maybe you can make an idea:
dn: cn=yuki,ou=groups,dc=example,dc=com
uidNumber: 1000
gidNumber: 1000
cn: rgomez
homeDirectory: /home/yuki
sn: san
uid: yuki
mail: [email protected]
givenName: yuki
objectClass: posixAccount
objectClass: inetOrgPerson
objectClass: top
userPassword: {TOTP1}GE2TKOBYMM4DGZRVG5QWIOBTGMYTCM3CMM4WKMTEGQ4DKMTG
My real user, as "userPassword" has a value like:
userPassword: {CRYPT}$6$X5$SAxgZVXqX..3oolAcPnkHaFddkfqKfOU3...
This sounds strange to me, "only use this branch in the authentication" " with only TOTP password", so you want a 1FA with totp ? 6 digits pin code is only 10**6 = 1000000 possibilities.
My web-app is only accesible via VPN at this moment. The idea is that the users doesn't have the "password remember" of the web browser, because we see as a security breach inside the office and outside. Right now we prefer a 6 digits password (random and only usable for 30 seconds) than a very long difficult password but the the browser has saved. BTW, the TOTP module for LDAP, allows 8 or 10 digits passwords, but it must change the code before compilation. I compiled the TOTP module against Debian's OpenLDAP's code. I have a "how I did" the compilation, so if you need to make your test ask for it and I'll translate into english and put somewhere.
As I mentioned, I'll try to make the changes of your suggestions tonight.
Is this still relevant or should you close it @coudot?