<varlistentry>
<term><option>--recovery-pin=</option></term>
- <listitem><para>Takes a boolean. Defaults to false. Honoured by <command>make-policy</command>. If
- true, will query the user for a PIN to unlock the TPM2 NV index with. If no policy was created before
- this PIN is used to protect the newly allocated NV index. If a policy has been created before the PIN
- is used to unlock write access to the NV index. If this option is not used a PIN is automatically
- generated. Regardless if user supplied or automatically generated, it is stored in encrypted form in
- the policy metadata file. The recovery PIN may be used to regain write access to an NV index in case
- the access policy became out of date.</para>
+ <listitem><para>Takes one of <literal>hide</literal>, <literal>show</literal> or
+ <literal>query</literal>. Defaults to <literal>hide</literal>. Honoured by
+ <command>make-policy</command>. If <literal>query</literal>, will query the user for a PIN to unlock
+ the TPM2 NV index with. If no policy was created before, this PIN is used to protect the newly
+ allocated NV index. If a policy has been created before, the PIN is used to unlock write access to
+ the NV index. If either <literal>hide</literal> or <literal>show</literal> is used, a PIN is
+ automatically generated, and — only in case of <literal>show</literal> — displayed on
+ screen. Regardless if user supplied or automatically generated, it is stored in encrypted form in the
+ policy metadata file. The recovery PIN may be used to regain write access to an NV index in case the
+ access policy became out of date.</para>
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
</varlistentry>
#include "random-util.h"
#include "recovery-key.h"
#include "sort-util.h"
+#include "string-table.h"
#include "terminal-util.h"
#include "tpm2-util.h"
#include "unaligned.h"
#include "varlink-io.systemd.PCRLock.h"
#include "verbs.h"
+typedef enum RecoveryPinMode {
+ RECOVERY_PIN_HIDE, /* generate a recovery PIN automatically, but don't show it (alias: "no") */
+ RECOVERY_PIN_SHOW, /* generate a recovery PIN automatically, and display it to the user */
+ RECOVERY_PIN_QUERY, /* asks the user for a PIN to use interactively (alias: "yes") */
+ _RECOVERY_PIN_MODE_MAX,
+ _RECOVERY_PIN_MODE_INVALID = -EINVAL,
+} RecoveryPinMode;
+
static PagerFlags arg_pager_flags = 0;
static JsonFormatFlags arg_json_format_flags = JSON_FORMAT_OFF|JSON_FORMAT_NEWLINE;
static char **arg_components = NULL;
static char *arg_location_start = NULL;
static char *arg_location_end = NULL;
static TPM2_HANDLE arg_nv_index = 0;
-static bool arg_recovery_pin = false;
+static RecoveryPinMode arg_recovery_pin = RECOVERY_PIN_HIDE;
static char *arg_policy_path = NULL;
static bool arg_force = false;
static BootEntryTokenType arg_entry_token_type = BOOT_ENTRY_TOKEN_AUTO;
(UINT32_C(1) << TPM2_PCR_SHIM_POLICY) | \
(UINT32_C(1) << TPM2_PCR_SYSTEM_IDENTITY))
+static const char* recovery_pin_mode_table[_RECOVERY_PIN_MODE_MAX] = {
+ [RECOVERY_PIN_HIDE] = "hide",
+ [RECOVERY_PIN_SHOW] = "show",
+ [RECOVERY_PIN_QUERY] = "query",
+};
+
+DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_BOOLEAN(recovery_pin_mode, RecoveryPinMode, RECOVERY_PIN_QUERY);
+
typedef struct EventLogRecordBank EventLogRecordBank;
typedef struct EventLogRecord EventLogRecord;
typedef struct EventLogRegisterBank EventLogRegisterBank;
return 1;
}
-static int make_policy(bool force, bool recovery_pin) {
+static int make_policy(bool force, RecoveryPinMode recovery_pin_mode) {
int r;
/* Here's how this all works: after predicting all possible PCR values for next boot (with
/* Acquire a recovery PIN, either from the user, or create a randomized one */
_cleanup_(erase_and_freep) char *pin = NULL;
- if (recovery_pin) {
+ if (recovery_pin_mode == RECOVERY_PIN_QUERY) {
r = getenv_steal_erase("PIN", &pin);
if (r < 0)
return log_error_errno(r, "Failed to acquire PIN from environment: %m");
r = make_recovery_key(&pin);
if (r < 0)
return log_error_errno(r, "Failed to generate a randomized recovery PIN: %m");
+
+ if (recovery_pin_mode == RECOVERY_PIN_SHOW)
+ printf("%s Selected recovery PIN is: %s%s%s\n",
+ special_glyph(SPECIAL_GLYPH_LOCK_AND_KEY),
+ ansi_highlight_cyan(),
+ pin,
+ ansi_normal());
}
_cleanup_(tpm2_handle_freep) Tpm2Handle *nv_handle = NULL;
}
case ARG_RECOVERY_PIN:
- r = parse_boolean_argument("--recovery-pin", optarg, &arg_recovery_pin);
- if (r < 0)
- return r;
+ arg_recovery_pin = recovery_pin_mode_from_string(optarg);
+ if (arg_recovery_pin < 0)
+ return log_error_errno(arg_recovery_pin, "Failed to parse --recovery-pin= mode: %s", optarg);
break;
case ARG_PCRLOCK:
if (r != 0)
return r;
- r = make_policy(p.force, /* recovery_key= */ false);
+ r = make_policy(p.force, /* recovery_key= */ RECOVERY_PIN_HIDE);
if (r < 0)
return r;
if (r == 0)