--- Ice-3.4.2.orig/cpp/src/IceGrid/InternalRegistryI.cpp 2011-06-15 21:43:59.000000000 +0200 +++ Ice-3.4.2/cpp/src/IceGrid/InternalRegistryI.cpp 2012-03-04 19:55:44.000000000 +0100 @@ -19,6 +19,8 @@ #include #include #include +#include +#include using namespace std; using namespace IceGrid; @@ -38,6 +40,8 @@ Ice::PropertiesPtr properties = database->getCommunicator()->getProperties(); _nodeSessionTimeout = properties->getPropertyAsIntWithDefault("IceGrid.Registry.NodeSessionTimeout", 30); _replicaSessionTimeout = properties->getPropertyAsIntWithDefault("IceGrid.Registry.ReplicaSessionTimeout", 30); + _requireNodeCertCN = properties->getPropertyAsIntWithDefault("IceGrid.Registry.RequireNodeCertCN", 0); + _requireReplicaCertCN = properties->getPropertyAsIntWithDefault("IceGrid.Registry.RequireReplicaCertCN", 0); } InternalRegistryI::~InternalRegistryI() @@ -50,7 +54,56 @@ const LoadInfo& load, const Ice::Current& current) { - const Ice::LoggerPtr logger = _database->getTraceLevels()->logger; + const TraceLevelsPtr traceLevels = _database->getTraceLevels(); + const Ice::LoggerPtr logger = traceLevels->logger; + if(!info || !node) + { + return 0; + } + + if(_requireNodeCertCN) + { + try + { + IceSSL::ConnectionInfoPtr sslConnInfo = IceSSL::ConnectionInfoPtr::dynamicCast(current.con->getInfo()); + if(sslConnInfo) + { + if (sslConnInfo->certs.empty() || + !IceSSL::Certificate::decode(sslConnInfo->certs[0])->getSubjectDN().match("CN=" + info->name)) + { + if(traceLevels->node > 0) + { + Ice::Trace out(logger, traceLevels->nodeCat); + out << "certificate CN doesn't match node name `" << info->name << "'"; + } + throw PermissionDeniedException("certificate CN doesn't match node name `" + info->name + "'"); + } + } + else + { + if(traceLevels->node > 0) + { + Ice::Trace out(logger, traceLevels->nodeCat); + out << "node certificate for `" << info->name << "' is required to connect to this registry"; + } + throw PermissionDeniedException("node certificate is required to connect to this registry"); + } + } + catch(const PermissionDeniedException& ex) + { + throw ex; + } + catch(const IceUtil::Exception&) + { + if(traceLevels->node > 0) + { + Ice::Trace out(logger, traceLevels->nodeCat); + out << "unexpected exception while verifying certificate for node `" << info->name << "'"; + } + throw PermissionDeniedException("unable to verify certificate for node `" + info->name + "'"); + } + } + try { NodeSessionIPtr session = new NodeSessionI(_database, node, info, _nodeSessionTimeout, load); @@ -68,7 +121,56 @@ const InternalRegistryPrx& prx, const Ice::Current& current) { - const Ice::LoggerPtr logger = _database->getTraceLevels()->logger; + const TraceLevelsPtr traceLevels = _database->getTraceLevels(); + const Ice::LoggerPtr logger = traceLevels->logger; + if(!info || !prx) + { + return 0; + } + + if(_requireReplicaCertCN) + { + try + { + IceSSL::ConnectionInfoPtr sslConnInfo = IceSSL::ConnectionInfoPtr::dynamicCast(current.con->getInfo()); + if(sslConnInfo) + { + if (sslConnInfo->certs.empty() || + !IceSSL::Certificate::decode(sslConnInfo->certs[0])->getSubjectDN().match("CN=" + info->name)) + { + if(traceLevels->replica > 0) + { + Ice::Trace out(logger, traceLevels->replicaCat); + out << "certificate CN doesn't match replica name `" << info->name << "'"; + } + throw PermissionDeniedException("certificate CN doesn't match replica name `" + info->name + "'"); + } + } + else + { + if(traceLevels->replica > 0) + { + Ice::Trace out(logger, traceLevels->replicaCat); + out << "replica certificate for `" << info->name << "' is required to connect to this registry"; + } + throw PermissionDeniedException("replica certificate is required to connect to this registry"); + } + } + catch(const PermissionDeniedException& ex) + { + throw ex; + } + catch(const IceUtil::Exception&) + { + if(traceLevels->replica > 0) + { + Ice::Trace out(logger, traceLevels->replicaCat); + out << "unexpected exception while verifying certificate for replica `" << info->name << "'"; + } + throw PermissionDeniedException("unable to verify certificate for replica `" + info->name + "'"); + } + } + try { ReplicaSessionIPtr s = new ReplicaSessionI(_database, _wellKnownObjects, info, prx, _replicaSessionTimeout);