Ít nhất là trong Ubuntu của tôi, các thông báo "quá giống nhau" đã xuất hiện khi: "... hơn một nửa số ký tự là khác nhau ...." (xem bên dưới để biết chi tiết). nhờ hỗ trợ PAM, như được giải thích rõ ràng trong câu trả lời @slhck.
Đối với nền tảng khác, nơi PAM không được sử dụng, các thông báo "quá giống nhau" xuất hiện khi: "... hơn một nửa số ký tự là khác nhau ...." (xem bên dưới để biết chi tiết)
Để tự mình kiểm tra tuyên bố này, bạn có thể kiểm tra mã nguồn. Đây là cách làm.
Chương trình "passwd" được bao gồm trong gói passwd:
verzulli@iMac:~$ which passwd
/usr/bin/passwd
verzulli@iMac:~$ dpkg -S /usr/bin/passwd
passwd: /usr/bin/passwd
Khi chúng tôi đang xử lý các công nghệ Nguồn mở, chúng tôi có quyền truy cập không hạn chế vào mã nguồn. Bắt nó đơn giản như:
verzulli@iMac:/usr/local/src/passwd$ apt-get source passwd
Sau đó, thật dễ dàng để tìm thấy đoạn mã có liên quan:
verzulli@iMac:/usr/local/src/passwd$ grep -i -r 'too similar' .
[...]
./shadow-4.1.5.1/NEWS:- new password is not "too similar" if it is long enough
./shadow-4.1.5.1/libmisc/obscure.c: msg = _("too similar");
Một kiểm tra nhanh để "obscure.c" đưa ra điều này (Tôi chỉ cắt và dán đoạn mã có liên quan):
static const char *password_check (
const char *old,
const char *new,
const struct passwd *pwdp)
{
const char *msg = NULL;
char *oldmono, *newmono, *wrapped;
if (strcmp (new, old) == 0) {
return _("no change");
}
[...]
if (palindrome (oldmono, newmono)) {
msg = _("a palindrome");
} else if (strcmp (oldmono, newmono) == 0) {
msg = _("case changes only");
} else if (similar (oldmono, newmono)) {
msg = _("too similar");
} else if (simple (old, new)) {
msg = _("too simple");
} else if (strstr (wrapped, newmono) != NULL) {
msg = _("rotated");
} else {
}
[...]
return msg;
}
Vì vậy, bây giờ, chúng ta biết rằng có một chức năng "tương tự" dựa trên kiểm tra cái cũ và cái mới nếu cả hai đều giống nhau. Đây là đoạn trích:
/*
* more than half of the characters are different ones.
*/
static bool similar (const char *old, const char *new)
{
int i, j;
/*
* XXX - sometimes this fails when changing from a simple password
* to a really long one (MD5). For now, I just return success if
* the new password is long enough. Please feel free to suggest
* something better... --marekm
*/
if (strlen (new) >= 8) {
return false;
}
for (i = j = 0; ('\0' != new[i]) && ('\0' != old[i]); i++) {
if (strchr (new, old[i]) != NULL) {
j++;
}
}
if (i >= j * 2) {
return false;
}
return true;
}
Tôi chưa xem lại mã C. Tôi giới hạn bản thân trong việc tin tưởng nhận xét ngay trước khi định nghĩa hàm :-)
Sự khác biệt giữa các nền tảng nhận biết PAM và NON-PAM được xác định trong tệp "obscure.c" có cấu trúc như sau:
#include <config.h>
#ifndef USE_PAM
[...lots of things, including all the above...]
#else /* !USE_PAM */
extern int errno; /* warning: ANSI C forbids an empty source file */
#endif /* !USE_PAM */