Pure-ftpd и Postgreql Auth с солью пароля - PullRequest
5 голосов
/ 03 августа 2011

Я недавно приступил к задаче настройки сервера PureFTP. На работе мы используем Postgresql 8.4. Схема по существу сводится к,

username        text
password        character(40)
password_salt   text

password сохраняется как хэш sha1( password + salt ). Используя Postgresql's pgcrypto, я могу предоставить username и password и выяснить, есть ли у пользователя auth:

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 Ответ

2 голосов
/ 17 октября 2012

У меня была та же проблема. Тем не менее, написание моего собственного модуля аутентификации было бы излишним, так как доступный 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 для 'cleartext' на (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' (без апострофа) * ​​1040 *
  • PGSQLGetSalt: Здесь вы указываете поле в вашей базе данных для извлечения соли, как и в случае с зашифрованным паролем, который вы должны получить через PGSQLGetPw.

Редактировать: О, и не забудьте освободить выделенную память в конце функции!

Я также могу предоставить diff-файл, который работает для релиза 1.0.36 .. вот, пожалуйста! Осторожно, я добавил if после освобождения salted_password позже (потому что только позже понял, как это может привести к ошибке, если salted_password указывает на пароль), поэтому его нет в diff, и мне лень менять файл diff: /

...