forked from bucko13/bcoin-boilerplate
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpaste.sh
More file actions
executable file
·148 lines (131 loc) · 3.76 KB
/
Copy pathpaste.sh
File metadata and controls
executable file
·148 lines (131 loc) · 3.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#!/bin/bash
# Client for paste.sh - https://paste.sh/client
#
# Install:
# cd ~/bin
# curl -O https://raw.github.com/dgl/paste.sh/master/paste.sh
# chmod +x paste.sh
#
# Usage:
# Send clipboard:
# $ paste.sh
# Send output of command:
# $ foo 2&>1 | paste.sh
# File:
# $ paste.sh some-file
#
# Public paste (shorter URL, as no encryption, limited to command line client
# for now):
# $ paste.sh -p [same usage as above]
#
# Print paste:
# $ paste.sh 'https://paste.sh/xxxxx#xxxx'
# (You need to quote or escape the URL due to the #)
HOST=https://paste.sh
TMPTMPL=paste.XXXXXXXX
die() {
echo "${1}" >&2
exit ${2:-1}
}
# Generate x bytes of randomness, then base64 encode and make URL safe
randbase64() {
openssl rand -base64 -rand /dev/urandom $1 2>/dev/null | tr '+/' '-_'
}
# Write data to a temp file and open it on given fd to avoid passing on command
# line
tmpfd() {
tmp="$(mktemp -t $TMPTMPL)"
echo "$1" > "$tmp" || die "Unable to write to temp. file."
eval "exec $2<$tmp"
rm -f $tmp || die "Unable to remove temp. file. Aborting to avoid key leak"
}
writekey() {
# The full key includes some extras for more entropy. (OpenSSL adds a salt
# too, so the ID isn't really needed, but won't hurt).
tmpfd "${id}${serverkey}${clientkey}${HOST}" 3
}
encrypt() {
local cmd arg
cmd="$1"
arg="$2"
# Generate ID, get server key
id="$(randbase64 6)"
# TODO: Retry if the error is the id is already taken
serverkey=$(curl -fsS "$HOST/new?id=$id")
# Yes, this is essentially another salt
[[ -n ${serverkey} ]] || die "Failed getting server salt"
# Generate client key (nothing stopping you changing this, this seemed like a
# reasonable trade off; 144 bits)
clientkey="$(randbase64 18)"
if [[ $public == 1 ]]; then
clientkey=
id="p${id}"
fi
file=$(mktemp -t $TMPTMPL)
trap 'rm -f "${file}"' EXIT
# It would be nice to use PBKDF2 or just more iterations of the key derivation
# function, but the OpenSSL command line tool can't do that.
writekey
$cmd "$arg" \
| openssl enc -aes-256-cbc -md sha512 -pass fd:3 -base64 > "${file}"
# Get rid of the temp. file once server supports HTTP/1.1 chunked uploads
# correctly.
curl -sS -0 -H "X-Server-Key: ${serverkey}" -T "${file}" "$HOST/${id}" \
|| die "Failed pasting data"
echo -n "$HOST/${id}"
if [[ -n $clientkey ]]; then
echo "#${clientkey}"
else
echo
fi
}
decrypt() {
url=$(cut -d# -f1 <<< "$1")
id=$(cut -d/ -f4 <<< "${url}")
clientkey=$(cut -sd# -f2 <<< "$1")
tmpfile=$(mktemp -t $TMPTMPL)
trap 'rm -f "${tmpfile}"' EXIT
curl -fsS -o "${tmpfile}" "${url}.txt" || exit $?
serverkey=$(head -n1 "${tmpfile}")
writekey
tail -n +2 "${tmpfile}" | \
openssl enc -d -aes-256-cbc -md sha512 -pass fd:3 -base64
exit $?
}
openssl version &>/dev/null || die "Please install OpenSSL" 127
curl --version &>/dev/null || die "Please install curl" 127
# Try to use memory if we can (Linux, probably) and the user hasn't set TMPDIR
if [ -z "$TMPDIR" -a -w /dev/shm ]; then
export TMPDIR=/dev/shm
fi
# What are we doing?
public=0
main() {
if [[ $# -gt 0 ]]; then
if [[ ${1:0:8} = https:// ]]; then
decrypt "$1"
elif [ -e "${1}" -o "${1}" == "-" ]; then
# File (also handle "-", via cat)
if [ "${1}" != "-" -a "$(stat -c %s "${1}")" -gt $[640 * 1024] ]; then
die "${1}: File too big"
fi
encrypt "cat --" "$1"
elif [[ ${1} == "-p" ]]; then
shift
public=1
main "$@"
else
echo "$1: No such file and not a https URL"
exit 1
fi
elif ! [ -t 0 ]; then # Something piped to us, read it
encrypt cat "-"
else # No input, read clipboard
if [[ $(uname) = Darwin ]]; then
encrypt pbpaste
else
encrypt xsel "-o"
fi
fi
}
main "$@"