mirror of
https://github.com/systemd/systemd
synced 2026-03-17 10:34:46 +01:00
Compare commits
No commits in common. "f7e31e9dfd5a3f383c872e8a9062ef3cd4d34d95" and "18503cac4104c83ec323920c44f1433edf82f773" have entirely different histories.
f7e31e9dfd
...
18503cac41
@ -106,7 +106,7 @@
|
|||||||
but might not on older. It is possible to convert the machine ID into a UUID v4-compatible one. For more
|
but might not on older. It is possible to convert the machine ID into a UUID v4-compatible one. For more
|
||||||
information, see
|
information, see
|
||||||
<citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>. It is
|
<citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>. It is
|
||||||
hence guaranteed that these functions will never return the ID consisting of all zero or all one bits
|
hence guaranteed that thes functions will never return the ID consisting of all zero or all one bits
|
||||||
(<constant>SD_ID128_NULL</constant>, <constant>SD_ID128_ALLF</constant>) — with the possible exception of
|
(<constant>SD_ID128_NULL</constant>, <constant>SD_ID128_ALLF</constant>) — with the possible exception of
|
||||||
<function>sd_id128_get_machine()</function>, as mentioned.</para>
|
<function>sd_id128_get_machine()</function>, as mentioned.</para>
|
||||||
|
|
||||||
|
|||||||
@ -128,11 +128,8 @@
|
|||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>--fido2-with-client-pin=</option><replaceable>BOOL</replaceable></term>
|
<term><option>--fido2-with-client-pin=</option><replaceable>BOOL</replaceable></term>
|
||||||
|
|
||||||
<listitem><para>When enrolling a FIDO2 security token, controls whether to require the user to enter
|
<listitem><para>When enrolling a FIDO2 security token, controls whether to require the user to
|
||||||
a PIN when unlocking the volume (the FIDO2 <literal>clientPin</literal> feature). Defaults to
|
enter a PIN when unlocking the volume. Defaults to <literal>yes</literal>.</para></listitem>
|
||||||
<literal>yes</literal>. (Note: this setting is without effect if the security token does not support
|
|
||||||
the <literal>clientPin</literal> feature at all, or does not allow enabling or disabling
|
|
||||||
it.)</para></listitem>
|
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@ -140,8 +137,7 @@
|
|||||||
|
|
||||||
<listitem><para>When enrolling a FIDO2 security token, controls whether to require the user to
|
<listitem><para>When enrolling a FIDO2 security token, controls whether to require the user to
|
||||||
verify presence (tap the token, the FIDO2 <literal>up</literal> feature) when unlocking the volume.
|
verify presence (tap the token, the FIDO2 <literal>up</literal> feature) when unlocking the volume.
|
||||||
Defaults to <literal>yes</literal>. (Note: this setting is without effect if the security token does not support
|
Defaults to <literal>yes</literal>.
|
||||||
the <literal>up</literal> feature at all, or does not allow enabling or disabling it.)
|
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
@ -149,9 +145,8 @@
|
|||||||
<term><option>--fido2-with-user-verification=</option><replaceable>BOOL</replaceable></term>
|
<term><option>--fido2-with-user-verification=</option><replaceable>BOOL</replaceable></term>
|
||||||
|
|
||||||
<listitem><para>When enrolling a FIDO2 security token, controls whether to require user verification
|
<listitem><para>When enrolling a FIDO2 security token, controls whether to require user verification
|
||||||
when unlocking the volume (the FIDO2 <literal>uv</literal> feature). Defaults to
|
when unlocking the volume (the FIDO2 <literal>uv</literal> feature)). Defaults to <literal>no</literal>.
|
||||||
<literal>no</literal>. (Note: this setting is without effect if the security token does not support
|
</para></listitem>
|
||||||
the <literal>uv</literal> feature at all, or does not allow enabling or disabling it.)</para></listitem>
|
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
|
|||||||
@ -577,13 +577,12 @@ char* path_extend_internal(char **x, ...) {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
add = 1 + strlen(p);
|
add = 1 + strlen(p);
|
||||||
if (sz > SIZE_MAX - add) { /* overflow check */
|
if (sz > SIZE_MAX - add) /* overflow check */
|
||||||
va_end(ap);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
sz += add;
|
sz += add;
|
||||||
}
|
}
|
||||||
|
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
nx = realloc(x ? *x : NULL, GREEDY_ALLOC_ROUND_UP(sz+1));
|
nx = realloc(x ? *x : NULL, GREEDY_ALLOC_ROUND_UP(sz+1));
|
||||||
|
|||||||
@ -303,11 +303,11 @@ int unit_file_build_name_map(
|
|||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
if (paths) {
|
if (paths) {
|
||||||
r = set_put(paths, filename);
|
r = set_consume(paths, filename);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
if (r == 0)
|
/* We will still use filename below. This is safe because we know the set
|
||||||
_filename_free = filename; /* Make sure we free the filename. */
|
* holds a reference. */
|
||||||
} else
|
} else
|
||||||
_filename_free = filename; /* Make sure we free the filename. */
|
_filename_free = filename; /* Make sure we free the filename. */
|
||||||
|
|
||||||
|
|||||||
@ -2708,7 +2708,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, UnitNotifyFlag
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* And now, add the unit or depending units to various queues that will act on the new situation if
|
/* And now, add the unit or depending units to various queues that will act on the new situation if
|
||||||
* needed. These queues generally check for continuous state changes rather than events (like most of
|
* needed. These queues generally check for continous state changes rather than events (like most of
|
||||||
* the state propagation above), and do work deferred instead of instantly, since they typically
|
* the state propagation above), and do work deferred instead of instantly, since they typically
|
||||||
* don't want to run during reloading, and usually involve checking combined state of multiple units
|
* don't want to run during reloading, and usually involve checking combined state of multiple units
|
||||||
* at once. */
|
* at once. */
|
||||||
@ -5831,7 +5831,7 @@ int unit_get_dependency_array(const Unit *u, UnitDependencyAtom atom, Unit ***re
|
|||||||
|
|
||||||
/* Gets a list of units matching a specific atom as array. This is useful when iterating through
|
/* Gets a list of units matching a specific atom as array. This is useful when iterating through
|
||||||
* dependencies while modifying them: the array is an "atomic snapshot" of sorts, that can be read
|
* dependencies while modifying them: the array is an "atomic snapshot" of sorts, that can be read
|
||||||
* while the dependency table is continuously updated. */
|
* while the dependency table is continously updated. */
|
||||||
|
|
||||||
UNIT_FOREACH_DEPENDENCY(other, u, atom) {
|
UNIT_FOREACH_DEPENDENCY(other, u, atom) {
|
||||||
if (!GREEDY_REALLOC(array, n + 1))
|
if (!GREEDY_REALLOC(array, n + 1))
|
||||||
|
|||||||
@ -45,8 +45,7 @@ int enroll_fido2(
|
|||||||
&cid, &cid_size,
|
&cid, &cid_size,
|
||||||
&salt, &salt_size,
|
&salt, &salt_size,
|
||||||
&secret, &secret_size,
|
&secret, &secret_size,
|
||||||
NULL,
|
NULL);
|
||||||
&lock_with);
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
|||||||
@ -117,7 +117,8 @@ int find_fido2_auto_data(
|
|||||||
size_t cid_size = 0, salt_size = 0;
|
size_t cid_size = 0, salt_size = 0;
|
||||||
_cleanup_free_ char *rp = NULL;
|
_cleanup_free_ char *rp = NULL;
|
||||||
int r, keyslot = -1;
|
int r, keyslot = -1;
|
||||||
Fido2EnrollFlags required = 0;
|
/* For backward compatibility, require pin and presence by default */
|
||||||
|
Fido2EnrollFlags required = FIDO2ENROLL_PIN | FIDO2ENROLL_UP;
|
||||||
|
|
||||||
assert(cd);
|
assert(cd);
|
||||||
assert(ret_salt);
|
assert(ret_salt);
|
||||||
@ -192,8 +193,7 @@ int find_fido2_auto_data(
|
|||||||
"FIDO2 token data's 'fido2-clientPin-required' field is not a boolean.");
|
"FIDO2 token data's 'fido2-clientPin-required' field is not a boolean.");
|
||||||
|
|
||||||
SET_FLAG(required, FIDO2ENROLL_PIN, json_variant_boolean(w));
|
SET_FLAG(required, FIDO2ENROLL_PIN, json_variant_boolean(w));
|
||||||
} else
|
}
|
||||||
required |= FIDO2ENROLL_PIN_IF_NEEDED; /* compat with 248, where the field was unset */
|
|
||||||
|
|
||||||
w = json_variant_by_key(v, "fido2-up-required");
|
w = json_variant_by_key(v, "fido2-up-required");
|
||||||
if (w) {
|
if (w) {
|
||||||
@ -204,8 +204,7 @@ int find_fido2_auto_data(
|
|||||||
"FIDO2 token data's 'fido2-up-required' field is not a boolean.");
|
"FIDO2 token data's 'fido2-up-required' field is not a boolean.");
|
||||||
|
|
||||||
SET_FLAG(required, FIDO2ENROLL_UP, json_variant_boolean(w));
|
SET_FLAG(required, FIDO2ENROLL_UP, json_variant_boolean(w));
|
||||||
} else
|
}
|
||||||
required |= FIDO2ENROLL_UP_IF_NEEDED; /* compat with 248 */
|
|
||||||
|
|
||||||
w = json_variant_by_key(v, "fido2-uv-required");
|
w = json_variant_by_key(v, "fido2-uv-required");
|
||||||
if (w) {
|
if (w) {
|
||||||
@ -216,8 +215,7 @@ int find_fido2_auto_data(
|
|||||||
"FIDO2 token data's 'fido2-uv-required' field is not a boolean.");
|
"FIDO2 token data's 'fido2-uv-required' field is not a boolean.");
|
||||||
|
|
||||||
SET_FLAG(required, FIDO2ENROLL_UV, json_variant_boolean(w));
|
SET_FLAG(required, FIDO2ENROLL_UV, json_variant_boolean(w));
|
||||||
} else
|
}
|
||||||
required |= FIDO2ENROLL_UV_OMIT; /* compat with 248 */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cid)
|
if (!cid)
|
||||||
|
|||||||
@ -758,11 +758,7 @@ static int attach_luks_or_plain_or_bitlk_by_fido2(
|
|||||||
cid = arg_fido2_cid;
|
cid = arg_fido2_cid;
|
||||||
cid_size = arg_fido2_cid_size;
|
cid_size = arg_fido2_cid_size;
|
||||||
|
|
||||||
/* For now and for compatibility, if the user explicitly configured FIDO2 support and we do
|
required = FIDO2ENROLL_PIN | FIDO2ENROLL_UP; /* For backwards compatibility, PIN+presence is required by default. */
|
||||||
* not read FIDO2 metadata off the LUKS2 header, default to the systemd 248 logic, where we
|
|
||||||
* use PIN + UP when needed, and do not configure UV at all. Eventually, we should make this
|
|
||||||
* explicitly configurable. */
|
|
||||||
required = FIDO2ENROLL_PIN_IF_NEEDED | FIDO2ENROLL_UP_IF_NEEDED | FIDO2ENROLL_UV_OMIT;
|
|
||||||
} else {
|
} else {
|
||||||
r = find_fido2_auto_data(
|
r = find_fido2_auto_data(
|
||||||
cd,
|
cd,
|
||||||
|
|||||||
@ -162,8 +162,7 @@ int identity_add_fido2_parameters(
|
|||||||
&cid, &cid_size,
|
&cid, &cid_size,
|
||||||
&salt, &salt_size,
|
&salt, &salt_size,
|
||||||
&secret, &secret_size,
|
&secret, &secret_size,
|
||||||
&used_pin,
|
&used_pin);
|
||||||
NULL);
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
|||||||
@ -2141,7 +2141,7 @@ _public_ int sd_device_trigger_with_uuid(
|
|||||||
|
|
||||||
assert_return(device, -EINVAL);
|
assert_return(device, -EINVAL);
|
||||||
|
|
||||||
/* If no one wants to know the UUID, use the simple interface from pre-4.13 times */
|
/* If noone wants to know the UUID, use the simple interface from pre-4.13 times */
|
||||||
if (!ret_uuid)
|
if (!ret_uuid)
|
||||||
return sd_device_trigger(device, action);
|
return sd_device_trigger(device, action);
|
||||||
|
|
||||||
|
|||||||
@ -377,7 +377,7 @@ static int trie_store(struct trie *trie, const char *filename, bool compat) {
|
|||||||
r = fopen_temporary(filename, &t.f, &filename_tmp);
|
r = fopen_temporary(filename, &t.f, &filename_tmp);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
(void) fchmod(fileno(t.f), 0444);
|
fchmod(fileno(t.f), 0444);
|
||||||
|
|
||||||
/* write nodes */
|
/* write nodes */
|
||||||
if (fseeko(t.f, sizeof(struct trie_header_f), SEEK_SET) < 0)
|
if (fseeko(t.f, sizeof(struct trie_header_f), SEEK_SET) < 0)
|
||||||
|
|||||||
@ -163,7 +163,7 @@ int link_lldp_save(Link *link) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
||||||
(void) fchmod(fileno(f), 0644);
|
fchmod(fileno(f), 0644);
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
const void *p;
|
const void *p;
|
||||||
|
|||||||
@ -310,7 +310,7 @@ static int fido2_use_hmac_hash_specific_token(
|
|||||||
log_info("User presence required to unlock.");
|
log_info("User presence required to unlock.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_uv && !FLAGS_SET(required, FIDO2ENROLL_UV_OMIT)) {
|
if (has_uv) {
|
||||||
r = sym_fido_assert_set_uv(a, FLAGS_SET(required, FIDO2ENROLL_UV) ? FIDO_OPT_TRUE : FIDO_OPT_FALSE);
|
r = sym_fido_assert_set_uv(a, FLAGS_SET(required, FIDO2ENROLL_UV) ? FIDO_OPT_TRUE : FIDO_OPT_FALSE);
|
||||||
if (r != FIDO_OK)
|
if (r != FIDO_OK)
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EIO),
|
return log_error_errno(SYNTHETIC_ERRNO(EIO),
|
||||||
@ -322,98 +322,20 @@ static int fido2_use_hmac_hash_specific_token(
|
|||||||
log_info("User verification required to unlock.");
|
log_info("User verification required to unlock.");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
if (FLAGS_SET(required, FIDO2ENROLL_PIN)) {
|
||||||
bool retry_with_up = false, retry_with_pin = false;
|
char **i;
|
||||||
|
|
||||||
if (FLAGS_SET(required, FIDO2ENROLL_PIN)) {
|
if (!has_client_pin)
|
||||||
char **i;
|
log_warning("Weird, device asked for client PIN, but does not advertise it as feature. Ignoring.");
|
||||||
|
|
||||||
/* OK, we need a pin, try with all pins in turn */
|
/* OK, we needed a pin, try with all pins in turn */
|
||||||
if (strv_isempty(pins))
|
STRV_FOREACH(i, pins) {
|
||||||
r = FIDO_ERR_PIN_REQUIRED;
|
r = sym_fido_dev_get_assert(d, a, *i);
|
||||||
else
|
if (r != FIDO_ERR_PIN_INVALID)
|
||||||
STRV_FOREACH(i, pins) {
|
break;
|
||||||
r = sym_fido_dev_get_assert(d, a, *i);
|
|
||||||
if (r != FIDO_ERR_PIN_INVALID)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else
|
|
||||||
r = sym_fido_dev_get_assert(d, a, NULL);
|
|
||||||
|
|
||||||
/* In some conditions, where a PIN or UP is required we might accept that. Let's check the
|
|
||||||
* conditions and if so try immediately again. */
|
|
||||||
|
|
||||||
switch (r) {
|
|
||||||
|
|
||||||
case FIDO_ERR_UP_REQUIRED:
|
|
||||||
/* So the token asked for "up". Try to turn it on, for compat with systemd 248 and try again. */
|
|
||||||
|
|
||||||
if (!has_up)
|
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
|
||||||
"Token asks for user presence check but doesn't advertise 'up' feature.");
|
|
||||||
|
|
||||||
if (FLAGS_SET(required, FIDO2ENROLL_UP))
|
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
|
||||||
"Token asks for user presence check but was already enabled.");
|
|
||||||
|
|
||||||
if (FLAGS_SET(required, FIDO2ENROLL_UP_IF_NEEDED)) {
|
|
||||||
log_info("User presence required to unlock.");
|
|
||||||
retry_with_up = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FIDO_ERR_UNSUPPORTED_OPTION:
|
|
||||||
/* AuthenTrend ATKey.Pro returns this instead of FIDO_ERR_UP_REQUIRED, let's handle
|
|
||||||
* it gracefully (also see below.) */
|
|
||||||
|
|
||||||
if (has_up && (required & (FIDO2ENROLL_UP|FIDO2ENROLL_UP_IF_NEEDED)) == FIDO2ENROLL_UP_IF_NEEDED) {
|
|
||||||
log_notice("Got unsupported option error when when user presence test is turned off. Trying with user presence test turned on.");
|
|
||||||
retry_with_up = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FIDO_ERR_PIN_REQUIRED:
|
|
||||||
/* A pin was requested. Maybe supply one, if we are configured to do so on request */
|
|
||||||
|
|
||||||
if (!has_client_pin)
|
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
|
||||||
"Token asks for PIN but doesn't advertise 'clientPin' feature.");
|
|
||||||
|
|
||||||
if (FLAGS_SET(required, FIDO2ENROLL_PIN) && !strv_isempty(pins))
|
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
|
||||||
"Token asks for PIN but one was already supplied.");
|
|
||||||
|
|
||||||
if ((required & (FIDO2ENROLL_PIN|FIDO2ENROLL_PIN_IF_NEEDED)) == FIDO2ENROLL_PIN_IF_NEEDED) {
|
|
||||||
/* If a PIN so far wasn't specified but is requested by the device, and
|
|
||||||
* FIDO2ENROLL_PIN_IF_NEEDED is set, then provide it */
|
|
||||||
log_debug("Retrying to create credential with PIN.");
|
|
||||||
retry_with_pin = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
} else
|
||||||
if (!retry_with_up && !retry_with_pin)
|
r = sym_fido_dev_get_assert(d, a, NULL);
|
||||||
break;
|
|
||||||
|
|
||||||
if (retry_with_up) {
|
|
||||||
r = sym_fido_assert_set_up(a, FIDO_OPT_TRUE);
|
|
||||||
if (r != FIDO_OK)
|
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EIO),
|
|
||||||
"Failed to enable FIDO2 user presence test: %s", sym_fido_strerr(r));
|
|
||||||
|
|
||||||
required |= FIDO2ENROLL_UP;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (retry_with_pin)
|
|
||||||
required |= FIDO2ENROLL_PIN;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (r) {
|
switch (r) {
|
||||||
case FIDO_OK:
|
case FIDO_OK:
|
||||||
@ -546,8 +468,7 @@ int fido2_generate_hmac_hash(
|
|||||||
void **ret_cid, size_t *ret_cid_size,
|
void **ret_cid, size_t *ret_cid_size,
|
||||||
void **ret_salt, size_t *ret_salt_size,
|
void **ret_salt, size_t *ret_salt_size,
|
||||||
void **ret_secret, size_t *ret_secret_size,
|
void **ret_secret, size_t *ret_secret_size,
|
||||||
char **ret_usedpin,
|
char **ret_usedpin) {
|
||||||
Fido2EnrollFlags *ret_locked_with) {
|
|
||||||
|
|
||||||
_cleanup_(erase_and_freep) void *salt = NULL, *secret_copy = NULL;
|
_cleanup_(erase_and_freep) void *salt = NULL, *secret_copy = NULL;
|
||||||
_cleanup_(fido_assert_free_wrapper) fido_assert_t *a = NULL;
|
_cleanup_(fido_assert_free_wrapper) fido_assert_t *a = NULL;
|
||||||
@ -582,7 +503,6 @@ int fido2_generate_hmac_hash(
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
assert(device);
|
assert(device);
|
||||||
assert((lock_with & ~(FIDO2ENROLL_PIN|FIDO2ENROLL_UP|FIDO2ENROLL_UV)) == 0);
|
|
||||||
|
|
||||||
r = dlopen_libfido2();
|
r = dlopen_libfido2();
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@ -609,21 +529,20 @@ int fido2_generate_hmac_hash(
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
/* While enrolling degrade gracefully if the requested feature set isn't available, but let the user know */
|
if (!has_client_pin && FLAGS_SET(lock_with, FIDO2ENROLL_PIN))
|
||||||
if (!has_client_pin && FLAGS_SET(lock_with, FIDO2ENROLL_PIN)) {
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||||
log_notice("Requested to lock with PIN, but FIDO2 device %s does not support it, disabling.", device);
|
"Requested to lock with PIN, but FIDO2 device %s does not support it.",
|
||||||
lock_with &= ~FIDO2ENROLL_PIN;
|
device);
|
||||||
}
|
|
||||||
|
|
||||||
if (!has_up && FLAGS_SET(lock_with, FIDO2ENROLL_UP)) {
|
if (!has_up && FLAGS_SET(lock_with, FIDO2ENROLL_UP))
|
||||||
log_notice("Locking with user presence test requested, but FIDO2 device %s does not support it, disabling.", device);
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||||
lock_with &= ~FIDO2ENROLL_UP;
|
"Locking with user presence test requested, but FIDO2 device %s does not support it.",
|
||||||
}
|
device);
|
||||||
|
|
||||||
if (!has_uv && FLAGS_SET(lock_with, FIDO2ENROLL_UV)) {
|
if (!has_uv && FLAGS_SET(lock_with, FIDO2ENROLL_UV))
|
||||||
log_notice("Locking with user verification requested, but FIDO2 device %s does not support it, disabling.", device);
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||||
lock_with &= ~FIDO2ENROLL_UV;
|
"Locking with user verification requested, but FIDO2 device %s does not support it.",
|
||||||
}
|
device);
|
||||||
|
|
||||||
c = sym_fido_cred_new();
|
c = sym_fido_cred_new();
|
||||||
if (!c)
|
if (!c)
|
||||||
@ -673,9 +592,6 @@ int fido2_generate_hmac_hash(
|
|||||||
"Failed to turn off FIDO2 user verification option of credential: %s", sym_fido_strerr(r));
|
"Failed to turn off FIDO2 user verification option of credential: %s", sym_fido_strerr(r));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* As per specification "up" is assumed to be implicit when making credentials, hence we don't
|
|
||||||
* explicitly enable/disable it here */
|
|
||||||
|
|
||||||
log_info("Initializing FIDO2 credential on security token.");
|
log_info("Initializing FIDO2 credential on security token.");
|
||||||
|
|
||||||
log_notice("%s%s(Hint: This might require verification of user presence on security token.)",
|
log_notice("%s%s(Hint: This might require verification of user presence on security token.)",
|
||||||
@ -684,15 +600,13 @@ int fido2_generate_hmac_hash(
|
|||||||
|
|
||||||
r = sym_fido_dev_make_cred(d, c, NULL);
|
r = sym_fido_dev_make_cred(d, c, NULL);
|
||||||
if (r == FIDO_ERR_PIN_REQUIRED) {
|
if (r == FIDO_ERR_PIN_REQUIRED) {
|
||||||
|
|
||||||
if (!has_client_pin)
|
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
|
||||||
"Token asks for PIN but doesn't advertise 'clientPin' feature.");
|
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
_cleanup_(strv_free_erasep) char **pin = NULL;
|
_cleanup_(strv_free_erasep) char **pin = NULL;
|
||||||
char **i;
|
char **i;
|
||||||
|
|
||||||
|
if (!has_client_pin)
|
||||||
|
log_warning("Weird, device asked for client PIN, but does not advertise it as feature. Ignoring.");
|
||||||
|
|
||||||
r = ask_password_auto("Please enter security token PIN:", askpw_icon_name, NULL, "fido2-pin", "fido2-pin", USEC_INFINITY, 0, &pin);
|
r = ask_password_auto("Please enter security token PIN:", askpw_icon_name, NULL, "fido2-pin", "fido2-pin", USEC_INFINITY, 0, &pin);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to acquire user PIN: %m");
|
return log_error_errno(r, "Failed to acquire user PIN: %m");
|
||||||
@ -801,75 +715,11 @@ int fido2_generate_hmac_hash(
|
|||||||
emoji_enabled() ? " " : "");
|
emoji_enabled() ? " " : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
r = sym_fido_dev_get_assert(d, a, FLAGS_SET(lock_with, FIDO2ENROLL_PIN) ? used_pin : NULL);
|
||||||
bool retry_with_up = false, retry_with_pin = false;
|
if (r == FIDO_ERR_UP_REQUIRED && !FLAGS_SET(lock_with, FIDO2ENROLL_UP))
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||||
r = sym_fido_dev_get_assert(d, a, FLAGS_SET(lock_with, FIDO2ENROLL_PIN) ? used_pin : NULL);
|
"Locking without user presence test requested, but FIDO2 device %s requires it.",
|
||||||
|
device);
|
||||||
switch (r) {
|
|
||||||
|
|
||||||
case FIDO_ERR_UP_REQUIRED:
|
|
||||||
/* If the token asks for "up" when we turn off, then this might be a feature that
|
|
||||||
* isn't optional. Let's enable it */
|
|
||||||
|
|
||||||
if (!has_up)
|
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
|
||||||
"Token asks for user presence check but doesn't advertise 'up' feature.");
|
|
||||||
|
|
||||||
if (FLAGS_SET(lock_with, FIDO2ENROLL_UP))
|
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
|
||||||
"Token asks for user presence check but was already enabled.");
|
|
||||||
|
|
||||||
log_notice("Locking without user presence test requested, but FIDO2 device %s requires it, enabling.", device);
|
|
||||||
retry_with_up = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FIDO_ERR_UNSUPPORTED_OPTION:
|
|
||||||
/* AuthenTrend ATKey.Pro says it supports "up", but if we disable it it will fail
|
|
||||||
* with FIDO_ERR_UNSUPPORTED_OPTION, probably because it isn't actually
|
|
||||||
* optional. Let's see if turning it on works. This is very similar to the
|
|
||||||
* FIDO_ERR_UP_REQUIRED case, but since the error is so vague we implement it
|
|
||||||
* slightly more defensively. */
|
|
||||||
|
|
||||||
if (has_up && !FLAGS_SET(lock_with, FIDO2ENROLL_UP)) {
|
|
||||||
log_notice("Got unsupported option error when when user presence test is turned off. Trying with user presence test turned on.");
|
|
||||||
retry_with_up = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FIDO_ERR_PIN_REQUIRED:
|
|
||||||
if (!has_client_pin)
|
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
|
||||||
"Token asks for client PIN check but doesn't advertise 'clientPin' feature.");
|
|
||||||
|
|
||||||
if (FLAGS_SET(lock_with, FIDO2ENROLL_PIN))
|
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
|
||||||
"Token asks for user client PIN check but was already enabled.");
|
|
||||||
|
|
||||||
log_debug("Token requires PIN for assertion, enabling.");
|
|
||||||
retry_with_pin = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!retry_with_up && !retry_with_pin)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (retry_with_up) {
|
|
||||||
r = sym_fido_assert_set_up(a, FIDO_OPT_TRUE);
|
|
||||||
if (r != FIDO_OK)
|
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to enable FIDO2 user presence test: %s", sym_fido_strerr(r));
|
|
||||||
|
|
||||||
lock_with |= FIDO2ENROLL_UP;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (retry_with_pin)
|
|
||||||
lock_with |= FIDO2ENROLL_PIN;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r == FIDO_ERR_ACTION_TIMEOUT)
|
if (r == FIDO_ERR_ACTION_TIMEOUT)
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(ENOSTR),
|
return log_error_errno(SYNTHETIC_ERRNO(ENOSTR),
|
||||||
"Token action timeout. (User didn't interact with token quickly enough.)");
|
"Token action timeout. (User didn't interact with token quickly enough.)");
|
||||||
@ -901,9 +751,6 @@ int fido2_generate_hmac_hash(
|
|||||||
if (ret_usedpin)
|
if (ret_usedpin)
|
||||||
*ret_usedpin = TAKE_PTR(used_pin);
|
*ret_usedpin = TAKE_PTR(used_pin);
|
||||||
|
|
||||||
if (ret_locked_with)
|
|
||||||
*ret_locked_with = lock_with;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -7,9 +7,6 @@ typedef enum Fido2EnrollFlags {
|
|||||||
FIDO2ENROLL_PIN = 1 << 0,
|
FIDO2ENROLL_PIN = 1 << 0,
|
||||||
FIDO2ENROLL_UP = 1 << 1, /* User presence (ie: touching token) */
|
FIDO2ENROLL_UP = 1 << 1, /* User presence (ie: touching token) */
|
||||||
FIDO2ENROLL_UV = 1 << 2, /* User verification (ie: fingerprint) */
|
FIDO2ENROLL_UV = 1 << 2, /* User verification (ie: fingerprint) */
|
||||||
FIDO2ENROLL_PIN_IF_NEEDED = 1 << 3, /* If auth doesn't work without PIN ask for one, as in systemd 248 */
|
|
||||||
FIDO2ENROLL_UP_IF_NEEDED = 1 << 4, /* If auth doesn't work without UP, enable it, as in systemd 248 */
|
|
||||||
FIDO2ENROLL_UV_OMIT = 1 << 5, /* Leave "uv" untouched, as in systemd 248 */
|
|
||||||
_FIDO2ENROLL_TYPE_MAX,
|
_FIDO2ENROLL_TYPE_MAX,
|
||||||
_FIDO2ENROLL_TYPE_INVALID = -EINVAL,
|
_FIDO2ENROLL_TYPE_INVALID = -EINVAL,
|
||||||
} Fido2EnrollFlags;
|
} Fido2EnrollFlags;
|
||||||
@ -109,8 +106,7 @@ int fido2_generate_hmac_hash(
|
|||||||
void **ret_cid, size_t *ret_cid_size,
|
void **ret_cid, size_t *ret_cid_size,
|
||||||
void **ret_salt, size_t *ret_salt_size,
|
void **ret_salt, size_t *ret_salt_size,
|
||||||
void **ret_secret, size_t *ret_secret_size,
|
void **ret_secret, size_t *ret_secret_size,
|
||||||
char **ret_usedpin,
|
char **ret_usedpin);
|
||||||
Fido2EnrollFlags *ret_locked_with);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@ -175,7 +175,7 @@ static void test_malloc_size_safe(void) {
|
|||||||
assert_se(malloc_usable_size(NULL) == 0); /* as per man page, this is safe and defined */
|
assert_se(malloc_usable_size(NULL) == 0); /* as per man page, this is safe and defined */
|
||||||
assert_se(__builtin_object_size(NULL, 0) == SIZE_MAX); /* as per docs SIZE_MAX is returned for pointers where the size isn't known */
|
assert_se(__builtin_object_size(NULL, 0) == SIZE_MAX); /* as per docs SIZE_MAX is returned for pointers where the size isn't known */
|
||||||
|
|
||||||
/* Then, let's try these macros once with constant size values, so that __builtin_object_size()
|
/* Then, let's try these macros once with contant size values, so that __builtin_object_size()
|
||||||
* definitely can work (as long as -O2 is used when compiling) */
|
* definitely can work (as long as -O2 is used when compiling) */
|
||||||
assert_se(f = new(uint32_t, n));
|
assert_se(f = new(uint32_t, n));
|
||||||
TEST_SIZES(f, n);
|
TEST_SIZES(f, n);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user