@@ -4,8 +4,7 @@ use serde::de::DeserializeOwned;
44use std:: {
55 ffi:: OsStr ,
66 fmt:: Display ,
7- fs:: { self , OpenOptions } ,
8- io:: { self , Write } ,
7+ fs, io,
98 path:: { Path , PathBuf } ,
109 str:: FromStr ,
1110} ;
@@ -483,32 +482,11 @@ impl Args {
483482 . insert ( network_passphrase. into ( ) , contract_id. to_string ( ) ) ;
484483
485484 let content = serde_json:: to_string ( & data) ?;
485+ write_hardened_file ( & path, content. as_bytes ( ) ) ?;
486486
487487 #[ cfg( unix) ]
488- {
489- use std:: io:: Write as _;
490- use std:: os:: unix:: fs:: OpenOptionsExt ;
491- let mut to_file = OpenOptions :: new ( )
492- . create ( true )
493- . truncate ( true )
494- . write ( true )
495- . mode ( 0o600 )
496- . open ( & path) ?;
497- to_file. write_all ( content. as_bytes ( ) ) ?;
498- set_hardened_permissions ( & path) ?;
499- if let Ok ( root) = self . config_dir ( ) {
500- fix_config_permissions ( root) ;
501- }
502- }
503-
504- #[ cfg( not( unix) ) ]
505- {
506- let mut to_file = OpenOptions :: new ( )
507- . create ( true )
508- . truncate ( true )
509- . write ( true )
510- . open ( path) ?;
511- to_file. write_all ( content. as_bytes ( ) ) ?;
488+ if let Ok ( root) = self . config_dir ( ) {
489+ fix_config_permissions ( root) ;
512490 }
513491
514492 Ok ( ( ) )
@@ -524,17 +502,11 @@ impl Args {
524502 let content = fs:: read_to_string ( & path) . unwrap_or_default ( ) ;
525503 let mut data: alias:: Data = serde_json:: from_str ( & content) . unwrap_or_default ( ) ;
526504
527- let mut to_file = OpenOptions :: new ( )
528- . create ( true )
529- . truncate ( true )
530- . write ( true )
531- . open ( path) ?;
532-
533505 data. ids . remove :: < str > ( network_passphrase) ;
534506
535507 let content = serde_json:: to_string ( & data) ?;
536-
537- Ok ( to_file . write_all ( content . as_bytes ( ) ) ? )
508+ write_hardened_file ( & path , content . as_bytes ( ) ) ? ;
509+ Ok ( ( ) )
538510 }
539511
540512 pub fn get_contract_id (
@@ -662,6 +634,31 @@ pub(crate) fn set_hardened_permissions(path: &Path) -> io::Result<()> {
662634 Ok ( ( ) )
663635}
664636
637+ /// Writes `contents` to `path`, creating the file with `0600` on Unix and
638+ /// resetting the mode to exactly `0600` afterwards regardless of any
639+ /// pre-existing permissions. Falls back to `std::fs::write` on non-Unix
640+ /// platforms.
641+ pub ( crate ) fn write_hardened_file ( path : & Path , contents : & [ u8 ] ) -> io:: Result < ( ) > {
642+ #[ cfg( unix) ]
643+ {
644+ use std:: io:: Write as _;
645+ use std:: os:: unix:: fs:: OpenOptionsExt ;
646+ let mut file = std:: fs:: OpenOptions :: new ( )
647+ . write ( true )
648+ . create ( true )
649+ . truncate ( true )
650+ . mode ( 0o600 )
651+ . open ( path) ?;
652+ file. write_all ( contents) ?;
653+ set_hardened_permissions ( path) ?;
654+ }
655+
656+ #[ cfg( not( unix) ) ]
657+ std:: fs:: write ( path, contents) ?;
658+
659+ Ok ( ( ) )
660+ }
661+
665662pub fn ensure_directory ( dir : PathBuf ) -> Result < PathBuf , Error > {
666663 let parent = dir. parent ( ) . ok_or ( Error :: HomeDirNotFound ) ?;
667664
@@ -757,41 +754,15 @@ impl KeyType {
757754 ) -> Result < PathBuf , Error > {
758755 let filepath = ensure_directory ( self . path ( pwd, key) ) ?;
759756 let data = toml:: to_string ( value) . map_err ( |_| Error :: ConfigSerialization ) ?;
760- #[ cfg( unix) ]
761- {
762- use std:: io:: Write as _;
763- use std:: os:: unix:: fs:: OpenOptionsExt ;
764- let mut file = std:: fs:: OpenOptions :: new ( )
765- . write ( true )
766- . create ( true )
767- . truncate ( true )
768- . mode ( 0o600 )
769- . open ( & filepath)
770- . map_err ( |error| Error :: IdCreationFailed {
771- filepath : filepath. clone ( ) ,
772- error,
773- } ) ?;
774- file. write_all ( data. as_bytes ( ) )
775- . map_err ( |error| Error :: IdCreationFailed {
776- filepath : filepath. clone ( ) ,
777- error,
778- } ) ?;
779- }
780-
781- #[ cfg( not( unix) ) ]
782- std:: fs:: write ( & filepath, data) . map_err ( |error| Error :: IdCreationFailed {
783- filepath : filepath. clone ( ) ,
784- error,
757+ write_hardened_file ( & filepath, data. as_bytes ( ) ) . map_err ( |error| {
758+ Error :: IdCreationFailed {
759+ filepath : filepath. clone ( ) ,
760+ error,
761+ }
785762 } ) ?;
786763
787764 #[ cfg( unix) ]
788- {
789- set_hardened_permissions ( & filepath) . map_err ( |error| Error :: IdCreationFailed {
790- filepath : filepath. clone ( ) ,
791- error,
792- } ) ?;
793- fix_config_permissions ( pwd. to_path_buf ( ) ) ;
794- }
765+ fix_config_permissions ( pwd. to_path_buf ( ) ) ;
795766
796767 Ok ( filepath)
797768 }
0 commit comments