Персональный сайт Шикарева Игоря Валентиновича
 Главная  Статьи  Разработки  Ссылки  О себе  Карта сайта

 

Как подружить OpenSSL и библиотеку Synapse.

     Фирма, в которой я в настоящее время тружусь, занимается написанием и сопровождением софта для касс и киосков по приему коммунальных платежей от населения. Помимо приема коммунальных платежей, кассы принимают платежи за сотовые телефоны, Яндекс-Деньги, WebMoney. Такие платежи проводятся через систему E-Port (http://www.e-port.ru/). С ноября 2007 года непременным требованием E-Port стало, чтобы все поступающие пакеты в их систему имели цифровую подпись. Формирование закрытого и открытого ключа решено было делать при помощи OpenSSL (http://www.openssl.org/), а отсылки/приему пакетов, для большего контроля за происходящим решено было применять классы из библиотеки Synapse (http://www.ararat.cz/synapse/). Тем более в библиотеки была реализована возможность работы  по протоколу HTTPS. Программа, по передачи пакетов, была успешно модернизирована под новые требования, разработчики довольно потирали руки… Но как говорит народная мудрость: «Не все скоту (видимо близкий родич кота) масленица». При боевых испытаниях сервер приложений упорно останавливался с ошибкой, что не может загрузить библиотеку libeay32.dll, хотя библиотеки libssl32.dll и libeay32.dll исправно лежали рядом с сервером приложений. Повторное тестирование на компьютере разработчика не внесло ясности, так как обычно у разработчика все всегда исправно работает. Поиски по интернету не дали вразумительного ответа, только насторожило большое количество криков о помощи по поводу ошибок при работе компонентов Indy и OpenSSL. Как лекарство, предлагалось скачать «специальные рабочие» версии пары библиотек libssl32.dll и libeay32.dll. Скачивание «рабочих» версий не решало у нас проблему остановки сервера приложений из-за библиотеки libeay32.dll. Найти верную тропу для решения проблемы помог случай (а верней Ангел-хранитель подсказал, слава Богу!)… было вдруг замечено, что после запуска программы Macromedia Dreamweaver 8, и на машине разработчика возникала похожая ошибка о невозможности загрузить библиотеку libeay32.dll. После перегрузки компьютера, сервер приложений опять исправно начинал работать. Устроили с разработчиками маленький мозговой штурм и пришли к выводу (тут конечно гуру, которые разбираются в тонкостях загрузки библиотек в память операционной системы, могут меня поправить), что операционная система грузит в память библиотеки с использованием механизма отображения файлов в память, как идентификатор скорей всего используется имя самой библиотеки. Т.е. если какое-то приложение уже обратилось к библиотеки libssl32.dll или libeay32.dll (к слову, Dreamweaver тоже использует пару libssl32.dll и libeay32.dll), то скорей всего моя программа при обращении к этим библиотекам получит уже отображенные в памяти их образы, а не будет загружать библиотеки, лежащие рядом с приложением. Проблему усложняет то, что libssl32.dll и libeay32.dll должны быть одной версии. У меня на некоторых машинах при испытаниях сервер приложений останавливался с ошибкой, что версия libeay32.dll не соответствует версии libssl32.dll.
            На мой взгляд есть несколько решений возникшей проблемы:

  1. Использовать механизм инъекций в DLL, чтобы перехватывать вызов LoadLibrary и «подсовывать» нужную DLL при загрузки.
  2. Можно с помощью редактора PE информации поправить в libssl32.dll вызовы libeay32.dll на вызовы, к примеру, только_моя_dll_libeay32.dll
  3. Скачать исходники libssl32.dll и libeay32.dll и поправить их так, чтобы после компиляции получались DLL с именами synapse_libeay32.dll и synapse_libssl32.dll, и поправить исходники synapse, чтобы вызывались библиотеки с новыми именами.

Нами был выбран третий вариант, так как он был более понятен в реализации, а может быть просто на другие варианты не хватило мозгов. С сайта OpenSSL (http://www.openssl.org/), были скачаны исходники библиотеки openssl-0.9.8f.tar.gz, среда для компиляции была взята MinGW  (http://www.mingw.org). Для того чтобы после компиляции библиотек получились имена synapse_libeay32.dll и synapse_libssl32.dll, необходимо в исходниках проделать следующие изменения:

в файле util\mkdef.pl необходимо все вхождения строк SSLEAY и LIBEAY заменить на SYNAPSE_SSLEAY и SYNAPSE_LIBEAY соответственно. Для более точного понимания какие строки подверглись изменению, оригинальный текст файла сохранен в util\mkdef-orig.pl. Использую утилиту WinMerge, можно сравнить файлы по содержимому и увидеть какие строки подверглись модификации.
Аналогичную процедуру необходимо проделать и с ms\mingw32.bat (оригинальный файл сохранен под именем ms\mingw32-orig.bat). Хочу заострить внимание читателя, что для утилиты dllwrap необходимо добавить ключ --nodelete, чтобы запретить удаление файлов dll, после завершения процесса компиляции и линковки.

Итак, исходники поправили, теперь можно приступить к процессу компиляции. Перед началом надо убедиться, что в путях поиска Windows содержатся пути до интерпретатора Perl и подкаталога bin в каталоге куда установлена MinGW. В командной строке переходим в каталог  openssl-0.9.8f и запускаем ms\mingw32.bat. После окончания компиляции и линковки, в каталоге openssl-0.9.8f должны появиться два долгожданных файлика synapse_libeay32.dll и synapse_libssl32.dll. Если звезды для Вас сегодня неправильно расположены, то можно попытаться поправить карму, путем решения ошибок, на которых споткнулся процесс сборки. Либо скачать уже готовые библиотеки с моего сайта
synapse_openssl_dll.zip

Осталось заменить в файле ssl_openssl_lib.pas библиотеки Synapse (http://www.ararat.cz/synapse/) ssleay32.dll и libeay32.dll на synapse_ssleay32.dll и synapse_libeay32.dll соответственно.

Описанное выше решение конфликтов библиотек OpenSSL, позволило сделать систему по обмену с E-Port стабильной и не зависимой от DLL HELL.

Автор:
Шикарев Игорь Валентинович (инженер-программист).

Скомпилированные библиотеки OpenSSL версии 0.9.8f: synapse_openssl_dll.zip
Модифицированные исходники библиотеки OpenSSL версии 0.9.8f: openssl-0_9_8f-synapse.rar

 

 
Hosted by uCoz