00001 #include "orbsvcs/SSLIOP/SSLIOP_Factory.h"
00002 #include "orbsvcs/SSLIOP/SSLIOP_Acceptor.h"
00003 #include "orbsvcs/SSLIOP/SSLIOP_Connector.h"
00004 #include "orbsvcs/SSLIOP/SSLIOP_ORBInitializer.h"
00005 #include "ace/OS_NS_strings.h"
00006
00007 #include "orbsvcs/Security/Security_ORBInitializer.h"
00008
00009 #include "tao/debug.h"
00010 #include "tao/ORBInitializer_Registry.h"
00011
00012 #include "ace/SSL/sslconf.h"
00013 #include "ace/SSL/SSL_Context.h"
00014
00015 ACE_RCSID (SSLIOP,
00016 SSLIOP_Factory,
00017 "$Id: SSLIOP_Factory.cpp 77276 2007-02-21 08:26:36Z johnnyw $")
00018
00019
00020
00021
00022 static const unsigned char session_id_context_[] =
00023 "$Id: SSLIOP_Factory.cpp 77276 2007-02-21 08:26:36Z johnnyw $";
00024
00025
00026 static const char * const the_prefix[] = {"iiop", "ssliop"};
00027
00028
00029 static ACE_TCHAR const TAO_PATH_SEPARATOR_STRING[] =
00030 #if defined(ACE_WIN32)
00031 ACE_TEXT (";");
00032 #else
00033 ACE_TEXT (":");
00034 #endif
00035
00036 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00037
00038 namespace TAO
00039 {
00040 namespace SSLIOP
00041 {
00042 static const long ACCEPT_TIMEOUT = 10;
00043
00044 }
00045 }
00046
00047 TAO::SSLIOP::Protocol_Factory::Protocol_Factory (void)
00048 : TAO_Protocol_Factory (IOP::TAG_INTERNET_IOP),
00049 qop_ (::Security::SecQOPIntegrityAndConfidentiality),
00050 timeout_ (TAO::SSLIOP::ACCEPT_TIMEOUT)
00051 {
00052 }
00053
00054 TAO::SSLIOP::Protocol_Factory::~Protocol_Factory (void)
00055 {
00056 }
00057
00058 int
00059 TAO::SSLIOP::Protocol_Factory::match_prefix (const ACE_CString &prefix)
00060 {
00061
00062 return (ACE_OS::strcasecmp (prefix.c_str (), ::the_prefix[0]) == 0)
00063 || (ACE_OS::strcasecmp (prefix.c_str (), ::the_prefix[1]) == 0);
00064 }
00065
00066 const char *
00067 TAO::SSLIOP::Protocol_Factory::prefix (void) const
00068 {
00069
00070
00071
00072
00073 return ::the_prefix[0];
00074 }
00075
00076 char
00077 TAO::SSLIOP::Protocol_Factory::options_delimiter (void) const
00078 {
00079 return '/';
00080 }
00081
00082 TAO_Acceptor *
00083 TAO::SSLIOP::Protocol_Factory::make_acceptor (void)
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 }
00094
00095
00096
00097
00098 int
00099 TAO::SSLIOP::Protocol_Factory::parse_x509_file (char *arg,
00100 char **path)
00101 {
00102 ACE_ASSERT (arg != 0);
00103 ACE_ASSERT (path != 0);
00104
00105 char *lst = 0;
00106 const char *type_name = ACE_OS::strtok_r (arg, ":", &lst);
00107 *path = ACE_OS::strtok_r (0, "", &lst);
00108
00109 if (ACE_OS::strcasecmp (type_name, "ASN1") == 0)
00110 return SSL_FILETYPE_ASN1;
00111
00112 if (ACE_OS::strcasecmp (type_name, "PEM") == 0)
00113 return SSL_FILETYPE_PEM;
00114
00115 return -1;
00116 }
00117
00118
00119 int
00120 TAO::SSLIOP::Protocol_Factory::init (int argc,
00121 char* argv[])
00122 {
00123 char *certificate_path = 0;
00124 char *private_key_path = 0;
00125 char *dhparams_path = 0;
00126 char *ca_file = 0;
00127 char *ca_dir = 0;
00128 char *rand_path = 0;
00129
00130 int certificate_type = -1;
00131 int private_key_type = -1;
00132 int dhparams_type = -1;
00133
00134 int prevdebug = -1;
00135
00136 CSIIOP::AssociationOptions csiv2_target_supports =
00137 CSIIOP::Integrity | CSIIOP::Confidentiality;
00138 CSIIOP::AssociationOptions csiv2_target_requires =
00139 CSIIOP::Integrity | CSIIOP::Confidentiality;
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 ACE_SSL_Context * ssl_ctx = ACE_SSL_Context::instance ();
00150 ACE_ASSERT (ssl_ctx != 0);
00151
00152 size_t session_id_len =
00153 (sizeof session_id_context_ >= SSL_MAX_SSL_SESSION_ID_LENGTH)
00154 ? SSL_MAX_SSL_SESSION_ID_LENGTH
00155 : sizeof session_id_context_;
00156
00157
00158
00159 if( 1 != ::SSL_CTX_set_session_id_context (ssl_ctx->context(),
00160 session_id_context_,
00161 session_id_len))
00162 {
00163 if (TAO_debug_level > 0)
00164 ACE_DEBUG ((LM_ERROR,
00165 ACE_TEXT ("TAO (%P|%t) Unable to set the session id ")
00166 ACE_TEXT ("context to \'%s\'\n"), session_id_context_));
00167
00168 return -1;
00169 }
00170
00171 for (int curarg = 0; curarg != argc; ++curarg)
00172 {
00173 if ((ACE_OS::strcasecmp (argv[curarg],
00174 "-verbose") == 0)
00175 || (ACE_OS::strcasecmp (argv[curarg],
00176 "-v") == 0))
00177 {
00178 if (TAO_debug_level == 0)
00179 {
00180 prevdebug = TAO_debug_level;
00181 TAO_debug_level = 1;
00182 }
00183 }
00184
00185 else if (ACE_OS::strcasecmp (argv[curarg],
00186 "-SSLNoProtection") == 0)
00187 {
00188
00189
00190
00191 if (::SSL_CTX_set_cipher_list (ssl_ctx->context (),
00192 "DEFAULT:eNULL") == 0)
00193 {
00194 if (TAO_debug_level > 0)
00195 ACE_DEBUG ((LM_ERROR,
00196 ACE_TEXT ("TAO (%P|%t) Unable to set eNULL ")
00197 ACE_TEXT ("SSL cipher in SSLIOP ")
00198 ACE_TEXT ("factory.\n")));
00199
00200 return -1;
00201 }
00202
00203
00204
00205
00206
00207
00208 this->qop_ = ::Security::SecQOPNoProtection;
00209
00210 ACE_SET_BITS (csiv2_target_supports,
00211 CSIIOP::NoProtection);
00212
00213 ACE_CLR_BITS (csiv2_target_requires,
00214 CSIIOP::Confidentiality);
00215 }
00216
00217 else if (ACE_OS::strcasecmp (argv[curarg],
00218 "-SSLCertificate") == 0)
00219 {
00220 curarg++;
00221 if (curarg < argc)
00222 {
00223 certificate_type = parse_x509_file (argv[curarg], &certificate_path);
00224 }
00225 }
00226
00227 else if (ACE_OS::strcasecmp (argv[curarg],
00228 "-SSLPrivateKey") == 0)
00229 {
00230 curarg++;
00231 if (curarg < argc)
00232 {
00233 private_key_type = parse_x509_file (argv[curarg], &private_key_path);
00234 }
00235 }
00236
00237 else if (ACE_OS::strcasecmp (argv[curarg],
00238 "-SSLAuthenticate") == 0)
00239 {
00240 curarg++;
00241 if (curarg < argc)
00242 {
00243 int mode = SSL_VERIFY_NONE;
00244 if (ACE_OS::strcasecmp (argv[curarg], "NONE") == 0)
00245 {
00246 mode = SSL_VERIFY_NONE;
00247 }
00248 else if (ACE_OS::strcasecmp (argv[curarg], "SERVER") == 0)
00249 {
00250 mode = SSL_VERIFY_PEER;
00251
00252 ACE_SET_BITS (csiv2_target_supports,
00253 CSIIOP::EstablishTrustInTarget
00254 | CSIIOP::EstablishTrustInClient);
00255 }
00256 else if (ACE_OS::strcasecmp (argv[curarg], "CLIENT") == 0
00257 || ACE_OS::strcasecmp (argv[curarg],
00258 "SERVER_AND_CLIENT") == 0)
00259 {
00260 mode = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
00261
00262 ACE_SET_BITS (csiv2_target_supports,
00263 CSIIOP::EstablishTrustInTarget
00264 | CSIIOP::EstablishTrustInClient);
00265
00266 ACE_SET_BITS (csiv2_target_requires,
00267 CSIIOP::EstablishTrustInClient);
00268 }
00269
00270 ssl_ctx->default_verify_mode (mode);
00271 }
00272 }
00273
00274 else if (ACE_OS::strcasecmp (argv[curarg],
00275 "-SSLAcceptTimeout") == 0)
00276 {
00277 curarg++;
00278 if (curarg < argc)
00279 {
00280 float timeout = 0;
00281
00282 if (sscanf (argv[curarg], "%f", &timeout) != 1
00283 || timeout < 0)
00284 ACE_ERROR_RETURN ((LM_ERROR,
00285 "ERROR: Invalid -SSLAcceptTimeout "
00286 "value: %s.\n",
00287 argv[curarg]),
00288 -1);
00289 else
00290 this->timeout_.set (timeout);
00291 }
00292 }
00293
00294 else if (ACE_OS::strcasecmp (argv[curarg],
00295 "-SSLDHparams") == 0)
00296 {
00297 curarg++;
00298 if (curarg < argc)
00299 {
00300 dhparams_type = parse_x509_file (argv[curarg], &dhparams_path);
00301 }
00302 }
00303
00304 else if (ACE_OS::strcasecmp (argv[curarg],
00305 "-SSLCAfile") == 0)
00306 {
00307 curarg++;
00308 if (curarg < argc)
00309 {
00310 (void) parse_x509_file (argv[curarg], &ca_file);
00311 }
00312 }
00313
00314 else if (ACE_OS::strcasecmp (argv[curarg],
00315 "-SSLCApath") == 0)
00316 {
00317 curarg++;
00318 if (curarg < argc)
00319 {
00320 ca_dir = argv[curarg];
00321 }
00322 }
00323
00324 else if (ACE_OS::strcasecmp (argv[curarg],
00325 "-SSLrand") == 0)
00326 {
00327 curarg++;
00328 if (curarg < argc)
00329 {
00330 rand_path = argv[curarg];
00331 }
00332 }
00333 }
00334
00335
00336
00337 if (rand_path != 0)
00338 {
00339 short errors = 0;
00340 char *file_name = 0;
00341 const char *path = ACE_OS::strtok_r (rand_path,
00342 TAO_PATH_SEPARATOR_STRING,
00343 &file_name);
00344 while ( path != 0)
00345 {
00346 if( -1 == ssl_ctx->seed_file (path, -1))
00347 {
00348 errors++;
00349
00350 if (TAO_debug_level > 0)
00351 ACE_DEBUG ((LM_ERROR,
00352 ACE_TEXT ("TAO (%P|%t) Failed to load ")
00353 ACE_TEXT ("more entropy from <%s>: %m\n"), path));
00354 }
00355 else
00356 {
00357 if (TAO_debug_level > 0)
00358 ACE_DEBUG ((LM_ERROR,
00359 ACE_TEXT ("TAO (%P|%t) Loaded ")
00360 ACE_TEXT ("more entropy from <%s>\n"), path));
00361 }
00362
00363 path = ACE_OS::strtok_r (0, TAO_PATH_SEPARATOR_STRING, &file_name);
00364 }
00365
00366 if (errors > 0)
00367 return -1;
00368 }
00369
00370
00371
00372 if (ca_file != 0 || ca_dir != 0)
00373 {
00374 if (ssl_ctx->load_trusted_ca (ca_file, ca_dir) != 0)
00375 {
00376 if (TAO_debug_level > 0)
00377 ACE_DEBUG ((LM_ERROR,
00378 ACE_TEXT ("TAO (%P|%t) Unable to load ")
00379 ACE_TEXT ("CA certs from %s%s%s\n"),
00380 ((ca_file != 0) ? ca_file : ACE_TEXT ("a file pointed to by ")
00381 ACE_TEXT (ACE_SSL_CERT_FILE_ENV)
00382 ACE_TEXT (" env var (if any)")),
00383 ACE_TEXT (" and "),
00384 ((ca_dir != 0) ? ca_dir : ACE_TEXT ("a directory pointed to by ")
00385 ACE_TEXT (ACE_SSL_CERT_DIR_ENV)
00386 ACE_TEXT (" env var (if any)"))));
00387
00388 return -1;
00389 }
00390 else
00391 {
00392 if (TAO_debug_level > 0)
00393 ACE_DEBUG ((LM_INFO,
00394 ACE_TEXT ("TAO (%P|%t) SSLIOP loaded ")
00395 ACE_TEXT ("Trusted Certificates from %s%s%s\n"),
00396 ((ca_file != 0) ? ca_file : ACE_TEXT ("a file pointed to by ")
00397 ACE_TEXT (ACE_SSL_CERT_FILE_ENV)
00398 ACE_TEXT (" env var (if any)")),
00399 ACE_TEXT (" and "),
00400 ((ca_dir != 0) ? ca_dir : ACE_TEXT ("a directory pointed to by ")
00401 ACE_TEXT (ACE_SSL_CERT_DIR_ENV)
00402 ACE_TEXT (" env var (if any)"))));
00403 }
00404 }
00405
00406
00407
00408
00409
00410 if (dhparams_path == 0)
00411 {
00412
00413
00414
00415 dhparams_path = certificate_path;
00416 dhparams_type = certificate_type;
00417 }
00418
00419 if (dhparams_path != 0)
00420 {
00421 if (ssl_ctx->dh_params (dhparams_path,
00422 dhparams_type) != 0)
00423 {
00424 if (dhparams_path != certificate_path)
00425 {
00426
00427
00428
00429 if (TAO_debug_level > 0)
00430 ACE_DEBUG ((LM_ERROR,
00431 ACE_TEXT ("(%P|%t) SSLIOP_Factory: ")
00432 ACE_TEXT ("unable to set ")
00433 ACE_TEXT ("DH parameters <%s>\n"),
00434 dhparams_path));
00435 return -1;
00436 }
00437 else
00438 {
00439 if (TAO_debug_level > 0)
00440 ACE_DEBUG ((LM_INFO,
00441 ACE_TEXT ("(%P|%t) SSLIOP_Factory: ")
00442 ACE_TEXT ("No DH parameters found in ")
00443 ACE_TEXT ("certificate <%s>; either none ")
00444 ACE_TEXT ("are needed (RSA) or problems ")
00445 ACE_TEXT ("will ensue later.\n"),
00446 dhparams_path));
00447 }
00448 }
00449 else
00450 {
00451 if (TAO_debug_level > 0)
00452 ACE_DEBUG ((LM_INFO,
00453 ACE_TEXT ("(%P|%t) SSLIOP loaded ")
00454 ACE_TEXT ("Diffie-Hellman params ")
00455 ACE_TEXT ("from %s\n"),
00456 dhparams_path));
00457 }
00458 }
00459
00460
00461
00462
00463
00464 if (certificate_path != 0)
00465 {
00466 if (ssl_ctx->certificate (certificate_path,
00467 certificate_type) != 0)
00468 {
00469 if (TAO_debug_level > 0)
00470 ACE_DEBUG ((LM_ERROR,
00471 ACE_TEXT ("TAO (%P|%t) Unable to set ")
00472 ACE_TEXT ("SSL certificate <%s> ")
00473 ACE_TEXT ("in SSLIOP factory.\n"),
00474 certificate_path));
00475
00476 return -1;
00477 }
00478 else
00479 {
00480 if (TAO_debug_level > 0)
00481 ACE_DEBUG ((LM_INFO,
00482 ACE_TEXT ("TAO (%P|%t) SSLIOP loaded ")
00483 ACE_TEXT ("SSL certificate ")
00484 ACE_TEXT ("from %s\n"),
00485 certificate_path));
00486 }
00487 }
00488
00489 if (private_key_path != 0)
00490 {
00491 if (ssl_ctx->private_key (private_key_path, private_key_type) != 0)
00492 {
00493 if (TAO_debug_level > 0)
00494 {
00495 ACE_DEBUG ((LM_ERROR,
00496 ACE_TEXT ("TAO (%P|%t) Unable to set ")
00497 ACE_TEXT ("SSL private key ")
00498 ACE_TEXT ("<%s> in SSLIOP factory.\n"),
00499 private_key_path));
00500 }
00501
00502 return -1;
00503 }
00504 else
00505 {
00506 if (TAO_debug_level > 0)
00507 ACE_DEBUG ((LM_INFO,
00508 ACE_TEXT ("TAO (%P|%t) SSLIOP loaded ")
00509 ACE_TEXT ("Private Key ")
00510 ACE_TEXT ("from %s\n"),
00511 private_key_path));
00512 }
00513 }
00514
00515 if (this->register_orb_initializer (csiv2_target_supports,
00516 csiv2_target_requires) != 0)
00517 return -1;
00518
00519 if (prevdebug != -1)
00520 TAO_debug_level = prevdebug;
00521
00522 return 0;
00523 }
00524
00525 int
00526 TAO::SSLIOP::Protocol_Factory::register_orb_initializer (
00527 CSIIOP::AssociationOptions csiv2_target_supports,
00528 CSIIOP::AssociationOptions csiv2_target_requires)
00529 {
00530 try
00531 {
00532
00533
00534
00535 PortableInterceptor::ORBInitializer_ptr tmp;
00536 ACE_NEW_THROW_EX (tmp,
00537 TAO::Security::ORBInitializer,
00538 CORBA::NO_MEMORY (
00539 CORBA::SystemException::_tao_minor_code (
00540 TAO::VMCID,
00541 ENOMEM),
00542 CORBA::COMPLETED_NO));
00543
00544 PortableInterceptor::ORBInitializer_var initializer = tmp;
00545
00546 PortableInterceptor::register_orb_initializer (initializer.in ());
00547
00548
00549
00550 ACE_NEW_THROW_EX (tmp,
00551 TAO::SSLIOP::ORBInitializer (this->qop_,
00552 csiv2_target_supports,
00553 csiv2_target_requires),
00554 CORBA::NO_MEMORY (
00555 CORBA::SystemException::_tao_minor_code (
00556 TAO::VMCID,
00557 ENOMEM),
00558 CORBA::COMPLETED_NO));
00559
00560
00561 initializer = tmp;
00562
00563 PortableInterceptor::register_orb_initializer (initializer.in ());
00564 }
00565 catch (const CORBA::Exception& ex)
00566 {
00567 ex._tao_print_exception (
00568 "Unable to register SSLIOP ORB initializer.");
00569 return -1;
00570 }
00571
00572 return 0;
00573 }
00574
00575
00576 TAO_Connector *
00577 TAO::SSLIOP::Protocol_Factory::make_connector (void)
00578 {
00579 TAO_Connector *connector = 0;
00580
00581 ACE_NEW_RETURN (connector,
00582 TAO::SSLIOP::Connector (this->qop_),
00583 0);
00584 return connector;
00585 }
00586
00587 int
00588 TAO::SSLIOP::Protocol_Factory::requires_explicit_endpoint (void) const
00589 {
00590 return 0;
00591 }
00592
00593 TAO_END_VERSIONED_NAMESPACE_DECL
00594
00595 ACE_STATIC_SVC_DEFINE (TAO_SSLIOP_Protocol_Factory,
00596 ACE_TEXT ("SSLIOP_Factory"),
00597 ACE_SVC_OBJ_T,
00598 &ACE_SVC_NAME (TAO_SSLIOP_Protocol_Factory),
00599 ACE_Service_Type::DELETE_THIS
00600 | ACE_Service_Type::DELETE_OBJ,
00601 0)
00602
00603 ACE_FACTORY_DEFINE (TAO_SSLIOP, TAO_SSLIOP_Protocol_Factory)