Compare commits
12 Commits
0ca357bd6e
...
f30f82133c
Author | SHA1 | Date |
---|---|---|
Zbigniew Jędrzejewski-Szmek | f30f82133c | |
Lennart Poettering | d209e197f8 | |
Antonio Alvarez Feijoo | 9ed090230e | |
Luca Boccassi | 9bf6ffe166 | |
Lennart Poettering | 47c5ca237b | |
Lennart Poettering | 7f8a4f12df | |
Lennart Poettering | e412fc5e04 | |
Lennart Poettering | cc6baba720 | |
Lennart Poettering | 3ae48d071c | |
Antonio Alvarez Feijoo | 2ccacdd57c | |
Zbigniew Jędrzejewski-Szmek | 0e54562082 | |
Zbigniew Jędrzejewski-Szmek | 03af199aaf |
|
@ -265,32 +265,11 @@
|
|||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>Options</title>
|
||||
<title>Unlocking</title>
|
||||
|
||||
<para>The following options are understood:</para>
|
||||
<para>The following options are understood that may be used to unlock the device in preparation of the enrollment operations:</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><option>--password</option></term>
|
||||
|
||||
<listitem><para>Enroll a regular password/passphrase. This command is mostly equivalent to
|
||||
<command>cryptsetup luksAddKey</command>, however may be combined with
|
||||
<option>--wipe-slot=</option> in one call, see below.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v248"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--recovery-key</option></term>
|
||||
|
||||
<listitem><para>Enroll a recovery key. Recovery keys are mostly identical to passphrases, but are
|
||||
computer-generated instead of being chosen by a human, and thus have a guaranteed high entropy. The
|
||||
key uses a character set that is easy to type in, and may be scanned off screen via a QR code.
|
||||
</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v248"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--unlock-key-file=<replaceable>PATH</replaceable></option></term>
|
||||
|
||||
|
@ -328,7 +307,45 @@
|
|||
|
||||
<xi:include href="version-info.xml" xpointer="v256"/></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>Simple Enrollment</title>
|
||||
|
||||
<para>The following options are understood that may be used to enroll simple user input based
|
||||
unlocking:</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><option>--password</option></term>
|
||||
|
||||
<listitem><para>Enroll a regular password/passphrase. This command is mostly equivalent to
|
||||
<command>cryptsetup luksAddKey</command>, however may be combined with
|
||||
<option>--wipe-slot=</option> in one call, see below.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v248"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--recovery-key</option></term>
|
||||
|
||||
<listitem><para>Enroll a recovery key. Recovery keys are mostly identical to passphrases, but are
|
||||
computer-generated instead of being chosen by a human, and thus have a guaranteed high entropy. The
|
||||
key uses a character set that is easy to type in, and may be scanned off screen via a QR code.
|
||||
</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v248"/></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>PKCS#11 Enrollment</title>
|
||||
|
||||
<para>The following option is understood that may be used to enroll PKCS#11 tokens:</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><option>--pkcs11-token-uri=<replaceable>URI</replaceable></option></term>
|
||||
|
||||
|
@ -361,7 +378,15 @@
|
|||
|
||||
<xi:include href="version-info.xml" xpointer="v248"/></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>FIDO2 Enrollment</title>
|
||||
|
||||
<para>The following options are understood that may be used to enroll PKCS#11 tokens:</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><option>--fido2-credential-algorithm=<replaceable>STRING</replaceable></option></term>
|
||||
<listitem><para>Specify COSE algorithm used in credential generation. The default value is
|
||||
|
@ -461,7 +486,15 @@
|
|||
|
||||
<xi:include href="version-info.xml" xpointer="v249"/></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>TPM2 Enrollment</title>
|
||||
|
||||
<para>The following options are understood that may be used to enroll TPM2 devices:</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><option>--tpm2-device=<replaceable>PATH</replaceable></option></term>
|
||||
|
||||
|
@ -636,7 +669,15 @@
|
|||
|
||||
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>Other Options</title>
|
||||
|
||||
<para>The following additional options are understood:</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><option>--wipe-slot=<replaceable>SLOT<optional>,SLOT...</optional></replaceable></option></term>
|
||||
|
||||
|
|
|
@ -38,19 +38,12 @@ __get_tpm2_devices() {
|
|||
done
|
||||
}
|
||||
|
||||
__get_block_devices() {
|
||||
local i
|
||||
for i in /dev/*; do
|
||||
[ -b "$i" ] && printf '%s\n' "$i"
|
||||
done
|
||||
}
|
||||
|
||||
_systemd_cryptenroll() {
|
||||
local comps
|
||||
local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} words cword
|
||||
local -A OPTS=(
|
||||
[STANDALONE]='-h --help --version
|
||||
--password --recovery-key'
|
||||
--password --recovery-key --list-devices'
|
||||
[ARG]='--unlock-key-file
|
||||
--unlock-fido2-device
|
||||
--unlock-tpm2-device
|
||||
|
@ -116,7 +109,7 @@ _systemd_cryptenroll() {
|
|||
return 0
|
||||
fi
|
||||
|
||||
comps=$(__get_block_devices)
|
||||
comps=$(systemd-cryptenroll --list-devices)
|
||||
COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
|
||||
return 0
|
||||
}
|
||||
|
|
|
@ -193,7 +193,7 @@ static int help(void) {
|
|||
"\n%3$sSimple Enrollment:%4$s\n"
|
||||
" --password Enroll a user-supplied password\n"
|
||||
" --recovery-key Enroll a recovery key\n"
|
||||
"\n%3$sPKCS11 Enrollment:%4$s\n"
|
||||
"\n%3$sPKCS#11 Enrollment:%4$s\n"
|
||||
" --pkcs11-token-uri=URI\n"
|
||||
" Specify PKCS#11 security token URI\n"
|
||||
"\n%3$sFIDO2 Enrollment:%4$s\n"
|
||||
|
|
|
@ -234,7 +234,7 @@ static int handle_action_execute(
|
|||
/* If the actual operation is inhibited, warn and fail */
|
||||
if (inhibit_what_is_valid(inhibit_operation) &&
|
||||
!ignore_inhibited &&
|
||||
manager_is_inhibited(m, inhibit_operation, /* block= */ true, NULL, false, false, 0, &offending)) {
|
||||
manager_is_inhibited(m, inhibit_operation, NULL, /* flags= */ 0, UID_INVALID, &offending)) {
|
||||
_cleanup_free_ char *comm = NULL, *u = NULL;
|
||||
|
||||
(void) pidref_get_comm(&offending->pid, &comm);
|
||||
|
@ -372,7 +372,7 @@ int manager_handle_action(
|
|||
|
||||
/* If the key handling is inhibited, don't do anything */
|
||||
if (inhibit_key > 0) {
|
||||
if (manager_is_inhibited(m, inhibit_key, /* block= */ true, NULL, true, false, 0, NULL)) {
|
||||
if (manager_is_inhibited(m, inhibit_key, NULL, MANAGER_IS_INHIBITED_IGNORE_INACTIVE, UID_INVALID, NULL)) {
|
||||
log_debug("Refusing %s operation, %s is inhibited.",
|
||||
handle_action_to_string(handle),
|
||||
inhibit_what_to_string(inhibit_key));
|
||||
|
|
|
@ -411,7 +411,7 @@ int manager_get_idle_hint(Manager *m, dual_timestamp *t) {
|
|||
|
||||
assert(m);
|
||||
|
||||
idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, /* block= */ true, t, false, false, 0, NULL);
|
||||
idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, t, /* flags= */ 0, UID_INVALID, NULL);
|
||||
|
||||
HASHMAP_FOREACH(s, m->sessions) {
|
||||
dual_timestamp k;
|
||||
|
|
|
@ -1931,7 +1931,12 @@ int manager_dispatch_delayed(Manager *manager, bool timeout) {
|
|||
if (!manager->delayed_action || manager->action_job)
|
||||
return 0;
|
||||
|
||||
if (manager_is_inhibited(manager, manager->delayed_action->inhibit_what, /* block= */ false, NULL, false, false, 0, &offending)) {
|
||||
if (manager_is_inhibited(manager,
|
||||
manager->delayed_action->inhibit_what,
|
||||
NULL,
|
||||
MANAGER_IS_INHIBITED_CHECK_DELAY,
|
||||
UID_INVALID,
|
||||
&offending)) {
|
||||
_cleanup_free_ char *comm = NULL, *u = NULL;
|
||||
|
||||
if (!timeout)
|
||||
|
@ -2033,7 +2038,7 @@ int bus_manager_shutdown_or_sleep_now_or_later(
|
|||
|
||||
delayed =
|
||||
m->inhibit_delay_max > 0 &&
|
||||
manager_is_inhibited(m, a->inhibit_what, /* block= */ false, NULL, false, false, 0, NULL);
|
||||
manager_is_inhibited(m, a->inhibit_what, NULL, MANAGER_IS_INHIBITED_CHECK_DELAY, UID_INVALID, NULL);
|
||||
|
||||
if (delayed)
|
||||
/* Shutdown is delayed, keep in mind what we
|
||||
|
@ -2077,7 +2082,7 @@ static int verify_shutdown_creds(
|
|||
return r;
|
||||
|
||||
multiple_sessions = r > 0;
|
||||
blocked = manager_is_inhibited(m, a->inhibit_what, /* block= */ true, NULL, false, true, uid, &offending);
|
||||
blocked = manager_is_inhibited(m, a->inhibit_what, NULL, /* flags= */ 0, uid, &offending);
|
||||
interactive = flags & SD_LOGIND_INTERACTIVE;
|
||||
|
||||
if (multiple_sessions) {
|
||||
|
@ -2820,7 +2825,7 @@ static int method_can_shutdown_or_sleep(
|
|||
return r;
|
||||
|
||||
multiple_sessions = r > 0;
|
||||
blocked = manager_is_inhibited(m, a->inhibit_what, /* block= */ true, NULL, false, true, uid, NULL);
|
||||
blocked = manager_is_inhibited(m, a->inhibit_what, NULL, /* flags= */ 0, uid, NULL);
|
||||
|
||||
if (check_unit_state && a->target) {
|
||||
_cleanup_free_ char *load_state = NULL;
|
||||
|
|
|
@ -399,11 +399,9 @@ static int pidref_is_active_session(Manager *m, const PidRef *pid) {
|
|||
bool manager_is_inhibited(
|
||||
Manager *m,
|
||||
InhibitWhat w,
|
||||
bool block,
|
||||
dual_timestamp *since,
|
||||
bool ignore_inactive,
|
||||
bool ignore_uid,
|
||||
uid_t uid,
|
||||
ManagerIsInhibitedFlags flags,
|
||||
uid_t uid_to_ignore,
|
||||
Inhibitor **ret_offending) {
|
||||
|
||||
Inhibitor *i, *offending = NULL;
|
||||
|
@ -421,18 +419,19 @@ bool manager_is_inhibited(
|
|||
if (!(i->what & w))
|
||||
continue;
|
||||
|
||||
if ((block && !IN_SET(i->mode, INHIBIT_BLOCK, INHIBIT_BLOCK_WEAK)) ||
|
||||
(!block && i->mode != INHIBIT_DELAY))
|
||||
if ((flags & MANAGER_IS_INHIBITED_CHECK_DELAY) != (i->mode == INHIBIT_DELAY))
|
||||
continue;
|
||||
|
||||
if (ignore_inactive && pidref_is_active_session(m, &i->pid) <= 0)
|
||||
if ((flags & MANAGER_IS_INHIBITED_IGNORE_INACTIVE) &&
|
||||
pidref_is_active_session(m, &i->pid) <= 0)
|
||||
continue;
|
||||
|
||||
if (i->mode == INHIBIT_BLOCK_WEAK && ignore_uid && i->uid == uid)
|
||||
if (i->mode == INHIBIT_BLOCK_WEAK &&
|
||||
uid_is_valid(uid_to_ignore) &&
|
||||
uid_to_ignore == i->uid)
|
||||
continue;
|
||||
|
||||
if (!inhibited ||
|
||||
i->since.monotonic < ts.monotonic)
|
||||
if (!inhibited || i->since.monotonic < ts.monotonic)
|
||||
ts = i->since;
|
||||
|
||||
inhibited = true;
|
||||
|
|
|
@ -67,7 +67,20 @@ int inhibitor_create_fifo(Inhibitor *i);
|
|||
bool inhibitor_is_orphan(Inhibitor *i);
|
||||
|
||||
InhibitWhat manager_inhibit_what(Manager *m, InhibitMode mode);
|
||||
bool manager_is_inhibited(Manager *m, InhibitWhat w, bool block, dual_timestamp *since, bool ignore_inactive, bool ignore_uid, uid_t uid, Inhibitor **offending);
|
||||
|
||||
typedef enum ManagerIsInhibitedFlags {
|
||||
MANAGER_IS_INHIBITED_CHECK_DELAY = 1 << 0, /* When set, we only check delay inhibitors.
|
||||
* Otherwise, we only check block inhibitors. */
|
||||
MANAGER_IS_INHIBITED_IGNORE_INACTIVE = 1 << 1, /* When set, ignore inactive sessions. */
|
||||
} ManagerIsInhibitedFlags;
|
||||
|
||||
bool manager_is_inhibited(
|
||||
Manager *m,
|
||||
InhibitWhat w,
|
||||
dual_timestamp *since,
|
||||
ManagerIsInhibitedFlags flags,
|
||||
uid_t uid_to_ignore,
|
||||
Inhibitor **ret_offending);
|
||||
|
||||
static inline bool inhibit_what_is_valid(InhibitWhat w) {
|
||||
return w > 0 && w < _INHIBIT_WHAT_MAX;
|
||||
|
|
|
@ -392,7 +392,7 @@ int tpm2_make_pcr_json_array(uint32_t pcr_mask, sd_json_variant **ret);
|
|||
int tpm2_parse_pcr_json_array(sd_json_variant *v, uint32_t *ret);
|
||||
|
||||
int tpm2_make_luks2_json(int keyslot, uint32_t hash_pcr_mask, uint16_t pcr_bank, const struct iovec *pubkey, uint32_t pubkey_pcr_mask, uint16_t primary_alg, const struct iovec blobs[], size_t n_blobs, const struct iovec policy_hash[], size_t n_policy_hash, const struct iovec *salt, const struct iovec *srk, const struct iovec *pcrlock_nv, TPM2Flags flags, sd_json_variant **ret);
|
||||
int tpm2_parse_luks2_json(sd_json_variant *v, int *ret_keyslot, uint32_t *ret_hash_pcr_mask, uint16_t *ret_pcr_bank, struct iovec *ret_pubkey, uint32_t *ret_pubkey_pcr_mask, uint16_t *ret_primary_alg, struct iovec **ret_blobs, size_t *ret_n_blobs, struct iovec **ret_policy_hash, size_t *ret_n_policy_hash, struct iovec *ret_salt, struct iovec *ret_srk, struct iovec *pcrlock_nv, TPM2Flags *ret_flags);
|
||||
int tpm2_parse_luks2_json(sd_json_variant *v, int *ret_keyslot, uint32_t *ret_hash_pcr_mask, uint16_t *ret_pcr_bank, struct iovec *ret_pubkey, uint32_t *ret_pubkey_pcr_mask, uint16_t *ret_primary_alg, struct iovec **ret_blobs, size_t *ret_n_blobs, struct iovec **ret_policy_hash, size_t *ret_n_policy_hash, struct iovec *ret_salt, struct iovec *ret_srk, struct iovec *ret_pcrlock_nv, TPM2Flags *ret_flags);
|
||||
|
||||
/* Default to PCR 7 only */
|
||||
#define TPM2_PCR_INDEX_DEFAULT UINT32_C(7)
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "user-util.h"
|
||||
#include "userdb.h"
|
||||
#include "verbs.h"
|
||||
#include "virt.h"
|
||||
|
||||
static enum {
|
||||
OUTPUT_CLASSIC,
|
||||
|
@ -139,10 +140,16 @@ static int show_user(UserRecord *ur, Table *table) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool test_show_mapped(void) {
|
||||
/* Show mapped user range only in environments where user mapping is a thing. */
|
||||
return running_in_userns() > 0;
|
||||
}
|
||||
|
||||
static const struct {
|
||||
uid_t first, last;
|
||||
const char *name;
|
||||
UserDisposition disposition;
|
||||
bool (*test)(void);
|
||||
} uid_range_table[] = {
|
||||
{
|
||||
.first = 1,
|
||||
|
@ -175,11 +182,12 @@ static const struct {
|
|||
.last = MAP_UID_MAX,
|
||||
.name = "mapped",
|
||||
.disposition = USER_REGULAR,
|
||||
.test = test_show_mapped,
|
||||
},
|
||||
};
|
||||
|
||||
static int table_add_uid_boundaries(Table *table, const UIDRange *p) {
|
||||
int r;
|
||||
int r, n_added = 0;
|
||||
|
||||
assert(table);
|
||||
|
||||
|
@ -192,6 +200,9 @@ static int table_add_uid_boundaries(Table *table, const UIDRange *p) {
|
|||
if (!uid_range_covers(p, i->first, i->last - i->first + 1))
|
||||
continue;
|
||||
|
||||
if (i->test && !i->test())
|
||||
continue;
|
||||
|
||||
name = strjoin(special_glyph(SPECIAL_GLYPH_ARROW_DOWN),
|
||||
" begin ", i->name, " users ",
|
||||
special_glyph(SPECIAL_GLYPH_ARROW_DOWN));
|
||||
|
@ -249,9 +260,11 @@ static int table_add_uid_boundaries(Table *table, const UIDRange *p) {
|
|||
TABLE_INT, 1); /* sort after any other entry with the same UID */
|
||||
if (r < 0)
|
||||
return table_log_add_error(r);
|
||||
|
||||
n_added += 2;
|
||||
}
|
||||
|
||||
return ELEMENTSOF(uid_range_table) * 2;
|
||||
return n_added;
|
||||
}
|
||||
|
||||
static int add_unavailable_uid(Table *table, uid_t start, uid_t end) {
|
||||
|
@ -565,16 +578,22 @@ static int show_group(GroupRecord *gr, Table *table) {
|
|||
}
|
||||
|
||||
static int table_add_gid_boundaries(Table *table, const UIDRange *p) {
|
||||
int r;
|
||||
int r, n_added = 0;
|
||||
|
||||
assert(table);
|
||||
|
||||
FOREACH_ELEMENT(i, uid_range_table) {
|
||||
_cleanup_free_ char *name = NULL, *comment = NULL;
|
||||
|
||||
if (!FLAGS_SET(arg_disposition_mask, UINT64_C(1) << i->disposition))
|
||||
continue;
|
||||
|
||||
if (!uid_range_covers(p, i->first, i->last - i->first + 1))
|
||||
continue;
|
||||
|
||||
if (i->test && !i->test())
|
||||
continue;
|
||||
|
||||
name = strjoin(special_glyph(SPECIAL_GLYPH_ARROW_DOWN),
|
||||
" begin ", i->name, " groups ",
|
||||
special_glyph(SPECIAL_GLYPH_ARROW_DOWN));
|
||||
|
@ -626,9 +645,11 @@ static int table_add_gid_boundaries(Table *table, const UIDRange *p) {
|
|||
TABLE_INT, 1); /* sort after any other entry with the same GID */
|
||||
if (r < 0)
|
||||
return table_log_add_error(r);
|
||||
|
||||
n_added += 2;
|
||||
}
|
||||
|
||||
return ELEMENTSOF(uid_range_table) * 2;
|
||||
return n_added;
|
||||
}
|
||||
|
||||
static int add_unavailable_gid(Table *table, uid_t start, uid_t end) {
|
||||
|
|
Loading…
Reference in New Issue