summaryrefslogtreecommitdiff
path: root/cpp/src/Glacier2/SessionRouterI.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/Glacier2/SessionRouterI.cpp')
-rw-r--r--cpp/src/Glacier2/SessionRouterI.cpp626
1 files changed, 378 insertions, 248 deletions
diff --git a/cpp/src/Glacier2/SessionRouterI.cpp b/cpp/src/Glacier2/SessionRouterI.cpp
index 8b1dcf98d1e..4e10b51ebef 100644
--- a/cpp/src/Glacier2/SessionRouterI.cpp
+++ b/cpp/src/Glacier2/SessionRouterI.cpp
@@ -21,6 +21,9 @@ using namespace std;
using namespace Ice;
using namespace Glacier2;
+namespace Glacier2
+{
+
class SessionControlI : public SessionControl
{
public:
@@ -39,8 +42,8 @@ public:
private:
- SessionRouterIPtr _sessionRouter;
- ConnectionPtr _connection;
+ const SessionRouterIPtr _sessionRouter;
+ const ConnectionPtr _connection;
};
class ClientLocator : public ServantLocator
@@ -103,11 +106,100 @@ private:
const SessionRouterIPtr _sessionRouter;
};
+class UserPasswordAuthorizer : public Authorizer
+{
+public:
+
+ UserPasswordAuthorizer(const PermissionsVerifierPrx& verifier, const string& user, const string& password) :
+ _verifier(verifier), _user(user), _password(password)
+ {
+ }
+
+ virtual bool
+ authorize(string& reason, const Ice::Context& ctx)
+ {
+ return _verifier->checkPermissions(_user, _password, reason, ctx);
+ }
+
+private:
+
+ const PermissionsVerifierPrx _verifier;
+ const string _user;
+ const string _password;
+};
+
+class SSLPasswordAuthorizer : public Authorizer
+{
+public:
+
+ SSLPasswordAuthorizer(const SSLPermissionsVerifierPrx& verifier, const SSLInfo& info) :
+ _verifier(verifier), _info(info)
+ {
+ }
+
+ virtual bool
+ authorize(string& reason, const Ice::Context& ctx)
+ {
+ return _verifier->authorize(_info, reason, ctx);
+ }
+
+private:
+
+ const SSLPermissionsVerifierPrx _verifier;
+ const SSLInfo _info;
+};
+
+class UserSessionFactory : public SessionFactory
+{
+public:
+
+ UserSessionFactory(const SessionManagerPrx& manager, const string& user) :
+ _manager(manager), _user(user)
+ {
+ }
+
+ virtual SessionPrx
+ create(const SessionControlPrx& control, const Ice::Context& ctx)
+ {
+ return _manager->create(_user, control, ctx);
+ }
+
+private:
+
+ const SessionManagerPrx _manager;
+ const string _user;
+};
+
+class SSLSessionFactory : public SessionFactory
+{
+public:
+
+ SSLSessionFactory(const SSLSessionManagerPrx& manager, const SSLInfo& info) :
+ _manager(manager), _info(info)
+ {
+ }
+
+ virtual SessionPrx
+ create(const SessionControlPrx& control, const Ice::Context& ctx)
+ {
+ return _manager->create(_info, control, ctx);
+ }
+
+private:
+
+ const SSLSessionManagerPrx _manager;
+ const SSLInfo _info;
+};
+
+}
+
Glacier2::SessionRouterI::SessionRouterI(const ObjectAdapterPtr& clientAdapter,
const ObjectAdapterPtr& serverAdapter,
const ObjectAdapterPtr& adminAdapter,
const PermissionsVerifierPrx& verifier,
- const SessionManagerPrx& sessionManager) :
+ const SessionManagerPrx& sessionManager,
+ const SSLPermissionsVerifierPrx& sslVerifier,
+ const SSLSessionManagerPrx& sslSessionManager) :
_properties(clientAdapter->getCommunicator()->getProperties()),
_logger(clientAdapter->getCommunicator()->getLogger()),
_sessionTraceLevel(_properties->getPropertyAsInt("Glacier2.Trace.Session")),
@@ -117,6 +209,8 @@ Glacier2::SessionRouterI::SessionRouterI(const ObjectAdapterPtr& clientAdapter,
_adminAdapter(adminAdapter),
_verifier(verifier),
_sessionManager(sessionManager),
+ _sslVerifier(sslVerifier),
+ _sslSessionManager(sslSessionManager),
_sessionTimeout(IceUtil::Time::seconds(_properties->getPropertyAsInt("Glacier2.SessionTimeout"))),
_sessionThread(_sessionTimeout > IceUtil::Time() ? new SessionThread(this, _sessionTimeout) : 0),
_routersByConnectionHint(_routersByConnection.end()),
@@ -141,8 +235,7 @@ Glacier2::SessionRouterI::SessionRouterI(const ObjectAdapterPtr& clientAdapter,
// All other calls on the client object adapter are dispatched to
// a router servant based on connection information.
//
- ServantLocatorPtr clientLocator = new ClientLocator(this);
- _clientAdapter->addServantLocator(clientLocator, "");
+ _clientAdapter->addServantLocator(new ClientLocator(this), "");
//
// If there is a server object adapter, all calls on this adapter
@@ -151,8 +244,7 @@ Glacier2::SessionRouterI::SessionRouterI(const ObjectAdapterPtr& clientAdapter,
//
if(_serverAdapter)
{
- ServantLocatorPtr serverLocator = new ServerLocator(this);
- _serverAdapter->addServantLocator(serverLocator, "");
+ _serverAdapter->addServantLocator(new ServerLocator(this), "");
}
if(_sessionThread)
@@ -258,90 +350,27 @@ Glacier2::SessionRouterI::getCategoryForClient(const Ice::Current& current) cons
SessionPrx
Glacier2::SessionRouterI::createSession(const std::string& userId, const std::string& password, const Current& current)
{
+ SessionFactoryPtr factory;
+ if(_sessionManager)
{
- IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);
-
- if(_destroy)
- {
- current.con->close(true);
- throw ObjectNotExistException(__FILE__, __LINE__);
- }
-
- //
- // Check whether a session already exists for the connection.
- //
- {
- map<ConnectionPtr, RouterIPtr>::iterator p;
- if(_routersByConnectionHint != _routersByConnection.end() &&
- _routersByConnectionHint->first == current.con)
- {
- p = _routersByConnectionHint;
- }
- else
- {
- p = _routersByConnection.find(current.con);
- }
-
- if(p != _routersByConnection.end())
- {
- CannotCreateSessionException exc;
- exc.reason = "session exists";
- throw exc;
- }
- }
-
- //
- // If some other thread is currently trying to create a
- // session, we wait until this thread is finished.
- //
- bool searchAgain = false;
- while(_pending.find(current.con) != _pending.end())
- {
- wait();
-
- if(_destroy)
- {
- current.con->close(true);
- throw ObjectNotExistException(__FILE__, __LINE__);
- }
-
- searchAgain = true;
- }
-
- //
- // Check for existing sessions again if we waited above, as
- // new sessions have been added in the meantime.
- //
- if(searchAgain)
- {
- map<ConnectionPtr, RouterIPtr>::iterator p;
- if(_routersByConnectionHint != _routersByConnection.end() &&
- _routersByConnectionHint->first == current.con)
- {
- p = _routersByConnectionHint;
- }
- else
- {
- p = _routersByConnection.find(current.con);
- }
-
- if(p != _routersByConnection.end())
- {
- CannotCreateSessionException exc;
- exc.reason = "session exists";
- throw exc;
- }
- }
+ factory = new UserSessionFactory(_sessionManager, userId);
+ }
+ return createSessionInternal(userId, true, new UserPasswordAuthorizer(_verifier, userId, password), factory,
+ current);
+}
- //
- // No session exists yet, so we will try to create one. To
- // avoid that other threads try to create sessions for the
- // same connection, we add our endpoints to _pending.
- //
- _pending.insert(current.con);
+SessionPrx
+Glacier2::SessionRouterI::createSessionFromSecureConnection(const Current& current)
+{
+ if(!_sslVerifier)
+ {
+ PermissionDeniedException exc;
+ exc.reason = "no configured ssl permissions verifier";
+ throw exc;
}
- Ice::Context ctx = current.ctx;
+ string userDN;
+ SSLInfo sslinfo;
//
// Populate the SSL context information.
@@ -349,183 +378,44 @@ Glacier2::SessionRouterI::createSession(const std::string& userId, const std::st
try
{
IceSSL::ConnectionInfo info = IceSSL::getConnectionInfo(current.con);
- ctx["SSL.Active"] = "1";
- ctx["SSL.Cipher"] = info.cipher;
- ostringstream os;
- os << ntohs(info.remoteAddr.sin_port);
- ctx["SSL.Remote.Port"] = os.str();
- ctx["SSL.Remote.Host"] = IceInternal::inetAddrToString(info.remoteAddr.sin_addr);
- os.str("");
- os << ntohs(info.localAddr.sin_port);
- ctx["SSL.Local.Port"] = os.str();
- ctx["SSL.Local.Host"] = IceInternal::inetAddrToString(info.localAddr.sin_addr);
- if(!info.certs.empty())
- {
- try
- {
- ctx["SSL.PeerCert"] = info.certs[0]->encode();
- }
- catch(const IceSSL::CertificateEncodingException&)
- {
- }
- }
- }
- catch(const IceSSL::ConnectionInvalidException&)
- {
- }
+ sslinfo.remotePort = ntohs(info.remoteAddr.sin_port);
+ sslinfo.remoteHost = IceInternal::inetAddrToString(info.remoteAddr.sin_addr);
+ sslinfo.localPort = ntohs(info.localAddr.sin_port);
+ sslinfo.localHost = IceInternal::inetAddrToString(info.localAddr.sin_addr);
- try
- {
- //
- // Check the user-id and password.
- //
- string reason;
- bool ok;
+ sslinfo.cipher = info.cipher;
- try
- {
- ok = _verifier->checkPermissions(userId, password, reason, ctx);
- }
- catch(const Exception& ex)
+ if(info.certs.size() > 0)
{
- if(_sessionTraceLevel >= 1)
+ sslinfo.certs.resize(info.certs.size());
+ for(unsigned int i = 0; i < info.certs.size(); ++i)
{
- Trace out(_logger, "Glacier2");
- out << "exception while verifying password\n" << ex;
+ sslinfo.certs[i] = info.certs[i]->encode();
}
-
- PermissionDeniedException exc;
- exc.reason = "internal server error";
- throw exc;
- }
-
- if(!ok)
- {
- PermissionDeniedException exc;
- exc.reason = reason;
- throw exc;
+ userDN = info.certs[0]->getSubjectDN();
}
}
- catch(const Exception& ex)
- {
- IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);
-
- //
- // Signal other threads that we are done with trying to
- // establish a session for our connection;
- //
- _pending.erase(current.con);
- notify();
-
- ex.ice_throw();
- }
-
-
- SessionPrx session;
- Identity controlId;
- RouterIPtr router;
-
- try
+ catch(const IceSSL::ConnectionInvalidException&)
{
- //
- // If we have a session manager configured, we create a
- // client-visible session object.
- //
- if(_sessionManager)
- {
- SessionControlPrx control;
- if(_adminAdapter)
- {
- control = SessionControlPrx::uncheckedCast(
- _adminAdapter->addWithUUID(new SessionControlI(this, current.con)));
- controlId = control->ice_getIdentity();
- }
- session = _sessionManager->create(userId, control, ctx);
- }
-
- //
- // Add a new per-client router.
- //
- router = new RouterI(_clientAdapter, _serverAdapter, _adminAdapter, current.con, userId, session, controlId);
+ PermissionDeniedException exc;
+ exc.reason = "not ssl connection";
+ throw exc;
}
- catch(const Exception& ex)
+ catch(const IceSSL::CertificateEncodingException&)
{
- IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);
-
- //
- // Signal other threads that we are done with trying to
- // establish a session for our connection;
- //
- _pending.erase(current.con);
- notify();
-
- assert(!router);
-
- if(session)
- {
- try
- {
- session->destroy();
- }
- catch(const Exception&)
- {
- // Ignore all exceptions here.
- }
- }
-
- ex.ice_throw();
+ PermissionDeniedException exc;
+ exc.reason = "certificate encoding exception";
+ throw exc;
}
+ SessionFactoryPtr factory;
+ if(_sslSessionManager)
{
- IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);
-
- //
- // Signal other threads that we are done with trying to
- // establish a session for our connection;
- //
- _pending.erase(current.con);
- notify();
-
- if(_destroy)
- {
- try
- {
- router->destroy();
- }
- catch(const Exception&)
- {
- // Ignore all exceptions here.
- }
-
- current.con->close(true);
- throw ObjectNotExistException(__FILE__, __LINE__);
- }
-
- _routersByConnectionHint = _routersByConnection.insert(
- _routersByConnectionHint, pair<const ConnectionPtr, RouterIPtr>(current.con, router));
-
- if(_serverAdapter)
- {
- string category = router->getServerProxy(current)->ice_getIdentity().category;
- assert(!category.empty());
- pair<map<string, RouterIPtr>::iterator, bool> rc =
- _routersByCategory.insert(pair<const string, RouterIPtr>(category, router));
- assert(rc.second);
- _routersByCategoryHint = rc.first;
- }
-
- if(_sessionTraceLevel >= 1)
- {
- Trace out(_logger, "Glacier2");
- out << "created session\n";
- out << router->toString();
- }
+ factory = new SSLSessionFactory(_sslSessionManager, sslinfo);
}
-
- return session;
+ return createSessionInternal(userDN, false, new SSLPasswordAuthorizer(_sslVerifier, sslinfo), factory, current);
}
-
void
Glacier2::SessionRouterI::destroySession(const Current& current)
{
@@ -749,6 +639,246 @@ Glacier2::SessionRouterI::expireSessions()
}
}
+SessionPrx
+Glacier2::SessionRouterI::createSessionInternal(const string& userId, bool allowAddUserMode,
+ const AuthorizerPtr& authorizer, const SessionFactoryPtr& factory,
+ const Current& current)
+{
+ {
+ IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);
+
+ if(_destroy)
+ {
+ current.con->close(true);
+ throw ObjectNotExistException(__FILE__, __LINE__);
+ }
+
+ //
+ // Check whether a session already exists for the connection.
+ //
+ {
+ map<ConnectionPtr, RouterIPtr>::iterator p;
+ if(_routersByConnectionHint != _routersByConnection.end() &&
+ _routersByConnectionHint->first == current.con)
+ {
+ p = _routersByConnectionHint;
+ }
+ else
+ {
+ p = _routersByConnection.find(current.con);
+ }
+
+ if(p != _routersByConnection.end())
+ {
+ CannotCreateSessionException exc;
+ exc.reason = "session exists";
+ throw exc;
+ }
+ }
+
+ //
+ // If some other thread is currently trying to create a
+ // session, we wait until this thread is finished.
+ //
+ bool searchAgain = false;
+ while(_pending.find(current.con) != _pending.end())
+ {
+ wait();
+
+ if(_destroy)
+ {
+ current.con->close(true);
+ throw ObjectNotExistException(__FILE__, __LINE__);
+ }
+
+ searchAgain = true;
+ }
+
+ //
+ // Check for existing sessions again if we waited above, as
+ // new sessions have been added in the meantime.
+ //
+ if(searchAgain)
+ {
+ map<ConnectionPtr, RouterIPtr>::iterator p;
+ if(_routersByConnectionHint != _routersByConnection.end() &&
+ _routersByConnectionHint->first == current.con)
+ {
+ p = _routersByConnectionHint;
+ }
+ else
+ {
+ p = _routersByConnection.find(current.con);
+ }
+
+ if(p != _routersByConnection.end())
+ {
+ CannotCreateSessionException exc;
+ exc.reason = "session exists";
+ throw exc;
+ }
+ }
+
+ //
+ // No session exists yet, so we will try to create one. To
+ // avoid that other threads try to create sessions for the
+ // same connection, we add our endpoints to _pending.
+ //
+ _pending.insert(current.con);
+ }
+
+ try
+ {
+ //
+ // Authorize.
+ //
+ string reason;
+ bool ok;
+
+ try
+ {
+ ok = authorizer->authorize(reason, current.ctx);
+ }
+ catch(const Exception& ex)
+ {
+ if(_sessionTraceLevel >= 1)
+ {
+ Trace out(_logger, "Glacier2");
+ out << "exception while verifying password\n" << ex;
+ }
+
+ PermissionDeniedException exc;
+ exc.reason = "internal server error";
+ throw exc;
+ }
+
+ if(!ok)
+ {
+ PermissionDeniedException exc;
+ exc.reason = reason;
+ throw exc;
+ }
+ }
+ catch(const Exception& ex)
+ {
+ IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);
+
+ //
+ // Signal other threads that we are done with trying to
+ // establish a session for our connection;
+ //
+ _pending.erase(current.con);
+ notify();
+
+ ex.ice_throw();
+ }
+
+
+ SessionPrx session;
+ Identity controlId;
+ RouterIPtr router;
+
+ try
+ {
+ //
+ // If we have a session manager configured, we create a
+ // client-visible session object.
+ //
+ if(factory)
+ {
+ SessionControlPrx control;
+ if(_adminAdapter)
+ {
+ control = SessionControlPrx::uncheckedCast(
+ _adminAdapter->addWithUUID(new SessionControlI(this, current.con)));
+ controlId = control->ice_getIdentity();
+ }
+ session = factory->create(control, current.ctx);
+ }
+
+ //
+ // Add a new per-client router.
+ //
+ router = new RouterI(_clientAdapter, _serverAdapter, _adminAdapter, current.con, userId, allowAddUserMode,
+ session, controlId);
+ }
+ catch(const Exception& ex)
+ {
+ IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);
+
+ //
+ // Signal other threads that we are done with trying to
+ // establish a session for our connection;
+ //
+ _pending.erase(current.con);
+ notify();
+
+ assert(!router);
+
+ if(session)
+ {
+ try
+ {
+ session->destroy();
+ }
+ catch(const Exception&)
+ {
+ // Ignore all exceptions here.
+ }
+ }
+
+ ex.ice_throw();
+ }
+
+ {
+ IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);
+
+ //
+ // Signal other threads that we are done with trying to
+ // establish a session for our connection;
+ //
+ _pending.erase(current.con);
+ notify();
+
+ if(_destroy)
+ {
+ try
+ {
+ router->destroy();
+ }
+ catch(const Exception&)
+ {
+ // Ignore all exceptions here.
+ }
+
+ current.con->close(true);
+ throw ObjectNotExistException(__FILE__, __LINE__);
+ }
+
+ _routersByConnectionHint = _routersByConnection.insert(
+ _routersByConnectionHint, pair<const ConnectionPtr, RouterIPtr>(current.con, router));
+
+ if(_serverAdapter)
+ {
+ string category = router->getServerProxy(current)->ice_getIdentity().category;
+ assert(!category.empty());
+ pair<map<string, RouterIPtr>::iterator, bool> rc =
+ _routersByCategory.insert(pair<const string, RouterIPtr>(category, router));
+ assert(rc.second);
+ _routersByCategoryHint = rc.first;
+ }
+
+ if(_sessionTraceLevel >= 1)
+ {
+ Trace out(_logger, "Glacier2");
+ out << "created session\n";
+ out << router->toString();
+ }
+ }
+
+ return session;
+}
+
Glacier2::SessionRouterI::SessionThread::SessionThread(const SessionRouterIPtr& sessionRouter,
const IceUtil::Time& sessionTimeout) :
_sessionRouter(sessionRouter),