2015-06-01 10 views
3

Я хотел бы создать новую версию Open Pegasus Client (2.14.1). К сожалению, я столкнулся с некоторыми проблемами сборки. Кто-нибудь знает об обходном пути для этих проблем?Open Pegasus 2.14.1 проблема с подключением клиента

Моя среда:

  • ОС: Windows 8.1 Enterprise
  • Make версия: GNU Make 3.81
  • Pegasus источники версии: 2.14.1
  • OpenSSL версии: 1.0.2a

Мои сценарий довольно прост:

  1. Я загрузил исходный код Open Pegasus 2.14.1
  2. Я загрузил двоичные файлы OpenSSL (фактическая версия v1.0.2a).
  3. После извлечения исходного кода 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 
    
  4. Следующий шаг был строительство mu.exe инструмента. Итак, я выполнил «make buildmu» => успешно созданный и скопированный в папку «/ bin». Я бы хотел построить Pegasus так: "сделать сборку" => через некоторое время я получил эту ошибку:

    message.cpp (433): ошибка C2065: 'волшебный': необъявленный идентификатор

  5. Я попытался исправить эту проблему. Я обнаружил, что магия константа определена в файле \ pegasus-2.14.1 \ pegasus \ src \ Pegasus \ Common \ Linkable.h, поэтому у меня было два варианта: a) Сконфигурировать конфигурацию сборки в DEBUG (установить PEGASUS_DEBUG = true) b) Удалить условие DEBUG из линий 62 в Linkable.h файл Затем я снова попытался построить Пегас, к сожалению, я получил эту ошибку:

    ошибка LNK2005: _OPENSSL_Applink уже определен в SSLContext.obj

На данный момент я не имею понятия, как исправить эту проблему. Я просто попытался удалить эти строки:

# ifdef PEGASUS_OS_TYPE_WINDOWS 
# include<openssl/applink.c> 
# endif 

из файла SSLContextRep.h. После этой модификации я смог получить двоичные файлы клиентов Pegasus. Но эти двоичные файлы работают без SSL, когда я хочу использовать SSL-связь, я всегда получал ошибку: « Pegasus Exception:« Не удается подключиться к 10.199.1.139:5989. Ошибка подключения. »., Поэтому я предполагаю, что это потому, что мой код модификация в SSLContextRep.h.

Выходы из Pegasus Tracer:

SSL: Не подключен 1 ошибка: 140740BF: SSL процедуры: SSL23_CLIENT_HELLO: нет протоколов, доступных SSL: разъем Исключен SSL

Кто-нибудь знает, что может быть не так?Кто-нибудь владеет некоторыми (лучшими) шагами настройки среды для Windows для создания OpenPegasus?

Большое спасибо за любую помощь.


Edit:

Мне нужно, чтобы иметь возможность работать без сертификатов. Потому что я использую SSL-связь с различными массивами хранения, и у меня нет их сертификатов. Поэтому я использую этот конструктор SSLContext:

SSLContext sslContext(String::EMPTY, NULL, String::EMPTY); 

этот подход работает для меня штраф в версии OpenPegasus 2.13.

+0

я смог запустить OpenPegasus Tracer, я нашел выход из этого регистратора: SSL: Не подключен 1 Ошибка: 140740BF: SSL процедуры: SSL23_CLIENT_HELLO: нет доступных протоколов SSL: Deleted SSL сокет знаете ли вы что это значит? Выходы из ваших команд слишком длинны, какая информация вам интересна? –

+0

Хорошо, выходы из команд вы можете найти здесь (https://drive.google.com/file/d/0BwTVlfm1jzYfVmlDd29xU1ZKb2c/view?usp=sharing). –

+0

Спасибо, ты прав. –

ответ

1

Получил ответ от команды Open Pegasus dev. Они создали ошибку для проблемы с «магической» константой. Также они рекомендуют в моем случае использовать sslBackwardCompatibility = true для сборки.

Этот параметр помог мне частично. Для некоторых массивов хранения данных работала SSL-связь. Но для некоторых он все еще сообщает об исключении «Невозможно подключиться».

Только обходной путь, который я нашел, заключается в замене кода метода _makeSSLContext() кодом из версии OpenPegasus 2.13. После этой модификации я могу использовать SSL-связь со всеми моими массивами хранения + все функции новой версии Pegasus.

+0

* «Но для некоторых он все еще сообщает« Невозможно подключить »исключение ...» * - мы, возможно, сможем помочь с ними. Вероятно, он вернется к (1) якорю доверия, например, к частному CA или Verisign; и (2) сертификат сервера. 'openssl x509 -in -inform {PEM | DER} -text -noout' будет очень полезен для обоих. – jww

1
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 можно приобрести в ctor.

SSLSocket::SSLSocket(
    SocketHandle socket, 
    SSLContext * sslcontext, 
    ReadWriteSem * sslContextObjectLock, 
    const String& ipAddress) 

Но я уверен, что вам нужно имя DNS, а не IP-адрес, так как мультиплексирование различных серверов на том же IP, что вызвало необходимость SNI в первую очередь.

Но я мог ошибаться. const String& ipAddress действительно может быть DNS-именем.

+0

Благодарим вас за ответ и исследование. Вы правы, указав, что проблема заключается в методе _makeSSLContext(), потому что я попытался заменить этот метод на более старую версию (код из OpenPegasus 2.13), и SSL-связь начала работать нормально. Я также пробовал ваш модифицированный код. Теперь я получаю исключение «Не удалось загрузить сертификаты в хранилище доверия». Это проблема, потому что мне нужно работать без сертификатов. Мы подключаемся к различным массивам хранения, и у нас нет их сертификатов. Поэтому я использую пустой конструктор SSLContext. Этот подход отлично работает в версии 2.13. –