PageRenderTime 65ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/zuluCrypt-cli/bin/create_volumes.c

https://gitlab.com/m.schmidt/zuluCrypt
C | 440 lines | 282 code | 72 blank | 86 comment | 47 complexity | 1d291fd2ac0d7325465ae05c9cdd356b MD5 | raw file
Possible License(s): BSD-3-Clause-No-Nuclear-License-2014, BSD-2-Clause
  1. /*
  2. *
  3. * Copyright (c) 2011-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 <libintl.h>
  22. #include <locale.h>
  23. #include <stdio.h>
  24. #include <sys/stat.h>
  25. static int zuluExit( int st,stringList_t stl )
  26. {
  27. /*
  28. * this function is defined in ../string/StringList.c
  29. */
  30. StringListClearDelete( &stl ) ;
  31. switch ( st ){
  32. case 0 : printf( gettext( "SUCCESS: volume created successfully\n" ) ) ; break ;
  33. case 1 : printf( gettext( "ERROR: Presented file system is not supported,see documentation for more information\n" ) ) ;break ;
  34. case 2 : printf( gettext( "ERROR: Insufficient privilege to open a system device in read/write mode,\n\
  35. only root user or members of group zulucrypt-system can do that\n" ) ) ; break ;
  36. case 3 : printf( gettext( "ERROR: Could not create an encrypted volume\n" ) ) ; break ;
  37. case 4 : printf( gettext( "ERROR: Could not open volume for writing\n" ) ) ; break ;
  38. case 5 : printf( gettext( "ERROR: There seem to be an opened mapper associated with the device\n" ) ); break ;
  39. case 6 : printf( gettext( "ERROR: Can not create a volume on a mounted device\n" ) ) ; break ;
  40. case 7 : printf( gettext( "ERROR: Container file must be bigger than 3MB\n" ) ) ; break ;
  41. case 8 : printf( "ERROR: %s not found \n",ZULUCRYPTmkfs ) ; break ;
  42. case 9 : printf( gettext( "ERROR: Insufficient memory to hold your response\n" ) ) ; break ;
  43. case 10: printf( gettext( "INFO: Operation terminated per user request\n" ) ) ; break ;
  44. case 11: printf( gettext( "ERROR: Could not get passphrase in silent mode\n" ) ) ; break ;
  45. case 12: printf( gettext( "ERROR: Insufficient memory to hold the passphrase\n" ) ) ; break ;
  46. case 13: printf( gettext( "ERROR: Passphrases do not match\n" ) ) ; break ;
  47. case 14: printf( gettext( "ERROR: Invalid path to key file\n" ) ) ; break ;
  48. case 15: printf( gettext( "ERROR: Could not get a key from a key file\n" ) ) ; break ;
  49. case 16: printf( gettext( "ERROR: Couldnt get enought memory to hold the key file\n" ) ) ; break ;
  50. case 17: printf( gettext( "ERROR: Could not get a key from a socket\n" ) ) ; break ;
  51. case 18: printf( gettext( "ERROR: One or more required argument(s) for this operation is missing\n" )); break ;
  52. case 19: printf( gettext( "ERROR: Can not get passphrase in silent mode\n" ) ) ; break ;
  53. case 20: printf( gettext( "ERROR: Insufficient memory to hold passphrase\n" ) ) ; break ;
  54. case 21: printf( gettext( "ERROR: Passphrases do not match\n" ) ) ; break ;
  55. case 22: printf( gettext( "ERROR: Failed to create a volume\n" ) ) ; break ;
  56. case 23: printf( gettext( "ERROR: Wrong argument detected for tcrypt volume\n" ) ) ; break ;
  57. default: printf( gettext( "ERROR: Unrecognized error with status number %d encountered\n" ),st ) ;
  58. }
  59. return st ;
  60. }
  61. static int zuluExit_1( const char * type,stringList_t stl )
  62. {
  63. printf( gettext( "SUCCESS: Volume created successfully\n" ) ) ;
  64. if( StringAtLeastOneMatch_1( type,"luks","tcrypt","truecrypt","veracrypt","vera","vcrypt",NULL ) ){
  65. printf( gettext( "\nCreating a backup of the \"%s\" volume header is strongly adviced.\n" ),type ) ;
  66. printf( gettext( "Please read documentation on why this is important\n\n" ) ) ;
  67. }
  68. StringListClearDelete( &stl ) ;
  69. return 0 ;
  70. }
  71. int zuluCryptEXECreateVolume( const struct_opts * opts,const char * mapping_name,uid_t uid )
  72. {
  73. int ask_confirmation = opts->ask_confirmation ;
  74. const char * device = opts->device ;
  75. const char * fs = opts->fs ;
  76. const char * type = opts->type ;
  77. const char * key_source = opts->key_source ;
  78. const char * pass = opts->key ;
  79. const char * rng = opts->rng ;
  80. const char * const * tcrypt_keyfiles = opts->tcrypt_multiple_keyfiles ;
  81. /*
  82. * Below is a form of memory management.All strings are collected in a stringlist object to easily delete them
  83. * when the function returns.This allows for the function to have multiple exit points without risks of leaking
  84. * memory from manually examining each exit point to make sure all strings are deleted or go with multiple goto
  85. * code deleting blocks to take into account different exit points.
  86. */
  87. stringList_t stl ;
  88. string_t * stringArray = StringListArray( &stl,6 ) ;
  89. string_t * pass_1 = &stringArray[ 0 ] ;
  90. string_t * pass_2 = &stringArray[ 1 ] ;
  91. string_t * confirm = &stringArray[ 2 ] ;
  92. string_t * mapper = &stringArray[ 3 ] ;
  93. string_t * pass_3 = &stringArray[ 4 ] ;
  94. string_t * pass_4 = &stringArray[ 5 ] ;
  95. stringList_t stz = StringListVoid ;
  96. stringList_t stk = StringListVoid ;
  97. string_t p = StringVoid ;
  98. const char * volkey = "" ;
  99. size_t volkeysize = 0 ;
  100. const char * volkey_h = "" ;
  101. size_t volkeysize_h = 0 ;
  102. int tcrypt_source = TCRYPT_PASSPHRASE ;
  103. int tcrypt_source_h = TCRYPT_PASSPHRASE ;
  104. int st ;
  105. int j ;
  106. int k ;
  107. int truecrypt_volume = 0 ;
  108. int veracrypt_volume = 0 ;
  109. u_int64_t hidden_volume_size = 0 ;
  110. u_int64_t size ;
  111. create_tcrypt_t tcrypt ;
  112. const char * tcrypt_hidden_volume_size = opts->tcrypt_hidden_volume_size ;
  113. const char * tcrypt_hidden_volume_key = opts->tcrypt_hidden_volume_key ;
  114. const char * tcrypt_hidden_volume_key_file = opts->existing_key ;
  115. const char * const * tcrypt_hidden_volume_keyFiles = opts->tcrypt_hidden_volume_multiple_keyfiles ;
  116. /*
  117. * zulucryptFileSystemIsNotSupported() is defined in ../lib/mount_fs_options.c
  118. */
  119. if( !zulucryptFileSystemIsSupported( fs ) ){
  120. return zuluExit( 1,stl ) ;
  121. }
  122. /*
  123. * zuluCryptPartitionIsSystemPartition() is defined in ./volumess.c
  124. */
  125. if( zuluCryptPartitionIsSystemPartition( device,uid ) ){
  126. if( !zuluCryptUserIsAMemberOfAGroup( uid,"zulucrypt" ) ){
  127. return zuluExit( 2,stl ) ;
  128. }
  129. }
  130. /*
  131. * zuluCryptSecurityDeviceIsWritable() is defined in path_access.c
  132. */
  133. st = zuluCryptCanOpenPathForWriting( device,uid ) ;
  134. /*
  135. * 1-permissions denied
  136. * 2-invalid path
  137. * 3-shenanigans
  138. * 4-common error
  139. */
  140. switch( st ){
  141. case 0 : break ;
  142. case 1 : return zuluExit( 4,stl ) ;
  143. case 2 : return zuluExit( 4,stl ) ;
  144. case 3 : return zuluExit( 4,stl ) ;
  145. case 4 : return zuluExit( 4,stl ) ;
  146. default: return zuluExit( 4,stl ) ;
  147. }
  148. /*
  149. * ZULUCRYPTlongMapperPath is set in ../constants.h
  150. * zuluCryptCreateMapperName() is defined at ../lib/create_mapper_name.c
  151. */
  152. *mapper = zuluCryptCreateMapperName( device,mapping_name,uid,ZULUCRYPTlongMapperPath ) ;
  153. j = zuluCryptCheckOpenedMapper( StringContent( *mapper ) ) ;
  154. /*
  155. * defined in ../lib/process_mountinfo.c
  156. */
  157. k = zuluCryptPartitionIsMounted( device ) ;
  158. if( j == 1 ){
  159. return zuluExit( 5,stl ) ;
  160. }
  161. if( k == 1 ){
  162. return zuluExit( 6,stl ) ;
  163. }
  164. if( StringPrefixEqual( device,"/dev/loop" ) ){
  165. zuluCryptSecurityGainElevatedPrivileges() ;
  166. /*
  167. * zuluCryptGetVolumeSize() is defined in volumes.c
  168. */
  169. size = zuluCryptGetVolumeSize( device ) ;
  170. zuluCryptSecurityDropElevatedPrivileges() ;
  171. if( size < 3145728 ){
  172. return zuluExit( 7,stl ) ;
  173. }
  174. }
  175. /*
  176. * ZULUCRYPTmkfs is defined at "../constants.h"
  177. * File systems are created not through file systems APIs but through mkfs.xxx executables started using exec call.
  178. */
  179. if( zuluCryptPathIsNotValid( ZULUCRYPTmkfs ) ){
  180. return zuluExit( 8,stl ) ;
  181. }
  182. if( ask_confirmation ){
  183. printf( gettext( "\nThis operation will destroy all data in a device at: \"%s\"\n" ),device ) ;
  184. printf( gettext( "Are you sure you want to proceed?\n" ) ) ;
  185. printf( gettext( "Type \"YES\" and press enter if you want to process: " ) ) ;
  186. *confirm = StringGetFromTerminal_1( 3 ) ;
  187. if( *confirm == StringVoid ){
  188. return zuluExit( 9,stl ) ;
  189. }else{
  190. if( StringNotEqual( *confirm,gettext( "YES" ) ) ){
  191. return zuluExit( 10,stl ) ;
  192. }
  193. }
  194. }
  195. truecrypt_volume = StringAtLeastOneMatch_1( type,"tcrypt","truecrypt",NULL ) ;
  196. veracrypt_volume = StringAtLeastOneMatch_1( type,"vcrypt","veracrypt","vera",NULL ) ;
  197. if( key_source == NULL ){
  198. printf( gettext( "Enter passphrase: " ) ) ;
  199. /*
  200. * ZULUCRYPT_KEY_MAX_SIZE is set in ../constants.h
  201. */
  202. switch( StringSilentlyGetFromTerminal_1( pass_1,ZULUCRYPT_KEY_MAX_SIZE ) ){
  203. case 1 : return zuluExit( 11,stl ) ;
  204. case 2 : return zuluExit( 12,stl ) ;
  205. }
  206. printf( gettext( "\nRe enter passphrase: " ) ) ;
  207. switch( StringSilentlyGetFromTerminal_1( pass_2,ZULUCRYPT_KEY_MAX_SIZE ) ){
  208. case 1 : return zuluExit( 11,stl ) ;
  209. case 2 : return zuluExit( 12,stl ) ;
  210. }
  211. printf( "\n" ) ;
  212. if( !StringEqualString( *pass_1,*pass_2 ) ){
  213. return zuluExit( 13,stl ) ;
  214. }
  215. tcrypt_source = TCRYPT_PASSPHRASE ;
  216. }else{
  217. if( StringsAreEqual( key_source,"-p" ) ){
  218. *pass_1 = String( pass ) ;
  219. tcrypt_source = TCRYPT_PASSPHRASE ;
  220. }else if( StringsAreEqual( key_source,"-f" ) ){
  221. /*
  222. * function is defined at "path_access.c"
  223. */
  224. switch( zuluCryptGetPassFromFile( pass,uid,pass_1 ) ){
  225. case 1 : return zuluExit( 14,stl ) ;
  226. case 4 : return zuluExit( 15,stl ) ;
  227. case 2 : return zuluExit( 16,stl ) ;
  228. case 5 : return zuluExit( 17,stl ) ;
  229. }
  230. if( StringHasComponent( pass,"/.zuluCrypt-socket" ) ){
  231. tcrypt_source = TCRYPT_PASSPHRASE ;
  232. }else{
  233. tcrypt_source = TCRYPT_KEYFILE ;
  234. }
  235. }else{
  236. return zuluExit( 18,stl ) ;
  237. }
  238. }
  239. if( tcrypt_hidden_volume_size != NULL ){
  240. if( !( truecrypt_volume || veracrypt_volume ) ){
  241. return zuluExit( 23,stl ) ;
  242. }else{
  243. hidden_volume_size = StringConvertToInt( tcrypt_hidden_volume_size ) ;
  244. if( tcrypt_hidden_volume_key_file != NULL ){
  245. /*
  246. * function is defined in "path_access.c"
  247. */
  248. switch( zuluCryptGetPassFromFile( tcrypt_hidden_volume_key_file,uid,pass_3 ) ){
  249. case 1 : return zuluExit( 14,stl ) ;
  250. case 4 : return zuluExit( 15,stl ) ;
  251. case 2 : return zuluExit( 16,stl ) ;
  252. case 5 : return zuluExit( 17,stl ) ;
  253. }
  254. if( StringHasComponent( tcrypt_hidden_volume_key_file,"/.zuluCrypt-socket" ) ){
  255. tcrypt_source_h = TCRYPT_PASSPHRASE ;
  256. }else{
  257. tcrypt_source_h = TCRYPT_KEYFILE ;
  258. }
  259. }else if( tcrypt_hidden_volume_key == NULL ){
  260. printf( gettext( "Enter tcrypt hidden passphrase: " ) ) ;
  261. /*
  262. * ZULUCRYPT_KEY_MAX_SIZE is set in ../constants.h
  263. */
  264. switch( StringSilentlyGetFromTerminal_1( pass_3,ZULUCRYPT_KEY_MAX_SIZE ) ){
  265. case 1 : return zuluExit( 19,stl ) ;
  266. case 2 : return zuluExit( 20,stl ) ;
  267. }
  268. printf( gettext( "\nRe enter tcrypt hidden passphrase: " ) ) ;
  269. switch( StringSilentlyGetFromTerminal_1( pass_4,ZULUCRYPT_KEY_MAX_SIZE ) ){
  270. case 1 : return zuluExit( 19,stl ) ;
  271. case 2 : return zuluExit( 20,stl ) ;
  272. }
  273. printf( "\n" ) ;
  274. if( !StringEqualString( *pass_3,*pass_4 ) ){
  275. return zuluExit( 21,stl ) ;
  276. }
  277. tcrypt_source_h = TCRYPT_PASSPHRASE ;
  278. }else if( tcrypt_hidden_volume_key != NULL ){
  279. *pass_3 = String( tcrypt_hidden_volume_key ) ;
  280. tcrypt_source_h = TCRYPT_PASSPHRASE ;
  281. }else{
  282. return zuluExit( 18,stl ) ;
  283. }
  284. volkey_h = StringContent( *pass_3 ) ;
  285. volkeysize_h = StringLength( *pass_3 ) ;
  286. }
  287. }
  288. volkey = StringContent( *pass_1 ) ;
  289. volkeysize = StringLength( *pass_1 ) ;
  290. if( truecrypt_volume || veracrypt_volume ){
  291. memset( &tcrypt,'\0',sizeof( create_tcrypt_t ) ) ;
  292. tcrypt.device = device ;
  293. tcrypt.fs = fs ;
  294. tcrypt.fs_h = fs ;
  295. tcrypt.encryption_options = rng ;
  296. tcrypt.hidden_volume_size = hidden_volume_size ;
  297. tcrypt.veraCrypt_volume = veracrypt_volume ;
  298. if( tcrypt_keyfiles[ 0 ] != NULL ){
  299. /*
  300. * zuluCryptCreateKeyFiles() is defined in create_volume.c
  301. */
  302. stz = zuluCryptCreateKeyFiles( tcrypt_keyfiles,0 ) ;
  303. }
  304. if( tcrypt_source == TCRYPT_KEYFILE ){
  305. zuluCryptSecurityGainElevatedPrivileges() ;
  306. /*
  307. * zuluCryptCreateKeyFile() is defined in ../lib/open_tcrypt.c
  308. */
  309. p = zuluCryptCreateKeyFile( volkey,volkeysize,"create-key-" ) ;
  310. zuluCryptSecurityDropElevatedPrivileges() ;
  311. stz = StringListAppendString_1( stz,&p ) ;
  312. tcrypt.passphrase = "" ;
  313. tcrypt.passphrase_size = 0 ;
  314. }else{
  315. tcrypt.passphrase = volkey ;
  316. tcrypt.passphrase_size = volkeysize ;
  317. }
  318. tcrypt.keyfiles = StringListStringArray_0( stz ) ;
  319. tcrypt.keyfiles_number = StringListSize( stz ) ;
  320. if( tcrypt.hidden_volume_size > 0 ){
  321. if( tcrypt_hidden_volume_keyFiles[ 0 ] != NULL ){
  322. /*
  323. * zuluCryptCreateKeyFiles() is defined in open_volume.c
  324. */
  325. stk = zuluCryptCreateKeyFiles( tcrypt_hidden_volume_keyFiles,1000 ) ;
  326. }
  327. if( tcrypt_source_h == TCRYPT_KEYFILE ){
  328. zuluCryptSecurityGainElevatedPrivileges() ;
  329. p = zuluCryptCreateKeyFile( volkey_h,volkeysize_h,"create-key_h-" ) ;
  330. zuluCryptSecurityDropElevatedPrivileges() ;
  331. stk = StringListAppendString_1( stk,&p ) ;
  332. tcrypt.passphrase_h = "" ;
  333. tcrypt.passphrase_h_size = 0 ;
  334. }else{
  335. tcrypt.passphrase_h = volkey_h ;
  336. tcrypt.passphrase_h_size = volkeysize_h ;
  337. }
  338. tcrypt.keyfiles_h = StringListStringArray_0( stk ) ;
  339. tcrypt.keyfiles_h_number = StringListSize( stk ) ;
  340. }
  341. zuluCryptSecurityGainElevatedPrivileges() ;
  342. /*
  343. * zuluCryptCreateTCryptVolume() is defined in ../lib/create_tcrypt.c
  344. */
  345. st = zuluCryptCreateTCryptVolume( &tcrypt ) ;
  346. zuluCryptSecurityDropElevatedPrivileges() ;
  347. /*
  348. * zuluCryptDeleteKeyFiles() is defined in open_volume.c
  349. */
  350. zuluCryptDeleteKeyFiles( stz ) ;
  351. zuluCryptDeleteKeyFiles( stk ) ;
  352. StringFree( tcrypt.keyfiles_h ) ;
  353. StringFree( tcrypt.keyfiles ) ;
  354. StringListMultipleDelete( &stz,&stk,NULL ) ;
  355. }else{
  356. zuluCryptSecurityGainElevatedPrivileges() ;
  357. /*
  358. * zuluCryptCreateVolume() is defined in ../lib/create_volume.c
  359. */
  360. st = zuluCryptCreateVolume( device,fs,type,volkey,volkeysize,rng ) ;
  361. zuluCryptSecurityDropElevatedPrivileges() ;
  362. }
  363. if( st == 0 ){
  364. return zuluExit_1( type,stl ) ;
  365. }else{
  366. return zuluExit( 22,stl ) ;
  367. }
  368. }