Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add variable enumeration for bash #1441

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion source/Calamari.Common/FeatureToggles/FeatureToggle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public enum FeatureToggle {
KubernetesLiveObjectStatusFeatureToggle,
KubernetesAuthAwsCliWithExecFeatureToggle,
ForceUtf8ZipFileDecodingFeatureToggle,
DisableFSharpScriptExecutionFeatureToggle
DisableFSharpScriptExecutionFeatureToggle,
BashParametersArrayFeatureToggle
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Text;
using Calamari.Common.Features.Processes;
using Calamari.Common.Features.Scripts;
using Calamari.Common.FeatureToggles;
using Calamari.Common.Plumbing;
using Calamari.Common.Plumbing.Extensions;
using Calamari.Common.Plumbing.FileSystem;
Expand Down Expand Up @@ -42,8 +43,18 @@ public static string PrepareConfigurationFile(string workingDirectory, IVariable

var builder = new StringBuilder(BootstrapScriptTemplate);
var encryptedVariables = EncryptVariables(variables);

var variableString = GetEncryptedVariablesKvp(variables);

builder.Replace("#### VariableDeclarations ####", string.Join(LinuxNewLine, GetVariableSwitchConditions(encryptedVariables)));

builder.Replace("#### BashParametersArrayFeatureToggle ####", FeatureToggle.BashParametersArrayFeatureToggle.IsEnabled(variables) ? "true" : "false");
if (FeatureToggle.BashParametersArrayFeatureToggle.IsEnabled(variables))
{
builder.Replace("#### VARIABLESTRING.IV ####", variableString.iv);
builder.Replace("#### VARIABLESTRING.ENCRYPTED ####", variableString.encrypted);
}

using (var file = new FileStream(configurationFile, FileMode.CreateNew, FileAccess.Write))
using (var writer = new StreamWriter(file, Encoding.ASCII))
{
Expand All @@ -54,6 +65,29 @@ public static string PrepareConfigurationFile(string workingDirectory, IVariable
File.SetAttributes(configurationFile, FileAttributes.Hidden);
return configurationFile;
}

static string EncodeAsHex(string value)
{
var bytes = Encoding.UTF8.GetBytes(value);
return BitConverter.ToString(bytes).Replace("-", "");
}

static (string encrypted, string iv) GetEncryptedVariablesKvp(IVariables variables)
{
var sb = new StringBuilder();
foreach (var variable in variables.Where(v => !ScriptVariables.IsLibraryScriptModule(v.Key)))
{
var value = variable.Value ?? "nul";
sb.Append($"{EncodeAsHex(variable.Key)}").Append("$").AppendLine(EncodeAsHex(value));
}

var encrypted = VariableEncryptor.Encrypt(sb.ToString());
var rawEncrypted = AesEncryption.ExtractIV(encrypted, out var iv);
return (
Convert.ToBase64String(rawEncrypted),
ToHex(iv)
);
}

static IList<EncryptedVariable> EncryptVariables(IVariables variables)
{
Expand Down
82 changes: 81 additions & 1 deletion source/Calamari.Common/Features/Scripting/Bash/Bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -263,4 +263,84 @@ function log_environment_information
echo "##octopus[stdout-default]"
}

log_environment_information
log_environment_information

function decrypt_and_parse_variables {
local encrypted="$1"
local iv="$2"

local decrypted
decrypted=$(decrypt_variable "$encrypted" "$iv")
declare -gA octopus_parameters=()

key_byte_lengths=()
value_byte_lengths=()
concatenated_hex=""
while IFS='$' read -r hex_key hex_value; do
hex_value="${hex_value//$'\n'/}"
key_byte_len=$(( ${#hex_key} / 2 ))
value_byte_len=$(( ${#hex_value} / 2 ))
key_byte_lengths+=("$key_byte_len")
value_byte_lengths+=("$value_byte_len")
concatenated_hex+="${hex_key}${hex_value}"
done <<< "$decrypted"

decoded_output=$(hex_to_string "$concatenated_hex")

exec 3< <(printf "%s" "$decoded_output")

for idx in "${!key_byte_lengths[@]}"; do
key_byte_len="${key_byte_lengths[idx]}"
value_byte_len="${value_byte_lengths[idx]}"

LC_ALL=C read -r -N "$key_byte_len" decoded_key <&3
LC_ALL=C read -r -N "$value_byte_len" decoded_value <&3

[[ "$decoded_value" == "nul" ]] && decoded_value=""
octopus_parameters["$decoded_key"]="$decoded_value"
done

exec 3<&-
}

hex_to_string() {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we use xxd this can be removed. xxd is generally included with vim and should be available on most Linux machines but is not generally available on Mac.

local hex_string="$1"
hex_string="${hex_string//[$'\t\r\n ']/}"
if (( ${#hex_string} % 2 )); then
hex_string="0$hex_string"
fi
echo "$hex_string" | awk '
BEGIN {
hexmap["0"] = 0; hexmap["1"] = 1; hexmap["2"] = 2; hexmap["3"] = 3;
hexmap["4"] = 4; hexmap["5"] = 5; hexmap["6"] = 6; hexmap["7"] = 7;
hexmap["8"] = 8; hexmap["9"] = 9; hexmap["A"] = 10; hexmap["B"] = 11;
hexmap["C"] = 12; hexmap["D"] = 13; hexmap["E"] = 14; hexmap["F"] = 15;
hexmap["a"] = 10; hexmap["b"] = 11; hexmap["c"] = 12; hexmap["d"] = 13;
hexmap["e"] = 14; hexmap["f"] = 15;
}
function hex2dec(hex, i, n, d) {
n = 0;
for (i = 1; i <= length(hex); i++) {
d = substr(hex, i, 1);
n = n * 16 + hexmap[d];
}
return n;
}
{
for (i = 1; i <= length($0); i += 2)
printf "%c", hex2dec(substr($0, i, 2));
}'
}

bashParametersArrayFeatureToggle=#### BashParametersArrayFeatureToggle ####

if [ "$bashParametersArrayFeatureToggle" = true ]; then
if (( ${BASH_VERSINFO[0]:-0} > 4 || (${BASH_VERSINFO[0]:-0} == 4 && ${BASH_VERSINFO[1]:-0} > 2) )); then
decrypt_and_parse_variables "#### VARIABLESTRING.ENCRYPTED ####" "#### VARIABLESTRING.IV ####"
else
echo "Bash version 4.2 or later is required to use octopus_parameters"
fi
fi



Loading