I'm doing a PAM-type thing, and it needs to check a user's password in /etc/shadow.
Usually, this involves reading the password line for the encryption ID, the salt, and the password. Using the ID and salt, the user-provided password can be hashed using crypt(3) or m_crypt (on the same man page), and the result compared. This works fine on many systems, such as Ubuntu, but I'm having major problems on SUSE.
The system is using Blowfish, with the "correct handling of 8-bit chars". This has a hash ID of "2y". Unfortunately, whenever crypt(3) gets called on this, it segfaults. The same goes for ID "2a", which was the first code that identified Blowfish. All other hashing algorithms work.
The system must have a working crypt (or equivalent) that does Blowfish hashing, since the /etc/shadow file has examples of it, but I can't make this work. Can anyone point me in the right direction?
An example of the segfault:
#define _XOPEN_SOURCE
#include <unistd.h>
#include <stdio.h>
int main(int argc, char** argv) {
char *pass = "tqbfjotld";
char *salt = "$2y$10$";
char *pp = NULL;
pp = crypt(pass, salt);
printf("%s\n", pp);
return 0;
}
The salt $2a$10$ also shows the error.
It works on other systems, like Ubuntu, and other hashing algorithms work fine on SUSE.
Any ideas please?
crypt() returning NULL means error, probably invalid salt as 2y is unknown. According to Wikipedia it seems to be a fairly recent addition: https://en.wikipedia.org/wiki/Crypt_%28C%29
"$2y$ - Post-2011 bug discovery, $2y$ may be used to unambiguously use the new, corrected algorithm. On an implementation suffering from the bug, $2y$ simply won't work. On a newer, fixed implementation, it will produce the same result as using $2a$."
Try this to get the error:
glibc-2.19 does not support any of the Blowfish algorithms, I get a NULL pointer on a recent Debian 8.1 as well.
Maybe your SUSE system contains password entries that were migrated over the time and are not even usable any more. Or some other piece of software like a custom PAM module evaluates and checks the password entries using a custom library and not by using the standard libc crypt() function.