Войти
VTEM SlideshowVTEM SlideshowVTEM Slideshow


Аутентификация пользователей через Web-интерфейс

 

Про аутентификацию пользователей существует масса статей и для такой процедуры написано тысячи скриптов. Но, в большинстве все такие методы рассчитаны на хранение паролей и логинов в определенном файле или на аутентификацию пользователей при помощи файла .htaccess. Здесь же речь будет идти про аутентификацию реальных пользователей Unix хостинга через web-интерфейс.

Есть очень много методов для решения такой задачи, но используют чаще 2 способа:

шифруют пароль, который введен в форме и сопоставляют его с паролем в файле shadow или passwd
используют pop3 аутентификацию.
Первый метод достаточно неудобный, так как его реализация требует прав суперадмина (root) для открытия файла зашифрованных паролей (shadow), и в следствие, есть пробелом в безопасности сервера. Он реализуется путем исполнения cgi - скрипта с правами суперадминистратора root (suid).

Вообщем, алгоритм простой:

взять пару логин и пароль с веб - формы;
зашифровать пароль таким же алгоритмом, что и на сервере;
открыть файл shadow для сравнения пароля, там хранящегося с полученным с веб - формы.
Если результат сравнения положителен, аутентификация прошла успешна и увы в противном случае.
Не забыть позакрывать все файлы.
Все достаточно просто. Открываем файл, читаем его в буфер, находим необходимую строку, закриптовываем пароль, сравнили с тем, что в файле и по делам их воздаем аутентифицирующемуся пользователю. В Unix системах шифрование происходит в одну сторону - к зашифрованному паролю добаваляется большая порция избыточной информации (salt - соли) и выдернуть пароль назад оттуда не есть возможным. Так что, "взлом" паролей возможен только методом подбора. Но, а если пользователь легальный и пароль действителен, то зашифруя его, сразу же успешно проходим аутентификацию. За что мне нравится язык Perl, так это отсутствие необходимости изобретать уже давно изобретенные велосипеды. Проверка пароля сводится к вызову стандартной системной функции crypt($text,$salt).

Действует такая функция  так : в качестве параметров подается пароль в "чистом" виде и зашифрованный, на выходе она должна выдать тот же зашифрованный пароль. Если этого не произходит, значит пароль в виде простого текста был неправильный. В общем вся процедура выглядит примерно так:


#!/usr/bin/suidperl
#
# читаем форму
.........
&check_passwd;
sub check_passwd {
my $shadow = "/etc/shadow";<br /> # ниже две строчки = переданные из формы пароль/логин<br /> $plaintext = $form{'password'};<br /> $username = $form{'login'};<br /> # пытаемся открыть файл зашифрованных паролей (на нормальной системе<br /> # он доступен только для чтения только root-ом.)<br /> # и заодно попытаемся его залочить.<br /> open (SHADOW, "<$shadow") or die "Internal system error: $!";<br /> flock (SHADOW, 2) or die "Internal lock error: $!";<br /> @shadows=;<br /> flock SHADOW, 8;<br /> # закроем shadow<br /> close SHADOW;</p> <p>foreach $line(@shadows) {<br /> chomp($line);<br /> ($currentuser, $currentpass, $restofline) = split /:/, $line, 3;<br /> if ($currentuser eq $username)<br /> # Выдергиваем зашифрованный пароль из shadow<br /> $saltedpass = $currentpass;<br /> # Проверяем его стандартной функцией crypt<br /> if ( crypt ($plaintext, $saltedpass) eq $saltedpass) {<br /> print "Authentification for $username success!\n";<br /> } else {<br /> print "Authentification for $username failure!\n";<br /> }<br /> }<br /> }<br /> }</p> <p>Файлу, содержащему этот "шедевр" программистского искусства следует в целях безопасности установить атрибуты: Владелец - root. Взведенный бит установки ID пользователя при исполнении режим доступа r-sr-xr-x грубо говоря, в восьмеричном отображении оно будет смотрется как 104555. В этом suid-e и кроется опасность - если кто-то придумает всунуть свой код в вашу программу, то сможет легко получить доступ к вашей системе.
(кто не верит - прочитайте что-нибудь про Ramen - он еще и не то делает/делал)

А поэтому этот метод, как небезопасный,  использовать не стоит. Лучше взять уже готовую Perl-библиотеку: Net.

Аутентификация.

Простой и безопасный метод проверки подлинности пользователя. Берется библиотека Net::POP3 и стандартными методами пытаемся залогиниться в почтовый ящик. Если нам это удалось, то логин и пароль верны и обратный результат в другом случае. Модуль Net::POP3 дает пользователю создать объект и 14 методов к нему. Все методы учить нет смысла - они довольно-таки неподробно описаны в документации к модулю, нас более интересует метод login($user,$passwd). Он возвращает значение undef в случае неудачной аутентификации, или, в случае удачного входа в почту, количество писем в нем, или строку "0E0", если писем нет , т.е. "пишут". Порядок работы с ним следующий:

use Net::POP3;
&parse_form # Читаем из формы переданные пароль и логин
# Создаем объект
$pop = Net::POP3->new('popserver') || print "Cannot create connection\n";
# пробуем залогиниться
# в $res будет возвращен результат логина
$res = $pop->login($form{'login'},$form{'password'});
if ($res == undef) {
# неудача
print "Incorrect username or password!\n";
} else {
# залогинились
# делаем, что нам надо
#
# следующий код нарисован для того, чтобы хоть что-то
# делалось.
if ($res eq "0E0") {
# писем нет
print "You have $res messages in mailbox.\n";
} else {
# письма есть
print "You have $res messages in mailbox.\n";
}
}
#закрываем соединение.
$pop->quit();
Намного проще и безопаснее, чем лезть в  безопасности Unix систем - файл shadow. Да и не нужно просить админа хостинга установить на ваш скрипт setuid bit, хотя заранее можно сказать, что любой нормальный админ вам в этом откажет и будет на все сто прав.

А библиотека Net есть почти на любом сервере, где есть доступ к perl-интерпретатору.



Hosting tools

Who's Online

Сейчас 17 гостей и ни одного зарегистрированного пользователя на сайте