Go to the documentation of this file.00001
00002
00003 #include "ace/INet/SSL_CallbackManager.h"
00004
00005 #if !defined (__ACE_INLINE__)
00006 #include "ace/INet/SSL_CallbackManager.inl"
00007 #endif
00008
00009 #include "ace/Truncate.h"
00010 #include "ace/Singleton.h"
00011 #include "ace/INet/INet_Log.h"
00012
00013 #include <openssl/x509.h>
00014
00015 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00016
00017 namespace ACE
00018 {
00019 namespace INet
00020 {
00021
00022 int SSL_CallbackManager::ssl_ctx_mngr_index_ = (-2);
00023
00024 SSL_CallbackManager::SSL_CallbackManager ()
00025 {
00026 }
00027
00028 SSL_CallbackManager::~SSL_CallbackManager ()
00029 {
00030 }
00031
00032 void SSL_CallbackManager::initialize_callbacks (ACE_SSL_Context* ssl_ctx)
00033 {
00034 if (ssl_ctx_mngr_index_ < -1)
00035 {
00036 ssl_ctx_mngr_index_ = ::SSL_CTX_get_ex_new_index (0, 0, 0,0,0);
00037 if (ssl_ctx_mngr_index_ < 0)
00038 {
00039 INET_ERROR (1, (LM_ERROR, DLINFO
00040 ACE_TEXT ("SSL_CallbackManager::initialize_callbacks - ")
00041 ACE_TEXT ("failed to allocate SSL_CTX ex_data index.\n")));
00042 return;
00043 }
00044 }
00045
00046 this->ssl_ctx_ = ssl_ctx == 0 ? ACE_SSL_Context::instance () : ssl_ctx;
00047 ::SSL_CTX_set_ex_data (this->ssl_ctx_->context (), ssl_ctx_mngr_index_, this);
00048 this->ssl_ctx_->default_verify_callback (verify_certificate_callback);
00049 ::SSL_CTX_set_default_passwd_cb (ssl_ctx->context(), passwd_callback);
00050 ::SSL_CTX_set_default_passwd_cb_userdata (ssl_ctx->context(), this);
00051 }
00052
00053 SSL_CallbackManager* SSL_CallbackManager::instance ()
00054 {
00055 return ACE_Singleton<SSL_CallbackManager, ACE_SYNCH::MUTEX>::instance ();
00056 }
00057
00058 int SSL_CallbackManager::verify_certificate_callback (SSL_CertificateCallbackArg& arg)
00059 {
00060 TCertificateCallback cert_cb = this->cert_callback_;
00061 if (cert_cb)
00062 {
00063 cert_cb->handle_certificate_failure (arg);
00064 }
00065 return (arg.ignore_error () ? 1 : 0);
00066 }
00067
00068 void SSL_CallbackManager::passwd_callback (ACE_CString& pwd)
00069 {
00070 TPasswordCallback pw_cb = passwd_callback_;
00071 if (pw_cb)
00072 {
00073 pw_cb->get_privatekey_password (pwd);
00074 }
00075 }
00076
00077 int SSL_CallbackManager::verify_certificate_callback (int ok, X509_STORE_CTX* cert_ctx)
00078 {
00079 if (!ok && ssl_ctx_mngr_index_>=0)
00080 {
00081
00082 void* ex_data = ::X509_STORE_CTX_get_ex_data (cert_ctx, ::SSL_get_ex_data_X509_STORE_CTX_idx());
00083 ::SSL* ssl = reinterpret_cast< ::SSL* > (ex_data);
00084
00085 ::SSL_CTX* ssl_ctx = ::SSL_get_SSL_CTX (ssl);
00086
00087 ex_data = ::SSL_CTX_get_ex_data (ssl_ctx, ssl_ctx_mngr_index_);
00088 SSL_CallbackManager* cbmngr = reinterpret_cast<SSL_CallbackManager*> (ex_data);
00089
00090 SSL_CertificateCallbackArg arg (cbmngr->context(), cert_ctx);
00091 ok = cbmngr->verify_certificate_callback (arg);
00092 }
00093
00094 return ok;
00095 }
00096
00097 int SSL_CallbackManager::passwd_callback (char* buf, int size, int , void* user_data)
00098 {
00099 if (user_data == 0)
00100 return 0;
00101
00102 SSL_CallbackManager* cbmngr = reinterpret_cast<SSL_CallbackManager*> (user_data);
00103
00104 ACE_CString pwd;
00105 cbmngr->passwd_callback (pwd);
00106 if (!pwd.empty ())
00107 {
00108 ACE_OS::strncpy (buf, pwd.c_str (), size);
00109 buf[size - 1] = '\0';
00110 if (size > ACE_Utils::truncate_cast<int> (pwd.length ()))
00111 size = ACE_Utils::truncate_cast<int> (pwd.length ());
00112
00113 return size;
00114 }
00115 else
00116 return 0;
00117 }
00118
00119 }
00120 }
00121
00122 ACE_END_VERSIONED_NAMESPACE_DECL