diff options
Diffstat (limited to 'M4-RCs/qpid/cpp/src/qpid/acl/AclReader.cpp')
-rw-r--r-- | M4-RCs/qpid/cpp/src/qpid/acl/AclReader.cpp | 511 |
1 files changed, 0 insertions, 511 deletions
diff --git a/M4-RCs/qpid/cpp/src/qpid/acl/AclReader.cpp b/M4-RCs/qpid/cpp/src/qpid/acl/AclReader.cpp deleted file mode 100644 index c407339390..0000000000 --- a/M4-RCs/qpid/cpp/src/qpid/acl/AclReader.cpp +++ /dev/null @@ -1,511 +0,0 @@ -/* - * - * Copyright (c) 2006 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include "qpid/acl/AclReader.h" - -#include <cctype> -#include <cstring> -#include <fstream> -#include <sstream> -#include "qpid/log/Statement.h" -#include "qpid/Exception.h" - -#include <iomanip> // degug -#include <iostream> // debug - -#define ACL_FORMAT_ERR_LOG_PREFIX "ACL format error: " << fileName << ":" << lineNumber << ": " - -namespace qpid { -namespace acl { - -AclReader::aclRule::aclRule(const AclResult r, const std::string n, const groupMap& groups) : res(r), actionAll(true), objStatus(NONE) { - processName(n, groups); -} -AclReader::aclRule::aclRule(const AclResult r, const std::string n, const groupMap& groups, const Action a) : res(r), actionAll(false), action(a), objStatus(NONE) { - processName(n, groups); -} - -void AclReader::aclRule::setObjectType(const ObjectType o) { - objStatus = VALUE; - object = o; -} - -void AclReader::aclRule::setObjectTypeAll() { - objStatus = ALL; -} - -bool AclReader::aclRule::addProperty(const Property p, const std::string v) { - return props.insert(propNvPair(p, v)).second; -} - -bool AclReader::aclRule::validate(const AclHelper::objectMapPtr& /*validationMap*/) { - // TODO - invalid rules won't ever be called in real life... - return true; -} - -// Debug aid -std::string AclReader::aclRule::toString() { - std::ostringstream oss; - oss << AclHelper::getAclResultStr(res) << " ["; - for (nsCitr itr = names.begin(); itr != names.end(); itr++) { - if (itr != names.begin()) oss << ", "; - oss << *itr; - } - oss << "]"; - if (actionAll) { - oss << " *"; - } else { - oss << " " << AclHelper::getActionStr(action); - } - if (objStatus == ALL) { - oss << " *"; - } else if (objStatus == VALUE) { - oss << " " << AclHelper::getObjectTypeStr(object); - } - for (pmCitr i=props.begin(); i!=props.end(); i++) { - oss << " " << AclHelper::getPropertyStr(i->first) << "=" << i->second; - } - return oss.str(); -} - -void AclReader::loadDecisionData( boost::shared_ptr<AclData> d ) -{ - d->clear(); - QPID_LOG(debug, "ACL Load Rules"); - int cnt = rules.size(); - bool foundmode = false; - for (rlCitr i=rules.end()-1; cnt; i--,cnt--) { - QPID_LOG(debug, "ACL Processing " << std::setfill(' ') << std::setw(2) << cnt << " " << (*i)->toString()); - - if (!foundmode && (*i)->actionAll && (*i)->names.size()==1 && (*((*i)->names.begin())).compare("*")==0 ){ - d->decisionMode = (*i)->res; - QPID_LOG(debug, "ACL FoundMode " << AclHelper::getAclResultStr(d->decisionMode)); - foundmode=true; - }else{ - AclData::rule rule((*i)->props); - bool addrule= true; - - switch ((*i)->res) - { - case qpid::acl::ALLOWLOG: - rule.log = true; - if (d->decisionMode == qpid::acl::ALLOW || d->decisionMode == qpid::acl::ALLOWLOG) - rule.logOnly = true; - break; - case qpid::acl::ALLOW: - if (d->decisionMode == qpid::acl::ALLOW || d->decisionMode == qpid::acl::ALLOWLOG) - addrule = false; - break; - case qpid::acl::DENYLOG: - rule.log = true; - if (d->decisionMode == qpid::acl::DENY || d->decisionMode == qpid::acl::DENYLOG) - rule.logOnly = true; - break; - case qpid::acl::DENY: - if (d->decisionMode == qpid::acl::DENY || d->decisionMode == qpid::acl::DENYLOG) - addrule = false; - break; - default: - throw Exception("Invalid ACL Result loading rules."); - } - - - // Action -> Object -> map<user -> set<Rule> > - if (addrule){ - 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 - - QPID_LOG(debug, "ACL Adding action:" << 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 ) { - - QPID_LOG(debug, "ACL Adding object:" << AclHelper::getObjectTypeStr((ObjectType)ocnt) ); - - //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()) { - QPID_LOG(debug, "ACL Adding rule & user:" << *itr); - 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); - QPID_LOG(debug, "ACL Adding rule to user:" << *itr); - } - } - - } - - } - }else{ - QPID_LOG(debug, "ACL Skipping based on Mode:" << AclHelper::getAclResultStr(d->decisionMode) ); - } - } - - } - - -} - - - - -void AclReader::aclRule::processName(const std::string& name, const groupMap& groups) { - if (name.compare("all") == 0) { - names.insert("*"); - } else { - gmCitr itr = groups.find(name); - if (itr == groups.end()) { - names.insert(name); - } else { - names.insert(itr->second->begin(), itr->second->end()); - } - } -} - -AclReader::AclReader() : lineNumber(0), contFlag(false), validationMap(new AclHelper::objectMap) { - AclHelper::loadValidationMap(validationMap); - names.insert("*"); -} - -AclReader::~AclReader() {} - -std::string AclReader::getError() { - return errorStream.str(); -} - -int AclReader::read(const std::string& fn, boost::shared_ptr<AclData> d) { - fileName = fn; - lineNumber = 0; - char buff[1024]; - std::ifstream ifs(fn.c_str(), std::ios_base::in); - if (!ifs.good()) { - errorStream << "Unable to open ACL file \"" << fn << "\": eof=" << (ifs.eof()?"T":"F") << "; fail=" << (ifs.fail()?"T":"F") << "; bad=" << (ifs.bad()?"T":"F"); - return -1; - } - try { - bool err = false; - while (ifs.good()) { - ifs.getline(buff, 1024); - lineNumber++; - if (std::strlen(buff) > 0 && buff[0] != '#') // Ignore blank lines and comments - err |= !processLine(buff); - } - if (!ifs.eof()) - { - errorStream << "Unable to read ACL file \"" << fn << "\": eof=" << (ifs.eof()?"T":"F") << "; fail=" << (ifs.fail()?"T":"F") << "; bad=" << (ifs.bad()?"T":"F"); - ifs.close(); - return -2; - } - ifs.close(); - if (err) return -3; - QPID_LOG(notice, "Read ACL file \"" << fn << "\""); - } catch (const std::exception& e) { - errorStream << "Unable to read ACL file \"" << fn << "\": " << e.what(); - ifs.close(); - return -4; - } catch (...) { - errorStream << "Unable to read ACL file \"" << fn << "\": Unknown exception"; - ifs.close(); - return -5; - } - printNames(); - printRules(); - loadDecisionData(d); - - return 0; -} - -bool AclReader::processLine(char* line) { - bool ret = false; - std::vector<std::string> toks; - - // Check for continuation - char* contCharPtr = std::strrchr(line, '\\'); - bool cont = contCharPtr != 0; - if (cont) *contCharPtr = 0; - - int numToks = tokenize(line, toks); - if (numToks && (toks[0].compare("group") == 0 || contFlag)) { - ret = processGroupLine(toks, cont); - } else if (numToks && toks[0].compare("acl") == 0) { - ret = processAclLine(toks); - } else { - // Check for whitespace only line, ignore these - bool ws = true; - for (unsigned i=0; i<std::strlen(line) && ws; i++) { - if (!std::isspace(line[i])) ws = false; - } - if (ws) { - ret = true; - } else { - errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Non-continuation line must start with \"group\" or \"acl\"."; - ret = false; - } - } - contFlag = cont; - return ret; -} - -int AclReader::tokenize(char* line, std::vector<std::string>& toks) { - const char* tokChars = " \t\n\f\v\r"; - int cnt = 0; - char* cp = std::strtok(line, tokChars); - while (cp != 0) { - toks.push_back(std::string(cp)); - cnt++; - cp = std::strtok(0, tokChars); - } - return cnt; -} - -// Return true if the line is successfully processed without errors -// If cont is true, then groupName must be set to the continuation group name -bool AclReader::processGroupLine(tokList& toks, const bool cont) { - const unsigned toksSize = toks.size(); - if (contFlag) { - gmCitr citr = groups.find(groupName); - for (unsigned i = 0; i < toksSize; i++) { - if (!checkName(toks[i])) { - errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Name \"" << toks[i] << "\" contains illegal characters."; - return false; - } - addName(toks[i], citr->second); - } - } else { - if (toksSize < (cont ? 2 : 3)) { - errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Insufficient tokens for group definition."; - return false; - } - if (!checkName(toks[1])) { - errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Group name \"" << toks[1] << "\" contains illegal characters."; - return false; - } - gmCitr citr = addGroup(toks[1]); - if (citr == groups.end()) return false; - for (unsigned i = 2; i < toksSize; i++) { - if (!checkName(toks[i])) { - errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Name \"" << toks[i] << "\" contains illegal characters."; - return false; - } - addName(toks[i], citr->second); - } - } - return true; -} - -// Return true if sucessfully added group -AclReader::gmCitr AclReader::addGroup(const std::string& newGroupName) { - gmCitr citr = groups.find(newGroupName); - if (citr != groups.end()) { - errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Duplicate group name \"" << newGroupName << "\"."; - return groups.end(); - } - groupPair p(newGroupName, nameSetPtr(new nameSet)); - gmRes res = groups.insert(p); - assert(res.second); - groupName = newGroupName; - return res.first; -} - -void AclReader::addName(const std::string& name, nameSetPtr groupNameSet) { - gmCitr citr = groups.find(name); - if (citr != groups.end() && citr->first != name){ - // This is a previously defined group: add all the names in that group to this group - groupNameSet->insert(citr->second->begin(), citr->second->end()); - } else { - // Not a known group name - groupNameSet->insert(name); - addName(name); - } -} - -void AclReader::addName(const std::string& name) { - names.insert(name); -} - -// Debug aid -void AclReader::printNames() const { - QPID_LOG(debug, "Group list: " << groups.size() << " groups found:" ); - std::string tmp; - for (gmCitr i=groups.begin(); i!= groups.end(); i++) { - tmp += " \""; - tmp += i->first; - tmp += "\":"; - for (nsCitr j=i->second->begin(); j!=i->second->end(); j++) { - tmp += " "; - tmp += *j; - } - QPID_LOG(debug, tmp); - tmp.clear(); - } - QPID_LOG(debug, "Name list: " << names.size() << " names found:" ); - tmp.clear(); - for (nsCitr k=names.begin(); k!=names.end(); k++) { - tmp += " "; - tmp += *k; - } - QPID_LOG(debug, tmp); -} - -bool AclReader::processAclLine(tokList& toks) { - const unsigned toksSize = toks.size(); - if (toksSize < 4) { - errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Insufficient tokens for acl definition."; - return false; - } - - AclResult res; - try { - res = AclHelper::getAclResult(toks[1]); - } catch (...) { - errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Unknown ACL permission \"" << toks[1] << "\"."; - return false; - } - - bool actionAllFlag = toks[3].compare("all") == 0; - bool userAllFlag = toks[2].compare("all") == 0; - Action action; - if (actionAllFlag) { - - if (userAllFlag && toksSize > 4) { - errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Tokens found after action \"all\"."; - return false; - } - action = ACT_CONSUME; // dummy; compiler must initialize action for this code path - } else { - try { - action = AclHelper::getAction(toks[3]); - } catch (...) { - errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Unknown action \"" << toks[3] << "\"."; - return false; - } - } - - // Create rule obj; then add object (if any) and properties (if any) - aclRulePtr rule; - if (actionAllFlag) { - rule.reset(new aclRule(res, toks[2], groups)); - } else { - rule.reset(new aclRule(res, toks[2], groups, action)); - } - - if (toksSize >= 5) { // object name-value pair - if (toks[4].compare("all") == 0) { - rule->setObjectTypeAll(); - } else { - try { - rule->setObjectType(AclHelper::getObjectType(toks[4])); - } catch (...) { - errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Unknown object \"" << toks[4] << "\"."; - return false; - } - } - } - - if (toksSize >= 6) { // property name-value pair(s) - for (unsigned i=5; i<toksSize; i++) { - nvPair propNvp = splitNameValuePair(toks[i]); - if (propNvp.second.size() == 0) { - errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Badly formed property name-value pair \"" << propNvp.first << "\". (Must be name=value)"; - return false; - } - Property prop; - try { - prop = AclHelper::getProperty(propNvp.first); - } catch (...) { - errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Unknown property \"" << propNvp.first << "\"."; - return false; - } - rule->addProperty(prop, propNvp.second); - } - } - // Check if name (toks[2]) is group; if not, add as name of individual - if (toks[2].compare("all") != 0) { - if (groups.find(toks[2]) == groups.end()) { - addName(toks[2]); - } - } - - // If rule validates, add to rule list - if (!rule->validate(validationMap)) { - errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Invalid object/action/property combination."; - return false; - } - rules.push_back(rule); - - return true; -} - -// Debug aid -void AclReader::printRules() const { - QPID_LOG(debug, "Rule list: " << rules.size() << " ACL rules found:"); - int cnt = 0; - for (rlCitr i=rules.begin(); i<rules.end(); i++,cnt++) { - QPID_LOG(debug, " " << std::setfill(' ') << std::setw(2) << cnt << " " << (*i)->toString()); - } -} - -// Static function -// Return true if the name is well-formed (ie contains legal characters) -bool AclReader::checkName(const std::string& name) { - for (unsigned i=0; i<name.size(); i++) { - const char ch = name.at(i); - if (!std::isalnum(ch) && ch != '-' && ch != '_' && ch != '@') return false; - } - return true; -} - -// Static function -// Split name-value pair around '=' char of the form "name=value" -AclReader::nvPair AclReader::splitNameValuePair(const std::string& nvpString) { - std::size_t pos = nvpString.find("="); - if (pos == std::string::npos || pos == nvpString.size() - 1) { - return nvPair(nvpString, ""); - } - return nvPair(nvpString.substr(0, pos), nvpString.substr(pos+1)); -} - -}} // namespace qpid::acl |