error handling
[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 dir=$(dirname "$0")
50
51 if test -e @PKGDATADIRECTORY@/progname.sh
52 then
53     . @PKGDATADIRECTORY@/progname.sh
54 else
55     . $dir/../../contrib/build-common/sh/lib.sh/progname.sh
56 fi
57
58 if test -e @PKGDATADIRECTORY@/existence.sh
59 then
60     . @PKGDATADIRECTORY@/existence.sh
61 else
62     . $dir/../../contrib/build-common/sh/lib.sh/existence.sh
63 fi
64
65 if test -e @PKGDATADIRECTORY@/msg.sh
66 then
67     . @PKGDATADIRECTORY@/msg.sh
68 else
69     . $dir/../../contrib/build-common/sh/lib.sh/msg.sh
70 fi
71
72 if test -e @PKGDATADIRECTORY@/version_gnunet.sh
73 then
74     . @PKGDATADIRECTORY@/version_gnunet.sh
75 else
76     . $dir/../../contrib/build-common/sh/lib.sh/version_gnunet.sh
77 fi
78
79 # Whitespace normalization without depending on shell features:
80 tab='   '
81 tab2='   '
82 nl='
83 '
84
85 setdefaults()
86 {
87     verbosity=0
88     resfile=
89     results=/dev/null
90     tmpdir=${TMPDIR:-/tmp}
91     runcmd=
92 }
93
94 usage()
95 {
96     if [ -n "$*" ]; then
97         echo "${nl}${progname}: $*"
98     fi
99     cat <<_usage_
100
101 Usage: ${progname} [-hvVto] [-c FILE]
102
103 Options:
104 ${tab}-c FILE Use the configuration file FILE.
105 ${tab}-h${tab2}${tab2}Print this help message.
106 ${tab}-o${tab2}${tab2}Display summary of statusmessages
107 ${tab}-t${tab2}${tab2}Short developer test on binaries
108 ${tab}-v${tab2}${tab2}Print the version and exit.
109 ${tab}-V${tab2}${tab2}be verbose
110
111 _usage_
112         exit 1
113 }
114
115
116 generate_ca()
117 {
118     echo ""
119     infomsg "Generating CA"
120     TMPDIR=${TMPDIR:-/tmp}
121     if test -e "$TMPDIR"; then
122         GNSCERT=`mktemp -t certXXXXXXXX.pem` || exit 1
123         GNSCAKY=`mktemp -t cakyXXXXXXXX.pem` || exit 1
124         GNSCANO=`mktemp -t canoXXXXXXXX.pem` || exit 1
125     else
126         # This warning is mostly pointless.
127         warningmsg "You need to export the TMPDIR variable"
128     fi
129
130     # # ------------- gnutls
131     #
132     # if ! which certutil > /dev/null
133     # then
134     #     warningmsg "The 'certutil' command was not found."
135     #     warningmsg "Not importing into browsers."
136     #     warningmsg "For 'certutil' install nss."
137     # else
138     #     # Generate CA key
139     #     # pkcs#8 password-protects key
140     #     certtool --pkcs8 --generate-privkey --sec-param high --outfile ca-key.pem
141     #     # self-sign the CA to create public certificate
142     #     certtool --generate-self-signed --load-privkey ca-key.pem --template ca.cfg --outfile ca.pem
143
144     # ------------- openssl
145
146     GNUTLS_CA_TEMPLATE=@PKGDATADIRECTORY@/gnunet-gns-proxy-ca.template
147     OPENSSLCFG=@PKGDATADIRECTORY@/openssl.cnf
148     CERTTOOL=""
149     OPENSSL=0
150     if test -x $(existence gnunet-certtool)
151     # if test -z "`gnutls-certtool --version`" > /dev/null
152     then
153       # We only support gnutls certtool for now. Treat the grep
154       # for "gnutls" in the output with extra care, it only matches
155       # the email address! It is probably safer to run strings(1)
156       # over certtool for a string matching "gnutls"
157       if test -z "`certtool --version | grep gnutls`" > /dev/null
158       then
159         warningmsg "'gnutls-certtool' or 'certtool' command not found. Trying openssl."
160         # if test -z "`openssl version`" > /dev/null
161         if test -x $(existence openssl)
162         then
163           OPENSSL=1
164         else
165           warningmsg "Install either gnutls certtool or openssl for certificate generation!"
166           statusmsg  "Cleaning up."
167           rm -f $GNSCAKY $GNSCERT
168           exit 1
169         fi
170       fi
171       CERTTOOL="certtool"
172     else
173       CERTTOOL="gnutls-certtool"
174     fi
175     if test -n "${GNUNET_CONFIG_FILE}"; then
176         GNUNET_CONFIG="-c ${GNUNET_CONFIG_FILE}"
177     else
178         GNUNET_CONFIG=""
179     fi
180     GNS_CA_CERT_PEM=`gnunet-config ${GNUNET_CONFIG} -s gns-proxy -o PROXY_CACERT -f ${options}`
181     mkdir -p `dirname $GNS_CA_CERT_PEM`
182
183     if test 1 -eq $OPENSSL
184     then
185         if test 1 -eq $verbosity; then
186             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"
187         else
188             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
189         fi
190         infomsg "Removing passphrase from key"
191         if test 1 -eq $verbosity; then
192             openssl rsa -passin pass:"GNU Name System" -in $GNSCAKY -out $GNSCANO
193         else
194             openssl rsa -passin pass:"GNU Name System" -in $GNSCAKY -out $GNSCANO >/dev/null 2>&1
195         fi
196       cat $GNSCERT $GNSCANO > $GNS_CA_CERT_PEM
197     else
198         if test 1 -eq $verbosity; then
199             $CERTTOOL --generate-privkey --outfile $GNSCAKY
200             $CERTTOOL --template $GNUTLS_CA_TEMPLATE --generate-self-signed --load-privkey $GNSCAKY --outfile $GNSCERT
201         else
202             $CERTTOOL --generate-privkey --outfile $GNSCAKY >/dev/null 2>&1
203             $CERTTOOL --template $GNUTLS_CA_TEMPLATE --generate-self-signed --load-privkey $GNSCAKY --outfile $GNSCERT >/dev/null 2>&1
204         fi
205       infomsg "Making private key available to gnunet-gns-proxy"
206       cat $GNSCERT $GNSCAKY > $GNS_CA_CERT_PEM
207     fi
208 }
209
210 importbrowsers()
211 {
212     # if test -z "`command -v certutil`" > /dev/null 2>&1
213     if test -x $(existence gnutls-certutil) || test -x $(existence certutil)
214     then
215         statusmsg "Importing CA into browsers"
216         # TODO: Error handling?
217         for f in ~/.mozilla/firefox/*.*/
218         do
219             if [ -d $f ]; then
220                 infomsg "Importing CA into Firefox at $f"
221                 # delete old certificate (if any)
222                 certutil -D -n "GNS Proxy CA" -d "$f" >/dev/null 2>/dev/null
223                 # add new certificate
224                 certutil -A -n "GNS Proxy CA" -t CT,, -d "$f" < $GNSCERT
225             fi
226         done
227         for f in ~/.mozilla/icecat/*.*/
228         do
229             if [ -d $f ]; then
230                 infomsg "Importing CA into Icecat at $f"
231                 # delete old certificate (if any)
232                 certutil -D -n "GNS Proxy CA" -d "$f" >/dev/null 2>/dev/null
233                 # add new certificate
234                 certutil -A -n "GNS Proxy CA" -t CT,, -d "$f" < $GNSCERT
235             fi
236         done
237         # TODO: Error handling?
238         if [ -d ~/.pki/nssdb/ ]; then
239             statusmsg "Importing CA into Chrome at ~/.pki/nssdb/"
240             # delete old certificate (if any)
241             certutil -D -n "GNS Proxy CA" -d ~/.pki/nssdb/ >/dev/null 2>/dev/null
242             # add new certificate
243             certutil -A -n "GNS Proxy CA" -t CT,, -d ~/.pki/nssdb/ < $GNSCERT
244         fi
245     else
246         warningmsg "The 'certutil' command was not found."
247         warningmsg "Not importing into browsers."
248         warningmsg "For 'certutil' install nss."
249     fi
250 }
251
252 clean_up()
253 {
254     infomsg "Cleaning up."
255     rm -f $GNSCAKY $GNSCANO $GNSCERT
256     if test -e $SETUP_TMPDIR
257     then
258         rm -rf $SETUP_TMPDIR
259     fi
260
261     linemsg
262     statusmsg "You can now start gnunet-gns-proxy."
263     statusmsg "Afterwards, configure your browser "
264     statusmsg "to use a SOCKS proxy on port 7777. "
265     linemsg
266 }
267
268 main()
269 {
270     setdefaults
271     while getopts "vhVtoc:" opt; do
272         case $opt in
273             v)
274                 print_version
275                 exit 0
276                 ;;
277             h)
278                 usage
279                 ;;
280             V)
281                 verbosity=1
282                 ;;
283             c)
284                 options="$options -c $OPTARG"
285                 infomsg "Using configuration file $OPTARG"
286                 GNUNET_CONFIG_FILE=${OPTARG}
287                 ;;
288             t)
289                 verbosity=1
290                 infomsg "Running short developer test"
291                 if test -x $(existence openssl); then
292                    openssl version
293                 fi
294                 if test -x $(existence certtool); then
295                     certtool --version
296                 fi
297                 if test -x $(existence gnutls-certtool); then
298                     gnutls-certtool --version
299                 fi
300                 exit 0
301                 ;;
302             o)
303                 resfile=$(mktemp -t ${progname}.results)
304                 results="${resfile}"
305                 ;;
306             \?)
307                 echo "Invalid option: -$OPTARG" >&2
308                 usage
309                 ;;
310             :)
311                 echo "Option -$OPTARG requires an argument." >&2
312                 usage
313                 ;;
314         esac
315     done
316     generate_ca
317     importbrowsers
318     if [ -s "${results}" ]; then
319         echo "===> Summary of results:"
320         sed -e 's/^===>//;s/^/  /' "${results}"
321         echo "===> ."
322         infomsg "Please remove ${results} manually."
323     fi
324     clean_up
325 }
326
327 main "$@"