突然有个奇怪的问题:默认的FreeBSD中,密码最长是多少个字符?
答案是:128。
在/usr/src/include/pwd.h里面有定义:
#define _PASSWORD_LEN 128 /* max length, not counting NULL */
struct passwd {
char *pw_name; /* user name */
char *pw_passwd; /* encrypted password */
uid_t pw_uid; /* user uid */
gid_t pw_gid; /* user gid */
time_t pw_change; /* password change time */
char *pw_class; /* user access class */
char *pw_gecos; /* Honeywell login info */
char *pw_dir; /* home directory */
char *pw_shell; /* default shell */
time_t pw_expire; /* account expiration */
int pw_fields; /* internal: fields filled in */
};
_PASSWORD_LEN就是最大的密码长度。另外从上面的passwd结构体中,可以看到密码结构包令的信息还是挺多的,包括密码创建的时间都有。
获取密码的函数为getpass,源代码文件为/usr/src/lib/libc/gen/readpassphrase.c:
……
char *
getpass(const char *prompt)
{
static char buf[_PASSWORD_LEN + 1];
if (readpassphrase(prompt, buf, sizeof(buf), RPP_ECHO_OFF) == NULL)
buf[0] = '\0';
return(buf);
}
……
另外还有一个典型的应用,在/usr/src/sbin/init/init.c中:
for (;;) {
clear = getpass("Password:");
if (clear == 0 || *clear == '\0')
_exit(0);
password = crypt(clear, pp->pw_passwd);
bzero(clear, _PASSWORD_LEN);
if (password == NULL ||
strcmp(password, pp->pw_passwd) == 0)
break;
warning("single-user login failed\n");
}
注意这个地方输入的时候没提_PASSWORD_LEN的事,然后就直接对输入的字符串进行了crypt,是不是会有点漏洞呢?其实没有问题,因为这个地方调用了getpass函数(见上文),在getpass中,已经使用了sizeof(buf),buf的长度又限定为_PASSWORD_LEN,所以不存在超长的问题。
如果你想增加这个最大密码长度,可以修改pwd.h后重新编译基本系统,即重新make world一次。
另外,/usr/include中也有一个pwd.h,修改这个文件没有效果,因为这个文件是给后来链接libc的程序使用的。