diff options
author | Benoit Foucher <benoit@zeroc.com> | 2006-05-22 16:06:20 +0000 |
---|---|---|
committer | Benoit Foucher <benoit@zeroc.com> | 2006-05-22 16:06:20 +0000 |
commit | c97c4be950e6b9b37b3cedbf521e285bfd6e0b08 (patch) | |
tree | a0e80a132ef496811babcd5d37550d9e708323db /cpp/src | |
parent | LiveDeployment now shown using tables (diff) | |
download | ice-c97c4be950e6b9b37b3cedbf521e285bfd6e0b08.tar.bz2 ice-c97c4be950e6b9b37b3cedbf521e285bfd6e0b08.tar.xz ice-c97c4be950e6b9b37b3cedbf521e285bfd6e0b08.zip |
Added session servant locator to secure access to session servants.
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/IceGrid/AdminSessionI.cpp | 24 | ||||
-rw-r--r-- | cpp/src/IceGrid/Makefile | 1 | ||||
-rw-r--r-- | cpp/src/IceGrid/RegistryI.cpp | 74 | ||||
-rw-r--r-- | cpp/src/IceGrid/RegistryI.h | 12 | ||||
-rw-r--r-- | cpp/src/IceGrid/ServerI.cpp | 4 | ||||
-rw-r--r-- | cpp/src/IceGrid/SessionI.cpp | 35 | ||||
-rw-r--r-- | cpp/src/IceGrid/SessionI.h | 3 | ||||
-rw-r--r-- | cpp/src/IceGrid/SessionServantLocatorI.cpp | 62 | ||||
-rw-r--r-- | cpp/src/IceGrid/SessionServantLocatorI.h | 49 |
9 files changed, 227 insertions, 37 deletions
diff --git a/cpp/src/IceGrid/AdminSessionI.cpp b/cpp/src/IceGrid/AdminSessionI.cpp index 7d0f2e30424..32b9ef5e70f 100644 --- a/cpp/src/IceGrid/AdminSessionI.cpp +++ b/cpp/src/IceGrid/AdminSessionI.cpp @@ -285,9 +285,23 @@ Glacier2::SessionPrx AdminSSLSessionManagerI::create(const Glacier2::SSLInfo& info, const Glacier2::SessionControlPrx&, const Ice::Current& current) { - IceSSL::CertificatePtr cert = IceSSL::Certificate::decode(info.certs[0]); - string id = cert->getSubjectDN(); - AdminSessionIPtr session = new AdminSessionI(id, _database, _timeout, _registryObserverTopic, _nodeObserverTopic); - return Glacier2::SessionPrx::uncheckedCast(current.adapter->addWithUUID(session)); -} + string userDN; + if(!info.certs.empty()) // TODO: Require userDN? + { + try + { + IceSSL::CertificatePtr cert = IceSSL::Certificate::decode(info.certs[0]); + userDN = cert->getSubjectDN(); + } + catch(const Ice::Exception& ex) + { + // This shouldn't happen, the SSLInfo is supposed to be encoded by Glacier2. + Ice::Error out(_database->getTraceLevels()->logger); + out << "SSL session manager couldn't decode SSL certificates"; + return 0; + } + } + AdminSessionIPtr s = new AdminSessionI(userDN, _database, _timeout, _registryObserverTopic, _nodeObserverTopic); + return Glacier2::SessionPrx::uncheckedCast(current.adapter->addWithUUID(s)); +} diff --git a/cpp/src/IceGrid/Makefile b/cpp/src/IceGrid/Makefile index ca304cde6ab..b71c23c3edc 100644 --- a/cpp/src/IceGrid/Makefile +++ b/cpp/src/IceGrid/Makefile @@ -71,6 +71,7 @@ REGISTRY_OBJS = RegistryI.o \ ReapThread.o \ SessionI.o \ AdminSessionI.o \ + SessionServantLocatorI.o \ Topics.o \ QueryI.o \ WaitQueue.o diff --git a/cpp/src/IceGrid/RegistryI.cpp b/cpp/src/IceGrid/RegistryI.cpp index cca8d641311..8f0cf36eace 100644 --- a/cpp/src/IceGrid/RegistryI.cpp +++ b/cpp/src/IceGrid/RegistryI.cpp @@ -29,6 +29,7 @@ #include <IceGrid/SessionI.h> #include <IceGrid/AdminSessionI.h> #include <IceGrid/InternalRegistryI.h> +#include <IceGrid/SessionServantLocatorI.h> #include <fstream> @@ -255,6 +256,15 @@ RegistryI::start(bool nowarn) registryAdapter->activate(); // + // Add a default servant locator to the client object adapter. The + // default servant ensure that request on session objects are from + // the same connection as the connection that created the session. + // + _sessionServantLocator = new SessionServantLocatorI(clientAdapter); + clientAdapter->addServantLocator(_sessionServantLocator, ""); + + + // // Start the reaper threads. // int nodeSessionTimeout = properties->getPropertyAsIntWithDefault("IceGrid.Registry.NodeSessionTimeout", 10); @@ -376,7 +386,8 @@ RegistryI::start(bool nowarn) internalLocatorPrx, properties->getProperty("IceGrid.Registry.PermissionsVerifier"), properties->getPropertyWithDefault("IceGrid.Registry.CryptPasswords", - "passwords")); + "passwords"), + nowarn); if(!_clientVerifier) { return false; @@ -386,16 +397,17 @@ RegistryI::start(bool nowarn) internalLocatorPrx, properties->getProperty("IceGrid.Registry.AdminPermissionsVerifier"), properties->getPropertyWithDefault("IceGrid.Registry.AdminCryptPasswords", - "admin-passwords")); + "admin-passwords"), + nowarn); if(!_adminVerifier) { return false; } _sslClientVerifier = getSSLPermissionsVerifier( - internalLocatorPrx, properties->getProperty("IceGrid.Registry.SSLPermissionsVerifier")); + internalLocatorPrx, properties->getProperty("IceGrid.Registry.SSLPermissionsVerifier"), nowarn); _sslAdminVerifier = getSSLPermissionsVerifier( - internalLocatorPrx, properties->getProperty("IceGrid.Registry.AdminSSLPermissionsVerifier")); + internalLocatorPrx, properties->getProperty("IceGrid.Registry.AdminSSLPermissionsVerifier"), nowarn); // // Register well known objects with the object registry. @@ -473,7 +485,8 @@ RegistryI::createSession(const string& user, const string& password, const Ice:: } SessionIPtr session = _clientSessionManager->create(user, 0); - SessionPrx proxy = SessionPrx::uncheckedCast(current.adapter->addWithUUID(session)); + session->setServantLocator(_sessionServantLocator); + SessionPrx proxy = SessionPrx::uncheckedCast(_sessionServantLocator->add(session, current.con)); _clientReaper->add(new SessionReapable(current.adapter, session, proxy)); return proxy; } @@ -505,7 +518,8 @@ RegistryI::createAdminSession(const string& user, const string& password, const } AdminSessionIPtr session = _adminSessionManager->create(user); - AdminSessionPrx proxy = AdminSessionPrx::uncheckedCast(current.adapter->addWithUUID(session)); + session->setServantLocator(_sessionServantLocator); + AdminSessionPrx proxy = AdminSessionPrx::uncheckedCast(_sessionServantLocator->add(session, current.con)); _clientReaper->add(new SessionReapable(current.adapter, session, proxy)); return proxy; } @@ -520,7 +534,8 @@ RegistryI::createSessionFromSecureConnection(const Ice::Current& current) throw exc; } - Glacier2::SSLInfo info = getSSLInfo(current.con); + string userDN; + Glacier2::SSLInfo info = getSSLInfo(current.con, userDN); try { string reason; @@ -544,11 +559,11 @@ RegistryI::createSessionFromSecureConnection(const Ice::Current& current) throw exc; } - IceSSL::CertificatePtr cert = IceSSL::Certificate::decode(info.certs[0]); - SessionIPtr session = _clientSessionManager->create(cert->getSubjectDN(), 0); - SessionPrx proxy = SessionPrx::uncheckedCast(current.adapter->addWithUUID(session)); + SessionIPtr session = _clientSessionManager->create(userDN, 0); + session->setServantLocator(_sessionServantLocator); + SessionPrx proxy = SessionPrx::uncheckedCast(_sessionServantLocator->add(session, current.con)); _clientReaper->add(new SessionReapable(current.adapter, session, proxy)); - return proxy; + return proxy; } AdminSessionPrx @@ -561,7 +576,8 @@ RegistryI::createAdminSessionFromSecureConnection(const Ice::Current& current) throw exc; } - Glacier2::SSLInfo info = getSSLInfo(current.con); + string userDN; + Glacier2::SSLInfo info = getSSLInfo(current.con, userDN); try { string reason; @@ -584,10 +600,10 @@ RegistryI::createAdminSessionFromSecureConnection(const Ice::Current& current) exc.reason = "internal server error"; throw exc; } - - IceSSL::CertificatePtr cert = IceSSL::Certificate::decode(info.certs[0]); - AdminSessionIPtr session = _adminSessionManager->create(cert->getSubjectDN()); - AdminSessionPrx proxy = AdminSessionPrx::uncheckedCast(current.adapter->addWithUUID(session)); + + AdminSessionIPtr session = _adminSessionManager->create(userDN); + session->setServantLocator(_sessionServantLocator); + AdminSessionPrx proxy = AdminSessionPrx::uncheckedCast(_sessionServantLocator->add(session, current.con)); _clientReaper->add(new SessionReapable(current.adapter, session, proxy)); return proxy; } @@ -646,7 +662,8 @@ Glacier2::PermissionsVerifierPrx RegistryI::getPermissionsVerifier(const Ice::ObjectAdapterPtr& adapter, const Ice::LocatorPrx& locator, const string& verifierProperty, - const string& passwordsProperty) + const string& passwordsProperty, + bool nowarn) { // // Get the permissions verifier, or create a default one if no @@ -723,14 +740,18 @@ RegistryI::getPermissionsVerifier(const Ice::ObjectAdapterPtr& adapter, } catch(const Ice::LocalException& ex) { - Warning out(_communicator->getLogger()); - out << "couldn't contact permissions verifier `" + verifierProperty + "':" << ex; + if(!nowarn) + { + Warning out(_communicator->getLogger()); + out << "couldn't contact permissions verifier `" + verifierProperty + "':\n" << ex; + } + verifierPrx = Glacier2::PermissionsVerifierPrx::uncheckedCast(verifier->ice_locator(locator)); } return verifierPrx; } Glacier2::SSLPermissionsVerifierPrx -RegistryI::getSSLPermissionsVerifier(const Ice::LocatorPrx& locator, const string& verifierProperty) +RegistryI::getSSLPermissionsVerifier(const Ice::LocatorPrx& locator, const string& verifierProperty, bool nowarn) { // // Get the permissions verifier, or create a default one if no @@ -772,14 +793,18 @@ RegistryI::getSSLPermissionsVerifier(const Ice::LocatorPrx& locator, const strin } catch(const Ice::LocalException& ex) { - Warning out(_communicator->getLogger()); - out << "couldn't contact permissions verifier `" + verifierProperty + "':" << ex; + if(!nowarn) + { + Warning out(_communicator->getLogger()); + out << "couldn't contact permissions verifier `" + verifierProperty + "':\n" << ex; + } + verifierPrx = Glacier2::SSLPermissionsVerifierPrx::uncheckedCast(verifier->ice_locator(locator)); } return verifierPrx; } Glacier2::SSLInfo -RegistryI::getSSLInfo(const Ice::ConnectionPtr& connection) +RegistryI::getSSLInfo(const Ice::ConnectionPtr& connection, string& userDN) { Glacier2::SSLInfo sslinfo; try @@ -792,13 +817,14 @@ RegistryI::getSSLInfo(const Ice::ConnectionPtr& connection) sslinfo.cipher = info.cipher; - if(info.certs.size() > 0) + if(!info.certs.empty()) { sslinfo.certs.resize(info.certs.size()); for(unsigned int i = 0; i < info.certs.size(); ++i) { sslinfo.certs[i] = info.certs[i]->encode(); } + userDN = info.certs[0]->getSubjectDN(); } } catch(const IceSSL::ConnectionInvalidException&) diff --git a/cpp/src/IceGrid/RegistryI.h b/cpp/src/IceGrid/RegistryI.h index 0b31ed10738..0a82bcdf39c 100644 --- a/cpp/src/IceGrid/RegistryI.h +++ b/cpp/src/IceGrid/RegistryI.h @@ -30,6 +30,9 @@ typedef IceUtil::Handle<ReapThread> ReapThreadPtr; class WaitQueue; typedef IceUtil::Handle<WaitQueue> WaitQueuePtr; +class SessionServantLocatorI; +typedef IceUtil::Handle<SessionServantLocatorI> SessionServantLocatorIPtr; + class ClientSessionManagerI; typedef IceUtil::Handle<ClientSessionManagerI> ClientSessionManagerIPtr; @@ -59,10 +62,10 @@ private: void addWellKnownObject(const Ice::ObjectPrx&, const std::string&); void setupThreadPool(const Ice::PropertiesPtr&, const std::string&, int, int = 0); Glacier2::PermissionsVerifierPrx getPermissionsVerifier(const Ice::ObjectAdapterPtr&, const Ice::LocatorPrx&, - const std::string&, const std::string&); + const std::string&, const std::string&, bool); - Glacier2::SSLPermissionsVerifierPrx getSSLPermissionsVerifier(const Ice::LocatorPrx&, const std::string&); - Glacier2::SSLInfo getSSLInfo(const Ice::ConnectionPtr&); + Glacier2::SSLPermissionsVerifierPrx getSSLPermissionsVerifier(const Ice::LocatorPrx&, const std::string&, bool); + Glacier2::SSLInfo getSSLInfo(const Ice::ConnectionPtr&, std::string&); Ice::CommunicatorPtr _communicator; DatabasePtr _database; @@ -70,9 +73,12 @@ private: ReapThreadPtr _nodeReaper; ReapThreadPtr _clientReaper; WaitQueuePtr _waitQueue; + SessionServantLocatorIPtr _sessionServantLocator; + ClientSessionManagerIPtr _clientSessionManager; Glacier2::PermissionsVerifierPrx _clientVerifier; Glacier2::SSLPermissionsVerifierPrx _sslClientVerifier; + AdminSessionManagerIPtr _adminSessionManager; Glacier2::PermissionsVerifierPrx _adminVerifier; Glacier2::SSLPermissionsVerifierPrx _sslAdminVerifier; diff --git a/cpp/src/IceGrid/ServerI.cpp b/cpp/src/IceGrid/ServerI.cpp index a8ae661536c..bd310ac4ca9 100644 --- a/cpp/src/IceGrid/ServerI.cpp +++ b/cpp/src/IceGrid/ServerI.cpp @@ -57,8 +57,6 @@ chownRecursive(const string& path, uid_t uid, gid_t gid) string name = namelist[i]->d_name; assert(!name.empty()); - free(namelist[i]); - if(name != ".." && name != ".") { name = path + "/" + name; @@ -71,6 +69,8 @@ chownRecursive(const string& path, uid_t uid, gid_t gid) chownRecursive(name, uid, gid); } } + + free(namelist[i]); } free(namelist); diff --git a/cpp/src/IceGrid/SessionI.cpp b/cpp/src/IceGrid/SessionI.cpp index b00854091d8..362ed766e65 100644 --- a/cpp/src/IceGrid/SessionI.cpp +++ b/cpp/src/IceGrid/SessionI.cpp @@ -123,7 +123,11 @@ BaseSessionI::destroy(const Ice::Current& current) } _destroyed = true; - if(current.adapter) + if(_servantLocator) + { + _servantLocator->remove(current.id); + } + else if(current.adapter) { try { @@ -148,6 +152,15 @@ BaseSessionI::timestamp() const return _timestamp; } +void +BaseSessionI::setServantLocator(const SessionServantLocatorIPtr& servantLocator) +{ + // + // This is supposed to be called after creation only. + // + const_cast<SessionServantLocatorIPtr&>(_servantLocator) = servantLocator; +} + SessionI::SessionI(const string& id, const DatabasePtr& database, int timeout, @@ -307,7 +320,23 @@ Glacier2::SessionPrx ClientSSLSessionManagerI::create(const Glacier2::SSLInfo& info, const Glacier2::SessionControlPrx& ctl, const Ice::Current& current) { - IceSSL::CertificatePtr cert = IceSSL::Certificate::decode(info.certs[0]); - SessionIPtr session = new SessionI(cert->getSubjectDN(), _database, _timeout, _waitQueue, ctl); + string userDN; + if(!info.certs.empty()) // TODO: Require userDN? + { + try + { + IceSSL::CertificatePtr cert = IceSSL::Certificate::decode(info.certs[0]); + userDN = cert->getSubjectDN(); + } + catch(const Ice::Exception& ex) + { + // This shouldn't happen, the SSLInfo is supposed to be encoded by Glacier2. + Ice::Error out(_database->getTraceLevels()->logger); + out << "SSL session manager couldn't decode SSL certificates"; + return 0; + } + } + + SessionIPtr session = new SessionI(userDN, _database, _timeout, _waitQueue, ctl); return Glacier2::SessionPrx::uncheckedCast(current.adapter->addWithUUID(session)); } diff --git a/cpp/src/IceGrid/SessionI.h b/cpp/src/IceGrid/SessionI.h index 998f1f8e8ea..927f1e8a026 100644 --- a/cpp/src/IceGrid/SessionI.h +++ b/cpp/src/IceGrid/SessionI.h @@ -12,6 +12,7 @@ #include <IceUtil/Mutex.h> #include <IceGrid/Session.h> +#include <IceGrid/SessionServantLocatorI.h> namespace IceGrid { @@ -48,6 +49,7 @@ public: virtual void destroy(const Ice::Current&); IceUtil::Time timestamp() const; + void setServantLocator(const SessionServantLocatorIPtr&); protected: @@ -58,6 +60,7 @@ protected: const int _timeout; const TraceLevelsPtr _traceLevels; const DatabasePtr _database; + const SessionServantLocatorIPtr _servantLocator; bool _destroyed; IceUtil::Time _timestamp; }; diff --git a/cpp/src/IceGrid/SessionServantLocatorI.cpp b/cpp/src/IceGrid/SessionServantLocatorI.cpp new file mode 100644 index 00000000000..725e866b130 --- /dev/null +++ b/cpp/src/IceGrid/SessionServantLocatorI.cpp @@ -0,0 +1,62 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2006 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <IceUtil/UUID.h> +#include <Ice/LocalException.h> +#include <Ice/ObjectAdapter.h> +#include <IceGrid/SessionServantLocatorI.h> + +using namespace std; +using namespace IceGrid; + +SessionServantLocatorI::SessionServantLocatorI(const Ice::ObjectAdapterPtr& adapter) : _adapter(adapter) +{ +} + +Ice::ObjectPtr +SessionServantLocatorI::locate(const Ice::Current& current, Ice::LocalObjectPtr&) +{ + Lock sync(*this); + map<Ice::Identity, SessionServant>::const_iterator p = _servants.find(current.id); + if(p == _servants.end() || p->second.connection != current.con) + { + return 0; + } + return p->second.servant; +} + +void +SessionServantLocatorI::finished(const Ice::Current&, const Ice::ObjectPtr&, const Ice::LocalObjectPtr&) +{ +} + +void +SessionServantLocatorI::deactivate(const std::string&) +{ +} + +Ice::ObjectPrx +SessionServantLocatorI::add(const Ice::ObjectPtr& servant, const Ice::ConnectionPtr& con) +{ + Lock sync(*this); + Ice::Identity id; + id.name = IceUtil::generateUUID(); + if(!_servants.insert(make_pair(id, SessionServant(servant, con))).second) + { + throw Ice::AlreadyRegisteredException(__FILE__, __LINE__, "servant", id.name); + } + return _adapter->createProxy(id); +} + +void +SessionServantLocatorI::remove(const Ice::Identity& id) +{ + Lock sync(*this); + _servants.erase(id); +} diff --git a/cpp/src/IceGrid/SessionServantLocatorI.h b/cpp/src/IceGrid/SessionServantLocatorI.h new file mode 100644 index 00000000000..8f7da5ab972 --- /dev/null +++ b/cpp/src/IceGrid/SessionServantLocatorI.h @@ -0,0 +1,49 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2006 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICE_GRID_SESSIONSERVANTLOCATOR_H +#define ICE_GRID_SESSIONSERVANTLOCATOR_H + +#include <IceUtil/Mutex.h> +#include <Ice/ServantLocator.h> + +namespace IceGrid +{ + +class SessionServantLocatorI : public Ice::ServantLocator, public IceUtil::Mutex +{ +public: + + SessionServantLocatorI(const Ice::ObjectAdapterPtr&); + + Ice::ObjectPtr locate(const Ice::Current&, Ice::LocalObjectPtr&); + void finished(const Ice::Current&, const Ice::ObjectPtr&, const Ice::LocalObjectPtr&); + void deactivate(const std::string&); + + Ice::ObjectPrx add(const Ice::ObjectPtr&, const Ice::ConnectionPtr&); + void remove(const Ice::Identity&); + +private: + + struct SessionServant + { + SessionServant(const Ice::ObjectPtr& s, const Ice::ConnectionPtr& con) : servant(s), connection(con) { } + + const Ice::ObjectPtr servant; + const Ice::ConnectionPtr connection; + }; + + const Ice::ObjectAdapterPtr _adapter; + std::map<Ice::Identity, SessionServant> _servants; +}; +typedef IceUtil::Handle<SessionServantLocatorI> SessionServantLocatorIPtr; + +}; + +#endif |