fix(android): le cache retient le secret qui ouvre CE coffre
La separation laissait FVaultPwd vide apres une ouverture depuis le cache - seules la creation et la connexion le posaient - et la reconciliation refusait donc en boucle, "open vault first" alors que le coffre etait ouvert. Le cache porte un secret et un seul : celui du conteneur local pour un coffre ne ici, celui du depot pour un coffre publie. Les deux ne coexistent jamais, puisque la reconciliation detruit le conteneur local en passant l'autorite au depot. CachePwd choisit a l'ecriture, et la relecture le range dans la meme case. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+38
-15
@@ -322,6 +322,14 @@ type
|
|||||||
procedure PublishPending;
|
procedure PublishPending;
|
||||||
/// Demande au depot s'il a bouge, sans rien adopter.
|
/// Demande au depot s'il a bouge, sans rien adopter.
|
||||||
procedure ProbeRemote;
|
procedure ProbeRemote;
|
||||||
|
/// LE SECRET QUE LE CACHE DOIT RETENIR, et il n'y en a qu'un a la fois.
|
||||||
|
///
|
||||||
|
/// Un coffre ne ici s'ouvre par le mot de passe de son conteneur ; un
|
||||||
|
/// coffre publie s'ouvre par le secret du depot. Les deux ne coexistent
|
||||||
|
/// jamais - la reconciliation detruit le conteneur local en passant
|
||||||
|
/// l'autorite au depot - donc une seule case suffit, a condition de
|
||||||
|
/// toujours y mettre le bon.
|
||||||
|
function CachePwd: string;
|
||||||
/// Retire le code de deverrouillage : le cache se rescelle sous la seule
|
/// Retire le code de deverrouillage : le cache se rescelle sous la seule
|
||||||
/// cle de l'appareil. Exige un coffre ouvert.
|
/// cle de l'appareil. Exige un coffre ouvert.
|
||||||
procedure ClearUnlockCode;
|
procedure ClearUnlockCode;
|
||||||
@@ -965,7 +973,7 @@ begin
|
|||||||
|
|
||||||
if LLocalOnly then SaveLocalContainer(LBody);
|
if LLocalOnly then SaveLocalContainer(LBody);
|
||||||
try
|
try
|
||||||
SaveVault(LNew, FETag, FSyncPwd, BiometricAvailable, False,
|
SaveVault(LNew, FETag, CachePwd, BiometricAvailable, False,
|
||||||
FPinSealed, FKey, FKeySalt, FKeyIters);
|
FPinSealed, FKey, FKeySalt, FKeyIters);
|
||||||
except
|
except
|
||||||
on E: Exception do Log(' cache not written: ' + E.Message);
|
on E: Exception do Log(' cache not written: ' + E.Message);
|
||||||
@@ -1024,7 +1032,7 @@ begin
|
|||||||
// Le cache suit la fusion : sans cela il resterait sur notre
|
// Le cache suit la fusion : sans cela il resterait sur notre
|
||||||
// version d'avant, et le prochain essai repartirait de la.
|
// version d'avant, et le prochain essai repartirait de la.
|
||||||
try
|
try
|
||||||
SaveVault(LNew, FETag, FSyncPwd, BiometricAvailable, False,
|
SaveVault(LNew, FETag, CachePwd, BiometricAvailable, False,
|
||||||
FPinSealed, FKey, FKeySalt, FKeyIters);
|
FPinSealed, FKey, FKeySalt, FKeyIters);
|
||||||
except
|
except
|
||||||
on E: Exception do Log(' cache not written: ' + E.Message);
|
on E: Exception do Log(' cache not written: ' + E.Message);
|
||||||
@@ -1193,7 +1201,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
FETag := LPut.ETag;
|
FETag := LPut.ETag;
|
||||||
try
|
try
|
||||||
SaveVault(LMerged, FETag, FSyncPwd, BiometricAvailable, False,
|
SaveVault(LMerged, FETag, CachePwd, BiometricAvailable, False,
|
||||||
FPinSealed, FKey, FKeySalt, FKeyIters);
|
FPinSealed, FKey, FKeySalt, FKeyIters);
|
||||||
except
|
except
|
||||||
on E: Exception do Log(' cache not written: ' + E.Message);
|
on E: Exception do Log(' cache not written: ' + E.Message);
|
||||||
@@ -1354,7 +1362,7 @@ begin
|
|||||||
DropLocalContainer;
|
DropLocalContainer;
|
||||||
FVaultPwd := '';
|
FVaultPwd := '';
|
||||||
try
|
try
|
||||||
SaveVault(LMerged, FETag, FSyncPwd, BiometricAvailable, False,
|
SaveVault(LMerged, FETag, CachePwd, BiometricAvailable, False,
|
||||||
FPinSealed, FKey, FKeySalt, FKeyIters);
|
FPinSealed, FKey, FKeySalt, FKeyIters);
|
||||||
except
|
except
|
||||||
on E: Exception do Log(' cache not written: ' + E.Message);
|
on E: Exception do Log(' cache not written: ' + E.Message);
|
||||||
@@ -2012,15 +2020,25 @@ begin
|
|||||||
Log(' WARNING: cache has no fingerprint - the refresh will re-derive');
|
Log(' WARNING: cache has no fingerprint - the refresh will re-derive');
|
||||||
if LPwd <> '' then
|
if LPwd <> '' then
|
||||||
begin
|
begin
|
||||||
FSyncPwd := LPwd;
|
// DANS LA CASE QUI CONVIENT. Le cache d'un coffre ne ici porte le mot de
|
||||||
// ET LES REGLAGES AVEC. C'est ICI que tout passe - a chaque lancement -
|
// passe de son conteneur, pas un secret de depot : le ranger dans
|
||||||
// et non par la creation ni par la connexion, qui n'arrivent qu'une fois.
|
// FSyncPwd le ferait servir a sceller l'instantane, ce qu'on vient
|
||||||
// Corriger celles-la seules ne changeait donc rien : PushConfig reposait
|
// justement de defaire. Et sans cette relecture, FVaultPwd restait vide
|
||||||
// la valeur de premier lancement au demarrage, l'ouverture ne la
|
// apres une ouverture depuis le cache - la reconciliation refusait alors
|
||||||
// remplacait pas, et DoSync la PREFERE a celle du coffre.
|
// en boucle, "open vault first" alors que le coffre etait ouvert.
|
||||||
FPwd := LPwd;
|
if HasLocalContainer then
|
||||||
WebCall(Format('PM.setConfig(%s, %s, %s, false)',
|
FVaultPwd := LPwd
|
||||||
[JsArg(FUrl), JsArg(FToken), JsArg(FPwd)]));
|
else
|
||||||
|
begin
|
||||||
|
FSyncPwd := LPwd;
|
||||||
|
// ET LES REGLAGES AVEC. C'est ICI que tout passe - a chaque lancement -
|
||||||
|
// et non par la creation ni par la connexion, qui n'arrivent qu'une
|
||||||
|
// fois : PushConfig reposait la valeur de premier lancement au
|
||||||
|
// demarrage, l'ouverture ne la remplacait pas, et DoSync la PREFERE.
|
||||||
|
FPwd := LPwd;
|
||||||
|
WebCall(Format('PM.setConfig(%s, %s, %s, false)',
|
||||||
|
[JsArg(FUrl), JsArg(FToken), JsArg(FPwd)]));
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// LA PROTECTION RATTRAPE LE CACHE. Elle se decidait a l'ecriture seule,
|
// LA PROTECTION RATTRAPE LE CACHE. Elle se decidait a l'ecriture seule,
|
||||||
@@ -2866,7 +2884,7 @@ begin
|
|||||||
try
|
try
|
||||||
// ARequireAuth a FAUX : les deux protections s'excluent, un cache scelle
|
// ARequireAuth a FAUX : les deux protections s'excluent, un cache scelle
|
||||||
// par un code porte VER_PIN et non VER_WRAP.
|
// par un code porte VER_PIN et non VER_WRAP.
|
||||||
SaveVault(FPlain, FETag, FSyncPwd, False, False, ANew,
|
SaveVault(FPlain, FETag, CachePwd, False, False, ANew,
|
||||||
FKey, FKeySalt, FKeyIters);
|
FKey, FKeySalt, FKeyIters);
|
||||||
if not VaultNeedsPin then
|
if not VaultNeedsPin then
|
||||||
begin
|
begin
|
||||||
@@ -2890,6 +2908,11 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TForm8.CachePwd: string;
|
||||||
|
begin
|
||||||
|
if HasLocalContainer then Result := FVaultPwd else Result := FSyncPwd;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TForm8.ClearUnlockCode;
|
procedure TForm8.ClearUnlockCode;
|
||||||
begin
|
begin
|
||||||
if FBusy then Exit;
|
if FBusy then Exit;
|
||||||
@@ -2906,7 +2929,7 @@ begin
|
|||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
try
|
try
|
||||||
SaveVault(FPlain, FETag, FSyncPwd, BiometricAvailable, False, '',
|
SaveVault(FPlain, FETag, CachePwd, BiometricAvailable, False, '',
|
||||||
FKey, FKeySalt, FKeyIters, True);
|
FKey, FKeySalt, FKeyIters, True);
|
||||||
if VaultNeedsPin then
|
if VaultNeedsPin then
|
||||||
begin
|
begin
|
||||||
|
|||||||
Reference in New Issue
Block a user