Mysql – Pure FTPd and MySQL, working with sha512

encryptionftpMySQLpasswordpureftpd

I'm currently developing an application for shared hosting, using a complete MySQL backend for the machine. I've set up all my services, and they're quite operational, however I've a little problem with pure-ftpd.

As you may know, Pure-FTPd can work with MySQL thanks to pure-ftpd-mysql. Here's what the basic configuration looks like :

MYSQLServer             127.0.0.1
MYSQLPort               3306
MYSQLSocket             /var/run/mysqld/mysqld.sock
MYSQLUser               myftpdbuser
MYSQLPassword           myftpdbpassword
MYSQLDatabase           myftpdb
MYSQLCrypt              md5
# Here come the selection queries...

As you can see, I've chosen md5 as the encryption algorithm, but that's a problem. I'm using Symfony2, and I've set the encoder to sha512 for my users, and when I want to create an FTP account with the same password as one of my users, I have to copy the sha512 hash to the FTP account.

That's quite satisfying however, Pure-FTPd is configured for md5, therefore, it won't be able to check this password. I'd like to keep sha512 as much as possible, given that using md5 will require some modifications of my code for re-encryption.

Here's what the Pure-FTPd configuration sample says :

# Mandatory : how passwords are stored
# Valid values are : "cleartext", "crypt", "sha1", "md5" and "password"
# ("password" = MySQL password() function)
# You can also use "any" to try "crypt", "sha1", "md5" *and* "password"

So here's my question : is there any chance I could set Pure-FTPd to work with sha512, using "crypt" for instance ? Perhaps I could use crypt and configure it to use sha512 somewhere else, I don't know…

EDIT

I've tried working with the queries but I couldn't find any trick. Here's the password query :

MYSQLGetPW              SELECT password FROM ftp_accounts WHERE username='\L'

Solutions

After a few searches, and with the answer I got, I deduced 3 solutions :

  • Develop a Pure-FTPd authentication module design to perform the MySQL query, and handle the password encryption mechanism. This implies porting the PHP algorithm to C (or other language), which I did using the OpenSSL library. Initiate a SHA512_CTX structure and get your first digest. Iterate 500 times with the right parameters, and perform a base 64 encoding. You can also use the hexadecimal result, according to your Symfony settings.
  • Set crypt(3) to work with salted SHA512 hashes under PureFTPd. Tricky thing, when you start talking about 500 iterations.
  • Develop a Symfony2 command which performs the authentication for you. Easy as hell, works like a charm. Create an executable script (let's say /usr/bin/pureftpd-auth which simply calls /path/to/php /path/to/app/console your:ftp:auth:command. chmod it, give it a proper interpreter (#!/bin/bash, …) and start pure_authd and pureftpd on a shared socket to make them communicate. See http://download.pureftpd.org/pure-ftpd/doc/README.Authentication-Modules for more information.

Best Answer

glibc 2.7 and higher do support sha512, but only in a salted way. If you do have salted SHA512-hashes, using "crypt" should instantly work.

If you do have unsalted sha512-hashes: please do avoid them - seriously. There are pre-calculated databases available, so looking up the hash from those databases will give you instantly either the cleartext-password or at least something which will work for a successful login. Calculating hashes using current GPUs is extremely fast as well, so about any unsalted way needs to be avoided.

For example, https://www.crackstation.net/ gives you both a nice webinterface for looking up both millions of unsalted passwords from their hash and some education regarding "salted vs. unsaltes hashes", choosing correct (randomized) salts and "good" hash algorithms.

As a real-life-example, millions of unhashed password-hashes from linkedin and lastfm did leak onto the internet and it did take only a few days to find matching cleartext-passwords for most of them using pre-calculated hash databases or rainbow tables. Using salted hashes, it's more likely to take months or years to find some cleartext-data matching your hashes.

If you do understand the risks of unsalted hashes and still absolutely do need to implement unsalted sha512 via MySQL, you can do so by supplying a custom skript to pure-authd (it's fairly trivial doing so). See http://download.pureftpd.org/pure-ftpd/doc/README.Authentication-Modules for more information on this.