From 1dd274fec356ecd4fc95f9cc8fc6af37c7df213c Mon Sep 17 00:00:00 2001 From: Elliot Glaysher Date: Wed, 10 Jul 2019 13:44:02 -0700 Subject: [PATCH] Embed the nix SSL certificate file into the resulting binary. This writes the SSL certs to a temporary file on startup and then uses environment variables to control OpenSSL and curl so that they use them. We have to do this because OSX no longer ships the normal ca pems, and we statically link with these libraries. --- nix/pkgs/urbit/default.nix | 2 +- nix/pkgs/urbit/release.nix | 14 ++++++++------ nix/release.nix | 3 ++- pkg/urbit/.gitignore | 1 + pkg/urbit/Makefile | 13 +++++++++++-- pkg/urbit/daemon/main.c | 29 +++++++++++++++++++++++++++++ pkg/urbit/include/vere/vere.h | 1 + pkg/urbit/vere/daemon.c | 1 + 8 files changed, 54 insertions(+), 10 deletions(-) diff --git a/nix/pkgs/urbit/default.nix b/nix/pkgs/urbit/default.nix index 6244167f8..5e971e684 100644 --- a/nix/pkgs/urbit/default.nix +++ b/nix/pkgs/urbit/default.nix @@ -11,7 +11,7 @@ let deps = with pkgs; - [ curl gmp libsigsegv ncurses openssl zlib lmdb ]; + [ curl gmp libsigsegv ncurses openssl zlib lmdb cacert xxd ]; vendor = [ argon2 softfloat3 ed25519 ent ge-additions h2o scrypt uv murmur3 secp256k1 sni ]; diff --git a/nix/pkgs/urbit/release.nix b/nix/pkgs/urbit/release.nix index 13cfac209..171a89161 100644 --- a/nix/pkgs/urbit/release.nix +++ b/nix/pkgs/urbit/release.nix @@ -1,6 +1,6 @@ { env_name, env, deps }: -{ ent, ge-additions, name ? "urbit", debug ? false }: +{ ent, ge-additions, cacert, xxd, name ? "urbit", debug ? false }: let @@ -21,10 +21,12 @@ env.make_derivation { CPU_DEBUG = debug; EVENT_TIME_DEBUG = false; NCURSES = env.ncurses; + SSL_CERT_FILE = "${cacert}/etc/ssl/certs/ca-bundle.crt"; - name = "${name}-${env_name}"; - exename = name; - src = ../../../pkg/urbit; - cross_inputs = crossdeps ++ vendor ++ [ ent ]; - builder = ./release.sh; + name = "${name}-${env_name}"; + exename = name; + src = ../../../pkg/urbit; + native_inputs = [ xxd ]; + cross_inputs = crossdeps ++ vendor ++ [ ent ]; + builder = ./release.sh; } diff --git a/nix/release.nix b/nix/release.nix index 3e563fa91..648d5e6b1 100644 --- a/nix/release.nix +++ b/nix/release.nix @@ -21,7 +21,8 @@ let urbit = env: import ./pkgs/urbit/release.nix env - { ent = ent env; ge-additions = ge-additions env; debug = false; name = "urbit"; }; + { ent = ent env; ge-additions = ge-additions env; cacert = nixpkgs.cacert; + xxd = nixpkgs.xxd; debug = false; name = "urbit"; }; builds-for-platform = plat: plat.deps // { diff --git a/pkg/urbit/.gitignore b/pkg/urbit/.gitignore index e7a58fbfc..577a6369a 100644 --- a/pkg/urbit/.gitignore +++ b/pkg/urbit/.gitignore @@ -3,6 +3,7 @@ # /config.mk include/config.h +include/ca-bundle.h # # Build Outputs # diff --git a/pkg/urbit/Makefile b/pkg/urbit/Makefile index 985f05a1b..798c728c8 100644 --- a/pkg/urbit/Makefile +++ b/pkg/urbit/Makefile @@ -7,7 +7,7 @@ daemon = $(wildcard daemon/*.c) worker = $(wildcard worker/*.c) common = $(jets) $(noun) $(vere) -headers = $(shell find include -type f) +headers = $(shell find include -type f) include/ca-bundle.h common_objs = $(shell echo $(common) | sed 's/\.c/.o/g') daemon_objs = $(shell echo $(daemon) | sed 's/\.c/.o/g') @@ -22,6 +22,9 @@ all_exes = ./mug_tests jam_tests ./hashtable_tests ./urbit ./urbit-worker # -Wall issues all types of errors. This is off (for now) CFLAGS := $(CFLAGS) +ifeq ($(SSL_CERT_FILE),) + $(error SSL_CERT_FILE is undefined) +endif ################################################################################ @@ -40,10 +43,16 @@ clean: rm -f ./tags $(all_objs) $(all_exes) mrproper: clean - rm -f config.mk include/config.h + rm -f config.mk include/config.h include/ca-bundle.h ################################################################################ +include/ca-bundle.h: + @echo XXD -i $(SSL_CERT_FILE) + @cat $(SSL_CERT_FILE) > include/ca-bundle.crt + @xxd -i include/ca-bundle.crt > include/ca-bundle.h + @rm include/ca-bundle.crt + hashtable_tests: $(common_objs) tests/hashtable_tests.o @echo CC -o $@ @$(CC) $^ $(LDFLAGS) -o $@ diff --git a/pkg/urbit/daemon/main.c b/pkg/urbit/daemon/main.c index 0fb9ce51e..f87bd9319 100644 --- a/pkg/urbit/daemon/main.c +++ b/pkg/urbit/daemon/main.c @@ -24,6 +24,8 @@ #include "all.h" #include "vere/vere.h" +#include "ca-bundle.h" + /* Require unsigned char */ STATIC_ASSERT(( 0 == CHAR_MIN && UCHAR_MAX == CHAR_MAX ), @@ -362,6 +364,29 @@ _main_getopt(c3_i argc, c3_c** argv) return c3y; } +/* _setup_cert_store: writes our embedded certificate database to a temp file + */ +static void +_setup_cert_store(char* tmp_cert_file_name) +{ + errno = 0; + int fd = mkstemp(tmp_cert_file_name); + if (fd < 1) { + printf("boot: failed to write local ssl temporary certificate store: %s\n", + strerror(errno)); + exit(1); + } + + if (-1 == write(fd, include_ca_bundle_crt, include_ca_bundle_crt_len)) { + printf("boot: failed to write local ssl temporary certificate store: %s\n", + strerror(errno)); + exit(1); + } + + setenv("SSL_CERT_FILE", tmp_cert_file_name, 1); +} + + /* u3_ve_usage(): print usage and exit. */ static void @@ -677,6 +702,9 @@ main(c3_i argc, } // printf("vere: hostname is %s\n", u3_Host.ops_u.nam_c); + u3K.certs_c = strdup("/tmp/urbit-ca-cert-XXXXXX"); + _setup_cert_store(u3K.certs_c); + if ( c3y == u3_Host.ops_u.dem && c3n == u3_Host.ops_u.bat ) { printf("boot: running as daemon\n"); } @@ -752,5 +780,6 @@ main(c3_i argc, u3_daemon_commence(); } + return 0; } diff --git a/pkg/urbit/include/vere/vere.h b/pkg/urbit/include/vere/vere.h index 708adf3cb..a609251d6 100644 --- a/pkg/urbit/include/vere/vere.h +++ b/pkg/urbit/include/vere/vere.h @@ -699,6 +699,7 @@ */ typedef struct _u3_daemon { c3_c* soc_c; // socket name + c3_c* certs_c; // ssl certificate dump c3_w len_w; // number used c3_w all_w; // number allocated u3_pier** tab_u; // pier table diff --git a/pkg/urbit/vere/daemon.c b/pkg/urbit/vere/daemon.c index 96dba33e1..88dee816f 100644 --- a/pkg/urbit/vere/daemon.c +++ b/pkg/urbit/vere/daemon.c @@ -840,6 +840,7 @@ void _daemon_loop_exit() { unlink(u3K.soc_c); + unlink(u3K.certs_c); } /* u3_daemon_commence(): start the daemon