Compare commits

...

2 Commits

Author SHA1 Message Date
~lucidiot 316136ba65 Allow an arbitrary amount of CTL .cab URIs
This makes this tool a little bit more future proof
by enabling users to configure it to download not just
two specific files from anywhere, but any amount of files
from anywhere, in case they need more or less CTLs.
2022-11-08 06:31:01 +01:00
~lucidiot 128f9a3849 Almost-working cert installation
Everything works, but when reinstalling a certificate
trust list that already exists, the certificate wizard
still shows an UI despite being told not to.
2022-11-06 00:03:51 +01:00
11 changed files with 757 additions and 4 deletions

View File

@ -11,6 +11,9 @@
<AssemblyName>Lucidiot.CertBoat</AssemblyName>
<StartupObject>Lucidiot.CertBoat.Program</StartupObject>
<ApplicationIcon>icon.ico</ApplicationIcon>
<SupportUrl>https://tildegit.org/lucidiot/CertBoat/issues/</SupportUrl>
<ProductName>CertBoat</ProductName>
<PublisherName>lucidiot</PublisherName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -30,17 +33,55 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Deployment.Compression, Version=3.0.0.0, Culture=neutral, PublicKeyToken=ce35f76fcda82bad, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\vendor\Microsoft.Deployment.Compression.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Deployment.Compression.Cab, Version=3.0.0.0, Culture=neutral, PublicKeyToken=ce35f76fcda82bad, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\vendor\Microsoft.Deployment.Compression.Cab.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="NativeMethods.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
<Compile Include="Strings.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Strings.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<Content Include="icon.ico" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Strings.resx">
<SubType>Designer</SubType>
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Strings.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
<Visible>False</Visible>
<ProductName>.NET Framework 2.0</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

View File

@ -0,0 +1,87 @@
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
namespace Lucidiot.CertBoat {
[Flags]
internal enum CryptUIWizardFlags {
None = 0x0000,
NoUI = 0x0001,
IgnoreNoUIFlagForCSPs = 0x0002,
NoUIExceptCSP = 0x0003,
NoChangeDestStore = 0x00010000,
AllowCert = 0x00020000,
AllowCRL = 0x00040000,
AllowCTL = 0x00080000,
ToLocalMachine = 0x00100000,
ToCurrentUser = 0x00200000,
RemoteDestStore = 0x00400000
}
internal enum CryptUIImportSubject {
File = 1,
CertContext = 2,
CTLContext = 3,
CRLContext = 4,
CertStore = 5
}
[Flags]
internal enum CryptUIImportPFXFlags {
None = 0x0000,
Exportable = 0x0020,
UserProtected = 0x0001,
MachineKeyset = 0x0002,
UserKeyset = 0x1000
}
[StructLayout(LayoutKind.Sequential)]
internal struct CryptUIWizardFileImportInfo {
uint Size;
CryptUIImportSubject Subject;
[MarshalAs(UnmanagedType.LPWStr)]
string FileName;
CryptUIImportPFXFlags PFXFlags;
[MarshalAs(UnmanagedType.LPWStr)]
string Password;
internal CryptUIWizardFileImportInfo(string FileName) {
this.Subject = CryptUIImportSubject.File;
this.FileName = FileName;
this.PFXFlags = CryptUIImportPFXFlags.None;
this.Password = "";
this.Size = 0;
this.Size = (uint)Marshal.SizeOf(this);
}
}
internal static class NativeMethods {
[DllImport("cryptui.dll", SetLastError = true)]
private static extern bool CryptUIWizImport(
uint dwFlags,
IntPtr hwndParent,
[MarshalAs(UnmanagedType.LPWStr)] string pwszWizardTitle,
ref CryptUIWizardFileImportInfo pImportSrc,
IntPtr hDestCertStore);
internal static void ImportSTL(string fileName) {
CryptUIWizardFileImportInfo info = new CryptUIWizardFileImportInfo(fileName);
if (!CryptUIWizImport(
(uint) (CryptUIWizardFlags.NoUI | CryptUIWizardFlags.AllowCRL | CryptUIWizardFlags.AllowCTL | CryptUIWizardFlags.NoChangeDestStore),
// Parent window handle ignored because there is no UI
IntPtr.Zero,
// Window title ignored because there is no UI
null,
ref info,
// No destination store: the system guesses the best option
IntPtr.Zero
)) {
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
}
}

View File

@ -1,8 +1,187 @@
using System;
using System.IO;
using System.Net;
using System.Reflection;
using Microsoft.Deployment.Compression.Cab;
using System.Collections.Generic;
using Microsoft.Deployment.Compression;
namespace Lucidiot.CertBoat {
class Program {
static void Main(string[] args) {
public class ExtractException : Exception {
public ExtractException() : base() {
}
public ExtractException(string message)
: base(message) {
}
}
static class Program {
static int Main(string[] args) {
bool showHelp = false, showVersion = false, doUpdate = false, doCreateTask = false, doRemoveTask = false;
foreach (string rawArg in args) {
// One day, I will write a cool command line parser, but today is not that day.
string arg = rawArg.TrimStart(new char[] { '-', '/' });
if (arg.Equals("?", StringComparison.InvariantCultureIgnoreCase) || arg.Equals("help", StringComparison.InvariantCultureIgnoreCase))
showHelp = true;
else if (arg.Equals("version", StringComparison.InvariantCultureIgnoreCase))
showVersion = true;
else if (arg.Equals("update", StringComparison.InvariantCultureIgnoreCase))
doUpdate = true;
else if (arg.Equals("createscheduledtask", StringComparison.InvariantCultureIgnoreCase)
|| arg.Equals("create-scheduled-task", StringComparison.InvariantCultureIgnoreCase))
doCreateTask = true;
else if (arg.Equals("removescheduledtask", StringComparison.InvariantCultureIgnoreCase)
|| arg.Equals("remove-scheduled-task", StringComparison.InvariantCultureIgnoreCase))
doRemoveTask = true;
else {
Console.WriteLine(String.Format(Strings.UnknownArgument, rawArg));
PrintUsage();
return 2;
}
}
if (showHelp) {
PrintUsage();
return 0;
}
if (showVersion) {
Console.WriteLine(Assembly.GetExecutingAssembly().GetName().Version);
return 0;
}
// Creating and removing the scheduled tasks does not make sense; resolve this by only removing the scheduled tasks.
if (doCreateTask && doRemoveTask)
doCreateTask = false;
// Nothing was specified: update certs by default.
if (!doUpdate && !doCreateTask && !doRemoveTask)
doUpdate = true;
if (doCreateTask && !CreateScheduledTask())
return 1;
if (doRemoveTask && !RemoveScheduledTask())
return 1;
if (doUpdate && !Update())
return 1;
return 0;
}
static void PrintUsage() {
Console.WriteLine(String.Format(
Strings.Help,
Environment.GetCommandLineArgs()[0]
));
}
/// <summary>
/// Update the system certificate stores from the downloaded certificate trust lists.
/// </summary>
/// <returns>Whether or not at least one list was successfully downloaded and applied.</returns>
static bool Update() {
if (Properties.Settings.Default.CabinetUris.Count < 1) {
Console.WriteLine(Strings.NoCabinetUris);
}
bool success = false;
foreach (string uriString in Properties.Settings.Default.CabinetUris) {
Uri uri;
try {
uri = new Uri(uriString);
} catch (UriFormatException e) {
Console.WriteLine(String.Format(Strings.InvalidUri, e.ToString()));
continue;
}
success |= Update(uri);
}
return success;
}
private static bool Update(Uri uri) {
string cabpath, filepath;
try {
cabpath = Download(uri);
} catch (Exception e) {
Console.WriteLine(String.Format(Strings.DownloadFailure, uri, e.ToString()));
return false;
}
try {
filepath = ExtractSingleFileCabinet(cabpath);
} catch (Exception e) {
Console.WriteLine(String.Format(Strings.ExtractFailure, uri, e.ToString()));
return false;
} finally {
if (File.Exists(cabpath))
File.Delete(cabpath);
}
try {
NativeMethods.ImportSTL(filepath);
} catch (Exception e) {
Console.WriteLine(String.Format(Strings.ApplyFailure, uri, e.ToString()));
return false;
} finally {
if (File.Exists(filepath))
File.Delete(filepath);
}
Console.WriteLine(String.Format(Strings.ApplySuccess, uri));
return true;
}
/// <summary>
/// Perform a GET request on a URI and store the response body into a temporary file.
/// </summary>
/// <param name="uri">URI to make a GET request on.</param>
/// <returns>Path to the temporary file.</returns>
private static string Download(Uri uri) {
WebClient client = new WebClient();
client.Headers.Add(
HttpRequestHeader.UserAgent,
String.Format(
Properties.Settings.Default.UserAgent,
Assembly.GetExecutingAssembly().GetName().Version
)
);
string path = Path.GetTempFileName();
client.DownloadFile(uri, path);
return path;
}
/// <summary>
/// Extract the file of a cabinet file that only includes a single-file.
/// </summary>
/// <param name="cabPath">Path to the cabinet file.</param>
/// <returns>Path to the extracted file.</returns>
private static string ExtractSingleFileCabinet(string cabPath) {
CabInfo info = new CabInfo(cabPath);
IList<CabFileInfo> files = info.GetFiles();
if (files.Count < 1)
throw new ExtractException(Strings.ExtractFileNotFound);
if (files.Count > 1)
throw new ExtractException(Strings.ExtractMultipleFilesFound);
string destPath = Path.GetTempFileName();
info.UnpackFile(files[0].Name, destPath);
return destPath;
}
/// <summary>
/// Set up a task in the Task Scheduler to automatically update the certificates once a day.
/// </summary>
static bool CreateScheduledTask() {
throw new NotImplementedException();
}
/// <summary>
/// Remove any existing task related to this program from the Task Scheduler.
/// </summary>
static bool RemoveScheduledTask() {
throw new NotImplementedException();
}
}

View File

@ -0,0 +1,48 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.8797
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Lucidiot.CertBoat.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "8.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("CertBoat/{0}")]
public string UserAgent {
get {
return ((string)(this["UserAgent"]));
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute(@"<?xml version=""1.0"" encoding=""utf-16""?>
<ArrayOfString xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
<string>http://ctldl.windowsupdate.com/msdownload/update/v3/static/trustedr/en/authrootstl.cab</string>
<string>http://ctldl.windowsupdate.com/msdownload/update/v3/static/trustedr/en/disallowedcertstl.cab</string>
</ArrayOfString>")]
public global::System.Collections.Specialized.StringCollection CabinetUris {
get {
return ((global::System.Collections.Specialized.StringCollection)(this["CabinetUris"]));
}
}
}
}

View File

@ -0,0 +1,16 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="Lucidiot.CertBoat.Properties" GeneratedClassName="Settings">
<Profiles />
<Settings>
<Setting Name="UserAgent" Type="System.String" Scope="Application">
<Value Profile="(Default)">CertBoat/{0}</Value>
</Setting>
<Setting Name="CabinetUris" Type="System.Collections.Specialized.StringCollection" Scope="Application">
<Value Profile="(Default)">&lt;?xml version="1.0" encoding="utf-16"?&gt;
&lt;ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
&lt;string&gt;http://ctldl.windowsupdate.com/msdownload/update/v3/static/trustedr/en/authrootstl.cab&lt;/string&gt;
&lt;string&gt;http://ctldl.windowsupdate.com/msdownload/update/v3/static/trustedr/en/disallowedcertstl.cab&lt;/string&gt;
&lt;/ArrayOfString&gt;</Value>
</Setting>
</Settings>
</SettingsFile>

175
Lucidiot.CertBoat/Strings.Designer.cs generated Normal file
View File

@ -0,0 +1,175 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.8797
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Lucidiot.CertBoat {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Strings {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Strings() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Lucidiot.CertBoat.Strings", typeof(Strings).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to Installation of certificates from {0} failed:
///{1}.
/// </summary>
internal static string ApplyFailure {
get {
return ResourceManager.GetString("ApplyFailure", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Certificates have been updated from {0} successfully..
/// </summary>
internal static string ApplySuccess {
get {
return ResourceManager.GetString("ApplySuccess", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Download of {0} failed:
///{1}.
/// </summary>
internal static string DownloadFailure {
get {
return ResourceManager.GetString("DownloadFailure", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Extraction from {0} failed:
///{1}.
/// </summary>
internal static string ExtractFailure {
get {
return ResourceManager.GetString("ExtractFailure", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to No files found in cabinet file..
/// </summary>
internal static string ExtractFileNotFound {
get {
return ResourceManager.GetString("ExtractFileNotFound", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Multiple files found in cabinet file..
/// </summary>
internal static string ExtractMultipleFilesFound {
get {
return ResourceManager.GetString("ExtractMultipleFilesFound", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Compressed file is too large to be uncompressed..
/// </summary>
internal static string ExtractTooLarge {
get {
return ResourceManager.GetString("ExtractTooLarge", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Root CA certificates and certificate revocations updater for Windows 2000 and XP.
///
///Usage: {0} [/help | /?] [/version] [/update] [/createScheduledTask] [/removeScheduledTask]
///
////help, /? Show this help and exit.
////version Show the program&apos;s version and exit.
////update Download the latest Certificate Trust Lists from
/// Windows Update and apply them to the system&apos;s
/// certificate store.
////createScheduledTask Create and enable a [rest of string was truncated]&quot;;.
/// </summary>
internal static string Help {
get {
return ResourceManager.GetString("Help", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The string &quot;{0}&quot; could not be interpreted as a valid URI and cannot be downloaded.
///{1}.
/// </summary>
internal static string InvalidUri {
get {
return ResourceManager.GetString("InvalidUri", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The certificate trust lists cabinet URIs configuration is empty. No certificate updates can be performed..
/// </summary>
internal static string NoCabinetUris {
get {
return ResourceManager.GetString("NoCabinetUris", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Unknown argument &quot;{0}&quot;..
/// </summary>
internal static string UnknownArgument {
get {
return ResourceManager.GetString("UnknownArgument", resourceCulture);
}
}
}
}

View File

@ -0,0 +1,182 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ApplyFailure" xml:space="preserve">
<value>Installation of certificates from {0} failed:
{1}</value>
<comment>One of the CTLs could not be installed into the system's certificate store. {0} is the path to the CTL and {1} is the text representation of the exception that was thrown.</comment>
</data>
<data name="ApplySuccess" xml:space="preserve">
<value>Certificates have been updated from {0} successfully.</value>
<comment>A certificate trust list was successfully downloaded, extracted and installed into the system's certificate store. {0} is the URL that was downloaded.</comment>
</data>
<data name="DownloadFailure" xml:space="preserve">
<value>Download of {0} failed:
{1}</value>
<comment>One of the files could not be downloaded. {0} is replaced with the URL and {1} is the text representation of the exception that was thrown.</comment>
</data>
<data name="ExtractFailure" xml:space="preserve">
<value>Extraction from {0} failed:
{1}</value>
<comment>An STL file could not be extracted from a CAB file. {0} is the URL of the downloaded CAB file and {1} is the text representation of the exception that was thrown.</comment>
</data>
<data name="ExtractFileNotFound" xml:space="preserve">
<value>No files found in cabinet file.</value>
<comment>A message for an exception thrown when an extraction failed because the cabinet file contains 0 files.</comment>
</data>
<data name="ExtractMultipleFilesFound" xml:space="preserve">
<value>Multiple files found in cabinet file.</value>
<comment>A message for an exception thrown when an extraction failed because the cabinet file contains more than one file.</comment>
</data>
<data name="ExtractTooLarge" xml:space="preserve">
<value>Compressed file is too large to be uncompressed.</value>
<comment>A message for an exception thrown when an extraction failed because the compressed file is too large to be handled by CertBoat.</comment>
</data>
<data name="Help" xml:space="preserve">
<value>Root CA certificates and certificate revocations updater for Windows 2000 and XP.
Usage: {0} [/help | /?] [/version] [/update] [/createScheduledTask] [/removeScheduledTask]
/help, /? Show this help and exit.
/version Show the program's version and exit.
/update Download the latest Certificate Trust Lists from
Windows Update and apply them to the system's
certificate store.
/createScheduledTask Create and enable a task in the Task Scheduler to
download the latest Certificate Trust Lists and
apply them to the system's certificate store.
/removeScheduledTask Remove any existing tasks in the Task Scheduler
related to this program.
UNIX-style arguments are also accepted (--help, -?, etc.).</value>
</data>
<data name="InvalidUri" xml:space="preserve">
<value>The string "{0}" could not be interpreted as a valid URI and cannot be downloaded.
{1}</value>
<comment>A string set in the CabinetUris property in the application's XML configuration did not match a valid URI format. {0} is the offending string and {1} is the text representation of the exception that was thrown.</comment>
</data>
<data name="NoCabinetUris" xml:space="preserve">
<value>The certificate trust lists cabinet URIs configuration is empty. No certificate updates can be performed.</value>
<comment>The CabinetUris property in the application's XML configuration has been set to an empty list, and no certificates will be updated at all.</comment>
</data>
<data name="UnknownArgument" xml:space="preserve">
<value>Unknown argument "{0}".</value>
<comment>An unknown command line argument was set. {0} is the offending argument.</comment>
</data>
</root>

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="Lucidiot.CertBoat.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<applicationSettings>
<Lucidiot.CertBoat.Properties.Settings>
<setting name="UserAgent" serializeAs="String">
<value>CertBoat/{0}</value>
</setting>
<setting name="CabinetUris" serializeAs="Xml">
<value>
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<string>http://ctldl.windowsupdate.com/msdownload/update/v3/static/trustedr/en/authrootstl.cab</string>
<string>http://ctldl.windowsupdate.com/msdownload/update/v3/static/trustedr/en/disallowedcertstl.cab</string>
</ArrayOfString>
</value>
</setting>
</Lucidiot.CertBoat.Properties.Settings>
</applicationSettings>
</configuration>

Binary file not shown.

Binary file not shown.

1
vendor/README.md vendored Normal file
View File

@ -0,0 +1 @@
Those DLLs were found in [this NuGet package](https://www.nuget.org/packages/MSFTCompressionCab/), which does not state a license. They appear to have originally been part of the [WiX toolset](https://wixtoolset.org).