Author: rajith
Date: Wed May 12 01:48:38 2010
New Revision: 943351

URL: http://svn.apache.org/viewvc?rev=943351&view=rev
Log:
This commit contains a fix for QPID-2600
Added a test case to check if all allowed chars are accepted and the rest is 
rejected.
Added a check for empty continuation lines.
Improved error reporting by adding a line number.
Removed test_allowed_chars_for_username method from acl.py as the check for 
group name will flag the "@" char, making this test case redundent.

Modified:
    qpid/trunk/qpid/cpp/src/qpid/acl/AclReader.cpp
    qpid/trunk/qpid/cpp/src/qpid/acl/AclReader.h
    qpid/trunk/qpid/cpp/src/tests/acl.py

Modified: qpid/trunk/qpid/cpp/src/qpid/acl/AclReader.cpp
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/acl/AclReader.cpp?rev=943351&r1=943350&r2=943351&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/acl/AclReader.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/acl/AclReader.cpp Wed May 12 01:48:38 2010
@@ -297,13 +297,19 @@ int AclReader::read(const std::string& f
 bool AclReader::processLine(char* line) {
     bool ret = false;
     std::vector<std::string> toks;
-
+  
     // Check for continuation
     char* contCharPtr = std::strrchr(line, '\\');
     bool cont = contCharPtr != 0;
     if (cont) *contCharPtr = 0;
 
     int numToks = tokenize(line, toks);
+    
+    if (cont && numToks == 0){
+      errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line \"" << lineNumber << 
"\" contains an illegal extension.";
+      return false;
+    }
+
     if (numToks && (toks[0].compare("group") == 0 || contFlag)) {
         ret = processGroupLine(toks, cont);
     } else if (numToks && toks[0].compare("acl") == 0) {
@@ -317,7 +323,8 @@ bool AclReader::processLine(char* line) 
         if (ws) {
             ret = true;
         } else {
-            errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Non-continuation line 
must start with \"group\" or \"acl\".";
+            errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << 
lineNumber 
+                   << ", Non-continuation line must start with \"group\" or 
\"acl\".";
             ret = false;
         }
     }
@@ -341,32 +348,27 @@ int  AclReader::tokenize(char* line, std
 // 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;
-            }
             if (!isValidUserName(toks[i])) return false;
             addName(toks[i], citr->second);
         }
     } else {
         if (toksSize < (cont ? 2 : 3)) {
-            errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Insufficient tokens 
for group definition.";
+            errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << 
lineNumber 
+                        << ", Insufficient tokens for group definition.";
             return false;
         }
-        if (!checkName(toks[1])) {
-            errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Group name \"" << 
toks[1] << "\" contains illegal characters.";
+        if (!isValidGroupName(toks[1])) {
+            errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber
+                        << ", Group name \"" << toks[1] << "\" contains 
illegal characters.";
             return false;
         }
         gmCitr citr = addGroup(toks[1]);
         if (citr == groups.end()) return false;
         for (unsigned i = 2; i < toksSize; i++) {
-            if (!checkName(toks[i])) {
-                errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Name \"" << 
toks[i] << "\" contains illegal characters.";
-                return false;
-            }
             if (!isValidUserName(toks[i])) return false;
             addName(toks[i], citr->second);
         }
@@ -378,7 +380,8 @@ bool AclReader::processGroupLine(tokList
 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 << "\".";
+        errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber
+                    << ", Duplicate group name \"" << newGroupName << "\".";
         return groups.end();
     }
     groupPair p(newGroupName, nameSetPtr(new nameSet));
@@ -431,7 +434,8 @@ void AclReader::printNames() const {
 bool AclReader::processAclLine(tokList& toks) {
     const unsigned toksSize = toks.size();
     if (toksSize < 4) {
-        errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Insufficient tokens for 
acl definition.";
+        errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber
+                    << ", Insufficient tokens for acl definition.";
         return false;
     }
 
@@ -439,7 +443,8 @@ bool AclReader::processAclLine(tokList& 
     try {
         res = AclHelper::getAclResult(toks[1]);
     } catch (...) {
-        errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Unknown ACL permission 
\"" << toks[1] << "\".";
+        errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber
+                    << ", Unknown ACL permission \"" << toks[1] << "\".";
         return false;
     }
 
@@ -449,7 +454,8 @@ bool AclReader::processAclLine(tokList& 
     if (actionAllFlag) {
 
         if (userAllFlag && toksSize > 4) {
-            errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Tokens found after 
action \"all\".";
+            errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber
+                        << ", Tokens found after action \"all\".";
             return false;
         }
         action = ACT_CONSUME; // dummy; compiler must initialize action for 
this code path
@@ -457,7 +463,8 @@ bool AclReader::processAclLine(tokList& 
         try {
             action = AclHelper::getAction(toks[3]);
         } catch (...) {
-            errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Unknown action \"" << 
toks[3] << "\".";
+            errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber
+                        << ", Unknown action \"" << toks[3] << "\".";
             return false;
         }
     }
@@ -477,7 +484,8 @@ bool AclReader::processAclLine(tokList& 
             try {
                 rule->setObjectType(AclHelper::getObjectType(toks[4]));
             } catch (...) {
-                errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Unknown object 
\"" << toks[4] << "\".";
+                errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << 
lineNumber
+                            << ", Unknown object \"" << toks[4] << "\".";
                 return false;
             }
         }
@@ -487,14 +495,17 @@ bool AclReader::processAclLine(tokList& 
         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)";
+                errorStream << ACL_FORMAT_ERR_LOG_PREFIX <<  "Line : " << 
lineNumber
+                            <<", Badly formed property name-value pair \"" 
+                            << propNvp.first << "\". (Must be name=value)";
                 return false;
             }
             Property prop;
             try {
                 prop = AclHelper::getProperty(propNvp.first);
             } catch (...) {
-                errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Unknown property 
\"" << propNvp.first << "\".";
+                errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << 
lineNumber
+                            << ", Unknown property \"" << propNvp.first << 
"\".";
                 return false;
             }
             rule->addProperty(prop, propNvp.second);
@@ -509,7 +520,8 @@ bool AclReader::processAclLine(tokList& 
 
     // If rule validates, add to rule list
     if (!rule->validate(validationMap)) {
-        errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Invalid 
object/action/property combination.";
+        errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber
+                    << ", Invalid object/action/property combination.";
         return false;
     }
     rules.push_back(rule);
@@ -528,10 +540,10 @@ void AclReader::printRules() const {
 
 // Static function
 // Return true if the name is well-formed (ie contains legal characters)
-bool AclReader::checkName(const std::string& name) {
+bool AclReader::isValidGroupName(const std::string& name) {
     for (unsigned i=0; i<name.size(); i++) {
         const char ch = name.at(i);
-        if (!std::isalnum(ch) && ch != '-' && ch != '_' && ch != '@' && ch != 
'.') return false;
+        if (!std::isalnum(ch) && ch != '-' && ch != '_') return false;
     }
     return true;
 }
@@ -548,11 +560,20 @@ AclReader::nvPair AclReader::splitNameVa
 
 // Returns true if a username has the n...@realm format
 bool AclReader::isValidUserName(const std::string& name){
-       size_t pos = name.find('@');
+    size_t pos = name.find('@');
        if ( pos == std::string::npos || pos == name.length() -1){
-               errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Username '" << 
name << "' must contain a realm";
+               errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << 
lineNumber
+                    << ", Username '" << name << "' must contain a realm";
                return false;
        }
+    for (unsigned i=0; i<name.size(); i++) {
+        const char ch = name.at(i);
+        if (!std::isalnum(ch) && ch != '-' && ch != '_' && ch != '@' && ch != 
'.' && ch != '/'){
+            errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber
+                        << ", Username \"" << name << "\" contains illegal 
characters.";
+            return false;
+        }
+    }
        return true;
 }
 

Modified: qpid/trunk/qpid/cpp/src/qpid/acl/AclReader.h
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/acl/AclReader.h?rev=943351&r1=943350&r2=943351&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/acl/AclReader.h (original)
+++ qpid/trunk/qpid/cpp/src/qpid/acl/AclReader.h Wed May 12 01:48:38 2010
@@ -109,7 +109,7 @@ class AclReader {
     void printRules() const; // debug aid
     bool isValidUserName(const std::string& name);
 
-    static bool checkName(const std::string& name);
+    static bool isValidGroupName(const std::string& name);
     static nvPair splitNameValuePair(const std::string& nvpString);
 };
 

Modified: qpid/trunk/qpid/cpp/src/tests/acl.py
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/tests/acl.py?rev=943351&r1=943350&r2=943351&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/tests/acl.py (original)
+++ qpid/trunk/qpid/cpp/src/tests/acl.py Wed May 12 01:48:38 2010
@@ -117,36 +117,6 @@ class ACLTests(TestBase010):
         except qpid.session.SessionException, e:
             self.assertEqual(403,e.args[0].error_code)                
         
-
-    def test_group_and_user_with_same_name(self):
-        """
-        Test a group and user with same name
-        Ex. group admin admin 
-        """
-        aclf = ACLFile()
-        aclf.write('group b...@qpid b...@qpid\n')
-        aclf.write('acl deny b...@qpid bind exchange\n')
-        aclf.write('acl allow all all')
-        aclf.close()
-
-        result = self.reload_acl()
-        if (result.text.find("format error",0,len(result.text)) != -1):
-            self.fail(result) 
-
-        session = self.get_session('bob','bob')
-        try:
-            session.queue_declare(queue="allow_queue")
-        except qpid.session.SessionException, e:
-            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)
-       
  
    #=====================================
    # ACL file format tests
@@ -185,23 +155,26 @@ class ACLTests(TestBase010):
         """
          
         aclf = ACLFile()
-        aclf.write('group admins b...@qpid \ ')
+        aclf.write('group admins b...@qpid \n')
         aclf.write('          \ \n')
         aclf.write('j...@qpid \n')
         aclf.write('acl allow all all')
         aclf.close()        
         
         result = self.reload_acl()       
-        if (result.text.find("contains illegal characters",0,len(result.text)) 
== -1):
+        if (result.text.find("contains an illegal 
extension",0,len(result.text)) == -1):
+            self.fail(result)
+
+        if (result.text.find("Non-continuation line must start with \"group\" 
or \"acl\"",0,len(result.text)) == -1):
             self.fail(result)
 
+
     def test_user_domain(self):
         """
         Test a user defined without a realm
         Ex. group admin rajith
         """
-        aclf = ACLFile()
-        aclf.write('group test j...@example.com\n') # should be allowed
+        aclf = ACLFile()        
         aclf.write('group admin bob\n') # shouldn't be allowed
         aclf.write('acl deny admin bind exchange\n')
         aclf.write('acl allow all all')
@@ -211,6 +184,23 @@ class ACLTests(TestBase010):
         if (result.text.find("Username 'bob' must contain a 
realm",0,len(result.text)) == -1):
             self.fail(result)
 
+    def test_allowed_chars_for_username(self):
+        """
+        Test a user defined without a realm
+        Ex. group admin rajith
+        """
+        aclf = ACLFile()        
+        aclf.write('group test1 j...@example.com\n') # should be allowed
+        aclf.write('group test2 jack-j...@example.com\n') # should be allowed
+        aclf.write('group test3 jack_j...@example.com\n') # should be allowed
+        aclf.write('group test4 host/somemachine.example....@example.com\n') # 
should be allowed
+        aclf.write('acl allow all all')
+        aclf.close()
+         
+        result = self.reload_acl()
+        if (result.text.find("ACL format error",0,len(result.text)) != -1):
+            self.fail(result)
+
    #=====================================
    # ACL validation tests
    #=====================================



---------------------------------------------------------------------
Apache Qpid - AMQP Messaging Implementation
Project:      http://qpid.apache.org
Use/Interact: mailto:commits-subscr...@qpid.apache.org

Reply via email to