Pure-ftpd and Postgreql Auth with password salt Pure-ftpd and Postgreql Auth with password salt postgresql postgresql

Pure-ftpd and Postgreql Auth with password salt


I had the very same problem. However, writing my own custom authentication module would've been an overkill since the available pgsql auth does nearly everything I want..Here's what changes I made for it to suit my needs:

In log_pgsql_p.h add static char *salting; and static char *sqlreq_getsalt; and extend the static ConfigKeywords pgsql_config_keywords[] with { "PGSQLSalting", &salting }, and { "PGSQLGetSalt", &sqlreq_getsalt },.

In log_pgsql.h I added #define SALT_SQL_APPEND "append", #define SALT_SQL_PREPEND "prepend" and #define SALT_SQL_NONE "none".

In log_pgsql.c I then made the following changes in the pw_psql_check function:

I declared const char *salt = NULL; and char * salted_password = NULL; at the top.Directly before spwd gets assigned the result of the query to sqlreq_getpw I added

if (strcasecmp(salting, SALT_SQL_NONE) != 0) {    salt = pw_pgsql_getquery(id_sql_server, sqlreq_getsalt,                             escaped_account, escaped_ip,                             escaped_port, escaped_peer_ip,                             escaped_decimal_ip);}

Then, before the encryption takes place:

if (salt != NULL) {    int salted_pw_size = strlen(salt) + strlen(password) + 1;    salted_password = (char *) malloc(salted_pw_size);    if (strcasecmp(salting, SALT_SQL_APPEND) == 0) {        strcpy(salted_password, password);        strcat(salted_password, salt);                } else if (strcasecmp(salting, SALT_SQL_PREPEND) == 0) {        strcpy(salted_password, salt);        strcat(salted_password, password);    }} else {    salted_password = (char *) malloc(strlen(password));    strcpy(salted_password, password);}

And then I replaced the password argument in subsequent calls to the crypt-methods (crypt, crypto_hash_md5, crypto_hash_sha1) and the strcasecmp for 'cleartext' with (const char*)salted_password.

Now all that's left to do is tidying up the memory we allocated. Especially the plaintext-password with appended/prepended salt shouldn't remain in memory - call it paranoia if you want. So after the bye: label add

free((void *) salt;if(strcasecmp(salting, SALT_SQL_NONE) != 0) {    volatile char *salted_password_ = (volatile char *) salted_password;    while(*salted_password_ != 0) {        *salted_password_++ = 0;    }    free((void *) salted_password);}

With these changes you now have two additional parameters in your config file available:

  • PGSQLSalting: Accepts 'append' (appends the salt to the pw), 'prepend' and 'none' (without the apostrophe)
  • PGSQLGetSalt: Here you specify the field in your db to fetch the salt from, much like with the crypted password you need to retrieve via PGSQLGetPw.

Edit: Oh, and don't forget to free the allocated memory at the end of the function!

I also can provide a diff file that works for the release 1.0.36.. here you go! Beware though, i added the if around the freeing of salted_password later (because i only later realized how this might lead to an error if salted_password points to password), so this is not in the diff and I'm too lazy to change the diff file :/