Skip to content

Commit

Permalink
Added support for embedded command-line args and GnuPG keys to Bootst…
Browse files Browse the repository at this point in the history
…rapper
  • Loading branch information
bastianeicher committed Nov 17, 2021
1 parent 208b7d9 commit b8da7d8
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 33 deletions.
16 changes: 11 additions & 5 deletions src/Bootstrap.WinForms/App.config
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,20 @@

<!-- !!! This can be used to create a custom bootstrapper for a specific application. !!! -->

<!-- The name of the target application to bootstrap. Only relevant if app_mode is not 'none'. -->
<!-- The feed URI of the target application to bootstrap. -->
<add key="app_uri" value="" />

<!-- The name of the target application to bootstrap. -->
<add key="app_name" value="" />

<!-- The feed URI of the target application to bootstrap. Only relevant if app_mode is not 'none'. -->
<add key="app_uri" value="" />
<!-- The application bootstrapping mode to use: "run" or "integrate" -->
<add key="app_mode" value="" />

<!-- Additional command-line arguments to pass to the application (if "app_mode" is "run") or to 0install-win integrate (if "app_mode" is "integrate"). -->
<add key="app_args" value="" />

<!-- The application bootstrapping mode to use: none, run, integrate -->
<add key="app_mode" value="none" />
<!-- The GnuPG key fingerprint to trust for signing the application's feed. -->
<add key="app_fingerprint" value="" />


<!-- !!! This can be used to change the default values of Zero Install configuration options. Any existing user configuration will take precedence. !!! -->
Expand Down
16 changes: 11 additions & 5 deletions src/Bootstrap/App.config
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,20 @@
<appSettings>
<!-- !!! This can be used to create a custom bootstrapper for a specific application. !!! -->

<!-- The name of the target application to bootstrap. Only relevant if app_mode is not 'none'. -->
<!-- The feed URI of the target application to bootstrap. -->
<add key="app_uri" value="" />

<!-- The name of the target application to bootstrap. -->
<add key="app_name" value="" />

<!-- The feed URI of the target application to bootstrap. Only relevant if app_mode is not 'none'. -->
<add key="app_uri" value="" />
<!-- The application bootstrapping mode to use: "run" or "integrate" -->
<add key="app_mode" value="" />

<!-- Additional command-line arguments to pass to the application (if "app_mode" is "run") or to 0install-win integrate (if "app_mode" is "integrate"). -->
<add key="app_args" value="" />

<!-- The application bootstrapping mode to use: none, run, integrate -->
<add key="app_mode" value="none" />
<!-- The GnuPG key fingerprint to trust for signing the application's feed. -->
<add key="app_fingerprint" value="" />


<!-- !!! This can be used to change the default values of Zero Install configuration options. Any existing user configuration will take precedence. !!! -->
Expand Down
52 changes: 47 additions & 5 deletions src/Bootstrap/BootstrapProcess.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
using ZeroInstall.Services.Feeds;
using ZeroInstall.Store.Configuration;
using ZeroInstall.Store.Implementations;
using ZeroInstall.Store.Trust;

namespace ZeroInstall
{
Expand Down Expand Up @@ -179,6 +180,8 @@ public ExitCode Execute(IEnumerable<string> args)
// NOTE: This must be done before parsing command-line options, since they may manipulate Config
Config.Save();

TrustKeys();

_targetArgs.AddRange(GetEmbeddedArgs());
_targetArgs.AddRange(_options.Parse(args));

Expand All @@ -204,16 +207,55 @@ public ExitCode Execute(IEnumerable<string> args)
return (ExitCode)startInfo.Run();
}

/// <summary>
/// Adds keys for Zero Install (and optionally an app) to the <see cref="TrustDB"/>.
/// </summary>
private static void TrustKeys()
{
try
{
var trust = TrustDB.Load();
trust.TrustKey("88C8A1F375928691D7365C0259AA3927C24E4E1E", new Domain("apps.0install.net"));
if (!string.IsNullOrEmpty(EmbeddedConfig.Instance.AppFingerprint) && EmbeddedConfig.Instance.AppUri != null)
trust.TrustKey(EmbeddedConfig.Instance.AppFingerprint, new Domain(EmbeddedConfig.Instance.AppUri.Host));
trust.Save();
}
#region Error handling
catch (Exception ex)
{
Log.Error(ex);
}
#endregion
}

/// <summary>
/// Gets implicit command-line arguments based on the <see cref="EmbeddedConfig"/>, if any.
/// </summary>
private static IEnumerable<string> GetEmbeddedArgs()
=> EmbeddedConfig.Instance.AppMode switch
{
var config = EmbeddedConfig.Instance;
if (config.AppUri == null) yield break;

switch (config.AppMode)
{
BootstrapMode.Run => new[] {"run", EmbeddedConfig.Instance.AppUri.ToStringRfc()},
BootstrapMode.Integrate => new[] {"integrate", EmbeddedConfig.Instance.AppUri.ToStringRfc()},
_ => new string[0]
};
case BootstrapMode.Run:
yield return "run";
break;
case BootstrapMode.Integrate:
yield return "integrate";
break;
default:
yield break;
}

yield return config.AppUri.ToStringRfc();

if (!string.IsNullOrEmpty(config.AppArgs))
{
foreach (string arg in WindowsUtils.SplitArgs(config.AppArgs))
yield return arg;
}
}

/// <summary>
/// Handles arguments passed to the target that are also applicable to the bootstrapper.
Expand Down
52 changes: 34 additions & 18 deletions src/Bootstrap/EmbeddedConfig.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright Bastian Eicher et al.
// Licensed under the GNU Lesser Public License

using System;
using System.Configuration;
using NanoByte.Common;
using NanoByte.Common.Streams;
Expand All @@ -24,46 +23,63 @@ public class EmbeddedConfig
{
/// <summary>
/// The name of the target application to bootstrap.
/// Only relevant if <see cref="AppMode"/> is not <see cref="BootstrapMode.None"/>.
/// </summary>
public string AppName { get; }
public string? AppName { get; }

/// <summary>
/// The feed URI of the target application to bootstrap.
/// Only relevant if <see cref="AppMode"/> is not <see cref="BootstrapMode.None"/>.
/// </summary>
public FeedUri AppUri { get; }
public FeedUri? AppUri { get; }

/// <summary>
/// The application bootstrapping mode to use.
/// </summary>
public BootstrapMode AppMode { get; }

/// <summary>
/// Additional command-line arguments to pass to the application (if <see cref="AppMode"/> is <see cref="BootstrapMode.Run"/>) or <c>0install-win integrate</c> (if <see cref="AppMode"/> is <see cref="BootstrapMode.Integrate"/>).
/// </summary>
public string? AppArgs { get; }

/// <summary>
/// The GnuPG key fingerprint to trust for signing the application's feed.
/// </summary>
public string? AppFingerprint { get; }

/// <summary>
/// Loads the embedded configuration.
/// </summary>
private EmbeddedConfig()
{
var lines = typeof(EmbeddedConfig).GetEmbeddedString("EmbeddedConfig.txt").SplitMultilineText();
string[] lines = typeof(EmbeddedConfig).GetEmbeddedString("EmbeddedConfig.txt").SplitMultilineText();

try
string? ReadConfig(string key, int lineNumber, string placeholder)
{
AppUri = new(ConfigurationManager.AppSettings["app_uri"] ?? lines[0].TrimEnd());
Log.Info("Embedded config: AppUri: " + AppUri);
string setting = ConfigurationManager.AppSettings[key];
if (!string.IsNullOrEmpty(setting))
{
Log.Info($"AppSettings config: {key}: {setting}");
return setting;
}

AppName = ConfigurationManager.AppSettings["app_name"] ?? lines[1].TrimEnd();
Log.Info("Embedded config: AppName: " + AppName);
string line = lines[lineNumber].TrimEnd();
if (!string.IsNullOrEmpty(line) && !(line.Contains(placeholder) && line.StartsWith("--") && line.EndsWith("--")))
{
Log.Info($"Embedded config: {key}: {line}");
return line;
}

AppMode = GetAppMode(ConfigurationManager.AppSettings["app_mode"] ?? lines[2].TrimEnd());
Log.Info("Embedded config: AppMode: " + AppMode);
}
catch (UriFormatException)
{
// No (valid) feed URI set
return null;
}

AppUri = ReadConfig("app_uri", lineNumber: 0, nameof(AppUri))?.To(x => new FeedUri(x));
AppName = ReadConfig("app_name", lineNumber: 1, placeholder: nameof(AppName));
AppMode = GetAppMode(ReadConfig("app_mode", lineNumber: 2, placeholder: nameof(AppMode)));
AppArgs = ReadConfig("app_args", lineNumber: 3, placeholder: nameof(AppArgs));
AppFingerprint = ReadConfig("app_fingerprint", lineNumber: 4, placeholder: nameof(AppFingerprint));
}

private static BootstrapMode GetAppMode(string value)
private static BootstrapMode GetAppMode(string? value)
=> value switch
{
"run" => BootstrapMode.Run,
Expand Down
2 changes: 2 additions & 0 deletions src/Bootstrap/EmbeddedConfig.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
--------------------------------------------------------------------------------AppUri--------------------------------------------------------------------------------
----------------------------------------AppName----------------------------------------
--------------------AppMode--------------------
----------------------------------------AppArgs----------------------------------------
-------------AppFingerprint-------------

0 comments on commit b8da7d8

Please sign in to comment.