]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
Isolate hsm auth value from the cache
authorDavid Mulder <dmulder@samba.org>
Mon, 5 Aug 2024 18:57:12 +0000 (12:57 -0600)
committerDavid Mulder <dmulder@samba.org>
Wed, 23 Oct 2024 14:21:33 +0000 (14:21 +0000)
Signed-off-by: David Mulder <dmulder@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>
docs-xml/generate-pathconf-entities.sh
docs-xml/smbdotconf/himmelblaud/himmelblaudhsmpinpath.xml [new file with mode: 0644]
dynconfig/dynconfig.c
dynconfig/dynconfig.h
dynconfig/wscript
lib/param/loadparm.c
rust/himmelblaud/src/cache.rs
rust/himmelblaud/src/main.rs
rust/himmelblaud/src/utils.rs
rust/param/src/lib.rs
source3/param/loadparm.c

index 1b689a8a23f26060f1b0e9c51ac7bcba17569129..8d39c5034c066942826c6c5360aa6f39454d4052 100755 (executable)
@@ -19,4 +19,5 @@ echo "
 <!ENTITY pathconfig.SAMBA_DATADIR        '\${prefix}/var/samba'>
 <!ENTITY pathconfig.CTDB_DATADIR         '\${prefix}/share/ctdb'>
 <!ENTITY pathconfig.CONFIGFILE           '\${prefix}/etc/smb.conf'>
+<!ENTITY pathconfig.HIMMELBLAUD_HSM_PIN_PATH '\${prefix}/var/lib/himmelblaud/hsm-pin'>
 "
diff --git a/docs-xml/smbdotconf/himmelblaud/himmelblaudhsmpinpath.xml b/docs-xml/smbdotconf/himmelblaud/himmelblaudhsmpinpath.xml
new file mode 100644 (file)
index 0000000..8727127
--- /dev/null
@@ -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>
index 415ccc53c5257a92d796774b924388bfe0c2ea7e..69de711c4de718c32aa173e6523fc9b44964b89c 100644 (file)
@@ -107,3 +107,4 @@ DEFINE_DYN_CONFIG_PARAM(NTP_SIGND_SOCKET_DIR)
 DEFINE_DYN_CONFIG_PARAM(PYTHONDIR)
 DEFINE_DYN_CONFIG_PARAM(PYTHONARCHDIR)
 DEFINE_DYN_CONFIG_PARAM(SCRIPTSBINDIR)
+DEFINE_DYN_CONFIG_PARAM(HIMMELBLAUD_HSM_PIN_PATH)
index 72028a8c2e10eb975d94814dc718de5e94b2ff47..d06636de82727ea975756d4d4fe655f45539dab7 100644 (file)
@@ -58,3 +58,4 @@ DEFINE_DYN_CONFIG_PROTO(NTP_SIGND_SOCKET_DIR)
 DEFINE_DYN_CONFIG_PROTO(PYTHONDIR)
 DEFINE_DYN_CONFIG_PROTO(PYTHONARCHDIR)
 DEFINE_DYN_CONFIG_PROTO(SCRIPTSBINDIR)
+DEFINE_DYN_CONFIG_PROTO(HIMMELBLAUD_HSM_PIN_PATH)
index a784dac4e6cdd810629772ec4de8a991154b365e..c338fd348888c7987e0539552bec2afd6833ce34 100644 (file)
@@ -285,6 +285,13 @@ dynconfig = {
          'HELPTEXT':  'Where to put the smbpasswd file',
          '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):
index 01c8df0ed70aef4cb17492c40a9ab099f1a54f31..db434e6626266858fee0f83b534f8d15d39a221e 100644 (file)
@@ -3166,6 +3166,9 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
                                  "AD DC only");
 
        /* 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,
                                  "himmelblaud hello enabled",
                                  "false");
index 51047044939e8b242252bf1de0c4ce671553d365..ad1e44c9c5cf9005e6933132a0f2db02fd495f75 100644 (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(
         &mut self,
         hsm: &mut BoxedDynTpm,
index 81cfeca493ff9214097b3d7ade5b8e27290aac66..5b1f2a1917e83dc8b95b990eeb06675067542028 100644 (file)
@@ -200,13 +200,21 @@ async fn main() -> ExitCode {
         };
 
         // Check for and create the hsm pin if required.
-        let auth_value = match pcache.hsm_pin_fetch_or_create() {
-            Ok(auth_value) => auth_value,
-            Err(e) => {
-                DBG_ERR!("{:?}", e);
+        let hsm_pin_path = match lp.himmelblaud_hsm_pin_path() {
+            Ok(Some(hsm_pin_path)) => hsm_pin_path,
+            _ => {
+                DBG_ERR!("Failed loading hsm pin path.");
                 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
         let mut hsm: BoxedDynTpm = BoxedDynTpm::new(SoftTpm::new());
index 932232eaec78c9fdbf3487926f9246d102bc86c2..ff0fcb4e2db312c32b5aa1b0502e55988f71b086 100644 (file)
    You should have received a copy of the GNU General Public License
    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 std::path::PathBuf;
+use std::str::FromStr;
+use tokio::fs::File;
+use tokio::io::AsyncReadExt;
 
 pub fn split_username(
     username: &str,
@@ -29,3 +35,47 @@ pub fn split_username(
     }
     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)
+    })
+}
index 7b4bcaf53254d1600ced359b09c6c3425abc806d..1632a2ed758d7873b40aafc42486d74526d59483 100644 (file)
@@ -202,6 +202,7 @@ impl LoadParm {
     lpcfg_str!(cache_directory);
     lpcfg_str!(template_homedir);
     lpcfg_str!(template_shell);
+    lpcfg_str!(himmelblaud_hsm_pin_path);
 }
 
 unsafe impl Send for LoadParm {}
index ae23d22f40192f8a3b1412bbe89a25433fc66afc..6a0f7321017ea6f372f4a2c955ff4829aaf8e991 100644 (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;
 
        /* 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_sfa_fallback = false;