ПЗ (1195114), страница 3
Текст из файла (страница 3)
UINT TCPHeadSize;
PUDPHeader UDPHead;
UINT UDPHeadSize;
char* Data;
int DataSize;
} TPacketInfo,*PPacketInfo;
Функция GetPraviloID просматривает таблицу правил и ищет правило, под которое подпадает пакет. Если правило чётко указывает что пакет надо запретить или разрешить, то функция возвращает номер правила. А если в правиле указан фильтр, то пакет передаётся в фильтр, который определяет, запретить пакет или нет, если нет, то просматриваются следующие правила.
3.5 Фильтр HTTP трафика
Фильтр HTTP трафика простаивает, пакеты и выискивает заголовки HTTP запросов, после этого расшифровывает их. Определяет Host и URL после чего просматривает на совпадение со списками, если фрагмент Host или URL совпал со списком то пакет содержащий данный запрос удаляется.
HTTP основывается на парадигме запросов/ответов. Запрашивающая программа (обычно она называется клиент) устанавливает связь с обслуживающей программой-получателем (обычно называется сервер) и посылает запрос серверу в следующей форме: метод запроса, URI, версия протокола, за которой следует MIME-подобное сообщение, содержащее управляющую информацию запроса, информацию о клиенте и, может быть, тело сообщения. Сервер отвечает сообщением, содержащим строку статуса (включая версию протокола и код статуса - успех или ошибка), за которой следует MIME-подобное сообщение, включающее в себя информацию о сервере, метаинформацию о содержании ответа, и, вероятно, само тело ответа. Следует отметить, что одна программа может быть одновременно и клиентом и сервером. Использование этих терминов в данном тексте относится только к роли, выполняемой программой в течение данного конкретного сеанса связи, а не к общим функциям программы.
В Интернет коммуникации обычно основываются на TCP/IP протоколах. Для WWW номер порта по умолчанию - TCP 80, но также могут быть использованы и другие номера портов - это не исключает возможности использовать HTTP в качестве протокола верхнего уровня. Поэтому при создании фильтра HTTP пакетов должен определять является ли пакет HTTP запросом или нет в независимости от порта на который или с которого идут пакеты.
Для большинства приложений сеанс связи открывается клиентом для каждого запроса и закрывается сервером после окончания ответа на запрос. Тем не менее, это не является особенностью протокола. И клиент, и сервер должны иметь возможность закрывать сеанс связи, например, в результате какого-нибудь действия пользователя. В любом случае, разрыв связи, инициированный любой стороной, прерывает текущий запрос, независимо от его статуса.
Фильтр HTTP трафика фильтрует только запросы так как в HTTP протоколе сервер не может передать какие либо данные без запроса.
Запрос - это сообщение, посылаемое клиентом серверу.
Первая строка этого сообщения включает в себя метод, который должен быть применен к запрашиваемому ресурсу, идентификатор ресурса и используемую версию протокола. Для совместимости с протоколом HTTP/0.9, существует два формата HTTP запроса:
-
простой запрос: «GET» SP Запрашиваемый-URI CRLF
-
полный запрос: Строка-Статус
*(Общий-Заголовок | Заголовок-Запроса | Заголовок-Содержания ) CRLF
[ Содержание-Запроса ]
Если HTTP/1.0 сервер получает Простой-Запрос, он должен отвечать Простым-Ответом HTTP/0.9. HTTP/1.0 клиент, способный обрабатывать Полный-Ответ, никогда не должен посылать Простой-Запрос.
Запрашиваемый-URI может быть двух типов: абсолютный-URL и относительный-URL. Абсолютный-URL допускается только при обращении к proxy серверу. Строка запроса, например, может иметь такой вид:
GET http://www.w3.org/pub/WWW/TheProject.html HTTP/1.0
Относительный-URL используется при прямом соединении. Например, для http://www.w3.org/pub/WWW/TheProject.html необходимо соединится с серверов www.w3.org, через TCP соединение на 80 порт и послать запрос:
GET /pub/WWW/TheProject.html HTTP/1.0
На одном сервере может быть несколько обслуживаемы хостов. В запрос добавляется параметр Host который записывается следующим образом:
Host: SP Имя_хоста CRLF
Заголовок полного запроса состоит из строк заканчивающихся символами CRLF и заканчивается пустой строкой то есть символами CRLFCRLF.
Для анализа HTTP запросов используется функция FilterHTTP которая анализирует данные в пакете и если он является HTTP запросом то извлекает из него такие данные как URL и Host. Для этого она делит пакет на строки дотех пор пока не поподётся пустая строка или не закончатся данные в пакете. После этого происходит анализ первой строки запроса.
Первая строка запроса является простым запросом или Статус строкой полного запроса.
Строка Статус начинается со строки с названием метода, за которым следует URI-Запроса и использующаяся версия протокола. Строка Статус заканчивается символами CRLF. Элементы строки разделяются пробелами (SP). В Строке Статус не допускаются символы LF и CR, за исключением заключающей последовательности CRLF.
Строка-Статус: Метод SP URI-Запроса SP «Версия-HTTP» CRLF
Следует отметить, что отличие Строки Статус Полного-Запроса от Строки Статус Простого- Запроса заключается в присутствии поля «Версия-HTTP».
Для определения является ли первое слова в стороке методом HTTP запросов вызывается функция IsHTTPMetod. Которая которая вкачестве параметря получает первую строку запроса. В в HTTP запросе могут быть сдующие методы: GET, HEAD, PUT, POST, DELETE, LINK, UNLINK
Метод GET служит для получения любой информации, идентифицированной URI-Запроса. Если URI- Запроса ссылается на процесс, выдающий данные, в качестве ответа будут выступать данные, сгенерированные данным процессом, а не код самого процесса (если только это не является выходными данными процесса).
Метод GET изменяется на «условный GET», если сообщение запроса включает в себя поле заголовка «If-Modified-Since». В ответ на условный GET, тело запрашиваемого ресурса передается только, если он изменялся после даты, указанной в заголовке «If-Modified-Since». Алгоритм определения этого включает в себя следующие случаи:
-
Если код статуса ответа на запрос будет отличаться от «200 OK», или дата, указанная в поле заголовка «If-Modified-Since» некорректна, ответ будет идентичен ответу на обычный запрос GET.
-
Если после указанной даты ресурс изменялся, ответ будет также идентичен ответу на обычный запрос GET.
-
Если ресурс не изменялся после указанной даты, сервер вернет код статуса «304 Not Modified».
Использование метода условный GET направлено на разгрузку сети, так как он позволяет не передавать по сети избыточную информацию.
Метод HEAD аналогичен методу GET, за исключением того, что в ответе сервер не возвращает «Тело-Ответа». Метаинформация, содержащаяся в HTTP заголовках ответа на запрос HEAD, должна быть идентична информации HTTP заголовков ответа на запрос GET. Данный метод может использоваться для получения метаинформации о ресурсе без передачи по сети самого ресурса. Метод "Условный HEAD", аналогичный условному GET, не определен.
Метод POST используется для запроса сервера, чтобы тот принял информацию, включенную в запрос, как субординантную для ресурса, указанного в Строке Статус в поле URI-Запроса. Метод POST был разработан, чтобы была возможность использовать один общий метод для следующих функций:
-
аннотация существующих ресурсов;
-
добавление сообщений в группы новостей, почтовые списки или подобные группы статей;
-
доставка блоков данных процессам, обрабатывающим данные;
-
расширение баз данных через операцию добавления.
Реальная функция, выполняемая методом POST, определяется сервером и обычно зависит от URI- Запроса. Добавляемая информация рассматривается как субординатная указанному URI в том же смысле, как файл субординатен каталогу, в котором он находится, новая статья субординатна группе новостей, в которую она добавляется, запись субординатна базе данных.
Клиент может предложить URI для идентификации нового ресурса, включив в запрос заголовок "URI". Тем не менее, сервер должен рассматривать этот URI только как совет и может сохранить тело запроса под другим URI или вообще без него.
Если в результате обработки запроса POST был создан новый ресурс, ответ должен иметь код статуса, равный "201 Created", и содержать URI нового ресурса.
Метод PUT запрашивает сервер о сохранении «Тело-Запроса» под URI, равным URI-Запроса. Если URI-Запроса ссылается на уже существующий ресурс, «Тело-Запроса» должно рассматриваться как модифицированная версия данного ресурса. Если ресурс, на который ссылается URI-Запроса не существует, и данный URI может рассматриваться как описание для нового ресурса, сервер может создать ресурс с данным URI. Если был создан новый ресурс, сервер должен информировать направившего запрос клиента через ответ с кодом статуса «201 Created». Если существующий ресурс был модифицирован, должен быть послан ответ «200 OK», для информирования клиента об успешном завершении операции. Если ресурс с указанным URI не может быть создан или модифицирован, должно быть послано соответствующее сообщение об ошибке.
Фундаментальное различие между методами POST и PUT заключается в различном значении поля URI-Запроса. Для метода POST данный URI указывает ресурс, который будет управлять информацией, содержащейся в теле запроса, как неким придатком. Ресурс может быть обрабатывающим данные процессом, шлюзом в какой-нибудь другой протокол, или отдельным ресурсом, допускающим аннотации. В противоположность этому, URI для запроса PUT идентифицирует информацию, содержащуюся в «Содержание-Запроса». Использующий запрос PUT точно знает какой URI он собирается использовать, и получатель запроса не должен пытаться применить этот запрос к какому-нибудь другому ресурсу.
Метод DELETE используется для удаления ресурсов, идентифицированных с помощью URI-Запроса. Результаты работы данного метода на сервере могут быть изменены с помощью человеческого вмешательства (или каким-нибудь другим способом). В принципе, клиент никогда не может быть уверен, что операция удаления была выполнена, даже если код статуса, переданный сервером, информирует об успешном выполнении действия. Тем не менее, сервер не должен информировать об успехе до тех пор, пока на момент ответа он не будет собираться стереть данный ресурс или переместить его в некоторую недостижимую область.
Метод LINK устанавливает взаимосвязи между существующим ресурсом, указанным в URI-Запроса, и другими существующими ресурсами. Отличие метода LINK от остальных методов, допускающих установление ссылок между документами, заключается в том, что метод LINK не позволяет передавать в запросе «Тело-Запроса», и в том, что в результате работы данного метода не создаются новые ресурсы.
Метод UNLINK удаляет одну или более ссылочных взаимосвязей для ресурса, указанного в URI- Запроса. Эти взаимосвязи могут быть установлены с помощью метода LINK или какого-нибудь другого метода, поддерживающего заголовок «Link». Удаление ссылки на ресурс не означает, что ресурс прекращает существование или становится недоступным для будущих ссылок/7/.
Для обработки HTTP запросов был разработан фильтр реализованный в функции FilterHTTP(Листинг 3.6).
Листинг 3.6 - Описание IP заголовка.
FW_Actions FilterHTTP(TPacketInfo* PI)
{
char* Text=PI->Data ;
bool HeadOK=false, NextLine=true;
int LinesLen[128], NumLine=0, i, N1=0;
char* Lines[128];
if (!PI->TCPHead) return FWA_Skip;
for(i=0;i<PI->DataSize&&Text[i]&&NumLine<128;i++)
{
if (NextLine)
{
Lines[NumLine] = Text+i;
LinesLen[NumLine]=0;
}
LinesLen[NumLine]++;
NextLine=false;
if ((N1==0||N1==2)&&Text[i]=='\r') {N1++;}
else if ((N1==1||N1==3)&&Text[i]=='\n'){N1++;}
else N1=0;
if (N1==2) {NumLine++;NextLine=true;};
if (N1==4) {HeadOK=true;break;}
}
if (i==PI->DataSize&&NumLine==0) {NumLine=1;HeadOK=true;} //Простой запрос
if (HeadOK&&NumLine>0)
{
if (LinesLen[0]>4&&IsHTTPMetod(Lines[0]))
{
int i=4, l;
char URL[128]="", HOST[128]="", HTTP[32]="";
int URLSize=0, HOSTSize=0, HTTPSize=0, HostN, URLN;
for(;i<LinesLen[0]&&Lines[0][i]&&Lines[0][i]!=' '&&URLSize<128;i++)
URL[URLSize++]=Lines[0][i];
URL[URLSize]=0;
if (LinesLen[0]>=i)















