00001
00002
00003
00004
00005
00006
00007
00008 #include "DCPS/DdsDcps_pch.h"
00009 #include "SecurityRegistry.h"
00010 #include "SecurityConfig.h"
00011 #include "dds/DCPS/transport/framework/EntryExit.h"
00012 #include "dds/DCPS/Util.h"
00013 #include "dds/DCPS/Service_Participant.h"
00014 #include "dds/DCPS/EntityImpl.h"
00015 #include "dds/DCPS/ConfigUtils.h"
00016 #include "dds/DCPS/SafetyProfileStreams.h"
00017 #include "dds/DCPS/DomainParticipantImpl.h"
00018
00019 #include "ace/Singleton.h"
00020 #include "ace/OS_NS_strings.h"
00021 #include "ace/Service_Config.h"
00022
00023 OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL
00024
00025 namespace OpenDDS {
00026 namespace Security {
00027
00028 const OPENDDS_STRING SecurityRegistry::DEFAULT_CONFIG_NAME("_OPENDDS_DEFAULT_CONFIG");
00029 const OPENDDS_STRING SecurityRegistry::DEFAULT_INST_PREFIX("_OPENDDS_");
00030 const OPENDDS_STRING SecurityRegistry::DEFAULT_PLUGIN_NAME("BuiltIn");
00031 const OPENDDS_STRING SecurityRegistry::SECURITY_SECTION_NAME("security");
00032 const OPENDDS_STRING SecurityRegistry::ACCESS_CTRL_PLUGIN_NAME("access_ctrl_plugin");
00033 const OPENDDS_STRING SecurityRegistry::AUTHENTICATION_PLUGIN_NAME("auth_plugin");
00034 const OPENDDS_STRING SecurityRegistry::CRYPTO_PLUGIN_NAME("crypto_plugin");
00035
00036
00037 SecurityRegistry::SecurityConfigEntry::SecurityConfigEntry(const OPENDDS_STRING& entryName)
00038 : entry_name_(entryName)
00039 , auth_name_(DEFAULT_PLUGIN_NAME)
00040 , access_ctrl_name_(DEFAULT_PLUGIN_NAME)
00041 , crypto_name_(DEFAULT_PLUGIN_NAME)
00042 {
00043 }
00044
00045 SecurityRegistry::~SecurityRegistry()
00046 {
00047 DBG_ENTRY_LVL("SecurityRegistry", "~SecurityRegistry", 6);
00048 release();
00049 }
00050
00051 SecurityRegistry::SecurityConfigEntry::~SecurityConfigEntry()
00052 {
00053 }
00054
00055 void
00056 SecurityRegistry::SecurityConfigEntry::add_property(const OPENDDS_STRING& name, const OPENDDS_STRING& value)
00057 {
00058
00059 static const OPENDDS_STRING AUTH_CONFIG_PROP_NAME("auth_config");
00060 static const OPENDDS_STRING ACCESS_CTRL_CONFIG_PROP_NAME("access_ctrl_config");
00061 static const OPENDDS_STRING CRYPTO_CONFIG_PROP_NAME("crypto_config");
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 properties_.push_back(std::make_pair(name, value));
00074
00075 }
00076
00077
00078 SecurityRegistry*
00079 SecurityRegistry::instance()
00080 {
00081 return ACE_Unmanaged_Singleton<SecurityRegistry, ACE_Recursive_Thread_Mutex>::instance();
00082 }
00083
00084 void
00085 SecurityRegistry::close()
00086 {
00087 ACE_Unmanaged_Singleton<SecurityRegistry, ACE_Recursive_Thread_Mutex>::close();
00088 }
00089
00090 SecurityRegistry::SecurityRegistry()
00091 {
00092 DBG_ENTRY_LVL("SecurityRegistry", "SecurityRegistry", 6);
00093
00094 lib_directive_map_[DEFAULT_PLUGIN_NAME] = "dynamic OpenDDS_Security Service_Object * OpenDDS_Security:_make_BuiltInPluginLoader()";
00095 }
00096
00097 void
00098 SecurityRegistry::release()
00099 {
00100 DBG_ENTRY_LVL("SecurityRegistry", "release", 6);
00101 GuardType guard(lock_);
00102
00103 for (InstMap::iterator iter = registered_plugins_.begin(); iter != registered_plugins_.end(); ++iter) {
00104 iter->second->shutdown();
00105 }
00106
00107 registered_plugins_.clear();
00108 config_map_.clear();
00109 }
00110
00111 void
00112 SecurityRegistry::register_plugin(const OPENDDS_STRING& plugin_name,
00113 SecurityPluginInst_rch plugin)
00114 {
00115 GuardType guard(lock_);
00116
00117 if (registered_plugins_.find(plugin_name) != registered_plugins_.end()) {
00118 guard.release();
00119 ACE_ERROR((LM_ERROR,
00120 ACE_TEXT("(%P|%t) SecurityRegistry::register_plugin: ")
00121 ACE_TEXT("plugin=%C already exists.\n"),
00122 plugin_name.c_str()));
00123 } else {
00124 registered_plugins_.insert(std::make_pair(plugin_name, plugin));
00125 }
00126 }
00127
00128 SecurityConfig_rch
00129 SecurityRegistry::create_config(const OPENDDS_STRING& config_name)
00130 {
00131
00132
00133 SecurityConfig_rch existing_config;
00134 if (find_config(config_name, existing_config)) {
00135 return existing_config;
00136 }
00137
00138
00139
00140
00141 ConfigEntryMap::const_iterator iEntry = config_entries_.find(config_name);
00142 if (iEntry == config_entries_.end()) {
00143 ACE_ERROR((LM_ERROR,
00144 ACE_TEXT("(%P|%t) SecurityRegistry::create_config: ")
00145 ACE_TEXT("config=%C does not exist.\n"),
00146 config_name.c_str()));
00147 return SecurityConfig_rch();
00148 }
00149
00150
00151
00152 const SecurityConfigEntry_rch& entry = iEntry->second;
00153 SecurityPluginInst_rch auth_plugin_inst = get_plugin_inst(entry->get_auth_name());
00154 if (auth_plugin_inst.is_nil()) {
00155 ACE_ERROR((LM_ERROR,
00156 ACE_TEXT("(%P|%t) SecurityRegistry::create_config: ")
00157 ACE_TEXT("Failed to load authentication plugin %C\n"),
00158 entry->get_auth_name().c_str()));
00159 return SecurityConfig_rch();
00160 }
00161
00162 SecurityPluginInst_rch ac_plugin_inst = get_plugin_inst(entry->get_access_control_name());
00163 if (ac_plugin_inst.is_nil()) {
00164 ACE_ERROR((LM_ERROR,
00165 ACE_TEXT("(%P|%t) SecurityRegistry::create_config: ")
00166 ACE_TEXT("Failed to load access control plugin %C\n"),
00167 entry->get_access_control_name().c_str()));
00168 return SecurityConfig_rch();
00169 }
00170
00171 SecurityPluginInst_rch crypto_plugin_inst = get_plugin_inst(entry->get_crypto_name());
00172 if (crypto_plugin_inst.is_nil()) {
00173 ACE_ERROR((LM_ERROR,
00174 ACE_TEXT("(%P|%t) SecurityRegistry::create_config: ")
00175 ACE_TEXT("Failed to load crypto plugin %C\n"),
00176 entry->get_crypto_name().c_str()));
00177 return SecurityConfig_rch();
00178 }
00179
00180
00181
00182
00183 SecurityConfig_rch new_config =
00184 DCPS::make_rch<SecurityConfig>(config_name,
00185 auth_plugin_inst->create_authentication(),
00186 ac_plugin_inst->create_access_control(),
00187 crypto_plugin_inst->create_crypto_key_exchange(),
00188 crypto_plugin_inst->create_crypto_key_factory(),
00189 crypto_plugin_inst->create_crypto_transform(),
00190 entry->get_properties());
00191
00192 if (!add_config(config_name, new_config)) {
00193 ACE_ERROR((LM_ERROR,
00194 ACE_TEXT("(%P|%t) SecurityRegistry::create_config: ")
00195 ACE_TEXT("Error storing config instance %C\n"),
00196 config_name.c_str()));
00197 return SecurityConfig_rch();
00198 }
00199
00200 return new_config;
00201 }
00202
00203 SecurityConfig_rch
00204 SecurityRegistry::create_config(const OPENDDS_STRING& config_name,
00205 SecurityPluginInst_rch plugin)
00206 {
00207 SecurityConfig_rch existing_config;
00208 if (find_config(config_name, existing_config)) {
00209 return existing_config;
00210 }
00211
00212 SecurityConfig_rch new_config =
00213 DCPS::make_rch<SecurityConfig>(config_name,
00214 plugin->create_authentication(),
00215 plugin->create_access_control(),
00216 plugin->create_crypto_key_exchange(),
00217 plugin->create_crypto_key_factory(),
00218 plugin->create_crypto_transform(),
00219 ConfigPropertyList());
00220
00221 if (!add_config(config_name, new_config)) {
00222 ACE_ERROR((LM_ERROR,
00223 ACE_TEXT("(%P|%t) SecurityRegistry::create_config: ")
00224 ACE_TEXT("Error storing config instance %C\n"),
00225 config_name.c_str()));
00226 return SecurityConfig_rch();
00227 }
00228
00229 return new_config;
00230 }
00231
00232 SecurityConfig_rch
00233 SecurityRegistry::get_config(const OPENDDS_STRING& config_name) const
00234 {
00235 GuardType guard(lock_);
00236 ConfigMap::const_iterator found = config_map_.find(config_name);
00237 return found == config_map_.end() ? SecurityConfig_rch() : found->second;
00238 }
00239
00240 SecurityConfig_rch
00241 SecurityRegistry::default_config() const
00242 {
00243 #if defined(OPENDDS_SECURITY)
00244 GuardType guard(lock_);
00245 if (!default_config_ && !TheServiceParticipant->get_security()) {
00246 Authentication_var a;
00247 AccessControl_var b;
00248 CryptoKeyExchange_var c;
00249 CryptoKeyFactory_var d;
00250 CryptoTransform_var e;
00251 default_config_ = DCPS::make_rch<SecurityConfig>("NoPlugins", a, b, c, d, e,
00252 ConfigPropertyList());
00253 }
00254 #endif
00255 return default_config_;
00256 }
00257
00258 void
00259 SecurityRegistry::default_config(const SecurityConfig_rch& config)
00260 {
00261 GuardType guard(lock_);
00262 default_config_ = config;
00263 }
00264
00265 void
00266 SecurityRegistry::bind_config(const OPENDDS_STRING& name,
00267 DDS::DomainParticipant_ptr domain_participant)
00268 {
00269 bind_config(get_config(name), domain_participant);
00270 }
00271
00272 void
00273 SecurityRegistry::bind_config(const SecurityConfig_rch& config,
00274 DDS::DomainParticipant_ptr domain_participant)
00275 {
00276
00277 #if defined(OPENDDS_SECURITY)
00278 DCPS::DomainParticipantImpl* const dpi =
00279 dynamic_cast<DCPS::DomainParticipantImpl*>(domain_participant);
00280 if (dpi) {
00281 dpi->set_security_config(config);
00282 }
00283
00284 #else
00285 ACE_UNUSED_ARG(config);
00286 ACE_UNUSED_ARG(domain_participant);
00287 #endif
00288
00289 }
00290
00291 int
00292 SecurityRegistry::load_security_configuration(ACE_Configuration_Heap& cf)
00293 {
00294 const ACE_Configuration_Section_Key& root = cf.root_section();
00295 ACE_TString sect_name;
00296
00297 for (int index = 0; cf.enumerate_sections(root, index, sect_name) == 0; ++index) {
00298 if (ACE_OS::strcmp(sect_name.c_str(), SECURITY_SECTION_NAME.c_str()) == 0) {
00299
00300 ACE_Configuration_Section_Key sect;
00301 if (cf.open_section(root, sect_name.c_str(), 0, sect) != 0) {
00302 ACE_ERROR_RETURN((LM_ERROR,
00303 ACE_TEXT("(%P|%t) SecurityRegistry::load_plugin_properties: ")
00304 ACE_TEXT("failed to open section %s\n"),
00305 sect_name.c_str()),
00306 -1);
00307 }
00308
00309
00310 DCPS::ValueMap vm;
00311 if (DCPS::pullValues(cf, sect, vm) > 0) {
00312
00313 ACE_ERROR_RETURN((LM_ERROR,
00314 ACE_TEXT("(%P|%t) SecurityRegistry::load_plugin_properties: ")
00315 ACE_TEXT("[%s] sections must have a section name\n"),
00316 sect_name.c_str()),
00317 -1);
00318 }
00319
00320 DCPS::KeyList keys;
00321 if (DCPS::processSections(cf, sect, keys) != 0) {
00322 ACE_ERROR_RETURN((LM_ERROR,
00323 ACE_TEXT("(%P|%t) SecurityRegistry::load_plugin_properties: ")
00324 ACE_TEXT("too many nesting layers in [%s] section.\n"),
00325 sect_name.c_str()),
00326 -1);
00327 }
00328
00329
00330 for (DCPS::KeyList::const_iterator it = keys.begin(); it != keys.end(); ++it) {
00331 const OPENDDS_STRING& entry_name = it->first;
00332
00333 if (config_entries_.find(entry_name) != config_entries_.end()) {
00334 ACE_ERROR_RETURN((LM_ERROR,
00335 ACE_TEXT("(%P|%t) SecurityRegistry::load_plugin_properties: ")
00336 ACE_TEXT("duplicate sections named [%s/%C].\n"),
00337 sect_name.c_str(), entry_name.c_str()),
00338 -1);
00339 }
00340
00341
00342
00343 SecurityConfigEntry_rch newEntry =
00344 DCPS::make_rch<SecurityConfigEntry>(it->first);
00345 DCPS::ValueMap values;
00346 DCPS::pullValues(cf, it->second, values);
00347 for (DCPS::ValueMap::const_iterator val = values.begin(); val != values.end(); ++val) {
00348 newEntry->add_property(val->first, val->second);
00349 }
00350
00351 config_entries_[it->first] = newEntry;
00352 }
00353 }
00354 }
00355
00356 return 0;
00357 }
00358
00359 SecurityConfig_rch
00360 SecurityRegistry::fix_empty_default()
00361 {
00362 #if defined(OPENDDS_SECURITY)
00363 if (!default_config()) {
00364 load_security_plugin_lib(DEFAULT_PLUGIN_NAME);
00365 }
00366 #endif
00367
00368 return default_config();
00369 }
00370
00371 void
00372 SecurityRegistry::load_security_plugin_lib(const OPENDDS_STRING& security_plugin_type)
00373 {
00374 ACE_UNUSED_ARG(security_plugin_type);
00375 #if !defined(ACE_AS_STATIC_LIBS)
00376 GuardType guard(lock_);
00377 LibDirectiveMap::iterator lib_iter = lib_directive_map_.find(security_plugin_type);
00378 if (lib_iter != lib_directive_map_.end()) {
00379 ACE_TString directive = ACE_TEXT_CHAR_TO_TCHAR(lib_iter->second.c_str());
00380 guard.release();
00381 ACE_Service_Config::process_directive(directive.c_str());
00382 }
00383 #endif
00384 }
00385
00386 bool
00387 SecurityRegistry::find_config(const OPENDDS_STRING& name, SecurityConfig_rch& config)
00388 {
00389 GuardType guard(lock_);
00390
00391 bool found_config = false;
00392 ConfigMap::iterator iConfig = config_map_.find(name);
00393 if (iConfig != config_map_.end()) {
00394 config = iConfig->second;
00395 found_config = true;
00396 }
00397
00398 return found_config;
00399 }
00400
00401 bool
00402 SecurityRegistry::add_config(const OPENDDS_STRING& name, SecurityConfig_rch& config)
00403 {
00404 GuardType guard(lock_);
00405
00406 bool added_config = false;
00407 ConfigMap::iterator iConfig = config_map_.find(name);
00408 if (iConfig == config_map_.end()) {
00409 config_map_[name] = config;
00410 added_config = true;
00411 } else {
00412
00413 config = iConfig->second;
00414 added_config = true;
00415 }
00416
00417 return added_config;
00418 }
00419
00420 SecurityPluginInst_rch
00421 SecurityRegistry::get_plugin_inst(const OPENDDS_STRING& plugin_name)
00422 {
00423 GuardType guard(lock_);
00424
00425 SecurityPluginInst_rch plugin_inst;
00426
00427 if (find(registered_plugins_, plugin_name, plugin_inst) != 0) {
00428 #if !defined(ACE_AS_STATIC_LIBS)
00429 guard.release();
00430
00431 load_security_plugin_lib(plugin_name);
00432 guard.acquire();
00433
00434
00435 if (find(registered_plugins_, plugin_name, plugin_inst) != 0) {
00436 #endif
00437 ACE_ERROR((LM_ERROR,
00438 ACE_TEXT("(%P|%t) SecurityRegistry::create_inst: ")
00439 ACE_TEXT("plugin_type=%C is not registered.\n"),
00440 plugin_name.c_str()));
00441 return SecurityPluginInst_rch();
00442 #if !defined(ACE_AS_STATIC_LIBS)
00443 }
00444 #endif
00445 }
00446
00447 return plugin_inst;
00448 }
00449
00450
00451 }
00452 }
00453
00454 OPENDDS_END_VERSIONED_NAMESPACE_DECL