1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-22 13:34:15 +03:00

Isolate hsm auth value from the cache

Signed-off-by: David Mulder <dmulder@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>
This commit is contained in:
David Mulder 2024-08-05 12:57:12 -06:00
parent abcf7644a9
commit 948d0fcfe1
11 changed files with 92 additions and 30 deletions

View File

@ -19,4 +19,5 @@ echo "
<!ENTITY pathconfig.SAMBA_DATADIR '\${prefix}/var/samba'> <!ENTITY pathconfig.SAMBA_DATADIR '\${prefix}/var/samba'>
<!ENTITY pathconfig.CTDB_DATADIR '\${prefix}/share/ctdb'> <!ENTITY pathconfig.CTDB_DATADIR '\${prefix}/share/ctdb'>
<!ENTITY pathconfig.CONFIGFILE '\${prefix}/etc/smb.conf'> <!ENTITY pathconfig.CONFIGFILE '\${prefix}/etc/smb.conf'>
<!ENTITY pathconfig.HIMMELBLAUD_HSM_PIN_PATH '\${prefix}/var/lib/himmelblaud/hsm-pin'>
" "

View File

@ -0,0 +1,13 @@
<samba:parameter name="himmelblaud hsm pin path"
context="G"
type="string"
xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
<description>
<para>Specifies the file path where the HSM PIN is stored. This PIN is used
for unlocking TPM objects required for Azure Entra ID authentication. The HSM
PIN is critical for ensuring secure communication and authentication within
the Himmelblaud daemon.</para>
</description>
<value type="default">&pathconfig.HIMMELBLAUD_HSM_PIN_PATH;</value>
</samba:parameter>

View File

@ -107,3 +107,4 @@ DEFINE_DYN_CONFIG_PARAM(NTP_SIGND_SOCKET_DIR)
DEFINE_DYN_CONFIG_PARAM(PYTHONDIR) DEFINE_DYN_CONFIG_PARAM(PYTHONDIR)
DEFINE_DYN_CONFIG_PARAM(PYTHONARCHDIR) DEFINE_DYN_CONFIG_PARAM(PYTHONARCHDIR)
DEFINE_DYN_CONFIG_PARAM(SCRIPTSBINDIR) DEFINE_DYN_CONFIG_PARAM(SCRIPTSBINDIR)
DEFINE_DYN_CONFIG_PARAM(HIMMELBLAUD_HSM_PIN_PATH)

View File

@ -58,3 +58,4 @@ DEFINE_DYN_CONFIG_PROTO(NTP_SIGND_SOCKET_DIR)
DEFINE_DYN_CONFIG_PROTO(PYTHONDIR) DEFINE_DYN_CONFIG_PROTO(PYTHONDIR)
DEFINE_DYN_CONFIG_PROTO(PYTHONARCHDIR) DEFINE_DYN_CONFIG_PROTO(PYTHONARCHDIR)
DEFINE_DYN_CONFIG_PROTO(SCRIPTSBINDIR) DEFINE_DYN_CONFIG_PROTO(SCRIPTSBINDIR)
DEFINE_DYN_CONFIG_PROTO(HIMMELBLAUD_HSM_PIN_PATH)

View File

@ -285,6 +285,13 @@ dynconfig = {
'HELPTEXT': 'Where to put the smbpasswd file', 'HELPTEXT': 'Where to put the smbpasswd file',
'DELAY': True, 'DELAY': True,
}, },
'HIMMELBLAUD_HSM_PIN_PATH': {
'STD-PATH': '${LOCALSTATEDIR}/lib/himmelblaud/hsm-pin',
'FHS-PATH': '${LOCALSTATEDIR}/lib/himmelblaud/hsm-pin',
'OPTION': '--with-himmelblaud-hsm-pin-path',
'HELPTEXT': 'Where to store the hsm pin',
'DELAY': True,
},
} }
def options(opt): def options(opt):

View File

@ -3166,6 +3166,9 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
"AD DC only"); "AD DC only");
/* Set the default Himmelblaud globals */ /* Set the default Himmelblaud globals */
lpcfg_do_global_parameter(lp_ctx,
"himmelblaud hsm pin path",
get_dyn_HIMMELBLAUD_HSM_PIN_PATH());
lpcfg_do_global_parameter(lp_ctx, lpcfg_do_global_parameter(lp_ctx,
"himmelblaud hello enabled", "himmelblaud hello enabled",
"false"); "false");

View File

@ -404,32 +404,6 @@ impl PrivateCache {
}) })
} }
pub(crate) fn hsm_pin_fetch_or_create(
&mut self,
) -> Result<AuthValue, Box<NTSTATUS>> {
let hsm_pin = match self.cache.fetch_str("auth_value") {
Some(hsm_pin) => hsm_pin,
None => {
let auth_str = match AuthValue::generate() {
Ok(auth_str) => auth_str,
Err(e) => {
DBG_ERR!("Failed to create hsm pin: {:?}", e);
return Err(Box::new(NT_STATUS_UNSUCCESSFUL));
}
};
self.cache.store_bytes("auth_value", auth_str.as_bytes())?;
auth_str
}
};
match AuthValue::try_from(hsm_pin.as_bytes()) {
Ok(auth_value) => Ok(auth_value),
Err(e) => {
DBG_ERR!("Invalid hsm pin: {:?}", e);
return Err(Box::new(NT_STATUS_UNSUCCESSFUL));
}
}
}
pub(crate) fn loadable_machine_key_fetch_or_create( pub(crate) fn loadable_machine_key_fetch_or_create(
&mut self, &mut self,
hsm: &mut BoxedDynTpm, hsm: &mut BoxedDynTpm,

View File

@ -200,13 +200,21 @@ async fn main() -> ExitCode {
}; };
// Check for and create the hsm pin if required. // Check for and create the hsm pin if required.
let auth_value = match pcache.hsm_pin_fetch_or_create() { let hsm_pin_path = match lp.himmelblaud_hsm_pin_path() {
Ok(auth_value) => auth_value, Ok(Some(hsm_pin_path)) => hsm_pin_path,
Err(e) => { _ => {
DBG_ERR!("{:?}", e); DBG_ERR!("Failed loading hsm pin path.");
return ExitCode::FAILURE; return ExitCode::FAILURE;
} }
}; };
let auth_value =
match utils::hsm_pin_fetch_or_create(&hsm_pin_path).await {
Ok(auth_value) => auth_value,
Err(e) => {
DBG_ERR!("{:?}", e);
return ExitCode::FAILURE;
}
};
// Setup the HSM and its machine key // Setup the HSM and its machine key
let mut hsm: BoxedDynTpm = BoxedDynTpm::new(SoftTpm::new()); let mut hsm: BoxedDynTpm = BoxedDynTpm::new(SoftTpm::new());

View File

@ -18,7 +18,13 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
use dbg::{DBG_ERR, DBG_INFO};
use kanidm_hsm_crypto::AuthValue;
use ntstatus_gen::*; use ntstatus_gen::*;
use std::path::PathBuf;
use std::str::FromStr;
use tokio::fs::File;
use tokio::io::AsyncReadExt;
pub fn split_username( pub fn split_username(
username: &str, username: &str,
@ -29,3 +35,47 @@ pub fn split_username(
} }
Err(Box::new(NT_STATUS_INVALID_USER_PRINCIPAL_NAME)) Err(Box::new(NT_STATUS_INVALID_USER_PRINCIPAL_NAME))
} }
pub(crate) async fn hsm_pin_fetch_or_create(
hsm_pin_path: &str,
) -> Result<AuthValue, Box<NTSTATUS>> {
let auth_value = if !PathBuf::from_str(hsm_pin_path)
.map_err(|e| {
DBG_ERR!("Failed to create hsm pin: {:?}", e);
Box::new(NT_STATUS_UNSUCCESSFUL)
})?
.exists()
{
let auth_value = AuthValue::generate().map_err(|e| {
DBG_ERR!("Failed to create hsm pin: {:?}", e);
Box::new(NT_STATUS_UNSUCCESSFUL)
})?;
std::fs::write(hsm_pin_path, auth_value.clone()).map_err(|e| {
DBG_ERR!("Failed to write hsm pin: {:?}", e);
Box::new(NT_STATUS_UNSUCCESSFUL)
})?;
DBG_INFO!("Generated new HSM pin");
auth_value
} else {
let mut file = File::open(hsm_pin_path).await.map_err(|e| {
DBG_ERR!("Failed to read hsm pin: {:?}", e);
Box::new(NT_STATUS_UNSUCCESSFUL)
})?;
let mut auth_value = vec![];
file.read_to_end(&mut auth_value).await.map_err(|e| {
DBG_ERR!("Failed to read hsm pin: {:?}", e);
Box::new(NT_STATUS_UNSUCCESSFUL)
})?;
std::str::from_utf8(&auth_value)
.map_err(|e| {
DBG_ERR!("Failed to read hsm pin: {:?}", e);
Box::new(NT_STATUS_UNSUCCESSFUL)
})?
.to_string()
};
AuthValue::try_from(auth_value.as_bytes()).map_err(|e| {
DBG_ERR!("Invalid hsm pin: {:?}", e);
Box::new(NT_STATUS_UNSUCCESSFUL)
})
}

View File

@ -202,6 +202,7 @@ impl LoadParm {
lpcfg_str!(cache_directory); lpcfg_str!(cache_directory);
lpcfg_str!(template_homedir); lpcfg_str!(template_homedir);
lpcfg_str!(template_shell); lpcfg_str!(template_shell);
lpcfg_str!(himmelblaud_hsm_pin_path);
} }
unsafe impl Send for LoadParm {} unsafe impl Send for LoadParm {}

View File

@ -1005,6 +1005,9 @@ void loadparm_s3_init_globals(struct loadparm_context *lp_ctx,
Globals.acl_claims_evaluation = ACL_CLAIMS_EVALUATION_AD_DC_ONLY; Globals.acl_claims_evaluation = ACL_CLAIMS_EVALUATION_AD_DC_ONLY;
/* Set the default Himmelblaud globals */ /* Set the default Himmelblaud globals */
lpcfg_string_set(Globals.ctx,
&Globals.himmelblaud_hsm_pin_path,
get_dyn_HIMMELBLAUD_HSM_PIN_PATH());
Globals.himmelblaud_hello_enabled = false; Globals.himmelblaud_hello_enabled = false;
Globals.himmelblaud_sfa_fallback = false; Globals.himmelblaud_sfa_fallback = false;