Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Программирование под Linux [24-12-2002]


Информационный Канал Subscribe.Ru


Здравствуйте дорогие подписчики рассылки "Программирование под Linux" !!!
 ....----==== http://www.firststeps.ru/linux/ ====----....

Получение данных из shadow password

В прошлый раз мы с Вами разобрались с тем, как получать информацию о пользователе из файла /etc/passwd, но как оказалось получить пароль нам не удастся, потому что его там нет. А как быть, если он Вам нужен ? Ну, например, Вы решили написать собственный сервер POP3, который для авторизации требует наличие пароля.

Для работы со скрытыми паролями надо подключить файл shadow.h и вам станут доступны аналогичные процедуры:

#include <shadow.h>

struct spwd *getspnam (const char *name);

Обратите внимание, что в файле shadow.h нет определения функции получения информации о пользователе по его UID. Т.е. для работы нужно знать имя пользователя, соответственно сначала нужно воспользоваться функцией getpwuid(), чтобы по UID получить имя.

Функция getspnam() возвращает структуру struct spwd, либо NULL в случае неудачи. Данная структура определена следующим образом:

struct spwd
{
 char *sp_namp;              /* Login name.  */
 char *sp_pwdp;              /* Encrypted password. */
 long int sp_lstchg;         /* Date of last change. */
 long int sp_min;            /* Minimum number of days between changes. */
 long int sp_max;            /* Maximum number of days between changes. */
 long int sp_warn;           /* Number of days to warn user to change
                                   the password. */
 long int sp_inact;          /* Number of days the account may be
                                   inactive. */
 long int sp_expire;         /* Number of days since 1970-01-01 until
                                   account expires. */
 unsigned long int sp_flag;  /* Reserved.  */
};

Как видите структура гораздо больше, чем passwd. Большинство полей отвечает за временные параметры пароля, такие как его минимальное и максимальное время жизни, а также время жизни всего аккаунта.

И наверняка Вы заметили, что я немного соврал Вам в прошлый раз, когда сказал, что /etc/shadow содержит информацию аналогичную /etc/passwd. Получается, что кроме логина и пароля Вы тут не найдете домашней директории и шелла. В принципе верно, зачем хранить одно и тоже в нескольких местах ?! Выходит, что нам не удастся "отбиться от коллектива" и придется пользоваться обоими файлами.

Давайте посмотрим, как работает эта функция. Напишем маленькую программку shadowtest.c:

#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
#include <shadow.h>

int main(){
 struct passwd *userinfo;
 struct spwd *passw;
 uid_t userid;

 userid = getuid();
 userinfo = getpwuid(userid);

 if (userinfo != NULL){

  passw = getspnam(userinfo->pw_name);

  if (passw != NULL){
   printf("user login: %s\n",userinfo->pw_name);
   printf("user home: %s\n",userinfo->pw_dir);
   printf("user shell: %s\n",userinfo->pw_shell);
   printf("user password: %s\n",userinfo->pw_passwd);
   printf("user shadow password: %s\n",passw->sp_pwdp);
   printf("user last change: %ld\n",passw->sp_lstchg);
  };

 };

 return 0;
};

Компилируем и запускаем:

dron~# ./gcc shadowtest.c -o shadowtest
dron~# ./shadowtest
user login: root
user home: /root
user shell: /bin/bash
user password: x
user shadow password: $1$02p9xyDo$gnkh4vts/rArhJselceTV1
user last change: 12028

Как видите пароль нам получить удалось только из структуры struct spwd. Но он зашифрованный алгоритмом MD5, в данном случае настоящий пароль 12345678 (можете не мучаться над взломом :). Тут кстати следует поговорить о том, как хранятся пароли. Понятное дело, что если пароли будут храниться в виде plain text, т.е. в виде текста "как есть", то можно будет узнать пароль для любого пользователя совершенно спокойно. Современные правила безопасности вообще не разрешают хранить пароль в таком виде. Вместо этого пароль хранится в виде хеша от настояшего пароля. Функция вырабатывающая хеш берет настоящий пароль и вырабатывает на его основе уникальную последовательность чисел, которую не возможно обратно преобразовать в пароль, потому что математические функции работающие над выработкой пароля специально создаются однонаправленными. Создание таких процедур является сложной криптографической задачей и порой под силу только крупным научно-исследовательским институтам. К примеру у нас в России существуют засекреченные алгоритмы, некоторые из которых разрабатывались в течение 10 лет, так вот представьте каких трудов это стоит и представьте какие эти алгоритмы совершенные. Взять к примеру наш алгоритм шифрования ГОСТ 28147-89, который существует с 89 года и до сих пор остается одним из самых защищенных (он может иметь длину ключа 256 бит, в то время как DES имеет всего 56 бит и при нынешнем развитии компьютеров является чрезвычайно устаревшим). Однако для выработки хеша в системах Linux используются в основном алгоритмы DES и MD5, хотя первый уже используется крайне редко.

Так вот, сравнение правильности пароля происходит следующим образом. Программа получает настоящий пароль от пользователя, потом вырабатывает на его основе хеш и сравнивает его с тем, который она получила из файла /etc/shadow. Если хеши не совпадают, то значит пароли разные.

Количество подписчиков: 1073

Выпуск подготовил: Кузин Андрей (dron@mjk.msk.ru)

http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу

В избранное