summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe George <joe@zeroc.com>2015-03-11 11:48:35 -0400
committerJoe George <joe@zeroc.com>2015-05-12 11:42:05 -0400
commitdc60da4d945f25a8192e97eae9f32a62b0e1a61d (patch)
tree86108b0cf5a89cf8017efac9f0ee0589f0fa4e8f
parentIce 3.4.2 Patch 5 (diff)
downloadice-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/README5
-rw-r--r--cpp/demo/IceGrid/secure/application.xml5
-rw-r--r--cpp/demo/IceGrid/secure/config.admin2
-rw-r--r--cpp/demo/IceGrid/secure/config.client2
-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.node6
-rw-r--r--cpp/demo/IceGrid/secure/config.slave66
-rwxr-xr-xcpp/demo/IceGrid/secure/makecerts.py5
-rw-r--r--cpp/src/Ice/PropertyNames.cpp4
-rw-r--r--cpp/src/Ice/PropertyNames.h2
-rw-r--r--cpp/src/IceGrid/Internal.ice4
-rw-r--r--cpp/src/IceGrid/InternalRegistryI.cpp106
-rw-r--r--cpp/src/IceGrid/InternalRegistryI.h2
-rw-r--r--cpp/src/IceGrid/NodeSessionManager.cpp8
-rw-r--r--cpp/src/IceGrid/ReplicaSessionManager.cpp8
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());