-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathhtdecodetoken
More file actions
executable file
·200 lines (181 loc) · 4.79 KB
/
htdecodetoken
File metadata and controls
executable file
·200 lines (181 loc) · 4.79 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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
#!/bin/bash
# Based on
# https://gist.github.com/thomasdarimont/46358bc8167fce059d83a1ebdb92b0e7
# Modified to understand WLCG Bearer Token Discovery and to have an option
# to print the algorithm in the first part of the token
usage()
{
echo 'Usage: htdecodetoken [-a] [-H] [-s|-f] [-v] [file]'
echo
echo 'Decodes a JSON Web Token'
echo ' -a: show algorithm portion of JWT'
echo ' -H: show dates in human readable format instead of epoch'
echo ' -s: skip scitokens-verify validation (cannot be used with -f)'
echo ' This is the default if stdout is not a TTY, or if scitokens-verify'
echo ' is not available in the PATH.'
echo ' -f: force scitokens-verify validation (cannot be used with -s)'
echo ' -v: enable verbose mode, showing in stderr where token came from'
echo 'File name may be "-" to read from stdin.'
echo 'If file name not given, follows WLCG Bearer Token Discovery'
echo ' which is to first try $BEARER_TOKEN, next $BEARER_TOKEN_FILE,'
echo ' and next ${XDG_RUNTIME_DIR:-/tmp}/bt_u`id -u`.'
exit 1
} >&2
decode_base64_url() {
local len=$((${#1} % 4))
local result="$1"
if [ $len -eq 2 ]; then result="$1"'=='
elif [ $len -eq 3 ]; then result="$1"'='
fi
echo "$result" | tr '_-' '/+' | base64 --decode
}
decode_jwt() {
local showalg=$1
local token=$2
if "$showalg" ; then
decode_base64_url "$(echo "$token"|cut -d. -f1)" | jq .
fi
decode_base64_url "$(echo "$token"|cut -d. -f2)" | jq .
}
human_dates() {
local wrd
local w1
local date
for wrd in "$@"; do
w1=${wrd/,/}
if [[ "$w1" =~ ^[0-9]+$ ]]; then
# field is entirely numeric
echo -n "\"$(date --date=@$w1)\""
if [ "$wrd" != "$w1" ]; then
# add the comma back
echo ','
else
echo
fi
else
echo "$wrd"
fi
done
}
# script starts here -- "main"
set -e
# If stdout is not a TTY, we should not validate the token with scitokens-verify by default
SKIPVERIFY=false
if [ ! -t 1 ]; then
SKIPVERIFY=true
fi
VERBOSE=false
SHOWALG=false
HUMANDATE=false
SKIPVERIFYFLAGSET=false
FORCEVERIFYFLAGSET=false
NUMSHIFT=0
while getopts ":vaHsf" opt; do
case "$opt" in
a)
SHOWALG=true
(( NUMSHIFT+=1 ))
;;
H)
HUMANDATE=true
(( NUMSHIFT+=1 ))
;;
s)
if "$FORCEVERIFYFLAGSET" ; then
echo "Cannot use both -s and -f options together" >&2
usage
fi
SKIPVERIFY=true
SKIPVERIFYFLAGSET=true
(( NUMSHIFT+=1 ))
;;
f)
if "$SKIPVERIFYFLAGSET" ; then
echo "Cannot use both -s and -f options together" >&2
usage
fi
SKIPVERIFY=false
FORCEVERIFYFLAGSET=true
(( NUMSHIFT+=1 ))
;;
v)
VERBOSE=true
(( NUMSHIFT+=1 ))
;;
*)
usage
esac
done
shift "$NUMSHIFT"
TOKEN=""
TOKENFILE=""
if [ $# = 0 ]; then
if [ -n "$BEARER_TOKEN" ]; then
TOKEN="$BEARER_TOKEN"
if $VERBOSE; then
echo 'Token source: $BEARER_TOKEN' >&2
fi
else
TOKENFILE="${BEARER_TOKEN_FILE:-${XDG_RUNTIME_DIR:-/tmp}/bt_u`id -u`}"
fi
elif [ $# = 1 ]; then
if [ "$1" = - ]; then
read TOKEN # from stdin
if $VERBOSE; then
echo 'Token source: stdin' >&2
fi
else
TOKENFILE="$1"
fi
else
usage
fi
if [ -n "$TOKENFILE" ]; then
if [ ! -e "$TOKENFILE" ]; then
echo "$TOKENFILE not found" >&2
exit 1
fi
# the -n is needed here for when there is no ending newline in the file
read TOKEN <$TOKENFILE || [ -n "$TOKEN" ]
if $VERBOSE; then
echo "Token source: $TOKENFILE" >&2
fi
fi
if [ -z "$TOKEN" ]; then
echo "Token is empty" >&2
usage
fi
JWT="$(decode_jwt "$SHOWALG" "$TOKEN")"
if "$HUMANDATE" ; then
READABLE="$(human_dates $JWT)"
echo $READABLE | jq .
else
echo "$JWT" | jq .
fi
RET=$?
if "$SKIPVERIFY" ; then
# If we want to skip token verification, exit now
exit $RET
fi
set +e
VERIFY="$(command -v scitokens-verify)"
if [ $? != 0 ]; then
# silently exit if scitokens-verify not found
exit
fi
# scitokens-verify from scitokens-cpp versions greater than 1.2.0
# accepts token on stdin. That's safer to use so try it first.
# The echo command is a shell builtin so it won't show up even
# temporarily in a ps list.
VERIFYOUT="$(echo $TOKEN | $VERIFY 2>&1)"
RET=$?
if [ $RET != 0 ] && [[ "$VERIFYOUT" == *"Insufficient arguments"* ]]; then
VERIFYOUT="$($VERIFY $TOKEN)"
RET=$?
fi
if [ $RET != 0 ]; then
if [ -n "$VERIFYOUT" ]; then
echo "$VERIFYOUT" >&2
fi
exit $RET
fi