static int zuluGetKeys( string_t * key1,string_t * key2,string_t * key3 ) { int st ; /* * ZULUCRYPT_KEY_MAX_SIZE is set in ../constants.h */ printf( gettext( "Enter an existing passphrase: " ) ) ; st = StringSilentlyGetFromTerminal_1( key1,ZULUCRYPT_KEY_MAX_SIZE ) ; if( st != 0 ){ return st ; } printf( gettext( "\nEnter the new passphrase: " ) ) ; st = StringSilentlyGetFromTerminal_1( key2,ZULUCRYPT_KEY_MAX_SIZE ) ; if( st != 0 ){ StringClearDelete( key1 ) ; return st ; } printf( gettext( "\nRe enter the new passphrase: " ) ) ; st = StringSilentlyGetFromTerminal_1( key3,ZULUCRYPT_KEY_MAX_SIZE ) ; if( st != 0 ){ StringClearDelete( key1 ) ; StringClearDelete( key2 ) ; return st ; } printf( "\n" ) ; return 0 ; }
static string_t _get_password_0( int * r ) { string_t st = StringVoid ; *r = 1 ; printf( gettext( "Enter passphrase in the header file: " ) ) ; /* * ZULUCRYPT_KEY_MAX_SIZE is set in ../constants.h */ StringSilentlyGetFromTerminal_1( &st,ZULUCRYPT_KEY_MAX_SIZE ) ; return st ; }
static int crypt_opt( const struct_opts * opts,uid_t uid,int opt ) { string_t q = StringVoid ; string_t p = StringVoid ; int st ; const char * source = opts->device ; const char * dest = opts->m_opts ; const char * passphrase = opts->key ; const char * type = opts->key_source ; return zuluExit( 16 ) ; if( dest == NULL ){ return zuluExit( 9 ) ; } if( source == NULL ){ return zuluExit( 14 ) ; } /* * zuluCryptPathStartsWith() is defined in real_path.c */ if( zuluCryptPathStartsWith( dest,"/dev/" ) ){ return zuluExit( 10 ) ; } if( zuluCryptPathStartsWith( source,"/dev/" ) ){ return zuluExit( 15 ) ; } /* * zuluCryptPathIsValid() is defined in ../lib/is_path_valid.c */ if( zuluCryptPathIsValid( dest ) ){ return zuluExit( 5 ) ; } /* * zuluCryptPathIsNotValid() is defined in ../lib/is_path_valid.c */ if( zuluCryptPathIsNotValid( source ) ){ return zuluExit( 6 ) ; } /* * below two functions are defined in path_access.c */ if( zuluCryptCanOpenPathForWriting( dest,uid ) == 1 ){ return zuluExit( 10 ) ; } if( zuluCryptCanOpenPathForReading( source,uid ) == 1 ){ return zuluExit( 15 ) ; } if( type == NULL ){ printf( gettext( "Enter passphrase: " ) ) ; /* * ZULUCRYPT_KEY_MAX_SIZE is set in ../constants.h */ switch( StringSilentlyGetFromTerminal_1( &p,ZULUCRYPT_KEY_MAX_SIZE ) ){ case 1 : return zuluExit( 12 ) ; case 2 : return zuluExit( 13 ) ; } printf( gettext( "\nRe enter passphrase: " ) ) ; switch( StringSilentlyGetFromTerminal_1( &q,ZULUCRYPT_KEY_MAX_SIZE ) ){ case 1 : StringClearDelete( &p ) ; return zuluExit( 12 ) ; case 2 : StringClearDelete( &p ) ; return zuluExit( 13 ) ; } printf( "\n" ) ; if( !StringEqualString( p,q ) ){ StringClearDelete( &p ) ; StringClearDelete( &q ) ; return zuluExit( 8 ) ; }else{ StringDelete( &q ) ; } }else{ if( type == NULL ){ return zuluExit( 9 ) ; } if( StringsAreEqual( type,"-p" ) ){ p = String( passphrase ) ; }else if( StringsAreEqual( type,"-f" ) ){ p = StringGetFromFile( passphrase ) ; if( p == NULL ){ return zuluExit( 2 ) ; } }else{ return zuluExit( 3 ) ; } } if( opt == ENCRYPT ){ /* * zuluCryptEncryptFile() is defined in ./crypt_file.c */ st = zuluCryptEncryptFile( source,dest,StringContent( p ),StringLength( p ) ) ; }else{ /* * zuluCryptDecryptFile() is defined in ./crypt_file.c */ st = zuluCryptDecryptFile( source,dest,StringContent( p ),StringLength( p ) ) ; } StringClearDelete( &p ) ; switch( st ){ case 1 : return zuluExit( 4 ) ; case 2 : return zuluExit( 11 ) ; } chmod( dest,S_IRUSR | S_IWUSR ) ; chown( dest,uid,uid ) ; if( opt == 1 ){ return zuluExit( 1 ) ; }else{ return zuluExit( 0 ) ; } }
static int open_plain_as_me_1(const struct_opts * opts,const char * mapping_name,uid_t uid,int op ) { /* * Below is a form of memory management.All strings are collected in a stringlist object to easily delete them * when the function returns.This allows for the function to have multiple exit points without risks of leaking * memory from manually examining each exit point to make sure all strings are deleted or go with multiple goto * code deleting blocks to take into account different exit points. */ stringList_t stl ; string_t * stringArray = StringListArray( &stl,5 ) ; string_t * mapper = &stringArray[ 0 ] ; string_t * passphrase = &stringArray[ 1 ] ; string_t * p = &stringArray[ 2 ] ; string_t * dev_st = &stringArray[ 3 ] ; string_t * dev_1 = &stringArray[ 4 ] ; size_t len = 0 ; const char * source = opts->key_source ; const char * pass = opts->key ; int k = opts->ask_confirmation ; const char * cpass = NULL ; char * d ; const char * device = opts->device ; const char * dev = opts->device ; int j ; int n ; const char * cmapper ; if( StringPrefixEqual( device,"/dev/loop" ) ){ /* * zuluCryptLoopDeviceAddress() is defined in ../lib/create_loop_device.c */ d = zuluCryptLoopDeviceAddress( device ) ; *dev_st = StringInherit( &d ) ; dev = StringContent( *dev_st ) ; *dev_1 = StringCopy( *dev_st ) ; device = StringReplaceString( * dev_1,"\\040"," " ) ; } /* * zuluCryptPartitionIsSystemPartition() is defined in ./partition.c */ if( zuluCryptPartitionIsSystemPartition( device,uid ) ){ if( uid != 0 ){ return zuluExit( stl,8 ) ; } } /* * ZULUCRYPTlongMapperPath and ZULUCRYPTshortMapperPath are in ../constants.h * zuluCryptCreateMapperName() is defined at ../lib/create_mapper_name.c */ *mapper = zuluCryptCreateMapperName( device,mapping_name,uid,ZULUCRYPTshortMapperPath ) ; *p = zuluCryptCreateMapperName( device,mapping_name,uid,ZULUCRYPTlongMapperPath ) ; j = zuluCryptCheckOpenedMapper( StringContent( *p ) ) ; /* * zuluCryptPartitionIsMounted() is defined in ../lib/process_mountinfo.c */ n = zuluCryptPartitionIsMounted( dev ) ; if( j == 1 ){ return zuluExit( stl,13 ) ; } if( n == 1 ){ return zuluExit( stl,14 ) ; } if( k == 0 ){ *passphrase = StringRandomString( 64 ) ; cpass = StringContent( *passphrase ) ; len = StringLength( *passphrase ) ; }else if( source == NULL ){ printf( gettext( "Enter passphrase: " ) ) ; /* * ZULUCRYPT_KEY_MAX_SIZE is set in ../constants.h */ switch( StringSilentlyGetFromTerminal_1( passphrase,ZULUCRYPT_KEY_MAX_SIZE ) ){ case 1 : return zuluExit( stl,16 ) ; case 2 : return zuluExit( stl,17 ) ; } printf( "\n" ) ; cpass = StringContent( *passphrase ) ; len = StringLength( *passphrase ) ; }else{ if( strcmp( source,"-p" ) == 0 ){ *passphrase = String( pass ) ; cpass = StringContent( *passphrase ) ; len = StringLength( *passphrase ) ; }else if( strcmp( source,"-f" ) == 0 ){ /* * zuluCryptGetPassFromFile() is defined at "path_access.c" */ switch( zuluCryptGetPassFromFile( pass,uid,passphrase ) ){ case 1 : return zuluExit( stl,10 ) ; case 2 : return zuluExit( stl,11 ) ; case 4 : return zuluExit( stl,12 ) ; } cpass = StringContent( *passphrase ) ; len = StringLength( *passphrase ) ; } } if( zuluCryptSecurityGainElevatedPrivileges() ){ /* * zuluCryptOpenPlain() is defined in ../lib/open_plain.c */ if( zuluCryptOpenPlain( device,StringContent( *mapper ),"rw",cpass,len ) != 0 ){ zuluCryptSecurityDropElevatedPrivileges() ; return zuluExit( stl,1 ) ; } } zuluCryptSecurityDropElevatedPrivileges() ; /* * Create a mapper path(usually at /dev/mapper) associated with opened plain mapper above. */ cmapper = StringMultiplePrepend( *mapper,"/",crypt_get_dir(),NULL ) ; /* * mapper path is usually a soft link to /dev/dm-X * resolve the mapper path to its respective /dev/dm-X and set permission on it. * * We set permission of /dev/dm-X pointing to the device to "u+rw" because we want notmal user to be able * to write to the device through the mapper. * * Useful when a normal user want to delete content of the device by writing random data to it. */ d = zuluCryptRealPath( cmapper ) ; if( zuluCryptSecurityGainElevatedPrivileges() ){ if( d != NULL ){ _ignore_result( chown( d,uid,0 ) ) ; _ignore_result( chmod( d,S_IRWXU ) ) ; StringFree( d ) ; } zuluCryptSecurityDropElevatedPrivileges() ; }else{ return zuluExit( stl,1 ) ; } if( op == 1 ){ return zuluExit( stl,0 ) ; }else{ StringListClearDelete( &stl ) ; return 0 ; } }
int zuluCryptEXEOpenVolume( const struct_opts * opts,const char * mapping_name,uid_t uid ) { int share = opts->share ; int open_mount = opts->open_mount ; const char * device = opts->device ; const char * mount_point = opts->mount_point ; const char * m_opts = opts->m_opts ; const char * source = opts->key_source ; const char * pass = opts->key ; const char * plugin_path = opts->plugin_path ; const char * fs_opts = opts->fs_opts ; const char * offset = opts->offset ; const char * const * tcrypt_keyfiles = opts->tcrypt_multiple_keyfiles ; /* * Below is a form of memory management.All strings are collected in a stringlist object to easily delete them * when the function returns.This allows for the function to have multiple exit points without risks of leaking * memory from manually examining each exit point to make sure all strings are deleted or go with multiple goto * code deleting blocks to take into account different exit points. */ stringList_t stl ; string_t * stringArray = StringListArray( &stl,6 ) ; string_t * passphrase = &stringArray[ 0 ] ; string_t * m_name = &stringArray[ 1 ] ; string_t * data = &stringArray[ 2 ] ; string_t * m_point = &stringArray[ 3 ] ; string_t * mapper = &stringArray[ 4 ] ; string_t * mapper_path = &stringArray[ 5 ] ; const char * key = NULL ; const char * mapper_name ; const char * e ; size_t key_len = 0 ; int st = 0 ; stringList_t stz ; tvcrypt v_info ; unsigned long m_flags ; int tcrypt_keyfile = 0 ; const char * uuid ; char * device_path ; /* * open_struct_t is declared in ../lib/include.h */ open_struct_t volume ; struct stat statstr ; /* * zuluCryptVolumeIsInSystemVolumeList() is defined in volumes.c */ if( zuluCryptVolumeIsInSystemVolumeList( device ) ){ /* * check permissions only if volume is explicity mentioned as system. * This is an exception to avoid some udev bad behaviors on udev enabled build */ if( !zuluCryptUserIsAMemberOfAGroup( uid,"zulucrypt" ) ){ return zuluExit( 22,device,mount_point,stl ) ; } } if( m_opts == NULL ){ m_opts = "rw" ; } /* * zuluCryptMountFlagsAreNotCorrect() is defined in ./mount_flags.c */ if( zuluCryptMountFlagsAreNotCorrect( m_opts,uid,&m_flags ) ){ return zuluExit( 5,device,mount_point,stl ) ; } if( StringHasComponent( m_opts,"rw" ) ){ /* * zuluCryptSecurityDeviceIsWritable() is defined in path_access.c */ st = zuluCryptCanOpenPathForWriting( device,uid ) ; }else{ /* * zuluCryptSecurityDeviceIsReadable() is defined in path_access.c */ st = zuluCryptCanOpenPathForReading( device,uid ) ; } /* * 1-permissions denied * 2-invalid path * 3-shenanigans * 4-common error */ switch( st ){ case 0 : break ; case 1 : return zuluExit( 6,device,mount_point,stl ) ; case 2 : return zuluExit( 6,device,mount_point,stl ) ; case 3 : return zuluExit( 6,device,mount_point,stl ) ; case 4 : return zuluExit( 6,device,mount_point,stl ) ; default: return zuluExit( 6,device,mount_point,stl ) ; } if( open_mount ){ /* * zuluCryptCreateMountPoint() is defined in create_mount_point.c */ *m_point = zuluCryptCreateMountPoint( device,mount_point,m_opts,uid ) ; mount_point = StringContent( *m_point ) ; if( mount_point == NULL ){ return zuluExit( 9,device,mount_point,stl ) ; } }else{ if( uid != 0 ){ return zuluExit( 7,device,mount_point,stl ) ; } if( mount_point != NULL ){ return zuluExit( 8,device,mount_point,stl ) ; } } if( share ){ /* * zuluCryptBindSharedMountPointPathTaken() is defined in bind.c */ if( zuluCryptBindSharedMountPointPathTaken( *m_point ) ){ return zuluExit_1( 10,opts,device,mount_point,stl ) ; } } /* * zuluCryptCreateMapperName() is defined in ../lib/create_mapper_name.c */ *m_name = zuluCryptCreateMapperName( device,mapping_name,uid,ZULUCRYPTshortMapperPath ) ; *mapper = StringCopy( *m_name ) ; mapper_name = StringContent( *m_name ) ; *mapper_path = String( zuluCryptMapperPrefix() ) ; e = StringMultipleAppend( *mapper_path,"/",mapper_name,NULL ) ; if( stat( e,&statstr ) == 0 ){ return zuluExit_1( 11,opts,device,mount_point,stl ) ; } if( plugin_path != NULL ){ /* * zuluCryptUUIDFromPath() is defined in path_access.c */ uuid = zuluCryptUUIDFromPath( device ) ; device_path = _device_path( device ) ; /* * zuluCryptPluginManagerGetKeyFromModule is defined in ../pluginManager/zuluCryptPluginManager.c */ *passphrase = zuluCryptPluginManagerGetKeyFromModule( device_path,plugin_path,uuid,uid,opts,&st ) ; StringFree( device_path ) ; StringFree( uuid ) ; if( st != 0 || *passphrase == StringVoid ){ return zuluExit_1( 12,opts,device,mount_point,stl ) ; } key_len = StringLength( *passphrase ) ; key = StringContent( *passphrase ) ; zuluCryptSecurityLockMemory_1( *passphrase ) ; }else if( source == NULL && tcrypt_keyfiles[ 0 ] == NULL ){ printf( gettext( "Enter passphrase: " ) ) ; /* * ZULUCRYPT_KEY_MAX_SIZE is set in ../constants.h */ switch( StringSilentlyGetFromTerminal_1( passphrase,ZULUCRYPT_KEY_MAX_SIZE ) ){ case 1 : return zuluExit_1( 13,opts,device,mount_point,stl ) ; case 2 : return zuluExit_1( 14,opts,device,mount_point,stl ) ; } printf( "\n" ) ; key = StringContent( *passphrase ) ; key_len = StringLength( *passphrase ) ; zuluCryptSecurityLockMemory_1( *passphrase ) ; }else{ if( source == NULL || pass == NULL ){ if( tcrypt_keyfiles == NULL ){ return zuluExit_1( 15,opts,device,mount_point,stl ) ; } } if( StringsAreEqual( source,"-p" ) ){ key = pass ; key_len = StringSize( pass ) ; }else if( StringsAreEqual( source,"-f" ) ){ if( StringHasNoComponent( pass,"/.zuluCrypt-socket" ) ){ tcrypt_keyfile = 1 ; } /* * function is defined at "path_access.c" */ switch( zuluCryptGetPassFromFile( pass,uid,data ) ){ case 1 : return zuluExit_1( 16,opts,device,mount_point,stl ) ; case 2 : return zuluExit_1( 17,opts,device,mount_point,stl ) ; case 4 : return zuluExit_1( 18,opts,device,mount_point,stl ) ; case 5 : return zuluExit_1( 19,opts,device,mount_point,stl ) ; } key = StringContent( *data ) ; key_len = StringLength( *data ) ; zuluCryptSecurityLockMemory_1( *data ) ; } } memset( &volume,'\0',sizeof( open_struct_t ) ) ; if( key != NULL ){ volume.key = key ; volume.key_len = key_len ; }else{ volume.key = "" ; volume.key_len = 0 ; } volume.device = device ; volume.offset = offset ; volume.mapper_name = mapper_name ; volume.m_point = mount_point ; volume.fs_opts = fs_opts ; volume.uid = uid ; volume.m_opts = m_opts ; volume.m_flags = m_flags ; /* * zuluCryptTrueCryptVeraCryptVolumeInfo() is defined in this source file. */ zuluCryptTrueCryptVeraCryptVolumeInfo( opts->type,&v_info ) ; volume.iteration_count = v_info.iteration_count ; volume.veraCrypt_volume = StringAtLeastOneMatch( v_info.type,"vcrypt","veracrypt","vera",NULL ) ; StringDelete( &v_info.type ) ; plugin_path = plugin_path + StringLastIndexOfChar_1( plugin_path,'/' ) + 1 ; volume.luks_detached_header = StringHasComponent( plugin_path,"luks" ) ; volume.general_detached_header = StringHasComponent( plugin_path,"generic_header" ) ; if( tcrypt_keyfile ){ volume.key_source = TCRYPT_KEYFILE ; } if( tcrypt_keyfiles[ 0 ] != NULL ){ /* * Here, we take a list of keyfiles supplied by the user and then copy them to a safe * location at "/run/zuluCrypt" and then we pass these safe copies to cryptsetup. * * The idea is not to let cryptsetup, a privileged process handle user managed files. */ stz = zuluCryptCreateKeyFiles( tcrypt_keyfiles,0 ) ; volume.tcrypt_keyfiles_count = StringListSize( stz ) ; volume.tcrypt_keyfiles = StringListStringArray_0( stz ) ; st = _open_volume( &volume ) ; zuluCryptDeleteKeyFiles( stz ) ; StringFree( volume.tcrypt_keyfiles ) ; StringListDelete( &stz ) ; }else{ st = _open_volume( &volume ) ; } /* * below two return values comes from ../lib/mount_volume.c */ if( st == -1 ){ st = 20 ; } if( st == 12 ){ st = 21 ; } if( st == 8 || st == 3 ){ st = 3 ; } device = StringMultiplePrepend( *mapper,"/",zuluCryptMapperPrefix(),NULL ) ; if( st == 0 && share ){ /* * user wish to share the mount point bind the mount point to a publicly accessed path at /run/media/public/ */ /* * zuluCryptBindMountVolume() is defined in ../zuluCrypt-cli/bin/bind.c */ zuluCryptBindMountVolume( device,*m_point,m_flags ) ; } /* * zuluCryptCheckInvalidKey() is defined in check_invalid_key.c */ zuluCryptCheckInvalidKey( opts->device ) ; return zuluExit_1( st,opts,device,mount_point,stl ) ; }
int zuluCryptEXERemoveKey( const struct_opts * opts,uid_t uid ) { int ask_confirmation = opts->ask_confirmation ; const char * device = opts->device ; const char * keyType = opts->key_source ; const char * keytoremove = opts->key ; stringList_t stl = StringListInit() ; string_t * pass = StringListAssign( stl ) ; string_t * confirm = StringListAssign( stl ) ; int status = 0 ; const char * key ; size_t key_size ; /* * zuluCryptPartitionIsSystemPartition() is defined in ./partitions.c */ if( zuluCryptPartitionIsSystemPartition( device,uid ) ){ if( !zuluCryptUserIsAMemberOfAGroup( uid,"zulucrypt" ) ){ return zuluExit( 4,stl ) ; } } /* * zuluCryptCanOpenPathForWriting is defined in path_access.c */ status = zuluCryptCanOpenPathForWriting( device,uid ) ; /* * 1-permissions denied * 2-invalid path * 3-shenanigans * 4-common error */ switch( status ){ case 0 : break ; case 1 : return zuluExit( 5,stl ) ; case 2 : return zuluExit( 5,stl ) ; case 3 : return zuluExit( 5,stl ) ; case 4 : return zuluExit( 5,stl ) ; default: return zuluExit( 5,stl ) ; } if( _zuluCryptExECheckEmptySlots( device ) == 3 ){ if( ask_confirmation ){ printf( gettext( "WARNING: There is only one key in the volume and all data in it will be lost if you continue.\n" ) ) ; printf( gettext( "Do you still want to continue? Type \"YES\" if you do: " ) ) ; *confirm = StringGetFromTerminal_1( 3 ) ; if( *confirm == StringVoid ){ return zuluExit( 6,stl ) ; } if( !StringEqual( *confirm,gettext( "YES" ) ) ){ return zuluExit( 7,stl ) ; } } } if( keyType == NULL ){ printf( gettext( "Enter a key to be removed: " ) ) ; /* * ZULUCRYPT_KEY_MAX_SIZE is set in ../constants.h */ switch( StringSilentlyGetFromTerminal_1( pass,ZULUCRYPT_KEY_MAX_SIZE ) ){ case 1 : return zuluExit( 8,stl ) ; case 2 : return zuluExit( 9,stl ) ; } printf( "\n" ) ; key = StringContent( *pass ) ; key_size = StringLength( *pass ) ; zuluCryptSecurityLockMemory_1( *pass ) ; }else{ if( keyType == NULL || keytoremove == NULL ){ return zuluExit( 10,stl ) ; } if( StringsAreEqual( keyType,"-f" ) ){ /* * zuluCryptGetPassFromFile() is defined at path_access.c" */ switch( zuluCryptGetPassFromFile( keytoremove,uid,pass ) ){ case 1 : return zuluExit( 11,stl ) ; case 2 : return zuluExit( 12,stl ) ; case 4 : return zuluExit( 13,stl ) ; case 5 : return zuluExit( 14,stl ) ; } key = StringContent( *pass ) ; key_size = StringLength( *pass ) ; zuluCryptSecurityLockMemory_1( *pass ) ; }else if( StringsAreEqual( keyType, "-p" ) ){ key = keytoremove ; key_size = StringSize( keytoremove ) ; }else{ return zuluExit( 10,stl ) ; } } zuluCryptSecurityGainElevatedPrivileges() ; /* * zuluCryptRemoveKey() is defined in ../lib/remove_key.c */ status = zuluCryptRemoveKey( device,key,key_size ) ; zuluCryptSecurityDropElevatedPrivileges() ; if( status == 1 ){ status = zuluExit_1( status,device,stl ) ; }else{ status = zuluExit( status,stl ) ; } /* * zuluCryptCheckInvalidKey() is defined in check_invalid_key.c */ zuluCryptCheckInvalidKey( opts->device ) ; return status ; }