diff options
author | Joe George <joe@zeroc.com> | 2015-03-11 11:48:35 -0400 |
---|---|---|
committer | Joe George <joe@zeroc.com> | 2015-05-12 11:42:05 -0400 |
commit | dc60da4d945f25a8192e97eae9f32a62b0e1a61d (patch) | |
tree | 86108b0cf5a89cf8017efac9f0ee0589f0fa4e8f | |
parent | Ice 3.4.2 Patch 5 (diff) | |
download | ice-dc60da4d945f25a8192e97eae9f32a62b0e1a61d.tar.bz2 ice-dc60da4d945f25a8192e97eae9f32a62b0e1a61d.tar.xz ice-dc60da4d945f25a8192e97eae9f32a62b0e1a61d.zip |
Various Fixes
- Added support for this functionality to connecting registry
- replicas
- Renamed the property to IceGrid.Registry.RequireNodeCertCN and
added IceGrid.Registry.RequireReplicaCertCN
- Use the IceGrid::PermissionDeniedException to reject the connection
and print an appropriate error message on the node side.
- Reject non SSL connections if the property is configured
- Added support for the property in the secure IceGrid demo.
-rw-r--r-- | cpp/demo/IceGrid/secure/README | 5 | ||||
-rw-r--r-- | cpp/demo/IceGrid/secure/application.xml | 5 | ||||
-rw-r--r-- | cpp/demo/IceGrid/secure/config.admin | 2 | ||||
-rw-r--r-- | cpp/demo/IceGrid/secure/config.client | 2 | ||||
-rw-r--r-- | cpp/demo/IceGrid/secure/config.master (renamed from cpp/demo/IceGrid/secure/config.registry) | 21 | ||||
-rw-r--r-- | cpp/demo/IceGrid/secure/config.node | 6 | ||||
-rw-r--r-- | cpp/demo/IceGrid/secure/config.slave | 66 | ||||
-rwxr-xr-x | cpp/demo/IceGrid/secure/makecerts.py | 5 | ||||
-rw-r--r-- | cpp/src/Ice/PropertyNames.cpp | 4 | ||||
-rw-r--r-- | cpp/src/Ice/PropertyNames.h | 2 | ||||
-rw-r--r-- | cpp/src/IceGrid/Internal.ice | 4 | ||||
-rw-r--r-- | cpp/src/IceGrid/InternalRegistryI.cpp | 106 | ||||
-rw-r--r-- | cpp/src/IceGrid/InternalRegistryI.h | 2 | ||||
-rw-r--r-- | cpp/src/IceGrid/NodeSessionManager.cpp | 8 | ||||
-rw-r--r-- | cpp/src/IceGrid/ReplicaSessionManager.cpp | 8 |
15 files changed, 222 insertions, 24 deletions
diff --git a/cpp/demo/IceGrid/secure/README b/cpp/demo/IceGrid/secure/README index 3fa12aa21a0..e15cf714f19 100644 --- a/cpp/demo/IceGrid/secure/README +++ b/cpp/demo/IceGrid/secure/README @@ -31,9 +31,10 @@ so you might as well use a certificate without a password and rely on the filesystem permissions to restrict access to the certificate. Once the certificates are generated, you can start the IceGrid -registry, node, and Glacier2 router: +registries, node, and Glacier2 router: -$ icegridregistry --Ice.Config=config.registry +$ icegridregistry --Ice.Config=config.master +$ icegridregistry --Ice.Config=config.slave $ icegridnode --Ice.Config=config.node $ glacier2router --Ice.Config=config.glacier2 diff --git a/cpp/demo/IceGrid/secure/application.xml b/cpp/demo/IceGrid/secure/application.xml index 1da08d848da..741c5992fc7 100644 --- a/cpp/demo/IceGrid/secure/application.xml +++ b/cpp/demo/IceGrid/secure/application.xml @@ -20,8 +20,9 @@ <property name="IceSSL.DefaultDir" value="certs"/> <property name="Ice.Admin.Endpoints" value="ssl -h 127.0.0.1"/> - <property name="IceSSL.TrustOnly.Client" value="CN=IceGrid Registry"/> - <property name="IceSSL.TrustOnly.Server.Ice.Admin" value="CN=IceGrid Node"/> + <property name="IceSSL.TrustOnly.Client" value="CN=Master;CN=Slave"/> + <property name="IceSSL.TrustOnly.Client" value="CN=Master;CN=Slave"/> + <property name="IceSSL.TrustOnly.Server.Ice.Admin" value="CN=Node"/> </properties> <node name="Node"> diff --git a/cpp/demo/IceGrid/secure/config.admin b/cpp/demo/IceGrid/secure/config.admin index 3ae72a9d52a..b3a5a2207ae 100644 --- a/cpp/demo/IceGrid/secure/config.admin +++ b/cpp/demo/IceGrid/secure/config.admin @@ -14,7 +14,7 @@ IceGridAdmin.Password=dummy # SSL Configuration # IceSSL.DefaultDir=certs -IceSSL.TrustOnly.Client=CN="IceGrid Registry";CN="Glacier2" +IceSSL.TrustOnly.Client=CN="Master";CN="Slave";CN="Glacier2" # C++ configuration Ice.Plugin.IceSSL.cpp=IceSSL:createIceSSL diff --git a/cpp/demo/IceGrid/secure/config.client b/cpp/demo/IceGrid/secure/config.client index 3ea6283bb05..f5d45bc8387 100644 --- a/cpp/demo/IceGrid/secure/config.client +++ b/cpp/demo/IceGrid/secure/config.client @@ -1,7 +1,7 @@ # # The IceGrid locator proxy. # -Ice.Default.Locator=DemoIceGrid/Locator:tcp -p 4061 +Ice.Default.Locator=DemoIceGrid/Locator:tcp -p 4061:tcp -p 14061 # # Trace properties. diff --git a/cpp/demo/IceGrid/secure/config.registry b/cpp/demo/IceGrid/secure/config.master index 84b42ed1af8..95cba08d973 100644 --- a/cpp/demo/IceGrid/secure/config.registry +++ b/cpp/demo/IceGrid/secure/config.master @@ -9,7 +9,14 @@ IceGrid.InstanceName=DemoIceGrid IceGrid.Registry.Client.Endpoints=tcp -p 4061 -t 10000:ssl -p 4062 -t 10000 IceGrid.Registry.Server.Endpoints=ssl -t 10000 IceGrid.Registry.Internal.Endpoints=ssl -t 10000 -IceGrid.Registry.Data=db/registry +IceGrid.Registry.Data=db/master + +# +# Ensure that nodes and slaves connecting to this registry have a name +# matching the certificate CN. +# +IceGrid.Registry.RequireNodeCertCN=1 +IceGrid.Registry.RequireReplicaCertCN=1 # # IceGrid admin clients must use a secure connection to connect to the @@ -23,12 +30,12 @@ IceGrid.Registry.AdminPermissionsVerifier=DemoIceGrid/NullPermissionsVerifier # #Ice.Plugin.DB=IceGridSqlDB:createSqlDB #IceGrid.SQL.DatabaseType=QSQLITE -#IceGrid.SQL.DatabaseName=db/registry/Registry.db +#IceGrid.SQL.DatabaseName=db/master/Registry.db # # Trace properties. # -Ice.ProgramName=Registry +Ice.ProgramName=Master IceGrid.Registry.Trace.Node=2 IceGrid.Registry.Trace.Replica=2 @@ -38,8 +45,8 @@ IceGrid.Registry.Trace.Replica=2 Ice.Plugin.IceSSL=IceSSL:createIceSSL IceSSL.DefaultDir=certs IceSSL.CertAuthFile=ca_cert.pem -IceSSL.CertFile=registry_cert.pem -IceSSL.KeyFile=registry_key.pem +IceSSL.CertFile=master_cert.pem +IceSSL.KeyFile=master_key.pem # # Don't require certificates. This is useful for admin clients that don't @@ -48,7 +55,7 @@ IceSSL.KeyFile=registry_key.pem # IceSSL.VerifyPeer=1 -IceSSL.TrustOnly.Client=CN="IceGrid Registry";CN="IceGrid Node";CN="Glacier2" +IceSSL.TrustOnly.Client=CN="Master";CN="Slave";CN="Node";CN="Glacier2" IceSSL.TrustOnly.Server.IceGrid.Registry.Server=CN="Server" -IceSSL.TrustOnly.Server.IceGrid.Registry.Internal=CN="IceGrid Node";CN="IceGrid Registry" +IceSSL.TrustOnly.Server.IceGrid.Registry.Internal=CN="Node";CN="Master";CN="Slave" IceSSL.TrustOnly.Server.IceGrid.Registry.AdminSessionManager=CN="Glacier2" diff --git a/cpp/demo/IceGrid/secure/config.node b/cpp/demo/IceGrid/secure/config.node index 9629a099eb1..17e99114d34 100644 --- a/cpp/demo/IceGrid/secure/config.node +++ b/cpp/demo/IceGrid/secure/config.node @@ -1,7 +1,7 @@ # # The IceGrid locator proxy. # -Ice.Default.Locator=DemoIceGrid/Locator:ssl -p 4062 -t 10000 +Ice.Default.Locator=DemoIceGrid/Locator:ssl -p 4062 -t 10000:ssl -p 14062 -t 10000 # # IceGrid node configuration. @@ -26,5 +26,5 @@ IceSSL.CertAuthFile=ca_cert.pem IceSSL.CertFile=node_cert.pem IceSSL.KeyFile=node_key.pem -IceSSL.TrustOnly.Client=CN="Server";CN="IceGrid Registry" -IceSSL.TrustOnly.Server=CN="IceGrid Registry" +IceSSL.TrustOnly.Client=CN="Server";CN="Master";CN="Slave" +IceSSL.TrustOnly.Server=CN="Master";CN="Slave" diff --git a/cpp/demo/IceGrid/secure/config.slave b/cpp/demo/IceGrid/secure/config.slave new file mode 100644 index 00000000000..3de35efd0a0 --- /dev/null +++ b/cpp/demo/IceGrid/secure/config.slave @@ -0,0 +1,66 @@ +# +# The IceGrid locator proxy. +# +Ice.Default.Locator=DemoIceGrid/Locator:ssl -p 4062 -t 10000 + +# +# The IceGrid instance name. +# +IceGrid.InstanceName=DemoIceGrid + +# +# IceGrid registry configuration. +# +IceGrid.Registry.Client.Endpoints=tcp -p 14061 -t 10000:ssl -p 14062 -t 10000 +IceGrid.Registry.Server.Endpoints=ssl -t 10000 +IceGrid.Registry.Internal.Endpoints=ssl -t 10000 +IceGrid.Registry.Data=db/slave +IceGrid.Registry.ReplicaName=Slave + +# +# Ensure that nodes connecting to this registry have a name matching +# the certificate CN. +# +IceGrid.Registry.RequireNodeCertCN=1 + +# +# IceGrid admin clients must use a secure connection to connect to the +# registry or use Glacier2. +# +IceGrid.Registry.AdminSessionManager.Endpoints=ssl -t 10000 +IceGrid.Registry.AdminPermissionsVerifier=DemoIceGrid/NullPermissionsVerifier + +# +# IceGrid SQL configuration if using SQL database. +# +#Ice.Plugin.DB=IceGridSqlDB:createSqlDB +#IceGrid.SQL.DatabaseType=QSQLITE +#IceGrid.SQL.DatabaseName=db/slave/Registry.db + +# +# Trace properties. +# +Ice.ProgramName=Slave +IceGrid.Registry.Trace.Node=2 +IceGrid.Registry.Trace.Replica=2 + +# +# SSL Configuration +# +Ice.Plugin.IceSSL=IceSSL:createIceSSL +IceSSL.DefaultDir=certs +IceSSL.CertAuthFile=ca_cert.pem +IceSSL.CertFile=slave_cert.pem +IceSSL.KeyFile=slave_key.pem + +# +# Don't require certificates. This is useful for admin clients that don't +# use certificate but still need to establish a secure connection for the +# username/password authentication +# +IceSSL.VerifyPeer=1 + +IceSSL.TrustOnly.Client=CN="Master";CN="Slave";CN="Node";CN="Glacier2" +IceSSL.TrustOnly.Server.IceGrid.Registry.Server=CN="Server" +IceSSL.TrustOnly.Server.IceGrid.Registry.Internal=CN="Node";CN="Master";CN="Slave" +IceSSL.TrustOnly.Server.IceGrid.Registry.AdminSessionManager=CN="Glacier2" diff --git a/cpp/demo/IceGrid/secure/makecerts.py b/cpp/demo/IceGrid/secure/makecerts.py index 2f95d04dbfe..6d49467d33e 100755 --- a/cpp/demo/IceGrid/secure/makecerts.py +++ b/cpp/demo/IceGrid/secure/makecerts.py @@ -44,8 +44,9 @@ runIceca("init --overwrite --no-password") print print -createCertificate("registry", "IceGrid Registry") -createCertificate("node", "IceGrid Node") +createCertificate("master", "Master") +createCertificate("slave", "Slave") +createCertificate("node", "Node") createCertificate("glacier2", "Glacier2") createCertificate("server", "Server") diff --git a/cpp/src/Ice/PropertyNames.cpp b/cpp/src/Ice/PropertyNames.cpp index 337a1295399..202e97044f9 100644 --- a/cpp/src/Ice/PropertyNames.cpp +++ b/cpp/src/Ice/PropertyNames.cpp @@ -8,7 +8,7 @@ // ********************************************************************** // -// Generated by makeprops.py from file ..\config\PropertyNames.xml, Mon May 09 07:39:43 2011 +// Generated by makeprops.py from file ../config/PropertyNames.xml, Tue Jul 12 07:22:34 2011 // IMPORTANT: Do not edit this file -- any edits made here will be lost! @@ -335,6 +335,8 @@ const IceInternal::Property IceGridPropsData[] = IceInternal::Property("IceGrid.Registry.PermissionsVerifier", false, 0), IceInternal::Property("IceGrid.Registry.ReplicaName", false, 0), IceInternal::Property("IceGrid.Registry.ReplicaSessionTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.RequireNodeCertCN", false, 0), + IceInternal::Property("IceGrid.Registry.RequireReplicaCertCN", false, 0), IceInternal::Property("IceGrid.Registry.Server.ACM", false, 0), IceInternal::Property("IceGrid.Registry.Server.AdapterId", false, 0), IceInternal::Property("IceGrid.Registry.Server.Endpoints", false, 0), diff --git a/cpp/src/Ice/PropertyNames.h b/cpp/src/Ice/PropertyNames.h index 23a715ebc7f..e34b52836b3 100644 --- a/cpp/src/Ice/PropertyNames.h +++ b/cpp/src/Ice/PropertyNames.h @@ -8,7 +8,7 @@ // ********************************************************************** // -// Generated by makeprops.py from file ..\config\PropertyNames.xml, Mon May 09 07:39:43 2011 +// Generated by makeprops.py from file ../config/PropertyNames.xml, Tue Jul 12 07:22:34 2011 // IMPORTANT: Do not edit this file -- any edits made here will be lost! diff --git a/cpp/src/IceGrid/Internal.ice b/cpp/src/IceGrid/Internal.ice index 3d2faf1ed32..6c32f9cc0ab 100644 --- a/cpp/src/IceGrid/Internal.ice +++ b/cpp/src/IceGrid/Internal.ice @@ -702,7 +702,7 @@ interface InternalRegistry extends FileReader * **/ NodeSession* registerNode(InternalNodeInfo info, Node* prx, LoadInfo loadInf) - throws NodeActiveException; + throws NodeActiveException, PermissionDeniedException; /** * @@ -721,7 +721,7 @@ interface InternalRegistry extends FileReader * **/ ReplicaSession* registerReplica(InternalReplicaInfo info, InternalRegistry* prx) - throws ReplicaActiveException; + throws ReplicaActiveException, PermissionDeniedException; /** * diff --git a/cpp/src/IceGrid/InternalRegistryI.cpp b/cpp/src/IceGrid/InternalRegistryI.cpp index 61178ec4fed..1d4def0abba 100644 --- a/cpp/src/IceGrid/InternalRegistryI.cpp +++ b/cpp/src/IceGrid/InternalRegistryI.cpp @@ -19,6 +19,8 @@ #include <IceGrid/ReplicaSessionI.h> #include <IceGrid/ReplicaSessionManager.h> #include <IceGrid/FileCache.h> +#include <IceSSL/IceSSL.h> +#include <IceSSL/RFC2253.h> using namespace std; using namespace IceGrid; @@ -38,6 +40,8 @@ InternalRegistryI::InternalRegistryI(const RegistryIPtr& registry, 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.RequireNodeCertCN", 0); } InternalRegistryI::~InternalRegistryI() @@ -50,7 +54,56 @@ InternalRegistryI::registerNode(const InternalNodeInfoPtr& info, 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 @@ InternalRegistryI::registerReplica(const InternalReplicaInfoPtr& info, 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); diff --git a/cpp/src/IceGrid/InternalRegistryI.h b/cpp/src/IceGrid/InternalRegistryI.h index 2e87a358b4e..32f7828a373 100644 --- a/cpp/src/IceGrid/InternalRegistryI.h +++ b/cpp/src/IceGrid/InternalRegistryI.h @@ -68,6 +68,8 @@ private: ReplicaSessionManager& _session; int _nodeSessionTimeout; int _replicaSessionTimeout; + bool _requireNodeCertCN; + bool _requireReplicaCertCN; }; }; diff --git a/cpp/src/IceGrid/NodeSessionManager.cpp b/cpp/src/IceGrid/NodeSessionManager.cpp index 792d8bda8f9..a10ab102b8e 100644 --- a/cpp/src/IceGrid/NodeSessionManager.cpp +++ b/cpp/src/IceGrid/NodeSessionManager.cpp @@ -110,6 +110,14 @@ NodeSessionKeepAliveThread::createSession(InternalRegistryPrx& registry, IceUtil } exception.reset(ex.ice_clone()); } + catch(const PermissionDeniedException& ex) + { + if(traceLevels) + { + traceLevels->logger->error("connection to the the registry `" + _name + "' was denied:\n" + ex.reason); + } + exception.reset(ex.ice_clone()); + } catch(const Ice::Exception& ex) { exception.reset(ex.ice_clone()); diff --git a/cpp/src/IceGrid/ReplicaSessionManager.cpp b/cpp/src/IceGrid/ReplicaSessionManager.cpp index 57997d60027..b2114dc1b12 100644 --- a/cpp/src/IceGrid/ReplicaSessionManager.cpp +++ b/cpp/src/IceGrid/ReplicaSessionManager.cpp @@ -500,6 +500,14 @@ ReplicaSessionManager::createSession(InternalRegistryPrx& registry, IceUtil::Tim } exception.reset(ex.ice_clone()); } + catch(const PermissionDeniedException& ex) + { + if(_traceLevels) + { + _traceLevels->logger->error("connection to the the registry `" + _name + "' was denied:\n" + ex.reason); + } + exception.reset(ex.ice_clone()); + } catch(const Ice::Exception& ex) { exception.reset(ex.ice_clone()); |