Я хотел бы собрать новую версию Open Pegasus Client (2.14.1). К сожалению, я столкнулся с некоторыми проблемами сборки. Кто-нибудь знает обходной путь для этих проблем?
Моя среда это:
Мой сценарий довольно прост:
После извлечения исходного кода Pegasus я установил свою среду с
эти настройки:
call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\vcvars32.bat"set PEGASUS_ROOT=D:/Dev/pegasus-2.14.1/pegasus
set PEGASUS_HOME=%PEGASUS_ROOT%
set PEGASUS_PLATFORM=WIN32_IX86_MSVC
set path=%path%;%PEGASUS_HOME%\bin
set OPENSSL_HOME=D:/Dev/OpenSSL-Win32
set PEGASUS_HAS_SSL=true
Следующим шагом было создание инструмента mu.exe. Итак, я выполнил «сделать
buildmu «=> успешно собрать и скопировать в папку» / bin «.
нравится собирать Пегас так: «make build» => через некоторое время я получил это
ошибка:
Message.cpp (433): ошибка C2065: «магия»: необъявленный идентификатор
Я пытался решить эту проблему. Я обнаружил, что магическая константа определена
в файле \ pegasus-2.14.1 \ pegasus \ src \ Pegasus \ Common \ Linkable.h, чтобы я
было две опции: а) Переключить конфигурацию сборки на DEBUG (установить
PEGASUS_DEBUG = true) б) Удалить условие DEBUG из строк 62 в
Файл Linkable.h Затем я попытался собрать Pegasus снова, к сожалению,
Я получил эту ошибку:
ошибка LNK2005: _OPENSSL_Applink уже определено в SSLContext.obj
На данный момент я понятия не имею, как решить эту проблему. Я просто попытался удалить эти строки:
# ifdef PEGASUS_OS_TYPE_WINDOWS
# include<openssl/applink.c>
# endif
из файла SSLContextRep.h. После этой модификации мне удалось получить клиенты Pegasus с двоичными файлами. Но эти двоичные файлы работают только без SSL, когда я хочу использовать SSL-связь, у меня всегда получалось сообщение об ошибке: «Исключение Pegasus:« Не удается подключиться к 10.199.1.139:5989. Соединение не удалось. ».», Поэтому я предполагаю, что это из-за модификации моего кода в SSLContextRep.h.
Выходы от Pegasus Tracer:
SSL: не подключен 1 ошибка: 140740BF: подпрограммы SSL: SSL23_CLIENT_HELLO: протоколы недоступны
SSL: удаленный сокет SSL
Кто-нибудь знает, что может быть не так? Есть ли у кого-нибудь (лучше) шаги по настройке среды для Windows для сборки OpenPegasus?
Заранее большое спасибо за любую помощь.
Редактировать:
Мне нужно уметь работать без сертификатов. Потому что я использую связь SSL с различными массивами хранения и у меня нет их сертификатов. Поэтому я использую этот конструктор SSLContext:
SSLContext sslContext(String::EMPTY, NULL, String::EMPTY);
у меня этот подход прекрасно работает в версии OpenPegasus 2.13.
Outputs from Pegasus Tracer:
SSL: Not connected 1 error:140740BF:SSL routines:SSL23_CLIENT_HELLO:no protocols available SSL: Deleted SSL socket
Вот откуда пришло сообщение:
$ grep -nR "Deleted SSL socket" *
src/Pegasus/Common/TLS.cpp:172: PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3, "---> SSL: Deleted SSL socket");
И код вокруг строки 172:
SSLSocket::~SSLSocket()
{
PEG_METHOD_ENTER(TRC_SSL, "SSLSocket::~SSLSocket()");
close();
delete static_cast<SharedPtr<X509_STORE, FreeX509STOREPtr>*>(_crlStore);
SSL_free(static_cast<SSL*>(_SSLConnection));
PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3, "---> SSL: Deleted SSL socket");
PEG_METHOD_EXIT();
}
Если вы посмотрите в .../src/Pegasus/Common/SSLContext.cpp
, ты увидишь:
SSL_CTX* SSLContextRep::_makeSSLContext()
{
PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::_makeSSLContext()");
//
// create SSL Context Area
//
SSL_CTX *sslContext = NULL;
if (!(sslContext = SSL_CTX_new(SSLv23_method())))
{
PEG_METHOD_EXIT();
MessageLoaderParms parms(
"Common.SSLContext.COULD_NOT_GET",
"Could not get SSL CTX");
throw SSLException(parms);
}
int options = SSL_OP_ALL;
SSL_CTX_set_options(sslContext, options);
if ( _sslCompatibility == false )
{
#ifdef TLS1_2_VERSION
// Enable only TLSv1.2 and disable all other protocol (SSL v2, SSL v3,
// TLS v1.0, TLSv1.1)
options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_SSLv3;
#else
PEG_METHOD_EXIT();
MessageLoaderParms parms(
" Common.SSLContext.TLS_1_2_PROTO_NOT_SUPPORTED",
"TLSv1.2 protocol support is not detected on this system. "" To run in less secured mode, set sslBackwardCompatibility=true"" in planned config file and start cimserver.");
throw SSLException(parms);
#endif
}
// sslv2 is off permanently even if sslCompatibility is true
options |= SSL_OP_NO_SSLv2;
SSL_CTX_set_options(sslContext, options);
#ifdef PEGASUS_SSL_WEAKENCRYPTION
if (!(SSL_CTX_set_cipher_list(sslContext, SSL_TXT_EXP40)))
{
SSL_CTX_free(sslContext);
sslContext = NULL;
MessageLoaderParms parms(
"Common.SSLContext.COULD_NOT_SET_CIPHER_LIST",
"Could not set the cipher list");
throw SSLException(parms);
}
#endif
if (_cipherSuite.size() != 0)
{
if (!(SSL_CTX_set_cipher_list(sslContext, _cipherSuite.getCString())))
{
SSL_CTX_free(sslContext);
sslContext = NULL;
PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3,
"---> SSL: Cipher Suite could not be specified");
MessageLoaderParms parms(
"Common.SSLContext.COULD_NOT_SET_CIPHER_LIST",
"Could not set the cipher list");
throw SSLException(parms);
}
else
{
PEG_TRACE((TRC_SSL, Tracer::LEVEL3,
"---> SSL: Cipher suite set to %s",
(const char *)_cipherSuite.getCString()));
}
}
...
}
Я бы отказался от этой функции по двум причинам и вместо этого добавил бы что-то вроде следующего.
Во-первых, это одна из тех аморфных процедур, написанных как для клиента, так и для сервера. Из моего опыта работы с OpenSSL я узнал, что у вас есть отдельные функции для SSL_CTX* GetClientContext()
а также SSL_CTX* GetServerContext()
,
Во-вторых, с точки зрения безопасности, вы не позволяете людям входить в плохое состояние с такими вещами, как PEGASUS_SSL_WEAKENCRYPTION
или пустой список шифров. Вы убираете пистолет, чтобы они не могли выстрелить себе в ногу.
SSL_CTX* SSLContextRep::_makeSSLContext()
{
PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::_makeSSLContext()");
SSL_CTX *sslContext = NULL;
if (!(sslContext = SSL_CTX_new(SSLv23_method())))
{
PEG_METHOD_EXIT();
MessageLoaderParms parms(
"Common.SSLContext.COULD_NOT_GET",
"Could not get SSL CTX");
throw SSLException(parms);
}
// TLS 1.0 and above. No compression because it leaks information.
static const long options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION;
SSL_CTX_set_options(sslContext, options);
const char* const PREFERRED_CIPHERS = "HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4";
int res = SSL_set_cipher_list(sslContext, PREFERRED_CIPHERS);
if(res != 1)
{
PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3,
"---> SSL: Cipher Suite could not be specified");
MessageLoaderParms parms(
"Common.SSLContext.COULD_NOT_SET_CIPHER_LIST",
"Could not set the cipher list");
throw SSLException(parms);
}
// Keep this stuff
SSL_CTX_set_quiet_shutdown(sslContext, 1);
SSL_CTX_set_mode(sslContext, SSL_MODE_AUTO_RETRY);
SSL_CTX_set_mode(sslContext, SSL_MODE_ENABLE_PARTIAL_WRITE);
SSL_CTX_set_session_cache_mode(sslContext, SSL_SESS_CACHE_OFF);
SSL_CTX_set_mode(sslContext, SSL_MODE_RELEASE_BUFFERS);
// Back to gutting. We don't allow VERIFY_PEER_NONE.
{
PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4,
"---> SSL: certificate verification callback specified");
SSL_CTX_set_verify(sslContext,
SSL_VERIFY_PEER, prepareForCallback);
}
// Some more gutting. Certificates have to be verified.
if(_trustStore.size() == 0)
{
PEG_TRACE((TRC_SSL, Tracer::LEVEL1,
"---> SSL: Could not load certificates from the ""trust store: %s",
(const char*)_trustStore.getCString()));
MessageLoaderParms parms(
"Common.SSLContext.COULD_NOT_LOAD_CERTIFICATES",
"Could not load certificates in to trust store.");
SSL_CTX_free(sslContext);
sslContext = NULL;
PEG_METHOD_EXIT();
throw SSLException(parms);
}
if ( !SSL_CTX_load_verify_locations(
sslContext, _trustStore.getCString(), NULL) )
{
PEG_TRACE((TRC_SSL, Tracer::LEVEL1,
"---> SSL: Could not load certificates from the ""trust store: %s",
(const char*)_trustStore.getCString()));
MessageLoaderParms parms(
"Common.SSLContext.COULD_NOT_LOAD_CERTIFICATES",
"Could not load certificates in to trust store.");
SSL_CTX_free(sslContext);
sslContext = NULL;
PEG_METHOD_EXIT();
throw SSLException(parms);
}
// I'm not sure what to do with CRLs. They are usually a DoS waiting to happen....
if (_crlPath.size() != 0)
{
// need to save this -- can we make it static since there's only
// one CRL for cimserver?
X509_LOOKUP* pLookup;
_crlStore.reset(X509_STORE_new());
if (_crlStore.get() == NULL)
{
SSL_CTX_free(sslContext);
sslContext = NULL;
PEG_METHOD_EXIT();
throw PEGASUS_STD(bad_alloc)();
}
// the validity of the crlstore was checked in ConfigManager
// during server startup
if (FileSystem::isDirectory(_crlPath))
{
PEG_TRACE((TRC_SSL, Tracer::LEVEL4,
"---> SSL: CRL store is a directory in %s",
(const char*)_crlPath.getCString()));
if ((pLookup = X509_STORE_add_lookup(
_crlStore.get(), X509_LOOKUP_hash_dir())) == NULL)
{
MessageLoaderParms parms(
"Common.SSLContext.COULD_NOT_LOAD_CRLS",
"Could not load certificate revocation list.");
_crlStore.reset();
SSL_CTX_free(sslContext);
sslContext = NULL;
PEG_METHOD_EXIT();
throw SSLException(parms);
}
X509_LOOKUP_add_dir(
pLookup, (const char*)_crlPath.getCString(), X509_FILETYPE_PEM);
PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3,
"---> SSL: Successfully configured CRL directory");
}
else
{
PEG_TRACE((TRC_SSL, Tracer::LEVEL4,
"---> SSL: CRL store is the file %s",
(const char*)_crlPath.getCString()));
if ((pLookup = X509_STORE_add_lookup(
_crlStore.get(), X509_LOOKUP_file())) == NULL)
{
MessageLoaderParms parms(
"Common.SSLContext.COULD_NOT_LOAD_CRLS",
"Could not load certificate revocation list.");
_crlStore.reset();
SSL_CTX_free(sslContext);
sslContext = NULL;
PEG_METHOD_EXIT();
throw SSLException(parms);
}
X509_LOOKUP_load_file(
pLookup, (const char*)_crlPath.getCString(), X509_FILETYPE_PEM);
PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4,
"---> SSL: Successfully configured CRL file");
}
}
Boolean keyLoaded = false;
// Gut server specific certificate and key routines since this is a client.
PEG_METHOD_EXIT();
return sslContext;
}
TLS 1.2 и наборы шифров AEAD являются очень хороший выбор. Однако для большинства целей TLS 1.0 и выше вполне подойдет.
Я думаю, что это может быть причиной 0x140740BF
в клиенте. Это из линии SSLContext.cpp
824:
SSL_CTX_set_verify(sslContext,
SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, prepareForCallback);
Похоже, сервер требует сертификат.
… но обычно вы получаете другое предупреждение TLS.
И источники не называют SSL_set_tlsext_host_name
Таким образом, SNI, кажется, сломан. Вам, вероятно, следует подать отчет об ошибке для этого …
$ grep -nR SSL_set_tlsext_host_name *
$
Вам нужно будет выяснить, где клиент устанавливает соединение, и установить его как SSL*
опция:
SSL_set_tlsext_host_name(ssl, hostname);
Где-то вокруг SSLSocket::SSLSocket
может быть хорошим выбором, потому что его конструктор принимает строку и sslConnection
доступно в КТО.
SSLSocket::SSLSocket(
SocketHandle socket,
SSLContext * sslcontext,
ReadWriteSem * sslContextObjectLock,
const String& ipAddress)
Но я почти уверен, что вам нужно DNS-имя, а не IP-адрес, потому что мультиплексирование разных серверов на одном IP-адресе вызвало необходимость SNI.
Но я могу ошибаться. const String& ipAddress
на самом деле может быть имя DNS.
Я получил ответ от команды разработчиков Open Pegasus. Они создали ошибку для проблемы с «волшебной» константой. Также они рекомендуют в моем случае использовать конфигурацию sslBackwardCompatibility = true для сборки.
Эта настройка помогла мне частично. Для некоторых массивов хранения связь SSL начала работать. Но для некоторых это все еще сообщает исключение «Не удается подключиться».
Единственный обходной путь, который я нашел, — заменить код метода _makeSSLContext () на код из версии OpenPegasus 2.13. После этой модификации я могу использовать связь SSL со всеми моими массивами хранения + все функции из новой версии Pegasus.