使用密码salt的pure-ftpd和Postgresql Auth

时间:2011-08-02 21:53:31

标签: postgresql salt saltedhash pureftpd

我最近开始设置PureFTP服务器的任务。在工作中我们使用Postgresql 8.4。该模式基本上归结为,

username        text
password        character(40)
password_salt   text

password存储为sha1( password + salt )的哈希值。使用Postgresql的pgcrypto我可以提供usernamepassword并查看用户是否有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中编写代码的方法。

显然,我有另一种写custom authentication module的选择,但我认为pg模块会支持这种基本的腌制。

参考

1 个答案:

答案 0 :(得分:2)

我遇到了同样的问题。然而,编写我自己的自定义身份验证模块将是一个过度杀伤,因为可用的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);
}

然后我在后续调用crypt-methods(crypt,crypto_hash_md5,crypto_hash_sha1)和password for' cleartext'中替换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:接受'追加' (将盐加到pw上),' prepend'并且没有' (没有撇号)
  • PGSQLGetSalt:在这里你指定数据库中的字段来获取盐,就像你需要通过PGSQLGetPw检索的加密密码一样。

编辑:哦,不要忘记在功能结束时释放分配的内存!

我也可以提供一个适用于1.0.36版本的差异文件。here you go!请注意,我添加了if后面的salted_pa​​ssword释放(因为我后来才意识到这可能会导致如果salted_pa​​ssword指向密码则出错,所以这不在差异中,而且我懒得更改差异文件:/