Skip to content

Commit 02099b8

Browse files
Merge pull request #15746 from rabbitmq/mk-trust-store-cli-commands
Trust store: introduce proper CLI commands (cherry picked from commit 9e4767c)
1 parent f3c7401 commit 02099b8

4 files changed

Lines changed: 185 additions & 28 deletions

File tree

deps/rabbitmq_trust_store/README.md

Lines changed: 19 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -160,25 +160,29 @@ certificates from a directory.
160160

161161
### Listing certificates
162162

163-
To list the currently loaded certificates use the `rabbitmqctl` utility as follows:
163+
To list the currently loaded certificates, use `rabbitmqctl`:
164164

165-
```
166-
rabbitmqctl eval 'io:format(rabbit_trust_store:list()).'
165+
``` sh
166+
# Available as of RabbitMQ `4.3.0`, `4.2.6`
167+
rabbitmqctl list_trust_store_certificates
167168
```
168169

169-
This will output a formatted list of certificates similar to:
170+
This will output a table of certificates similar to:
170171

171172
```
172-
Name: cert.pem
173-
Serial: 1 | 0x1
174-
Subject: O=client,CN=snowman.local
175-
Issuer: L=87613,CN=MyTestRootCA
176-
Validity: "2016-05-24T15:28:25Z - 2026-05-22T15:28:25Z"
173+
Listing trust store certificates on node rabbit@hostname...
174+
name serial subject issuer validity
175+
cert.pem 0x1 O=client,CN=snowman.local L=87613,CN=MyTestRootCA 2016-05-24T15:28:25Z - 2026-05-22T15:28:25Z
177176
```
178177

179-
Note that this command reads each certificate from disk in order to extract
180-
all the relevant information. If there are a large number of certificates in the
181-
trust store use this command sparingly.
178+
### Refreshing certificates
179+
180+
To trigger a manual refresh of the trust store certificates, use `rabbitmqctl`:
181+
182+
``` sh
183+
# Available as of RabbitMQ `4.3.0`, `4.2.6`
184+
rabbitmqctl refresh_trust_store
185+
```
182186

183187

184188
## How it Works
@@ -188,23 +192,11 @@ whitelists the certificates in the given directory, then accepting
188192
sockets can query the trust-store with their client's certificate. It
189193
refreshes the whitelist to correspond with changes in the directory's
190194
contents, installing and removing certificate details, after a refresh
191-
interval or a manual refresh (by invoking a `rabbitmqctl eval
192-
'rabbit_trust_store:refresh().'` from the commandline).
193-
194-
195-
## Building from Source
196-
197-
See [Plugin Development guide](https://www.rabbitmq.com/plugin-development.html).
198-
199-
TL;DR: running
200-
201-
make dist
202-
203-
will build the plugin and put build artifacts under the `./plugins` directory.
195+
interval or a manual refresh (by running `rabbitmqctl refresh_trust_store`).
204196

205197

206198
## Copyright and License
207199

208-
(c) 2007-2024 Broadcom. The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. All rights reserved.
200+
(c) 2007-2026 Broadcom. The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. All rights reserved.
209201

210-
Released under the MPL, the same license as RabbitMQ.
202+
Released under the MPLv2, the same license as RabbitMQ.
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
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-2026 Broadcom. All Rights Reserved. The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. All rights reserved.
6+
%%
7+
8+
-module('Elixir.RabbitMQ.CLI.Ctl.Commands.ListTrustStoreCertificatesCommand').
9+
10+
-behaviour('Elixir.RabbitMQ.CLI.CommandBehaviour').
11+
12+
-export([
13+
usage/0,
14+
usage_doc_guides/0,
15+
validate/2,
16+
merge_defaults/2,
17+
banner/2,
18+
run/2,
19+
switches/0,
20+
aliases/0,
21+
output/2,
22+
scopes/0,
23+
formatter/0,
24+
help_section/0,
25+
description/0
26+
]).
27+
28+
29+
%%
30+
%% Command Behavior
31+
%%
32+
33+
usage() ->
34+
<<"list_trust_store_certificates">>.
35+
36+
usage_doc_guides() ->
37+
[<<"https://rabbitmq.com/docs/ssl">>].
38+
39+
description() ->
40+
<<"Lists certificates in the trust store on a node">>.
41+
42+
help_section() ->
43+
{plugin, trust_store}.
44+
45+
formatter() ->
46+
'Elixir.RabbitMQ.CLI.Formatters.Table'.
47+
48+
validate(_, _) ->
49+
ok.
50+
51+
merge_defaults(A, O) ->
52+
{A, O}.
53+
54+
banner(_, #{node := Node}) ->
55+
erlang:iolist_to_binary([<<"Listing trust store certificates on node ">>,
56+
atom_to_binary(Node, utf8), <<"...">>]).
57+
58+
run(_Args, #{node := Node}) ->
59+
case rabbit_misc:rpc_call(Node, rabbit_trust_store, list_certificates, []) of
60+
{badrpc, _} = Error ->
61+
Error;
62+
Certs when is_list(Certs) ->
63+
{stream, Certs}
64+
end.
65+
66+
switches() ->
67+
[].
68+
69+
aliases() ->
70+
[].
71+
72+
output({stream, Certs}, _Opts) ->
73+
{stream, Certs};
74+
output(E, _Opts) ->
75+
'Elixir.RabbitMQ.CLI.DefaultOutput':output(E).
76+
77+
scopes() ->
78+
['ctl', 'diagnostics'].
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
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-2026 Broadcom. All Rights Reserved. The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. All rights reserved.
6+
%%
7+
8+
-module('Elixir.RabbitMQ.CLI.Ctl.Commands.RefreshTrustStoreCommand').
9+
10+
-behaviour('Elixir.RabbitMQ.CLI.CommandBehaviour').
11+
12+
-export([
13+
usage/0,
14+
usage_doc_guides/0,
15+
validate/2,
16+
merge_defaults/2,
17+
banner/2,
18+
run/2,
19+
aliases/0,
20+
output/2,
21+
help_section/0,
22+
description/0
23+
]).
24+
25+
%%
26+
%% Command Behavior
27+
%%
28+
29+
usage() ->
30+
<<"refresh_trust_store">>.
31+
32+
usage_doc_guides() ->
33+
[<<"https://rabbitmq.com/docs/ssl">>].
34+
35+
description() ->
36+
<<"Refreshes trust store certificates on a node">>.
37+
38+
help_section() ->
39+
{plugin, trust_store}.
40+
41+
validate(_, _) ->
42+
ok.
43+
44+
merge_defaults(A, O) ->
45+
{A, O}.
46+
47+
banner(_, #{node := Node}) ->
48+
erlang:iolist_to_binary([<<"Refreshing trust store certificates on node ">>,
49+
atom_to_binary(Node, utf8), <<"...">>]).
50+
51+
run(_Args, #{node := Node}) ->
52+
case rabbit_misc:rpc_call(Node, rabbit_trust_store, refresh, []) of
53+
{badrpc, _} = Error ->
54+
Error;
55+
ok ->
56+
ok
57+
end.
58+
59+
aliases() ->
60+
[].
61+
62+
output(Output, _Opts) ->
63+
'Elixir.RabbitMQ.CLI.DefaultOutput':output(Output).

deps/rabbitmq_trust_store/src/rabbit_trust_store.erl

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
-behaviour(gen_server).
1111

12-
-export([mode/0, refresh/0, list/0]). %% Console Interface.
12+
-export([mode/0, refresh/0, list/0, list_certificates/0]). %% Console Interface.
1313
-export([whitelisted/3, is_whitelisted/1]). %% Client-side Interface.
1414
-export([start_link/0]).
1515
-export([init/1, terminate/2,
@@ -87,6 +87,30 @@ list() ->
8787
ets:tab2list(table_name())),
8888
string:join(Formatted, "~n~n").
8989

90+
-spec list_certificates() -> [map()].
91+
list_certificates() ->
92+
lists:map(
93+
fun(#entry{
94+
name = N,
95+
cert_id = CertId,
96+
certificate = Cert,
97+
issuer_id = {_, Serial}}) ->
98+
Name = case N of
99+
undefined -> unicode:characters_to_binary(io_lib:format("~tp", [CertId]));
100+
_ -> unicode:characters_to_binary(N)
101+
end,
102+
Validity = unicode:characters_to_binary(rabbit_ssl:peer_cert_validity(Cert)),
103+
Subject = unicode:characters_to_binary(rabbit_ssl:peer_cert_subject(Cert)),
104+
Issuer = unicode:characters_to_binary(rabbit_ssl:peer_cert_issuer(Cert)),
105+
SerialHex = unicode:characters_to_binary(io_lib:format("0x~.16.0B", [Serial])),
106+
#{name => Name,
107+
serial => SerialHex,
108+
subject => Subject,
109+
issuer => Issuer,
110+
validity => Validity}
111+
end,
112+
ets:tab2list(table_name())).
113+
90114
%% Client (SSL Socket) Interface
91115

92116
-spec whitelisted(certificate(), event(), state()) -> outcome().

0 commit comments

Comments
 (0)