mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Add OpenSSL integration with ACE (5.6.6) for Windows. Will be used in the future.
*nix users will already have these files. Credits to the original authors over at ACE. --HG-- branch : trunk
This commit is contained in:
253
dep/ACE_wrappers/ace/SSL/SSL_Asynch_BIO.cpp
Normal file
253
dep/ACE_wrappers/ace/SSL/SSL_Asynch_BIO.cpp
Normal file
@@ -0,0 +1,253 @@
|
||||
// -*- C++ -*-
|
||||
|
||||
#include "SSL_Asynch_BIO.h"
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER > 0x0090581fL && ((defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) || (defined (ACE_HAS_AIO_CALLS)))
|
||||
|
||||
#include "SSL_Asynch_Stream.h"
|
||||
#include "ace/OS_NS_string.h"
|
||||
#include "ace/Truncate.h"
|
||||
|
||||
ACE_RCSID (ACE_SSL,
|
||||
SSL_Asynch_BIO,
|
||||
"$Id: SSL_Asynch_BIO.cpp 82574 2008-08-08 19:35:06Z parsons $")
|
||||
|
||||
#if (defined (ACE_HAS_VERSIONED_NAMESPACE) && ACE_HAS_VERSIONED_NAMESPACE == 1)
|
||||
# define ACE_ASYNCH_BIO_WRITE_NAME ACE_PREPROC_CONCATENATE(ACE_VERSIONED_NAMESPACE_NAME, _ACE_Asynch_BIO_write)
|
||||
# define ACE_ASYNCH_BIO_READ_NAME ACE_PREPROC_CONCATENATE(ACE_VERSIONED_NAMESPACE_NAME, _ACE_Asynch_BIO_read)
|
||||
# define ACE_ASYNCH_BIO_PUTS_NAME ACE_PREPROC_CONCATENATE(ACE_VERSIONED_NAMESPACE_NAME, _ACE_Asynch_BIO_puts)
|
||||
# define ACE_ASYNCH_BIO_CTRL_NAME ACE_PREPROC_CONCATENATE(ACE_VERSIONED_NAMESPACE_NAME, _ACE_Asynch_BIO_ctrl)
|
||||
# define ACE_ASYNCH_BIO_NEW_NAME ACE_PREPROC_CONCATENATE(ACE_VERSIONED_NAMESPACE_NAME, _ACE_Asynch_BIO_new)
|
||||
# define ACE_ASYNCH_BIO_FREE_NAME ACE_PREPROC_CONCATENATE(ACE_VERSIONED_NAMESPACE_NAME, _ACE_Asynch_BIO_free)
|
||||
#else
|
||||
# define ACE_ASYNCH_BIO_WRITE_NAME ACE_Asynch_BIO_write
|
||||
# define ACE_ASYNCH_BIO_READ_NAME ACE_Asynch_BIO_read
|
||||
# define ACE_ASYNCH_BIO_PUTS_NAME ACE_Asynch_BIO_puts
|
||||
# define ACE_ASYNCH_BIO_CTRL_NAME ACE_Asynch_BIO_ctrl
|
||||
# define ACE_ASYNCH_BIO_NEW_NAME ACE_Asynch_BIO_new
|
||||
# define ACE_ASYNCH_BIO_FREE_NAME ACE_Asynch_BIO_free
|
||||
#endif /* ACE_HAS_VERSIONED_NAMESPACE == 1 */
|
||||
|
||||
/**
|
||||
* @name OpenSSL BIO Helper Methods for use with ACE's Asynchronous
|
||||
* SSL I/O support.
|
||||
*/
|
||||
//@{
|
||||
extern "C"
|
||||
{
|
||||
int ACE_ASYNCH_BIO_WRITE_NAME (BIO *pBIO, const char *buf, int len);
|
||||
int ACE_ASYNCH_BIO_READ_NAME (BIO *pBIO, char *buf, int len);
|
||||
int ACE_ASYNCH_BIO_PUTS_NAME (BIO *pBIO, const char *str);
|
||||
long ACE_ASYNCH_BIO_CTRL_NAME (BIO *pBIO, int cmd, long arg1, void *arg2);
|
||||
int ACE_ASYNCH_BIO_NEW_NAME (BIO *pBIO);
|
||||
int ACE_ASYNCH_BIO_FREE_NAME (BIO *pBIO);
|
||||
}
|
||||
//@}
|
||||
|
||||
#define BIO_TYPE_ACE ( 21 | BIO_TYPE_SOURCE_SINK )
|
||||
|
||||
static BIO_METHOD methods_ACE =
|
||||
{
|
||||
BIO_TYPE_ACE, // BIO_TYPE_PROXY_SERVER,
|
||||
"ACE_Asynch_BIO",
|
||||
ACE_ASYNCH_BIO_WRITE_NAME,
|
||||
ACE_ASYNCH_BIO_READ_NAME,
|
||||
ACE_ASYNCH_BIO_PUTS_NAME,
|
||||
0, /* ACE_ASYNCH_BIO_GETS_NAME, */
|
||||
ACE_ASYNCH_BIO_CTRL_NAME,
|
||||
ACE_ASYNCH_BIO_NEW_NAME,
|
||||
ACE_ASYNCH_BIO_FREE_NAME,
|
||||
0
|
||||
};
|
||||
|
||||
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
|
||||
|
||||
BIO *
|
||||
ACE_SSL_make_BIO (void * ssl_asynch_stream)
|
||||
{
|
||||
BIO * const pBIO = BIO_new (&methods_ACE);
|
||||
|
||||
if (pBIO)
|
||||
BIO_ctrl (pBIO,
|
||||
BIO_C_SET_FILE_PTR,
|
||||
0,
|
||||
ssl_asynch_stream);
|
||||
|
||||
return pBIO;
|
||||
}
|
||||
|
||||
/**
|
||||
* @struct @c ACE_SSL_Asynch_Stream_Accessor
|
||||
*
|
||||
* @brief Privileged @c ACE_SSL_Asynch_Stream accessor.
|
||||
*
|
||||
* This structure is a @c friend to the @c ACE_SSL_Asynch_Stream
|
||||
* class so that it can gain access to the protected
|
||||
* ssl_bio_{read,write}() methods in that class. It is full declared
|
||||
* in this implementation file to hide its interface from users to
|
||||
* prevent potential abuse of the friend relationship between it and
|
||||
* the @c ACE_SSL_Asynch_Stream class.
|
||||
*/
|
||||
struct ACE_SSL_Asynch_Stream_Accessor
|
||||
{
|
||||
static int read (ACE_SSL_Asynch_Stream * stream,
|
||||
char * buf,
|
||||
size_t len,
|
||||
int & errval)
|
||||
{
|
||||
return stream->ssl_bio_read (buf, len, errval);
|
||||
}
|
||||
|
||||
static int write (ACE_SSL_Asynch_Stream * stream,
|
||||
const char * buf,
|
||||
size_t len,
|
||||
int & errval)
|
||||
{
|
||||
return stream->ssl_bio_write (buf, len, errval);
|
||||
}
|
||||
};
|
||||
|
||||
ACE_END_VERSIONED_NAMESPACE_DECL
|
||||
|
||||
int
|
||||
ACE_ASYNCH_BIO_NEW_NAME (BIO * pBIO)
|
||||
{
|
||||
pBIO->init = 0; // not initialized
|
||||
pBIO->num = 0; // still zero ( we can use it )
|
||||
pBIO->ptr = 0; // will be pointer to ACE_SSL_Asynch_Stream
|
||||
pBIO->flags = 0; //
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
ACE_ASYNCH_BIO_FREE_NAME (BIO * pBIO)
|
||||
{
|
||||
if (pBIO && pBIO->shutdown)
|
||||
{
|
||||
pBIO->ptr = 0;
|
||||
pBIO->init = 0;
|
||||
pBIO->num = 0;
|
||||
pBIO->flags = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ACE_ASYNCH_BIO_READ_NAME (BIO * pBIO, char * buf, int len)
|
||||
{
|
||||
BIO_clear_retry_flags (pBIO);
|
||||
|
||||
ACE_SSL_Asynch_Stream * const p_stream =
|
||||
static_cast<ACE_SSL_Asynch_Stream *> (pBIO->ptr);
|
||||
|
||||
if (pBIO->init == 0 || p_stream == 0 || buf == 0 || len <= 0)
|
||||
return -1;
|
||||
|
||||
BIO_clear_retry_flags (pBIO);
|
||||
|
||||
int errval = 0;
|
||||
|
||||
int retval =
|
||||
ACE_SSL_Asynch_Stream_Accessor::read (p_stream,
|
||||
buf,
|
||||
len,
|
||||
errval);
|
||||
|
||||
if (retval >= 0)
|
||||
return retval;
|
||||
|
||||
if (errval == EINPROGRESS)
|
||||
BIO_set_retry_read (pBIO);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
ACE_ASYNCH_BIO_WRITE_NAME (BIO * pBIO, const char * buf, int len)
|
||||
{
|
||||
BIO_clear_retry_flags (pBIO);
|
||||
|
||||
ACE_SSL_Asynch_Stream * p_stream =
|
||||
static_cast<ACE_SSL_Asynch_Stream *> (pBIO->ptr);
|
||||
|
||||
if (pBIO->init == 0 || p_stream == 0 || buf == 0 || len <= 0)
|
||||
return -1;
|
||||
|
||||
BIO_clear_retry_flags (pBIO);
|
||||
|
||||
int errval = 0;
|
||||
|
||||
int retval =
|
||||
ACE_SSL_Asynch_Stream_Accessor::write (p_stream,
|
||||
buf,
|
||||
len,
|
||||
errval);
|
||||
|
||||
if (retval >= 0)
|
||||
return retval;
|
||||
|
||||
if (errval == EINPROGRESS)
|
||||
BIO_set_retry_write (pBIO);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
long
|
||||
ACE_ASYNCH_BIO_CTRL_NAME (BIO * pBIO, int cmd, long num, void *ptr)
|
||||
{
|
||||
long ret = 1;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case BIO_C_SET_FILE_PTR:
|
||||
pBIO->shutdown = static_cast<int> (num);
|
||||
pBIO->ptr = ptr;
|
||||
pBIO->init = 1;
|
||||
break;
|
||||
|
||||
case BIO_CTRL_INFO:
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
case BIO_CTRL_GET_CLOSE:
|
||||
ret = pBIO->shutdown;
|
||||
break;
|
||||
|
||||
case BIO_CTRL_SET_CLOSE:
|
||||
pBIO->shutdown = static_cast<int> (num);
|
||||
break;
|
||||
|
||||
case BIO_CTRL_PENDING:
|
||||
case BIO_CTRL_WPENDING:
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
case BIO_CTRL_DUP:
|
||||
case BIO_CTRL_FLUSH:
|
||||
ret = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
ACE_ASYNCH_BIO_PUTS_NAME (BIO *pBIO, const char *str)
|
||||
{
|
||||
size_t const n = ACE_OS::strlen (str);
|
||||
|
||||
return ACE_ASYNCH_BIO_WRITE_NAME (pBIO,
|
||||
str,
|
||||
ACE_Utils::truncate_cast<int> (n));
|
||||
}
|
||||
|
||||
#endif /* OPENSSL_VERSION_NUMBER > 0x0090581fL && (ACE_WIN32 ||
|
||||
ACE_HAS_AIO_CALLS) */
|
||||
42
dep/ACE_wrappers/ace/SSL/SSL_Asynch_BIO.h
Normal file
42
dep/ACE_wrappers/ace/SSL/SSL_Asynch_BIO.h
Normal file
@@ -0,0 +1,42 @@
|
||||
// -*- C++ -*-
|
||||
|
||||
//=============================================================================
|
||||
/**
|
||||
* @file SSL_Asynch_BIO.h
|
||||
*
|
||||
* $Id: SSL_Asynch_BIO.h 80826 2008-03-04 14:51:23Z wotte $
|
||||
*
|
||||
* @author Alexander Libman <alibman@baltimore.com>
|
||||
* @author Ossama Othman <ossama@uci.edu>
|
||||
*
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
#ifndef ACE_SSL_ASYNCH_BIO_H
|
||||
#define ACE_SSL_ASYNCH_BIO_H
|
||||
|
||||
#include /**/ "ace/pre.h"
|
||||
|
||||
#include "SSL_Export.h"
|
||||
|
||||
#if !defined (ACE_LACKS_PRAGMA_ONCE)
|
||||
#pragma once
|
||||
#endif /* ACE_LACKS_PRAGMA_ONCE */
|
||||
|
||||
// This must be included before any <openssl> include on LynxOS
|
||||
#include "ace/os_include/os_stdio.h"
|
||||
|
||||
#include <openssl/bio.h>
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER > 0x0090581fL && ((defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) || (defined (ACE_HAS_AIO_CALLS)))
|
||||
|
||||
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
|
||||
extern BIO * ACE_SSL_make_BIO (void * ssl_asynch_stream);
|
||||
ACE_END_VERSIONED_NAMESPACE_DECL
|
||||
|
||||
#endif /* OPENSSL_VERSION_NUMBER > 0x0090581fL (ACE_WIN32 ||
|
||||
ACE_HAS_AIO_CALLS) */
|
||||
|
||||
#include /**/ "ace/post.h"
|
||||
|
||||
#endif /* ACE_SSL_ASYNCH_BIO_H */
|
||||
1063
dep/ACE_wrappers/ace/SSL/SSL_Asynch_Stream.cpp
Normal file
1063
dep/ACE_wrappers/ace/SSL/SSL_Asynch_Stream.cpp
Normal file
File diff suppressed because it is too large
Load Diff
425
dep/ACE_wrappers/ace/SSL/SSL_Asynch_Stream.h
Normal file
425
dep/ACE_wrappers/ace/SSL/SSL_Asynch_Stream.h
Normal file
@@ -0,0 +1,425 @@
|
||||
// -*- C++ -*-
|
||||
|
||||
//=============================================================================
|
||||
/**
|
||||
* @file SSL_Asynch_Stream.h
|
||||
*
|
||||
* $Id: SSL_Asynch_Stream.h 80826 2008-03-04 14:51:23Z wotte $
|
||||
*
|
||||
* @author Alexander Libman <alibman@baltimore.com>
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
#ifndef ACE_SSL_ASYNCH_STREAM_H
|
||||
#define ACE_SSL_ASYNCH_STREAM_H
|
||||
|
||||
#include /**/ "ace/pre.h"
|
||||
#include "SSL_Context.h"
|
||||
|
||||
#if !defined (ACE_LACKS_PRAGMA_ONCE)
|
||||
#pragma once
|
||||
#endif /* ACE_LACKS_PRAGMA_ONCE */
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER > 0x0090581fL && ((defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) || (defined (ACE_HAS_AIO_CALLS)))
|
||||
|
||||
#include "SSL_Asynch_BIO.h"
|
||||
|
||||
#include "ace/Asynch_IO_Impl.h"
|
||||
#include "ace/Message_Block.h"
|
||||
#include "ace/Synch_Traits.h"
|
||||
#include "ace/Thread_Mutex.h"
|
||||
|
||||
/*
|
||||
* This facility doesn't follow the normal ACE asynch I/O support classes'
|
||||
* interface/implementation arrangement. It's not needed because rather than
|
||||
* branching off to platform-specific APIs, all platforms use the OpenSSL
|
||||
* API. Thus, you can think of this class as the implementation class (for
|
||||
* OpenSSL) and there's no separate interface class.
|
||||
* Also, since both read and write operations are defined in one I/O
|
||||
* factory, there's no single Result class defined as there is for
|
||||
* ACE_Asynch_Read_Stream, et al. There are separate result classes defined
|
||||
* for read and write operations.
|
||||
*/
|
||||
|
||||
#if defined (ACE_WIN32)
|
||||
# include "ace/WIN32_Asynch_IO.h"
|
||||
typedef ACE_WIN32_Asynch_Result A_RESULT;
|
||||
typedef ACE_WIN32_Asynch_Read_Stream_Result ARS_RESULT;
|
||||
typedef ACE_WIN32_Asynch_Write_Stream_Result AWS_RESULT;
|
||||
|
||||
# define ERR_CANCELED ERROR_OPERATION_ABORTED
|
||||
|
||||
#else
|
||||
# include "ace/POSIX_Asynch_IO.h"
|
||||
typedef ACE_POSIX_Asynch_Result A_RESULT;
|
||||
typedef ACE_POSIX_Asynch_Read_Stream_Result ARS_RESULT;
|
||||
typedef ACE_POSIX_Asynch_Write_Stream_Result AWS_RESULT;
|
||||
|
||||
# define ERR_CANCELED ECANCELED
|
||||
|
||||
#endif /* ACE_WIN32 */
|
||||
|
||||
|
||||
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
|
||||
|
||||
class ACE_SSL_Asynch_Stream; // Forward decl for use in result class def.
|
||||
|
||||
/**
|
||||
* @class ACE_SSL_Asynch_Read_Stream_Result
|
||||
*
|
||||
* Result class that communicates result of read operations initiated on
|
||||
* an ACE_SSL_Asynch_Stream object.
|
||||
*/
|
||||
class ACE_SSL_Asynch_Read_Stream_Result : public ARS_RESULT
|
||||
{
|
||||
/// Factory class will have special permissions.
|
||||
friend class ACE_SSL_Asynch_Stream;
|
||||
|
||||
protected:
|
||||
ACE_SSL_Asynch_Read_Stream_Result (ACE_Handler &handler,
|
||||
ACE_HANDLE handle,
|
||||
ACE_Message_Block &message_block,
|
||||
size_t bytes_to_read,
|
||||
const void* act,
|
||||
ACE_HANDLE event,
|
||||
int priority,
|
||||
int signal_number);
|
||||
};
|
||||
|
||||
/**
|
||||
* @class ACE_SSL_Asynch_Write_Stream_Result
|
||||
*
|
||||
* Result class that communicates result of write operations initiated on
|
||||
* an ACE_SSL_Asynch_Stream object.
|
||||
*/
|
||||
class ACE_SSL_Asynch_Write_Stream_Result : public AWS_RESULT
|
||||
{
|
||||
/// Factory class will have special permissions.
|
||||
friend class ACE_SSL_Asynch_Stream;
|
||||
|
||||
protected:
|
||||
ACE_SSL_Asynch_Write_Stream_Result (ACE_Handler &handler,
|
||||
ACE_HANDLE handle,
|
||||
ACE_Message_Block &message_block,
|
||||
size_t bytes_to_read,
|
||||
const void* act,
|
||||
ACE_HANDLE event,
|
||||
int priority,
|
||||
int signal_number);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @class ACE_SSL_Asynch_Result
|
||||
*
|
||||
* Result class that is used internally for socket close notifications.
|
||||
*/
|
||||
class ACE_SSL_Asynch_Result : public A_RESULT
|
||||
{
|
||||
public:
|
||||
ACE_SSL_Asynch_Result (ACE_Handler &handler);
|
||||
|
||||
void complete (size_t bytes_transferred,
|
||||
int success,
|
||||
const void * completion_key,
|
||||
u_long error);
|
||||
};
|
||||
|
||||
|
||||
// Only provide forward declarations to prevent possible abuse of the
|
||||
// friend declarations in ACE_SSL_Asynch_Stream.
|
||||
struct ACE_SSL_Asynch_Stream_Accessor;
|
||||
|
||||
/**
|
||||
* @class ACE_SSL_Asynch_Stream
|
||||
*
|
||||
* @brief This class is a factory for initiating asynchronous reads
|
||||
* and writes on an SSL stream.
|
||||
*
|
||||
* Once open() is called, multiple asynchronous read and write operations
|
||||
* can be started using this class. The handler object (derived from
|
||||
* ACE_Handler) specified in open() will receive completion events for the
|
||||
* operations initiated via this class.
|
||||
*/
|
||||
class ACE_SSL_Export ACE_SSL_Asynch_Stream
|
||||
: public ACE_Asynch_Operation,
|
||||
public ACE_Handler
|
||||
{
|
||||
public:
|
||||
|
||||
// Use a class/struct to work around scoping
|
||||
// problems for extern "C" free functions with some compilers. For
|
||||
// example, some can't handle
|
||||
//
|
||||
// friend ::some_extern_c_free_function (...)
|
||||
//
|
||||
// Note that we could use a straight C++ (i.e. not extern "C") free
|
||||
// function, but using a class or struct allows us to hide the
|
||||
// interface from the user, which prevents abuse of this friend
|
||||
// relationship.
|
||||
friend struct ACE_SSL_Asynch_Stream_Accessor;
|
||||
|
||||
enum Stream_Type
|
||||
{
|
||||
ST_CLIENT = 0x0001,
|
||||
ST_SERVER = 0x0002
|
||||
};
|
||||
|
||||
/// Constructor.
|
||||
/**
|
||||
* @arg context Pointer to an ACE_SSL_Context instance containing
|
||||
* the OpenSSL information to be associated with this
|
||||
* ACE_SSL_Asynch_Stream. The needed SSL data will be
|
||||
* copied before return. Therefore, this object can be
|
||||
* reused, modified, or deleted upon return. If a 0 pointer
|
||||
* is passed, the ACE_SSL_Context::instance() method will
|
||||
* be called to get access to a singleton.
|
||||
*/
|
||||
ACE_SSL_Asynch_Stream (Stream_Type s_type = ST_SERVER,
|
||||
ACE_SSL_Context * context = 0);
|
||||
|
||||
/// Destructor
|
||||
virtual ~ACE_SSL_Asynch_Stream (void);
|
||||
|
||||
int cancel (void);
|
||||
|
||||
int close (void);
|
||||
|
||||
/**
|
||||
* Initializes the factory with information which will be used with
|
||||
* each asynchronous call.
|
||||
*
|
||||
* @arg handler The ACE_Handler that will be called to handle completions
|
||||
* for operations initiated using this factory.
|
||||
* @arg handle The handle that future read/write operations will use.
|
||||
*
|
||||
* @retval 0 for success.
|
||||
* @retval -1 for failure; consult @c errno for further information.
|
||||
*/
|
||||
int open (ACE_Handler &handler,
|
||||
ACE_HANDLE handle = ACE_INVALID_HANDLE,
|
||||
const void *completion_key = 0,
|
||||
ACE_Proactor *proactor = 0);
|
||||
|
||||
/**
|
||||
* Initiates an asynchronous read. If the operation is successfully
|
||||
* initiated, the handle_read_stream() method will be called on the
|
||||
* ACE_Handler object passed to open() when the operation completes.
|
||||
* Data is read into the specified ACE_Message_Block beginning at its
|
||||
* write pointer; the block's write pointer is updated to reflect any
|
||||
* added data when the operation completes.
|
||||
*
|
||||
* @arg message_block The specified ACE_Message_Block will receive any
|
||||
* data that is read. Data will be read into the
|
||||
* block beginning at the block's write pointer.
|
||||
* @arg num_bytes_to_read The maximum number of bytes to read. The actual
|
||||
* amount read may be less.
|
||||
* @arg act ACT which is passed to the completion handler in
|
||||
* the result object.
|
||||
* @arg priority Specifies the operation priority. This has an
|
||||
* affect on POSIX only. Works like @i nice in Unix.
|
||||
* Negative values are not allowed. 0 means priority
|
||||
* of the operation same as the process priority.
|
||||
* 1 means priority of the operation is one less than
|
||||
* process, and so forth. This parameter has no
|
||||
* affect on Win32.
|
||||
* @arg signal_number The POSIX4 real-time signal number to be used
|
||||
* for the operation. signal_number ranges from
|
||||
* ACE_SIGRTMIN to ACE_SIGRTMAX. This argument is
|
||||
* unused on non-POSIX4 systems.
|
||||
*
|
||||
* @retval 0 for success.
|
||||
* @retval -1 for failure; consult @c errno for further information.
|
||||
*/
|
||||
int read (ACE_Message_Block &message_block,
|
||||
size_t num_bytes_to_read,
|
||||
const void *act = 0,
|
||||
int priority = 0,
|
||||
int signal_number = ACE_SIGRTMIN);
|
||||
|
||||
/**
|
||||
* Initiates an asynchronous write. If the operation is successfully
|
||||
* initiated, the handle_write_stream() method will be called on the
|
||||
* ACE_Handler object passed to open() when the operation completes.
|
||||
* Data is taken from the specified ACE_Message_Block beginning at its
|
||||
* read pointer; the block's read pointer is updated to reflect any
|
||||
* data successfully sent when the operation completes.
|
||||
*
|
||||
* @arg message_block The specified ACE_Message_Block is the source of
|
||||
* data that is written. Data will be taken from the
|
||||
* block beginning at the block's read pointer.
|
||||
* @arg bytes_to_write The maximum number of bytes to write. The actual
|
||||
* amount written may be less.
|
||||
* @arg act ACT which is passed to the completion handler in
|
||||
* the result object.
|
||||
* @arg priority Specifies the operation priority. This has an
|
||||
* affect on POSIX only. Works like @i nice in Unix.
|
||||
* Negative values are not allowed. 0 means priority
|
||||
* of the operation same as the process priority.
|
||||
* 1 means priority of the operation is one less than
|
||||
* process, and so forth. This parameter has no
|
||||
* affect on Win32.
|
||||
* @arg signal_number The POSIX4 real-time signal number to be used
|
||||
* for the operation. signal_number ranges from
|
||||
* ACE_SIGRTMIN to ACE_SIGRTMAX. This argument is
|
||||
* unused on non-POSIX4 systems.
|
||||
*
|
||||
* @retval 0 for success.
|
||||
* @retval -1 for failure; consult @c errno for further information.
|
||||
*/
|
||||
int write (ACE_Message_Block &message_block,
|
||||
size_t bytes_to_write,
|
||||
const void *act = 0,
|
||||
int priority = 0,
|
||||
int signal_number = ACE_SIGRTMIN);
|
||||
|
||||
protected:
|
||||
/// Virtual from ACE_Asynch_Operation. Since this class is essentially an
|
||||
/// implementation class, simply return 0.
|
||||
virtual ACE_Asynch_Operation_Impl *implementation (void) const { return 0; }
|
||||
|
||||
/// virtual from ACE_Handler
|
||||
|
||||
/// This method is called when BIO write request is completed. It
|
||||
/// processes the IO completion and calls do_SSL_state_machine().
|
||||
virtual void handle_write_stream
|
||||
(const ACE_Asynch_Write_Stream::Result &result);
|
||||
|
||||
/// This method is called when BIO read request is completed. It
|
||||
/// processes the IO completion and calls do_SSL_state_machine().
|
||||
virtual void handle_read_stream
|
||||
(const ACE_Asynch_Read_Stream::Result &result);
|
||||
|
||||
/// This method is called when all SSL sessions are closed and no
|
||||
/// more pending AIOs exist. It also calls users handle_wakeup().
|
||||
virtual void handle_wakeup (void);
|
||||
|
||||
/**
|
||||
* @name SSL State Machine
|
||||
*/
|
||||
//@{
|
||||
int do_SSL_state_machine (void);
|
||||
int do_SSL_handshake (void);
|
||||
int do_SSL_read (void);
|
||||
int do_SSL_write(void);
|
||||
int do_SSL_shutdown(void);
|
||||
//@}
|
||||
|
||||
void print_error (int err_ssl,
|
||||
const ACE_TCHAR *pText);
|
||||
|
||||
int pending_BIO_count (void);
|
||||
|
||||
/// This method is called to notify user handler when user's read in
|
||||
/// done.
|
||||
int notify_read (int bytes_transferred, int error);
|
||||
|
||||
/// This method is called to notify user handler when user's write
|
||||
/// in done.
|
||||
int notify_write (int bytes_transferred, int error);
|
||||
|
||||
/// This method is called to notify ourself that SSL session is
|
||||
/// shutdown and that there is no more I/O activity now and in the
|
||||
/// future.
|
||||
int notify_close(void);
|
||||
|
||||
/**
|
||||
* @name BIO Helpers
|
||||
*/
|
||||
//@{
|
||||
int ssl_bio_read (char * buf, size_t len, int & errval);
|
||||
int ssl_bio_write (const char * buf, size_t len, int & errval);
|
||||
//@}
|
||||
|
||||
private:
|
||||
|
||||
// Preventing copying through construction or assignment.
|
||||
ACE_SSL_Asynch_Stream (ACE_SSL_Asynch_Stream const &);
|
||||
ACE_SSL_Asynch_Stream & operator= (ACE_SSL_Asynch_Stream const &);
|
||||
|
||||
protected:
|
||||
|
||||
/// Stream Type ST_CLIENT/ST_SERVER
|
||||
Stream_Type type_;
|
||||
|
||||
/// The real file/socket handle
|
||||
ACE_HANDLE handle_;
|
||||
|
||||
/// The proactor
|
||||
ACE_Proactor * proactor_;
|
||||
|
||||
/// External,i.e user handler
|
||||
ACE_Handler * ext_handler_;
|
||||
|
||||
/// External, i.e. read result faked for user
|
||||
ACE_SSL_Asynch_Read_Stream_Result * ext_read_result_ ;
|
||||
|
||||
/// External, i.e. write result faked for user
|
||||
ACE_SSL_Asynch_Write_Stream_Result * ext_write_result_ ;
|
||||
|
||||
/// Stream state/flags
|
||||
enum Stream_Flag
|
||||
{
|
||||
/// istream_ open OK
|
||||
SF_STREAM_OPEN = 0x0001,
|
||||
/// request to SSL shutdown
|
||||
SF_REQ_SHUTDOWN = 0x0002,
|
||||
/// SSL shutdown finished
|
||||
SF_SHUTDOWN_DONE = 0x0004,
|
||||
/// Close notification sent
|
||||
SF_CLOSE_NTF_SENT = 0x0008,
|
||||
/// Stream can be safely destroyed
|
||||
SF_DELETE_ENABLE = 0x0010
|
||||
};
|
||||
|
||||
int flags_;
|
||||
|
||||
/// The SSL session.
|
||||
SSL * ssl_;
|
||||
|
||||
/// The BIO implementation
|
||||
BIO * bio_;
|
||||
|
||||
/// The real streams which work under the ssl connection.
|
||||
/// BIO performs I/O via this streams
|
||||
enum BIO_Flag // internal IO flags
|
||||
{
|
||||
/// End of stream
|
||||
BF_EOS = 0x01,
|
||||
/// Real AIO in progress
|
||||
BF_AIO = 0x02
|
||||
};
|
||||
|
||||
/**
|
||||
* @name Internal stream, buffer and info for BIO read
|
||||
*/
|
||||
//@{
|
||||
ACE_Asynch_Read_Stream bio_istream_;
|
||||
ACE_Message_Block bio_inp_msg_;
|
||||
int bio_inp_errno_;
|
||||
int bio_inp_flag_;
|
||||
//@}
|
||||
|
||||
/**
|
||||
* @name Internal stream, buffer and info for BIO write
|
||||
*/
|
||||
//@{
|
||||
ACE_Asynch_Write_Stream bio_ostream_;
|
||||
ACE_Message_Block bio_out_msg_;
|
||||
int bio_out_errno_;
|
||||
int bio_out_flag_;
|
||||
//@}
|
||||
|
||||
/// Mutex to protect work
|
||||
ACE_SYNCH_MUTEX mutex_;
|
||||
|
||||
};
|
||||
|
||||
ACE_END_VERSIONED_NAMESPACE_DECL
|
||||
|
||||
#endif /* OPENSSL_VERSION_NUMBER > 0x0090581fL && (ACE_WIN32 ||
|
||||
ACE_HAS_AIO_CALLS) */
|
||||
|
||||
#include /**/ "ace/post.h"
|
||||
|
||||
#endif /* ACE_SSL_ASYNCH_STREAM_H */
|
||||
640
dep/ACE_wrappers/ace/SSL/SSL_Context.cpp
Normal file
640
dep/ACE_wrappers/ace/SSL/SSL_Context.cpp
Normal file
@@ -0,0 +1,640 @@
|
||||
#include "SSL_Context.h"
|
||||
|
||||
#include "sslconf.h"
|
||||
|
||||
#if !defined(__ACE_INLINE__)
|
||||
#include "SSL_Context.inl"
|
||||
#endif /* __ACE_INLINE__ */
|
||||
|
||||
#include "ace/Guard_T.h"
|
||||
#include "ace/Object_Manager.h"
|
||||
#include "ace/Log_Msg.h"
|
||||
#include "ace/Singleton.h"
|
||||
#include "ace/Synch_Traits.h"
|
||||
#include "ace/Truncate.h"
|
||||
#include "ace/ACE.h"
|
||||
#include "ace/OS_NS_errno.h"
|
||||
#include "ace/OS_NS_string.h"
|
||||
|
||||
#ifdef ACE_HAS_THREADS
|
||||
# include "ace/Thread_Mutex.h"
|
||||
# include "ace/OS_NS_Thread.h"
|
||||
#endif /* ACE_HAS_THREADS */
|
||||
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/safestack.h>
|
||||
|
||||
ACE_RCSID (ACE_SSL,
|
||||
SSL_Context,
|
||||
"$Id: SSL_Context.cpp 82574 2008-08-08 19:35:06Z parsons $")
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
/// Reference count of the number of times the ACE_SSL_Context was
|
||||
/// initialized.
|
||||
int ssl_library_init_count = 0;
|
||||
|
||||
// @@ This should also be done with a singleton, otherwise it is not
|
||||
// thread safe and/or portable to some weird platforms...
|
||||
|
||||
#ifdef ACE_HAS_THREADS
|
||||
/// Array of mutexes used internally by OpenSSL when the SSL
|
||||
/// application is multithreaded.
|
||||
ACE_SSL_Context::lock_type * ssl_locks = 0;
|
||||
|
||||
// @@ This should also be managed by a singleton.
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ACE_HAS_THREADS
|
||||
|
||||
# if (defined (ACE_HAS_VERSIONED_NAMESPACE) && ACE_HAS_VERSIONED_NAMESPACE == 1)
|
||||
# define ACE_SSL_LOCKING_CALLBACK_NAME ACE_PREPROC_CONCATENATE(ACE_VERSIONED_NAMESPACE_NAME, _ACE_SSL_locking_callback)
|
||||
# define ACE_SSL_THREAD_ID_NAME ACE_PREPROC_CONCATENATE(ACE_VERSIONED_NAMESPACE_NAME, _ACE_SSL_thread_id)
|
||||
# else
|
||||
# define ACE_SSL_LOCKING_CALLBACK_NAME ACE_SSL_locking_callback
|
||||
# define ACE_SSL_THREAD_ID_NAME ACE_SSL_thread_id
|
||||
# endif /* ACE_HAS_VERSIONED_NAMESPACE == 1 */
|
||||
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
void
|
||||
ACE_SSL_LOCKING_CALLBACK_NAME (int mode,
|
||||
int type,
|
||||
const char * /* file */,
|
||||
int /* line */)
|
||||
{
|
||||
// #ifdef undef
|
||||
// fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n",
|
||||
// CRYPTO_thread_id(),
|
||||
// (mode&CRYPTO_LOCK)?"l":"u",
|
||||
// (type&CRYPTO_READ)?"r":"w",file,line);
|
||||
// #endif
|
||||
// /*
|
||||
// if (CRYPTO_LOCK_SSL_CERT == type)
|
||||
// fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n",
|
||||
// CRYPTO_thread_id(),
|
||||
// mode,file,line);
|
||||
// */
|
||||
if (mode & CRYPTO_LOCK)
|
||||
(void) ssl_locks[type].acquire ();
|
||||
else
|
||||
(void) ssl_locks[type].release ();
|
||||
}
|
||||
|
||||
// -------------------------------
|
||||
|
||||
// Return the current thread ID. OpenSSL uses this on platforms
|
||||
// that need it.
|
||||
unsigned long
|
||||
ACE_SSL_THREAD_ID_NAME (void)
|
||||
{
|
||||
return (unsigned long) ACE_VERSIONED_NAMESPACE_NAME::ACE_OS::thr_self ();
|
||||
}
|
||||
}
|
||||
#endif /* ACE_HAS_THREADS */
|
||||
|
||||
|
||||
// ****************************************************************
|
||||
|
||||
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
|
||||
|
||||
#ifdef ACE_HAS_THREADS
|
||||
ACE_SSL_Context::lock_type * ACE_SSL_Context::locks_ = 0;
|
||||
#endif /* ACE_HAS_THREADS */
|
||||
|
||||
ACE_SSL_Context::ACE_SSL_Context (void)
|
||||
: context_ (0),
|
||||
mode_ (-1),
|
||||
default_verify_mode_ (SSL_VERIFY_NONE),
|
||||
have_ca_ (0)
|
||||
{
|
||||
ACE_SSL_Context::ssl_library_init ();
|
||||
}
|
||||
|
||||
ACE_SSL_Context::~ACE_SSL_Context (void)
|
||||
{
|
||||
if (this->context_)
|
||||
{
|
||||
::SSL_CTX_free (this->context_);
|
||||
this->context_ = 0;
|
||||
}
|
||||
|
||||
ACE_SSL_Context::ssl_library_fini ();
|
||||
}
|
||||
|
||||
ACE_SSL_Context *
|
||||
ACE_SSL_Context::instance (void)
|
||||
{
|
||||
return ACE_Singleton<ACE_SSL_Context, ACE_SYNCH_MUTEX>::instance ();
|
||||
}
|
||||
|
||||
void
|
||||
ACE_SSL_Context::ssl_library_init (void)
|
||||
{
|
||||
ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex,
|
||||
ace_ssl_mon,
|
||||
*ACE_Static_Object_Lock::instance ()));
|
||||
|
||||
if (ssl_library_init_count == 0)
|
||||
{
|
||||
// Initialize the locking callbacks before initializing anything
|
||||
// else.
|
||||
#ifdef ACE_HAS_THREADS
|
||||
int const num_locks = ::CRYPTO_num_locks ();
|
||||
|
||||
this->locks_ = new lock_type[num_locks];
|
||||
ssl_locks = this->locks_;
|
||||
|
||||
# if !defined (WIN32)
|
||||
// This call isn't necessary on some platforms. See the CRYPTO
|
||||
// library's threads(3) man page for details.
|
||||
::CRYPTO_set_id_callback (ACE_SSL_THREAD_ID_NAME);
|
||||
# endif /* !WIN32 */
|
||||
::CRYPTO_set_locking_callback (ACE_SSL_LOCKING_CALLBACK_NAME);
|
||||
#endif /* ACE_HAS_THREADS */
|
||||
|
||||
::SSLeay_add_ssl_algorithms ();
|
||||
::SSL_load_error_strings ();
|
||||
|
||||
// Seed the random number generator. Note that the random
|
||||
// number generator can be seeded more than once to "stir" its
|
||||
// state.
|
||||
|
||||
#ifdef WIN32
|
||||
// Seed the random number generator by sampling the screen.
|
||||
::RAND_screen ();
|
||||
#endif /* WIN32 */
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x00905100L
|
||||
// OpenSSL < 0.9.5 doesn't have EGD support.
|
||||
|
||||
const char *egd_socket_file =
|
||||
ACE_OS::getenv (ACE_SSL_EGD_FILE_ENV);
|
||||
|
||||
if (egd_socket_file != 0)
|
||||
(void) this->egd_file (egd_socket_file);
|
||||
#endif /* OPENSSL_VERSION_NUMBER */
|
||||
|
||||
const char *rand_file =
|
||||
ACE_OS::getenv (ACE_SSL_RAND_FILE_ENV);
|
||||
|
||||
if (rand_file != 0)
|
||||
(void) this->seed_file (rand_file);
|
||||
|
||||
// Initialize the mutexes that will be used by the SSL and
|
||||
// crypto library.
|
||||
|
||||
}
|
||||
|
||||
++ssl_library_init_count;
|
||||
}
|
||||
|
||||
void
|
||||
ACE_SSL_Context::ssl_library_fini (void)
|
||||
{
|
||||
ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex,
|
||||
ace_ssl_mon,
|
||||
*ACE_Static_Object_Lock::instance ()));
|
||||
|
||||
--ssl_library_init_count;
|
||||
if (ssl_library_init_count == 0)
|
||||
{
|
||||
::ERR_free_strings ();
|
||||
::EVP_cleanup ();
|
||||
|
||||
// Clean up the locking callbacks after everything else has been
|
||||
// cleaned up.
|
||||
#ifdef ACE_HAS_THREADS
|
||||
::CRYPTO_set_locking_callback (0);
|
||||
ssl_locks = 0;
|
||||
|
||||
delete [] this->locks_;
|
||||
this->locks_ = 0;
|
||||
|
||||
#endif /* ACE_HAS_THREADS */
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ACE_SSL_Context::set_mode (int mode)
|
||||
{
|
||||
ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex,
|
||||
ace_ssl_mon,
|
||||
*ACE_Static_Object_Lock::instance (),
|
||||
-1));
|
||||
|
||||
if (this->context_ != 0)
|
||||
return -1;
|
||||
|
||||
SSL_METHOD *method = 0;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case ACE_SSL_Context::SSLv2_client:
|
||||
method = ::SSLv2_client_method ();
|
||||
break;
|
||||
case ACE_SSL_Context::SSLv2_server:
|
||||
method = ::SSLv2_server_method ();
|
||||
break;
|
||||
case ACE_SSL_Context::SSLv2:
|
||||
method = ::SSLv2_method ();
|
||||
break;
|
||||
case ACE_SSL_Context::SSLv3_client:
|
||||
method = ::SSLv3_client_method ();
|
||||
break;
|
||||
case ACE_SSL_Context::SSLv3_server:
|
||||
method = ::SSLv3_server_method ();
|
||||
break;
|
||||
case ACE_SSL_Context::SSLv3:
|
||||
method = ::SSLv3_method ();
|
||||
break;
|
||||
case ACE_SSL_Context::SSLv23_client:
|
||||
method = ::SSLv23_client_method ();
|
||||
break;
|
||||
case ACE_SSL_Context::SSLv23_server:
|
||||
method = ::SSLv23_server_method ();
|
||||
break;
|
||||
case ACE_SSL_Context::SSLv23:
|
||||
method = ::SSLv23_method ();
|
||||
break;
|
||||
case ACE_SSL_Context::TLSv1_client:
|
||||
method = ::TLSv1_client_method ();
|
||||
break;
|
||||
case ACE_SSL_Context::TLSv1_server:
|
||||
method = ::TLSv1_server_method ();
|
||||
break;
|
||||
case ACE_SSL_Context::TLSv1:
|
||||
method = ::TLSv1_method ();
|
||||
break;
|
||||
default:
|
||||
method = ::SSLv3_method ();
|
||||
break;
|
||||
}
|
||||
|
||||
this->context_ = ::SSL_CTX_new (method);
|
||||
if (this->context_ == 0)
|
||||
return -1;
|
||||
|
||||
this->mode_ = mode;
|
||||
|
||||
// Load the trusted certificate authority (default) certificate
|
||||
// locations. But do not return -1 on error, doing so confuses CTX
|
||||
// allocation (severe error) with the less important loading of CA
|
||||
// certificate location error. If it is important for your
|
||||
// application then call ACE_SSL_Context::have_trusted_ca(),
|
||||
// immediately following this call to set_mode().
|
||||
(void) this->load_trusted_ca ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ACE_SSL_Context::load_trusted_ca (const char* ca_file,
|
||||
const char* ca_dir,
|
||||
bool use_env_defaults)
|
||||
{
|
||||
this->check_context ();
|
||||
|
||||
if (ca_file == 0 && use_env_defaults)
|
||||
{
|
||||
// Use the default environment settings.
|
||||
ca_file = ACE_OS::getenv (ACE_SSL_CERT_FILE_ENV);
|
||||
if (ca_file == 0)
|
||||
ca_file = ACE_DEFAULT_SSL_CERT_FILE;
|
||||
}
|
||||
|
||||
if (ca_dir == 0 && use_env_defaults)
|
||||
{
|
||||
// Use the default environment settings.
|
||||
ca_dir = ACE_OS::getenv (ACE_SSL_CERT_DIR_ENV);
|
||||
if (ca_dir == 0)
|
||||
ca_dir = ACE_DEFAULT_SSL_CERT_DIR;
|
||||
}
|
||||
|
||||
// NOTE: SSL_CTX_load_verify_locations() returns 0 on error.
|
||||
if (::SSL_CTX_load_verify_locations (this->context_,
|
||||
ca_file,
|
||||
ca_dir) <= 0)
|
||||
{
|
||||
if (ACE::debug ())
|
||||
ACE_SSL_Context::report_error ();
|
||||
return -1;
|
||||
}
|
||||
|
||||
++this->have_ca_;
|
||||
|
||||
// For TLS/SSL servers scan all certificates in ca_file and ca_dir and
|
||||
// list them as acceptable CAs when requesting a client certificate.
|
||||
if (mode_ == SSLv23
|
||||
|| mode_ == SSLv23_server
|
||||
|| mode_ == TLSv1
|
||||
|| mode_ == TLSv1_server
|
||||
|| mode_ == SSLv3
|
||||
|| mode_ == SSLv3_server
|
||||
|| mode_ == SSLv2
|
||||
|| mode_ == SSLv2_server)
|
||||
{
|
||||
// Note: The STACK_OF(X509_NAME) pointer is a copy of the pointer in
|
||||
// the CTX; any changes to it by way of these function calls will
|
||||
// change the CTX directly.
|
||||
STACK_OF (X509_NAME) * cert_names = 0;
|
||||
cert_names = ::SSL_CTX_get_client_CA_list (this->context_);
|
||||
bool error = false;
|
||||
|
||||
// Add CAs from both the file and dir, if specified. There should
|
||||
// already be a STACK_OF(X509_NAME) in the CTX, but if not, we create
|
||||
// one.
|
||||
if (ca_file)
|
||||
{
|
||||
if (cert_names == 0)
|
||||
{
|
||||
if ((cert_names = ::SSL_load_client_CA_file (ca_file)) != 0)
|
||||
::SSL_CTX_set_client_CA_list (this->context_, cert_names);
|
||||
else
|
||||
error = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add new certificate names to the list.
|
||||
error = (0 == ::SSL_add_file_cert_subjects_to_stack (cert_names,
|
||||
ca_file));
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
if (ACE::debug ())
|
||||
ACE_SSL_Context::report_error ();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// SSL_add_dir_cert_subjects_to_stack is defined at 0.9.8a (but not
|
||||
// on OpenVMS or Mac Classic); it may be available earlier. Change
|
||||
// this comparison if so.
|
||||
#if defined (OPENSSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x0090801fL)
|
||||
# if !defined (OPENSSL_SYS_VMS) && !defined (OPENSSL_SYS_MACINTOSH_CLASSIC)
|
||||
# if !defined (OPENSSL_SYS_WIN32) || (OPENSSL_VERSION_NUMBER > 0x0090807fL)
|
||||
|
||||
if (ca_dir != 0)
|
||||
{
|
||||
if (cert_names == 0)
|
||||
{
|
||||
if ((cert_names = sk_X509_NAME_new_null ()) == 0)
|
||||
{
|
||||
if (ACE::debug ())
|
||||
ACE_SSL_Context::report_error ();
|
||||
return -1;
|
||||
}
|
||||
::SSL_CTX_set_client_CA_list (this->context_, cert_names);
|
||||
}
|
||||
if (0 == ::SSL_add_dir_cert_subjects_to_stack (cert_names, ca_dir))
|
||||
{
|
||||
if (ACE::debug ())
|
||||
ACE_SSL_Context::report_error ();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
# endif /* !OPENSSL_SYS_WIN32 || OPENSSL_VERSION_NUMBER >= 0x0090807fL */
|
||||
# endif /* !OPENSSL_SYS_VMS && !OPENSSL_SYS_MACINTOSH_CLASSIC */
|
||||
#endif /* OPENSSL_VERSION_NUMBER >= 0.9.8a release */
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ACE_SSL_Context::private_key (const char *file_name,
|
||||
int type)
|
||||
{
|
||||
if (this->private_key_.type () != -1)
|
||||
return 0;
|
||||
|
||||
this->check_context ();
|
||||
|
||||
this->private_key_ = ACE_SSL_Data_File (file_name, type);
|
||||
|
||||
if (::SSL_CTX_use_PrivateKey_file (this->context_,
|
||||
this->private_key_.file_name (),
|
||||
this->private_key_.type ()) <= 0)
|
||||
{
|
||||
this->private_key_ = ACE_SSL_Data_File ();
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
return this->verify_private_key ();
|
||||
}
|
||||
|
||||
int
|
||||
ACE_SSL_Context::verify_private_key (void)
|
||||
{
|
||||
this->check_context ();
|
||||
|
||||
return (::SSL_CTX_check_private_key (this->context_) <= 0 ? -1 : 0);
|
||||
}
|
||||
|
||||
int
|
||||
ACE_SSL_Context::certificate (const char *file_name,
|
||||
int type)
|
||||
{
|
||||
if (this->certificate_.type () != -1)
|
||||
return 0;
|
||||
|
||||
this->certificate_ = ACE_SSL_Data_File (file_name, type);
|
||||
|
||||
this->check_context ();
|
||||
|
||||
if (::SSL_CTX_use_certificate_file (this->context_,
|
||||
this->certificate_.file_name (),
|
||||
this->certificate_.type ()) <= 0)
|
||||
{
|
||||
this->certificate_ = ACE_SSL_Data_File ();
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ACE_SSL_Context::certificate (X509* cert)
|
||||
{
|
||||
// Is it really a good idea to return 0 if we're not setting the
|
||||
// certificate?
|
||||
if (this->certificate_.type () != -1)
|
||||
return 0;
|
||||
|
||||
this->check_context();
|
||||
|
||||
if (::SSL_CTX_use_certificate (this->context_, cert) <= 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No file is associated with the certificate, set this to a fictional
|
||||
// value so we don't reset it later.
|
||||
this->certificate_ = ACE_SSL_Data_File ("MEMORY CERTIFICATE");
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ACE_SSL_Context::set_verify_peer (int strict, int once, int depth)
|
||||
{
|
||||
this->check_context ();
|
||||
|
||||
// Setup the peer verififcation mode.
|
||||
|
||||
int verify_mode = SSL_VERIFY_PEER;
|
||||
if (once)
|
||||
verify_mode |= SSL_VERIFY_CLIENT_ONCE;
|
||||
if (strict)
|
||||
verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
|
||||
|
||||
// set the default verify mode
|
||||
this->default_verify_mode (verify_mode);
|
||||
|
||||
// Set the max certificate depth but later let the verify_callback
|
||||
// catch the depth error by adding one to the required depth.
|
||||
if (depth > 0)
|
||||
::SSL_CTX_set_verify_depth (this->context_, depth + 1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ACE_SSL_Context::random_seed (const char * seed)
|
||||
{
|
||||
int len = ACE_Utils::truncate_cast<int> (ACE_OS::strlen (seed));
|
||||
::RAND_seed (seed, len);
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x00905100L
|
||||
// RAND_status() returns 1 if the PRNG has enough entropy.
|
||||
return (::RAND_status () == 1 ? 0 : -1);
|
||||
#else
|
||||
return 0; // Ugly, but OpenSSL <= 0.9.4 doesn't have RAND_status().
|
||||
#endif /* OPENSSL_VERSION_NUMBER >= 0x00905100L */
|
||||
}
|
||||
|
||||
int
|
||||
ACE_SSL_Context::egd_file (const char * socket_file)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x00905100L
|
||||
// OpenSSL < 0.9.5 doesn't have EGD support.
|
||||
ACE_UNUSED_ARG (socket_file);
|
||||
ACE_NOTSUP_RETURN (-1);
|
||||
#else
|
||||
// RAND_egd() returns the amount of entropy used to seed the random
|
||||
// number generator. The actual value should be greater than 16,
|
||||
// i.e. 128 bits.
|
||||
if (::RAND_egd (socket_file) > 0)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
#endif /* OPENSSL_VERSION_NUMBER >= 0x00905100L */
|
||||
}
|
||||
|
||||
int
|
||||
ACE_SSL_Context::seed_file (const char * seed_file, long bytes)
|
||||
{
|
||||
// RAND_load_file() returns the number of bytes used to seed the
|
||||
// random number generator. If the file reads ok, check RAND_status to
|
||||
// see if it got enough entropy.
|
||||
if (::RAND_load_file (seed_file, bytes) > 0)
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x00905100L
|
||||
// RAND_status() returns 1 if the PRNG has enough entropy.
|
||||
return (::RAND_status () == 1 ? 0 : -1);
|
||||
#else
|
||||
return 0; // Ugly, but OpenSSL <= 0.9.4 doesn't have RAND_status().
|
||||
#endif /* OPENSSL_VERSION_NUMBER >= 0x00905100L */
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
ACE_SSL_Context::report_error (unsigned long error_code)
|
||||
{
|
||||
if (error_code == 0)
|
||||
return;
|
||||
|
||||
char error_string[256];
|
||||
|
||||
(void) ::ERR_error_string (error_code, error_string);
|
||||
|
||||
ACE_ERROR ((LM_ERROR,
|
||||
ACE_TEXT ("ACE_SSL (%P|%t) error code: %u - %C\n"),
|
||||
error_code,
|
||||
error_string));
|
||||
}
|
||||
|
||||
void
|
||||
ACE_SSL_Context::report_error (void)
|
||||
{
|
||||
unsigned long err = ::ERR_get_error ();
|
||||
ACE_SSL_Context::report_error (err);
|
||||
ACE_OS::last_error (err);
|
||||
}
|
||||
|
||||
int
|
||||
ACE_SSL_Context::dh_params (const char *file_name,
|
||||
int type)
|
||||
{
|
||||
if (this->dh_params_.type () != -1)
|
||||
return 0;
|
||||
|
||||
// For now we only support PEM encodings
|
||||
if (type != SSL_FILETYPE_PEM)
|
||||
return -1;
|
||||
|
||||
this->dh_params_ = ACE_SSL_Data_File (file_name, type);
|
||||
|
||||
this->check_context ();
|
||||
|
||||
{
|
||||
// Swiped from Rescorla's examples and the OpenSSL s_server.c app
|
||||
DH * ret=0;
|
||||
BIO * bio = 0;
|
||||
|
||||
if ((bio = ::BIO_new_file (this->dh_params_.file_name (), "r")) == 0)
|
||||
{
|
||||
this->dh_params_ = ACE_SSL_Data_File ();
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = PEM_read_bio_DHparams (bio, 0, 0, 0);
|
||||
BIO_free (bio);
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
this->dh_params_ = ACE_SSL_Data_File ();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (::SSL_CTX_set_tmp_dh (this->context_, ret) < 0)
|
||||
{
|
||||
this->dh_params_ = ACE_SSL_Data_File ();
|
||||
return -1;
|
||||
}
|
||||
DH_free (ret);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ****************************************************************
|
||||
|
||||
#if defined (ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION)
|
||||
|
||||
template ACE_Singleton<ACE_SSL_Context, ACE_SYNCH_MUTEX> *
|
||||
ACE_Singleton<ACE_SSL_Context, ACE_SYNCH_MUTEX>::singleton_;
|
||||
|
||||
#endif /* ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION */
|
||||
|
||||
ACE_END_VERSIONED_NAMESPACE_DECL
|
||||
384
dep/ACE_wrappers/ace/SSL/SSL_Context.h
Normal file
384
dep/ACE_wrappers/ace/SSL/SSL_Context.h
Normal file
@@ -0,0 +1,384 @@
|
||||
// -*- C++ -*-
|
||||
|
||||
//=============================================================================
|
||||
/**
|
||||
* @file SSL_Context.h
|
||||
*
|
||||
* $Id: SSL_Context.h 80826 2008-03-04 14:51:23Z wotte $
|
||||
*
|
||||
* @author Carlos O'Ryan <coryan@ece.uci.edu>
|
||||
* @author Ossama Othman <ossama@dre.vanderbilt.edu>
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef ACE_SSL_CONTEXT_H
|
||||
#define ACE_SSL_CONTEXT_H
|
||||
|
||||
#include /**/ "ace/pre.h"
|
||||
|
||||
#include "SSL_Export.h"
|
||||
|
||||
#if !defined (ACE_LACKS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif /* ACE_LACKS_PRAGMA_ONCE */
|
||||
|
||||
#include "ace/SString.h"
|
||||
|
||||
#ifdef ACE_HAS_THREADS
|
||||
# include "ace/Synch_Traits.h"
|
||||
#endif /* ACE_HAS_THREADS */
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
|
||||
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
|
||||
|
||||
class ACE_SSL_Export ACE_SSL_Data_File
|
||||
{
|
||||
public:
|
||||
|
||||
/// Default constructor
|
||||
ACE_SSL_Data_File (void);
|
||||
|
||||
/// Contructor from a file name and the file type.
|
||||
ACE_SSL_Data_File (const char *file_name,
|
||||
int type = SSL_FILETYPE_PEM);
|
||||
|
||||
/// The file name
|
||||
const char *file_name (void) const;
|
||||
|
||||
/// The type
|
||||
int type (void) const;
|
||||
|
||||
private:
|
||||
|
||||
/// The file name
|
||||
ACE_CString file_name_;
|
||||
|
||||
/// The type, used by the SSL library to parse the file contents.
|
||||
int type_;
|
||||
};
|
||||
|
||||
// ****************************************************************
|
||||
|
||||
|
||||
/**
|
||||
* @class ACE_SSL_Context
|
||||
*
|
||||
* @brief A wrapper for the OpenSSL SSL_CTX related functions.
|
||||
*
|
||||
* This class provides a wrapper for the SSL_CTX data structure.
|
||||
* Since most applications have a single SSL_CTX structure, this class
|
||||
* can be used as a singleton.
|
||||
*/
|
||||
class ACE_SSL_Export ACE_SSL_Context
|
||||
{
|
||||
public:
|
||||
|
||||
#ifdef ACE_HAS_THREADS
|
||||
typedef ACE_SYNCH_MUTEX lock_type;
|
||||
#endif /* ACE_HAS_THREADS */
|
||||
|
||||
enum {
|
||||
INVALID_METHOD = -1,
|
||||
SSLv2_client = 1,
|
||||
SSLv2_server,
|
||||
SSLv2,
|
||||
SSLv3_client,
|
||||
SSLv3_server,
|
||||
SSLv3,
|
||||
SSLv23_client,
|
||||
SSLv23_server,
|
||||
SSLv23,
|
||||
TLSv1_client,
|
||||
TLSv1_server,
|
||||
TLSv1
|
||||
};
|
||||
|
||||
/// Constructor
|
||||
ACE_SSL_Context (void);
|
||||
|
||||
/// Destructor
|
||||
~ACE_SSL_Context (void);
|
||||
|
||||
/// The Singleton context, the SSL components use the singleton if
|
||||
/// nothing else is available.
|
||||
static ACE_SSL_Context *instance (void);
|
||||
|
||||
/**
|
||||
* Set the CTX mode. The mode can be set only once, afterwards the
|
||||
* function has no effect and returns -1.
|
||||
* Once the mode is set the underlying SSL_CTX is initialized and
|
||||
* the class can be used.
|
||||
* If the mode is not set, then the class automatically initializes
|
||||
* itself to the default mode.
|
||||
*/
|
||||
int set_mode (int mode = ACE_SSL_Context::SSLv23);
|
||||
|
||||
int get_mode (void) const;
|
||||
|
||||
/// Get the SSL context
|
||||
SSL_CTX *context (void);
|
||||
|
||||
/// Get the file name and file format used for the private key
|
||||
int private_key_type (void) const;
|
||||
const char *private_key_file_name (void) const;
|
||||
|
||||
/// Set the private key file.
|
||||
/**
|
||||
* @note This method should only be called after a certificate has
|
||||
* been set since key verification is performed against the
|
||||
* certificate, among other things.
|
||||
*/
|
||||
int private_key (const char *file_name, int type = SSL_FILETYPE_PEM);
|
||||
|
||||
/// Verify that the private key is valid.
|
||||
/**
|
||||
* @note This method should only be called after a certificate has
|
||||
* been set since key verification is performed against the
|
||||
* certificate, among other things.
|
||||
*/
|
||||
int verify_private_key (void);
|
||||
|
||||
/// Get the file name and file format used for the certificate file
|
||||
int certificate_type (void) const;
|
||||
const char *certificate_file_name (void) const;
|
||||
|
||||
/// Set the certificate file.
|
||||
int certificate (const char *file_name,
|
||||
int type = SSL_FILETYPE_PEM);
|
||||
|
||||
/// Load certificate from memory rather than a file.
|
||||
int certificate (X509* cert);
|
||||
|
||||
/**
|
||||
* Load the location of the trusted certification authority
|
||||
* certificates. Note that CA certificates are stored in PEM format
|
||||
* as a sequence of certificates in @a ca_file or as a set of
|
||||
* individual certificates in @a ca_dir (or both).
|
||||
*
|
||||
* Note this method is called by set_mode() to load the default
|
||||
* environment settings for @a ca_file and @a ca_dir, if any. This
|
||||
* allows for automatic service configuration (and backward
|
||||
* compatibility with previous versions).
|
||||
*
|
||||
* Note that the underlying SSL function will add valid file and
|
||||
* directory names to the load location lists maintained as part of
|
||||
* the SSL_CTX table. It therefore doesn't make sense to keep a
|
||||
* copy of the file and path name of the most recently added
|
||||
* @a ca_file or @a ca_path.
|
||||
*
|
||||
* @param[in] ca_file CA file pathname. Passed to
|
||||
* @c SSL_CTX_load_verify_locations() if not
|
||||
* 0. If 0, behavior depends on the value of
|
||||
* @a use_env_defaults.
|
||||
* @param[in] ca_dir CA directory pathname. Passed to
|
||||
* @c SSL_CTX_load_verify_locations() if not
|
||||
* 0. If 0, behavior depends on the value of
|
||||
* @a use_env_defaults.
|
||||
* @param[in] use_env_defaults If false, the specified @a ca_file argument
|
||||
* is passed to
|
||||
* @c SSL_CTX_load_verify_locations(),
|
||||
* regardless of its value.
|
||||
* If true (the default), additional defaults
|
||||
* can be applied to either @a ca_file,
|
||||
* @a ca_dir, or both. The following
|
||||
* additional defaults are applied when the
|
||||
* @a ca_file argument is 0:
|
||||
* - The @c SSL_CERT_FILE environment variable
|
||||
* will be queried for a file name to use as
|
||||
* the @a ca_file argument. The environment
|
||||
* variable name to query can be changed by
|
||||
* supplying a @c ACE_SSL_CERT_FILE_ENV
|
||||
* configuration item when building ACE.
|
||||
* - If there is no @c SSL_CERT_FILE in the
|
||||
* current environment, the file specified
|
||||
* by the @c ACE_DEFAULT_SSL_CERT_FILE ACE
|
||||
* configuration item will be used. The
|
||||
* default value is "cert.pem" on Windows
|
||||
* and "/etc/ssl/cert.pem" on all other
|
||||
* platforms.
|
||||
* The following additional defaults are
|
||||
* applied when the @a ca_dir argument is 0:
|
||||
* - The @c SSL_CERT_DIR environment variable
|
||||
* will be queried for a file name to use as
|
||||
* the @a ca_dir argument. The environment
|
||||
* variable name to query can be changed by
|
||||
* supplying a @c ACE_SSL_CERT_DIR_ENV
|
||||
* configuration item when building ACE.
|
||||
* - If there is no @c SSL_CERT_DIR in the
|
||||
* current environment, the directory
|
||||
* specified by the @c
|
||||
* ACE_DEFAULT_SSL_CERT_DIR ACE
|
||||
* configuration item will be used. The
|
||||
* default value is "certs" on Windows
|
||||
* and "/etc/ssl/certs" on all other
|
||||
* platforms.
|
||||
*
|
||||
* @return 0 for success or -1 on error.
|
||||
*
|
||||
* @see OpenSSL manual SSL_CTX_load_verify_locations(3) for a
|
||||
* detailed description of the CA file and directory requirements
|
||||
* and processing.
|
||||
*/
|
||||
int load_trusted_ca (const char* ca_file = 0,
|
||||
const char* ca_dir = 0,
|
||||
bool use_env_defaults = true);
|
||||
|
||||
/**
|
||||
* Test whether any CA locations have been successfully loaded and
|
||||
* return the number of successful attempts.
|
||||
*
|
||||
* @retval >0 The number of successful CA load attempts.
|
||||
* @retval 0 If all CA load attempts have failed.
|
||||
*/
|
||||
int have_trusted_ca (void) const;
|
||||
|
||||
|
||||
/**
|
||||
* @todo Complete this documentation where elipses(...) are used
|
||||
*
|
||||
* @doc Use this method when certificate chain verification is
|
||||
* required. The default server behaviour is SSL_VERIFY_NONE
|
||||
* i.e. client certicates are requested for verified. This method
|
||||
* can be used to configure server to request client certificates
|
||||
* and perform the certificate verification. If <strict> is set
|
||||
* true the client connection is rejected when certificate
|
||||
* verification fails. Otherwise the session is accepted with a
|
||||
* warning, which is the default behaviour. If <once> is set true
|
||||
* (default), certificates are requested only once per session.
|
||||
* The last parameter <depth> can be used to set the verification
|
||||
* depth.
|
||||
*
|
||||
* Note for verification to work correctly there should be a valid
|
||||
* CA name list set using load_trusted_ca().
|
||||
*
|
||||
* @see OpenSSL documentation of SSL_CTX_set_verify(3) for details of
|
||||
* the verification process.
|
||||
*
|
||||
* @see OpenSSL documentation ... set_verify_depth(3) ...
|
||||
*
|
||||
* Note that this method overrides the use of the
|
||||
* default_verify_mode() method.
|
||||
*/
|
||||
void set_verify_peer (int strict = 0, int once = 1, int depth = 0);
|
||||
|
||||
|
||||
/// TODO: a implementation that will lookup the CTX table for the list
|
||||
/// of files and paths etc.
|
||||
/// Query the location of trusted certification authority
|
||||
/// certificates.
|
||||
// const char* ca_file_name(void) const;
|
||||
// const char* ca_dir_name(void) const;
|
||||
|
||||
/**
|
||||
* Set and query the default verify mode for this context, it is
|
||||
* inherited by all the ACE_SSL objects created using the context.
|
||||
* It can be overriden on a per-ACE_SSL object.
|
||||
*/
|
||||
void default_verify_mode (int mode);
|
||||
int default_verify_mode (void) const;
|
||||
|
||||
/**
|
||||
* @name OpenSSL Random Number Generator Seed Related Methods
|
||||
*
|
||||
* These are methods that can be used to seed OpenSSL's
|
||||
* pseudo-random number generator. These methods can be called more
|
||||
* than once.
|
||||
*/
|
||||
//@{
|
||||
/// Seed the underlying random number generator. This value should
|
||||
/// have at least 128 bits of entropy.
|
||||
static int random_seed (const char * seed);
|
||||
|
||||
/// Set the Entropy Gathering Daemon (EGD) UNIX domain socket file to
|
||||
/// read random seed values from.
|
||||
static int egd_file (const char * socket_file);
|
||||
|
||||
/**
|
||||
* Set the file that contains the random seed value state, and the
|
||||
* amount of bytes to read. "-1" bytes causes the entire file to be
|
||||
* read.
|
||||
*/
|
||||
static int seed_file (const char * seed_file, long bytes = -1);
|
||||
//@}
|
||||
|
||||
/// Print SSL error corresponding to the given error code.
|
||||
static void report_error (unsigned long error_code);
|
||||
|
||||
/// Print the last SSL error for the current thread.
|
||||
static void report_error (void);
|
||||
|
||||
/**
|
||||
* @name Diffie-Hellman (DH) Parameters
|
||||
*
|
||||
* When using DSS-based certificates, Diffie-Hellman keys need to be
|
||||
* exchanged. These must be provided in the form of DH key
|
||||
* generation parameters loaded in, or as fixed keys hardcoded into
|
||||
* the code itself. ACE_SSL supports loaded parameters.
|
||||
*
|
||||
*/
|
||||
//@{
|
||||
/**
|
||||
* Load Diffie-Hellman parameters from file_name. The specified file can be
|
||||
* a standalone file containing only DH parameters (e.g., as created
|
||||
* by <code>openssl dhparam</code>), or it can be a certificate which has
|
||||
* a PEM-encoded set of DH params concatenated on to i.
|
||||
*/
|
||||
int dh_params (const char *file_name, int type = SSL_FILETYPE_PEM);
|
||||
const char *dh_params_file_name () const;
|
||||
int dh_params_file_type () const;
|
||||
//@}
|
||||
|
||||
private:
|
||||
|
||||
/// Verify if the context has been initialized or not.
|
||||
void check_context (void);
|
||||
|
||||
/// @@ More to document
|
||||
void ssl_library_init ();
|
||||
void ssl_library_fini ();
|
||||
|
||||
// = Prevent assignment and copy initialization.
|
||||
//@{
|
||||
ACE_SSL_Context (const ACE_SSL_Context &);
|
||||
ACE_SSL_Context & operator= (const ACE_SSL_Context &);
|
||||
//@}
|
||||
|
||||
private:
|
||||
|
||||
/// The SSL_CTX structure
|
||||
SSL_CTX *context_;
|
||||
|
||||
/// Cache the mode so we can answer fast
|
||||
int mode_;
|
||||
|
||||
/// The private key, certificate, and Diffie-Hellman paramters files
|
||||
ACE_SSL_Data_File private_key_;
|
||||
ACE_SSL_Data_File certificate_;
|
||||
ACE_SSL_Data_File dh_params_;
|
||||
|
||||
/// The default verify mode.
|
||||
int default_verify_mode_;
|
||||
|
||||
/// count of successful CA load attempts
|
||||
int have_ca_;
|
||||
|
||||
#ifdef ACE_HAS_THREADS
|
||||
/// Array of mutexes used internally by OpenSSL when the SSL
|
||||
/// application is multithreaded.
|
||||
static lock_type * locks_;
|
||||
#endif /* ACE_HAS_THREADS */
|
||||
|
||||
};
|
||||
|
||||
ACE_END_VERSIONED_NAMESPACE_DECL
|
||||
|
||||
#if defined(__ACE_INLINE__)
|
||||
#include "SSL_Context.inl"
|
||||
#endif /* __ACE_INLINE__ */
|
||||
|
||||
#include /**/ "ace/post.h"
|
||||
|
||||
#endif /* ACE_SSL_CONTEXT_H */
|
||||
113
dep/ACE_wrappers/ace/SSL/SSL_Context.inl
Normal file
113
dep/ACE_wrappers/ace/SSL/SSL_Context.inl
Normal file
@@ -0,0 +1,113 @@
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// $Id: SSL_Context.inl 80826 2008-03-04 14:51:23Z wotte $
|
||||
|
||||
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
|
||||
|
||||
ACE_INLINE
|
||||
ACE_SSL_Data_File::ACE_SSL_Data_File (void)
|
||||
: type_ (-1)
|
||||
{
|
||||
}
|
||||
|
||||
ACE_INLINE
|
||||
ACE_SSL_Data_File::ACE_SSL_Data_File (const char *file_name,
|
||||
int type)
|
||||
: file_name_ (file_name),
|
||||
type_ (type)
|
||||
{
|
||||
}
|
||||
|
||||
ACE_INLINE const char *
|
||||
ACE_SSL_Data_File::file_name (void) const
|
||||
{
|
||||
return this->file_name_.c_str ();
|
||||
}
|
||||
|
||||
ACE_INLINE int
|
||||
ACE_SSL_Data_File::type (void) const
|
||||
{
|
||||
return this->type_;
|
||||
}
|
||||
|
||||
// ****************************************************************
|
||||
|
||||
ACE_INLINE void
|
||||
ACE_SSL_Context::check_context (void)
|
||||
{
|
||||
if (this->context_ == 0)
|
||||
{
|
||||
this->set_mode ();
|
||||
}
|
||||
|
||||
::SSL_CTX_set_verify (this->context_, this->default_verify_mode (), 0);
|
||||
}
|
||||
|
||||
ACE_INLINE SSL_CTX *
|
||||
ACE_SSL_Context::context (void)
|
||||
{
|
||||
this->check_context ();
|
||||
return this->context_;
|
||||
}
|
||||
|
||||
ACE_INLINE int
|
||||
ACE_SSL_Context::private_key_type (void) const
|
||||
{
|
||||
return this->private_key_.type ();
|
||||
}
|
||||
|
||||
ACE_INLINE const char*
|
||||
ACE_SSL_Context::private_key_file_name (void) const
|
||||
{
|
||||
return this->private_key_.file_name ();
|
||||
}
|
||||
|
||||
ACE_INLINE int
|
||||
ACE_SSL_Context::certificate_type (void) const
|
||||
{
|
||||
return this->certificate_.type ();
|
||||
}
|
||||
|
||||
ACE_INLINE const char*
|
||||
ACE_SSL_Context::certificate_file_name (void) const
|
||||
{
|
||||
return this->certificate_.file_name ();
|
||||
}
|
||||
|
||||
ACE_INLINE int
|
||||
ACE_SSL_Context::dh_params_file_type (void) const
|
||||
{
|
||||
return this->dh_params_.type ();
|
||||
}
|
||||
|
||||
ACE_INLINE const char*
|
||||
ACE_SSL_Context::dh_params_file_name (void) const
|
||||
{
|
||||
return this->dh_params_.file_name ();
|
||||
}
|
||||
|
||||
ACE_INLINE void
|
||||
ACE_SSL_Context::default_verify_mode (int mode)
|
||||
{
|
||||
this->default_verify_mode_ = mode;
|
||||
}
|
||||
|
||||
ACE_INLINE int
|
||||
ACE_SSL_Context::default_verify_mode (void) const
|
||||
{
|
||||
return this->default_verify_mode_;
|
||||
}
|
||||
|
||||
ACE_INLINE int
|
||||
ACE_SSL_Context::get_mode (void) const
|
||||
{
|
||||
return this->mode_;
|
||||
}
|
||||
|
||||
ACE_INLINE int
|
||||
ACE_SSL_Context::have_trusted_ca (void) const
|
||||
{
|
||||
return this->have_ca_;
|
||||
}
|
||||
|
||||
ACE_END_VERSIONED_NAMESPACE_DECL
|
||||
45
dep/ACE_wrappers/ace/SSL/SSL_Export.h
Normal file
45
dep/ACE_wrappers/ace/SSL/SSL_Export.h
Normal file
@@ -0,0 +1,45 @@
|
||||
// -*- C++ -*-
|
||||
// $Id: SSL_Export.h 80826 2008-03-04 14:51:23Z wotte $
|
||||
// Definition for Win32 Export directives.
|
||||
// This file is generated automatically by
|
||||
// generate_export_file.pl
|
||||
// ------------------------------
|
||||
#if !defined (ACE_SSL_EXPORT_H)
|
||||
#define ACE_SSL_EXPORT_H
|
||||
#define ACE_SSL_BUILD_DLL
|
||||
|
||||
#include /**/ "ace/config-all.h"
|
||||
|
||||
#if defined (ACE_AS_STATIC_LIBS) && !defined (ACE_SSL_HAS_DLL)
|
||||
# define ACE_SSL_HAS_DLL 0
|
||||
#endif /* ACE_AS_STATIC_LIBS && ACE_SSL_HAS_DLL */
|
||||
|
||||
#if !defined (ACE_SSL_HAS_DLL)
|
||||
#define ACE_SSL_HAS_DLL 1
|
||||
#endif /* ! ACE_SSL_HAS_DLL */
|
||||
|
||||
#if defined (ACE_SSL_HAS_DLL)
|
||||
# if (ACE_SSL_HAS_DLL == 1)
|
||||
# if defined (ACE_SSL_BUILD_DLL)
|
||||
# define ACE_SSL_Export ACE_Proper_Export_Flag
|
||||
# define ACE_SSL_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T)
|
||||
# define ACE_SSL_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
|
||||
# else
|
||||
# define ACE_SSL_Export ACE_Proper_Import_Flag
|
||||
# define ACE_SSL_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T)
|
||||
# define ACE_SSL_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
|
||||
# endif /* ACE_SSL_BUILD_DLL */
|
||||
# else
|
||||
# define ACE_SSL_Export
|
||||
# define ACE_SSL_SINGLETON_DECLARATION(T)
|
||||
# define ACE_SSL_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
|
||||
# endif /* ! ACE_SSL_HAS_DLL == 1 */
|
||||
#else
|
||||
# define ACE_SSL_Export
|
||||
# define ACE_SSL_SINGLETON_DECLARATION(T)
|
||||
# define ACE_SSL_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
|
||||
#endif /* ACE_SSL_HAS_DLL */
|
||||
|
||||
#endif /* ACE_SSL_EXPORT_H */
|
||||
|
||||
// End of auto generated file.
|
||||
72
dep/ACE_wrappers/ace/SSL/SSL_SOCK.cpp
Normal file
72
dep/ACE_wrappers/ace/SSL/SSL_SOCK.cpp
Normal file
@@ -0,0 +1,72 @@
|
||||
// $Id: SSL_SOCK.cpp 80826 2008-03-04 14:51:23Z wotte $
|
||||
|
||||
#include "SSL_SOCK.h"
|
||||
|
||||
#if !defined (__ACE_INLINE__)
|
||||
#include "SSL_SOCK.inl"
|
||||
#endif /* __ACE_INLINE__ */
|
||||
|
||||
#include "ace/OS_NS_errno.h"
|
||||
#include "ace/os_include/os_signal.h"
|
||||
|
||||
ACE_RCSID (ACE_SSL,
|
||||
SSL_SOCK,
|
||||
"$Id: SSL_SOCK.cpp 80826 2008-03-04 14:51:23Z wotte $")
|
||||
|
||||
|
||||
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
|
||||
|
||||
ACE_SSL_SOCK::ACE_SSL_SOCK (void)
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK::ACE_SSL_SOCK");
|
||||
}
|
||||
|
||||
ACE_SSL_SOCK::~ACE_SSL_SOCK (void)
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK::~ACE_SSL_SOCK");
|
||||
}
|
||||
|
||||
int
|
||||
ACE_SSL_SOCK::enable (int value) const
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK::enable");
|
||||
|
||||
switch (value)
|
||||
{
|
||||
#ifdef SIGURG
|
||||
case SIGURG:
|
||||
case ACE_SIGURG:
|
||||
#endif /* SIGURG */
|
||||
case SIGIO:
|
||||
case ACE_SIGIO:
|
||||
case ACE_CLOEXEC:
|
||||
ACE_NOTSUP_RETURN (-1);
|
||||
case ACE_NONBLOCK:
|
||||
return ACE_IPC_SAP::enable (value);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ACE_SSL_SOCK::disable (int value) const
|
||||
{
|
||||
ACE_TRACE("ACE_SSL_SOCK::disable");
|
||||
switch (value)
|
||||
{
|
||||
#ifdef SIGURG
|
||||
case SIGURG:
|
||||
case ACE_SIGURG:
|
||||
#endif /* SIGURG */
|
||||
case SIGIO:
|
||||
case ACE_SIGIO:
|
||||
case ACE_CLOEXEC:
|
||||
ACE_NOTSUP_RETURN (-1);
|
||||
case ACE_NONBLOCK:
|
||||
return ACE_IPC_SAP::disable (value);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
ACE_END_VERSIONED_NAMESPACE_DECL
|
||||
103
dep/ACE_wrappers/ace/SSL/SSL_SOCK.h
Normal file
103
dep/ACE_wrappers/ace/SSL/SSL_SOCK.h
Normal file
@@ -0,0 +1,103 @@
|
||||
// -*- C++ -*-
|
||||
|
||||
//=============================================================================
|
||||
/**
|
||||
* @file SSL_SOCK.h
|
||||
*
|
||||
* $Id: SSL_SOCK.h 80826 2008-03-04 14:51:23Z wotte $
|
||||
*
|
||||
* @author Ossama Othman <ossama@ece.uci.edu>
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef ACE_SSL_SOCK_H
|
||||
#define ACE_SSL_SOCK_H
|
||||
|
||||
#include /**/ "ace/pre.h"
|
||||
|
||||
#include "SSL_Export.h"
|
||||
|
||||
#if !defined (ACE_LACKS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif /* ACE_LACKS_PRAGMA_ONCE */
|
||||
|
||||
#include "ace/SOCK.h"
|
||||
|
||||
#if defined (ACE_HAS_TEMPLATE_TYPEDEFS)
|
||||
# define ACE_SSL_SOCK_ACCEPTOR ACE_SSL_SOCK_Acceptor
|
||||
# define ACE_SSL_SOCK_CONNECTOR ACE_SSL_SOCK_Connector
|
||||
# define ACE_SSL_SOCK_STREAM ACE_SSL_SOCK_Stream
|
||||
#else
|
||||
# define ACE_SSL_SOCK_ACCEPTOR ACE_SSL_SOCK_Acceptor, ACE_INET_Addr
|
||||
# define ACE_SSL_SOCK_CONNECTOR ACE_SSL_SOCK_Connector, ACE_INET_Addr
|
||||
# define ACE_SSL_SOCK_STREAM ACE_SSL_SOCK_Stream, ACE_INET_Addr
|
||||
#endif /* ACE_HAS_TEMPLATE_TYPEDEFS */
|
||||
|
||||
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
|
||||
|
||||
/**
|
||||
* @class ACE_SSL_SOCK
|
||||
*
|
||||
* @brief An abstract class that forms the basis for more specific
|
||||
* classes, such as "ACE_SSL_SOCK_Acceptor" and
|
||||
* "ACE_SSL_SOCK_Stream". Do not instantiate this class.
|
||||
*
|
||||
* This class provides functions that are common to all of the
|
||||
* ACE_SSL_SOCK_* classes. ACE_SSL_SOCK provides the ability
|
||||
* to get and set socket options, get the local and remote
|
||||
* addresses, and close the socket.
|
||||
*/
|
||||
class ACE_SSL_Export ACE_SSL_SOCK : public ACE_SOCK
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Override ACE_SOCK base class implementations with these SSL
|
||||
* specific ones.
|
||||
*/
|
||||
//@{
|
||||
int set_option (int level,
|
||||
int option,
|
||||
void *optval,
|
||||
int optlen) const;
|
||||
int get_option (int level,
|
||||
int option,
|
||||
void *optval,
|
||||
int *optlen) const;
|
||||
int enable (int value) const;
|
||||
int disable (int value) const;
|
||||
void set_handle (ACE_HANDLE);
|
||||
ACE_HANDLE get_handle (void) const;
|
||||
int control (int cmd, void *arg) const;
|
||||
//@}
|
||||
|
||||
protected:
|
||||
|
||||
/// Default constructor is private to prevent instances of this class
|
||||
/// from being defined.
|
||||
ACE_SSL_SOCK (void);
|
||||
|
||||
/// Destructor
|
||||
/**
|
||||
* Not a virtual destructor. Protected destructor to prevent
|
||||
* operator delete() from being called through a base class
|
||||
* ACE_SSL_SOCK pointer/reference.
|
||||
*/
|
||||
~ACE_SSL_SOCK (void);
|
||||
|
||||
};
|
||||
|
||||
ACE_END_VERSIONED_NAMESPACE_DECL
|
||||
|
||||
#if defined (__ACE_INLINE__)
|
||||
#include "SSL_SOCK.inl"
|
||||
#endif /* __ACE_INLINE__ */
|
||||
|
||||
#include /**/ "ace/post.h"
|
||||
|
||||
#endif /* ACE_SSL_SOCK_H */
|
||||
|
||||
|
||||
|
||||
|
||||
71
dep/ACE_wrappers/ace/SSL/SSL_SOCK.inl
Normal file
71
dep/ACE_wrappers/ace/SSL/SSL_SOCK.inl
Normal file
@@ -0,0 +1,71 @@
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// $Id: SSL_SOCK.inl 80826 2008-03-04 14:51:23Z wotte $
|
||||
|
||||
#include "ace/OS_NS_sys_socket.h"
|
||||
|
||||
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
|
||||
|
||||
ACE_INLINE void
|
||||
ACE_SSL_SOCK::set_handle (ACE_HANDLE fd)
|
||||
{
|
||||
this->ACE_SOCK::set_handle (fd);
|
||||
}
|
||||
|
||||
ACE_INLINE ACE_HANDLE
|
||||
ACE_SSL_SOCK::get_handle (void) const
|
||||
{
|
||||
// return this->ssl_ ? (ACE_HANDLE) ::SSL_get_fd (this->ssl_) : ACE_INVALID_HANDLE;
|
||||
return this->ACE_SOCK::get_handle ();
|
||||
}
|
||||
|
||||
|
||||
ACE_INLINE int
|
||||
ACE_SSL_SOCK::control (int cmd, void *arg) const
|
||||
{
|
||||
return ACE_OS::ioctl (this->get_handle (), cmd, arg);
|
||||
}
|
||||
|
||||
ACE_INLINE int
|
||||
ACE_SSL_SOCK::set_option (int level,
|
||||
int option,
|
||||
void *optval,
|
||||
int optlen) const
|
||||
{
|
||||
// switch (option)
|
||||
// {
|
||||
// case SO_SNDBUF:
|
||||
// return ::BIO_set_write_buffer_size (this->io_bio_, *((int *) optval));
|
||||
// case SO_RCVCBUF:
|
||||
// return ::BIO_set_read_buffer_size (this->io_bio_, *((int *) optval));
|
||||
// default:
|
||||
return ACE_OS::setsockopt (this->get_handle (),
|
||||
level,
|
||||
option, (char *) optval,
|
||||
optlen);
|
||||
// }
|
||||
}
|
||||
|
||||
// Provides access to the ACE_OS::getsockopt system call.
|
||||
|
||||
ACE_INLINE int
|
||||
ACE_SSL_SOCK::get_option (int level,
|
||||
int option,
|
||||
void *optval,
|
||||
int *optlen) const
|
||||
{
|
||||
// switch (option)
|
||||
// {
|
||||
// case SO_SNDBUF:
|
||||
// return ::BIO_get_write_buffer_size (this->io_bio_, *((int *) optval));
|
||||
// case SO_RCVCBUF:
|
||||
// return ::BIO_get_read_buffer_size (this->io_bio_, *((int *) optval));
|
||||
// default:
|
||||
return ACE_OS::getsockopt (this->get_handle (),
|
||||
level,
|
||||
option, (char *) optval,
|
||||
optlen);
|
||||
// }
|
||||
}
|
||||
|
||||
ACE_END_VERSIONED_NAMESPACE_DECL
|
||||
250
dep/ACE_wrappers/ace/SSL/SSL_SOCK_Acceptor.cpp
Normal file
250
dep/ACE_wrappers/ace/SSL/SSL_SOCK_Acceptor.cpp
Normal file
@@ -0,0 +1,250 @@
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// $Id: SSL_SOCK_Acceptor.cpp 82577 2008-08-09 17:43:11Z mitza $
|
||||
|
||||
|
||||
#include "SSL_SOCK_Acceptor.h"
|
||||
|
||||
#include "ace/Handle_Set.h"
|
||||
#include "ace/OS_Errno.h"
|
||||
#include "ace/OS_NS_errno.h"
|
||||
#include "ace/Log_Msg.h"
|
||||
#include "ace/Time_Value.h"
|
||||
#include "ace/Countdown_Time.h"
|
||||
#include "ace/Truncate.h"
|
||||
|
||||
#if !defined (__ACE_INLINE__)
|
||||
#include "SSL_SOCK_Acceptor.inl"
|
||||
#endif /* __ACE_INLINE__ */
|
||||
|
||||
ACE_RCSID (ACE_SSL,
|
||||
SSL_SOCK_Acceptor,
|
||||
"$Id: SSL_SOCK_Acceptor.cpp 82577 2008-08-09 17:43:11Z mitza $")
|
||||
|
||||
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
|
||||
|
||||
ACE_ALLOC_HOOK_DEFINE(ACE_SSL_SOCK_Acceptor)
|
||||
|
||||
ACE_SSL_SOCK_Acceptor::~ACE_SSL_SOCK_Acceptor (void)
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Acceptor::~ACE_SSL_SOCK_Acceptor");
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ACE_SSL_SOCK_Acceptor::ssl_accept (ACE_SSL_SOCK_Stream &new_stream,
|
||||
ACE_Time_Value *timeout) const
|
||||
{
|
||||
SSL *ssl = new_stream.ssl ();
|
||||
|
||||
if (SSL_is_init_finished (ssl))
|
||||
return 0;
|
||||
|
||||
if (!SSL_in_accept_init (ssl))
|
||||
::SSL_set_accept_state (ssl);
|
||||
|
||||
ACE_HANDLE handle = new_stream.get_handle ();
|
||||
|
||||
// We're going to call SSL_accept, optionally doing ACE::select and
|
||||
// retrying the SSL_accept, until the SSL handshake is done or
|
||||
// it fails.
|
||||
// To get the timeout affect, set the socket to nonblocking mode
|
||||
// before beginning if there is a timeout specified. If the timeout
|
||||
// is 0 (wait as long as it takes) then don't worry about the blocking
|
||||
// status; we'll block in SSL_accept if the socket is blocking, and
|
||||
// block in ACE::select if not.
|
||||
int reset_blocking_mode = 0;
|
||||
if (timeout != 0)
|
||||
{
|
||||
reset_blocking_mode = ACE_BIT_DISABLED (ACE::get_flags (handle),
|
||||
ACE_NONBLOCK);
|
||||
// Set the handle into non-blocking mode if it's not already
|
||||
// in it.
|
||||
if (reset_blocking_mode
|
||||
&& ACE::set_flags (handle,
|
||||
ACE_NONBLOCK) == -1)
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Take into account the time between each select() call below.
|
||||
ACE_Countdown_Time countdown (timeout);
|
||||
|
||||
int status;
|
||||
do
|
||||
{
|
||||
// These handle sets are used to set up for whatever SSL_accept
|
||||
// says it wants next. They're reset on each pass around the loop.
|
||||
ACE_Handle_Set rd_handle;
|
||||
ACE_Handle_Set wr_handle;
|
||||
|
||||
status = ::SSL_accept (ssl);
|
||||
switch (::SSL_get_error (ssl, status))
|
||||
{
|
||||
case SSL_ERROR_NONE:
|
||||
status = 0; // To tell caller about success
|
||||
break; // Done
|
||||
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
wr_handle.set_bit (handle);
|
||||
status = 1; // Wait for more activity
|
||||
break;
|
||||
|
||||
case SSL_ERROR_WANT_READ:
|
||||
rd_handle.set_bit (handle);
|
||||
status = 1; // Wait for more activity
|
||||
break;
|
||||
|
||||
case SSL_ERROR_ZERO_RETURN:
|
||||
// The peer has notified us that it is shutting down via
|
||||
// the SSL "close_notify" message so we need to
|
||||
// shutdown, too.
|
||||
status = -1;
|
||||
break;
|
||||
|
||||
case SSL_ERROR_SYSCALL:
|
||||
// On some platforms (e.g. MS Windows) OpenSSL does not
|
||||
// store the last error in errno so explicitly do so.
|
||||
//
|
||||
// Explicitly check for EWOULDBLOCK since it doesn't get
|
||||
// converted to an SSL_ERROR_WANT_{READ,WRITE} on some
|
||||
// platforms. If SSL_accept failed outright, though, don't
|
||||
// bother checking more. This can happen if the socket gets
|
||||
// closed during the handshake.
|
||||
if (ACE_OS::set_errno_to_last_error () == EWOULDBLOCK &&
|
||||
status == -1)
|
||||
{
|
||||
// Although the SSL_ERROR_WANT_READ/WRITE isn't getting
|
||||
// set correctly, the read/write state should be valid.
|
||||
// Use that to decide what to do.
|
||||
status = 1; // Wait for more activity
|
||||
if (SSL_want_write (ssl))
|
||||
wr_handle.set_bit (handle);
|
||||
else if (SSL_want_read (ssl))
|
||||
rd_handle.set_bit (handle);
|
||||
else
|
||||
status = -1; // Doesn't want anything - bail out
|
||||
}
|
||||
else
|
||||
status = -1;
|
||||
break;
|
||||
|
||||
default:
|
||||
ACE_SSL_Context::report_error ();
|
||||
status = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (status == 1)
|
||||
{
|
||||
// Must have at least one handle to wait for at this point.
|
||||
ACE_ASSERT (rd_handle.num_set() == 1 || wr_handle.num_set () == 1);
|
||||
status = ACE::select (int (handle) + 1,
|
||||
&rd_handle,
|
||||
&wr_handle,
|
||||
0,
|
||||
timeout);
|
||||
|
||||
(void) countdown.update ();
|
||||
|
||||
// 0 is timeout, so we're done.
|
||||
// -1 is error, so we're done.
|
||||
// Could be both handles set (same handle in both masks) so
|
||||
// set to 1.
|
||||
if (status >= 1)
|
||||
status = 1;
|
||||
else // Timeout or failure
|
||||
status = -1;
|
||||
}
|
||||
|
||||
} while (status == 1 && !SSL_is_init_finished (ssl));
|
||||
|
||||
if (reset_blocking_mode)
|
||||
{
|
||||
ACE_Errno_Guard eguard (errno);
|
||||
ACE::clr_flags (handle, ACE_NONBLOCK);
|
||||
}
|
||||
|
||||
return (status == -1 ? -1 : 0);
|
||||
|
||||
}
|
||||
|
||||
// General purpose routine for accepting new connections.
|
||||
// Since our underlying acceptor is of the plain old ACE_SOCK_Acceptor
|
||||
// variety, get the basic socket setup done with it, then take care of
|
||||
// the SSL handshake if the socket is accepted.
|
||||
int
|
||||
ACE_SSL_SOCK_Acceptor::accept (ACE_SSL_SOCK_Stream &new_stream,
|
||||
ACE_Addr *remote_addr,
|
||||
ACE_Time_Value *timeout,
|
||||
int restart,
|
||||
int reset_new_handle) const
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Acceptor::accept");
|
||||
|
||||
// Take into account the time to complete the basic TCP handshake
|
||||
// and the SSL handshake.
|
||||
ACE_Countdown_Time countdown (timeout);
|
||||
|
||||
ACE_SOCK_Stream temp_stream;
|
||||
if (-1 == this->acceptor_.accept (temp_stream,
|
||||
remote_addr,
|
||||
timeout,
|
||||
restart,
|
||||
reset_new_handle))
|
||||
return -1;
|
||||
|
||||
(void) countdown.update ();
|
||||
|
||||
new_stream.set_handle (temp_stream.get_handle ());
|
||||
temp_stream.set_handle (ACE_INVALID_HANDLE);
|
||||
|
||||
if (this->ssl_accept (new_stream, timeout) == -1)
|
||||
{
|
||||
new_stream.close ();
|
||||
new_stream.set_handle (ACE_INVALID_HANDLE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
ACE_SSL_SOCK_Acceptor::accept (ACE_SSL_SOCK_Stream &new_stream,
|
||||
ACE_Accept_QoS_Params qos_params,
|
||||
ACE_Addr *remote_addr,
|
||||
ACE_Time_Value *timeout,
|
||||
int restart,
|
||||
int reset_new_handle) const
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Acceptor::accept");
|
||||
|
||||
// Take into account the time to complete the basic TCP handshake
|
||||
// and the SSL handshake.
|
||||
ACE_Countdown_Time countdown (timeout);
|
||||
|
||||
ACE_SOCK_Stream temp_stream;
|
||||
if (-1 == this->acceptor_.accept (temp_stream,
|
||||
qos_params,
|
||||
remote_addr,
|
||||
timeout,
|
||||
restart,
|
||||
reset_new_handle))
|
||||
return -1;
|
||||
|
||||
(void) countdown.update ();
|
||||
|
||||
new_stream.set_handle (temp_stream.get_handle ());
|
||||
temp_stream.set_handle (ACE_INVALID_HANDLE);
|
||||
|
||||
if (this->ssl_accept (new_stream, timeout) == -1)
|
||||
{
|
||||
new_stream.close ();
|
||||
new_stream.set_handle (ACE_INVALID_HANDLE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ACE_END_VERSIONED_NAMESPACE_DECL
|
||||
197
dep/ACE_wrappers/ace/SSL/SSL_SOCK_Acceptor.h
Normal file
197
dep/ACE_wrappers/ace/SSL/SSL_SOCK_Acceptor.h
Normal file
@@ -0,0 +1,197 @@
|
||||
// -*- C++ -*-
|
||||
|
||||
//=============================================================================
|
||||
/**
|
||||
* @file SSL_SOCK_Acceptor.h
|
||||
*
|
||||
* $Id: SSL_SOCK_Acceptor.h 81826 2008-06-02 15:29:53Z schmidt $
|
||||
*
|
||||
* @author John Heitmann
|
||||
* @author Chris Zimman
|
||||
* @author Ossama Othman <ossama@uci.edu>
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
#ifndef ACE_SSL_SOCK_ACCEPTOR_H
|
||||
#define ACE_SSL_SOCK_ACCEPTOR_H
|
||||
|
||||
#include /**/ "ace/pre.h"
|
||||
|
||||
#include "SSL_Export.h"
|
||||
|
||||
#if !defined (ACE_LACKS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif /* ACE_LACKS_PRAGMA_ONCE */
|
||||
|
||||
#include "SSL_SOCK_Stream.h"
|
||||
|
||||
#include "ace/SOCK_Acceptor.h"
|
||||
#include "ace/OS_QoS.h"
|
||||
|
||||
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
|
||||
|
||||
/**
|
||||
* @class ACE_SSL_SOCK_Acceptor
|
||||
*
|
||||
* @brief Defines a factory that creates new @c ACE_SSL_SOCK_Stream
|
||||
* objects passively.
|
||||
*
|
||||
* The ACE_SSL_SOCK_Acceptor has its own @c ACE_SOCK_Acceptor
|
||||
* which handles the basic socket acceptance. This class is a
|
||||
* wrapper which adds the SSL acceptance handshake handling.
|
||||
* Since SSL is record oriented, some additional steps must be taken
|
||||
* after the basic socket acceptance to complete the SSL handshake that
|
||||
* takes place at session establishment.
|
||||
*
|
||||
* @note The user must currently ensure that only one thread services
|
||||
* a given SSL session at any given time since some underlying
|
||||
* SSL implementations, such as OpenSSL, are not entirely
|
||||
* thread-safe or reentrant.
|
||||
*/
|
||||
class ACE_SSL_Export ACE_SSL_SOCK_Acceptor : public ACE_SSL_SOCK
|
||||
{
|
||||
public:
|
||||
|
||||
/// Default constructor.
|
||||
ACE_SSL_SOCK_Acceptor (void);
|
||||
|
||||
/// Default destructor.
|
||||
~ACE_SSL_SOCK_Acceptor (void);
|
||||
|
||||
/**
|
||||
* Initiate a passive mode SSL/BSD-style acceptor socket.
|
||||
* @param local_sap The address that we're going to listen for
|
||||
* connections on. If this is @c ACE_Addr::sap_any,
|
||||
* this socket listens on an the "any" IP address
|
||||
* and selects an unused port. To find out what port
|
||||
* was selected, call this object's
|
||||
* @c ACE_SOCK::get_local_addr(ACE_Addr&) method
|
||||
* upon return.
|
||||
*/
|
||||
ACE_SSL_SOCK_Acceptor (const ACE_Addr &local_sap,
|
||||
int reuse_addr = 0,
|
||||
int protocol_family = PF_UNSPEC,
|
||||
int backlog = ACE_DEFAULT_BACKLOG,
|
||||
int protocol = 0);
|
||||
|
||||
/**
|
||||
* Initiate a passive-mode QoS-enabled acceptor socket.
|
||||
* @param local_sap The address that we're going to listen for
|
||||
* connections on. If this is @c ACE_Addr::sap_any,
|
||||
* this socket listens on an the "any" IP address
|
||||
* and selects an unused port. To find out what port
|
||||
* was selected, call this object's
|
||||
* @c ACE_SOCK::get_local_addr(ACE_Addr&) method
|
||||
* upon return.
|
||||
*/
|
||||
ACE_SSL_SOCK_Acceptor (const ACE_Addr &local_sap,
|
||||
ACE_Protocol_Info *protocolinfo,
|
||||
ACE_SOCK_GROUP g,
|
||||
u_long flags,
|
||||
int reuse_addr,
|
||||
int protocol_family = PF_UNSPEC,
|
||||
int backlog = ACE_DEFAULT_BACKLOG,
|
||||
int protocol = 0);
|
||||
|
||||
/**
|
||||
* Initiate a passive mode SSL/BSD-style acceptor socket.
|
||||
* @param local_sap The address that we're going to listen for
|
||||
* connections on. If this is @c ACE_Addr::sap_any,
|
||||
* this socket listens on an the "any" IP address
|
||||
* and selects an unused port. To find out what port
|
||||
* was selected, call this object's
|
||||
* @c ACE_SOCK::get_local_addr(ACE_Addr&) method
|
||||
* upon return.
|
||||
*
|
||||
* @return 0 if success; -1 for failure (errno contains error code).
|
||||
*/
|
||||
int open (const ACE_Addr &local_sap,
|
||||
int reuse_addr = 0,
|
||||
int protocol_family = PF_UNSPEC,
|
||||
int backlog = ACE_DEFAULT_BACKLOG,
|
||||
int protocol = 0);
|
||||
|
||||
/// Close the listening socket.
|
||||
int close (void);
|
||||
|
||||
/**
|
||||
* @name Passive Connection "accept" Methods
|
||||
*
|
||||
* These are the canonical methods exposed by the Acceptor pattern.
|
||||
*/
|
||||
//@{
|
||||
/**
|
||||
* Accept a new ACE_SSL_SOCK_Stream connection. On successful return,
|
||||
* the socket has been accepted and the SSL handshake has been completed.
|
||||
* @param new_stream The @c ACE_SSL_SOCK_Stream object that will receive
|
||||
* the new SSL socket.
|
||||
* @param remote_addr Pointer to an @c ACE_INET_Addr object that will
|
||||
* receive the address of the peer that connected.
|
||||
* @param timeout The maximum time to wait for the combined socket
|
||||
* acceptance and handshake completion. 0 means
|
||||
* block forever, a timeout of {0, 0} means poll.
|
||||
* @param restart 1 means "restart if interrupted," that is,
|
||||
* if errno == EINTR.
|
||||
*
|
||||
* @return 0 if success; -1 for failure (errno contains error code).
|
||||
*/
|
||||
int accept (ACE_SSL_SOCK_Stream &new_stream,
|
||||
ACE_Addr *remote_addr = 0,
|
||||
ACE_Time_Value *timeout = 0,
|
||||
int restart = 1,
|
||||
int reset_new_handle = 0) const;
|
||||
|
||||
/**
|
||||
* Accept a new ACE_SSL_SOCK_Stream connection using the RVSP QoS
|
||||
* information in qos_params.
|
||||
* @param new_stream The @c ACE_SSL_SOCK_Stream object that will receive
|
||||
* the new SSL socket.
|
||||
* @param remote_addr Pointer to an @c ACE_INET_Addr object that will
|
||||
* receive the address of the peer that connected.
|
||||
* @param timeout The maximum time to wait for the combined socket
|
||||
* acceptance and handshake completion. 0 means
|
||||
* block forever, a timeout of {0, 0} means poll.
|
||||
* @param restart 1 means "restart if interrupted," that is,
|
||||
* if errno == EINTR.
|
||||
*
|
||||
* @return 0 if success; -1 for failure (errno contains error code).
|
||||
*/
|
||||
int accept (ACE_SSL_SOCK_Stream &new_stream,
|
||||
ACE_Accept_QoS_Params qos_params,
|
||||
ACE_Addr *remote_addr = 0,
|
||||
ACE_Time_Value *timeout = 0,
|
||||
int restart = 1,
|
||||
int reset_new_handle = 0) const;
|
||||
//@}
|
||||
|
||||
/// Meta-type info
|
||||
//@{
|
||||
typedef ACE_INET_Addr PEER_ADDR;
|
||||
typedef ACE_SSL_SOCK_Stream PEER_STREAM;
|
||||
//@}
|
||||
|
||||
/// Declare the dynamic allocation hooks.
|
||||
ACE_ALLOC_HOOK_DECLARE;
|
||||
|
||||
protected:
|
||||
|
||||
/// Complete SSL passive connection establishment.
|
||||
int ssl_accept (ACE_SSL_SOCK_Stream &new_stream,
|
||||
ACE_Time_Value *timeout) const;
|
||||
|
||||
private:
|
||||
|
||||
/// The BSD-socket workhorse
|
||||
ACE_SOCK_Acceptor acceptor_;
|
||||
|
||||
};
|
||||
|
||||
ACE_END_VERSIONED_NAMESPACE_DECL
|
||||
|
||||
#if defined (__ACE_INLINE__)
|
||||
#include "SSL_SOCK_Acceptor.inl"
|
||||
#endif /* __ACE_INLINE__ */
|
||||
|
||||
#include /**/ "ace/post.h"
|
||||
|
||||
#endif /* ACE_SSL_SOCK_ACCEPTOR_H */
|
||||
85
dep/ACE_wrappers/ace/SSL/SSL_SOCK_Acceptor.inl
Normal file
85
dep/ACE_wrappers/ace/SSL/SSL_SOCK_Acceptor.inl
Normal file
@@ -0,0 +1,85 @@
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// $Id: SSL_SOCK_Acceptor.inl 80826 2008-03-04 14:51:23Z wotte $
|
||||
|
||||
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
|
||||
|
||||
ACE_INLINE
|
||||
ACE_SSL_SOCK_Acceptor::ACE_SSL_SOCK_Acceptor (void)
|
||||
: acceptor_ ()
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Acceptor::ACE_SSL_SOCK_Acceptor");
|
||||
}
|
||||
|
||||
ACE_INLINE
|
||||
ACE_SSL_SOCK_Acceptor::ACE_SSL_SOCK_Acceptor (const ACE_Addr &local_sap,
|
||||
int reuse_addr,
|
||||
int protocol_family,
|
||||
int backlog,
|
||||
int protocol)
|
||||
: acceptor_ (local_sap,
|
||||
reuse_addr,
|
||||
protocol_family,
|
||||
backlog,
|
||||
protocol)
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Acceptor::ACE_SSL_SOCK_Acceptor");
|
||||
|
||||
this->set_handle (this->acceptor_.get_handle ());
|
||||
}
|
||||
|
||||
ACE_INLINE
|
||||
ACE_SSL_SOCK_Acceptor::ACE_SSL_SOCK_Acceptor (const ACE_Addr &local_sap,
|
||||
ACE_Protocol_Info *protocolinfo,
|
||||
ACE_SOCK_GROUP g,
|
||||
u_long flags,
|
||||
int reuse_addr,
|
||||
int protocol_family,
|
||||
int backlog,
|
||||
int protocol)
|
||||
: acceptor_ (local_sap,
|
||||
protocolinfo,
|
||||
g,
|
||||
flags,
|
||||
reuse_addr,
|
||||
protocol_family,
|
||||
backlog,
|
||||
protocol)
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Acceptor::ACE_SSL_SOCK_Acceptor");
|
||||
|
||||
this->set_handle (this->acceptor_.get_handle ());
|
||||
}
|
||||
|
||||
ACE_INLINE int
|
||||
ACE_SSL_SOCK_Acceptor::open (const ACE_Addr &local_sap,
|
||||
int reuse_addr,
|
||||
int protocol_family,
|
||||
int backlog,
|
||||
int protocol)
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Acceptor::open");
|
||||
if (this->acceptor_.open (local_sap,
|
||||
reuse_addr,
|
||||
protocol_family,
|
||||
backlog,
|
||||
protocol) != 0)
|
||||
return -1;
|
||||
else
|
||||
this->set_handle (this->acceptor_.get_handle ());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ACE_INLINE int
|
||||
ACE_SSL_SOCK_Acceptor::close (void)
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Acceptor::close ()");
|
||||
|
||||
int result = this->acceptor_.close ();
|
||||
this->set_handle (ACE_INVALID_HANDLE);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ACE_END_VERSIONED_NAMESPACE_DECL
|
||||
425
dep/ACE_wrappers/ace/SSL/SSL_SOCK_Connector.cpp
Normal file
425
dep/ACE_wrappers/ace/SSL/SSL_SOCK_Connector.cpp
Normal file
@@ -0,0 +1,425 @@
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// $Id: SSL_SOCK_Connector.cpp 82577 2008-08-09 17:43:11Z mitza $
|
||||
|
||||
#include "SSL_SOCK_Connector.h"
|
||||
|
||||
#include "ace/OS_NS_errno.h"
|
||||
#include "ace/Handle_Set.h"
|
||||
#include "ace/INET_Addr.h"
|
||||
#include "ace/Log_Msg.h"
|
||||
#include "ace/Countdown_Time.h"
|
||||
#include "ace/Truncate.h"
|
||||
|
||||
#include <openssl/err.h>
|
||||
|
||||
#if !defined (__ACE_INLINE__)
|
||||
#include "SSL_SOCK_Connector.inl"
|
||||
#endif /* __ACE_INLINE__ */
|
||||
|
||||
ACE_RCSID (ACE_SSL,
|
||||
SSL_SOCK_Connector,
|
||||
"$Id: SSL_SOCK_Connector.cpp 82577 2008-08-09 17:43:11Z mitza $")
|
||||
|
||||
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
|
||||
|
||||
ACE_ALLOC_HOOK_DEFINE(ACE_SSL_SOCK_Connector)
|
||||
|
||||
ACE_SSL_SOCK_Connector::~ACE_SSL_SOCK_Connector (void)
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Connector::~ACE_SSL_SOCK_Connector");
|
||||
}
|
||||
|
||||
int
|
||||
ACE_SSL_SOCK_Connector::ssl_connect (ACE_SSL_SOCK_Stream &new_stream,
|
||||
const ACE_Time_Value *timeout)
|
||||
{
|
||||
SSL *ssl = new_stream.ssl ();
|
||||
|
||||
if (SSL_is_init_finished (ssl))
|
||||
return 0;
|
||||
|
||||
// Check if a connection is already pending for the given SSL
|
||||
// structure.
|
||||
if (!SSL_in_connect_init (ssl))
|
||||
::SSL_set_connect_state (ssl);
|
||||
|
||||
ACE_HANDLE handle = new_stream.get_handle ();
|
||||
|
||||
// We're going to call SSL_connect, optionally doing ACE::select and
|
||||
// retrying the SSL_connect, until the SSL handshake is done or
|
||||
// it fails.
|
||||
// To get the timeout affect, set the socket to nonblocking mode
|
||||
// before beginning if there is a timeout specified. If the timeout
|
||||
// is 0 (wait as long as it takes) then don't worry about the blocking
|
||||
// status; we'll block in SSL_connect if the socket is blocking, and
|
||||
// block in ACE::select if not.
|
||||
int reset_blocking_mode = 0;
|
||||
if (timeout != 0)
|
||||
{
|
||||
reset_blocking_mode = ACE_BIT_DISABLED (ACE::get_flags (handle),
|
||||
ACE_NONBLOCK);
|
||||
// Set the handle into non-blocking mode if it's not already
|
||||
// in it.
|
||||
if (reset_blocking_mode
|
||||
&& ACE::set_flags (handle,
|
||||
ACE_NONBLOCK) == -1)
|
||||
return -1;
|
||||
}
|
||||
|
||||
ACE_Time_Value t;
|
||||
if (timeout != 0)
|
||||
t = *timeout; // Need a non-const copy.
|
||||
|
||||
// Take into account the time between each select() call below.
|
||||
ACE_Countdown_Time countdown ((timeout == 0 ? 0 : &t));
|
||||
|
||||
int status;
|
||||
|
||||
do
|
||||
{
|
||||
// These handle sets are used to set up for whatever SSL_connect
|
||||
// says it wants next. They're reset on each pass around the loop.
|
||||
ACE_Handle_Set rd_handle;
|
||||
ACE_Handle_Set wr_handle;
|
||||
|
||||
status = ::SSL_connect (ssl);
|
||||
switch (::SSL_get_error (ssl, status))
|
||||
{
|
||||
case SSL_ERROR_NONE:
|
||||
// Start out with non-blocking disabled on the SSL stream.
|
||||
new_stream.disable (ACE_NONBLOCK);
|
||||
status = 0; // To tell caller about success
|
||||
break; // Done
|
||||
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
wr_handle.set_bit (handle);
|
||||
status = 1; // Wait for more activity
|
||||
break;
|
||||
|
||||
case SSL_ERROR_WANT_READ:
|
||||
rd_handle.set_bit (handle);
|
||||
status = 1; // Wait for more activity
|
||||
break;
|
||||
|
||||
case SSL_ERROR_ZERO_RETURN:
|
||||
// The peer has notified us that it is shutting down via
|
||||
// the SSL "close_notify" message so we need to
|
||||
// shutdown, too.
|
||||
status = -1;
|
||||
break;
|
||||
|
||||
case SSL_ERROR_SYSCALL:
|
||||
// On some platforms (e.g. MS Windows) OpenSSL does not
|
||||
// store the last error in errno so explicitly do so.
|
||||
//
|
||||
// Explicitly check for EWOULDBLOCK since it doesn't get
|
||||
// converted to an SSL_ERROR_WANT_{READ,WRITE} on some
|
||||
// platforms. If SSL_connect failed outright, though, don't
|
||||
// bother checking more. This can happen if the socket gets
|
||||
// closed during the handshake.
|
||||
if (ACE_OS::set_errno_to_last_error () == EWOULDBLOCK &&
|
||||
status == -1)
|
||||
{
|
||||
// Although the SSL_ERROR_WANT_READ/WRITE isn't getting
|
||||
// set correctly, the read/write state should be valid.
|
||||
// Use that to decide what to do.
|
||||
status = 1; // Wait for more activity
|
||||
if (SSL_want_write (ssl))
|
||||
{
|
||||
wr_handle.set_bit (handle);
|
||||
}
|
||||
else if (SSL_want_read (ssl))
|
||||
{
|
||||
rd_handle.set_bit (handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
status = -1; // Doesn't want anything - bail out
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = -1;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
ACE_SSL_Context::report_error ();
|
||||
status = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (status == 1)
|
||||
{
|
||||
// Must have at least one handle to wait for at this point.
|
||||
ACE_ASSERT (rd_handle.num_set () == 1 || wr_handle.num_set () == 1);
|
||||
|
||||
// Block indefinitely if timeout pointer is zero.
|
||||
status = ACE::select (int (handle) + 1,
|
||||
&rd_handle,
|
||||
&wr_handle,
|
||||
0,
|
||||
(timeout == 0 ? 0 : &t));
|
||||
|
||||
(void) countdown.update ();
|
||||
|
||||
// 0 is timeout, so we're done.
|
||||
// -1 is error, so we're done.
|
||||
// Could be both handles set (same handle in both masks) so set to 1.
|
||||
if (status >= 1)
|
||||
{
|
||||
status = 1;
|
||||
}
|
||||
else // Timeout or socket failure
|
||||
{
|
||||
status = -1;
|
||||
}
|
||||
}
|
||||
|
||||
} while (status == 1 && !SSL_is_init_finished (ssl));
|
||||
|
||||
if (reset_blocking_mode)
|
||||
{
|
||||
ACE_Errno_Guard eguard (errno);
|
||||
ACE::clr_flags (handle, ACE_NONBLOCK);
|
||||
}
|
||||
|
||||
return (status == -1 ? -1 : 0);
|
||||
}
|
||||
|
||||
int
|
||||
ACE_SSL_SOCK_Connector::connect (ACE_SSL_SOCK_Stream &new_stream,
|
||||
const ACE_Addr &remote_sap,
|
||||
const ACE_Time_Value *timeout,
|
||||
const ACE_Addr &local_sap,
|
||||
int reuse_addr,
|
||||
int flags,
|
||||
int perms)
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Connector::connect");
|
||||
|
||||
// Take into account the time to complete the basic TCP handshake
|
||||
// and the SSL handshake.
|
||||
ACE_Time_Value time_copy;
|
||||
ACE_Countdown_Time countdown (&time_copy);
|
||||
if (timeout != 0)
|
||||
{
|
||||
time_copy += *timeout;
|
||||
countdown.start ();
|
||||
}
|
||||
|
||||
int result =
|
||||
this->connector_.connect (new_stream.peer (),
|
||||
remote_sap,
|
||||
timeout,
|
||||
local_sap,
|
||||
reuse_addr,
|
||||
flags,
|
||||
perms);
|
||||
|
||||
int error = 0;
|
||||
if (result == -1)
|
||||
error = errno; // Save us some TSS accesses.
|
||||
|
||||
// Obtain the handle from the underlying SOCK_Stream and set it in
|
||||
// the SSL_SOCK_Stream. Note that the case where a connection is in
|
||||
// progress is also handled. In that case, the handle must also be
|
||||
// set in the SSL_SOCK_Stream so that the correct handle is returned
|
||||
// when performing non-blocking connect()s.
|
||||
if (new_stream.get_handle () == ACE_INVALID_HANDLE
|
||||
&& (result == 0
|
||||
|| (result == -1 && (error == EWOULDBLOCK
|
||||
|| error == EINPROGRESS))))
|
||||
new_stream.set_handle (new_stream.peer ().get_handle ());
|
||||
|
||||
if (result == -1)
|
||||
return result;
|
||||
|
||||
// If using a timeout, update the countdown timer to reflect the time
|
||||
// spent on the connect itself, then pass the remaining time to
|
||||
// ssl_connect to bound the time on the handshake.
|
||||
if (timeout != 0)
|
||||
{
|
||||
countdown.update ();
|
||||
timeout = &time_copy;
|
||||
}
|
||||
|
||||
result = this->ssl_connect (new_stream, timeout);
|
||||
|
||||
if (result == -1)
|
||||
new_stream.close ();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
ACE_SSL_SOCK_Connector::connect (ACE_SSL_SOCK_Stream &new_stream,
|
||||
const ACE_Addr &remote_sap,
|
||||
ACE_QoS_Params qos_params,
|
||||
const ACE_Time_Value *timeout,
|
||||
const ACE_Addr &local_sap,
|
||||
ACE_Protocol_Info *protocolinfo,
|
||||
ACE_SOCK_GROUP g,
|
||||
u_long flags,
|
||||
int reuse_addr,
|
||||
int perms)
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Connector::connect");
|
||||
|
||||
// Take into account the time to complete the basic TCP handshake
|
||||
// and the SSL handshake.
|
||||
ACE_Time_Value time_copy;
|
||||
ACE_Countdown_Time countdown (&time_copy);
|
||||
if (timeout != 0)
|
||||
{
|
||||
time_copy += *timeout;
|
||||
countdown.start ();
|
||||
}
|
||||
|
||||
int result = this->connector_.connect (new_stream.peer (),
|
||||
remote_sap,
|
||||
qos_params,
|
||||
timeout,
|
||||
local_sap,
|
||||
protocolinfo,
|
||||
g,
|
||||
flags,
|
||||
reuse_addr,
|
||||
perms);
|
||||
|
||||
int error = 0;
|
||||
if (result == -1)
|
||||
error = errno; // Save us some TSS accesses.
|
||||
|
||||
// Obtain the handle from the underlying SOCK_Stream and set it in
|
||||
// the SSL_SOCK_Stream. Note that the case where a connection is in
|
||||
// progress is also handled. In that case, the handle must also be
|
||||
// set in the SSL_SOCK_Stream so that the correct handle is returned
|
||||
// when performing non-blocking connect()s.
|
||||
if (new_stream.get_handle () == ACE_INVALID_HANDLE
|
||||
&& (result == 0
|
||||
|| (result == -1 && (error == EWOULDBLOCK
|
||||
|| error == EINPROGRESS))))
|
||||
new_stream.set_handle (new_stream.peer ().get_handle ());
|
||||
|
||||
if (result == -1)
|
||||
return result;
|
||||
|
||||
// If using a timeout, update the countdown timer to reflect the time
|
||||
// spent on the connect itself, then pass the remaining time to
|
||||
// ssl_connect to bound the time on the handshake.
|
||||
if (timeout != 0)
|
||||
{
|
||||
countdown.update ();
|
||||
timeout = &time_copy;
|
||||
}
|
||||
|
||||
result = this->ssl_connect (new_stream, timeout);
|
||||
|
||||
if (result == -1)
|
||||
new_stream.close ();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Try to complete a non-blocking connection.
|
||||
|
||||
int
|
||||
ACE_SSL_SOCK_Connector::complete (ACE_SSL_SOCK_Stream &new_stream,
|
||||
ACE_Addr *remote_sap,
|
||||
const ACE_Time_Value *tv)
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Connector::complete");
|
||||
|
||||
// Take into account the time to complete the basic TCP handshake
|
||||
// and the SSL handshake.
|
||||
ACE_Time_Value time_copy;
|
||||
ACE_Countdown_Time countdown (&time_copy);
|
||||
if (tv != 0)
|
||||
{
|
||||
time_copy += *tv;
|
||||
countdown.start ();
|
||||
}
|
||||
|
||||
// Only attempt to complete the TCP connection if it that hasn't
|
||||
// already been done.
|
||||
ACE_INET_Addr raddr;
|
||||
if (new_stream.peer ().get_remote_addr (raddr) != 0
|
||||
&& this->connector_.complete (new_stream.peer (),
|
||||
remote_sap,
|
||||
tv) == -1)
|
||||
return -1;
|
||||
|
||||
// The handle in the SSL_SOCK_Stream should have already been set in
|
||||
// the connect() method.
|
||||
|
||||
// If using a timeout, update the countdown timer to reflect the time
|
||||
// spent on the connect itself, then pass the remaining time to
|
||||
// ssl_connect to bound the time on the handshake.
|
||||
if (tv != 0)
|
||||
{
|
||||
countdown.update ();
|
||||
tv = &time_copy;
|
||||
}
|
||||
|
||||
if (this->ssl_connect (new_stream, tv) == -1)
|
||||
{
|
||||
new_stream.close ();
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
ACE_SSL_SOCK_Connector::ACE_SSL_SOCK_Connector (
|
||||
ACE_SSL_SOCK_Stream &new_stream,
|
||||
const ACE_Addr &remote_sap,
|
||||
const ACE_Time_Value *timeout,
|
||||
const ACE_Addr &local_sap,
|
||||
int reuse_addr,
|
||||
int flags,
|
||||
int perms)
|
||||
: connector_ ()
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Connector::ACE_SSL_SOCK_Connector");
|
||||
this->connect (new_stream,
|
||||
remote_sap,
|
||||
timeout,
|
||||
local_sap,
|
||||
reuse_addr,
|
||||
flags,
|
||||
perms);
|
||||
}
|
||||
|
||||
ACE_SSL_SOCK_Connector::ACE_SSL_SOCK_Connector (
|
||||
ACE_SSL_SOCK_Stream &new_stream,
|
||||
const ACE_Addr &remote_sap,
|
||||
ACE_QoS_Params qos_params,
|
||||
const ACE_Time_Value *timeout,
|
||||
const ACE_Addr &local_sap,
|
||||
ACE_Protocol_Info *protocolinfo,
|
||||
ACE_SOCK_GROUP g,
|
||||
u_long flags,
|
||||
int reuse_addr,
|
||||
int perms)
|
||||
: connector_ ()
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Connector::ACE_SSL_SOCK_Connector");
|
||||
|
||||
this->connect (new_stream,
|
||||
remote_sap,
|
||||
qos_params,
|
||||
timeout,
|
||||
local_sap,
|
||||
protocolinfo,
|
||||
g,
|
||||
flags,
|
||||
reuse_addr,
|
||||
perms);
|
||||
}
|
||||
|
||||
ACE_END_VERSIONED_NAMESPACE_DECL
|
||||
318
dep/ACE_wrappers/ace/SSL/SSL_SOCK_Connector.h
Normal file
318
dep/ACE_wrappers/ace/SSL/SSL_SOCK_Connector.h
Normal file
@@ -0,0 +1,318 @@
|
||||
// -*- C++ -*-
|
||||
|
||||
//=============================================================================
|
||||
/**
|
||||
* @file SSL_SOCK_Connector.h
|
||||
*
|
||||
* $Id: SSL_SOCK_Connector.h 80826 2008-03-04 14:51:23Z wotte $
|
||||
*
|
||||
* @author Ossama Othman <ossama@uci.edu>
|
||||
* @author Carlos O'Ryan <coryan@uci.edu>
|
||||
* @author John Heitmann
|
||||
* @author Chris Zimman
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef ACE_SSL_SOCK_CONNECTOR_H
|
||||
#define ACE_SSL_SOCK_CONNECTOR_H
|
||||
|
||||
#include /**/ "ace/pre.h"
|
||||
|
||||
#include "SSL_Export.h"
|
||||
|
||||
#if !defined (ACE_LACKS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif /* ACE_LACKS_PRAGMA_ONCE */
|
||||
|
||||
#include "SSL_SOCK_Stream.h"
|
||||
|
||||
#include "ace/SOCK_Connector.h"
|
||||
#include "ace/OS_QoS.h"
|
||||
|
||||
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
|
||||
|
||||
/**
|
||||
* @class ACE_SSL_SOCK_Connector
|
||||
*
|
||||
* @brief Defines a factory that creates new <ACE_SSL_SOCK_Stream>s
|
||||
* actively.
|
||||
*
|
||||
* The ACE_SSL_SOCK_Connector doesn't have a socket of its own,
|
||||
* i.e., it simply "borrows" the one from the ACE_SSL_SOCK_Stream
|
||||
* that's being connected. The reason for this is that the
|
||||
* underlying socket API doesn't use a "factory" socket to connect
|
||||
* "data-mode" sockets. Therefore, there's no need to inherit
|
||||
* ACE_SSL_SOCK_Connector from ACE_SSL_SOCK.
|
||||
*
|
||||
* Since SSL is record-oriented, some additional work is done after
|
||||
* the plain socket is connected.
|
||||
*
|
||||
* @note The user must currently ensure that only one thread services
|
||||
* a given SSL session at any given time since some underlying
|
||||
* SSL implementations, such as OpenSSL, are not entirely
|
||||
* thread-safe or reentrant.
|
||||
*/
|
||||
class ACE_SSL_Export ACE_SSL_SOCK_Connector
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
/// Default constructor.
|
||||
ACE_SSL_SOCK_Connector (void);
|
||||
|
||||
/**
|
||||
* Actively connect to a peer, producing a connected @c ACE_SSL_SOCK_Stream
|
||||
* object if the connection succeeds. This method performs both the
|
||||
* initial socket connect and the SSL handshake.
|
||||
*
|
||||
* @param new_stream The @c ACE_SSL_SOCK_Stream object that will be
|
||||
* connected to the peer.
|
||||
* @param remote_sap The address that we are trying to connect to.
|
||||
* The protocol family of @c remote_sap is used for
|
||||
* the connected socket. That is, if @c remote_sap
|
||||
* contains an IPv6 address, a socket with family
|
||||
* PF_INET6 will be used, else it will be PF_INET.
|
||||
* @param timeout Pointer to an @c ACE_Time_Value object with amount
|
||||
* of time to wait to connect. If the pointer is 0
|
||||
* then the call blocks until the connection attempt
|
||||
* is complete, whether it succeeds or fails. If
|
||||
* *timeout == {0, 0} then the connection is done
|
||||
* using nonblocking mode. In this case, if the
|
||||
* connection can't be made immediately, this method
|
||||
* returns -1 and errno == EWOULDBLOCK.
|
||||
* If *timeout > {0, 0} then this is the maximum amount
|
||||
* of time to wait before timing out; if the specified
|
||||
* amount of time passes before the connection is made,
|
||||
* this method returns -1 and errno == ETIME. Note
|
||||
* the difference between this case and when a blocking
|
||||
* connect is attmpted that TCP times out - in the latter
|
||||
* case, errno will be ETIMEDOUT.
|
||||
* @param local_sap (optional) The local address to bind to. If it's
|
||||
* the default value of @c ACE_Addr::sap_any then the
|
||||
* OS will choose an unused port.
|
||||
* @param reuse_addr (optional) If the value is 1, the local address
|
||||
* (@c local_sap) is reused, even if it hasn't been
|
||||
* cleaned up yet.
|
||||
* @param flags Ignored.
|
||||
* @param perms Ignored.
|
||||
*
|
||||
* @return Returns 0 if the connection succeeds. If it fails,
|
||||
* -1 is returned and errno contains a specific error
|
||||
* code.
|
||||
*/
|
||||
ACE_SSL_SOCK_Connector (ACE_SSL_SOCK_Stream &new_stream,
|
||||
const ACE_Addr &remote_sap,
|
||||
const ACE_Time_Value *timeout = 0,
|
||||
const ACE_Addr &local_sap = ACE_Addr::sap_any,
|
||||
int reuse_addr = 0,
|
||||
int flags = 0,
|
||||
int perms = 0);
|
||||
|
||||
/**
|
||||
* Actively connect to a peer, producing a connected @c ACE_SSL_SOCK_Stream
|
||||
* object if the connection succeeds. This method performs both the
|
||||
* initial socket connect and the SSL handshake.
|
||||
*
|
||||
* @param new_stream The @c ACE_SSL_SOCK_Stream object that will be
|
||||
* connected to the peer.
|
||||
* @param remote_sap The address that we are trying to connect to.
|
||||
* The protocol family of @c remote_sap is used for
|
||||
* the connected socket. That is, if @c remote_sap
|
||||
* contains an IPv6 address, a socket with family
|
||||
* PF_INET6 will be used, else it will be PF_INET.
|
||||
* @param qos_params Contains QoS parameters that are passed to the
|
||||
* IntServ (RSVP) and DiffServ protocols.
|
||||
* @see ACE_QoS_Params.
|
||||
* @param timeout Pointer to an @c ACE_Time_Value object with amount
|
||||
* of time to wait to connect. If the pointer is 0
|
||||
* then the call blocks until the connection attempt
|
||||
* is complete, whether it succeeds or fails. If
|
||||
* *timeout == {0, 0} then the connection is done
|
||||
* using nonblocking mode. In this case, if the
|
||||
* connection can't be made immediately, this method
|
||||
* returns -1 and errno == EWOULDBLOCK.
|
||||
* If *timeout > {0, 0} then this is the maximum amount
|
||||
* of time to wait before timing out; if the specified
|
||||
* amount of time passes before the connection is made,
|
||||
* this method returns -1 and errno == ETIME. Note
|
||||
* the difference between this case and when a blocking
|
||||
* connect is attmpted that TCP times out - in the latter
|
||||
* case, errno will be ETIMEDOUT.
|
||||
* @param local_sap (optional) The local address to bind to. If it's
|
||||
* the default value of @c ACE_Addr::sap_any then the
|
||||
* OS will choose an unused port.
|
||||
* @param reuse_addr (optional) If the value is 1, the local address
|
||||
* (@c local_sap) is reused, even if it hasn't been
|
||||
* cleaned up yet.
|
||||
* @param flags Ignored.
|
||||
* @param perms Ignored.
|
||||
*
|
||||
* @return Returns 0 if the connection succeeds. If it fails,
|
||||
* -1 is returned and errno contains a specific error
|
||||
* code.
|
||||
*/
|
||||
ACE_SSL_SOCK_Connector (ACE_SSL_SOCK_Stream &new_stream,
|
||||
const ACE_Addr &remote_sap,
|
||||
ACE_QoS_Params qos_params,
|
||||
const ACE_Time_Value *timeout = 0,
|
||||
const ACE_Addr &local_sap = ACE_Addr::sap_any,
|
||||
ACE_Protocol_Info *protocolinfo = 0,
|
||||
ACE_SOCK_GROUP g = 0,
|
||||
u_long flags = 0,
|
||||
int reuse_addr = 0,
|
||||
int perms = 0);
|
||||
|
||||
/// Default dtor.
|
||||
~ACE_SSL_SOCK_Connector (void);
|
||||
|
||||
/**
|
||||
* Actively connect to a peer, producing a connected @c ACE_SSL_SOCK_Stream
|
||||
* object if the connection succeeds. This method performs both the
|
||||
* initial socket connect and the SSL handshake.
|
||||
*
|
||||
* @param new_stream The @c ACE_SSL_SOCK_Stream object that will be
|
||||
* connected to the peer.
|
||||
* @param remote_sap The address that we are trying to connect to.
|
||||
* The protocol family of @c remote_sap is used for
|
||||
* the connected socket. That is, if @c remote_sap
|
||||
* contains an IPv6 address, a socket with family
|
||||
* PF_INET6 will be used, else it will be PF_INET.
|
||||
* @param timeout Pointer to an @c ACE_Time_Value object with amount
|
||||
* of time to wait to connect. If the pointer is 0
|
||||
* then the call blocks until the connection attempt
|
||||
* is complete, whether it succeeds or fails. If
|
||||
* *timeout == {0, 0} then the connection is done
|
||||
* using nonblocking mode. In this case, if the
|
||||
* connection can't be made immediately, this method
|
||||
* returns -1 and errno == EWOULDBLOCK.
|
||||
* If *timeout > {0, 0} then this is the maximum amount
|
||||
* of time to wait before timing out; if the specified
|
||||
* amount of time passes before the connection is made,
|
||||
* this method returns -1 and errno == ETIME. Note
|
||||
* the difference between this case and when a blocking
|
||||
* connect is attmpted that TCP times out - in the latter
|
||||
* case, errno will be ETIMEDOUT.
|
||||
* @param local_sap (optional) The local address to bind to. If it's
|
||||
* the default value of @c ACE_Addr::sap_any then the
|
||||
* OS will choose an unused port.
|
||||
* @param reuse_addr (optional) If the value is 1, the local address
|
||||
* (@c local_sap) is reused, even if it hasn't been
|
||||
* cleaned up yet.
|
||||
* @param flags Ignored.
|
||||
* @param perms Ignored.
|
||||
*
|
||||
* @return Returns 0 if the connection succeeds. If it fails,
|
||||
* -1 is returned and errno contains a specific error
|
||||
* code.
|
||||
*/
|
||||
int connect (ACE_SSL_SOCK_Stream &new_stream,
|
||||
const ACE_Addr &remote_sap,
|
||||
const ACE_Time_Value *timeout = 0,
|
||||
const ACE_Addr &local_sap = ACE_Addr::sap_any,
|
||||
int reuse_addr = 0,
|
||||
int flags = 0,
|
||||
int perms = 0);
|
||||
|
||||
/**
|
||||
* Actively connect to a peer, producing a connected @c ACE_SSL_SOCK_Stream
|
||||
* object if the connection succeeds. This method performs both the
|
||||
* initial socket connect and the SSL handshake.
|
||||
*
|
||||
* @param new_stream The @c ACE_SSL_SOCK_Stream object that will be
|
||||
* connected to the peer.
|
||||
* @param remote_sap The address that we are trying to connect to.
|
||||
* The protocol family of @c remote_sap is used for
|
||||
* the connected socket. That is, if @c remote_sap
|
||||
* contains an IPv6 address, a socket with family
|
||||
* PF_INET6 will be used, else it will be PF_INET.
|
||||
* @param qos_params Contains QoS parameters that are passed to the
|
||||
* IntServ (RSVP) and DiffServ protocols.
|
||||
* @see ACE_QoS_Params.
|
||||
* @param timeout Pointer to an @c ACE_Time_Value object with amount
|
||||
* of time to wait to connect. If the pointer is 0
|
||||
* then the call blocks until the connection attempt
|
||||
* is complete, whether it succeeds or fails. If
|
||||
* *timeout == {0, 0} then the connection is done
|
||||
* using nonblocking mode. In this case, if the
|
||||
* connection can't be made immediately, this method
|
||||
* returns -1 and errno == EWOULDBLOCK.
|
||||
* If *timeout > {0, 0} then this is the maximum amount
|
||||
* of time to wait before timing out; if the specified
|
||||
* amount of time passes before the connection is made,
|
||||
* this method returns -1 and errno == ETIME. Note
|
||||
* the difference between this case and when a blocking
|
||||
* connect is attmpted that TCP times out - in the latter
|
||||
* case, errno will be ETIMEDOUT.
|
||||
* @param local_sap (optional) The local address to bind to. If it's
|
||||
* the default value of @c ACE_Addr::sap_any then the
|
||||
* OS will choose an unused port.
|
||||
* @param reuse_addr (optional) If the value is 1, the local address
|
||||
* (@c local_sap) is reused, even if it hasn't been
|
||||
* cleaned up yet.
|
||||
* @param flags Ignored.
|
||||
* @param perms Ignored.
|
||||
*
|
||||
* @return Returns 0 if the connection succeeds. If it fails,
|
||||
* -1 is returned and errno contains a specific error
|
||||
* code.
|
||||
*/
|
||||
int connect (ACE_SSL_SOCK_Stream &new_stream,
|
||||
const ACE_Addr &remote_sap,
|
||||
ACE_QoS_Params qos_params,
|
||||
const ACE_Time_Value *timeout = 0,
|
||||
const ACE_Addr &local_sap = ACE_Addr::sap_any,
|
||||
ACE_Protocol_Info *protocolinfo = 0,
|
||||
ACE_SOCK_GROUP g = 0,
|
||||
u_long flags = 0,
|
||||
int reuse_addr = 0,
|
||||
int perms = 0);
|
||||
|
||||
/**
|
||||
* Try to complete a non-blocking connection.
|
||||
* If connection completion is successful then <new_stream> contains
|
||||
* the connected ACE_SSL_SOCK_Stream. If <remote_sap> is non-NULL
|
||||
* then it will contain the address of the connected peer.
|
||||
*/
|
||||
int complete (ACE_SSL_SOCK_Stream &new_stream,
|
||||
ACE_Addr *remote_sap = 0,
|
||||
const ACE_Time_Value *timeout = 0);
|
||||
|
||||
/// Resets any event associations on this handle
|
||||
int reset_new_handle (ACE_HANDLE handle);
|
||||
|
||||
/// Meta-type info
|
||||
//@{
|
||||
typedef ACE_INET_Addr PEER_ADDR;
|
||||
typedef ACE_SSL_SOCK_Stream PEER_STREAM;
|
||||
//@}
|
||||
|
||||
/// Dump the state of an object.
|
||||
void dump (void) const;
|
||||
|
||||
/// Declare the dynamic allocation hooks.
|
||||
ACE_ALLOC_HOOK_DECLARE;
|
||||
|
||||
protected:
|
||||
|
||||
/// Complete non-blocking SSL active connection.
|
||||
int ssl_connect (ACE_SSL_SOCK_Stream &new_stream,
|
||||
const ACE_Time_Value *timeout);
|
||||
|
||||
private:
|
||||
|
||||
/// The class that does all of the non-secure socket connection.
|
||||
/// It is default contructed, and subsequently used by connect().
|
||||
ACE_SOCK_Connector connector_;
|
||||
|
||||
};
|
||||
|
||||
ACE_END_VERSIONED_NAMESPACE_DECL
|
||||
|
||||
#if defined (__ACE_INLINE__)
|
||||
#include "SSL_SOCK_Connector.inl"
|
||||
#endif /* __ACE_INLINE__ */
|
||||
|
||||
#include /**/ "ace/post.h"
|
||||
|
||||
#endif /* ACE_SSL_SOCK_CONNECTOR_H */
|
||||
28
dep/ACE_wrappers/ace/SSL/SSL_SOCK_Connector.inl
Normal file
28
dep/ACE_wrappers/ace/SSL/SSL_SOCK_Connector.inl
Normal file
@@ -0,0 +1,28 @@
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// $Id: SSL_SOCK_Connector.inl 80826 2008-03-04 14:51:23Z wotte $
|
||||
|
||||
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
|
||||
|
||||
ACE_INLINE
|
||||
ACE_SSL_SOCK_Connector::ACE_SSL_SOCK_Connector (void)
|
||||
: connector_ ()
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Connector::ACE_SSL_SOCK_Connector");
|
||||
}
|
||||
|
||||
ACE_INLINE int
|
||||
ACE_SSL_SOCK_Connector::reset_new_handle (ACE_HANDLE handle)
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Connector::reset_new_handle");
|
||||
return this->connector_.reset_new_handle (handle);
|
||||
}
|
||||
|
||||
ACE_INLINE void
|
||||
ACE_SSL_SOCK_Connector::dump (void) const
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Connector::dump");
|
||||
this->connector_.dump ();
|
||||
}
|
||||
|
||||
ACE_END_VERSIONED_NAMESPACE_DECL
|
||||
630
dep/ACE_wrappers/ace/SSL/SSL_SOCK_Stream.cpp
Normal file
630
dep/ACE_wrappers/ace/SSL/SSL_SOCK_Stream.cpp
Normal file
@@ -0,0 +1,630 @@
|
||||
// $Id: SSL_SOCK_Stream.cpp 82577 2008-08-09 17:43:11Z mitza $
|
||||
|
||||
#include "ace/Handle_Set.h"
|
||||
#include "ace/Log_Msg.h"
|
||||
#include "ace/Countdown_Time.h"
|
||||
#include "ace/OS_NS_string.h"
|
||||
#include "ace/OS_NS_sys_select.h"
|
||||
#include "ace/OS_Memory.h"
|
||||
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "SSL_SOCK_Stream.h"
|
||||
|
||||
#if !defined (__ACE_INLINE__)
|
||||
#include "SSL_SOCK_Stream.inl"
|
||||
#endif /* __ACE_INLINE__ */
|
||||
|
||||
ACE_RCSID (ACE_SSL,
|
||||
SSL_SOCK_Stream,
|
||||
"$Id: SSL_SOCK_Stream.cpp 82577 2008-08-09 17:43:11Z mitza $")
|
||||
|
||||
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
|
||||
|
||||
ACE_ALLOC_HOOK_DEFINE(ACE_SSL_SOCK_Stream)
|
||||
|
||||
ACE_SSL_SOCK_Stream::ACE_SSL_SOCK_Stream (ACE_SSL_Context *context)
|
||||
: ssl_ (0),
|
||||
stream_ ()
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Stream::ACE_SSL_SOCK_Stream");
|
||||
|
||||
ACE_SSL_Context * ctx =
|
||||
(context == 0 ? ACE_SSL_Context::instance () : context);
|
||||
|
||||
this->ssl_ = ::SSL_new (ctx->context ());
|
||||
|
||||
if (this->ssl_ == 0)
|
||||
{
|
||||
ACE_ERROR ((LM_ERROR,
|
||||
"(%P|%t) ACE_SSL_SOCK_Stream "
|
||||
"- cannot allocate new SSL structure %p\n",
|
||||
ACE_TEXT ("")));
|
||||
}
|
||||
}
|
||||
|
||||
ACE_SSL_SOCK_Stream::~ACE_SSL_SOCK_Stream (void)
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Stream::~ACE_SSL_SOCK_Stream");
|
||||
|
||||
::SSL_free (this->ssl_);
|
||||
|
||||
// @@ Question: should we reference count the Context object or
|
||||
// leave that to the application developer? We do not reference
|
||||
// count reactors (for example) and following some simple rules
|
||||
// seems to work fine!
|
||||
}
|
||||
|
||||
ssize_t
|
||||
ACE_SSL_SOCK_Stream::sendv (const iovec iov[],
|
||||
size_t n,
|
||||
const ACE_Time_Value *max_wait_time) const
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Stream::sendv");
|
||||
|
||||
// There is subtle problem in this method that occurs when using
|
||||
// non-blocking IO. The semantics of a non-blocking scatter write
|
||||
// (sendv()) are not possible to retain with the emulation in this
|
||||
// method.
|
||||
|
||||
ssize_t bytes_sent = 0;
|
||||
|
||||
ACE_Time_Value t;
|
||||
ACE_Time_Value *timeout = const_cast<ACE_Time_Value *> (max_wait_time);
|
||||
|
||||
if (max_wait_time != 0)
|
||||
{
|
||||
// Make a copy since ACE_Countdown_Time modifies the
|
||||
// ACE_Time_Value.
|
||||
t = *max_wait_time;
|
||||
timeout = &t;
|
||||
}
|
||||
|
||||
// Take into account the time between each send.
|
||||
ACE_Countdown_Time countdown (timeout);
|
||||
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
{
|
||||
ssize_t const result = this->send (iov[i].iov_base,
|
||||
iov[i].iov_len,
|
||||
timeout);
|
||||
|
||||
if (result == -1)
|
||||
{
|
||||
// There is a subtle difference in behaviour depending on
|
||||
// whether or not any data was sent. If no data was sent,
|
||||
// then always return -1. Otherwise return bytes_sent.
|
||||
// This gives the caller an opportunity to keep track of
|
||||
if (bytes_sent > 0)
|
||||
break;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes_sent += result;
|
||||
|
||||
// Do not continue on to the next loop iteration if the
|
||||
// amount of data sent was less than the amount data given.
|
||||
// This avoids a subtle problem where "holes" in the data
|
||||
// stream would occur if partial sends of a given buffer in
|
||||
// the iovec array occured.
|
||||
if (static_cast<size_t> (result) < static_cast<size_t> (iov[i].iov_len))
|
||||
break;
|
||||
}
|
||||
|
||||
(void) countdown.update ();
|
||||
}
|
||||
|
||||
return bytes_sent;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
ACE_SSL_SOCK_Stream::recvv (iovec *io_vec,
|
||||
const ACE_Time_Value *timeout) const
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Stream::recvv");
|
||||
|
||||
// From ACE_SOCK_IO::recvv().
|
||||
#if defined (FIONREAD)
|
||||
ACE_Handle_Set handle_set;
|
||||
handle_set.reset ();
|
||||
handle_set.set_bit (this->get_handle ());
|
||||
|
||||
io_vec->iov_base = 0;
|
||||
|
||||
// Check the status of the current socket.
|
||||
switch (
|
||||
ACE_OS::select (int (this->get_handle ()) + 1,
|
||||
handle_set,
|
||||
0,
|
||||
0,
|
||||
timeout))
|
||||
{
|
||||
case -1:
|
||||
return -1;
|
||||
/* NOTREACHED */
|
||||
case 0:
|
||||
errno = ETIME;
|
||||
return -1;
|
||||
/* NOTREACHED */
|
||||
default:
|
||||
// Goes fine, fallthrough to get data
|
||||
break;
|
||||
}
|
||||
|
||||
int inlen;
|
||||
|
||||
if (ACE_OS::ioctl (this->get_handle (),
|
||||
FIONREAD,
|
||||
&inlen) == -1)
|
||||
return -1;
|
||||
else if (inlen > 0)
|
||||
{
|
||||
ACE_NEW_RETURN (io_vec->iov_base,
|
||||
char[inlen],
|
||||
-1);
|
||||
io_vec->iov_len = this->recv (io_vec->iov_base,
|
||||
inlen);
|
||||
return io_vec->iov_len;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
#else
|
||||
ACE_UNUSED_ARG (io_vec);
|
||||
ACE_UNUSED_ARG (timeout);
|
||||
ACE_NOTSUP_RETURN (-1);
|
||||
#endif /* FIONREAD */
|
||||
}
|
||||
|
||||
ssize_t
|
||||
ACE_SSL_SOCK_Stream::send (const void *buf,
|
||||
size_t len,
|
||||
int flags,
|
||||
const ACE_Time_Value *timeout) const
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Stream::send");
|
||||
|
||||
// If SSL has data in the buffer, i.e. SSL_pending() returns a
|
||||
// non-zero value, then don't block on select().
|
||||
if (timeout == 0 || ::SSL_pending (this->ssl_))
|
||||
return this->send (buf, len, flags);
|
||||
|
||||
int val = 0;
|
||||
if (ACE::enter_send_timedwait (this->get_handle (),
|
||||
timeout,
|
||||
val) == -1)
|
||||
return -1;
|
||||
|
||||
ssize_t const bytes_transferred = this->send (buf, len, flags);
|
||||
|
||||
ACE::restore_non_blocking_mode (this->get_handle (), val);
|
||||
|
||||
return bytes_transferred;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
ACE_SSL_SOCK_Stream::recv (void *buf,
|
||||
size_t n,
|
||||
int flags,
|
||||
const ACE_Time_Value *timeout) const
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Stream::recv");
|
||||
|
||||
return this->recv_i (buf, n, flags, timeout);
|
||||
}
|
||||
|
||||
|
||||
ssize_t
|
||||
ACE_SSL_SOCK_Stream::send (size_t n, ...) const
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Stream::send");
|
||||
|
||||
size_t const total_tuples = n / 2;
|
||||
|
||||
va_list argp;
|
||||
va_start (argp, n);
|
||||
|
||||
ssize_t bytes_sent = 0;
|
||||
|
||||
// NOTE: This method used to fill an IO vector (e.g. iovec) and then
|
||||
// send it using a scatter write (sendv()). However, it is
|
||||
// not possible to emulate a non-blocking scatter write over
|
||||
// SSL. As such, there is no point in attempting to use
|
||||
// scatter writes over SSL.
|
||||
for (size_t i = 0; i < total_tuples; ++i)
|
||||
{
|
||||
ssize_t const data_len = va_arg (argp, ssize_t);
|
||||
ssize_t const result = this->send (va_arg (argp, char *), data_len);
|
||||
|
||||
if (result == -1)
|
||||
{
|
||||
// There is a subtle difference in behaviour depending on
|
||||
// whether or not any data was sent. If no data was sent,
|
||||
// then always return -1. Otherwise return bytes_sent.
|
||||
// This gives the caller an opportunity to keep track of
|
||||
// which data was actually sent.
|
||||
if (bytes_sent > 0)
|
||||
break;
|
||||
else
|
||||
{
|
||||
va_end (argp);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes_sent += result;
|
||||
|
||||
// Do not continue on to the next loop iteration if the
|
||||
// amount of data sent was less than the amount of data
|
||||
// given. This avoids a subtle problem where "holes" in the
|
||||
// data stream would occur if partial sends of a given
|
||||
// buffer in the varargs occured.
|
||||
if (result < data_len)
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
va_end (argp);
|
||||
|
||||
return bytes_sent;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
ACE_SSL_SOCK_Stream::recv (size_t n, ...) const
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Stream::recv");
|
||||
|
||||
size_t const total_tuples = n / 2;
|
||||
|
||||
va_list argp;
|
||||
va_start (argp, n);
|
||||
|
||||
ssize_t bytes_recv = 0;
|
||||
|
||||
for (size_t i = 0; i < total_tuples; ++i)
|
||||
{
|
||||
ssize_t const data_len = va_arg (argp, ssize_t);
|
||||
ssize_t const result = this->recv (va_arg (argp, char *), data_len);
|
||||
|
||||
if (result == -1)
|
||||
{
|
||||
// There is a subtle difference in behaviour depending on
|
||||
// whether or not any data was received. If no data was
|
||||
// received, then always return -1. Otherwise return
|
||||
// bytes_received. This gives the caller an opportunity to
|
||||
// keep track of which data was actually received.
|
||||
if (bytes_recv > 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
va_end (argp);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes_recv += result;
|
||||
|
||||
// Do not continue on to the next loop iteration if the
|
||||
// amount of data received was less than the amount of data
|
||||
// desired. This avoids a subtle problem where "holes" in
|
||||
// the data stream would occur if partial receives of a
|
||||
// given buffer in the varargs occured.
|
||||
if (result < data_len)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
va_end (argp);
|
||||
|
||||
return bytes_recv;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
ACE_SSL_SOCK_Stream::send_n (const void *buf,
|
||||
size_t len,
|
||||
int flags,
|
||||
const ACE_Time_Value *timeout,
|
||||
size_t *bt) const
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Stream::send_n");
|
||||
|
||||
// No support for send flags in SSL.
|
||||
if (flags != 0)
|
||||
{
|
||||
ACE_NOTSUP_RETURN (-1);
|
||||
}
|
||||
|
||||
/* This code mimics ACE::send_n */
|
||||
// Total number of bytes written.
|
||||
size_t temp = 0;
|
||||
size_t &bytes_transferred = ((bt == 0) ? temp : *bt);
|
||||
|
||||
// Actual number of bytes written in each <send> attempt
|
||||
ssize_t n = 0;
|
||||
|
||||
for (bytes_transferred = 0;
|
||||
bytes_transferred < len;
|
||||
bytes_transferred += n)
|
||||
{
|
||||
n = this->send ((const char*) buf + bytes_transferred,
|
||||
len - bytes_transferred,
|
||||
flags,
|
||||
timeout);
|
||||
|
||||
if (n < 0)
|
||||
{
|
||||
if (errno == EWOULDBLOCK)
|
||||
{
|
||||
// If blocked, try again.
|
||||
n = 0;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (n == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ACE_Utils::truncate_cast<ssize_t> (bytes_transferred);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
ACE_SSL_SOCK_Stream::recv_n (void *buf,
|
||||
size_t len,
|
||||
int flags,
|
||||
const ACE_Time_Value *timeout,
|
||||
size_t *bt) const
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Stream::recv_n");
|
||||
|
||||
if (flags != 0)
|
||||
{
|
||||
if ((flags | MSG_PEEK) != MSG_PEEK)
|
||||
{
|
||||
ACE_NOTSUP_RETURN (-1);
|
||||
}
|
||||
}
|
||||
|
||||
size_t temp = 0;
|
||||
size_t &bytes_transferred = ((bt == 0) ? temp : *bt);
|
||||
|
||||
ssize_t n = 0;
|
||||
|
||||
for (bytes_transferred = 0;
|
||||
bytes_transferred < len;
|
||||
bytes_transferred += n)
|
||||
{
|
||||
n = this->recv ((char*) buf + bytes_transferred,
|
||||
len - bytes_transferred,
|
||||
flags,
|
||||
timeout);
|
||||
|
||||
if (n < 0)
|
||||
{
|
||||
if (errno == EWOULDBLOCK)
|
||||
{
|
||||
// If blocked, try again.
|
||||
n = 0;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (n == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ACE_Utils::truncate_cast<ssize_t> (bytes_transferred);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
ACE_SSL_SOCK_Stream::recv_n (void *buf, int len, int flags) const
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Stream::recv_n");
|
||||
|
||||
if (flags != 0)
|
||||
{
|
||||
if ((flags | MSG_PEEK) != MSG_PEEK)
|
||||
{
|
||||
ACE_NOTSUP_RETURN (-1);
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t bytes_transferred = 0;
|
||||
ssize_t n = 0;
|
||||
|
||||
for (bytes_transferred = 0;
|
||||
bytes_transferred < len;
|
||||
bytes_transferred += n)
|
||||
{
|
||||
n = this->recv ((char*) buf + bytes_transferred,
|
||||
len - bytes_transferred,
|
||||
flags);
|
||||
|
||||
if (n < 0)
|
||||
{
|
||||
if (errno == EWOULDBLOCK)
|
||||
{
|
||||
// If blocked, try again.
|
||||
n = 0;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (n == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ACE_Utils::truncate_cast<ssize_t> (bytes_transferred);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
ACE_SSL_SOCK_Stream::send_n (const void *buf, int len, int flags) const
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Stream::send_n");
|
||||
|
||||
// Send flags are unsupported in SSL
|
||||
if (flags != 0)
|
||||
{
|
||||
ACE_NOTSUP_RETURN (-1);
|
||||
}
|
||||
|
||||
/* The following code mimics <ACE::send_n> */
|
||||
size_t bytes_transferred = 0;
|
||||
ssize_t n = 0;
|
||||
|
||||
for (bytes_transferred = 0;
|
||||
bytes_transferred < (size_t) len;
|
||||
bytes_transferred += n)
|
||||
{
|
||||
n = this->send ((const char*) buf + bytes_transferred,
|
||||
len - bytes_transferred,
|
||||
flags);
|
||||
|
||||
if (n < 0)
|
||||
{
|
||||
if (errno == EWOULDBLOCK)
|
||||
{
|
||||
// If blocked, try again.
|
||||
n = 0;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (n == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ACE_Utils::truncate_cast<ssize_t> (bytes_transferred);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
ACE_SSL_SOCK_Stream::sendv_n (const iovec iov[], size_t iovcnt) const
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Stream::sendv_n");
|
||||
|
||||
ssize_t bytes_sent = 0;
|
||||
|
||||
for (size_t i = 0; i < iovcnt; ++i)
|
||||
{
|
||||
ssize_t result = this->send_n (iov[i].iov_base,
|
||||
iov[i].iov_len);
|
||||
|
||||
|
||||
if (result == -1)
|
||||
{
|
||||
// There is a subtle difference in behaviour depending on
|
||||
// whether or not any data was sent. If no data was sent,
|
||||
// then always return -1. Otherwise return bytes_sent.
|
||||
// This gives the caller an opportunity to keep track of
|
||||
// which data was actually sent.
|
||||
if (bytes_sent > 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes_sent += result;
|
||||
}
|
||||
}
|
||||
|
||||
return bytes_sent;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
ACE_SSL_SOCK_Stream::recvv_n (iovec iov[], size_t iovcnt) const
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Stream::recvv_n");
|
||||
|
||||
ssize_t bytes_read = 0;
|
||||
|
||||
for (size_t i = 0; i < iovcnt; ++i)
|
||||
{
|
||||
ssize_t const result = this->recv_n (iov[i].iov_base,
|
||||
iov[i].iov_len);
|
||||
|
||||
if (result == -1)
|
||||
{
|
||||
// There is a subtle difference in behaviour depending on
|
||||
// whether or not any data was read. If no data was read,
|
||||
// then always return -1. Otherwise return bytes_read.
|
||||
// This gives the caller an opportunity to keep track of
|
||||
// which data was actually read.
|
||||
if (bytes_read > 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes_read += result;
|
||||
}
|
||||
}
|
||||
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
int
|
||||
ACE_SSL_SOCK_Stream::get_remote_addr (ACE_Addr &addr) const
|
||||
{
|
||||
// Some applications use get_remote_addr() as a way of determining
|
||||
// whether or not a connection has been established. In SSL's case,
|
||||
// the remote addr will be available once the TCP handshake has been
|
||||
// complete. Despite that fact, the SSL connection may not have
|
||||
// been completed. In such a case, a successful return from
|
||||
// get_remote_addr() would be misleading.
|
||||
|
||||
if (SSL_is_init_finished (this->ssl_))
|
||||
{
|
||||
return this->ACE_SSL_SOCK::get_remote_addr (addr);
|
||||
}
|
||||
|
||||
if (this->get_handle () == ACE_INVALID_HANDLE)
|
||||
{
|
||||
errno = EBADF;
|
||||
}
|
||||
else
|
||||
{
|
||||
errno = ENOTCONN;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
ACE_END_VERSIONED_NAMESPACE_DECL
|
||||
321
dep/ACE_wrappers/ace/SSL/SSL_SOCK_Stream.h
Normal file
321
dep/ACE_wrappers/ace/SSL/SSL_SOCK_Stream.h
Normal file
@@ -0,0 +1,321 @@
|
||||
// -*- C++ -*-
|
||||
|
||||
//=============================================================================
|
||||
/**
|
||||
* @file SSL_SOCK_Stream.h
|
||||
*
|
||||
* $Id: SSL_SOCK_Stream.h 80826 2008-03-04 14:51:23Z wotte $
|
||||
*
|
||||
* @author Ossama Othman <ossama@uci.edu>
|
||||
* @author Carlos O'Ryan <coryan@uci.edu>
|
||||
* @author John Heitmann
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef ACE_SSL_SOCK_STREAM_H
|
||||
#define ACE_SSL_SOCK_STREAM_H
|
||||
|
||||
#include /**/ "ace/pre.h"
|
||||
|
||||
#include "SSL_Export.h"
|
||||
|
||||
#if !defined (ACE_LACKS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif /* ACE_LACKS_PRAGMA_ONCE */
|
||||
|
||||
// This must be included before any <openssl> include on LynxOS
|
||||
#include "ace/os_include/os_stdio.h"
|
||||
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "SSL_SOCK.h"
|
||||
#include "SSL_Context.h"
|
||||
|
||||
#include "ace/SOCK_Stream.h"
|
||||
|
||||
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
|
||||
|
||||
/**
|
||||
* @class ACE_SSL_SOCK_Stream
|
||||
*
|
||||
* @brief Defines methods in the ACE_SSL_SOCK_Stream abstraction.
|
||||
*
|
||||
* This class encapsulates the methods and functionality necessary to
|
||||
* send and receive data over TLS/SSL.
|
||||
* @par
|
||||
* Since SSL is record-oriented, some additional steps must be taken
|
||||
* to make the ACE_SSL_SOCK_Stream interact properly with the
|
||||
* Reactor (if one is used) when performing non-blocking IO. In
|
||||
* particular, if ::SSL_pending (ssl), where "ssl" is a pointer to the
|
||||
* SSL data structure returned from ACE_SSL_SOCK_Stream::ssl(),
|
||||
* returns a non-zero value then the event handler that calls the IO
|
||||
* methods in this class should return a value greater than zero to
|
||||
* force the Reactor to invoke the event handler before polling for
|
||||
* additional events (e.g. blocking on select()).
|
||||
*
|
||||
* @note The user must currently ensure that only one thread services
|
||||
* a given SSL session at any given time since underlying SSL
|
||||
* implementations, such as OpenSSL, are not entirely
|
||||
* thread-safe or reentrant.
|
||||
*/
|
||||
class ACE_SSL_Export ACE_SSL_SOCK_Stream : public ACE_SSL_SOCK
|
||||
{
|
||||
public:
|
||||
|
||||
/// Constructor
|
||||
/**
|
||||
* @param context Pointer to @c ACE_SSL_Context instance containing
|
||||
* the OpenSSL @c SSL data structure to be associated
|
||||
* with this @c ACE_SSL_SOCK_Stream. The @c SSL data
|
||||
* structure will be copied to make it at least
|
||||
* logically independent of the supplied @a context.
|
||||
*/
|
||||
ACE_SSL_SOCK_Stream (ACE_SSL_Context *context =
|
||||
ACE_SSL_Context::instance ());
|
||||
|
||||
/// Destructor
|
||||
~ACE_SSL_SOCK_Stream (void);
|
||||
|
||||
/// Send an n byte buffer to the ssl socket using the semantics of
|
||||
/// send(3n).
|
||||
/**
|
||||
* ACE_SSL supports no flags for sending at this time.
|
||||
*/
|
||||
ssize_t send (const void *buf,
|
||||
size_t n,
|
||||
int flags) const;
|
||||
|
||||
/// Recv an n byte buffer from the ssl socket using the semantics of
|
||||
/// recv(3n).
|
||||
/**
|
||||
* ACE_SSL supports MSG_PEEK, but no other flags at this time.
|
||||
*/
|
||||
ssize_t recv (void *buf,
|
||||
size_t n,
|
||||
int flags) const;
|
||||
|
||||
/// Send an n byte buffer to the ssl socket using the semantics of
|
||||
/// write(2).
|
||||
ssize_t send (const void *buf,
|
||||
size_t n) const;
|
||||
|
||||
/// Recv an n byte buffer from the ssl socket using the semantics of
|
||||
/// read(2).
|
||||
ssize_t recv (void *buf,
|
||||
size_t n) const;
|
||||
|
||||
/// Send an iovec of size n to the ssl socket.
|
||||
/**
|
||||
* Note that it is not possible to perform a "scattered" write with
|
||||
* the underlying OpenSSL implementation. As such, the expected
|
||||
* semantics are not fully reproduced with this implementation.
|
||||
*/
|
||||
ssize_t sendv (const iovec iov[],
|
||||
size_t n,
|
||||
const ACE_Time_Value *timeout = 0) const;
|
||||
|
||||
/**
|
||||
* Allows a client to read from a socket without having to provide a
|
||||
* buffer to read. This method determines how much data is in the
|
||||
* socket, allocates a buffer of this size, reads in the data, and
|
||||
* returns the number of bytes read. The caller is responsible for
|
||||
* deleting the member in the iov_base field of io_vec using
|
||||
* delete [] io_vec->iov_base.
|
||||
*/
|
||||
ssize_t recvv (iovec *io_vec,
|
||||
const ACE_Time_Value *timeout = 0) const;
|
||||
|
||||
/**
|
||||
* Wait to timeout amount of time to send up to n bytes into buf
|
||||
* (uses the send() call). If send() times out -1 is returned with
|
||||
* errno == ETIME. If it succeeds the number of bytes sent is
|
||||
* returned. No flags are supported.
|
||||
*/
|
||||
ssize_t send (const void *buf,
|
||||
size_t n,
|
||||
int flags,
|
||||
const ACE_Time_Value *timeout) const;
|
||||
|
||||
/**
|
||||
* Wait up to timeout amount of time to receive up to n bytes into
|
||||
* buf (uses the recv() call). If recv() times out -1 is returned
|
||||
* with errno == ETIME. If it succeeds the number of bytes received
|
||||
* is returned. MSG_PEEK is the only supported flag.
|
||||
*/
|
||||
ssize_t recv (void *buf,
|
||||
size_t n,
|
||||
int flags,
|
||||
const ACE_Time_Value *timeout) const;
|
||||
|
||||
/**
|
||||
* Wait to to timeout amount of time to send up to n bytes into
|
||||
* buf (uses the send() call). If send() times out
|
||||
* a -1 is returned with errno == ETIME. If it succeeds the
|
||||
* number of bytes sent is returned.
|
||||
*/
|
||||
ssize_t send (const void *buf,
|
||||
size_t n,
|
||||
const ACE_Time_Value *timeout) const;
|
||||
|
||||
/**
|
||||
* Wait up to timeout amount of time to receive up to n bytes
|
||||
* into buf (uses the recv() call). If recv() times
|
||||
* out a -1 is returned with @c errno == ETIME. If it succeeds the
|
||||
* number of bytes received is returned.
|
||||
*/
|
||||
ssize_t recv (void *buf,
|
||||
size_t n,
|
||||
const ACE_Time_Value *timeout) const;
|
||||
|
||||
/// Send n varargs messages to the connected ssl socket.
|
||||
ssize_t send (size_t n,
|
||||
...) const;
|
||||
|
||||
/// Recv n varargs messages to the connected ssl socket.
|
||||
ssize_t recv (size_t n,
|
||||
...) const;
|
||||
|
||||
/// Send n bytes, keep trying until n are sent.
|
||||
ssize_t send_n (const void *buf, int n) const;
|
||||
|
||||
/// Recv n bytes, keep trying until n are received.
|
||||
ssize_t recv_n (void *buf, int n) const;
|
||||
|
||||
/**
|
||||
* @note In the following four methods, only MSG_PEEK is supported
|
||||
* for recv_n(), and no flags are supported for send_n().
|
||||
*/
|
||||
//@{
|
||||
/// Send n bytes, keep trying until n are sent.
|
||||
ssize_t send_n (const void *buf, int n, int flags) const;
|
||||
|
||||
/// Recv n bytes, keep trying until n are sent.
|
||||
ssize_t recv_n (void *buf, int n, int flags) const;
|
||||
|
||||
/**
|
||||
* Try to send exactly len bytes into buf (uses the send() call).
|
||||
* If send() blocks for longer than timeout the number of bytes
|
||||
* actually sent is returned with errno == ETIME. If a timeout does
|
||||
* not occur, send_n() return len (i.e., the number of bytes
|
||||
* requested to be sent).
|
||||
*/
|
||||
ssize_t send_n (const void *buf,
|
||||
size_t len,
|
||||
int flags,
|
||||
const ACE_Time_Value *timeout,
|
||||
size_t *bytes_transferred = 0) const;
|
||||
|
||||
/**
|
||||
* Try to receive exactly len bytes into buf (uses the recv() call).
|
||||
* The ACE_Time_Value indicates how long to blocking trying to
|
||||
* receive. If timeout == 0, the caller will block until action is
|
||||
* possible, else will wait until the relative time specified in
|
||||
* timeout elapses). If recv() blocks for longer than timeout the
|
||||
* number of bytes actually read is returned with errno == ETIME.
|
||||
* If a timeout does not occur, recv_n return len (i.e., the number
|
||||
* of bytes requested to be read).
|
||||
*/
|
||||
ssize_t recv_n (void *buf,
|
||||
size_t len,
|
||||
int flags,
|
||||
const ACE_Time_Value *timeout,
|
||||
size_t *bytes_transferred = 0) const;
|
||||
//@}
|
||||
|
||||
/**
|
||||
* Send an iovec of size n to the connected socket. Will block
|
||||
* until all bytes are sent or an error occurs.
|
||||
*/
|
||||
ssize_t sendv_n (const iovec iov[],
|
||||
size_t n) const;
|
||||
|
||||
/// Receive an iovec of size n to the connected socket.
|
||||
ssize_t recvv_n (iovec iov[],
|
||||
size_t n) const;
|
||||
|
||||
|
||||
/**
|
||||
* Selectively close endpoints.
|
||||
*/
|
||||
//@{
|
||||
/// Close down the reader.
|
||||
int close_reader (void);
|
||||
|
||||
/// Close down the writer.
|
||||
int close_writer (void);
|
||||
//@}
|
||||
|
||||
///Close down the socket.
|
||||
int close (void);
|
||||
|
||||
/// Meta-type info
|
||||
typedef ACE_INET_Addr PEER_ADDR;
|
||||
|
||||
/// Declare the dynamic allocation hooks.
|
||||
ACE_ALLOC_HOOK_DECLARE;
|
||||
|
||||
/// Overridden set_handle() method.
|
||||
/**
|
||||
* Only an ACE_SSL_SOCK_Acceptor or ACE_SSL_SOCK_Connector should
|
||||
* access this method since some state in the underlying "ssl_" data
|
||||
* structure is set during SSL connection establishment.
|
||||
*/
|
||||
void set_handle (ACE_HANDLE fd);
|
||||
|
||||
/// Return a pointer to the underlying SSL structure.
|
||||
SSL *ssl (void) const;
|
||||
|
||||
/**
|
||||
* Return the address of the remotely connected peer (if there is
|
||||
* one), in the referenced <ACE_Addr>. Returns 0 if successful, else
|
||||
* -1.
|
||||
*
|
||||
* @note If the TCP connection has been completed but the SSL
|
||||
* connection has not been completed yet, -1 will be
|
||||
* returned.
|
||||
*/
|
||||
int get_remote_addr (ACE_Addr &) const;
|
||||
|
||||
/// Return the underlying ACE_SOCK_Stream which ACE_SSL runs atop of.
|
||||
ACE_SOCK_Stream & peer (void);
|
||||
|
||||
protected:
|
||||
|
||||
/// Underlying send() helper method common to all public send()
|
||||
/// methods.
|
||||
ssize_t send_i (const void *buf,
|
||||
size_t n,
|
||||
int flags) const;
|
||||
|
||||
/// Underlying send() helper method common to all public send()
|
||||
/// methods.
|
||||
ssize_t recv_i (void *buf,
|
||||
size_t n,
|
||||
int flags,
|
||||
const ACE_Time_Value *timeout) const;
|
||||
|
||||
private:
|
||||
|
||||
ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_SSL_SOCK_Stream &))
|
||||
ACE_UNIMPLEMENTED_FUNC (ACE_SSL_SOCK_Stream (const ACE_SSL_SOCK_Stream &))
|
||||
|
||||
protected:
|
||||
|
||||
/// The SSL session.
|
||||
SSL *ssl_;
|
||||
|
||||
/// The stream which works under the ssl connection.
|
||||
ACE_SOCK_Stream stream_;
|
||||
|
||||
};
|
||||
|
||||
ACE_END_VERSIONED_NAMESPACE_DECL
|
||||
|
||||
#if defined (__ACE_INLINE__)
|
||||
#include "SSL_SOCK_Stream.inl"
|
||||
#endif /* __ACE_INLINE__ */
|
||||
|
||||
#include /**/ "ace/post.h"
|
||||
|
||||
#endif /* ACE_SSL_SOCK_STREAM_H */
|
||||
330
dep/ACE_wrappers/ace/SSL/SSL_SOCK_Stream.inl
Normal file
330
dep/ACE_wrappers/ace/SSL/SSL_SOCK_Stream.inl
Normal file
@@ -0,0 +1,330 @@
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// $Id: SSL_SOCK_Stream.inl 82579 2008-08-10 23:03:06Z mitza $
|
||||
|
||||
#include "ace/OS_NS_errno.h"
|
||||
#include "ace/Truncate.h"
|
||||
|
||||
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
|
||||
|
||||
ACE_INLINE void
|
||||
ACE_SSL_SOCK_Stream::set_handle (ACE_HANDLE fd)
|
||||
{
|
||||
if (this->ssl_ == 0 || fd == ACE_INVALID_HANDLE)
|
||||
{
|
||||
this->ACE_SSL_SOCK::set_handle (ACE_INVALID_HANDLE);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
(void) ::SSL_set_fd (this->ssl_, (int) fd);
|
||||
this->ACE_SSL_SOCK::set_handle (fd);
|
||||
this->stream_.set_handle (fd);
|
||||
}
|
||||
}
|
||||
|
||||
ACE_INLINE ssize_t
|
||||
ACE_SSL_SOCK_Stream::send_i (const void *buf,
|
||||
size_t n,
|
||||
int flags) const
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Stream::send_i");
|
||||
|
||||
// NOTE: Caller must provide thread-synchronization.
|
||||
|
||||
// No send flags are supported in SSL.
|
||||
if (flags != 0)
|
||||
{
|
||||
ACE_NOTSUP_RETURN (-1);
|
||||
}
|
||||
|
||||
int const bytes_sent = ::SSL_write (this->ssl_,
|
||||
static_cast<const char *> (buf),
|
||||
ACE_Utils::truncate_cast<int> (n));
|
||||
|
||||
switch (::SSL_get_error (this->ssl_, bytes_sent))
|
||||
{
|
||||
case SSL_ERROR_NONE:
|
||||
return bytes_sent;
|
||||
|
||||
case SSL_ERROR_WANT_READ:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
errno = EWOULDBLOCK;
|
||||
|
||||
return -1;
|
||||
|
||||
case SSL_ERROR_ZERO_RETURN:
|
||||
// The peer has notified us that it is shutting down via the SSL
|
||||
// "close_notify" message so we need to shutdown, too.
|
||||
(void) ::SSL_shutdown (this->ssl_);
|
||||
|
||||
return bytes_sent;
|
||||
|
||||
case SSL_ERROR_SYSCALL:
|
||||
if (bytes_sent == 0)
|
||||
// An EOF occured but the SSL "close_notify" message was not
|
||||
// sent. This is a protocol error, but we ignore it.
|
||||
return 0;
|
||||
|
||||
// If not an EOF, then fall through to "default" case.
|
||||
|
||||
// On some platforms (e.g. MS Windows) OpenSSL does not store
|
||||
// the last error in errno so explicitly do so.
|
||||
ACE_OS::set_errno_to_last_error ();
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
// Reset errno to prevent previous values (e.g. EWOULDBLOCK)
|
||||
// from being associated with fatal SSL errors.
|
||||
errno = 0;
|
||||
|
||||
ACE_SSL_Context::report_error ();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
ACE_INLINE ssize_t
|
||||
ACE_SSL_SOCK_Stream::send (const void *buf,
|
||||
size_t n,
|
||||
int flags) const
|
||||
{
|
||||
return this->send_i (buf, n, flags);
|
||||
}
|
||||
|
||||
ACE_INLINE ssize_t
|
||||
ACE_SSL_SOCK_Stream::recv_i (void *buf,
|
||||
size_t n,
|
||||
int flags,
|
||||
const ACE_Time_Value *timeout) const
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Stream::recv_i");
|
||||
|
||||
// NOTE: Caller must provide thread-synchronization.
|
||||
|
||||
int bytes_read = 0;
|
||||
ACE_HANDLE const handle = this->get_handle ();
|
||||
|
||||
// Value for current I/O mode (blocking/non-blocking)
|
||||
int val = 0;
|
||||
|
||||
if (timeout != 0)
|
||||
ACE::record_and_set_non_blocking_mode (handle,
|
||||
val);
|
||||
|
||||
// Only block on select() with a timeout if no data in the
|
||||
// internal OpenSSL buffer is pending read completion for
|
||||
// the same reasons stated above, i.e. all data must be read
|
||||
// before blocking on select().
|
||||
if (timeout != 0
|
||||
&& !::SSL_pending (this->ssl_))
|
||||
{
|
||||
if (ACE::enter_recv_timedwait (handle,
|
||||
timeout,
|
||||
val) == -1)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flags)
|
||||
{
|
||||
if (ACE_BIT_ENABLED (flags, MSG_PEEK))
|
||||
{
|
||||
bytes_read = ::SSL_peek (this->ssl_,
|
||||
static_cast<char *> (buf),
|
||||
ACE_Utils::truncate_cast<int> (n));
|
||||
}
|
||||
else
|
||||
{
|
||||
ACE_NOTSUP_RETURN (-1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes_read = ::SSL_read (this->ssl_,
|
||||
static_cast<char *> (buf),
|
||||
ACE_Utils::truncate_cast<int> (n));
|
||||
}
|
||||
|
||||
int const status = ::SSL_get_error (this->ssl_, bytes_read);
|
||||
switch (status)
|
||||
{
|
||||
case SSL_ERROR_NONE:
|
||||
if (timeout != 0)
|
||||
ACE::restore_non_blocking_mode (handle, val);
|
||||
|
||||
return bytes_read;
|
||||
|
||||
case SSL_ERROR_WANT_READ:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
errno = EWOULDBLOCK;
|
||||
|
||||
return -1;
|
||||
|
||||
case SSL_ERROR_ZERO_RETURN:
|
||||
if (timeout != 0)
|
||||
ACE::restore_non_blocking_mode (handle, val);
|
||||
|
||||
// The peer has notified us that it is shutting down via the SSL
|
||||
// "close_notify" message so we need to shutdown, too.
|
||||
(void) ::SSL_shutdown (this->ssl_);
|
||||
|
||||
return bytes_read;
|
||||
|
||||
case SSL_ERROR_SYSCALL:
|
||||
if (bytes_read == 0)
|
||||
// An EOF occured but the SSL "close_notify" message was not
|
||||
// sent. This is a protocol error, but we ignore it.
|
||||
return 0;
|
||||
|
||||
// If not an EOF, then fall through to "default" case.
|
||||
|
||||
// On some platforms (e.g. MS Windows) OpenSSL does not store
|
||||
// the last error in errno so explicitly do so.
|
||||
ACE_OS::set_errno_to_last_error ();
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
// Reset errno to prevent previous values (e.g. EWOULDBLOCK)
|
||||
// from being associated with a fatal SSL error.
|
||||
errno = 0;
|
||||
|
||||
ACE_SSL_Context::report_error ();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
ACE_INLINE ssize_t
|
||||
ACE_SSL_SOCK_Stream::recv (void *buf,
|
||||
size_t n,
|
||||
int flags) const
|
||||
{
|
||||
return this->recv_i (buf, n, flags, 0);
|
||||
}
|
||||
|
||||
ACE_INLINE ssize_t
|
||||
ACE_SSL_SOCK_Stream::send (const void *buf,
|
||||
size_t n) const
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Stream::send");
|
||||
|
||||
return this->send_i (buf, n, 0);
|
||||
}
|
||||
|
||||
ACE_INLINE ssize_t
|
||||
ACE_SSL_SOCK_Stream::recv (void *buf,
|
||||
size_t n) const
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Stream::recv");
|
||||
|
||||
return this->recv_i (buf, n, 0, 0);
|
||||
}
|
||||
|
||||
ACE_INLINE ssize_t
|
||||
ACE_SSL_SOCK_Stream::send (const void *buf,
|
||||
size_t len,
|
||||
const ACE_Time_Value *timeout) const
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Stream::send");
|
||||
return this->send (buf, len, 0, timeout);
|
||||
}
|
||||
|
||||
ACE_INLINE ssize_t
|
||||
ACE_SSL_SOCK_Stream::recv (void *buf,
|
||||
size_t n,
|
||||
const ACE_Time_Value *timeout) const
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Stream::recv");
|
||||
return this->recv (buf, n, 0, timeout);
|
||||
}
|
||||
|
||||
ACE_INLINE ssize_t
|
||||
ACE_SSL_SOCK_Stream::recv_n (void *buf, int buf_size) const
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Stream::recv_n");
|
||||
return this->recv_n (buf, buf_size, 0);
|
||||
}
|
||||
|
||||
ACE_INLINE ssize_t
|
||||
ACE_SSL_SOCK_Stream::send_n (const void *buf, int len) const
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Stream::send_n");
|
||||
return this->send_n (buf, len, 0);
|
||||
}
|
||||
|
||||
ACE_INLINE int
|
||||
ACE_SSL_SOCK_Stream::close_reader (void)
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Stream::close_reader");
|
||||
return this->stream_.close_reader ();
|
||||
}
|
||||
|
||||
ACE_INLINE int
|
||||
ACE_SSL_SOCK_Stream::close_writer (void)
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Stream::close_writer");
|
||||
return this->stream_.close_writer ();
|
||||
}
|
||||
|
||||
ACE_INLINE int
|
||||
ACE_SSL_SOCK_Stream::close (void)
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Stream::close");
|
||||
|
||||
if (this->ssl_ == 0 || this->get_handle () == ACE_INVALID_HANDLE)
|
||||
return 0; // SSL_SOCK_Stream was never opened.
|
||||
|
||||
// SSL_shutdown() returns 1 on successful shutdown of the SSL
|
||||
// connection, not 0.
|
||||
int const status = ::SSL_shutdown (this->ssl_);
|
||||
|
||||
switch (::SSL_get_error (this->ssl_, status))
|
||||
{
|
||||
case SSL_ERROR_NONE:
|
||||
case SSL_ERROR_SYSCALL: // Ignore this error condition.
|
||||
|
||||
// Reset the SSL object to allow another connection to be made
|
||||
// using this ACE_SSL_SOCK_Stream instance. This prevents the
|
||||
// previous SSL session state from being associated with the new
|
||||
// SSL session/connection.
|
||||
(void) ::SSL_clear (this->ssl_);
|
||||
this->set_handle (ACE_INVALID_HANDLE);
|
||||
return this->stream_.close ();
|
||||
|
||||
case SSL_ERROR_WANT_READ:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
errno = EWOULDBLOCK;
|
||||
break;
|
||||
|
||||
default:
|
||||
ACE_SSL_Context::report_error ();
|
||||
|
||||
ACE_Errno_Guard error (errno); // Save/restore errno
|
||||
(void) this->stream_.close ();
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
ACE_INLINE ACE_SOCK_Stream &
|
||||
ACE_SSL_SOCK_Stream::peer (void)
|
||||
{
|
||||
ACE_TRACE ("ACE_SSL_SOCK_Stream::peer");
|
||||
return this->stream_;
|
||||
}
|
||||
|
||||
ACE_INLINE SSL *
|
||||
ACE_SSL_SOCK_Stream::ssl (void) const
|
||||
{
|
||||
return this->ssl_;
|
||||
}
|
||||
|
||||
ACE_END_VERSIONED_NAMESPACE_DECL
|
||||
55
dep/ACE_wrappers/ace/SSL/sslconf.h
Normal file
55
dep/ACE_wrappers/ace/SSL/sslconf.h
Normal file
@@ -0,0 +1,55 @@
|
||||
// -*- C++ -*-
|
||||
|
||||
//=============================================================================
|
||||
/**
|
||||
* @file sslconf.h
|
||||
*
|
||||
* $Id: sslconf.h 80826 2008-03-04 14:51:23Z wotte $
|
||||
*
|
||||
* @author Carlos O'Ryan <coryan@ece.uci.edu>
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef ACE_SSLCONF_H
|
||||
#define ACE_SSLCONF_H
|
||||
|
||||
#include /**/ "ace/pre.h"
|
||||
|
||||
#include /**/ "ace/config-all.h"
|
||||
|
||||
#if !defined (ACE_DEFAULT_SSL_CERT_FILE)
|
||||
# ifdef WIN32
|
||||
# define ACE_DEFAULT_SSL_CERT_FILE "cert.pem"
|
||||
# else
|
||||
# define ACE_DEFAULT_SSL_CERT_FILE "/etc/ssl/cert.pem"
|
||||
# endif /* WIN32 */
|
||||
#endif /* ACE_DEFAULT_SSL_CERT_FILE */
|
||||
|
||||
#if !defined (ACE_DEFAULT_SSL_CERT_DIR)
|
||||
# ifdef WIN32
|
||||
# define ACE_DEFAULT_SSL_CERT_DIR "certs"
|
||||
# else
|
||||
# define ACE_DEFAULT_SSL_CERT_DIR "/etc/ssl/certs"
|
||||
# endif /* WIN32 */
|
||||
#endif /* ACE_DEFAULT_SSL_CERT_DIR */
|
||||
|
||||
#if !defined (ACE_SSL_CERT_FILE_ENV)
|
||||
#define ACE_SSL_CERT_FILE_ENV "SSL_CERT_FILE"
|
||||
#endif /* ACE_SSL_CERT_FILE_ENV */
|
||||
|
||||
#if !defined (ACE_SSL_CERT_DIR_ENV)
|
||||
#define ACE_SSL_CERT_DIR_ENV "SSL_CERT_DIR"
|
||||
#endif /* ACE_SSL_CERT_DIR_ENV */
|
||||
|
||||
#if !defined (ACE_SSL_EGD_FILE_ENV)
|
||||
#define ACE_SSL_EGD_FILE_ENV "SSL_EGD_FILE"
|
||||
#endif /* ACE_SSL_EGD_FILE_ENV */
|
||||
|
||||
#if !defined (ACE_SSL_RAND_FILE_ENV)
|
||||
#define ACE_SSL_RAND_FILE_ENV "SSL_RAND_FILE"
|
||||
#endif /* ACE_SSL_RAND_FILE_ENV */
|
||||
|
||||
#include /**/ "ace/post.h"
|
||||
|
||||
#endif /* ACE_SSLCONF_H */
|
||||
@@ -51,7 +51,7 @@
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/MP /wd 4748 /wd 4244"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\dep\ACE_wrappers"
|
||||
AdditionalIncludeDirectories="..\..\dep\include;..\..\dep\ACE_wrappers"
|
||||
PreprocessorDefinitions="ACE_BUILD_DLL;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
|
||||
MinimalRebuild="false"
|
||||
BasicRuntimeChecks="3"
|
||||
@@ -76,7 +76,7 @@
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies=""
|
||||
AdditionalDependencies="..\..\dep\lib\$(PlatformName)_$(ConfigurationName)\ssleay32.lib ..\..\dep\lib\$(PlatformName)_$(ConfigurationName)\libeay32.lib"
|
||||
OutputFile="$(OutDir)\ACEd.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
@@ -140,7 +140,7 @@
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/MP /wd 4748 /wd 4244"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\dep\ACE_wrappers"
|
||||
AdditionalIncludeDirectories="..\..\dep\include;..\..\dep\ACE_wrappers"
|
||||
PreprocessorDefinitions="ACE_BUILD_DLL;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
|
||||
MinimalRebuild="false"
|
||||
BasicRuntimeChecks="3"
|
||||
@@ -166,7 +166,7 @@
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/machine:AMD64"
|
||||
AdditionalDependencies=""
|
||||
AdditionalDependencies="..\..\dep\lib\$(PlatformName)_$(ConfigurationName)\ssleay32.lib ..\..\dep\lib\$(PlatformName)_$(ConfigurationName)\libeay32.lib"
|
||||
OutputFile="$(OutDir)\ACEd.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
@@ -230,7 +230,7 @@
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/MP /wd 4748 /wd 4244"
|
||||
Optimization="2"
|
||||
AdditionalIncludeDirectories="..\..\dep\ACE_wrappers"
|
||||
AdditionalIncludeDirectories="..\..\dep\include;..\..\dep\ACE_wrappers"
|
||||
PreprocessorDefinitions="ACE_BUILD_DLL;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SECURE_SCL=0"
|
||||
RuntimeLibrary="2"
|
||||
RuntimeTypeInfo="true"
|
||||
@@ -252,7 +252,7 @@
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies=""
|
||||
AdditionalDependencies="..\..\dep\lib\$(PlatformName)_$(ConfigurationName)\ssleay32.lib ..\..\dep\lib\$(PlatformName)_$(ConfigurationName)\libeay32.lib"
|
||||
OutputFile="$(OutDir)\ACE.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
@@ -318,7 +318,7 @@
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/MP /wd 4748 /wd 4244"
|
||||
Optimization="2"
|
||||
AdditionalIncludeDirectories="..\..\dep\ACE_wrappers"
|
||||
AdditionalIncludeDirectories="..\..\dep\include;..\..\dep\ACE_wrappers"
|
||||
PreprocessorDefinitions="ACE_BUILD_DLL;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SECURE_SCL=0"
|
||||
RuntimeLibrary="2"
|
||||
RuntimeTypeInfo="true"
|
||||
@@ -342,7 +342,7 @@
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/machine:AMD64"
|
||||
AdditionalDependencies=""
|
||||
AdditionalDependencies="..\..\dep\lib\$(PlatformName)_$(ConfigurationName)\ssleay32.lib ..\..\dep\lib\$(PlatformName)_$(ConfigurationName)\libeay32.lib"
|
||||
OutputFile="$(OutDir)\ACE.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
@@ -1400,6 +1400,34 @@
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\SPIPE_Stream.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\SSL\SSL_Asynch_BIO.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\SSL\SSL_Asynch_Stream.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\SSL\SSL_Context.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\SSL\SSL_SOCK.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\SSL\SSL_SOCK_Acceptor.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\SSL\SSL_SOCK_Connector.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\SSL\SSL_SOCK_Stream.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\SString.cpp"
|
||||
>
|
||||
@@ -3689,6 +3717,42 @@
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\SPIPE_Stream.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\SSL\SSL_Asynch_BIO.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\SSL\SSL_Asynch_Stream.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\SSL\SSL_Context.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\SSL\SSL_Export.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\SSL\SSL_SOCK.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\SSL\SSL_SOCK_Acceptor.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\SSL\SSL_SOCK_Connector.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\SSL\SSL_SOCK_Stream.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\SSL\sslconf.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\SString.h"
|
||||
>
|
||||
@@ -4990,6 +5054,30 @@
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\SPIPE_Stream.inl"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\SSL\SSL_Asynch_Stream.inl"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\SSL\SSL_Context.inl"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\SSL\SSL_SOCK.inl"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\SSL\SSL_SOCK_Acceptor.inl"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\SSL\SSL_SOCK_Connector.inl"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\SSL\SSL_SOCK_Stream.inl"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\SString.inl"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user