summaryrefslogtreecommitdiff
path: root/cpp/src/IceSSL/TrustManager.cpp
diff options
context:
space:
mode:
authorMark Spruiell <mes@zeroc.com>2009-08-03 15:34:00 -0700
committerMark Spruiell <mes@zeroc.com>2009-08-03 15:34:00 -0700
commite54654cf238a719e5ed7632defe397931beb569f (patch)
tree52ee683eed4232cb5e06c0f2013af2b13060edf2 /cpp/src/IceSSL/TrustManager.cpp
parent4171 - Global namespace pollution (diff)
downloadice-e54654cf238a719e5ed7632defe397931beb569f.tar.bz2
ice-e54654cf238a719e5ed7632defe397931beb569f.tar.xz
ice-e54654cf238a719e5ed7632defe397931beb569f.zip
bug 4087 - anti-trust rule in IceSSL
Diffstat (limited to 'cpp/src/IceSSL/TrustManager.cpp')
-rw-r--r--cpp/src/IceSSL/TrustManager.cpp125
1 files changed, 99 insertions, 26 deletions
diff --git a/cpp/src/IceSSL/TrustManager.cpp b/cpp/src/IceSSL/TrustManager.cpp
index dbafb0a2aac..cc36d651ddc 100644
--- a/cpp/src/IceSSL/TrustManager.cpp
+++ b/cpp/src/IceSSL/TrustManager.cpp
@@ -31,17 +31,26 @@ TrustManager::TrustManager(const Ice::CommunicatorPtr& communicator) :
try
{
key = "IceSSL.TrustOnly";
- _all = parse(properties->getProperty(key));
+ parse(properties->getProperty(key), _rejectAll, _acceptAll);
key = "IceSSL.TrustOnly.Client";
- _client = parse(properties->getProperty(key));
+ parse(properties->getProperty(key), _rejectClient, _acceptClient);
key = "IceSSL.TrustOnly.Server";
- _allServer = parse(properties->getProperty(key));
+ parse(properties->getProperty(key), _rejectAllServer, _acceptAllServer);
Ice::PropertyDict dict = properties->getPropertiesForPrefix("IceSSL.TrustOnly.Server.");
for(Ice::PropertyDict::const_iterator p = dict.begin(); p != dict.end(); ++p)
{
string name = p->first.substr(string("IceSSL.TrustOnly.Server.").size());
key = p->first;
- _server[name] = parse(p->second);
+ list<DistinguishedName> reject, accept;
+ parse(p->second, reject, accept);
+ if(!reject.empty())
+ {
+ _rejectServer[name] = reject;
+ }
+ if(!accept.empty())
+ {
+ _acceptServer[name] = accept;
+ }
}
}
catch(const ParseException& e)
@@ -55,39 +64,66 @@ TrustManager::TrustManager(const Ice::CommunicatorPtr& communicator) :
bool
TrustManager::verify(const ConnectionInfo& info)
{
- list<list<DistinguishedName> > trustset;
- if(_all.size() > 0)
+ list<list<DistinguishedName> > reject, accept;
+
+ if(_rejectAll.size() > 0)
{
- trustset.push_back(_all);
+ reject.push_back(_rejectAll);
+ }
+ if(info.incoming)
+ {
+ if(_rejectAllServer.size() > 0)
+ {
+ reject.push_back(_rejectAllServer);
+ }
+ if(info.adapterName.size() > 0)
+ {
+ map<string, list<DistinguishedName> >::const_iterator p = _rejectServer.find(info.adapterName);
+ if(p != _rejectServer.end())
+ {
+ reject.push_back(p->second);
+ }
+ }
+ }
+ else
+ {
+ if(_rejectClient.size() > 0)
+ {
+ reject.push_back(_rejectClient);
+ }
}
+ if(_acceptAll.size() > 0)
+ {
+ accept.push_back(_acceptAll);
+ }
if(info.incoming)
{
- if(_allServer.size() > 0)
+ if(_acceptAllServer.size() > 0)
{
- trustset.push_back(_allServer);
+ accept.push_back(_acceptAllServer);
}
if(info.adapterName.size() > 0)
{
- map<string, list<DistinguishedName> >::const_iterator p = _server.find(info.adapterName);
- if(p != _server.end())
+ map<string, list<DistinguishedName> >::const_iterator p = _acceptServer.find(info.adapterName);
+ if(p != _acceptServer.end())
{
- trustset.push_back(p->second);
+ accept.push_back(p->second);
}
}
}
else
{
- if(_client.size() > 0)
+ if(_acceptClient.size() > 0)
{
- trustset.push_back(_client);
+ accept.push_back(_acceptClient);
}
}
//
// If there is nothing to match against, then we accept the cert.
//
- if(trustset.size() == 0)
+ if(reject.empty() && accept.empty())
{
return true;
}
@@ -141,16 +177,42 @@ TrustManager::verify(const ConnectionInfo& info)
}
}
}
-
+
+ list<list<DistinguishedName> >::const_iterator p;
+
//
- // Try matching against everything in the trust set.
+ // Fail if we match anything in the reject set.
//
- for(list<list<DistinguishedName> >::const_iterator p = trustset.begin(); p != trustset.end(); ++p)
+ for(p = reject.begin(); p != reject.end(); ++p)
{
if(_traceLevel > 1)
{
Ice::Trace trace(_communicator->getLogger(), "Security");
- trace << "trust manager matching PDNs:\n";
+ trace << "trust manager rejecting PDNs:\n";
+ for(list<DistinguishedName>::const_iterator r = p->begin(); r != p->end(); ++r)
+ {
+ if(r != p->begin())
+ {
+ trace << ';';
+ }
+ trace << string(*r);
+ }
+ }
+ if(match(*p, subject))
+ {
+ return false;
+ }
+ }
+
+ //
+ // Succeed if we match anything in the accept set.
+ //
+ for(p = accept.begin(); p != accept.end(); ++p)
+ {
+ if(_traceLevel > 1)
+ {
+ Ice::Trace trace(_communicator->getLogger(), "Security");
+ trace << "trust manager accepting PDNs:\n";
for(list<DistinguishedName>::const_iterator r = p->begin(); r != p->end(); ++r)
{
if(r != p->begin())
@@ -165,6 +227,11 @@ TrustManager::verify(const ConnectionInfo& info)
return true;
}
}
+
+ //
+ // At this point we accept the connection if there are no explicit accept rules.
+ //
+ return accept.empty();
}
return false;
@@ -183,17 +250,23 @@ TrustManager::match(const list< DistinguishedName>& matchSet, const Distinguishe
return false;
}
-list<DistinguishedName>
-TrustManager::parse(const string& value) const
+void
+TrustManager::parse(const string& value, list<DistinguishedName>& reject, list<DistinguishedName>& accept) const
{
- list<DistinguishedName> result;
if(!value.empty())
{
- RFC2253::RDNSeqSeq dns = RFC2253::parse(value);
- for(RFC2253::RDNSeqSeq::const_iterator p = dns.begin(); p != dns.end(); ++p)
+ RFC2253::RDNEntrySeq dns = RFC2253::parse(value);
+
+ for(RFC2253::RDNEntrySeq::const_iterator p = dns.begin(); p != dns.end(); ++p)
{
- result.push_back(DistinguishedName(*p));
+ if(p->negate)
+ {
+ reject.push_back(DistinguishedName(p->rdn));
+ }
+ else
+ {
+ accept.push_back(DistinguishedName(p->rdn));
+ }
}
}
- return result;
}