diff options
| author | Daniil Fedotov <dfedotov@pivotal.io> | 2017-06-28 10:35:36 +0100 |
|---|---|---|
| committer | Daniil Fedotov <dfedotov@pivotal.io> | 2017-06-28 10:35:36 +0100 |
| commit | 07d98c35116c305050659294f950c16f81b9038e (patch) | |
| tree | 1bc2afb1adde9da8f6607d08c6a58e32ae2aa3b5 | |
| parent | 2bddf88c8ee0b247e105d32371b74c769e16043c (diff) | |
| download | rabbitmq-server-git-07d98c35116c305050659294f950c16f81b9038e.tar.gz | |
Add CTL commands to decode encoded value and list ciphers and hashes
`rabbitmqctl encode --decode` and `rabbitmqctl encode --list-ciphers`
is a bit weird API, which makes every argument in the encode command
optional.
`rabbitmqctl decode` is not equal to `rabbitmqctl encode --decode`
same for `rabbitmqctl list_ciphers` and `rabbitmqctl list_hashes`
| -rw-r--r-- | src/rabbit_control_main.erl | 32 | ||||
| -rw-r--r-- | src/rabbit_control_pbe.erl | 105 |
2 files changed, 88 insertions, 49 deletions
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 ++ "."), |
