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.Diagnostics.Commands.ErlangCookieSourcesCommand do
8  @behaviour RabbitMQ.CLI.CommandBehaviour
9
10  import RabbitMQ.CLI.Core.ANSI
11
12  use RabbitMQ.CLI.Core.AcceptsDefaultSwitchesAndTimeout
13  use RabbitMQ.CLI.Core.MergesNoDefaults
14  use RabbitMQ.CLI.Core.AcceptsNoPositionalArguments
15
16  def distribution(_), do: :none
17
18  def run([], opts) do
19    switch_cookie = opts[:erlang_cookie]
20    home_dir = get_home_dir()
21    cookie_file_path = Path.join(home_dir, ".erlang.cookie")
22    cookie_file_stat = case File.stat(Path.join(home_dir, ".erlang.cookie")) do
23      {:error, :enoent} -> nil
24      {:ok, value}     -> value
25    end
26    cookie_file_type = case cookie_file_stat do
27      nil   -> nil
28      value -> value.type
29    end
30    cookie_file_access = case cookie_file_stat do
31      nil   -> nil
32      value -> value.access
33    end
34    cookie_file_size = case cookie_file_stat do
35      nil   -> nil
36      value -> value.size
37    end
38
39    %{
40      os_env_cookie_set: System.get_env("RABBITMQ_ERLANG_COOKIE") != nil,
41      os_env_cookie_value_length: String.length(System.get_env("RABBITMQ_ERLANG_COOKIE") || ""),
42      switch_cookie_set: switch_cookie != nil,
43      switch_cookie_value_length: String.length(to_string(switch_cookie) || ""),
44      effective_user: System.get_env("USER"),
45      home_dir: home_dir,
46      cookie_file_path: cookie_file_path,
47      cookie_file_exists: File.exists?(cookie_file_path),
48      cookie_file_type: cookie_file_type,
49      cookie_file_access: cookie_file_access,
50      cookie_file_size: cookie_file_size
51    }
52  end
53
54  def banner([], %{}), do: "Listing Erlang cookie sources used by CLI tools..."
55
56  def output(result, %{formatter: "json"}) do
57    {:ok, result}
58  end
59
60  def output(result, _opts) do
61    cookie_file_lines = [
62      "#{bright("Cookie File")}\n",
63      "Effective user: #{result[:effective_user] || "(none)"}",
64      "Effective home directory: #{result[:home_dir] || "(none)"}",
65      "Cookie file path: #{result[:cookie_file_path]}",
66      "Cookie file exists? #{result[:cookie_file_exists]}",
67      "Cookie file type: #{result[:cookie_file_type] || "(n/a)"}",
68      "Cookie file access: #{result[:cookie_file_access] || "(n/a)"}",
69      "Cookie file size: #{result[:cookie_file_size] || "(n/a)"}",
70    ]
71
72    switch_lines = [
73      "\n#{bright("Cookie CLI Switch")}\n",
74      "--erlang-cookie value set? #{result[:switch_cookie_set]}",
75      "--erlang-cookie value length: #{result[:switch_cookie_value_length] || 0}"
76    ]
77
78    os_env_lines = [
79      "\n#{bright("Env variable ")} #{bright_red("(Deprecated)")}\n",
80      "RABBITMQ_ERLANG_COOKIE value set? #{result[:os_env_cookie_set]}",
81      "RABBITMQ_ERLANG_COOKIE value length: #{result[:os_env_cookie_value_length] || 0}"
82    ]
83
84    lines = cookie_file_lines ++ switch_lines ++ os_env_lines
85
86    {:ok, lines}
87  end
88
89  def help_section(), do: :configuration
90
91  def description() do
92    "Display Erlang cookie source (e.g. $HOME/.erlang.cookie file) information useful for troubleshooting"
93  end
94
95  def usage, do: "erlang_cookie_sources"
96
97  def formatter(), do: RabbitMQ.CLI.Formatters.StringPerLine
98
99  #
100  # Implementation
101  #
102
103  @doc """
104  Computes HOME directory path the same way Erlang VM/ei does,
105  including taking Windows-specific env variables into account.
106  """
107  def get_home_dir() do
108    homedrive = System.get_env("HOMEDRIVE")
109    homepath  = System.get_env("HOMEPATH")
110
111    case {homedrive != nil, homepath != nil} do
112      {true, true} -> "#{homedrive}#{homepath}"
113      _            -> System.get_env("HOME")
114    end
115  end
116end
117