PageRenderTime 53ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/zuluCrypt-cli/bin/open_volume.c

https://gitlab.com/m.schmidt/zuluCrypt
C | 529 lines | 329 code | 85 blank | 115 comment | 71 complexity | b0856088859948b5be02aea3e3006c12 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 <sys/types.h>
  22. #include <string.h>
  23. #include <locale.h>
  24. #include <stdio.h>
  25. #include <libintl.h>
  26. #include <sys/stat.h>
  27. #include <unistd.h>
  28. stringList_t zuluCryptCreateKeyFiles( const char * const * list,int s )
  29. {
  30. #define buffer_size 32
  31. char buffer[ buffer_size ] ;
  32. const char * e ;
  33. int i ;
  34. stringList_t stz = StringListVoid ;
  35. string_t xt ;
  36. string_t zt ;
  37. for( i = 0 ; list[ i ] != NULL ; i++ ){
  38. e = *( list + i ) ;
  39. zuluCryptSecurityDropElevatedPrivileges() ;
  40. /*
  41. * TrueCrypt only uses the first 1MB of keyfile.
  42. */
  43. if( StringGetFromFile_3( &xt,e,0,1048576 ) == 0 ){
  44. zuluCryptSecurityGainElevatedPrivileges() ;
  45. e = StringIntToString_1( buffer,buffer_size,i + s ) ;
  46. /*
  47. * zuluCryptCreateKeyFile_1() is defined in ../lib/open_tcrypt.c
  48. */
  49. zt = zuluCryptCreateKeyFile_1( xt,e ) ;
  50. StringDelete( &xt ) ;
  51. stz = StringListAppendString_1( stz,&zt ) ;
  52. }
  53. }
  54. zuluCryptSecurityDropElevatedPrivileges() ;
  55. return stz ;
  56. }
  57. void zuluCryptDeleteKeyFiles( stringList_t stl )
  58. {
  59. StringListIterator it ;
  60. StringListIterator end ;
  61. StringListGetIterators( stl,&it,&end ) ;
  62. zuluCryptSecurityGainElevatedPrivileges() ;
  63. while( it != end ){
  64. /*
  65. * zuluCryptDeleteFile_1() is defined in ../lib/file_path_security.c
  66. */
  67. zuluCryptDeleteFile_1( *it ) ;
  68. it++ ;
  69. }
  70. zuluCryptSecurityDropElevatedPrivileges() ;
  71. }
  72. static char * _device_path( const char * device )
  73. {
  74. char * path ;
  75. if( StringPrefixEqual( device,"/dev/loop" ) ){
  76. zuluCryptSecurityGainElevatedPrivileges() ;
  77. /*
  78. * zuluCryptLoopDeviceAddress_1() is defined in ../zuluCrypt-cli/create_loop_device.c
  79. */
  80. path = zuluCryptLoopDeviceAddress_1( device ) ;
  81. zuluCryptSecurityDropElevatedPrivileges() ;
  82. if( path == NULL ){
  83. return StringCopy_2( device ) ;
  84. }else{
  85. return path ;
  86. }
  87. }else{
  88. return StringCopy_2( device ) ;
  89. }
  90. }
  91. static void _printResult( const char * device,const char * m_point )
  92. {
  93. char * e ;
  94. zuluCryptSecurityGainElevatedPrivileges() ;
  95. /*
  96. * zuluCryptGetVolumeTypeFromMapperPath() is defined in ../lib/status.c
  97. */
  98. e = zuluCryptGetVolumeTypeFromMapperPath( device ) ;
  99. zuluCryptSecurityDropElevatedPrivileges() ;
  100. if( StringHasComponent( e,"LUKS" ) ){
  101. printf( gettext( "SUCCESS: %s volume opened successfully\n" ),"luks" ) ;
  102. }else if( StringHasComponent( e,"PLAIN" ) ){
  103. printf( gettext( "SUCCESS: %s volume opened successfully\n" ),"plain" ) ;
  104. }else if( StringHasComponent( e,"TCRYPT" ) ){
  105. printf( gettext( "SUCCESS: %s volume opened successfully\n" ),"tcrypt" ) ;
  106. }else if( StringHasComponent( e,"VCRYPT" ) ){
  107. printf( gettext( "SUCCESS: %s volume opened successfully\n" ),"vcrypt" ) ;
  108. }else{
  109. printf( gettext( "SUCCESS: volume opened successfully\n" ) ) ;
  110. }
  111. StringFree( e ) ;
  112. if( m_point != NULL ){
  113. printf( gettext( "volume mounted at: %s\n" ),m_point ) ;
  114. }
  115. }
  116. static int zuluExit( int st,const char * device,const char * m_point,stringList_t stl )
  117. {
  118. switch( st ){
  119. case 0 : _printResult( device,m_point ) ; break ;
  120. case 1 : printf( gettext( "ERROR: Failed to mount ntfs/exfat file system using ntfs-3g,is ntfs-3g/exfat package installed?\n" ) ) ;break ;
  121. case 2 : printf( gettext( "ERROR: There seem to be an open volume accociated with given address\n" ) ) ; break ;
  122. case 3 : printf( gettext( "ERROR: No file or device exist on given path\n" ) ) ; break ;
  123. case 4 : printf( gettext( "ERROR: Volume could not be opened with the presented key\n" ) ) ; break ;
  124. case 5 : printf( gettext( "ERROR: Insufficient privilege to mount the device with given options\n" ) ) ; break ;
  125. case 6 : printf( gettext( "ERROR: Insufficient privilege to open device in read write mode or device does not exist\n" ) ) ; break ;
  126. case 7 : printf( gettext( "ERROR: Only root user can perform this operation\n" ) ) ; break ;
  127. case 8 : printf( gettext( "ERROR: -O and -m options can not be used together\n" ) ) ; break ;
  128. case 9 : printf( gettext( "ERROR: Could not create mount point, invalid path or path already taken\n" ) ) ; break ;
  129. case 10: printf( gettext( "ERROR: Shared mount point path aleady taken\n" ) ) ; break ;
  130. case 11: printf( gettext( "ERROR: There seem to be an opened mapper associated with the device\n" ) ) ; break ;
  131. case 12: printf( gettext( "ERROR: Could not get a passphrase from the module\n" ) ) ; break ;
  132. case 13: printf( gettext( "ERROR: Could not get passphrase in silent mode\n" ) ); break ;
  133. case 14: printf( gettext( "ERROR: Insufficient memory to hold passphrase\n" ) ) ; break ;
  134. case 15: printf( gettext( "ERROR: One or more required argument(s) for this operation is missing\n" ) ) ; break ;
  135. case 16: printf( gettext( "ERROR: Invalid path to key file\n" ) ) ; break ;
  136. case 17: printf( gettext( "ERROR: Could not get enought memory to hold the key file\n" ) ) ; break ;
  137. case 18: printf( gettext( "ERROR: Insufficient privilege to open key file for reading\n" ) ); break ;
  138. case 19: printf( gettext( "ERROR: Could not get a passphrase through a local socket\n" ) ); break ;
  139. case 20: printf( gettext( "ERROR: Failed to mount a filesystem:invalid/unsupported mount option or unsupported file system encountered\n" ) );break ;
  140. case 21: printf( gettext( "ERROR: Could not create a lock on /etc/mtab\n" ) ) ; break ;
  141. case 22: printf( gettext( "ERROR: Insufficient privilege to open a system volume\n" ) ) ; break ;
  142. default: printf( gettext( "ERROR: Unrecognized error with status number %d encountered\n" ),st ) ;
  143. }
  144. zuluCryptSecurityUnlockMemory( stl ) ;
  145. StringListClearDelete( &stl ) ;
  146. return st ;
  147. }
  148. /*
  149. * open_volume function below can be devided into two, the first part is before the mount point folder is created and the
  150. * other part is after. This function is called after the mount point is created to see if it the mount point folder
  151. * should be removed first before calling the above function.The above function is called directly when "open_volume"
  152. * function is to be exited before the mount point is created. *
  153. */
  154. static int zuluExit_1( int st,const struct_opts * opts,const char * device,const char * m_point,stringList_t stl )
  155. {
  156. if( opts->open_mount && st != 0 ){
  157. zuluCryptSecurityGainElevatedPrivileges() ;
  158. rmdir( m_point ) ;
  159. zuluCryptSecurityDropElevatedPrivileges() ;
  160. }
  161. return zuluExit( st,device,m_point,stl ) ;
  162. }
  163. static int _open_volume( const open_struct_t * volume )
  164. {
  165. int r ;
  166. zuluCryptSecurityGainElevatedPrivileges() ;
  167. /*
  168. * zuluCryptOpenVolume_2() is defined in ../lib/open_volume.c
  169. */
  170. r = zuluCryptOpenVolume_2( volume ) ;
  171. zuluCryptSecurityDropElevatedPrivileges() ;
  172. return r ;
  173. }
  174. void zuluCryptTrueCryptVeraCryptVolumeInfo( const char * type,tvcrypt * e )
  175. {
  176. stringList_t stl = StringListSplit( type,'.' ) ;
  177. size_t p = StringListSize( stl ) ;
  178. const char * q ;
  179. memset( e,'\0',sizeof( tvcrypt ) ) ;
  180. if( p > 0 ){
  181. e->type = StringListCopyStringAtFirstPlace( stl ) ;
  182. if( p > 1 ){
  183. q = StringListContentAtSecondPlace( stl ) ;
  184. e->iteration_count = ( int )StringConvertToInt( q ) ;
  185. }
  186. }
  187. StringListDelete( &stl ) ;
  188. }
  189. int zuluCryptEXEOpenVolume( const struct_opts * opts,const char * mapping_name,uid_t uid )
  190. {
  191. int share = opts->share ;
  192. int open_mount = opts->open_mount ;
  193. const char * device = opts->device ;
  194. const char * mount_point = opts->mount_point ;
  195. const char * m_opts = opts->m_opts ;
  196. const char * source = opts->key_source ;
  197. const char * pass = opts->key ;
  198. const char * plugin_path = opts->plugin_path ;
  199. const char * fs_opts = opts->fs_opts ;
  200. const char * offset = opts->offset ;
  201. const char * const * tcrypt_keyfiles = opts->tcrypt_multiple_keyfiles ;
  202. /*
  203. * Below is a form of memory management.All strings are collected in a stringlist object to easily delete them
  204. * when the function returns.This allows for the function to have multiple exit points without risks of leaking
  205. * memory from manually examining each exit point to make sure all strings are deleted or go with multiple goto
  206. * code deleting blocks to take into account different exit points.
  207. */
  208. stringList_t stl ;
  209. string_t * stringArray = StringListArray( &stl,6 ) ;
  210. string_t * passphrase = &stringArray[ 0 ] ;
  211. string_t * m_name = &stringArray[ 1 ] ;
  212. string_t * data = &stringArray[ 2 ] ;
  213. string_t * m_point = &stringArray[ 3 ] ;
  214. string_t * mapper = &stringArray[ 4 ] ;
  215. string_t * mapper_path = &stringArray[ 5 ] ;
  216. const char * key = NULL ;
  217. const char * mapper_name ;
  218. const char * e ;
  219. size_t key_len = 0 ;
  220. int st = 0 ;
  221. stringList_t stz ;
  222. tvcrypt v_info ;
  223. unsigned long m_flags ;
  224. int tcrypt_keyfile = 0 ;
  225. const char * uuid ;
  226. char * device_path ;
  227. /*
  228. * open_struct_t is declared in ../lib/include.h
  229. */
  230. open_struct_t volume ;
  231. struct stat statstr ;
  232. /*
  233. * zuluCryptVolumeIsInSystemVolumeList() is defined in volumes.c
  234. */
  235. if( zuluCryptVolumeIsInSystemVolumeList( device ) ){
  236. /*
  237. * check permissions only if volume is explicity mentioned as system.
  238. * This is an exception to avoid some udev bad behaviors on udev enabled build
  239. */
  240. if( !zuluCryptUserIsAMemberOfAGroup( uid,"zulucrypt" ) ){
  241. return zuluExit( 22,device,mount_point,stl ) ;
  242. }
  243. }
  244. if( m_opts == NULL ){
  245. m_opts = "rw" ;
  246. }
  247. /*
  248. * zuluCryptMountFlagsAreNotCorrect() is defined in ./mount_flags.c
  249. */
  250. if( zuluCryptMountFlagsAreNotCorrect( m_opts,uid,&m_flags ) ){
  251. return zuluExit( 5,device,mount_point,stl ) ;
  252. }
  253. if( StringHasComponent( m_opts,"rw" ) ){
  254. /*
  255. * zuluCryptSecurityDeviceIsWritable() is defined in path_access.c
  256. */
  257. st = zuluCryptCanOpenPathForWriting( device,uid ) ;
  258. }else{
  259. /*
  260. * zuluCryptSecurityDeviceIsReadable() is defined in path_access.c
  261. */
  262. st = zuluCryptCanOpenPathForReading( device,uid ) ;
  263. }
  264. /*
  265. * 1-permissions denied
  266. * 2-invalid path
  267. * 3-shenanigans
  268. * 4-common error
  269. */
  270. switch( st ){
  271. case 0 : break ;
  272. case 1 : return zuluExit( 6,device,mount_point,stl ) ;
  273. case 2 : return zuluExit( 6,device,mount_point,stl ) ;
  274. case 3 : return zuluExit( 6,device,mount_point,stl ) ;
  275. case 4 : return zuluExit( 6,device,mount_point,stl ) ;
  276. default: return zuluExit( 6,device,mount_point,stl ) ;
  277. }
  278. if( open_mount ){
  279. /*
  280. * zuluCryptCreateMountPoint() is defined in create_mount_point.c
  281. */
  282. *m_point = zuluCryptCreateMountPoint( device,mount_point,m_opts,uid ) ;
  283. mount_point = StringContent( *m_point ) ;
  284. if( mount_point == NULL ){
  285. return zuluExit( 9,device,mount_point,stl ) ;
  286. }
  287. }else{
  288. if( uid != 0 ){
  289. return zuluExit( 7,device,mount_point,stl ) ;
  290. }
  291. if( mount_point != NULL ){
  292. return zuluExit( 8,device,mount_point,stl ) ;
  293. }
  294. }
  295. if( share ){
  296. /*
  297. * zuluCryptBindSharedMountPointPathTaken() is defined in bind.c
  298. */
  299. if( zuluCryptBindSharedMountPointPathTaken( *m_point ) ){
  300. return zuluExit_1( 10,opts,device,mount_point,stl ) ;
  301. }
  302. }
  303. /*
  304. * zuluCryptCreateMapperName() is defined in ../lib/create_mapper_name.c
  305. */
  306. *m_name = zuluCryptCreateMapperName( device,mapping_name,uid,ZULUCRYPTshortMapperPath ) ;
  307. *mapper = StringCopy( *m_name ) ;
  308. mapper_name = StringContent( *m_name ) ;
  309. *mapper_path = String( zuluCryptMapperPrefix() ) ;
  310. e = StringMultipleAppend( *mapper_path,"/",mapper_name,NULL ) ;
  311. if( stat( e,&statstr ) == 0 ){
  312. return zuluExit_1( 11,opts,device,mount_point,stl ) ;
  313. }
  314. if( plugin_path != NULL ){
  315. /*
  316. * zuluCryptUUIDFromPath() is defined in path_access.c
  317. */
  318. uuid = zuluCryptUUIDFromPath( device ) ;
  319. device_path = _device_path( device ) ;
  320. /*
  321. * zuluCryptPluginManagerGetKeyFromModule is defined in ../pluginManager/zuluCryptPluginManager.c
  322. */
  323. *passphrase = zuluCryptPluginManagerGetKeyFromModule( device_path,plugin_path,uuid,uid,opts,&st ) ;
  324. StringFree( device_path ) ;
  325. StringFree( uuid ) ;
  326. if( st != 0 || *passphrase == StringVoid ){
  327. return zuluExit_1( 12,opts,device,mount_point,stl ) ;
  328. }
  329. key_len = StringLength( *passphrase ) ;
  330. key = StringContent( *passphrase ) ;
  331. zuluCryptSecurityLockMemory_1( *passphrase ) ;
  332. }else if( source == NULL && tcrypt_keyfiles[ 0 ] == NULL ){
  333. printf( gettext( "Enter passphrase: " ) ) ;
  334. /*
  335. * ZULUCRYPT_KEY_MAX_SIZE is set in ../constants.h
  336. */
  337. switch( StringSilentlyGetFromTerminal_1( passphrase,ZULUCRYPT_KEY_MAX_SIZE ) ){
  338. case 1 : return zuluExit_1( 13,opts,device,mount_point,stl ) ;
  339. case 2 : return zuluExit_1( 14,opts,device,mount_point,stl ) ;
  340. }
  341. printf( "\n" ) ;
  342. key = StringContent( *passphrase ) ;
  343. key_len = StringLength( *passphrase ) ;
  344. zuluCryptSecurityLockMemory_1( *passphrase ) ;
  345. }else{
  346. if( source == NULL || pass == NULL ){
  347. if( tcrypt_keyfiles == NULL ){
  348. return zuluExit_1( 15,opts,device,mount_point,stl ) ;
  349. }
  350. }
  351. if( StringsAreEqual( source,"-p" ) ){
  352. key = pass ;
  353. key_len = StringSize( pass ) ;
  354. }else if( StringsAreEqual( source,"-f" ) ){
  355. if( StringHasNoComponent( pass,"/.zuluCrypt-socket" ) ){
  356. tcrypt_keyfile = 1 ;
  357. }
  358. /*
  359. * function is defined at "path_access.c"
  360. */
  361. switch( zuluCryptGetPassFromFile( pass,uid,data ) ){
  362. case 1 : return zuluExit_1( 16,opts,device,mount_point,stl ) ;
  363. case 2 : return zuluExit_1( 17,opts,device,mount_point,stl ) ;
  364. case 4 : return zuluExit_1( 18,opts,device,mount_point,stl ) ;
  365. case 5 : return zuluExit_1( 19,opts,device,mount_point,stl ) ;
  366. }
  367. key = StringContent( *data ) ;
  368. key_len = StringLength( *data ) ;
  369. zuluCryptSecurityLockMemory_1( *data ) ;
  370. }
  371. }
  372. memset( &volume,'\0',sizeof( open_struct_t ) ) ;
  373. if( key != NULL ){
  374. volume.key = key ;
  375. volume.key_len = key_len ;
  376. }else{
  377. volume.key = "" ;
  378. volume.key_len = 0 ;
  379. }
  380. volume.device = device ;
  381. volume.offset = offset ;
  382. volume.mapper_name = mapper_name ;
  383. volume.m_point = mount_point ;
  384. volume.fs_opts = fs_opts ;
  385. volume.uid = uid ;
  386. volume.m_opts = m_opts ;
  387. volume.m_flags = m_flags ;
  388. /*
  389. * zuluCryptTrueCryptVeraCryptVolumeInfo() is defined in this source file.
  390. */
  391. zuluCryptTrueCryptVeraCryptVolumeInfo( opts->type,&v_info ) ;
  392. volume.iteration_count = v_info.iteration_count ;
  393. volume.veraCrypt_volume = StringAtLeastOneMatch( v_info.type,"vcrypt","veracrypt","vera",NULL ) ;
  394. StringDelete( &v_info.type ) ;
  395. plugin_path = plugin_path + StringLastIndexOfChar_1( plugin_path,'/' ) + 1 ;
  396. volume.luks_detached_header = StringHasComponent( plugin_path,"luks" ) ;
  397. if( tcrypt_keyfile ){
  398. volume.key_source = TCRYPT_KEYFILE ;
  399. }
  400. if( tcrypt_keyfiles[ 0 ] != NULL ){
  401. /*
  402. * Here, we take a list of keyfiles supplied by the user and then copy them to a safe
  403. * location at "/run/zuluCrypt" and then we pass these safe copies to cryptsetup.
  404. *
  405. * The idea is not to let cryptsetup, a privileged process handle user managed files.
  406. */
  407. stz = zuluCryptCreateKeyFiles( tcrypt_keyfiles,0 ) ;
  408. volume.tcrypt_keyfiles_count = StringListSize( stz ) ;
  409. volume.tcrypt_keyfiles = StringListStringArray_0( stz ) ;
  410. st = _open_volume( &volume ) ;
  411. zuluCryptDeleteKeyFiles( stz ) ;
  412. StringFree( volume.tcrypt_keyfiles ) ;
  413. StringListDelete( &stz ) ;
  414. }else{
  415. st = _open_volume( &volume ) ;
  416. }
  417. /*
  418. * below two return values comes from ../lib/mount_volume.c
  419. */
  420. if( st == -1 ){
  421. st = 20 ;
  422. }
  423. if( st == 12 ){
  424. st = 21 ;
  425. }
  426. if( st == 8 || st == 3 ){
  427. st = 3 ;
  428. }
  429. device = StringMultiplePrepend( *mapper,"/",zuluCryptMapperPrefix(),NULL ) ;
  430. if( st == 0 && share ){
  431. /*
  432. * user wish to share the mount point bind the mount point to a publicly accessed path at /run/media/public/
  433. */
  434. /*
  435. * zuluCryptBindMountVolume() is defined in ../zuluCrypt-cli/bin/bind.c
  436. */
  437. zuluCryptBindMountVolume( device,*m_point,m_flags ) ;
  438. }
  439. /*
  440. * zuluCryptCheckInvalidKey() is defined in check_invalid_key.c
  441. */
  442. zuluCryptCheckInvalidKey( opts->device ) ;
  443. return zuluExit_1( st,opts,device,mount_point,stl ) ;
  444. }