7582450454
Exe d'essai qui saute l'ecran, licence retiree : toasts « Not found », impossible d'entrer. Le 404 est le generique d'une route inexistante, donc aucun indice qu'une verification de licence existe. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
247 lines
11 KiB
Markdown
247 lines
11 KiB
Markdown
# Système de licences — scénario d'essai
|
|
|
|
Écrit le **2026-09-05**, après la séance qui a posé la vérification hors ligne,
|
|
le liage au poste et l'écran d'activation.
|
|
|
|
Ce plan ne cherche pas à montrer que ça marche : **il cherche les endroits où ça
|
|
casserait sans prévenir**. Un système de licences échoue de deux façons
|
|
opposées, et les deux coûtent cher — refuser un client qui a payé, ou ouvrir à
|
|
quelqu'un qui n'a rien. Chaque essai ci-dessous vise l'une des deux.
|
|
|
|
Ce que la séance a déjà appris, et qui vaut d'être gardé en tête : **l'empreinte
|
|
du poste dépendait de l'ordre de démarrage.** Selon que WMI répondait ou non,
|
|
la même machine se présentait sous deux identités et refusait sa propre licence.
|
|
Rien dans une utilisation normale ne l'aurait montré. D'où la série D.
|
|
|
|
---
|
|
|
|
## Préparation
|
|
|
|
**L'outil de remise à zéro** : pose un fichier `config.txt` à côté de l'exe
|
|
(n'importe quel contenu, même vide). Un bouton rouge **Deactivate (debug)**
|
|
apparaît alors au bas de *Settings → Licence* : il efface la licence rangée et
|
|
rien d'autre. Sans `config.txt` le bouton n'apparaît pas, et la commande
|
|
sous-jacente est de toute façon inerte — un exe livré ne peut pas être
|
|
désactivé par ce chemin.
|
|
|
|
Ne supprime `%LOCALAPPDATA%\PMServer\prefs.bin` qu'en dernier recours : ça
|
|
désactive aussi, mais emporte le mode de déverrouillage, le nom retenu et les
|
|
réglages de sync.
|
|
|
|
**Ce qu'il faut sous la main** :
|
|
|
|
- ta licence valable, liée à ce poste ;
|
|
- l'Installation ID de ce poste (Settings → Licence, ou l'écran d'activation) ;
|
|
- `tools/licence.ps1` et la clé privée.
|
|
|
|
**Ordre** : `A → B → C → D → E`. La série A établit l'état de référence ; les
|
|
suivantes le cassent volontairement.
|
|
|
|
---
|
|
|
|
## A. Le chemin normal
|
|
|
|
1. Coffre déjà activé, lancer l'application.
|
|
**À voir** : l'écran d'activation **n'apparaît pas**. On tombe directement
|
|
sur l'écran de connexion.
|
|
2. Settings → Licence.
|
|
**À voir** : *Licensed to*, *Email*, *Issued* et *Installation ID* remplis.
|
|
Le nom affiché est celui que tu as tapé à l'émission — il vient de la charge
|
|
utile signée, pas d'un réglage local.
|
|
3. Fermer, relancer.
|
|
**À voir** : toujours pas d'écran d'activation. C'est ce qui prouve que la
|
|
licence est rangée et relue, pas seulement acceptée une fois.
|
|
|
|
---
|
|
|
|
## B. Ce qui doit être refusé
|
|
|
|
Chaque essai part de l'écran d'activation (licence effacée).
|
|
|
|
1. **Chaîne quelconque** : taper `nimportequoi`.
|
|
**À voir** : *This licence key is not valid*, **en rouge**. L'écran reste.
|
|
2. **Licence tronquée** : coller ta licence valable en retirant les dix derniers
|
|
caractères.
|
|
**À voir** : même refus. La signature ne tolère pas un octet.
|
|
3. **Charge utile trafiquée** : prendre ta licence, changer **un seul caractère
|
|
dans la partie avant le point** (le nom, l'adresse), coller.
|
|
**À voir** : même refus. C'est l'essai qui prouve que le contenu affiché dans
|
|
Settings ne peut pas être maquillé.
|
|
4. **Licence d'un autre poste** :
|
|
```
|
|
tools\licence.ps1 -For "x@y.z" -Name "Autre" -Machine "AAAA-BBBB-CCCC-DDDD"
|
|
```
|
|
coller le résultat.
|
|
**À voir** : refus. **C'est le cœur du liage** — une licence parfaitement
|
|
signée, mais pas pour cette machine.
|
|
5. **Licence d'une autre paire de clés** :
|
|
```
|
|
tools\licence.ps1 -Init -KeyFile "%TEMP%\faux.key"
|
|
tools\licence.ps1 -For "x@y.z" -Name "Faux" -Machine "<TON ID>" -KeyFile "%TEMP%\faux.key"
|
|
```
|
|
coller le résultat.
|
|
**À voir** : refus. **C'est le cœur de la signature** — la bonne machine, la
|
|
bonne forme, mais pas ta clé. Si cet essai passait, n'importe qui pourrait
|
|
fabriquer des licences.
|
|
Puis supprimer `%TEMP%\faux.key`.
|
|
6. **Ta vraie licence**, pour finir.
|
|
**À voir** : l'écran disparaît, on passe à la connexion.
|
|
|
|
---
|
|
|
|
## C. Ce qui ne doit PAS être refusé
|
|
|
|
Le risque symétrique, et le plus coûteux commercialement.
|
|
|
|
1. Coller ta licence **avec des espaces avant et après** (une sélection à la
|
|
souris en attrape presque toujours).
|
|
**À voir** : acceptée. Le code fait `Trim`.
|
|
2. Coller ta licence **avec un retour à la ligne** collé au bout.
|
|
**À voir** : acceptée.
|
|
3. Après activation, **redémarrer la machine** (pas seulement l'application).
|
|
**À voir** : toujours activée. Le port du serveur change à chaque
|
|
lancement — si la licence avait vécu dans `localStorage`, elle serait
|
|
perdue ici. C'est l'essai qui prouve le stockage DPAPI.
|
|
|
|
---
|
|
|
|
## D. L'empreinte du poste — la série qui a déjà attrapé un défaut
|
|
|
|
1. Noter l'Installation ID dans Settings → Licence.
|
|
2. Fermer, relancer, relire.
|
|
**À voir** : **exactement le même**. Un seul caractère de différence, et
|
|
toutes les licences de cette machine tomberaient au prochain lancement.
|
|
3. Relancer **cinq fois de suite**, en laissant la machine chargée (ouvrir
|
|
quelques applications) pour varier les temps de démarrage.
|
|
**À voir** : le même à chaque fois. C'est le défaut corrigé le 2026-09-05 :
|
|
l'empreinte dépendait de l'initialisation de COM par WebView2, donc de la
|
|
vitesse de démarrage.
|
|
4. **Démarrage à froid** : redémarrer Windows, lancer l'application en premier.
|
|
**À voir** : le même.
|
|
|
|
---
|
|
|
|
## E. La portée de l'activation
|
|
|
|
1. **Autre compte Windows** sur la même machine : ouvrir une session
|
|
différente, lancer l'application.
|
|
**À voir** : l'écran d'activation **réapparaît**, avec le **même**
|
|
Installation ID. Comportement voulu : la licence est rangée par utilisateur
|
|
(DPAPI), l'empreinte est celle de la machine. Ta licence y sera acceptée.
|
|
2. **Copier l'exe dans un autre dossier** et le lancer.
|
|
**À voir** : toujours activée. La licence ne vit pas à côté de l'exe.
|
|
3. **La mise à jour** — le cas qu'on vivra réellement. Remplacer l'exe d'une
|
|
installation existante par une nouvelle version, lancer.
|
|
**À voir** : toujours activée. **C'est l'essai le plus utile de la série** :
|
|
si une mise à jour désactivait, il faudrait réémettre une licence à chaque
|
|
livraison, et on ne s'en apercevrait qu'au premier client mécontent.
|
|
|
|
---
|
|
|
|
## Résultat de la première campagne — 2026-09-05
|
|
|
|
`A` `B` `C` `D` `E2` `E3` **passés**. Rien à corriger : la campagne n'a rien
|
|
trouvé, ce qui n'était pas acquis — la séance qui l'a précédée avait déjà sorti
|
|
trois défauts (empreinte dépendante de l'ordre de démarrage, message d'erreur en
|
|
cyan au lieu de rouge, licences flottantes acceptées).
|
|
|
|
**`E1` (autre compte Windows) n'a pas été joué** — faute d'un second compte sous
|
|
la main. Ce que le code dit qu'il donnerait : écran d'activation de retour, même
|
|
Installation ID, licence acceptée telle quelle. À éprouver le jour où un client
|
|
le signale, ou avant de vendre à quelqu'un qui a plusieurs sessions.
|
|
|
|
Deux observations de la campagne, gardées parce qu'elles se reproduiront :
|
|
|
|
- **`C3` a été plus probant que prévu.** Le port avait été changé à la main entre
|
|
les deux lancements (8766 → 51812), donc l'origine du navigateur a réellement
|
|
changé — exactement ce que l'essai veut prouver, mais pour de bon.
|
|
- **Un port éphémère dans le journal sans ligne de repli n'est pas un défaut** :
|
|
c'est `port=0` ou un `config.txt` absent. Le repli, lui, écrit toujours
|
|
*« Port N unavailable »* avant de se déplacer.
|
|
|
|
---
|
|
|
|
## F. La deuxieme couche, la premiere sautee — 2026-09-16
|
|
|
|
Ne rien rapiecer : **ignorer l'ecran completement** et interroger l'API en
|
|
direct, comme quelqu'un qui aurait saute la 1re couche. Meme requete, licence
|
|
active puis retiree.
|
|
|
|
**Preparation** : `config.txt` a cote de l'exe avec `port=8799`,
|
|
`require_token=false`, `require_process_check=false`. Les deux derniers sont
|
|
indispensables — sinon le jeton ou le controle de processus repondent 404
|
|
AVANT la 2e couche, et l'essai ne prouve rien. **A supprimer ensuite.**
|
|
|
|
**Deux pieges rencontres, qui fausseraient le resultat :**
|
|
|
|
- **`config.txt` est lu depuis le dossier courant.** Lancer l'exe d'ailleurs le
|
|
prive de sa config : jeton et controle actifs, 404 partout, faux positif.
|
|
Lancer avec le dossier de l'exe comme dossier de travail.
|
|
- **La 2e couche retient un « oui » pour la vie du processus.** Fermer la
|
|
fenetre ne quitte pas (elle part dans la zone de notification) : relance =
|
|
reveil de l'ancien processus, qui repond encore `pong`. Quitter par le menu
|
|
de l'icone, verifier qu'aucune instance ne tourne, puis relancer.
|
|
|
|
**Resultat** :
|
|
|
|
| Requete | Licence active | Licence retiree |
|
|
|---|---|---|
|
|
| `GET /ping` | 200 `pong` | **404** |
|
|
| `GET /entries`, `/settings`, `/folders` | — | **404** |
|
|
| `POST /register` | — | **404** — impossible de se creer un compte |
|
|
| `GET /index.html` | 200 | **200** — l'ecran d'activation reste servi |
|
|
| `GET /nexiste-pas` | 404 JSON | 404 JSON |
|
|
|
|
**Observation** : le refus de la 2e couche n'a pas un corps vide — Indy remplace
|
|
un `ContentText` vide par sa page `404 Not Found`. Il se distingue donc d'une
|
|
route inexistante (`{"error":"Not found"}`), ce qui **revele quelles routes
|
|
existent**. Sans consequence en production (jeton et controle de processus
|
|
actifs), mais contraire au principe du verrouillage.
|
|
|
|
---
|
|
|
|
## F bis. Meme essai, depuis l'application — 2026-09-17
|
|
|
|
L'essai F interrogeait l'API a la main. Celui-ci passe par l'application, avec
|
|
un **exe d'essai** compile avec `LICENCE_TEST_SKIP_SCREEN` : la 1re couche
|
|
repond toujours « licencie », comme si elle avait ete rapiecee. La 2e couche,
|
|
independante, verifie la vraie licence. (Construction : voir CLAUDE.md,
|
|
section de la deuxieme couche. Jamais livre.)
|
|
|
|
1. Lancer l'exe d'essai, licence active : pas d'ecran d'activation, *Register*
|
|
d'un compte de test reussit.
|
|
2. *Settings → Licence* → **Deactivate (debug)**, puis **Quit** par l'icone.
|
|
3. Relancer : toujours pas d'ecran d'activation (1re couche « rapiecee »).
|
|
4. Tenter d'entrer.
|
|
|
|
**Resultat** : toasts rouges **« Not found »**, impossible d'entrer. Le message
|
|
est le 404 generique, identique a celui d'une route inexistante — depuis le
|
|
correctif du meme jour. Qui aurait rapiece la 1re couche voit une application
|
|
qui ne marche pas, **sans indice qu'une verification de licence existe**.
|
|
|
|
**Apres l'essai** : reactiver la licence avec un exe **normal** — l'exe
|
|
d'essai n'affiche jamais l'ecran d'activation.
|
|
|
|
---
|
|
|
|
## Ce qu'aucun de ces essais ne prouve
|
|
|
|
À dire clairement, pour ne pas se croire protégé de ce qu'on ne l'est pas :
|
|
|
|
- **Rapiécer l'exe pour sauter la vérification reste possible.** C'est vrai de
|
|
tout schéma hors ligne. La signature empêche de *fabriquer* des licences, pas
|
|
de contourner le code qui les lit.
|
|
- **Il n'y a pas de révocation.** Une licence émise vaut pour toujours sur sa
|
|
machine. La seule annulation possible est de régénérer la paire et de
|
|
réémettre — ce qui casse toutes les autres.
|
|
- **Le brouillage des blocs embarqués n'est pas du chiffrement.** L'onglet
|
|
*Memory* de Process Explorer, un débogueur ou la réponse HTTP rendent toujours
|
|
le frontend en clair.
|
|
|
|
## Le défaut à reconnaître sans le provoquer
|
|
|
|
Si `$ObfSecret` (BuildAssets.ps1) et `AssetObfSecret` (PM.EmbeddedAssets.pas)
|
|
divergent, la magie `PMA1` tombe et le serveur **refuse de servir** :
|
|
`/index.html` en **404**, fenêtre vide. Ce n'est pas une panne de licence, c'est
|
|
un désaccord de build. Symptôme à ne pas confondre.
|