Compare commits
6 Commits
32d4a94da2
...
4518a8d188
Author | SHA1 | Date |
---|---|---|
Federico Giovanardi | 4518a8d188 | |
Luca Boccassi | 9bf6ffe166 | |
Lennart Poettering | cc6baba720 | |
Lennart Poettering | 3ae48d071c | |
Antonio Alvarez Feijoo | 2ccacdd57c | |
Federico Giovanardi | 9d58f3b81e |
|
@ -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>
|
||||
|
||||
|
|
|
@ -577,6 +577,17 @@
|
|||
<xi:include href="version-info.xml" xpointer="v251"/>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>--include-parents</option></term>
|
||||
<listitem>
|
||||
<para>Trigger parent devices of found devices even if the parents
|
||||
won't match the filter condition.
|
||||
This is useful if we are interested to limit the coldplug activities to
|
||||
some devices or subsystems.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v258"/>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>-w</option></term>
|
||||
<term><option>--settle</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
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ _udevadm() {
|
|||
--json --subsystem-match --subsystem-nomatch --attr-match --attr-nomatch --property-match
|
||||
--tag-match --sysname-match --name-match --parent-match'
|
||||
[TRIGGER_STANDALONE]='-v --verbose -n --dry-run -q --quiet -w --settle --wait-daemon --uuid
|
||||
--initialized-match --initialized-nomatch'
|
||||
--initialized-match --initialized-nomatch --include-parents'
|
||||
[TRIGGER_ARG]='-t --type -c --action -s --subsystem-match -S --subsystem-nomatch
|
||||
-a --attr-match -A --attr-nomatch -p --property-match
|
||||
-g --tag-match -y --sysname-match --name-match -b --parent-match
|
||||
|
|
|
@ -38,6 +38,7 @@ _udevadm_trigger(){
|
|||
'--tag-match=[Trigger events for devices with a matching tag.]:TAG' \
|
||||
'--sysname-match=[Trigger events for devices with a matching sys device name.]:NAME' \
|
||||
'--parent-match=[Trigger events for all children of a given device.]:NAME' \
|
||||
'--include-parents[Also trigger parent devices of found devices.]' \
|
||||
'--initialized-match[Trigger events for devices that are already initialized.]' \
|
||||
'--initialized-nomatch[Trigger events for devices that are not initialized yet.]' \
|
||||
'--uuid[Print synthetic uevent UUID.]' \
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -1058,3 +1058,8 @@ global:
|
|||
sd_device_monitor_get_timeout;
|
||||
sd_device_monitor_receive;
|
||||
} LIBSYSTEMD_256;
|
||||
|
||||
LIBSYSTEMD_258 {
|
||||
global:
|
||||
sd_device_enumerator_add_all_parents;
|
||||
} LIBSYSTEMD_257;
|
||||
|
|
|
@ -24,6 +24,17 @@ typedef enum DeviceEnumerationType {
|
|||
_DEVICE_ENUMERATION_TYPE_INVALID = -EINVAL,
|
||||
} DeviceEnumerationType;
|
||||
|
||||
typedef enum MatchFlag {
|
||||
MATCH_NONE = 0,
|
||||
MATCH_BASIC = 1u << 0,
|
||||
MATCH_SYSNAME = 1u << 1,
|
||||
MATCH_SUBSYSTEM = 1u << 2,
|
||||
MATCH_PARENT = 1u << 3,
|
||||
MATCH_TAG = 1u << 4,
|
||||
|
||||
MATCH_ALL = (1u << 5) - 1,
|
||||
} MatchFlag;
|
||||
|
||||
struct sd_device_enumerator {
|
||||
unsigned n_ref;
|
||||
|
||||
|
@ -46,6 +57,7 @@ struct sd_device_enumerator {
|
|||
Set *match_tag;
|
||||
Set *match_parent;
|
||||
MatchInitializedType match_initialized;
|
||||
MatchFlag parent_match_flags;
|
||||
};
|
||||
|
||||
_public_ int sd_device_enumerator_new(sd_device_enumerator **ret) {
|
||||
|
@ -61,6 +73,7 @@ _public_ int sd_device_enumerator_new(sd_device_enumerator **ret) {
|
|||
.n_ref = 1,
|
||||
.type = _DEVICE_ENUMERATION_TYPE_INVALID,
|
||||
.match_initialized = MATCH_INITIALIZED_COMPAT,
|
||||
.parent_match_flags = MATCH_ALL,
|
||||
};
|
||||
|
||||
*ret = TAKE_PTR(enumerator);
|
||||
|
@ -273,6 +286,15 @@ _public_ int sd_device_enumerator_allow_uninitialized(sd_device_enumerator *enum
|
|||
|
||||
return 1;
|
||||
}
|
||||
_public_ int sd_device_enumerator_add_all_parents(sd_device_enumerator *enumerator) {
|
||||
assert_return(enumerator, -EINVAL);
|
||||
|
||||
enumerator->parent_match_flags = MATCH_NONE;
|
||||
|
||||
enumerator->scan_uptodate = false;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int device_enumerator_add_match_is_initialized(sd_device_enumerator *enumerator, MatchInitializedType type) {
|
||||
assert_return(enumerator, -EINVAL);
|
||||
|
@ -567,15 +589,6 @@ static bool match_subsystem(sd_device_enumerator *enumerator, const char *subsys
|
|||
return set_fnmatch(enumerator->match_subsystem, enumerator->nomatch_subsystem, subsystem);
|
||||
}
|
||||
|
||||
typedef enum MatchFlag {
|
||||
MATCH_SYSNAME = 1u << 0,
|
||||
MATCH_SUBSYSTEM = 1u << 1,
|
||||
MATCH_PARENT = 1u << 2,
|
||||
MATCH_TAG = 1u << 3,
|
||||
|
||||
MATCH_ALL = (1u << 4) - 1,
|
||||
} MatchFlag;
|
||||
|
||||
static int test_matches(
|
||||
sd_device_enumerator *enumerator,
|
||||
sd_device *device,
|
||||
|
@ -618,6 +631,7 @@ static int test_matches(
|
|||
!match_tag(enumerator, device))
|
||||
return false;
|
||||
|
||||
if (FLAGS_SET(flags, MATCH_BASIC)) {
|
||||
r = match_initialized(enumerator, device);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
@ -630,6 +644,7 @@ static int test_matches(
|
|||
|
||||
if (!device_match_sysattr(device, enumerator->match_sysattr, enumerator->nomatch_sysattr))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -743,7 +758,7 @@ static int enumerator_scan_dir_and_add_devices(
|
|||
/* Also include all potentially matching parent devices in the enumeration. These are things
|
||||
* like root busses — e.g. /sys/devices/pci0000:00/ or /sys/devices/pnp0/, which ar not
|
||||
* linked from /sys/class/ or /sys/bus/, hence pick them up explicitly here. */
|
||||
k = enumerator_add_parent_devices(enumerator, device, MATCH_ALL);
|
||||
k = enumerator_add_parent_devices(enumerator, device, enumerator->parent_match_flags);
|
||||
if (k < 0)
|
||||
r = k;
|
||||
}
|
||||
|
|
|
@ -499,6 +499,41 @@ TEST(sd_device_enumerator_add_match_parent) {
|
|||
}
|
||||
}
|
||||
|
||||
TEST(sd_device_enumerator_add_all_parents) {
|
||||
_cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
|
||||
unsigned devices_count_with_parents = 0;
|
||||
unsigned devices_count_without_parents = 0;
|
||||
|
||||
/* STEP 1: enumerate all block devices without all_parents() */
|
||||
ASSERT_OK(sd_device_enumerator_new(&e));
|
||||
ASSERT_OK(sd_device_enumerator_allow_uninitialized(e));
|
||||
|
||||
/* filter in only a subsystem */
|
||||
ASSERT_OK(sd_device_enumerator_add_nomatch_sysname(e, "loop*"));
|
||||
ASSERT_OK(sd_device_enumerator_add_match_subsystem(e, "block", true));
|
||||
ASSERT_OK(sd_device_enumerator_add_match_property(e, "DEVTYPE", "partition"));
|
||||
|
||||
FOREACH_DEVICE(e, dev) {
|
||||
ASSERT_TRUE(device_in_subsystem(dev, "block"));
|
||||
ASSERT_TRUE(device_is_devtype(dev, "partition"));
|
||||
devices_count_without_parents++;
|
||||
}
|
||||
|
||||
log_debug("found %u devices", devices_count_without_parents);
|
||||
|
||||
/* STEP 2: enumerate again with all_parents() */
|
||||
ASSERT_OK(sd_device_enumerator_add_all_parents(e) >= 0);
|
||||
|
||||
unsigned int not_filtered_parent_count = 0;
|
||||
FOREACH_DEVICE(e, dev) {
|
||||
if (!device_in_subsystem(dev, "block") || !device_is_devtype(dev,"partition"))
|
||||
not_filtered_parent_count++;
|
||||
devices_count_with_parents++;
|
||||
}
|
||||
log_debug("found %u devices out of %u that would have been excluded without all_parents()", not_filtered_parent_count,devices_count_with_parents);
|
||||
ASSERT_EQ(devices_count_with_parents, devices_count_without_parents + not_filtered_parent_count);
|
||||
}
|
||||
|
||||
TEST(sd_device_get_child) {
|
||||
_cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
|
||||
int r;
|
||||
|
|
|
@ -137,6 +137,7 @@ int sd_device_enumerator_add_nomatch_sysname(sd_device_enumerator *enumerator, c
|
|||
int sd_device_enumerator_add_match_tag(sd_device_enumerator *enumerator, const char *tag);
|
||||
int sd_device_enumerator_add_match_parent(sd_device_enumerator *enumerator, sd_device *parent);
|
||||
int sd_device_enumerator_allow_uninitialized(sd_device_enumerator *enumerator);
|
||||
int sd_device_enumerator_add_all_parents(sd_device_enumerator *enumerator);
|
||||
|
||||
/* device monitor */
|
||||
|
||||
|
|
|
@ -266,6 +266,7 @@ static int help(void) {
|
|||
" -y --sysname-match=NAME Trigger devices with this /sys path\n"
|
||||
" --name-match=NAME Trigger devices with this /dev name\n"
|
||||
" -b --parent-match=NAME Trigger devices with that parent device\n"
|
||||
" --include-parents Trigger parent devices of found devices\n"
|
||||
" --initialized-match Trigger devices that are already initialized\n"
|
||||
" --initialized-nomatch Trigger devices that are not initialized yet\n"
|
||||
" -w --settle Wait for the triggered events to complete\n"
|
||||
|
@ -287,6 +288,7 @@ int trigger_main(int argc, char *argv[], void *userdata) {
|
|||
ARG_PRIORITIZED_SUBSYSTEM,
|
||||
ARG_INITIALIZED_MATCH,
|
||||
ARG_INITIALIZED_NOMATCH,
|
||||
ARG_INCLUDE_PARENTS,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
|
@ -304,6 +306,7 @@ int trigger_main(int argc, char *argv[], void *userdata) {
|
|||
{ "sysname-match", required_argument, NULL, 'y' },
|
||||
{ "name-match", required_argument, NULL, ARG_NAME },
|
||||
{ "parent-match", required_argument, NULL, 'b' },
|
||||
{ "include-parents", no_argument, NULL, ARG_INCLUDE_PARENTS },
|
||||
{ "initialized-match", no_argument, NULL, ARG_INITIALIZED_MATCH },
|
||||
{ "initialized-nomatch", no_argument, NULL, ARG_INITIALIZED_NOMATCH },
|
||||
{ "settle", no_argument, NULL, 'w' },
|
||||
|
@ -428,6 +431,11 @@ int trigger_main(int argc, char *argv[], void *userdata) {
|
|||
return log_error_errno(r, "Failed to add parent match '%s': %m", optarg);
|
||||
break;
|
||||
}
|
||||
case ARG_INCLUDE_PARENTS:
|
||||
r = sd_device_enumerator_add_all_parents(e);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to always include all parents: %m");
|
||||
break;
|
||||
case 'w':
|
||||
arg_settle = true;
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue