Use a variable on the stack to not have a temporary in the call
[ACE_TAO.git] / ACE / protocols / ace / INet / SSL_CallbackManager.cpp
blobf78dab0db4bd33e52317dc827c79f9a102992418
1 #include "ace/INet/SSL_CallbackManager.h"
3 #if !defined (__ACE_INLINE__)
4 #include "ace/INet/SSL_CallbackManager.inl"
5 #endif
7 #include "ace/Truncate.h"
8 #include "ace/Singleton.h"
9 #include "ace/INet/INet_Log.h"
11 #include <openssl/x509.h>
13 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
15 namespace ACE
17 namespace INet
19 int SSL_CallbackManager::ssl_ctx_mngr_index_ = (-2);
21 SSL_CallbackManager::SSL_CallbackManager ()
25 SSL_CallbackManager::~SSL_CallbackManager ()
29 void SSL_CallbackManager::initialize_callbacks (ACE_SSL_Context* ssl_ctx)
31 if (ssl_ctx_mngr_index_ < -1)
33 ssl_ctx_mngr_index_ = ::SSL_CTX_get_ex_new_index (0, 0, 0,0,0);
34 if (ssl_ctx_mngr_index_ < 0)
36 INET_ERROR (1, (LM_ERROR, DLINFO
37 ACE_TEXT ("SSL_CallbackManager::initialize_callbacks - ")
38 ACE_TEXT ("failed to allocate SSL_CTX ex_data index.\n")));
39 return;
43 this->ssl_ctx_ = ssl_ctx == 0 ? ACE_SSL_Context::instance () : ssl_ctx;
44 ::SSL_CTX_set_ex_data (this->ssl_ctx_->context (), ssl_ctx_mngr_index_, this);
45 this->ssl_ctx_->default_verify_callback (extern_C_verify_certificate_callback);
46 ::SSL_CTX_set_default_passwd_cb (ssl_ctx->context(), extern_C_passwd_callback);
47 ::SSL_CTX_set_default_passwd_cb_userdata (ssl_ctx->context(), this);
50 SSL_CallbackManager* SSL_CallbackManager::instance ()
52 return ACE_Singleton<SSL_CallbackManager, ACE_SYNCH::MUTEX>::instance ();
55 int SSL_CallbackManager::verify_certificate_callback (SSL_CertificateCallbackArg& arg)
57 TCertificateCallback cert_cb = this->cert_callback_;
58 if (cert_cb)
60 cert_cb->handle_certificate_failure (arg);
62 return (arg.ignore_error () ? 1 : 0);
65 void SSL_CallbackManager::passwd_callback (ACE_CString& pwd)
67 TPasswordCallback pw_cb = passwd_callback_;
68 if (pw_cb)
70 pw_cb->get_privatekey_password (pwd);
74 int extern_C_verify_certificate_callback (int ok, X509_STORE_CTX* cert_ctx)
76 if (!ok && SSL_CallbackManager::ssl_ctx_mngr_index_>=0)
78 // Retrieve the pointer to the SSL of the connection currently treated
79 void* ex_data = ::X509_STORE_CTX_get_ex_data (cert_ctx, ::SSL_get_ex_data_X509_STORE_CTX_idx());
80 ::SSL* ssl = reinterpret_cast< ::SSL* > (ex_data);
81 // Retrieve SSL_CTX pointer of the connection currently treated
82 ::SSL_CTX* ssl_ctx = ::SSL_get_SSL_CTX (ssl);
83 // Retrieve our SSL_CallbackManager
84 ex_data = ::SSL_CTX_get_ex_data (ssl_ctx, SSL_CallbackManager::ssl_ctx_mngr_index_);
85 SSL_CallbackManager* cbmngr = reinterpret_cast<SSL_CallbackManager*> (ex_data);
87 SSL_CertificateCallbackArg arg (cbmngr->context(), cert_ctx);
88 ok = cbmngr->verify_certificate_callback (arg);
91 return ok;
94 int extern_C_passwd_callback (char* buf, int size, int /*rwflag*/, void* user_data)
96 if (user_data == 0)
97 return 0;
99 SSL_CallbackManager* cbmngr = reinterpret_cast<SSL_CallbackManager*> (user_data);
101 ACE_CString pwd;
102 cbmngr->passwd_callback (pwd);
103 if (!pwd.empty ())
105 ACE_OS::strncpy (buf, pwd.c_str (), size);
106 buf[size - 1] = '\0';
107 if (size > ACE_Utils::truncate_cast<int> (pwd.length ()))
108 size = ACE_Utils::truncate_cast<int> (pwd.length ());
110 return size;
112 else
113 return 0;
119 ACE_END_VERSIONED_NAMESPACE_DECL