Ver código fonte

VerifyPrecompiledFiles -> DisablePrecompiledFileVerifications. Also status tweaks.

Martijn Laan 2 meses atrás
pai
commit
8a2994ee98

+ 10 - 9
ISHelp/isetup.xml

@@ -988,6 +988,7 @@ DefaultGroupName=My Program
 <li><link topic="setup_compression">Compression</link></li>
 <li><link topic="setup_compressionthreads">CompressionThreads</link></li>
 <li><link topic="setup_depcompatible">DEPCompatible</link></li>
+<li><link topic="setup_disableprecompiledfileverifications">DisablePrecompiledFileVerifications</link></li>
 <li><link topic="setup_diskclustersize">DiskClusterSize</link></li>
 <li><link topic="setup_diskslicesize">DiskSliceSize</link></li>
 <li><link topic="setup_diskspanning">DiskSpanning</link></li>
@@ -1022,7 +1023,6 @@ DefaultGroupName=My Program
 <li><link topic="setup_terminalservicesaware">TerminalServicesAware</link></li>
 <li><link topic="setup_useduserareaswarning">UsedUserAreasWarning</link></li>
 <li><link topic="setup_usesetupldr">UseSetupLdr</link></li>
-<li><link topic="setup_verifyprecompiledfiles">VerifyPrecompiledFiles</link></li>
 <li><link topic="setup_versioninfocompany">VersionInfoCompany</link></li>
 <li><link topic="setup_versioninfocopyright">VersionInfoCopyright</link></li>
 <li><link topic="setup_versioninfodescription">VersionInfoDescription</link></li>
@@ -4744,6 +4744,15 @@ Name: portablemode; Description: "Portable Mode"</pre></example>
 </body>
 </setuptopic>
 
+<setuptopic directive="DisablePrecompiledFileVerifications">
+<setupvalid>One or more of the following, separated by spaces: <br/><tt>setupe32</tt> <br/><tt>setupldre32</tt> <br/><tt>is7zdll</tt> <br/><tt>isbunzipdll</tt> <br/><tt>isunzlibdll</tt> <br/><tt>islzmaexe</tt></setupvalid>
+<setupdefault><i>(blank)</i></setupdefault>
+<body>
+<p>The compiler verifies precompiled files before using them. For certain files, you can disable verification if necessary. Use this directive to specify the list of files that should not be verified.</p>
+<p><tt>islzmaexe</tt> applies to both <i>islzma32.exe</i> and <i>islzma64.exe</i>. Similarly, <tt>is7z.dll</tt> applies not only to <i>isz7.dll</i>, but also to both <i>is7zxr.dll</i> and <i>is7zxa.dll</i>.</p>
+</body>
+</setuptopic>
+
 <setuptopic directive="DisableAppendDir">
 <setupvalid><link topic="yesnonotes"><tt>yes</tt> or <tt>no</tt></link></setupvalid>
 <setupdefault><tt>no</tt></setupdefault>
@@ -5250,14 +5259,6 @@ DiskSliceSize=1457664
 </body>
 </setuptopic>
 
-<setuptopic directive="VerifyPrecompiledFiles">
-<setupvalid><link topic="yesnonotes"><tt>yes</tt> or <tt>no</tt></link></setupvalid>
-<setupdefault><tt>yes</tt></setupdefault>
-<body>
-<p>Normally the compiler verifies that precompiled files like <i>SetupLdr.e32</i> and <i>Setup.e32</i> remain unchanged before using them. If you wish to disable this feature for some reason, set this directive to <tt>no</tt>.</p>
-</body>
-</setuptopic>
-
 <setuptopic directive="AllowCancelDuringInstall">
 <setupvalid><link topic="yesnonotes"><tt>yes</tt> or <tt>no</tt></link></setupvalid>
 <setupdefault><tt>yes</tt></setupdefault>

+ 9 - 5
Projects/Src/Compiler.HelperFunc.pas

@@ -12,7 +12,7 @@ unit Compiler.HelperFunc;
 interface
 
 uses
-  Windows, Classes, Shared.FileClass;
+  Windows, Classes, SysUtils, Shared.FileClass;
 
 type
   TColor = $7FFFFFFF-1..$7FFFFFFF;
@@ -68,7 +68,8 @@ const
 function IdentToColor(const Ident: string; var Color: Longint): Boolean;
 function StringToColor(const S: string): TColor;
 function IsRelativePath(const Filename: String): Boolean;
-function CreateMemoryStreamFromFile(const Filename: String; const CheckTrust: Boolean = False): TMemoryStream;
+function CreateMemoryStreamFromFile(const Filename: String; const CheckTrust: Boolean = False;
+  const OnCheckedTrust: TProc<Boolean> = nil): TMemoryStream;
 function FileSizeAndCRCIs(const Filename: String; const Size: Cardinal;
   const CRC: Longint): Boolean;
 function IsX86OrX64Executable(const F: TFile): Boolean;
@@ -82,7 +83,7 @@ procedure GenerateRandomBytes(var Buffer; Bytes: Cardinal);
 implementation
 
 uses
-  SysUtils, TrustFunc, Shared.CommonFunc, Shared.Int64Em,
+  TrustFunc, Shared.CommonFunc, Shared.Int64Em,
   Compression.Base, Compiler.Messages;
 
 type
@@ -167,7 +168,8 @@ begin
     Result := False;
 end;
 
-function CreateMemoryStreamFromFile(const Filename: String; const CheckTrust: Boolean): TMemoryStream;
+function CreateMemoryStreamFromFile(const Filename: String; const CheckTrust: Boolean;
+  const OnCheckedTrust: TProc<Boolean>): TMemoryStream;
 { Creates a TMemoryStream and loads the contents of the specified file into it }
 var
   F: TFile;
@@ -178,12 +180,14 @@ begin
     var FS: TFileStream;
     if CheckTrust then begin
       try
-        FS := CheckFileTrust(Filename, [cftoKeepOpen])
+        FS := CheckFileTrust(Filename, [cftoKeepOpen]);
       except
         raise Exception.CreateFmt(SCompilerCheckPrecompiledFileTrustError, [GetExceptMessage]);
       end;
     end else
       FS := nil;
+    if Assigned(OnCheckedTrust) then
+      OnCheckedTrust(CheckTrust);
     try
       { Why not use TMemoryStream.LoadFromFile here?
         1. On Delphi 2 it opens files for exclusive access (not good).

+ 2 - 1
Projects/Src/Compiler.Messages.pas

@@ -53,7 +53,8 @@ const
   SCompilerStatusFilesCompressingVersion = '   Compressing: %s   (%u.%u.%u.%u)';
   SCompilerStatusFilesStoring = '   Storing: %s';
   SCompilerStatusFilesStoringVersion = '   Storing: %s   (%u.%u.%u.%u)';
-  SCompilerStatusFilesVerified = '      Verification successful.';
+  SCompilerStatusVerified = '   Verification successful';
+  SCompilerStatusVerificationDisabled = '   Verification disabled!';
   SCompilerStatusCompressingSetupExe = '   Compressing Setup program executable';
   SCompilerStatusUpdatingVersionInfo = '   Updating version info (%s)';
   SCompilerStatusUpdatingManifest = '   Updating manifest (%s)';

+ 53 - 13
Projects/Src/Compiler.SetupCompiler.pas

@@ -62,6 +62,9 @@ type
 
   TCheckOrInstallKind = (cikCheck, cikDirectiveCheck, cikInstall);
 
+  TPrecompiledFile = (pfSetupE32, pfSetupLdrE32, pfIs7zDll, pfIsbunzipDll, pfIsunzlibDll, pfIslzmaExe);
+  TPrecompiledFiles = set of TPrecompiledFile;
+
   TSetupCompiler = class
   private
     ScriptFiles: TStringList;
@@ -113,7 +116,8 @@ type
     InternalCompressLevel, CompressLevel: Integer;
     InternalCompressProps, CompressProps: TLZMACompressorProps;
     UseSolidCompression: Boolean;
-    DontMergeDuplicateFiles, DontVerifyPrecompiledFiles: Boolean;
+    DontMergeDuplicateFiles: Boolean;
+    DisablePrecompiledFileVerifications: TPrecompiledFiles;
     Password: String;
     CryptKey: TSetupEncryptionKey;
     TimeStampsInUTC: Boolean;
@@ -163,6 +167,7 @@ type
     procedure AddStatus(const S: String; const Warning: Boolean = False);
     procedure AddStatusFmt(const Msg: String; const Args: array of const;
       const Warning: Boolean);
+    procedure OnCheckedTrust(CheckedTrust: Boolean);
     class procedure AbortCompile(const Msg: String);
     class procedure AbortCompileParamError(const Msg, ParamName: String);
     function PrependDirName(const Filename, Dir: String): String;
@@ -1352,6 +1357,14 @@ begin
   AddStatus(Format(Msg, Args), Warning);
 end;
 
+procedure TSetupCompiler.OnCheckedTrust(CheckedTrust: Boolean);
+begin
+  if CheckedTrust then
+    AddStatus(SCompilerStatusVerified)
+  else
+    AddStatus(SCompilerStatusVerificationDisabled);
+end;
+
 class procedure TSetupCompiler.AbortCompile(const Msg: String);
 begin
   raise EISCompileError.Create(Msg);
@@ -2449,7 +2462,7 @@ var
 
   function StrToPrivilegesRequiredOverrides(S: String): TSetupPrivilegesRequiredOverrides;
   const
-    Overrides: array[0..1] of PChar = ('commandline', 'dialog');
+    Overrides: array of PChar = ['commandline', 'dialog'];
   begin
     Result := [];
     while True do
@@ -2461,6 +2474,24 @@ var
       end;
   end;
 
+  function StrToPrecompiledFiles(S: String): TPrecompiledFiles;
+  const
+    PrecompiledFiles: array of PChar = ['setupe32', 'setupldre32', 'is7zdll', 'isbunzipdll', 'isunzlibdll', 'islzmaexe'];
+  begin
+    Result := [];
+    while True do
+      case ExtractFlag(S, PrecompiledFiles) of
+        -2: Break;
+        -1: Invalid;
+        0: Include(Result, pfSetupE32);
+        1: Include(Result, pfSetupLdrE32);
+        2: Include(Result, pfIs7zDll);
+        3: Include(Result, pfIsbunzipDll);
+        4: Include(Result, pfIsunzlibDll);
+        5: Include(Result, pfIslzmaExe);
+      end;
+  end;
+
   procedure StrToPercentages(const S: String; var X, Y: Integer; const Min, Max: Integer);
   var
     I: Integer;
@@ -2749,6 +2780,10 @@ begin
     ssDisableFinishedPage: begin
         SetSetupHeaderOption(shDisableFinishedPage);
       end;
+    ssDisablePrecompiledFileVerifications: begin
+      DisablePrecompiledFileVerifications := StrToPrecompiledFiles(Value);
+      CompressProps.WorkerProcessCheckTrust := not (pfIslzmaExe in DisablePrecompiledFileVerifications);
+    end;
     ssDisableProgramGroupPage: begin
         if CompareText(Value, 'auto') = 0 then
           SetupHeader.DisableProgramGroupPage := dpAuto
@@ -3131,10 +3166,6 @@ begin
     ssUserInfoPage: begin
         SetSetupHeaderOption(shUserInfoPage);
       end;
-    ssVerifyPrecompiledFiles: begin
-      DontVerifyPrecompiledFiles := not StrToBool(Value);
-      CompressProps.WorkerProcessCheckTrust := not DontVerifyPrecompiledFiles;
-    end;
     ssVersionInfoCompany: begin
         VersionInfoCompany := Value;
       end;
@@ -7266,7 +7297,7 @@ var
           if FLExtraInfo.Verification.Typ <> fvNone then begin
             if not SHA256DigestsEqual(FL.SHA256Sum, ExpectedFileHash) then
               VerificationError(veFileHashIncorrect, FileLocationEntryFilenames[I]);
-            AddStatus(SCompilerStatusFilesVerified);
+            AddStatus(SCompilerStatusVerified);
           end;
         finally
           SourceFile.Free;
@@ -7289,7 +7320,8 @@ var
   end;
 
   procedure CopyFileOrAbort(const SourceFile, DestFile: String;
-    const CheckTrust: Boolean; const CheckFileTrustOptions: TCheckFileTrustOptions);
+    const CheckTrust: Boolean; const CheckFileTrustOptions: TCheckFileTrustOptions;
+    const OnCheckedTrust: TProc<Boolean>);
   var
     ErrorCode: DWORD;
   begin
@@ -7302,6 +7334,8 @@ var
         AbortCompileFmt(SCompilerCheckPrecompiledFileTrustError, [Msg]);
       end;
     end;
+    if Assigned(OnCheckedTrust) then
+      OnCheckedTrust(CheckTrust);
 
     if not CopyFile(PChar(SourceFile), PChar(DestFile), False) then begin
       ErrorCode := GetLastError;
@@ -7445,7 +7479,8 @@ var
       E32Filename := CompilerDir + 'Setup.e32';
       { make a copy and update icons, version info and if needed manifest }
       ConvertFilename := OutputDir + OutputBaseFilename + '.e32.tmp';
-      CopyFileOrAbort(E32Filename, ConvertFilename, not DontVerifyPrecompiledFiles, [cftoTrustAllOnDebug]);
+      CopyFileOrAbort(E32Filename, ConvertFilename, not(pfSetupE32 in DisablePrecompiledFileVerifications),
+        [cftoTrustAllOnDebug], OnCheckedTrust);
       SetFileAttributes(PChar(ConvertFilename), FILE_ATTRIBUTE_ARCHIVE);
       TempFilename := ConvertFilename;
       if SetupIconFilename <> '' then begin
@@ -7678,6 +7713,7 @@ begin
     CompressLevel := clLZMAMax;
     CompressProps := TLZMACompressorProps.Create;
     CompressProps.WorkerProcessCheckTrust := True;
+    CompressProps.WorkerProcessOnCheckedTrust := OnCheckedTrust;
     UseSetupLdr := True;
     TerminalServicesAware := True;
     DEPCompatible := True;
@@ -8170,18 +8206,21 @@ begin
     case SetupHeader.CompressMethod of
       cmZip: begin
           AddStatus(Format(SCompilerStatusReadingFile, ['isunzlib.dll']));
-          DecompressorDLL := CreateMemoryStreamFromFile(CompilerDir + 'isunzlib.dll', not DontVerifyPrecompiledFiles);
+          DecompressorDLL := CreateMemoryStreamFromFile(CompilerDir + 'isunzlib.dll',
+            not(pfIsunzlibDll in DisablePrecompiledFileVerifications), OnCheckedTrust);
         end;
       cmBzip: begin
           AddStatus(Format(SCompilerStatusReadingFile, ['isbunzip.dll']));
-          DecompressorDLL := CreateMemoryStreamFromFile(CompilerDir + 'isbunzip.dll', not DontVerifyPrecompiledFiles);
+          DecompressorDLL := CreateMemoryStreamFromFile(CompilerDir + 'isbunzip.dll',
+            not(pfIsbunzipDll in DisablePrecompiledFileVerifications), OnCheckedTrust);
         end;
     end;
 
     { Read 7-Zip DLL }
     if SetupHeader.SevenZipLibraryName <> '' then begin
       AddStatus(Format(SCompilerStatusReadingFile, [SetupHeader.SevenZipLibraryName]));
-      SevenZipDLL := CreateMemoryStreamFromFile(CompilerDir + SetupHeader.SevenZipLibraryName, not DontVerifyPrecompiledFiles);
+      SevenZipDLL := CreateMemoryStreamFromFile(CompilerDir + SetupHeader.SevenZipLibraryName,
+        not(pfIs7zDll in DisablePrecompiledFileVerifications), OnCheckedTrust);
     end;
 
     { Add default types if necessary }
@@ -8239,7 +8278,8 @@ begin
           end;
         end
         else begin
-          CopyFileOrAbort(CompilerDir + 'SetupLdr.e32', ExeFilename, not DontVerifyPrecompiledFiles, [cftoTrustAllOnDebug]);
+          CopyFileOrAbort(CompilerDir + 'SetupLdr.e32', ExeFilename, not(pfSetupLdrE32 in DisablePrecompiledFileVerifications),
+            [cftoTrustAllOnDebug], OnCheckedTrust);
           { if there was a read-only attribute, remove it }
           SetFileAttributes(PChar(ExeFilename), FILE_ATTRIBUTE_ARCHIVE);
           if SetupIconFilename <> '' then begin

+ 12 - 3
Projects/Src/Compression.LZMACompressor.pas

@@ -41,6 +41,7 @@ type
     NumFastBytes: Integer;
     NumThreads: Integer;
     WorkerProcessCheckTrust: Boolean;
+    WorkerProcessOnCheckedTrust: TProc<Boolean>;
     WorkerProcessFilename: String;
     constructor Create;
   end;
@@ -182,6 +183,7 @@ type
     FProcess: THandle;
     FSharedMapping: THandle;
     FCheckTrust: Boolean;
+    FOnCheckedTrust: TProc<Boolean>;
     FExeFilename: String;
   public
     constructor Create(const AEvents: PLZMACompressorSharedEvents); override;
@@ -191,6 +193,7 @@ type
       override;
     procedure UnexpectedTerminationError; override;
     property CheckTrust: Boolean read FCheckTrust write FCheckTrust;
+    property OnCheckedTrust: TProc<Boolean> read FOnCheckedTrust write FOnCheckedTrust;
     property ExeFilename: String read FExeFilename write FExeFilename;
   end;
 
@@ -782,6 +785,8 @@ begin
         LZMAInternalError(Format(SCompilerCheckPrecompiledFileTrustError, [GetExceptMessage]));
       end;
     end;
+    if Assigned(FOnCheckedTrust) then
+      FOnCheckedTrust(FCheckTrust);
     try
       if not CreateProcess(PChar(FExeFilename),
          PChar(Format('islzma_exe %d 0x%x', [ISLZMA_EXE_VERSION, ProcessDataMapping])),
@@ -896,6 +901,7 @@ begin
   EncProps.NumThreads := -1;
 
   var WorkerProcessCheckTrust := False;
+  var WorkerProcessOnCheckedTrust: TProc<Boolean> := nil;
   var WorkerProcessFilename := '';
 
   if ACompressorProps is TLZMACompressorProps then begin
@@ -914,15 +920,18 @@ begin
     if Props.NumThreads <> 0 then
       EncProps.NumThreads := Props.NumThreads;
     WorkerProcessCheckTrust := Props.WorkerProcessCheckTrust;
+    WorkerProcessOnCheckedTrust := Props.WorkerProcessOnCheckedTrust;
     WorkerProcessFilename := Props.WorkerProcessFilename;
   end;
 
   EncProps.NumHashBytes := numHashBytes[EncProps.BTMode = 1];
 
   if WorkerProcessFilename <> '' then begin
-    FWorker := TLZMAWorkerProcess.Create(@FEvents);
-    (FWorker as TLZMAWorkerProcess).CheckTrust := WorkerProcessCheckTrust;
-    (FWorker as TLZMAWorkerProcess).ExeFilename := WorkerProcessFilename;
+    const LZMAWorker = TLZMAWorkerProcess.Create(@FEvents);
+    FWorker := LZMAWorker;
+    LZMAWorker.CheckTrust := WorkerProcessCheckTrust;
+    LZMAWorker.OnCheckedTrust := WorkerProcessOnCheckedTrust;
+    LZMAWorker.ExeFilename := WorkerProcessFilename;
   end
   else begin
     if not LZMADLLInitialized then

+ 1 - 1
Projects/Src/Shared.SetupSectionDirectives.pas

@@ -69,6 +69,7 @@ type
     ssDirExistsWarning,
     ssDisableDirPage,
     ssDisableFinishedPage,
+    ssDisablePrecompiledFileVerifications,
     ssDisableProgramGroupPage,
     ssDisableReadyMemo,
     ssDisableReadyPage,
@@ -155,7 +156,6 @@ type
     ssUsePreviousUserInfo,
     ssUseSetupLdr,
     ssUserInfoPage,
-    ssVerifyPrecompiledFiles,
     ssVersionInfoCompany,
     ssVersionInfoCopyright,
     ssVersionInfoDescription,

+ 1 - 1
whatsnew.htm

@@ -176,7 +176,7 @@ issigtool --key-file="MyKey.ispublickey" verify "MyProg.dll"</pre>
   </li>
   <li>Other related changes:
   <ul>
-    <li>The compiler now verifies that precompiled files like <i>SetupLdr.e32</i> and <i>Setup.e32</i> remain unchanged before using them. Can be disabled using new [Setup] section directive <tt>VerifyPrecompiledFiles</tt>. Doing so is <i>not</i> recommended.</li>
+    <li>The compiler now verifies additional precompiled files, such as <i>Setup.e32</i> and <i>SetupLdr.e32</i>, to ensure they remain unchanged before using them. Can be disabled using new [Setup] section directive <tt>DisablePrecompiledFileVerifications</tt>, though doing so is <i>not</i> recommended.</li>
     <li>Added new <tt>[Files]</tt> section parameter <tt>Hash</tt>. Instructs the compiler or Setup to do a simple SHA-256 hash check instead of a full signature verification, as an alternative to using the <tt>issigverify</tt> flag.<br/>
         Example script:
       <pre>[Files]