Skip to content

Commit 48de191

Browse files
committed
Add authentication to the command line client
Sadly even OpenSSL's newer "openssl mac" subcommand needs the key to be provided on the command line. Give up and shell out to Perl and implement HMAC ourselves. Probably a clue this shouldn't be a shell script. However the domain *is* paste.sh.
1 parent d8235bb commit 48de191

File tree

1 file changed

+25
-2
lines changed

1 file changed

+25
-2
lines changed

paste.sh

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,10 @@ encrypt() {
9090
(echo -n "${header}${header:+$'\n\n'}"; $cmd "$arg") \
9191
| 3<<<"$(writekey)" openssl enc -aes-256-cbc -md sha512 -pass fd:3 -iter 1 -base64 > "${file}"
9292

93-
# Get rid of the temp file once server supports HTTP/1.1 chunked uploads
94-
# correctly.
93+
et="\"$(etag <"${file}")\""
9594
(curl -sS -o /dev/fd/3 -H "X-Server-Key: ${serverkey}" \
9695
-H "Content-type: text/vnd.paste.sh-${VERSION}" \
96+
-H "ETag: $et" \
9797
-T "${file}" "${HOST}/${id}" -b "$pasteauth" -w '%{http_code}' \
9898
| grep -q 200) 3>&1 || exit $?
9999

@@ -116,6 +116,15 @@ decrypt() {
116116
-D "${headfile}" "${url}.txt" || exit $?
117117
serverkey=$(head -n1 "${tmpfile}")
118118
ct="$(grep -i '^content-type:' ${headfile} | cut -d':' -f2)"
119+
120+
et="$(grep -i '^etag:' ${headfile} | cut -d':' -f2 | tr -d '\015 ')"
121+
if [[ -n "$et" ]]; then
122+
expected_et="\"$(etag <"${tmpfile}")\""
123+
if [[ "$et" != "$expected_et" ]]; then
124+
die "Decryption failed (Invalid decryption key or damaged data)" 1
125+
fi
126+
fi
127+
119128
remove=cat
120129
ITERS="-iter 1"
121130
if [[ $ct = *text/plain* ]]; then
@@ -145,6 +154,20 @@ fsize() {
145154
fi
146155
}
147156

157+
etag() {
158+
# "61757468206b6579" is "auth key"
159+
openssl base64 -d | hmac "$(writekey | hmac "61757468206b6579")" "-binary" | openssl base64 -A | sed 's/==$//'
160+
}
161+
162+
# Implement HMAC on top of OpenSSL's digest command, as openssl's CLI support
163+
# for generating a HMAC needs the key on the command line.
164+
hmac() {
165+
local key="$1"
166+
local opts="$2"
167+
key="$key" perl -e'print join("", map { chr hex } $ENV{key} =~ /(..)/g)^"\x36"x128; print join "", <>' | openssl sha512 -binary | \
168+
key="$key" perl -e'print join("", map { chr hex } $ENV{key} =~ /(..)/g)^"\x5c"x128; print join "", <>' | openssl sha512 $opts
169+
}
170+
148171
# Try to use memory if we can (Linux, probably) and the user hasn't set TMPDIR
149172
if [ -z "$TMPDIR" -a -w /dev/shm ]; then
150173
export TMPDIR=/dev/shm

0 commit comments

Comments
 (0)