diff --git a/Makefile b/Makefile
index 305e13a5..54802581 100644
--- a/Makefile
+++ b/Makefile
@@ -12,6 +12,17 @@ CODESPELL = $(shell which codespell)
SPELLCHECK = $(CODESPELL) -S _build -S doc -S .git -L applys,nd,accout,mattern,pres,fo
SPELLFIX = $(SPELLCHECK) -i 3 -w
+# Architecture Auto configuration
+UNAME_M := $(shell uname -m)
+ifeq ($(UNAME_M), x86_64)
+ DOCKER_PLATFORM = amd64
+else ifeq ($(UNAME_M), aarch64)
+ DOCKER_PLATFORM = arm64
+else ifeq ($(UNAME_M), arm64)
+ DOCKER_PLATFORM = arm64
+else ifeq ($(UNAME_M), armv7l)
+ DOCKER_PLATFORM = arm32v7
+endif
.PHONY: genvars compile check test xref eunit dialyzer tar spellcheck spellfix
@@ -33,6 +44,10 @@ docs: xref
cp -r doc/assets/* apps/bondy/doc/assets/
cp -r doc/assets/* apps/bondy_broker_bridge/doc/assets/
+clean: node1-clean node2-clean node3-clean
+ ${REBAR} clean
+
+
clean-docs:
rm -rf apps/bondy/doc/*
rm -f apps/bondy/doc/.build
@@ -119,18 +134,28 @@ node1:
${REBAR} as node1 release
ERL_DIST_PORT=27781 _build/node1/rel/bondy/bin/bondy console
+node1-clean:
+ ${REBAR} as node1 clean
+
node2:
${REBAR} as node2 release
ERL_DIST_PORT=27782 _build/node2/rel/bondy/bin/bondy console
+node2-clean:
+ ${REBAR} as node2 clean
+
node3:
${REBAR} as node3 release
ERL_DIST_PORT=27783 _build/node3/rel/bondy/bin/bondy console
+node3-clean:
+ ${REBAR} as node3 clean
edge1:
${REBAR} as edge1 release
- ERL_DIST_PORT=27784 _build/edge1/rel/bondy/bin/bondy console
+ EDGE1_DEVICE1_PRIVKEY=4ffddd896a530ce5ee8c86b83b0d31835490a97a9cd718cb2f09c9fd31c4a7d71766c9e6ec7d7b354fd7a2e4542753a23cae0b901228305621e5b8713299ccdd \
+ ERL_DIST_PORT=27784 \
+ _build/edge1/rel/bondy/bin/bondy console
run-node1:
@@ -155,7 +180,7 @@ docker-build:
docker rmi bondy-prod || true
docker build \
--pull \
- --platform linux/amd64 \
+ --platform linux/$(DOCKER_PLATFORM) \
--load \
-t "bondy-prod" \
-f deployment/Dockerfile .
@@ -167,7 +192,7 @@ docker-build-alpine:
docker rmi bondy-prod || true
docker build \
--pull \
- --platform linux/amd64 \
+ --platform linux/$(DOCKER_PLATFORM) \
--load \
-t "bondy-prod" \
-f deployment/alpine.Dockerfile .
@@ -179,7 +204,7 @@ docker-build-slim:
docker rmi bondy-prod || true
docker build \
--pull \
- --platform linux/amd64 \
+ --platform linux/$(DOCKER_PLATFORM) \
--load \
-t "bondy-prod" \
-f deployment/slim.Dockerfile .
diff --git a/README.md b/README.md
index 1e743268..c205997d 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,10 @@
![Bondy logo](https://github.com/Leapsight/bondy/blob/develop/doc/assets/bondy_bg.png?raw=true)
-![Version](https://img.shields.io/badge/version-1.0.0--beta.78-blue?style=for-the-badge)
+![Version](https://img.shields.io/badge/version-1.0.00-rc.1-blue?style=for-the-badge)
![Docker Pulls](https://img.shields.io/docker/pulls/leapsight/bondy?style=for-the-badge)
![Docker Build (master)](https://img.shields.io/github/actions/workflow/status/bondy-io/bondy/docker_image_build.yaml?&branch=master&label=docker-master&style=for-the-badge)
![Docker Build (develop)](https://img.shields.io/github/actions/workflow/status/bondy-io/bondy/docker_image_build.yaml?&branch=develop&label=docker-develop&style=for-the-badge)
-![Docker Build (latest-tag)](https://img.shields.io/github/actions/workflow/status/bondy-io/bondy/docker_image_build.yaml?&tag=version-1.0.0-beta.78&label=docker-1.0.0-beta.78&style=for-the-badge)
+![Docker Build (latest-tag)](https://img.shields.io/github/actions/workflow/status/bondy-io/bondy/docker_image_build.yaml?&tag=version-1.0.0-rc.1&label=docker-1.0.0-rc.1&style=for-the-badge)
![Architectures](https://img.shields.io/badge/architecture-linux%2Famd64%20%7C%20linux%2Farm64%20%7C%20macOS%2Fintel%20%7C%20macOS%2FM1-lightgrey?style=for-the-badge)
@@ -134,13 +134,14 @@ leapsight/bondy:master
### Building from source
#### Requirements
* macOS (Intel|Apple Silicon) or Linux (amd64|arm64)
-* [Erlang](https://www.erlang.org/) 24 or later
-* [Rebar3](https://rebar3.readme.io/) 3.17.0 or later
+* [Erlang](https://www.erlang.org/) 26.0.2 or later
+* [Rebar3](https://rebar3.readme.io/) 3.22.1 or later
* openssl
* libssl
* [Libsodium](https://github.com/jedisct1/libsodium)
* libsnappy
* liblz4
+* libcrypto
#### Building
@@ -156,7 +157,7 @@ rebar3 as prod tar
Untar and copy the resulting tarball to the location where you want to install Bondy e.g. `~/tmp/bondy`.
```shell
-tar -zxvf _build/prod/rel/bondy-1.0.0-beta.78.tar.qz -C ~/tmp/bondy
+tar -zxvf _build/prod/rel/bondy-1.0.0-rc.1.tar.qz -C ~/tmp/bondy
```
#### Running
diff --git a/apps/bondy/src/bondy.app.src b/apps/bondy/src/bondy.app.src
index 8deec902..3f7e2b07 100644
--- a/apps/bondy/src/bondy.app.src
+++ b/apps/bondy/src/bondy.app.src
@@ -26,10 +26,10 @@
"Bondy implements the open Web Application Messaging Protocol (WAMP) "
"and is written in Erlang."
},
- {vsn, "1.0.0-beta.78"},
+ {vsn, "1.0.0-rc.1"},
{registered, []},
%% We pass the version number in the bondy_app:start/2 arguments
- {mod, {bondy_app, [{vsn, "1.0.0-beta.78"}]}},
+ {mod, {bondy_app, [{vsn, "1.0.0-rc.1"}]}},
{applications,[
%% Erlang/OTP
stdlib,
diff --git a/apps/bondy/src/bondy_bridge_relay.erl b/apps/bondy/src/bondy_bridge_relay.erl
index da438a3e..64732be8 100644
--- a/apps/bondy/src/bondy_bridge_relay.erl
+++ b/apps/bondy/src/bondy_bridge_relay.erl
@@ -1,5 +1,5 @@
%% =============================================================================
-%% bondy_bridge_relay_listener.erl -
+%% bondy_bridge_relay.erl -
%%
%% Copyright (c) 2016-2023 Leapsight. All rights reserved.
%%
@@ -222,6 +222,28 @@
(_) -> false
end
},
+ hostname_verification => #{
+ alias => <<"hostname_verification">>,
+ %% We rename the prop
+ key => customize_hostname_check,
+ required => false,
+ datatype => {in, [
+ wildcard, none,
+ <<"wildcard">>, <<"none">>
+ ]},
+ validator => fun
+ (V) when V == <<"wildcard">>; V == wildcard ->
+ %% tls_options will end up having
+ %% #{
+ %% ...
+ %% customize_hostname_check => [{match_fun, Match}]
+ %% }
+ Match = public_key:pkix_verify_hostname_match_fun(https),
+ {ok, [{match_fun, Match}]};
+ (_) ->
+ {ok, []}
+ end
+ },
versions => #{
alias => <<"versions">>,
required => true,
diff --git a/apps/bondy/src/bondy_bridge_relay_client.erl b/apps/bondy/src/bondy_bridge_relay_client.erl
index 40d8e99d..89a0e002 100644
--- a/apps/bondy/src/bondy_bridge_relay_client.erl
+++ b/apps/bondy/src/bondy_bridge_relay_client.erl
@@ -1217,8 +1217,8 @@ signer(_, #{cryptosign := #{privkey_env_var := Var}}) ->
end
end;
-signer(_, _) ->
- error(invalid_cryptosign_config).
+signer(_, Conf) ->
+ error({invalid_cryptosign_config, Conf}).
%% @private
diff --git a/apps/bondy/src/bondy_system_gc.erl b/apps/bondy/src/bondy_system_gc.erl
index ad88590a..55ec8718 100644
--- a/apps/bondy/src/bondy_system_gc.erl
+++ b/apps/bondy/src/bondy_system_gc.erl
@@ -71,6 +71,7 @@ garbage_collect() ->
init([]) ->
+ ok = schedule_gc(),
{ok, #state{}}.
@@ -96,6 +97,10 @@ handle_cast(Event, State) ->
{noreply, State}.
+handle_info(scheduled_gc, State) ->
+ ok = do_gc(),
+ ok = schedule_gc(),
+ {noreply, State};
handle_info(Info, State) ->
?LOG_DEBUG(#{
@@ -123,11 +128,25 @@ code_change(_OldVsn, State, _Extra) ->
%% =============================================================================
+
+schedule_gc() ->
+ Interval = bondy_config:get(gc_interval, timer:minutes(5)),
+ erlang:send_after(Interval, self(), scheduled_gc),
+ ok.
+
+
+
do_gc() ->
- L = [element(1, X) || X <- recon:proc_count(memory, 100)],
+ {process_count, Count} = erlang:system_info(process_count),
+ Ratio = bondy_config:get(gc_ratio, 0.3),
+ N = round(Count * Ratio),
+ L = [element(1, X) || X <- recon:proc_count(memory, N)],
[
erlang:garbage_collect(P)
|| P <- L, {status, waiting} == process_info(P, status)
],
+
+ %% We gc ourselves
+ erlang:garbage_collect(),
ok.
\ No newline at end of file
diff --git a/apps/bondy/src/bondy_table_owner.erl b/apps/bondy/src/bondy_table_owner.erl
index 47466a66..f714406f 100644
--- a/apps/bondy/src/bondy_table_owner.erl
+++ b/apps/bondy/src/bondy_table_owner.erl
@@ -222,7 +222,7 @@ handle_call({add_and_claim, Name, Opts0}, {From, _Tag}, St) ->
handle_call({add_or_claim, Name, Opts0}, {From, _Tag}, St) ->
case lookup(Name) of
{ok, Tab} ->
- ok = do_give_away(Tab, From),
+ true = do_give_away(Tab, From),
{reply, {ok, Tab}, St};
error ->
Opts1 = set_heir(Opts0),
diff --git a/apps/bondy/test/bondy_ct.erl b/apps/bondy/test/bondy_ct.erl
index ca1e7dc3..94870c56 100644
--- a/apps/bondy/test/bondy_ct.erl
+++ b/apps/bondy/test/bondy_ct.erl
@@ -20,9 +20,9 @@
-include_lib("common_test/include/ct.hrl").
-if(?OTP_RELEASE >= 25).
- %% already defined by OTP
+ -define(TEST_SERVER, test_server).
-else.
- -define(CT_PEER, ct_slave).
+ -define(TEST_SERVER, ct_slave).
-endif.
-define(KERNEL_ENV, [
@@ -45,11 +45,9 @@
[{remote_gl,{fun logger_filters:remote_gl/2,stop}},
{no_domain,
{fun logger_filters:domain/2,{log,undefined,[]}}},
- {domain,
- {fun logger_filters:domain/2,{stop,equal,[sasl]}}},
{domain,
{fun logger_filters:domain/2,
- {log,super,[otp,bondy_audit]}}}],
+ {log,super,[otp, sasl, bondy_audit]}}}],
formatter =>
{bondy_logger_formatter,#{
colored => true,colored_alert => "\e[0;45m",
@@ -119,10 +117,15 @@
{tiered_slow_level,0}]},
{partisan,
[{exchange_tick_period,60000},
- {tls_options,
- [{cacertfile,"./etc/cacert.pem"},
- {keyfile,"./etc/key.pem"},
- {certfile,"./etc/cert.pem"},
+ {tls_server_options,
+ [{cacertfile,"./etc/ssl/server/cacert.pem"},
+ {keyfile,"./etc/ssl/server/key.pem"},
+ {certfile,"./etc/ssl/server/keycert.pem"},
+ {versions,['tlsv1.3']}]},
+ {tls_client_options,
+ [{cacertfile,"./etc/ssl/client/cacert.pem"},
+ {keyfile,"./etc/ssl/client/key.pem"},
+ {certfile,"./etc/ssl/client/keycert.pem"},
{versions,['tlsv1.3']}]},
{tls,false},
{peer_service_manager,partisan_pluggable_peer_service_manager},
@@ -166,9 +169,9 @@
{config_file,"./etc/oauth2_config.json"}]},
{bridge_relay_tls,
[{socket_opts,
- [{cacertfile,"./etc/cacert.pem"},
- {keyfile,"./etc/key.pem"},
- {certfile,"./etc/cert.pem"},
+ [{cacertfile,"./etc/ssl/server/cacert.pem"},
+ {keyfile,"./etc/ssl/server/key.pem"},
+ {certfile,"./etc/ssl/server/keycert.pem"},
{nodelay,true},
{keepalive,true},
{versions,['tlsv1.3']}]},
@@ -206,9 +209,9 @@
{enabled,false}]},
{wamp_tls,
[{socket_opts,
- [{cacertfile,"./etc/cacert.pem"},
- {keyfile,"./etc/key.pem"},
- {certfile,"./etc/cert.pem"},
+ [{cacertfile,"./etc/ssl/server/cacert.pem"},
+ {keyfile,"./etc/ssl/server/key.pem"},
+ {certfile,"./etc/ssl/server/keycert.pem"},
{nodelay,true},
{keepalive,true},
{versions,['tlsv1.2','tlsv1.3']}]},
@@ -240,9 +243,9 @@
{wamp_serializers,[{bert,4},{erl,15}]},
{api_gateway_https,
[{socket_opts,
- [{cacertfile,"./etc/cacert.pem"},
- {keyfile,"./etc/key.pem"},
- {certfile,"./etc/cert.pem"},
+ [{cacertfile,"./etc/ssl/server/cacert.pem"},
+ {keyfile,"./etc/ssl/server/key.pem"},
+ {certfile,"./etc/ssl/server/keycert.pem"},
{nodelay,true},
{keepalive,false},
{versions,['tlsv1.3']}]},
@@ -261,9 +264,9 @@
{api_gateway,[{config_file,"./etc/api_gateway_config.json"}]},
{admin_api_https,
[{socket_opts,
- [{cacertfile,"./etc/cacert.pem"},
- {keyfile,"./etc/key.pem"},
- {certfile,"./etc/cert.pem"},
+ [{cacertfile,"./etc/ssl/server/cacert.pem"},
+ {keyfile,"./etc/ssl/server/key.pem"},
+ {certfile,"./etc/ssl/server/keycert.pem"},
{nodelay,true},
{keepalive,false},
{versions,['tlsv1.3']}]},
@@ -424,7 +427,7 @@ stop_bondy() ->
%% -----------------------------------------------------------------------------
-%% @doc Starts a set of CT_PEER nodes as per `Config' and joins them in a
+%% @doc Starts a set of TEST_SERVER nodes as per `Config' and joins them in a
%% cluster.
%% @end
%% -----------------------------------------------------------------------------
@@ -438,7 +441,7 @@ start_cluster(_Case, _Config, _Options) ->
%% -----------------------------------------------------------------------------
stop_nodes(Nodes) ->
StopFun = fun({Name, _Node}) ->
- case ?CT_PEER:stop(Name) of
+ case ?TEST_SERVER:stop(Name) of
{ok, _} ->
ok;
{error, stop_timeout, _} ->
diff --git a/apps/bondy_broker_bridge/rebar.config b/apps/bondy_broker_bridge/rebar.config
index 6b11203c..27a436ba 100644
--- a/apps/bondy_broker_bridge/rebar.config
+++ b/apps/bondy_broker_bridge/rebar.config
@@ -10,7 +10,7 @@
},
%% Used by Kafka Bridge
{brod,
- {git, "https://github.com/klarna/brod.git", {tag, "3.16.1"}}
+ {git, "https://github.com/klarna/brod.git", {tag, "3.17.0"}}
},
{hash, ".*",
{git, "https://github.com/leapsight/hash", {branch, master}}
diff --git a/apps/bondy_broker_bridge/src/bondy_broker_bridge.app.src b/apps/bondy_broker_bridge/src/bondy_broker_bridge.app.src
index fc4bd0b1..54120c43 100644
--- a/apps/bondy_broker_bridge/src/bondy_broker_bridge.app.src
+++ b/apps/bondy_broker_bridge/src/bondy_broker_bridge.app.src
@@ -2,7 +2,7 @@
{description,
"Bondy Broker Bridge is an application that is part of Bondy and provides a way to integrate Events with external brokers and systems."
},
- {vsn, "1.0.0-beta.78"},
+ {vsn, "1.0.0-rc.1"},
{registered, []},
{mod, {bondy_broker_bridge_app, []}},
{applications, [
@@ -26,4 +26,4 @@
{"Website", "https://getbondy.io"},
{"Docker", "https://hub.docker.com/r/leapsight/bondy"}
]}
- ]}.
+]}.
diff --git a/config/dev/bondy.conf.template b/config/dev/bondy.conf.template
index bcf0796d..37d0a34e 100644
--- a/config/dev/bondy.conf.template
+++ b/config/dev/bondy.conf.template
@@ -13,9 +13,9 @@ admin_api.https.acceptors_pool_size = 200
admin_api.https.enabled = off
admin_api.https.keepalive = off
admin_api.https.max_connections = 250000
-admin_api.https.cacertfile = ${BONDY_ETC_DIR}/ssl/cacert.pem
-admin_api.https.certfile = ${BONDY_ETC_DIR}/ssl/cert.pem
-admin_api.https.keyfile = ${BONDY_ETC_DIR}/ssl/key.pem
+admin_api.https.cacertfile = ${BONDY_ETC_DIR}/ssl/server/cacert.pem
+admin_api.https.certfile = ${BONDY_ETC_DIR}/ssl/server/keycert.pem
+admin_api.https.keyfile = ${BONDY_ETC_DIR}/ssl/server/key.pem
admin_api.https.enabled = on
api_gateway.config_file = ${BONDY_ETC_DIR}/api_spec.json
api_gateway.http.acceptors_pool_size = 200
@@ -28,9 +28,9 @@ api_gateway.https.backlog = 4096
api_gateway.https.keepalive = off
api_gateway.https.max_connections = 500000
api_gateway.https.nodelay = on
-api_gateway.https.cacertfile = ${BONDY_ETC_DIR}/ssl/cacert.pem
-api_gateway.https.certfile = ${BONDY_ETC_DIR}/ssl/cert.pem
-api_gateway.https.keyfile = ${BONDY_ETC_DIR}/ssl/key.pem
+api_gateway.https.cacertfile = ${BONDY_ETC_DIR}/ssl/server/cacert.pem
+api_gateway.https.certfile = ${BONDY_ETC_DIR}/ssl/server/keycert.pem
+api_gateway.https.keyfile = ${BONDY_ETC_DIR}/ssl/server/key.pem
api_gateway.https.enabled = on
broker_bridge.config_file = ${BONDY_ETC_DIR}/broker_bridge_config.json
@@ -55,10 +55,17 @@ cluster.peer_discovery.timeout = 5s
cluster.peer_discovery.type = bondy_peer_discovery_static_agent
cluster.peer_discovery.config.nodes.1 = bondy1@127.0.0.1
cluster.peer_discovery.config.nodes.2 = bondy2@127.0.0.1
-cluster.tls.cacertfile = ${BONDY_ETC_DIR}/ssl/cacert.pem
-cluster.tls.certfile = ${BONDY_ETC_DIR}/ssl/cert.pem
-cluster.tls.keyfile = ${BONDY_ETC_DIR}/ssl/key.pem
cluster.tls.enabled = on
+cluster.tls.server.cacertfile = ${BONDY_ETC_DIR}/ssl/server/cacert.pem
+cluster.tls.server.certfile = ${BONDY_ETC_DIR}/ssl/server/keycert.pem
+cluster.tls.server.keyfile = ${BONDY_ETC_DIR}/ssl/server/key.pem
+cluster.tls.server.versions = 1.2,1.3
+cluster.tls.server.verify = verify_none
+cluster.tls.client.cacertfile = ${BONDY_ETC_DIR}/ssl/client/cacert.pem
+cluster.tls.client.certfile = ${BONDY_ETC_DIR}/ssl/client/keycert.pem
+cluster.tls.client.keyfile = ${BONDY_ETC_DIR}/ssl/client/key.pem
+cluster.tls.client.versions = 1.2,1.3
+# cluster.tls.client.verify = verify_none
distributed_cookie = bondy
erlang.async_threads = 64
erlang.max_ports = 65536
diff --git a/config/docker/vm.args b/config/docker/vm.args
index ecd24021..89d8a5ce 100644
--- a/config/docker/vm.args
+++ b/config/docker/vm.args
@@ -22,15 +22,25 @@
## Connections between hidden nodes and other nodes are not transitive, they must be set up explicitly.
-hidden
-## Increase distribution port buffer size.
-+zdbbl 32768
## -----------------------------------------------------------------------------
-## Erlang
+## Emulator Flags
## -----------------------------------------------------------------------------
+## Increase distribution port buffer size.
++zdbbl 32768
+
+# Disable Speculative Scheduler Busy Waiting
+# The threshold determines how long schedulers are to busy wait when running out
+# of work before going to sleep.
+sbwt none
+# As +sbwt but affects dirty CPU schedulers.
++sbwtdcpu none
+
+# As +sbwt but affects dirty IO schedulers.
++sbwtdio none
+
## Enable Time Correction
+c true
@@ -40,9 +50,6 @@
## Max processes
+P 2000000
-## Kernel polling
-+K true
-
## Async I/O threads
+A 64
diff --git a/config/make_certs b/config/make_certs
index 9b9c5e97..9953613e 100755
--- a/config/make_certs
+++ b/config/make_certs
@@ -18,41 +18,102 @@
%% %CopyrightEnd%
%%
+-record(config, {commonName,
+ organizationalUnitName = "Bondy",
+ organizationName = "Leapsight",
+ localityName = "London",
+ countryName = "UK",
+ emailAddress = "cert@leapsight.com",
+ default_bits = 2048,
+ v2_crls = true,
+ ecc_certs = false,
+ issuing_distribution_point = false,
+ crldp_crlissuer = false,
+ crl_port = 8000,
+ openssl_cmd = "openssl",
+ hostname = "host.example.com"}).
+
+%% Added for escript
main([]) ->
all("./_ssl/", "./_ssl").
-dn(CName) ->
- #{
- commonName => CName,
- organizationalUnitName => "Bondy",
- organizationName => "Leapsight",
- localityName => "London",
- countryName => "UK",
- emailAddress => "cert@leapsight.com"
- }.
-
-
-all(DataDir, Output) ->
- cmd("mkdir -p " ++ Output, []),
- OpenSSLCmd = "openssl",
- create_rnd(DataDir, Output), % For all requests
- rootCA(Output, OpenSSLCmd, "erlangCA"),
- intermediateCA(Output, OpenSSLCmd, "otpCA", "erlangCA"),
- endusers(Output, OpenSSLCmd, "otpCA", ["client", "server"]),
- collect_certs(Output, ["erlangCA", "otpCA"], ["client", "server"]),
+default_config() ->
+ #config{hostname = net_adm:localhost()}.
+
+make_config(Args) ->
+ make_config(Args, default_config()).
+
+make_config([], C) ->
+ C;
+make_config([{organizationalUnitName, Name}|T], C) when is_list(Name) ->
+ make_config(T, C#config{organizationalUnitName = Name});
+make_config([{organizationName, Name}|T], C) when is_list(Name) ->
+ make_config(T, C#config{organizationName = Name});
+make_config([{localityName, Name}|T], C) when is_list(Name) ->
+ make_config(T, C#config{localityName = Name});
+make_config([{countryName, Name}|T], C) when is_list(Name) ->
+ make_config(T, C#config{countryName = Name});
+make_config([{emailAddress, Name}|T], C) when is_list(Name) ->
+ make_config(T, C#config{emailAddress = Name});
+make_config([{default_bits, Bits}|T], C) when is_integer(Bits) ->
+ make_config(T, C#config{default_bits = Bits});
+make_config([{v2_crls, Bool}|T], C) when is_boolean(Bool) ->
+ make_config(T, C#config{v2_crls = Bool});
+make_config([{crl_port, Port}|T], C) when is_integer(Port) ->
+ make_config(T, C#config{crl_port = Port});
+make_config([{ecc_certs, Bool}|T], C) when is_boolean(Bool) ->
+ make_config(T, C#config{ecc_certs = Bool});
+make_config([{issuing_distribution_point, Bool}|T], C) when is_boolean(Bool) ->
+ make_config(T, C#config{issuing_distribution_point = Bool});
+make_config([{crldp_crlissuer, Bool}|T], C) when is_boolean(Bool) ->
+ make_config(T, C#config{crldp_crlissuer = Bool});
+make_config([{openssl_cmd, Cmd}|T], C) when is_list(Cmd) ->
+ make_config(T, C#config{openssl_cmd = Cmd});
+make_config([{hostname, Hostname}|T], C) when is_list(Hostname) ->
+ make_config(T, C#config{hostname = Hostname}).
+
+
+all([DataDir, PrivDir]) ->
+ all(DataDir, PrivDir).
+
+all(DataDir, PrivDir) ->
+ all(DataDir, PrivDir, #config{}).
+
+all(DataDir, PrivDir, C) when is_list(C) ->
+ all(DataDir, PrivDir, make_config(C));
+all(DataDir, PrivDir, C = #config{}) ->
+ ok = filelib:ensure_dir(filename:join(PrivDir, "erlangCA")),
+ create_rnd(DataDir, PrivDir), % For all requests
+ rootCA(PrivDir, "erlangCA", C),
+ intermediateCA(PrivDir, "otpCA", "erlangCA", C),
+ endusers(PrivDir, "otpCA", ["client", "server", "revoked", "undetermined", "a.server", "b.server"], C),
+ endusers(PrivDir, "erlangCA", ["localhost"], C),
%% Create keycert files
- SDir = filename:join([Output, "server"]),
+ SDir = filename:join([PrivDir, "server"]),
SC = filename:join([SDir, "cert.pem"]),
SK = filename:join([SDir, "key.pem"]),
SKC = filename:join([SDir, "keycert.pem"]),
append_files([SK, SC], SKC),
- CDir = filename:join([Output, "client"]),
+ CDir = filename:join([PrivDir, "client"]),
CC = filename:join([CDir, "cert.pem"]),
CK = filename:join([CDir, "key.pem"]),
CKC = filename:join([CDir, "keycert.pem"]),
append_files([CK, CC], CKC),
- remove_rnd(Output).
+ RDir = filename:join([PrivDir, "revoked"]),
+ RC = filename:join([RDir, "cert.pem"]),
+ RK = filename:join([RDir, "key.pem"]),
+ RKC = filename:join([RDir, "keycert.pem"]),
+ revoke(PrivDir, "otpCA", "revoked", C),
+ append_files([RK, RC], RKC),
+ MDir = filename:join([PrivDir, "undetermined"]),
+ MC = filename:join([MDir, "cert.pem"]),
+ MK = filename:join([MDir, "key.pem"]),
+ MKC = filename:join([MDir, "keycert.pem"]),
+ remove_entry(PrivDir, "otpCA", "undetermined", C),
+ append_files([MK, MC], MKC),
+ remove_rnd(PrivDir),
+ {ok, C}.
append_files(FileNames, ResultFileName) ->
{ok, ResultFile} = file:open(ResultFileName, [write]),
@@ -65,111 +126,221 @@ do_append_files([F|Fs], RF) ->
ok = file:write(RF, Data),
do_append_files(Fs, RF).
-rootCA(Root, OpenSSLCmd, Name) ->
- create_ca_dir(Root, Name, ca_cnf(Name)),
- DN = dn(Name),
- create_self_signed_cert(Root, OpenSSLCmd, Name, req_cnf(DN)),
- ok.
+rootCA(Root, Name, C) ->
+ create_ca_dir(Root, Name, ca_cnf(Root, C#config{commonName = Name})),
+ create_self_signed_cert(Root, Name, req_cnf(Root, C#config{commonName = Name}), C),
+ file:copy(filename:join([Root, Name, "cert.pem"]), filename:join([Root, Name, "cacerts.pem"])),
+ gencrl(Root, Name, C).
-intermediateCA(Root, OpenSSLCmd, CA, ParentCA) ->
- CA = "otpCA",
- create_ca_dir(Root, CA, ca_cnf(CA)),
+intermediateCA(Root, CA, ParentCA, C) ->
+ create_ca_dir(Root, CA, ca_cnf(Root, C#config{commonName = CA})),
CARoot = filename:join([Root, CA]),
- DN = dn(CA),
CnfFile = filename:join([CARoot, "req.cnf"]),
- file:write_file(CnfFile, req_cnf(DN)),
+ file:write_file(CnfFile, req_cnf(Root, C#config{commonName = CA})),
KeyFile = filename:join([CARoot, "private", "key.pem"]),
ReqFile = filename:join([CARoot, "req.pem"]),
- create_req(Root, OpenSSLCmd, CnfFile, KeyFile, ReqFile),
+ create_req(Root, CnfFile, KeyFile, ReqFile, C),
CertFile = filename:join([CARoot, "cert.pem"]),
- sign_req(Root, OpenSSLCmd, ParentCA, "ca_cert", ReqFile, CertFile).
-
-endusers(Root, OpenSSLCmd, CA, Users) ->
- lists:foreach(fun(User) -> enduser(Root, OpenSSLCmd, CA, User) end, Users).
-
-enduser(Root, OpenSSLCmd, CA, User) ->
+ sign_req(Root, ParentCA, "ca_cert", ReqFile, CertFile, C),
+ CACertsFile = filename:join(CARoot, "cacerts.pem"),
+ file:copy(filename:join([Root, ParentCA, "cacerts.pem"]), CACertsFile),
+ %% append this CA's cert to the cacerts file
+ {ok, Bin} = file:read_file(CertFile),
+ {ok, FD} = file:open(CACertsFile, [append]),
+ file:write(FD, ["\n", Bin]),
+ file:close(FD),
+ gencrl(Root, CA, C).
+
+endusers(Root, CA, Users, C) ->
+ [enduser(Root, CA, User, C) || User <- Users].
+
+enduser(Root, CA, User, C) ->
UsrRoot = filename:join([Root, User]),
file:make_dir(UsrRoot),
CnfFile = filename:join([UsrRoot, "req.cnf"]),
- DN = dn(User),
- file:write_file(CnfFile, req_cnf(DN)),
+ file:write_file(CnfFile, req_cnf(Root, C#config{commonName = User})),
KeyFile = filename:join([UsrRoot, "key.pem"]),
ReqFile = filename:join([UsrRoot, "req.pem"]),
- create_req(Root, OpenSSLCmd, CnfFile, KeyFile, ReqFile),
+ create_req(Root, CnfFile, KeyFile, ReqFile, C),
+ %create_req(Root, CnfFile, KeyFile, ReqFile),
CertFileAllUsage = filename:join([UsrRoot, "cert.pem"]),
- sign_req(Root, OpenSSLCmd, CA, "user_cert", ReqFile, CertFileAllUsage),
+ sign_req(Root, CA, "user_cert", ReqFile, CertFileAllUsage, C),
CertFileDigitalSigOnly = filename:join([UsrRoot, "digital_signature_only_cert.pem"]),
- sign_req(Root, OpenSSLCmd, CA, "user_cert_digital_signature_only", ReqFile, CertFileDigitalSigOnly).
-
-collect_certs(Root, CAs, Users) ->
- Bins = lists:foldr(
- fun(CA, Acc) ->
- File = filename:join([Root, CA, "cert.pem"]),
- {ok, Bin} = file:read_file(File),
- [Bin, "\n" | Acc]
- end, [], CAs),
- lists:foreach(
- fun(User) ->
- File = filename:join([Root, User, "cacerts.pem"]),
- file:write_file(File, Bins)
- end, Users).
+ sign_req(Root, CA, "user_cert_digital_signature_only", ReqFile, CertFileDigitalSigOnly, C),
+ CACertsFile = filename:join(UsrRoot, "cacerts.pem"),
+ file:copy(filename:join([Root, CA, "cacerts.pem"]), CACertsFile),
+ ok.
-create_self_signed_cert(Root, OpenSSLCmd, CAName, Cnf) ->
+revoke(Root, CA, User, C) ->
+ UsrCert = filename:join([Root, User, "cert.pem"]),
+ CACnfFile = filename:join([Root, CA, "ca.cnf"]),
+ Cmd = [C#config.openssl_cmd, " ca"
+ " -revoke ", UsrCert,
+ [" -crl_reason keyCompromise" || C#config.v2_crls ],
+ " -config ", CACnfFile],
+ Env = [{"ROOTDIR", filename:absname(Root)}],
+ cmd(Cmd, Env),
+ gencrl(Root, CA, C).
+
+%% Remove the certificate's entry from the database. The OCSP responder
+%% will consider the certificate to be unknown.
+remove_entry(Root, CA, User, C) ->
+ Db = filename:join([Root, CA, "index.txt"]),
+ remove_line_with_pattern(Db, "/CN=" ++ User ++ "/"),
+ gencrl(Root, CA, C).
+
+remove_line_with_pattern(File, Pattern) ->
+ {ok, Bin} = file:read_file(File),
+ AllLines = string:lexemes(Bin, [$\n,"\r\n"]),
+ MaybeRemove = fun(Line, Acc) ->
+ case string:find(Line, Pattern) of
+ nomatch -> [Line|Acc];
+ _ -> Acc
+ end
+ end,
+ RevLines = lists:foldl(MaybeRemove, [], AllLines),
+ Lines = lists:join("\n", lists:reverse(RevLines)),
+ ok = file:write_file(File, Lines).
+
+gencrl(Root, CA, C) ->
+ %% By default, the CRL is valid for a week from now.
+ gencrl(Root, CA, C, 24*7).
+
+gencrl(Root, CA, C, CrlHours) ->
+ CACnfFile = filename:join([Root, CA, "ca.cnf"]),
+ CACRLFile = filename:join([Root, CA, "crl.pem"]),
+ Cmd = [C#config.openssl_cmd, " ca"
+ " -gencrl ",
+ " -crlhours ", integer_to_list(CrlHours),
+ " -out ", CACRLFile,
+ " -config ", CACnfFile],
+ Env = [{"ROOTDIR", filename:absname(Root)}],
+ cmd(Cmd, Env).
+
+%% This function sets the number of seconds until the next CRL is due.
+gencrl_sec(Root, CA, C, CrlSecs) ->
+ CACnfFile = filename:join([Root, CA, "ca.cnf"]),
+ CACRLFile = filename:join([Root, CA, "crl.pem"]),
+ Cmd = [C#config.openssl_cmd, " ca"
+ " -gencrl ",
+ " -crlsec ", integer_to_list(CrlSecs),
+ " -out ", CACRLFile,
+ " -config ", CACnfFile],
+ Env = [{"ROOTDIR", filename:absname(Root)}],
+ cmd(Cmd, Env).
+
+can_generate_expired_crls(C) ->
+ %% OpenSSL can generate CRLs with an expiration date in the past,
+ %% if we pass a negative number for -crlhours. However, LibreSSL
+ %% rejects this with the error "invalid argument -24: too small".
+ %% Let's check which one we have.
+ Cmd = [C#config.openssl_cmd, " ca -crlhours -24"],
+ Output = os:cmd(Cmd),
+ 0 =:= string:str(Output, "too small").
+
+verify(Root, CA, User, C) ->
+ CAFile = filename:join([Root, User, "cacerts.pem"]),
+ CACRLFile = filename:join([Root, CA, "crl.pem"]),
+ CertFile = filename:join([Root, User, "cert.pem"]),
+ Cmd = [C#config.openssl_cmd, " verify"
+ " -CAfile ", CAFile,
+ " -CRLfile ", CACRLFile, %% this is undocumented, but seems to work
+ " -crl_check ",
+ CertFile],
+ Env = [{"ROOTDIR", filename:absname(Root)}],
+ try cmd(Cmd, Env) catch
+ exit:{eval_cmd, _, _} ->
+ invalid
+ end.
+
+create_self_signed_cert(Root, CAName, Cnf, C = #config{ecc_certs = true}) ->
CARoot = filename:join([Root, CAName]),
CnfFile = filename:join([CARoot, "req.cnf"]),
file:write_file(CnfFile, Cnf),
KeyFile = filename:join([CARoot, "private", "key.pem"]),
CertFile = filename:join([CARoot, "cert.pem"]),
- Cmd = [OpenSSLCmd, " req"
- " -new"
- " -x509"
- " -config ", CnfFile,
- " -keyout ", KeyFile,
- " -out ", CertFile],
- Env = [{"ROOTDIR", Root}],
+ Cmd = [C#config.openssl_cmd, " ecparam"
+ " -out ", KeyFile,
+ " -name secp521r1 ",
+ %" -name sect283k1 ",
+ " -genkey "],
+ Env = [{"ROOTDIR", filename:absname(Root)}],
cmd(Cmd, Env),
- fix_key_file(OpenSSLCmd, KeyFile).
-
-% openssl 1.0 generates key files in pkcs8 format by default and we don't handle this format
-fix_key_file(OpenSSLCmd, KeyFile) ->
- KeyFileTmp = KeyFile ++ ".tmp",
- Cmd = [OpenSSLCmd, " rsa",
- " -in ",
- KeyFile,
- " -out ",
- KeyFileTmp],
- cmd(Cmd, []),
- ok = file:rename(KeyFileTmp, KeyFile).
+
+ Cmd2 = [C#config.openssl_cmd, " req"
+ " -new"
+ " -x509"
+ " -config ", CnfFile,
+ " -key ", KeyFile,
+ " -outform PEM ",
+ " -out ", CertFile],
+ cmd(Cmd2, Env);
+create_self_signed_cert(Root, CAName, Cnf, C) ->
+ CARoot = filename:join([Root, CAName]),
+ CnfFile = filename:join([CARoot, "req.cnf"]),
+ file:write_file(CnfFile, Cnf),
+ KeyFile = filename:join([CARoot, "private", "key.pem"]),
+ CertFile = filename:join([CARoot, "cert.pem"]),
+ Cmd = [C#config.openssl_cmd, " req"
+ " -new"
+ " -x509"
+ " -config ", CnfFile,
+ " -keyout ", KeyFile,
+ " -outform PEM",
+ " -out ", CertFile],
+ Env = [{"ROOTDIR", filename:absname(Root)}],
+ cmd(Cmd, Env).
+
create_ca_dir(Root, CAName, Cnf) ->
CARoot = filename:join([Root, CAName]),
+ ok = filelib:ensure_dir(CARoot),
file:make_dir(CARoot),
create_dirs(CARoot, ["certs", "crl", "newcerts", "private"]),
create_rnd(Root, filename:join([CAName, "private"])),
create_files(CARoot, [{"serial", "01\n"},
- {"index.txt", ""},
- {"ca.cnf", Cnf}]).
-
-create_req(Root, OpenSSLCmd, CnfFile, KeyFile, ReqFile) ->
- Cmd = [OpenSSLCmd, " req"
- " -new"
- " -config ", CnfFile,
- " -keyout ", KeyFile,
- " -out ", ReqFile],
- Env = [{"ROOTDIR", Root}],
+ {"crlnumber", "01"},
+ {"index.txt", ""},
+ {"ca.cnf", Cnf}]).
+
+create_req(Root, CnfFile, KeyFile, ReqFile, C = #config{ecc_certs = true}) ->
+ Cmd = [C#config.openssl_cmd, " ecparam"
+ " -out ", KeyFile,
+ " -name secp521r1 ",
+ %" -name sect283k1 ",
+ " -genkey "],
+ Env = [{"ROOTDIR", filename:absname(Root)}],
cmd(Cmd, Env),
- fix_key_file(OpenSSLCmd, KeyFile).
+ Cmd2 = [C#config.openssl_cmd, " req"
+ " -new ",
+ " -key ", KeyFile,
+ " -outform PEM ",
+ " -out ", ReqFile,
+ " -config ", CnfFile],
+ cmd(Cmd2, Env);
+ %fix_key_file(KeyFile).
+create_req(Root, CnfFile, KeyFile, ReqFile, C) ->
+ Cmd = [C#config.openssl_cmd, " req"
+ " -new"
+ " -config ", CnfFile,
+ " -outform PEM ",
+ " -keyout ", KeyFile,
+ " -out ", ReqFile],
+ Env = [{"ROOTDIR", filename:absname(Root)}],
+ cmd(Cmd, Env).
+ %fix_key_file(KeyFile).
-sign_req(Root, OpenSSLCmd, CA, CertType, ReqFile, CertFile) ->
+
+sign_req(Root, CA, CertType, ReqFile, CertFile, C) ->
CACnfFile = filename:join([Root, CA, "ca.cnf"]),
- Cmd = [OpenSSLCmd, " ca"
- " -batch"
- " -notext"
- " -config ", CACnfFile,
- " -extensions ", CertType,
- " -in ", ReqFile,
- " -out ", CertFile],
- Env = [{"ROOTDIR", Root}],
+ Cmd = [C#config.openssl_cmd, " ca"
+ " -batch"
+ " -notext"
+ " -config ", CACnfFile,
+ " -extensions ", CertType,
+ " -in ", ReqFile,
+ " -out ", CertFile],
+ Env = [{"ROOTDIR", filename:absname(Root)}],
cmd(Cmd, Env).
%%
@@ -178,13 +349,13 @@ sign_req(Root, OpenSSLCmd, CA, CertType, ReqFile, CertFile) ->
create_dirs(Root, Dirs) ->
lists:foreach(fun(Dir) ->
- file:make_dir(filename:join([Root, Dir])) end,
- Dirs).
+ file:make_dir(filename:join([Root, Dir])) end,
+ Dirs).
create_files(Root, NameContents) ->
lists:foreach(
fun({Name, Contents}) ->
- file:write_file(filename:join([Root, Name]), Contents) end,
+ file:write_file(filename:join([Root, Name]), Contents) end,
NameContents).
create_rnd(FromDir, ToDir) ->
@@ -199,130 +370,307 @@ remove_rnd(Dir) ->
cmd(Cmd, Env) ->
FCmd = lists:flatten(Cmd),
Port = open_port({spawn, FCmd}, [stream, eof, exit_status, stderr_to_stdout,
- {env, Env}]),
- eval_cmd(Port).
+ {env, Env}]),
+ eval_cmd(Port, FCmd).
-eval_cmd(Port) ->
+eval_cmd(Port, Cmd) ->
receive
- {Port, {data, _}} ->
- eval_cmd(Port);
- {Port, eof} ->
- ok
+ {Port, {data, _}} ->
+ eval_cmd(Port, Cmd);
+ {Port, eof} ->
+ ok
end,
receive
- {Port, {exit_status, Status}} when Status /= 0 ->
- %% io:fwrite("exit status: ~w~n", [Status]),
- exit({eval_cmd, Status})
+ {Port, {exit_status, 0}} ->
+ ok;
+ {Port, {exit_status, Status}} ->
+ exit({eval_cmd, Cmd, Status})
after 0 ->
- ok
+ ok
end.
%%
%% Contents of configuration files
%%
-req_cnf(DN) ->
- #{
- commonName := CName,
- organizationalUnitName := OrganizationalUnitName,
- organizationName := OrganizationName,
- localityName := Local,
- countryName := Country,
- emailAddress := Email
- } = DN,
-
+req_cnf(Root, C) ->
["# Purpose: Configuration for requests (end users and CAs)."
"\n"
- "ROOTDIR = $ENV::ROOTDIR\n"
+ "ROOTDIR = " ++ Root ++ "\n"
"\n"
"[req]\n"
- "input_password = secret\n"
- "output_password = secret\n"
- "default_bits = 1024\n"
- "RANDFILE = $ROOTDIR/RAND\n"
- "encrypt_key = no\n"
- "default_md = sha1\n"
- "#string_mask = pkix\n"
- "x509_extensions = ca_ext\n"
- "prompt = no\n"
+ "input_password = secret\n"
+ "output_password = secret\n"
+ "default_bits = ", integer_to_list(C#config.default_bits), "\n"
+ "RANDFILE = $ROOTDIR/RAND\n"
+ "encrypt_key = no\n"
+ "default_md = sha256\n"
+ "#string_mask = pkix\n"
+ "x509_extensions = ca_ext\n"
+ "prompt = no\n"
"distinguished_name= name\n"
"\n"
"[name]\n"
- "commonName = ", CName, "\n"
- "organizationalUnitName = ", OrganizationalUnitName, "\n"
- "organizationName = ", OrganizationName, "\n"
- "localityName = ", Local, "\n"
- "countryName = ", Country, "\n"
- "emailAddress = ", Email, "\n"
+ "commonName = ", C#config.commonName, "\n"
+ "organizationalUnitName = ", C#config.organizationalUnitName, "\n"
+ "organizationName = ", C#config.organizationName, "\n"
+ "localityName = ", C#config.localityName, "\n"
+ "countryName = ", C#config.countryName, "\n"
+ "emailAddress = ", C#config.emailAddress, "\n"
"\n"
"[ca_ext]\n"
- "basicConstraints = critical, CA:true\n"
- "keyUsage = cRLSign, keyCertSign\n"
+ "basicConstraints = critical, CA:true\n"
+ "keyUsage = cRLSign, keyCertSign\n"
"subjectKeyIdentifier = hash\n"
- "subjectAltName = email:copy\n"].
+ "subjectAltName = email:copy\n"].
+
+ca_cnf(
+ Root,
+ #config{
+ issuing_distribution_point = true,
+ hostname = Hostname} = C) ->
+ ["# Purpose: Configuration for CAs.\n"
+ "\n"
+ "ROOTDIR = " ++ Root ++ "\n"
+ "default_ca = ca\n"
+ "\n"
+
+ "[ca]\n"
+ "dir = $ROOTDIR/", C#config.commonName, "\n"
+ "certs = $dir/certs\n"
+ "crl_dir = $dir/crl\n"
+ "database = $dir/index.txt\n"
+ "new_certs_dir = $dir/newcerts\n"
+ "certificate = $dir/cert.pem\n"
+ "serial = $dir/serial\n"
+ "crl = $dir/crl.pem\n",
+ ["crlnumber = $dir/crlnumber\n" || C#config.v2_crls],
+ "private_key = $dir/private/key.pem\n"
+ "RANDFILE = $dir/private/RAND\n"
+ "\n"
+ "x509_extensions = user_cert\n",
+ ["crl_extensions = crl_ext\n" || C#config.v2_crls],
+ "unique_subject = no\n"
+ "default_days = 3600\n"
+ "default_md = sha256\n"
+ "preserve = no\n"
+ "policy = policy_match\n"
+ "\n"
+
+ "[policy_match]\n"
+ "commonName = supplied\n"
+ "organizationalUnitName = optional\n"
+ "organizationName = match\n"
+ "countryName = match\n"
+ "localityName = match\n"
+ "emailAddress = supplied\n"
+ "\n"
+
+ "[crl_ext]\n"
+ "authorityKeyIdentifier=keyid:always,issuer:always\n",
+ ["issuingDistributionPoint=critical, @idpsec\n" || C#config.issuing_distribution_point],
+ "[idpsec]\n"
+ "fullname=URI:http://localhost:8000/",C#config.commonName,"/crl.pem\n"
-ca_cnf(CA) ->
+ "[user_cert]\n"
+ "basicConstraints = CA:false\n"
+ "keyUsage = nonRepudiation, digitalSignature, keyEncipherment\n"
+ "subjectKeyIdentifier = hash\n"
+ "authorityKeyIdentifier = keyid,issuer:always\n"
+ "subjectAltName = DNS.1:" ++ Hostname ++ "\n"
+ "issuerAltName = issuer:copy\n"
+ "crlDistributionPoints=@crl_section\n"
+
+ "[crl_section]\n"
+ %% intentionally invalid
+ "URI.1=http://localhost/",C#config.commonName,"/crl.pem\n"
+ "URI.2=http://localhost:",integer_to_list(C#config.crl_port),"/",C#config.commonName,"/crl.pem\n"
+ "\n"
+
+ "[user_cert_digital_signature_only]\n"
+ "basicConstraints = CA:false\n"
+ "keyUsage = digitalSignature\n"
+ "subjectKeyIdentifier = hash\n"
+ "authorityKeyIdentifier = keyid,issuer:always\n"
+ "subjectAltName = DNS.1:" ++ Hostname ++ "\n"
+ "issuerAltName = issuer:copy\n"
+ "\n"
+
+ "[ca_cert]\n"
+ "basicConstraints = critical,CA:true\n"
+ "keyUsage = cRLSign, keyCertSign\n"
+ "subjectKeyIdentifier = hash\n"
+ "authorityKeyIdentifier = keyid:always,issuer:always\n"
+ "subjectAltName = DNS.1:" ++ Hostname ++ "\n"
+ "issuerAltName = issuer:copy\n"
+ "crlDistributionPoints=@crl_section\n"
+ ];
+
+ca_cnf(
+ Root,
+ #config{
+ crldp_crlissuer = true,
+ hostname = Hostname} = C) ->
["# Purpose: Configuration for CAs.\n"
"\n"
- "ROOTDIR = $ENV::ROOTDIR\n"
- "default_ca = ca\n"
+ "ROOTDIR = " ++ Root ++ "\n"
+ "default_ca = ca\n"
"\n"
"[ca]\n"
- "dir = $ROOTDIR/", CA, "\n"
- "certs = $dir/certs\n"
- "crl_dir = $dir/crl\n"
- "database = $dir/index.txt\n"
- "new_certs_dir = $dir/newcerts\n"
- "certificate = $dir/cert.pem\n"
- "serial = $dir/serial\n"
- "crl = $dir/crl.pem\n"
- "private_key = $dir/private/key.pem\n"
- "RANDFILE = $dir/private/RAND\n"
+ "dir = $ROOTDIR/", C#config.commonName, "\n"
+ "certs = $dir/certs\n"
+ "crl_dir = $dir/crl\n"
+ "database = $dir/index.txt\n"
+ "new_certs_dir = $dir/newcerts\n"
+ "certificate = $dir/cert.pem\n"
+ "serial = $dir/serial\n"
+ "crl = $dir/crl.pem\n",
+ ["crlnumber = $dir/crlnumber\n" || C#config.v2_crls],
+ "private_key = $dir/private/key.pem\n"
+ "RANDFILE = $dir/private/RAND\n"
"\n"
- "x509_extensions = user_cert\n"
+ "x509_extensions = user_cert\n",
+ ["crl_extensions = crl_ext\n" || C#config.v2_crls],
"unique_subject = no\n"
- "default_days = 3600\n"
- "default_md = sha1\n"
- "preserve = no\n"
- "policy = policy_match\n"
+ "default_days = 3600\n"
+ "default_md = sha256\n"
+ "preserve = no\n"
+ "policy = policy_match\n"
"\n"
"[policy_match]\n"
- "commonName = supplied\n"
- "organizationalUnitName = optional\n"
- "organizationName = match\n"
- "countryName = match\n"
- "localityName = match\n"
- "emailAddress = supplied\n"
+ "commonName = supplied\n"
+ "organizationalUnitName = optional\n"
+ "organizationName = match\n"
+ "countryName = match\n"
+ "localityName = match\n"
+ "emailAddress = supplied\n"
"\n"
+ "[crl_ext]\n"
+ "authorityKeyIdentifier=keyid:always,issuer:always\n",
+
"[user_cert]\n"
- "basicConstraints = CA:false\n"
- "keyUsage = nonRepudiation, digitalSignature, keyEncipherment\n"
+ "basicConstraints = CA:false\n"
+ "keyUsage = nonRepudiation, digitalSignature, keyEncipherment\n"
+ "subjectKeyIdentifier = hash\n"
+ "authorityKeyIdentifier = keyid,issuer:always\n"
+ "subjectAltName = DNS.1:" ++ Hostname ++ "\n"
+ "issuerAltName = issuer:copy\n"
+ "crlDistributionPoints=crl_section\n"
+
+ "[crl_section]\n"
+ "fullname=URI:http://localhost/",C#config.commonName,"/crl.pem\n"
+ "CRLissuer=dirName:issuer_sect\n"
+
+ "[issuer_sect]\n"
+ "C=UK\n"
+ "O=Organisation\n"
+ "CN=Some Name\n"
+
+ "[user_cert_digital_signature_only]\n"
+ "basicConstraints = CA:false\n"
+ "keyUsage = digitalSignature\n"
"subjectKeyIdentifier = hash\n"
"authorityKeyIdentifier = keyid,issuer:always\n"
- "subjectAltName = email:copy\n"
- "issuerAltName = issuer:copy\n"
+ "subjectAltName = DNS.1:" ++ Hostname ++ "\n"
+ "issuerAltName = issuer:copy\n"
+ "\n"
+
+ "[ca_cert]\n"
+ "basicConstraints = critical,CA:true\n"
+ "keyUsage = cRLSign, keyCertSign\n"
+ "subjectKeyIdentifier = hash\n"
+ "authorityKeyIdentifier = keyid:always,issuer:always\n"
+ "subjectAltName = email:copy\n"
+ "issuerAltName = issuer:copy\n"
+ ];
+
+ca_cnf(
+ Root,
+ #config{
+ issuing_distribution_point = false,
+ hostname = Hostname
+ } = C) ->
+ ["# Purpose: Configuration for CAs.\n"
+ "\n"
+ "ROOTDIR = " ++ Root ++ "\n"
+ "default_ca = ca\n"
+ "\n"
+
+ "[ca]\n"
+ "dir = $ROOTDIR/", C#config.commonName, "\n"
+ "certs = $dir/certs\n"
+ "crl_dir = $dir/crl\n"
+ "database = $dir/index.txt\n"
+ "new_certs_dir = $dir/newcerts\n"
+ "certificate = $dir/cert.pem\n"
+ "serial = $dir/serial\n"
+ "crl = $dir/crl.pem\n",
+ ["crlnumber = $dir/crlnumber\n" || C#config.v2_crls],
+ "private_key = $dir/private/key.pem\n"
+ "RANDFILE = $dir/private/RAND\n"
+ "\n"
+ "x509_extensions = user_cert\n",
+ ["crl_extensions = crl_ext\n" || C#config.v2_crls],
+ "unique_subject = no\n"
+ "default_days = 3600\n"
+ "default_md = sha256\n"
+ "preserve = no\n"
+ "policy = policy_match\n"
"\n"
+ "[policy_match]\n"
+ "commonName = supplied\n"
+ "organizationalUnitName = optional\n"
+ "organizationName = match\n"
+ "countryName = match\n"
+ "localityName = match\n"
+ "emailAddress = supplied\n"
+ "\n"
+
+ "[crl_ext]\n"
+ "authorityKeyIdentifier=keyid:always,issuer:always\n",
+ %["issuingDistributionPoint=critical, @idpsec\n" || C#config.issuing_distribution_point],
+
+ %"[idpsec]\n"
+ %"fullname=URI:http://localhost:8000/",C#config.commonName,"/crl.pem\n"
+
+ "[user_cert]\n"
+ "basicConstraints = CA:false\n"
+ "keyUsage = nonRepudiation, digitalSignature, keyEncipherment\n"
+ "subjectKeyIdentifier = hash\n"
+ "authorityKeyIdentifier = keyid,issuer:always\n"
+ "subjectAltName = DNS.1:" ++ Hostname ++ "\n"
+ "issuerAltName = issuer:copy\n"
+ %"crlDistributionPoints=@crl_section\n"
+
+ %%"[crl_section]\n"
+ %% intentionally invalid
+ %%"URI.1=http://localhost/",C#config.commonName,"/crl.pem\n"
+ %%"URI.2=http://localhost:",integer_to_list(C#config.crl_port),"/",C#config.commonName,"/crl.pem\n"
+ %%"\n"
+
"[user_cert_digital_signature_only]\n"
- "basicConstraints = CA:false\n"
- "keyUsage = digitalSignature\n"
+ "basicConstraints = CA:false\n"
+ "keyUsage = digitalSignature\n"
"subjectKeyIdentifier = hash\n"
"authorityKeyIdentifier = keyid,issuer:always\n"
- "subjectAltName = email:copy\n"
- "issuerAltName = issuer:copy\n"
+ "subjectAltName = DNS.1:" ++ Hostname ++ "\n"
+ "issuerAltName = issuer:copy\n"
"\n"
"[ca_cert]\n"
- "basicConstraints = critical,CA:true\n"
- "keyUsage = cRLSign, keyCertSign\n"
+ "basicConstraints = critical,CA:true\n"
+ "keyUsage = cRLSign, keyCertSign\n"
"subjectKeyIdentifier = hash\n"
"authorityKeyIdentifier = keyid:always,issuer:always\n"
- "subjectAltName = email:copy\n"
- "issuerAltName = issuer:copy\n"].
+ "subjectAltName = email:copy\n"
+ "issuerAltName = issuer:copy\n"
+ %"crlDistributionPoints=@crl_section\n"
+ ].
\ No newline at end of file
diff --git a/config/test/edge_1_bondy.conf.template b/config/test/edge_1_bondy.conf.template
index b0edd305..ed4cf50a 100644
--- a/config/test/edge_1_bondy.conf.template
+++ b/config/test/edge_1_bondy.conf.template
@@ -37,17 +37,17 @@ api_gateway.https.nodelay = on
api_gateway.https.port = 19083
# broker_bridge.config_file = ${BONDY_ETC_DIR}/broker_bridge_config.json
-broker_bridge.kafka.clients.default.allow_topic_auto_creation = on
-broker_bridge.kafka.clients.default.auto_start_producers = on
-broker_bridge.kafka.clients.default.endpoints = [{"127.0.0.1", 9092}]
-broker_bridge.kafka.clients.default.max_metadata_sock_retry = 5
-broker_bridge.kafka.clients.default.producer.partition_restart_delay_seconds = 2s
-broker_bridge.kafka.clients.default.producer.required_acks = 1
-broker_bridge.kafka.clients.default.producer.topic_restart_delay_seconds = 10s
-broker_bridge.kafka.clients.default.reconnect_cool_down_seconds = 10s
-broker_bridge.kafka.clients.default.restart_delay_seconds = 10s
-broker_bridge.kafka.enabled = off
-broker_bridge.kafka.topics.wamp_events = com.leapsight.wamp.events
+# broker_bridge.kafka.clients.default.allow_topic_auto_creation = on
+# broker_bridge.kafka.clients.default.auto_start_producers = on
+# broker_bridge.kafka.clients.default.endpoints = [{"127.0.0.1", 9092}]
+# broker_bridge.kafka.clients.default.max_metadata_sock_retry = 5
+# broker_bridge.kafka.clients.default.producer.partition_restart_delay_seconds = 2s
+# broker_bridge.kafka.clients.default.producer.required_acks = 1
+# broker_bridge.kafka.clients.default.producer.topic_restart_delay_seconds = 10s
+# broker_bridge.kafka.clients.default.reconnect_cool_down_seconds = 10s
+# broker_bridge.kafka.clients.default.restart_delay_seconds = 10s
+# broker_bridge.kafka.enabled = off
+# broker_bridge.kafka.topics.wamp_events = com.leapsight.wamp.events
cluster.parallelism = 1
cluster.peer_port = 19086
@@ -96,10 +96,10 @@ wamp.tcp.port = 19082
wamp.tls.enabled = off
# wamp.tls.acceptors_pool_size = 200
# wamp.tls.backlog = 1024
-# wamp.tls.cacertfile = ${BONDY_ETC_DIR}/cacert.pem
-# wamp.tls.certfile = ${BONDY_ETC_DIR}/cert.pem
+# wamp.tls.cacertfile = ${BONDY_ETC_DIR}/ssl/server/cacert.pem
+# wamp.tls.certfile = ${BONDY_ETC_DIR}/ssl/server/keycert.pem
# wamp.tls.keepalive = on
-# wamp.tls.keyfile = ${BONDY_ETC_DIR}/key.pem
+# wamp.tls.keyfile = ${BONDY_ETC_DIR}/ssl/server/key.pem
# wamp.tls.max_connections = 100000
# wamp.tls.nodelay = on
# wamp.tls.port = 19085
@@ -108,18 +108,21 @@ wamp.tls.enabled = off
wamp.websocket.compression_enabled = on
-# bridge.edge = on
-# bridge.edge.transport = tls
-# bridge.edge.timeout = 5s
-# bridge.edge.reconnect = on
-# bridge.edge.reconnect.max_retries = 10
-
-
-# bridge.edge.endpoint = 127.0.0.1:18093
-# bridge.edge.realm.1.uri = com.leapsight.test
-# bridge.edge.realm.1.authid = device1
-# bridge.edge.realm.1.cryptosign.pubkey = 1766c9e6ec7d7b354fd7a2e4542753a23cae0b901228305621e5b8713299ccdd
-# bridge.edge.realm.1.cryptosign.privkey_env_var = EDGE1_DEVICE1_PRIVKEY
+bridge.edge = on
+bridge.edge.endpoint = 127.0.0.1:18093
+bridge.edge.transport = tls
+bridge.edge.timeout = 5s
+bridge.edge.reconnect = on
+bridge.edge.reconnect.max_retries = 10
+bridge.edge.tls.cacertfile = ${BONDY_ETC_DIR}/ssl/client/cacert.pem
+bridge.edge.tls.certfile = ${BONDY_ETC_DIR}/ssl/client/keycert.pem
+bridge.edge.tls.keyfile = ${BONDY_ETC_DIR}/ssl/client/key.pem
+bridge.edge.tls.versions = 1.2,1.3
+bridge.edge.tls.verify = verify_none
+bridge.edge.realm.1.uri = com.leapsight.test
+bridge.edge.realm.1.authid = device1
+bridge.edge.realm.1.cryptosign.pubkey = 1766c9e6ec7d7b354fd7a2e4542753a23cae0b901228305621e5b8713299ccdd
+bridge.edge.realm.1.cryptosign.privkey_env_var = EDGE1_DEVICE1_PRIVKEY
# bridge.edge.realm.1.procedure.1 = com.example.add exact out
# bridge.edge.realm.1.procedure.2 = com.example.mult exact out
# bridge.edge.realm.1.topic.1 = com.example. prefix out
diff --git a/config/test/node_1_bondy.conf.template b/config/test/node_1_bondy.conf.template
index 8f671a76..ca1886e2 100644
--- a/config/test/node_1_bondy.conf.template
+++ b/config/test/node_1_bondy.conf.template
@@ -23,7 +23,7 @@ admin_api.https.keepalive = off
admin_api.https.max_connections = 250000
admin_api.https.backlog = 18084
admin_api.https.cacertfile = ${BONDY_ETC_DIR}/ssl/server/cacert.pem
-admin_api.https.certfile = ${BONDY_ETC_DIR}/ssl/server/cert.pem
+admin_api.https.certfile = ${BONDY_ETC_DIR}/ssl/server/keycert.pem
admin_api.https.keyfile = ${BONDY_ETC_DIR}/ssl/server/key.pem
api_gateway.config_file = ${BONDY_ETC_DIR}/api_gateway_config.json
@@ -42,7 +42,7 @@ api_gateway.https.keepalive = off
api_gateway.https.max_connections = 500000
api_gateway.https.nodelay = on
api_gateway.https.cacertfile = ${BONDY_ETC_DIR}/ssl/server/cacert.pem
-api_gateway.https.certfile = ${BONDY_ETC_DIR}/ssl/server/cert.pem
+api_gateway.https.certfile = ${BONDY_ETC_DIR}/ssl/server/keycert.pem
api_gateway.https.keyfile = ${BONDY_ETC_DIR}/ssl/server/key.pem
broker_bridge.config_file = ${BONDY_ETC_DIR}/broker_bridge_config.json
@@ -71,13 +71,15 @@ cluster.peer_discovery.timeout = 5s
# cluster.peer_discovery.config.nodes.1 = bondy1@127.0.0.1:18086
cluster.tls.enabled = on
cluster.tls.server.cacertfile = ${BONDY_ETC_DIR}/ssl/server/cacert.pem
-cluster.tls.server.certfile = ${BONDY_ETC_DIR}/ssl/server/cert.pem
+cluster.tls.server.certfile = ${BONDY_ETC_DIR}/ssl/server/keycert.pem
cluster.tls.server.keyfile = ${BONDY_ETC_DIR}/ssl/server/key.pem
cluster.tls.server.versions = 1.2,1.3
-# cluster.tls.client.cacertfile = ${BONDY_ETC_DIR}/ssl/client/cacert.pem
-# cluster.tls.client.certfile = ${BONDY_ETC_DIR}/ssl/client/cert.pem
-# cluster.tls.client.keyfile = ${BONDY_ETC_DIR}/ssl/client/key.pem
-# cluster.tls.client.versions = 1.2,1.3
+cluster.tls.server.verify = verify_none
+cluster.tls.client.cacertfile = ${BONDY_ETC_DIR}/ssl/client/cacert.pem
+cluster.tls.client.certfile = ${BONDY_ETC_DIR}/ssl/client/keycert.pem
+cluster.tls.client.keyfile = ${BONDY_ETC_DIR}/ssl/client/key.pem
+cluster.tls.client.versions = 1.2,1.3
+cluster.tls.client.verify = verify_none
erlang.async_threads = 64
erlang.max_ports = 65536
@@ -118,7 +120,7 @@ wamp.tls.port = 18085
wamp.tls.acceptors_pool_size = 200
wamp.tls.backlog = 1024
wamp.tls.cacertfile = ${BONDY_ETC_DIR}/ssl/server/cacert.pem
-wamp.tls.certfile = ${BONDY_ETC_DIR}/ssl/server/cert.pem
+wamp.tls.certfile = ${BONDY_ETC_DIR}/ssl/server/keycert.pem
wamp.tls.keyfile = ${BONDY_ETC_DIR}/ssl/server/key.pem
wamp.tls.keepalive = on
wamp.tls.max_connections = 100000
@@ -134,6 +136,6 @@ bridge.listener.tcp.port = 18092
bridge.listener.tls = on
bridge.listener.tls.port = 18093
bridge.listener.tls.cacertfile = ${BONDY_ETC_DIR}/ssl/server/cacert.pem
-bridge.listener.tls.certfile = ${BONDY_ETC_DIR}/ssl/server/cert.pem
+bridge.listener.tls.certfile = ${BONDY_ETC_DIR}/ssl/server/keycert.pem
bridge.listener.tls.keyfile = ${BONDY_ETC_DIR}/ssl/server/key.pem
bridge.listener.tls.idle_timeout = 30s
\ No newline at end of file
diff --git a/config/test/node_2_bondy.conf.template b/config/test/node_2_bondy.conf.template
index dccc7e0a..e677ba31 100644
--- a/config/test/node_2_bondy.conf.template
+++ b/config/test/node_2_bondy.conf.template
@@ -59,13 +59,15 @@ cluster.peer_discovery.type = bondy_peer_discovery_static_agent
cluster.peer_discovery.config.nodes.1 = bondy1@127.0.0.1:18086
cluster.tls.enabled = on
cluster.tls.server.cacertfile = ${BONDY_ETC_DIR}/ssl/server/cacert.pem
-cluster.tls.server.certfile = ${BONDY_ETC_DIR}/ssl/server/cert.pem
+cluster.tls.server.certfile = ${BONDY_ETC_DIR}/ssl/server/keycert.pem
cluster.tls.server.keyfile = ${BONDY_ETC_DIR}/ssl/server/key.pem
cluster.tls.server.versions = 1.2,1.3
+cluster.tls.server.verify = verify_none
cluster.tls.client.cacertfile = ${BONDY_ETC_DIR}/ssl/client/cacert.pem
-cluster.tls.client.certfile = ${BONDY_ETC_DIR}/ssl/client/cert.pem
+cluster.tls.client.certfile = ${BONDY_ETC_DIR}/ssl/client/keycert.pem
cluster.tls.client.keyfile = ${BONDY_ETC_DIR}/ssl/client/key.pem
cluster.tls.client.versions = 1.2,1.3
+cluster.tls.client.verify = verify_none
erlang.async_threads = 64
erlang.max_ports = 65536
diff --git a/config/test/node_3_bondy.conf.template b/config/test/node_3_bondy.conf.template
index 456fe97c..a93df17d 100644
--- a/config/test/node_3_bondy.conf.template
+++ b/config/test/node_3_bondy.conf.template
@@ -59,13 +59,15 @@ cluster.peer_discovery.type = bondy_peer_discovery_static_agent
cluster.peer_discovery.config.nodes.1 = bondy1@127.0.0.1:18086
cluster.tls.enabled = on
cluster.tls.server.cacertfile = ${BONDY_ETC_DIR}/ssl/server/cacert.pem
-cluster.tls.server.certfile = ${BONDY_ETC_DIR}/ssl/server/cert.pem
+cluster.tls.server.certfile = ${BONDY_ETC_DIR}/ssl/server/keycert.pem
cluster.tls.server.keyfile = ${BONDY_ETC_DIR}/ssl/server/key.pem
cluster.tls.server.versions = 1.2,1.3
+cluster.tls.server.verify = verify_none
cluster.tls.client.cacertfile = ${BONDY_ETC_DIR}/ssl/client/cacert.pem
-cluster.tls.client.certfile = ${BONDY_ETC_DIR}/ssl/client/cert.pem
+cluster.tls.client.certfile = ${BONDY_ETC_DIR}/ssl/client/keycert.pem
cluster.tls.client.keyfile = ${BONDY_ETC_DIR}/ssl/client/key.pem
cluster.tls.client.versions = 1.2,1.3
+cluster.tls.client.verify = verify_none
erlang.async_threads = 64
erlang.max_ports = 65536
@@ -101,8 +103,9 @@ wamp.tcp.nodelay = on
wamp.tcp.port = 18282
wamp.tls.acceptors_pool_size = 200
wamp.tls.backlog = 1024
-wamp.tls.cacertfile = ${BONDY_ETC_DIR}/cacert.pem
-wamp.tls.certfile = ${BONDY_ETC_DIR}/cert.pem
+wamp.tls.cacertfile = ${BONDY_ETC_DIR}/ssl/server/cacert.pem
+wamp.tls.certfile = ${BONDY_ETC_DIR}/ssl/server/keycert.pem
+wamp.tls.keyfile = ${BONDY_ETC_DIR}/ssl/server/key.pem
wamp.tls.enabled = off
wamp.tls.keepalive = on
wamp.tls.keyfile = ${BONDY_ETC_DIR}/key.pem
diff --git a/deployment/Dockerfile b/deployment/Dockerfile
index 81edf1e7..82701529 100644
--- a/deployment/Dockerfile
+++ b/deployment/Dockerfile
@@ -4,7 +4,7 @@
# Build stage 1
# ===========================================================================
-FROM erlang:24 AS builder
+FROM erlang:26 AS builder
# Install build dependencies
RUN --mount=type=cache,id=apt,sharing=locked,target=/var/cache/apt apt-get update && \
@@ -69,7 +69,7 @@ ENV HOME "/bondy"
RUN apt-get update \
&& apt-get -y install \
sudo bash procps iproute2 net-tools curl jq nano \
- openssl libsodium-dev libsnappy-dev \
+ openssl libsodium-dev libsnappy-dev\
&& rm -rf /var/lib/apt/lists/* \
&& groupadd -g 1000 -r bondy \
&& useradd -u 1000 -r -g bondy -d /bondy -s /bin/bash -c "bondy" bondy \
diff --git a/deployment/alpine.Dockerfile b/deployment/alpine.Dockerfile
index 48da9122..1d9148b1 100644
--- a/deployment/alpine.Dockerfile
+++ b/deployment/alpine.Dockerfile
@@ -4,7 +4,7 @@
# Build stage 1
# ===========================================================================
-FROM erlang:24-alpine AS builder
+FROM erlang:26-alpine AS builder
# Install build dependencies
RUN --mount=type=cache,id=apk,sharing=locked,target=/var/cache/apk \
@@ -28,7 +28,7 @@ RUN rebar3 as docker tar && \
# Build stage 2
# ===========================================================================
-FROM alpine:3.16 as runner
+FROM alpine:3.18.3 as runner
# We define defaults
# We assume you have DNS. Erlang will take the FQDN and generate
diff --git a/rebar.config b/rebar.config
index 9aca3d97..b8e7f440 100644
--- a/rebar.config
+++ b/rebar.config
@@ -1,4 +1,4 @@
-{minimum_otp_vsn, "R24"}.
+{minimum_otp_vsn, "R26.0.2"}.
{erl_opts, [
% warn_export_all,
@@ -26,19 +26,19 @@
%% Crypto
%% -------------------------------------------------------------------------
{jose,
- {git, "https://github.com/potatosalad/erlang-jose.git", {tag, "1.11.2"}}
+ {git, "https://github.com/potatosalad/erlang-jose.git", {tag, "1.11.6"}}
},
{pbkdf2,
{git, "https://github.com/leapsight-oss/erlang-pbkdf2.git", {branch, "master"}}
},
- {stringprep, "1.0.27"},
+ {stringprep, "1.0.29"},
{enacl, "1.2.1"},
%% -------------------------------------------------------------------------
%% Web Server|client
%% -------------------------------------------------------------------------
%% Used to implement WebSockets, API Gateway, HTTP Admin API
%% and /metrics endpoint
- {cowboy, "2.9.0"},
+ {cowboy, "2.10.0"},
%% Used by API Gateway to implement forward action to
%% downstream HTTP services
hackney,
@@ -46,7 +46,21 @@
%% -------------------------------------------------------------------------
%% Utils
%% -------------------------------------------------------------------------
- {uuid, "2.0.4", {pkg, uuid_erl}},
+ {uuid, "2.0.6", {pkg, uuid_erl}},
+ {app_config,
+ {git, "https://github.com/leapsight/app_config.git", {tag, "1.1.1"}}
+ },
+ {leap, {
+ git,
+ "https://gitlab.com/leapsight/leap.git",
+ {branch, "master"}
+ }},
+ %% Leapsight utility library
+ {utils, {
+ git,
+ "https://github.com/leapsight/utils.git",
+ {tag, "1.3.7"}
+ }},
lrw,
%% -------------------------------------------------------------------------
%% Concurrency|Load|Traffic Management
@@ -63,11 +77,11 @@
%% Instrumentation/Debugging
%% -------------------------------------------------------------------------
bear,
- {observer_cli, "1.7.2"},
+ {observer_cli, "1.7.4"},
%% Exposes metrics to Promethues
- {prometheus, "4.8.1"},
+ {prometheus, "4.10.0"},
{prometheus_cowboy, "0.1.8"},
- {telemetry, "1.0.0"},
+ {telemetry, "1.2.1"},
{riak_sysmon,
{git, "https://github.com/Leapsight/riak_sysmon.git", {tag, "2.2.0"}}
},
@@ -88,7 +102,7 @@
{partisan, {
git,
"http://github.com/lasp-lang/partisan.git",
- {tag, "v5.0.0-rc.4"}
+ {tag, "v5.0.0-rc.7"}
}},
%% The embedded database using Partisan, Plumtree and dvvsets.
%% Stores data in ets and leveldb, also performs active anti-entropy
@@ -96,7 +110,7 @@
{plum_db, {
git,
"https://github.com/Leapsight/plum_db.git",
- {tag, "1.0.7"}
+ {tag, "1.0.11"}
}},
%% A partial implementation of an Adaptive Radix Trie.
%% We use it to store the procedure and topic tries.
@@ -111,18 +125,6 @@
git,
"https://gitlab.com/leapsight/mops.git",
{branch, "master"}
- }},
- %% Leapsight utility library implementing relational algebra
- {leap, {
- git,
- "https://gitlab.com/leapsight/leap.git",
- {branch, "master"}
- }},
- %% Leapsight utility library
- {utils, {
- git,
- "https://gitlab.com/leapsight/utils.git",
- {tag, "1.3.5"}
}}
]}.
@@ -134,7 +136,7 @@
{relx, [
- {release, {bondy, "1.0.0-beta.78"},[
+ {release, {bondy, "1.0.0-rc.1"},[
%% Erlang/OTP
crypto,
inets,
@@ -338,8 +340,8 @@
"{{platform_etc_dir}}/ssl/server/cacert.pem"
},
{copy,
- "config/_ssl/server/cert.pem",
- "{{platform_etc_dir}}/ssl/server/cert.pem"
+ "config/_ssl/server/keycert.pem",
+ "{{platform_etc_dir}}/ssl/server/keycert.pem"
},
{copy,
"config/_ssl/server/key.pem",
@@ -350,8 +352,8 @@
"{{platform_etc_dir}}/ssl/client/cacert.pem"
},
{copy,
- "config/_ssl/client/cert.pem",
- "{{platform_etc_dir}}/ssl/client/cert.pem"
+ "config/_ssl/client/keycert.pem",
+ "{{platform_etc_dir}}/ssl/client/keycert.pem"
},
{copy,
"config/_ssl/client/key.pem",
@@ -392,8 +394,8 @@
"{{platform_etc_dir}}/ssl/server/cacert.pem"
},
{copy,
- "config/_ssl/server/cert.pem",
- "{{platform_etc_dir}}/ssl/server/cert.pem"
+ "config/_ssl/server/keycert.pem",
+ "{{platform_etc_dir}}/ssl/server/keycert.pem"
},
{copy,
"config/_ssl/server/key.pem",
@@ -404,8 +406,8 @@
"{{platform_etc_dir}}/ssl/client/cacert.pem"
},
{copy,
- "config/_ssl/client/cert.pem",
- "{{platform_etc_dir}}/ssl/client/cert.pem"
+ "config/_ssl/client/keycert.pem",
+ "{{platform_etc_dir}}/ssl/client/keycert.pem"
},
{copy,
"config/_ssl/client/key.pem",
@@ -449,8 +451,8 @@
"{{platform_etc_dir}}/ssl/server/cacert.pem"
},
{copy,
- "config/_ssl/server/cert.pem",
- "{{platform_etc_dir}}/ssl/server/cert.pem"
+ "config/_ssl/server/keycert.pem",
+ "{{platform_etc_dir}}/ssl/server/keycert.pem"
},
{copy,
"config/_ssl/server/key.pem",
@@ -461,8 +463,8 @@
"{{platform_etc_dir}}/ssl/client/cacert.pem"
},
{copy,
- "config/_ssl/client/cert.pem",
- "{{platform_etc_dir}}/ssl/client/cert.pem"
+ "config/_ssl/client/keycert.pem",
+ "{{platform_etc_dir}}/ssl/client/keycert.pem"
},
{copy,
"config/_ssl/client/key.pem",
@@ -506,8 +508,8 @@
"{{platform_etc_dir}}/ssl/server/cacert.pem"
},
{copy,
- "config/_ssl/server/cert.pem",
- "{{platform_etc_dir}}/ssl/server/cert.pem"
+ "config/_ssl/server/keycert.pem",
+ "{{platform_etc_dir}}/ssl/server/keycert.pem"
},
{copy,
"config/_ssl/server/key.pem",
@@ -518,8 +520,8 @@
"{{platform_etc_dir}}/ssl/client/cacert.pem"
},
{copy,
- "config/_ssl/client/cert.pem",
- "{{platform_etc_dir}}/ssl/client/cert.pem"
+ "config/_ssl/client/keycert.pem",
+ "{{platform_etc_dir}}/ssl/client/keycert.pem"
},
{copy,
"config/_ssl/client/key.pem",
@@ -565,6 +567,30 @@
{template,
"config/test/sys.config",
"releases/{{release_version}}/sys.config"
+ },
+ {copy,
+ "config/_ssl/server/cacerts.pem",
+ "{{platform_etc_dir}}/ssl/server/cacert.pem"
+ },
+ {copy,
+ "config/_ssl/server/keycert.pem",
+ "{{platform_etc_dir}}/ssl/server/keycert.pem"
+ },
+ {copy,
+ "config/_ssl/server/key.pem",
+ "{{platform_etc_dir}}/ssl/server/key.pem"
+ },
+ {copy,
+ "config/_ssl/client/cacerts.pem",
+ "{{platform_etc_dir}}/ssl/client/cacert.pem"
+ },
+ {copy,
+ "config/_ssl/client/keycert.pem",
+ "{{platform_etc_dir}}/ssl/client/keycert.pem"
+ },
+ {copy,
+ "config/_ssl/client/key.pem",
+ "{{platform_etc_dir}}/ssl/client/key.pem"
}
]}
]}
@@ -843,11 +869,12 @@
"releases/{{release_version}}/schema/",
"etc/generated/user_defined.config"
},
- {
- "{{deps_dir}}/eleveldb/priv",
- "releases/{{release_version}}/schema/",
- "etc/generated/user_defined.config"
- },
+ %% Incorporated in plum_db
+ %% {
+ %% "{{deps_dir}}/eleveldb/priv",
+ %% "releases/{{release_version}}/schema/",
+ %% "etc/generated/user_defined.config"
+ %% },
{
"{{deps_dir}}/plum_db/priv",
"releases/{{release_version}}/schema/",
diff --git a/rebar.lock b/rebar.lock
index a8e7428f..f16da1db 100644
--- a/rebar.lock
+++ b/rebar.lock
@@ -2,9 +2,9 @@
[{<<"accept">>,{pkg,<<"accept">>,<<"0.3.5">>},2},
{<<"acceptor_pool">>,{pkg,<<"acceptor_pool">>,<<"1.0.0">>},1},
{<<"app_config">>,
- {git,"https://gitlab.com/leapsight/app_config.git",
- {ref,"e6a4dc99c0c9f17a6d4d865e40aefc409986f849"}},
- 1},
+ {git,"https://github.com/leapsight/app_config.git",
+ {ref,"01fa09bf6b7cac41b13a15552b6a9cc132acdaf4"}},
+ 0},
{<<"art">>,
{git,"https://gitlab.com/leapsight/art.git",
{ref,"35f8db5c877def1b4916791dce9a7858dc94dd33"}},
@@ -19,11 +19,11 @@
{<<"bert">>,{pkg,<<"bert">>,<<"0.1.0">>},0},
{<<"brod">>,
{git,"https://github.com/klarna/brod.git",
- {ref,"5d9f189623070f4927cb88af563552695b305fce"}},
+ {ref,"6966f0244b87904363cb8053ac0364ff281411d9"}},
0},
- {<<"certifi">>,{pkg,<<"certifi">>,<<"2.9.0">>},1},
- {<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.9.0">>},0},
- {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},1},
+ {<<"certifi">>,{pkg,<<"certifi">>,<<"2.12.0">>},1},
+ {<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.10.0">>},0},
+ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.12.1">>},1},
{<<"crc32cer">>,{pkg,<<"crc32cer">>,<<"0.1.8">>},2},
{<<"eini">>,{pkg,<<"eini">>,<<"1.2.9">>},1},
{<<"eleveldb">>,
@@ -35,9 +35,9 @@
{ref,"b62e070111e635e739628254eab8db2835631d28"}},
0},
{<<"enacl">>,{pkg,<<"enacl">>,<<"1.2.1">>},0},
- {<<"erlcloud">>,{pkg,<<"erlcloud">>,<<"3.6.1">>},0},
+ {<<"erlcloud">>,{pkg,<<"erlcloud">>,<<"3.7.3">>},0},
{<<"gproc">>,{pkg,<<"gproc">>,<<"0.9.0">>},1},
- {<<"hackney">>,{pkg,<<"hackney">>,<<"1.18.1">>},0},
+ {<<"hackney">>,{pkg,<<"hackney">>,<<"1.19.1">>},0},
{<<"hash">>,
{git,"https://github.com/leapsight/hash",
{ref,"dfbcc9ee089626f84068a1dcee3b1753a716871e"}},
@@ -50,7 +50,7 @@
0},
{<<"jsone">>,{pkg,<<"jsone">>,<<"1.6.1">>},1},
{<<"jsx">>,{pkg,<<"jsx">>,<<"2.11.0">>},1},
- {<<"kafka_protocol">>,{pkg,<<"kafka_protocol">>,<<"4.0.1">>},1},
+ {<<"kafka_protocol">>,{pkg,<<"kafka_protocol">>,<<"4.1.3">>},1},
{<<"key_value">>,
{git,"https://gitlab.com/leapsight/key_value.git",
{ref,"414fb19cd067b368666ceb5a2a63f1f24109562b"}},
@@ -66,6 +66,10 @@
{<<"lhttpc">>,{pkg,<<"lhttpc">>,<<"1.6.2">>},1},
{<<"logger_colorful">>,{pkg,<<"logger_colorful">>,<<"0.1.0">>},0},
{<<"lrw">>,{pkg,<<"lrw">>,<<"2.0.1">>},0},
+ {<<"maps_utils">>,
+ {git,"https://github.com/Leapsight/maps_utils.git",
+ {ref,"afa2da62e0e691ce33d1008cc424c994fff339bf"}},
+ 1},
{<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},1},
{<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.2.0">>},1},
{<<"mops">>,
@@ -73,16 +77,16 @@
{ref,"3955142d3720dc5b7a481e28124a2c5421dcd078"}},
0},
{<<"msgpack">>,{pkg,<<"msgpack">>,<<"0.7.0">>},0},
- {<<"observer_cli">>,{pkg,<<"observer_cli">>,<<"1.7.2">>},0},
+ {<<"observer_cli">>,{pkg,<<"observer_cli">>,<<"1.7.4">>},0},
{<<"opentelemetry_api">>,{pkg,<<"opentelemetry_api">>,<<"1.2.1">>},1},
{<<"opentelemetry_semantic_conventions">>,
{pkg,<<"opentelemetry_semantic_conventions">>,<<"0.2.0">>},
2},
- {<<"p1_utils">>,{pkg,<<"p1_utils">>,<<"1.0.23">>},1},
+ {<<"p1_utils">>,{pkg,<<"p1_utils">>,<<"1.0.25">>},1},
{<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.4.1">>},0},
{<<"partisan">>,
{git,"http://github.com/lasp-lang/partisan.git",
- {ref,"bcccdfc0a5b126344dda0ca9b7871e8225f7ad23"}},
+ {ref,"095d732cf9dd50e908c9c907a3481b2ac9b46a94"}},
0},
{<<"pbkdf2">>,
{git,"https://github.com/leapsight-oss/erlang-pbkdf2.git",
@@ -90,15 +94,15 @@
0},
{<<"plum_db">>,
{git,"https://github.com/Leapsight/plum_db.git",
- {ref,"0353f25f074a1f6f25ead0143a59a4ba7cd36b2b"}},
+ {ref,"6dc8819140d3502c2c24841d03f1362b584e397c"}},
0},
- {<<"prometheus">>,{pkg,<<"prometheus">>,<<"4.8.1">>},0},
+ {<<"prometheus">>,{pkg,<<"prometheus">>,<<"4.10.0">>},0},
{<<"prometheus_cowboy">>,{pkg,<<"prometheus_cowboy">>,<<"0.1.8">>},0},
{<<"prometheus_httpd">>,{pkg,<<"prometheus_httpd">>,<<"2.1.11">>},1},
{<<"quantile_estimator">>,{pkg,<<"quantile_estimator">>,<<"0.2.1">>},1},
- {<<"quickrand">>,{pkg,<<"quickrand">>,<<"2.0.4">>},1},
+ {<<"quickrand">>,{pkg,<<"quickrand">>,<<"2.0.6">>},1},
{<<"ranch">>,{pkg,<<"ranch">>,<<"1.8.0">>},1},
- {<<"recon">>,{pkg,<<"recon">>,<<"2.5.2">>},1},
+ {<<"recon">>,{pkg,<<"recon">>,<<"2.5.4">>},1},
{<<"riak_sysmon">>,
{git,"https://github.com/Leapsight/riak_sysmon.git",
{ref,"726df1f4c31108bb9366fb767b480f286e51f7fc"}},
@@ -106,11 +110,10 @@
{<<"setup">>,{pkg,<<"setup">>,<<"2.1.0">>},1},
{<<"sext">>,{pkg,<<"sext">>,<<"1.8.0">>},1},
{<<"sidejob">>,{pkg,<<"sidejob">>,<<"2.1.0">>},0},
- {<<"snappyer">>,{pkg,<<"snappyer">>,<<"1.2.8">>},1},
- {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.6">>},1},
- {<<"stringprep">>,{pkg,<<"stringprep">>,<<"1.0.27">>},0},
- {<<"supervisor3">>,{pkg,<<"supervisor3">>,<<"1.1.11">>},1},
- {<<"telemetry">>,{pkg,<<"telemetry">>,<<"1.0.0">>},0},
+ {<<"snappyer">>,{pkg,<<"snappyer">>,<<"1.2.9">>},1},
+ {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.7">>},1},
+ {<<"stringprep">>,{pkg,<<"stringprep">>,<<"1.0.29">>},0},
+ {<<"telemetry">>,{pkg,<<"telemetry">>,<<"1.2.1">>},0},
{<<"tuplespace">>,
{git,"https://gitlab.com/leapsight/tuplespace.git",
{ref,"d5e540dc2e1d3a4b75dbf3841de99d4547e118ff"}},
@@ -118,10 +121,10 @@
{<<"types">>,{pkg,<<"types">>,<<"0.1.8">>},1},
{<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.7.0">>},1},
{<<"utils">>,
- {git,"https://gitlab.com/leapsight/utils.git",
- {ref,"881e59760358bf22979d6ef1fcd96fc476c8b3ca"}},
+ {git,"https://github.com/leapsight/utils.git",
+ {ref,"641bd36d997970d355a700009bbaa6b84f0bd987"}},
0},
- {<<"uuid">>,{pkg,<<"uuid_erl">>,<<"2.0.4">>},0},
+ {<<"uuid">>,{pkg,<<"uuid_erl">>,<<"2.0.6">>},0},
{<<"wamp">>,
{git,"https://github.com/Leapsight/wamp.git",
{ref,"73c97fd06c5905d492d252d01bbd73cebe4ae337"}},
@@ -134,49 +137,48 @@
{<<"base16">>, <<"283644E2B21BD5915ACB7178BED7851FB07C6E5749B8FAD68A53C501092176D9">>},
{<<"bear">>, <<"430419C1126B477686CDE843E88BA0F2C7DC5CDF0881C677500074F704339A99">>},
{<<"bert">>, <<"A87D6693515070A9B287C1043CB7E5B2406BE0357685022764BFBD2609703555">>},
- {<<"certifi">>, <<"6F2A475689DD47F19FB74334859D460A2DC4E3252A3324BD2111B8F0429E7E21">>},
- {<<"cowboy">>, <<"865DD8B6607E14CF03282E10E934023A1BD8BE6F6BACF921A7E2A96D800CD452">>},
- {<<"cowlib">>, <<"0B9FF9C346629256C42EBE1EEB769A83C6CB771A6EE5960BD110AB0B9B872063">>},
+ {<<"certifi">>, <<"2D1CCA2EC95F59643862AF91F001478C9863C2AC9CB6E2F89780BFD8DE987329">>},
+ {<<"cowboy">>, <<"FF9FFEFF91DAE4AE270DD975642997AFE2A1179D94B1887863E43F681A203E26">>},
+ {<<"cowlib">>, <<"A9FA9A625F1D2025FE6B462CB865881329B5CAFF8F1854D1CBC9F9533F00E1E1">>},
{<<"crc32cer">>, <<"C6C2275C5FB60A95F4935D414F30B50EE9CFED494081C9B36EBB02EDFC2F48DB">>},
{<<"eini">>, <<"FCC3CBD49BBDD9A1D9735C7365DAFFCD84481CCE81E6CB80537883AA44AC4895">>},
{<<"enacl">>, <<"7776480B9B3D42A51D66DBBCBF17FA3D79285B3D2ADCB4D5B5BD0B70F0EF1949">>},
- {<<"erlcloud">>, <<"51B9045F96FE67A8823D384A163269403A30CD1CAD8C47EEEFF7026F17B16912">>},
+ {<<"erlcloud">>, <<"31F8A89C391B003350C832BDA550EC93E813889D2A3533915435A56B0ACCA844">>},
{<<"gproc">>, <<"853CCB7805E9ADA25D227A157BA966F7B34508F386A3E7E21992B1B484230699">>},
- {<<"hackney">>, <<"F48BF88F521F2A229FC7BAE88CF4F85ADC9CD9BCF23B5DC8EB6A1788C662C4F6">>},
+ {<<"hackney">>, <<"59DE4716E985DD2B5CBD4954FA1AE187E2B610A9C4520FFCB0B1653C3D6E5559">>},
{<<"idna">>, <<"8A63070E9F7D0C62EB9D9FCB360A7DE382448200FBBD1B106CC96D3D8099DF8D">>},
{<<"jobs">>, <<"329C024A889249EA8262D0EF70BC7A498B7C96DA95977EBD026B13B069FB0E13">>},
{<<"jsone">>, <<"7EA1098FE004C4127320FE0E3CF6A951B01F82039FEAA56C322DC7E34DD59762">>},
{<<"jsx">>, <<"08154624050333919B4AC1B789667D5F4DB166DC50E190C4D778D1587F102EE0">>},
- {<<"kafka_protocol">>, <<"FC696880C73483C8B032C4BB60F2873046035C7824E1EDCB924CFCE643CF23DD">>},
+ {<<"kafka_protocol">>, <<"362D85A898D4148A43DBABB10A30BB2D6FF32BA0097EB06981D11B34E2E0A9CD">>},
{<<"lhttpc">>, <<"044F16F0018C7AA7E945E9E9406C7F6035E0B8BC08BF77B00C78CE260E1071E3">>},
{<<"logger_colorful">>, <<"548A7F21C7F2F6713CD2E1A7B1323B2AD712E11AE5913D2FB05BE6F34B799081">>},
{<<"lrw">>, <<"E5BCA6EFD184C03451FF416D3B8FA250BFE867E02B705AF530A0E61CE7B5B32A">>},
{<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>},
{<<"mimerl">>, <<"67E2D3F571088D5CFD3E550C383094B47159F3EEE8FFA08E64106CDF5E981BE3">>},
{<<"msgpack">>, <<"128AE0A2227C7E7A2847C0F0F73551C268464F8C1EE96BFFB920BC0A5712B295">>},
- {<<"observer_cli">>, <<"1679C65D70049389195FDD9E5FE00F995946935D1DCC6357E514CA1AF136E238">>},
+ {<<"observer_cli">>, <<"3C1BFB6D91BF68F6A3D15F46AE20DA0F7740D363EE5BC041191CE8722A6C4FAE">>},
{<<"opentelemetry_api">>, <<"7B69ED4F40025C005DE0B74FCE8C0549625D59CB4DF12D15C32FE6DC5076FF42">>},
{<<"opentelemetry_semantic_conventions">>, <<"B67FE459C2938FCAB341CB0951C44860C62347C005ACE1B50F8402576F241435">>},
- {<<"p1_utils">>, <<"7F94466ADA69BD982EA7BB80FBCA18E7053E7D0B82C9D9E37621FA508587069B">>},
+ {<<"p1_utils">>, <<"2D39B5015A567BBD2CC7033EEB93A7C60D8C84EFE1EF69A3473FAA07FA268187">>},
{<<"parse_trans">>, <<"6E6AA8167CB44CC8F39441D05193BE6E6F4E7C2946CB2759F015F8C56B76E5FF">>},
- {<<"prometheus">>, <<"FA76B152555273739C14B06F09F485CF6D5D301FE4E9D31B7FF803D26025D7A0">>},
+ {<<"prometheus">>, <<"792ADBF0130FF61B5FA8826F013772AF24B6E57B984445C8D602C8A0355704A1">>},
{<<"prometheus_cowboy">>, <<"CFCE0BC7B668C5096639084FCD873826E6220EA714BF60A716F5BD080EF2A99C">>},
{<<"prometheus_httpd">>, <<"F616ED9B85B536B195D94104063025A91F904A4CFC20255363F49A197D96C896">>},
{<<"quantile_estimator">>, <<"EF50A361F11B5F26B5F16D0696E46A9E4661756492C981F7B2229EF42FF1CD15">>},
- {<<"quickrand">>, <<"168CA3A8466A26912B8C3A1D6AA58975E1BB49E5C7AFB4998B80F6B90F910490">>},
+ {<<"quickrand">>, <<"37E49398D614534F2861633F8E1155828676DF31ED90872616E4A526E6B9CF38">>},
{<<"ranch">>, <<"8C7A100A139FD57F17327B6413E4167AC559FBC04CA7448E9BE9057311597A1D">>},
- {<<"recon">>, <<"CBA53FA8DB83AD968C9A652E09C3ED7DDCC4DA434F27C3EAA9CA47FFB2B1FF03">>},
+ {<<"recon">>, <<"05DD52A119EE4059FA9DAA1AB7CE81BC7A8161A2F12E9D42E9D551FFD2BA901C">>},
{<<"setup">>, <<"05F69185A5EB71474C9BC6BA892565651EC7507791F85632B7B914DBFE130510">>},
{<<"sext">>, <<"90A95B889F5C781B70BBCF44278B763148E313C376B60D87CE664CB1C1DD29B5">>},
{<<"sidejob">>, <<"5D6A7C9C620778CB1908E46B552D767DF2ED4D77070BB7B5B8773D4FF18D1D37">>},
- {<<"snappyer">>, <<"201CE9067A33C71A6A5087C0C3A49A010B17112D461E6DF696C722DCB6D0934A">>},
- {<<"ssl_verify_fun">>, <<"CF344F5692C82D2CD7554F5EC8FD961548D4FD09E7D22F5B62482E5AEAEBD4B0">>},
- {<<"stringprep">>, <<"02808C7024BC6285CA6A8A67E7ADDFC16F35DDA55551A582C5181D8EA960E890">>},
- {<<"supervisor3">>, <<"D81CDEC31D102FDE407423E1D05B569572850DEEBED86B951D5233C387CBA80B">>},
- {<<"telemetry">>, <<"0F453A102CDF13D506B7C0AB158324C337C41F1CC7548F0BC0E130BBF0AE9452">>},
+ {<<"snappyer">>, <<"9CC58470798648CE34C662CA0AA6DAAE31367667714C9A543384430A3586E5D3">>},
+ {<<"ssl_verify_fun">>, <<"354C321CF377240C7B8716899E182CE4890C5938111A1296ADD3EC74CF1715DF">>},
+ {<<"stringprep">>, <<"02F23E8C3A219A3DFE40A22E908BECE3A2F68AF0FF599EA8A7B714ECB21E62EE">>},
+ {<<"telemetry">>, <<"68FDFE8D8F05A8428483A97D7AAB2F268AAFF24B49E0F599FAA091F1D4E7F61C">>},
{<<"types">>, <<"5782B67231E8C174FE2835395E71E669FE0121076779D2A09F1C0D58EE0E2F13">>},
{<<"unicode_util_compat">>, <<"BC84380C9AB48177092F43AC89E4DFA2C6D62B40B8BD132B1059ECC7232F9A78">>},
- {<<"uuid">>, <<"77C3E3EE1E1701A2856CE945846D7CEB71931C60633A305D0B0FEAE03B2B3B5C">>}]},
+ {<<"uuid">>, <<"8767AAE0D93A0EFD062B5B30BB21188E121721C683200E164445065C08C2100A">>}]},
{pkg_hash_ext,[
{<<"accept">>, <<"11B18C220BCC2EAB63B5470C038EF10EB6783BCB1FCDB11AA4137DEFA5AC1BB8">>},
{<<"acceptor_pool">>, <<"0CBCD83FDC8B9AD2EEE2067EF8B91A14858A5883CB7CD800E6FCD5803E158788">>},
@@ -184,47 +186,46 @@
{<<"base16">>, <<"02AFD0827E61A7B07093873E063575CA3A2B07520567C7F8CEC7C5D42F052D76">>},
{<<"bear">>, <<"157B67901ADF84FF0DA6EAE035CA1292A0AC18AA55148154D8C582B2C68959DB">>},
{<<"bert">>, <<"2A561521EC3529B248658A3E2D3D4BFE6729B0AB8291C701BF15EF413EDA1506">>},
- {<<"certifi">>, <<"266DA46BDB06D6C6D35FDE799BCB28D36D985D424AD7C08B5BB48F5B5CDD4641">>},
- {<<"cowboy">>, <<"2C729F934B4E1AA149AFF882F57C6372C15399A20D54F65C8D67BEF583021BDE">>},
- {<<"cowlib">>, <<"2B3E9DA0B21C4565751A6D4901C20D1B4CC25CBB7FD50D91D2AB6DD287BC86A9">>},
+ {<<"certifi">>, <<"EE68D85DF22E554040CDB4BE100F33873AC6051387BAF6A8F6CE82272340FF1C">>},
+ {<<"cowboy">>, <<"3AFDCCB7183CC6F143CB14D3CF51FA00E53DB9EC80CDCD525482F5E99BC41D6B">>},
+ {<<"cowlib">>, <<"163B73F6367A7341B33C794C4E88E7DBFE6498AC42DCD69EF44C5BC5507C8DB0">>},
{<<"crc32cer">>, <<"251499085482920DEB6C9B7AADABF9FB4C432F96ADD97AB42AEE4501E5B6F591">>},
{<<"eini">>, <<"DA64AE8DB7C2F502E6F20CDF44CD3D9BE364412B87FF49FEBF282540F673DFCB">>},
{<<"enacl">>, <<"67BBBEDDD2564DC899A3DCBC3765CD6AD71629134F1E500A50EC071F0F75E552">>},
- {<<"erlcloud">>, <<"9881E84692CF49435B7773CD91F71D8A6435532CCC30F3D2F6485036D9A93B2F">>},
+ {<<"erlcloud">>, <<"112B6E9B1C78FA4CD8E189681F2249E6E8C133D5AAB746ACFECBFA40B18E42DA">>},
{<<"gproc">>, <<"587E8AF698CCD3504CF4BA8D90F893EDE2B0F58CABB8A916E2BF9321DE3CF10B">>},
- {<<"hackney">>, <<"A4ECDAFF44297E9B5894AE499E9A070EA1888C84AFDD1FD9B7B2BC384950128E">>},
+ {<<"hackney">>, <<"8AA08234BDEFC269995C63C2282CF3CD0E36FEBE3A6BFAB11B610572FDD1CAD0">>},
{<<"idna">>, <<"92376EB7894412ED19AC475E4A86F7B413C1B9FBB5BD16DCCD57934157944CEA">>},
{<<"jobs">>, <<"09D486146BD32897726BB1F63DD95D1EB7F6F5A4C21C38CA58AB1646E8229724">>},
{<<"jsone">>, <<"A6C1DF6081DF742068D2ED747A4FE8A7740C56421B53E02BC9D4907DD3502922">>},
{<<"jsx">>, <<"EED26A0D04D217F9EECEFFFB89714452556CF90EB38F290A27A4D45B9988F8C0">>},
- {<<"kafka_protocol">>, <<"687BFD9989998EC8FBBC3ED50D1239A6C07A7DC15B52914AD477413B89ECB621">>},
+ {<<"kafka_protocol">>, <<"28CF73001270D972524DD0FAD4A59074F4441219F9CF237AD808A2AC1EC97487">>},
{<<"lhttpc">>, <<"76B5FA6149D1E10D4B1FBC4EBD51D371DB19C1AB9F0A9ECF5B526440DF064E97">>},
{<<"logger_colorful">>, <<"D2A11586B2311FF2CC4B2C38835FE8C8768D2087AE9BF7D9EA80C8C33E92689D">>},
{<<"lrw">>, <<"B81D24DE6248EA2509279C992F7B675B110EE166A63F4B2FAB97652446CAD611">>},
{<<"metrics">>, <<"69B09ADDDC4F74A40716AE54D140F93BEB0FB8978D8636EADED0C31B6F099F16">>},
{<<"mimerl">>, <<"F278585650AA581986264638EBF698F8BB19DF297F66AD91B18910DFC6E19323">>},
{<<"msgpack">>, <<"4649353DA003E6F438D105E4B1E0F17757F6F5EC8687A6F30875FF3AC4CE2A51">>},
- {<<"observer_cli">>, <<"A1D280C112BB5443F09B63041D6C5DDA39B40829DB40B24FDF208E1B86DAB353">>},
+ {<<"observer_cli">>, <<"50DE6D95D814F447458BD5D72666A74624EDDB0EF98BDCEE61A0153AAE0865FF">>},
{<<"opentelemetry_api">>, <<"6D7A27B7CAD2AD69A09CABF6670514CAFCEC717C8441BEB5C96322BAC3D05350">>},
{<<"opentelemetry_semantic_conventions">>, <<"D61FA1F5639EE8668D74B527E6806E0503EFC55A42DB7B5F39939D84C07D6895">>},
- {<<"p1_utils">>, <<"47F21618694EEEE5006AF1C88731AD86B757161E7823C29B6F73921B571C8502">>},
+ {<<"p1_utils">>, <<"9219214428F2C6E5D3187FF8EB9A8783695C2427420BE9A259840E07ADA32847">>},
{<<"parse_trans">>, <<"620A406CE75DADA827B82E453C19CF06776BE266F5A67CFF34E1EF2CBB60E49A">>},
- {<<"prometheus">>, <<"6EDFBE928D271C7F657A6F2C46258738086584BD6CAE4A000B8B9A6009BA23A5">>},
+ {<<"prometheus">>, <<"2A99BB6DCE85E238C7236FDE6B0064F9834DC420DDBD962AAC4EA2A3C3D59384">>},
{<<"prometheus_cowboy">>, <<"BA286BECA9302618418892D37BCD5DC669A6CC001F4EB6D6AF85FF81F3F4F34C">>},
{<<"prometheus_httpd">>, <<"0BBE831452CFDF9588538EB2F570B26F30C348ADAE5E95A7D87F35A5910BCF92">>},
{<<"quantile_estimator">>, <<"282A8A323CA2A845C9E6F787D166348F776C1D4A41EDE63046D72D422E3DA946">>},
- {<<"quickrand">>, <<"4CB18E9304CF28E054E8DC6E151D1AC7F174E6FE31D5C1A07F71279B92A90800">>},
+ {<<"quickrand">>, <<"86A03C7FC96B9C6B9FA6BEF5FCEB773E359C772EE3814BE60B8EB44B54F99140">>},
{<<"ranch">>, <<"49FBCFD3682FAB1F5D109351B61257676DA1A2FDBE295904176D5E521A2DDFE5">>},
- {<<"recon">>, <<"2C7523C8DEE91DFF41F6B3D63CBA2BD49EB6D2FE5BF1EEC0DF7F87EB5E230E1C">>},
+ {<<"recon">>, <<"E9AB01AC7FC8572E41EB59385EFEB3FB0FF5BF02103816535BACAEDF327D0263">>},
{<<"setup">>, <<"EFD072578F0CF85BEA96CAAFFC7ADB0992398272522660A136E10567377071C5">>},
{<<"sext">>, <<"BC6016CB8690BAF677EACACFE6E7CADFEC8DC7E286CBBED762F6CD55B0678E73">>},
{<<"sidejob">>, <<"6DC3DAC041C8C07C64401ECD22684730DA1497F5F14377B3CA9C5B2B9A135181">>},
- {<<"snappyer">>, <<"35518E79A28548B56D8FD6AEE2F565F12F51C2D3D053F9CFA817C83BE88C4F3D">>},
- {<<"ssl_verify_fun">>, <<"BDB0D2471F453C88FF3908E7686F86F9BE327D065CC1EC16FA4540197EA04680">>},
- {<<"stringprep">>, <<"A5967B1144CA8002A58A03D16DD109FBD0BCDB82616CEAD2F983944314AF6A00">>},
- {<<"supervisor3">>, <<"E6C2DEDBCABCBA24995A218ACA12DB5E208B80D3252692B22EF0F1A266104B50">>},
- {<<"telemetry">>, <<"73BC09FA59B4A0284EFB4624335583C528E07EC9AE76ACA96EA0673850AEC57A">>},
+ {<<"snappyer">>, <<"18D00CA218AE613416E6EECAFE1078DB86342A66F86277BD45C95F05BF1C8B29">>},
+ {<<"ssl_verify_fun">>, <<"FE4C190E8F37401D30167C8C405EDA19469F34577987C76DDE613E838BBC67F8">>},
+ {<<"stringprep">>, <<"928EBA304C3006EB1512110EBD7B87DB163B00859A09375A1E4466152C6C462A">>},
+ {<<"telemetry">>, <<"DAD9CE9D8EFFC621708F99EAC538EF1CBE05D6A874DD741DE2E689C47FEAFED5">>},
{<<"types">>, <<"04285239F4954C5EDE56F78ED7778EDE24E3F2E997F7B16402A167AF0CC2658A">>},
{<<"unicode_util_compat">>, <<"25EEE6D67DF61960CF6A794239566599B09E17E668D3700247BC498638152521">>},
- {<<"uuid">>, <<"7A4CCD1C151D9B88B4383FA802BCCF9BCB3754B7F53D7CAA164D51A14A6652E4">>}]}
+ {<<"uuid">>, <<"1D54D5DE4CC66317D882F62347A21655601E84CCCE913E80AADE202CDB3A8C65">>}]}
].
diff --git a/schema/bondy.schema b/schema/bondy.schema
index 270a68db..d9145fc1 100644
--- a/schema/bondy.schema
+++ b/schema/bondy.schema
@@ -668,14 +668,14 @@
hidden
]}.
-%% The Cowboy acceptors_pool_size for the Admin API https listener
+%% The Cowboy acceptors_pool_size for the Admin API http listener
{mapping, "admin_api.http.acceptors_pool_size", "bondy.admin_api_http.acceptors_pool_size", [
{datatype, integer},
{validators, ["pos_integer"]},
{default, 200}
]}.
-%% The Cowboy max number of connections for the Admin API https listener
+%% The Cowboy max number of connections for the Admin API http listener
{mapping, "admin_api.http.max_connections", "bondy.admin_api_http.max_connections", [
{datatype, integer},
{validators, ["pos_integer"]},
@@ -1891,14 +1891,12 @@
%% The time the agent will wait to initiate the next join attempt. For this to
%% take effect cluster.peer_discovery.automatic_join needs to be on.
-{mapping, "cluster.peer_discovery.join_retry_interval", "bondy.peer_discovery.join_retry_interval", [
+{mapping, "cluster.peer_discovery.join_retry_interval",
+ "bondy.peer_discovery.join_retry_interval", [
{default, "5s"},
{datatype, {duration, ms}}
]}.
-
-
-
%% The name of a module implementing the bondy_peer_discovery_agent behaviour.
%% At the moment Bondy provides only the `bondy_peer_discovery_dns_agent', which
%% ssumes that all Bondy nodes are deployed using a common base name e.g. bondy,
@@ -1960,6 +1958,28 @@ end}.
{datatype, flag}
]}.
+%% @doc If the `off' value is provided, it does nothing and the configuration
+%% will use any value provided by cluster.tls.server.cacertfile.
+%% If the `on' value is provided tries to load the trusted CA certificates
+%% provided by the OS. If no cacerts could be loaded it disables the option and
+%% revers to cluster.tls.server.cacertfile.
+%% If a DER-encoded trusted certificates string is provided it overrides option
+%% cluster.tls.server.cacertfile.
+{mapping, "cluster.tls.server.cacerts", "partisan.tls_server_options.cacerts", [
+ {default, false},
+ {datatype, [flag, string]}
+]}.
+
+%% @doc Defaults to verify_none as additional options are needed to be able to
+%% perform the certificate verification. A warning will be emitted unless
+%% verify_none is explicitly configured. Usually the applications will want to
+%% configure verify_peer together with an appropriate cacert or cacertfile
+%% option.
+{mapping, "cluster.tls.server.verify", "partisan.tls_server_options.verify", [
+ {datatype, {enum, [verify_peer, verify_none]}},
+ {default, verify_none}
+]}.
+
%% @doc Default cert location for cluster TLS connection
{mapping, "cluster.tls.server.certfile", "partisan.tls_server_options.certfile", [
{datatype, file},
@@ -1985,11 +2005,24 @@ end}.
{default, "1.3"}
]}.
-{mapping, "cluster.tls.server.verify", "partisan.tls_server_options.verify", [
+
+
+{mapping, "cluster.tls.client.verify", "partisan.tls_client_options.verify", [
{datatype, {enum, [verify_peer, verify_none]}},
{default, verify_none}
]}.
+%% @doc If the `off' value is provided, it does nothing and the configuration
+%% will use any value provided by cluster.tls.client.cacertfile.
+%% If the `on' value is provided tries to load the trusted CA certificates
+%% provided by the OS. If no cacerts could be loaded it disables the option and
+%% revers to cluster.tls.client.cacertfile.
+%% If a DER-encoded trusted certificates string is provided it overrides option
+%% cluster.tls.client.cacertfile.
+{mapping, "cluster.tls.client.cacerts", "partisan.tls_client_options.cacerts", [
+ {default, false},
+ {datatype, [flag, string]}
+]}.
%% @doc Default cert location for cluster TLS connection
{mapping, "cluster.tls.client.certfile", "partisan.tls_client_options.certfile", [
@@ -2016,11 +2049,6 @@ end}.
{default, "1.3"}
]}.
-{mapping, "cluster.tls.client.verify", "partisan.tls_client_options.verify", [
- {datatype, {enum, [verify_peer, verify_none]}},
- {default, verify_none}
-]}.
-
{translation, "partisan.tls_server_options.versions",
fun(Conf) ->
diff --git a/schema/bondy_bridge_relay.schema b/schema/bondy_bridge_relay.schema
index 4d40a3cc..3c5c8145 100644
--- a/schema/bondy_bridge_relay.schema
+++ b/schema/bondy_bridge_relay.schema
@@ -58,6 +58,13 @@
{commented, "{{platform_etc_dir}}/client/cacert.pem"}
]}.
+
+{mapping, "bridge.$name.tls.hostname_verification",
+ "bondy.bridges", [
+ {datatype, {enum, [wildcard, none]}},
+ {default, wildcard}
+]}.
+
%% @doc A comma separate list of TLS protocol versions that will be supported
%% At the moment Bondy only supports versions 1.2 and 1.3
{mapping, "bridge.$name.tls.versions", "bondy.bridges", [
@@ -478,6 +485,7 @@
when KeyStr == <<"cacertfile">>;
KeyStr == <<"certfile">>;
KeyStr == <<"keyfile">>;
+ KeyStr == <<"hostname_verification">>;
KeyStr == <<"verify">> ->
Key = binary_to_atom(KeyStr),
Put([Name, tls_opts, Key], Value, Acc);
@@ -931,7 +939,7 @@ end}.
%% with the edge.tls config variable, for example:
{mapping, "bridge.listener.tls.certfile", "bondy.bridge_relay_tls.tls_opts.certfile", [
{datatype, file},
- {default, "{{platform_etc_dir}}/cert.pem"}
+ {default, "{{platform_etc_dir}}/keycert.pem"}
]}.
%% @doc Default key location for https can be overridden with the
diff --git a/schema/logger.schema b/schema/logger.schema
index eae09a5b..6004156b 100644
--- a/schema/logger.schema
+++ b/schema/logger.schema
@@ -8,7 +8,6 @@
]}}
]}.
-
%% =============================================================================
%% DEFAULT HANDLER
%% =============================================================================
@@ -263,12 +262,17 @@
%% and print them to a dedicated handler.
%%
%% The value is a comma separated string which con contain one or more of the
-%% following elements: "otp", "sasl" and "bondy_audit"
+%% following elements: "otp", "ssl" and "bondy_audit"
{mapping, "log.handlers.default.filter_domains", "kernel.logger", [
{default, "otp, bondy_audit"},
{datatype, string}
]}.
+{mapping, "log.handlers.default.allow_progress_reports", "kernel.logger", [
+ {default, off},
+ {datatype, flag}
+]}.
+
%% When formatting maps limit their depth to a value. If -1 is provided, this
%% option is disabled.
{mapping, "log.handlers.default.formatter.map_depth", "kernel.logger", [
@@ -599,6 +603,11 @@
{datatype, string}
]}.
+{mapping, "log.handlers.$id.allow_progress_reports", "kernel.logger", [
+ {default, off},
+ {datatype, flag}
+]}.
+
%% When formatting maps limit their depth to a value. If -1 is provided, this
%% option is disabled.
{mapping, "log.handlers.$id.formatter.map_depth", "kernel.logger", [
@@ -775,35 +784,60 @@
end,
%% Filters
- AllDomains = sets:from_list([otp, sasl, bondy_audit]),
+ AllDomains = sets:from_list([otp, ssl, bondy_audit]),
ConfDomains = cuttlefish:conf_get(
HandlerPrefix ++ ["filter_domains"], HandlersConf
),
+ AllowProgressReports = cuttlefish:conf_get(
+ HandlerPrefix ++ ["allow_progress_reports"], HandlersConf
+ ),
+ ProgressAction =
+ case AllowProgressReports of
+ true -> log;
+ false -> stop
+ end,
+
LogDomains = sets:from_list([
list_to_existing_atom(string:strip(X, both))
|| X <- string:tokens(ConfDomains, ",")
]),
StopDomains = sets:subtract(AllDomains, LogDomains),
+ DomainFilter = fun
+ (Action, _, D) when D == otp; D == sasl ->
+ {
+ fun logger_filters:domain/2,
+ {Action, equal, [otp, sasl]}
+ };
+ (Action, Rel, D) ->
+ {
+ fun logger_filters:domain/2,
+ {Action, equal, [D]}
+ }
+ end,
+ LogFilters = [
+ {D,
+ DomainFilter(log, sub, D)
+ } || D <- sets:to_list(LogDomains)
+ ],
+ StopFilters = [
+ {D,
+ DomainFilter(stop, super, D)
+ } || D <- sets:to_list(StopDomains)
+ ],
Filters = [
+ {progress,
+ {fun logger_filters:progress/2, ProgressAction}
+ },
{remote_gl,
{fun logger_filters:remote_gl/2, stop}
},
{no_domain,
{fun logger_filters:domain/2, {log, undefined, []}}
- },
- {domain,
- {
- fun logger_filters:domain/2,
- {stop, equal, sets:to_list(StopDomains)}}
- },
- {domain,
- {
- fun logger_filters:domain/2,
- {log, super, sets:to_list(LogDomains)}}
- }
+ } | LogFilters ++ StopFilters
],
+
%% Formatter
FormatConf = cuttlefish_variable:filter_by_prefix(
HandlerPrefix ++ ["formatter"], CuttleConf