Skip to content

Commit 0cad86e

Browse files
Merge pull request #1276 from rabbitmq/rabbitmq-server-ctl-decode
Add CTL commands to decode encoded value and list ciphers and hashes
2 parents 63503f1 + 6b65e41 commit 0cad86e

File tree

3 files changed

+146
-52
lines changed

3 files changed

+146
-52
lines changed

docs/rabbitmqctl.1.xml

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2167,9 +2167,9 @@
21672167
<varlistentry>
21682168
<term>fraction</term>
21692169
<listitem><para>
2170-
Limit relative to the total amount available RAM
2171-
as a non-negative floating point number.
2172-
Values lower than 1.0 can be dangerous and
2170+
Limit relative to the total amount available RAM
2171+
as a non-negative floating point number.
2172+
Values lower than 1.0 can be dangerous and
21732173
should be used carefully.
21742174
</para></listitem>
21752175
</varlistentry>
@@ -2249,6 +2249,61 @@ rabbitmqctl encode --cipher blowfish_cfb64 --hash sha256 --iterations 10000 \
22492249
</variablelist>
22502250
</listitem>
22512251
</varlistentry>
2252+
2253+
<varlistentry>
2254+
<!-- one-line formatting matters for rabbit_ctl_usage.erl code generation -->
2255+
<term><cmdsynopsis><command>decode</command> <arg choice="opt"><replaceable>value</replaceable></arg> <arg choice="opt"><replaceable>passphrase</replaceable></arg></cmdsynopsis>
2256+
</term>
2257+
<listitem>
2258+
<variablelist>
2259+
<varlistentry>
2260+
<term>
2261+
<cmdsynopsis>
2262+
<arg choice="opt"><replaceable>value</replaceable></arg>
2263+
<arg choice="opt"><replaceable>passphrase</replaceable></arg>
2264+
</cmdsynopsis>
2265+
</term>
2266+
<listitem>
2267+
<para>
2268+
Value to decrypt (as produced by the encode command) and passphrase.
2269+
</para>
2270+
<para role="example-prefix">For example:</para>
2271+
<screen role="example">rabbitmqctl decode '{encrypted,'&lt;&lt;"..."&gt;&gt;}' mypassphrase</screen>
2272+
</listitem>
2273+
</varlistentry>
2274+
</variablelist>
2275+
</listitem>
2276+
</varlistentry>
2277+
2278+
<varlistentry>
2279+
<term><cmdsynopsis><command>list_hashes</command></cmdsynopsis></term>
2280+
<listitem>
2281+
<para>
2282+
Lists hash functions supported by encoding commands.
2283+
</para>
2284+
<para role="example-prefix">For example:</para>
2285+
<screen role="example">rabbitmqctl list_hashes</screen>
2286+
<para role="example">
2287+
This command instructs the RabbitMQ broker to list all
2288+
hash functions supported by encoding commands.
2289+
</para>
2290+
</listitem>
2291+
</varlistentry>
2292+
2293+
<varlistentry>
2294+
<term><cmdsynopsis><command>list_ciphers</command></cmdsynopsis></term>
2295+
<listitem>
2296+
<para>
2297+
Lists cipher suites supported by encoding commands.
2298+
</para>
2299+
<para role="example-prefix">For example:</para>
2300+
<screen role="example">rabbitmqctl list_ciphers</screen>
2301+
<para role="example">
2302+
This command instructs the RabbitMQ broker to list all
2303+
cipher suites supported by encoding commands.
2304+
</para>
2305+
</listitem>
2306+
</varlistentry>
22522307
</variablelist>
22532308
</refsect2>
22542309
</refsect1>

src/rabbit_control_main.erl

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,10 @@
9898
set_vm_memory_high_watermark,
9999
set_disk_free_limit,
100100
help,
101-
{encode, [?DECODE_DEF, ?CIPHER_DEF, ?HASH_DEF, ?ITERATIONS_DEF, ?LIST_CIPHERS_DEF, ?LIST_HASHES_DEF]}
101+
{encode, [?DECODE_DEF, ?CIPHER_DEF, ?HASH_DEF, ?ITERATIONS_DEF, ?LIST_CIPHERS_DEF, ?LIST_HASHES_DEF]},
102+
{decode, [?CIPHER_DEF, ?HASH_DEF, ?ITERATIONS_DEF]},
103+
list_ciphers,
104+
list_hashes
102105
]).
103106

104107
-define(GLOBAL_QUERIES,
@@ -620,15 +623,38 @@ action(eval, Node, [Expr], _Opts, _Inform) ->
620623
action(help, _Node, _Args, _Opts, _Inform) ->
621624
io:format("~s", [rabbit_ctl_usage:usage()]);
622625

623-
action(encode, _Node, Args, Opts, _Inform) ->
626+
action(encode, Node, Args, Opts, Inform) ->
624627
ListCiphers = lists:member({?LIST_CIPHERS_OPT, true}, Opts),
625628
ListHashes = lists:member({?LIST_HASHES_OPT, true}, Opts),
626629
Decode = lists:member({?DECODE_OPT, true}, Opts),
630+
case {ListCiphers, ListHashes, Decode} of
631+
{true, _, _} ->
632+
action(list_ciphers, Node, Args, Opts, Inform);
633+
{_, true, _} ->
634+
action(list_hashes, Node, Args, Opts, Inform);
635+
{_, _, true} ->
636+
action(decode, Node, Args, Opts, Inform);
637+
{_, _, _} ->
638+
Cipher = list_to_atom(proplists:get_value(?CIPHER_OPT, Opts)),
639+
Hash = list_to_atom(proplists:get_value(?HASH_OPT, Opts)),
640+
Iterations = list_to_integer(proplists:get_value(?ITERATIONS_OPT, Opts)),
641+
{_, Msg} = rabbit_control_pbe:encode(Cipher, Hash, Iterations, Args),
642+
io:format(Msg ++ "~n")
643+
end;
644+
645+
action(decode, _Node, Args, Opts, _Inform) ->
627646
Cipher = list_to_atom(proplists:get_value(?CIPHER_OPT, Opts)),
628647
Hash = list_to_atom(proplists:get_value(?HASH_OPT, Opts)),
629648
Iterations = list_to_integer(proplists:get_value(?ITERATIONS_OPT, Opts)),
649+
{_, Msg} = rabbit_control_pbe:decode(Cipher, Hash, Iterations, Args),
650+
io:format(Msg ++ "~n");
651+
652+
action(list_hashes, _Node, _Args, _Opts, _Inform) ->
653+
{_, Msg} = rabbit_control_pbe:list_hashes(),
654+
io:format(Msg ++ "~n");
630655

631-
{_, Msg} = rabbit_control_pbe:encode(ListCiphers, ListHashes, Decode, Cipher, Hash, Iterations, Args),
656+
action(list_ciphers, _Node, _Args, _Opts, _Inform) ->
657+
{_, Msg} = rabbit_control_pbe:list_ciphers(),
632658
io:format(Msg ++ "~n");
633659

634660
action(Command, Node, Args, Opts, Inform) ->

src/rabbit_control_pbe.erl

Lines changed: 59 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -16,61 +16,74 @@
1616

1717
-module(rabbit_control_pbe).
1818

19-
-export([encode/7]).
19+
-export([decode/4, encode/4, list_ciphers/0, list_hashes/0]).
2020

2121
% for testing purposes
2222
-export([evaluate_input_as_term/1]).
2323

24-
encode(ListCiphers, _ListHashes, _Decode, _Cipher, _Hash, _Iterations, _Args) when ListCiphers ->
25-
{ok, io_lib:format("~p", [rabbit_pbe:supported_ciphers()])};
24+
list_ciphers() ->
25+
{ok, io_lib:format("~p", [rabbit_pbe:supported_ciphers()])}.
2626

27-
encode(_ListCiphers, ListHashes, _Decode, _Cipher, _Hash, _Iterations, _Args) when ListHashes ->
28-
{ok, io_lib:format("~p", [rabbit_pbe:supported_hashes()])};
27+
list_hashes() ->
28+
{ok, io_lib:format("~p", [rabbit_pbe:supported_hashes()])}.
2929

30-
encode(_ListCiphers, _ListHashes, Decode, Cipher, Hash, Iterations, Args) ->
31-
CipherExists = lists:member(Cipher, rabbit_pbe:supported_ciphers()),
32-
HashExists = lists:member(Hash, rabbit_pbe:supported_hashes()),
33-
encode_encrypt_decrypt(CipherExists, HashExists, Decode, Cipher, Hash, Iterations, Args).
34-
35-
encode_encrypt_decrypt(CipherExists, _HashExists, _Decode, _Cipher, _Hash, _Iterations, _Args) when CipherExists =:= false ->
36-
{error, io_lib:format("The requested cipher is not supported", [])};
37-
38-
encode_encrypt_decrypt(_CipherExists, HashExists, _Decode, _Cipher, _Hash, _Iterations, _Args) when HashExists =:= false ->
39-
{error, io_lib:format("The requested hash is not supported", [])};
40-
41-
encode_encrypt_decrypt(_CipherExists, _HashExists, _Decode, _Cipher, _Hash, Iterations, _Args) when Iterations =< 0 ->
30+
validate(_Cipher, _Hash, Iterations, _Args) when Iterations =< 0 ->
4231
{error, io_lib:format("The requested number of iterations is incorrect", [])};
32+
validate(_Cipher, _Hash, _Iterations, Args) when length(Args) < 2 ->
33+
{error, io_lib:format("Please provide a value to encode/decode and a passphrase", [])};
34+
validate(_Cipher, _Hash, _Iterations, Args) when length(Args) > 2 ->
35+
{error, io_lib:format("Too many arguments. Please provide a value to encode/decode and a passphrase", [])};
36+
validate(Cipher, Hash, _Iterations, _Args) ->
37+
case lists:member(Cipher, rabbit_pbe:supported_ciphers()) of
38+
false ->
39+
{error, io_lib:format("The requested cipher is not supported", [])};
40+
true ->
41+
case lists:member(Hash, rabbit_pbe:supported_hashes()) of
42+
false ->
43+
{error, io_lib:format("The requested hash is not supported", [])};
44+
true -> ok
45+
end
46+
end.
4347

44-
encode_encrypt_decrypt(_CipherExists, _HashExists, Decode, Cipher, Hash, Iterations, Args) when length(Args) == 2, Decode =:= false ->
45-
[Value, PassPhrase] = Args,
46-
try begin
47-
TermValue = evaluate_input_as_term(Value),
48-
Result = rabbit_pbe:encrypt_term(Cipher, Hash, Iterations, list_to_binary(PassPhrase), TermValue),
49-
{ok, io_lib:format("~p", [{encrypted, Result}])}
50-
end
51-
catch
52-
_:Msg -> {error, io_lib:format("Error during cipher operation: ~p", [Msg])}
53-
end;
54-
55-
encode_encrypt_decrypt(_CipherExists, _HashExists, Decode, Cipher, Hash, Iterations, Args) when length(Args) == 2, Decode ->
56-
[Value, PassPhrase] = Args,
57-
try begin
58-
TermValue = evaluate_input_as_term(Value),
59-
TermToDecrypt = case TermValue of
60-
{encrypted, EncryptedTerm} ->
61-
EncryptedTerm;
62-
_ ->
63-
TermValue
64-
end,
65-
Result = rabbit_pbe:decrypt_term(Cipher, Hash, Iterations, list_to_binary(PassPhrase), TermToDecrypt),
66-
{ok, io_lib:format("~p", [Result])}
67-
end
68-
catch
69-
_:Msg -> {error, io_lib:format("Error during cipher operation: ~p", [Msg])}
70-
end;
48+
encode(Cipher, Hash, Iterations, Args) ->
49+
case validate(Cipher, Hash, Iterations, Args) of
50+
{error, Err} -> {error, Err};
51+
ok ->
52+
[Value, PassPhrase] = Args,
53+
try begin
54+
TermValue = evaluate_input_as_term(Value),
55+
Result = rabbit_pbe:encrypt_term(Cipher, Hash, Iterations,
56+
list_to_binary(PassPhrase),
57+
TermValue),
58+
{ok, io_lib:format("~p", [{encrypted, Result}])}
59+
end
60+
catch
61+
_:Msg -> {error, io_lib:format("Error during cipher operation: ~p", [Msg])}
62+
end
63+
end.
7164

72-
encode_encrypt_decrypt(_CipherExists, _HashExists, _Decode, _Cipher, _Hash, _Iterations, _Args) ->
73-
{error, io_lib:format("Please provide a value to encode/decode and a passphrase", [])}.
65+
decode(Cipher, Hash, Iterations, Args) ->
66+
case validate(Cipher, Hash, Iterations, Args) of
67+
{error, Err} -> {error, Err};
68+
ok ->
69+
[Value, PassPhrase] = Args,
70+
try begin
71+
TermValue = evaluate_input_as_term(Value),
72+
TermToDecrypt = case TermValue of
73+
{encrypted, EncryptedTerm} ->
74+
EncryptedTerm;
75+
_ ->
76+
TermValue
77+
end,
78+
Result = rabbit_pbe:decrypt_term(Cipher, Hash, Iterations,
79+
list_to_binary(PassPhrase),
80+
TermToDecrypt),
81+
{ok, io_lib:format("~p", [Result])}
82+
end
83+
catch
84+
_:Msg -> {error, io_lib:format("Error during cipher operation: ~p", [Msg])}
85+
end
86+
end.
7487

7588
evaluate_input_as_term(Input) ->
7689
{ok,Tokens,_EndLine} = erl_scan:string(Input ++ "."),

0 commit comments

Comments
 (0)