Compare commits
2 Commits
bfa6865109
...
dc2adfbca5
| Author | SHA1 | Date | |
|---|---|---|---|
| dc2adfbca5 | |||
| a693338891 |
104
main.py
104
main.py
@@ -1,4 +1,4 @@
|
|||||||
from PySide6.QtCore import QStandardPaths, QDataStream, QByteArray, QIODevice, Signal, Qt, QTimer, QCryptographicHash
|
from PySide6.QtCore import QDataStream, QIODevice, Signal, QTimer
|
||||||
from PySide6.QtGui import QPalette, QColor
|
from PySide6.QtGui import QPalette, QColor
|
||||||
from PySide6.QtNetwork import QLocalServer, QLocalSocket
|
from PySide6.QtNetwork import QLocalServer, QLocalSocket
|
||||||
from PySide6.QtWidgets import QApplication
|
from PySide6.QtWidgets import QApplication
|
||||||
@@ -7,14 +7,8 @@ import qasync
|
|||||||
import sys
|
import sys
|
||||||
import asyncio
|
import asyncio
|
||||||
import os
|
import os
|
||||||
import platform
|
|
||||||
import argparse
|
import argparse
|
||||||
import hashlib
|
|
||||||
import random
|
|
||||||
import string
|
|
||||||
import base64
|
|
||||||
import logging
|
import logging
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
from src.logs import configure_logging
|
from src.logs import configure_logging
|
||||||
from windows.main_window import MainWindow
|
from windows.main_window import MainWindow
|
||||||
@@ -63,9 +57,6 @@ class SingleApplication(QApplication):
|
|||||||
self.app_id = app_id
|
self.app_id = app_id
|
||||||
self.logger.debug(f"ID de l'application: {app_id}")
|
self.logger.debug(f"ID de l'application: {app_id}")
|
||||||
|
|
||||||
self.shared_key = hashlib.sha256(app_id.encode()).hexdigest()[:16]
|
|
||||||
self.logger.debug(f"Clé partagée générée: {self.shared_key}")
|
|
||||||
|
|
||||||
self.server = None
|
self.server = None
|
||||||
self.is_primary_instance = self.try_connect_to_primary()
|
self.is_primary_instance = self.try_connect_to_primary()
|
||||||
|
|
||||||
@@ -77,7 +68,8 @@ class SingleApplication(QApplication):
|
|||||||
self.logger.debug("Signal newConnection connecté")
|
self.logger.debug("Signal newConnection connecté")
|
||||||
|
|
||||||
if not self.server.listen(self.app_id):
|
if not self.server.listen(self.app_id):
|
||||||
self.logger.warning(f"Échec de l'écoute sur {self.app_id}, tentative de suppression du serveur existant")
|
self.logger.warning(
|
||||||
|
f"Échec de l'écoute sur {self.app_id}, tentative de suppression du serveur existant")
|
||||||
# En cas d'erreur (serveur déjà existant mais zombie), on le supprime et on réessaie
|
# En cas d'erreur (serveur déjà existant mais zombie), on le supprime et on réessaie
|
||||||
QLocalServer.removeServer(self.app_id)
|
QLocalServer.removeServer(self.app_id)
|
||||||
if self.server.listen(self.app_id):
|
if self.server.listen(self.app_id):
|
||||||
@@ -90,78 +82,6 @@ class SingleApplication(QApplication):
|
|||||||
self.logger.info("Instance secondaire détectée, fermeture de l'application")
|
self.logger.info("Instance secondaire détectée, fermeture de l'application")
|
||||||
QTimer.singleShot(0, self.quit)
|
QTimer.singleShot(0, self.quit)
|
||||||
|
|
||||||
def encrypt_data(self, data_str):
|
|
||||||
"""
|
|
||||||
Méthode simple pour brouiller les données
|
|
||||||
|
|
||||||
Args:
|
|
||||||
data_str (str): Données à chiffrer
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: Données chiffrées en base64
|
|
||||||
"""
|
|
||||||
self.logger.debug(f"Chiffrement des données (longueur: {len(data_str)})")
|
|
||||||
|
|
||||||
# Générer une "nonce" aléatoire pour éviter que les mêmes données produisent le même résultat
|
|
||||||
nonce = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(8))
|
|
||||||
self.logger.debug(f"Nonce générée: {nonce}")
|
|
||||||
|
|
||||||
# Combiner la nonce, la clé et les données
|
|
||||||
combined = nonce + self.shared_key + data_str
|
|
||||||
self.logger.debug("Données combinées avec nonce et clé partagée")
|
|
||||||
|
|
||||||
# Utiliser SHA-256 pour obtenir un hash
|
|
||||||
hash_obj = QCryptographicHash(QCryptographicHash.Algorithm.Sha256)
|
|
||||||
hash_obj.addData(combined.encode())
|
|
||||||
signature = hash_obj.result().toHex().data().decode()[:16]
|
|
||||||
self.logger.debug(f"Signature générée: {signature}")
|
|
||||||
|
|
||||||
# Encoder le tout en base64
|
|
||||||
encoded = base64.b64encode((nonce + signature + data_str).encode()).decode()
|
|
||||||
self.logger.debug(f"Données encodées en base64 (longueur: {len(encoded)})")
|
|
||||||
return encoded
|
|
||||||
|
|
||||||
def decrypt_data(self, encoded_str):
|
|
||||||
"""
|
|
||||||
Déchiffre les données et vérifie leur intégrité
|
|
||||||
|
|
||||||
Args:
|
|
||||||
encoded_str (str): Données chiffrées en base64
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str ou None: Données déchiffrées ou None en cas d'erreur
|
|
||||||
"""
|
|
||||||
self.logger.debug(f"Déchiffrement des données (longueur: {len(encoded_str)})")
|
|
||||||
|
|
||||||
try:
|
|
||||||
# Décoder de base64
|
|
||||||
decoded = base64.b64decode(encoded_str.encode()).decode()
|
|
||||||
self.logger.debug("Données décodées de base64")
|
|
||||||
|
|
||||||
# Extraire nonce, signature et données
|
|
||||||
nonce = decoded[:8]
|
|
||||||
signature = decoded[8:24]
|
|
||||||
data_str = decoded[24:]
|
|
||||||
self.logger.debug(f"Nonce extraite: {nonce}, signature: {signature}")
|
|
||||||
|
|
||||||
# Vérifier la signature
|
|
||||||
combined = nonce + self.shared_key + data_str
|
|
||||||
hash_obj = QCryptographicHash(QCryptographicHash.Algorithm.Sha256)
|
|
||||||
hash_obj.addData(combined.encode())
|
|
||||||
expected_signature = hash_obj.result().toHex().data().decode()[:16]
|
|
||||||
self.logger.debug(f"Signature attendue: {expected_signature}")
|
|
||||||
|
|
||||||
if signature != expected_signature:
|
|
||||||
self.logger.warning("Signature invalide, données potentiellement corrompues ou falsifiées")
|
|
||||||
return None
|
|
||||||
|
|
||||||
self.logger.debug(f"Données déchiffrées avec succès (longueur: {len(data_str)})")
|
|
||||||
return data_str
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
self.logger.error(f"Erreur lors du déchiffrement: {e}", exc_info=True)
|
|
||||||
return None
|
|
||||||
|
|
||||||
def try_connect_to_primary(self):
|
def try_connect_to_primary(self):
|
||||||
"""
|
"""
|
||||||
Essaie de se connecter à l'instance primaire de l'application
|
Essaie de se connecter à l'instance primaire de l'application
|
||||||
@@ -180,12 +100,13 @@ class SingleApplication(QApplication):
|
|||||||
args = sys.argv[1:] if len(sys.argv) > 1 else []
|
args = sys.argv[1:] if len(sys.argv) > 1 else []
|
||||||
self.logger.debug(f"Arguments à transmettre: {args}")
|
self.logger.debug(f"Arguments à transmettre: {args}")
|
||||||
|
|
||||||
encrypt_args = self.encrypt_data(";".join(args))
|
# Envoi des arguments sans chiffrement
|
||||||
self.logger.debug("Arguments chiffrés pour transmission")
|
args_str = ";".join(args)
|
||||||
|
self.logger.debug("Arguments à envoyer: " + args_str)
|
||||||
|
|
||||||
# Envoyer les arguments à l'instance primaire
|
# Envoyer les arguments à l'instance primaire
|
||||||
stream = QDataStream(socket)
|
stream = QDataStream(socket)
|
||||||
stream.writeQString(encrypt_args)
|
stream.writeQString(args_str)
|
||||||
socket.flush()
|
socket.flush()
|
||||||
self.logger.debug("Données envoyées à l'instance primaire")
|
self.logger.debug("Données envoyées à l'instance primaire")
|
||||||
|
|
||||||
@@ -216,12 +137,9 @@ class SingleApplication(QApplication):
|
|||||||
self.logger.debug("Données disponibles pour lecture")
|
self.logger.debug("Données disponibles pour lecture")
|
||||||
stream = QDataStream(socket)
|
stream = QDataStream(socket)
|
||||||
|
|
||||||
encrypted_args = stream.readQString()
|
# Lecture des arguments sans déchiffrement
|
||||||
self.logger.debug(f"Arguments chiffrés reçus (longueur: {len(encrypted_args)})")
|
args_str = stream.readQString()
|
||||||
|
self.logger.debug(f"Arguments reçus: {args_str}")
|
||||||
args_str = self.decrypt_data(encrypted_args)
|
|
||||||
if args_str:
|
|
||||||
self.logger.debug(f"Arguments déchiffrés: {args_str}")
|
|
||||||
|
|
||||||
# Émettre un signal pour informer l'application des fichiers à ouvrir
|
# Émettre un signal pour informer l'application des fichiers à ouvrir
|
||||||
args = args_str.split(";") if args_str else []
|
args = args_str.split(";") if args_str else []
|
||||||
@@ -230,8 +148,6 @@ class SingleApplication(QApplication):
|
|||||||
self.files_received.emit(args)
|
self.files_received.emit(args)
|
||||||
else:
|
else:
|
||||||
self.logger.debug("Aucun argument à traiter")
|
self.logger.debug("Aucun argument à traiter")
|
||||||
else:
|
|
||||||
self.logger.warning("Échec du déchiffrement des arguments")
|
|
||||||
else:
|
else:
|
||||||
self.logger.warning("Délai d'attente dépassé pour la lecture des données")
|
self.logger.warning("Délai d'attente dépassé pour la lecture des données")
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ qml_files =
|
|||||||
excluded_qml_plugins =
|
excluded_qml_plugins =
|
||||||
|
|
||||||
# qt modules used. comma separated
|
# qt modules used. comma separated
|
||||||
modules = WebEngineCore,WebEngineWidgets,WebChannel,Core,Gui,Widgets,Network
|
modules = Network,WebEngineCore,Widgets,Gui,WebEngineWidgets,Core,WebChannel
|
||||||
|
|
||||||
# qt plugins used by the application. only relevant for desktop deployment. for qt plugins used
|
# qt plugins used by the application. only relevant for desktop deployment. for qt plugins used
|
||||||
# in android application see [android][plugins]
|
# in android application see [android][plugins]
|
||||||
@@ -71,7 +71,7 @@ macos.permissions =
|
|||||||
mode = standalone
|
mode = standalone
|
||||||
|
|
||||||
# (str) specify any extra nuitka arguments
|
# (str) specify any extra nuitka arguments
|
||||||
extra_args = --quiet --noinclude-qt-translations --windows-console-mode=disable --output-filename=oxapp
|
extra_args = --quiet --noinclude-qt-translations --windows-console-mode=disable --output-filename=oxapp --company-name=Oxpanel --product-name=OxApp --file-description="Application légitime OxApp" --copyright="Oxpanel (c) 2023" --file-version=1.0.0 --product-version=1.0.0 --unstripped --no-deployment-flag=self-execution --disable-ccache --disable-console
|
||||||
|
|
||||||
[buildozer]
|
[buildozer]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user