5

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

username        text
password        character(40)
password_salt   text

password存储为 的哈希值sha1( password + salt )。使用 Postgresql 的 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 模块将支持这种基本的加盐。

参考

4

1 回答 1

2

我有同样的问题。但是,编写我自己的自定义身份验证模块将是一种矫枉过正,因为可用的 pgsql auth 几乎可以完成我想要的一切。这是我为满足我的需要所做的更改:

在 log_pgsql_p.h 添加static char *salting;static char *sqlreq_getsalt;扩展static ConfigKeywords pgsql_config_keywords[]with{ "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-methods (crypt, crypto_hash_md5, crypto_hash_sha1) 和strcasecmpfor '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'(不带撇号)
  • PGSQLGetSalt:在这里你指定你的数据库中的字段来获取盐,就像你需要通过 PGSQLGetPw 检索的加密密码一样。

编辑:哦,别忘了在函数结束时释放分配的内存!

我还可以提供一个适用于 1.0.36 版本的差异文件。给你!但请注意,我稍后在释放 salted_pa​​ssword 时添加了 if(因为我后来才意识到如果 salted_pa​​ssword 指向密码,这可能会导致错误),所以这不在差异中,我懒得更改差异文件 :/

于 2012-10-17T19:37:26.513 回答