From 5dd4ef06bb2ed23bb86e37eb02f2453aa6584573 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustavo=20I=C3=B1iguez=20Goia?= Date: Fri, 3 Jan 2025 14:48:35 +0100 Subject: [PATCH] ui: allow to use multiple protobuffer versions Protobuffers compiled with protobuf < 3.20.0 are incompatible with protobuf >= 4.0.0: https://github.com/evilsocket/opensnitch/wiki/GUI-known-problems#gui-does-not-show-up This has been a source of problems for some users (#1214, #647), and in some distributions, previous protobuffer does no longer work due to incompatibility with the protobuf package version installed (OpenSuse Tumbleweed). So in order to solve this issue, we provide several protobuffers, for old and new protobuf versions: proto/ui_pb2* for protobuf >= 4.0.0 proto/pre3200/ui_pb2* for protobuf >= 3.6.0 and < 3.20.0 To avoid import errors, each protobuffer must be placed in its own directory, and the name of the protobuffer files must be named with the syntax _pb2.py/_pb2_grpc.py: ui_pb2.py and ui_pb2_grpc.py The default compiled protobuffer will be opensnitch/proto/ui_*.py instead of opensnitch/ui_*.py --- proto/Makefile | 6 +++--- ui/MANIFEST.in | 1 + ui/Makefile | 2 +- ui/bin/opensnitch-ui | 6 ++++-- ui/opensnitch/dialogs/firewall.py | 3 ++- ui/opensnitch/dialogs/firewall_rule.py | 3 ++- ui/opensnitch/dialogs/preferences.py | 4 +++- ui/opensnitch/dialogs/processdetails.py | 4 +++- ui/opensnitch/dialogs/prompt/__init__.py | 5 +++-- ui/opensnitch/dialogs/ruleseditor.py | 4 +++- ui/opensnitch/dialogs/stats.py | 4 +++- ui/opensnitch/firewall/__init__.py | 4 +++- ui/opensnitch/firewall/chains.py | 4 +++- ui/opensnitch/firewall/exprs.py | 4 +++- ui/opensnitch/firewall/rules.py | 4 +++- ui/opensnitch/nodes.py | 4 +++- ui/opensnitch/rules.py | 4 +++- ui/opensnitch/service.py | 4 ++-- utils/packaging/ui/deb/debian/rules | 12 +----------- utils/packaging/ui/rpm/opensnitch-ui.spec | 2 +- 20 files changed, 50 insertions(+), 34 deletions(-) diff --git a/proto/Makefile b/proto/Makefile index 2d4c3d6dcf..9744be397e 100644 --- a/proto/Makefile +++ b/proto/Makefile @@ -4,9 +4,9 @@ all: ../daemon/ui/protocol/ui.pb.go ../ui/opensnitch/ui_pb2.py protoc -I. ui.proto --go_out=../daemon/ui/protocol/ --go-grpc_out=../daemon/ui/protocol/ --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative ../ui/opensnitch/ui_pb2.py: ui.proto - python3 -m grpc_tools.protoc -I. --python_out=../ui/opensnitch/ --grpc_python_out=../ui/opensnitch/ ui.proto + python3 -m grpc_tools.protoc -I. --python_out=../ui/opensnitch/proto/ --grpc_python_out=../ui/opensnitch/proto/ ui.proto clean: @rm -rf ../daemon/ui/protocol/ui.pb.go - @rm -rf ../ui/opensnitch/ui_pb2.py - @rm -rf ../ui/opensnitch/ui_pb2_grpc.py + @rm -rf ../ui/opensnitch/proto/ui_pb2.py + @rm -rf ../ui/opensnitch/proto/ui_pb2_grpc.py diff --git a/ui/MANIFEST.in b/ui/MANIFEST.in index 4d02baf90a..d21350df52 100644 --- a/ui/MANIFEST.in +++ b/ui/MANIFEST.in @@ -1,3 +1,4 @@ +recursive-include opensnitch/proto * recursive-include opensnitch/res * recursive-include opensnitch/i18n *.qm recursive-include opensnitch/database/migrations *.sql diff --git a/ui/Makefile b/ui/Makefile index 0976022bab..51ea1758e8 100644 --- a/ui/Makefile +++ b/ui/Makefile @@ -5,7 +5,7 @@ install: opensnitch/resources_rc.py: translations deps @pyrcc5 -o opensnitch/resources_rc.py opensnitch/res/resources.qrc - sed -i 's/^import ui_pb2/from . import ui_pb2/' opensnitch/ui_pb2* + @find opensnitch/proto/ -name 'ui_pb2_grpc.py' -exec sed -i 's/^import ui_pb2/from . import ui_pb2/' {} \; translations: @cd i18n ; make diff --git a/ui/bin/opensnitch-ui b/ui/bin/opensnitch-ui index 5471617c11..43a7046791 100755 --- a/ui/bin/opensnitch-ui +++ b/ui/bin/opensnitch-ui @@ -42,9 +42,11 @@ from opensnitch.service import UIService from opensnitch.config import Config from opensnitch.utils import Themes, Utils, Versions, Message from opensnitch.utils.xdg import xdg_opensnitch_dir, xdg_current_session -from opensnitch.ui_pb2_grpc import add_UIServicer_to_server from opensnitch import auth +import opensnitch.proto as proto +ui_pb2, ui_pb2_grpc = proto.import_() + app_id = os.path.join(xdg_opensnitch_dir, "io.github.evilsocket.opensnitch") def on_exit(): @@ -202,7 +204,7 @@ Examples: ('grpc.max_receive_message_length', maxmsglen), )) - add_UIServicer_to_server(service, server) + ui_pb2_grpc.add_UIServicer_to_server(service, server) auth_type = auth.Simple if args.socket_auth != None: diff --git a/ui/opensnitch/dialogs/firewall.py b/ui/opensnitch/dialogs/firewall.py index b8fdb90af5..fd282742ad 100644 --- a/ui/opensnitch/dialogs/firewall.py +++ b/ui/opensnitch/dialogs/firewall.py @@ -11,10 +11,11 @@ from opensnitch.config import Config from opensnitch.nodes import Nodes from opensnitch.dialogs.firewall_rule import FwRuleDialog -from opensnitch import ui_pb2 import opensnitch.firewall as Fw import opensnitch.firewall.profiles as FwProfiles +import opensnitch.proto as proto +ui_pb2, ui_pb2_grpc = proto.import_() DIALOG_UI_PATH = "%s/../res/firewall.ui" % os.path.dirname(sys.modules[__name__].__file__) class FirewallDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]): diff --git a/ui/opensnitch/dialogs/firewall_rule.py b/ui/opensnitch/dialogs/firewall_rule.py index 411582b0dd..9e8eca0655 100644 --- a/ui/opensnitch/dialogs/firewall_rule.py +++ b/ui/opensnitch/dialogs/firewall_rule.py @@ -9,10 +9,11 @@ from opensnitch.config import Config from opensnitch.nodes import Nodes from opensnitch.utils import NetworkServices, NetworkInterfaces, QuickHelp, Icons, Utils -from opensnitch import ui_pb2 import opensnitch.firewall as Fw from opensnitch.firewall.utils import Utils as FwUtils +import opensnitch.proto as proto +ui_pb2, ui_pb2_grpc = proto.import_() DIALOG_UI_PATH = "%s/../res/firewall_rule.ui" % os.path.dirname(sys.modules[__name__].__file__) class FwRuleDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]): diff --git a/ui/opensnitch/dialogs/preferences.py b/ui/opensnitch/dialogs/preferences.py index 3f284000a8..00ca7788e3 100644 --- a/ui/opensnitch/dialogs/preferences.py +++ b/ui/opensnitch/dialogs/preferences.py @@ -15,7 +15,9 @@ from opensnitch.notifications import DesktopNotifications from opensnitch.rules import DefaultRulesPath -from opensnitch import ui_pb2, auth +from opensnitch import auth +import opensnitch.proto as proto +ui_pb2, ui_pb2_grpc = proto.import_() DIALOG_UI_PATH = "%s/../res/preferences.ui" % os.path.dirname(sys.modules[__name__].__file__) class PreferencesDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]): diff --git a/ui/opensnitch/dialogs/processdetails.py b/ui/opensnitch/dialogs/processdetails.py index 8e07958988..3fb621975b 100644 --- a/ui/opensnitch/dialogs/processdetails.py +++ b/ui/opensnitch/dialogs/processdetails.py @@ -5,7 +5,9 @@ from PyQt5 import QtCore, QtGui, uic, QtWidgets -from opensnitch import ui_pb2 +import opensnitch.proto as proto +ui_pb2, ui_pb2_grpc = proto.import_() + from opensnitch.nodes import Nodes from opensnitch.desktop_parser import LinuxDesktopParser from opensnitch.utils import Message, Icons diff --git a/ui/opensnitch/dialogs/prompt/__init__.py b/ui/opensnitch/dialogs/prompt/__init__.py index 0679f4a720..ff17effc72 100644 --- a/ui/opensnitch/dialogs/prompt/__init__.py +++ b/ui/opensnitch/dialogs/prompt/__init__.py @@ -22,8 +22,9 @@ from opensnitch.rules import Rules, Rule from opensnitch.nodes import Nodes -from opensnitch import ui_pb2 from opensnitch.dialogs.prompt import _utils, _constants, _checksums, _details +import opensnitch.proto as proto +ui_pb2, ui_pb2_grpc = proto.import_() from network_aliases import NetworkAliases @@ -589,7 +590,7 @@ def _send_rule(self): self._rule.operator.type, self._rule.operator.operand, self._rule.operator.data = _utils.get_combo_operator( self.whatCombo.itemData(what_idx), self.whatCombo.currentText(), - self._con) + self._con) if self._rule.operator.data == "": print("popups: Invalid rule, discarding: ", self._rule) self._rule = None diff --git a/ui/opensnitch/dialogs/ruleseditor.py b/ui/opensnitch/dialogs/ruleseditor.py index 8ad7daf053..03e2b9a0c7 100644 --- a/ui/opensnitch/dialogs/ruleseditor.py +++ b/ui/opensnitch/dialogs/ruleseditor.py @@ -7,10 +7,12 @@ import sys import os import pwd -from opensnitch import ui_pb2 import time import ipaddress +import opensnitch.proto as proto +ui_pb2, ui_pb2_grpc = proto.import_() + from opensnitch.config import Config from opensnitch.nodes import Nodes from opensnitch.database import Database diff --git a/ui/opensnitch/dialogs/stats.py b/ui/opensnitch/dialogs/stats.py index 5dbc535956..939482eea8 100644 --- a/ui/opensnitch/dialogs/stats.py +++ b/ui/opensnitch/dialogs/stats.py @@ -9,7 +9,6 @@ from PyQt5 import QtCore, QtGui, uic, QtWidgets from PyQt5.QtCore import QCoreApplication as QC -from opensnitch import ui_pb2 from opensnitch.config import Config from opensnitch.version import version from opensnitch.nodes import Nodes @@ -32,6 +31,9 @@ from opensnitch.plugins import PluginBase from opensnitch.rules import Rule, Rules +import opensnitch.proto as proto +ui_pb2, ui_pb2_grpc = proto.import_() + DIALOG_UI_PATH = "%s/../res/stats.ui" % os.path.dirname(sys.modules[__name__].__file__) class StatsDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]): diff --git a/ui/opensnitch/firewall/__init__.py b/ui/opensnitch/firewall/__init__.py index cd5ec54e66..a41057b7fd 100644 --- a/ui/opensnitch/firewall/__init__.py +++ b/ui/opensnitch/firewall/__init__.py @@ -1,6 +1,8 @@ from PyQt5.QtCore import QObject, QCoreApplication as QC from google.protobuf import json_format -from opensnitch import ui_pb2 + +import opensnitch.proto as proto +ui_pb2, ui_pb2_grpc = proto.import_() from opensnitch.nodes import Nodes from .enums import * diff --git a/ui/opensnitch/firewall/chains.py b/ui/opensnitch/firewall/chains.py index 125fb416de..227b163437 100644 --- a/ui/opensnitch/firewall/chains.py +++ b/ui/opensnitch/firewall/chains.py @@ -1,6 +1,8 @@ -from opensnitch import ui_pb2 from .enums import * +import opensnitch.proto as proto +ui_pb2, ui_pb2_grpc = proto.import_() + class Chains(): def __init__(self, nodes): diff --git a/ui/opensnitch/firewall/exprs.py b/ui/opensnitch/firewall/exprs.py index 5fa1267d7e..4f7f630a57 100644 --- a/ui/opensnitch/firewall/exprs.py +++ b/ui/opensnitch/firewall/exprs.py @@ -1,7 +1,9 @@ -from opensnitch import ui_pb2 from .enums import * +import opensnitch.proto as proto +ui_pb2, ui_pb2_grpc = proto.import_() + class Expr(): """ Expr returns a new nftables expression that defines a match or an action: diff --git a/ui/opensnitch/firewall/rules.py b/ui/opensnitch/firewall/rules.py index 201641faa0..dc5f3395cc 100644 --- a/ui/opensnitch/firewall/rules.py +++ b/ui/opensnitch/firewall/rules.py @@ -3,10 +3,12 @@ from google.protobuf.json_format import MessageToJson import uuid -from opensnitch import ui_pb2 from .enums import Operator from .exprs import ExprLog +import opensnitch.proto as proto +ui_pb2, ui_pb2_grpc = proto.import_() + class Rules(QObject): rulesUpdated = pyqtSignal() diff --git a/ui/opensnitch/nodes.py b/ui/opensnitch/nodes.py index f3d191cf57..4370b051e3 100644 --- a/ui/opensnitch/nodes.py +++ b/ui/opensnitch/nodes.py @@ -4,12 +4,14 @@ import time import json -from opensnitch import ui_pb2 from opensnitch.database import Database from opensnitch.config import Config from opensnitch.utils import NetworkInterfaces from opensnitch.rules import Rules +import opensnitch.proto as proto +ui_pb2, ui_pb2_grpc = proto.import_() + class Nodes(QObject): __instance = None nodesUpdated = pyqtSignal(int) # total diff --git a/ui/opensnitch/rules.py b/ui/opensnitch/rules.py index 07193b08fb..ca487d48ad 100644 --- a/ui/opensnitch/rules.py +++ b/ui/opensnitch/rules.py @@ -1,10 +1,12 @@ from PyQt5.QtCore import QObject, pyqtSignal -from opensnitch import ui_pb2 from opensnitch.database import Database from opensnitch.database.enums import RuleFields from opensnitch.config import Config +import opensnitch.proto as proto +ui_pb2, ui_pb2_grpc = proto.import_() + import os import json from slugify import slugify diff --git a/ui/opensnitch/service.py b/ui/opensnitch/service.py index 163b09f14e..ac15478d93 100644 --- a/ui/opensnitch/service.py +++ b/ui/opensnitch/service.py @@ -12,8 +12,8 @@ path = os.path.abspath(os.path.dirname(__file__)) sys.path.append(path) -from opensnitch import ui_pb2 -from opensnitch import ui_pb2_grpc +import opensnitch.proto as proto +ui_pb2, ui_pb2_grpc = proto.import_() from opensnitch.dialogs.prompt import PromptDialog from opensnitch.dialogs.stats import StatsDialog diff --git a/utils/packaging/ui/deb/debian/rules b/utils/packaging/ui/deb/debian/rules index 6f0a752469..d7f75bfc27 100755 --- a/utils/packaging/ui/deb/debian/rules +++ b/utils/packaging/ui/deb/debian/rules @@ -13,25 +13,15 @@ override_dh_auto_clean: python3 setup.py clean -a find . -name \*.pyc -exec rm {} \; - - override_dh_auto_build: python3 setup.py build --force - - override_dh_auto_install: cd i18n; make cp -r i18n/locales/ opensnitch/i18n/ pyrcc5 -o opensnitch/resources_rc.py opensnitch/res/resources.qrc - sed -i 's/^import ui_pb2/from . import ui_pb2/' opensnitch/ui_pb2* + find opensnitch/proto/ -name 'ui_pb2_grpc.py' -exec sed -i 's/^import ui_pb2/from . import ui_pb2/' {} \; python3 setup.py install --force --root=debian/python3-opensnitch-ui --no-compile -O0 --install-layout=deb - - override_dh_python2: dh_python2 --no-guessing-versions - - - - diff --git a/utils/packaging/ui/rpm/opensnitch-ui.spec b/utils/packaging/ui/rpm/opensnitch-ui.spec index 5f34d6119d..5d99f6c0aa 100644 --- a/utils/packaging/ui/rpm/opensnitch-ui.spec +++ b/utils/packaging/ui/rpm/opensnitch-ui.spec @@ -78,7 +78,7 @@ fi cd i18n; make; cd .. cp -r i18n/locales/ opensnitch/i18n pyrcc5 -o opensnitch/resources_rc.py opensnitch/res/resources.qrc -sed -i 's/^import ui_pb2/from . import ui_pb2/' opensnitch/ui_pb2* +find opensnitch/proto/ -name 'ui_pb2_grpc.py' -exec sed -i 's/^import ui_pb2/from . import ui_pb2/' {} \; python3 setup.py build %install