diff options
Diffstat (limited to 'qpid/cpp/src/qpid/acl/AclData.cpp')
-rw-r--r-- | qpid/cpp/src/qpid/acl/AclData.cpp | 261 |
1 files changed, 261 insertions, 0 deletions
diff --git a/qpid/cpp/src/qpid/acl/AclData.cpp b/qpid/cpp/src/qpid/acl/AclData.cpp new file mode 100644 index 0000000000..658529b270 --- /dev/null +++ b/qpid/cpp/src/qpid/acl/AclData.cpp @@ -0,0 +1,261 @@ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "qpid/acl/AclData.h" +#include "qpid/log/Statement.h" +#include "qpid/sys/IntegerTypes.h" +#include <boost/lexical_cast.hpp> + +namespace qpid { +namespace acl { + +AclData::AclData():decisionMode(qpid::acl::DENY),transferAcl(false),aclSource("UNKNOWN") +{ + for (unsigned int cnt=0; cnt< qpid::acl::ACTIONSIZE; cnt++){ + actionList[cnt]=0; + } + +} + +void AclData::clear () +{ + for (unsigned int cnt=0; cnt< qpid::acl::ACTIONSIZE; cnt++){ + if (actionList[cnt]){ + for (unsigned int cnt1=0; cnt1< qpid::acl::OBJECTSIZE; cnt1++) + delete actionList[cnt][cnt1]; + } + delete[] actionList[cnt]; + } + +} + +bool AclData::matchProp(const std::string & src, const std::string& src1) +{ + // allow wildcard on the end of strings... + if (src.data()[src.size()-1]=='*') { + return (src.compare(0, src.size()-1, src1, 0,src.size()-1 ) == 0); + } else { + return (src.compare(src1)==0) ; + } +} + +AclResult AclData::lookup(const std::string& id, const Action& action, const ObjectType& objType, + const std::string& name, std::map<Property, std::string>* params) { + + QPID_LOG(debug, "ACL: Lookup for id:" << id << " action:" << AclHelper::getActionStr((Action) action) + << " objectType:" << AclHelper::getObjectTypeStr((ObjectType) objType) << " name:" << name + << " with params " << AclHelper::propertyMapToString(params)); + + AclResult aclresult = decisionMode; + if (actionList[action] && actionList[action][objType]) { + AclData::actObjItr itrRule = actionList[action][objType]->find(id); + if (itrRule == actionList[action][objType]->end()) + itrRule = actionList[action][objType]->find("*"); + + if (itrRule != actionList[action][objType]->end()) { + + QPID_LOG(debug, "ACL: checking the following rules for : " << itrRule->first ); + + //loop the vector + for (ruleSetItr i = itrRule->second.begin(); i < itrRule->second.end(); i++) { + QPID_LOG(debug, "ACL: checking rule " << i->toString()); + // loop the names looking for match + bool match = true; + for (propertyMapItr pMItr = i->props.begin(); (pMItr != i->props.end()) && match; pMItr++) { + //match name is exists first + if (pMItr->first == acl::PROP_NAME) { + if (matchProp(pMItr->second, name)){ + QPID_LOG(debug, "ACL: name '" << name << "' matched with name '" + << pMItr->second << "' given in the rule"); + }else{ + match = false; + QPID_LOG(debug, "ACL: name '" << name << "' didn't match with name '" + << pMItr->second << "' given in the rule"); + } + } else if (params) { //match pMItr against params + propertyMapItr paramItr = params->find(pMItr->first); + if (paramItr == params->end()) { + match = false; + QPID_LOG(debug, "ACL: the given parameter map in lookup doesn't contain the property '" + << AclHelper::getPropertyStr(pMItr->first) << "'"); + }else if ( pMItr->first == acl::PROP_MAXQUEUECOUNT || pMItr->first == acl::PROP_MAXQUEUESIZE ) { + if ( pMItr->first == paramItr->first ) { + + uint64_t aclMax = 0; + uint64_t paramMax = 0; + + try{ + aclMax = boost::lexical_cast<uint64_t>(pMItr->second); + }catch(const boost::bad_lexical_cast&){ + match = false; + QPID_LOG(error,"Error evaluating rule. " << + "Illegal value given in ACL source <" << aclSource << + "> for property '" << + AclHelper::getPropertyStr(pMItr->first) << "' : " << + boost::lexical_cast<std::string>(pMItr->second)); + break; + } + + try{ + paramMax = boost::lexical_cast<uint64_t>(paramItr->second); + }catch(const boost::bad_lexical_cast&){ + match = false; + QPID_LOG(error,"Error evaluating rule. " << + "Illegal value given in lookup for property '" << + AclHelper::getPropertyStr(pMItr->first) << "' : " << + boost::lexical_cast<std::string>(paramItr->second)); + break; + } + + QPID_LOG(debug, "ACL: Numeric comparison for property " << + AclHelper::getPropertyStr(paramItr->first) << + " (value given in lookup = " << + boost::lexical_cast<std::string>(paramItr->second) << + ", value give in rule = " << + boost::lexical_cast<std::string>(pMItr->second) << " )"); + + if (( aclMax ) && ( paramMax == 0 || paramMax > aclMax)){ + match = decisionMode == qpid::acl::ALLOW ; + QPID_LOG(debug, "ACL: Limit exceeded and match=" << + (match ? "true": "false") << + " as decision mode is " << AclHelper::getAclResultStr(decisionMode)); + } + } + }else if (matchProp(pMItr->second, paramItr->second)) { + QPID_LOG(debug, "ACL: the pair(" + << AclHelper::getPropertyStr(paramItr->first) << "," << paramItr->second + << ") given in lookup matched the pair(" + << AclHelper::getPropertyStr(pMItr->first) << "," << pMItr->second << ") given in the rule"); + } else { + QPID_LOG(debug, "ACL: the pair(" + << AclHelper::getPropertyStr(paramItr->first) << "," << paramItr->second + << ") given in lookup doesn't match the pair(" + << AclHelper::getPropertyStr(pMItr->first) << "," << pMItr->second << ") given in the rule"); + match = false; + } + } + } + if (match) + { + aclresult = getACLResult(i->logOnly, i->log); + QPID_LOG(debug,"Successful match, the decision is:" << AclHelper::getAclResultStr(aclresult)); + return aclresult; + } + } + } + } + + QPID_LOG(debug,"No successful match, defaulting to the decision mode " << AclHelper::getAclResultStr(aclresult)); + return aclresult; +} + +AclResult AclData::lookup(const std::string& id, const Action& action, const ObjectType& objType, const std::string& /*Exchange*/ name, const std::string& RoutingKey) +{ + + QPID_LOG(debug, "ACL: Lookup for id:" << id << " action:" << AclHelper::getActionStr((Action) action) + << " objectType:" << AclHelper::getObjectTypeStr((ObjectType) objType) << " exchange name:" << name + << " with routing key " << RoutingKey); + + AclResult aclresult = decisionMode; + + if (actionList[action] && actionList[action][objType]){ + AclData::actObjItr itrRule = actionList[action][objType]->find(id); + + if (itrRule == actionList[action][objType]->end()) + itrRule = actionList[action][objType]->find("*"); + + if (itrRule != actionList[action][objType]->end() ) { + + QPID_LOG(debug, "ACL: checking the following rules for : " << itrRule->first ); + + //loop the vector + for (ruleSetItr i=itrRule->second.begin(); i<itrRule->second.end(); i++) { + QPID_LOG(debug, "ACL: checking rule " << i->toString()); + + // loop the names looking for match + bool match =true; + for (propertyMapItr pMItr = i->props.begin(); (pMItr != i->props.end()) && match; pMItr++) + { + //match name is exists first + if (pMItr->first == acl::PROP_NAME){ + if (matchProp(pMItr->second, name)){ + QPID_LOG(debug, "ACL: name '" << name << "' matched with name '" + << pMItr->second << "' given in the rule"); + + }else{ + match= false; + QPID_LOG(debug, "ACL: name '" << name << "' didn't match with name '" + << pMItr->second << "' given in the rule"); + } + }else if (pMItr->first == acl::PROP_ROUTINGKEY){ + if (matchProp(pMItr->second, RoutingKey)){ + QPID_LOG(debug, "ACL: name '" << name << "' matched with routing_key '" + << pMItr->second << "' given in the rule"); + }else{ + match= false; + QPID_LOG(debug, "ACL: name '" << name << "' didn't match with routing_key '" + << pMItr->second << "' given in the rule"); + } + } + } + if (match){ + aclresult = getACLResult(i->logOnly, i->log); + QPID_LOG(debug,"Successful match, the decision is:" << AclHelper::getAclResultStr(aclresult)); + return aclresult; + } + } + } + } + QPID_LOG(debug,"No successful match, defaulting to the decision mode " << AclHelper::getAclResultStr(aclresult)); + return aclresult; + +} + + +AclResult AclData::getACLResult(bool logOnly, bool log) +{ + switch (decisionMode) + { + case qpid::acl::ALLOWLOG: + case qpid::acl::ALLOW: + if (logOnly) return qpid::acl::ALLOWLOG; + if (log) + return qpid::acl::DENYLOG; + else + return qpid::acl::DENY; + + + case qpid::acl::DENYLOG: + case qpid::acl::DENY: + if (logOnly) return qpid::acl::DENYLOG; + if (log) + return qpid::acl::ALLOWLOG; + else + return qpid::acl::ALLOW; + } + + QPID_LOG(error, "ACL Decision Failed, setting DENY"); + return qpid::acl::DENY; +} + +AclData::~AclData() +{ + clear(); +} + +}} |