@@ -353,6 +372,22 @@
+
+ restrictNet
+ textChanged(QString)
+ UdsActorSetupDialog
+ configChanged()
+
+
+ 341
+ 139
+
+
+ 295
+ 121
+
+
+
finish()
diff --git a/actor/src/udsactor/__init__.py b/actor/src/udsactor/__init__.py
index 630f9f4d..2fa9dded 100644
--- a/actor/src/udsactor/__init__.py
+++ b/actor/src/udsactor/__init__.py
@@ -31,6 +31,7 @@
from . import types
from . import rest
from . import platform
+from . import tools
__title__ = 'udsactor'
__author__ = 'Adolfo Gómez '
diff --git a/actor/src/udsactor/linux/store.py b/actor/src/udsactor/linux/store.py
index 9226ac91..869475e3 100644
--- a/actor/src/udsactor/linux/store.py
+++ b/actor/src/udsactor/linux/store.py
@@ -56,6 +56,7 @@ def readConfig() -> types.ActorConfigurationType:
validateCertificate=uds.getboolean('validate', fallback=False),
master_token=uds.get('master_token', None),
own_token=uds.get('own_token', None),
+ restrict_net=uds.get('restrict_net', None),
pre_command=uds.get('pre_command', None),
runonce_command=uds.get('runonce_command', None),
post_command=uds.get('post_command', None),
@@ -78,6 +79,7 @@ def writeConfig(config: types.ActorConfigurationType) -> None:
writeIfValue(config.actorType, 'type')
writeIfValue(config.master_token, 'master_token')
writeIfValue(config.own_token, 'own_token')
+ writeIfValue(config.restrict_net, 'restrict_net')
writeIfValue(config.pre_command, 'pre_command')
writeIfValue(config.post_command, 'post_command')
writeIfValue(config.runonce_command, 'runonce_command')
diff --git a/actor/src/udsactor/service.py b/actor/src/udsactor/service.py
index 64916f5c..2347e2c1 100644
--- a/actor/src/udsactor/service.py
+++ b/actor/src/udsactor/service.py
@@ -39,6 +39,7 @@ import typing
from . import platform
from . import rest
from . import types
+from . import tools
from .log import logger, DEBUG, INFO, ERROR, FATAL
from .http import clients_pool, server, cert
@@ -245,7 +246,7 @@ class CommonService: # pylint: disable=too-many-instance-attributes
return
while self._isAlive:
- self._interfaces = list(platform.operations.getNetworkInfo())
+ self._interfaces = tools.validNetworkCards(self._cfg.restrict_net, platform.operations.getNetworkInfo())
if self._interfaces:
break
self.doWait(5000)
diff --git a/actor/src/udsactor/tools.py b/actor/src/udsactor/tools.py
index 8d87646f..38764157 100644
--- a/actor/src/udsactor/tools.py
+++ b/actor/src/udsactor/tools.py
@@ -28,11 +28,17 @@
'''
@author: Adolfo Gómez, dkmaster at dkmon dot com
'''
-# pylint: disable=invalid-name
+from re import I
import threading
+import ipaddress
+import typing
from udsactor.log import logger
+if typing.TYPE_CHECKING:
+ from udsactor.types import ActorConfigurationType, InterfaceInfoType
+
+
class ScriptExecutorThread(threading.Thread):
def __init__(self, script: str) -> None:
super(ScriptExecutorThread, self).__init__()
@@ -45,3 +51,36 @@ class ScriptExecutorThread(threading.Thread):
except Exception as e:
logger.error('Error executing script: {}'.format(e))
logger.exception()
+
+
+# Convert "X.X.X.X/X" to ipaddress.IPv4Network
+def strToNoIPV4Network(net: typing.Optional[str]) -> typing.Optional[ipaddress.IPv4Network]:
+ if not net: # Empty or None
+ return None
+ try:
+ return ipaddress.IPv4Interface(net).network
+ except Exception:
+ return None
+
+
+def validNetworkCards(
+ net: typing.Optional[str], cards: typing.Iterable[InterfaceInfoType]
+) -> typing.List[InterfaceInfoType]:
+ try:
+ subnet = strToNoIPV4Network(net)
+ except Exception as e:
+ logger.error('Invalid network: {}'.format(e))
+ subnet = None
+
+ if subnet is None:
+ return list(cards)
+
+ def isValid(ip: str, subnet: ipaddress.IPv4Network) -> bool:
+ if not ip:
+ return False
+ try:
+ return ipaddress.IPv4Address(ip) in subnet
+ except Exception:
+ return False
+
+ return [c for c in cards if isValid(c.ip, subnet)]
diff --git a/actor/src/udsactor/types.py b/actor/src/udsactor/types.py
index 3140dd66..8e56122d 100644
--- a/actor/src/udsactor/types.py
+++ b/actor/src/udsactor/types.py
@@ -35,6 +35,7 @@ class ActorConfigurationType(typing.NamedTuple):
actorType: typing.Optional[str] = None
master_token: typing.Optional[str] = None
own_token: typing.Optional[str] = None
+ restrict_net: typing.Optional[str] = None
pre_command: typing.Optional[str] = None
runonce_command: typing.Optional[str] = None
diff --git a/actor/src/ui/setup_dialog_ui.py b/actor/src/ui/setup_dialog_ui.py
index 38b7a480..7f6d1896 100644
--- a/actor/src/ui/setup_dialog_ui.py
+++ b/actor/src/ui/setup_dialog_ui.py
@@ -2,9 +2,10 @@
# Form implementation generated from reading ui file 'setup-dialog.ui'
#
-# Created by: PyQt5 UI code generator 5.13.2
+# Created by: PyQt5 UI code generator 5.15.2
#
-# WARNING! All changes made in this file will be lost!
+# WARNING: Any manual changes made to this file will be lost when pyuic5 is
+# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
diff --git a/actor/src/ui/setup_dialog_unmanaged_ui.py b/actor/src/ui/setup_dialog_unmanaged_ui.py
index 7f63525e..5ed834fd 100644
--- a/actor/src/ui/setup_dialog_unmanaged_ui.py
+++ b/actor/src/ui/setup_dialog_unmanaged_ui.py
@@ -2,9 +2,10 @@
# Form implementation generated from reading ui file 'setup-dialog-unmanaged.ui'
#
-# Created by: PyQt5 UI code generator 5.13.2
+# Created by: PyQt5 UI code generator 5.15.2
#
-# WARNING! All changes made in this file will be lost!
+# WARNING: Any manual changes made to this file will be lost when pyuic5 is
+# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
@@ -14,7 +15,7 @@ class Ui_UdsActorSetupDialog(object):
def setupUi(self, UdsActorSetupDialog):
UdsActorSetupDialog.setObjectName("UdsActorSetupDialog")
UdsActorSetupDialog.setWindowModality(QtCore.Qt.WindowModal)
- UdsActorSetupDialog.resize(595, 220)
+ UdsActorSetupDialog.resize(591, 243)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
@@ -34,12 +35,12 @@ class Ui_UdsActorSetupDialog(object):
UdsActorSetupDialog.setModal(True)
self.saveButton = QtWidgets.QPushButton(UdsActorSetupDialog)
self.saveButton.setEnabled(True)
- self.saveButton.setGeometry(QtCore.QRect(10, 180, 181, 23))
+ self.saveButton.setGeometry(QtCore.QRect(10, 210, 181, 23))
self.saveButton.setMinimumSize(QtCore.QSize(181, 0))
self.saveButton.setContextMenuPolicy(QtCore.Qt.DefaultContextMenu)
self.saveButton.setObjectName("saveButton")
self.closeButton = QtWidgets.QPushButton(UdsActorSetupDialog)
- self.closeButton.setGeometry(QtCore.QRect(410, 180, 171, 23))
+ self.closeButton.setGeometry(QtCore.QRect(410, 210, 171, 23))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
@@ -49,11 +50,11 @@ class Ui_UdsActorSetupDialog(object):
self.closeButton.setObjectName("closeButton")
self.testButton = QtWidgets.QPushButton(UdsActorSetupDialog)
self.testButton.setEnabled(False)
- self.testButton.setGeometry(QtCore.QRect(210, 180, 181, 23))
+ self.testButton.setGeometry(QtCore.QRect(210, 210, 181, 23))
self.testButton.setMinimumSize(QtCore.QSize(181, 0))
self.testButton.setObjectName("testButton")
self.layoutWidget = QtWidgets.QWidget(UdsActorSetupDialog)
- self.layoutWidget.setGeometry(QtCore.QRect(10, 10, 571, 161))
+ self.layoutWidget.setGeometry(QtCore.QRect(10, 10, 571, 228))
self.layoutWidget.setObjectName("layoutWidget")
self.formLayout = QtWidgets.QFormLayout(self.layoutWidget)
self.formLayout.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
@@ -84,7 +85,7 @@ class Ui_UdsActorSetupDialog(object):
self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.serviceToken)
self.label_loglevel = QtWidgets.QLabel(self.layoutWidget)
self.label_loglevel.setObjectName("label_loglevel")
- self.formLayout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.label_loglevel)
+ self.formLayout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.label_loglevel)
self.logLevelComboBox = QtWidgets.QComboBox(self.layoutWidget)
self.logLevelComboBox.setFrame(True)
self.logLevelComboBox.setObjectName("logLevelComboBox")
@@ -96,7 +97,13 @@ class Ui_UdsActorSetupDialog(object):
self.logLevelComboBox.setItemText(2, "ERROR")
self.logLevelComboBox.addItem("")
self.logLevelComboBox.setItemText(3, "FATAL")
- self.formLayout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.logLevelComboBox)
+ self.formLayout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.logLevelComboBox)
+ self.label_restrictNet = QtWidgets.QLabel(self.layoutWidget)
+ self.label_restrictNet.setObjectName("label_restrictNet")
+ self.formLayout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.label_restrictNet)
+ self.restrictNet = QtWidgets.QLineEdit(self.layoutWidget)
+ self.restrictNet.setObjectName("restrictNet")
+ self.formLayout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.restrictNet)
self.label_host.raise_()
self.host.raise_()
self.label_serviceToken.raise_()
@@ -105,6 +112,8 @@ class Ui_UdsActorSetupDialog(object):
self.label_security.raise_()
self.label_loglevel.raise_()
self.logLevelComboBox.raise_()
+ self.label_restrictNet.raise_()
+ self.restrictNet.raise_()
self.retranslateUi(UdsActorSetupDialog)
self.logLevelComboBox.setCurrentIndex(1)
@@ -113,6 +122,7 @@ class Ui_UdsActorSetupDialog(object):
self.saveButton.clicked.connect(UdsActorSetupDialog.saveConfig)
self.host.textChanged['QString'].connect(UdsActorSetupDialog.configChanged)
self.serviceToken.textChanged['QString'].connect(UdsActorSetupDialog.configChanged)
+ self.restrictNet.textChanged['QString'].connect(UdsActorSetupDialog.configChanged)
QtCore.QMetaObject.connectSlotsByName(UdsActorSetupDialog)
def retranslateUi(self, UdsActorSetupDialog):
@@ -139,4 +149,7 @@ class Ui_UdsActorSetupDialog(object):
self.serviceToken.setToolTip(_translate("UdsActorSetupDialog", "UDS user with administration rights (Will not be stored on template)"))
self.serviceToken.setWhatsThis(_translate("UdsActorSetupDialog", "Administrator user on UDS Server.
Note: This credential will not be stored on client. Will be used to obtain an unique token for this image.
"))
self.label_loglevel.setText(_translate("UdsActorSetupDialog", "Log Level"))
+ self.label_restrictNet.setText(_translate("UdsActorSetupDialog", "Restrict Net"))
+ self.restrictNet.setToolTip(_translate("UdsActorSetupDialog", "UDS user with administration rights (Will not be stored on template)"))
+ self.restrictNet.setWhatsThis(_translate("UdsActorSetupDialog", "Administrator user on UDS Server.
Note: This credential will not be stored on client. Will be used to obtain an unique token for this image.
"))
from ui import uds_rc
diff --git a/actor/src/ui/uds_rc.py b/actor/src/ui/uds_rc.py
index 26d1f8e7..e9a5d15e 100644
--- a/actor/src/ui/uds_rc.py
+++ b/actor/src/ui/uds_rc.py
@@ -2,7 +2,7 @@
# Resource object code
#
-# Created by: The Resource Compiler for PyQt5 (Qt v5.13.2)
+# Created by: The Resource Compiler for PyQt5 (Qt v5.15.2)
#
# WARNING! All changes made in this file will be lost!
diff --git a/client-py3/full/src/uds/tools.py b/client-py3/full/src/uds/tools.py
index d82baf66..b335e6da 100644
--- a/client-py3/full/src/uds/tools.py
+++ b/client-py3/full/src/uds/tools.py
@@ -234,8 +234,8 @@ def verifySignature(script: bytes, signature: bytes) -> bool:
)
try:
- public_key.verify(
- base64.b64decode(signature), script, padding.PKCS1v15(), hashes.SHA256()
+ public_key.verify( # type: ignore
+ base64.b64decode(signature), script, padding.PKCS1v15(), hashes.SHA256() # type: ignore
)
except Exception: # InvalidSignature
return False