Open Pegasus 2.14.1 client connection problem

I would like to create a new version of Open Pegasus Client (2.14.1). Unfortunately I ran into some build issues. Does anyone know of some ways to solve these problems?

My environment:

  • OS: Windows 8.1 Enterprise
  • Make version: GNU Make 3.81
  • version of Pegasus sources: 2.14.1
  • OpenSSL version: 1.0.2a

My scenario is pretty simple:

  • I downloaded Open Pegasus 2.14.1 source code
  • I downloaded the OpenSSL binaries (actual version is v1.0.2a).
  • After extracting the Pegasus source code, I set up my environment with these settings:

    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
    
          

  • The next step was to create the mu.exe tool. So, I ran "make buildmu" => successfully build and copy to "/ bin" folder. how to build Pegasus like this: "make build" => after a while i got this Error:

    Message.cpp (433): error C2065: magic: undeclared identifier

  • I tried to fix this problem. I found the magic constant is defined in the \ pegasus-2.14.1 \ pegasus \ src \ Pegasus \ Common \ Linkable.h file, so I have two options: a) Configuring the build configuration in DEBUG (setting PEGASUS_DEBUG = true) b) Remove DEBUG condition from lines 62 in Linkable.h file Then I tried to create Pegasus again, unfortunately I got this error:

    error LNK2005: _OPENSSL_Applink is already defined in SSLContext.obj

At this point, I don't know how to fix this problem. I just tried to remove these lines:

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

      

from SSLContextRep.h file. After this modification, I was able to get the Pegasus client binaries. But these binaries work without SSL, when I want to use SSL communication, I always got the error: Pegasus Exception: "Can't connect to 10.199.1.139:5989. Connection failed. '." So I guess it is related to so that my code modification is in SSLContextRep.h.

Outputs from Pegasus Tracer:

SSL: not connected 1 error: 140740BF: SSL procedures: SSL23_CLIENT_HELLO: No protocols available SSL: Remote SSL socket

Does anyone know what could be wrong? Does anyone own some (best) Windows environment setup steps to build OpenPegasus?

Thanks a lot in advance for any help.


Edit:

I need to work without certificates. Because I am using SSL communication with various storage arrays and I do not have their certificates. So I am using this SSLContext constructor:

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

      

this approach works fine for me in OpenPegasus 2.13 version.

+3


source to share


2 answers


I got a response from the Open Pegasus dev team. They created an error for the "magic" constant problem. Also they recommend in my case to use sslBackwardCompatibility = true for the build.

This option helped me in part. SSL communication worked for some storage arrays. But for some, it still reports the "Unable to connect" exception.



The only workaround I found was to replace the _makeSSLContext () method code with the code from OpenPegasus 2.13 version. After this modification I can use SSL communication with all my storage arrays + all the features of the new Pegasus version.

+1


source


Outputs from Pegasus Tracer:

    SSL: Not connected 1 error:140740BF:SSL routines:SSL23_CLIENT_HELLO:no protocols available SSL: Deleted SSL socket

      

Here's where the message appears:

$ grep -nR "Deleted SSL socket" *
src/Pegasus/Common/TLS.cpp:172:    PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3, "---> SSL: Deleted SSL socket");

      

And the code around line 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();
}

      




If you look in .../src/Pegasus/Common/SSLContext.cpp

, you will see:

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()));
        }
    }
    ...
}

      

I would disable this feature for two reasons and add something like the following instead.

First, its one of those amorphous routines written by both the client and the server. What I found from my experience with OpenSSL, you have separate functions for SSL_CTX* GetClientContext()

and SSL_CTX* GetServerContext()

.

Second, from a security perspective, you prevent people from getting into a bad state with things like PEGASUS_SSL_WEAKENCRYPTION

or an empty cipher list. You remove the gun so they don't shoot in the leg.

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 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 and AEAD encryption suites are very good choices. For most purposes, however, TLS 1.0 and up is fine.




I think this might be the cause 0x140740BF

in the client. Its from line SSLContext.cpp

, 824:

SSL_CTX_set_verify(sslContext,
    SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, prepareForCallback);

      

It looks like the server requires a certificate.

... but usually you get a different TLS warning.




And the sources don't call SSL_set_tlsext_host_name

, so SNI turns out to be broken. You should probably provide a bug report for this ...

$ grep -nR SSL_set_tlsext_host_name *
$

      

You will need to figure out where the client is making its connection and set that as a parameter SSL*

:

SSL_set_tlsext_host_name(ssl, hostname);

      

Somewhere around there SSLSocket::SSLSocket

might be a good choice because its constructor takes a string and sslConnection

is available in the ctor.

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

      

But I'm pretty sure you want a DNS name, not an IP address, because multiplexing different servers on the same IP made it necessary to use SNI.

But I could be wrong. const String& ipAddress

can be a DNS name.

+1


source







All Articles