Author: kgiusti
Date: Fri Mar 19 14:59:47 2010
New Revision: 925252
URL: http://svn.apache.org/viewvc?rev=925252&view=rev
Log:
authorize agent method call
Modified:
qpid/branches/qmf-devel0.7a/qpid/cpp/src/qpid/management/ManagementAgent.cpp
Modified:
qpid/branches/qmf-devel0.7a/qpid/cpp/src/qpid/management/ManagementAgent.cpp
URL:
http://svn.apache.org/viewvc/qpid/branches/qmf-devel0.7a/qpid/cpp/src/qpid/management/ManagementAgent.cpp?rev=925252&r1=925251&r2=925252&view=diff
==============================================================================
---
qpid/branches/qmf-devel0.7a/qpid/cpp/src/qpid/management/ManagementAgent.cpp
(original)
+++
qpid/branches/qmf-devel0.7a/qpid/cpp/src/qpid/management/ManagementAgent.cpp
Fri Mar 19 14:59:47 2010
@@ -54,12 +54,14 @@ namespace _qmf = qmf::org::apache::qpid:
static qpid::messaging::Variant::Map mapEncodeSchemaId(const std::string&
pname,
const std::string&
cname,
+ const std::string& type,
const uint8_t *md5Sum)
{
qpid::messaging::Variant::Map map_;
map_["_package_name"] = pname;
map_["_class_name"] = cname;
+ map_["_type"] = type;
map_["_hash_str"] = std::string((const char *)md5Sum,
qpid::management::ManagementObject::MD5_LEN);
return map_;
@@ -251,6 +253,7 @@ ObjectId ManagementAgent::addObject(Mana
map_["_schema_id"] = mapEncodeSchemaId(object->getPackageName(),
object->getClassName(),
+ "_data",
object->getMd5Sum());
object->mapEncodeValues(values, true, false); // send props only
map_["_values"] = values;
@@ -285,6 +288,7 @@ void ManagementAgent::raiseEvent(const M
map_["_schema_id"] = mapEncodeSchemaId(event.getPackageName(),
event.getEventName(),
+ "_event",
event.getMd5Sum());
event.mapEncode(values);
map_["_values"] = values;
@@ -300,6 +304,7 @@ void ManagementAgent::raiseEvent(const M
sendBuffer(msg.getContent(), 0, headers, mExchange,
"console.event.1.0." + event.getPackageName() + "." +
event.getEventName());
+ QPID_LOG(trace, "SEND raiseEvent class=" << event.getPackageName() << "."
<< event.getEventName());
}
ManagementAgent::Periodic::Periodic (ManagementAgent& _agent, uint32_t
_seconds)
@@ -562,6 +567,7 @@ void ManagementAgent::periodicProcessing
map_["_schema_id"] =
mapEncodeSchemaId(object->getPackageName(),
object->getClassName(),
+ "_data",
object->getMd5Sum());
object->mapEncodeValues(values, send_props, send_stats);
map_["_values"] = values;
@@ -617,6 +623,7 @@ void ManagementAgent::periodicProcessing
map_["_schema_id"] = mapEncodeSchemaId((*cdIter)->getPackageName(),
(*cdIter)->getClassName(),
+ "_data",
(*cdIter)->getMd5Sum());
(*cdIter)->mapEncodeValues(values, true, false);
map_["_values"] = values;
@@ -675,6 +682,7 @@ void ManagementAgent::deleteObjectNowLH(
map_["_schema_id"] = mapEncodeSchemaId(object->getPackageName(),
object->getClassName(),
+ "_data",
object->getMd5Sum());
object->mapEncodeValues(values, true, false);
map_["_values"] = values;
@@ -752,14 +760,14 @@ bool ManagementAgent::dispatchCommand (D
void ManagementAgent::handleMethodRequestLH (Buffer& inBuffer, string
replyToKey,
uint32_t sequence, const
ConnectionToken* connToken)
{
+#if 1 // deprecated
QPID_LOG(warning, "Ignoring old-format QMF Method Request!!!");
-#if 1
+ // prevent "unused param" warnings
(void)inBuffer;
(void)replyToKey;
(void)sequence;
(void)connToken;
#else
- // @todo KAG use new method req format
string methodName;
string packageName;
string className;
@@ -768,9 +776,7 @@ void ManagementAgent::handleMethodReques
uint32_t outLen;
AclModule* acl = broker->getAcl();
- //ObjectId objId(inBuffer);
- assert(false); // KAG TODO FIXME
- ObjectId objId(std::string("fleabag???"));
+ ObjectId objId(inBuffer);
inBuffer.getShortString(packageName);
inBuffer.getShortString(className);
inBuffer.getBin128(hash);
@@ -823,8 +829,7 @@ void ManagementAgent::handleMethodReques
try {
outBuffer.record();
Mutex::ScopedUnlock u(userLock);
- //iter->second->doMethod(methodName, inBuffer, outBuffer);
- assert(false); // KAG TODO FIX
+ iter->second->doMethod(methodName, inBuffer, outBuffer);
} catch(exception& e) {
outBuffer.restore();
outBuffer.putLong(Manageable::STATUS_EXCEPTION);
@@ -864,6 +869,7 @@ void ManagementAgent::handleMethodReques
((outMap["_error"].asMap())["_values"].asMap())["_status_text"] =
Manageable::StatusText(Manageable::STATUS_PARAMETER_INVALID);
outMap.encode();
sendBuffer(outMsg.getContent(), sequence, headers, dExchange, replyTo);
+ QPID_LOG(trace, "SEND MethodResponse (invalid param) to=" << replyTo
<< " seq=" << sequence);
return;
}
@@ -884,6 +890,7 @@ void ManagementAgent::handleMethodReques
((outMap["_error"].asMap())["_values"].asMap())["_status_text"] =
e.what();
outMap.encode();
sendBuffer(outMsg.getContent(), sequence, headers, dExchange, replyTo);
+ QPID_LOG(trace, "SEND MethodResponse (invalid format) to=" << replyTo
<< " seq=" << sequence);
return;
}
@@ -894,6 +901,7 @@ void ManagementAgent::handleMethodReques
((outMap["_error"].asMap())["_values"].asMap())["_status_text"] =
Manageable::StatusText(Manageable::STATUS_UNKNOWN_OBJECT);
outMap.encode();
sendBuffer(outMsg.getContent(), sequence, headers, dExchange, replyTo);
+ QPID_LOG(trace, "SEND MethodResponse (unknown object) to=" << replyTo
<< " seq=" << sequence);
return;
}
@@ -934,10 +942,15 @@ void ManagementAgent::handleMethodReques
} catch(exception& e) {
((outMap["_error"].asMap())["_values"].asMap())["_status"] =
Manageable::STATUS_EXCEPTION;
((outMap["_error"].asMap())["_values"].asMap())["_status_text"] =
e.what();
+ outMap.encode();
+ sendBuffer(outMsg.getContent(), sequence, headers, dExchange, replyTo);
+ QPID_LOG(trace, "SEND MethodResponse (exception) to=" << replyTo << "
seq=" << sequence);
+ return;
}
outMap.encode();
sendBuffer(outMsg.getContent(), sequence, headers, dExchange, replyTo);
+ QPID_LOG(trace, "SEND MethodResponse to=" << replyTo << " seq=" <<
sequence);
}
@@ -1077,7 +1090,6 @@ void ManagementAgent::SchemaClass::appen
void ManagementAgent::handleSchemaRequestLH(Buffer& inBuffer, string
replyToKey, uint32_t sequence)
{
- // @todo KAG: use new schema format
string packageName;
SchemaClassKey key;
@@ -1119,7 +1131,6 @@ void ManagementAgent::handleSchemaRespon
string packageName;
SchemaClassKey key;
- // KAG: TODO - Handle new schema format
inBuffer.record();
inBuffer.getOctet();
inBuffer.getShortString(packageName);
@@ -1362,69 +1373,163 @@ void ManagementAgent::handleGetQueryLH (
bool ManagementAgent::authorizeAgentMessageLH(Message& msg)
{
- // KAG TODO: handle both old and new clients
-
Buffer inBuffer (inputBuffer, MA_BUFFER_SIZE);
- uint8_t opcode;
- uint32_t sequence;
- string replyToKey;
+ uint32_t sequence = 0;
+ bool methodReq = false;
+ bool mapMsg = false;
+ string packageName;
+ string className;
+ string methodName;
if (msg.encodedSize() > MA_BUFFER_SIZE)
return false;
msg.encodeContent(inBuffer);
+ uint32_t bufferLen = inBuffer.getPosition();
inBuffer.reset();
- if (!checkHeader(inBuffer, &opcode, &sequence))
- // KAG TODO: handle new map style messages also!
- //return false;
- assert(false);
+ const framing::MessageProperties* p =
+ msg.getFrames().getHeaders()->get<framing::MessageProperties>();
+
+ const framing::FieldTable *headers = msg.getApplicationHeaders();
+
+ if (headers && headers->getAsString("app_id") == "qmf2")
+ {
+ mapMsg = true;
+
+ if (p && p->hasCorrelationId()) {
+ std::string cid = p->getCorrelationId();
+ if (!cid.empty()) {
+ try {
+ sequence = boost::lexical_cast<uint32_t>(cid);
+ } catch(const boost::bad_lexical_cast&) {
+ QPID_LOG(warning,
+ "Bad correlation Id for received QMF authorize
req: [" << cid << "]");
+ return false;
+ }
+ }
+ }
+
+ if (headers->getAsString("qmf.opcode") == "_method_request")
+ {
+ methodReq = true;
+
+ // extract object id and method name
+
+ std::string body;
+ inBuffer.getRawData(body, bufferLen);
+ qpid::messaging::Message inMsg(body);
+ qpid::messaging::MapView inMap(inMsg);
+ qpid::messaging::MapView::const_iterator oid, mid;
+
+ ObjectId objId;
+
+ if ((oid = inMap.find("_object_id")) == inMap.end() ||
+ (mid = inMap.find("_method_name")) == inMap.end()) {
+ QPID_LOG(warning,
+ "Missing fields in QMF authorize req received.");
+ return false;
+ }
+
+ try {
+ // coversions will throw if input is invalid.
+ objId = ObjectId(oid->second.asMap());
+ methodName = mid->second.getString();
+ } catch(exception& e) {
+ QPID_LOG(warning,
+ "Badly formatted QMF authorize req received.");
+ return false;
+ }
+
+ // look up schema for object to get package and class name
+
+ ManagementObjectMap::iterator iter = managementObjects.find(objId);
+
+ if (iter == managementObjects.end() || iter->second->isDeleted()) {
+ QPID_LOG(debug, "ManagementAgent::authorizeAgentMessageLH:
stale object id " <<
+ objId);
+ return false;
+ }
+
+ packageName = iter->second->getPackageName();
+ className = iter->second->getClassName();
+ }
+ } else { // old style binary message format
+
+ uint8_t opcode;
- if (opcode == 'M') {
+ if (!checkHeader(inBuffer, &opcode, &sequence))
+ return false;
+
+ if (opcode == 'M') {
+ methodReq = true;
+
+ // extract method name & schema package and class name
+
+ uint8_t hash[16];
+ inBuffer.getLongLong(); // skip over object id
+ inBuffer.getLongLong();
+ inBuffer.getShortString(packageName);
+ inBuffer.getShortString(className);
+ inBuffer.getBin128(hash);
+ inBuffer.getShortString(methodName);
+
+ }
+ }
+
+ if (methodReq) {
// TODO: check method call against ACL list.
+ map<acl::Property, string> params;
AclModule* acl = broker->getAcl();
if (acl == 0)
return true;
string userId = ((const qpid::broker::ConnectionState*)
msg.getPublisher())->getUserId();
- string packageName;
- string className;
- uint8_t hash[16];
- string methodName;
-
- map<acl::Property, string> params;
- //ObjectId objId(inBuffer);
- inBuffer.getLongLong();
- inBuffer.getLongLong();
- inBuffer.getShortString(packageName);
- inBuffer.getShortString(className);
- inBuffer.getBin128(hash);
- inBuffer.getShortString(methodName);
-
params[acl::PROP_SCHEMAPACKAGE] = packageName;
params[acl::PROP_SCHEMACLASS] = className;
if (acl->authorise(userId, acl::ACT_ACCESS, acl::OBJ_METHOD,
methodName, ¶ms))
return true;
+ // authorization failed, send reply if replyTo present
+
const framing::MessageProperties* p =
msg.getFrames().getHeaders()->get<framing::MessageProperties>();
if (p && p->hasReplyTo()) {
const framing::ReplyTo& rt = p->getReplyTo();
- replyToKey = rt.getRoutingKey();
+ string replyToKey = rt.getRoutingKey();
- Buffer outBuffer(outputBuffer, MA_BUFFER_SIZE);
- uint32_t outLen;
+ if (mapMsg) {
- // KAG TODO: old-style response
- encodeHeader(outBuffer, 'm', sequence);
- outBuffer.putLong(Manageable::STATUS_FORBIDDEN);
-
outBuffer.putMediumString(Manageable::StatusText(Manageable::STATUS_FORBIDDEN));
- outLen = MA_BUFFER_SIZE - outBuffer.available();
- outBuffer.reset();
- sendBuffer(outBuffer, outLen, dExchange, replyToKey);
- QPID_LOG(trace, "SEND MethodResponse status=FORBIDDEN" << " seq="
<< sequence)
- }
+ qpid::messaging::Message outMsg;
+ qpid::messaging::MapContent outMap(outMsg);
+ qpid::messaging::Variant::Map headers;
+
+ headers["method"] = "response";
+ headers["qmf.opcode"] = "_method_response";
+ headers["qmf.content"] = "_data";
+ headers["qmf.agent"] = std::string(agentName);
+
+ ((outMap["_error"].asMap())["_values"].asMap())["_status"] =
Manageable::STATUS_FORBIDDEN;
+
((outMap["_error"].asMap())["_values"].asMap())["_status_text"] =
Manageable::StatusText(Manageable::STATUS_FORBIDDEN);
+ outMap.encode();
+ sendBuffer(outMsg.getContent(), sequence, headers, dExchange,
replyToKey);
+
+ } else {
+
+ Buffer outBuffer(outputBuffer, MA_BUFFER_SIZE);
+ uint32_t outLen;
+
+ encodeHeader(outBuffer, 'm', sequence);
+ outBuffer.putLong(Manageable::STATUS_FORBIDDEN);
+
outBuffer.putMediumString(Manageable::StatusText(Manageable::STATUS_FORBIDDEN));
+ outLen = MA_BUFFER_SIZE - outBuffer.available();
+ outBuffer.reset();
+ sendBuffer(outBuffer, outLen, dExchange, replyToKey);
+ }
+
+ QPID_LOG(trace, "SEND MethodResponse status=FORBIDDEN" << " seq="
<< sequence);
+ }
return false;
}
---------------------------------------------------------------------
Apache Qpid - AMQP Messaging Implementation
Project: http://qpid.apache.org
Use/Interact: mailto:[email protected]