chore(android): section 5 - ten permissions down to three, no secrets in release

The manifest asked for fine and coarse location, camera, phone, phone state
and external storage - Delphi's defaults, none of them used. On a password
vault those are exactly the wrong signals: whoever reads the app's listing saw
a request for position and camera with no possible explanation. The list is
written by hand now.

A trap on the way: naming the substitution marker inside the comment that
explains its removal is enough to bring it back. The substitution is textual
and does not care that it lands in a comment.

The bench credentials are no longer compiled into a release - the local
include is debug-only. Verified in the binary in UTF-8 AND UTF-16: Delphi
stores strings as UTF-16, so an ASCII grep returned zero on both sides and
proved nothing.

The log leaves the home screen in release without leaving the application: a
1.5 s press on the status line brings it back. Nothing secret is in it, but a
permanent Log button is development noise, and diagnostics must stay reachable
for the day something goes wrong remotely.

And the Release configuration did not compile at all, which nobody knew: the
two self-checks had their declarations under IFDEF DEBUG and their bodies
outside. Invisible as long as one only ever builds Debug.

Signing is what remains, and the keystore password is the user's to hold.
This commit is contained in:
r-zakarya
2026-08-21 17:38:46 +01:00
parent eb9999c4b2
commit 0b0f1e3fcd
4 changed files with 119 additions and 7 deletions
+27
View File
@@ -89,7 +89,20 @@ const
// jeton authentifie l'appareil, le mot de passe ouvre le coffre entier. Ni
// l'un ni l'autre n'a sa place dans un depot, meme sans remote. Absents apres
// un clone -> recopier PMA.LocalConfig.template.inc.
//
// EN RELEASE ILS N'EXISTENT PAS. Ce sont des commodites de banc d'essai : elles
// evitent de retaper un jeton de quarante caracteres a chaque reinstallation.
// Compilees dans un APK distribue, elles y placeraient en clair de quoi lire le
// depot ET de quoi ouvrir le coffre - il suffirait de decompresser le fichier.
// Le fichier local n'est donc meme pas inclus : une release se compile sans
// lui, et un clone qui ne l'a pas construit quand meme.
{$IFDEF DEBUG}
{$I android-client\PMA.LocalConfig.inc}
{$ELSE}
const
FIRSTRUN_TOKEN = '';
TEST_PWD = '';
{$ENDIF}
type
TForm8 = class(TForm)
@@ -358,6 +371,11 @@ begin
PushConfig;
ShowUnlock;
{$IFNDEF DEBUG}
// Le journal quitte l'ecran d'accueil, sans quitter l'application : un appui
// long sur la ligne d'etat le ramene. Voir PM.hideLog.
WebCall('PM.hideLog()');
{$ENDIF}
{$IFDEF DEBUG}
// VERIFICATION DU CHIFFREMENT AVANT TOUTE ECRITURE REELLE (§4). Elle depose
@@ -530,6 +548,13 @@ begin
if ASecret = '' then Exit('(vide)');
Result := Copy(THashSHA2.GetHashString(ASecret), 1, 8);
end;
{$IFDEF DEBUG}
/// LES DEUX AUTO-CONTROLES SONT DE DEBOGAGE, corps compris. Leurs declarations
/// l'etaient deja ; leurs implementations ne l'etaient pas, et une release ne
/// compilait donc pas du tout - la classe ne les declarant plus, le corps
/// devenait un membre inconnu. Defaut invisible tant qu'on ne construit qu'en
/// debogage, ce qui a ete le cas jusqu'a l'empaquetage.
///
/// Chiffre un petit conteneur, le relit, et le laisse sur le disque prive pour
/// qu'une autre implementation le verifie. Iterations volontairement basses :
/// ce qu'on eprouve ici est le CABLAGE - cle, IV, place du tag - pas le cout
@@ -629,6 +654,8 @@ end;
/// PAR UUID ET NON PAR INDICE : le coffre vient d'etre remplace par celui du
/// serveur, et rien ne garantit que la meme entree occupe le meme rang - un
/// tri se fait sur le nom affiche, qu'une autre machine a pu changer.
{$ENDIF}
procedure TForm8.ReopenEntryByUuid(const AUuid: string);
var
I: Integer;