Pure-ftpd и Postgreql Auth с солью пароля
Недавно я приступил к настройке сервера PureFTP. На работе мы используем Postgresql 8.4. Схема по существу сводится к
username text
password character(40)
password_salt text
password
хранится как хеш sha1( password + salt )
, Используя Postgresql's pgcrypto, я могу предоставить username
, а также password
и узнайте, есть ли у пользователя авторизация:
SELECT
encode( digest( $password ||password_salt, 'sha1' ), 'hex' ) = password
AS password_correct
, username
, password
, password_salt
FROM contact.person;
Теперь проблема в том, что такая функция потребует от меня ввода пароля в запрос. Это не представляется возможным с текущей реализацией Pureftp auth-postgresql. Поддерживается только предоставление:
\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.
Есть ли другой способ сделать это? Мне либо нужно ввести пароль в запрос, либо вывести соль и пароль и найти другой способ написания кода в Pureftp.
Очевидно, у меня есть еще один вариант написания пользовательского модуля аутентификации, но я думаю, что этот базовый солевой режим будет поддерживаться модулем pg.
Рекомендации
1 ответ
У меня была та же проблема. Тем не менее, написание своего собственного модуля аутентификации было бы излишним, так как доступный pgsql auth делает почти все, что я хочу... Вот какие изменения я сделал для него, чтобы удовлетворить мои потребности:
В log_pgsql_p.h добавить static char *salting;
а также static char *sqlreq_getsalt;
и расширить static ConfigKeywords pgsql_config_keywords[]
с { "PGSQLSalting", &salting },
а также { "PGSQLGetSalt", &sqlreq_getsalt },
,
В log_pgsql.h я добавил #define SALT_SQL_APPEND "append"
, #define SALT_SQL_PREPEND "prepend"
а также #define SALT_SQL_NONE "none"
,
В log_pgsql.c я затем внес следующие изменения в pw_psql_check
функция:
Я объявил const char *salt = NULL;
а также char * salted_password = NULL;
на вершине. Прямо перед spwd
присваивается результат запроса sqlreq_getpw
я добавил
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);
}
Затем, прежде чем произойдет шифрование:
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);
}
И тогда я заменил password
аргумент в последующих вызовах методов crypt (crypt, crypto_hash_md5, crypto_hash_sha1) и strcasecmp
для "открытого текста" с (const char*)salted_password
,
Теперь осталось только привести в порядок память, которую мы распределили. Особенно незашифрованный пароль с добавленной / добавленной солью не должен оставаться в памяти - называйте это паранойей, если хотите. Так что после bye:
добавить ярлык
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);
}
С этими изменениями у вас теперь есть два дополнительных параметра в вашем конфигурационном файле:
- PGSQLSalting: принимает 'append' (добавляет соль к pw), 'prepend' и 'none' (без апострофа)
- PGSQLGetSalt: Здесь вы указываете поле в вашей базе данных для извлечения соли, как и в случае с зашифрованным паролем, который вы должны получить через PGSQLGetPw.
Изменить: О, и не забудьте освободить выделенную память в конце функции!
Я также могу предоставить diff-файл, который работает для релиза 1.0.36.. вот, пожалуйста ! Однако остерегайтесь, я добавил if вокруг освобождения salted_password позже (потому что только позже я понял, как это может привести к ошибке, если salted_password указывает на пароль), так что это не в diff, и я слишком ленив, чтобы изменить diff файл:/