From d8f9ef2557557189b63e6b267748883a74ca2973 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Thu, 24 Jan 2019 09:06:30 -0800 Subject: [PATCH] make PeerInfo available during search phase --- src/client/pv/pvAccess.h | 28 ++++++++++++++++++++++++++-- src/server/pv/responseHandlers.h | 11 +++++++---- src/server/responseHandlers.cpp | 15 ++++++++++++--- 3 files changed, 45 insertions(+), 9 deletions(-) diff --git a/src/client/pv/pvAccess.h b/src/client/pv/pvAccess.h index 66edf75..888a4e5 100644 --- a/src/client/pv/pvAccess.h +++ b/src/client/pv/pvAccess.h @@ -393,6 +393,8 @@ public: static ChannelFind::shared_pointer buildDummy(const std::tr1::shared_ptr& provider); }; +struct PeerInfo; // see pv/security.h + /** * */ @@ -410,6 +412,30 @@ public: const epics::pvData::Status& status, ChannelFind::shared_pointer const & channelFind, bool wasFound) = 0; + + /** + * @brief Return information on requesting peer if applicable. + * + * A server-type ChannelProvider will use this method to discover if a remote client + * has provided credentials which may be used in access control decisions. + * + * The returned PeerInfo is only required to have valid values for: peer, transport, and transportVersion. + * PeerInfo::authority may be empty if authentication has not yet occured (UDP search). + * + * Default implementation returns NULL. + * + * isConnected()==true and getPeerInfo()==NULL when the ChannelProvider does not provide + * information about the peer. This should be treated as an unauthenticated, anonymous, + * peer. + * + * The returned instance must not change, and a different instance should be returned + * if/when peer information changes (eg. after reconnect). + * + * May return !NULL when !isConnected(). getPeerInfo() must be called _before_ + * testing isConnected() in situations where connection state is being polled. + */ + virtual std::tr1::shared_ptr getPeerInfo() + { return std::tr1::shared_ptr(); } }; /** @@ -819,8 +845,6 @@ public: }; -struct PeerInfo; // see pv/security.h - class ChannelRequester; /** diff --git a/src/server/pv/responseHandlers.h b/src/server/pv/responseHandlers.h index 5e6ee74..aec3d07 100644 --- a/src/server/pv/responseHandlers.h +++ b/src/server/pv/responseHandlers.h @@ -135,7 +135,9 @@ class ServerChannelFindRequesterImpl: public std::tr1::enable_shared_from_this { public: - ServerChannelFindRequesterImpl(ServerContextImpl::shared_pointer const & context, epics::pvData::int32 expectedResponseCount); + ServerChannelFindRequesterImpl(ServerContextImpl::shared_pointer const & context, + const PeerInfo::const_shared_pointer& peer, + epics::pvData::int32 expectedResponseCount); virtual ~ServerChannelFindRequesterImpl() {} void clear(); ServerChannelFindRequesterImpl* set(std::string _name, epics::pvData::int32 searchSequenceId, @@ -155,9 +157,10 @@ private: osiSockAddr _sendTo; bool _responseRequired; bool _wasFound; - ServerContextImpl::shared_pointer _context; - epics::pvData::Mutex _mutex; - epics::pvData::int32 _expectedResponseCount; + const ServerContextImpl::shared_pointer _context; + const PeerInfo::const_shared_pointer& _peer; + mutable epics::pvData::Mutex _mutex; + const epics::pvData::int32 _expectedResponseCount; epics::pvData::int32 _responseCount; bool _serverSearch; }; diff --git a/src/server/responseHandlers.cpp b/src/server/responseHandlers.cpp index a5fc1d4..7d3f455 100644 --- a/src/server/responseHandlers.cpp +++ b/src/server/responseHandlers.cpp @@ -335,6 +335,14 @@ void ServerSearchHandler::handleResponse(osiSockAddr* responseFrom, } } + PeerInfo::shared_pointer info; + if(allowed) { + info.reset(new PeerInfo); + info->transport = "pva"; + info->peer = transport->getRemoteName(); + info->transportVersion = transport->getRevision(); + } + if (count > 0) { // regular name search @@ -350,7 +358,7 @@ void ServerSearchHandler::handleResponse(osiSockAddr* responseFrom, const std::vector& _providers = _context->getChannelProviders(); int providerCount = _providers.size(); - std::tr1::shared_ptr tp(new ServerChannelFindRequesterImpl(_context, providerCount)); + std::tr1::shared_ptr tp(new ServerChannelFindRequesterImpl(_context, info, providerCount)); tp->set(name, searchSequenceId, cid, responseAddress, responseRequired, false); for (int i = 0; i < providerCount; i++) @@ -368,7 +376,7 @@ void ServerSearchHandler::handleResponse(osiSockAddr* responseFrom, double delay = double(rand())/RAND_MAX; // [0, 1] delay = delay*0.1 + 0.05; - std::tr1::shared_ptr tp(new ServerChannelFindRequesterImpl(_context, 1)); + std::tr1::shared_ptr tp(new ServerChannelFindRequesterImpl(_context, info, 1)); tp->set("", searchSequenceId, 0, responseAddress, true, true); TimerCallback::shared_pointer tc = tp; @@ -377,12 +385,13 @@ void ServerSearchHandler::handleResponse(osiSockAddr* responseFrom, } } -ServerChannelFindRequesterImpl::ServerChannelFindRequesterImpl(ServerContextImpl::shared_pointer const & context, +ServerChannelFindRequesterImpl::ServerChannelFindRequesterImpl(ServerContextImpl::shared_pointer const & context, const PeerInfo::const_shared_pointer &peer, int32 expectedResponseCount) : _guid(context->getGUID()), _sendTo(), _wasFound(false), _context(context), + _peer(peer), _expectedResponseCount(expectedResponseCount), _responseCount(0), _serverSearch(false)