960d2b388a
PM.Licence verifie une chaine charge-utile.signature contre la cle publique de l'editeur, via BCryptVerifySignature. Aucun ASN.1 : la signature du script est deja en r||s brut et les coordonnees se rangent telles quelles dans un BCRYPT_ECCPUBLIC_BLOB. La cle publique est livree A ZERO — tant que la sortie de licence.ps1 -Init n'y est pas collee, aucune licence n'est valide. C'est le defaut sur : un blob par defaut qui accepterait quelque chose serait pire. IsLicensed REVERIFIE la licence rangee plutot que de lire un drapeau. La signature est verifiee AVANT que la charge utile soit analysee. SelfTestLicence a l'initialization rejoue un vecteur fige signe par une paire de test : valable accepte, un octet retourne refuse. Verifie en executant l'unite, pas seulement en la compilant. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
58 lines
2.3 KiB
ObjectPascal
58 lines
2.3 KiB
ObjectPascal
program PMServer;
|
|
|
|
uses
|
|
System.SysUtils, // FindCmdLineSwitch
|
|
System.StartUpCopy,
|
|
FMX.Forms,
|
|
PM.SingleInstance in 'Source\PM.SingleInstance.pas',
|
|
UMainForm in 'UMainForm.pas' {MainForm},
|
|
PM.JSON in 'Source\PM.JSON.pas',
|
|
PM.Database in 'Source\PM.Database.pas',
|
|
PM.Router in 'Source\PM.Router.pas',
|
|
PM.StaticFiles in 'Source\PM.StaticFiles.pas',
|
|
PM.EmbeddedAssets in 'Source\PM.EmbeddedAssets.pas',
|
|
PM.Crypto in 'Source\PM.Crypto.pas',
|
|
PM.RateLimit in 'Source\PM.RateLimit.pas',
|
|
PM.Audit in 'Source\PM.Audit.pas',
|
|
PM.Session in 'Source\PM.Session.pas',
|
|
PM.HTTPServer in 'Source\PM.HTTPServer.pas',
|
|
PM.Bridge in 'Source\PM.Bridge.pas',
|
|
PM.QuickUnlock in 'Source\PM.QuickUnlock.pas',
|
|
PM.PinUnlock in 'Source\PM.PinUnlock.pas',
|
|
PM.UserPrefs in 'Source\PM.UserPrefs.pas',
|
|
PM.Licence in 'Source\PM.Licence.pas',
|
|
PM.AutoStart in 'Source\PM.AutoStart.pas',
|
|
PM.Favicon in 'Source\PM.Favicon.pas',
|
|
PM.ProcessLockdown in 'Source\PM.ProcessLockdown.pas',
|
|
PM.Handler.Ping in 'Handlers\PM.Handler.Ping.pas',
|
|
PM.Handler.Auth in 'Handlers\PM.Handler.Auth.pas',
|
|
PM.Handler.Folders in 'Handlers\PM.Handler.Folders.pas',
|
|
PM.Handler.Entries in 'Handlers\PM.Handler.Entries.pas',
|
|
PM.Handler.Passkey in 'Handlers\PM.Handler.Passkey.pas',
|
|
PM.Handler.Recovery in 'Handlers\PM.Handler.Recovery.pas',
|
|
PM.Handler.Audit in 'Handlers\PM.Handler.Audit.pas',
|
|
PM.Handler.Settings in 'Handlers\PM.Handler.Settings.pas',
|
|
PM.Handler.Attachments in 'Handlers\PM.Handler.Attachments.pas';
|
|
|
|
{$R *.res}
|
|
{$R assets\assets.res}
|
|
|
|
begin
|
|
// Single-instance: if another PMServer is running, bring it to front
|
|
// (it'll handle WM_PMSHOW on its message-only window) and exit. Avoids
|
|
// two icons in the tray and two HTTP servers fighting for the port.
|
|
if not PM.SingleInstance.AcquireOrSignal then
|
|
Exit;
|
|
|
|
Application.Initialize;
|
|
// --tray ("Start with Windows"): FMX puts its taskbar proxy on screen before
|
|
// FormCreate is ever reached — measured — so the watcher has to start here,
|
|
// before the form is built. It only touches raw Win32 (FindWindowEx +
|
|
// ShowWindow), never an FMX object: an earlier attempt that poked
|
|
// MainForm.Visible/Handle at this point died with an access violation.
|
|
if FindCmdLineSwitch('tray', True) then
|
|
StartTrayProxyHider;
|
|
Application.CreateForm(TMainForm, MainForm);
|
|
Application.Run;
|
|
end.
|