Ver código fonte

Add SignToolRetryCount and SignToolMinimumTimeBetween.

Martijn Laan 7 anos atrás
pai
commit
8be7f42399

+ 2 - 0
Components/ScintStylerInnoSetup.pas

@@ -197,7 +197,9 @@ type
     ssSignedUninstaller,
     ssSignedUninstaller,
     ssSignedUninstallerDir,
     ssSignedUninstallerDir,
     ssSignTool,
     ssSignTool,
+    ssSignToolMinimumTimeBetween,
     ssSignToolRetryCount,
     ssSignToolRetryCount,
+    ssSignToolRetryDelay,
     ssSlicesPerDisk,
     ssSlicesPerDisk,
     ssSolidCompression,
     ssSolidCompression,
     ssSourceDir,
     ssSourceDir,

+ 30 - 1
ISHelp/isetup.xml

@@ -912,7 +912,9 @@ DefaultGroupName=My Program
 <li><link topic="setup_signeduninstaller">SignedUninstaller</link></li>
 <li><link topic="setup_signeduninstaller">SignedUninstaller</link></li>
 <li><link topic="setup_signeduninstallerdir">SignedUninstallerDir</link></li>
 <li><link topic="setup_signeduninstallerdir">SignedUninstallerDir</link></li>
 <li><link topic="setup_signtool">SignTool</link></li>
 <li><link topic="setup_signtool">SignTool</link></li>
+<li><link topic="setup_signtoolminimumtimebetween">SignToolMinimumTimeBetween</link></li>
 <li><link topic="setup_signtoolretrycount">SignToolRetryCount</link></li>
 <li><link topic="setup_signtoolretrycount">SignToolRetryCount</link></li>
+<li><link topic="setup_signtoolretrydelay">SignToolRetryDelay</link></li>
 <li><link topic="setup_slicesperdisk">SlicesPerDisk</link></li>
 <li><link topic="setup_slicesperdisk">SlicesPerDisk</link></li>
 <li><link topic="setup_solidcompression">SolidCompression</link></li>
 <li><link topic="setup_solidcompression">SolidCompression</link></li>
 <li><link topic="setup_sourcedir">SourceDir</link></li>
 <li><link topic="setup_sourcedir">SourceDir</link></li>
@@ -5009,10 +5011,23 @@ SignTool=byparam format c:
 <p>Further details on obtaining signing certificates and using code-signing tools are beyond the scope of this documentation.</p>
 <p>Further details on obtaining signing certificates and using code-signing tools are beyond the scope of this documentation.</p>
 <p><i>Note:</i> If you use a Sign Tool and your Setup contains a large amount of data, it is recommended that you enable <link topic="setup_diskspanning">Disk spanning</link> with <link topic="setup_diskslicesize">DiskSliceSize</link> set to <tt>max</tt>. If you don't do this, the user might experience a long delay after starting Setup caused by Windows verifying the digital signature against all your data. There should be no security reduction from using disk spanning in practice: all files extracted from the unsigned .bin files undergo SHA-1 verification (provided <tt>dontverifychecksum</tt> isn't used). The SHA-1 hashes for this (along with all other metadata) are kept inside Setup's EXE, which is protected by the digital signature.</p>
 <p><i>Note:</i> If you use a Sign Tool and your Setup contains a large amount of data, it is recommended that you enable <link topic="setup_diskspanning">Disk spanning</link> with <link topic="setup_diskslicesize">DiskSliceSize</link> set to <tt>max</tt>. If you don't do this, the user might experience a long delay after starting Setup caused by Windows verifying the digital signature against all your data. There should be no security reduction from using disk spanning in practice: all files extracted from the unsigned .bin files undergo SHA-1 verification (provided <tt>dontverifychecksum</tt> isn't used). The SHA-1 hashes for this (along with all other metadata) are kept inside Setup's EXE, which is protected by the digital signature.</p>
 <p><b>See also:</b><br/>
 <p><b>See also:</b><br/>
+<link topic="setup_signtoolminimumtimebetween">SignToolMinimumTimeBetween</link><br/>
 <link topic="setup_signtoolretrycount">SignToolRetryCount</link></p>
 <link topic="setup_signtoolretrycount">SignToolRetryCount</link></p>
 </body>
 </body>
 </setuptopic>
 </setuptopic>
 
 
+<setuptopic directive="SignToolMinimumTimeBetween">
+<keyword value="signature" />
+<keyword value="digital signature" />
+<keyword value="code signing" />
+<setupdefault><tt>0</tt></setupdefault>
+<body>
+<p>If not set to 0, specifies the minimum number of milliseconds that should have elapsed between consecutive digital signing actions by the Setup Compiler. For example, if set to 5000 then the Setup Compiler will perform 1 digital signing per 5 seconds at most. Can be used to avoid being rejected by rate limiting timestamp services.</p>
+<p><b>See also:</b><br/>
+<link topic="setup_signtool">SignTool</link></p>
+</body>
+</setuptopic>
+
 <setuptopic directive="SignToolRetryCount">
 <setuptopic directive="SignToolRetryCount">
 <keyword value="signature" />
 <keyword value="signature" />
 <keyword value="digital signature" />
 <keyword value="digital signature" />
@@ -5021,7 +5036,21 @@ SignTool=byparam format c:
 <body>
 <body>
 <p>Specifies the number of times the Setup Compiler should automatically retry digital signing on any errors.</p>
 <p>Specifies the number of times the Setup Compiler should automatically retry digital signing on any errors.</p>
 <p><b>See also:</b><br/>
 <p><b>See also:</b><br/>
-<link topic="setup_signtool">SignTool</link></p>
+<link topic="setup_signtool">SignTool</link><br/>
+<link topic="setup_signtoolretrydelay">SignToolRetryDelay</link></p>
+</body>
+</setuptopic>
+
+<setuptopic directive="SignToolRetryDelay">
+<keyword value="signature" />
+<keyword value="digital signature" />
+<keyword value="code signing" />
+<setupdefault><tt>500</tt></setupdefault>
+<body>
+<p>Specifies the number of milliseconds the Setup Compiler should wait before any automatic digital signing retries specified by <link topic="setup_signtoolretrycount">SignToolRetryCount</link>.</p>
+<p><b>See also:</b><br/>
+<link topic="setup_signtool">SignTool</link><br/>
+<link topic="setup_signtoolretrycount">SignToolRetryCount</link></p>
 </body>
 </body>
 </setuptopic>
 </setuptopic>
 
 

+ 1 - 0
Projects/CompMsgs.pas

@@ -135,6 +135,7 @@ const
   SCompilerStatusSigningSourceFile = '   Signing: %s';
   SCompilerStatusSigningSourceFile = '   Signing: %s';
   SCompilerStatusSourceFileAlreadySigned = '   Skipping signing, already signed: %s';
   SCompilerStatusSourceFileAlreadySigned = '   Skipping signing, already signed: %s';
   SCompilerStatusSigning = '   Running Sign Tool command: %s';
   SCompilerStatusSigning = '   Running Sign Tool command: %s';
+  SCompilerStatusSigningWithDelay = '   Running Sign Tool command in %d milliseconds: %s';
   SCompilerStatusWillRetrySigning = '   Sign Tool command failed (%s). Will retry (%d tries left).';
   SCompilerStatusWillRetrySigning = '   Sign Tool command failed (%s). Will retry (%d tries left).';
 
 
   SCompilerSuccessfulMessage2 = 'The setup images were successfully created ' +
   SCompilerSuccessfulMessage2 = 'The setup images were successfully created ' +

+ 38 - 8
Projects/Compile.pas

@@ -156,7 +156,9 @@ type
     ssSignedUninstaller,
     ssSignedUninstaller,
     ssSignedUninstallerDir,
     ssSignedUninstallerDir,
     ssSignTool,
     ssSignTool,
+    ssSignToolMinimumTimeBetween,
     ssSignToolRetryCount,
     ssSignToolRetryCount,
+    ssSignToolRetryDelay,
     ssSlicesPerDisk,
     ssSlicesPerDisk,
     ssSolidCompression,
     ssSolidCompression,
     ssSourceDir,
     ssSourceDir,
@@ -346,7 +348,8 @@ type
     {$IFDEF UNICODE} PreLangDataList, {$ENDIF} LangDataList: TList;
     {$IFDEF UNICODE} PreLangDataList, {$ENDIF} LangDataList: TList;
     SignToolList: TList;
     SignToolList: TList;
     SignTools, SignToolsParams: TStringList;
     SignTools, SignToolsParams: TStringList;
-    SignToolRetryCount: Integer;
+    SignToolRetryCount, SignToolRetryDelay, SignToolMinimumTimeBetween: Integer;
+    LastSignCommandStartTick: DWORD;
 
 
     OutputDir, OutputBaseFilename, OutputManifestFile, SignedUninstallerDir,
     OutputDir, OutputBaseFilename, OutputManifestFile, SignedUninstallerDir,
       ExeFilename: String;
       ExeFilename: String;
@@ -497,7 +500,7 @@ type
     procedure SeparateDirective(const Line: PChar; var Key, Value: String);
     procedure SeparateDirective(const Line: PChar; var Key, Value: String);
     procedure ShiftDebugEntryIndexes(AKind: TDebugEntryKind);
     procedure ShiftDebugEntryIndexes(AKind: TDebugEntryKind);
     procedure Sign(AExeFilename: String);
     procedure Sign(AExeFilename: String);
-    procedure SignCommand(const ACommand, AParams, AExeFilename: String; const RetryCount: Integer);
+    procedure SignCommand(const ACommand, AParams, AExeFilename: String; const RetryCount, RetryDelay, MinimumTimeBetween: Integer);
     procedure WriteDebugEntry(Kind: TDebugEntryKind; Index: Integer);
     procedure WriteDebugEntry(Kind: TDebugEntryKind; Index: Integer);
     procedure WriteCompiledCodeText(const CompiledCodeText: Ansistring);
     procedure WriteCompiledCodeText(const CompiledCodeText: Ansistring);
     procedure WriteCompiledCodeDebugInfo(const CompiledCodeDebugInfo: AnsiString);
     procedure WriteCompiledCodeDebugInfo(const CompiledCodeDebugInfo: AnsiString);
@@ -4121,12 +4124,24 @@ begin
         SignTools.Add(SignTool);
         SignTools.Add(SignTool);
         SignToolsParams.Add(SignToolParams);
         SignToolsParams.Add(SignToolParams);
       end;
       end;
+    ssSignToolMinimumTimeBetween: begin
+        I := StrToIntDef(Value, -1);
+        if I < 0 then
+          Invalid;
+        SignToolMinimumTimeBetween := I;
+      end;
     ssSignToolRetryCount: begin
     ssSignToolRetryCount: begin
         I := StrToIntDef(Value, -1);
         I := StrToIntDef(Value, -1);
         if I < 0 then
         if I < 0 then
           Invalid;
           Invalid;
         SignToolRetryCount := I;
         SignToolRetryCount := I;
       end;
       end;
+    ssSignToolRetryDelay: begin
+        I := StrToIntDef(Value, -1);
+        if I < 0 then
+          Invalid;
+        SignToolRetryDelay := I;
+      end;
     ssSlicesPerDisk: begin
     ssSlicesPerDisk: begin
         I := StrToIntDef(Value, -1);
         I := StrToIntDef(Value, -1);
         if (I < 1) or (I > 26) then
         if (I < 1) or (I > 26) then
@@ -7443,11 +7458,11 @@ var
 begin
 begin
   for I := 0 to SignTools.Count - 1 do begin
   for I := 0 to SignTools.Count - 1 do begin
     SignToolIndex := FindSignToolIndexByName(SignTools[I]); //can't fail, already checked
     SignToolIndex := FindSignToolIndexByName(SignTools[I]); //can't fail, already checked
-    SignCommand(TSignTool(SignToolList[SignToolIndex]).Command, SignToolsParams[I], AExeFilename, SignToolRetryCount);
+    SignCommand(TSignTool(SignToolList[SignToolIndex]).Command, SignToolsParams[I], AExeFilename, SignToolRetryCount, SignToolRetryDelay, SignToolMinimumTimeBetween);
   end;
   end;
 end;
 end;
 
 
-procedure TSetupCompiler.SignCommand(const ACommand, AParams, AExeFilename: String; const RetryCount: Integer);
+procedure TSetupCompiler.SignCommand(const ACommand, AParams, AExeFilename: String; const RetryCount, RetryDelay, MinimumTimeBetween: Integer);
 
 
   function FmtCommand(S: PChar; const AParams, AExeFileName: String): String;
   function FmtCommand(S: PChar; const AParams, AExeFileName: String): String;
   var
   var
@@ -7489,13 +7504,20 @@ procedure TSetupCompiler.SignCommand(const ACommand, AParams, AExeFilename: Stri
     end;
     end;
   end;
   end;
   
   
-  procedure InternalSignCommand(const AFormattedCommand: String);
+  procedure InternalSignCommand(const AFormattedCommand: String;
+    const Delay: Cardinal);
   var
   var
     StartupInfo: TStartupInfo;
     StartupInfo: TStartupInfo;
     ProcessInfo: TProcessInformation;
     ProcessInfo: TProcessInformation;
     LastError, ExitCode: DWORD;
     LastError, ExitCode: DWORD;
   begin
   begin
-    AddStatus(Format(SCompilerStatusSigning, [AFormattedCommand]));
+    if Delay <> 0 then begin
+      AddStatus(Format(SCompilerStatusSigningWithDelay, [Delay, AFormattedCommand]));
+      Sleep(Delay);
+    end else
+      AddStatus(Format(SCompilerStatusSigning, [AFormattedCommand]));
+
+    LastSignCommandStartTick := GetTickCount;
 
 
     FillChar(StartupInfo, SizeOf(StartupInfo), 0);
     FillChar(StartupInfo, SizeOf(StartupInfo), 0);
     StartupInfo.cb := SizeOf(StartupInfo);
     StartupInfo.cb := SizeOf(StartupInfo);
@@ -7529,6 +7551,7 @@ procedure TSetupCompiler.SignCommand(const ACommand, AParams, AExeFilename: Stri
 
 
 var
 var
   Params, Command: String;
   Params, Command: String;
+  MinimumTimeBetweenDelay: Cardinal;
   I: Integer;
   I: Integer;
 begin
 begin
   Params := FmtCommand(PChar(AParams), '', AExeFileName);
   Params := FmtCommand(PChar(AParams), '', AExeFileName);
@@ -7536,12 +7559,18 @@ begin
   
   
   for I := 0 to RetryCount do begin
   for I := 0 to RetryCount do begin
     try
     try
-      InternalSignCommand(Command);
+      if (MinimumTimeBetween <> 0) and (LastSignCommandStartTick <> 0) then begin
+        MinimumTimeBetweenDelay := MinimumTimeBetween - (GetTickCount - LastSignCommandStartTick);
+        if MinimumTimeBetweenDelay < 0 then
+          MinimumTimeBetweenDelay := 0;
+      end else
+        MinimumTimeBetweenDelay := 0;
+      InternalSignCommand(Command, MinimumTimeBetweenDelay);
       Break;
       Break;
     except on E: Exception do
     except on E: Exception do
       if I < RetryCount then begin
       if I < RetryCount then begin
         AddStatus(Format(SCompilerStatusWillRetrySigning, [E.Message, RetryCount-I]));
         AddStatus(Format(SCompilerStatusWillRetrySigning, [E.Message, RetryCount-I]));
-        Sleep(500); //wait a little bit before retrying
+        Sleep(RetryDelay);
       end else
       end else
         raise;
         raise;
     end;
     end;
@@ -8459,6 +8488,7 @@ begin
     WizardSmallImageFile := 'compiler:WIZMODERNSMALLIMAGE.BMP';
     WizardSmallImageFile := 'compiler:WIZMODERNSMALLIMAGE.BMP';
     DefaultDialogFontName := 'Tahoma';
     DefaultDialogFontName := 'Tahoma';
     SignToolRetryCount := 2;
     SignToolRetryCount := 2;
+    SignToolRetryDelay := 500;
     SetupHeader.CloseApplicationsFilter := '*.exe,*.dll,*.chm';
     SetupHeader.CloseApplicationsFilter := '*.exe,*.dll,*.chm';
     SetupHeader.WizardImageAlphaFormat := afIgnored;
     SetupHeader.WizardImageAlphaFormat := afIgnored;
 
 

+ 2 - 0
whatsnew.htm

@@ -31,6 +31,8 @@ For conditions of distribution and use, see <a href="http://www.jrsoftware.org/f
 <li>The <tt>WizardImageFile</tt> and <tt>WizardSmallImageFile</tt> [Setup] section directives now may list multiple files. This can be used to include multiple sizes of the wizard images to avoid blurred images on high DPI systems. See the help file for a list of recommended sizes. Note: when you test this be sure to first log out and back in after any DPI change.</li>
 <li>The <tt>WizardImageFile</tt> and <tt>WizardSmallImageFile</tt> [Setup] section directives now may list multiple files. This can be used to include multiple sizes of the wizard images to avoid blurred images on high DPI systems. See the help file for a list of recommended sizes. Note: when you test this be sure to first log out and back in after any DPI change.</li>
 <li>Any [Files] entries with the <tt>deleteafterinstall</tt> flag or with <tt>DestDir</tt> set to <tt>{tmp}</tt> or a subdirectory of <tt>{tmp}</tt> are no longer included in the <tt>EstimatedSize</tt> value in the Uninstall registry key.</li>
 <li>Any [Files] entries with the <tt>deleteafterinstall</tt> flag or with <tt>DestDir</tt> set to <tt>{tmp}</tt> or a subdirectory of <tt>{tmp}</tt> are no longer included in the <tt>EstimatedSize</tt> value in the Uninstall registry key.</li>
 <li><b>Change in default behavior:</b> If [Setup] section directive <tt>DisableWelcomePage</tt> is set (which it is by default), then the title of the wizard now includes <tt>AppVerName</tt> instead of <tt>AppName</tt>, in other words: it now includes the version number of the application. If <tt>WindowVisible</tt> is set to <tt>yes</tt> this applies to the background window instead.</li>
 <li><b>Change in default behavior:</b> If [Setup] section directive <tt>DisableWelcomePage</tt> is set (which it is by default), then the title of the wizard now includes <tt>AppVerName</tt> instead of <tt>AppName</tt>, in other words: it now includes the version number of the application. If <tt>WindowVisible</tt> is set to <tt>yes</tt> this applies to the background window instead.</li>
+<li>Added new [Setup] section directive: <tt>SignToolRetryDelay</tt>, which defaults to 500. Specifies the number of milliseconds the Setup Compiler should wait before any automatic digital signing retries specified by <tt>SignToolRetryCount</tt>.</li>
+<li>Added new [Setup] section directive: <tt>SignToolMinimumTimeBetween</tt>, which defaults to 0. If not set to 0, specifies the minimum number of milliseconds that should have elapsed between consecutive digital signing actions by the Setup Compiler. For example, if set to 5000 then the Setup Compiler will perform 1 digital signing per 5 seconds at most. Can be used to avoid being rejected by rate limiting timestamp services.</li>
 <li>Added new [Setup] section directive <tt>ArchitecturesAllowed</tt> value: <tt>arm64</tt>. This can be used to not allow Setup to run on Windows 10 on ARM64. Note that Windows 10 on ARM64 only supports 32-bit (x86) binaries and therefore Setup (even in older 3s) will never install in 64-bit mode on Windows 10 on ARM64.</li>
 <li>Added new [Setup] section directive <tt>ArchitecturesAllowed</tt> value: <tt>arm64</tt>. This can be used to not allow Setup to run on Windows 10 on ARM64. Note that Windows 10 on ARM64 only supports 32-bit (x86) binaries and therefore Setup (even in older 3s) will never install in 64-bit mode on Windows 10 on ARM64.</li>
 <li>Pascal Scripting: Added new <tt>IsX86</tt>, <tt>IsX64</tt>, <tt>IsIA64</tt>, and <tt>IsARM64</tt> support functions.</li>
 <li>Pascal Scripting: Added new <tt>IsX86</tt>, <tt>IsX64</tt>, <tt>IsIA64</tt>, and <tt>IsARM64</tt> support functions.</li>
 <li><i>Fix:</i> In 5.5.9 it was no longer possible to include a drive colon in [Setup] section directive <tt>OutputManifestFile</tt>.</li>
 <li><i>Fix:</i> In 5.5.9 it was no longer possible to include a drive colon in [Setup] section directive <tt>OutputManifestFile</tt>.</li>