summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles E. Rolke <chug@apache.org>2012-03-01 18:45:45 +0000
committerCharles E. Rolke <chug@apache.org>2012-03-01 18:45:45 +0000
commit247adf7d2c9a20ac4c3c23702e24a4171ba40089 (patch)
tree0528df7784e696ac137184fd132c55b8f186c7ac
parent0c926da1ca0d21c4eaa661a78b962440a760c519 (diff)
downloadqpid-python-247adf7d2c9a20ac4c3c23702e24a4171ba40089.tar.gz
QPID-3799 Acl update. Merge from branches/QPID-3799-acl
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1295730 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--qpid/cpp/src/qpid/acl/Acl.cpp78
-rw-r--r--qpid/cpp/src/qpid/acl/Acl.h29
-rw-r--r--qpid/cpp/src/qpid/acl/AclData.cpp568
-rw-r--r--qpid/cpp/src/qpid/acl/AclData.h89
-rw-r--r--qpid/cpp/src/qpid/acl/AclReader.cpp222
-rw-r--r--qpid/cpp/src/qpid/acl/AclReader.h80
-rw-r--r--qpid/cpp/src/qpid/acl/AclValidator.cpp61
-rw-r--r--qpid/cpp/src/qpid/acl/AclValidator.h24
-rw-r--r--qpid/cpp/src/qpid/broker/AclModule.h182
-rw-r--r--qpid/cpp/src/qpid/broker/ConnectionHandler.h1
-rw-r--r--qpid/cpp/src/qpid/broker/SemanticState.h1
-rwxr-xr-xqpid/cpp/src/tests/acl.py598
12 files changed, 1282 insertions, 651 deletions
diff --git a/qpid/cpp/src/qpid/acl/Acl.cpp b/qpid/cpp/src/qpid/acl/Acl.cpp
index 12bf13018c..6f758e46bf 100644
--- a/qpid/cpp/src/qpid/acl/Acl.cpp
+++ b/qpid/cpp/src/qpid/acl/Acl.cpp
@@ -66,10 +66,15 @@ Acl::Acl (AclValues& av, Broker& b): aclValues(av), broker(&b), transferAcl(fals
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)
+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
}
@@ -81,7 +86,12 @@ bool Acl::authorise(const std::string& id, const Action& action, const ObjectTyp
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)
+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;
{
@@ -96,31 +106,51 @@ bool Acl::authorise(const std::string& id, const Action& action, const ObjectTyp
}
-bool Acl::result(const AclResult& aclreslt, const std::string& id, const Action& action, const ObjectType& objType, const std::string& name)
+bool Acl::result(
+ const AclResult& aclreslt,
+ const std::string& id,
+ const Action& action,
+ const ObjectType& objType,
+ const std::string& name)
{
+ bool result(false);
+
switch (aclreslt)
{
case ALLOWLOG:
- QPID_LOG(info, "ACL Allow id:" << id <<" action:" << AclHelper::getActionStr(action) <<
- " ObjectType:" << AclHelper::getObjectTypeStr(objType) << " Name:" << name );
+ 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()));
+ AclHelper::getObjectTypeStr(objType),
+ name, types::Variant::Map()));
+ // FALLTHROUGH
case ALLOW:
- return true;
- case DENY:
- if (mgmtObject!=0) mgmtObject->inc_aclDenyCount();
- return false;
+ result = true;
+ break;
+
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);
+ 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;
+ AclHelper::getObjectTypeStr(objType),
+ name, types::Variant::Map()));
+ // FALLTHROUGH
+ case DENY:
+ if (mgmtObject!=0)
+ mgmtObject->inc_aclDenyCount();
+ result = false;
+ break;
+
+ default:
+ assert (false);
}
- return false;
+
+ QPID_LOG(debug, "ACL result() returns " << result);
+ return result;
}
bool Acl::readAclFile(std::string& errorText)
@@ -129,7 +159,7 @@ bool Acl::readAclFile(std::string& errorText)
return readAclFile(aclValues.aclFile, errorText);
}
-bool Acl::readAclFile(std::string& aclFile, std::string& errorText) {
+bool Acl::readAclFile(std::string& aclFile, std::string& errorText) {
boost::shared_ptr<AclData> d(new AclData);
AclReader ar;
if (ar.read(aclFile, d)){
@@ -142,17 +172,17 @@ bool Acl::readAclFile(std::string& aclFile, std::string& errorText) {
AclValidator validator;
validator.validate(d);
- {
+ {
Mutex::ScopedLock locker(dataLock);
data = d;
}
transferAcl = data->transferAcl; // any transfer ACL
if (data->transferAcl){
- QPID_LOG(debug,"Transfer ACL is Enabled!");
+ QPID_LOG(debug,"ACL: Transfer ACL is Enabled!");
}
- data->aclSource = aclFile;
+ data->aclSource = aclFile;
if (mgmtObject!=0){
mgmtObject->set_transferAcl(transferAcl?1:0);
mgmtObject->set_policyFile(aclFile);
@@ -174,7 +204,7 @@ ManagementObject* Acl::GetManagementObject(void) const
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 << "]");
+ QPID_LOG (debug, "ACL: Queue::ManagementMethod [id=" << methodId << "]");
switch (methodId)
{
diff --git a/qpid/cpp/src/qpid/acl/Acl.h b/qpid/cpp/src/qpid/acl/Acl.h
index 77f43838de..cc90fa4097 100644
--- a/qpid/cpp/src/qpid/acl/Acl.h
+++ b/qpid/cpp/src/qpid/acl/Acl.h
@@ -56,22 +56,39 @@ private:
boost::shared_ptr<AclData> data;
qmf::org::apache::qpid::acl::Acl* mgmtObject; // mgnt owns lifecycle
qpid::management::ManagementAgent* agent;
- mutable qpid::sys::Mutex dataLock;
+ mutable qpid::sys::Mutex dataLock;
public:
Acl (AclValues& av, broker::Broker& b);
void initialize();
-
+
inline virtual bool doTransferAcl() {return transferAcl;};
-
+
// create specilied authorise methods for cases that need faster matching as needed.
- virtual bool authorise(const std::string& id, const Action& action, const ObjectType& objType, const std::string& name, std::map<Property, std::string>* params=0);
- virtual bool authorise(const std::string& id, const Action& action, const ObjectType& objType, const std::string& ExchangeName,const std::string& RoutingKey);
+ virtual bool authorise(
+ const std::string& id,
+ const Action& action,
+ const ObjectType& objType,
+ const std::string& name,
+ std::map<Property,
+ std::string>* params=0);
+
+ virtual bool authorise(
+ const std::string& id,
+ const Action& action,
+ const ObjectType& objType,
+ const std::string& ExchangeName,
+ const std::string& RoutingKey);
virtual ~Acl();
private:
- bool result(const AclResult& aclreslt, const std::string& id, const Action& action, const ObjectType& objType, const std::string& name);
+ bool result(
+ const AclResult& aclreslt,
+ const std::string& id,
+ const Action& action,
+ const ObjectType& objType,
+ const std::string& name);
bool readAclFile(std::string& errorText);
bool readAclFile(std::string& aclFile, std::string& errorText);
virtual qpid::management::ManagementObject* GetManagementObject(void) const;
diff --git a/qpid/cpp/src/qpid/acl/AclData.cpp b/qpid/cpp/src/qpid/acl/AclData.cpp
index 06fc223a73..03a8a19db9 100644
--- a/qpid/cpp/src/qpid/acl/AclData.cpp
+++ b/qpid/cpp/src/qpid/acl/AclData.cpp
@@ -24,151 +24,301 @@
namespace qpid {
namespace acl {
- AclData::AclData():decisionMode(qpid::acl::DENY),transferAcl(false),aclSource("UNKNOWN")
+ //
+ // constructor
+ //
+ AclData::AclData():
+ decisionMode(qpid::acl::DENY),
+ transferAcl(false),
+ aclSource("UNKNOWN")
{
- for (unsigned int cnt=0; cnt< qpid::acl::ACTIONSIZE; cnt++){
+ for (unsigned int cnt=0; cnt< qpid::acl::ACTIONSIZE; cnt++)
+ {
actionList[cnt]=0;
}
-
}
+
+ //
+ // clear
+ //
void AclData::clear ()
{
- for (unsigned int cnt=0; cnt< qpid::acl::ACTIONSIZE; cnt++){
- if (actionList[cnt]){
+ 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][cnt1];
}
delete[] actionList[cnt];
}
-
}
- bool AclData::matchProp(const std::string & src, const std::string& src1)
+
+ //
+ // matchProp
+ //
+ // Compare a rule's property name with a lookup name,
+ // The rule's name may contains a trailing '*' to specify a wildcard match.
+ //
+ bool AclData::matchProp(const std::string& ruleStr,
+ const std::string& lookupStr)
{
- // 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) ;
+ // allow wildcard on the end of rule strings...
+ if (ruleStr.data()[ruleStr.size()-1]=='*')
+ {
+ return ruleStr.compare(0,
+ ruleStr.size()-1,
+ lookupStr,
+ 0,
+ ruleStr.size()-1 ) == 0;
+ }
+ else
+ {
+ return ruleStr.compare(lookupStr) == 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{
+
+ //
+ // lookup
+ //
+ // The ACL main business logic function of matching rules and declaring
+ // an allow or deny result.
+ //
+ 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));
+
+ // A typical log looks like:
+ // ACL: Lookup for id:bob@QPID action:create objectType:queue name:q2
+ // with params { durable=false passive=false autodelete=false
+ // exclusive=false alternate= policytype= maxqueuesize=0
+ // maxqueuecount=0 }
+
+ // Default result is blanket decision mode for the entire ACL list.
+ AclResult aclresult = decisionMode;
+
+ // Test for lists of rules at the intersection of the Action & Object
+ if (actionList[action] && actionList[action][objType])
+ {
+ // Find the list of rules for this actorId
+ AclData::actObjItr itrRule = actionList[action][objType]->find(id);
+
+ // If individual actorId not found then find a rule set for '*'.
+ if (itrRule == actionList[action][objType]->end())
+ itrRule = actionList[action][objType]->find("*");
+
+ if (itrRule != actionList[action][objType]->end())
+ {
+ // A list of rules exists for this actor/action/object tuple.
+ // Iterate the rule set to search for a matching rule.
+ ruleSetItr rsItr = itrRule->second.end();
+ for (int cnt = itrRule->second.size(); cnt != 0; cnt--)
+ {
+ rsItr--;
+
+ QPID_LOG(debug, "ACL: checking rule " << rsItr->toString());
+
+ bool match = true;
+ bool limitChecked = true;
+
+ // Iterate this rule's properties. A 'match' is true when
+ // all of the rule's properties are found to be satisfied
+ // in the lookup param list. The lookup may specify things
+ // (they usually do) that are not in the rule properties but
+ // these things don't interfere with the rule match.
+
+ for (specPropertyMapItr rulePropMapItr = rsItr->props.begin();
+ (rulePropMapItr != rsItr->props.end()) && match;
+ rulePropMapItr++)
+ {
+ // The rule property map's NAME property is given in
+ // the calling args and not in the param map.
+ if (rulePropMapItr->first == acl::SPECPROP_NAME)
+ {
+ if (matchProp(rulePropMapItr->second, name))
+ {
+ QPID_LOG(debug, "ACL: lookup name '" << name
+ << "' matched with rule name '"
+ << rulePropMapItr->second << "'");
+ }
+ else
+ {
+ match = false;
+ QPID_LOG(debug, "ACL: lookup name '" << name
+ << "' didn't match with rule name '"
+ << rulePropMapItr->second << "'");
+ }
+ }
+ else
+ {
+ if (params)
+ {
+ // The rule's property map non-NAME properties
+ // found in the lookup's params list.
+ // In some cases the param's index is not the same
+ // as rule's index.
+ propertyMapItr lookupParamItr;
+ switch (rulePropMapItr->first)
+ {
+ case acl::SPECPROP_MAXQUEUECOUNTUPPERLIMIT:
+ case acl::SPECPROP_MAXQUEUECOUNTLOWERLIMIT:
+ lookupParamItr = params->find(PROP_MAXQUEUECOUNT);
+ break;
+
+ case acl::SPECPROP_MAXQUEUESIZEUPPERLIMIT:
+ case acl::SPECPROP_MAXQUEUESIZELOWERLIMIT:
+ lookupParamItr = params->find(PROP_MAXQUEUESIZE);
+ break;
+
+ default:
+ lookupParamItr = params->find((Property)rulePropMapItr->first);
+ break;
+ };
+
+ if (lookupParamItr == params->end())
+ {
+ // Now the rule has a specified property
+ // that does not exist in the caller's
+ // lookup params list.
+ // This rule does not match.
match = false;
- QPID_LOG(debug, "ACL: name '" << name << "' didn't match with name '"
- << pMItr->second << "' given in the rule");
+ QPID_LOG(debug, "ACL: lookup parameter map doesn't contain the rule property '"
+ << AclHelper::getPropertyStr(rulePropMapItr->first) << "'");
}
- } 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&){
+ else
+ {
+ // Now account for the business of rules
+ // whose property indexes are mismatched.
+ switch (rulePropMapItr->first)
+ {
+ case acl::SPECPROP_MAXQUEUECOUNTUPPERLIMIT:
+ case acl::SPECPROP_MAXQUEUESIZEUPPERLIMIT:
+ limitChecked &=
+ compareIntMax(
+ rulePropMapItr->first,
+ boost::lexical_cast<std::string>(rulePropMapItr->second),
+ boost::lexical_cast<std::string>(lookupParamItr->second));
+ break;
+
+ case acl::SPECPROP_MAXQUEUECOUNTLOWERLIMIT:
+ case acl::SPECPROP_MAXQUEUESIZELOWERLIMIT:
+ limitChecked &=
+ compareIntMin(
+ rulePropMapItr->first,
+ boost::lexical_cast<std::string>(rulePropMapItr->second),
+ boost::lexical_cast<std::string>(lookupParamItr->second));
+ break;
+
+ default:
+ if (matchProp(rulePropMapItr->second, lookupParamItr->second))
+ {
+ QPID_LOG(debug, "ACL: the pair("
+ << AclHelper::getPropertyStr(lookupParamItr->first)
+ << "," << lookupParamItr->second
+ << ") given in lookup matched the pair("
+ << AclHelper::getPropertyStr(rulePropMapItr->first) << ","
+ << rulePropMapItr->second
+ << ") given in the rule");
+ }
+ else
+ {
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, "ACL: the pair("
+ << AclHelper::getPropertyStr(lookupParamItr->first)
+ << "," << lookupParamItr->second
+ << ") given in lookup doesn't match the pair("
+ << AclHelper::getPropertyStr(rulePropMapItr->first)
+ << "," << rulePropMapItr->second
+ << ") given in the rule");
}
- }
- }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;
- }
+ break;
+ };
+ }
+ }
+ else
+ {
+ // params don't exist.
}
}
- if (match)
+ }
+ if (match)
+ {
+ aclresult = rsItr->ruleMode;
+ if (!limitChecked)
{
- aclresult = getACLResult(i->logOnly, i->log);
- QPID_LOG(debug,"Successful match, the decision is:" << AclHelper::getAclResultStr(aclresult));
- return aclresult;
+ // Now a lookup matched all rule properties but one
+ // of the numeric limit checks has failed.
+ // Demote allow rules to corresponding deny rules.
+ switch (aclresult)
+ {
+ case acl::ALLOW:
+ aclresult = acl::DENY;
+ break;
+ case acl::ALLOWLOG:
+ aclresult = acl::DENYLOG;
+ break;
+ default:
+ break;
+ };
}
+ QPID_LOG(debug,"ACL: Successful match, the decision is:"
+ << AclHelper::getAclResultStr(aclresult));
+ return aclresult;
+ }
+ else
+ {
+ // This rule did not match the requested lookup and
+ // does not contribute to an ACL decision.
}
}
}
+ else
+ {
+ // The Action-Object list has entries but not for this actorId
+ // nor for *.
+ }
+ }
+ else
+ {
+ // The Action-Object list has no entries.
+ }
- QPID_LOG(debug,"No successful match, defaulting to the decision mode " << AclHelper::getAclResultStr(aclresult));
- return aclresult;
+ QPID_LOG(debug,"ACL: 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)
+
+ //
+ // lookup
+ //
+ // The ACL main business logic function of matching rules and declaring
+ // an allow or deny result.
+ //
+ 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
+ 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;
@@ -179,83 +329,181 @@ namespace acl {
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 );
-
+ if (itrRule != actionList[action][objType]->end() )
+ {
//loop the vector
- for (ruleSetItr i=itrRule->second.begin(); i<itrRule->second.end(); i++) {
- QPID_LOG(debug, "ACL: checking rule " << i->toString());
+ ruleSetItr rsItr = itrRule->second.end();
+ for (int cnt = itrRule->second.size(); cnt != 0; cnt--)
+ {
+ rsItr--;
// loop the names looking for match
bool match =true;
- for (propertyMapItr pMItr = i->props.begin(); (pMItr != i->props.end()) && match; pMItr++)
+ for (specPropertyMapItr pMItr = rsItr->props.begin();
+ (pMItr != rsItr->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");
+ switch (pMItr->first)
+ {
+ case acl::SPECPROP_NAME:
+ if (matchProp(pMItr->second, name))
+ {
+ QPID_LOG(debug, "ACL: lookup exchange name '"
+ << name << "' matched with rule name '"
+ << pMItr->second << "'");
- }else{
+ }
+ 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{
+ QPID_LOG(debug, "ACL: lookup exchange name '"
+ << name << "' did not match with rule name '"
+ << pMItr->second << "'");
+ }
+ break;
+
+ case acl::SPECPROP_ROUTINGKEY:
+ if (matchProp(pMItr->second, RoutingKey))
+ {
+ QPID_LOG(debug, "ACL: lookup key name '"
+ << name << "' matched with rule routing key '"
+ << pMItr->second << "'");
+ }
+ else
+ {
match= false;
- QPID_LOG(debug, "ACL: name '" << name << "' didn't match with routing_key '"
- << pMItr->second << "' given in the rule");
- }
- }
+ QPID_LOG(debug, "ACL: lookup key name '"
+ << name << "' did not match with rule routing key '"
+ << pMItr->second << "'");
+ }
+ break;
+
+ default:
+ // Don't care
+ break;
+ };
}
if (match){
- aclresult = getACLResult(i->logOnly, i->log);
- QPID_LOG(debug,"Successful match, the decision is:" << AclHelper::getAclResultStr(aclresult));
+ aclresult = rsItr->ruleMode;
+ QPID_LOG(debug,"ACL: Successful match, the decision is:"
+ << AclHelper::getAclResultStr(aclresult));
return aclresult;
}
}
}
}
- QPID_LOG(debug,"No successful match, defaulting to the decision mode " << AclHelper::getAclResultStr(aclresult));
+ QPID_LOG(debug,"ACL: No successful match, defaulting to the decision mode "
+ << AclHelper::getAclResultStr(aclresult));
return aclresult;
}
- AclResult AclData::getACLResult(bool logOnly, bool log)
+ //
+ //
+ //
+ AclData::~AclData()
+ {
+ clear();
+ }
+
+
+ //
+ // Limit check a MAX int limit
+ //
+ bool AclData::compareIntMax(const qpid::acl::SpecProperty theProperty,
+ const std::string theAclValue,
+ const std::string theLookupValue)
{
- switch (decisionMode)
+ uint64_t aclMax (0);
+ uint64_t paramMax (0);
+
+ try
{
- 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;
+ aclMax = boost::lexical_cast<uint64_t>(theAclValue);
+ }
+ catch(const boost::bad_lexical_cast&)
+ {
+ assert (false);
+ return false;
+ }
+ try
+ {
+ paramMax = boost::lexical_cast<uint64_t>(theLookupValue);
+ }
+ catch(const boost::bad_lexical_cast&)
+ {
+ QPID_LOG(error,"ACL: Error evaluating rule. "
+ << "Illegal value given in lookup for property '"
+ << AclHelper::getPropertyStr(theProperty)
+ << "' : " << theLookupValue);
+ return false;
+ }
- 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(debug, "ACL: Numeric greater-than comparison for property "
+ << AclHelper::getPropertyStr(theProperty)
+ << " (value given in lookup = " << theLookupValue
+ << ", value give in rule = " << theAclValue << " )");
+
+ if (( aclMax ) && ( paramMax == 0 || paramMax > aclMax))
+ {
+ QPID_LOG(debug, "ACL: Max limit exceeded for property '"
+ << AclHelper::getPropertyStr(theProperty) << "'");
+ return false;
}
- QPID_LOG(error, "ACL Decision Failed, setting DENY");
- return qpid::acl::DENY;
+ return true;
}
- AclData::~AclData()
+
+ //
+ // limit check a MIN int limit
+ //
+ bool AclData::compareIntMin(const qpid::acl::SpecProperty theProperty,
+ const std::string theAclValue,
+ const std::string theLookupValue)
{
- clear();
+ uint64_t aclMin (0);
+ uint64_t paramMin (0);
+
+ try
+ {
+ aclMin = boost::lexical_cast<uint64_t>(theAclValue);
+ }
+ catch(const boost::bad_lexical_cast&)
+ {
+ assert (false);
+ return false;
+ }
+
+ try
+ {
+ paramMin = boost::lexical_cast<uint64_t>(theLookupValue);
+ }
+ catch(const boost::bad_lexical_cast&)
+ {
+ QPID_LOG(error,"ACL: Error evaluating rule. "
+ << "Illegal value given in lookup for property '"
+ << AclHelper::getPropertyStr(theProperty)
+ << "' : " << theLookupValue);
+ return false;
+ }
+
+ QPID_LOG(debug, "ACL: Numeric less-than comparison for property "
+ << AclHelper::getPropertyStr(theProperty)
+ << " (value given in lookup = " << theLookupValue
+ << ", value give in rule = " << theAclValue << " )");
+
+ if (( aclMin ) && ( paramMin == 0 || paramMin < aclMin))
+ {
+ QPID_LOG(debug, "ACL: Min limit exceeded for property '"
+ << AclHelper::getPropertyStr(theProperty) << "'");
+ return false;
+ }
+
+ return true;
}
-}}
+}}
diff --git a/qpid/cpp/src/qpid/acl/AclData.h b/qpid/cpp/src/qpid/acl/AclData.h
index 81125fdcbc..1c1cb3e9c6 100644
--- a/qpid/cpp/src/qpid/acl/AclData.h
+++ b/qpid/cpp/src/qpid/acl/AclData.h
@@ -33,50 +33,91 @@ class AclData {
public:
typedef std::map<qpid::acl::Property, std::string> propertyMap;
- typedef propertyMap::const_iterator propertyMapItr;
+ typedef propertyMap::const_iterator propertyMapItr;
+
+ typedef std::map<qpid::acl::SpecProperty, std::string> specPropertyMap;
+ typedef specPropertyMap::const_iterator specPropertyMapItr;
+
+ //
+ // rule
+ //
+ // Created by AclReader and stored in a ruleSet vector for subsequent
+ // run-time lookup matching and allow/deny decisions.
+ // RuleSet vectors are indexed by Action-Object-actorId so these
+ // attributes are not part of a rule.
+ // A single ACL file entry may create many rule entries in
+ // many ruleset vectors.
+ //
struct rule {
- bool log;
- bool logOnly; // this is a rule is to log only
+ int rawRuleNum; // rule number in ACL file
+ qpid::acl::AclResult ruleMode; // combined allow/deny log/nolog
+ specPropertyMap props; //
- // key value map
- //??
- propertyMap props;
-
- rule (propertyMap& p):log(false),logOnly(false),props(p) {};
+ rule (int ruleNum, qpid::acl::AclResult res, specPropertyMap& p) :
+ rawRuleNum(ruleNum),
+ ruleMode(res),
+ 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 << "[rule " << rawRuleNum
+ << " ruleMode = " << AclHelper::getAclResultStr(ruleMode)
+ << " props{";
+ for (specPropertyMapItr pMItr = props.begin();
+ pMItr != props.end();
+ pMItr++) {
+ ruleStr << " "
+ << AclHelper::getPropertyStr((SpecProperty) 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;
+ 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;
- 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);
+ // Action*[] -> Object*[] -> map<user -> set<Rule> >
+ aclAction* actionList[qpid::acl::ACTIONSIZE];
+ qpid::acl::AclResult decisionMode; // allow/deny[-log] if no matching rule found
+ bool transferAcl;
+ std::string aclSource;
+
+ AclResult lookup(
+ const std::string& id, // actor id
+ const Action& action,
+ const ObjectType& objType,
+ const std::string& name, // object name
+ std::map<Property, std::string>* params=0);
+
+ AclResult lookup(
+ const std::string& id, // actor id
+ const Action& action,
+ const ObjectType& objType,
+ const std::string& ExchangeName,
+ const std::string& RoutingKey);
bool matchProp(const std::string & src, const std::string& src1);
void clear ();
AclData();
virtual ~AclData();
+
+private:
+ bool compareIntMax(const qpid::acl::SpecProperty theProperty,
+ const std::string theAclValue,
+ const std::string theLookupValue);
+
+ bool compareIntMin(const qpid::acl::SpecProperty theProperty,
+ const std::string theAclValue,
+ const std::string theLookupValue);
};
}} // namespace qpid::acl
diff --git a/qpid/cpp/src/qpid/acl/AclReader.cpp b/qpid/cpp/src/qpid/acl/AclReader.cpp
index 74358a20c1..80debf1bd1 100644
--- a/qpid/cpp/src/qpid/acl/AclReader.cpp
+++ b/qpid/cpp/src/qpid/acl/AclReader.cpp
@@ -49,7 +49,7 @@ namespace acl {
objStatus = ALL;
}
- bool AclReader::aclRule::addProperty(const Property p, const std::string v) {
+ bool AclReader::aclRule::addProperty(const SpecProperty p, const std::string v) {
return props.insert(propNvPair(p, v)).second;
}
@@ -85,146 +85,108 @@ namespace acl {
void AclReader::loadDecisionData(boost::shared_ptr<AclData> d) {
d->clear();
- QPID_LOG(debug, "ACL Load Rules");
- int cnt = rules.size();
+ QPID_LOG(debug, "ACL: Load Rules");
bool foundmode = false;
- for (rlCitr i = rules.end(); cnt; cnt--) {
+ rlCitr i = rules.end();
+ for (int cnt = rules.size(); cnt; cnt--) {
i--;
- QPID_LOG(debug, "ACL Processing " << std::setfill(' ') << std::setw(2)
+ 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 "
+ 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.");
- }
+ AclData::rule rule(cnt, (*i)->res, (*i)->props);
// 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) {
-
- if (acnt == acl::ACT_PUBLISH)
- d->transferAcl = true; // we have transfer ACL
-
- actionstr << AclHelper::getActionStr((Action) acnt) << ",";
-
- //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 actionstr;
+ for (int acnt = ((*i)->actionAll ? 0 : (*i)->action);
+ acnt < acl::ACTIONSIZE;
+ (*i)->actionAll ? acnt++ : acnt = acl::ACTIONSIZE) {
+
+ if (acnt == acl::ACT_PUBLISH)
+ d->transferAcl = true; // we have transfer ACL
+
+ actionstr << AclHelper::getActionStr((Action) acnt) << ",";
+
+ //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;
}
- std::ostringstream objstr;
- for (int ocnt = ((*i)->objStatus != aclRule::VALUE ? 0 : (*i)->object);
+ // TODO: 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) {
- objstr << AclHelper::getObjectTypeStr((ObjectType) ocnt) << ",";
+ (*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);
+ }
+ }
}
+ }
- 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 << ",";
- }
+ 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) << ",";
+ }
- 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));
+ 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)
+ << "}" );
+ }
}
-
}
@@ -277,7 +239,7 @@ namespace acl {
}
ifs.close();
if (err) return -3;
- QPID_LOG(notice, "Read ACL file \"" << fn << "\"");
+ QPID_LOG(notice, "ACL: Read file \"" << fn << "\"");
} catch (const std::exception& e) {
errorStream << "Unable to read ACL file \"" << fn << "\": " << e.what();
ifs.close();
@@ -410,8 +372,8 @@ namespace acl {
// Debug aid
void AclReader::printNames() const {
- QPID_LOG(debug, "Group list: " << groups.size() << " groups found:" );
- std::string tmp;
+ QPID_LOG(debug, "ACL: Group list: " << groups.size() << " groups found:" );
+ std::string tmp("ACL: ");
for (gmCitr i=groups.begin(); i!= groups.end(); i++) {
tmp += " \"";
tmp += i->first;
@@ -421,10 +383,10 @@ namespace acl {
tmp += *j;
}
QPID_LOG(debug, tmp);
- tmp.clear();
+ tmp = "ACL: ";
}
- QPID_LOG(debug, "Name list: " << names.size() << " names found:" );
- tmp.clear();
+ QPID_LOG(debug, "ACL: name list: " << names.size() << " names found:" );
+ tmp = "ACL: ";
for (nsCitr k=names.begin(); k!=names.end(); k++) {
tmp += " ";
tmp += *k;
@@ -501,9 +463,9 @@ namespace acl {
<< propNvp.first << "\". (Must be name=value)";
return false;
}
- Property prop;
+ SpecProperty prop;
try {
- prop = AclHelper::getProperty(propNvp.first);
+ prop = AclHelper::getSpecProperty(propNvp.first);
} catch (...) {
errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber
<< ", Unknown property \"" << propNvp.first << "\".";
@@ -532,10 +494,10 @@ namespace acl {
// Debug aid
void AclReader::printRules() const {
- QPID_LOG(debug, "Rule list: " << rules.size() << " ACL rules found:");
- int cnt = 0;
+ QPID_LOG(debug, "ACL: Rule list: " << rules.size() << " ACL rules found:");
+ int cnt = 1;
for (rlCitr i=rules.begin(); i<rules.end(); i++,cnt++) {
- QPID_LOG(debug, " " << std::setfill(' ') << std::setw(2) << cnt << " " << (*i)->toString());
+ QPID_LOG(debug, "ACL: " << std::setfill(' ') << std::setw(2) << cnt << " " << (*i)->toString());
}
}
diff --git a/qpid/cpp/src/qpid/acl/AclReader.h b/qpid/cpp/src/qpid/acl/AclReader.h
index 62c6f38f37..730013f4ed 100644
--- a/qpid/cpp/src/qpid/acl/AclReader.h
+++ b/qpid/cpp/src/qpid/acl/AclReader.h
@@ -33,65 +33,71 @@ namespace qpid {
namespace acl {
class AclReader {
- typedef std::set<std::string> nameSet;
- typedef nameSet::const_iterator nsCitr;
- typedef boost::shared_ptr<nameSet> nameSetPtr;
-
- typedef std::pair<std::string, nameSetPtr> groupPair;
- typedef std::map<std::string, nameSetPtr> groupMap;
- typedef groupMap::const_iterator gmCitr;
- typedef std::pair<gmCitr, bool> gmRes;
-
- typedef std::pair<Property, std::string> propNvPair;
- typedef std::map<Property, std::string> propMap;
- typedef propMap::const_iterator pmCitr;
-
+ typedef std::set<std::string> nameSet;
+ typedef nameSet::const_iterator nsCitr;
+ typedef boost::shared_ptr<nameSet> nameSetPtr;
+
+ typedef std::pair<std::string, nameSetPtr> groupPair;
+ typedef std::map<std::string, nameSetPtr> groupMap;
+ typedef groupMap::const_iterator gmCitr;
+ typedef std::pair<gmCitr, bool> gmRes;
+
+ typedef std::pair<SpecProperty, std::string> propNvPair;
+ typedef std::map<SpecProperty, std::string> propMap;
+ typedef propMap::const_iterator pmCitr;
+
+ //
+ // aclRule
+ //
+ // A temporary rule created during ACL file processing.
+ //
class aclRule {
public:
enum objectStatus {NONE, VALUE, ALL};
- AclResult res;
- nameSet names;
- bool actionAll; // True if action is set to keyword "all"
- Action action; // Ignored if action is set to keyword "all"
- objectStatus objStatus;
- ObjectType object; // Ignored for all status values except VALUE
- propMap props;
+
+ AclResult res;
+ nameSet names;
+ bool actionAll; // True if action is set to keyword "all"
+ Action action; // Ignored if action is set to keyword "all"
+ objectStatus objStatus;
+ ObjectType object; // Ignored for all status values except VALUE
+ propMap props;
public:
aclRule(const AclResult r, const std::string n, const groupMap& groups); // action = "all"
aclRule(const AclResult r, const std::string n, const groupMap& groups, const Action a);
void setObjectType(const ObjectType o);
void setObjectTypeAll();
- bool addProperty(const Property p, const std::string v);
+ bool addProperty(const SpecProperty p, const std::string v);
bool validate(const AclHelper::objectMapPtr& validationMap);
std::string toString(); // debug aid
private:
void processName(const std::string& name, const groupMap& groups);
};
- typedef boost::shared_ptr<aclRule> aclRulePtr;
- typedef std::vector<aclRulePtr> ruleList;
- typedef ruleList::const_iterator rlCitr;
+ typedef boost::shared_ptr<aclRule> aclRulePtr;
+ typedef std::vector<aclRulePtr> ruleList;
+ typedef ruleList::const_iterator rlCitr;
- typedef std::vector<std::string> tokList;
- typedef tokList::const_iterator tlCitr;
+ typedef std::vector<std::string> tokList;
+ typedef tokList::const_iterator tlCitr;
- typedef std::set<std::string> keywordSet;
- typedef keywordSet::const_iterator ksCitr;
+ typedef std::set<std::string> keywordSet;
+ typedef keywordSet::const_iterator ksCitr;
typedef std::pair<std::string, std::string> nvPair; // Name-Value pair
- std::string fileName;
- int lineNumber;
- bool contFlag;
- std::string groupName;
- nameSet names;
- groupMap groups;
- ruleList rules;
+ std::string fileName;
+ int lineNumber;
+ bool contFlag;
+ std::string groupName;
+ nameSet names;
+ groupMap groups;
+ ruleList rules;
AclHelper::objectMapPtr validationMap;
- std::ostringstream errorStream;
+ std::ostringstream errorStream;
public:
AclReader();
virtual ~AclReader();
- int read(const std::string& fn, boost::shared_ptr<AclData> d);
+ int read(const std::string& fn, boost::shared_ptr<AclData> d); // return=0 for success
std::string getError();
private:
diff --git a/qpid/cpp/src/qpid/acl/AclValidator.cpp b/qpid/cpp/src/qpid/acl/AclValidator.cpp
index d5a00b005b..49bb65db4b 100644
--- a/qpid/cpp/src/qpid/acl/AclValidator.cpp
+++ b/qpid/cpp/src/qpid/acl/AclValidator.cpp
@@ -29,7 +29,7 @@
namespace qpid {
namespace acl {
- AclValidator::IntPropertyType::IntPropertyType(int64_t i,int64_t j) : min(i), max(j){
+ AclValidator::IntPropertyType::IntPropertyType(int64_t i,int64_t j) : min(i), max(j){
}
bool AclValidator::IntPropertyType::validate(const std::string& val) {
@@ -49,12 +49,12 @@ namespace acl {
}
std::string AclValidator::IntPropertyType::allowedValues() {
- return "values should be between " +
+ 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){
+ AclValidator::EnumPropertyType::EnumPropertyType(std::vector<std::string>& allowed): values(allowed){
}
bool AclValidator::EnumPropertyType::validate(const std::string& val) {
@@ -78,24 +78,27 @@ namespace acl {
}
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()))
- )
- );
+ validators.insert(Validator(acl::SPECPROP_MAXQUEUESIZELOWERLIMIT,
+ boost::shared_ptr<PropertyType>(
+ new IntPropertyType(0,std::numeric_limits<int64_t>::max()))));
+
+ validators.insert(Validator(acl::SPECPROP_MAXQUEUESIZEUPPERLIMIT,
+ boost::shared_ptr<PropertyType>(
+ new IntPropertyType(0,std::numeric_limits<int64_t>::max()))));
+
+ validators.insert(Validator(acl::SPECPROP_MAXQUEUECOUNTLOWERLIMIT,
+ boost::shared_ptr<PropertyType>(
+ new IntPropertyType(0,std::numeric_limits<int64_t>::max()))));
+
+ validators.insert(Validator(acl::SPECPROP_MAXQUEUECOUNTUPPERLIMIT,
+ 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))
- )
- );
+ validators.insert(Validator(acl::SPECPROP_POLICYTYPE,
+ boost::shared_ptr<PropertyType>(
+ new EnumPropertyType(v))));
}
@@ -114,9 +117,9 @@ namespace acl {
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
+ d->actionList[cnt][cnt1]->end(),
+ boost::bind(&AclValidator::validateRuleSet, this, _1));
+ }//if
}//for
}//if
}//for
@@ -125,25 +128,29 @@ namespace acl {
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));
+ 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));
+ boost::bind(&AclValidator::validateProperty, this, _1));
}
- void AclValidator::validateProperty(std::pair<const qpid::acl::Property, std::string>& prop){
+ void AclValidator::validateProperty(std::pair<const qpid::acl::SpecProperty, std::string>& prop){
ValidatorItr itr = validators.find(prop.first);
if (itr != validators.end()){
- QPID_LOG(debug,"Found validator for property " << itr->second->allowedValues());
+ QPID_LOG(debug,"ACL: Found validator for property '" << acl::AclHelper::getPropertyStr(itr->first)
+ << "'. " << itr->second->allowedValues());
if (!itr->second->validate(prop.second)){
- throw Exception( prop.second + " is not a valid value for '" +
+ QPID_LOG(debug, "ACL: Property failed validation. '" << prop.second << "' is not a valid value for '"
+ << AclHelper::getPropertyStr(prop.first) << "'");
+
+ throw Exception( prop.second + " is not a valid value for '" +
AclHelper::getPropertyStr(prop.first) + "', " +
itr->second->allowedValues());
- }
+ }
}
}
diff --git a/qpid/cpp/src/qpid/acl/AclValidator.h b/qpid/cpp/src/qpid/acl/AclValidator.h
index 966e5d326b..f85c241b06 100644
--- a/qpid/cpp/src/qpid/acl/AclValidator.h
+++ b/qpid/cpp/src/qpid/acl/AclValidator.h
@@ -33,18 +33,18 @@ namespace acl {
class AclValidator {
/* Base Property */
- class PropertyType{
-
+ class PropertyType{
+
public:
virtual ~PropertyType(){};
virtual bool validate(const std::string& val)=0;
virtual std::string allowedValues()=0;
};
- class IntPropertyType : public PropertyType{
+ class IntPropertyType : public PropertyType{
int64_t min;
int64_t max;
-
+
public:
IntPropertyType(int64_t min,int64_t max);
virtual ~IntPropertyType (){};
@@ -53,7 +53,7 @@ class AclValidator {
};
class EnumPropertyType : public PropertyType{
- std::vector<std::string> values;
+ std::vector<std::string> values;
public:
EnumPropertyType(std::vector<std::string>& allowed);
@@ -61,23 +61,23 @@ class AclValidator {
virtual bool validate(const std::string& val);
virtual std::string allowedValues();
};
-
- typedef std::pair<acl::Property,boost::shared_ptr<PropertyType> > Validator;
- typedef std::map<acl::Property,boost::shared_ptr<PropertyType> > ValidatorMap;
+
+ typedef std::pair<acl::SpecProperty,boost::shared_ptr<PropertyType> > Validator;
+ typedef std::map<acl::SpecProperty,boost::shared_ptr<PropertyType> > ValidatorMap;
typedef ValidatorMap::iterator ValidatorItr;
-
+
ValidatorMap validators;
public:
void validateRuleSet(std::pair<const std::string, qpid::acl::AclData::ruleSet>& rules);
void validateRule(qpid::acl::AclData::rule& rule);
- void validateProperty(std::pair<const qpid::acl::Property, std::string>& prop);
- void validate(boost::shared_ptr<AclData> d);
+ void validateProperty(std::pair<const qpid::acl::SpecProperty, std::string>& prop);
+ void validate(boost::shared_ptr<AclData> d);
AclValidator();
~AclValidator();
};
-
+
}} // namespace qpid::acl
#endif // QPID_ACL_ACLVALIDATOR_H
diff --git a/qpid/cpp/src/qpid/broker/AclModule.h b/qpid/cpp/src/qpid/broker/AclModule.h
index e32ff266b9..be143a23e7 100644
--- a/qpid/cpp/src/qpid/broker/AclModule.h
+++ b/qpid/cpp/src/qpid/broker/AclModule.h
@@ -32,17 +32,83 @@ 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};
+ // Interface enumerations.
+ // These enumerations define enum lists and implied text strings
+ // to match. They are used in two areas:
+ // 1. In the ACL specifications in the ACL file, file parsing, and
+ // internal rule storage.
+ // 2. In the authorize interface in the rest of the broker where
+ // code requests the ACL module to authorize an action.
+
+ // ObjectType shared between ACL spec and ACL authorise interface
+ enum ObjectType {
+ OBJ_QUEUE,
+ OBJ_EXCHANGE,
+ OBJ_BROKER,
+ OBJ_LINK,
+ OBJ_METHOD,
+ OBJECTSIZE }; // OBJECTSIZE must be last in list
+
+ // Action shared between ACL spec and ACL authorise interface
+ 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
+
+ // Property used in ACL authorize interface
+ 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 };
+
+ // Property used in ACL spec file
+ // Note for properties common to file processing/rule storage and to
+ // broker rule lookups the identical enum values are used.
+ enum SpecProperty {
+ SPECPROP_NAME = PROP_NAME,
+ SPECPROP_DURABLE = PROP_DURABLE,
+ SPECPROP_OWNER = PROP_OWNER,
+ SPECPROP_ROUTINGKEY = PROP_ROUTINGKEY,
+ SPECPROP_PASSIVE = PROP_PASSIVE,
+ SPECPROP_AUTODELETE = PROP_AUTODELETE,
+ SPECPROP_EXCLUSIVE = PROP_EXCLUSIVE,
+ SPECPROP_TYPE = PROP_TYPE,
+ SPECPROP_ALTERNATE = PROP_ALTERNATE,
+ SPECPROP_QUEUENAME = PROP_QUEUENAME,
+ SPECPROP_SCHEMAPACKAGE = PROP_SCHEMAPACKAGE,
+ SPECPROP_SCHEMACLASS = PROP_SCHEMACLASS,
+ SPECPROP_POLICYTYPE = PROP_POLICYTYPE,
+
+ SPECPROP_MAXQUEUESIZELOWERLIMIT,
+ SPECPROP_MAXQUEUESIZEUPPERLIMIT,
+ SPECPROP_MAXQUEUECOUNTLOWERLIMIT,
+ SPECPROP_MAXQUEUECOUNTUPPERLIMIT };
+
+// AclResult shared between ACL spec and ACL authorise interface
+ enum AclResult {
+ ALLOW,
+ ALLOWLOG,
+ DENY,
+ DENYLOG };
} // namespace acl
@@ -54,14 +120,25 @@ namespace broker {
public:
- // effienty turn off ACL on message transfer.
+ // Some ACLs are invoked on every message transfer.
+ // doTransferAcl pervents time consuming ACL calls on a per-message basis.
virtual bool doTransferAcl()=0;
- virtual bool authorise(const std::string& id, const acl::Action& action, const acl::ObjectType& objType, const std::string& name,
+ 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 bool authorise(
+ const std::string& id,
+ const acl::Action& action,
+ const acl::ObjectType& objType,
+ const std::string& ExchangeName,
+ const std::string& RoutingKey)=0;
+
+ // Add specialized authorise() methods as required.
virtual ~AclModule() {};
};
@@ -134,7 +211,7 @@ namespace acl {
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;
+ if (str.compare("maxqueuecount") == 0) return PROP_MAXQUEUECOUNT;
throw str;
}
static inline std::string getPropertyStr(const Property p) {
@@ -153,11 +230,57 @@ namespace acl {
case PROP_SCHEMACLASS: return "schemaclass";
case PROP_POLICYTYPE: return "policytype";
case PROP_MAXQUEUESIZE: return "maxqueuesize";
- case PROP_MAXQUEUECOUNT: return "maxqueuecount";
+ case PROP_MAXQUEUECOUNT: return "maxqueuecount";
default: assert(false); // should never get here
}
return "";
}
+ static inline SpecProperty getSpecProperty(const std::string& str) {
+ if (str.compare("name") == 0) return SPECPROP_NAME;
+ if (str.compare("durable") == 0) return SPECPROP_DURABLE;
+ if (str.compare("owner") == 0) return SPECPROP_OWNER;
+ if (str.compare("routingkey") == 0) return SPECPROP_ROUTINGKEY;
+ if (str.compare("passive") == 0) return SPECPROP_PASSIVE;
+ if (str.compare("autodelete") == 0) return SPECPROP_AUTODELETE;
+ if (str.compare("exclusive") == 0) return SPECPROP_EXCLUSIVE;
+ if (str.compare("type") == 0) return SPECPROP_TYPE;
+ if (str.compare("alternate") == 0) return SPECPROP_ALTERNATE;
+ if (str.compare("queuename") == 0) return SPECPROP_QUEUENAME;
+ if (str.compare("schemapackage") == 0) return SPECPROP_SCHEMAPACKAGE;
+ if (str.compare("schemaclass") == 0) return SPECPROP_SCHEMACLASS;
+ if (str.compare("policytype") == 0) return SPECPROP_POLICYTYPE;
+ if (str.compare("queuemaxsizelowerlimit") == 0) return SPECPROP_MAXQUEUESIZELOWERLIMIT;
+ if (str.compare("queuemaxsizeupperlimit") == 0) return SPECPROP_MAXQUEUESIZEUPPERLIMIT;
+ if (str.compare("queuemaxcountlowerlimit") == 0) return SPECPROP_MAXQUEUECOUNTLOWERLIMIT;
+ if (str.compare("queuemaxcountupperlimit") == 0) return SPECPROP_MAXQUEUECOUNTUPPERLIMIT;
+ // Allow old names in ACL file as aliases for newly-named properties
+ if (str.compare("maxqueuesize") == 0) return SPECPROP_MAXQUEUESIZEUPPERLIMIT;
+ if (str.compare("maxqueuecount") == 0) return SPECPROP_MAXQUEUECOUNTUPPERLIMIT;
+ throw str;
+ }
+ static inline std::string getPropertyStr(const SpecProperty p) {
+ switch (p) {
+ case SPECPROP_NAME: return "name";
+ case SPECPROP_DURABLE: return "durable";
+ case SPECPROP_OWNER: return "owner";
+ case SPECPROP_ROUTINGKEY: return "routingkey";
+ case SPECPROP_PASSIVE: return "passive";
+ case SPECPROP_AUTODELETE: return "autodelete";
+ case SPECPROP_EXCLUSIVE: return "exclusive";
+ case SPECPROP_TYPE: return "type";
+ case SPECPROP_ALTERNATE: return "alternate";
+ case SPECPROP_QUEUENAME: return "queuename";
+ case SPECPROP_SCHEMAPACKAGE: return "schemapackage";
+ case SPECPROP_SCHEMACLASS: return "schemaclass";
+ case SPECPROP_POLICYTYPE: return "policytype";
+ case SPECPROP_MAXQUEUESIZELOWERLIMIT: return "queuemaxsizelowerlimit";
+ case SPECPROP_MAXQUEUESIZEUPPERLIMIT: return "queuemaxsizeupperlimit";
+ case SPECPROP_MAXQUEUECOUNTLOWERLIMIT: return "queuemaxcountlowerlimit";
+ case SPECPROP_MAXQUEUECOUNTUPPERLIMIT: return "queuemaxcountupperlimit";
+ default: assert(false); // should never get here
+ }
+ return "";
+ }
static inline AclResult getAclResult(const std::string& str) {
if (str.compare("allow") == 0) return ALLOW;
if (str.compare("allow-log") == 0) return ALLOWLOG;
@@ -187,8 +310,11 @@ namespace acl {
typedef boost::shared_ptr<objectMap> objectMapPtr;
typedef std::map<Property, std::string> propMap;
typedef propMap::const_iterator propMapItr;
+ typedef std::map<SpecProperty, std::string> specPropMap;
+ typedef specPropMap::const_iterator specPropMapItr;
- // This map contains the legal combinations of object/action/properties found in an ACL file
+ // 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();
@@ -260,21 +386,31 @@ namespace acl {
map->insert(objectPair(OBJ_METHOD, a4));
}
- static std::string propertyMapToString(const std::map<Property, std::string>* params) {
+ //
+ // properyMapToString
+ //
+ template <typename T>
+ static std::string propertyMapToString(
+ const std::map<T, 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;
+ for (typename std::map<T, std::string>::const_iterator
+ pMItr = params->begin(); pMItr != params->end(); pMItr++)
+ {
+ ss << " " << getPropertyStr((T) pMItr-> first)
+ << "=" << pMItr->second;
}
}
ss << " }";
return ss.str();
}
+
};
-
+
}} // namespace qpid::acl
#endif // QPID_ACLMODULE_ACL_H
diff --git a/qpid/cpp/src/qpid/broker/ConnectionHandler.h b/qpid/cpp/src/qpid/broker/ConnectionHandler.h
index 05c5f00c57..2e25543308 100644
--- a/qpid/cpp/src/qpid/broker/ConnectionHandler.h
+++ b/qpid/cpp/src/qpid/broker/ConnectionHandler.h
@@ -35,7 +35,6 @@
#include "qpid/framing/ProtocolInitiation.h"
#include "qpid/framing/ProtocolVersion.h"
#include "qpid/Exception.h"
-#include "qpid/broker/AclModule.h"
#include "qpid/sys/SecurityLayer.h"
diff --git a/qpid/cpp/src/qpid/broker/SemanticState.h b/qpid/cpp/src/qpid/broker/SemanticState.h
index 2b4b92e8ac..e5e1d2da16 100644
--- a/qpid/cpp/src/qpid/broker/SemanticState.h
+++ b/qpid/cpp/src/qpid/broker/SemanticState.h
@@ -40,7 +40,6 @@
#include "qpid/sys/AggregateOutput.h"
#include "qpid/sys/Mutex.h"
#include "qpid/sys/AtomicValue.h"
-#include "qpid/broker/AclModule.h"
#include "qmf/org/apache/qpid/broker/Subscription.h"
#include <list>
diff --git a/qpid/cpp/src/tests/acl.py b/qpid/cpp/src/tests/acl.py
index 16261795ff..a1b7f93a2e 100755
--- a/qpid/cpp/src/tests/acl.py
+++ b/qpid/cpp/src/tests/acl.py
@@ -7,9 +7,9 @@
# to you 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
@@ -31,13 +31,13 @@ import qpid.messaging
class ACLFile:
def __init__(self, policy='data_dir/policy.acl'):
self.f = open(policy,'w')
-
+
def write(self,line):
self.f.write(line)
-
+
def close(self):
self.f.close()
-
+
class ACLTests(TestBase010):
def get_session(self, user, passwd):
@@ -75,8 +75,8 @@ class ACLTests(TestBase010):
#=====================================
# ACL general tests
- #=====================================
-
+ #=====================================
+
def test_deny_mode(self):
"""
Test the deny all mode
@@ -85,12 +85,12 @@ class ACLTests(TestBase010):
aclf.write('acl allow anonymous all all\n')
aclf.write('acl allow bob@QPID create queue\n')
aclf.write('acl deny all all')
- aclf.close()
-
+ aclf.close()
+
result = self.reload_acl()
if (result):
- self.fail(result)
-
+ self.fail(result)
+
session = self.get_session('bob','bob')
try:
session.queue_declare(queue="deny_queue")
@@ -98,13 +98,13 @@ class ACLTests(TestBase010):
if (403 == e.args[0].error_code):
self.fail("ACL should allow queue create request");
self.fail("Error during queue create request");
-
+
try:
session.exchange_bind(exchange="amq.direct", queue="deny_queue", binding_key="routing_key")
self.fail("ACL should deny queue bind request");
except qpid.session.SessionException, e:
- self.assertEqual(403,e.args[0].error_code)
-
+ self.assertEqual(403,e.args[0].error_code)
+
def test_allow_mode(self):
"""
Test the allow all mode
@@ -112,12 +112,12 @@ class ACLTests(TestBase010):
aclf = self.get_acl_file()
aclf.write('acl deny bob@QPID bind exchange\n')
aclf.write('acl allow all all')
- aclf.close()
-
+ aclf.close()
+
result = self.reload_acl()
if (result):
- self.fail(result)
-
+ self.fail(result)
+
session = self.get_session('bob','bob')
try:
session.queue_declare(queue="allow_queue")
@@ -125,18 +125,42 @@ class ACLTests(TestBase010):
if (403 == e.args[0].error_code):
self.fail("ACL should allow queue create request");
self.fail("Error during queue create request");
-
+
try:
session.exchange_bind(exchange="amq.direct", queue="allow_queue", binding_key="routing_key")
self.fail("ACL should deny queue bind request");
except qpid.session.SessionException, e:
- self.assertEqual(403,e.args[0].error_code)
-
-
+ self.assertEqual(403,e.args[0].error_code)
+
+
+ def test_allow_mode_with_specfic_allow_override(self):
+ """
+ Specific allow overrides a general deny
+ """
+ aclf = self.get_acl_file()
+ aclf.write('group admins bob@QPID joe@QPID \n')
+ aclf.write('acl allow bob@QPID create queue \n')
+ aclf.write('acl deny admins create queue \n')
+ aclf.write('acl allow all all')
+ aclf.close()
+
+ result = self.reload_acl()
+ if (result):
+ self.fail(result)
+
+ session = self.get_session('bob','bob')
+
+ try:
+ session.queue_declare(queue='zed')
+ except qpid.session.SessionException, e:
+ if (403 == e.args[0].error_code):
+ self.fail("ACL should allow create queue request");
+
+
#=====================================
# ACL file format tests
- #=====================================
-
+ #=====================================
+
def test_empty_groups(self):
"""
Test empty groups
@@ -145,11 +169,11 @@ class ACLTests(TestBase010):
aclf.write('acl group\n')
aclf.write('acl group admins bob@QPID joe@QPID\n')
aclf.write('acl allow all all')
- aclf.close()
-
- result = self.reload_acl()
+ aclf.close()
+
+ result = self.reload_acl()
if (result.find("Insufficient tokens for acl definition",0,len(result)) == -1):
- self.fail("ACL Reader should reject the acl file due to empty group name")
+ self.fail("ACL Reader should reject the acl file due to empty group name")
def test_illegal_acl_formats(self):
"""
@@ -159,24 +183,24 @@ class ACLTests(TestBase010):
aclf.write('acl group admins bob@QPID joe@QPID\n')
aclf.write('acl allow all all')
aclf.close()
-
- result = self.reload_acl()
+
+ result = self.reload_acl()
if (result.find("Unknown ACL permission",0,len(result)) == -1):
- self.fail(result)
-
+ self.fail(result)
+
def test_illegal_extension_lines(self):
"""
Test illegal extension lines
"""
-
+
aclf = self.get_acl_file()
aclf.write('group admins bob@QPID \n')
aclf.write(' \ \n')
aclf.write('joe@QPID \n')
aclf.write('acl allow all all')
- aclf.close()
-
- result = self.reload_acl()
+ aclf.close()
+
+ result = self.reload_acl()
if (result.find("contains an illegal extension",0,len(result)) == -1):
self.fail(result)
@@ -194,7 +218,7 @@ class ACLTests(TestBase010):
aclf.write('host/123.example.com@TEST.COM\n') # should be allowed
aclf.write('acl allow all all')
aclf.close()
-
+
result = self.reload_acl()
if (result):
self.fail(result)
@@ -209,7 +233,7 @@ class ACLTests(TestBase010):
aclf.write('acl deny admin bind exchange\n')
aclf.write('acl allow all all')
aclf.close()
-
+
result = self.reload_acl()
if (result.find("Username 'bob' must contain a realm",0,len(result)) == -1):
self.fail(result)
@@ -225,7 +249,7 @@ class ACLTests(TestBase010):
aclf.write('group test4 host/somemachine.example.com@EXAMPLE.COM\n') # should be allowed
aclf.write('acl allow all all')
aclf.close()
-
+
result = self.reload_acl()
if (result):
self.fail(result)
@@ -233,7 +257,7 @@ class ACLTests(TestBase010):
aclf = self.get_acl_file()
aclf.write('group test1 joe$H@EXAMPLE.com\n') # shouldn't be allowed
aclf.write('acl allow all all')
- aclf.close()
+ aclf.close()
result = self.reload_acl()
if (result.find("Username \"joe$H@EXAMPLE.com\" contains illegal characters",0,len(result)) == -1):
@@ -247,78 +271,190 @@ class ACLTests(TestBase010):
"""
Test illegal queue policy
"""
-
+
aclf = self.get_acl_file()
aclf.write('acl deny bob@QPID create queue name=q2 exclusive=true policytype=ding\n')
aclf.write('acl allow all all')
- aclf.close()
-
- result = self.reload_acl()
+ aclf.close()
+
+ result = self.reload_acl()
expected = "ding is not a valid value for 'policytype', possible values are one of" \
- " { 'ring' 'ring_strict' 'flow_to_disk' 'reject' }";
+ " { 'ring' 'ring_strict' 'flow_to_disk' 'reject' }";
if (result.find(expected) == -1):
- self.fail(result)
+ self.fail(result)
- def test_illegal_queue_size(self):
+ def test_illegal_queuemaxsize_upper_limit_spec(self):
"""
Test illegal queue policy
"""
-
+ #
+ # Use maxqueuesize
+ #
aclf = self.get_acl_file()
aclf.write('acl deny bob@QPID create queue name=q2 maxqueuesize=-1\n')
aclf.write('acl allow all all')
- aclf.close()
-
- result = self.reload_acl()
- expected = "-1 is not a valid value for 'maxqueuesize', " \
- "values should be between 0 and 9223372036854775807";
+ aclf.close()
+
+ result = self.reload_acl()
+ expected = "-1 is not a valid value for 'queuemaxsizeupperlimit', " \
+ "values should be between 0 and 9223372036854775807";
if (result.find(expected) == -1):
- self.fail(result)
+ self.fail(result)
aclf = self.get_acl_file()
aclf.write('acl deny bob@QPID create queue name=q2 maxqueuesize=9223372036854775808\n')
- aclf.write('acl allow all all')
- aclf.close()
-
- result = self.reload_acl()
- expected = "9223372036854775808 is not a valid value for 'maxqueuesize', " \
+ aclf.write('acl allow all all')
+ aclf.close()
+
+ result = self.reload_acl()
+ expected = "9223372036854775808 is not a valid value for 'queuemaxsizeupperlimit', " \
"values should be between 0 and 9223372036854775807";
if (result.find(expected) == -1):
- self.fail(result)
+ self.fail(result)
+ #
+ # Use queuemaxsizeupperlimit
+ #
+ aclf = self.get_acl_file()
+ aclf.write('acl deny bob@QPID create queue name=q2 queuemaxsizeupperlimit=-1\n')
+ aclf.write('acl allow all all')
+ aclf.close()
- def test_illegal_queue_count(self):
+ result = self.reload_acl()
+ expected = "-1 is not a valid value for 'queuemaxsizeupperlimit', " \
+ "values should be between 0 and 9223372036854775807";
+ if (result.find(expected) == -1):
+ self.fail(result)
+
+ aclf = self.get_acl_file()
+ aclf.write('acl deny bob@QPID create queue name=q2 queuemaxsizeupperlimit=9223372036854775808\n')
+ aclf.write('acl allow all all')
+ aclf.close()
+
+ result = self.reload_acl()
+ expected = "9223372036854775808 is not a valid value for 'queuemaxsizeupperlimit', " \
+ "values should be between 0 and 9223372036854775807";
+ if (result.find(expected) == -1):
+ self.fail(result)
+
+
+
+ def test_illegal_queuemaxcount_upper_limit_spec(self):
"""
Test illegal queue policy
"""
-
+ #
+ # Use maxqueuecount
+ #
+
aclf = self.get_acl_file()
aclf.write('acl deny bob@QPID create queue name=q2 maxqueuecount=-1\n')
aclf.write('acl allow all all')
- aclf.close()
-
- result = self.reload_acl()
- expected = "-1 is not a valid value for 'maxqueuecount', " \
- "values should be between 0 and 9223372036854775807";
+ aclf.close()
+
+ result = self.reload_acl()
+ expected = "-1 is not a valid value for 'queuemaxcountupperlimit', " \
+ "values should be between 0 and 9223372036854775807";
if (result.find(expected) == -1):
- self.fail(result)
+ self.fail(result)
aclf = self.get_acl_file()
aclf.write('acl deny bob@QPID create queue name=q2 maxqueuecount=9223372036854775808\n')
- aclf.write('acl allow all all')
- aclf.close()
-
- result = self.reload_acl()
- expected = "9223372036854775808 is not a valid value for 'maxqueuecount', " \
+ aclf.write('acl allow all all')
+ aclf.close()
+
+ result = self.reload_acl()
+ expected = "9223372036854775808 is not a valid value for 'queuemaxcountupperlimit', " \
+ "values should be between 0 and 9223372036854775807";
+ if (result.find(expected) == -1):
+ self.fail(result)
+
+ #
+ # use maxqueuecountupperlimit
+ #
+ aclf = self.get_acl_file()
+ aclf.write('acl deny bob@QPID create queue name=q2 queuemaxcountupperlimit=-1\n')
+ aclf.write('acl allow all all')
+ aclf.close()
+
+ result = self.reload_acl()
+ expected = "-1 is not a valid value for 'queuemaxcountupperlimit', " \
+ "values should be between 0 and 9223372036854775807";
+ if (result.find(expected) == -1):
+ self.fail(result)
+
+ aclf = self.get_acl_file()
+ aclf.write('acl deny bob@QPID create queue name=q2 queuemaxcountupperlimit=9223372036854775808\n')
+ aclf.write('acl allow all all')
+ aclf.close()
+
+ result = self.reload_acl()
+ expected = "9223372036854775808 is not a valid value for 'queuemaxcountupperlimit', " \
+ "values should be between 0 and 9223372036854775807";
+ if (result.find(expected) == -1):
+ self.fail(result)
+
+
+ def test_illegal_queuemaxsize_lower_limit_spec(self):
+ """
+ Test illegal queue policy
+ """
+ aclf = self.get_acl_file()
+ aclf.write('acl deny bob@QPID create queue name=q2 queuemaxsizelowerlimit=-1\n')
+ aclf.write('acl allow all all')
+ aclf.close()
+
+ result = self.reload_acl()
+ expected = "-1 is not a valid value for 'queuemaxsizelowerlimit', " \
+ "values should be between 0 and 9223372036854775807";
+ if (result.find(expected) == -1):
+ self.fail(result)
+
+ aclf = self.get_acl_file()
+ aclf.write('acl deny bob@QPID create queue name=q2 queuemaxsizelowerlimit=9223372036854775808\n')
+ aclf.write('acl allow all all')
+ aclf.close()
+
+ result = self.reload_acl()
+ expected = "9223372036854775808 is not a valid value for 'queuemaxsizelowerlimit', " \
+ "values should be between 0 and 9223372036854775807";
+ if (result.find(expected) == -1):
+ self.fail(result)
+
+
+
+ def test_illegal_queuemaxcount_lower_limit_spec(self):
+ """
+ Test illegal queue policy
+ """
+
+ aclf = self.get_acl_file()
+ aclf.write('acl deny bob@QPID create queue name=q2 queuemaxcountlowerlimit=-1\n')
+ aclf.write('acl allow all all')
+ aclf.close()
+
+ result = self.reload_acl()
+ expected = "-1 is not a valid value for 'queuemaxcountlowerlimit', " \
+ "values should be between 0 and 9223372036854775807";
+ if (result.find(expected) == -1):
+ self.fail(result)
+
+ aclf = self.get_acl_file()
+ aclf.write('acl deny bob@QPID create queue name=q2 queuemaxcountlowerlimit=9223372036854775808\n')
+ aclf.write('acl allow all all')
+ aclf.close()
+
+ result = self.reload_acl()
+ expected = "9223372036854775808 is not a valid value for 'queuemaxcountlowerlimit', " \
"values should be between 0 and 9223372036854775807";
if (result.find(expected) == -1):
- self.fail(result)
+ self.fail(result)
#=====================================
# ACL queue tests
#=====================================
-
+
def test_queue_allow_mode(self):
"""
Test cases for queue acl in allow mode
@@ -328,37 +464,37 @@ class ACLTests(TestBase010):
aclf.write('acl deny bob@QPID create queue name=q2 exclusive=true policytype=ring\n')
aclf.write('acl deny bob@QPID access queue name=q3\n')
aclf.write('acl deny bob@QPID purge queue name=q3\n')
- aclf.write('acl deny bob@QPID delete queue name=q4\n')
- aclf.write('acl deny bob@QPID create queue name=q5 maxqueuesize=1000 maxqueuecount=100\n')
+ aclf.write('acl deny bob@QPID delete queue name=q4\n')
+ aclf.write('acl deny bob@QPID create queue name=q5 maxqueuesize=1000 maxqueuecount=100\n')
aclf.write('acl allow all all')
- aclf.close()
-
+ aclf.close()
+
result = self.reload_acl()
if (result):
- self.fail(result)
-
+ self.fail(result)
+
session = self.get_session('bob','bob')
-
+
try:
session.queue_declare(queue="q1", durable=True, passive=True)
self.fail("ACL should deny queue create request with name=q1 durable=true passive=true");
except qpid.session.SessionException, e:
self.assertEqual(403,e.args[0].error_code)
session = self.get_session('bob','bob')
-
+
try:
queue_options = {}
- queue_options["qpid.policy_type"] = "ring"
+ queue_options["qpid.policy_type"] = "ring"
session.queue_declare(queue="q2", exclusive=True, arguments=queue_options)
self.fail("ACL should deny queue create request with name=q2 exclusive=true qpid.policy_type=ring");
except qpid.session.SessionException, e:
- self.assertEqual(403,e.args[0].error_code)
+ self.assertEqual(403,e.args[0].error_code)
session = self.get_session('bob','bob')
-
+
try:
queue_options = {}
- queue_options["qpid.policy_type"] = "ring_strict"
- session.queue_declare(queue="q2", exclusive=True, arguments=queue_options)
+ queue_options["qpid.policy_type"] = "ring_strict"
+ session.queue_declare(queue="q2", exclusive=True, arguments=queue_options)
except qpid.session.SessionException, e:
if (403 == e.args[0].error_code):
self.fail("ACL should allow queue create request with name=q2 exclusive=true qpid.policy_type=ring_strict");
@@ -366,17 +502,17 @@ class ACLTests(TestBase010):
try:
queue_options = {}
queue_options["qpid.max_count"] = 200
- queue_options["qpid.max_size"] = 500
+ queue_options["qpid.max_size"] = 500
session.queue_declare(queue="q5", exclusive=True, arguments=queue_options)
self.fail("ACL should deny queue create request with name=q2, qpid.max_size=500 and qpid.max_count=200");
except qpid.session.SessionException, e:
- self.assertEqual(403,e.args[0].error_code)
+ self.assertEqual(403,e.args[0].error_code)
session = self.get_session('bob','bob')
try:
queue_options = {}
queue_options["qpid.max_count"] = 200
- queue_options["qpid.max_size"] = 100
+ queue_options["qpid.max_size"] = 100
session.queue_declare(queue="q2", exclusive=True, arguments=queue_options)
except qpid.session.SessionException, e:
if (403 == e.args[0].error_code):
@@ -394,33 +530,33 @@ class ACLTests(TestBase010):
except qpid.session.SessionException, e:
self.assertEqual(403,e.args[0].error_code)
session = self.get_session('bob','bob')
-
+
try:
session.queue_purge(queue="q3")
self.fail("ACL should deny queue purge request for q3");
except qpid.session.SessionException, e:
self.assertEqual(403,e.args[0].error_code)
session = self.get_session('bob','bob')
-
+
try:
session.queue_purge(queue="q4")
except qpid.session.SessionException, e:
if (403 == e.args[0].error_code):
self.fail("ACL should allow queue purge request for q4");
-
+
try:
session.queue_delete(queue="q4")
self.fail("ACL should deny queue delete request for q4");
except qpid.session.SessionException, e:
self.assertEqual(403,e.args[0].error_code)
session = self.get_session('bob','bob')
-
+
try:
session.queue_delete(queue="q3")
except qpid.session.SessionException, e:
if (403 == e.args[0].error_code):
self.fail("ACL should allow queue delete request for q3");
-
+
def test_queue_deny_mode(self):
"""
@@ -431,26 +567,27 @@ class ACLTests(TestBase010):
aclf.write('acl allow bob@QPID create queue name=q2 exclusive=true policytype=ring\n')
aclf.write('acl allow bob@QPID access queue name=q3\n')
aclf.write('acl allow bob@QPID purge queue name=q3\n')
- aclf.write('acl allow bob@QPID create queue name=q3\n')
- aclf.write('acl allow bob@QPID create queue name=q4\n')
- aclf.write('acl allow bob@QPID delete queue name=q4\n')
- aclf.write('acl allow bob@QPID create queue name=q5 maxqueuesize=1000 maxqueuecount=100\n')
+ aclf.write('acl allow bob@QPID create queue name=q3\n')
+ aclf.write('acl allow bob@QPID create queue name=q4\n')
+ aclf.write('acl allow bob@QPID delete queue name=q4\n')
+ aclf.write('acl allow bob@QPID create queue name=q5 maxqueuesize=1000 maxqueuecount=100\n')
+ aclf.write('acl allow bob@QPID create queue name=q6 queuemaxsizelowerlimit=50 queuemaxsizeupperlimit=100 queuemaxcountlowerlimit=50 queuemaxcountupperlimit=100\n')
aclf.write('acl allow anonymous all all\n')
aclf.write('acl deny all all')
- aclf.close()
-
+ aclf.close()
+
result = self.reload_acl()
if (result):
- self.fail(result)
-
+ self.fail(result)
+
session = self.get_session('bob','bob')
-
+
try:
session.queue_declare(queue="q1", durable=True, passive=True)
except qpid.session.SessionException, e:
if (403 == e.args[0].error_code):
self.fail("ACL should allow queue create request with name=q1 durable=true passive=true");
-
+
try:
session.queue_declare(queue="q1", durable=False, passive=False)
self.fail("ACL should deny queue create request with name=q1 durable=true passive=false");
@@ -462,32 +599,81 @@ class ACLTests(TestBase010):
session.queue_declare(queue="q2", exclusive=False)
self.fail("ACL should deny queue create request with name=q2 exclusive=false");
except qpid.session.SessionException, e:
- self.assertEqual(403,e.args[0].error_code)
+ self.assertEqual(403,e.args[0].error_code)
session = self.get_session('bob','bob')
-
+
try:
queue_options = {}
queue_options["qpid.max_count"] = 200
- queue_options["qpid.max_size"] = 500
+ queue_options["qpid.max_size"] = 500
session.queue_declare(queue="q5", arguments=queue_options)
- self.fail("ACL should deny queue create request with name=q2 maxqueuesize=500 maxqueuecount=200");
+ self.fail("ACL should deny queue create request with name=q5 maxqueuesize=500 maxqueuecount=200");
except qpid.session.SessionException, e:
- self.assertEqual(403,e.args[0].error_code)
+ self.assertEqual(403,e.args[0].error_code)
session = self.get_session('bob','bob')
try:
queue_options = {}
queue_options["qpid.max_count"] = 100
- queue_options["qpid.max_size"] = 500
- session.queue_declare(queue="q5", arguments=queue_options)
+ queue_options["qpid.max_size"] = 500
+ session.queue_declare(queue="q5", arguments=queue_options)
+ except qpid.session.SessionException, e:
+ if (403 == e.args[0].error_code):
+ self.fail("ACL should allow queue create request with name=q5 maxqueuesize=500 maxqueuecount=200");
+
+ try:
+ queue_options = {}
+ queue_options["qpid.max_count"] = 49
+ queue_options["qpid.max_size"] = 100
+ session.queue_declare(queue="q6", arguments=queue_options)
+ self.fail("ACL should deny queue create request with name=q6 maxqueuesize=100 maxqueuecount=49");
+ except qpid.session.SessionException, e:
+ self.assertEqual(403,e.args[0].error_code)
+ session = self.get_session('bob','bob')
+
+ try:
+ queue_options = {}
+ queue_options["qpid.max_count"] = 101
+ queue_options["qpid.max_size"] = 100
+ session.queue_declare(queue="q6", arguments=queue_options)
+ self.fail("ACL should allow queue create request with name=q6 maxqueuesize=100 maxqueuecount=101");
+ except qpid.session.SessionException, e:
+ self.assertEqual(403,e.args[0].error_code)
+ session = self.get_session('bob','bob')
+
+ try:
+ queue_options = {}
+ queue_options["qpid.max_count"] = 100
+ queue_options["qpid.max_size"] = 49
+ session.queue_declare(queue="q6", arguments=queue_options)
+ self.fail("ACL should deny queue create request with name=q6 maxqueuesize=49 maxqueuecount=100");
+ except qpid.session.SessionException, e:
+ self.assertEqual(403,e.args[0].error_code)
+ session = self.get_session('bob','bob')
+
+ try:
+ queue_options = {}
+ queue_options["qpid.max_count"] = 100
+ queue_options["qpid.max_size"] =101
+ session.queue_declare(queue="q6", arguments=queue_options)
+ self.fail("ACL should deny queue create request with name=q6 maxqueuesize=101 maxqueuecount=100");
+ except qpid.session.SessionException, e:
+ self.assertEqual(403,e.args[0].error_code)
+ session = self.get_session('bob','bob')
+
+ try:
+ queue_options = {}
+ queue_options["qpid.max_count"] = 50
+ queue_options["qpid.max_size"] = 50
+ session.queue_declare(queue="q6", arguments=queue_options)
except qpid.session.SessionException, e:
if (403 == e.args[0].error_code):
- self.fail("ACL should allow queue create request with name=q2 maxqueuesize=500 maxqueuecount=200");
+ self.fail("ACL should allow queue create request with name=q6 maxqueuesize=50 maxqueuecount=50");
try:
queue_options = {}
queue_options["qpid.policy_type"] = "ring"
- session.queue_declare(queue="q2", exclusive=True, arguments=queue_options)
+ session.queue_declare(queue="q2", exclusive=True, arguments=queue_options)
except qpid.session.SessionException, e:
if (403 == e.args[0].error_code):
self.fail("ACL should allow queue create request for q2 with exclusive=true policytype=ring");
@@ -505,14 +691,14 @@ class ACLTests(TestBase010):
except qpid.session.SessionException, e:
self.assertEqual(403,e.args[0].error_code)
session = self.get_session('bob','bob')
-
+
try:
session.queue_purge(queue="q4")
self.fail("ACL should deny queue purge request for q4");
except qpid.session.SessionException, e:
self.assertEqual(403,e.args[0].error_code)
session = self.get_session('bob','bob')
-
+
try:
session.queue_purge(queue="q3")
except qpid.session.SessionException, e:
@@ -524,14 +710,14 @@ class ACLTests(TestBase010):
except qpid.session.SessionException, e:
if (403 == e.args[0].error_code):
self.fail("ACL should allow queue query request for q3");
-
+
try:
session.queue_delete(queue="q3")
self.fail("ACL should deny queue delete request for q3");
except qpid.session.SessionException, e:
self.assertEqual(403,e.args[0].error_code)
session = self.get_session('bob','bob')
-
+
try:
session.queue_delete(queue="q4")
except qpid.session.SessionException, e:
@@ -541,9 +727,9 @@ class ACLTests(TestBase010):
#=====================================
# ACL exchange tests
#=====================================
-
+
def test_exchange_acl_allow_mode(self):
- session = self.get_session('bob','bob')
+ session = self.get_session('bob','bob')
session.queue_declare(queue="baz")
"""
@@ -557,12 +743,12 @@ class ACLTests(TestBase010):
aclf.write('acl deny bob@QPID unbind exchange name=myEx queuename=q1 routingkey=rk1\n')
aclf.write('acl deny bob@QPID delete exchange name=myEx\n')
aclf.write('acl allow all all')
- aclf.close()
-
+ aclf.close()
+
result = self.reload_acl()
if (result):
- self.fail(result)
-
+ self.fail(result)
+
session = self.get_session('bob','bob')
session.queue_declare(queue='q1')
session.queue_declare(queue='q2')
@@ -574,21 +760,21 @@ class ACLTests(TestBase010):
except qpid.session.SessionException, e:
self.assertEqual(403,e.args[0].error_code)
session = self.get_session('bob','bob')
-
+
try:
session.exchange_declare(exchange='testEx', type='direct', durable=True, passive=False)
except qpid.session.SessionException, e:
print e
if (403 == e.args[0].error_code):
self.fail("ACL should allow exchange create request for testEx with any parameter other than durable=true and passive=true");
-
+
try:
session.exchange_declare(exchange='ex1', type='direct')
self.fail("ACL should deny exchange create request with name=ex1 type=direct");
- except qpid.session.SessionException, e:
- self.assertEqual(403,e.args[0].error_code)
+ except qpid.session.SessionException, e:
+ self.assertEqual(403,e.args[0].error_code)
session = self.get_session('bob','bob')
-
+
try:
session.exchange_declare(exchange='myXml', type='direct')
except qpid.session.SessionException, e:
@@ -610,13 +796,13 @@ class ACLTests(TestBase010):
session = self.get_session('bob','bob')
try:
- session.exchange_query(name='amq.topic')
+ session.exchange_query(name='amq.topic')
except qpid.session.SessionException, e:
if (403 == e.args[0].error_code):
self.fail("ACL should allow exchange query request for exchange='amq.topic'");
-
+
try:
- session.exchange_bound(exchange='myEx', queue='q1', binding_key='rk2.*')
+ session.exchange_bound(exchange='myEx', queue='q1', binding_key='rk2.*')
except qpid.session.SessionException, e:
if (403 == e.args[0].error_code):
self.fail("ACL should allow exchange bound request for myEx with queuename=q1 and binding_key='rk2.*'");
@@ -625,12 +811,12 @@ class ACLTests(TestBase010):
session.exchange_bind(exchange='myEx', queue='q1', binding_key='rk1')
self.fail("ACL should deny exchange bind request with exchange='myEx' queuename='q1' bindingkey='rk1'");
except qpid.session.SessionException, e:
- self.assertEqual(403,e.args[0].error_code)
+ self.assertEqual(403,e.args[0].error_code)
session = self.get_session('bob','bob')
try:
session.exchange_bind(exchange='myEx', queue='q1', binding_key='x')
- except qpid.session.SessionException, e:
+ except qpid.session.SessionException, e:
if (403 == e.args[0].error_code):
self.fail("ACL should allow exchange bind request for exchange='myEx', queue='q1', binding_key='x'");
@@ -644,7 +830,7 @@ class ACLTests(TestBase010):
session.exchange_unbind(exchange='myEx', queue='q1', binding_key='rk1')
self.fail("ACL should deny exchange unbind request with exchange='myEx' queuename='q1' bindingkey='rk1'");
except qpid.session.SessionException, e:
- self.assertEqual(403,e.args[0].error_code)
+ self.assertEqual(403,e.args[0].error_code)
session = self.get_session('bob','bob')
try:
@@ -658,20 +844,20 @@ class ACLTests(TestBase010):
except qpid.session.SessionException, e:
if (403 == e.args[0].error_code):
self.fail("ACL should allow exchange unbind request for exchange='myEx', queue='q2', binding_key='rk1'");
-
+
try:
session.exchange_delete(exchange='myEx')
self.fail("ACL should deny exchange delete request for myEx");
except qpid.session.SessionException, e:
self.assertEqual(403,e.args[0].error_code)
session = self.get_session('bob','bob')
-
+
try:
session.exchange_delete(exchange='myXml')
except qpid.session.SessionException, e:
if (403 == e.args[0].error_code):
self.fail("ACL should allow exchange delete request for myXml");
-
+
def test_exchange_acl_deny_mode(self):
session = self.get_session('bob','bob')
@@ -682,18 +868,18 @@ class ACLTests(TestBase010):
"""
aclf = self.get_acl_file()
aclf.write('acl allow bob@QPID create exchange name=myEx durable=true passive=false\n')
- aclf.write('acl allow bob@QPID bind exchange name=amq.topic queuename=bar routingkey=foo.*\n')
+ aclf.write('acl allow bob@QPID bind exchange name=amq.topic queuename=bar routingkey=foo.*\n')
aclf.write('acl allow bob@QPID unbind exchange name=amq.topic queuename=bar routingkey=foo.*\n')
aclf.write('acl allow bob@QPID access exchange name=myEx queuename=q1 routingkey=rk1.*\n')
aclf.write('acl allow bob@QPID delete exchange name=myEx\n')
- aclf.write('acl allow anonymous all all\n')
+ aclf.write('acl allow anonymous all all\n')
aclf.write('acl deny all all')
- aclf.close()
-
+ aclf.close()
+
result = self.reload_acl()
if (result):
- self.fail(result)
-
+ self.fail(result)
+
session = self.get_session('bob','bob')
try:
@@ -701,14 +887,14 @@ class ACLTests(TestBase010):
except qpid.session.SessionException, e:
if (403 == e.args[0].error_code):
self.fail("ACL should allow exchange create request for myEx with durable=true and passive=false");
-
+
try:
session.exchange_declare(exchange='myEx', type='direct', durable=False)
self.fail("ACL should deny exchange create request with name=myEx durable=false");
except qpid.session.SessionException, e:
self.assertEqual(403,e.args[0].error_code)
session = self.get_session('bob','bob')
-
+
try:
session.exchange_bind(exchange='amq.topic', queue='bar', binding_key='foo.bar')
except qpid.session.SessionException, e:
@@ -763,13 +949,13 @@ class ACLTests(TestBase010):
session = self.get_session('bob','bob')
try:
- session.exchange_query(name='myEx')
+ session.exchange_query(name='myEx')
except qpid.session.SessionException, e:
if (403 == e.args[0].error_code):
self.fail("ACL should allow exchange query request for exchange='myEx'");
-
+
try:
- session.exchange_bound(exchange='myEx', queue='q1', binding_key='rk1.*')
+ session.exchange_bound(exchange='myEx', queue='q1', binding_key='rk1.*')
except qpid.session.SessionException, e:
if (403 == e.args[0].error_code):
self.fail("ACL should allow exchange bound request for myEx with queuename=q1 and binding_key='rk1.*'");
@@ -780,7 +966,7 @@ class ACLTests(TestBase010):
except qpid.session.SessionException, e:
self.assertEqual(403,e.args[0].error_code)
session = self.get_session('bob','bob')
-
+
try:
session.exchange_delete(exchange='myEx')
except qpid.session.SessionException, e:
@@ -836,24 +1022,24 @@ class ACLTests(TestBase010):
#=====================================
# ACL consume tests
#=====================================
-
+
def test_consume_allow_mode(self):
"""
Test cases for consume in allow mode
"""
aclf = self.get_acl_file()
aclf.write('acl deny bob@QPID consume queue name=q1\n')
- aclf.write('acl deny bob@QPID consume queue name=q2\n')
+ aclf.write('acl deny bob@QPID consume queue name=q2\n')
aclf.write('acl allow all all')
- aclf.close()
-
+ aclf.close()
+
result = self.reload_acl()
if (result):
- self.fail(result)
-
+ self.fail(result)
+
session = self.get_session('bob','bob')
-
-
+
+
try:
session.queue_declare(queue='q1')
session.queue_declare(queue='q2')
@@ -861,27 +1047,27 @@ class ACLTests(TestBase010):
except qpid.session.SessionException, e:
if (403 == e.args[0].error_code):
self.fail("ACL should allow create queue request");
-
+
try:
session.message_subscribe(queue='q1', destination='myq1')
self.fail("ACL should deny subscription for queue='q1'");
except qpid.session.SessionException, e:
self.assertEqual(403,e.args[0].error_code)
session = self.get_session('bob','bob')
-
+
try:
session.message_subscribe(queue='q2', destination='myq1')
self.fail("ACL should deny subscription for queue='q2'");
except qpid.session.SessionException, e:
self.assertEqual(403,e.args[0].error_code)
session = self.get_session('bob','bob')
-
+
try:
session.message_subscribe(queue='q3', destination='myq1')
except qpid.session.SessionException, e:
if (403 == e.args[0].error_code):
- self.fail("ACL should allow subscription for q3");
-
+ self.fail("ACL should allow subscription for q3");
+
def test_consume_deny_mode(self):
"""
@@ -890,18 +1076,18 @@ class ACLTests(TestBase010):
aclf = self.get_acl_file()
aclf.write('acl allow bob@QPID consume queue name=q1\n')
aclf.write('acl allow bob@QPID consume queue name=q2\n')
- aclf.write('acl allow bob@QPID create queue\n')
- aclf.write('acl allow anonymous all\n')
+ aclf.write('acl allow bob@QPID create queue\n')
+ aclf.write('acl allow anonymous all\n')
aclf.write('acl deny all all')
- aclf.close()
-
+ aclf.close()
+
result = self.reload_acl()
if (result):
- self.fail(result)
-
+ self.fail(result)
+
session = self.get_session('bob','bob')
-
-
+
+
try:
session.queue_declare(queue='q1')
session.queue_declare(queue='q2')
@@ -915,20 +1101,20 @@ class ACLTests(TestBase010):
session.message_subscribe(queue='q2', destination='myq2')
except qpid.session.SessionException, e:
if (403 == e.args[0].error_code):
- self.fail("ACL should allow subscription for q1 and q2");
-
+ self.fail("ACL should allow subscription for q1 and q2");
+
try:
session.message_subscribe(queue='q3', destination='myq3')
self.fail("ACL should deny subscription for queue='q3'");
except qpid.session.SessionException, e:
self.assertEqual(403,e.args[0].error_code)
session = self.get_session('bob','bob')
-
+
#=====================================
# ACL publish tests
#=====================================
-
+
def test_publish_acl_allow_mode(self):
"""
Test various publish acl
@@ -936,40 +1122,40 @@ class ACLTests(TestBase010):
aclf = self.get_acl_file()
aclf.write('acl deny bob@QPID publish exchange name=amq.direct routingkey=rk1\n')
aclf.write('acl deny bob@QPID publish exchange name=amq.topic\n')
- aclf.write('acl deny bob@QPID publish exchange name=myEx routingkey=rk2\n')
+ aclf.write('acl deny bob@QPID publish exchange name=myEx routingkey=rk2\n')
aclf.write('acl allow all all')
- aclf.close()
-
+ aclf.close()
+
result = self.reload_acl()
if (result):
- self.fail(result)
-
+ self.fail(result)
+
session = self.get_session('bob','bob')
-
+
props = session.delivery_properties(routing_key="rk1")
-
- try:
+
+ try:
session.message_transfer(destination="amq.direct", message=Message(props,"Test"))
self.fail("ACL should deny message transfer to name=amq.direct routingkey=rk1");
except qpid.session.SessionException, e:
self.assertEqual(403,e.args[0].error_code)
- session = self.get_session('bob','bob')
-
+ session = self.get_session('bob','bob')
+
try:
session.message_transfer(destination="amq.topic", message=Message(props,"Test"))
self.fail("ACL should deny message transfer to name=amq.topic");
except qpid.session.SessionException, e:
self.assertEqual(403,e.args[0].error_code)
session = self.get_session('bob','bob')
-
+
try:
session.exchange_declare(exchange='myEx', type='direct', durable=False)
session.message_transfer(destination="myEx", message=Message(props,"Test"))
except qpid.session.SessionException, e:
if (403 == e.args[0].error_code):
- self.fail("ACL should allow message transfer to exchange myEx with routing key rk1");
-
-
+ self.fail("ACL should allow message transfer to exchange myEx with routing key rk1");
+
+
props = session.delivery_properties(routing_key="rk2")
try:
session.message_transfer(destination="amq.direct", message=Message(props,"Test"))
@@ -986,39 +1172,39 @@ class ACLTests(TestBase010):
aclf.write('acl allow bob@QPID publish exchange name=amq.direct routingkey=rk1\n')
aclf.write('acl allow bob@QPID publish exchange name=amq.topic\n')
aclf.write('acl allow bob@QPID publish exchange name=myEx routingkey=rk2\n')
- aclf.write('acl allow bob@QPID create exchange\n')
- aclf.write('acl allow anonymous all all \n')
+ aclf.write('acl allow bob@QPID create exchange\n')
+ aclf.write('acl allow anonymous all all \n')
aclf.write('acl deny all all')
- aclf.close()
-
+ aclf.close()
+
result = self.reload_acl()
if (result):
- self.fail(result)
-
+ self.fail(result)
+
session = self.get_session('bob','bob')
-
+
props = session.delivery_properties(routing_key="rk2")
-
- try:
+
+ try:
session.message_transfer(destination="amq.direct", message=Message(props,"Test"))
self.fail("ACL should deny message transfer to name=amq.direct routingkey=rk2");
except qpid.session.SessionException, e:
self.assertEqual(403,e.args[0].error_code)
- session = self.get_session('bob','bob')
-
+ session = self.get_session('bob','bob')
+
try:
session.message_transfer(destination="amq.topic", message=Message(props,"Test"))
except qpid.session.SessionException, e:
if (403 == e.args[0].error_code):
- self.fail("ACL should allow message transfer to exchange amq.topic with any routing key");
-
+ self.fail("ACL should allow message transfer to exchange amq.topic with any routing key");
+
try:
session.exchange_declare(exchange='myEx', type='direct', durable=False)
session.message_transfer(destination="myEx", message=Message(props,"Test"))
except qpid.session.SessionException, e:
if (403 == e.args[0].error_code):
- self.fail("ACL should allow message transfer to exchange myEx with routing key=rk2");
-
+ self.fail("ACL should allow message transfer to exchange myEx with routing key=rk2");
+
props = session.delivery_properties(routing_key="rk1")
try:
@@ -1026,7 +1212,7 @@ class ACLTests(TestBase010):
self.fail("ACL should deny message transfer to name=myEx routingkey=rk1");
except qpid.session.SessionException, e:
self.assertEqual(403,e.args[0].error_code)
- session = self.get_session('bob','bob')
+ session = self.get_session('bob','bob')
try:
session.message_transfer(destination="amq.direct", message=Message(props,"Test"))