History

add remotelyCallable and remoteCallerID to provide additional security to Entities.callEntityServerMethod()

ZappoMan committed 9 years ago

Commit a7e21d71 parent fb7f6df4 files · +38 −7Browse files

Showing the changes to libraries/script-engine/src/ScriptEngine.cpp (1 of 4 files). Show all

Unified · Split

libraries/script-engine/src/ScriptEngine.cpp+33−4
@@ -2476,7 +2476,7 @@ void ScriptEngine::callWithEnvironment(const EntityItemID& entityID, const QUrl& · 2475 unmodified lines
2476 doWithEnvironment(entityID, sandboxURL, operation);2476 doWithEnvironment(entityID, sandboxURL, operation);
2477}2477}
2478 2478
2479void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const QStringList& params) {2479void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const QStringList& params, const QUuid& remoteCallerID) {
2480 if (QThread::currentThread() != thread()) {2480 if (QThread::currentThread() != thread()) {
2481#ifdef THREAD_DEBUGGING2481#ifdef THREAD_DEBUGGING
2482 qCDebug(scriptengine) << "*** WARNING *** ScriptEngine::callEntityScriptMethod() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "] "2482 qCDebug(scriptengine) << "*** WARNING *** ScriptEngine::callEntityScriptMethod() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "] "
@@ -2486,7 +2486,8 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS · 3 unmodified lines
2486 QMetaObject::invokeMethod(this, "callEntityScriptMethod",2486 QMetaObject::invokeMethod(this, "callEntityScriptMethod",
2487 Q_ARG(const EntityItemID&, entityID),2487 Q_ARG(const EntityItemID&, entityID),
2488 Q_ARG(const QString&, methodName),2488 Q_ARG(const QString&, methodName),
2489 Q_ARG(const QStringList&, params));2489 Q_ARG(const QStringList&, params),
2490 Q_ARG(const QUuid&, remoteCallerID));
2490 return;2491 return;
2491 }2492 }
2492#ifdef THREAD_DEBUGGING2493#ifdef THREAD_DEBUGGING
@@ -2500,13 +2501,41 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS · 7 unmodified lines
2500 if (isEntityScriptRunning(entityID)) {2501 if (isEntityScriptRunning(entityID)) {
2501 EntityScriptDetails details = _entityScripts[entityID];2502 EntityScriptDetails details = _entityScripts[entityID];
2502 QScriptValue entityScript = details.scriptObject; // previously loaded2503 QScriptValue entityScript = details.scriptObject; // previously loaded
2503 if (entityScript.property(methodName).isFunction()) {2504
2505 // If this is a remote call, we need to check to see if the function is remotely callable
2506 // we do this by checking for the existance of the 'remotelyCallable' property on the
2507 // entityScript. And we confirm that the method name is included. If this fails, the
2508 // function will not be called.
2509 bool callAllowed = false;
2510 if (remoteCallerID == QUuid()) {
2511 callAllowed = true;
2512 } else {
2513 if (entityScript.property("remotelyCallable").isArray()) {
2514 auto callables = entityScript.property("remotelyCallable");
2515 auto callableCount = callables.property("length").toInteger();
2516 for (int i = 0; i < callableCount; i++) {
2517 auto callable = callables.property(i).toString();
2518 if (callable == methodName) {
2519 callAllowed = true;
2520 break;
2521 }
2522 }
2523 }
2524 if (!callAllowed) {
2525 qDebug() << "Method [" << methodName << "] not remotely callable.";
2526 }
2527 }
2528
2529 if (callAllowed && entityScript.property(methodName).isFunction()) {
2504 QScriptValueList args;2530 QScriptValueList args;
2505 args << entityID.toScriptValue(this);2531 args << entityID.toScriptValue(this);
2506 args << qScriptValueFromSequence(this, params);2532 args << qScriptValueFromSequence(this, params);
2533
2534 QScriptValue oldData = this->globalObject().property("remoteCallerID");
2535 this->globalObject().setProperty("remoteCallerID", remoteCallerID.toString()); // Make the remoteCallerID available to javascript as a global.
2507 callWithEnvironment(entityID, details.definingSandboxURL, entityScript.property(methodName), entityScript, args);2536 callWithEnvironment(entityID, details.definingSandboxURL, entityScript.property(methodName), entityScript, args);
2537 this->globalObject().setProperty("remoteCallerID", oldData);
2508 }2538 }
2509
2510 }2539 }
2511}2540}
2512 2541