@@ -204,14 +204,17 @@ pub fn clevis_info_from_metadata(
204204 pin_dispatch ( & subjson, CLEVIS_RECURSION_LIMIT ) . map ( Some )
205205}
206206
207- /// Returns true if the Tang config has a thumbprint or an advertisement
208- /// or all Tang configs in the nested sss config have thumbprints or
209- /// advertisements.
210- fn all_tang_configs_have_url_trust_info (
207+ fn traverse_clevis_config < T > (
211208 pin : & str ,
212209 clevis_config : & Value ,
213210 recursion_limit : u64 ,
214- ) -> StratisResult < bool > {
211+ tang_func : & dyn Fn ( & Map < String , Value > ) -> StratisResult < T > ,
212+ tpm2_func : & dyn Fn ( & Map < String , Value > ) -> StratisResult < T > ,
213+ sss : & mut ( & T , & mut dyn FnMut ( T , T ) -> StratisResult < T > ) ,
214+ ) -> StratisResult < T >
215+ where
216+ T : Clone ,
217+ {
215218 if recursion_limit == 0 {
216219 return Err ( StratisError :: Msg (
217220 "Reached the recursion limit for parsing nested SSS tokens" . to_string ( ) ,
@@ -220,14 +223,7 @@ fn all_tang_configs_have_url_trust_info(
220223
221224 if pin == "tang" {
222225 if let Some ( obj) = clevis_config. as_object ( ) {
223- Ok ( obj
224- . get ( "thp" )
225- . map ( |val| val. as_str ( ) . is_some ( ) )
226- . or_else ( || {
227- obj. get ( "adv" )
228- . map ( |val| val. as_str ( ) . is_some ( ) || val. as_object ( ) . is_some ( ) )
229- } )
230- . unwrap_or ( false ) )
226+ tang_func ( obj)
231227 } else {
232228 Err ( StratisError :: Msg ( format ! (
233229 "configuration for Clevis is is not in JSON object format: {clevis_config}"
@@ -236,14 +232,16 @@ fn all_tang_configs_have_url_trust_info(
236232 } else if pin == "sss" {
237233 if let Some ( obj) = clevis_config. as_object ( ) {
238234 if let Some ( obj) = obj. get ( "pins" ) . and_then ( |val| val. as_object ( ) ) {
239- obj. iter ( ) . try_fold ( true , |b, ( pin, config) | {
240- Ok (
241- b && all_tang_configs_have_url_trust_info (
242- pin,
243- config,
244- recursion_limit - 1 ,
245- ) ?,
246- )
235+ obj. iter ( ) . try_fold ( sss. 0 . clone ( ) , |acc, ( pin, config) | {
236+ let res = traverse_clevis_config (
237+ pin,
238+ config,
239+ recursion_limit - 1 ,
240+ tang_func,
241+ tpm2_func,
242+ sss,
243+ ) ?;
244+ sss. 1 ( acc, res)
247245 } )
248246 } else {
249247 Err ( StratisError :: Msg (
@@ -256,12 +254,45 @@ fn all_tang_configs_have_url_trust_info(
256254 ) ) )
257255 }
258256 } else if pin == "tpm2" {
259- Ok ( true )
257+ if let Some ( obj) = clevis_config. as_object ( ) {
258+ tpm2_func ( obj)
259+ } else {
260+ Err ( StratisError :: Msg ( format ! (
261+ "configuration for Clevis is is not in JSON object format: {clevis_config}"
262+ ) ) )
263+ }
260264 } else {
261265 Err ( StratisError :: Msg ( format ! ( "Unrecognized pin {pin}" ) ) )
262266 }
263267}
264268
269+ /// Returns true if the Tang config has a thumbprint or an advertisement
270+ /// or all Tang configs in the nested sss config have thumbprints or
271+ /// advertisements.
272+ fn all_tang_configs_have_url_trust_info (
273+ pin : & str ,
274+ clevis_config : & Value ,
275+ recursion_limit : u64 ,
276+ ) -> StratisResult < bool > {
277+ traverse_clevis_config (
278+ pin,
279+ clevis_config,
280+ recursion_limit,
281+ & |obj| {
282+ Ok ( obj
283+ . get ( "thp" )
284+ . map ( |val| val. as_str ( ) . is_some ( ) )
285+ . or_else ( || {
286+ obj. get ( "adv" )
287+ . map ( |val| val. as_str ( ) . is_some ( ) || val. as_object ( ) . is_some ( ) )
288+ } )
289+ . unwrap_or ( false ) )
290+ } ,
291+ & |_| Ok ( true ) ,
292+ & mut ( & true , & mut |acc, premise| Ok ( acc && premise) ) ,
293+ )
294+ }
295+
265296/// Interpret non-Clevis keys that may contain additional information about
266297/// how to configure Clevis when binding. Remove any expected non-Clevis keys
267298/// from the configuration.
0 commit comments