
Поскольку мой вопрос по теме, похоже, не пользуется особой популярностью, вот еще один: Каков правильный способ аутентификации пользователя с помощью запроса имени пользователя и пароля в Linux в настоящее время?
В принципе, я предполагаю, что мне пришлось бы получить имя пользователя и пароль, прочитать соль и хэш соответствующего пользователя из /etc/shadow
. Затем я бы вычислил хэш заданного пароля и сохраненной соли и проверил бы, совпадает ли результат с хешем, сохраненным в /etc/shadow
.
Обычно я мог бы просто аутентифицироваться через PAM (например pam_unix
), который уже все это делает, но мое приложение — это пользовательский модуль PAM, и я не нашел метода, чтобы вызвать один модуль PAM из другого. Если это возможно каким-то образом, я бы с радостью выбрал это решение.
На данный момент я нахожу этот урок действительно устаревшим.http://www.tldp.org/HOWTO/Shadow-Password-HOWTO-8.htmlс 1996 года, когда, по-видимому, поддержка теней еще не была встроена в libc. Он упоминает pw_auth
и valid
как вспомогательные функции для аутентификации. Я пробовал внедрять их в свой код и связывать с libshadow.a
shadow-tools, но получаю ошибки 'unresolved external reference' для pw_auth
и valid
. Код выглядит примерно так:
if ((pw->pw_passwd && pw->pw_passwd[0] == '@'
&& pw_auth (pw->pw_passwd+1, pw->pw_name, PW_LOGIN, NULL))
|| !valid (passwd, pw)) {
return (UPAP_AUTHNAK);
}
Я не проверял это более подробно, но в любом случае это не лучшее решение, поскольку мне пришлось бы обновлять свой код каждый раз при обновлении shadow-utils.
Я бы предпочел ссылку на библиотеку (не PAM), которая обеспечивает аутентификацию против /etc/shadow
. Есть ли такая вещь, и я ее еще не нашел? Или какое-то другое решение?
решение1
Ваши опасения по поводу обновления shadow-utils на мой взгляд необоснованны. Процедуры, описанные в этом HOWTO, доступны в моих системах Ubuntu 12.04 и Mint 17 без установки чего-либо специального.
Структуру для чтения /etc/shadow
информации в программе на языке C можно найти в /usr/include/shadow.h
и с помощью , man 5 shadow
а функции, которые вам понадобятся для поиска, например, запись теневого пароля по имени, как определено в , /usr/include/shadow.h
и getspnam
это также даст вам страницу руководства ( man getspnam
), описывающую ее и все связанные функции.
Исходя из этого, вы должны иметь возможность получить хэшированную запись пароля для любого заданного имени. Хэшированный пароль должен иметь несколько токенов '$', вырезать все после и включая последний '$' из хэшированного пароля и представить это как соль для crypt()
, версия glibc (согласно man 3 crypt
) должна иметь возможность обрабатывать "расширенные" соли, которые указывают записи SHA512, как это более распространено в настоящее время.