I've recently begun the task of setting up an PureFTP server. At work we use Postgresql 8.4. The schema essentially boils down to,
username text
password character(40)
password_salt text
The password
is stored as hash of sha1( password + salt )
. Using Postgresql's pgcrypto I can supply a username
, and password
and find out if the user has auth:
SELECT
encode( digest( $password ||password_salt, 'sha1' ), 'hex' ) = password
AS password_correct
, username
, password
, password_salt
FROM contact.person;
Now the issue that I'm having is that such a function would require me getting the password into the query. This doesn't seem possible with Pureftp's current implementation of auth-postgresql. It only supports providing:
\L is replaced by the login of a user trying to authenticate.
\I is replaced by the IP address the client connected to.
\P is replaced by the port number the client connected to.
\R is replaced by the remote IP address the client connected from.
\D is replaced by the remote IPv4 address, as a long decimal number.
Is there another way I can do this? I either need to get the password into the query, or get the salt and password out and find another way to write the code in Pureftp.
Obviously, I have another option of writing a custom authentication module, but I would think this basic salting would be supported by the pg module.
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:
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 :/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With