diff --git a/android-client/web/app.html b/android-client/web/app.html
index 6dd1330..f9e4bb1 100644
--- a/android-client/web/app.html
+++ b/android-client/web/app.html
@@ -162,6 +162,7 @@
.btn.wide { padding: 13px 18px; font-size: 15px; }
.btn.main { background: var(--accent); }
.btn:disabled { opacity: .45; }
+ .field-in:disabled { opacity: .5; }
/* Rouge sourd : assez pour qu'on ne le confonde pas avec Copy, pas assez
pour attirer l'oeil sur la seule action irreversible de l'ecran. */
.btn.danger { background: rgba(220, 80, 80, .30); }
@@ -1669,6 +1670,15 @@ function openSettings() {
document.getElementById('sPinNew').value = '';
document.getElementById('secCode').hidden = !vaultOpen;
document.getElementById('sRepoErr').hidden = true;
+ // UN COFFRE EXISTE MAIS EST FERME : le mot de passe de synchro ne se change
+ // pas d'ici. Il ne vit que dans le coffre scelle, et seul un coffre ouvert
+ // permet de le verifier puis de l'y ranger - tape coffre ferme, il etait
+ // perdu a la fermeture de l'app.
+ var sp = document.getElementById('sPwd'),
+ locked = (authMode === 'open' || authMode === 'login') && !vaultOpen;
+ sp.disabled = locked;
+ sp.placeholder = locked ? 'sync password - open the vault to change it'
+ : 'sync password';
cfgBase = cfgNow();
syncSaveBtn(false);
// La section n'existe que coffre ouvert : le dire tant qu'elle manque, et se
diff --git a/mainApk.pas b/mainApk.pas
index 0d294c2..5750dae 100644
--- a/mainApk.pas
+++ b/mainApk.pas
@@ -972,12 +972,15 @@ end;
/// oublier trois fois - a l'editeur, puis au formulaire de creation.
function TForm8.OpenContainer(const AContainer, APwd: string): string;
var
- LSalt: TBytes;
- LIters: Integer;
+ LSalt, LNewKey, LNewSalt: TBytes;
+ LIters, LNewIters: Integer;
LSw: TStopwatch;
begin
LSw := TStopwatch.StartNew;
- if (FKey <> nil) and ContainerKdfParams(AContainer, LSalt, LIters)
+ // LA CLE EN MAIN EST CELLE DE L'ANCIEN MOT DE PASSE. La reutiliser quand
+ // l'utilisateur vient d'en enregistrer un autre ouvrait le depot sans jamais
+ // essayer celui-ci : un mot de passe faux passait pour bon.
+ if (not FPwdUserSet) and (FKey <> nil) and ContainerKdfParams(AContainer, LSalt, LIters)
and (LIters = FKeyIters) and (Length(LSalt) = Length(FKeySalt))
and CompareMem(Pointer(LSalt), Pointer(FKeySalt), Length(LSalt)) then
begin
@@ -986,7 +989,14 @@ begin
[LSw.ElapsedMilliseconds]));
Exit;
end;
- Result := DecryptContainerEx(AContainer, APwd, FKey, FKeySalt, FKeyIters);
+ // DANS DES LOCALES, rangees seulement apres un dechiffrement reussi : les
+ // parametres `out` de type TBytes sont vides des l'appel, et un essai rate
+ // effacait la bonne cle - la publication suivante aurait alors re-derive
+ // avec le mauvais mot de passe.
+ Result := DecryptContainerEx(AContainer, APwd, LNewKey, LNewSalt, LNewIters);
+ FKey := LNewKey;
+ FKeySalt := LNewSalt;
+ FKeyIters := LNewIters;
Log(Format(' key derived in %d ms', [LSw.ElapsedMilliseconds]));
end;
@@ -1798,7 +1808,16 @@ begin
FUrl := TNetEncoding.URL.Decode(Param('u')).Trim;
FToken := TNetEncoding.URL.Decode(Param('t')).Trim;
FPwd := TNetEncoding.URL.Decode(Param('p'));
- if FPwd <> FPwdShown then FPwdUserSet := True;
+ if FPwd <> FPwdShown then
+ begin
+ FPwdUserSet := True;
+ FPwdShown := FPwd;
+ // COFFRE OUVERT : on verifie tout de suite (DoSync retelecharge et
+ // dechiffre sous ce mot de passe), et un bon mot de passe est range
+ // dans le coffre scelle - le seul endroit ou il survit a la fermeture.
+ if (FPlain <> '') and (FUrl <> '') and (FToken <> '') and (FPwd <> '') then
+ TThread.ForceQueue(nil, procedure begin DoSync(nil); end);
+ end;
FPin := TNetEncoding.URL.Decode(Param('c'));
// L'empreinte du mot de passe AUSSI : si une saisie destinee au jeton
// atterrit dans le champ voisin - les deux sont masques - c'est celle-ci
@@ -2276,8 +2295,9 @@ begin
else if FPwdUserSet then
begin
// L'utilisateur a enregistre un autre mot de passe de synchro depuis :
- // c'est lui qui sert, bon ou mauvais - la synchro le dira.
- FSyncPwd := FPwd;
+ // il RESTE dans les reglages (FPwd), mais seul celui du cache - verifie -
+ // sert au rafraichissement de fond. Le nouveau se verifie par Sync.
+ FSyncPwd := LPwd;
Log(' sync password set in Settings kept over the cached one');
end
else