-
Notifications
You must be signed in to change notification settings - Fork 0
/
sri
executable file
·179 lines (164 loc) · 6.01 KB
/
sri
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
#!/bin/sh
#
## generate SRI checksums
#
### text formatting presets
if command -v tput > /dev/null; then
cyan=$(tput setaf 6)
err=$(tput bold)$(tput setaf 1)
magenta=$(tput setaf 5)
norm=$(tput sgr0)
ok=$(tput setaf 2)
else
cyan=''
err=''
magenta=''
norm=''
ok=''
fi
### trap
trap trapExit 1 2 3 6
### functions
displayError (){
printf "\n%sERROR: %s\n" "$err" "$2"
printf "Exiting now.%s\n\n" "$norm"
exit "$1"
}
scriptHelp (){
printf "\n%sUsage: %s%s %s[--help] [--sha256|--sha384|--sha512] %s--file '/path/to/file1 %s[/path/to/file2 ...]'%s --directory /directory/to/hash %s[--filter 'filter']%s\n\n" "$magenta" "$norm" "$scriptName" "$cyan" "$norm" "$cyan" "$norm" "$cyan" "$norm"
printf "If both '--file' and '--directory' are specified, *both* will be processed.\n\n"
printf "%s---parameters---%s\n" "$magenta" "$norm"
printf "%s-h|-?|--help%s: Show this help page\n" "$cyan" "$norm"
printf "%s-2|--sha256%s: Generate SHA256 SRI hash\n" "$cyan" "$norm"
printf "%s-3|--sha384%s: Generate SHA384 SRI hash (default)\n" "$cyan" "$norm"
printf "%s-5|--sha512%s: Generate SHA512 SRI hash\n" "$cyan" "$norm"
printf "%s-f|--file%s: Full path of the file(s) to hash. Quoted space-delimited list accepted. Wildcards NOT accepted.\n" "$cyan" "$norm"
printf "%s-d|--dir|--directory%s: Hash each file within specified directory.\n" "$cyan" "$norm"
printf "%s--filter%s: Only considered when processing a directory (-d flag). Will only hash files matching this filter. Eg: '*.css', 'file*.ext'\n\n" "$cyan" "$norm"
printf "%s---examples---%s\n" "$magenta" "$norm"
printf "Generate default SHA384 hash for styles.css located in the current directory:\n"
printf "%s./%s -f styles.css%s\n\n" "$cyan" "$scriptName" "$norm"
printf "Generate SHA512 hash for /var/www/js/script.js:\n"
printf "%s./%s -5 --file /var/www/js/script.js%s\n\n" "$cyan" "$scriptName" "$norm"
printf "Generate default SHA384 hashes for 'script.js' and 'style.css', located in different places:\n"
printf "%s./%s -f '/var/www/js/script.js /var/www/css/style.css'%s\n\n" "$cyan" "$scriptName" "$norm"
printf "Generate default SHA384 hashes for all files in ~/webpage/css/:\n"
printf "%s./%s --directory ~/webpage/css%s\n\n" "$cyan" "$scriptName" "$norm"
printf "Generate default SHA384 hashes for all files with names starting with 'foo' within /var/www/includes/:\n"
printf "%s./%s -d /var/www/includes --filter 'foo*'%s\n\n" "$cyan" "$scriptName" "$norm"
printf "Generate SHA256 hashes for all '.css' files in /var/www/css and 'script.js' in /var/www/js/:\n"
printf "%s./%s -2 -f /var/www/js/script.js -d /var/www/css --filter '*.css'%s\n\n" "$cyan" "$scriptName" "$norm"
printf "N.B. If you copy this script to somewhere in your path, like /usr/local/bin, then you can run it like any other command without having to specify a leading path ('./' in above examples):\n"
printf "%s%s -f /var/www/css/styles.css%s\n\n" "$cyan" "$scriptName" "$norm"
exit 0;
}
trapExit (){
printf "\n%sERROR: Caught signal. Exiting.%s\n\n" "$err" "$norm"
exit 99
}
### default variables
scriptName="$( basename "$0" )"
doDir=0
doFiles=0
unset hashDir
unset hashFiles
filter='*'
algo='sha384'
### check pre-requisites
if ! command -v openssl > /dev/null; then
displayError 2 'openSSL is not installed'
fi
### process startup parameters
if [ -z "$1" ]; then scriptHelp; fi
while [ $# -gt 0 ]; do
case "$1" in
-h|-\?|--help)
# display script help
scriptHelp
exit 0
;;
-2|--sha256)
# generate SRI using sha256
algo='sha256'
;;
-3|--sha384)
# generate SRI using sha384 (default)
algo='sha384'
;;
-5|--sha512)
# generate SRI using sha512
algo='sha512'
;;
-d|--dir*)
# verify directory exists
if [ -d "$2" ]; then
doDir=1
hashDir="${2%/}"
elif [ -z "$2" ]; then
displayError 1 "No directory specified."
else
displayError 1 "Directory '$2' does not exist."
fi
shift
;;
-f|--file)
# has supplied list of files
if [ -z "$2" ]; then
displayError 1 'No filename(s) specified.'
else
doFiles=1
hashFiles="$2"
fi
shift
;;
--filter)
if [ -z "$2" ]; then
displayError 1 'Filter cannot be blank.'
else
filter="$2"
fi
shift
;;
*)
# unknown option
printf "\n%sUnknown option: %s.\n" "$err" "$1"
printf "%sUse '--help' for valid options.%s\n\n" "$cyan" "$norm"
exit 1
;;
esac
shift
done
printf "\n"
### do SRI generation
if [ "$doDir" -eq 1 ]; then
for file in "$hashDir"/${filter}; do
hash=$( openssl dgst -${algo} -binary "$file" | openssl base64 -A) > /dev/null 2>&1
if [ -z "$hash" ]; then
printf "%s --> unable to generate SRI hash\n" "$file"
else
printf "%s%s --> %s%s-%s%s\n" "$magenta" "$file" "$ok" "$algo" "$hash" "$norm"
fi
done
fi
if [ "$doFiles" -eq 1 ]; then
for file in $hashFiles; do
# verify file exists, then hash it
if [ -f "$file" ]; then
hash=$( openssl dgst -${algo} -binary "$file" | openssl base64 -A) > /dev/null 2>&1
if [ -z "$hash" ]; then
printf "%s --> unable to generate SRI hash\n" "$file"
else
printf "%s%s --> %s%s-%s%s\n" "$magenta" "$file" "$ok" "$algo" "$hash" "$norm"
fi
else
printf "%s%s --> does not exist\n" "$err" "$file"
fi
done
fi
printf "\n"
exit 0
### error codes
# 0: no errors, normal execution
# 1: parameter error
# 2: cannot find openSSL binary
#EOF