Для иллюстрации мониторинга подключений создадим новое приложение и сразу же подключим к нему заголовочный файл NetAPI. На форме нам понадобятся один компонент типа Tl istView - для отображения подключений и две кнопки - для получения из системы текущих подключений и удаления выделенного подключения. Для компонента TListView нужно выполнить следующие изменения:

• в свойстве Name указать имя lwSessions;
• в свойстве Vi ewStyl е установить значение vsReport;

• дважды щелкнуть левой кнопкой мыши на свойстве Columns и в редакторе колонок создать 5 колонок со следующими именами:

о Компьютер - для отображения имени или адреса компьютера, подключенного к нашему компьютеру;
о Пользователь - учетная запись, которая используется при входе;
о Открыто - сколько файлов открыто пользователем;
о Время - в течение какого времени пользователь находится в системе;
о Простаивает - сколько времени пользователь находится в системе в неактивном состоянии, то есть подключен, но не работает с сетью;
о Тип - тип клиента, подключившегося к системе. В данном поле выводится ОС клиента. Это поле будет заполняться только для NT-систем;

о Протокол - какой протокол используется. При подключении через сетевое окружение мы сможем увидеть в этой колонке /Device/NetBiosSmb. Поле будет заполняться только для NT-систем.

Для того чтобы компонент TListView стал еще более удобным, можно изменить следующие свойства:

• RowSelect - установим в true, чтобы при выборе элемента выделялась вся строка;
• HideSelection - установим в false, чтобы при потере фокуса выделение не исчезало;

• GridLines - установим в true, чтобы отображать сетку. На рис. 5.16 вы можете увидеть форму будущей программы.

5.9.1. Просмотр подключений

На этом визуальное оформление закончено, переходим к программированию.

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

private {Private declarations} bNT: Boolean:
fHandleNT. fHandle9x: THandle: SessionKeys: array [0 .1024] of Integer:

Назначение всего, кроме SessionKeys, должно быть понятно (см. раздел 5.8). Массив SessionKeys будет использоваться для хранения ключей, которые необходимы при удалении в 9х-системах.

По событию OnShow для формы делаем проверку ОС, загрузку библиотеки и нужных функций (листинг 5.20).

Листинг 5.20. Опредедение ОС и загрузка нужной бибпиотеки

procedure TMonitorForm.FormShow(Sender: TObject): var
ver: TOSVersionlnfo: begin
ver.dwOSVersionlnfoSize := SizeOf(TOSVersionlnfo);
GetVersionEx(Ver):
case Ver.dwPlatformld of
VER_PLATF0RM_WIN32_NT: bNT := True:
VER_PLATF0RH_WIN32_WIND0WS: bNT := False:
VER_PLATF0RH_WIN32s: bNT := False
end:
if bNT then
begin
fHandleNT = LoadLibraryC-NETAPI32.DLL1).
@NetSessionEnumNT := GetProcAddress(fHandleNT. 'NetSessionEnum'): @NetSessionDelNT := GetProcAddress(fHandleNT. 'NetSessionDel'):
end
else
begin
fHandle9x .= LoadLibraryCSVRAPI.DLL').
@NetSessionEnum := GetProcAddress(fHandle9x. 'NetSessionEnum'): @NetSessionDel := GetProcAddress(fHandle9x. 'NetSessionDel');
end;
end;

Код похож на тот, что мы использовали в разделе 5.8, только здесь сразу же определяются адреса нужных функций NetSessionEnum и NetSessionDel (их назначение мы рассмотрим чуть позже). Таким образом, затрачивается несколько процессорных тактов при загрузке, но эти же такты экономятся при каждом обращении к функциям.

Теперь посмотрим на код, который должен выполняться по нажатии кнопки Показать (листинг 5.21).

Листинг 5.21. Получение списка подключений

procedure TMomtorForm.bnShowClick(Sender: TObject): var
Sessionlnfo50: array [0..1024] of TSessionInfo50; Sessionlnfo502: PSessionInfo502Array. TotalEntries. EntriesReadNT: DWORD;
EntriesRead. TotalAvial- Word;
i: integer: begin
1wSess i ons.Iterns.CI ea r;

if bNT then begin // Далее идет код для NT-систем Sessionlnfo502 := nil.

if NetSessionEnumNTCnil. nil. nil. 502. @SessionInfo502.
DWORD(-l). @entriesreadNT. @totalentries, nil) <> 0 then
exit:
for i := 0 to EntriesReadNT-1 do begin
with lwSessions.Items.Add do begin
Caption := string(SessionInfo502"[i].sesi502_cname):
Sublterns.Add(SessionInfo502"[i].sesi502_username):
Sublterns.Add(IntToStr(Sess i onInfo502"[i].ses i 502_num_opens)):
SubI terns.Add(Ti meToStr(Ses s i onInfo502"[i].Ses i 502_Ti me));
продолжение &

Листинг 5.21 (продолжение) Subltems Add(TimeToStr(SessionInfo502"[i] se"si502_id1e_time)). SubI terns.Add(Sess i on In fо502л[i].Ses i 502_c1typejiame): Subltems.Add(SessionInfo502*[i].Sesi502_transport): end, end:

end else begin // Далее идет код для 9х-систем

if NetSessionEnum(nil, 50, @SessionInfo50, SizeOf(SessionInfo50).
@EntnesRead. @TotalAvial) <> 0 then
exit:
for i =0 to EntriesRead-1 do begin
with lwSessions Items.Add do begin
Caption := string(SessionInfo50[i].Sesi50_cname): Subltems.Add(SessionInfo50[i].Sesi50_username);
Sublterns.Add(IntToStr(Sess i onInfo50[i].ses i 50_num_opens)): Subltems.Add(TimeToStr(Sessionlnfo50[i].Sesi50_Time)): Sublterns.Add(Ti meToSt r (Ses s i on I nf o50 [ i ]. ses i 50_i dl e_t i me)): SessionKeys[i]:= Sessionlnfo50[i] sesi50_key.
end: end;
end:
end:

Код разбит на две части - для NT-систем и для Эх-систем. В каждой из частей вызывается функция NetSessionEnumNT или NetSessionEnum (в зависимости от ОС) для получения списка подключений. После этого содержимое списка переносится в список ListView.

Функции NetSessionEnum и NetSessionEnumNT считывают подключения и работают в разных системах. Функцию NetSessionEnumNT нужно использовать в NT-системах. Она описывается следующим образом:

function NetSessionEnumNT(
ServerName.
UncClientName.
UserName: PWideChar;
Level: DWORD:
BufPtr: Pointer;
Prefmaxlen: DWORD;
EntriesRead.
Total Entries.
ResumeJHandle. LPDWORD )• DWORD: stdcall:

В Windows 9х используется NetSessionEnum, которая имеет следующий вид:

NetSessionEnum: function(
pszServer- PChar:
sLevel: DWORD:
pbBuffer: Pointer:
cbBuffer DWORD:
pcEntriesRead.
pcTotalAvial: Pointer ): integer: stdcall:

Рассмотрим параметры функции NetSessionEnumNT, для NetSessionEnum они имеют аналогичное значение:

• ServerName - имя сервера, на котором нужно просмотреть подключения;
• UncClientName - имя сессии компьютера, информацию о которой необходимо получить. Если имя не указано, то будут получены все сессии;
• UserName - имя пользователя, о котором нужно получить информацию о подключениях. Укажите нулевое значение, чтобы получить информацию о подключениях на всех учетных записях;

• Level - уровень получения информации. От уровня зависит структура возвращаемых данных; .

• BufPtr - указатель на буфер, через который будут возвращены данные;
• Prefmaxlen - количество записей, которые надо получить. Если указать -1, то-будут получены все записи;
• Entri esRead - через этот параметр нам вернут действительное количество прочитанных записей;
• Total Entries - через этот параметр нам вернут количество записей в системе. Если этот параметр равен Entri esRead, то мы прочитали все;

• Resume_Handl е - если вы запросили не все записи и увидели, что параметр Total -Entries больше Entri esRead, то есть прочитаны не все записи, то в данном параметре можно указать запись, с которой нужно начать перечисление для получения оставшихся записей.

Данные о подключении будут возвращаться в виде массива структур TSession-Info502 для NT-систем и TSessionInfo50 для 9х-систем. Эти структуры имеют следующий вид:

TSessionInfo502 = packed record Sesi502_cname: PWideChar;
Sesi502_username: PWideChar: Sesi502_num_opens: DWORD: Sesi502_time. DWORD: Sesi502_idle_time: DWORD: Sesi502_user_flags: DWORD: Sesi502_cltype_name: PWideChar: Sesi502_transport: PWideChar:
end;
TSessionInfo50 = packed record
Sesi50_cname: PChar;
Sesi50_username: PChar: sesi50_key: Cardinal: sesi50_num_conns: Word. sesi50_num_opens: Word. sesi50_time: Cardinal, sesi50_idle_time: Cardinal: sesi50_protocol: Byte;
padl: Byte:
end:

Большинство параметров схожи и имеют основные отличия в типах. Рассмотрим параметры структуры TSessionInfo502:

• sesi502_cname - имя клиента, запросившего соединение;
• sesi502_username - имя пользователя, под которым работает клиент. Это учетная запись, от нее зависят права;
• sesi502_num_opens - текущее количество открытых файлов, устройств или каналов;
• sesi502_time - время пребывания в системе. Время указано в виде целого числа, и о его преобразовании в часы, минуты, секунды мы поговорим чуть позже;
• sesi502_idle_time - время простоя с момента последнего обращения к ресурсам машины. Время указано в виде целого числа, и о его преобразовании в часы, минуты, секунды мы поговорим чуть позже;
• sesi502_user_flags - флаги, которые могут принимать следующие значения: О SESS_GUEST - используемая учетная запись является гостевой;
О SESS_NOENCRYPTION - клиент запросил соединение без шифрования пароля;
• . se$i502_cltype_name - тип клиента;

• sesi502_transport - протокол, используемый для подключения.

Для Windows 9х в структуре TSessionInfo50 очень важным параметром является sesi50_key. Это ключевое поле, которое позволяет однозначно идентифицировать сессию. Данный ключ впоследствии понадобится для закрытия сессии. Именно поэтому поле сохраняется в отдельном массиве для дальнейшего использования при закрытии.

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

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

1. Следила за тем, чтобы в системе не было подключений сразу двух администраторов. Если оказывается два "админа", то выдается сообщение, и я прослеживаю, откуда и кто пытается использовать такие высокие права на моем сервере.

2. Выдавала сообщение, когда подключения по определенным учетным записям выходили за пределы допустимого.

5.9.1. Просмотр подключений

Рис. 5.17. Результат работы программы

3. Когда адрес подключившегося компьютера не соответствовал допустимому в моей сети, появлялось предупреждающее сообщение.

Для решения подобных задач нужно постоянно обновлять информацию о соединениях и следить за количеством подключений с определенными правами (учетными записями). Попробуйте сами решить эти задачи. Главное - сделать это эффективно и с наименьшей нагрузкой. Могу сказать, что не надо "сканировать" без перерыва, можно установить промежуток в одну секунду. Если кто-то успел подключиться за этот промежуток времени и выйти из системы, то он, скорее всего, не успел сделать ничего вредного и такие подключения можно игнорировать.

ПРИМЕЧАНИЕ -

Исходный код рассмотренного здесь примера находится на компакт-диске в каталоге 5оигсез\сЬ05\Моп№ог5е55ЮП.

5.9. Мониторинг сетевой активности || Оглавление || 5.9.2. Преобразование времени


Delphi в шутку и всерьез: что умеют хакеры



Новости за месяц

  • Декабрь
    2021
  • Пн
  • Вт
  • Ср
  • Чт
  • Пт
  • Сб
  • Вс
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31