1%% This Source Code Form is subject to the terms of the Mozilla Public 2%% License, v. 2.0. If a copy of the MPL was not distributed with this 3%% file, You can obtain one at https://mozilla.org/MPL/2.0/. 4%% 5%% Copyright (c) 2007-2021 VMware, Inc. or its affiliates. All rights reserved. 6%% 7 8-module(rabbit_trust_store_app). 9-behaviour(application). 10-export([change_SSL_options/0]). 11-export([revert_SSL_options/0]). 12-export([start/2, stop/1]). 13 14-rabbit_boot_step({rabbit_trust_store, [ 15 {description, "Overrides TLS options in take RabbitMQ trust store into account"}, 16 {mfa, {?MODULE, change_SSL_options, []}}, 17 {cleanup, {?MODULE, revert_SSL_options, []}}, 18 %% {requires, ...}, 19 {enables, networking}]}). 20 21change_SSL_options() -> 22 After = case application:get_env(rabbit, ssl_options) of 23 undefined -> 24 Before = [], 25 edit(Before); 26 {ok, Before} when is_list(Before) -> 27 ok = application:set_env(rabbit, initial_SSL_options, Before), 28 edit(Before) 29 end, 30 ok = application:set_env(rabbit, 31 ssl_options, After). 32 33revert_SSL_options() -> 34 {ok, Cfg} = application:get_env(rabbit, initial_SSL_options), 35 ok = application:set_env(rabbit, ssl_options, Cfg). 36 37start(normal, _) -> 38 rabbit_trust_store_sup:start_link(). 39 40stop(_) -> 41 ok. 42 43 44%% Ancillary & Constants 45 46edit(Options) -> 47 case proplists:get_value(verify_fun, Options) of 48 undefined -> 49 ok; 50 Val -> 51 rabbit_log:warning("RabbitMQ trust store plugin is used " 52 "and the verify_fun TLS option is set: ~p. " 53 "It will be overwritten by the plugin.", [Val]), 54 ok 55 end, 56 %% Only enter those options neccessary for this application. 57 lists:keymerge(1, required_options(), 58 [{verify_fun, {delegate(), continue}}, 59 {partial_chain, fun partial_chain/1} | Options]). 60 61delegate() -> fun rabbit_trust_store:whitelisted/3. 62 63partial_chain(Chain) -> 64 % special handling of clients that present a chain rather than just a peer cert. 65 case lists:reverse(Chain) of 66 [PeerDer, Ca | _] -> 67 Peer = public_key:pkix_decode_cert(PeerDer, otp), 68 % If the Peer is whitelisted make it's immediate Authority a trusted one. 69 % This means the peer will automatically be validated. 70 case rabbit_trust_store:is_whitelisted(Peer) of 71 true -> {trusted_ca, Ca}; 72 false -> unknown_ca 73 end; 74 _ -> unknown_ca 75 end. 76 77required_options() -> 78 [{verify, verify_peer}, {fail_if_no_peer_cert, true}]. 79