【问题标题】:Pure-ftpd and Postgreql Auth with password saltPure-ftpd 和 Postgreql Auth 与密码 salt
【发布时间】:2012-10-19 05:30:54
【问题描述】:

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

username        text
password        character(40)
password_salt   text

password 存储为sha1( password + salt ) 的哈希值。使用 Postgresql 的 pgcrypto,我可以提供 usernamepassword 并查看用户是否具有身份验证:

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模块会支持这种基本的加盐。

参考

【问题讨论】:

  • 我认为你必须这样做:用户的密码,明文,crypt()ed 格式或 MD5。 Pure-FTPd 也接受 PGSQLCrypt 字段的“任何”值。使用“any”,尝试所有散列函数(不是明文)。
  • 是的,但他们在没有 DB 盐的情况下进行了尝试。 =(该死的,这不好。
  • 您可能需要深入研究源代码才能找到答案,但它可能接受在 md5 或加密密码之前或之后添加的盐?我相信这就是 /etc/shadow 存储它们的方式。如果你最终编写了自己的身份验证并且可以做任何你想做的事情,你应该使用带有河豚算法的 postgres crypt 而不是 sha1。

标签: postgresql salt saltedhash pureftpd


【解决方案1】:

我遇到了同样的问题。但是,编写我自己的自定义身份验证模块将是一种矫枉过正,因为可用的 pgsql 身份验证几乎可以完成我想要的一切。 以下是我对其进行的更改以满足我的需要:

在 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 方法(crypt、crypto_hash_md5、crypto_hash_sha1)的调用中替换了 password 参数,并将“明文”的 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 检索的加密密码一样。

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

我还可以提供一个适用于 1.0.36 版本的 diff 文件。here you go! 不过要注意,我后来在释放 salted_pa​​ssword 时添加了 if(因为我后来才意识到,如果salted_pa​​ssword 指向密码),所以这不在差异中,我懒得更改差异文件:/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-19
    • 2014-03-20
    • 2020-02-02
    • 1970-01-01
    • 2018-07-29
    • 2016-02-13
    • 2017-04-11
    • 2014-07-18
    相关资源
    最近更新 更多