Annotation of /trunk/openssl-c_rehash/openssl-c_rehash.sh
Parent Directory | Revision Log
Revision 2875 -
(hide annotations)
(download)
(as text)
Wed Jul 29 07:35:57 2015 UTC (8 years, 10 months ago) by niro
File MIME type: application/x-sh
File size: 4270 byte(s)
Wed Jul 29 07:35:57 2015 UTC (8 years, 10 months ago) by niro
File MIME type: application/x-sh
File size: 4270 byte(s)
-initial import
1 | niro | 2875 | #!/bin/sh |
2 | # | ||
3 | # Ben Secrest <blsecres@gmail.com> | ||
4 | # | ||
5 | # sh c_rehash script, scan all files in a directory | ||
6 | # and add symbolic links to their hash values. | ||
7 | # | ||
8 | # based on the c_rehash perl script distributed with openssl | ||
9 | # | ||
10 | # LICENSE: See OpenSSL license | ||
11 | # ^^acceptable?^^ | ||
12 | # | ||
13 | # see: http://cvs.pld-linux.org/cgi-bin/viewvc.cgi/cvs/packages/openssl/openssl-c_rehash.sh?view=log | ||
14 | # | ||
15 | |||
16 | # default certificate location | ||
17 | DIR=/etc/openssl | ||
18 | |||
19 | # for filetype bitfield | ||
20 | IS_CERT=$(( 1 << 0 )) | ||
21 | IS_CRL=$(( 1 << 1 )) | ||
22 | |||
23 | |||
24 | # check to see if a file is a certificate file or a CRL file | ||
25 | # arguments: | ||
26 | # 1. the filename to be scanned | ||
27 | # returns: | ||
28 | # bitfield of file type; uses ${IS_CERT} and ${IS_CRL} | ||
29 | # | ||
30 | check_file() | ||
31 | { | ||
32 | local IS_TYPE=0 | ||
33 | |||
34 | # make IFS a newline so we can process grep output line by line | ||
35 | local OLDIFS=${IFS} | ||
36 | IFS=$( printf "\n" ) | ||
37 | |||
38 | # XXX: could be more efficient to have two 'grep -m' but is -m portable? | ||
39 | for LINE in $( grep '^-----BEGIN .*-----' ${1} ) | ||
40 | do | ||
41 | if echo ${LINE} \ | ||
42 | | grep -q -E '^-----BEGIN (X509 |TRUSTED )?CERTIFICATE-----' | ||
43 | then | ||
44 | IS_TYPE=$(( ${IS_TYPE} | ${IS_CERT} )) | ||
45 | |||
46 | if [ $(( ${IS_TYPE} & ${IS_CRL} )) -ne 0 ] | ||
47 | then | ||
48 | break | ||
49 | fi | ||
50 | elif echo ${LINE} | grep -q '^-----BEGIN X509 CRL-----' | ||
51 | then | ||
52 | IS_TYPE=$(( ${IS_TYPE} | ${IS_CRL} )) | ||
53 | |||
54 | if [ $(( ${IS_TYPE} & ${IS_CERT} )) -ne 0 ] | ||
55 | then | ||
56 | break | ||
57 | fi | ||
58 | fi | ||
59 | done | ||
60 | |||
61 | # restore IFS | ||
62 | IFS=${OLDIFS} | ||
63 | |||
64 | return ${IS_TYPE} | ||
65 | } | ||
66 | |||
67 | |||
68 | # | ||
69 | # use openssl to fingerprint a file | ||
70 | # arguments: | ||
71 | # 1. the filename to fingerprint | ||
72 | # 2. the method to use (x509, crl) | ||
73 | # returns: | ||
74 | # none | ||
75 | # assumptions: | ||
76 | # user will capture output from last stage of pipeline | ||
77 | # | ||
78 | fingerprint() | ||
79 | { | ||
80 | ${SSL_CMD} ${2} -fingerprint -noout -in ${1} | sed 's/^.*=//' | tr -d ':' | ||
81 | } | ||
82 | |||
83 | |||
84 | # | ||
85 | # link_hash - create links to certificate files | ||
86 | # arguments: | ||
87 | # 1. the filename to create a link for | ||
88 | # 2. the type of certificate being linked (x509, crl) | ||
89 | # returns: | ||
90 | # 0 on success, 1 otherwise | ||
91 | # | ||
92 | link_hash() | ||
93 | { | ||
94 | local FINGERPRINT=$( fingerprint ${1} ${2} ) | ||
95 | local HASH=$( ${SSL_CMD} ${2} -hash -noout -in ${1} ) | ||
96 | local SUFFIX=0 | ||
97 | local LINKFILE='' | ||
98 | local TAG='' | ||
99 | |||
100 | if [ ${2} = "crl" ] | ||
101 | then | ||
102 | TAG='r' | ||
103 | fi | ||
104 | |||
105 | LINKFILE=${HASH}.${TAG}${SUFFIX} | ||
106 | |||
107 | while [ -f ${LINKFILE} ] | ||
108 | do | ||
109 | if [ ${FINGERPRINT} = $( fingerprint ${LINKFILE} ${2} ) ] | ||
110 | then | ||
111 | echo "WARNING: Skipping duplicate file ${1}" >&2 | ||
112 | return 1 | ||
113 | fi | ||
114 | |||
115 | SUFFIX=$(( ${SUFFIX} + 1 )) | ||
116 | LINKFILE=${HASH}.${TAG}${SUFFIX} | ||
117 | done | ||
118 | |||
119 | echo "${1} => ${LINKFILE}" | ||
120 | |||
121 | # assume any system with a POSIX shell will either support symlinks or | ||
122 | # do something to handle this gracefully | ||
123 | ln -s ${1} ${LINKFILE} | ||
124 | |||
125 | return 0 | ||
126 | } | ||
127 | |||
128 | |||
129 | # hash_dir create hash links in a given directory | ||
130 | hash_dir() | ||
131 | { | ||
132 | echo "Doing ${1}" | ||
133 | |||
134 | cd ${1} | ||
135 | |||
136 | ls -1 * 2>/dev/null | while read FILE | ||
137 | do | ||
138 | if echo ${FILE} | grep -q -E '^[[:xdigit:]]{8}\.r?[[:digit:]]+$' \ | ||
139 | && [ -h "${FILE}" ] | ||
140 | then | ||
141 | rm ${FILE} | ||
142 | fi | ||
143 | done | ||
144 | |||
145 | ls -1 *.pem 2>/dev/null | while read FILE | ||
146 | do | ||
147 | check_file ${FILE} | ||
148 | local FILE_TYPE=${?} | ||
149 | local TYPE_STR='' | ||
150 | |||
151 | if [ $(( ${FILE_TYPE} & ${IS_CERT} )) -ne 0 ] | ||
152 | then | ||
153 | TYPE_STR='x509' | ||
154 | elif [ $(( ${FILE_TYPE} & ${IS_CRL} )) -ne 0 ] | ||
155 | then | ||
156 | TYPE_STR='crl' | ||
157 | else | ||
158 | echo "WARNING: ${FILE} does not contain a certificate or CRL: skipping" >&2 | ||
159 | continue | ||
160 | fi | ||
161 | |||
162 | link_hash ${FILE} ${TYPE_STR} | ||
163 | done | ||
164 | } | ||
165 | |||
166 | |||
167 | # choose the name of an ssl application | ||
168 | if [ -n "${OPENSSL}" ] | ||
169 | then | ||
170 | SSL_CMD=$(which ${OPENSSL} 2>/dev/null) | ||
171 | else | ||
172 | SSL_CMD=/usr/bin/openssl | ||
173 | OPENSSL=${SSL_CMD} | ||
174 | export OPENSSL | ||
175 | fi | ||
176 | |||
177 | # fix paths | ||
178 | PATH=${PATH}:${DIR}/bin | ||
179 | export PATH | ||
180 | |||
181 | # confirm existance/executability of ssl command | ||
182 | if ! [ -x ${SSL_CMD} ] | ||
183 | then | ||
184 | echo "${0}: rehashing skipped ('openssl' program not available)" >&2 | ||
185 | exit 0 | ||
186 | fi | ||
187 | |||
188 | # determine which directories to process | ||
189 | old_IFS=$IFS | ||
190 | if [ ${#} -gt 0 ] | ||
191 | then | ||
192 | IFS=':' | ||
193 | DIRLIST=${*} | ||
194 | elif [ -n "${SSL_CERT_DIR}" ] | ||
195 | then | ||
196 | DIRLIST=$SSL_CERT_DIR | ||
197 | else | ||
198 | DIRLIST=${DIR}/certs | ||
199 | fi | ||
200 | |||
201 | IFS=':' | ||
202 | |||
203 | # process directories | ||
204 | for CERT_DIR in ${DIRLIST} | ||
205 | do | ||
206 | if [ -d ${CERT_DIR} -a -w ${CERT_DIR} ] | ||
207 | then | ||
208 | IFS=$old_IFS | ||
209 | hash_dir ${CERT_DIR} | ||
210 | IFS=':' | ||
211 | fi | ||
212 | done |