@@ -19,12 +19,12 @@ pub(crate) use bootstrap::{
1919use super :: UNIX_O_NOFOLLOW ;
2020use super :: {
2121 AcmeAccountCredentialsPath , AcmeAccountStoreError , AcmeMutationLock ,
22- MAX_ACCOUNT_CREDENTIALS_BYTES , managed_certificate_segment, unique_transaction_id,
22+ MAX_ACCOUNT_CREDENTIALS_BYTES , managed_certificate_segment, reject_pending_account_bootstrap,
23+ reject_pending_account_deactivation, reject_pending_account_mutation, unique_transaction_id,
2324} ;
2425
2526const ACME_ACCOUNT_DIR : & str = "accounts" ;
2627const ACME_ACCOUNT_CREDENTIALS_FILE : & str = "credentials.json" ;
27- const ACME_ACCOUNT_DEACTIVATION_FILE : & str = ".credentials.deactivation.pending" ;
2828
2929#[ cfg( feature = "acme-client" ) ]
3030pub ( crate ) enum AccountStoreAttempt < T > {
@@ -120,29 +120,9 @@ fn load_account_credentials_locked(
120120 directory : & Path ,
121121 allow_bootstrap_recovery : bool ,
122122) -> Result < Option < instant_acme:: AccountCredentials > , AcmeAccountStoreError > {
123- let pending = directory. join ( ACME_ACCOUNT_DEACTIVATION_FILE ) ;
124- if pending
125- . try_exists ( )
126- . map_err ( |error| account_store_io_error ( & pending, error) ) ?
127- {
128- return Err ( AcmeAccountStoreError :: UnsafePath {
129- path : pending,
130- message : "account deactivation is in an ambiguous pending state; operator recovery is required"
131- . to_owned ( ) ,
132- } ) ;
133- }
134- let bootstrap_pending = directory. join ( ".credentials.bootstrap.pending" ) ;
135- if !allow_bootstrap_recovery
136- && bootstrap_pending
137- . try_exists ( )
138- . map_err ( |error| account_store_io_error ( & bootstrap_pending, error) ) ?
139- {
140- return Err ( AcmeAccountStoreError :: UnsafePath {
141- path : bootstrap_pending,
142- message :
143- "account bootstrap is pending; recovery must complete before credentials are used"
144- . to_owned ( ) ,
145- } ) ;
123+ reject_pending_account_deactivation ( directory) ?;
124+ if !allow_bootstrap_recovery {
125+ reject_pending_account_bootstrap ( directory) ?;
146126 }
147127 let metadata = match fs:: symlink_metadata ( path) {
148128 Ok ( metadata) => metadata,
@@ -243,7 +223,7 @@ fn begin_account_deactivation_locked(
243223 lock : AcmeMutationLock ,
244224) -> Result < AccountDeactivationTransaction , AcmeAccountStoreError > {
245225 ensure_safe_account_destination ( & active) ?;
246- let pending = directory. join ( ACME_ACCOUNT_DEACTIVATION_FILE ) ;
226+ let pending = directory. join ( super :: acme_account_state :: ACCOUNT_DEACTIVATION_PENDING_FILE ) ;
247227 match fs:: symlink_metadata ( & pending) {
248228 Ok ( _) => {
249229 return Err ( AcmeAccountStoreError :: UnsafePath {
@@ -305,17 +285,7 @@ pub fn store_account_credentials(
305285 ensure_safe_account_directory ( directory) ?;
306286 let _mutation_lock = AcmeMutationLock :: acquire ( directory)
307287 . map_err ( |error| account_store_io_error ( & directory. join ( ".fluxheim-acme.lock" ) , error) ) ?;
308- let bootstrap_pending = directory. join ( ".credentials.bootstrap.pending" ) ;
309- if bootstrap_pending
310- . try_exists ( )
311- . map_err ( |error| account_store_io_error ( & bootstrap_pending, error) ) ?
312- {
313- return Err ( AcmeAccountStoreError :: UnsafePath {
314- path : bootstrap_pending,
315- message : "account bootstrap is pending; credentials must be promoted by the bootstrap transaction"
316- . to_owned ( ) ,
317- } ) ;
318- }
288+ reject_pending_account_mutation ( directory) ?;
319289 store_account_credentials_locked ( & credentials_path, directory, credentials)
320290}
321291
@@ -379,6 +349,7 @@ pub fn remove_account_credentials(
379349 ensure_safe_account_directory ( directory) ?;
380350 let _mutation_lock = AcmeMutationLock :: acquire ( directory)
381351 . map_err ( |error| account_store_io_error ( & directory. join ( ".fluxheim-acme.lock" ) , error) ) ?;
352+ reject_pending_account_mutation ( directory) ?;
382353 ensure_safe_account_destination ( & credentials_path. path ) ?;
383354 match fs:: remove_file ( & credentials_path. path ) {
384355 Ok ( ( ) ) => {
0 commit comments