diff --git a/defaults.inc b/defaults.inc index e0089a0..dd5eda1 100755 --- a/defaults.inc +++ b/defaults.inc @@ -3,7 +3,7 @@ action="${1:-}" FOLDER='/opt/idssys/ta-proxmenu' -VERS='2026.7.28-4' +VERS='2026.7.28-5' noupdate=' ' diff --git a/inc/secure-input.inc b/inc/secure-input.inc new file mode 100644 index 0000000..ea14dff --- /dev/null +++ b/inc/secure-input.inc @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +TAPM_READ_MASKED() { + local destination="$1" + local character='' + local value='' + + while IFS= read -r -s -n 1 character; do + if [[ -z "$character" ]]; then + break + fi + case "$character" in + $'\177' | $'\b') + if [[ -n "$value" ]]; then + value="${value%?}" + printf '\b \b' + fi + ;; + *) + value+="$character" + printf '*' + ;; + esac + done + printf '\n' + printf -v "$destination" '%s' "$value" +} diff --git a/proxmenu-scripts.sh b/proxmenu-scripts.sh index 352d662..338307a 100755 --- a/proxmenu-scripts.sh +++ b/proxmenu-scripts.sh @@ -8,6 +8,7 @@ source /opt/idssys/ta-proxmenu/inc/git-update.inc source /opt/idssys/ta-proxmenu/inc/ha-status.inc source /opt/idssys/ta-proxmenu/inc/post-install.inc source /opt/idssys/ta-proxmenu/inc/rmm.inc +source /opt/idssys/ta-proxmenu/inc/secure-input.inc source /opt/idssys/ta-proxmenu/inc/deploy-iso-nfs-lxc.sh source /opt/idssys/ta-proxmenu/inc/deploy-pulse-lxc.sh source /opt/idssys/ta-proxmenu/inc/virtio-helpers.inc @@ -172,8 +173,7 @@ TAPM_AUTHORIZE() { fi echo echo -en "${idsCL[LightYellow]}Paste the TAPM deployment code: ${idsCL[Default]}" - read -r -s deploycode - echo + TAPM_READ_MASKED deploycode deploycode="${deploycode^^}" if [[ ! "$deploycode" =~ ^TAPM-[0-9A-HJKMNP-TV-Z]{5}-[0-9A-HJKMNP-TV-Z]{5}$ ]]; then unset deploycode @@ -311,8 +311,7 @@ INSTALL_SCREENCONNECT() { fi TAPM_CLEAR_AUTHORIZATION echo -en "\n${idsCL[LightYellow]}Paste the URL provided from the Build Installer: ${idsCL[Default]}" - read -r -s SCURL - echo + TAPM_READ_MASKED SCURL [[ -n "$SCURL" ]] || { echo "No URL supplied."; FINISH_FAILED_ACTION; return; } if ! TAPM_CREATE_TEMP_DIR screenconnect; then unset SCURL @@ -368,8 +367,7 @@ INSTALL_RMM() { TAPM_CLEAR_AUTHORIZATION echo -en "\n${idsCL[LightYellow]}Paste the Linux Server URL provided from the Download Agent screen: ${idsCL[Default]}" - read -r -s RMMURL - echo + TAPM_READ_MASKED RMMURL [[ -n "$RMMURL" ]] || { echo "No URL supplied."; FINISH_FAILED_ACTION; return; } if ! TOKEN="$(TAPM_RMM_TOKEN_FROM_URL "$RMMURL")"; then echo "Unable to extract the RMM token from the URL." @@ -439,6 +437,7 @@ INSTALL_S1() { FINISH_FAILED_ACTION return fi + echo if ! TAPM_CREATE_TEMP_DIR sentinelone; then TAPM_CLEAR_AUTHORIZATION @@ -477,8 +476,7 @@ INSTALL_S1() { TAPM_CLEAR_AUTHORIZATION echo -en "${idsCL[LightYellow]}Paste the customers SentinelOne Site Token: ${idsCL[Default]}" - read -r -s s1token - echo + TAPM_READ_MASKED s1token [[ -n "$s1token" ]] || { TAPM_CLEAN_TEMP_DIR "$temp_dir" echo "No SentinelOne site token supplied." diff --git a/tests/test-secure-input.sh b/tests/test-secure-input.sh new file mode 100644 index 0000000..a4b1b6d --- /dev/null +++ b/tests/test-secure-input.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +set -euo pipefail + +TEST_ROOT="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd -P)" +# shellcheck source=../inc/secure-input.inc +source "${TEST_ROOT}/inc/secure-input.inc" + +masked_value='' +output_file="$(mktemp)" +trap 'rm -f "$output_file"' EXIT + +TAPM_READ_MASKED masked_value >"$output_file" <<'EOF' +TAPM-secret +EOF + +if [[ "$masked_value" != 'TAPM-secret' ]]; then + printf 'FAIL: masked input did not preserve the entered value\n' >&2 + exit 1 +fi +if [[ "$(cat "$output_file")" != '***********' ]]; then + printf 'FAIL: masked input did not display one marker per character\n' >&2 + exit 1 +fi + +printf 'PASS: masked secret input\n'