redo security (aka. access control)
Break up monolithic SecurityPlugin API into three parts. 1. Authentication. 2. Authorization. 3. Access Control decision. Left to ChannelProviders
This commit is contained in:
@@ -201,14 +201,15 @@ public:
|
||||
protected:
|
||||
ServerChannelRequesterImpl(Transport::shared_pointer const & transport,
|
||||
const std::string channelName,
|
||||
const pvAccessID cid, ChannelSecuritySession::shared_pointer const & css);
|
||||
const pvAccessID cid);
|
||||
public:
|
||||
virtual ~ServerChannelRequesterImpl() {}
|
||||
static ChannelRequester::shared_pointer create(ChannelProvider::shared_pointer const & provider,
|
||||
Transport::shared_pointer const & transport, const std::string channelName,
|
||||
const pvAccessID cid, ChannelSecuritySession::shared_pointer const & css);
|
||||
const pvAccessID cid);
|
||||
virtual void channelCreated(const epics::pvData::Status& status, Channel::shared_pointer const & channel) OVERRIDE FINAL;
|
||||
virtual void channelStateChange(Channel::shared_pointer const & c, const Channel::ConnectionState isConnected) OVERRIDE FINAL;
|
||||
virtual std::tr1::shared_ptr<const PeerInfo> getPeerInfo() OVERRIDE FINAL;
|
||||
virtual std::string getRequesterName() OVERRIDE FINAL;
|
||||
virtual void message(std::string const & message, epics::pvData::MessageType messageType) OVERRIDE FINAL;
|
||||
virtual void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control) OVERRIDE FINAL;
|
||||
@@ -217,7 +218,6 @@ private:
|
||||
std::tr1::weak_ptr<detail::BlockingServerTCPTransportCodec> _transport;
|
||||
const std::string _channelName;
|
||||
const pvAccessID _cid;
|
||||
ChannelSecuritySession::shared_pointer const & _css;
|
||||
epics::pvData::Status _status;
|
||||
epics::pvData::Mutex _mutex;
|
||||
};
|
||||
|
||||
@@ -33,8 +33,7 @@ public:
|
||||
*/
|
||||
ServerChannel(Channel::shared_pointer const & channel,
|
||||
const ChannelRequester::shared_pointer& requester,
|
||||
pvAccessID cid, pvAccessID sid,
|
||||
ChannelSecuritySession::shared_pointer const & css);
|
||||
pvAccessID cid, pvAccessID sid);
|
||||
~ServerChannel();
|
||||
|
||||
const Channel::shared_pointer& getChannel() const { return _channel; }
|
||||
@@ -43,9 +42,6 @@ public:
|
||||
|
||||
pvAccessID getSID() const { return _sid; }
|
||||
|
||||
ChannelSecuritySession::shared_pointer getChannelSecuritySession() const
|
||||
{ return _channelSecuritySession; }
|
||||
|
||||
void registerRequest(pvAccessID id, const std::tr1::shared_ptr<BaseChannelRequester>& request);
|
||||
|
||||
void unregisterRequest(pvAccessID id);
|
||||
@@ -77,8 +73,6 @@ private:
|
||||
bool _destroyed;
|
||||
|
||||
mutable epics::pvData::Mutex _mutex;
|
||||
|
||||
const ChannelSecuritySession::shared_pointer _channelSecuritySession;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -51,7 +51,6 @@ public:
|
||||
Transport::shared_pointer getSearchTransport() OVERRIDE FINAL;
|
||||
Configuration::const_shared_pointer getConfiguration() OVERRIDE FINAL;
|
||||
TransportRegistry* getTransportRegistry() OVERRIDE FINAL;
|
||||
const securityPlugins_t& getSecurityPlugins() OVERRIDE FINAL;
|
||||
|
||||
virtual void newServerDetected() OVERRIDE FINAL;
|
||||
|
||||
|
||||
@@ -194,15 +194,30 @@ void ServerConnectionValidationHandler::handleResponse(
|
||||
std::string securityPluginName = SerializeHelper::deserializeString(payloadBuffer, transport.get());
|
||||
|
||||
// optional authNZ plug-in initialization data
|
||||
PVField::shared_pointer data;
|
||||
if (payloadBuffer->getRemaining())
|
||||
data = SerializationHelper::deserializeFull(payloadBuffer, transport.get());
|
||||
PVStructure::shared_pointer data;
|
||||
if (payloadBuffer->getRemaining()) {
|
||||
PVField::shared_pointer raw(SerializationHelper::deserializeFull(payloadBuffer, transport.get()));
|
||||
if(raw && raw->getField()->getType()==structure) {
|
||||
data = std::tr1::static_pointer_cast<PVStructure>(raw);
|
||||
} else {
|
||||
// was originally allowed, but never used
|
||||
}
|
||||
}
|
||||
|
||||
detail::BlockingServerTCPTransportCodec* casTransport(static_cast<detail::BlockingServerTCPTransportCodec*>(transport.get()));
|
||||
//TODO: simplify byzantine class heirarchy...
|
||||
assert(casTransport);
|
||||
|
||||
casTransport->authNZInitialize(securityPluginName, data);
|
||||
try {
|
||||
casTransport->authNZInitialize(securityPluginName, data);
|
||||
}catch(std::exception& e){
|
||||
if (IS_LOGGABLE(logLevelDebug))
|
||||
{
|
||||
LOG(logLevelDebug, "Security plug-in '%s' failed to create a session for PVA client: %s.", securityPluginName.c_str(), casTransport->getRemoteName().c_str());
|
||||
}
|
||||
casTransport->verified(pvData::Status::error(e.what()));
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -732,30 +747,13 @@ void ServerCreateChannelHandler::handleResponse(osiSockAddr* responseFrom,
|
||||
return;
|
||||
}
|
||||
|
||||
SecuritySession::shared_pointer securitySession = transport->getSecuritySession();
|
||||
ChannelSecuritySession::shared_pointer css;
|
||||
try {
|
||||
css = securitySession->createChannelSession(channelName);
|
||||
if (!css)
|
||||
throw SecurityException("null channelSecuritySession");
|
||||
} catch (SecurityException& se) {
|
||||
// TODO use std::make_shared
|
||||
std::tr1::shared_ptr<ServerChannelRequesterImpl> tp(new ServerChannelRequesterImpl(transport, channelName, cid, css));
|
||||
ChannelRequester::shared_pointer cr = tp;
|
||||
|
||||
Status asStatus(Status::STATUSTYPE_ERROR,
|
||||
string("Insufficient rights to create a channel: ") + se.what());
|
||||
cr->channelCreated(asStatus, Channel::shared_pointer());
|
||||
return;
|
||||
}
|
||||
|
||||
if (channelName == SERVER_CHANNEL_NAME)
|
||||
{
|
||||
// TODO singleton!!!
|
||||
ServerRPCService::shared_pointer serverRPCService(new ServerRPCService(_context));
|
||||
|
||||
// TODO use std::make_shared
|
||||
std::tr1::shared_ptr<ServerChannelRequesterImpl> tp(new ServerChannelRequesterImpl(transport, channelName, cid, css));
|
||||
std::tr1::shared_ptr<ServerChannelRequesterImpl> tp(new ServerChannelRequesterImpl(transport, channelName, cid));
|
||||
ChannelRequester::shared_pointer cr = tp;
|
||||
Channel::shared_pointer serverChannel = createRPCChannel(ChannelProvider::shared_pointer(), channelName, cr, serverRPCService);
|
||||
cr->channelCreated(Status::Ok, serverChannel);
|
||||
@@ -766,7 +764,7 @@ void ServerCreateChannelHandler::handleResponse(osiSockAddr* responseFrom,
|
||||
ServerContextImpl::s_channelNameToProvider_t::const_iterator it;
|
||||
|
||||
if (_providers.size() == 1)
|
||||
ServerChannelRequesterImpl::create(_providers[0], transport, channelName, cid, css);
|
||||
ServerChannelRequesterImpl::create(_providers[0], transport, channelName, cid);
|
||||
else {
|
||||
ChannelProvider::shared_pointer prov;
|
||||
{
|
||||
@@ -775,7 +773,7 @@ void ServerCreateChannelHandler::handleResponse(osiSockAddr* responseFrom,
|
||||
prov = it->second.lock();
|
||||
}
|
||||
if(prov)
|
||||
ServerChannelRequesterImpl::create(prov, transport, channelName, cid, css);
|
||||
ServerChannelRequesterImpl::create(prov, transport, channelName, cid);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -786,12 +784,11 @@ void ServerCreateChannelHandler::disconnect(Transport::shared_pointer const & tr
|
||||
}
|
||||
|
||||
ServerChannelRequesterImpl::ServerChannelRequesterImpl(const Transport::shared_pointer &transport,
|
||||
const string channelName, const pvAccessID cid, ChannelSecuritySession::shared_pointer const & css) :
|
||||
const string channelName, const pvAccessID cid) :
|
||||
_serverChannel(),
|
||||
_transport(std::tr1::static_pointer_cast<detail::BlockingServerTCPTransportCodec>(transport)),
|
||||
_channelName(channelName),
|
||||
_cid(cid),
|
||||
_css(css),
|
||||
_status(),
|
||||
_mutex()
|
||||
{
|
||||
@@ -799,10 +796,10 @@ ServerChannelRequesterImpl::ServerChannelRequesterImpl(const Transport::shared_p
|
||||
|
||||
ChannelRequester::shared_pointer ServerChannelRequesterImpl::create(
|
||||
ChannelProvider::shared_pointer const & provider, Transport::shared_pointer const & transport,
|
||||
const string channelName, const pvAccessID cid, ChannelSecuritySession::shared_pointer const & css)
|
||||
const string channelName, const pvAccessID cid)
|
||||
{
|
||||
// TODO use std::make_shared
|
||||
std::tr1::shared_ptr<ServerChannelRequesterImpl> tp(new ServerChannelRequesterImpl(transport, channelName, cid, css));
|
||||
std::tr1::shared_ptr<ServerChannelRequesterImpl> tp(new ServerChannelRequesterImpl(transport, channelName, cid));
|
||||
ChannelRequester::shared_pointer cr = tp;
|
||||
// TODO exception guard and report error back
|
||||
provider->createChannel(channelName, cr, transport->getPriority());
|
||||
@@ -824,7 +821,7 @@ void ServerChannelRequesterImpl::channelCreated(const Status& status, Channel::s
|
||||
pvAccessID sid = transport->preallocateChannelSID();
|
||||
try
|
||||
{
|
||||
serverChannel.reset(new ServerChannel(channel, shared_from_this(), _cid, sid, _css));
|
||||
serverChannel.reset(new ServerChannel(channel, shared_from_this(), _cid, sid));
|
||||
|
||||
// ack allocation and register
|
||||
transport->registerChannel(sid, serverChannel);
|
||||
@@ -836,11 +833,6 @@ void ServerChannelRequesterImpl::channelCreated(const Status& status, Channel::s
|
||||
throw;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_css)
|
||||
_css->close();
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
@@ -861,9 +853,6 @@ void ServerChannelRequesterImpl::channelCreated(const Status& status, Channel::s
|
||||
}
|
||||
TransportSender::shared_pointer thisSender = shared_from_this();
|
||||
transport->enqueueSendRequest(thisSender);
|
||||
// TODO make sure that serverChannel gets destroyed
|
||||
if (_css)
|
||||
_css->close();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
@@ -874,9 +863,6 @@ void ServerChannelRequesterImpl::channelCreated(const Status& status, Channel::s
|
||||
}
|
||||
TransportSender::shared_pointer thisSender = shared_from_this();
|
||||
transport->enqueueSendRequest(thisSender);
|
||||
// TODO make sure that serverChannel gets destroyed
|
||||
if (_css)
|
||||
_css->close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -909,6 +895,17 @@ void ServerChannelRequesterImpl::channelStateChange(Channel::shared_pointer cons
|
||||
}
|
||||
}
|
||||
|
||||
std::tr1::shared_ptr<const PeerInfo> ServerChannelRequesterImpl::getPeerInfo()
|
||||
{
|
||||
if(detail::BlockingServerTCPTransportCodec::shared_pointer transport = _transport.lock()) {
|
||||
epicsGuard<epicsMutex> G(transport->_mutex);
|
||||
return transport->_peerInfo;
|
||||
|
||||
} else {
|
||||
return std::tr1::shared_ptr<const PeerInfo>();
|
||||
}
|
||||
}
|
||||
|
||||
string ServerChannelRequesterImpl::getRequesterName()
|
||||
{
|
||||
detail::BlockingServerTCPTransportCodec::shared_pointer transport = _transport.lock();
|
||||
|
||||
@@ -18,14 +18,12 @@ size_t ServerChannel::num_instances;
|
||||
|
||||
ServerChannel::ServerChannel(Channel::shared_pointer const & channel,
|
||||
const ChannelRequester::shared_pointer &requester,
|
||||
pvAccessID cid, pvAccessID sid,
|
||||
ChannelSecuritySession::shared_pointer const & css):
|
||||
pvAccessID cid, pvAccessID sid):
|
||||
_channel(channel),
|
||||
_requester(requester),
|
||||
_cid(cid),
|
||||
_sid(sid),
|
||||
_destroyed(false),
|
||||
_channelSecuritySession(css)
|
||||
_destroyed(false)
|
||||
{
|
||||
REFTRACE_INCREMENT(num_instances);
|
||||
if (!channel.get())
|
||||
@@ -76,10 +74,6 @@ void ServerChannel::destroy()
|
||||
// removal via unregisterRequest() during iteration
|
||||
_requests.swap(reqs);
|
||||
|
||||
// close channel security session
|
||||
// TODO try catch
|
||||
_channelSecuritySession->close();
|
||||
|
||||
// ... and the channel
|
||||
// TODO try catch
|
||||
_channel->destroy();
|
||||
|
||||
@@ -533,12 +533,6 @@ epicsTimeStamp& ServerContextImpl::getStartTime()
|
||||
return _startTime;
|
||||
}
|
||||
|
||||
|
||||
const Context::securityPlugins_t& ServerContextImpl::getSecurityPlugins()
|
||||
{
|
||||
return SecurityPluginRegistry::instance().getServerSecurityPlugins();
|
||||
}
|
||||
|
||||
ServerContext::shared_pointer startPVAServer(std::string const & providerNames, int timeToRun, bool runInSeparateThread, bool printInfo)
|
||||
{
|
||||
ServerContext::shared_pointer ret(ServerContext::create(ServerContext::Config()
|
||||
|
||||
Reference in New Issue
Block a user