Skip to content

Commit

Permalink
Better error handling and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
BertalanD committed Jun 3, 2020
1 parent d8ab2be commit 608be83
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 10 deletions.
2 changes: 1 addition & 1 deletion sssteg.1
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
.\"You should have received a copy of the GNU General Public License
.\"along with this program. If not, see <http://www.gnu.org/licenses/>.
.\"
.Dd $Mdocdate: May 30 2020 $
.Dd $Mdocdate: June 03 2020 $
.Dt SSSTEG 1
.Os
.Sh NAME
Expand Down
23 changes: 14 additions & 9 deletions sssteg.sh
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,12 @@ input_hide() {
[ "$num_files" -lt 2 ] && die "you must specify at least 2 cover files."
[ "$num_files" -lt "$threshold" ] && die "threshold can't be higher than the number of cover files."

if [ -z "${password+x}" ]; then
# password was not set
read_secret password "Choose a password to protect the secrets: "
elif [ "$password" = "-" ]; then
if [ "$password" = "-" ]; then
# password is being piped in
password="$(cat)"
elif [ -z "${password+x}" ]; then
# password was not set
read_secret password "Choose a password to protect the secrets: "
fi

[ -z "$secret" ] && [ -z "$secret_file" ] && read_secret secret "Enter the secret, up to 128 ASCII characters: "
Expand All @@ -157,7 +157,8 @@ input_hide() {
inner_hide() {
[ -d "sssteg" ] || mkdir sssteg

printf '%s' "$secret" | ssss-split -n "$num_files" -t "$threshold" -w "$label" -qx | while read -r line || exit 1; do
hex_shares="$(printf '%s' "$secret" | ssss-split -n "$num_files" -t "$threshold" -w "$label" -qx)" || die "there was an error while splitting the secret."
echo "$hex_shares" | while read -r line; do
stegofile="${PWD}/sssteg/$(basename "$1")" || die "Cannot read $1"
if echo "$line" | steghide embed -ef - -cf "$1" -sf "$stegofile" -p "$password" -q; then
msg "Saved ${stegofile}"
Expand Down Expand Up @@ -197,9 +198,10 @@ input_restore() {
if [ "$(echo "$labels" | LC_CTYPE=C wc -w)" = 1 ]; then
label_number=1
elif [ -z "$labels" ]; then
[ -d "sssteg" ] && warn "did you mean to get the stego files from the sssteg directory?"
die "no stego files were found. Maybe password is incorrect or wrong files?"
else
msg "Secrets with these labels were found:"
msg "secrets with these labels were found:"
i=0
for hex_label in $labels; do
i=$((i + 1))
Expand Down Expand Up @@ -233,16 +235,19 @@ inner_restore() {
threshold="${threshold:-$line_count}"
[ "$line_count" -lt "$threshold" ] && die "fewer stego files were found than threshold. Maybe password is incorrect?"

# a perfect pipe is split because there is no `pipefail`
if forked_ssss; then
echo "$result" | ssss-combine -t "$threshold" -qx | base16decode >"$output_file" || die "an error occurred while combining shares."
restored_hex="$(echo "$result" | ssss-combine -t "$threshold" -qx)" || die "there was an error while combining shares."
echo "$restored_hex" | tail -n 1 | base16decode >"$output_file" || die "an error occurred while writing secret."
else
echo "$result" | ssss-combine -t "$threshold" -qx 2>&1 | while IFS= read -r line || [ -n "$line" ]; do
full_output="$(echo "$result" | ssss-combine -t "$threshold" -qx 2>&1)" || die "there was an error while combining shares."
echo "$full_output" | while IFS= read -r line || [ -n "$line" ]; do
if printf "%s\n" "$line" | grep -E '^[0-9a-f]+$'; then
echo "$line"
else
echo "$line" 1>&2
fi
done | tail -n 1 | base16decode >"$output_file"
done | tail -n 1 | base16decode >"$output_file" || die "an error occurred while writing secret."
fi

[ "$output_file" = "/dev/stdout" ] || msg "Saved $output_file"
Expand Down
42 changes: 42 additions & 0 deletions tests/tests.bats
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ export secret_test_strings=( 'A very very important secret'
'\n'
'Árvíztűrő tükörfúrógép')

# Cleanup if test case was cut short (i.e. failed)
function teardown {
rmdir sssteg || true
rm out || true
rm base16decode || true
}

@test "correctly encode text to base16" {
source "$src"
for ((i=0;i<${#hex_test_strings[@]};++i)); do
Expand Down Expand Up @@ -182,3 +189,38 @@ export secret_test_strings=( 'A very very important secret'
[ "$status" = 1 ]
[ "${lines[-1]}" = "Error: you can't pipe both the secret and the password." ]
}

@test "fail if non-interactive without arguments" {
run ../sssteg.sh hide ${cover_files[@]} </dev/null
[ "$status" = 1 ]
[ "${lines[-1]}" = "Error: running in non-interactive mode, cannot ask for password." ]
}

@test "meaningful error with empty secret via command line" {
run ../sssteg.sh hide -p "password" -s "" ${cover_files[@]}
[ "$status" = 1 ]
[ "${lines[-1]}" = "Error: '-s' requires a non-empty argument." ]
}

@test "meaningful error with empty secret file" {
run ../sssteg.sh hide -p "password" -f /dev/null ${cover_files[@]}
[ "$status" = 1 ]
[ "${lines[-1]}" = "Error: there was an error while splitting the secret." ]
}

@test "meaningful error with empty secret via file" {
run ../sssteg.sh hide -p "password" -s - ${cover_files[@]} </dev/null
[ "$status" = 1 ]
[ "${lines[-1]}" = "Error: there was an error while splitting the secret." ]
}

@test "fail with different length shares" {
../sssteg.sh hide -p "password" -s "short" -t 2 ${cover_files[0]} ${cover_files[1]} ${cover_files[2]}
../sssteg.sh hide -p "password" -s "this is a super long secret" -t 2 ${cover_files[3]} ${cover_files[4]}

run ../sssteg.sh restore -p "password" -t 4 ./sssteg/*.jpg
[ "$status" = 1 ]
[ "${lines[-1]}" = "Error: there was an error while combining shares." ]

rm -r sssteg
}

0 comments on commit 608be83

Please sign in to comment.