diff options
| author | Michael Klishin <michael@novemberain.com> | 2017-06-28 18:13:02 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-06-28 18:13:02 +0300 |
| commit | 0cad86e34ee6144df8c62fde3f9113b39808ded1 (patch) | |
| tree | e249093eb33df3b20945c80632832cfa3f886dc2 | |
| parent | 63503f124d50c7585c535d24d064eb10f7f4278a (diff) | |
| parent | 6b65e41330a40060919b0cc19b895a57348493a5 (diff) | |
| download | rabbitmq-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.xml | 61 | ||||
| -rw-r--r-- | src/rabbit_control_main.erl | 32 | ||||
| -rw-r--r-- | src/rabbit_control_pbe.erl | 105 |
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,'<<"...">>}' 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 ++ "."), |
