You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by tr...@apache.org on 2010/11/09 22:15:06 UTC

svn commit: r1033232 - in /qpid/trunk/qpid/cpp: examples/qmf-agent/ include/qpid/management/ managementgen/qmfgen/ managementgen/qmfgen/templates/ src/qpid/agent/ src/qpid/management/

Author: tross
Date: Tue Nov  9 21:15:03 2010
New Revision: 1033232

URL: http://svn.apache.org/viewvc?rev=1033232&view=rev
Log:
QPID-2934 Feature to pass the authenticated userId to QMF agent method handlers for authorization

Modified:
    qpid/trunk/qpid/cpp/examples/qmf-agent/example.cpp
    qpid/trunk/qpid/cpp/examples/qmf-agent/schema.xml
    qpid/trunk/qpid/cpp/include/qpid/management/Manageable.h
    qpid/trunk/qpid/cpp/include/qpid/management/ManagementObject.h
    qpid/trunk/qpid/cpp/managementgen/qmfgen/schema.py
    qpid/trunk/qpid/cpp/managementgen/qmfgen/templates/Class.h
    qpid/trunk/qpid/cpp/src/qpid/agent/ManagementAgentImpl.cpp
    qpid/trunk/qpid/cpp/src/qpid/agent/ManagementAgentImpl.h
    qpid/trunk/qpid/cpp/src/qpid/management/Manageable.cpp
    qpid/trunk/qpid/cpp/src/qpid/management/ManagementAgent.cpp

Modified: qpid/trunk/qpid/cpp/examples/qmf-agent/example.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/examples/qmf-agent/example.cpp?rev=1033232&r1=1033231&r2=1033232&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/examples/qmf-agent/example.cpp (original)
+++ qpid/trunk/qpid/cpp/examples/qmf-agent/example.cpp Tue Nov  9 21:15:03 2010
@@ -24,6 +24,7 @@
 #include <qpid/agent/ManagementAgent.h>
 #include <qpid/sys/Mutex.h>
 #include <qpid/sys/Time.h>
+#include <qpid/log/Statement.h>
 #include "qpid/types/Variant.h"
 #include "qmf/org/apache/qpid/agent/example/Parent.h"
 #include "qmf/org/apache/qpid/agent/example/Child.h"
@@ -72,7 +73,8 @@ public:
     { return mgmtObject; }
 
     void doLoop();
-    status_t ManagementMethod (uint32_t methodId, Args& args, string& text);
+    bool AuthorizeMethod(uint32_t methodId, Args& args, const string& userId);
+    status_t ManagementMethod(uint32_t methodId, Args& args, string& text);
 };
 
 class ChildClass : public Manageable
@@ -137,6 +139,14 @@ void CoreClass::doLoop()
     }
 }
 
+
+bool CoreClass::AuthorizeMethod(uint32_t methodId, Args& args, const string& userId)
+{
+    QPID_LOG(trace, "AuthorizeMethod for methodId=" << methodId << " userId=" << userId);
+    return methodId != _qmf::Parent::METHOD_AUTH_FAIL;
+}
+
+
 Manageable::status_t CoreClass::ManagementMethod(uint32_t methodId, Args& args, string& /*text*/)
 {
     Mutex::ScopedLock _lock(vectorLock);

Modified: qpid/trunk/qpid/cpp/examples/qmf-agent/schema.xml
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/examples/qmf-agent/schema.xml?rev=1033232&r1=1033231&r2=1033232&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/examples/qmf-agent/schema.xml (original)
+++ qpid/trunk/qpid/cpp/examples/qmf-agent/schema.xml Tue Nov  9 21:15:03 2010
@@ -45,6 +45,9 @@
       <arg name="aList"  dir="IO" type="list"/>
     </method>
 
+    <method name="auth_fail" desc="Method that fails authorization">
+    </method>
+
   </class>
 
 

Modified: qpid/trunk/qpid/cpp/include/qpid/management/Manageable.h
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/include/qpid/management/Manageable.h?rev=1033232&r1=1033231&r2=1033232&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/include/qpid/management/Manageable.h (original)
+++ qpid/trunk/qpid/cpp/include/qpid/management/Manageable.h Tue Nov  9 21:15:03 2010
@@ -63,6 +63,11 @@ class QPID_COMMON_EXTERN Manageable
     //  method being called and must be down-cast to the appropriate sub class
     //  before use.
     virtual status_t ManagementMethod(uint32_t methodId, Args& args, std::string& text);
+
+    //  This optional method can be overridden to allow the agent application to
+    //  authorize method invocations.  Return true iff the authenticated user identified
+    //  in userId us authorized to execute the method.
+    virtual bool AuthorizeMethod(uint32_t methodId, Args& args, const std::string& userId);
 };
 
 inline Manageable::~Manageable(void) {}

Modified: qpid/trunk/qpid/cpp/include/qpid/management/ManagementObject.h
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/include/qpid/management/ManagementObject.h?rev=1033232&r1=1033231&r2=1033232&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/include/qpid/management/ManagementObject.h (original)
+++ qpid/trunk/qpid/cpp/include/qpid/management/ManagementObject.h Tue Nov  9 21:15:03 2010
@@ -175,7 +175,8 @@ protected:
     virtual void mapDecodeValues(const types::Variant::Map& map) = 0;
     virtual void doMethod(std::string&           methodName,
                           const types::Variant::Map& inMap,
-                          types::Variant::Map& outMap) = 0;
+                          types::Variant::Map& outMap,
+                          const std::string& userId) = 0;
     QPID_COMMON_EXTERN void writeTimestamps(types::Variant::Map& map) const;
     QPID_COMMON_EXTERN void readTimestamps(const types::Variant::Map& buf);
 
@@ -187,7 +188,7 @@ protected:
     virtual void readProperties(const std::string&) {}
     virtual void writeProperties(std::string&) const {}
     virtual void writeStatistics(std::string&, bool = false) {}
-    virtual void doMethod(std::string&, const std::string&, std::string&) {}
+    virtual void doMethod(std::string&, const std::string&, std::string&, const std::string&) {}
 
     QPID_COMMON_EXTERN virtual void setReference(ObjectId objectId);
 

Modified: qpid/trunk/qpid/cpp/managementgen/qmfgen/schema.py
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/managementgen/qmfgen/schema.py?rev=1033232&r1=1033231&r2=1033232&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/managementgen/qmfgen/schema.py (original)
+++ qpid/trunk/qpid/cpp/managementgen/qmfgen/schema.py Tue Nov  9 21:15:03 2010
@@ -1228,12 +1228,12 @@ class SchemaClass:
           inArgCount = inArgCount + 1
 
     if methodCount == 0:
-      stream.write ("string&, const string&, string& outStr")
+      stream.write ("string&, const string&, string& outStr, const string&")
     else:
       if inArgCount == 0:
-        stream.write ("string& methodName, const string&, string& outStr")
+        stream.write ("string& methodName, const string&, string& outStr, const string& userId")
       else:
-        stream.write ("string& methodName, const string& inStr, string& outStr")
+        stream.write ("string& methodName, const string& inStr, string& outStr, const string& userId")
 
 
   def genDoMapMethodArgs (self, stream, variables):
@@ -1248,16 +1248,16 @@ class SchemaClass:
     if methodCount == 0:
       stream.write ("string&," +
                     " const ::qpid::types::Variant::Map&," +
-                    " ::qpid::types::Variant::Map& outMap")
+                    " ::qpid::types::Variant::Map& outMap, const string&")
     else:
       if inArgCount == 0:
         stream.write ("string& methodName," +
                       " const ::qpid::types::Variant::Map&," +
-                      " ::qpid::types::Variant::Map& outMap")
+                      " ::qpid::types::Variant::Map& outMap, const string& userId")
       else:
         stream.write ("string& methodName," +
                       " const ::qpid::types::Variant::Map& inMap," +
-                      " ::qpid::types::Variant::Map& outMap")
+                      " ::qpid::types::Variant::Map& outMap, const string& userId")
 
   def genHiLoStatResets (self, stream, variables):
     for inst in self.statistics:
@@ -1367,8 +1367,13 @@ class SchemaClass:
                                                    arg.dir.lower () + "_" +\
                                                    arg.name, "inBuf") + ";\n")
 
-      stream.write ("        status = coreObject->ManagementMethod (METHOD_" +\
+      stream.write ("        bool allow = coreObject->AuthorizeMethod(METHOD_" +\
+                    method.getName().upper() + ", ioArgs, userId);\n")
+      stream.write ("        if (allow)\n")
+      stream.write ("            status = coreObject->ManagementMethod (METHOD_" +\
                     method.getName().upper() + ", ioArgs, text);\n")
+      stream.write ("        else\n")
+      stream.write ("            status = Manageable::STATUS_FORBIDDEN;\n")
       stream.write ("        outBuf.putLong        (status);\n")
       stream.write ("        outBuf.putMediumString(::qpid::management::Manageable::StatusText (status, text));\n")
       for arg in method.args:
@@ -1402,8 +1407,13 @@ class SchemaClass:
                                  arg.name,
                                  "inMap")
 
-      stream.write ("        status = coreObject->ManagementMethod (METHOD_" +\
+      stream.write ("        bool allow = coreObject->AuthorizeMethod(METHOD_" +\
+                    method.getName().upper() + ", ioArgs, userId);\n")
+      stream.write ("        if (allow)\n")
+      stream.write ("            status = coreObject->ManagementMethod (METHOD_" +\
                     method.getName().upper() + ", ioArgs, text);\n")
+      stream.write ("        else\n")
+      stream.write ("            status = Manageable::STATUS_FORBIDDEN;\n")
       stream.write ("        outMap[\"_status_code\"] = (uint32_t) status;\n")
       stream.write ("        outMap[\"_status_text\"] = ::qpid::management::Manageable::StatusText(status, text);\n")
       for arg in method.args:

Modified: qpid/trunk/qpid/cpp/managementgen/qmfgen/templates/Class.h
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/managementgen/qmfgen/templates/Class.h?rev=1033232&r1=1033231&r2=1033232&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/managementgen/qmfgen/templates/Class.h (original)
+++ qpid/trunk/qpid/cpp/managementgen/qmfgen/templates/Class.h Tue Nov  9 21:15:03 2010
@@ -79,7 +79,8 @@ class /*MGEN:Class.NameCap*/ : public ::
     void mapDecodeValues(const ::qpid::types::Variant::Map& map);
     void doMethod(std::string&           methodName,
                   const ::qpid::types::Variant::Map& inMap,
-                  ::qpid::types::Variant::Map& outMap);
+                  ::qpid::types::Variant::Map& outMap,
+                  const std::string& userId);
     std::string getKey() const;
 /*MGEN:IF(Root.GenQMFv1)*/
     uint32_t writePropertiesSize() const;
@@ -88,7 +89,8 @@ class /*MGEN:Class.NameCap*/ : public ::
     void writeStatistics(std::string& buf, bool skipHeaders = false);
     void doMethod(std::string& methodName,
                   const std::string& inBuf,
-                  std::string& outBuf);
+                  std::string& outBuf,
+                  const std::string& userId);
 /*MGEN:ENDIF*/
 
     writeSchemaCall_t getWriteSchemaCall() { return writeSchema; }

Modified: qpid/trunk/qpid/cpp/src/qpid/agent/ManagementAgentImpl.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/agent/ManagementAgentImpl.cpp?rev=1033232&r1=1033231&r2=1033232&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/agent/ManagementAgentImpl.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/agent/ManagementAgentImpl.cpp Tue Nov  9 21:15:03 2010
@@ -360,7 +360,7 @@ uint32_t ManagementAgentImpl::pollCallba
         methodQueue.pop_front();
         {
             sys::Mutex::ScopedUnlock unlock(agentLock);
-            invokeMethodRequest(item->body, item->cid, item->replyTo);
+            invokeMethodRequest(item->body, item->cid, item->replyTo, item->userId);
             delete item;
         }
     }
@@ -559,7 +559,7 @@ void ManagementAgentImpl::handleConsoleA
     QPID_LOG(trace, "RCVD ConsoleAddedInd");
 }
 
-void ManagementAgentImpl::invokeMethodRequest(const string& body, const string& cid, const string& replyTo)
+void ManagementAgentImpl::invokeMethodRequest(const string& body, const string& cid, const string& replyTo, const string& userId)
 {
     string  methodName;
     bool    failed = false;
@@ -606,7 +606,7 @@ void ManagementAgentImpl::invokeMethodRe
                               Manageable::STATUS_UNKNOWN_OBJECT);
                 failed = true;
             } else {
-                oPtr->doMethod(methodName, inArgs, callMap);
+                oPtr->doMethod(methodName, inArgs, callMap, userId);
 
                 if (callMap["_status_code"].asUint32() == 0) {
                     outMap["_arguments"] = Variant::Map();
@@ -837,12 +837,12 @@ void ManagementAgentImpl::handleLocateRe
     }
 }
 
-void ManagementAgentImpl::handleMethodRequest(const string& body, const string& cid, const string& replyTo)
+void ManagementAgentImpl::handleMethodRequest(const string& body, const string& cid, const string& replyTo, const string& userId)
 {
     if (extThread) {
         sys::Mutex::ScopedLock lock(agentLock);
 
-        methodQueue.push_back(new QueuedMethod(cid, replyTo, body));
+        methodQueue.push_back(new QueuedMethod(cid, replyTo, body, userId));
         if (pipeHandle != 0) {
             pipeHandle->write("X", 1);
         } else if (notifyable != 0) {
@@ -861,7 +861,7 @@ void ManagementAgentImpl::handleMethodRe
             inCallback = false;
         }
     } else {
-        invokeMethodRequest(body, cid, replyTo);
+        invokeMethodRequest(body, cid, replyTo, userId);
     }
 
     QPID_LOG(trace, "RCVD MethodRequest");
@@ -876,13 +876,17 @@ void ManagementAgentImpl::received(Messa
         replyToKey = rt.getRoutingKey();
     }
 
+    string userId;
+    if (mp.hasUserId())
+        userId = mp.getUserId();
+
     if (mp.hasAppId() && mp.getAppId() == "qmf2")
     {
         string opcode = mp.getApplicationHeaders().getAsString("qmf.opcode");
         string cid = msg.getMessageProperties().getCorrelationId();
 
         if      (opcode == "_agent_locate_request") handleLocateRequest(msg.getData(), cid, replyToKey);
-        else if (opcode == "_method_request")       handleMethodRequest(msg.getData(), cid, replyToKey);
+        else if (opcode == "_method_request")       handleMethodRequest(msg.getData(), cid, replyToKey, userId);
         else if (opcode == "_query_request")        handleGetQuery(msg.getData(), cid, replyToKey);
         else {
             QPID_LOG(warning, "Support for QMF V2 Opcode [" << opcode << "] TBD!!!");

Modified: qpid/trunk/qpid/cpp/src/qpid/agent/ManagementAgentImpl.h
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/agent/ManagementAgentImpl.h?rev=1033232&r1=1033231&r2=1033232&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/agent/ManagementAgentImpl.h (original)
+++ qpid/trunk/qpid/cpp/src/qpid/agent/ManagementAgentImpl.h Tue Nov  9 21:15:03 2010
@@ -128,12 +128,13 @@ class ManagementAgentImpl : public Manag
     };
 
     struct QueuedMethod {
-    QueuedMethod(const std::string& _cid, const std::string& _reply, const std::string& _body) :
-        cid(_cid), replyTo(_reply), body(_body) {}
+    QueuedMethod(const std::string& _cid, const std::string& _reply, const std::string& _body, const std::string& _uid) :
+        cid(_cid), replyTo(_reply), body(_body), userId(_uid) {}
 
         std::string cid;
         std::string replyTo;
         std::string body;
+        std::string userId;
     };
 
     typedef std::deque<QueuedMethod*> MethodQueue;
@@ -282,11 +283,11 @@ class ManagementAgentImpl : public Manag
     void handlePackageRequest (qpid::framing::Buffer& inBuffer);
     void handleClassQuery     (qpid::framing::Buffer& inBuffer);
     void handleSchemaRequest  (qpid::framing::Buffer& inBuffer, uint32_t sequence, const std::string& replyTo);
-    void invokeMethodRequest  (const std::string& body, const std::string& cid, const std::string& replyTo);
+    void invokeMethodRequest  (const std::string& body, const std::string& cid, const std::string& replyTo, const std::string& userId);
 
     void handleGetQuery       (const std::string& body, const std::string& cid, const std::string& replyTo);
     void handleLocateRequest  (const std::string& body, const std::string& sequence, const std::string& replyTo);
-    void handleMethodRequest  (const std::string& body, const std::string& sequence, const std::string& replyTo);
+    void handleMethodRequest  (const std::string& body, const std::string& sequence, const std::string& replyTo, const std::string& userId);
     void handleConsoleAddedIndication();
     void getHeartbeatContent  (qpid::types::Variant::Map& map);
 };

Modified: qpid/trunk/qpid/cpp/src/qpid/management/Manageable.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/management/Manageable.cpp?rev=1033232&r1=1033231&r2=1033232&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/management/Manageable.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/management/Manageable.cpp Tue Nov  9 21:15:03 2010
@@ -46,3 +46,8 @@ Manageable::status_t Manageable::Managem
     return STATUS_UNKNOWN_METHOD;
 }
 
+bool Manageable::AuthorizeMethod(uint32_t, Args&, const std::string&)
+{
+    return true;
+}
+

Modified: qpid/trunk/qpid/cpp/src/qpid/management/ManagementAgent.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/management/ManagementAgent.cpp?rev=1033232&r1=1033231&r2=1033232&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/management/ManagementAgent.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/management/ManagementAgent.cpp Tue Nov  9 21:15:03 2010
@@ -1083,8 +1083,8 @@ void ManagementAgent::handleMethodReques
         return;
     }
 
+    string userId = ((const qpid::broker::ConnectionState*) connToken)->getUserId();
     if (acl != 0) {
-        string userId = ((const qpid::broker::ConnectionState*) connToken)->getUserId();
         map<acl::Property, string> params;
         params[acl::PROP_SCHEMAPACKAGE] = packageName;
         params[acl::PROP_SCHEMACLASS]   = className;
@@ -1115,7 +1115,7 @@ void ManagementAgent::handleMethodReques
                 outBuffer.record();
                 sys::Mutex::ScopedUnlock u(userLock);
                 string outBuf;
-                iter->second->doMethod(methodName, inArgs, outBuf);
+                iter->second->doMethod(methodName, inArgs, outBuf, userId);
                 outBuffer.putRawData(outBuf);
             } catch(exception& e) {
                 outBuffer.restore();
@@ -1193,8 +1193,8 @@ void ManagementAgent::handleMethodReques
         return;
     }
 
+    string userId = ((const qpid::broker::ConnectionState*) connToken)->getUserId();
     if (acl != 0) {
-        string userId = ((const qpid::broker::ConnectionState*) connToken)->getUserId();
         map<acl::Property, string> params;
         params[acl::PROP_SCHEMAPACKAGE] = iter->second->getPackageName();
         params[acl::PROP_SCHEMACLASS]   = iter->second->getClassName();
@@ -1214,7 +1214,7 @@ void ManagementAgent::handleMethodReques
 
     try {
         sys::Mutex::ScopedUnlock u(userLock);
-        iter->second->doMethod(methodName, inArgs, callMap);
+        iter->second->doMethod(methodName, inArgs, callMap, userId);
         errorCode = callMap["_status_code"].asUint32();
         if (errorCode == 0) {
             outMap["_arguments"] = Variant::Map();



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