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 :/