【问题标题】:crypt on suse leads to segfaultsuse 上的 crypt 导致段错误
【发布时间】:2015-09-04 10:53:17
【问题描述】:

我正在做 PAM 类型的事情,它需要检查 /etc/shadow 中的用户密码。

通常,这涉及读取加密 ID、salt 和密码的密码行。使用 ID 和 salt,可以使用 crypt(3) 或 m_crypt(在同一手册页上)对用户提供的密码进行哈希处理,并比较结果。这在许多系统上都可以正常工作,例如 Ubuntu,但我在 SUSE 上遇到了重大问题。

系统使用 Blowfish,“正确处理 8 位字符”。它的哈希 ID 为“2y”。不幸的是,每当 crypt(3) 被调用时,它都会出现段错误。 ID“2a”也是如此,这是识别 Blowfish 的第一个代码。所有其他散列算法都有效。

系统必须有一个可以进行 Blowfish 散列的工作 crypt(或等效的),因为 /etc/shadow 文件有它的示例,但我无法完成这项工作。谁能指出我正确的方向?

段错误示例:

#define _XOPEN_SOURCE
#include <unistd.h>
#include <stdio.h>

int main(int argc, char** argv) {
  char *pass = "tqbfjotld";
  char *salt = "$2y$10$";
  char *pp = NULL;
  pp = crypt(pass, salt);
  printf("%s\n", pp);
  return 0;
}

盐 $2a$10$ 也显示错误。

它可以在 Ubuntu 等其他系统上运行,而其他哈希算法在 SUSE 上也可以正常运行。

有什么想法吗?

【问题讨论】:

  • 自己没用过,不过2a是河豚,2y是什么?
  • 对 crypt 的调用返回 NULL 值。是 printf() 导致了 seg 错误事件,因为字符串参数为 NULL。
  • 根据 crypt 的文档,salt 必须是指向 2 char 字符串的指针。当我只使用两个字符的字符串作为盐时,它工作得很好。请阅读 crypt 的手册页
  • @user3629249:该手册页具有误导性,您会在下方找到“Glibc 注释”,其中描述了更复杂的“盐”值。
  • @SouravGhosh:请参阅 en.wikipedia.org/wiki/Crypt_%28C%29#Blowfish-based_scheme 关于“2y”,这是一个相当新的添加。

标签: c passwords hashcode crypt


【解决方案1】:

使用$2y$10$xxx 作为盐,xxx 表示$2y$10$ 后面的22 个字符。 如果你想知道为什么是 22,请看:https://en.wikipedia.org/wiki/Bcrypt

【讨论】:

    【解决方案2】:

    crypt() 返回 NULL 表示错误,可能是无效的盐,因为 2y 是未知的。 根据维基百科,这似乎是一个相当新的添加: https://en.wikipedia.org/wiki/Crypt_%28C%29

    "$2y$ - 2011 年后的错误发现,$2y$ 可用于明确使用新的、更正的算法。在遭受错误的实现中,$2y$ 根本不起作用。在较新的,固定实现,它将产生与使用 $2a$ 相同的结果。”

    试试这个得到错误:

    #include <errno.h>
    printf("%p (errno=%d: %s)\n", pp, errno, strerror(errno));
    

    glibc-2.19 不支持任何 Blowfish 算法,我在最近的 Debian 8.1 上也得到了一个 NULL 指针。

    也许您的 SUSE 系统包含随时间迁移的密码条目,甚至不再可用。或者其他一些软件,如自定义 PAM 模块,使用自定义库而不是使用标准 libc crypt() 函数来评估和检查密码条目。

    【讨论】:

    • 我认为 2y 可以在这个系统上运行,因为它正在使用 $2y$ 创建新的用户帐户(所以 passwd 可以从某个地方正确获取它)。
    • 错误号是 22。不幸的是,它没有附带字符串(strerror 返回 NULL)。
    • 我不知道可以运行 /lib/libc.so.6,但现在我可以在可用扩展下看到:“Michael Glad 和其他人的 crypt add-on version 2.1” .这让我有点困惑,因为 libc 中没有“crypt”函数(有 common_crypt 等)。当我链接时,我需要使用 -lcrypt。这与 libc 是分开的,不是吗?
    • @PaulG: Error 22 is "Invalid Argument" 根据 /usr/include/asm-generic/errno-base.h: #define EINVAL 22 /* Invalid argument / libcrypt ist part libc6 项目的,例如libc 的 Debian 数据包列表中有它: $ dpkg -L libc6 | grep crypt /lib/i386-linux-gnu/libcrypt-2.19.so /lib/i386-linux-gnu/libcrypt.so.1 您可能需要检查“grep password /etc/pam.d/”也许你在任何地方都有一个 pam_bsd_special_crypt.so :-)
    • 动了脑筋,用 ldd 跑过 passwd。原来它使用了来自 libxcrypt.so 的 crypt(实际上是 crypt_r)。不幸的是,我仍在努力弄清楚如何链接到那个:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-03
    • 2012-08-17
    • 1970-01-01
    • 2011-01-11
    相关资源
    最近更新 更多