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 "SSLIOP_Factory.cpp,v 1.40 2006/03/14 06:14:35 jtc Exp")
00018
00019
00020
00021
00022 static const unsigned char session_id_context_[] =
00023 "SSLIOP_Factory.cpp,v 1.40 2006/03/14 06:14:35 jtc Exp";
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,
00492 private_key_type) != 0)
00493 {
00494 if (TAO_debug_level > 0)
00495 {
00496 ACE_DEBUG ((LM_ERROR,
00497 ACE_TEXT ("TAO (%P|%t) Unable to set ")
00498 ACE_TEXT ("SSL private key ")
00499 ACE_TEXT ("<%s> in SSLIOP factory.\n"),
00500 private_key_path));
00501 }
00502
00503 return -1;
00504 }
00505 else
00506 {
00507 if (TAO_debug_level > 0)
00508 ACE_DEBUG ((LM_INFO,
00509 ACE_TEXT ("TAO (%P|%t) SSLIOP loaded ")
00510 ACE_TEXT ("Private Key ")
00511 ACE_TEXT ("from %s\n"),
00512 private_key_path));
00513 }
00514 }
00515
00516 if (this->register_orb_initializer (csiv2_target_supports,
00517 csiv2_target_requires) != 0)
00518 return -1;
00519
00520 if (prevdebug != -1)
00521 TAO_debug_level = prevdebug;
00522
00523 return 0;
00524 }
00525
00526 int
00527 TAO::SSLIOP::Protocol_Factory::register_orb_initializer (
00528 CSIIOP::AssociationOptions csiv2_target_supports,
00529 CSIIOP::AssociationOptions csiv2_target_requires)
00530 {
00531 ACE_DECLARE_NEW_CORBA_ENV;
00532 ACE_TRY
00533 {
00534
00535
00536
00537 PortableInterceptor::ORBInitializer_ptr tmp;
00538 ACE_NEW_THROW_EX (tmp,
00539 TAO::Security::ORBInitializer,
00540 CORBA::NO_MEMORY (
00541 CORBA::SystemException::_tao_minor_code (
00542 TAO::VMCID,
00543 ENOMEM),
00544 CORBA::COMPLETED_NO));
00545 ACE_TRY_CHECK;
00546
00547 PortableInterceptor::ORBInitializer_var initializer = tmp;
00548
00549 PortableInterceptor::register_orb_initializer (initializer.in ()
00550 ACE_ENV_ARG_PARAMETER);
00551 ACE_TRY_CHECK;
00552
00553
00554
00555 ACE_NEW_THROW_EX (tmp,
00556 TAO::SSLIOP::ORBInitializer (this->qop_,
00557 csiv2_target_supports,
00558 csiv2_target_requires),
00559 CORBA::NO_MEMORY (
00560 CORBA::SystemException::_tao_minor_code (
00561 TAO::VMCID,
00562 ENOMEM),
00563 CORBA::COMPLETED_NO));
00564 ACE_TRY_CHECK;
00565
00566
00567 initializer = tmp;
00568
00569 PortableInterceptor::register_orb_initializer (initializer.in ()
00570 ACE_ENV_ARG_PARAMETER);
00571 ACE_TRY_CHECK;
00572 }
00573 ACE_CATCHANY
00574 {
00575 ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
00576 "Unable to register SSLIOP ORB "
00577 "initializer.");
00578 return -1;
00579 }
00580 ACE_ENDTRY;
00581 ACE_CHECK_RETURN (-1);
00582
00583 return 0;
00584 }
00585
00586
00587 TAO_Connector *
00588 TAO::SSLIOP::Protocol_Factory::make_connector (void)
00589 {
00590 TAO_Connector *connector = 0;
00591
00592 ACE_NEW_RETURN (connector,
00593 TAO::SSLIOP::Connector (this->qop_),
00594 0);
00595 return connector;
00596 }
00597
00598 int
00599 TAO::SSLIOP::Protocol_Factory::requires_explicit_endpoint (void) const
00600 {
00601 return 0;
00602 }
00603
00604 TAO_END_VERSIONED_NAMESPACE_DECL
00605
00606 ACE_STATIC_SVC_DEFINE (TAO_SSLIOP_Protocol_Factory,
00607 ACE_TEXT ("SSLIOP_Factory"),
00608 ACE_SVC_OBJ_T,
00609 &ACE_SVC_NAME (TAO_SSLIOP_Protocol_Factory),
00610 ACE_Service_Type::DELETE_THIS
00611 | ACE_Service_Type::DELETE_OBJ,
00612 0)
00613
00614 ACE_FACTORY_DEFINE (TAO_SSLIOP, TAO_SSLIOP_Protocol_Factory)