gnunet-gns-proxy-setup-ca: fix implementation and describe new changes.
[oweals/gnunet.git] / src / gns / gnunet-gns-proxy-setup-ca.in
1 #!/bin/sh
2 #
3 # This shell script will generate an X509 certificate for
4 # your gnunet-gns-proxy and install it (for both GNUnet
5 # and your browser).
6 #
7 # TODO: Implement support for more browsers
8 # TODO: Debug and switch to the new version
9 # TODO  - The only remaining task is fixing the getopts
10 # TODO: Error checks
11 #
12 # The current version partially reuses and recycles
13 # code from build.sh by NetBSD (although not entirely
14 # used because it needs debugging):
15 #
16 # Copyright (c) 2001-2011 The NetBSD Foundation, Inc.
17 # All rights reserved.
18 #
19 # This code is derived from software contributed to
20 # The NetBSD Foundation by Todd Vierling and Luke Mewburn.
21 #
22 # Redistribution and use in source and binary forms, with or
23 # without modification, are permitted provided that the following
24 # conditions are met:
25 # 1. Redistributions of source code must retain the above
26 #    copyright notice, this list of conditions and the following
27 #    disclaimer.
28 # 2. Redistributions in binary form must reproduce the above
29 #    copyright notice, this list of conditions and the following
30 #    disclaimer in the documentation and/or other materials
31 #    provided with the distribution.
32 #
33 # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
34 # CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
35 # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
36 # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
37 # DISCLAIMED.
38 # IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR
39 # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
40 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
41 # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
44 # LIABILITY, OR TORT
45 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
46 # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
47 # OF SUCH DAMAGE.
48
49 progname=${0##*/}
50
51 # Whitespace normalization without depending on shell features:
52 tab='   '
53 tab2='   '
54 nl='
55 '
56 # trap "exit 1" 1 2 3 15
57
58 setdefaults()
59 {
60     verbosity=0
61     resfile=
62     results=/dev/null
63     tmpdir=${TMPDIR:-/tmp}
64     runcmd=
65 }
66
67 statusmsg()
68 {
69     ${runcmd} echo "${tab}$@" | tee -a "${results}"
70 }
71
72 infomsg()
73 {
74     if [ x$verbosity = x1 ]; then
75         statusmsg "INFO:${tab}$@"
76     fi
77 }
78
79 warningmsg()
80 {
81     statusmsg "WARNING:${tab}$@"
82 }
83
84 errormsg()
85 {
86     statusmsg "ERROR:${tab}$@"
87 }
88
89 linemsg()
90 {
91     statusmsg "========================================="
92 }
93
94 existence()
95 {
96     command -v "$1" >/dev/null 2>&1
97 }
98
99 usage()
100 {
101     if [ -n "$*" ]; then
102         echo "${nl}${progname}: $*"
103     fi
104     cat <<_usage_
105
106 Usage: ${progname} [-hvVto] [-c FILE]
107
108 Options:
109 ${tab}-c FILE Use the configuration file FILE.
110 ${tab}-h${tab2}${tab2}Print this help message.
111 ${tab}-o${tab2}${tab2}Display summary of statusmessages
112 ${tab}-t${tab2}${tab2}Short developer test on binaries
113 ${tab}-v${tab2}${tab2}Print the version and exit.
114 ${tab}-V${tab2}${tab2}be verbose
115
116 _usage_
117         exit 1
118 }
119
120
121 generate_ca()
122 {
123     echo ""
124     infomsg "Generating CA"
125     TMPDIR=${TMPDIR:-/tmp}
126     if test -e "$TMPDIR"; then
127         GNSCERT=`mktemp -t certXXXXXXXX.pem` || exit 1
128         GNSCAKY=`mktemp -t cakyXXXXXXXX.pem` || exit 1
129         GNSCANO=`mktemp -t canoXXXXXXXX.pem` || exit 1
130     else
131         # This warning is mostly pointless.
132         warningmsg "You need to export the TMPDIR variable"
133     fi
134
135     # # ------------- gnutls
136     #
137     # if ! which certutil > /dev/null
138     # then
139     #     warningmsg "The 'certutil' command was not found."
140     #     warningmsg "Not importing into browsers."
141     #     warningmsg "For 'certutil' install nss."
142     # else
143     #     # Generate CA key
144     #     # pkcs#8 password-protects key
145     #     certtool --pkcs8 --generate-privkey --sec-param high --outfile ca-key.pem
146     #     # self-sign the CA to create public certificate
147     #     certtool --generate-self-signed --load-privkey ca-key.pem --template ca.cfg --outfile ca.pem
148
149     # ------------- openssl
150
151     GNUTLS_CA_TEMPLATE=@pkgdatadir@/gnunet-gns-proxy-ca.template
152     OPENSSLCFG=@pkgdatadir@/openssl.cnf
153     CERTTOOL=""
154     OPENSSL=0
155     if test -x $(existence gnunet-certtool)
156     # if test -z "`gnutls-certtool --version`" > /dev/null
157     then
158       # We only support gnutls certtool for now. Treat the grep
159       # for "gnutls" in the output with extra care, it only matches
160       # the email address! It is probably safer to run strings(1)
161       # over certtool for a string matching "gnutls"
162       if test -z "`certtool --version | grep gnutls`" > /dev/null
163       then
164         warningmsg "'gnutls-certtool' or 'certtool' command not found. Trying openssl."
165         # if test -z "`openssl version`" > /dev/null
166         if test -x $(existence openssl)
167         then
168           OPENSSL=1
169         else
170           warningmsg "Install either gnutls certtool or openssl for certificate generation!"
171           statusmsg  "Cleaning up."
172           rm -f $GNSCAKY $GNSCERT
173           exit 1
174         fi
175       fi
176       CERTTOOL="certtool"
177     else
178       CERTTOOL="gnutls-certtool"
179     fi
180     if test -n "${GNUNET_CONFIG_FILE}"; then
181         GNUNET_CONFIG="-c ${GNUNET_CONFIG_FILE}"
182     else
183         GNUNET_CONFIG=""
184     fi
185     GNS_CA_CERT_PEM=`gnunet-config ${GNUNET_CONFIG} -s gns-proxy -o PROXY_CACERT -f ${options}`
186     mkdir -p `dirname $GNS_CA_CERT_PEM`
187
188     if test 1 -eq $OPENSSL
189     then
190         if test 1 -eq $verbosity; then
191             openssl req -config $OPENSSLCFG -new -x509 -days 3650 -extensions v3_ca -keyout $GNSCAKY -out $GNSCERT -subj "/C=ZZ/L=World/O=GNU/OU=GNUnet/CN=GNS Proxy CA/emailAddress=bounce@gnunet.org" -passout pass:"GNU Name System"
192         else
193             openssl req -config $OPENSSLCFG -new -x509 -days 3650 -extensions v3_ca -keyout $GNSCAKY -out $GNSCERT -subj "/C=ZZ/L=World/O=GNU/OU=GNUnet/CN=GNS Proxy CA/emailAddress=bounce@gnunet.org" -passout pass:"GNU Name System" >/dev/null 2>&1
194         fi
195         infomsg "Removing passphrase from key"
196         if test 1 -eq $verbosity; then
197             openssl rsa -passin pass:"GNU Name System" -in $GNSCAKY -out $GNSCANO
198         else
199             openssl rsa -passin pass:"GNU Name System" -in $GNSCAKY -out $GNSCANO >/dev/null 2>&1
200         fi
201       cat $GNSCERT $GNSCANO > $GNS_CA_CERT_PEM
202     else
203         if test 1 -eq $verbosity; then
204             $CERTTOOL --generate-privkey --outfile $GNSCAKY
205             $CERTTOOL --template $GNUTLS_CA_TEMPLATE --generate-self-signed --load-privkey $GNSCAKY --outfile $GNSCERT
206         else
207             $CERTTOOL --generate-privkey --outfile $GNSCAKY >/dev/null 2>&1
208             $CERTTOOL --template $GNUTLS_CA_TEMPLATE --generate-self-signed --load-privkey $GNSCAKY --outfile $GNSCERT >/dev/null 2>&1
209         fi
210       infomsg "Making private key available to gnunet-gns-proxy"
211       cat $GNSCERT $GNSCAKY > $GNS_CA_CERT_PEM
212     fi
213 }
214
215 importbrowsers()
216 {
217     # if test -z "`command -v certutil`" > /dev/null 2>&1
218     if test -x $(existence gnutls-certutil) || test -x $(existence certutil)
219     then
220         statusmsg "Importing CA into browsers"
221         # TODO: Error handling?
222         for f in ~/.mozilla/firefox/*.*/
223         do
224             if [ -d $f ]; then
225                 infomsg "Importing CA into Firefox at $f"
226                 # delete old certificate (if any)
227                 certutil -D -n "GNS Proxy CA" -d "$f" >/dev/null 2>/dev/null
228                 # add new certificate
229                 certutil -A -n "GNS Proxy CA" -t CT,, -d "$f" < $GNSCERT
230             fi
231         done
232         # TODO: Error handling?
233         if [ -d ~/.pki/nssdb/ ]; then
234             statusmsg "Importing CA into Chrome at ~/.pki/nssdb/"
235             # delete old certificate (if any)
236             certutil -D -n "GNS Proxy CA" -d ~/.pki/nssdb/ >/dev/null 2>/dev/null
237             # add new certificate
238             certutil -A -n "GNS Proxy CA" -t CT,, -d ~/.pki/nssdb/ < $GNSCERT
239         fi
240     else
241         warningmsg "The 'certutil' command was not found."
242         warningmsg "Not importing into browsers."
243         warningmsg "For 'certutil' install nss."
244     fi
245 }
246
247 print_version()
248 {
249     GNUNET_ARM_VERSION=`gnunet-arm -v | awk '{print $2 " " $3}'`
250     echo ${progname} $GNUNET_ARM_VERSION
251 }
252
253 clean_up()
254 {
255     infomsg "Cleaning up."
256     rm -f $GNSCAKY $GNSCANO $GNSCERT
257     if test -e $SETUP_TMPDIR
258     then
259         rm -rf $SETUP_TMPDIR
260     fi
261
262     linemsg
263     statusmsg "You can now start gnunet-gns-proxy."
264     statusmsg "Afterwards, configure your browser "
265     statusmsg "to use a SOCKS proxy on port 7777. "
266     linemsg
267 }
268
269 main()
270 {
271     setdefaults
272     while getopts "vhVtoc:" opt; do
273         case $opt in
274             v)
275                 print_version
276                 exit 0
277                 ;;
278             h)
279                 usage
280                 ;;
281             V)
282                 verbosity=1
283                 ;;
284             c)
285                 options="$options -c $OPTARG"
286                 infomsg "Using configuration file $OPTARG"
287                 GNUNET_CONFIG_FILE=${OPTARG}
288                 ;;
289             t)
290                 verbosity=1
291                 infomsg "Running short developer test"
292                 if test -x $(existence openssl); then
293                    openssl version
294                 fi
295                 if test -x $(existence certtool); then
296                     certtool --version
297                 fi
298                 if test -x $(existence gnutls-certtool); then
299                     gnutls-certtool --version
300                 fi
301                 exit 0
302                 ;;
303             o)
304                 resfile=$(mktemp -t ${progname}.results)
305                 results="${resfile}"
306                 ;;
307             \?)
308                 echo "Invalid option: -$OPTARG" >&2
309                 usage
310                 ;;
311             :)
312                 echo "Option -$OPTARG requires an argument." >&2
313                 usage
314                 ;;
315         esac
316     done
317     generate_ca
318     importbrowsers
319     if [ -s "${results}" ]; then
320         echo "===> Summary of results:"
321         sed -e 's/^===>//;s/^/  /' "${results}"
322         echo "===> ."
323         infomsg "Please remove ${results} manually."
324     fi
325     clean_up
326 }
327
328 main "$@"