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