summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnaud Cogoluègnes <acogoluegnes@gmail.com>2016-10-11 16:13:36 +0200
committerArnaud Cogoluègnes <acogoluegnes@gmail.com>2016-10-11 16:13:36 +0200
commit82036e04518ef1033e6f23f51803edd163638c94 (patch)
treef5b057b9ab264c5db26188c8673187691f4ae884
parent65b0d3355e0880ec2b47a68fa3523656f7e2a390 (diff)
downloadrabbitmq-server-git-82036e04518ef1033e6f23f51803edd163638c94.tar.gz
Create tests for rabbitmqctl encode
-rw-r--r--include/rabbit_cli.hrl6
-rw-r--r--src/rabbit_control_main.erl59
-rw-r--r--src/rabbit_control_pbe.erl77
-rw-r--r--src/rabbit_pbe.erl12
-rw-r--r--test/unit_SUITE.erl80
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.
%% -------------------------------------------------------------------