#! /bin/sh # Env: # GNUTLS_CFLAGS # GNUTLS_LIBS # PKG_CONFIG if [ -f config.sh ]; then # configure wrote the env into this file: . ./config.sh export GNUTLS_CFLAGS GNUTLS_LIBS PKG_CONFIG fi stdlib=`ocamlc -where` rm -f config.h ulimit -c 0 # no coredumps compiler="ocamlc -custom" if ocamlopt; then compiler=ocamlopt; fi log=`pwd`/"config.log" rm -f $log touch $log out="config.h" rm -f $out touch $out mkdir -p testdir ###################################################################### # Programs linked with ocamlc have more libraries linked in by default. # Because of this, we use ocamlopt if available. call_ocamlc () { echo '$' $compiler -ccopt "$GNUTLS_CFLAGS" "$@" -cclib "$GNUTLS_LIBS" >>$log ( cd testdir; $compiler -ccopt "$GNUTLS_CFLAGS" "$@" -cclib "$GNUTLS_LIBS" ) >>$log 2>&1 return $? } have_gnutls_crypto_h=0 have_gnutls_abstract_h=0 have_nettle_gcm_h=0 have_nettle_camellia_h=0 add_include="" init_header() { echo "Checking presence of $1" echo "# HEADER $1" >> $log cat <<EOF >testdir/test.c #include <gnutls/gnutls.h> #include <$1> EOF call_ocamlc -c test.c } init_nettle_set_key() { # older versions of Nettle have cipher->set_encrypt_key with three args, # and newer only two args. (Also for set_decrypt_key.) echo "Checking whether set_en/decrypt_key has two args" echo "# set_key" >> $log cat <<EOF >testdir/test.c #include <nettle/nettle-types.h> #include <nettle/nettle-meta.h> #include <stdlib.h> int main (int argc, char *argv[], char *envp[]) { struct nettle_cipher *cipher; void *ctx; cipher = &nettle_aes128; ctx = malloc(cipher->context_size); cipher->set_encrypt_key(ctx, (const uint8_t *) "0123456789abcdef"); cipher->set_decrypt_key(ctx, (const uint8_t *) "0123456789abcdef"); return 0; } EOF call_ocamlc -c test.c } init_checks() { if init_header "gnutls/crypto.h"; then have_gnutls_crypto_h=1 add_include="$add_include #include <gnutls/crypto.h>" echo "#define HAVE_GNUTLS_CRYPTO_H" >>$out else echo "#undef HAVE_GNUTLS_CRYPTO_H" >>$out fi if init_header "gnutls/abstract.h"; then have_gnutls_abstract_h=1 add_include="$add_include #include <gnutls/abstract.h>" echo "#define HAVE_GNUTLS_ABSTRACT_H" >>$out else echo "#undef HAVE_GNUTLS_ABSTRACT_H" >>$out fi if init_header "nettle/camellia.h"; then have_nettle_camellia_h=1 add_include="$add_include #include <nettle/camellia.h>" echo "#define HAVE_NETTLE_CAMELLIA_H" >>$out else echo "#undef HAVE_NETTLE_CAMELLIA_H" >>$out fi if init_header "nettle/gcm.h"; then have_nettle_gcm_h=1 add_include="$add_include #include <nettle/gcm.h>" echo "#define HAVE_NETTLE_GCM_H" >>$out else echo "#undef HAVE_NETTLE_GCM_H" >>$out fi if init_nettle_set_key; then echo "#define HAVE_NETTLE_SET_KEY_WITH_TWO_ARGS" >>$out else echo "#undef HAVE_NETTLE_SET_KEY_WITH_TWO_ARGS" >>$out fi } check_enum () { macro="$1" enum="$2" echo "Checking enum $enum" echo "# ENUM $enum" >> $log cat <<EOF >testdir/test.c #include <gnutls/gnutls.h> #include <gnutls/openpgp.h> #include <gnutls/x509.h> #include <nettle/nettle-meta.h> $add_include int main (int argc, char *argv[], char *envp[]) { int n; n = $enum; return 0; } EOF if call_ocamlc -c test.c; then echo "#define $macro" >>$out else echo "#undef $macro" >>$out fi } check_fun() { macro="$1" fun="$2" echo "Checking function $fun" echo "# FUN $fun" >> $log cat <<EOF >testdir/main.ml external test : unit -> unit = "do_test" let () = test() EOF cat <<EOF >testdir/test.c #include <gnutls/gnutls.h> #include <gnutls/openpgp.h> #include <gnutls/x509.h> #include <nettle/nettle-meta.h> #include "caml/mlvalues.h" $add_include value do_test(value dummy) { void *p; p = & $fun; return (p != NULL) ? 0 : 1; } EOF if call_ocamlc -o test test.c main.ml; then echo "#define $macro" >>$out else echo "#undef $macro" >>$out fi } check_type() { macro="$1" ty="$2" echo "Checking type $ty" echo "# TYPE $ty" >> $log cat <<EOF >testdir/test.c #include <gnutls/gnutls.h> #include <gnutls/openpgp.h> #include <gnutls/x509.h> #include <nettle/nettle-meta.h> $add_include int main (int argc, char *argv[], char *envp[]) { $ty * x; return 0; } EOF if call_ocamlc -c test.c; then echo "#define $macro" >>$out else echo "#undef $macro" >>$out fi } ###################################################################### echo "Generating stubs" rm -f config_checks.sh echo "$ ocaml -I ../../tools gnutls.descr" >>$log ocaml -I ../../tools gnutls.descr || exit 1 echo "$ ocaml -I ../../tools nettle.descr" >>$log ocaml -I ../../tools nettle.descr || exit 1 init_checks . ./config_checks.sh if [ -n "$GNUTLS_SYSTEM_TRUST_FILE" ]; then echo "System certificates: $GNUTLS_SYSTEM_TRUST_FILE" cat <<EOF >nettls_gnutls_config.ml let system_trust = \`File "$GNUTLS_SYSTEM_TRUST_FILE" EOF else if grep '#define HAVE_FUN_gnutls_certificate_set_x509_system_trust' \ config.h >/dev/null 2>/dev/null; then echo "System certificates: from GnuTLS" cat <<EOF >nettls_gnutls_config.ml let system_trust = \`Gnutls EOF else path="" for p in \ /etc/ssl/ca-bundle.pem \ /etc/ssl/certs/ca-certificates.crt \ /etc/pki/tls/cert.pem \ /usr/local/share/certs/ca-root-nss.crt \ /etc/ssl/cert.pem; \ do if [ -f "$p" ]; then path="$p" break fi done if [ -n "$path" ]; then echo "System certificates: $path" cat <<EOF >nettls_gnutls_config.ml let system_trust = \`File "$path" EOF else echo "System certificates: NOT FOUND" echo "This is an error. Without system certificates, clients" echo "will not be able to make TLS-secured connections." echo "Set the -gnutls-system-trust-file configuration option manually!" echo "ERROR" exit 1 fi fi fi touch done_reconfigure