#include <SSLIOP_Factory.h>
Inheritance diagram for TAO::SSLIOP::Protocol_Factory:
Public Member Functions | |
Protocol_Factory (void) | |
Constructor. | |
virtual | ~Protocol_Factory (void) |
Destructor. | |
virtual int | init (int argc, char *argv[]) |
Dynamic linking hook. | |
virtual int | match_prefix (const ACE_CString &prefix) |
Verify prefix is a match. | |
virtual const char * | prefix (void) const |
Returns the prefix used by the protocol. | |
virtual char | options_delimiter (void) const |
virtual TAO_Acceptor * | make_acceptor (void) |
virtual TAO_Connector * | make_connector (void) |
virtual int | requires_explicit_endpoint (void) const |
Private Member Functions | |
int | register_orb_initializer (CSIIOP::AssociationOptions csiv2_target_supports, CSIIOP::AssociationOptions csiv2_target_requires) |
Create and register the SSLIOP ORB initializer. | |
Static Private Member Functions | |
static int | parse_x509_file (char *arg, char **path) |
Private Attributes | |
::Security::QOP | qop_ |
ACE_Time_Value | timeout_ |
The accept() timeout. |
This class implements the SSLIOP-specific protocol factory implementation for use in TAO's pluggable protocols framework.
Definition at line 54 of file SSLIOP_Factory.h.
TAO::SSLIOP::Protocol_Factory::Protocol_Factory | ( | void | ) |
Constructor.
Definition at line 47 of file SSLIOP_Factory.cpp.
00048 : TAO_Protocol_Factory (IOP::TAG_INTERNET_IOP), 00049 qop_ (::Security::SecQOPIntegrityAndConfidentiality), 00050 timeout_ (TAO::SSLIOP::ACCEPT_TIMEOUT) 00051 { 00052 }
TAO::SSLIOP::Protocol_Factory::~Protocol_Factory | ( | void | ) | [virtual] |
int TAO::SSLIOP::Protocol_Factory::init | ( | int | argc, | |
char * | argv[] | |||
) | [virtual] |
Dynamic linking hook.
Implements TAO_Protocol_Factory.
Definition at line 119 of file SSLIOP_Factory.cpp.
References ACE_ASSERT, ACE_CLR_BITS, ACE_DEBUG, ACE_ERROR, ACE_ERROR_RETURN, ACE_SET_BITS, ACE_TEXT(), Confidentiality, EstablishTrustInClient, EstablishTrustInTarget, Integrity, LM_DEBUG, LM_ERROR, LM_INFO, NoProtection, parse_x509_file(), qop_, SecQOPNoProtection, session_id_context_, ACE_Time_Value::set(), ACE_OS::strcasecmp(), ACE_OS::strtok_r(), TAO_debug_level, TAO_PATH_SEPARATOR_STRING, and timeout_.
00120 { 00121 char *certificate_path = 0; 00122 char *private_key_path = 0; 00123 char *dhparams_path = 0; 00124 char *ca_file = 0; 00125 char *ca_dir = 0; 00126 char *rand_path = 0; 00127 00128 int certificate_type = -1; 00129 int private_key_type = -1; 00130 int dhparams_type = -1; 00131 00132 int prevdebug = -1; 00133 00134 CSIIOP::AssociationOptions csiv2_target_supports = 00135 CSIIOP::Integrity | CSIIOP::Confidentiality; 00136 CSIIOP::AssociationOptions csiv2_target_requires = 00137 CSIIOP::Integrity | CSIIOP::Confidentiality; 00138 00139 // Force the Singleton instance to be initialized/instantiated. 00140 // Some SSLIOP option combinations below will result in the 00141 // Singleton instance never being initialized. In that case, 00142 // problems may occur later on due to lack of initialization of the 00143 // underlying SSL library (e.g. OpenSSL), which occurs when an 00144 // ACE_SSL_Context is instantiated. 00145 00146 // The code is cleaner this way anyway. 00147 ACE_SSL_Context * ssl_ctx = ACE_SSL_Context::instance (); 00148 ACE_ASSERT (ssl_ctx != 0); 00149 00150 size_t session_id_len = 00151 (sizeof session_id_context_ >= SSL_MAX_SSL_SESSION_ID_LENGTH) 00152 ? SSL_MAX_SSL_SESSION_ID_LENGTH 00153 : sizeof session_id_context_; 00154 00155 // Note that this function returns 1, if the operation succeded. 00156 // See SSL_CTX_set_session_id_context(3) 00157 if( 1 != ::SSL_CTX_set_session_id_context (ssl_ctx->context(), 00158 session_id_context_, 00159 session_id_len)) 00160 { 00161 if (TAO_debug_level > 0) 00162 ACE_ERROR ((LM_ERROR, 00163 ACE_TEXT ("TAO (%P|%t) Unable to set the session id ") 00164 ACE_TEXT ("context to \'%s\'\n"), session_id_context_)); 00165 00166 return -1; 00167 } 00168 00169 for (int curarg = 0; curarg != argc; ++curarg) 00170 { 00171 if ((ACE_OS::strcasecmp (argv[curarg], 00172 "-verbose") == 0) 00173 || (ACE_OS::strcasecmp (argv[curarg], 00174 "-v") == 0)) 00175 { 00176 if (TAO_debug_level == 0) 00177 { 00178 prevdebug = TAO_debug_level; 00179 TAO_debug_level = 1; 00180 } 00181 } 00182 00183 else if (ACE_OS::strcasecmp (argv[curarg], 00184 "-SSLNoProtection") == 0) 00185 { 00186 // Enable the eNULL cipher. Note that enabling the "eNULL" 00187 // cipher only disables encryption. However, certificate 00188 // exchanges will still occur. 00189 if (::SSL_CTX_set_cipher_list (ssl_ctx->context (), 00190 "DEFAULT:eNULL") == 0) 00191 { 00192 if (TAO_debug_level > 0) 00193 ACE_DEBUG ((LM_ERROR, 00194 ACE_TEXT ("TAO (%P|%t) Unable to set eNULL ") 00195 ACE_TEXT ("SSL cipher in SSLIOP ") 00196 ACE_TEXT ("factory.\n"))); 00197 00198 return -1; 00199 } 00200 00201 // This does not disable secure invocations on the server 00202 // side. It merely enables insecure ones. On the client 00203 // side, secure invocations will be disabled unless 00204 // overridden by a SecurityLevel2::QOPPolicy in the object 00205 // reference. 00206 this->qop_ = ::Security::SecQOPNoProtection; 00207 00208 ACE_SET_BITS (csiv2_target_supports, 00209 CSIIOP::NoProtection); 00210 00211 ACE_CLR_BITS (csiv2_target_requires, 00212 CSIIOP::Confidentiality); 00213 } 00214 00215 else if (ACE_OS::strcasecmp (argv[curarg], 00216 "-SSLCertificate") == 0) 00217 { 00218 curarg++; 00219 if (curarg < argc) 00220 { 00221 certificate_type = parse_x509_file (argv[curarg], &certificate_path); 00222 } 00223 } 00224 00225 else if (ACE_OS::strcasecmp (argv[curarg], 00226 "-SSLPrivateKey") == 0) 00227 { 00228 curarg++; 00229 if (curarg < argc) 00230 { 00231 private_key_type = parse_x509_file (argv[curarg], &private_key_path); 00232 } 00233 } 00234 00235 else if (ACE_OS::strcasecmp (argv[curarg], 00236 "-SSLAuthenticate") == 0) 00237 { 00238 curarg++; 00239 if (curarg < argc) 00240 { 00241 int mode = SSL_VERIFY_NONE; 00242 if (ACE_OS::strcasecmp (argv[curarg], "NONE") == 0) 00243 { 00244 mode = SSL_VERIFY_NONE; 00245 } 00246 else if (ACE_OS::strcasecmp (argv[curarg], "SERVER") == 0) 00247 { 00248 mode = SSL_VERIFY_PEER; 00249 00250 ACE_SET_BITS (csiv2_target_supports, 00251 CSIIOP::EstablishTrustInTarget 00252 | CSIIOP::EstablishTrustInClient); 00253 } 00254 else if (ACE_OS::strcasecmp (argv[curarg], "CLIENT") == 0 00255 || ACE_OS::strcasecmp (argv[curarg], 00256 "SERVER_AND_CLIENT") == 0) 00257 { 00258 mode = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT; 00259 00260 ACE_SET_BITS (csiv2_target_supports, 00261 CSIIOP::EstablishTrustInTarget 00262 | CSIIOP::EstablishTrustInClient); 00263 00264 ACE_SET_BITS (csiv2_target_requires, 00265 CSIIOP::EstablishTrustInClient); 00266 } 00267 00268 ssl_ctx->default_verify_mode (mode); 00269 } 00270 } 00271 00272 else if (ACE_OS::strcasecmp (argv[curarg], 00273 "-SSLAcceptTimeout") == 0) 00274 { 00275 curarg++; 00276 if (curarg < argc) 00277 { 00278 float timeout = 0; 00279 00280 if (sscanf (argv[curarg], "%f", &timeout) != 1 00281 || timeout < 0) 00282 ACE_ERROR_RETURN ((LM_ERROR, 00283 "ERROR: Invalid -SSLAcceptTimeout " 00284 "value: %s.\n", 00285 argv[curarg]), 00286 -1); 00287 else 00288 this->timeout_.set (timeout); 00289 } 00290 } 00291 00292 else if (ACE_OS::strcasecmp (argv[curarg], 00293 "-SSLDHparams") == 0) 00294 { 00295 curarg++; 00296 if (curarg < argc) 00297 { 00298 dhparams_type = parse_x509_file (argv[curarg], &dhparams_path); 00299 } 00300 } 00301 00302 else if (ACE_OS::strcasecmp (argv[curarg], 00303 "-SSLCAfile") == 0) 00304 { 00305 curarg++; 00306 if (curarg < argc) 00307 { 00308 (void) parse_x509_file (argv[curarg], &ca_file); 00309 } 00310 } 00311 00312 else if (ACE_OS::strcasecmp (argv[curarg], 00313 "-SSLCApath") == 0) 00314 { 00315 curarg++; 00316 if (curarg < argc) 00317 { 00318 ca_dir = argv[curarg]; 00319 } 00320 } 00321 00322 else if (ACE_OS::strcasecmp (argv[curarg], 00323 "-SSLrand") == 0) 00324 { 00325 curarg++; 00326 if (curarg < argc) 00327 { 00328 rand_path = argv[curarg]; 00329 } 00330 } 00331 } 00332 00333 // Load some (more) entropy from the user specified sources 00334 // in addition to what's pointed to by ACE_SSL_RAND_FILE_ENV 00335 if (rand_path != 0) 00336 { 00337 short errors = 0; 00338 char *file_name = 0; 00339 const char *path = ACE_OS::strtok_r (rand_path, 00340 TAO_PATH_SEPARATOR_STRING, 00341 &file_name); 00342 while ( path != 0) 00343 { 00344 if( -1 == ssl_ctx->seed_file (path, -1)) 00345 { 00346 ++errors; 00347 00348 if (TAO_debug_level > 0) 00349 ACE_ERROR ((LM_ERROR, 00350 ACE_TEXT ("TAO (%P|%t) Failed to load ") 00351 ACE_TEXT ("more entropy from <%s>: %m\n"), path)); 00352 } 00353 else 00354 { 00355 if (TAO_debug_level > 0) 00356 ACE_DEBUG ((LM_DEBUG, 00357 ACE_TEXT ("TAO (%P|%t) Loaded ") 00358 ACE_TEXT ("more entropy from <%s>\n"), path)); 00359 } 00360 00361 path = ACE_OS::strtok_r (0, TAO_PATH_SEPARATOR_STRING, &file_name); 00362 } 00363 00364 if (errors > 0) 00365 return -1; 00366 } 00367 00368 // Load any trusted certificates explicitely rather than relying on 00369 // previously set SSL_CERT_FILE and/or SSL_CERT_PATH environment variable 00370 if (ca_file != 0 || ca_dir != 0) 00371 { 00372 if (ssl_ctx->load_trusted_ca (ca_file, ca_dir) != 0) 00373 { 00374 if (TAO_debug_level > 0) 00375 ACE_ERROR ((LM_ERROR, 00376 ACE_TEXT ("TAO (%P|%t) Unable to load ") 00377 ACE_TEXT ("CA certs from %s%s%s\n"), 00378 ((ca_file != 0) ? ca_file : ACE_TEXT ("a file pointed to by ") 00379 ACE_TEXT (ACE_SSL_CERT_FILE_ENV) 00380 ACE_TEXT (" env var (if any)")), 00381 ACE_TEXT (" and "), 00382 ((ca_dir != 0) ? ca_dir : ACE_TEXT ("a directory pointed to by ") 00383 ACE_TEXT (ACE_SSL_CERT_DIR_ENV) 00384 ACE_TEXT (" env var (if any)")))); 00385 00386 return -1; 00387 } 00388 else 00389 { 00390 if (TAO_debug_level > 0) 00391 ACE_DEBUG ((LM_INFO, 00392 ACE_TEXT ("TAO (%P|%t) SSLIOP loaded ") 00393 ACE_TEXT ("Trusted Certificates from %s%s%s\n"), 00394 ((ca_file != 0) ? ca_file : ACE_TEXT ("a file pointed to by ") 00395 ACE_TEXT (ACE_SSL_CERT_FILE_ENV) 00396 ACE_TEXT (" env var (if any)")), 00397 ACE_TEXT (" and "), 00398 ((ca_dir != 0) ? ca_dir : ACE_TEXT ("a directory pointed to by ") 00399 ACE_TEXT (ACE_SSL_CERT_DIR_ENV) 00400 ACE_TEXT (" env var (if any)")))); 00401 } 00402 } 00403 00404 // Load in the DH params. If there was a file explicitly specified, 00405 // then we do that here, otherwise we load them in from the cert file. 00406 // Note that we only do this on the server side, I think so we might 00407 // need to defer this 'til later in the acceptor or something... 00408 if (dhparams_path == 0) 00409 { 00410 // If the user didn't explicitly specify a DH parameters file, we 00411 // also might find it concatenated in the certificate file. 00412 // So, we set the dhparams to that if it wasn't explicitly set. 00413 dhparams_path = certificate_path; 00414 dhparams_type = certificate_type; 00415 } 00416 00417 if (dhparams_path != 0) 00418 { 00419 if (ssl_ctx->dh_params (dhparams_path, 00420 dhparams_type) != 0) 00421 { 00422 if (dhparams_path != certificate_path) 00423 { 00424 // We only want to fail catastrophically if the user specified 00425 // a dh parameter file and we were unable to actually find it 00426 // and load from it. 00427 if (TAO_debug_level > 0) 00428 ACE_ERROR ((LM_ERROR, 00429 ACE_TEXT ("(%P|%t) SSLIOP_Factory: ") 00430 ACE_TEXT ("unable to set ") 00431 ACE_TEXT ("DH parameters <%s>\n"), 00432 dhparams_path)); 00433 return -1; 00434 } 00435 else 00436 { 00437 if (TAO_debug_level > 0) 00438 ACE_DEBUG ((LM_INFO, 00439 ACE_TEXT ("(%P|%t) SSLIOP_Factory: ") 00440 ACE_TEXT ("No DH parameters found in ") 00441 ACE_TEXT ("certificate <%s>; either none ") 00442 ACE_TEXT ("are needed (RSA) or problems ") 00443 ACE_TEXT ("will ensue later.\n"), 00444 dhparams_path)); 00445 } 00446 } 00447 else 00448 { 00449 if (TAO_debug_level > 0) 00450 ACE_DEBUG ((LM_INFO, 00451 ACE_TEXT ("(%P|%t) SSLIOP loaded ") 00452 ACE_TEXT ("Diffie-Hellman params ") 00453 ACE_TEXT ("from %s\n"), 00454 dhparams_path)); 00455 } 00456 } 00457 00458 // The certificate must be set before the private key since the 00459 // ACE_SSL_Context attempts to check the private key for 00460 // consistency. That check requires the certificate to be available 00461 // in the underlying SSL_CTX. 00462 if (certificate_path != 0) 00463 { 00464 if (ssl_ctx->certificate (certificate_path, 00465 certificate_type) != 0) 00466 { 00467 if (TAO_debug_level > 0) 00468 ACE_ERROR ((LM_ERROR, 00469 ACE_TEXT ("TAO (%P|%t) Unable to set ") 00470 ACE_TEXT ("SSL certificate <%s> ") 00471 ACE_TEXT ("in SSLIOP factory.\n"), 00472 certificate_path)); 00473 00474 return -1; 00475 } 00476 else 00477 { 00478 if (TAO_debug_level > 0) 00479 ACE_DEBUG ((LM_INFO, 00480 ACE_TEXT ("TAO (%P|%t) SSLIOP loaded ") 00481 ACE_TEXT ("SSL certificate ") 00482 ACE_TEXT ("from %s\n"), 00483 certificate_path)); 00484 } 00485 } 00486 00487 if (private_key_path != 0) 00488 { 00489 if (ssl_ctx->private_key (private_key_path, private_key_type) != 0) 00490 { 00491 if (TAO_debug_level > 0) 00492 { 00493 ACE_ERROR ((LM_ERROR, 00494 ACE_TEXT ("TAO (%P|%t) Unable to set ") 00495 ACE_TEXT ("SSL private key ") 00496 ACE_TEXT ("<%s> in SSLIOP factory.\n"), 00497 private_key_path)); 00498 } 00499 00500 return -1; 00501 } 00502 else 00503 { 00504 if (TAO_debug_level > 0) 00505 ACE_DEBUG ((LM_INFO, 00506 ACE_TEXT ("TAO (%P|%t) SSLIOP loaded ") 00507 ACE_TEXT ("Private Key ") 00508 ACE_TEXT ("from %s\n"), 00509 private_key_path)); 00510 } 00511 } 00512 00513 if (this->register_orb_initializer (csiv2_target_supports, 00514 csiv2_target_requires) != 0) 00515 return -1; 00516 00517 if (prevdebug != -1) 00518 TAO_debug_level = prevdebug; 00519 00520 return 0; 00521 }
TAO_Acceptor * TAO::SSLIOP::Protocol_Factory::make_acceptor | ( | void | ) | [virtual] |
Implements TAO_Protocol_Factory.
Definition at line 83 of file SSLIOP_Factory.cpp.
References ACE_NEW_RETURN.
00084 { 00085 TAO_Acceptor *acceptor = 0; 00086 00087 ACE_NEW_RETURN (acceptor, 00088 TAO::SSLIOP::Acceptor (this->qop_, 00089 this->timeout_), 00090 0); 00091 00092 return acceptor; 00093 }
TAO_Connector * TAO::SSLIOP::Protocol_Factory::make_connector | ( | void | ) | [virtual] |
Implements TAO_Protocol_Factory.
Definition at line 575 of file SSLIOP_Factory.cpp.
References ACE_NEW_RETURN.
00576 { 00577 TAO_Connector *connector = 0; 00578 00579 ACE_NEW_RETURN (connector, 00580 TAO::SSLIOP::Connector (this->qop_), 00581 0); 00582 return connector; 00583 }
int TAO::SSLIOP::Protocol_Factory::match_prefix | ( | const ACE_CString & | prefix | ) | [virtual] |
Verify prefix is a match.
Implements TAO_Protocol_Factory.
Definition at line 59 of file SSLIOP_Factory.cpp.
References prefix(), ACE_OS::strcasecmp(), and the_prefix.
00060 { 00061 // Check for the proper prefix for this protocol. 00062 return (ACE_OS::strcasecmp (prefix.c_str (), ::the_prefix[0]) == 0) 00063 || (ACE_OS::strcasecmp (prefix.c_str (), ::the_prefix[1]) == 0); 00064 }
char TAO::SSLIOP::Protocol_Factory::options_delimiter | ( | void | ) | const [virtual] |
Return the character used to mark where an endpoint ends and where its options begin.
Implements TAO_Protocol_Factory.
Definition at line 77 of file SSLIOP_Factory.cpp.
int TAO::SSLIOP::Protocol_Factory::parse_x509_file | ( | char * | arg, | |
char ** | path | |||
) | [static, private] |
Parse an X509 file path, which is expected to looks like: <X509Path> ::= <Prefix> ':' <Path> <Prefix> ::= 'PEM' | 'ASN1' <Path> ::= any-string Returns either SSL_FILETYPE_ASN1, SSL_FILETYPE_PEM or -1 if the prefix can not be recognized. The *path will point to the part of the original buffer, after the initial ':', or will contain 0, if no path was specified.
Beware: This function modifies the buffer pointed to by arg!
Definition at line 99 of file SSLIOP_Factory.cpp.
References ACE_ASSERT, ACE_OS::strcasecmp(), and ACE_OS::strtok_r().
Referenced by init().
00100 { 00101 ACE_ASSERT (arg != 0); 00102 ACE_ASSERT (path != 0); 00103 00104 char *lst = 0; 00105 const char *type_name = ACE_OS::strtok_r (arg, ":", &lst); 00106 *path = ACE_OS::strtok_r (0, "", &lst); 00107 00108 if (ACE_OS::strcasecmp (type_name, "ASN1") == 0) 00109 return SSL_FILETYPE_ASN1; 00110 00111 if (ACE_OS::strcasecmp (type_name, "PEM") == 0) 00112 return SSL_FILETYPE_PEM; 00113 00114 return -1; 00115 }
const char * TAO::SSLIOP::Protocol_Factory::prefix | ( | void | ) | const [virtual] |
Returns the prefix used by the protocol.
Implements TAO_Protocol_Factory.
Definition at line 67 of file SSLIOP_Factory.cpp.
References the_prefix.
Referenced by match_prefix().
00068 { 00069 // Note: This method doesn't seem to be used anywhere. Moreover, 00070 // keeping it may make things more confusing - a Factory can 00071 // well be handling multiple protocol prefixes, not just one! 00072 // Shouldn't it be deprecated? 00073 return ::the_prefix[0]; 00074 }
int TAO::SSLIOP::Protocol_Factory::register_orb_initializer | ( | CSIIOP::AssociationOptions | csiv2_target_supports, | |
CSIIOP::AssociationOptions | csiv2_target_requires | |||
) | [private] |
Create and register the SSLIOP ORB initializer.
Definition at line 524 of file SSLIOP_Factory.cpp.
References CORBA::SystemException::_tao_minor_code(), CORBA::Exception::_tao_print_exception(), ACE_NEW_THROW_EX, CORBA::COMPLETED_NO, PortableInterceptor::register_orb_initializer(), and TAO::VMCID.
00527 { 00528 try 00529 { 00530 // @todo: This hard-coding should be fixed once SECIOP is 00531 // supported. 00532 // Register the Security ORB initializer. 00533 PortableInterceptor::ORBInitializer_ptr tmp; 00534 ACE_NEW_THROW_EX (tmp, 00535 TAO::Security::ORBInitializer, 00536 CORBA::NO_MEMORY ( 00537 CORBA::SystemException::_tao_minor_code ( 00538 TAO::VMCID, 00539 ENOMEM), 00540 CORBA::COMPLETED_NO)); 00541 00542 PortableInterceptor::ORBInitializer_var initializer = tmp; 00543 00544 PortableInterceptor::register_orb_initializer (initializer.in ()); 00545 00546 // Register the SSLIOP ORB initializer. 00547 // PortableInterceptor::ORBInitializer_ptr tmp; 00548 ACE_NEW_THROW_EX (tmp, 00549 TAO::SSLIOP::ORBInitializer (this->qop_, 00550 csiv2_target_supports, 00551 csiv2_target_requires), 00552 CORBA::NO_MEMORY ( 00553 CORBA::SystemException::_tao_minor_code ( 00554 TAO::VMCID, 00555 ENOMEM), 00556 CORBA::COMPLETED_NO)); 00557 00558 //PortableInterceptor::ORBInitializer_var initializer = tmp; 00559 initializer = tmp; 00560 00561 PortableInterceptor::register_orb_initializer (initializer.in ()); 00562 } 00563 catch (const CORBA::Exception& ex) 00564 { 00565 ex._tao_print_exception ( 00566 "Unable to register SSLIOP ORB initializer."); 00567 return -1; 00568 } 00569 00570 return 0; 00571 }
int TAO::SSLIOP::Protocol_Factory::requires_explicit_endpoint | ( | void | ) | const [virtual] |
::Security::QOP TAO::SSLIOP::Protocol_Factory::qop_ [private] |
Default quality-of-protection settings for the SSLIOP pluggable protocol.
Definition at line 108 of file SSLIOP_Factory.h.
Referenced by init().
The accept() timeout.
This timeout includes the overall time to complete the SSL handshake. This includes both the TCP handshake and the SSL handshake.
Definition at line 116 of file SSLIOP_Factory.h.
Referenced by init().