Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Первае шаги в программировании Linux

.doc
Скачиваний:
8
Добавлен:
08.04.2015
Размер:
377.34 Кб
Скачать

MANPATH=/usr/local/man:/usr/man:/usr/X11R6/man:/usr/lib/java/man

HOSTNAME=darkstar.example.net

SHELL=/bin/bash

TERM=xterm

USER=root

MC_TMPDIR=/tmp/mc-root

T1LIB_CONFIG=/usr/share/t1lib/t1lib.config

MINICOM=-c on

PATH=/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:

MAIL=/var/mail/root

LC_COLLATE=C

PWD=/@@@@@@

INPUTRC=/etc/inputrc

JAVA_HOME=/usr/lib/java

LANG=en_US

PS1=\u@\h:\w\$

HISTCONTROL=ignorespace

PS2=>

HOME=/root

SHLVL=2

LOGNAME=root

LESS=-M

LESSOPEN=|lesspipe.sh %s

OLDPWD=/usr/include

_=./a.out

Я конечно вырезал некоторые переменные, которые слишком большие, но все равно достаточно информативно и можно считать, что программа знает о среде в которой запущена практически все.

Для доступа к переменным окружения, есть несколько функций:

  • char * getenv (const char *name) - возвращает указатель на значение переменной с именем name, если переменная среды не найдена, то возвращается NULL. Не рекомендуется модифицировать значение полученной строки, так как она указывает непосредственно в массив переменных среды, и можно испортить их значения. В связи с этим также не требуется выделение дополнительной памяти для сохранения результата.

  • int setenv (const char *name, const char *value, int replace) - добавляет новое или заменяет старое значение в массиве переменных среды с именем name и значением value (даже если value пустая строка). Под новую переменную выделяется память и заносится строка вида "имя=значение". Если в переменных среды уже есть переменная с именем name, то процесс замены контролируется параметром replace, если он равен нулю, то никаких действий не производится.

  • int putenv (char *string) - добавляет или удаляет переменную окружения. Для добавления или изменения переменной используйте строку формата "имя=значение", для удаления просто "имя". В отличие от setenv() функция putenv() не выделяет память для параметра, а использует указатель на значение string, поэтому после вызова этой функции любое изменение строки string автоматически приведет к изменению переменной среды. Также перед удалением строки из памяти, следует сначала удалить эту переменную из массива переменных окружения.

  • int unsetenv (const char *name) - удаляет полностью из массива переменных окружения переменную с именем name.

  • int clearenv(void) - полностью очищает массив переменных окружения.

Используя набор данных функций вы можете полностью управлять переменными среды, которые доступны вашей программе.

#include <stdlib.h>

int main(int argc,char **argv) {

char *HOME = getenv("HOME");

char *USER = getenv("USER");

printf("Home directory: \"%s\"\n",HOME);

printf("User name: \"%s\"\n",USER);

return 0;

};

При вызове данной программы вы узнаете свой домашний каталог и имя пользователя. Например:

root@darkstar:/@@@@@@# ./a.out

Home directory: "/root"

User name: "root"

Использование переменных окружения полезно не только, когда Вам требуется настроить в нескольких программах какие-то параметры, но и для обмена данными между процессами. То есть в одной программе Вы создаете переменную, а в другой получаете значение этой переменной. Таким образом можно наладить обмен простыми короткими данными между процессами. Но, конечно, все-таки не стоит сильно злоупотреблять этой возможностью :)

Шаг 18 - Генерация хешей MD2, MD4, MD5 с помощью OpenSSL

Иногда хочется иметь готовый код использования какой-нибудь функции, а найти его не получается... Поэтому приходится писать свою собственную документацию.

Набор хеш-функций MD2, MD4 и MD5 в библиотеке OpenSSL используется для вычисления хешей данных. Для тех, кто не знает, что такое хеш, возможно будет более понятным термин контрольная сумма или чексумма (от англ. checksum). Это число генерируется на основе содержимого данных и используется в основном для проверки целостности данных. Все алгоритмы вычисления хешей разрабатывались таким образом, чтобы даже при изменении одного бита данных результирующий хеш менялся до неузнаваемости, по сравнению с первоначальным. Причем по хешу данных (по понятным причинам необратимости работы алгоритма) предсказать содержимое данных невозможно.

root@localhost:/home/dron# echo -n "Arnold Schwarzenegger" | md5sum

c8d96c6f9a91ba729ca1688f90f6d2b7 -

root@localhost:/home/dron# echo -n "Brnold Schwarzenegger" | md5sum

c0707d286aaadc1a8c1f5e77cb5a4961 -

Этим свойством можно пользоваться для реализации процесса аутентификации без передачи идентификационных данных по сети в открытом виде. Наиболее наглядным примером использования хеш-функции MD5 является реализация алгоритма защищенной проверки пароля APOP в протоколе POP3. Все тонкости работы алгоритма я описывать не буду, только основные моменты и сам принцип.

Реализация APOP в POP3 позволяет произвести проверку пароля между сервером и клиентом без передачи пароля в открытом виде. Идея проста и заключается в том, что обе стороны (сервер и клиент) изначально пароль знают, да в общем-то другого и быть не может :) Сервер во время подключения клиента к своему приглашению добавляет слово-сальт (словом salt в терминах Юникса обозначается префикс используемый для шифрования паролей DES). Сальт меняется сервером периодически, для этого можно использовать текущее время в секундах, идентификатор процесса или просто случайное число. Это слово-сальт клиент добавляет к паролю и потом передает хеш-функцию MD5 от полученной строки серверу. Сервер производит такую же операцию и сравнивает результат работы MD5 с переданным хешем от клиента. Таким образом получается, что пароль в открытом виде не передается, а по передаваемому хешу практически не возможно подобрать пароль.

Библиотека OpenSSL для работы с хешами предоставляет множество различных по скорости работы и криптостойкости алгоритмов. Я приведу пример работы с семеством Message-Digest (MD) алгоритмов, в которое входят алгоритмы MD2, MD4 и MD5. Набор функций для работы с ними одинаковы и отличаются соответственно названиями:

  • MD*_Init() - инициализация контекста для хеширования.

  • MD*_Update() - обновление контекста новыми данными.

  • MD*_Final() - выработка конечного хеша.

  • MD*() - обобщенная функция для хеширования.

Для работы с этими алгоритмами необходимо подключить соответствующий заголовочный файл, например для MD5:

#include <openssl/md5.h>

Выработка хеша делается следующим образом (для примера возьмем последовательность 0123456789):

/* start main.c */

#include <stdio.h>

#include <stdlib.h>

#include <openssl/md5.h>

int main() {

int i;

MD5_CTX md5handler;

unsigned char md5digest[MD5_DIGEST_LENGTH];

MD5_Init(&md5handler);

MD5_Update(&md5handler, "01234", 5);

MD5_Update(&md5handler, "56789", 5);

MD5_Final(md5digest,&md5handler);

for (i=0;i<MD5_DIGEST_LENGTH;i++) {

printf("%02x",md5digest[i]);

};

printf("\n");

return 0;

};

/* end of main.c */

Компилируем:

gcc main.c -lcrypto

Пробуем:

root@localhost:/home/dron# ./a.out

781e5e245d69b566979b86e28d23f2c7

Для проверки результата работы можно использовать команду md5sum:

root@localhost:/home/dron# echo -n "0123456789" | md5sum

781e5e245d69b566979b86e28d23f2c7 -

Как видите совпадает. Этим набором функций можно хешировать большие объемы данных последовательно вызывая MD5_Update:

void MD5_Update(MD5_CTX *c, const void *data,

unsigned long len);

Но, если Вам требуется хешировать небольшие объемы данных целиком помещающиеся в буфер, то можно пользоваться упрощенной функцией:

unsigned char *MD5(const unsigned char *d, unsigned long n,

unsigned char *md);

Пример:

#include <stdio.h>

#include <stdlib.h>

#include <openssl/md5.h>

int main() {

int i;

MD5_CTX md5handler;

unsigned char md5digest[MD5_DIGEST_LENGTH];

MD5("0123456789",10, md5digest);

for (i=0;i<MD5_DIGEST_LENGTH;i++) {

printf("%02x",md5digest[i]);

};

printf("\n");

return 0;

};

Получается более компактное и красивое решение.

Использовать алгоритмы MD2 и MD4 можно аналогично, хотя сегодня они практически нигде не применяются, так как являются более старыми версиями.

Тут вы можете оставить комментарий к выбранному абзацу или сообщить об ошибке.

Оставленные комментарии видны всем.