summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Klishin <michael@novemberain.com>2017-06-28 18:13:02 +0300
committerGitHub <noreply@github.com>2017-06-28 18:13:02 +0300
commit0cad86e34ee6144df8c62fde3f9113b39808ded1 (patch)
treee249093eb33df3b20945c80632832cfa3f886dc2
parent63503f124d50c7585c535d24d064eb10f7f4278a (diff)
parent6b65e41330a40060919b0cc19b895a57348493a5 (diff)
downloadrabbitmq-server-git-0cad86e34ee6144df8c62fde3f9113b39808ded1.tar.gz
Merge pull request #1276 from rabbitmq/rabbitmq-server-ctl-decode
Add CTL commands to decode encoded value and list ciphers and hashes
-rw-r--r--docs/rabbitmqctl.1.xml61
-rw-r--r--src/rabbit_control_main.erl32
-rw-r--r--src/rabbit_control_pbe.erl105
3 files changed, 146 insertions, 52 deletions
diff --git a/docs/rabbitmqctl.1.xml b/docs/rabbitmqctl.1.xml
index f9d5f17511..2ec063266a 100644
--- a/docs/rabbitmqctl.1.xml
+++ b/docs/rabbitmqctl.1.xml
@@ -2167,9 +2167,9 @@
<varlistentry>
<term>fraction</term>
<listitem><para>
- Limit relative to the total amount available RAM
- as a non-negative floating point number.
- Values lower than 1.0 can be dangerous and
+ Limit relative to the total amount available RAM
+ as a non-negative floating point number.
+ Values lower than 1.0 can be dangerous and
should be used carefully.
</para></listitem>
</varlistentry>
@@ -2249,6 +2249,61 @@ rabbitmqctl encode --cipher blowfish_cfb64 --hash sha256 --iterations 10000 \
</variablelist>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <!-- one-line formatting matters for rabbit_ctl_usage.erl code generation -->
+ <term><cmdsynopsis><command>decode</command> <arg choice="opt"><replaceable>value</replaceable></arg> <arg choice="opt"><replaceable>passphrase</replaceable></arg></cmdsynopsis>
+ </term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <cmdsynopsis>
+ <arg choice="opt"><replaceable>value</replaceable></arg>
+ <arg choice="opt"><replaceable>passphrase</replaceable></arg>
+ </cmdsynopsis>
+ </term>
+ <listitem>
+ <para>
+ Value to decrypt (as produced by the encode command) and passphrase.
+ </para>
+ <para role="example-prefix">For example:</para>
+ <screen role="example">rabbitmqctl decode '{encrypted,'&lt;&lt;"..."&gt;&gt;}' mypassphrase</screen>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><cmdsynopsis><command>list_hashes</command></cmdsynopsis></term>
+ <listitem>
+ <para>
+ Lists hash functions supported by encoding commands.
+ </para>
+ <para role="example-prefix">For example:</para>
+ <screen role="example">rabbitmqctl list_hashes</screen>
+ <para role="example">
+ This command instructs the RabbitMQ broker to list all
+ hash functions supported by encoding commands.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><cmdsynopsis><command>list_ciphers</command></cmdsynopsis></term>
+ <listitem>
+ <para>
+ Lists cipher suites supported by encoding commands.
+ </para>
+ <para role="example-prefix">For example:</para>
+ <screen role="example">rabbitmqctl list_ciphers</screen>
+ <para role="example">
+ This command instructs the RabbitMQ broker to list all
+ cipher suites supported by encoding commands.
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect2>
</refsect1>
diff --git a/src/rabbit_control_main.erl b/src/rabbit_control_main.erl
index e18bc8d1f6..dc2d43d05e 100644
--- a/src/rabbit_control_main.erl
+++ b/src/rabbit_control_main.erl
@@ -98,7 +98,10 @@
set_vm_memory_high_watermark,
set_disk_free_limit,
help,
- {encode, [?DECODE_DEF, ?CIPHER_DEF, ?HASH_DEF, ?ITERATIONS_DEF, ?LIST_CIPHERS_DEF, ?LIST_HASHES_DEF]}
+ {encode, [?DECODE_DEF, ?CIPHER_DEF, ?HASH_DEF, ?ITERATIONS_DEF, ?LIST_CIPHERS_DEF, ?LIST_HASHES_DEF]},
+ {decode, [?CIPHER_DEF, ?HASH_DEF, ?ITERATIONS_DEF]},
+ list_ciphers,
+ list_hashes
]).
-define(GLOBAL_QUERIES,
@@ -620,15 +623,38 @@ action(eval, Node, [Expr], _Opts, _Inform) ->
action(help, _Node, _Args, _Opts, _Inform) ->
io:format("~s", [rabbit_ctl_usage:usage()]);
-action(encode, _Node, Args, Opts, _Inform) ->
+action(encode, Node, Args, Opts, Inform) ->
ListCiphers = lists:member({?LIST_CIPHERS_OPT, true}, Opts),
ListHashes = lists:member({?LIST_HASHES_OPT, true}, Opts),
Decode = lists:member({?DECODE_OPT, true}, Opts),
+ case {ListCiphers, ListHashes, Decode} of
+ {true, _, _} ->
+ action(list_ciphers, Node, Args, Opts, Inform);
+ {_, true, _} ->
+ action(list_hashes, Node, Args, Opts, Inform);
+ {_, _, true} ->
+ action(decode, Node, Args, Opts, Inform);
+ {_, _, _} ->
+ Cipher = list_to_atom(proplists:get_value(?CIPHER_OPT, Opts)),
+ Hash = list_to_atom(proplists:get_value(?HASH_OPT, Opts)),
+ Iterations = list_to_integer(proplists:get_value(?ITERATIONS_OPT, Opts)),
+ {_, Msg} = rabbit_control_pbe:encode(Cipher, Hash, Iterations, Args),
+ io:format(Msg ++ "~n")
+ end;
+
+action(decode, _Node, Args, Opts, _Inform) ->
Cipher = list_to_atom(proplists:get_value(?CIPHER_OPT, Opts)),
Hash = list_to_atom(proplists:get_value(?HASH_OPT, Opts)),
Iterations = list_to_integer(proplists:get_value(?ITERATIONS_OPT, Opts)),
+ {_, Msg} = rabbit_control_pbe:decode(Cipher, Hash, Iterations, Args),
+ io:format(Msg ++ "~n");
+
+action(list_hashes, _Node, _Args, _Opts, _Inform) ->
+ {_, Msg} = rabbit_control_pbe:list_hashes(),
+ io:format(Msg ++ "~n");
- {_, Msg} = rabbit_control_pbe:encode(ListCiphers, ListHashes, Decode, Cipher, Hash, Iterations, Args),
+action(list_ciphers, _Node, _Args, _Opts, _Inform) ->
+ {_, Msg} = rabbit_control_pbe:list_ciphers(),
io:format(Msg ++ "~n");
action(Command, Node, Args, Opts, Inform) ->
diff --git a/src/rabbit_control_pbe.erl b/src/rabbit_control_pbe.erl
index ff498ed4aa..40d8741d74 100644
--- a/src/rabbit_control_pbe.erl
+++ b/src/rabbit_control_pbe.erl
@@ -16,61 +16,74 @@
-module(rabbit_control_pbe).
--export([encode/7]).
+-export([decode/4, encode/4, list_ciphers/0, list_hashes/0]).
% for testing purposes
-export([evaluate_input_as_term/1]).
-encode(ListCiphers, _ListHashes, _Decode, _Cipher, _Hash, _Iterations, _Args) when ListCiphers ->
- {ok, io_lib:format("~p", [rabbit_pbe:supported_ciphers()])};
+list_ciphers() ->
+ {ok, io_lib:format("~p", [rabbit_pbe:supported_ciphers()])}.
-encode(_ListCiphers, ListHashes, _Decode, _Cipher, _Hash, _Iterations, _Args) when ListHashes ->
- {ok, io_lib:format("~p", [rabbit_pbe:supported_hashes()])};
+list_hashes() ->
+ {ok, io_lib:format("~p", [rabbit_pbe:supported_hashes()])}.
-encode(_ListCiphers, _ListHashes, Decode, Cipher, Hash, Iterations, Args) ->
- CipherExists = lists:member(Cipher, rabbit_pbe:supported_ciphers()),
- HashExists = lists:member(Hash, rabbit_pbe:supported_hashes()),
- encode_encrypt_decrypt(CipherExists, HashExists, Decode, Cipher, Hash, Iterations, Args).
-
-encode_encrypt_decrypt(CipherExists, _HashExists, _Decode, _Cipher, _Hash, _Iterations, _Args) when CipherExists =:= false ->
- {error, io_lib:format("The requested cipher is not supported", [])};
-
-encode_encrypt_decrypt(_CipherExists, HashExists, _Decode, _Cipher, _Hash, _Iterations, _Args) when HashExists =:= false ->
- {error, io_lib:format("The requested hash is not supported", [])};
-
-encode_encrypt_decrypt(_CipherExists, _HashExists, _Decode, _Cipher, _Hash, Iterations, _Args) when Iterations =< 0 ->
+validate(_Cipher, _Hash, Iterations, _Args) when Iterations =< 0 ->
{error, io_lib:format("The requested number of iterations is incorrect", [])};
+validate(_Cipher, _Hash, _Iterations, Args) when length(Args) < 2 ->
+ {error, io_lib:format("Please provide a value to encode/decode and a passphrase", [])};
+validate(_Cipher, _Hash, _Iterations, Args) when length(Args) > 2 ->
+ {error, io_lib:format("Too many arguments. Please provide a value to encode/decode and a passphrase", [])};
+validate(Cipher, Hash, _Iterations, _Args) ->
+ case lists:member(Cipher, rabbit_pbe:supported_ciphers()) of
+ false ->
+ {error, io_lib:format("The requested cipher is not supported", [])};
+ true ->
+ case lists:member(Hash, rabbit_pbe:supported_hashes()) of
+ false ->
+ {error, io_lib:format("The requested hash is not supported", [])};
+ true -> ok
+ end
+ end.
-encode_encrypt_decrypt(_CipherExists, _HashExists, Decode, Cipher, Hash, Iterations, Args) when length(Args) == 2, Decode =:= false ->
- [Value, PassPhrase] = Args,
- try begin
- TermValue = evaluate_input_as_term(Value),
- Result = rabbit_pbe:encrypt_term(Cipher, Hash, Iterations, list_to_binary(PassPhrase), TermValue),
- {ok, io_lib:format("~p", [{encrypted, Result}])}
- end
- catch
- _:Msg -> {error, io_lib:format("Error during cipher operation: ~p", [Msg])}
- end;
-
-encode_encrypt_decrypt(_CipherExists, _HashExists, Decode, Cipher, Hash, Iterations, Args) when length(Args) == 2, Decode ->
- [Value, PassPhrase] = Args,
- try begin
- TermValue = evaluate_input_as_term(Value),
- TermToDecrypt = case TermValue of
- {encrypted, EncryptedTerm} ->
- EncryptedTerm;
- _ ->
- TermValue
- end,
- Result = rabbit_pbe:decrypt_term(Cipher, Hash, Iterations, list_to_binary(PassPhrase), TermToDecrypt),
- {ok, io_lib:format("~p", [Result])}
- end
- catch
- _:Msg -> {error, io_lib:format("Error during cipher operation: ~p", [Msg])}
- end;
+encode(Cipher, Hash, Iterations, Args) ->
+ case validate(Cipher, Hash, Iterations, Args) of
+ {error, Err} -> {error, Err};
+ ok ->
+ [Value, PassPhrase] = Args,
+ try begin
+ TermValue = evaluate_input_as_term(Value),
+ Result = rabbit_pbe:encrypt_term(Cipher, Hash, Iterations,
+ list_to_binary(PassPhrase),
+ TermValue),
+ {ok, io_lib:format("~p", [{encrypted, Result}])}
+ end
+ catch
+ _:Msg -> {error, io_lib:format("Error during cipher operation: ~p", [Msg])}
+ end
+ end.
-encode_encrypt_decrypt(_CipherExists, _HashExists, _Decode, _Cipher, _Hash, _Iterations, _Args) ->
- {error, io_lib:format("Please provide a value to encode/decode and a passphrase", [])}.
+decode(Cipher, Hash, Iterations, Args) ->
+ case validate(Cipher, Hash, Iterations, Args) of
+ {error, Err} -> {error, Err};
+ ok ->
+ [Value, PassPhrase] = Args,
+ try begin
+ TermValue = evaluate_input_as_term(Value),
+ TermToDecrypt = case TermValue of
+ {encrypted, EncryptedTerm} ->
+ EncryptedTerm;
+ _ ->
+ TermValue
+ end,
+ Result = rabbit_pbe:decrypt_term(Cipher, Hash, Iterations,
+ list_to_binary(PassPhrase),
+ TermToDecrypt),
+ {ok, io_lib:format("~p", [Result])}
+ end
+ catch
+ _:Msg -> {error, io_lib:format("Error during cipher operation: ~p", [Msg])}
+ end
+ end.
evaluate_input_as_term(Input) ->
{ok,Tokens,_EndLine} = erl_scan:string(Input ++ "."),