我在 Ubuntu 14.04 上安装了 Exim 4.80 服务器。我想从 Dovecot Auth 切换到 MySQL。密码以 crypt 形式存储(使用 sha256,以 $5$ 开头)。扩展如下所示:
server_condition = ${if crypteq{$3}{${lookup mysql{SELECT password FROM accounts LEFT JOIN domains ON accounts.domain=domains.id AND domains.domain='${quote_mysql:${domain:$2}}' WHERE accounts.name='${quote_mysql:${local_part:$2}}'}}}{yes}{no}}
当我打开调试日志记录时,我得到如下信息:
10 主题=$5$fBzbQG0FRF1Lt2QI$Nhmrw5gKq62vmHDD8Eov9WCoGRPkk-----已编辑----
10 加密=$5$fBzbQG0FRF1Lt2QI$Nhmrw5gKq62vmHDD8Eov9WCoGRPkk-----已编辑----
两个 REDACTED 完全相等。然后发生以下情况:
10 扩展字符串:无
我仔细研究了 Exim 源代码,发现以下代码负责调试消息和 crypteq 的结果
#define STR(s) # s
#define XSTR(s) STR(s)
DEBUG(D_auth) debug_printf("crypteq: using %s()\n"
" subject=%s\n crypted=%s\n",
(which == 0)? XSTR(DEFAULT_CRYPT) : (which == 1)? "crypt" : "crypt16",
coded, sub[1]);
#undef STR
#undef XSTR
/* If the encrypted string contains fewer than two characters (for the
salt), force failure. Otherwise we get false positives: with an empty
string the yield of crypt() is an empty string! */
tempcond = (Ustrlen(sub[1]) < 2)? FALSE :
(Ustrcmp(coded, sub[1]) == 0);
}
因此 subject= 是编码变量,由 crypt 函数生成,而 crypted= 是 sub[1]。这两个是相同的。运算符的成功仅取决于 sub[1] 是否长于两个字符(这显然是正确的)以及它们是否相同(这也应该是正确的)。
有人知道为什么会发生这种情况吗?
编辑:如果我直接将哈希放在括号中而不进行 MySQL 查找,则不会发生这种情况。MySQL 似乎存在扩展失败。
答案1
好的,所以对于其他遇到此问题的人来说:MySQL 扩展以某种方式添加了空格(即使数据库中显然没有空格)。要解决此问题,请将 MySQL 扩展封装在具有哈希长度的 substr 中。sha256-crypt 哈希的一个示例如下:
${substr{0}{63}{${查找mysql{
那么它就可以工作了。