Форум 1С
Программистам, бухгалтерам, администраторам, пользователям
Задай вопрос - получи решение проблемы
29 мар 2024, 16:30

Мониторинг лицензий

Автор worm2, 02 июл 2015, 11:34

0 Пользователей и 1 гость просматривают эту тему.

worm2

Здравствуйте!

Я не имею отношения к 1С, видел её только издалека.

Но мы для защиты нашей программы используем те же ключи HASP, что и 1С. И вот в связи с этим возник вопрос к специалистам по администрированию 1С.

Нам поставлена задача "...ведения на сервере лицензий Журнала Использования Лицензий, в который должна помещаться следующая имнформация: учетная запись пользователя, наименование модуля ПО, дата и время занятия лицензии, дата и время освобождения...". И было сказано, что "1С это делает".

Я прекрасно знаю штатные средства компании Aladdin для работы с сетевым ключом HASP: драйвер haspdinst, менеджер лицензий lmsetup, сетевой монитор aksmon, файлы конфигурации nethasp.ini, nhsrv.ini. Но этих средств недостаточно для решения поставленной задачи. У aksmon невозможно расширить функциональность, более того, протокол его общения с сервером по порту 475 является секретным. По порту 1947 можно найти массу диагностической информации, но сессии ключа (те, которые видит aksmon), почему-то, не видны. Мы используем только базовый (legacy) функционал ключей HASP, никаких новых фич HASP HL, Sentinel не используем.

Как же 1С делает это? Может, есть умельцы, которые смогли расшифровать протокол, или что-то ещё сделать? Видел в сети ссылки на какой-то "BaseHaspServer", но до скачивания не смог добраться.

Нет ли здесь специалистов, которые могут помочь в этом вопросе?

worm2

Сам себе отвечу.
В составе Aladdin HASP Monitor есть библиотека hsmon.dll.
Она экспортирует функцию с очень информативным названием "mightyfunc".
Сигнатура следующая:
extern "C" void __cdecl mightyfunc(const char *request, char *response, long *psize);
(может быть, не void, что она там возвращает, я не в курсе).
В request передаётся строка запроса (команда), в response помещается ответ. psize: на входе — указатель на размер буфера в байтах, на выходе — требуемый для полного ответа размер буфера.
Команды следующие:
SET CONFIG,FILENAME=".\nethasp.ini"
SCAN SERVERS
STATUS
GET SERVERS
GET LOGINS,HS,ID=<идентификатор менеджера лицензий>,MA=1
(есть ещё, но мне больше не надо было).
Вызываются в том порядке, в котором я написал.
После SET CONFIG должна ответить OK.
После SCAN SERVERS — SCANNING, затем нужно в цикле вызывать STATUS, пока не вернёт OK.
После этого GET SERVERS вернёт EMPTY, или одну, или несколько строк с описанием сервера, типа:
HS,ID=1281897265,NAME="SERVER",PROT="UDP(192.168.1.1)",VER="8.320",OS="WIN32"
Нужно выбрать нужный сервер и передавать его идентификатор в GET LOGINS. MA=1 — это номер ключа (если в сервер воткнуто несколько ключей, то может потребоваться указать другой номер ключа).
GET LOGINS возвращает EMPTY, или строки типа:
HS,ID=1281897265,MA="1",SLOT=3,INDEX=13,PROT="UDP(192.168.1.3)",TIMEOUT=450,NAME="Vasya-Pupkin"
Осталось их распарсить, и будет щастье (SLOT — это номер программы).

Для нелюбителей программировать есть утилита, которая делает всё сама:
https://www.zabbix.com/forum/showpost.php?p=96243&postcount=4
(Сам ZABBIX не нужен).

trim_

Добрый день, worm2!
Подскажите, пожалуйста, где можно взять список команд для библиотеки hsmon.dll?
В вашем сообщении (https://forum-baza.ru/index.php?topic=48218.0) есть описание некоторых из них, либо подскажите, как вы их узнали?!
Просто при использовании данных команд не удается корректно завершить приложение вызывающее библиотеку. Возможно, что-то требуется послать для корректного завершения работы с библиотекой...
Заранее благодарю!

worm2

Здравствуйте.
Цитата: trim_ от 03 ноя 2015, 14:10
Подскажите, пожалуйста, где можно взять список команд для библиотеки hsmon.dll?
В вашем сообщении (https://forum-baza.ru/index.php?topic=48218.0) есть описание некоторых из них. Либо подскажите, как вы их узнали?!
Я узнал о такой возможности из утилиты, на которую ссылался в том сообщении.
В той утилите есть примеры команд
SET CONFIG,FILENAME
SCAN SERVERS
GET SERVERS
GET LOGINS

Остальные команды можно выдрать из HSMON.DLL простым просмотром в бинарном редакторе:
GET SERVERINFO,ID=123
GET MODULES,ID=123
GET MODULEINFO,ID=123,MA="a"
GET SLOTS,ID=123,MA="a"
GET SLOTINFO,ID=123,MA="a",SLOT=7
GET LOGININFO,ID=123,MA="a",SLOT=7,INDEX=4
GET STATUS
STATUS
VERSION
HELP

Сигнатуру функции и порядок вызова узнал путём трассировки той программы, HaspMonitor.exe, под отладчиком.
Цитировать
Просто при использовании данных команд не удается корректно завершить приложение вызывающее библиотеку. Возможно, что-то требуется послать для корректного завершения работы с библиотекой...
Проверьте ещё раз внимательно сигнатуру:
extern "C" void __cdecl mightyfunc(const char *request, char *response, long *psize);
У меня в Delphi это выглядит так:
function mightyfunc(const Command: PAnsiChar; Answer: PAnsiChar; var AnswerSize: LongInt): LongInt; cdecl; external 'hsmon.dll';

Я вызываю её всегда с буфером, который содержит 65536 байт плюс один байт на нулевой терминатор строки:

function MonitorCommand(const Command: AnsiString): AnsiString;
var
  buffer: PAnsiChar;
  answerSize: Integer;
begin
  buffer := AllocMem(65537);
  try
    answerSize := 65536;
    mightyfunc(PAnsiChar(Command), buffer, answerSize);
    Result := StrPas(buffer);
  finally
    ReallocMem(buffer, 0);
  end;
end;

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

  answer := AnsiUpperCase(Trim(MonitorCommand('SCAN SERVERS')));
  i := 0;
  while (answer = 'SCANNING') and (i < ScanCycle{число секунд, сколько ждать ответа}) do
  begin
    Inc(i);
    Sleep(1000);
    answer := AnsiUpperCase(Trim(MonitorCommand('STATUS')));
  end;
  if answer = 'OK'
  then // серверы успешно просканированы

trim_

Цитата: worm2 от 24 ноя 2015, 16:15
buffer := AllocMem(65537);
Разобрался, проблема была в размере выделяемой памяти под буфер и передаваемый в функцию размер буфера. В моем случае потребовался больший размер response = new char[65536 * 1024];
Спасибо за хорошую наводку! 

Похожие темы (2)

Рейтинг@Mail.ru

Поиск