1

I am using pure-ftpd with mysql to auth users.

Here is my mysql.conf

MYSQLServer localhost MYSQLPort 3306 MYSQLSocket /var/run/mysqld/mysqld.sock MYSQLUser user MYSQLPassword pwd MYSQLDatabase my_db MYSQLCrypt crypt() MYSQLGetPW SELECT password FROM ftp_users WHERE login="\L" MYSQLGetUID SELECT u_id FROM ftp_users WHERE login="\L" MYSQLGetGID SELECT g_id FROM ftp_users WHERE login="\L" MYSQLGetDir SELECT dir FROM ftp_users WHERE login="\L" MySQLGetQTAFS SELECT quota_files FROM ftp_users WHERE login="\L" MySQLGetQTASZ SELECT quota_size FROM ftp_users WHERE login="\L" MySQLGetRatioUL SELECT ul_ratio FROM ftp_users WHERE login="\L" MySQLGetRatioDL SELECT dl_ratio FROM ftp_users WHERE login="\L" MySQLGetBandwidthUL SELECT ul_bandwidth FROM ftp_users WHERE login="\L" MySQLGetBandwidthDL SELECT dl_bandwidth FROM ftp_users WHERE login="\L" 

I then have tried restarting pure-ftpd-mysql and pure-ftpd

My table has a field with the pwd as

password varchar(255) 

When I insert a user with a plaintext pwd, I can login fine with both login and password. When I insert a hash with 'lol' such as SHA512 or a BCrypt hash. It doesn't allow me to login with the pwd 'lol'.

BCrypt $2a$06$JrvxpMAvi6MnRSIvZQMMxOffIDLtEP7lrKNe0k0CTsK51v4zujfpS SHA512 3DD28C5A23F780659D83DD99981E2DCB82BD4C4BDC8D97A7DA50AE84C7A7229A6DC0AE8AE4748640A4CC07CCC2D55DBDC023A99B3EF72BC6CE49E30B84253DAE 

However, if I paste in the hash, it successfully logs in as I assume it takes it as a plaintext value.

I have tried changing the mysql.conf to

MYSQLCrypt crypt 

But this breaks it completely. There are many sites which say to use crypt, but the comments in my configuration file list crypt() as one of the options.

I have read through many posts and forums but the closest thing I found was this, which doesn't work at all.

https://serverfault.com/a/630806/302696

Here is what pure-ftpd starts with

Starting ftp server: Running: /usr/sbin/pure-ftpd-mysql -l mysql:/etc/pure-ftpd/db/mysql.conf -l puredb:/etc/pure-ftpd/pureftpd.pdb -l puredb:/etc/pure-ftpd/pureftpd.pdb -E -F /etc/pure-ftpd/fortunes.txt -j -H -J ALL:!aNULL:!SSLv3 -u 1000 -8 UTF-8 -A -O clf:/var/log/pure-ftpd/transfer.log -B 

So basically it is not using crypt or I am not using it correctly. I though it could handle SHA512 natively with mysql but it doesn't. Other things I can think of is that I need code with the configuration but I can't see why it would require anything.

1 Answer 1

5
+100

--- BEGIN tl;dr ---

Assuming your Pure-FTPd is running on a Linux host with glibc 2.7+:

  • Use MySQLCrypt cryptwithout parentheses
  • Run this Python 3 one-liner on the same system where Pure-FTPd runs:

    python3 -c 'import sys, crypt, getpass; print(crypt.crypt(getpass.getpass("Password: "), crypt.METHOD_SHA512))' 
  • Enter the desired password.

  • Copy and paste the crypt-ed password (starting with $6$) into the database.

--- END tl;dr ---

The idea behind non-plaintext MySQLCrypt is to disable plaintext passwords altogether. The parenthesized MySQLCrypt crypt() still accepting the hash as a plaintext password suggests that Pure-FTPd treated the string crypt() as an unknown crypt method and ignored the directive altogether, using the default crypt method of plaintext instead. The un-parenthesized MySQLCrypt crypt “breaking” plaintext logins is actually a step in the right direction: It disabled plaintext login and started treating passwords in the database as crypt-ed only.

Now, the question is how to properly hash a password into an acceptable form. According to src/mysql.c of Pure-FTPd, MySQLCrypt crypt would cause it to use the crypt() function, whose acceptable forms depend on the implementation. For example, if you are running Pure-FTPd on a Linux machine with glibc 2.7 or higher, there are 4 forms accepted:

  • SHA-512 (starts with $6$)
  • SHA-256 (starts with $5$)
  • MD5 (starts with $1$)
  • Traditional DES (starts with an alphanumeric letter); should probably be avoided though

There are a few ways of invoking the system crypt(); my preferred method is Python 3's built-in crypt module. This short script would do our bidding:

import sys from crypt import crypt, METHOD_SHA512 from getpass import getpass print(crypt(getpass("Password: "), METHOD_SHA512)) 

Or if you prefer a triple-clickable, copy-and-paste-friendly one-liner:

python3 -c 'import sys, crypt, getpass; print(crypt.crypt(getpass.getpass("Password: "), crypt.METHOD_SHA512))' 

A sample run:

root@ip-172-16-16-117:~# python3 -c 'import sys, crypt, getpass; print(crypt.crypt(getpass.getpass("Password: "), crypt.METHOD_SHA512))' Password: $6$vTbR62VMHKQNqnEk$TmfeMj/Q6G62RM.hi7liD0IrEvtUp2.jgXbfVRPone/sFTeOwJKftTrrW9j8Hd8.kJsF36OKwP4xHrnURGZTo/ 

It is imperative that this command be run on the same host where Pure-FTPd runs, in order to use the same crypt() implementation.

The long line that starts with $6$ is the crypt-ed password. The $6$ prefix itself marks the password as hashed using SHA-512. If the system crypt() does not support SHA-512, the output will not start $6$; in this case, another algorithm should be used. For example, on macOS, a possible output is $6UCLzI8sPv16. Note that it is excessively short and also lacks the dollar sign after $6: This is because the macOS implementation of crypt() does not support SHA-512.

2
  • By the way, the SHA512 3DD28C5A23F780659D83DD99981E2DCB82BD4C4BDC8D97A7DA50AE84C7A7229A6DC0AE8AE4748640A4CC07CCC2D55DBDC023A99B3EF72BC6CE49E30B84253DAE hash you posted is the unsalted hash of the password string (lol). Pure-FTPd supports only two unsalted password hashes: SHA-1 (MySQLCrypt sha1) and MD5 (MySQLCrypt md5), and even those two are deprecated. Unsalted SHA-512 is unsupported, and will likely be never implemented. Commented Mar 20, 2017 at 20:55
  • Thank-you for explaining this step by step, I was seriously at loss with why it wasn't accepting the hashes I was giving it. I generated a pwd using your python script and it worked like a charm. As for moving forward, this information is really handy for future projects that deal with encryption, many thanks! Commented Mar 20, 2017 at 21:46

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.