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

📄 tlsschannel.cpp

📁 Jabber code library, developed with c
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 2007-2008 by Jakob Schroeter <js@camaya.net> * This file is part of the gloox library. http://camaya.net/gloox * * This software is distributed under a license. The full license * agreement can be found in the file LICENSE in this distribution. * This software may not be copied, modified, sold or distributed * other than expressed in the named license agreement. * * This software is distributed without any warranty. */#include "tlsschannel.h"#ifdef HAVE_WINTLS#include <stdio.h> // just for debugging output#include <iostream>namespace gloox{  SChannel::SChannel( TLSHandler* th, const std::string& server )    : TLSBase( th, server ), m_cleanedup( true )  {    //printf(">> SChannel::SChannel()\n");  }  SChannel::~SChannel()  {    m_handler = 0;    cleanup();    //printf(">> SChannel::~SChannel()\n");  }  bool SChannel::encrypt( const std::string& data )  {    if( !m_handler )      return false;    //printf(">> SChannel::encrypt()\n");    std::string data_copy = data;    SecBuffer buffer[4];    SecBufferDesc buffer_desc;    DWORD cbIoBufferLength = m_sizes.cbHeader + m_sizes.cbMaximumMessage + m_sizes.cbTrailer;    PBYTE e_iobuffer = static_cast<PBYTE>( LocalAlloc( LMEM_FIXED, cbIoBufferLength ) );    if( e_iobuffer == NULL )    {      //printf("**** Out of memory (2)\n");      cleanup();      if( !m_secure )        m_handler->handleHandshakeResult( this, false, m_certInfo );      return false;    }    PBYTE e_message = e_iobuffer + m_sizes.cbHeader;    do    {      const int size = data_copy.size() > m_sizes.cbMaximumMessage                                  ? m_sizes.cbMaximumMessage                                  : data_copy.size();      memcpy( e_message, data_copy.data(), size );      if( data_copy.size() > m_sizes.cbMaximumMessage )        data_copy.erase( 0, m_sizes.cbMaximumMessage );      else        data_copy = "";      buffer[0].pvBuffer     = e_iobuffer;      buffer[0].cbBuffer     = m_sizes.cbHeader;      buffer[0].BufferType   = SECBUFFER_STREAM_HEADER;      buffer[1].pvBuffer     = e_message;      buffer[1].cbBuffer     = size;      buffer[1].BufferType   = SECBUFFER_DATA;      buffer[2].pvBuffer     = static_cast<char*>(buffer[1].pvBuffer) + buffer[1].cbBuffer;      buffer[2].cbBuffer     = m_sizes.cbTrailer;      buffer[2].BufferType   = SECBUFFER_STREAM_TRAILER;      buffer[3].BufferType   = SECBUFFER_EMPTY;      buffer_desc.ulVersion       = SECBUFFER_VERSION;      buffer_desc.cBuffers        = 4;      buffer_desc.pBuffers        = buffer;      SECURITY_STATUS e_status = EncryptMessage( &m_context, 0, &buffer_desc, 0 );      if( SUCCEEDED( e_status ) )      {        std::string encrypted( reinterpret_cast<const char*>(e_iobuffer),                               buffer[0].cbBuffer + buffer[1].cbBuffer + buffer[2].cbBuffer );        m_handler->handleEncryptedData( this, encrypted );        //if (data_copy.size() <= m_sizes.cbMaximumMessage) data_copy = "";      }      else      {        LocalFree( e_iobuffer );        cleanup();        if( !m_secure )          m_handler->handleHandshakeResult( this, false, m_certInfo );        return false;      }    }    while( data_copy.size() > 0 );    LocalFree( e_iobuffer );    return true;  }  int SChannel::decrypt( const std::string& data )  {    if( !m_handler )      return 0;    //printf(">> SChannel::decrypt()\n");    if( m_secure )    {      m_buffer += data;      SecBuffer buffer[4];      SecBufferDesc buffer_desc;      DWORD cbIoBufferLength = m_sizes.cbHeader + m_sizes.cbMaximumMessage + m_sizes.cbTrailer;      PBYTE e_iobuffer = static_cast<PBYTE>( LocalAlloc( LMEM_FIXED, cbIoBufferLength ) );      if( e_iobuffer == NULL )      {        //printf("**** Out of memory (2)\n");        cleanup();        if( !m_secure )          m_handler->handleHandshakeResult( this, false, m_certInfo );        return 0;      }      SECURITY_STATUS e_status;      // copy data chunk from tmp string into encryption memory buffer      do      {        memcpy( e_iobuffer, m_buffer.data(), m_buffer.size() >               cbIoBufferLength ? cbIoBufferLength : m_buffer.size() );        buffer[0].pvBuffer     = e_iobuffer;        buffer[0].cbBuffer     = m_buffer.size() > cbIoBufferLength ? cbIoBufferLength : m_buffer.size();        buffer[0].BufferType   = SECBUFFER_DATA;        buffer[1].cbBuffer = buffer[2].cbBuffer = buffer[3].cbBuffer = 0;        buffer[1].BufferType = buffer[2].BufferType = buffer[3].BufferType  = SECBUFFER_EMPTY;        buffer_desc.ulVersion       = SECBUFFER_VERSION;        buffer_desc.cBuffers        = 4;        buffer_desc.pBuffers        = buffer;        unsigned long processed_data = buffer[0].cbBuffer;        e_status = DecryptMessage( &m_context, &buffer_desc, 0, 0 );        // print_error(e_status, "decrypt() ~ DecryptMessage()");        // for (int n=0; n<4; n++)        //     printf("buffer[%d].cbBuffer: %d   \t%d\n", n, buffer[n].cbBuffer, buffer[n].BufferType);        // Locate data and (optional) extra buffers.        SecBuffer* pDataBuffer  = NULL;        SecBuffer* pExtraBuffer = NULL;        for( int i = 1; i < 4; i++ )        {          if( pDataBuffer == NULL && buffer[i].BufferType == SECBUFFER_DATA )          {            pDataBuffer = &buffer[i];            //printf("buffer[%d].BufferType = SECBUFFER_DATA\n",i);          }          if( pExtraBuffer == NULL && buffer[i].BufferType == SECBUFFER_EXTRA )          {            pExtraBuffer = &buffer[i];          }        }        if( e_status == SEC_E_OK )        {          std::string decrypted( reinterpret_cast<const char*>( pDataBuffer->pvBuffer ),                                 pDataBuffer->cbBuffer );          m_handler->handleDecryptedData( this, decrypted );          if( pExtraBuffer == NULL )          {            m_buffer.erase( 0, processed_data );          }          else          {            //std::cout << "m_buffer.size() = " << pExtraBuffer->cbBuffer << std::endl;            m_buffer.erase( 0, m_buffer.size() - pExtraBuffer->cbBuffer );            //std::cout << "m_buffer.size() = " << m_buffer.size() << std::endl;          }        }        else if( e_status == SEC_E_INCOMPLETE_MESSAGE )        {          break;        }        else        {          //std::cout << "decrypt !!!ERROR!!!\n";          cleanup();          if( !m_secure )            m_handler->handleHandshakeResult( this, false, m_certInfo );          break;        }      }      while( m_buffer.size() != 0 );      LocalFree( e_iobuffer );    }    else    {      handshakeStage( data );    }    //printf("<< SChannel::decrypt()\n");    return 0;  }  void SChannel::cleanup()  {    m_buffer = "";    if( !m_cleanedup )    {      m_valid = false;      m_secure = false;      m_cleanedup = true;      DeleteSecurityContext( &m_context );      FreeCredentialsHandle( &m_credHandle );    }  }  bool SChannel::handshake()  {    if( !m_handler )      return false;    //printf(">> SChannel::handshake()\n");    SECURITY_STATUS error;    ULONG return_flags;    TimeStamp t;    SecBuffer obuf[1];    SecBufferDesc obufs;    SCHANNEL_CRED tlscred;    ULONG request = ISC_REQ_ALLOCATE_MEMORY                    | ISC_REQ_CONFIDENTIALITY                    | ISC_REQ_EXTENDED_ERROR                    | ISC_REQ_INTEGRITY                    | ISC_REQ_REPLAY_DETECT                    | ISC_REQ_SEQUENCE_DETECT                    | ISC_REQ_STREAM                    | ISC_REQ_MANUAL_CRED_VALIDATION;    /* initialize TLS credential */    memset( &tlscred, 0, sizeof( SCHANNEL_CRED ) );    tlscred.dwVersion = SCHANNEL_CRED_VERSION;    tlscred.grbitEnabledProtocols = SP_PROT_TLS1;    /* acquire credentials */    error = AcquireCredentialsHandle( 0,                                      UNISP_NAME,                                      SECPKG_CRED_OUTBOUND,                                      0,                                      &tlscred,                                      0,                                      0,                                      &m_credHandle,                                      &t );    //print_error(error, "handshake() ~ AcquireCredentialsHandle()");    if( error != SEC_E_OK )    {      cleanup();      m_handler->handleHandshakeResult( this, false, m_certInfo );      return false;    }    else    {      /* initialize buffers */      obuf[0].cbBuffer = 0;      obuf[0].pvBuffer = 0;      obuf[0].BufferType = SECBUFFER_TOKEN;      /* initialize buffer descriptors */      obufs.ulVersion = SECBUFFER_VERSION;      obufs.cBuffers = 1;      obufs.pBuffers = obuf;      /* negotiate security */      SEC_CHAR* hname = const_cast<char*>( m_server.c_str() );      error = InitializeSecurityContext( &m_credHandle,                                         0,                                         hname,                                         request,                                         0,                                         SECURITY_NETWORK_DREP,                                         0,                                         0,                                         &m_context,                                         &obufs,                                         &return_flags,                                         NULL );      //print_error(error, "handshake() ~ InitializeSecurityContext()");      if( error == SEC_I_CONTINUE_NEEDED )      {        m_cleanedup = false;        //std::cout << "obuf[1].cbBuffer: " << obuf[0].cbBuffer << "\n";        std::string senddata( static_cast<char*>(obuf[0].pvBuffer), obuf[0].cbBuffer );        FreeContextBuffer( obuf[0].pvBuffer );        m_handler->handleEncryptedData( this, senddata );        return true;      }      else      {        cleanup();        m_handler->handleHandshakeResult( this, false, m_certInfo );        return false;      }    }    return true;  }  void SChannel::handshakeStage( const std::string& data )  {    //printf(" >> handshake_stage\n");    m_buffer += data;    SECURITY_STATUS error;    ULONG a;    TimeStamp t;    SecBuffer ibuf[2], obuf[1];    SecBufferDesc ibufs, obufs;    ULONG request = ISC_REQ_ALLOCATE_MEMORY                    | ISC_REQ_CONFIDENTIALITY                    | ISC_REQ_EXTENDED_ERROR                    | ISC_REQ_INTEGRITY                    | ISC_REQ_REPLAY_DETECT                    | ISC_REQ_SEQUENCE_DETECT                    | ISC_REQ_STREAM                    | ISC_REQ_MANUAL_CRED_VALIDATION;    SEC_CHAR* hname = const_cast<char*>( m_server.c_str() );    do    {      /* initialize buffers */      ibuf[0].cbBuffer = m_buffer.size();      ibuf[0].pvBuffer = static_cast<void*>( const_cast<char*>( m_buffer.c_str() ) );      //std::cout << "Size: " << m_buffer.size() << "\n";      ibuf[1].cbBuffer = 0;      ibuf[1].pvBuffer = 0;      obuf[0].cbBuffer = 0;      obuf[0].pvBuffer = 0;      ibuf[0].BufferType = SECBUFFER_TOKEN;      ibuf[1].BufferType = SECBUFFER_EMPTY;      obuf[0].BufferType = SECBUFFER_EMPTY;      /* initialize buffer descriptors */      ibufs.ulVersion = obufs.ulVersion = SECBUFFER_VERSION;      ibufs.cBuffers = 2;      obufs.cBuffers = 1;      ibufs.pBuffers = ibuf;      obufs.pBuffers = obuf;      /*       * std::cout << "obuf[0].cbBuffer: " << obuf[0].cbBuffer << "\t" << obuf[0].BufferType << "\n";       * std::cout << "ibuf[0].cbBuffer: " << ibuf[0].cbBuffer << "\t" << ibuf[0].BufferType << "\n";       * std::cout << "ibuf[1].cbBuffer: " << ibuf[1].cbBuffer << "\t" << ibuf[1].BufferType << "\n";       */      /* negotiate security */      error = InitializeSecurityContext( &m_credHandle,                                         &m_context,                                         hname,                                         request,                                         0,                                         0,                                         &ibufs,                                         0,                                         0,                                         &obufs,                                         &a,                                         &t );      //print_error(error, "handshake() ~ InitializeSecurityContext()");      if( error == SEC_E_OK )      {        // EXTRA STUFF??        if( ibuf[1].BufferType == SECBUFFER_EXTRA )        {          m_buffer.erase( 0, m_buffer.size() - ibuf[1].cbBuffer );        }        else        {          m_buffer = "";        }        setSizes();

⌨️ 快捷键说明

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