PageRenderTime 46ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/zuluCrypt-cli/bin/save_and_restore_volume_header.c

https://gitlab.com/m.schmidt/zuluCrypt
C | 703 lines | 485 code | 120 blank | 98 comment | 104 complexity | cf0d48fd5ca7667fe14a9bf0928393b4 MD5 | raw file
Possible License(s): BSD-3-Clause-No-Nuclear-License-2014, BSD-2-Clause
  1. /*
  2. *
  3. * Copyright (c) 2012-2015
  4. * name : Francis Banyikwa
  5. * email: mhogomchungu@gmail.com
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "includes.h"
  20. #include "../lib/includes.h"
  21. #include <libcryptsetup.h>
  22. #include <sys/syscall.h>
  23. #include <errno.h>
  24. #include <sys/mman.h>
  25. #include <libintl.h>
  26. #include <locale.h>
  27. #include <stdio.h>
  28. #include <sys/stat.h>
  29. #include <fcntl.h>
  30. #include <unistd.h>
  31. #include "truecrypt_support_1.h"
  32. #define SIZE 512
  33. #define ignore_result( x ) if( x ){;}
  34. static int zuluExit( int st,const char * dev )
  35. {
  36. switch( st ){
  37. case 0 : printf( gettext( "SUCCESS: Header saved successfully\n" ) ) ; break ;
  38. case 1 : printf( gettext( "SUCCESS: Header restored successfully\n" ) ) ; break ;
  39. case 2 : printf( gettext( "ERROR: Presented device is not a LUKS device\n" ) ) ; break ;
  40. case 3 : printf( gettext( "ERROR: Failed to perform requested operation\n" ) ) ; break ;
  41. case 4 : printf( gettext( "ERROR: Failed to perform requested operation\n" ) ) ; break ;
  42. case 5 : printf( gettext( "INFO: Operation terminater per user request\n" ) ) ; break ;
  43. case 6 : printf( gettext( "ERROR: Path to be used to create a back up file is occupied or permission denied\n" ) ); break ;
  44. case 7 : printf( gettext( "ERROR: Failed to perform requested operation\n" ) ) ; break ;
  45. case 8 : printf( gettext( "ERROR: Insufficient privilege to open backup header file for reading\n" ) ) ; break ;
  46. case 9 : printf( gettext( "ERROR: Invalid path to back up header file\n" ) ) ; break ;
  47. case 10: printf( gettext( "ERROR: Insufficient privilege to create a backup header in a destination folder\n" )); break ;
  48. case 11: printf( gettext( "ERROR: Invalid path to device\n" ) ) ; break ;
  49. case 12: printf( gettext( "ERROR: Argument for path to a backup header file is missing\n" ) ) ; break ;
  50. case 13: printf( gettext( "ERROR: Argument for path to a backup header file is missing\n" ) ) ; break ;
  51. case 14: printf( gettext( "ERROR: Only root and \"zulucrypt\" group members can restore and back up luks headers on system devices\n" ) ); break ;
  52. case 15: printf( gettext( "ERROR: Insufficient privilege to open device for writing\n" ) ) ; break ;
  53. case 16: printf( gettext( "ERROR: Could not resolve path to device\n" ) ) ; break ;
  54. case 17: printf( gettext( "ERROR: Backup file does not appear to contain luks header\n" ) ) ; break ;
  55. case 18: printf( gettext( "ERROR: Insufficient privilege to open device for reading\n" ) ) ; break ;
  56. case 19: printf( gettext( "ERROR: Insufficient memory to hold your responce\n" ) ) ; break ;
  57. case 20: printf( gettext( "ERROR: Wrong password entered or volume is not a truecrypt volume\n" ) ) ; break ;
  58. }
  59. StringFree( dev ) ;
  60. if( st == 1 ){
  61. return 0 ;
  62. }else{
  63. return st ;
  64. }
  65. }
  66. /*
  67. * This place is a bit involving and an explanation seem to be the least i can do.
  68. *
  69. * We do not want cryptsetup and tcplay to access file paths a normal can modify for security
  70. * reasons and hence we copy user provided files to "/run/zuluCrypt" folder and then
  71. * pass these copied files to cryptsetup or tcplay.This happens when we are restoring
  72. * header files.
  73. *
  74. * When we are taking header backups,we let these tools create the header backups in
  75. * "/run/zuluCrypt" and then we copied these created header files from "/run/zuluCrypt"
  76. * to where the normal user expect them to be.
  77. *
  78. * normal user should zero access to "/run/zuluCrypt" path.
  79. */
  80. /*
  81. * Below function creates a secured folder path,ie a folder path a normal user has no access to
  82. */
  83. static string_t _create_work_directory( void )
  84. {
  85. /*
  86. * ZULUCRYPTtempFolder and ZULUCRYPtmountMiniPath are set in ../constants.h
  87. */
  88. const char * temp_path = "/run/zuluCrypt/" ;
  89. struct stat xt ;
  90. mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH | S_IROTH ;
  91. zuluCryptSecurityGainElevatedPrivileges() ;
  92. #define path_does_not_exist( x ) stat( x,&xt ) != 0
  93. if( path_does_not_exist( "/run" ) ){
  94. mkdir( "/run",mode ) ;
  95. ignore_result( chown( "/run",0,0 ) ) ;
  96. }
  97. if( path_does_not_exist( temp_path ) ){
  98. mkdir( temp_path,S_IRWXU ) ;
  99. ignore_result( chown( temp_path,0,0 ) ) ;
  100. }
  101. zuluCryptSecurityDropElevatedPrivileges() ;
  102. return String( temp_path ) ;
  103. }
  104. /*
  105. * Below function copies a file owned and managed by a user to a secured location so that it can be accessed securely.
  106. */
  107. static int _secure_file_path( const char ** path,const char * source )
  108. {
  109. int fd_source ;
  110. int fd_temp ;
  111. char buffer[ SIZE ] ;
  112. size_t len ;
  113. const char * temp_path ;
  114. struct stat ststr ;
  115. string_t st_path = _create_work_directory() ;
  116. StringAppend( st_path,"0-" ) ;
  117. temp_path = StringAppendInt( st_path,syscall( SYS_gettid ) ) ;
  118. zuluCryptSecurityDropElevatedPrivileges() ;
  119. fd_source = open( source,O_RDONLY ) ;
  120. if( fd_source == -1 ){
  121. StringDelete( &st_path ) ;
  122. return 0 ;
  123. }
  124. fstat( fd_source,&ststr ) ;
  125. if( ststr.st_size >= 3145728 ){
  126. /*
  127. * headers are less than 3MB so we obvious have a wrong file
  128. */
  129. StringDelete( &st_path ) ;
  130. return 0 ;
  131. }
  132. zuluCryptSecurityGainElevatedPrivileges() ;
  133. fd_temp = open( temp_path,O_WRONLY | O_CREAT,S_IRUSR | S_IWUSR | S_IRGRP |S_IROTH ) ;
  134. if( fd_temp == -1 ){
  135. close( fd_source ) ;
  136. StringDelete( &st_path ) ;
  137. return 0 ;
  138. }
  139. while( 1 ){
  140. len = read( fd_source,buffer,SIZE ) ;
  141. if( len < SIZE ){
  142. ignore_result( write( fd_temp,buffer,len ) ) ;
  143. break ;
  144. }else{
  145. ignore_result( write( fd_temp,buffer,len ) ) ;
  146. }
  147. }
  148. close( fd_source ) ;
  149. close( fd_temp ) ;
  150. zuluCryptSecurityDropElevatedPrivileges() ;
  151. *path = StringDeleteHandle( &st_path ) ;
  152. return 1 ;
  153. }
  154. /*
  155. * this function return a secured file path to be used to create a file at the path
  156. */
  157. static const char * _secure_file_path_1( void )
  158. {
  159. string_t st_path = _create_work_directory() ;
  160. StringAppend( st_path,"1-" ) ;
  161. StringAppendInt( st_path,syscall( SYS_gettid ) ) ;
  162. return StringDeleteHandle( &st_path ) ;
  163. }
  164. /*
  165. * Below function copies a secured file from secured location to a user owned and managed location.
  166. * The source file will be deleted when the copy is done.
  167. */
  168. static int _secure_copy_file( const char * source,const char * dest,uid_t uid )
  169. {
  170. int st = 4 ;
  171. int fd_source ;
  172. int fd_dest ;
  173. size_t len ;
  174. char buffer[ SIZE ] ;
  175. zuluCryptSecurityDropElevatedPrivileges() ;
  176. fd_dest = open( dest,O_WRONLY | O_CREAT,S_IRUSR | S_IWUSR | S_IRGRP |S_IROTH ) ;
  177. if( fd_dest == -1 ){
  178. zuluCryptSecurityGainElevatedPrivileges() ;
  179. zuluCryptDeleteFile( source ) ;
  180. zuluCryptSecurityDropElevatedPrivileges() ;
  181. return 6 ;
  182. }
  183. zuluCryptSecurityGainElevatedPrivileges() ;
  184. fd_source = open( source,O_RDONLY ) ;
  185. if( fd_source != -1 ){
  186. while( 1 ){
  187. len = read( fd_source,buffer,SIZE ) ;
  188. if( len < SIZE ){
  189. ignore_result( write( fd_dest,buffer,len ) ) ;
  190. break ;
  191. }else{
  192. ignore_result( write( fd_dest,buffer,len ) ) ;
  193. }
  194. }
  195. ignore_result( chmod( dest,S_IRUSR ) ) ;
  196. ignore_result( chown( dest,uid,uid ) ) ;
  197. st = 0 ;
  198. }
  199. /*
  200. * zuluCryptDeleteFile() is defined in ../lib/file_path_security.c
  201. */
  202. zuluCryptDeleteFile( source ) ;
  203. zuluCryptSecurityDropElevatedPrivileges() ;
  204. return st ;
  205. }
  206. static int _save_luks_header( const struct_opts * opts,const char * temp_path,const char * path,uid_t uid )
  207. {
  208. struct crypt_device * cd ;
  209. int st ;
  210. if( crypt_init( &cd,opts->device ) != 0 ){
  211. st = 3 ;
  212. }else{
  213. st = crypt_header_backup( cd,NULL,temp_path ) ;
  214. crypt_free( cd ) ;
  215. if( st == 0 ){
  216. st = _secure_copy_file( temp_path,path,uid ) ;
  217. }else{
  218. st = 4 ;
  219. }
  220. }
  221. return st ;
  222. }
  223. #if TCPLAY_NEW_API
  224. static int zuluExit_1( int r,string_t st,string_t xt )
  225. {
  226. StringMultipleDelete( &xt,&st,NULL ) ;
  227. return r ;
  228. }
  229. static string_t _get_password( int * r )
  230. {
  231. string_t st = StringVoid ;
  232. *r = 1 ;
  233. printf( gettext( "Enter passphrase in the volume: " ) ) ;
  234. /*
  235. * ZULUCRYPT_KEY_MAX_SIZE is set in ../constants.h
  236. */
  237. StringSilentlyGetFromTerminal_1( &st,ZULUCRYPT_KEY_MAX_SIZE ) ;
  238. return st ;
  239. }
  240. static string_t _get_password_0( int * r )
  241. {
  242. string_t st = StringVoid ;
  243. *r = 1 ;
  244. printf( gettext( "Enter passphrase in the header file: " ) ) ;
  245. /*
  246. * ZULUCRYPT_KEY_MAX_SIZE is set in ../constants.h
  247. */
  248. StringSilentlyGetFromTerminal_1( &st,ZULUCRYPT_KEY_MAX_SIZE ) ;
  249. return st ;
  250. }
  251. static int _modify_tcrypt( info_t * info,const struct_opts * opts )
  252. {
  253. int k = 4 ;
  254. int r ;
  255. string_t st = StringVoid ;
  256. string_t xt = StringVoid ;
  257. if( StringsAreEqual( opts->key_source,"-p" ) ){
  258. info->header_key = opts->key ;
  259. info->header_key_source = "passphrase" ;
  260. info->header_new_key_source = "new_passphrase" ;
  261. }else if( opts->key == NULL && StringsAreNotEqual( opts->key_source,"-f" ) ){
  262. st = info->getKey( &r ) ;
  263. if( r ){
  264. info->key = StringContent( st ) ;
  265. info->header_key = info->key ;
  266. info->header_key_source = "passphrase" ;
  267. info->header_new_key_source = "new_passphrase" ;
  268. }else{
  269. return zuluExit_1( k,st,xt ) ;
  270. }
  271. }else{
  272. /*
  273. * function is defined at "path_access.c"
  274. */
  275. zuluCryptGetPassFromFile( opts->key,info->uid,&st ) ;
  276. zuluCryptSecurityGainElevatedPrivileges() ;
  277. if( st == StringVoid ){
  278. return zuluExit_1( k,st,xt ) ;
  279. }else{
  280. if( StringHasComponent( opts->key,".zuluCrypt-socket" ) ){
  281. info->key = StringContent( st ) ;
  282. info->header_key = info->key ;
  283. info->header_key_source = "passphrase" ;
  284. info->header_new_key_source = "new_passphrase" ;
  285. }else{
  286. /*
  287. * zuluCryptCreateKeyFile_1 is defined in ../lib/open_tcrypt.c
  288. */
  289. xt = zuluCryptCreateKeyFile_1( st,"tcrypt-bk-" ) ;
  290. if( xt == StringVoid ){
  291. return zuluExit_1( k,st,xt ) ;
  292. }else{
  293. info->key = StringContent( xt ) ;
  294. info->header_key = info->key ;
  295. info->header_key_source = "keyfiles" ;
  296. info->header_new_key_source = "new_keyfiles" ;
  297. }
  298. }
  299. }
  300. }
  301. info->header_new_key = info->header_key ;
  302. /*
  303. * zuluCryptModifyTcryptHeader() is defined in ../lib/create_tcrypt.c
  304. */
  305. k = zuluCryptModifyTcryptHeader( info ) ;
  306. if( xt != StringVoid ){
  307. /*
  308. * zuluCryptDeleteFile_1() is defined in ../lib/file_path_security.c
  309. */
  310. zuluCryptDeleteFile_1( xt ) ;
  311. }
  312. return zuluExit_1( k,st,xt ) ;
  313. }
  314. static int _save_truecrypt_header( const struct_opts * opts,const char * temp_path,const char * path,uid_t uid )
  315. {
  316. int r ;
  317. /*
  318. * info_t structure is declared in ../lib/include.h
  319. */
  320. info_t info ;
  321. memset( &info,'\0',sizeof( info_t ) ) ;
  322. info.device = opts->device ;
  323. info.header_source = "save_header_to_file" ;
  324. info.getKey = _get_password ;
  325. info.tmp_path = temp_path ;
  326. info.uid = uid ;
  327. info.rng = opts->rng ;
  328. info.opt = opts->m_opts ;
  329. r = _modify_tcrypt( &info,opts ) ;
  330. if( opts->key == NULL && StringsAreNotEqual( opts->key_source,"-f" ) ){
  331. printf( "\n" ) ;
  332. }
  333. if( r == TC_OK ){
  334. return _secure_copy_file( temp_path,path,uid ) ;
  335. }else{
  336. return 20 ;
  337. }
  338. }
  339. static int _restore_truecrypt_header( const struct_opts * opts,const char * temp_path,uid_t uid )
  340. {
  341. int r ;
  342. /*
  343. * info_t structure is declared in ../lib/include.h
  344. */
  345. info_t info ;
  346. memset( &info,'\0',sizeof( info_t ) ) ;
  347. info.device = opts->device ;
  348. info.header_source = "header_from_file" ;
  349. info.getKey = _get_password_0 ;
  350. info.tmp_path = temp_path ;
  351. info.uid = uid ;
  352. info.rng = opts->rng ;
  353. info.opt = opts->m_opts ;
  354. r = _modify_tcrypt( &info,opts ) ;
  355. if( opts->key == NULL && StringsAreNotEqual( opts->key_source,"-f" ) ){
  356. printf( "\n" ) ;
  357. }
  358. if( r == TC_OK ){
  359. return 1 ;
  360. }else{
  361. return 20 ;
  362. }
  363. }
  364. #else
  365. static int _save_truecrypt_header( const struct_opts * opts,const char * temp_path,const char * path,uid_t uid )
  366. {
  367. if( 0 && opts && temp_path && path && uid ){;}
  368. return 7 ;
  369. }
  370. static int _restore_truecrypt_header( const struct_opts * opts,const char * temp_path,uid_t uid )
  371. {
  372. if( 0 && opts && temp_path && uid ){;}
  373. return 7 ;
  374. }
  375. #endif
  376. static int _save_header( const struct_opts * opts,const char * path,uid_t uid )
  377. {
  378. int st = 4 ;
  379. const char * temp_path = _secure_file_path_1() ;
  380. zuluCryptSecurityGainElevatedPrivileges() ;
  381. if( zuluCryptVolumeIsLuks( opts->device ) ){
  382. st = _save_luks_header( opts,temp_path,path,uid ) ;
  383. }else{
  384. st = _save_truecrypt_header( opts,temp_path,path,uid ) ;
  385. }
  386. zuluCryptSecurityDropElevatedPrivileges() ;
  387. StringFree( temp_path ) ;
  388. return st ;
  389. }
  390. static int _restore_luks_header( const struct_opts * opts,const char * temp_path )
  391. {
  392. int st ;
  393. struct crypt_device * cd ;
  394. if( crypt_init( &cd,opts->device ) != 0 ){
  395. st = 7 ;
  396. }else{
  397. if( crypt_load( cd,NULL,NULL ) != 0 ){
  398. st = 2 ;
  399. }else{
  400. if( crypt_header_restore( cd,NULL,temp_path ) == 0 ){
  401. st = 1 ;
  402. }else{
  403. st = 7 ;
  404. }
  405. }
  406. crypt_free( cd ) ;
  407. }
  408. return st ;
  409. }
  410. static int _restore_header( const struct_opts * opts,const char * dev,const char * path,int ask_confirmation,uid_t uid )
  411. {
  412. const char * temp_path = NULL ;
  413. int k ;
  414. int st = 7;
  415. string_t confirm ;
  416. const char * warn = gettext( "\
  417. Are you sure you want to replace a header on device \"%s\" with a backup copy at \"%s\"?\n\
  418. Type \"YES\" and press Enter to continue: " ) ;
  419. if( uid ){;}
  420. if( ask_confirmation ){
  421. zuluCryptSecurityDropElevatedPrivileges() ;
  422. printf( warn,dev,path ) ;
  423. confirm = StringGetFromTerminal_1( 3 ) ;
  424. if( confirm != StringVoid ){
  425. k = StringEqual( confirm,gettext( "YES" ) );
  426. StringDelete( &confirm ) ;
  427. if( k == 0 ){
  428. return 5 ;
  429. }
  430. }else{
  431. return 19 ;
  432. }
  433. }
  434. if( _secure_file_path( &temp_path,path ) ){
  435. zuluCryptSecurityGainElevatedPrivileges() ;
  436. if( zuluCryptVolumeIsLuks( temp_path ) ){
  437. /*
  438. * temp_path will point to a header back up file and it is assumed that a user
  439. * want to restore a header to a luks volume since the backup header has luks signature
  440. */
  441. st = _restore_luks_header( opts,temp_path ) ;
  442. }else{
  443. /*
  444. * the header back up has no luks signature and hence it is assumed that a request is
  445. * made to restore a truecrypt header backup
  446. */
  447. st = _restore_truecrypt_header( opts,temp_path,uid ) ;
  448. }
  449. zuluCryptDeleteFile( temp_path ) ;
  450. StringFree( temp_path ) ;
  451. zuluCryptSecurityDropElevatedPrivileges() ;
  452. return st ;
  453. }else{
  454. return 7 ;
  455. }
  456. }
  457. int zuluCryptEXESaveAndRestoreVolumeHeader( const struct_opts * opts,uid_t uid,int option )
  458. {
  459. const char * device = opts->device ;
  460. const char * path = opts->back_up_file_path ;
  461. int st ;
  462. int k ;
  463. const char * dev = NULL ;
  464. const char * dev_1 = NULL ;
  465. if( StringPrefixEqual( device,"/dev/loop" ) ){
  466. /*
  467. * zuluCryptLoopDeviceAddress_1() is defined in ../lib/create_loop_device.c
  468. */
  469. dev = zuluCryptLoopDeviceAddress_1( device ) ;
  470. dev_1 = dev ;
  471. /*
  472. * zuluCryptPartitionIsSystemPartition() is defined in partitions.c
  473. */
  474. k = zuluCryptPartitionIsSystemPartition( dev,uid ) ;
  475. }else{
  476. dev_1 = device ;
  477. /*
  478. * zuluCryptPartitionIsSystemPartition() is defined in partitions.c
  479. */
  480. k = zuluCryptPartitionIsSystemPartition( device,uid ) ;
  481. }
  482. if( k == 1 ){
  483. if( uid != 0 || !zuluCryptUserIsAMemberOfAGroup( uid,"zulucrypt" ) ){
  484. return zuluExit( 14,dev ) ;
  485. }
  486. }
  487. if( path == NULL ){
  488. if( option == VOLUME_HEADER_RESTORE ){
  489. return zuluExit( 12,dev ) ;
  490. }else{
  491. return zuluExit( 13,dev ) ;
  492. }
  493. }
  494. if( option == VOLUME_HEADER_RESTORE ){
  495. st = _restore_header( opts,dev_1,path,opts->ask_confirmation,uid ) ;
  496. }else{
  497. st = _save_header( opts,path,uid ) ;
  498. }
  499. return zuluExit( st,dev ) ;
  500. }
  501. static int _files_are_equal( const char * file1,const char * file2 )
  502. {
  503. struct stat st1 ;
  504. struct stat st2 ;
  505. int fd1;
  506. int fd2;
  507. int r = 1 ;
  508. void * map1 ;
  509. void * map2 ;
  510. fd1 = open( file1,O_RDONLY ) ;
  511. if( fd1 == -1 ){
  512. return 0 ;
  513. }
  514. fd2 = open( file2,O_RDONLY ) ;
  515. if( fd2 == -1 ){
  516. close( fd1 ) ;
  517. return 0 ;
  518. }
  519. fstat( fd1,&st1 ) ;
  520. fstat( fd2,&st2 ) ;
  521. /*
  522. * headers are less than 3MB,anything larger is automatically an error
  523. */
  524. if( st1.st_size < 3145728 && st2.st_size < 3145728 ){
  525. map1 = mmap( 0,st1.st_size,PROT_READ,MAP_PRIVATE,fd1,0 ) ;
  526. if( map1 != MAP_FAILED ){
  527. map2 = mmap( 0,st2.st_size,PROT_READ,MAP_PRIVATE,fd2,0 ) ;
  528. if( map2 != MAP_FAILED ){
  529. if( st1.st_size > st2.st_size ){
  530. r = memcmp( map1,map2,st1.st_size ) ;
  531. }else{
  532. r = memcmp( map1,map2,st2.st_size ) ;
  533. }
  534. munmap( map2,st2.st_size ) ;
  535. }
  536. munmap( map1,st1.st_size ) ;
  537. }
  538. }else{
  539. return 0 ;
  540. }
  541. close( fd1 ) ;
  542. close( fd2 ) ;
  543. return r == 0 ;
  544. }
  545. static int _save_tmp_header( const char * device,const char * backup )
  546. {
  547. struct crypt_device * cd ;
  548. int st = 1 ;
  549. if( crypt_init( &cd,device ) == 0 ){
  550. st = crypt_header_backup( cd,NULL,backup ) ;
  551. crypt_free( cd ) ;
  552. }
  553. return st == 0 ;
  554. }
  555. int zuluCryptHeaderMatchBackUpHeader( const char * device,const char * header_backup,uid_t uid )
  556. {
  557. const char * header_path = NULL;
  558. const char * device_header = NULL;
  559. int st = 0 ;
  560. if( uid ){;}
  561. if( device == NULL || header_backup == NULL ){
  562. return 0 ;
  563. }
  564. _secure_file_path( &header_path,header_backup ) ;
  565. if( header_path == NULL ){
  566. return 0 ;
  567. }
  568. device_header = _secure_file_path_1() ;
  569. if( device_header == NULL ){
  570. StringFree( header_path ) ;
  571. return 0 ;
  572. }
  573. zuluCryptSecurityGainElevatedPrivileges() ;
  574. if( _save_tmp_header( device,device_header ) ){
  575. st = _files_are_equal( header_path,device_header ) ;
  576. }
  577. zuluCryptDeleteFile( header_path ) ;
  578. zuluCryptDeleteFile( device_header ) ;
  579. zuluCryptSecurityDropElevatedPrivileges() ;
  580. StringFree( header_path ) ;
  581. StringFree( device_header ) ;
  582. return st ;
  583. }