C suse上的地穴导致了segfault

C suse上的地穴导致了segfault,c,passwords,hashcode,crypt,C,Passwords,Hashcode,Crypt,我正在做一个PAM类型的事情,它需要在/etc/shadow中检查用户的密码 通常,这涉及读取加密ID、salt和密码的密码行。使用ID和salt,可以使用crypt(3)或m_crypt(在同一手册页上)对用户提供的密码进行散列,并比较结果。这在很多系统上都很好,比如Ubuntu,但是我在SUSE上遇到了一些大问题 该系统使用的是河豚,具有“正确处理8位字符”的功能。它的哈希ID为“2y”。不幸的是,每当调用crypt(3)时,它都会出错。ID“2a”也是如此,这是识别河豚的第一个代码。所有其

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

通常,这涉及读取加密ID、salt和密码的密码行。使用ID和salt,可以使用crypt(3)或m_crypt(在同一手册页上)对用户提供的密码进行散列,并比较结果。这在很多系统上都很好,比如Ubuntu,但是我在SUSE上遇到了一些大问题

该系统使用的是河豚,具有“正确处理8位字符”的功能。它的哈希ID为“2y”。不幸的是,每当调用crypt(3)时,它都会出错。ID“2a”也是如此,这是识别河豚的第一个代码。所有其他哈希算法都可以工作

该系统必须有一个可以工作的crypt(或等效的crypt)来执行Blowfish散列,因为/etc/shadow文件中有它的例子,但我不能让它工作。谁能给我指出正确的方向吗

segfault的一个示例:

#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;
}
定义源代码
#包括
#包括
int main(int argc,字符**argv){
char*pass=“tqbfjotld”;
char*salt=“$2y$10$”;
char*pp=NULL;
pp=地穴(通道,盐);
printf(“%s\n”,pp);
返回0;
}
salt$2a$10$也显示了错误

它可以在其他系统上运行,比如Ubuntu,其他哈希算法在SUSE上运行良好

有什么想法吗?

crypt()返回NULL表示错误,可能是无效的salt,因为2y未知。 根据维基百科,这似乎是一个相当新的补充:

“$2y$-2011年缺陷发现后,$2y$可用于明确使用新的、已纠正的算法。在有缺陷的实现上,$2y$根本不起作用。在更新的、已修复的实现上,它将产生与使用$2a$相同的结果。”

请尝试以下操作以获取错误:

#include <errno.h>
printf("%p (errno=%d: %s)\n", pp, errno, strerror(errno));
#包括
printf(“%p(errno=%d:%s)\n”,pp,errno,strerror(errno));
glibc-2.19不支持任何河豚算法,我在最近的Debian 8.1上也得到了一个空指针


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

使用
$2y$10$xxx
作为salt,
xxx
表示
$2y$10$
后面的22个字符。
如果你想知道为什么是22,请看:。

从未使用过我自己,但是
2a
是河豚,什么是
2y
?对crypt的调用返回的值为NULL。正是printf()导致了seg故障事件,因为字符串参数为NULL。根据crypt的文档,salt必须是指向2个字符字符串的指针。当我只使用两个字符的字符串作为盐时,它工作得非常好。请阅读手册页了解更多信息crypt@user3629249:手册页有误导性,再往下看,你会发现“Glibc notes”,其中描述了“salt”的更复杂的值。@SouravGhosh:关于“2y”,这是一个相当新的添加项。我认为2y在这个系统上可以工作,因为它使用$2y$创建新的用户帐户(所以passwd从某处正确地提取了它)。错误号是22。不幸的是,这不是一个字符串(strerror返回NULL)。我不知道可以运行/lib/libc.so.6,但现在我知道了,我在可用扩展下看到了:“MichaelGlady和其他人编写的crypt插件版本2.1”.这让我有点困惑,因为libc中没有“crypt”函数(其中有common_crypt)。当我链接时,我需要使用-lcrypt。这与libc是分开的,不是吗?@PaulG:Error 22是“无效参数”根据/usr/include/asm generic/errno base.h:#define EINVAL 22/*无效参数/libcrypt是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 anywhere:-)使用了我的大脑,并在passwd上运行了ldd。结果它使用了来自libxcrypt.so的crypt(实际上是crypt_r)。不幸的是,我仍在努力找出如何链接到它:)