Présentation du projet
Dangerzone est un outil open source conçu pour convertir des documents potentiellement dangereux (PDF, fichiers bureautiques, images) en PDF sécurisés. Son système de mise à jour intègre une stratégie de vérification asynchrone pour fournir les dernières correctifs de sécurité sans impacter l'expérience utilisaetur.
Conception architecturale
Le mécanisme repose sur une architecture modulaire avec composants principaux : un gestionnaire de préférences utilisateur, un contrôleur de fréquence, un client API et une interface de notification. Un modèle à états régit le cycle de vérification des mises à jour.
Détails d'implémentation des fonctionnalités
1. Gestion des préférences utilisateur
Le système adopte une approche progressive pour recueillir le consentement de l'utilisateur :
def verifier_autorisation_mise_a_jour(self) -> bool:
if self.parametres.get("autorisation_mise_a_jour") is not None:
return self.parametres["autorisation_mise_a_jour"]
if systeme_exploitation() == "Linux" and not environnement_dev():
self.parametres["autorisation_mise_a_jour"] = False
return False
if not self.horodatage_derniere_verification:
self.horodatage_derniere_verification = 0
self.sauvegarder_configuration()
return False
choix = solliciter_consentement_utilisateur()
self.parametres["autorisation_mise_a_jour"] = choix
return choix
2. Mécanisme de temporisation intelligent
Un intervalle de 12 heures entre les vérifications réduit la charge réseau :
INTERVALLE_VERIFICATION_SEC = 43200
def appliquer_temporisation(self) -> bool:
horodatage_courant = obtenir_temps_actuel()
dernier_check = self.parametres["horodatage_derniere_verification"]
if horodatage_courant < dernier_check + INTERVALLE_VERIFICATION_SEC:
logger.debug("Temporisation active")
return True
return False
3. Intégration avec l'API GitHub
Les informations de version sont récupérées via l'endpoint des releases GitHub :
| Point d'accès | Timeout | Traitement |
|---|---|---|
| https://api.github.com/repos/freedomofpress/dangerzone/releases/latest | 15 secondes | Analyse JSON et conversion Markdown |
def recuperer_derniere_version(self) -> BulletinMiseAJour:
try:
reponse = requetes.get(self.ADRESSE_API, timeout=self.DELAI_REQUETE)
if reponse.status_code != 200:
raise Exception(f"Erreur HTTP {reponse.status_code}")
donnees = reponse.json()
numero_version = donnees["tag_name"].replace("v", "")
journal_modifications = convertir_markdown(donnees["body"])
return BulletinMiseAJour(version=numero_version, changelog=journal_modifications)
except Exception as e:
raise Exception(f"Échec de la récupération : {e}")
4. Traitement asynchrone
L'utilisation de threads Qt assure une vérification non bloquante :
class ThreadVerification(QtCore.QThread):
signal_fin = QtCore.Signal(BulletinMiseAJour)
def run(self) -> None:
resultat = effectuer_verification()
self.signal_fin.emit(resultat)
Interface utilisateur
Indicateurs visuels dans le menu
| État | Icône | Signification |
|---|---|---|
| Mise à jour disponible | Point vert | Nouvelle version téléchargeable |
| Erreur de vérification | Point rouge | Échec de la procédure |
| État normal | Icône par défaut | Aucune mise à jour |
Dialogue de notification
def presenter_mise_a_jour(self) -> None:
version_dispo = self.parametres["derniere_version"]
details = self.parametres["journal_mise_a_jour"]
conteneur_details = WidgetDeroulable("Nouvelles fonctionnalités")
zone_affichage = QtWidgets.QTextBrowser()
zone_affichage.setHtml(details)
fenetre = BoiteDialogue(
self.app,
titre=f"Version {version_dispo} de Dangerzone",
corps=MESSAGE_NOTIFICATION,
element_central=conteneur_details,
bouton_valider="Compris",
sans_annulation=True
)
fenetre.afficher()
Gestion des erreurs
def traiter_resultat_verification(self, bulletin: BulletinMiseAJour) -> None:
if bulletin.est_erreur:
compte_erreurs = self.parametres["nb_erreurs_consecutives"] + 1
self.parametres["nb_erreurs_consecutives"] = compte_erreurs
if compte_erreurs < 3:
logger.debug(f"Erreur non signalée ({compte_erreurs})")
return
self.bouton_menu.changer_icone(ICONE_ERREUR)
self.afficher_alerte_erreur()
Sécurité et confidentialité
| Mesure | Implémentation | Objectif |
|---|---|---|
| Limitation de fréquence | Intervalle de 12 heures | Réduire l'empreinte réseau |
| Désactivation sur Linux | Comportement par défaut | Respect de la vie privée |
| Contrôle des timeouts | Expiration après 15 secondes | Éviter les blocages |
Le système respecte les principes de minimisation des données : aucune collecte d'informations personnelles, requêtes uniquement en lecture sur l'API publique.
Paramètres de configuration
| Clé | Type | Valeur par défaut | Description |
|---|---|---|---|
| autorisation_mise_a_jour | Booléen optionnel | Non défini | Préférence utilisateur pour les mises à jour |
| horodatage_derniere_verification | Entier | 0 | Timestamp de la dernière vérification |
| derniere_version | Chaîne | Version courante | Version mise en cache |
| journal_mise_a_jour | Chaîne | Vide | Journal des modifications en cache |
| nb_erreurs_consecutives | Entier | 0 | Compteur d'échecs consécutifs |
Recommandations
Pour les utilisateurs standards
- Activer les vérifications automatiques pour bénéficier des correctifs de sécurité
- Effectuer des vérifications manuelles régulières même si le système automatique est désactivé
- Prêter attention aux indicateurs d'erreur pour identifier les problèmes de connectivité
Pour les environnements sensibles
- Désactiver les mises à jour automatiques dans les réseaux isolés (air-gap)
- Personnaliser les sources de mise à jour pour les déploiements internes
- Surveiller les journaux pour tracer l'activité des vérifications
Pour les développeurs
- Tester le flux complet de vérification et la gestion des erreurs
- Envisager l'ajout de signatures cryptographiques pour valider les paquets
- Prévoir des mécanismes de restauration en cas d'échec de mise à jour