⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tls.cpp

📁 Pegasus is an open-source implementationof the DMTF CIM and WBEM standards. It is designed to be por
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//%2006//////////////////////////////////////////////////////////////////////////// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.// Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;// IBM Corp.; EMC Corporation, The Open Group.// Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;// EMC Corporation; VERITAS Software Corporation; The Open Group.// Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;// EMC Corporation; Symantec Corporation; The Open Group.//// Permission is hereby granted, free of charge, to any person obtaining a copy// of this software and associated documentation files (the "Software"), to// deal in the Software without restriction, including without limitation the// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or// sell copies of the Software, and to permit persons to whom the Software is// furnished to do so, subject to the following conditions:// // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN// ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.////==============================================================================////%/////////////////////////////////////////////////////////////////////////////#include <Pegasus/Common/Socket.h>#include <Pegasus/Common/Tracer.h>#include <Pegasus/Common/SSLContextRep.h>#include <Pegasus/Common/SSLContext.h>#include <Pegasus/Common/MessageLoader.h>#include <Pegasus/Common/FileSystem.h>#include "TLS.h"#ifdef PEGASUS_OS_ZOS#include "SocketzOS_inline.h"#endif//// use the following definitions only if SSL is available//#ifdef PEGASUS_HAS_SSLPEGASUS_NAMESPACE_BEGIN//// Basic SSL socket//SSLSocket::SSLSocket(    SocketHandle socket,    SSLContext * sslcontext,    ReadWriteSem * sslContextObjectLock)   :   _SSLConnection(0),   _socket(socket),   _SSLContext(sslcontext),   _sslContextObjectLock(sslContextObjectLock),   _SSLCallbackInfo(0),   _certificateVerified(false){    PEG_METHOD_ENTER(TRC_SSL, "SSLSocket::SSLSocket()");    _sslReadErrno = 0;    //    // create the SSLConnection area    //    if (!( _SSLConnection = SSL_new(_SSLContext->_rep->getContext() )))    {        PEG_METHOD_EXIT();        MessageLoaderParms parms(            "Common.TLS.COULD_NOT_GET_SSL_CONNECTION_AREA",            "Could not get SSL Connection Area");        throw SSLException(parms);    }    // This try/catch block is necessary so that we can free the SSL Connection    // Area if any exceptions are thrown.    try    {        //        // set the verification callback data        //        // we are only storing one set of data, so we can just use index 0,        // this is defined in SSLContext.h        //int index = SSL_get_ex_new_index(        //    0, (void*)"pegasus", NULL, NULL, NULL);        //        // Create a new callback info for each new connection        //        _SSLCallbackInfo.reset(new SSLCallbackInfo(            _SSLContext->getSSLCertificateVerifyFunction()#ifdef PEGASUS_ENABLE_SSL_CRL_VERIFICATION            , _SSLContext->getCRLStore()));#else            ));#endif        if (SSL_set_ex_data(                _SSLConnection,                SSLCallbackInfo::SSL_CALLBACK_INDEX,                _SSLCallbackInfo.get()))        {            PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,                "--->SSL: Set callback info");        }        else        {            PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3,                "--->SSL: Error setting callback info");        }        //        // and connect the active socket with the ssl operation        //        if (!(SSL_set_fd(_SSLConnection, _socket) ))        {            PEG_METHOD_EXIT();            MessageLoaderParms parms(                "Common.TLS.COULD_NOT_LINK_SOCKET",                "Could not link socket to SSL Connection");            throw SSLException(parms);        }    }    catch (...)    {        SSL_free(_SSLConnection);        throw;    }    PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4, "---> SSL: Created SSL socket");    PEG_METHOD_EXIT();}SSLSocket::~SSLSocket(){    PEG_METHOD_ENTER(TRC_SSL, "SSLSocket::~SSLSocket()");    SSL_free(_SSLConnection);    PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, "---> SSL: Deleted SSL socket");    PEG_METHOD_EXIT();}Boolean SSLSocket::incompleteReadOccurred(Sint32 retCode){    Sint32 err = SSL_get_error(_SSLConnection, retCode);    Tracer::trace(TRC_SSL, Tracer::LEVEL4,        "In SSLSocket::incompleteReadOccurred : err = %d", err);    return ((err == SSL_ERROR_SYSCALL) &&            (_sslReadErrno == EAGAIN || _sslReadErrno == EINTR)) ||           (err == SSL_ERROR_WANT_READ) ||           (err == SSL_ERROR_WANT_WRITE);}Sint32 SSLSocket::read(void* ptr, Uint32 size){    PEG_METHOD_ENTER(TRC_SSL, "SSLSocket::read()");    Sint32 rc;    PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4, "---> SSL: (r) ");    PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,        SSL_state_string_long(_SSLConnection));    rc = SSL_read(_SSLConnection, (char *)ptr, size);    _sslReadErrno = errno;    PEG_METHOD_EXIT();    return rc;}Sint32 SSLSocket::timedWrite( const void* ptr,                              Uint32 size,                              Uint32 socketWriteTimeout){    PEG_METHOD_ENTER(TRC_SSL, "SSLSocket::timedWrite()");    Sint32 bytesWritten = 0;    Sint32 totalBytesWritten = 0;    Boolean socketTimedOut = false;    Uint32 selreturn = 0;  while (1)  {    PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4, "---> SSL: (w) ");    PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,                     SSL_state_string_long(_SSLConnection) );    bytesWritten = SSL_write(_SSLConnection, (char *)ptr, size);    // Some data written this cycle ?    // Add it to the total amount of written data.    if (bytesWritten > 0)    {        totalBytesWritten += bytesWritten;        socketTimedOut = false;    }    // All data written ? return amount of data written    if ((Uint32)bytesWritten == size)    {        // exit the while loop        break;    }    // If data has been written partially, we resume writing data    // this also accounts for the case of a signal interrupt    // (i.e. errno = EINTR)    if (bytesWritten > 0)    {        size -= bytesWritten;        ptr = (void *)((char *)ptr + bytesWritten);        continue;    }    // Something went wrong, SSL return with everything not > 0 is an error    if (bytesWritten <= 0)    {        // if we already waited for the socket to get ready, bail out        if (socketTimedOut)        {            // bytesWritten contains the error indication            PEG_METHOD_EXIT();            return bytesWritten;        }        // just interrupted by a signal, try again#ifdef PEGASUS_OS_TYPE_WINDOWS        if (WSAGetLastError() == WSAEINTR) continue;#else        if (errno == EINTR) continue;#endif        // socket not ready ...#ifdef PEGASUS_OS_TYPE_WINDOWS        if (WSAGetLastError() == WSAEWOULDBLOCK)#else        if (errno == EAGAIN || errno == EWOULDBLOCK)#endif        {            fd_set fdwrite;            // max. timeout seconds waiting for the socket to get ready            struct timeval tv = {socketWriteTimeout , 0 };            FD_ZERO(&fdwrite);            FD_SET(_socket, &fdwrite);            selreturn = select(FD_SETSIZE, NULL, &fdwrite, NULL, &tv);            if (selreturn == 0) socketTimedOut = true; // ran out of time            continue;        }        // bytesWritten contains the error indication        PEG_METHOD_EXIT();        return bytesWritten;    }  }    PEG_METHOD_EXIT();    return totalBytesWritten;}void SSLSocket::close(){    PEG_METHOD_ENTER(TRC_SSL, "SSLSocket::close()");    SSL_shutdown(_SSLConnection);    Socket::close(_socket);    PEG_METHOD_EXIT();}void SSLSocket::enableBlocking(){    Socket::enableBlocking(_socket);}void SSLSocket::disableBlocking(){    Socket::disableBlocking(_socket);}void SSLSocket::initializeInterface(){    Socket::initializeInterface();    PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, "---> SSL: initialized SSL");}void SSLSocket::uninitializeInterface(){    Socket::uninitializeInterface();}Sint32 SSLSocket::accept(){    PEG_METHOD_ENTER(TRC_SSL, "SSLSocket::accept()");    Sint32 ssl_rc,ssl_rsn;    //ATTN: these methods get implicitly done with the SSL_accept call    //SSL_do_handshake(_SSLConnection);    //SSL_set_accept_state(_SSLConnection);    // Make sure the SSLContext object is not updated during this operation.    ReadLock rlock(*_sslContextObjectLock);    ssl_rc = SSL_accept(_SSLConnection);    if (ssl_rc < 0)    {        ssl_rsn = SSL_get_error(_SSLConnection, ssl_rc);        Tracer::trace(TRC_SSL, Tracer::LEVEL3,            "---> SSL: Not accepted %d", ssl_rsn );        if ((ssl_rsn == SSL_ERROR_WANT_READ) ||            (ssl_rsn == SSL_ERROR_WANT_WRITE))        {            PEG_METHOD_EXIT();            return 0;        }        else        {            PEG_METHOD_EXIT();            return -1;        }    }    else if (ssl_rc == 0)    {       ssl_rsn = SSL_get_error(_SSLConnection, ssl_rc);       PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, "Shutdown SSL_accept()");       Tracer::trace(TRC_SSL, Tracer::LEVEL4, "Error Code:  %d", ssl_rsn );       PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,           "Error string: " + String(ERR_error_string(ssl_rc, NULL)));       PEG_METHOD_EXIT();       return -1;    }    PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, "---> SSL: Accepted");    //    // If peer certificate verification is enabled or request received on    // export connection, get the peer certificate and verify the trust    // store validation result.    //    if (_SSLContext->isPeerVerificationEnabled())    {        PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3,            "Attempting to certify client");        //        // get client's certificate        //        X509 * client_cert = SSL_get_peer_certificate(_SSLConnection);        if (client_cert != NULL)        {            //            // get certificate verification result            //            int verifyResult = SSL_get_verify_result(_SSLConnection);            Tracer::trace(TRC_SSL, Tracer::LEVEL3,                "Verification Result:  %d", verifyResult );            if (verifyResult == X509_V_OK)            {                PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,                    "---> SSL: Client Certificate verified.");                //                // set flag to indicate that the certificate was verified in                // the trust store.                //                _certificateVerified = true;            }            else            {                PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,                     "---> SSL: Client Certificate not verified");            }            X509_free(client_cert);        }        else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -