1## This Source Code Form is subject to the terms of the Mozilla Public 2## License, v. 2.0. If a copy of the MPL was not distributed with this 3## file, You can obtain one at https://mozilla.org/MPL/2.0/. 4## 5## Copyright (c) 2007-2021 VMware, Inc. or its affiliates. All rights reserved. 6 7defmodule RabbitMQ.CLI.Ctl.Commands.EncodeCommand do 8 alias RabbitMQ.CLI.Core.{DocGuide, Helpers} 9 10 @behaviour RabbitMQ.CLI.CommandBehaviour 11 use RabbitMQ.CLI.DefaultOutput 12 13 def switches() do 14 [ 15 cipher: :atom, 16 hash: :atom, 17 iterations: :integer 18 ] 19 end 20 21 def distribution(_), do: :none 22 23 def merge_defaults(args, opts) do 24 with_defaults = Map.merge(%{ 25 cipher: :rabbit_pbe.default_cipher(), 26 hash: :rabbit_pbe.default_hash(), 27 iterations: :rabbit_pbe.default_iterations() 28 }, opts) 29 {args, with_defaults} 30 end 31 32 def validate(args, _) when length(args) < 2 do 33 {:validation_failure, {:not_enough_args, "Please provide a value to decode and a passphrase."}} 34 end 35 36 def validate(args, _) when length(args) > 2 do 37 {:validation_failure, :too_many_args} 38 end 39 40 def validate(args, opts) when length(args) === 2 do 41 case {supports_cipher(opts.cipher), supports_hash(opts.hash), opts.iterations > 0} do 42 {false, _, _} -> 43 {:validation_failure, {:bad_argument, "The requested cipher is not supported."}} 44 45 {_, false, _} -> 46 {:validation_failure, {:bad_argument, "The requested hash is not supported"}} 47 48 {_, _, false} -> 49 {:validation_failure, {:bad_argument, "The requested number of iterations is incorrect"}} 50 51 {true, true, true} -> 52 :ok 53 end 54 end 55 56 def run([value, passphrase], %{cipher: cipher, hash: hash, iterations: iterations}) do 57 try do 58 term_value = Helpers.evaluate_input_as_term(value) 59 result = {:encrypted, _} = :rabbit_pbe.encrypt_term(cipher, hash, iterations, passphrase, term_value) 60 {:ok, result} 61 catch 62 _, _ -> 63 {:error, "Error during cipher operation."} 64 end 65 end 66 67 def formatter(), do: RabbitMQ.CLI.Formatters.Erlang 68 69 def banner([_, _], _) do 70 "Encrypting value ..." 71 end 72 73 def usage, do: "encode value passphrase [--cipher <cipher>] [--hash <hash>] [--iterations <iterations>]" 74 75 def usage_additional() do 76 [ 77 ["<value>", "config value to encode"], 78 ["<passphrase>", "passphrase to use with the config value encryption key"], 79 ["--cipher <cipher>", "cipher suite to use"], 80 ["--hash <hash>", "hashing function to use"], 81 ["--iterations <iterations>", "number of iteration to apply"] 82 ] 83 end 84 85 def usage_doc_guides() do 86 [ 87 DocGuide.configuration() 88 ] 89 end 90 91 def help_section(), do: :configuration 92 93 def description(), do: "Encrypts a sensitive configuration value" 94 95 # 96 # Implementation 97 # 98 99 defp supports_cipher(cipher), do: Enum.member?(:rabbit_pbe.supported_ciphers(), cipher) 100 101 defp supports_hash(hash), do: Enum.member?(:rabbit_pbe.supported_hashes(), hash) 102end 103