diff options
author | Charles E. Rolke <chug@apache.org> | 2012-02-17 17:16:33 +0000 |
---|---|---|
committer | Charles E. Rolke <chug@apache.org> | 2012-02-17 17:16:33 +0000 |
commit | 1b56500400c5f846c8f828af3385b035b63f8f66 (patch) | |
tree | 4454c23619b028968a072ba9feb4828723b7dcf7 /cpp/src/qpid | |
parent | 5b18da896e9889e1e9382d7f6ebcfe8012d95aef (diff) | |
download | qpid-python-1b56500400c5f846c8f828af3385b035b63f8f66.tar.gz |
NO-JIRA ACL whitespace police.
No code change.
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@1245660 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/src/qpid')
-rw-r--r-- | cpp/src/qpid/acl/Acl.cpp | 220 | ||||
-rw-r--r-- | cpp/src/qpid/acl/AclData.cpp | 458 | ||||
-rw-r--r-- | cpp/src/qpid/acl/AclData.h | 92 | ||||
-rw-r--r-- | cpp/src/qpid/acl/AclReader.cpp | 932 | ||||
-rw-r--r-- | cpp/src/qpid/acl/AclValidator.cpp | 232 | ||||
-rw-r--r-- | cpp/src/qpid/broker/AclModule.h | 449 |
6 files changed, 1191 insertions, 1192 deletions
diff --git a/cpp/src/qpid/acl/Acl.cpp b/cpp/src/qpid/acl/Acl.cpp index 4b3dda7962..12bf13018c 100644 --- a/cpp/src/qpid/acl/Acl.cpp +++ b/cpp/src/qpid/acl/Acl.cpp @@ -49,7 +49,7 @@ namespace _qmf = qmf::org::apache::qpid::acl; Acl::Acl (AclValues& av, Broker& b): aclValues(av), broker(&b), transferAcl(false), mgmtObject(0) { - + agent = broker->getManagementAgent(); if (agent != 0){ @@ -63,129 +63,129 @@ Acl::Acl (AclValues& av, Broker& b): aclValues(av), broker(&b), transferAcl(fals if (mgmtObject!=0) mgmtObject->set_enforcingAcl(0); } QPID_LOG(info, "ACL Plugin loaded"); - if (mgmtObject!=0) mgmtObject->set_enforcingAcl(1); + if (mgmtObject!=0) mgmtObject->set_enforcingAcl(1); } - bool Acl::authorise(const std::string& id, const Action& action, const ObjectType& objType, const std::string& name, std::map<Property, std::string>* params) - { - boost::shared_ptr<AclData> dataLocal; - { +bool Acl::authorise(const std::string& id, const Action& action, const ObjectType& objType, const std::string& name, std::map<Property, std::string>* params) +{ + boost::shared_ptr<AclData> dataLocal; + { Mutex::ScopedLock locker(dataLock); dataLocal = data; //rcu copy - } + } - // add real ACL check here... - AclResult aclreslt = dataLocal->lookup(id,action,objType,name,params); + // add real ACL check here... + AclResult aclreslt = dataLocal->lookup(id,action,objType,name,params); - return result(aclreslt, id, action, objType, name); - } + return result(aclreslt, id, action, objType, name); +} - bool Acl::authorise(const std::string& id, const Action& action, const ObjectType& objType, const std::string& ExchangeName, const std::string& RoutingKey) - { - boost::shared_ptr<AclData> dataLocal; - { +bool Acl::authorise(const std::string& id, const Action& action, const ObjectType& objType, const std::string& ExchangeName, const std::string& RoutingKey) +{ + boost::shared_ptr<AclData> dataLocal; + { Mutex::ScopedLock locker(dataLock); dataLocal = data; //rcu copy - } - - // only use dataLocal here... - AclResult aclreslt = dataLocal->lookup(id,action,objType,ExchangeName,RoutingKey); - - return result(aclreslt, id, action, objType, ExchangeName); - } - - - bool Acl::result(const AclResult& aclreslt, const std::string& id, const Action& action, const ObjectType& objType, const std::string& name) - { - switch (aclreslt) - { - case ALLOWLOG: - QPID_LOG(info, "ACL Allow id:" << id <<" action:" << AclHelper::getActionStr(action) << - " ObjectType:" << AclHelper::getObjectTypeStr(objType) << " Name:" << name ); - agent->raiseEvent(_qmf::EventAllow(id, AclHelper::getActionStr(action), - AclHelper::getObjectTypeStr(objType), - name, types::Variant::Map())); - case ALLOW: - return true; - case DENY: - if (mgmtObject!=0) mgmtObject->inc_aclDenyCount(); - return false; - case DENYLOG: - if (mgmtObject!=0) mgmtObject->inc_aclDenyCount(); - default: - QPID_LOG(info, "ACL Deny id:" << id << " action:" << AclHelper::getActionStr(action) << " ObjectType:" << AclHelper::getObjectTypeStr(objType) << " Name:" << name); - agent->raiseEvent(_qmf::EventDeny(id, AclHelper::getActionStr(action), - AclHelper::getObjectTypeStr(objType), - name, types::Variant::Map())); - return false; - } - return false; - } - - bool Acl::readAclFile(std::string& errorText) - { - // only set transferAcl = true if a rule implies the use of ACL on transfer, else keep false for performance reasons. - return readAclFile(aclValues.aclFile, errorText); - } - - bool Acl::readAclFile(std::string& aclFile, std::string& errorText) { - boost::shared_ptr<AclData> d(new AclData); - AclReader ar; - if (ar.read(aclFile, d)){ - agent->raiseEvent(_qmf::EventFileLoadFailed("", ar.getError())); - errorText = ar.getError(); - QPID_LOG(error,ar.getError()); - return false; - } - - AclValidator validator; - validator.validate(d); - - { + } + + // only use dataLocal here... + AclResult aclreslt = dataLocal->lookup(id,action,objType,ExchangeName,RoutingKey); + + return result(aclreslt, id, action, objType, ExchangeName); +} + + +bool Acl::result(const AclResult& aclreslt, const std::string& id, const Action& action, const ObjectType& objType, const std::string& name) +{ + switch (aclreslt) + { + case ALLOWLOG: + QPID_LOG(info, "ACL Allow id:" << id <<" action:" << AclHelper::getActionStr(action) << + " ObjectType:" << AclHelper::getObjectTypeStr(objType) << " Name:" << name ); + agent->raiseEvent(_qmf::EventAllow(id, AclHelper::getActionStr(action), + AclHelper::getObjectTypeStr(objType), + name, types::Variant::Map())); + case ALLOW: + return true; + case DENY: + if (mgmtObject!=0) mgmtObject->inc_aclDenyCount(); + return false; + case DENYLOG: + if (mgmtObject!=0) mgmtObject->inc_aclDenyCount(); + default: + QPID_LOG(info, "ACL Deny id:" << id << " action:" << AclHelper::getActionStr(action) << " ObjectType:" << AclHelper::getObjectTypeStr(objType) << " Name:" << name); + agent->raiseEvent(_qmf::EventDeny(id, AclHelper::getActionStr(action), + AclHelper::getObjectTypeStr(objType), + name, types::Variant::Map())); + return false; + } + return false; +} + +bool Acl::readAclFile(std::string& errorText) +{ + // only set transferAcl = true if a rule implies the use of ACL on transfer, else keep false for performance reasons. + return readAclFile(aclValues.aclFile, errorText); +} + +bool Acl::readAclFile(std::string& aclFile, std::string& errorText) { + boost::shared_ptr<AclData> d(new AclData); + AclReader ar; + if (ar.read(aclFile, d)){ + agent->raiseEvent(_qmf::EventFileLoadFailed("", ar.getError())); + errorText = ar.getError(); + QPID_LOG(error,ar.getError()); + return false; + } + + AclValidator validator; + validator.validate(d); + + { Mutex::ScopedLock locker(dataLock); data = d; - } - transferAcl = data->transferAcl; // any transfer ACL + } + transferAcl = data->transferAcl; // any transfer ACL - if (data->transferAcl){ + if (data->transferAcl){ QPID_LOG(debug,"Transfer ACL is Enabled!"); - } - - data->aclSource = aclFile; - if (mgmtObject!=0){ - mgmtObject->set_transferAcl(transferAcl?1:0); - mgmtObject->set_policyFile(aclFile); - sys::AbsTime now = sys::AbsTime::now(); - int64_t ns = sys::Duration(sys::EPOCH, now); - mgmtObject->set_lastAclLoad(ns); - agent->raiseEvent(_qmf::EventFileLoaded("")); - } - return true; - } - - Acl::~Acl(){} - - ManagementObject* Acl::GetManagementObject(void) const - { - return (ManagementObject*) mgmtObject; - } - - Manageable::status_t Acl::ManagementMethod (uint32_t methodId, Args& /*args*/, string& text) - { - Manageable::status_t status = Manageable::STATUS_UNKNOWN_METHOD; - QPID_LOG (debug, "Queue::ManagementMethod [id=" << methodId << "]"); - - switch (methodId) - { - case _qmf::Acl::METHOD_RELOADACLFILE : - readAclFile(text); - if (text.empty()) - status = Manageable::STATUS_OK; - else - status = Manageable::STATUS_USER; - break; - } + } + + data->aclSource = aclFile; + if (mgmtObject!=0){ + mgmtObject->set_transferAcl(transferAcl?1:0); + mgmtObject->set_policyFile(aclFile); + sys::AbsTime now = sys::AbsTime::now(); + int64_t ns = sys::Duration(sys::EPOCH, now); + mgmtObject->set_lastAclLoad(ns); + agent->raiseEvent(_qmf::EventFileLoaded("")); + } + return true; +} + +Acl::~Acl(){} + +ManagementObject* Acl::GetManagementObject(void) const +{ + return (ManagementObject*) mgmtObject; +} + +Manageable::status_t Acl::ManagementMethod (uint32_t methodId, Args& /*args*/, string& text) +{ + Manageable::status_t status = Manageable::STATUS_UNKNOWN_METHOD; + QPID_LOG (debug, "Queue::ManagementMethod [id=" << methodId << "]"); + + switch (methodId) + { + case _qmf::Acl::METHOD_RELOADACLFILE : + readAclFile(text); + if (text.empty()) + status = Manageable::STATUS_OK; + else + status = Manageable::STATUS_USER; + break; + } return status; } diff --git a/cpp/src/qpid/acl/AclData.cpp b/cpp/src/qpid/acl/AclData.cpp index 658529b270..06fc223a73 100644 --- a/cpp/src/qpid/acl/AclData.cpp +++ b/cpp/src/qpid/acl/AclData.cpp @@ -24,238 +24,238 @@ 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); + AclData::AclData():decisionMode(qpid::acl::DENY),transferAcl(false),aclSource("UNKNOWN") + { + for (unsigned int cnt=0; cnt< qpid::acl::ACTIONSIZE; cnt++){ + actionList[cnt]=0; + } - 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; + } + + 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)); } - } - } - } - QPID_LOG(debug,"No successful match, defaulting to the decision mode " << AclHelper::getAclResultStr(aclresult)); + } + }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(); -} + } + + + 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(); + } }} diff --git a/cpp/src/qpid/acl/AclData.h b/cpp/src/qpid/acl/AclData.h index efd3b60145..81125fdcbc 100644 --- a/cpp/src/qpid/acl/AclData.h +++ b/cpp/src/qpid/acl/AclData.h @@ -32,53 +32,53 @@ class AclData { public: - typedef std::map<qpid::acl::Property, std::string> propertyMap; - typedef propertyMap::const_iterator propertyMapItr; - struct rule { - - bool log; - bool logOnly; // this is a rule is to log only - - // key value map - //?? - propertyMap props; - - - rule (propertyMap& p):log(false),logOnly(false),props(p) {}; - - std::string toString () const { - std::ostringstream ruleStr; - ruleStr << "[log=" << log << ", logOnly=" << logOnly << " props{"; - for (propertyMapItr pMItr = props.begin(); pMItr != props.end(); pMItr++) { - ruleStr << " " << AclHelper::getPropertyStr((Property) pMItr-> first) << "=" << pMItr->second; - } - ruleStr << " }]"; - return ruleStr.str(); - } - }; - typedef std::vector<rule> ruleSet; - typedef ruleSet::const_iterator ruleSetItr; - typedef std::map<std::string, ruleSet > actionObject; // user - typedef actionObject::iterator actObjItr; - typedef actionObject* aclAction; - - // Action*[] -> Object*[] -> map<user -> set<Rule> > - aclAction* actionList[qpid::acl::ACTIONSIZE]; - qpid::acl::AclResult decisionMode; // determines if the rule set is a deny or allow mode. - bool transferAcl; - std::string aclSource; - - AclResult lookup(const std::string& id, const Action& action, const ObjectType& objType, const std::string& name, std::map<Property, std::string>* params=0); - AclResult lookup(const std::string& id, const Action& action, const ObjectType& objType, const std::string& ExchangeName, const std::string& RoutingKey); - AclResult getACLResult(bool logOnly, bool log); - - bool matchProp(const std::string & src, const std::string& src1); - void clear (); - - AclData(); - virtual ~AclData(); + typedef std::map<qpid::acl::Property, std::string> propertyMap; + typedef propertyMap::const_iterator propertyMapItr; + struct rule { + + bool log; + bool logOnly; // this is a rule is to log only + + // key value map + //?? + propertyMap props; + + + rule (propertyMap& p):log(false),logOnly(false),props(p) {}; + + std::string toString () const { + std::ostringstream ruleStr; + ruleStr << "[log=" << log << ", logOnly=" << logOnly << " props{"; + for (propertyMapItr pMItr = props.begin(); pMItr != props.end(); pMItr++) { + ruleStr << " " << AclHelper::getPropertyStr((Property) pMItr-> first) << "=" << pMItr->second; + } + ruleStr << " }]"; + return ruleStr.str(); + } + }; + typedef std::vector<rule> ruleSet; + typedef ruleSet::const_iterator ruleSetItr; + typedef std::map<std::string, ruleSet > actionObject; // user + typedef actionObject::iterator actObjItr; + typedef actionObject* aclAction; + + // Action*[] -> Object*[] -> map<user -> set<Rule> > + aclAction* actionList[qpid::acl::ACTIONSIZE]; + qpid::acl::AclResult decisionMode; // determines if the rule set is a deny or allow mode. + bool transferAcl; + std::string aclSource; + + AclResult lookup(const std::string& id, const Action& action, const ObjectType& objType, const std::string& name, std::map<Property, std::string>* params=0); + AclResult lookup(const std::string& id, const Action& action, const ObjectType& objType, const std::string& ExchangeName, const std::string& RoutingKey); + AclResult getACLResult(bool logOnly, bool log); + + bool matchProp(const std::string & src, const std::string& src1); + void clear (); + + AclData(); + virtual ~AclData(); }; - + }} // namespace qpid::acl #endif // QPID_ACL_ACLDATA_H diff --git a/cpp/src/qpid/acl/AclReader.cpp b/cpp/src/qpid/acl/AclReader.cpp index 31c69e69b5..74358a20c1 100644 --- a/cpp/src/qpid/acl/AclReader.cpp +++ b/cpp/src/qpid/acl/AclReader.cpp @@ -33,549 +33,549 @@ namespace qpid { namespace acl { -AclReader::aclRule::aclRule(const AclResult r, const std::string n, const groupMap& groups) : res(r), actionAll(true), objStatus(NONE) { - processName(n, groups); -} -AclReader::aclRule::aclRule(const AclResult r, const std::string n, const groupMap& groups, const Action a) : res(r), actionAll(false), action(a), objStatus(NONE) { - processName(n, groups); -} - -void AclReader::aclRule::setObjectType(const ObjectType o) { - objStatus = VALUE; - object = o; -} - -void AclReader::aclRule::setObjectTypeAll() { - objStatus = ALL; -} - -bool AclReader::aclRule::addProperty(const Property p, const std::string v) { - return props.insert(propNvPair(p, v)).second; -} - -bool AclReader::aclRule::validate(const AclHelper::objectMapPtr& /*validationMap*/) { - // TODO - invalid rules won't ever be called in real life... - return true; -} - -// Debug aid -std::string AclReader::aclRule::toString() { - std::ostringstream oss; - oss << AclHelper::getAclResultStr(res) << " ["; - for (nsCitr itr = names.begin(); itr != names.end(); itr++) { - if (itr != names.begin()) oss << ", "; - oss << *itr; + AclReader::aclRule::aclRule(const AclResult r, const std::string n, const groupMap& groups) : res(r), actionAll(true), objStatus(NONE) { + processName(n, groups); } - oss << "]"; - if (actionAll) { - oss << " *"; - } else { - oss << " " << AclHelper::getActionStr(action); + AclReader::aclRule::aclRule(const AclResult r, const std::string n, const groupMap& groups, const Action a) : res(r), actionAll(false), action(a), objStatus(NONE) { + processName(n, groups); } - if (objStatus == ALL) { - oss << " *"; - } else if (objStatus == VALUE) { - oss << " " << AclHelper::getObjectTypeStr(object); + + void AclReader::aclRule::setObjectType(const ObjectType o) { + objStatus = VALUE; + object = o; + } + + void AclReader::aclRule::setObjectTypeAll() { + objStatus = ALL; + } + + bool AclReader::aclRule::addProperty(const Property p, const std::string v) { + return props.insert(propNvPair(p, v)).second; } - for (pmCitr i=props.begin(); i!=props.end(); i++) { - oss << " " << AclHelper::getPropertyStr(i->first) << "=" << i->second; + + bool AclReader::aclRule::validate(const AclHelper::objectMapPtr& /*validationMap*/) { + // TODO - invalid rules won't ever be called in real life... + return true; } - return oss.str(); -} - -void AclReader::loadDecisionData(boost::shared_ptr<AclData> d) { - d->clear(); - QPID_LOG(debug, "ACL Load Rules"); - int cnt = rules.size(); - bool foundmode = false; - - for (rlCitr i = rules.end(); cnt; cnt--) { - i--; - QPID_LOG(debug, "ACL Processing " << std::setfill(' ') << std::setw(2) - << cnt << " " << (*i)->toString()); - - if (!foundmode && (*i)->actionAll && (*i)->names.size() == 1 - && (*((*i)->names.begin())).compare("*") == 0) { - d->decisionMode = (*i)->res; - QPID_LOG(debug, "ACL FoundMode " - << AclHelper::getAclResultStr(d->decisionMode)); - foundmode = true; + + // Debug aid + std::string AclReader::aclRule::toString() { + std::ostringstream oss; + oss << AclHelper::getAclResultStr(res) << " ["; + for (nsCitr itr = names.begin(); itr != names.end(); itr++) { + if (itr != names.begin()) oss << ", "; + oss << *itr; + } + oss << "]"; + if (actionAll) { + oss << " *"; } else { - AclData::rule rule((*i)->props); - bool addrule = true; - - switch ((*i)->res) { - case qpid::acl::ALLOWLOG: - rule.log = true; - if (d->decisionMode == qpid::acl::ALLOW || - d->decisionMode == qpid::acl::ALLOWLOG) - rule.logOnly = true; - break; - case qpid::acl::ALLOW: - if (d->decisionMode == qpid::acl::ALLOW || - d->decisionMode == qpid::acl::ALLOWLOG) - addrule = false; - break; - case qpid::acl::DENYLOG: - rule.log = true; - if (d->decisionMode == qpid::acl::DENY || - d->decisionMode == qpid::acl::DENYLOG) - rule.logOnly = true; - break; - case qpid::acl::DENY: - if (d->decisionMode == qpid::acl::DENY || - d->decisionMode == qpid::acl::DENYLOG) - addrule = false; - break; - default: - throw Exception("Invalid ACL Result loading rules."); - } + oss << " " << AclHelper::getActionStr(action); + } + if (objStatus == ALL) { + oss << " *"; + } else if (objStatus == VALUE) { + oss << " " << AclHelper::getObjectTypeStr(object); + } + for (pmCitr i=props.begin(); i!=props.end(); i++) { + oss << " " << AclHelper::getPropertyStr(i->first) << "=" << i->second; + } + return oss.str(); + } - // Action -> Object -> map<user -> set<Rule> > - if (addrule) { - std::ostringstream actionstr; - for (int acnt = ((*i)->actionAll ? 0 : (*i)->action); - acnt < acl::ACTIONSIZE; - (*i)->actionAll ? acnt++ : acnt = acl::ACTIONSIZE) { + void AclReader::loadDecisionData(boost::shared_ptr<AclData> d) { + d->clear(); + QPID_LOG(debug, "ACL Load Rules"); + int cnt = rules.size(); + bool foundmode = false; + + for (rlCitr i = rules.end(); cnt; cnt--) { + i--; + QPID_LOG(debug, "ACL Processing " << std::setfill(' ') << std::setw(2) + << cnt << " " << (*i)->toString()); + + if (!foundmode && (*i)->actionAll && (*i)->names.size() == 1 + && (*((*i)->names.begin())).compare("*") == 0) { + d->decisionMode = (*i)->res; + QPID_LOG(debug, "ACL FoundMode " + << AclHelper::getAclResultStr(d->decisionMode)); + foundmode = true; + } else { + AclData::rule rule((*i)->props); + bool addrule = true; + + switch ((*i)->res) { + case qpid::acl::ALLOWLOG: + rule.log = true; + if (d->decisionMode == qpid::acl::ALLOW || + d->decisionMode == qpid::acl::ALLOWLOG) + rule.logOnly = true; + break; + case qpid::acl::ALLOW: + if (d->decisionMode == qpid::acl::ALLOW || + d->decisionMode == qpid::acl::ALLOWLOG) + addrule = false; + break; + case qpid::acl::DENYLOG: + rule.log = true; + if (d->decisionMode == qpid::acl::DENY || + d->decisionMode == qpid::acl::DENYLOG) + rule.logOnly = true; + break; + case qpid::acl::DENY: + if (d->decisionMode == qpid::acl::DENY || + d->decisionMode == qpid::acl::DENYLOG) + addrule = false; + break; + default: + throw Exception("Invalid ACL Result loading rules."); + } - if (acnt == acl::ACT_PUBLISH) - d->transferAcl = true; // we have transfer ACL + // Action -> Object -> map<user -> set<Rule> > + if (addrule) { + std::ostringstream actionstr; + for (int acnt = ((*i)->actionAll ? 0 : (*i)->action); + acnt < acl::ACTIONSIZE; + (*i)->actionAll ? acnt++ : acnt = acl::ACTIONSIZE) { - actionstr << AclHelper::getActionStr((Action) acnt) << ","; + if (acnt == acl::ACT_PUBLISH) + d->transferAcl = true; // we have transfer ACL - //find the Action, create if not exist - if (d->actionList[acnt] == NULL) { - d->actionList[acnt] = - new AclData::aclAction[qpid::acl::OBJECTSIZE]; - for (int j = 0; j < qpid::acl::OBJECTSIZE; j++) - d->actionList[acnt][j] = NULL; - } + actionstr << AclHelper::getActionStr((Action) acnt) << ","; - // optimize this loop to limit to valid options only!! - for (int ocnt = ((*i)->objStatus != aclRule::VALUE ? 0 - : (*i)->object); - ocnt < acl::OBJECTSIZE; - (*i)->objStatus != aclRule::VALUE ? ocnt++ : ocnt = acl::OBJECTSIZE) { - - //find the Object, create if not exist - if (d->actionList[acnt][ocnt] == NULL) - d->actionList[acnt][ocnt] = - new AclData::actionObject; - - // add users and Rule to object set - bool allNames = false; - // check to see if names.begin is '*' - if ((*(*i)->names.begin()).compare("*") == 0) - allNames = true; - - for (nsCitr itr = (allNames ? names.begin() - : (*i)->names.begin()); - itr != (allNames ? names.end() : (*i)->names.end()); - itr++) { - - AclData::actObjItr itrRule = - d->actionList[acnt][ocnt]->find(*itr); - - if (itrRule == d->actionList[acnt][ocnt]->end()) { - AclData::ruleSet rSet; - rSet.push_back(rule); - d->actionList[acnt][ocnt]->insert - (make_pair(std::string(*itr), rSet)); - } else { - // TODO add code to check for dead rules - // allow peter create queue name=tmp <-- dead rule!! - // allow peter create queue - - itrRule->second.push_back(rule); + //find the Action, create if not exist + if (d->actionList[acnt] == NULL) { + d->actionList[acnt] = + new AclData::aclAction[qpid::acl::OBJECTSIZE]; + for (int j = 0; j < qpid::acl::OBJECTSIZE; j++) + d->actionList[acnt][j] = NULL; } - } + // optimize this loop to limit to valid options only!! + for (int ocnt = ((*i)->objStatus != aclRule::VALUE ? 0 + : (*i)->object); + ocnt < acl::OBJECTSIZE; + (*i)->objStatus != aclRule::VALUE ? ocnt++ : ocnt = acl::OBJECTSIZE) { + + //find the Object, create if not exist + if (d->actionList[acnt][ocnt] == NULL) + d->actionList[acnt][ocnt] = + new AclData::actionObject; + + // add users and Rule to object set + bool allNames = false; + // check to see if names.begin is '*' + if ((*(*i)->names.begin()).compare("*") == 0) + allNames = true; + + for (nsCitr itr = (allNames ? names.begin() + : (*i)->names.begin()); + itr != (allNames ? names.end() : (*i)->names.end()); + itr++) { + + AclData::actObjItr itrRule = + d->actionList[acnt][ocnt]->find(*itr); + + if (itrRule == d->actionList[acnt][ocnt]->end()) { + AclData::ruleSet rSet; + rSet.push_back(rule); + d->actionList[acnt][ocnt]->insert + (make_pair(std::string(*itr), rSet)); + } else { + // TODO add code to check for dead rules + // allow peter create queue name=tmp <-- dead rule!! + // allow peter create queue + + itrRule->second.push_back(rule); + } + } + + } } - } - std::ostringstream objstr; - for (int ocnt = ((*i)->objStatus != aclRule::VALUE ? 0 : (*i)->object); - ocnt < acl::OBJECTSIZE; - (*i)->objStatus != aclRule::VALUE ? ocnt++ : ocnt = acl::OBJECTSIZE) { - objstr << AclHelper::getObjectTypeStr((ObjectType) ocnt) << ","; - } + std::ostringstream objstr; + for (int ocnt = ((*i)->objStatus != aclRule::VALUE ? 0 : (*i)->object); + ocnt < acl::OBJECTSIZE; + (*i)->objStatus != aclRule::VALUE ? ocnt++ : ocnt = acl::OBJECTSIZE) { + objstr << AclHelper::getObjectTypeStr((ObjectType) ocnt) << ","; + } - bool allNames = ((*(*i)->names.begin()).compare("*") == 0); - std::ostringstream userstr; - for (nsCitr itr = (allNames ? names.begin() : (*i)->names.begin()); - itr != (allNames ? names.end() : (*i)->names.end()); - itr++) { - userstr << *itr << ","; - } + bool allNames = ((*(*i)->names.begin()).compare("*") == 0); + std::ostringstream userstr; + for (nsCitr itr = (allNames ? names.begin() : (*i)->names.begin()); + itr != (allNames ? names.end() : (*i)->names.end()); + itr++) { + userstr << *itr << ","; + } - QPID_LOG(debug, "ACL: Adding actions {" << - actionstr.str().substr(0,actionstr.str().length()-1) - << "} to objects {" << - objstr.str().substr(0,objstr.str().length()-1) - << "} with props " << - AclHelper::propertyMapToString(&rule.props) - << " for users {" << - userstr.str().substr(0,userstr.str().length()-1) - << "}" ); - } else { - QPID_LOG(debug, "ACL Skipping based on Mode:" - << AclHelper::getAclResultStr(d->decisionMode)); + QPID_LOG(debug, "ACL: Adding actions {" << + actionstr.str().substr(0,actionstr.str().length()-1) + << "} to objects {" << + objstr.str().substr(0,objstr.str().length()-1) + << "} with props " << + AclHelper::propertyMapToString(&rule.props) + << " for users {" << + userstr.str().substr(0,userstr.str().length()-1) + << "}" ); + } else { + QPID_LOG(debug, "ACL Skipping based on Mode:" + << AclHelper::getAclResultStr(d->decisionMode)); + } } + } } -} - -void AclReader::aclRule::processName(const std::string& name, const groupMap& groups) { - if (name.compare("all") == 0) { - names.insert("*"); - } else { - gmCitr itr = groups.find(name); - if (itr == groups.end()) { - names.insert(name); + void AclReader::aclRule::processName(const std::string& name, const groupMap& groups) { + if (name.compare("all") == 0) { + names.insert("*"); } else { - names.insert(itr->second->begin(), itr->second->end()); + gmCitr itr = groups.find(name); + if (itr == groups.end()) { + names.insert(name); + } else { + names.insert(itr->second->begin(), itr->second->end()); + } } } -} - -AclReader::AclReader() : lineNumber(0), contFlag(false), validationMap(new AclHelper::objectMap) { - AclHelper::loadValidationMap(validationMap); - names.insert("*"); -} - -AclReader::~AclReader() {} - -std::string AclReader::getError() { - return errorStream.str(); -} - -int AclReader::read(const std::string& fn, boost::shared_ptr<AclData> d) { - fileName = fn; - lineNumber = 0; - char buff[1024]; - std::ifstream ifs(fn.c_str(), std::ios_base::in); - if (!ifs.good()) { - errorStream << "Unable to open ACL file \"" << fn << "\": eof=" << (ifs.eof()?"T":"F") << "; fail=" << (ifs.fail()?"T":"F") << "; bad=" << (ifs.bad()?"T":"F"); - return -1; + + AclReader::AclReader() : lineNumber(0), contFlag(false), validationMap(new AclHelper::objectMap) { + AclHelper::loadValidationMap(validationMap); + names.insert("*"); + } + + AclReader::~AclReader() {} + + std::string AclReader::getError() { + return errorStream.str(); } - try { - bool err = false; - while (ifs.good()) { - ifs.getline(buff, 1024); - lineNumber++; - if (std::strlen(buff) > 0 && buff[0] != '#') // Ignore blank lines and comments - err |= !processLine(buff); + + int AclReader::read(const std::string& fn, boost::shared_ptr<AclData> d) { + fileName = fn; + lineNumber = 0; + char buff[1024]; + std::ifstream ifs(fn.c_str(), std::ios_base::in); + if (!ifs.good()) { + errorStream << "Unable to open ACL file \"" << fn << "\": eof=" << (ifs.eof()?"T":"F") << "; fail=" << (ifs.fail()?"T":"F") << "; bad=" << (ifs.bad()?"T":"F"); + return -1; } - if (!ifs.eof()) - { - errorStream << "Unable to read ACL file \"" << fn << "\": eof=" << (ifs.eof()?"T":"F") << "; fail=" << (ifs.fail()?"T":"F") << "; bad=" << (ifs.bad()?"T":"F"); + try { + bool err = false; + while (ifs.good()) { + ifs.getline(buff, 1024); + lineNumber++; + if (std::strlen(buff) > 0 && buff[0] != '#') // Ignore blank lines and comments + err |= !processLine(buff); + } + if (!ifs.eof()) + { + errorStream << "Unable to read ACL file \"" << fn << "\": eof=" << (ifs.eof()?"T":"F") << "; fail=" << (ifs.fail()?"T":"F") << "; bad=" << (ifs.bad()?"T":"F"); + ifs.close(); + return -2; + } ifs.close(); - return -2; + if (err) return -3; + QPID_LOG(notice, "Read ACL file \"" << fn << "\""); + } catch (const std::exception& e) { + errorStream << "Unable to read ACL file \"" << fn << "\": " << e.what(); + ifs.close(); + return -4; + } catch (...) { + errorStream << "Unable to read ACL file \"" << fn << "\": Unknown exception"; + ifs.close(); + return -5; } - ifs.close(); - if (err) return -3; - QPID_LOG(notice, "Read ACL file \"" << fn << "\""); - } catch (const std::exception& e) { - errorStream << "Unable to read ACL file \"" << fn << "\": " << e.what(); - ifs.close(); - return -4; - } catch (...) { - errorStream << "Unable to read ACL file \"" << fn << "\": Unknown exception"; - ifs.close(); - return -5; - } - printNames(); - printRules(); - loadDecisionData(d); - - return 0; -} - -bool AclReader::processLine(char* line) { - bool ret = false; - std::vector<std::string> toks; - - // Check for continuation - char* contCharPtr = std::strrchr(line, '\\'); - bool cont = contCharPtr != 0; - if (cont) *contCharPtr = 0; - - int numToks = tokenize(line, toks); - - if (cont && numToks == 0){ - errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line \"" << lineNumber << "\" contains an illegal extension."; - return false; + printNames(); + printRules(); + loadDecisionData(d); + + return 0; } - if (numToks && (toks[0].compare("group") == 0 || contFlag)) { - ret = processGroupLine(toks, cont); - } else if (numToks && toks[0].compare("acl") == 0) { - ret = processAclLine(toks); - } else { - // Check for whitespace only line, ignore these - bool ws = true; - for (unsigned i=0; i<std::strlen(line) && ws; i++) { - if (!std::isspace(line[i])) ws = false; + bool AclReader::processLine(char* line) { + bool ret = false; + std::vector<std::string> toks; + + // Check for continuation + char* contCharPtr = std::strrchr(line, '\\'); + bool cont = contCharPtr != 0; + if (cont) *contCharPtr = 0; + + int numToks = tokenize(line, toks); + + if (cont && numToks == 0){ + errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line \"" << lineNumber << "\" contains an illegal extension."; + return false; } - if (ws) { - ret = true; + + if (numToks && (toks[0].compare("group") == 0 || contFlag)) { + ret = processGroupLine(toks, cont); + } else if (numToks && toks[0].compare("acl") == 0) { + ret = processAclLine(toks); } else { - errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber - << ", Non-continuation line must start with \"group\" or \"acl\"."; - ret = false; + // Check for whitespace only line, ignore these + bool ws = true; + for (unsigned i=0; i<std::strlen(line) && ws; i++) { + if (!std::isspace(line[i])) ws = false; + } + if (ws) { + ret = true; + } else { + errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber + << ", Non-continuation line must start with \"group\" or \"acl\"."; + ret = false; + } } + contFlag = cont; + return ret; } - contFlag = cont; - return ret; -} - -int AclReader::tokenize(char* line, std::vector<std::string>& toks) { - const char* tokChars = " \t\n\f\v\r"; - int cnt = 0; - char* cp = std::strtok(line, tokChars); - while (cp != 0) { - toks.push_back(std::string(cp)); - cnt++; - cp = std::strtok(0, tokChars); - } - return cnt; -} - -// Return true if the line is successfully processed without errors -// If cont is true, then groupName must be set to the continuation group name -bool AclReader::processGroupLine(tokList& toks, const bool cont) { - const unsigned toksSize = toks.size(); - - if (contFlag) { - gmCitr citr = groups.find(groupName); - for (unsigned i = 0; i < toksSize; i++) { - if (!isValidUserName(toks[i])) return false; - addName(toks[i], citr->second); + + int AclReader::tokenize(char* line, std::vector<std::string>& toks) { + const char* tokChars = " \t\n\f\v\r"; + int cnt = 0; + char* cp = std::strtok(line, tokChars); + while (cp != 0) { + toks.push_back(std::string(cp)); + cnt++; + cp = std::strtok(0, tokChars); } - } else { - const unsigned minimumSize = (cont ? 2 : 3); - if (toksSize < minimumSize) { - errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber - << ", Insufficient tokens for group definition."; - return false; + return cnt; + } + + // Return true if the line is successfully processed without errors + // If cont is true, then groupName must be set to the continuation group name + bool AclReader::processGroupLine(tokList& toks, const bool cont) { + const unsigned toksSize = toks.size(); + + if (contFlag) { + gmCitr citr = groups.find(groupName); + for (unsigned i = 0; i < toksSize; i++) { + if (!isValidUserName(toks[i])) return false; + addName(toks[i], citr->second); + } + } else { + const unsigned minimumSize = (cont ? 2 : 3); + if (toksSize < minimumSize) { + errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber + << ", Insufficient tokens for group definition."; + return false; + } + if (!isValidGroupName(toks[1])) { + errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber + << ", Group name \"" << toks[1] << "\" contains illegal characters."; + return false; + } + gmCitr citr = addGroup(toks[1]); + if (citr == groups.end()) return false; + for (unsigned i = 2; i < toksSize; i++) { + if (!isValidUserName(toks[i])) return false; + addName(toks[i], citr->second); + } } - if (!isValidGroupName(toks[1])) { + return true; + } + + // Return true if sucessfully added group + AclReader::gmCitr AclReader::addGroup(const std::string& newGroupName) { + gmCitr citr = groups.find(newGroupName); + if (citr != groups.end()) { errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber - << ", Group name \"" << toks[1] << "\" contains illegal characters."; - return false; - } - gmCitr citr = addGroup(toks[1]); - if (citr == groups.end()) return false; - for (unsigned i = 2; i < toksSize; i++) { - if (!isValidUserName(toks[i])) return false; - addName(toks[i], citr->second); + << ", Duplicate group name \"" << newGroupName << "\"."; + return groups.end(); } + groupPair p(newGroupName, nameSetPtr(new nameSet)); + gmRes res = groups.insert(p); + assert(res.second); + groupName = newGroupName; + return res.first; } - return true; -} - -// Return true if sucessfully added group -AclReader::gmCitr AclReader::addGroup(const std::string& newGroupName) { - gmCitr citr = groups.find(newGroupName); - if (citr != groups.end()) { - errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber - << ", Duplicate group name \"" << newGroupName << "\"."; - return groups.end(); + + void AclReader::addName(const std::string& name, nameSetPtr groupNameSet) { + gmCitr citr = groups.find(name); + if (citr != groups.end() && citr->first != name){ + // This is a previously defined group: add all the names in that group to this group + groupNameSet->insert(citr->second->begin(), citr->second->end()); + } else { + // Not a known group name + groupNameSet->insert(name); + addName(name); + } } - groupPair p(newGroupName, nameSetPtr(new nameSet)); - gmRes res = groups.insert(p); - assert(res.second); - groupName = newGroupName; - return res.first; -} - -void AclReader::addName(const std::string& name, nameSetPtr groupNameSet) { - gmCitr citr = groups.find(name); - if (citr != groups.end() && citr->first != name){ - // This is a previously defined group: add all the names in that group to this group - groupNameSet->insert(citr->second->begin(), citr->second->end()); - } else { - // Not a known group name - groupNameSet->insert(name); - addName(name); + + void AclReader::addName(const std::string& name) { + names.insert(name); } -} - -void AclReader::addName(const std::string& name) { - names.insert(name); -} - -// Debug aid -void AclReader::printNames() const { - QPID_LOG(debug, "Group list: " << groups.size() << " groups found:" ); - std::string tmp; - for (gmCitr i=groups.begin(); i!= groups.end(); i++) { - tmp += " \""; - tmp += i->first; - tmp += "\":"; - for (nsCitr j=i->second->begin(); j!=i->second->end(); j++) { + + // Debug aid + void AclReader::printNames() const { + QPID_LOG(debug, "Group list: " << groups.size() << " groups found:" ); + std::string tmp; + for (gmCitr i=groups.begin(); i!= groups.end(); i++) { + tmp += " \""; + tmp += i->first; + tmp += "\":"; + for (nsCitr j=i->second->begin(); j!=i->second->end(); j++) { + tmp += " "; + tmp += *j; + } + QPID_LOG(debug, tmp); + tmp.clear(); + } + QPID_LOG(debug, "Name list: " << names.size() << " names found:" ); + tmp.clear(); + for (nsCitr k=names.begin(); k!=names.end(); k++) { tmp += " "; - tmp += *j; + tmp += *k; } QPID_LOG(debug, tmp); - tmp.clear(); - } - QPID_LOG(debug, "Name list: " << names.size() << " names found:" ); - tmp.clear(); - for (nsCitr k=names.begin(); k!=names.end(); k++) { - tmp += " "; - tmp += *k; - } - QPID_LOG(debug, tmp); -} - -bool AclReader::processAclLine(tokList& toks) { - const unsigned toksSize = toks.size(); - if (toksSize < 4) { - errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber - << ", Insufficient tokens for acl definition."; - return false; - } - - AclResult res; - try { - res = AclHelper::getAclResult(toks[1]); - } catch (...) { - errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber - << ", Unknown ACL permission \"" << toks[1] << "\"."; - return false; } - bool actionAllFlag = toks[3].compare("all") == 0; - bool userAllFlag = toks[2].compare("all") == 0; - Action action; - if (actionAllFlag) { - - if (userAllFlag && toksSize > 4) { + bool AclReader::processAclLine(tokList& toks) { + const unsigned toksSize = toks.size(); + if (toksSize < 4) { errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber - << ", Tokens found after action \"all\"."; + << ", Insufficient tokens for acl definition."; return false; } - action = ACT_CONSUME; // dummy; compiler must initialize action for this code path - } else { + + AclResult res; try { - action = AclHelper::getAction(toks[3]); + res = AclHelper::getAclResult(toks[1]); } catch (...) { errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber - << ", Unknown action \"" << toks[3] << "\"."; + << ", Unknown ACL permission \"" << toks[1] << "\"."; return false; } - } - // Create rule obj; then add object (if any) and properties (if any) - aclRulePtr rule; - if (actionAllFlag) { - rule.reset(new aclRule(res, toks[2], groups)); - } else { - rule.reset(new aclRule(res, toks[2], groups, action)); - } - - if (toksSize >= 5) { // object name-value pair - if (toks[4].compare("all") == 0) { - rule->setObjectTypeAll(); + bool actionAllFlag = toks[3].compare("all") == 0; + bool userAllFlag = toks[2].compare("all") == 0; + Action action; + if (actionAllFlag) { + + if (userAllFlag && toksSize > 4) { + errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber + << ", Tokens found after action \"all\"."; + return false; + } + action = ACT_CONSUME; // dummy; compiler must initialize action for this code path } else { try { - rule->setObjectType(AclHelper::getObjectType(toks[4])); + action = AclHelper::getAction(toks[3]); } catch (...) { errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber - << ", Unknown object \"" << toks[4] << "\"."; + << ", Unknown action \"" << toks[3] << "\"."; return false; } } - } - if (toksSize >= 6) { // property name-value pair(s) - for (unsigned i=5; i<toksSize; i++) { - nvPair propNvp = splitNameValuePair(toks[i]); - if (propNvp.second.size() == 0) { - errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber - <<", Badly formed property name-value pair \"" - << propNvp.first << "\". (Must be name=value)"; - return false; + // Create rule obj; then add object (if any) and properties (if any) + aclRulePtr rule; + if (actionAllFlag) { + rule.reset(new aclRule(res, toks[2], groups)); + } else { + rule.reset(new aclRule(res, toks[2], groups, action)); + } + + if (toksSize >= 5) { // object name-value pair + if (toks[4].compare("all") == 0) { + rule->setObjectTypeAll(); + } else { + try { + rule->setObjectType(AclHelper::getObjectType(toks[4])); + } catch (...) { + errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber + << ", Unknown object \"" << toks[4] << "\"."; + return false; + } } - Property prop; - try { - prop = AclHelper::getProperty(propNvp.first); - } catch (...) { - errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber - << ", Unknown property \"" << propNvp.first << "\"."; - return false; + } + + if (toksSize >= 6) { // property name-value pair(s) + for (unsigned i=5; i<toksSize; i++) { + nvPair propNvp = splitNameValuePair(toks[i]); + if (propNvp.second.size() == 0) { + errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber + <<", Badly formed property name-value pair \"" + << propNvp.first << "\". (Must be name=value)"; + return false; + } + Property prop; + try { + prop = AclHelper::getProperty(propNvp.first); + } catch (...) { + errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber + << ", Unknown property \"" << propNvp.first << "\"."; + return false; + } + rule->addProperty(prop, propNvp.second); } - rule->addProperty(prop, propNvp.second); } - } - // Check if name (toks[2]) is group; if not, add as name of individual - if (toks[2].compare("all") != 0) { - if (groups.find(toks[2]) == groups.end()) { - addName(toks[2]); + // Check if name (toks[2]) is group; if not, add as name of individual + if (toks[2].compare("all") != 0) { + if (groups.find(toks[2]) == groups.end()) { + addName(toks[2]); + } } - } - // If rule validates, add to rule list - if (!rule->validate(validationMap)) { - errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber - << ", Invalid object/action/property combination."; - return false; - } - rules.push_back(rule); + // If rule validates, add to rule list + if (!rule->validate(validationMap)) { + errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber + << ", Invalid object/action/property combination."; + return false; + } + rules.push_back(rule); - return true; -} + return true; + } -// Debug aid -void AclReader::printRules() const { - QPID_LOG(debug, "Rule list: " << rules.size() << " ACL rules found:"); - int cnt = 0; - for (rlCitr i=rules.begin(); i<rules.end(); i++,cnt++) { - QPID_LOG(debug, " " << std::setfill(' ') << std::setw(2) << cnt << " " << (*i)->toString()); + // Debug aid + void AclReader::printRules() const { + QPID_LOG(debug, "Rule list: " << rules.size() << " ACL rules found:"); + int cnt = 0; + for (rlCitr i=rules.begin(); i<rules.end(); i++,cnt++) { + QPID_LOG(debug, " " << std::setfill(' ') << std::setw(2) << cnt << " " << (*i)->toString()); + } } -} - -// Static function -// Return true if the name is well-formed (ie contains legal characters) -bool AclReader::isValidGroupName(const std::string& name) { - for (unsigned i=0; i<name.size(); i++) { - const char ch = name.at(i); - if (!std::isalnum(ch) && ch != '-' && ch != '_') return false; + + // Static function + // Return true if the name is well-formed (ie contains legal characters) + bool AclReader::isValidGroupName(const std::string& name) { + for (unsigned i=0; i<name.size(); i++) { + const char ch = name.at(i); + if (!std::isalnum(ch) && ch != '-' && ch != '_') return false; + } + return true; } - return true; -} - -// Static function -// Split name-value pair around '=' char of the form "name=value" -AclReader::nvPair AclReader::splitNameValuePair(const std::string& nvpString) { - std::size_t pos = nvpString.find("="); - if (pos == std::string::npos || pos == nvpString.size() - 1) { - return nvPair(nvpString, ""); + + // Static function + // Split name-value pair around '=' char of the form "name=value" + AclReader::nvPair AclReader::splitNameValuePair(const std::string& nvpString) { + std::size_t pos = nvpString.find("="); + if (pos == std::string::npos || pos == nvpString.size() - 1) { + return nvPair(nvpString, ""); + } + return nvPair(nvpString.substr(0, pos), nvpString.substr(pos+1)); } - return nvPair(nvpString.substr(0, pos), nvpString.substr(pos+1)); -} - -// Returns true if a username has the name@realm format -bool AclReader::isValidUserName(const std::string& name){ - size_t pos = name.find('@'); - if ( pos == std::string::npos || pos == name.length() -1){ - errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber - << ", Username '" << name << "' must contain a realm"; - return false; - } - for (unsigned i=0; i<name.size(); i++) { - const char ch = name.at(i); - if (!std::isalnum(ch) && ch != '-' && ch != '_' && ch != '@' && ch != '.' && ch != '/'){ + + // Returns true if a username has the name@realm format + bool AclReader::isValidUserName(const std::string& name){ + size_t pos = name.find('@'); + if ( pos == std::string::npos || pos == name.length() -1){ errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber - << ", Username \"" << name << "\" contains illegal characters."; + << ", Username '" << name << "' must contain a realm"; return false; } + for (unsigned i=0; i<name.size(); i++) { + const char ch = name.at(i); + if (!std::isalnum(ch) && ch != '-' && ch != '_' && ch != '@' && ch != '.' && ch != '/'){ + errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber + << ", Username \"" << name << "\" contains illegal characters."; + return false; + } + } + return true; } - return true; -} }} // namespace qpid::acl diff --git a/cpp/src/qpid/acl/AclValidator.cpp b/cpp/src/qpid/acl/AclValidator.cpp index 57b68e520a..d5a00b005b 100644 --- a/cpp/src/qpid/acl/AclValidator.cpp +++ b/cpp/src/qpid/acl/AclValidator.cpp @@ -29,122 +29,122 @@ namespace qpid { namespace acl { -AclValidator::IntPropertyType::IntPropertyType(int64_t i,int64_t j) : min(i), max(j){ -} - -bool AclValidator::IntPropertyType::validate(const std::string& val) { - int64_t v; - try - { - v = boost::lexical_cast<int64_t>(val); - }catch(const boost::bad_lexical_cast&){ - return 0; - } - - if (v < min || v >= max){ - return 0; - }else{ - return 1; - } -} - -std::string AclValidator::IntPropertyType::allowedValues() { - return "values should be between " + - boost::lexical_cast<std::string>(min) + " and " + - boost::lexical_cast<std::string>(max); -} - -AclValidator::EnumPropertyType::EnumPropertyType(std::vector<std::string>& allowed): values(allowed){ -} - -bool AclValidator::EnumPropertyType::validate(const std::string& val) { - for (std::vector<std::string>::iterator itr = values.begin(); itr != values.end(); ++itr ){ - if (val.compare(*itr) == 0){ - return 1; - } - } - - return 0; -} - -std::string AclValidator::EnumPropertyType::allowedValues() { - std::ostringstream oss; - oss << "possible values are one of { "; - for (std::vector<std::string>::iterator itr = values.begin(); itr != values.end(); itr++ ){ - oss << "'" << *itr << "' "; - } - oss << "}"; - return oss.str(); -} - -AclValidator::AclValidator(){ - validators.insert(Validator(acl::PROP_MAXQUEUESIZE, - boost::shared_ptr<PropertyType>( - new IntPropertyType(0,std::numeric_limits<int64_t>::max())) - ) - ); - - validators.insert(Validator(acl::PROP_MAXQUEUECOUNT, - boost::shared_ptr<PropertyType>( - new IntPropertyType(0,std::numeric_limits<int64_t>::max())) - ) - ); - - std::string policyTypes[] = {"ring", "ring_strict", "flow_to_disk", "reject"}; - std::vector<std::string> v(policyTypes, policyTypes + sizeof(policyTypes) / sizeof(std::string)); - validators.insert(Validator(acl::PROP_POLICYTYPE, - boost::shared_ptr<PropertyType>(new EnumPropertyType(v)) - ) - ); - -} - -AclValidator::~AclValidator(){ -} - -/* Iterate through the data model and validate the parameters. */ -void AclValidator::validate(boost::shared_ptr<AclData> d) { - - for (unsigned int cnt=0; cnt< qpid::acl::ACTIONSIZE; cnt++){ - - if (d->actionList[cnt]){ - - for (unsigned int cnt1=0; cnt1< qpid::acl::OBJECTSIZE; cnt1++){ - - if (d->actionList[cnt][cnt1]){ - - std::for_each(d->actionList[cnt][cnt1]->begin(), - d->actionList[cnt][cnt1]->end(), - boost::bind(&AclValidator::validateRuleSet, this, _1)); - }//if - }//for - }//if - }//for -} - -void AclValidator::validateRuleSet(std::pair<const std::string, qpid::acl::AclData::ruleSet>& rules){ - std::for_each(rules.second.begin(), - rules.second.end(), - boost::bind(&AclValidator::validateRule, this, _1)); -} - -void AclValidator::validateRule(qpid::acl::AclData::rule& rule){ - std::for_each(rule.props.begin(), - rule.props.end(), - boost::bind(&AclValidator::validateProperty, this, _1)); -} - -void AclValidator::validateProperty(std::pair<const qpid::acl::Property, std::string>& prop){ - ValidatorItr itr = validators.find(prop.first); - if (itr != validators.end()){ - QPID_LOG(debug,"Found validator for property " << itr->second->allowedValues()); - - if (!itr->second->validate(prop.second)){ - throw Exception( prop.second + " is not a valid value for '" + - AclHelper::getPropertyStr(prop.first) + "', " + - itr->second->allowedValues()); - } + AclValidator::IntPropertyType::IntPropertyType(int64_t i,int64_t j) : min(i), max(j){ + } + + bool AclValidator::IntPropertyType::validate(const std::string& val) { + int64_t v; + try + { + v = boost::lexical_cast<int64_t>(val); + }catch(const boost::bad_lexical_cast&){ + return 0; + } + + if (v < min || v >= max){ + return 0; + }else{ + return 1; + } + } + + std::string AclValidator::IntPropertyType::allowedValues() { + return "values should be between " + + boost::lexical_cast<std::string>(min) + " and " + + boost::lexical_cast<std::string>(max); + } + + AclValidator::EnumPropertyType::EnumPropertyType(std::vector<std::string>& allowed): values(allowed){ + } + + bool AclValidator::EnumPropertyType::validate(const std::string& val) { + for (std::vector<std::string>::iterator itr = values.begin(); itr != values.end(); ++itr ){ + if (val.compare(*itr) == 0){ + return 1; + } + } + + return 0; + } + + std::string AclValidator::EnumPropertyType::allowedValues() { + std::ostringstream oss; + oss << "possible values are one of { "; + for (std::vector<std::string>::iterator itr = values.begin(); itr != values.end(); itr++ ){ + oss << "'" << *itr << "' "; + } + oss << "}"; + return oss.str(); + } + + AclValidator::AclValidator(){ + validators.insert(Validator(acl::PROP_MAXQUEUESIZE, + boost::shared_ptr<PropertyType>( + new IntPropertyType(0,std::numeric_limits<int64_t>::max())) + ) + ); + + validators.insert(Validator(acl::PROP_MAXQUEUECOUNT, + boost::shared_ptr<PropertyType>( + new IntPropertyType(0,std::numeric_limits<int64_t>::max())) + ) + ); + + std::string policyTypes[] = {"ring", "ring_strict", "flow_to_disk", "reject"}; + std::vector<std::string> v(policyTypes, policyTypes + sizeof(policyTypes) / sizeof(std::string)); + validators.insert(Validator(acl::PROP_POLICYTYPE, + boost::shared_ptr<PropertyType>(new EnumPropertyType(v)) + ) + ); + + } + + AclValidator::~AclValidator(){ + } + + /* Iterate through the data model and validate the parameters. */ + void AclValidator::validate(boost::shared_ptr<AclData> d) { + + for (unsigned int cnt=0; cnt< qpid::acl::ACTIONSIZE; cnt++){ + + if (d->actionList[cnt]){ + + for (unsigned int cnt1=0; cnt1< qpid::acl::OBJECTSIZE; cnt1++){ + + if (d->actionList[cnt][cnt1]){ + + std::for_each(d->actionList[cnt][cnt1]->begin(), + d->actionList[cnt][cnt1]->end(), + boost::bind(&AclValidator::validateRuleSet, this, _1)); + }//if + }//for + }//if + }//for + } + + void AclValidator::validateRuleSet(std::pair<const std::string, qpid::acl::AclData::ruleSet>& rules){ + std::for_each(rules.second.begin(), + rules.second.end(), + boost::bind(&AclValidator::validateRule, this, _1)); + } + + void AclValidator::validateRule(qpid::acl::AclData::rule& rule){ + std::for_each(rule.props.begin(), + rule.props.end(), + boost::bind(&AclValidator::validateProperty, this, _1)); + } + + void AclValidator::validateProperty(std::pair<const qpid::acl::Property, std::string>& prop){ + ValidatorItr itr = validators.find(prop.first); + if (itr != validators.end()){ + QPID_LOG(debug,"Found validator for property " << itr->second->allowedValues()); + + if (!itr->second->validate(prop.second)){ + throw Exception( prop.second + " is not a valid value for '" + + AclHelper::getPropertyStr(prop.first) + "', " + + itr->second->allowedValues()); + } + } } -} }} diff --git a/cpp/src/qpid/broker/AclModule.h b/cpp/src/qpid/broker/AclModule.h index 2f4f7eaacc..e32ff266b9 100644 --- a/cpp/src/qpid/broker/AclModule.h +++ b/cpp/src/qpid/broker/AclModule.h @@ -32,248 +32,247 @@ namespace qpid { namespace acl { -enum ObjectType {OBJ_QUEUE, OBJ_EXCHANGE, OBJ_BROKER, OBJ_LINK, - OBJ_METHOD, OBJECTSIZE}; // OBJECTSIZE must be last in list -enum Action {ACT_CONSUME, ACT_PUBLISH, ACT_CREATE, ACT_ACCESS, ACT_BIND, - ACT_UNBIND, ACT_DELETE, ACT_PURGE, ACT_UPDATE, - ACTIONSIZE}; // ACTIONSIZE must be last in list -enum Property {PROP_NAME, PROP_DURABLE, PROP_OWNER, PROP_ROUTINGKEY, - PROP_PASSIVE, PROP_AUTODELETE, PROP_EXCLUSIVE, PROP_TYPE, - PROP_ALTERNATE, PROP_QUEUENAME, PROP_SCHEMAPACKAGE, - PROP_SCHEMACLASS, PROP_POLICYTYPE, PROP_MAXQUEUESIZE, - PROP_MAXQUEUECOUNT}; -enum AclResult {ALLOW, ALLOWLOG, DENY, DENYLOG}; + enum ObjectType {OBJ_QUEUE, OBJ_EXCHANGE, OBJ_BROKER, OBJ_LINK, + OBJ_METHOD, OBJECTSIZE}; // OBJECTSIZE must be last in list + enum Action {ACT_CONSUME, ACT_PUBLISH, ACT_CREATE, ACT_ACCESS, ACT_BIND, + ACT_UNBIND, ACT_DELETE, ACT_PURGE, ACT_UPDATE, + ACTIONSIZE}; // ACTIONSIZE must be last in list + enum Property {PROP_NAME, PROP_DURABLE, PROP_OWNER, PROP_ROUTINGKEY, + PROP_PASSIVE, PROP_AUTODELETE, PROP_EXCLUSIVE, PROP_TYPE, + PROP_ALTERNATE, PROP_QUEUENAME, PROP_SCHEMAPACKAGE, + PROP_SCHEMACLASS, PROP_POLICYTYPE, PROP_MAXQUEUESIZE, + PROP_MAXQUEUECOUNT}; + enum AclResult {ALLOW, ALLOWLOG, DENY, DENYLOG}; } // namespace acl namespace broker { -class AclModule -{ + class AclModule + { -public: - - // effienty turn off ACL on message transfer. - virtual bool doTransferAcl()=0; - - virtual bool authorise(const std::string& id, const acl::Action& action, const acl::ObjectType& objType, const std::string& name, - std::map<acl::Property, std::string>* params=0)=0; - virtual bool authorise(const std::string& id, const acl::Action& action, const acl::ObjectType& objType, const std::string& ExchangeName, - const std::string& RoutingKey)=0; - // create specilied authorise methods for cases that need faster matching as needed. + public: - virtual ~AclModule() {}; -}; + // effienty turn off ACL on message transfer. + virtual bool doTransferAcl()=0; + virtual bool authorise(const std::string& id, const acl::Action& action, const acl::ObjectType& objType, const std::string& name, + std::map<acl::Property, std::string>* params=0)=0; + virtual bool authorise(const std::string& id, const acl::Action& action, const acl::ObjectType& objType, const std::string& ExchangeName, + const std::string& RoutingKey)=0; + // create specilied authorise methods for cases that need faster matching as needed. + + virtual ~AclModule() {}; + }; } // namespace broker namespace acl { -class AclHelper { - private: - AclHelper(){} - public: - static inline ObjectType getObjectType(const std::string& str) { - if (str.compare("queue") == 0) return OBJ_QUEUE; - if (str.compare("exchange") == 0) return OBJ_EXCHANGE; - if (str.compare("broker") == 0) return OBJ_BROKER; - if (str.compare("link") == 0) return OBJ_LINK; - if (str.compare("method") == 0) return OBJ_METHOD; - throw str; - } - static inline std::string getObjectTypeStr(const ObjectType o) { - switch (o) { - case OBJ_QUEUE: return "queue"; - case OBJ_EXCHANGE: return "exchange"; - case OBJ_BROKER: return "broker"; - case OBJ_LINK: return "link"; - case OBJ_METHOD: return "method"; - default: assert(false); // should never get here + class AclHelper { + private: + AclHelper(){} + public: + static inline ObjectType getObjectType(const std::string& str) { + if (str.compare("queue") == 0) return OBJ_QUEUE; + if (str.compare("exchange") == 0) return OBJ_EXCHANGE; + if (str.compare("broker") == 0) return OBJ_BROKER; + if (str.compare("link") == 0) return OBJ_LINK; + if (str.compare("method") == 0) return OBJ_METHOD; + throw str; + } + static inline std::string getObjectTypeStr(const ObjectType o) { + switch (o) { + case OBJ_QUEUE: return "queue"; + case OBJ_EXCHANGE: return "exchange"; + case OBJ_BROKER: return "broker"; + case OBJ_LINK: return "link"; + case OBJ_METHOD: return "method"; + default: assert(false); // should never get here + } + return ""; + } + static inline Action getAction(const std::string& str) { + if (str.compare("consume") == 0) return ACT_CONSUME; + if (str.compare("publish") == 0) return ACT_PUBLISH; + if (str.compare("create") == 0) return ACT_CREATE; + if (str.compare("access") == 0) return ACT_ACCESS; + if (str.compare("bind") == 0) return ACT_BIND; + if (str.compare("unbind") == 0) return ACT_UNBIND; + if (str.compare("delete") == 0) return ACT_DELETE; + if (str.compare("purge") == 0) return ACT_PURGE; + if (str.compare("update") == 0) return ACT_UPDATE; + throw str; + } + static inline std::string getActionStr(const Action a) { + switch (a) { + case ACT_CONSUME: return "consume"; + case ACT_PUBLISH: return "publish"; + case ACT_CREATE: return "create"; + case ACT_ACCESS: return "access"; + case ACT_BIND: return "bind"; + case ACT_UNBIND: return "unbind"; + case ACT_DELETE: return "delete"; + case ACT_PURGE: return "purge"; + case ACT_UPDATE: return "update"; + default: assert(false); // should never get here + } + return ""; + } + static inline Property getProperty(const std::string& str) { + if (str.compare("name") == 0) return PROP_NAME; + if (str.compare("durable") == 0) return PROP_DURABLE; + if (str.compare("owner") == 0) return PROP_OWNER; + if (str.compare("routingkey") == 0) return PROP_ROUTINGKEY; + if (str.compare("passive") == 0) return PROP_PASSIVE; + if (str.compare("autodelete") == 0) return PROP_AUTODELETE; + if (str.compare("exclusive") == 0) return PROP_EXCLUSIVE; + if (str.compare("type") == 0) return PROP_TYPE; + if (str.compare("alternate") == 0) return PROP_ALTERNATE; + if (str.compare("queuename") == 0) return PROP_QUEUENAME; + if (str.compare("schemapackage") == 0) return PROP_SCHEMAPACKAGE; + if (str.compare("schemaclass") == 0) return PROP_SCHEMACLASS; + if (str.compare("policytype") == 0) return PROP_POLICYTYPE; + if (str.compare("maxqueuesize") == 0) return PROP_MAXQUEUESIZE; + if (str.compare("maxqueuecount") == 0) return PROP_MAXQUEUECOUNT; + throw str; } - return ""; - } - static inline Action getAction(const std::string& str) { - if (str.compare("consume") == 0) return ACT_CONSUME; - if (str.compare("publish") == 0) return ACT_PUBLISH; - if (str.compare("create") == 0) return ACT_CREATE; - if (str.compare("access") == 0) return ACT_ACCESS; - if (str.compare("bind") == 0) return ACT_BIND; - if (str.compare("unbind") == 0) return ACT_UNBIND; - if (str.compare("delete") == 0) return ACT_DELETE; - if (str.compare("purge") == 0) return ACT_PURGE; - if (str.compare("update") == 0) return ACT_UPDATE; - throw str; - } - static inline std::string getActionStr(const Action a) { - switch (a) { - case ACT_CONSUME: return "consume"; - case ACT_PUBLISH: return "publish"; - case ACT_CREATE: return "create"; - case ACT_ACCESS: return "access"; - case ACT_BIND: return "bind"; - case ACT_UNBIND: return "unbind"; - case ACT_DELETE: return "delete"; - case ACT_PURGE: return "purge"; - case ACT_UPDATE: return "update"; - default: assert(false); // should never get here + static inline std::string getPropertyStr(const Property p) { + switch (p) { + case PROP_NAME: return "name"; + case PROP_DURABLE: return "durable"; + case PROP_OWNER: return "owner"; + case PROP_ROUTINGKEY: return "routingkey"; + case PROP_PASSIVE: return "passive"; + case PROP_AUTODELETE: return "autodelete"; + case PROP_EXCLUSIVE: return "exclusive"; + case PROP_TYPE: return "type"; + case PROP_ALTERNATE: return "alternate"; + case PROP_QUEUENAME: return "queuename"; + case PROP_SCHEMAPACKAGE: return "schemapackage"; + case PROP_SCHEMACLASS: return "schemaclass"; + case PROP_POLICYTYPE: return "policytype"; + case PROP_MAXQUEUESIZE: return "maxqueuesize"; + case PROP_MAXQUEUECOUNT: return "maxqueuecount"; + default: assert(false); // should never get here + } + return ""; } - return ""; - } - static inline Property getProperty(const std::string& str) { - if (str.compare("name") == 0) return PROP_NAME; - if (str.compare("durable") == 0) return PROP_DURABLE; - if (str.compare("owner") == 0) return PROP_OWNER; - if (str.compare("routingkey") == 0) return PROP_ROUTINGKEY; - if (str.compare("passive") == 0) return PROP_PASSIVE; - if (str.compare("autodelete") == 0) return PROP_AUTODELETE; - if (str.compare("exclusive") == 0) return PROP_EXCLUSIVE; - if (str.compare("type") == 0) return PROP_TYPE; - if (str.compare("alternate") == 0) return PROP_ALTERNATE; - if (str.compare("queuename") == 0) return PROP_QUEUENAME; - if (str.compare("schemapackage") == 0) return PROP_SCHEMAPACKAGE; - if (str.compare("schemaclass") == 0) return PROP_SCHEMACLASS; - if (str.compare("policytype") == 0) return PROP_POLICYTYPE; - if (str.compare("maxqueuesize") == 0) return PROP_MAXQUEUESIZE; - if (str.compare("maxqueuecount") == 0) return PROP_MAXQUEUECOUNT; - throw str; - } - static inline std::string getPropertyStr(const Property p) { - switch (p) { - case PROP_NAME: return "name"; - case PROP_DURABLE: return "durable"; - case PROP_OWNER: return "owner"; - case PROP_ROUTINGKEY: return "routingkey"; - case PROP_PASSIVE: return "passive"; - case PROP_AUTODELETE: return "autodelete"; - case PROP_EXCLUSIVE: return "exclusive"; - case PROP_TYPE: return "type"; - case PROP_ALTERNATE: return "alternate"; - case PROP_QUEUENAME: return "queuename"; - case PROP_SCHEMAPACKAGE: return "schemapackage"; - case PROP_SCHEMACLASS: return "schemaclass"; - case PROP_POLICYTYPE: return "policytype"; - case PROP_MAXQUEUESIZE: return "maxqueuesize"; - case PROP_MAXQUEUECOUNT: return "maxqueuecount"; - default: assert(false); // should never get here + static inline AclResult getAclResult(const std::string& str) { + if (str.compare("allow") == 0) return ALLOW; + if (str.compare("allow-log") == 0) return ALLOWLOG; + if (str.compare("deny") == 0) return DENY; + if (str.compare("deny-log") == 0) return DENYLOG; + throw str; } - return ""; - } - static inline AclResult getAclResult(const std::string& str) { - if (str.compare("allow") == 0) return ALLOW; - if (str.compare("allow-log") == 0) return ALLOWLOG; - if (str.compare("deny") == 0) return DENY; - if (str.compare("deny-log") == 0) return DENYLOG; - throw str; - } - static inline std::string getAclResultStr(const AclResult r) { - switch (r) { - case ALLOW: return "allow"; - case ALLOWLOG: return "allow-log"; - case DENY: return "deny"; - case DENYLOG: return "deny-log"; - default: assert(false); // should never get here + static inline std::string getAclResultStr(const AclResult r) { + switch (r) { + case ALLOW: return "allow"; + case ALLOWLOG: return "allow-log"; + case DENY: return "deny"; + case DENYLOG: return "deny-log"; + default: assert(false); // should never get here + } + return ""; + } + + typedef std::set<Property> propSet; + typedef boost::shared_ptr<propSet> propSetPtr; + typedef std::pair<Action, propSetPtr> actionPair; + typedef std::map<Action, propSetPtr> actionMap; + typedef boost::shared_ptr<actionMap> actionMapPtr; + typedef std::pair<ObjectType, actionMapPtr> objectPair; + typedef std::map<ObjectType, actionMapPtr> objectMap; + typedef objectMap::const_iterator omCitr; + typedef boost::shared_ptr<objectMap> objectMapPtr; + typedef std::map<Property, std::string> propMap; + typedef propMap::const_iterator propMapItr; + + // This map contains the legal combinations of object/action/properties found in an ACL file + static void loadValidationMap(objectMapPtr& map) { + if (!map.get()) return; + map->clear(); + propSetPtr p0; // empty ptr, used for no properties + + // == Exchanges == + + propSetPtr p1(new propSet); + p1->insert(PROP_TYPE); + p1->insert(PROP_ALTERNATE); + p1->insert(PROP_PASSIVE); + p1->insert(PROP_DURABLE); + + propSetPtr p2(new propSet); + p2->insert(PROP_ROUTINGKEY); + + propSetPtr p3(new propSet); + p3->insert(PROP_QUEUENAME); + p3->insert(PROP_ROUTINGKEY); + + actionMapPtr a0(new actionMap); + a0->insert(actionPair(ACT_CREATE, p1)); + a0->insert(actionPair(ACT_DELETE, p0)); + a0->insert(actionPair(ACT_ACCESS, p0)); + a0->insert(actionPair(ACT_BIND, p2)); + a0->insert(actionPair(ACT_UNBIND, p2)); + a0->insert(actionPair(ACT_ACCESS, p3)); + a0->insert(actionPair(ACT_PUBLISH, p0)); + + map->insert(objectPair(OBJ_EXCHANGE, a0)); + + // == Queues == + + propSetPtr p4(new propSet); + p4->insert(PROP_ALTERNATE); + p4->insert(PROP_PASSIVE); + p4->insert(PROP_DURABLE); + p4->insert(PROP_EXCLUSIVE); + p4->insert(PROP_AUTODELETE); + p4->insert(PROP_POLICYTYPE); + p4->insert(PROP_MAXQUEUESIZE); + p4->insert(PROP_MAXQUEUECOUNT); + + actionMapPtr a1(new actionMap); + a1->insert(actionPair(ACT_ACCESS, p0)); + a1->insert(actionPair(ACT_CREATE, p4)); + a1->insert(actionPair(ACT_PURGE, p0)); + a1->insert(actionPair(ACT_DELETE, p0)); + a1->insert(actionPair(ACT_CONSUME, p0)); + + map->insert(objectPair(OBJ_QUEUE, a1)); + + // == Links == + + actionMapPtr a2(new actionMap); + a2->insert(actionPair(ACT_CREATE, p0)); + + map->insert(objectPair(OBJ_LINK, a2)); + + // == Method == + + propSetPtr p5(new propSet); + p5->insert(PROP_SCHEMAPACKAGE); + p5->insert(PROP_SCHEMACLASS); + + actionMapPtr a4(new actionMap); + a4->insert(actionPair(ACT_ACCESS, p5)); + + map->insert(objectPair(OBJ_METHOD, a4)); + } + + static std::string propertyMapToString(const std::map<Property, std::string>* params) { + std::ostringstream ss; + ss << "{"; + if (params) + { + for (propMapItr pMItr = params->begin(); pMItr != params->end(); pMItr++) { + ss << " " << getPropertyStr((Property) pMItr-> first) << "=" << pMItr->second; + } + } + ss << " }"; + return ss.str(); } - return ""; - } - - typedef std::set<Property> propSet; - typedef boost::shared_ptr<propSet> propSetPtr; - typedef std::pair<Action, propSetPtr> actionPair; - typedef std::map<Action, propSetPtr> actionMap; - typedef boost::shared_ptr<actionMap> actionMapPtr; - typedef std::pair<ObjectType, actionMapPtr> objectPair; - typedef std::map<ObjectType, actionMapPtr> objectMap; - typedef objectMap::const_iterator omCitr; - typedef boost::shared_ptr<objectMap> objectMapPtr; - typedef std::map<Property, std::string> propMap; - typedef propMap::const_iterator propMapItr; - - // This map contains the legal combinations of object/action/properties found in an ACL file - static void loadValidationMap(objectMapPtr& map) { - if (!map.get()) return; - map->clear(); - propSetPtr p0; // empty ptr, used for no properties - - // == Exchanges == - - propSetPtr p1(new propSet); - p1->insert(PROP_TYPE); - p1->insert(PROP_ALTERNATE); - p1->insert(PROP_PASSIVE); - p1->insert(PROP_DURABLE); - - propSetPtr p2(new propSet); - p2->insert(PROP_ROUTINGKEY); - - propSetPtr p3(new propSet); - p3->insert(PROP_QUEUENAME); - p3->insert(PROP_ROUTINGKEY); - - actionMapPtr a0(new actionMap); - a0->insert(actionPair(ACT_CREATE, p1)); - a0->insert(actionPair(ACT_DELETE, p0)); - a0->insert(actionPair(ACT_ACCESS, p0)); - a0->insert(actionPair(ACT_BIND, p2)); - a0->insert(actionPair(ACT_UNBIND, p2)); - a0->insert(actionPair(ACT_ACCESS, p3)); - a0->insert(actionPair(ACT_PUBLISH, p0)); - - map->insert(objectPair(OBJ_EXCHANGE, a0)); - - // == Queues == - - propSetPtr p4(new propSet); - p4->insert(PROP_ALTERNATE); - p4->insert(PROP_PASSIVE); - p4->insert(PROP_DURABLE); - p4->insert(PROP_EXCLUSIVE); - p4->insert(PROP_AUTODELETE); - p4->insert(PROP_POLICYTYPE); - p4->insert(PROP_MAXQUEUESIZE); - p4->insert(PROP_MAXQUEUECOUNT); - - actionMapPtr a1(new actionMap); - a1->insert(actionPair(ACT_ACCESS, p0)); - a1->insert(actionPair(ACT_CREATE, p4)); - a1->insert(actionPair(ACT_PURGE, p0)); - a1->insert(actionPair(ACT_DELETE, p0)); - a1->insert(actionPair(ACT_CONSUME, p0)); - - map->insert(objectPair(OBJ_QUEUE, a1)); - - // == Links == - - actionMapPtr a2(new actionMap); - a2->insert(actionPair(ACT_CREATE, p0)); - - map->insert(objectPair(OBJ_LINK, a2)); - - // == Method == - - propSetPtr p5(new propSet); - p5->insert(PROP_SCHEMAPACKAGE); - p5->insert(PROP_SCHEMACLASS); - - actionMapPtr a4(new actionMap); - a4->insert(actionPair(ACT_ACCESS, p5)); - - map->insert(objectPair(OBJ_METHOD, a4)); - } - - static std::string propertyMapToString(const std::map<Property, std::string>* params) { - std::ostringstream ss; - ss << "{"; - if (params) - { - for (propMapItr pMItr = params->begin(); pMItr != params->end(); pMItr++) { - ss << " " << getPropertyStr((Property) pMItr-> first) << "=" << pMItr->second; - } - } - ss << " }"; - return ss.str(); - } -}; + }; }} // namespace qpid::acl |