Index: main.cpp =================================================================== diff -u -r389f028cb9d4d320eae393de7c4408a58a619356 -r9ef6badf8e172436bba2bfad1642ae7e469e0361 --- main.cpp (.../main.cpp) (revision 389f028cb9d4d320eae393de7c4408a58a619356) +++ main.cpp (.../main.cpp) (revision 9ef6badf8e172436bba2bfad1642ae7e469e0361) @@ -41,6 +41,7 @@ #include "Compatible.h" // Project +#include "FileHandler.h" #include "MainTimer.h" #include "CanInterface.h" #include "FrameInterface.h" @@ -371,6 +372,37 @@ QCoreApplication::setApplicationVersion(version); } +/*! + * \brief lockdown + * \details runs the lockdown shellscript as a detached process + * and ment to be executed just before the application quits + * and only when application running in manufacturing mode. + * Must not stop application shutdown in any way. + * If any error happens it only logs. + */ +void lockdown() { + // there are two setup scenarios: + // only during setup mode which is -E (manufacturing setup) application is running under the root user permissions + // and all the files are copied to the /home/root/ te later be copied to secured locations + // and that will be done by lockdown.sh script running within application after the user is done with the setup and QUIT s the application. + if ( gEnableManufacturing ) { + QString scriptName = Storage::Device_Lockdown; + quint16 errorCode; + QString errorText; + errorCode = Device::DeviceError::checkScript (scriptName, Storage::Device_Lockdown ); + errorText = Device::DeviceError::deviceErrorText( errorCode, 1 ); + qDebug() << errorText; // since we are in the manufacturing mode it is possible to probably take a look at the serial, if not that is being logged. +#ifdef BUILD_FOR_TARGET + Storage::FileHandler::write("/home/root/lockdown.log" , errorText, false); +#else + Storage::FileHandler::write("/home/denali/lockdown.log" , errorText, false); +#endif + if ( ! errorCode ) { + QProcess::startDetached( scriptName, { qApp->applicationName() + ":" + QString::number(qApp->applicationPid()) }); + } + } +} + #ifdef UNIT_TEST #include TEST_CLASS_INCLUDE QTEST_MAIN(TEST_CLASS_NAME) @@ -500,6 +532,8 @@ Gui::_viewer->deleteLater(); + lockdown(); + return app_exec; } #endif Index: scripts/lockdown.sh =================================================================== diff -u --- scripts/lockdown.sh (revision 0) +++ scripts/lockdown.sh (revision 9ef6badf8e172436bba2bfad1642ae7e469e0361) @@ -0,0 +1,109 @@ +#!/bin/bash +########################################################################### +# +# Copyright (c) 2023 Diality Inc. - All Rights Reserved. +# +# This is inpart based on scripts developed by Sunrise Labs Inc. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file start.sh +# +# @author (last) Philip Braica +# @date (last) 22-Mar-2023 +# @author (original) Philip Braica +# @date (original) 22-Mar-2023 +# +############################################################################ + +# @details +# This file sets up and verifies some of the SOM security. + +# Does the file contain a string? if +# not, add a line at end. +# If $1 not in $2 then append line $3 to end. +# $1 What to look for. +# $2 File name. +# $3 What to add. +function appendIfMissing() { + # q for quiet, F for regular string match, not -x because not full line. + # Done as one command because this is done remotely. + grep -qF $1 $2 || echo $3 >> $2 +} + +# Remove all lines that contain $1 in file $2 then append $3. +# $1 What to look for. +# $2 File name. +function removeIfFound() { + sed -i /${1}/d $2 +} + +# Turn on some ssh security. +function secureSsh() { + local fileTarget="${PWD}/../../etc/ssh/sshd_config" + + # + chown -R root.denali ${fileTarget} + chmod -R g+rw ${fileTarget} + + # Remove add PermitRootLogin settings then add one to turn it off. + removeIfFound "PermitRootLogin" ${fileTarget} + appendIfMissing "PermitRootLogin" ${fileTarget} "PermitRootLogin no" + + # Restart service on remote. + systemctl restart system-sshd.slice +} + +# Move the customers app files to the app users home directories, +# changed the owner, and set the immutable attribute. +function moveCustomerAppFiles() { + # Move the files + mv ${PWD}/cloudsync ${PWD}/../cloudsync/ + mv ${PWD}/denali ${PWD}/../denali/ + + # Change the file owners. + chown -R cloudsync.cloudsync ${PWD}/../cloudsync + chmod -R o-rwx ${PWD}/../cloudsync + chown -R denali.denali ${PWD}/../denali + chmod -R o-rwx ${PWD}/../denali +} + +# Set all permissions for our users that +# are not root. +function setPermissionsCustomerAppFiles() { + + # Make sure the the other users have no access to these directories. + chmod -R o-rwx ${PWD}/../cloudsync + chmod -R o-rwx ${PWD}/../denali + + # Give read-only access to denali by making the group owner. + mkdir -p ${PWD}/../../var/configuration/CloudSync + chown -R cloudsync.denali ${PWD}/../../var/configuration/CloudSync + chmod -R g-w,g+r,o-rwx ${PWD}/../../var/configuration/CloudSync + + # Give read-only access to denali by making the group owner. + mkdir -p ${PWD}/../../media/sd-card/cloudsync + chown -R cloudsync.denali ${PWD}/../../media/sd-card/cloudsync + chmod -R g-w,g+r,o-rwx ${PWD}/../../media/sd-card/cloudsync + + # Set the immutable attribute for all of the files. + chattr -R +i ${PWD}/../cloudsync/* + chattr -R +i ${PWD}/../denali/* +} + +function main() { + + # Move the App Files to their home directories and setup the file + # permissions needed to make them work. + moveCustomerAppFiles + setPermissionsCustomerAppFiles + + # Turn off root login in by ssh. + secureSsh +} + +# Running the main function +main + +exit 0 Index: scripts/start.sh =================================================================== diff -u -r7f61c3b45a50145fe5c245018d481d6266166fa6 -r9ef6badf8e172436bba2bfad1642ae7e469e0361 --- scripts/start.sh (.../start.sh) (revision 7f61c3b45a50145fe5c245018d481d6266166fa6) +++ scripts/start.sh (.../start.sh) (revision 9ef6badf8e172436bba2bfad1642ae7e469e0361) @@ -137,11 +137,18 @@ } function manufacturingModePrompt() { - echo_star_comment - echo_star_message "Do you want to run in the Manufacturing Mode?" - echo_star_comment - read -p "Continue? [y,n]" -n 1 -r CONTINUE - echo "" # to echo prompts on new line +# I set to always enabled for now to always go to the manufacturing mode +# 1 - Even for normal setup start is moving files to /home/root, so the lockdown needs to run to move files. +# 2 - The UI still needs to be executed to decrypt the /var/configurations, otherwise the configurations can not be updated, +# and I don't have the ability to just decrypt and exit right now. +# Note: after the Cybersecurity release I will improve the user experience and will make it easier for manufacturing. + CONTINUE="y" + +# echo_star_comment +# echo_star_message "Do you want to run in the Manufacturing Mode?" +# echo_star_comment +# read -p "Continue? [y,n]" -n 1 -r CONTINUE +# echo "" # to echo prompts on new line if [ "$CONTINUE" == "y" ]; then sshRun "echo $SETUP_ENABLE_MANUFACTURING_MODE > $SETUP_CONF_FILE" echo_star_message "Set the setup in manufacturing mode" Index: sources/ApplicationController.cpp =================================================================== diff -u -rfb43510552969e9fb3c3f10ae693ba81ea7e8d52 -r9ef6badf8e172436bba2bfad1642ae7e469e0361 --- sources/ApplicationController.cpp (.../ApplicationController.cpp) (revision fb43510552969e9fb3c3f10ae693ba81ea7e8d52) +++ sources/ApplicationController.cpp (.../ApplicationController.cpp) (revision 9ef6badf8e172436bba2bfad1642ae7e469e0361) @@ -110,6 +110,8 @@ // From GUI connect(&_GuiController , SIGNAL(didActionTransmit(GuiActionType, const QVariantList &)), this , SLOT( onActionTransmit(GuiActionType, const QVariantList &))); + connect(&_GuiController , SIGNAL(didQuitApplication()), + this , SLOT( onQuitApplication())); // From HD/DG connect(&_MessageDispatcher, SIGNAL(didActionReceive(GuiActionType, const QVariantList &)), @@ -624,6 +626,13 @@ if ( gEnableManufacturing ) initSettings(); } +void ApplicationController::onQuitApplication() +{ + //DEBUG qDebug() << metaObject()->className() << __FUNCTION__ << QThread::currentThread(); + emit didQuitApplication(); + qApp->quit(); +} + /*! * \brief ApplicationController::versionsRequest * \details Sends a version request Index: sources/ApplicationController.h =================================================================== diff -u -r1da89b0452b8ef9448847618e75c118f3f58bd0c -r9ef6badf8e172436bba2bfad1642ae7e469e0361 --- sources/ApplicationController.h (.../ApplicationController.h) (revision 1da89b0452b8ef9448847618e75c118f3f58bd0c) +++ sources/ApplicationController.h (.../ApplicationController.h) (revision 9ef6badf8e172436bba2bfad1642ae7e469e0361) @@ -118,6 +118,8 @@ void onPOSTFail (Gui::GuiAlarmID vAlarmID); void onPOSTDone (bool vPass); + void onQuitApplication (); + signals: void didPOSTEthernet (bool vPass); void didPOSTWireless (bool vPass); @@ -171,6 +173,12 @@ * just to keep the conversation alive and let HD know UI is alive. */ void didKeepAliveBegin (); + /*! + * \brief didQuitApplication + * \details this signal is a placeholder for any farther notification to any class which needs to close itself. + * it will be used to let the other classes to stop and move to main thread. + */ + void didQuitApplication (); // Device Signal/Slots DEVICE_APP_BRIDGE_DEFINITION_LIST Index: sources/canbus/CanInterface.cpp =================================================================== diff -u -rc9f8f8cf3c6c37fc6460d8675c62c9442c4d4263 -r9ef6badf8e172436bba2bfad1642ae7e469e0361 --- sources/canbus/CanInterface.cpp (.../CanInterface.cpp) (revision c9f8f8cf3c6c37fc6460d8675c62c9442c4d4263) +++ sources/canbus/CanInterface.cpp (.../CanInterface.cpp) (revision 9ef6badf8e172436bba2bfad1642ae7e469e0361) @@ -194,6 +194,8 @@ return false; } // disabled coco end + _canDevice->setConfigurationParameter(QCanBusDevice::CanFdKey , _canFDKey ); + _canDevice->setConfigurationParameter(QCanBusDevice::BitRateKey , _canBitRate ); return true; } Index: sources/canbus/CanInterface.h =================================================================== diff -u -raf8d98b36b427e2b5f4d6659fcf3b58ee79eab6a -r9ef6badf8e172436bba2bfad1642ae7e469e0361 --- sources/canbus/CanInterface.h (.../CanInterface.h) (revision af8d98b36b427e2b5f4d6659fcf3b58ee79eab6a) +++ sources/canbus/CanInterface.h (.../CanInterface.h) (revision 9ef6badf8e172436bba2bfad1642ae7e469e0361) @@ -56,6 +56,7 @@ const char *_canType = "socketcan"; QString _canInterface = gActiveCANBus; // can0 by default, can be altered by -A(--active-can-bus) const int _canBitRate = 250000; + const bool _canFDKey = false; // member variables QCanBusDevice *_canDevice = nullptr; Index: sources/gui/GuiController.cpp =================================================================== diff -u -rc73feffa73c7fe073a7a7581144f5806dfc91beb -r9ef6badf8e172436bba2bfad1642ae7e469e0361 --- sources/gui/GuiController.cpp (.../GuiController.cpp) (revision c73feffa73c7fe073a7a7581144f5806dfc91beb) +++ sources/gui/GuiController.cpp (.../GuiController.cpp) (revision 9ef6badf8e172436bba2bfad1642ae7e469e0361) @@ -381,3 +381,12 @@ { emit didPOSTPass(vPass); } + +/*! + * \brief GuiController::doQuitApplication + * \details emit the didQuitApplication signal to ask ApplicationController to Quit the application gracefully. + */ +void GuiController::doQuitApplication() +{ + emit didQuitApplication(); +} Index: sources/gui/GuiController.h =================================================================== diff -u -rc73feffa73c7fe073a7a7581144f5806dfc91beb -r9ef6badf8e172436bba2bfad1642ae7e469e0361 --- sources/gui/GuiController.h (.../GuiController.h) (revision c73feffa73c7fe073a7a7581144f5806dfc91beb) +++ sources/gui/GuiController.h (.../GuiController.h) (revision 9ef6badf8e172436bba2bfad1642ae7e469e0361) @@ -74,6 +74,7 @@ void doExportLog (const GuiStringIndexMap &vExportList); // UI => OS void doExportService (const GuiStringIndexMap &vExportList); // UI => OS void doExportTreatment (const GuiStringIndexMap &vExportList); // UI => OS + void doQuitApplication (); private slots: // Should be private for thread safety and is connected internally. void onActionReceive (GuiActionType vAction, const QVariantList &vData); // UI <= HD/DG @@ -113,6 +114,8 @@ void didPOSTPass (bool vPass); + void didQuitApplication (); + // Device controller signal slots connection DEVICE_GUI_BRIDGE_DEFINITION_LIST Index: sources/gui/GuiView.cpp =================================================================== diff -u -rc73feffa73c7fe073a7a7581144f5806dfc91beb -r9ef6badf8e172436bba2bfad1642ae7e469e0361 --- sources/gui/GuiView.cpp (.../GuiView.cpp) (revision c73feffa73c7fe073a7a7581144f5806dfc91beb) +++ sources/gui/GuiView.cpp (.../GuiView.cpp) (revision 9ef6badf8e172436bba2bfad1642ae7e469e0361) @@ -48,6 +48,8 @@ // It should be defined in the class which wants to connect to signal. connect(this , SIGNAL(didActionTransmit(GuiActionType,const QVariantList &)), &_GuiController, SLOT( doActionTransmit(GuiActionType,const QVariantList &))); + connect(this , SIGNAL(didQuitApplication()), + &_GuiController, SLOT( doQuitApplication())); // From UI : USB drive umount connect(this , SIGNAL(didUSBDriveUmount()), @@ -383,3 +385,11 @@ manufactMode( gEnableManufacturing && vPass ); postPass(vPass); } + +/*! + * \brief GuiView::doQuitApplication + * \details emit the didQuitApplication signal to ask ApplicationController to Quit the application gracefully. + */ +void GuiView::doQuitApplication() { + emit didQuitApplication(); +} Index: sources/gui/GuiView.h =================================================================== diff -u -rc73feffa73c7fe073a7a7581144f5806dfc91beb -r9ef6badf8e172436bba2bfad1642ae7e469e0361 --- sources/gui/GuiView.h (.../GuiView.h) (revision c73feffa73c7fe073a7a7581144f5806dfc91beb) +++ sources/gui/GuiView.h (.../GuiView.h) (revision 9ef6badf8e172436bba2bfad1642ae7e469e0361) @@ -122,6 +122,7 @@ void doExportListRemove ( ); quint8 doExportListPercent(quint32 vIndex ); + void doQuitApplication(); signals: void didActionReceive (GuiActionType vAction, const QVariantList &vData); // UI <= HD/DG void didActionTransmit(GuiActionType vAction, const QVariantList &vData); // UI => HD/DG @@ -136,5 +137,7 @@ void didExportTreatment (const GuiStringIndexMap &vExportList); void didExport (); void didExportStat (quint32 vIndex, const QString &vFileName, quint8 vPercent); + + void didQuitApplication (); }; } Index: sources/gui/qml/pages/settings/SettingsStack.qml =================================================================== diff -u -r5a4a26f106ba03759e3a89b19690fa678f8a3aca -r9ef6badf8e172436bba2bfad1642ae7e469e0361 --- sources/gui/qml/pages/settings/SettingsStack.qml (.../SettingsStack.qml) (revision 5a4a26f106ba03759e3a89b19690fa678f8a3aca) +++ sources/gui/qml/pages/settings/SettingsStack.qml (.../SettingsStack.qml) (revision 9ef6badf8e172436bba2bfad1642ae7e469e0361) @@ -120,8 +120,15 @@ title : _GuiView.manufactSetup ? qsTr("Manufacturing Setup") : serviceMode ? qsTr("Service") : qsTr("Device Settings") backVisible : false confirmVisible : serviceMode - confirmText.text: qsTr("SHUTDOWN") - onConfirmClicked: _GuiView.doActionTransmit(GuiActions.ID_PowerOff, GuiActions.NoData) + confirmText.text: _GuiView.manufactSetup ? qsTr("QUIT") : qsTr("SHUTDOWN") + onConfirmClicked: { + if ( _GuiView.manufactSetup ) { + _GuiView.doQuitApplication() + } + else { + _GuiView.doActionTransmit(GuiActions.ID_PowerOff, GuiActions.NoData) + } + } itemsText : _root.itemsText itemsEnabled : _root.itemsEnabled itemsVisible : _root.itemsVisible Index: sources/storage/StorageGlobals.cpp =================================================================== diff -u -r5a4a26f106ba03759e3a89b19690fa678f8a3aca -r9ef6badf8e172436bba2bfad1642ae7e469e0361 --- sources/storage/StorageGlobals.cpp (.../StorageGlobals.cpp) (revision 5a4a26f106ba03759e3a89b19690fa678f8a3aca) +++ sources/storage/StorageGlobals.cpp (.../StorageGlobals.cpp) (revision 9ef6badf8e172436bba2bfad1642ae7e469e0361) @@ -193,6 +193,9 @@ // Device Decommissioning const char *Device_Decommission = "decommission.sh"; + // Device Lockdown + const char *Device_Lockdown = "lockdown.sh"; + const char *CloudSyncPath = "/var/configurations/CloudSync/credentials/"; } Index: sources/storage/StorageGlobals.h =================================================================== diff -u -r5a4a26f106ba03759e3a89b19690fa678f8a3aca -r9ef6badf8e172436bba2bfad1642ae7e469e0361 --- sources/storage/StorageGlobals.h (.../StorageGlobals.h) (revision 5a4a26f106ba03759e3a89b19690fa678f8a3aca) +++ sources/storage/StorageGlobals.h (.../StorageGlobals.h) (revision 9ef6badf8e172436bba2bfad1642ae7e469e0361) @@ -130,6 +130,9 @@ // Device Decommissioning extern const char *Device_Decommission; + // Device Lockdown + extern const char *Device_Lockdown; + extern const char *CloudSyncPath; }