gnunet-gns-proxy-setup-ca:
[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 setdefaults()
52 {
53     runcmd=
54     #TOP=$( (exec pwd -P 2>/dev/null) || (exec pwd 2>/dev/null) )
55 }
56
57 statusmsg()
58 {
59     ${runcmd} echo "    $@"
60 }
61
62 infomsg()
63 {
64     statusmsg "INFO: $@"
65 }
66
67 warningmsg()
68 {
69     statusmsg "WARNING: $@"
70 }
71
72 errormsg()
73 {
74     statusmsg "ERROR: $@"
75 }
76
77 linemsg()
78 {
79     statusmsg "========================================="
80 }
81
82 # Given a variable name in $1, modify the variable in place
83 # as follows:
84 # Convert possibly-relative path to absolute path by prepending
85 # ${TOP} if necessary.  Also delete trailing "/", if any.
86 resolvepath()
87 {
88     local var="$1"
89     local val
90     eval val=\"\${${var}}\"
91     case "${val}" in
92         /)
93         ;;
94         /*)
95             val="${val%/}"
96             ;;
97         *)
98             val="${TOP}/${val%/}"
99             ;;
100     esac
101     eval ${var}=\"\${val}\"
102 }
103
104 # usage()
105 # {
106 #     if [ -n "$*" ]; then
107 #         echo ""
108 #         echo "${progname}: $*"
109 #     fi
110 #     cat <<_usage_
111
112 # Usage: ${progname} [-fhv] [-c FILE] operation [...]
113
114 # Operations:
115 #    cert               Create the GNS certificate and only insert
116 #               it in GNS.
117 #    browser    Create the GNS certificate, insert it in
118 #               GNS and install it in webbrowsers found.
119 #    all                Create the GNS certificate, insert it in
120 #               GNS and install it in webbrowsers found.
121 #    help               Print this help message.
122
123 # Options:
124 #    -c FILE    Use the configuration file FILE.
125 #    -f         Perform expansions of the variables used in the config
126 #               value of gns-proxy. This will usually expand
127 #               $GNUNET_DATA_HOME to represent its path.
128 #    -h         Print this help message.
129 #    -v         Print the version.
130
131 # _usage_
132 #       exit 1
133 # }
134
135 usage()
136 {
137     if [ -n "$*" ]; then
138         echo ""
139         echo "${progname}: $*"
140     fi
141     cat <<_usage_
142
143 Usage: ${progname} [-hv] [-c FILE] [...]
144
145 Options:
146    -c FILE      Use the configuration file FILE.
147    -h           Print this help message.
148    -v           Print the version and exit.
149    -V           be verbose
150
151 _usage_
152         exit 1
153 }
154
155
156 # parseoptions()
157 # {
158 #     opts=':cfhv'
159 #     # For now use POSIX getopts. For the future, refer to
160 #     # the shell capabilities check build.sh has?
161 #     if type getopts >/dev/null 2>&1; then
162 #         # we are a posix shell, we can use the builtin getopts
163 #         getoptcmd='getopts ${opts} opt && opt=-${opt}'
164 #         optargcmd=':'
165 #         optremcmd='shift $((${OPTIND} -1))'
166 #     fi
167
168 #     # parse command line options.
169 #     while eval ${getoptcmd}; do
170 #         case ${opt} in
171
172 #             -c)
173 #                 eval ${optargcmd}; resolvepath OPTARG
174 #                 GNUNET_CONFIG_FILE="${OPTARG}"
175 #                 export GNUNET_CONFIG_FILE
176 #                 ;;
177 #             -f)
178 #                 GNUNET_PASS_FILENAME=1
179 #                 export GNUNET_PASS_FILENAME
180 #                 ;;
181 #             -v)
182 #                 print_version
183 #                 ;;
184 #             --)
185 #                 break
186 #                 ;;
187 #             -'?'|-h)
188 #                 usage
189 #                 ;;
190 #         esac
191 #     done
192
193 #     # operations
194 #     eval ${optremcmd}
195 #     while [ $# -gt 0 ]; do
196 #         op=$1; shift
197 #         operations="${operations} ${op}"
198 #         case "${op}" in
199 #             help)
200 #                 usage
201 #                 ;;
202 #             all|\
203 #             browser|\
204 #             cert)
205 #                 ;;
206 #             *)
207 #                 usage "Unknown operation \`${op}'"
208 #                 ;;
209 #         esac
210 #         op="$( echo "$op" | tr -s '.-' '__')"
211 #         eval do_${op}=true
212 #     done
213 # }
214     #[ -n "${operations}" ] || usage "Missing operation to perform."
215     # old code:
216     # while getopts "c:" opt; do
217     #     case $opt in
218     #         c)
219     #             options="$options -c $OPTARG"
220     #             ;;
221     #         \?)
222     #             echo "Invalid option: -$OPTARG" >&2
223     #             exit 1
224     #             ;;
225     #         :)
226     #             echo "Option -$OPTARG requires an argument." >&2
227     #             exit 1
228     #             ;;
229     #     esac
230     # done
231
232 generate_ca()
233 {
234     echo ""
235     infomsg "Generating CA"
236     TMPDIR=${TMPDIR:-/tmp}
237     if [ -e "$TMPDIR" ]; then
238         GNSCERT=`mktemp -t ${00##*/}.pem` || exit 1
239         GNSCAKY=`mktemp -t ${00##*/}.pem` || exit 1
240         GNSCANO=`mktemp -t ${00##*/}.pem` || exit 1
241     else
242         # This warning is mostly pointless.
243         warning "You need to export the TMPDIR variable"
244     fi
245     # else
246     #     # SETUP_TMPDIR="$HOME/gns_setup"
247     #     # if [ ! -e "$SETUP_TMPDIR" ]; then
248     #     #     mkdir -p $SETUP_TMPDIR
249     #     # fi
250     #     GNSCERT=`mktemp ${00##*/}.pem` || exit 1
251     #     GNSCAKY=`mktemp ${00##*/}.pem` || exit 1
252     #     GNSCANO=`mktemp ${00##*/}.pem` || exit 1
253     # fi
254
255     OPENSSLCFG=@pkgdatadir@/openssl.cnf
256     if ! which openssl > /dev/null
257     then
258         warningmsg "'openssl' command not found. Please install it."
259         infomsg    "Cleaning up."
260         rm -f $GNSCAKY $GNSCANO $GNSCERT
261         exit 1
262     fi
263     if [ -n "${GNUNET_CONFIG}" ]; then
264         GNUNET_CONFIG="-c ${GNUNET_CONFIG_FILE}"
265     else
266         GNUNET_CONFIG=""
267     fi
268     if [ GNUNET_PASS_FILENAME ]; then
269         GNUNET_OPT_F=""
270     else
271         GNUNET_OPT_F=" -f "
272     fi
273     GNS_CA_CERT_PEM=`gnunet-config ${GNUNET_CONFIG} -s gns-proxy -o PROXY_CACERT ${GNUNET_OPT_F} -f ${options}`
274     mkdir -p `dirname $GNS_CA_CERT_PEM`
275
276     # Bad names etc.
277     if [ verbosity ]; then
278         VERBOSE_OUTPUT=""
279     else
280         VERBOSE_OUTPUT="2>/dev/null"
281     fi
282     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" ${VERBOSE_OUTPUT}
283
284     statusmsg "Removing passphrase from key"
285     openssl rsa -passin pass:"GNU Name System" -in $GNSCAKY -out $GNSCANO ${VERBOSE_OUTPUT}
286
287     statusmsg "Making private key available to gnunet-gns-proxy"
288     cat $GNSCERT $GNSCANO > $GNS_CA_CERT_PEM
289 }
290
291 importbrowsers()
292 {
293     if ! which certutil > /dev/null
294     then
295         warningmsg "The 'certutil' command was not found."
296         warningmsg "Not importing into browsers."
297         warningmsg "For 'certutil' install nss."
298     else
299         statusmsg "Importing CA into browsers"
300         # TODO: Error handling?
301         for f in ~/.mozilla/firefox/*.*/
302         do
303             if [ -d $f ]; then
304                 statusmsg "Importing CA into Firefox at $f"
305                 # delete old certificate (if any)
306                 certutil -D -n "GNS Proxy CA" -d "$f" >/dev/null 2>/dev/null
307                 # add new certificate
308                 certutil -A -n "GNS Proxy CA" -t CT,, -d "$f" < $GNSCERT
309             fi
310         done
311         # TODO: Error handling?
312         if [ -d ~/.pki/nssdb/ ]; then
313             statusmsg "Importing CA into Chrome at ~/.pki/nssdb/"
314             # delete old certificate (if any)
315             certutil -D -n "GNS Proxy CA" -d ~/.pki/nssdb/ >/dev/null 2>/dev/null
316             # add new certificate
317             certutil -A -n "GNS Proxy CA" -t CT,, -d ~/.pki/nssdb/ < $GNSCERT
318         fi
319     fi
320 }
321
322 print_version()
323 {
324     GNUNET_ARM_VERSION=`gnunet-arm -v`
325     echo $GNUNET_ARM_VERSION
326 }
327
328 clean_up()
329 {
330     infomsg "Cleaning up."
331     rm -f $GNSCAKY $GNSCANO $GNSCERT
332     if [ -e $SETUP_TMPDIR ]; then
333         rm -rf $SETUP_TMPDIR
334     fi
335
336     linemsg
337     infomsg "You can now start gnunet-gns-proxy."
338     infomsg "Afterwards, configure your browser "
339     infomsg "to use a SOCKS proxy on port 7777. "
340     linemsg
341 }
342
343 main()
344 {
345     while getopts "vhVc:" opt; do
346         case $opt in
347             v)
348                 print_version
349                 exit 0
350                 ;;
351             h)
352                 usage
353                 ;;
354             V)
355                 verbosity=1
356                 ;;
357             c)
358                 options="$options -c $OPTARG"
359                 infomsg "Using configuration file $OPTARG"
360                 ;;
361             \?)
362                 echo "Invalid option: -$OPTARG" >&2
363                 usage
364                 ;;
365             :)
366                 echo "Option -$OPTARG requires an argument." >&2
367                 usage
368                 ;;
369         esac
370     done
371     setdefaults
372     generate_ca
373     importbrowsers
374     clean_up
375
376 # Needs debugging...
377 #    setdefaults
378 #    _args=$@
379 #    parseoptions "$@"
380 #    for op in ${operations}; do
381 #        case "${op}" in
382 #            cert)
383 #                ${runcmd} "${generate_ca}"
384 #                ${runcmd} "${clean_up}"
385 #                ;;
386 #            browser)
387 #                ${runcmd} "${generate_ca}"
388 #                ${runcmd} "${importbrowsers}"
389 #                ${runcmd} "${clean_up}"
390 #                ;;
391 #            all)
392 #                ${runcmd} "${generate_ca}"
393 #                ${runcmd} "${importbrowsers}"
394 #                ${runcmd} "${clean_up}"
395 #                ;;
396 #            *)
397 #                infomsg "Unknown operation \`${op}'"
398 #                ;;
399 #        esac
400 #    done
401 }
402
403 main "$@"