diff --git a/README.md b/README.md index a4d04b8254..d111667007 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,9 @@ ### [Download (Windows 64-bit, .zip)](https://realities.dev/cdn/hifi-community/v0860-kasen-VS-release+freshstart/Packaged_Release.zip) -#### Changes for **v0.86.0 K1** consist of: +#### Changes for **v0.86.0** consist of: + +#### Added in K1 (12/3/19) * Audio Buffer choppy audio bugfix by increasing the buffer size. * User Activity Logger disabled, option in code to log the reports to console. @@ -11,13 +13,21 @@ * Entity Script Whitelist, no scripts are whitelisted by default. * Background CMD outputs full log, instant close of application on closing of the CMD-line. +#### Added in K2 (12/8/19) + +* QML Interface to access and save whitelist live to interface.json +* Add "VideoDecodeStats" to .gitignore +* Fix VCPKG SDL2 to port files from 2.0.8 to 2.0.10 to fix CMake build issues. + This build has been tested on Windows 10 Pro 64-bit w/ Nvidia graphics drivers. ### Whitelist Instructions The whitelist checks every entity-script attempting to run on your client against a list of domains, their subfolders, or the specific script URL entirely. -The **Start** batch file launches and sets the whitelist environment variable for you (you have to edit in your whitelisted domains), however if you launch interface.exe directly then you must set the Windows environment variable "**EXTRA_WHITELIST**" with your whitelisted domains comma separated like so: "**https://kasen.io/,http://kasen.io/,https://exampledomain.com/scriptFolder/**" +The Interface has the whitelist settings under "**Settings -> Entity Script Whitelist**" for you to configure live. The whitelist checks against the domains literally, so you have to be precise to ensure security and functionality. For example, the difference between "http://" and "https://" matters as those will be seen as two different domains in the eyes of the whitelist. + +You can also set the Windows environment variable "**EXTRA_WHITELIST**" with your whitelisted domains comma separated like so: "**https://kasen.io/,http://kasen.io/,https://exampledomain.com/scriptFolder/**" Alternatively you can make a batch file placed in the same folder as interface.exe that sets the whitelist environment variable temporarily: @@ -26,10 +36,6 @@ set "EXTRA_WHITELIST=http://mpassets.highfidelity.com/,https://raw.githubusercon interface.exe ``` -By default, we are whitelisting High Fidelity's current known CDN domains so we can see their own/hosted entity-script related content. - -The whitelist checks against the domains literally, so you have to be precise to ensure security and functionality. For example, the difference between "http://" and "https://" matters as those will be seen as two different domains in the eyes of the whitelist. - ### Boot to Metaverse: The Goal Too many of us have our own personal combinations of High Fidelity from C++ modifications to different default scripts, all of which are lost to time as their fullest potential is never truly shared and propagated through the system. diff --git a/interface/resources/qml/hifi/dialogs/security/EntityScriptWhitelist.qml b/interface/resources/qml/hifi/dialogs/security/EntityScriptWhitelist.qml new file mode 100644 index 0000000000..ba3f27788d --- /dev/null +++ b/interface/resources/qml/hifi/dialogs/security/EntityScriptWhitelist.qml @@ -0,0 +1,106 @@ +// +// ScriptWhitelist.qml +// interface/resources/qml/hifi/dialogs/security +// +// Created by Kasen IO on 2019.12.05 | realities.dev | kasenvr@gmail.com +// Copyright 2019 Kasen IO +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +// Security Settings for the Entity Script Whitelist + +import Hifi 1.0 as Hifi +import QtQuick 2.8 +import QtQuick.Controls 2.3 +import QtQuick.Layouts 1.12 +import stylesUit 1.0 as HifiStylesUit +import controlsUit 1.0 as HiFiControls +import PerformanceEnums 1.0 +import "../../../windows" + + +Rectangle { + + function getWhitelistAsText() { + var whitelist = Settings.getValue("private/settingsSafeURLS"); + return whitelist; + } + + function setWhiteListAsText(whitelistText) { + console.info('SETTINGCURRENTVALUE: ', Settings.getValue('private/settingsSafeURLS'), whitelistText.text) + Settings.setValue("private/settingsSafeURLS", whitelistText.text); + console.info('SETVALUE: ', Settings.getValue('private/settingsSafeURLS'), whitelistText.text) + } + + anchors.fill: parent + width: parent.width; + height: 120; + color: "#80010203"; + + HifiStylesUit.RalewayRegular { + id: titleText; + text: "Entity Script Whitelist" + // Text size + size: 24; + // Style + color: "white"; + elide: Text.ElideRight; + // Anchors + anchors.top: parent.top; + anchors.left: parent.left; + anchors.leftMargin: 20; + anchors.right: parent.right; + anchors.rightMargin: 20; + height: 60; + } + + Rectangle { + id: textAreaRectangle; + color: "black"; + width: parent.width; + height: 250; + anchors.top: titleText.bottom; + + ScrollView { + id: textAreaScrollView + anchors.fill: parent; + width: parent.width + height: parent.height + contentWidth: parent.width + contentHeight: parent.height + clip: false; + + TextArea { + id: whitelistTextArea + text: getWhitelistAsText(); + width: parent.width; + height: parent.height; + font.family: "Ubuntu"; + font.pointSize: 12; + color: "white"; + } + } + + Button { + id: saveChanges + anchors.topMargin: 5; + anchors.leftMargin: 20; + anchors.rightMargin: 20; + x: textAreaRectangle.x + textAreaRectangle.width - width - 5; + y: textAreaRectangle.y + textAreaRectangle.height - height; + contentItem: Text { + text: saveChanges.text + font.family: "Ubuntu"; + font.pointSize: 12; + opacity: enabled ? 1.0 : 0.3 + color: "black" + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + text: "Save Changes" + onClicked: setWhiteListAsText(whitelistTextArea) + } + } +} \ No newline at end of file diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 508c44fbd1..9bc1dae56e 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -286,6 +286,20 @@ Menu::Menu() { hmd->toggleShouldShowTablet(); } }); + + // Settings > Entity Script Whitelist + action = addActionToQMenuAndActionHash(settingsMenu, "Entity Script Whitelist"); + connect(action, &QAction::triggered, [] { + auto tablet = DependencyManager::get()->getTablet("com.highfidelity.interface.tablet.system"); + auto hmd = DependencyManager::get(); + + DependencyManager::get()->clearCache(); + tablet->pushOntoStack("hifi/dialogs/security/EntityScriptWhitelist.qml"); + + if (!hmd->getShouldShowTablet()) { + hmd->toggleShouldShowTablet(); + } + }); // Settings > Developer Menu addCheckableActionToQMenuAndActionHash(settingsMenu, "Developer Menu", 0, false, this, SLOT(toggleDeveloperMenus())); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index ea118ec5dd..37b3f971fc 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -181,6 +181,7 @@ namespace MenuOption { const QString RunningScripts = "Running Scripts..."; const QString RunTimingTests = "Run Timing Tests"; const QString ScriptedMotorControl = "Enable Scripted Motor Control"; + const QString EntityScriptWhitelist = "Entity Script Whitelist"; const QString ShowTrackedObjects = "Show Tracked Objects"; const QString SelfieCamera = "Selfie"; const QString SendWrongDSConnectVersion = "Send wrong DS connect version"; diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index f205b016d1..d8d593df32 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -84,6 +84,11 @@ #include "../../midi/src/Midi.h" // FIXME why won't a simpler include work? #include "MIDIEvent.h" +#include "SettingHandle.h" +// #include "SettingManager.h" +// #include "SettingInterface.h" +// #include "SettingHelpers.h" + const QString ScriptEngine::_SETTINGS_ENABLE_EXTENDED_EXCEPTIONS { "com.highfidelity.experimental.enableExtendedJSExceptions" }; @@ -2362,10 +2367,18 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co QList safeURLS = { "https://FAKEURL.t43wt4g4g44FAKE" }; safeURLS += qEnvironmentVariable("EXTRA_WHITELIST").split(QRegExp("\\s*,\\s*"), QString::SkipEmptyParts); + // PULL SAFEURLS FROM INTERFACE.JSON Settings + + QVariant raw = Setting::Handle("private/settingsSafeURLS").get(); + QStringList settingsSafeURLS = raw.toString().split(QRegExp("[\r\n]+")); + safeURLS += settingsSafeURLS; + + // END PULL SAFEURLS FROM INTERFACE.JSON Settings + bool isInWhitelist = false; // assume unsafe for (const auto& str : safeURLS) { // qDebug() << "CHECKING" << entityID.toString() << scriptOrURL << "AGAINST" << str; - qDebug() << "SCRIPTOURL STARTSWITH" << scriptOrURL << "TESTING AGAINST" << str << "RESULTS IN" + qCDebug(scriptengine) << "SCRIPT URL STARTSWITH" << scriptOrURL << "TESTING AGAINST" << str << "RESULTS IN" << scriptOrURL.startsWith(str); if (scriptOrURL.startsWith(str)) { isInWhitelist = true; @@ -2373,7 +2386,7 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co } } if (!isInWhitelist) { - qDebug() << "(disabled entity script)" << entityID.toString() << scriptOrURL; + qCDebug(scriptengine) << "(disabled entity script)" << entityID.toString() << scriptOrURL; exception = makeError("UNSAFE_ENTITY_SCRIPTS == 0"); } else { QTimer timeout;