From a41c61405c9d85756d77e24b76e01ec1412b862f Mon Sep 17 00:00:00 2001 From: r-zakarya <82443831+r-zakarya@users.noreply.github.com> Date: Fri, 28 Aug 2026 16:30:30 +0100 Subject: [PATCH] fix(android): retirer le code de deverrouillage demande de le connaitre Le coffre ouvert ne prouvait rien : il peut l'etre depuis une heure et rester a l'ecran. Quiconque trouvait le telephone dans cet etat levait la protection en deux appuis, sans que rien ne le lui demande. Le code courant voyage maintenant avec la demande, et Delphi le compare a FPinSealed - ce sous quoi le cache est REELLEMENT scelle, pose seulement par une ouverture reussie, jamais par un champ. Fermee au passage : SetUnlockCode('') retirait le code en silence, ce qui contournait le controle qu'on vient de poser. Le FBusy de ClearUnlockCode ne sort plus sans un mot - une sortie muette se lit comme une reussite. Co-Authored-By: Claude Opus 5 --- android-client/web/app.html | 14 +++++++++++--- mainApk.pas | 30 +++++++++++++++++++++++++----- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/android-client/web/app.html b/android-client/web/app.html index afe8fbe..d4a3970 100644 --- a/android-client/web/app.html +++ b/android-client/web/app.html @@ -564,8 +564,12 @@
×
+ -
The code seals the copy kept on this device. It can be +
To remove the code, type the current one above first. + The code seals the copy kept on this device. It can be digits or a full password - a longer one is harder to guess, and it is asked for only when the vault opens. Removing it leaves the vault readable by anyone holding the phone unlocked.
@@ -1551,8 +1555,12 @@ document.getElementById('sPinClear').addEventListener('click', function (ev) { } b.removeAttribute('data-armed'); b.textContent = 'Remove the unlock code'; - send('pinclear'); - closeSettings(); + // LE CODE COURANT VOYAGE AVEC LA DEMANDE. Le coffre ouvert ne prouve rien : + // il peut l'etre depuis une heure et rester a l'ecran. Delphi compare a ce + // sous quoi le cache est reellement scelle, et refuse sinon. + send('pinclear?c=' + encodeURIComponent( + document.getElementById('sPinNew').value)); + document.getElementById('sPinNew').value = ''; }); function goList() { diff --git a/mainApk.pas b/mainApk.pas index 92df680..beee92e 100644 --- a/mainApk.pas +++ b/mainApk.pas @@ -332,7 +332,7 @@ type function CachePwd: string; /// Retire le code de deverrouillage : le cache se rescelle sous la seule /// cle de l'appareil. Exige un coffre ouvert. - procedure ClearUnlockCode; + procedure ClearUnlockCode(const AConfirm: string); /// Pose ou change le code de deverrouillage. Exige un coffre ouvert, donc /// le code courant deja connu - c'est ce qui empeche un tiers d'en poser un /// que le proprietaire ne connaitrait pas. @@ -1728,7 +1728,7 @@ begin SetUnlockCode(TNetEncoding.URL.Decode(Param('c'))) else if LAction = 'pinclear' then - ClearUnlockCode + ClearUnlockCode(TNetEncoding.URL.Decode(Param('c'))) else if LAction = 'delentry' then DeleteEntriesAt(TNetEncoding.URL.Decode(Param('i'))) @@ -2890,7 +2890,10 @@ begin if FBusy then Exit; if ANew = '' then begin - ClearUnlockCode; + // Un champ vide ne demande rien : c'est "Remove" qui retire, et lui exige + // le code courant. Repondre par un retrait silencieux serait une porte + // derobee vers exactement ce qu'on vient de fermer. + WebCall('PM.toast("Type a code first")'); Exit; end; // Le secret du depot n'entre pas ici : le code scelle le CACHE, et un coffre @@ -2932,9 +2935,19 @@ begin if HasLocalContainer then Result := FVaultPwd else Result := FSyncPwd; end; -procedure TForm8.ClearUnlockCode; +/// RETIRER UNE PROTECTION DEMANDE DE LA CONNAITRE. +/// +/// Le coffre ouvert ne suffit pas : il peut l'avoir ete il y a une heure et +/// rester a l'ecran. Quelqu'un qui trouve le telephone dans cet etat pouvait +/// lever le code en deux appuis, et rien ne le lui demandait. Retaper le code +/// courant ne coute rien a son proprietaire, et arrete l'autre. +procedure TForm8.ClearUnlockCode(const AConfirm: string); begin - if FBusy then Exit; + if FBusy then + begin + WebCall('PM.toast("Busy - wait for the current operation")'); + Exit; + end; if not VaultNeedsPin then begin WebCall('PM.toast("No unlock code to remove")'); @@ -2947,6 +2960,13 @@ begin WebCall('PM.toast("Open the vault first")'); Exit; end; + // Compare a ce que le cache est REELLEMENT scelle, pas a ce qui traine dans + // un champ : FPinSealed n'est pose qu'a une ouverture reussie. + if (FPinSealed = '') or (AConfirm <> FPinSealed) then + begin + WebCall('PM.toast("Type the current unlock code to remove it")'); + Exit; + end; try SaveVault(FPlain, FETag, CachePwd, BiometricAvailable, False, '', FKey, FKeySalt, FKeyIters, True);