add support for whitelist entity scripts

This commit is contained in:
Brad Hefta-Gaub 2016-11-09 19:12:11 -08:00
parent 4ae6cbad7b
commit 8758e4a9ba
4 changed files with 57 additions and 1 deletions

View file

@ -278,6 +278,13 @@ void EntityServer::readAdditionalConfiguration(const QJsonObject& settingsSectio
tree->setWantEditLogging(wantEditLogging);
tree->setWantTerseEditLogging(wantTerseEditLogging);
QString entityScriptSourceWhitelist;
if (readOptionString("entityScriptSourceWhitelist", settingsSectionObject, entityScriptSourceWhitelist)) {
tree->setEntityScriptSourceWhitelist(entityScriptSourceWhitelist);
} else {
tree->setEntityScriptSourceWhitelist("");
}
}
void EntityServer::nodeAdded(SharedNodePointer node) {

View file

@ -1075,6 +1075,14 @@
"default": "3600",
"advanced": true
},
{
"name": "entityScriptSourceWhitelist",
"label": "Entity Scripts Allowed from:",
"help": "The domains that entity scripts are allowed from. A comma separated list of domains that entity scripts are allowed from, if someone attempts to create and entity or edit an entity to have a different domain, it will be rejected. If left blank, any domain is allowed.",
"placeholder": "",
"default": "",
"advanced": true
},
{
"name": "persistFilePath",
"label": "Entities File Path",

View file

@ -63,6 +63,11 @@ EntityTree::~EntityTree() {
eraseAllOctreeElements(false);
}
void EntityTree::setEntityScriptSourceWhitelist(const QString& entityScriptSourceWhitelist) {
_entityScriptSourceWhitelist = entityScriptSourceWhitelist.split(',');
}
void EntityTree::createRootElement() {
_rootElement = createNewElement();
}
@ -925,6 +930,9 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c
quint64 startCreate = 0, endCreate = 0;
quint64 startLogging = 0, endLogging = 0;
const quint64 LAST_EDITED_SERVERSIDE_BUMP = 1; // usec
bool suppressDisallowedScript = false;
_totalEditMessages++;
EntityItemID entityItemID;
@ -935,7 +943,31 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c
entityItemID, properties);
endDecode = usecTimestampNow();
const quint64 LAST_EDITED_SERVERSIDE_BUMP = 1; // usec
if (validEditPacket && !_entityScriptSourceWhitelist.isEmpty() && !properties.getScript().isEmpty()) {
bool passedWhiteList = false;
auto entityScript = properties.getScript();
for (const auto& whiteListedPrefix : _entityScriptSourceWhitelist) {
if (entityScript.startsWith(whiteListedPrefix, Qt::CaseInsensitive)) {
passedWhiteList = true;
break;
}
}
if (!passedWhiteList) {
if (wantEditLogging()) {
qCDebug(entities) << "User [" << senderNode->getUUID() << "] attempting to set entity script not on whitelist, edit rejected";
}
// If this was an add, we also want to tell the client that sent this edit that the entity was not added.
if (message.getType() == PacketType::EntityAdd) {
QWriteLocker locker(&_recentlyDeletedEntitiesLock);
_recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID);
validEditPacket = passedWhiteList;
} else {
suppressDisallowedScript = true;
}
}
}
if ((message.getType() == PacketType::EntityAdd ||
(message.getType() == PacketType::EntityEdit && properties.lifetimeChanged())) &&
!senderNode->getCanRez() && senderNode->getCanRezTmp()) {
@ -960,6 +992,12 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c
EntityItemPointer existingEntity = findEntityByEntityItemID(entityItemID);
endLookup = usecTimestampNow();
if (existingEntity && message.getType() == PacketType::EntityEdit) {
if (suppressDisallowedScript) {
properties.setLastEdited(properties.getLastEdited() + LAST_EDITED_SERVERSIDE_BUMP);
properties.setScript(existingEntity->getScript());
}
// if the EntityItem exists, then update it
startLogging = usecTimestampNow();
if (wantEditLogging()) {

View file

@ -64,6 +64,7 @@ public:
void setEntityMaxTmpLifetime(float maxTmpEntityLifetime) { _maxTmpEntityLifetime = maxTmpEntityLifetime; }
void setEntityScriptSourceWhitelist(const QString& entityScriptSourceWhitelist);
/// Implements our type specific root element factory
virtual OctreeElementPointer createNewElement(unsigned char* octalCode = NULL) override;
@ -342,6 +343,8 @@ protected:
QHash<QUuid, QSet<EntityItemID>> _childrenOfAvatars; // which entities are children of which avatars
float _maxTmpEntityLifetime { DEFAULT_MAX_TMP_ENTITY_LIFETIME };
QStringList _entityScriptSourceWhitelist;
};
#endif // hifi_EntityTree_h