mirror of
https://github.com/kanidm/kanidm.git
synced 2025-02-23 12:37:00 +01:00
Expose TPM in more interface places (#2334)
This commit is contained in:
parent
e9ae132631
commit
060cb729a7
18
Cargo.lock
generated
18
Cargo.lock
generated
|
@ -1433,18 +1433,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "enum-map"
|
name = "enum-map"
|
||||||
version = "2.7.2"
|
version = "2.7.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "09e6b4f374c071b18172e23134e01026653dc980636ee139e0dfe59c538c61e5"
|
checksum = "6866f3bfdf8207509a033af1a75a7b08abda06bbaaeae6669323fd5a097df2e9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"enum-map-derive",
|
"enum-map-derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "enum-map-derive"
|
name = "enum-map-derive"
|
||||||
version = "0.16.0"
|
version = "0.17.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bfdb3d73d1beaf47c8593a1364e577fde072677cbfd103600345c0f547408cc0"
|
checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -1857,9 +1857,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gimli"
|
name = "gimli"
|
||||||
version = "0.28.0"
|
version = "0.28.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0"
|
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gix"
|
name = "gix"
|
||||||
|
@ -2994,11 +2994,12 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kanidm-hsm-crypto"
|
name = "kanidm-hsm-crypto"
|
||||||
version = "0.1.2"
|
version = "0.1.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fdc2a5dbe42b03b3e5e3f99eab1c5773032c8e508896691b3f4562c7de264d67"
|
checksum = "d325d5f7a3978ad1451f8bad2fdea1cc70a7b33dcaa8bbff7617a80d4c36c449"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"argon2",
|
"argon2",
|
||||||
|
"hex",
|
||||||
"openssl",
|
"openssl",
|
||||||
"serde",
|
"serde",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
@ -3175,6 +3176,7 @@ dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"clap",
|
"clap",
|
||||||
"clap_complete",
|
"clap_complete",
|
||||||
|
"compact_jwt 0.3.2",
|
||||||
"csv",
|
"csv",
|
||||||
"futures",
|
"futures",
|
||||||
"hashbrown 0.14.2",
|
"hashbrown 0.14.2",
|
||||||
|
|
|
@ -84,7 +84,7 @@ kanidmd_lib_macros = { path = "./server/lib-macros", version = "1.1.0-rc.15-dev"
|
||||||
kanidmd_testkit = { path = "./server/testkit", version = "1.1.0-rc.15-dev" }
|
kanidmd_testkit = { path = "./server/testkit", version = "1.1.0-rc.15-dev" }
|
||||||
kanidm_build_profiles = { path = "./libs/profiles", version = "1.1.0-rc.15-dev" }
|
kanidm_build_profiles = { path = "./libs/profiles", version = "1.1.0-rc.15-dev" }
|
||||||
kanidm_client = { path = "./libs/client", version = "1.1.0-rc.15-dev" }
|
kanidm_client = { path = "./libs/client", version = "1.1.0-rc.15-dev" }
|
||||||
kanidm-hsm-crypto = "^0.1.1"
|
kanidm-hsm-crypto = "^0.1.3"
|
||||||
kanidm_lib_crypto = { path = "./libs/crypto", version = "1.1.0-rc.15-dev" }
|
kanidm_lib_crypto = { path = "./libs/crypto", version = "1.1.0-rc.15-dev" }
|
||||||
kanidm_lib_file_permissions = { path = "./libs/file_permissions", version = "1.1.0-rc.15-dev" }
|
kanidm_lib_file_permissions = { path = "./libs/file_permissions", version = "1.1.0-rc.15-dev" }
|
||||||
kanidm_proto = { path = "./proto", version = "1.1.0-rc.15-dev" }
|
kanidm_proto = { path = "./proto", version = "1.1.0-rc.15-dev" }
|
||||||
|
@ -231,8 +231,6 @@ tracing = { version = "^0.1.40", features = [
|
||||||
tracing-subscriber = { version = "^0.3.18", features = ["env-filter"] }
|
tracing-subscriber = { version = "^0.3.18", features = ["env-filter"] }
|
||||||
tracing-forest = "^0.1.6"
|
tracing-forest = "^0.1.6"
|
||||||
|
|
||||||
tss-esapi = "^7.4.0"
|
|
||||||
|
|
||||||
url = "^2.4.1"
|
url = "^2.4.1"
|
||||||
urlencoding = "2.1.3"
|
urlencoding = "2.1.3"
|
||||||
utoipa = "4.1.0"
|
utoipa = "4.1.0"
|
||||||
|
|
|
@ -38,7 +38,7 @@ systemctl status kanidm-unixd-tasks
|
||||||
```
|
```
|
||||||
|
|
||||||
> **NOTE** The `kanidm_unixd_tasks` daemon is not required for PAM and nsswitch functionality. If
|
> **NOTE** The `kanidm_unixd_tasks` daemon is not required for PAM and nsswitch functionality. If
|
||||||
> disabled, your system will function as usual. It is, however, recommended due to the features it
|
> disabled, your system will function as usual. It is however strongly recommended due to the features it
|
||||||
> provides supporting Kanidm's capabilities.
|
> provides supporting Kanidm's capabilities.
|
||||||
|
|
||||||
Both unixd daemons use the connection configuration from /etc/kanidm/config. This is the covered in
|
Both unixd daemons use the connection configuration from /etc/kanidm/config. This is the covered in
|
||||||
|
@ -47,35 +47,9 @@ Both unixd daemons use the connection configuration from /etc/kanidm/config. Thi
|
||||||
You can also configure some unixd-specific options with the file /etc/kanidm/unixd:
|
You can also configure some unixd-specific options with the file /etc/kanidm/unixd:
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
pam_allowed_login_groups = ["posix_group"]
|
{{#rustdoc_include ../../examples/unixd}}
|
||||||
default_shell = "/bin/sh"
|
|
||||||
home_prefix = "/home/"
|
|
||||||
home_attr = "uuid"
|
|
||||||
home_alias = "spn"
|
|
||||||
use_etc_skel = false
|
|
||||||
uid_attr_map = "spn"
|
|
||||||
gid_attr_map = "spn"
|
|
||||||
selinux = true
|
|
||||||
allow_local_account_override = ["account_name"]
|
|
||||||
```
|
```
|
||||||
|
|
||||||
`pam_allowed_login_groups` defines a set of POSIX groups where membership of any of these groups
|
|
||||||
will be allowed to login via PAM. All POSIX users and groups can be resolved by nss regardless of
|
|
||||||
PAM login status. This may be a group name, spn, or uuid.
|
|
||||||
|
|
||||||
`default_shell` is the default shell for users. Defaults to `/bin/sh`.
|
|
||||||
|
|
||||||
`home_prefix` is the prepended path to where home directories are stored. Must end with a trailing
|
|
||||||
`/`. Defaults to `/home/`.
|
|
||||||
|
|
||||||
`home_attr` is the default token attribute used for the home directory path. Valid choices are
|
|
||||||
`uuid`, `name`, `spn`. Defaults to `uuid`.
|
|
||||||
|
|
||||||
`home_alias` is the default token attribute used for generating symlinks pointing to the user's home
|
|
||||||
directory. If set, this will become the value of the home path to nss calls. It is recommended you
|
|
||||||
choose a "human friendly" attribute here. Valid choices are `none`, `uuid`, `name`, `spn`. Defaults
|
|
||||||
to `spn`.
|
|
||||||
|
|
||||||
> **NOTICE:** All users in Kanidm can change their name (and their spn) at any time. If you change
|
> **NOTICE:** All users in Kanidm can change their name (and their spn) at any time. If you change
|
||||||
> `home_attr` from `uuid` you _must_ have a plan on how to manage these directory renames in your
|
> `home_attr` from `uuid` you _must_ have a plan on how to manage these directory renames in your
|
||||||
> system. We recommend that you have a stable ID (like the UUID), and symlinks from the name to the
|
> system. We recommend that you have a stable ID (like the UUID), and symlinks from the name to the
|
||||||
|
@ -85,27 +59,6 @@ to `spn`.
|
||||||
> **NOTE:** Ubuntu users please see:
|
> **NOTE:** Ubuntu users please see:
|
||||||
> [Why aren't snaps launching with home_alias set?](../frequently_asked_questions.md#why-arent-snaps-launching-with-home_alias-set)
|
> [Why aren't snaps launching with home_alias set?](../frequently_asked_questions.md#why-arent-snaps-launching-with-home_alias-set)
|
||||||
|
|
||||||
`use_etc_skel` controls if home directories should be prepopulated with the contents of `/etc/skel`
|
|
||||||
when first created. Defaults to false.
|
|
||||||
|
|
||||||
`uid_attr_map` chooses which attribute is used for domain local users in presentation. Defaults to
|
|
||||||
`spn`. Users from a trust will always use spn.
|
|
||||||
|
|
||||||
`gid_attr_map` chooses which attribute is used for domain local groups in presentation. Defaults to
|
|
||||||
`spn`. Groups from a trust will always use spn.
|
|
||||||
|
|
||||||
`selinux` controls whether the `kanidm_unixd_tasks` daemon should detect and enable SELinux runtime
|
|
||||||
compatibility features to ensure that newly created home directories are labeled correctly. This
|
|
||||||
setting as no bearing on systems without SELinux, as these features will automatically be disabled
|
|
||||||
if SELinux is not detected when the daemon starts. Note that `kanidm_unixd_tasks` must also be built
|
|
||||||
with the SELinux feature flag for this functionality. Defaults to true.
|
|
||||||
|
|
||||||
`allow_local_account_override` allows kanidm to "override" the content of a user or group that is
|
|
||||||
defined locally. By default kanidm will detect when a user/group conflict with their entries from
|
|
||||||
`/etc/passwd` or `/etc/group` and will ignore the kanidm entry. However if you want kanidm to
|
|
||||||
override users or groups from the local system, you must list them in this field. Note that this can
|
|
||||||
have many unexpected consequences, so it is not recommended to enable this.
|
|
||||||
|
|
||||||
You can then check the communication status of the daemon:
|
You can then check the communication status of the daemon:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|
111
examples/unixd
111
examples/unixd
|
@ -1,12 +1,117 @@
|
||||||
# this should be at /etc/kanidm/unixd, and configures kanidm-unixd
|
## Kanidm Unixd Service Configuration - /etc/kanidm/unixd
|
||||||
# some documentation is here: https://github.com/kanidm/kanidm/blob/master/book/src/pam_and_nsswitch.md
|
|
||||||
# pam_allowed_login_groups = ["posix_group"]
|
# Defines a set of POSIX groups where membership of any of these groups
|
||||||
|
# will be allowed to login via PAM. All POSIX users and groups can be
|
||||||
|
# resolved by nss regardless of PAM login status. This may be a group
|
||||||
|
# name, spn, or uuid.
|
||||||
|
#
|
||||||
|
# Default: empty set (no access allowed)
|
||||||
|
|
||||||
|
pam_allowed_login_groups = ["posix_group"]
|
||||||
|
|
||||||
|
# Kanidm unix will bind all cached credentials to a local Hardware Security
|
||||||
|
# Module (HSM) to prevent exfiltration and attacks against these. In addition,
|
||||||
|
# any internal private keys will also be stored in this HSM.
|
||||||
|
#
|
||||||
|
# * soft: A software hsm that encrypts all local key material
|
||||||
|
# * tpm: Use a tpm for all key storage and binding
|
||||||
|
#
|
||||||
|
# Default: soft
|
||||||
|
|
||||||
|
# hsm_type = "tpm"
|
||||||
|
|
||||||
|
|
||||||
|
# If using `hsm_type = "tpm"`, this allows configuration of the TCTI name of
|
||||||
|
# the tpm to use. For more, see: https://tpm2-tools.readthedocs.io/en/latest/man/common/tcti/
|
||||||
|
#
|
||||||
|
# You should leave this value as the default kernel resource manager.
|
||||||
|
#
|
||||||
|
# Default: device:/dev/tpmrm0
|
||||||
|
|
||||||
|
# tpm_tcti_name = "device:/dev/tpmrm0"
|
||||||
|
|
||||||
|
|
||||||
|
# Default shell for users if no value is set.
|
||||||
|
#
|
||||||
|
# Default: /bin/sh
|
||||||
|
|
||||||
# default_shell = "/bin/sh"
|
# default_shell = "/bin/sh"
|
||||||
|
|
||||||
|
|
||||||
|
# The prefix prepended to where home directories are stored. Must end with a trailing `/`.
|
||||||
|
#
|
||||||
|
# Default: /home/
|
||||||
|
|
||||||
# home_prefix = "/home/"
|
# home_prefix = "/home/"
|
||||||
|
|
||||||
|
|
||||||
|
# The attribute to use for the stable home directory path. Valid choices are
|
||||||
|
# `uuid`, `name`, `spn`.
|
||||||
|
|
||||||
|
# > **NOTICE:** All users in Kanidm can change their name (and their spn) at any time. If you change
|
||||||
|
# > `home_attr` from `uuid` you _must_ have a plan on how to manage these directory renames in your
|
||||||
|
# > system. We recommend that you have a stable ID (like the UUID), and symlinks from the name to the
|
||||||
|
# > UUID folder. Automatic support is provided for this via the unixd tasks daemon, as documented
|
||||||
|
# > here.
|
||||||
|
|
||||||
|
# Default: uuid
|
||||||
|
|
||||||
# home_attr = "uuid"
|
# home_attr = "uuid"
|
||||||
|
|
||||||
|
|
||||||
|
# The default token attribute used for generating symlinks pointing to the user's home
|
||||||
|
# directory. If set, this will become the value of the home path to nss calls. It is recommended you
|
||||||
|
# choose a "human friendly" attribute here. Valid choices are `none`, `uuid`, `name`, `spn`. Defaults
|
||||||
|
# to `spn`.
|
||||||
|
#
|
||||||
|
# Default: spn
|
||||||
|
|
||||||
# home_alias = "spn"
|
# home_alias = "spn"
|
||||||
|
|
||||||
|
|
||||||
|
# Controls if home directories should be prepopulated with the contents of `/etc/skel`
|
||||||
|
# when first created.
|
||||||
|
#
|
||||||
|
# Default: false
|
||||||
|
|
||||||
# use_etc_skel = false
|
# use_etc_skel = false
|
||||||
|
|
||||||
|
|
||||||
|
# Chooses which attribute is used for domain local users in presentation of the uid value.
|
||||||
|
#
|
||||||
|
# Default: spn
|
||||||
|
# NOTE: Users from a trust will always use spn.
|
||||||
|
|
||||||
# uid_attr_map = "spn"
|
# uid_attr_map = "spn"
|
||||||
|
|
||||||
|
|
||||||
|
# Chooses which attribute is used for domain local groups in presentation of the gid value.
|
||||||
|
|
||||||
|
# Default: spn
|
||||||
|
# NOTE: Groups from a trust will always use spn.
|
||||||
|
|
||||||
# gid_attr_map = "spn"
|
# gid_attr_map = "spn"
|
||||||
|
|
||||||
|
|
||||||
|
# `selinux` controls whether the `kanidm_unixd_tasks` daemon should detect and enable SELinux runtime
|
||||||
|
# compatibility features to ensure that newly created home directories are labeled correctly. This
|
||||||
|
# setting as no bearing on systems without SELinux, as these features will automatically be disabled
|
||||||
|
# if SELinux is not detected when the daemon starts. Note that `kanidm_unixd_tasks` must also be built
|
||||||
|
# with the SELinux feature flag for this functionality.
|
||||||
|
#
|
||||||
|
# Default: true
|
||||||
|
|
||||||
|
# selinux = true
|
||||||
|
|
||||||
|
|
||||||
|
# allows kanidm to "override" the content of a user or group that is defined locally when a name
|
||||||
|
# collision occurs. By default kanidm will detect when a user/group conflict with their entries from
|
||||||
|
# `/etc/passwd` or `/etc/group` and will ignore the kanidm entry. However if you want kanidm to
|
||||||
|
# override users or groups from the local system, you must list them in this field. Note that this can
|
||||||
|
# have many unexpected consequences, so it is not recommended to enable this.
|
||||||
|
#
|
||||||
|
# Default: Empty set (no overrides)
|
||||||
|
|
||||||
# allow_local_account_override = ["admin"]
|
# allow_local_account_override = ["admin"]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -55,10 +55,16 @@ const DS_SSHA512_HASH_LEN: usize = 64;
|
||||||
const ARGON2_VERSION: u32 = 19;
|
const ARGON2_VERSION: u32 = 19;
|
||||||
const ARGON2_SALT_LEN: usize = 16;
|
const ARGON2_SALT_LEN: usize = 16;
|
||||||
const ARGON2_KEY_LEN: usize = 32;
|
const ARGON2_KEY_LEN: usize = 32;
|
||||||
|
// Default amount of ram we sacrifice per thread is 8MB
|
||||||
const ARGON2_MIN_RAM_KIB: u32 = 8 * 1024;
|
const ARGON2_MIN_RAM_KIB: u32 = 8 * 1024;
|
||||||
const ARGON2_MAX_RAM_KIB: u32 = 32 * 1024;
|
// Max is 64MB. This may change in time.
|
||||||
|
const ARGON2_MAX_RAM_KIB: u32 = 64 * 1024;
|
||||||
|
// Amount of ram to subtract when we do a T cost iter. This
|
||||||
|
// is because t=2 m=32 == t=3 m=20. So we just step down a little
|
||||||
|
// to keep the value about the same.
|
||||||
|
const ARGON2_TCOST_RAM_ITER_KIB: u32 = 12 * 1024;
|
||||||
const ARGON2_MIN_T_COST: u32 = 2;
|
const ARGON2_MIN_T_COST: u32 = 2;
|
||||||
const ARGON2_MAX_T_COST: u32 = 4;
|
const ARGON2_MAX_T_COST: u32 = 16;
|
||||||
const ARGON2_MAX_P_COST: u32 = 1;
|
const ARGON2_MAX_P_COST: u32 = 1;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
@ -254,10 +260,7 @@ impl CryptoPolicy {
|
||||||
// thread x ram will be used. If we had 8 threads at 64mb of ram, that would require
|
// thread x ram will be used. If we had 8 threads at 64mb of ram, that would require
|
||||||
// 512mb of ram alone just for hashing. This becomes worse as core counts scale, with
|
// 512mb of ram alone just for hashing. This becomes worse as core counts scale, with
|
||||||
// 24 core xeons easily reaching 1.5GB in these cases.
|
// 24 core xeons easily reaching 1.5GB in these cases.
|
||||||
//
|
|
||||||
// To try to balance this we cap max ram at 32MB for now.
|
|
||||||
|
|
||||||
// Default amount of ram we sacrifice per thread is 8MB
|
|
||||||
let mut m_cost = ARGON2_MIN_RAM_KIB;
|
let mut m_cost = ARGON2_MIN_RAM_KIB;
|
||||||
let mut t_cost = ARGON2_MIN_T_COST;
|
let mut t_cost = ARGON2_MIN_T_COST;
|
||||||
let p_cost = ARGON2_MAX_P_COST;
|
let p_cost = ARGON2_MAX_P_COST;
|
||||||
|
@ -278,7 +281,7 @@ impl CryptoPolicy {
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(ubt) = Password::bench_argon2id(params) {
|
if let Some(ubt) = Password::bench_argon2id(params) {
|
||||||
trace!("{}µs - t_cost {} m_cost {}", ubt.as_nanos(), t_cost, m_cost);
|
debug!("{}µs - t_cost {} m_cost {}", ubt.as_nanos(), t_cost, m_cost);
|
||||||
// Parameter adjustment
|
// Parameter adjustment
|
||||||
if ubt < target_time {
|
if ubt < target_time {
|
||||||
if m_cost < ARGON2_MAX_RAM_KIB {
|
if m_cost < ARGON2_MAX_RAM_KIB {
|
||||||
|
@ -293,7 +296,7 @@ impl CryptoPolicy {
|
||||||
m_cost * 2
|
m_cost * 2
|
||||||
} else {
|
} else {
|
||||||
// Close! Increase in a small step
|
// Close! Increase in a small step
|
||||||
m_cost + (2 * 1024)
|
m_cost + 1024
|
||||||
};
|
};
|
||||||
|
|
||||||
m_cost = if m_adjust > ARGON2_MAX_RAM_KIB {
|
m_cost = if m_adjust > ARGON2_MAX_RAM_KIB {
|
||||||
|
@ -308,15 +311,20 @@ impl CryptoPolicy {
|
||||||
// here though, just to give a little window under that for adjustment.
|
// here though, just to give a little window under that for adjustment.
|
||||||
//
|
//
|
||||||
// Similar, once we hit t=4 we just need to have max ram.
|
// Similar, once we hit t=4 we just need to have max ram.
|
||||||
let m_adjust = (t_cost.saturating_sub(ARGON2_MIN_T_COST)
|
t_cost += 1;
|
||||||
* ARGON2_MIN_RAM_KIB)
|
// Halve the ram cost.
|
||||||
+ ARGON2_MAX_RAM_KIB;
|
let m_adjust = m_cost
|
||||||
|
.checked_sub(ARGON2_TCOST_RAM_ITER_KIB)
|
||||||
|
.unwrap_or(ARGON2_MIN_RAM_KIB);
|
||||||
|
|
||||||
|
// Floor and Ceil
|
||||||
m_cost = if m_adjust > ARGON2_MAX_RAM_KIB {
|
m_cost = if m_adjust > ARGON2_MAX_RAM_KIB {
|
||||||
ARGON2_MAX_RAM_KIB
|
ARGON2_MAX_RAM_KIB
|
||||||
|
} else if m_adjust < ARGON2_MIN_RAM_KIB {
|
||||||
|
ARGON2_MIN_RAM_KIB
|
||||||
} else {
|
} else {
|
||||||
m_adjust
|
m_adjust
|
||||||
};
|
};
|
||||||
t_cost += 1;
|
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
// Unable to proceed, parameters are maxed out.
|
// Unable to proceed, parameters are maxed out.
|
||||||
|
@ -1291,7 +1299,7 @@ mod tests {
|
||||||
let im_pw = "{ARGON2}$argon2id$v=19$m=65536,t=2,p=1$IyTQMsvzB2JHDiWx8fq7Ew$VhYOA7AL0kbRXI5g2kOyyp8St1epkNj7WZyUY4pAIQQ";
|
let im_pw = "{ARGON2}$argon2id$v=19$m=65536,t=2,p=1$IyTQMsvzB2JHDiWx8fq7Ew$VhYOA7AL0kbRXI5g2kOyyp8St1epkNj7WZyUY4pAIQQ";
|
||||||
let password = "password";
|
let password = "password";
|
||||||
let r = Password::try_from(im_pw).expect("Failed to parse");
|
let r = Password::try_from(im_pw).expect("Failed to parse");
|
||||||
assert!(r.requires_upgrade());
|
assert!(!r.requires_upgrade());
|
||||||
assert!(r.verify(password).unwrap_or(false));
|
assert!(r.verify(password).unwrap_or(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1363,7 +1371,7 @@ mod tests {
|
||||||
|
|
||||||
let mut hsm: Box<dyn Tpm> = Box::new(SoftTpm::new());
|
let mut hsm: Box<dyn Tpm> = Box::new(SoftTpm::new());
|
||||||
|
|
||||||
let auth_value = AuthValue::new_random().unwrap();
|
let auth_value = AuthValue::ephemeral().unwrap();
|
||||||
|
|
||||||
let loadable_machine_key = hsm.machine_key_create(&auth_value).unwrap();
|
let loadable_machine_key = hsm.machine_key_create(&auth_value).unwrap();
|
||||||
let machine_key = hsm
|
let machine_key = hsm
|
||||||
|
|
|
@ -13,10 +13,15 @@ SupplementaryGroups=tss
|
||||||
UMask=0027
|
UMask=0027
|
||||||
CacheDirectory=kanidm-unixd
|
CacheDirectory=kanidm-unixd
|
||||||
RuntimeDirectory=kanidm-unixd
|
RuntimeDirectory=kanidm-unixd
|
||||||
|
StateDirectory=kanidm-unixd
|
||||||
|
|
||||||
Type=simple
|
Type=simple
|
||||||
ExecStart=/usr/sbin/kanidm_unixd
|
ExecStart=/usr/sbin/kanidm_unixd
|
||||||
|
|
||||||
|
## If you wish to setup an external HSM pin you should set:
|
||||||
|
# LoadCredential=hsmpin:/etc/kanidm/kanidm-unixd-hsm-pin
|
||||||
|
# Environment=KANIDM_HSM_PIN_PATH=%d/hsmpin
|
||||||
|
|
||||||
# Implied by dynamic user.
|
# Implied by dynamic user.
|
||||||
# ProtectHome=
|
# ProtectHome=
|
||||||
# ProtectSystem=strict
|
# ProtectSystem=strict
|
||||||
|
|
|
@ -57,6 +57,7 @@ base64urlsafedata = { workspace = true }
|
||||||
bytes = { workspace = true }
|
bytes = { workspace = true }
|
||||||
clap = { workspace = true, features = ["derive", "env"] }
|
clap = { workspace = true, features = ["derive", "env"] }
|
||||||
csv = { workspace = true }
|
csv = { workspace = true }
|
||||||
|
compact_jwt = { workspace = true, features = ["hsm-crypto"] }
|
||||||
futures = { workspace = true }
|
futures = { workspace = true }
|
||||||
hashbrown = { workspace = true }
|
hashbrown = { workspace = true }
|
||||||
libc = { workspace = true }
|
libc = { workspace = true }
|
||||||
|
|
|
@ -15,4 +15,4 @@ pub const DEFAULT_UID_ATTR_MAP: UidAttr = UidAttr::Spn;
|
||||||
pub const DEFAULT_GID_ATTR_MAP: UidAttr = UidAttr::Spn;
|
pub const DEFAULT_GID_ATTR_MAP: UidAttr = UidAttr::Spn;
|
||||||
pub const DEFAULT_SELINUX: bool = true;
|
pub const DEFAULT_SELINUX: bool = true;
|
||||||
pub const DEFAULT_TPM_TCTI_NAME: &str = "device:/dev/tpmrm0";
|
pub const DEFAULT_TPM_TCTI_NAME: &str = "device:/dev/tpmrm0";
|
||||||
pub const DEFAULT_HSM_PIN_PATH: &str = "/etc/kanidm/unixd-hsm-pin";
|
pub const DEFAULT_HSM_PIN_PATH: &str = "/var/lib/kanidm-unixd/hsm-pin";
|
||||||
|
|
|
@ -439,7 +439,6 @@ async fn process_etc_passwd_group(
|
||||||
|
|
||||||
async fn read_hsm_pin(hsm_pin_path: &str) -> Result<Vec<u8>, Box<dyn Error>> {
|
async fn read_hsm_pin(hsm_pin_path: &str) -> Result<Vec<u8>, Box<dyn Error>> {
|
||||||
if !PathBuf::from_str(hsm_pin_path)?.exists() {
|
if !PathBuf::from_str(hsm_pin_path)?.exists() {
|
||||||
// TODO generate the file by default
|
|
||||||
return Err(std::io::Error::new(
|
return Err(std::io::Error::new(
|
||||||
std::io::ErrorKind::NotFound,
|
std::io::ErrorKind::NotFound,
|
||||||
format!("HSM PIN file '{}' not found", hsm_pin_path),
|
format!("HSM PIN file '{}' not found", hsm_pin_path),
|
||||||
|
@ -453,6 +452,21 @@ async fn read_hsm_pin(hsm_pin_path: &str) -> Result<Vec<u8>, Box<dyn Error>> {
|
||||||
Ok(contents)
|
Ok(contents)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn write_hsm_pin(hsm_pin_path: &str) -> Result<(), Box<dyn Error>> {
|
||||||
|
if !PathBuf::from_str(hsm_pin_path)?.exists() {
|
||||||
|
let new_pin = AuthValue::generate().map_err(|hsm_err| {
|
||||||
|
error!(?hsm_err, "Unable to generate new pin");
|
||||||
|
std::io::Error::new(std::io::ErrorKind::Other, "Unable to generate new pin")
|
||||||
|
})?;
|
||||||
|
|
||||||
|
std::fs::write(hsm_pin_path, new_pin)?;
|
||||||
|
|
||||||
|
info!("Generated new HSM pin");
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::main(flavor = "current_thread")]
|
#[tokio::main(flavor = "current_thread")]
|
||||||
async fn main() -> ExitCode {
|
async fn main() -> ExitCode {
|
||||||
let cuid = get_current_uid();
|
let cuid = get_current_uid();
|
||||||
|
@ -652,8 +666,8 @@ async fn main() -> ExitCode {
|
||||||
.to_str()
|
.to_str()
|
||||||
.unwrap_or("<db_parent_path invalid>")
|
.unwrap_or("<db_parent_path invalid>")
|
||||||
);
|
);
|
||||||
let diag = kanidm_lib_file_permissions::diagnose_path(db_path.as_ref());
|
let diag = kanidm_lib_file_permissions::diagnose_path(db_path.as_ref());
|
||||||
info!(%diag);
|
info!(%diag);
|
||||||
return ExitCode::FAILURE
|
return ExitCode::FAILURE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -702,8 +716,8 @@ async fn main() -> ExitCode {
|
||||||
"Refusing to run - DB path {} already exists and is not a file.",
|
"Refusing to run - DB path {} already exists and is not a file.",
|
||||||
db_path.to_str().unwrap_or("<db_path invalid>")
|
db_path.to_str().unwrap_or("<db_path invalid>")
|
||||||
);
|
);
|
||||||
let diag = kanidm_lib_file_permissions::diagnose_path(db_path.as_ref());
|
let diag = kanidm_lib_file_permissions::diagnose_path(db_path.as_ref());
|
||||||
info!(%diag);
|
info!(%diag);
|
||||||
return ExitCode::FAILURE
|
return ExitCode::FAILURE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -715,8 +729,8 @@ async fn main() -> ExitCode {
|
||||||
db_path.to_str().unwrap_or("<db_path invalid>"),
|
db_path.to_str().unwrap_or("<db_path invalid>"),
|
||||||
e
|
e
|
||||||
);
|
);
|
||||||
let diag = kanidm_lib_file_permissions::diagnose_path(db_path.as_ref());
|
let diag = kanidm_lib_file_permissions::diagnose_path(db_path.as_ref());
|
||||||
info!(%diag);
|
info!(%diag);
|
||||||
return ExitCode::FAILURE
|
return ExitCode::FAILURE
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -744,6 +758,22 @@ async fn main() -> ExitCode {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// perform any db migrations.
|
||||||
|
let mut dbtxn = db.write().await;
|
||||||
|
if dbtxn.migrate()
|
||||||
|
.and_then(|_| {
|
||||||
|
dbtxn.commit()
|
||||||
|
}).is_err() {
|
||||||
|
error!("Failed to migrate database");
|
||||||
|
return ExitCode::FAILURE
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for and create the hsm pin if required.
|
||||||
|
if let Err(err) = write_hsm_pin(cfg.hsm_pin_path.as_str()).await {
|
||||||
|
error!(?err, "Failed to create HSM PIN into {}", cfg.hsm_pin_path.as_str());
|
||||||
|
return ExitCode::FAILURE
|
||||||
|
};
|
||||||
|
|
||||||
// read the hsm pin
|
// read the hsm pin
|
||||||
let hsm_pin = match read_hsm_pin(cfg.hsm_pin_path.as_str()).await {
|
let hsm_pin = match read_hsm_pin(cfg.hsm_pin_path.as_str()).await {
|
||||||
Ok(hp) => hp,
|
Ok(hp) => hp,
|
||||||
|
@ -802,7 +832,8 @@ async fn main() -> ExitCode {
|
||||||
let machine_key = match hsm.machine_key_load(&auth_value, &loadable_machine_key) {
|
let machine_key = match hsm.machine_key_load(&auth_value, &loadable_machine_key) {
|
||||||
Ok(mk) => mk,
|
Ok(mk) => mk,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!(?err, "Unable to load machine key");
|
error!(?err, "Unable to load machine root key - This can occur if you have changed your HSM pin");
|
||||||
|
error!("To proceed you must remove the content of the cache db ({}) to reset all keys", cfg.db_path.as_str());
|
||||||
return ExitCode::FAILURE
|
return ExitCode::FAILURE
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1238,7 +1238,7 @@ mod tests {
|
||||||
#[cfg(not(feature = "tpm"))]
|
#[cfg(not(feature = "tpm"))]
|
||||||
let mut hsm: Box<dyn Tpm> = Box::new(SoftTpm::new());
|
let mut hsm: Box<dyn Tpm> = Box::new(SoftTpm::new());
|
||||||
|
|
||||||
let auth_value = AuthValue::new_random().unwrap();
|
let auth_value = AuthValue::ephemeral().unwrap();
|
||||||
|
|
||||||
let loadable_machine_key = hsm.machine_key_create(&auth_value).unwrap();
|
let loadable_machine_key = hsm.machine_key_create(&auth_value).unwrap();
|
||||||
let machine_key = hsm
|
let machine_key = hsm
|
||||||
|
|
|
@ -104,18 +104,34 @@ pub trait IdProvider {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn provider_authenticate(&self) -> Result<(), IdpError>;
|
/// This is similar to a "domain join" process. What do we actually need to pass here
|
||||||
|
/// for this to work for kanidm or himmelblau? Should we make it take a generic?
|
||||||
|
/*
|
||||||
|
async fn configure_machine_identity<D: KeyStoreTxn + Send>(
|
||||||
|
&self,
|
||||||
|
_keystore: &mut D,
|
||||||
|
_tpm: &mut (dyn tpm::Tpm + Send),
|
||||||
|
_machine_key: &tpm::MachineKey,
|
||||||
|
) -> Result<(), IdpError> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
async fn provider_authenticate(&self, _tpm: &mut (dyn tpm::Tpm + Send))
|
||||||
|
-> Result<(), IdpError>;
|
||||||
|
|
||||||
async fn unix_user_get(
|
async fn unix_user_get(
|
||||||
&self,
|
&self,
|
||||||
_id: &Id,
|
_id: &Id,
|
||||||
_token: Option<&UserToken>,
|
_token: Option<&UserToken>,
|
||||||
|
_tpm: &mut (dyn tpm::Tpm + Send),
|
||||||
) -> Result<UserToken, IdpError>;
|
) -> Result<UserToken, IdpError>;
|
||||||
|
|
||||||
async fn unix_user_online_auth_init(
|
async fn unix_user_online_auth_init(
|
||||||
&self,
|
&self,
|
||||||
_account_id: &str,
|
_account_id: &str,
|
||||||
_token: Option<&UserToken>,
|
_token: Option<&UserToken>,
|
||||||
|
_tpm: &mut (dyn tpm::Tpm + Send),
|
||||||
) -> Result<(AuthRequest, AuthCredHandler), IdpError>;
|
) -> Result<(AuthRequest, AuthCredHandler), IdpError>;
|
||||||
|
|
||||||
async fn unix_user_online_auth_step(
|
async fn unix_user_online_auth_step(
|
||||||
|
@ -123,6 +139,7 @@ pub trait IdProvider {
|
||||||
_account_id: &str,
|
_account_id: &str,
|
||||||
_cred_handler: &mut AuthCredHandler,
|
_cred_handler: &mut AuthCredHandler,
|
||||||
_pam_next_req: PamAuthRequest,
|
_pam_next_req: PamAuthRequest,
|
||||||
|
_tpm: &mut (dyn tpm::Tpm + Send),
|
||||||
) -> Result<(AuthResult, AuthCacheAction), IdpError>;
|
) -> Result<(AuthResult, AuthCacheAction), IdpError>;
|
||||||
|
|
||||||
async fn unix_user_offline_auth_init(
|
async fn unix_user_offline_auth_init(
|
||||||
|
@ -155,5 +172,9 @@ pub trait IdProvider {
|
||||||
) -> Result<AuthResult, IdpError>;
|
) -> Result<AuthResult, IdpError>;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
async fn unix_group_get(&self, id: &Id) -> Result<GroupToken, IdpError>;
|
async fn unix_group_get(
|
||||||
|
&self,
|
||||||
|
id: &Id,
|
||||||
|
_tpm: &mut (dyn tpm::Tpm + Send),
|
||||||
|
) -> Result<GroupToken, IdpError>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,7 +115,10 @@ impl IdProvider for KanidmProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Needs .read on all types except re-auth.
|
// Needs .read on all types except re-auth.
|
||||||
async fn provider_authenticate(&self) -> Result<(), IdpError> {
|
async fn provider_authenticate(
|
||||||
|
&self,
|
||||||
|
_tpm: &mut (dyn tpm::Tpm + Send),
|
||||||
|
) -> Result<(), IdpError> {
|
||||||
match self.client.write().await.auth_anonymous().await {
|
match self.client.write().await.auth_anonymous().await {
|
||||||
Ok(_uat) => Ok(()),
|
Ok(_uat) => Ok(()),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
@ -129,6 +132,7 @@ impl IdProvider for KanidmProvider {
|
||||||
&self,
|
&self,
|
||||||
id: &Id,
|
id: &Id,
|
||||||
_token: Option<&UserToken>,
|
_token: Option<&UserToken>,
|
||||||
|
_tpm: &mut (dyn tpm::Tpm + Send),
|
||||||
) -> Result<UserToken, IdpError> {
|
) -> Result<UserToken, IdpError> {
|
||||||
match self
|
match self
|
||||||
.client
|
.client
|
||||||
|
@ -191,6 +195,7 @@ impl IdProvider for KanidmProvider {
|
||||||
&self,
|
&self,
|
||||||
_account_id: &str,
|
_account_id: &str,
|
||||||
_token: Option<&UserToken>,
|
_token: Option<&UserToken>,
|
||||||
|
_tpm: &mut (dyn tpm::Tpm + Send),
|
||||||
) -> Result<(AuthRequest, AuthCredHandler), IdpError> {
|
) -> Result<(AuthRequest, AuthCredHandler), IdpError> {
|
||||||
// Not sure that I need to do much here?
|
// Not sure that I need to do much here?
|
||||||
Ok((AuthRequest::Password, AuthCredHandler::Password))
|
Ok((AuthRequest::Password, AuthCredHandler::Password))
|
||||||
|
@ -201,6 +206,7 @@ impl IdProvider for KanidmProvider {
|
||||||
account_id: &str,
|
account_id: &str,
|
||||||
cred_handler: &mut AuthCredHandler,
|
cred_handler: &mut AuthCredHandler,
|
||||||
pam_next_req: PamAuthRequest,
|
pam_next_req: PamAuthRequest,
|
||||||
|
_tpm: &mut (dyn tpm::Tpm + Send),
|
||||||
) -> Result<(AuthResult, AuthCacheAction), IdpError> {
|
) -> Result<(AuthResult, AuthCacheAction), IdpError> {
|
||||||
match (cred_handler, pam_next_req) {
|
match (cred_handler, pam_next_req) {
|
||||||
(AuthCredHandler::Password, PamAuthRequest::Password { cred }) => {
|
(AuthCredHandler::Password, PamAuthRequest::Password { cred }) => {
|
||||||
|
@ -303,7 +309,11 @@ impl IdProvider for KanidmProvider {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
async fn unix_group_get(&self, id: &Id) -> Result<GroupToken, IdpError> {
|
async fn unix_group_get(
|
||||||
|
&self,
|
||||||
|
id: &Id,
|
||||||
|
_tpm: &mut (dyn tpm::Tpm + Send),
|
||||||
|
) -> Result<GroupToken, IdpError> {
|
||||||
match self
|
match self
|
||||||
.client
|
.client
|
||||||
.read()
|
.read()
|
||||||
|
|
|
@ -110,11 +110,6 @@ where
|
||||||
let hsm = Mutex::new(hsm);
|
let hsm = Mutex::new(hsm);
|
||||||
let mut hsm_lock = hsm.lock().await;
|
let mut hsm_lock = hsm.lock().await;
|
||||||
|
|
||||||
// setup and do a migrate.
|
|
||||||
let mut dbtxn = db.write().await;
|
|
||||||
dbtxn.migrate().map_err(|_| ())?;
|
|
||||||
dbtxn.commit().map_err(|_| ())?;
|
|
||||||
|
|
||||||
// Setup our internal keys
|
// Setup our internal keys
|
||||||
let mut dbtxn = db.write().await;
|
let mut dbtxn = db.write().await;
|
||||||
|
|
||||||
|
@ -477,7 +472,16 @@ where
|
||||||
account_id: &Id,
|
account_id: &Id,
|
||||||
token: Option<UserToken>,
|
token: Option<UserToken>,
|
||||||
) -> Result<Option<UserToken>, ()> {
|
) -> Result<Option<UserToken>, ()> {
|
||||||
match self.client.unix_user_get(account_id, token.as_ref()).await {
|
let mut hsm_lock = self.hsm.lock().await;
|
||||||
|
|
||||||
|
let user_get_result = self
|
||||||
|
.client
|
||||||
|
.unix_user_get(account_id, token.as_ref(), &mut **hsm_lock.deref_mut())
|
||||||
|
.await;
|
||||||
|
|
||||||
|
drop(hsm_lock);
|
||||||
|
|
||||||
|
match user_get_result {
|
||||||
Ok(mut n_tok) => {
|
Ok(mut n_tok) => {
|
||||||
if self.check_nxset(&n_tok.name, n_tok.gidnumber).await {
|
if self.check_nxset(&n_tok.name, n_tok.gidnumber).await {
|
||||||
// Refuse to release the token, it's in the denied set.
|
// Refuse to release the token, it's in the denied set.
|
||||||
|
@ -527,7 +531,16 @@ where
|
||||||
grp_id: &Id,
|
grp_id: &Id,
|
||||||
token: Option<GroupToken>,
|
token: Option<GroupToken>,
|
||||||
) -> Result<Option<GroupToken>, ()> {
|
) -> Result<Option<GroupToken>, ()> {
|
||||||
match self.client.unix_group_get(grp_id).await {
|
let mut hsm_lock = self.hsm.lock().await;
|
||||||
|
|
||||||
|
let group_get_result = self
|
||||||
|
.client
|
||||||
|
.unix_group_get(grp_id, &mut **hsm_lock.deref_mut())
|
||||||
|
.await;
|
||||||
|
|
||||||
|
drop(hsm_lock);
|
||||||
|
|
||||||
|
match group_get_result {
|
||||||
Ok(n_tok) => {
|
Ok(n_tok) => {
|
||||||
if self.check_nxset(&n_tok.name, n_tok.gidnumber).await {
|
if self.check_nxset(&n_tok.name, n_tok.gidnumber).await {
|
||||||
// Refuse to release the token, it's in the denied set.
|
// Refuse to release the token, it's in the denied set.
|
||||||
|
@ -863,8 +876,9 @@ where
|
||||||
};
|
};
|
||||||
|
|
||||||
let maybe_err = if online_at_init {
|
let maybe_err = if online_at_init {
|
||||||
|
let mut hsm_lock = self.hsm.lock().await;
|
||||||
self.client
|
self.client
|
||||||
.unix_user_online_auth_init(account_id, token.as_ref())
|
.unix_user_online_auth_init(account_id, token.as_ref(), &mut **hsm_lock.deref_mut())
|
||||||
.await
|
.await
|
||||||
} else {
|
} else {
|
||||||
// Can the auth proceed offline?
|
// Can the auth proceed offline?
|
||||||
|
@ -919,11 +933,20 @@ where
|
||||||
},
|
},
|
||||||
CacheState::Online,
|
CacheState::Online,
|
||||||
) => {
|
) => {
|
||||||
|
let mut hsm_lock = self.hsm.lock().await;
|
||||||
|
|
||||||
let maybe_cache_action = self
|
let maybe_cache_action = self
|
||||||
.client
|
.client
|
||||||
.unix_user_online_auth_step(account_id, cred_handler, pam_next_req)
|
.unix_user_online_auth_step(
|
||||||
|
account_id,
|
||||||
|
cred_handler,
|
||||||
|
pam_next_req,
|
||||||
|
&mut **hsm_lock.deref_mut(),
|
||||||
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
|
drop(hsm_lock);
|
||||||
|
|
||||||
match maybe_cache_action {
|
match maybe_cache_action {
|
||||||
Ok((res, AuthCacheAction::None)) => Ok(res),
|
Ok((res, AuthCacheAction::None)) => Ok(res),
|
||||||
Ok((
|
Ok((
|
||||||
|
@ -1120,7 +1143,16 @@ where
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
CacheState::OfflineNextCheck(_time) => {
|
CacheState::OfflineNextCheck(_time) => {
|
||||||
match self.client.provider_authenticate().await {
|
let mut hsm_lock = self.hsm.lock().await;
|
||||||
|
|
||||||
|
let prov_auth_result = self
|
||||||
|
.client
|
||||||
|
.provider_authenticate(&mut **hsm_lock.deref_mut())
|
||||||
|
.await;
|
||||||
|
|
||||||
|
drop(hsm_lock);
|
||||||
|
|
||||||
|
match prov_auth_result {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
debug!("OfflineNextCheck -> authenticated");
|
debug!("OfflineNextCheck -> authenticated");
|
||||||
self.set_cachestate(CacheState::Online).await;
|
self.set_cachestate(CacheState::Online).await;
|
||||||
|
|
|
@ -10,7 +10,7 @@ use kanidm_unix_common::constants::{
|
||||||
DEFAULT_GID_ATTR_MAP, DEFAULT_HOME_ALIAS, DEFAULT_HOME_ATTR, DEFAULT_HOME_PREFIX,
|
DEFAULT_GID_ATTR_MAP, DEFAULT_HOME_ALIAS, DEFAULT_HOME_ATTR, DEFAULT_HOME_PREFIX,
|
||||||
DEFAULT_SHELL, DEFAULT_UID_ATTR_MAP,
|
DEFAULT_SHELL, DEFAULT_UID_ATTR_MAP,
|
||||||
};
|
};
|
||||||
use kanidm_unix_common::db::Db;
|
use kanidm_unix_common::db::{Cache, CacheTxn, Db};
|
||||||
use kanidm_unix_common::idprovider::interface::Id;
|
use kanidm_unix_common::idprovider::interface::Id;
|
||||||
use kanidm_unix_common::idprovider::kanidm::KanidmProvider;
|
use kanidm_unix_common::idprovider::kanidm::KanidmProvider;
|
||||||
use kanidm_unix_common::resolver::Resolver;
|
use kanidm_unix_common::resolver::Resolver;
|
||||||
|
@ -103,9 +103,15 @@ async fn setup_test(fix_fn: Fixture) -> (Resolver<KanidmProvider>, KanidmClient)
|
||||||
)
|
)
|
||||||
.expect("Failed to setup DB");
|
.expect("Failed to setup DB");
|
||||||
|
|
||||||
|
let mut dbtxn = db.write().await;
|
||||||
|
dbtxn
|
||||||
|
.migrate()
|
||||||
|
.and_then(|_| dbtxn.commit())
|
||||||
|
.expect("Unable to migrate cache db");
|
||||||
|
|
||||||
let mut hsm: Box<dyn Tpm + Send> = Box::new(SoftTpm::new());
|
let mut hsm: Box<dyn Tpm + Send> = Box::new(SoftTpm::new());
|
||||||
|
|
||||||
let auth_value = AuthValue::new_random().unwrap();
|
let auth_value = AuthValue::ephemeral().unwrap();
|
||||||
|
|
||||||
let loadable_machine_key = hsm.machine_key_create(&auth_value).unwrap();
|
let loadable_machine_key = hsm.machine_key_create(&auth_value).unwrap();
|
||||||
let machine_key = hsm
|
let machine_key = hsm
|
||||||
|
|
Loading…
Reference in a new issue