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 80431 2008-01-15 19:06:41Z johnnyw $")
00018
00019
00020
00021
00022 static const unsigned char session_id_context_[] =
00023 "$Id: SSLIOP_Factory.cpp 80431 2008-01-15 19:06:41Z 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, char **path)
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 }
00116
00117
00118 int
00119 TAO::SSLIOP::Protocol_Factory::init (int argc, char* argv[])
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
00140
00141
00142
00143
00144
00145
00146
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
00156
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
00187
00188
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
00202
00203
00204
00205
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
00334
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
00369
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
00405
00406
00407
00408 if (dhparams_path == 0)
00409 {
00410
00411
00412
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
00425
00426
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
00459
00460
00461
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 }
00522
00523 int
00524 TAO::SSLIOP::Protocol_Factory::register_orb_initializer (
00525 CSIIOP::AssociationOptions csiv2_target_supports,
00526 CSIIOP::AssociationOptions csiv2_target_requires)
00527 {
00528 try
00529 {
00530
00531
00532
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
00547
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
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 }
00572
00573
00574 TAO_Connector *
00575 TAO::SSLIOP::Protocol_Factory::make_connector (void)
00576 {
00577 TAO_Connector *connector = 0;
00578
00579 ACE_NEW_RETURN (connector,
00580 TAO::SSLIOP::Connector (this->qop_),
00581 0);
00582 return connector;
00583 }
00584
00585 int
00586 TAO::SSLIOP::Protocol_Factory::requires_explicit_endpoint (void) const
00587 {
00588 return 0;
00589 }
00590
00591 TAO_END_VERSIONED_NAMESPACE_DECL
00592
00593 ACE_STATIC_SVC_DEFINE (TAO_SSLIOP_Protocol_Factory,
00594 ACE_TEXT ("SSLIOP_Factory"),
00595 ACE_SVC_OBJ_T,
00596 &ACE_SVC_NAME (TAO_SSLIOP_Protocol_Factory),
00597 ACE_Service_Type::DELETE_THIS
00598 | ACE_Service_Type::DELETE_OBJ,
00599 0)
00600
00601 ACE_FACTORY_DEFINE (TAO_SSLIOP, TAO_SSLIOP_Protocol_Factory)