diff options
| author | Arnaud Cogoluègnes <acogoluegnes@gmail.com> | 2016-10-11 16:13:36 +0200 |
|---|---|---|
| committer | Arnaud Cogoluègnes <acogoluegnes@gmail.com> | 2016-10-11 16:13:36 +0200 |
| commit | 82036e04518ef1033e6f23f51803edd163638c94 (patch) | |
| tree | f5b057b9ab264c5db26188c8673187691f4ae884 | |
| parent | 65b0d3355e0880ec2b47a68fa3523656f7e2a390 (diff) | |
| download | rabbitmq-server-git-82036e04518ef1033e6f23f51803edd163638c94.tar.gz | |
Create tests for rabbitmqctl encode
| -rw-r--r-- | include/rabbit_cli.hrl | 6 | ||||
| -rw-r--r-- | src/rabbit_control_main.erl | 59 | ||||
| -rw-r--r-- | src/rabbit_control_pbe.erl | 77 | ||||
| -rw-r--r-- | src/rabbit_pbe.erl | 12 | ||||
| -rw-r--r-- | test/unit_SUITE.erl | 80 |
5 files changed, 173 insertions, 61 deletions
diff --git a/include/rabbit_cli.hrl b/include/rabbit_cli.hrl index 5a42b01bf2..53be9fcda0 100644 --- a/include/rabbit_cli.hrl +++ b/include/rabbit_cli.hrl @@ -55,9 +55,9 @@ -define(ONLINE_DEF, {?ONLINE_OPT, flag}). -define(LOCAL_DEF, {?LOCAL_OPT, flag}). -define(DECODE_DEF, {?DECODE_OPT, flag}). --define(CIPHER_DEF, {?CIPHER_OPT, {option, "aes_cbc256"}}). --define(HASH_DEF, {?HASH_OPT, {option, "sha512"}}). --define(ITERATIONS_DEF, {?ITERATIONS_OPT, {option, "1000"}}). +-define(CIPHER_DEF, {?CIPHER_OPT, {option, atom_to_list(rabbit_pbe:default_cipher())}}). +-define(HASH_DEF, {?HASH_OPT, {option, atom_to_list(rabbit_pbe:default_hash())}}). +-define(ITERATIONS_DEF, {?ITERATIONS_OPT, {option, integer_to_list(rabbit_pbe:default_iterations())}}). -define(LIST_CIPHERS_DEF, {?LIST_CIPHERS_OPT, flag}). -define(LIST_HASHES_DEF, {?LIST_HASHES_OPT, flag}). diff --git a/src/rabbit_control_main.erl b/src/rabbit_control_main.erl index 9c32d9484f..ce242c9f91 100644 --- a/src/rabbit_control_main.erl +++ b/src/rabbit_control_main.erl @@ -588,7 +588,8 @@ action(encode, _Node, Args, Opts, _Inform) -> Hash = list_to_atom(proplists:get_value(?HASH_OPT, Opts)), Iterations = list_to_integer(proplists:get_value(?ITERATIONS_OPT, Opts)), - encode(ListCiphers, ListHashes, Decode, Cipher, Hash, Iterations, Args); + {_, Msg} = rabbit_control_pbe:encode(ListCiphers, ListHashes, Decode, Cipher, Hash, Iterations, Args), + io:format(Msg ++ "~n"); action(Command, Node, Args, Opts, Inform) -> %% For backward compatibility, run commands accepting a timeout with @@ -717,62 +718,6 @@ purge_queue(Q) -> ok end). -%% encode-related functions -encode(ListCiphers, _ListHashes, _Decode, _Cipher, _Hash, _Iterations, _Args) when ListCiphers -> - io:format("~p~n", [rabbit_pbe:supported_ciphers()]); - -encode(_ListCiphers, ListHashes, _Decode, _Cipher, _Hash, _Iterations, _Args) when ListHashes -> - io:format("~p~n", [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 -> - io:format("The requested cipher is not supported~n"); - -encode_encrypt_decrypt(_CipherExists, HashExists, _Decode, _Cipher, _Hash, _Iterations, _Args) when HashExists =:= false -> - io:format("The requested hash is not supported~n"); - -encode_encrypt_decrypt(_CipherExists, _HashExists, _Decode, _Cipher, _Hash, Iterations, _Args) when Iterations =< 0 -> - io:format("The requested number of iterations is incorrect~n"); - -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), - io:format("{encrypted, ~p}~n", [Result]) - end - catch - _:Msg -> io:format("Error during cipher operation: ~p~n", [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), - io:format("~p~n", [Result]) - end - catch - _:Msg -> io:format("Error during cipher operation: ~p~n", [Msg]) - end; - -encode_encrypt_decrypt(_CipherExists, _HashExists, _Decode, _Cipher, _Hash, _Iterations, _Args) -> - io:format("Please provide a value to encode/decode and a passphrase~n"). - -evaluate_input_as_term(Input) -> - {ok,Tokens,_EndLine} = erl_scan:string(Input ++ "."), - {ok,AbsForm} = erl_parse:parse_exprs(Tokens), - {value,TermValue,_Bs} = erl_eval:exprs(AbsForm, erl_eval:new_bindings()), - TermValue. - %%---------------------------------------------------------------------------- require_mnesia_stopped(Node, Fun) -> diff --git a/src/rabbit_control_pbe.erl b/src/rabbit_control_pbe.erl new file mode 100644 index 0000000000..dd4f9efa28 --- /dev/null +++ b/src/rabbit_control_pbe.erl @@ -0,0 +1,77 @@ +% The contents of this file are subject to the Mozilla Public License +%% Version 1.1 (the "License"); you may not use this file except in +%% compliance with the License. You may obtain a copy of the License +%% at http://www.mozilla.org/MPL/ +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and +%% limitations under the License. +%% +%% The Original Code is RabbitMQ. +%% +%% The Initial Developer of the Original Code is GoPivotal, Inc. +%% Copyright (c) 2007-2016 Pivotal Software, Inc. All rights reserved. +%% + +-module(rabbit_control_pbe). + +-export([encode/7]). + +% 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()])}; + +encode(_ListCiphers, ListHashes, _Decode, _Cipher, _Hash, _Iterations, _Args) when ListHashes -> + {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 -> + {error, io_lib:format("The requested number of iterations is incorrect", [])}; + +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_encrypt_decrypt(_CipherExists, _HashExists, _Decode, _Cipher, _Hash, _Iterations, _Args) -> + {error, io_lib:format("Please provide a value to encode/decode and a passphrase", [])}. + +evaluate_input_as_term(Input) -> + {ok,Tokens,_EndLine} = erl_scan:string(Input ++ "."), + {ok,AbsForm} = erl_parse:parse_exprs(Tokens), + {value,TermValue,_Bs} = erl_eval:exprs(AbsForm, erl_eval:new_bindings()), + TermValue. diff --git a/src/rabbit_pbe.erl b/src/rabbit_pbe.erl index b073d2e2d6..f4998d4a13 100644 --- a/src/rabbit_pbe.erl +++ b/src/rabbit_pbe.erl @@ -16,7 +16,7 @@ -module(rabbit_pbe). --export([supported_ciphers/0, supported_hashes/0]). +-export([supported_ciphers/0, supported_hashes/0, default_cipher/0, default_hash/0, default_iterations/0]). -export([encrypt_term/5, decrypt_term/5]). -export([encrypt/5, decrypt/5]). @@ -30,6 +30,16 @@ supported_hashes() -> proplists:get_value(hashs, crypto:supports()) -- [md4, ripemd160]. +%% Default encryption parameters (keep those in sync with rabbit.app.src) +default_cipher() -> + aes_cbc256. + +default_hash() -> + sha512. + +default_iterations() -> + 1000. + %% Encryption/decryption of arbitrary Erlang terms. encrypt_term(Cipher, Hash, Iterations, PassPhrase, Term) -> diff --git a/test/unit_SUITE.erl b/test/unit_SUITE.erl index 905a92a10b..e363fe6cb6 100644 --- a/test/unit_SUITE.erl +++ b/test/unit_SUITE.erl @@ -45,6 +45,7 @@ groups() -> encrypt_decrypt, encrypt_decrypt_term, decrypt_config, + rabbitmqctl_encode, pg_local, pmerge, plmerge, @@ -409,6 +410,85 @@ decrypt_start_app_undefined(Config) -> _:_ -> exit(unexpected_exception) end. +rabbitmqctl_encode(_Config) -> + % list ciphers and hashes + {ok, _} = rabbit_control_pbe:encode(true, false, undefined, undefined, undefined, undefined, undefined), + {ok, _} = rabbit_control_pbe:encode(false, true, undefined, undefined, undefined, undefined, undefined), + % incorrect ciphers, hashes and iteration number + {error, _} = rabbit_control_pbe:encode(false, false, undefined, funny_cipher, undefined, undefined, undefined), + {error, _} = rabbit_control_pbe:encode(false, false, undefined, undefined, funny_hash, undefined, undefined), + {error, _} = rabbit_control_pbe:encode(false, false, undefined, undefined, undefined, -1, undefined), + {error, _} = rabbit_control_pbe:encode(false, false, undefined, undefined, undefined, 0, undefined), + % incorrect number of arguments + {error, _} = rabbit_control_pbe:encode( + false, false, + false, % encrypt + rabbit_pbe:default_cipher(), rabbit_pbe:default_hash(), rabbit_pbe:default_iterations(), + [] + ), + {error, _} = rabbit_control_pbe:encode( + false, false, + false, % encrypt + rabbit_pbe:default_cipher(), rabbit_pbe:default_hash(), rabbit_pbe:default_iterations(), + [undefined] + ), + {error, _} = rabbit_control_pbe:encode( + false, false, + false, % encrypt + rabbit_pbe:default_cipher(), rabbit_pbe:default_hash(), rabbit_pbe:default_iterations(), + [undefined, undefined, undefined] + ), + + % encrypt/decrypt + % string + rabbitmqctl_encode_encrypt_decrypt("foobar"), + % binary + rabbitmqctl_encode_encrypt_decrypt("<<\"foobar\">>"), + % tuple + rabbitmqctl_encode_encrypt_decrypt("{password,<<\"secret\">>}"), + + ok. + +rabbitmqctl_encode_encrypt_decrypt(Secret) -> + PassPhrase = "passphrase", + {ok, Output} = rabbit_control_pbe:encode( + false, false, + false, % encrypt + rabbit_pbe:default_cipher(), rabbit_pbe:default_hash(), rabbit_pbe:default_iterations(), + [Secret, PassPhrase] + ), + {encrypted, Encrypted} = rabbit_control_pbe:evaluate_input_as_term(lists:flatten(Output)), + + {ok, Result} = rabbit_control_pbe:encode( + false, false, + true, % decrypt + rabbit_pbe:default_cipher(), rabbit_pbe:default_hash(), rabbit_pbe:default_iterations(), + [lists:flatten(io_lib:format("~p", [Encrypted])), PassPhrase] + ), + Secret = lists:flatten(Result), + % decrypt with {encrypted, ...} form as input + {ok, Result} = rabbit_control_pbe:encode( + false, false, + true, % decrypt + rabbit_pbe:default_cipher(), rabbit_pbe:default_hash(), rabbit_pbe:default_iterations(), + [lists:flatten(io_lib:format("~p", [{encrypted, Encrypted}])), PassPhrase] + ), + + % wrong passphrase + {error, _} = rabbit_control_pbe:encode( + false, false, + true, % decrypt + rabbit_pbe:default_cipher(), rabbit_pbe:default_hash(), rabbit_pbe:default_iterations(), + [lists:flatten(io_lib:format("~p", [Encrypted])), PassPhrase ++ " "] + ), + {error, _} = rabbit_control_pbe:encode( + false, false, + true, % decrypt + rabbit_pbe:default_cipher(), rabbit_pbe:default_hash(), rabbit_pbe:default_iterations(), + [lists:flatten(io_lib:format("~p", [{encrypted, Encrypted}])), PassPhrase ++ " "] + ) + . + %% ------------------------------------------------------------------- %% pg_local. %% ------------------------------------------------------------------- |
