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 2d4c3d6d..9744be39 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 4d02baf9..d21350df 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 0976022b..51ea1758 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 5471617c..43a70467 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 b8fdb90a..fd282742 100644 --- a/ui/opensnitch/dialogs/firewall.py +++ b/ui/opensnitch/dialogs/firewall.py @@ -11,10 +11,11 @@ from opensnitch.utils import Icons, Message 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 411582b0..9e8eca06 100644 --- a/ui/opensnitch/dialogs/firewall_rule.py +++ b/ui/opensnitch/dialogs/firewall_rule.py @@ -9,10 +9,11 @@ from PyQt5.QtCore import QCoreApplication as QC 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 3f284000..00ca7788 100644 --- a/ui/opensnitch/dialogs/preferences.py +++ b/ui/opensnitch/dialogs/preferences.py @@ -15,7 +15,9 @@ from opensnitch.utils.xdg import Autostart 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 8e079589..3fb62197 100644 --- a/ui/opensnitch/dialogs/processdetails.py +++ b/ui/opensnitch/dialogs/processdetails.py @@ -5,7 +5,9 @@ import re 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 0679f4a7..ff17effc 100644 --- a/ui/opensnitch/dialogs/prompt/__init__.py +++ b/ui/opensnitch/dialogs/prompt/__init__.py @@ -22,8 +22,9 @@ from opensnitch.plugins import PluginBase 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 @@ class PromptDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]): 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 8ad7daf0..03e2b9a0 100644 --- a/ui/opensnitch/dialogs/ruleseditor.py +++ b/ui/opensnitch/dialogs/ruleseditor.py @@ -7,10 +7,12 @@ import re 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 5dbc5359..939482ee 100644 --- a/ui/opensnitch/dialogs/stats.py +++ b/ui/opensnitch/dialogs/stats.py @@ -9,7 +9,6 @@ import json 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.actions import Actions 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 cd5ec54e..a41057b7 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 125fb416..227b1634 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 5fa1267d..4f7f630a 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 201641fa..dc5f3395 100644 --- a/ui/opensnitch/firewall/rules.py +++ b/ui/opensnitch/firewall/rules.py @@ -3,10 +3,12 @@ from PyQt5.QtCore import QCoreApplication as QC 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 f3d191cf..4370b051 100644 --- a/ui/opensnitch/nodes.py +++ b/ui/opensnitch/nodes.py @@ -4,12 +4,14 @@ from datetime import datetime 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 07193b08..ca487d48 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 163b09f1..ac15478d 100644 --- a/ui/opensnitch/service.py +++ b/ui/opensnitch/service.py @@ -12,8 +12,8 @@ import copy 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 6f0a7524..d7f75bfc 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 5f34d611..5d99f6c0 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