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