summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniil Fedotov <dfedotov@pivotal.io>2017-06-28 10:35:36 +0100
committerDaniil Fedotov <dfedotov@pivotal.io>2017-06-28 10:35:36 +0100
commit07d98c35116c305050659294f950c16f81b9038e (patch)
tree1bc2afb1adde9da8f6607d08c6a58e32ae2aa3b5
parent2bddf88c8ee0b247e105d32371b74c769e16043c (diff)
downloadrabbitmq-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.erl32
-rw-r--r--src/rabbit_control_pbe.erl105
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 ++ "."),