/* * this function will parse /etc/crypttab to see if it has any entries to be used as system partition. * * sample example of the file content this function was build on. * * secret /dev/sda15 none * secret_1 UUID=d2d210b8-0b1f-419f-9172-9d509ea9af0c none * */ stringList_t zuluCryptGetPartitionFromCrypttab( void ) { stringList_t stl = StringListVoid ; stringList_t stl_1 = StringListVoid ; stringList_t stz ; string_t st ; StringListIterator it ; StringListIterator end ; st = StringGetFromFile( "/etc/crypttab" ) ; stl = StringListStringSplit( st,'\n' ) ; StringDelete( &st ) ; StringListGetIterators( stl,&it,&end ) ; while( it != end ){ st = *it ; it++ ; if( !StringStartsWith( st,"#" ) ){ stz = StringListStringSplit( st,' ' ) ; st = StringListStringAtSecondPlace( stz ) ; stl_1 = _eval_path( st,stl_1 ) ; StringListDelete( &stz ) ; } } StringListDelete( &stl ) ; return stl_1 ; }
static int _zuluCryptUnmountVolume_0( string_t st,char ** m_point ) { int h ; stringList_t stl = StringListStringSplit( st,' ' ) ; StringListIterator it = StringListBegin( stl ) ; /* * zuluCryptDecodeMountEntry() is defined in mount_volume.c */ const char * mout_point = zuluCryptDecodeMountEntry( *( it + 1 ) ) ; if( StringContains( *( it + 2 ),"fuse" ) ){ /* * Dont know whats going on but FUSE based file systems do not seem to work with umount() */ h = _unmount( _unmount_fuse,mout_point ) ; }else{ h = _unmount( _unmount_rest,mout_point ) ; } if( h == 0 && m_point != NULL ){ *m_point = StringCopy_2( mout_point ) ; } StringListDelete( &stl ) ; return h ; }
static int _fileSystemIsSupported( const char * fs ) { string_t st = StringGetFromVirtualFile( "/proc/filesystems" ) ; stringList_t stl = StringListStringSplit( st,'\n' ) ; StringListIterator it = StringListBegin( stl ) ; StringListIterator end = StringListEnd( stl ) ; string_t xt ; int r = 0 ; while( it != end ){ xt = *it ; it++ ; if( !StringStartsWith( xt,"nodev" ) ){ if( StringContains( xt,fs ) ){ r = 1 ; break ; } } } StringDelete( &st ) ; StringListDelete( &stl ) ; return r ; }
static inline int _option_contain_not_allowed( const char * fs,const char * fs_opts ) { stringList_t stl = StringListSplit( fs_opts,',' ) ; int r = 1 ; if( stl != StringListVoid ){ if( StringHasAtLeastOneComponent_1( fs,"fat","dos",NULL ) ){ r = allowed_vfat( stl ) ; }else if( StringsAreEqual( fs,"ntfs" ) ){ r = allowed_ntfs( stl ) ; }else if( StringsAreEqual( fs,"udf" ) ){ r = allowed_udf( stl ) ; }else if( StringsAreEqual( fs,"iso9660" ) ){ r = allowed_iso9660( stl ) ; }else if( StringsAreEqual( fs,"btrfs" ) ){ r = allowed_btrfs( stl ) ; }else{ r = 1 ; } StringListDelete( &stl ) ; }else{ r = 1 ; } return r ; }
int zuluCryptVolumeIsInSystemVolumeList( const char * device ) { stringList_t p = zuluCryptGetPartitionFromConfigFile( "/etc/zuluCrypt/system_volumes.list" ) ; int r = StringListHasEntry( p,device ) ; StringListDelete( &p ) ; return r ; }
static string_t _get_mapper_property_from_udev( const char * mapper,const char * prefix,size_t position ) { DIR * dir = opendir( "/dev/disk/by-id/" ) ; struct dirent * e ; const char * f = mapper + StringSize( crypt_get_dir() ) + 1 ; stringList_t stl ; string_t st = StringVoid ; if( dir != NULL ){ while( ( e = readdir( dir ) ) != NULL ){ if( StringStartsAndEndsWith( e->d_name,prefix,f ) ){ stl = StringListSplit( e->d_name,'-' ) ; st = StringListCopyStringAt( stl,position ) ; StringListDelete( &stl ) ; break ; } } closedir( dir ) ; } return st ; }
static char * _zuluCryptResolveDevRoot( void ) { const char * e ; char * dev ; string_t st = StringGetFromVirtualFile( "/proc/cmdline" ) ; stringList_t stl = StringListStringSplit( st,' ' ) ; StringDelete( &st ) ; st = StringListHasSequence_1( stl,"root=/dev/" ) ; if( st != StringVoid ){ e = StringContent( st ) + 5 ; dev = zuluCryptResolvePath( e ) ; }else{ st = StringListHasSequence_1( stl,"root=UUID=" ) ; if( st != StringVoid ){ /* * zuluCryptDeviceFromUUID() is defined in ./blkid_evaluate_tag.c */ e = StringContent( st ) + 10 ; dev = zuluCryptDeviceFromUUID( e ) ; }else{ dev = NULL ; } } StringListDelete( &stl ) ; return dev ; }
stringList_t zuluCryptGetPartitionFromConfigFile( const char * path ) { StringListIterator it ; StringListIterator end ; stringList_t stl ; stringList_t stl_1 = StringListVoid ; string_t st = StringVoid ; zuluCryptSecurityGainElevatedPrivileges() ; st = StringGetFromFile( path ) ; zuluCryptSecurityDropElevatedPrivileges() ; stl = StringListStringSplit( st,'\n' ) ; StringDelete( &st ) ; StringListGetIterators( stl,&it,&end ) ; while( it != end ){ stl_1 = _eval_path( *it,stl_1 ) ; it++ ; } StringListDelete( &stl ) ; return stl_1 ; }
string_t zuluCryptGetMountEntry( const char * path ) { stringList_t stl = zuluCryptGetMoutedList() ; string_t st = zuluCryptGetMountEntry_1( stl,path ) ; StringListDelete( &stl ) ; return st ; }
int zuluCryptOpenPlain_2( const char * device,const char * mapper, const char * mode,const char * key,size_t key_len, const char * options ) { open_struct_t opt ; stringList_t stl ; int r ; char * const * e = NULL ; size_t n = 0 ; args s = { "/dev/urandom","aes","cbc-essiv:sha256","256","ripemd160","0" } ; memset( &opt,'\0',sizeof( open_struct_t ) ) ; opt.device = device ; opt.mapper_name = mapper ; opt.key = key ; opt.key_len = key_len ; opt.m_opts = mode ; opt.variables = &s ; stl = StringListSplit( options,'.' ) ; StringListStringArray_1( &e,&n,stl ) ; if( n == 6 ){ s.rng = *( e + 0 ) ; s.algo = *( e + 1 ) ; s.cipher = *( e + 2 ) ; s.keySize = *( e + 3 ) ; s.hash = *( e + 4 ) ; s.offset = *( e + 5 ) ; }else if( n == 5 ){ s.algo = *( e + 0 ) ; s.cipher = *( e + 1 ) ; s.keySize = *( e + 2 ) ; s.hash = *( e + 3 ) ; s.offset = *( e + 4 ) ; } /* * zuluCryptResolveDevicePath_0() is defined in resolve_path.c */ r = zuluCryptResolveDevicePath_0( _open_plain,&opt,2 ) ; StringListDelete( &stl ) ; StringFree( e ) ; return r ; }
int _zuluCryptPartitionIsSystemPartition( const char * dev,uid_t uid ) { stringList_t stl ; int r = 0 ; stl = zuluCryptPartitions( ZULUCRYPTsystemPartitions,uid ) ; if( stl != StringListVoid ){ r = StringListHasEntry( stl,dev ) ; StringListDelete( &stl ) ; } return r ; }
static int _mounted( ssize_t( *function )( stringList_t,const char * ),string_t st ) { stringList_t stl = zuluCryptGetMoutedList() ; ssize_t r = function( stl,StringContent( st ) ) ; StringListDelete( &stl ) ; StringDelete( &st ) ; return r != -1 ; }
static stringList_t _volumeList( string_t ( *function )( const vInfo * ) ) { char * const * entry = NULL ; size_t entry_len = 0 ; stringList_t tmp ; stringList_t stx = StringListVoid ; stringList_t stl ; StringListIterator it ; StringListIterator end ; string_t st = StringGetFromVirtualFile( "/proc/self/mountinfo" ) ; stl = StringListStringSplit( st,'\n' ) ; StringDelete( &st ) ; StringListGetIterators( stl,&it,&end ) ; while( it != end ) { tmp = StringListStringSplit( *it,' ' ) ; it++ ; stx = _add_entry( stx,tmp,function,&entry,&entry_len ) ; StringListDelete( &tmp ) ; } StringFree( entry ) ; StringListDelete( &stl ) ; return stx ; }
static void _get_file_system_options_from_config_file( const char * device,string_t st ) { char * f ; const char * e ; StringListIterator it ; StringListIterator end ; string_t xt = StringGetFromFile( "/etc/zuluCrypt/fs_options" ) ; stringList_t stl = StringListStringSplit( xt,'\n' ) ; stringList_t stz ; StringDelete( &xt ) ; f = _get_uuid_from_device( device ) ; StringListGetIterators( stl,&it,&end ) ; while( it != end ){ e = StringRemoveString( *it,"\"" ) ; it++ ; if( StringPrefixMatch( e,"UUID=",5 ) ){ if( StringPrefixEqual( e + 5,f ) ){ stz = StringListSplit( e,' ' ) ; e = StringListContentAtSecondPlace( stz ) ; StringMultipleAppend( st,",",e,NULL ) ; StringListDelete( &stz ) ; break ; } } } StringListDelete( &stl ) ; StringFree( f ) ; }
char * zuluCryptGetMountPointFromPath( const char * path ) { string_t st = zuluCryptGetMountEntry( path ) ; stringList_t stl ; if( st == StringVoid ) { return NULL ; } else { stl = StringListStringSplit( st,' ' ) ; StringDelete( &st ) ; if( stl == StringListVoid ) { return NULL ; } else { st = StringListCopyStringAtSecondPlace( stl ) ; StringListDelete( &stl ) ; zuluCryptDecodeMountEntry( st ) ; return StringDeleteHandle( &st ) ; } } }
int zuluCryptPrintPartitions( int option,int info,uid_t uid ) { stringList_t stl = StringListVoid ; switch( option ){ case 1 : stl = zuluCryptPartitions( ZULUCRYPTallPartitions,uid ) ;break ; case 2 : stl = zuluCryptPartitions( ZULUCRYPTsystemPartitions,uid ) ;break ; case 3 : stl = zuluCryptPartitions( ZULUCRYPTnonSystemPartitions,uid ) ;break ; } if( stl != StringListVoid ){ switch( info ){ case 1 : StringListForEachString( stl,zuluCryptPrintPartitionProperties ) ; break ; case 2 : _zuluCryptPrintUnMountedPartitionProperties( stl ) ; break ; default: _print_list( stl ) ; } StringListDelete( &stl ) ; } return 0 ; }
int zuluCryptDeviceIsSupported( const char * device,uid_t uid ) { stringList_t stl ; int r ; if( StringPrefixEqual( device,"/dev/loop" ) ){ return 1 ; }else{ stl = zuluCryptPartitions( ZULUCRYPTallPartitions,uid ) ; r = StringListHasEntry( stl,device ) ; StringListDelete( &stl ) ; if( r == 1 ){ return 1 ; }else{ /* * zuluCryptUserIsAMemberOfAGroup() is defined in security.c */ return zuluCryptUserIsAMemberOfAGroup( uid,"zulucrypt" ) ; } } }
void zuluCryptTrueCryptVeraCryptVolumeInfo( const char * type,tvcrypt * e ) { stringList_t stl = StringListSplit( type,'.' ) ; size_t p = StringListSize( stl ) ; const char * q ; memset( e,'\0',sizeof( tvcrypt ) ) ; if( p > 0 ){ e->type = StringListCopyStringAtFirstPlace( stl ) ; if( p > 1 ){ q = StringListContentAtSecondPlace( stl ) ; e->iteration_count = ( int )StringConvertToInt( q ) ; } } StringListDelete( &stl ) ; }
static void _zuluCryptPrintUnMountedPartitionProperties( stringList_t stl ) { /* * zuluCryptGetMoutedList() is defined in ../lib/process_mountinfo.c */ stringList_t stx = zuluCryptGetMoutedList() ; StringListIterator it ; StringListIterator end ; string_t st ; StringListGetIterators( stl,&it,&end ) ; while( it != end ){ st = *it ; it++ ; if( StringListHasStartSequence( stx,StringAppend( st," " ) ) == -1 ){ zuluCryptPrintPartitionProperties( StringRemoveRight( st,1 ) ) ; } } StringListDelete( &stx ) ; }
int zuluCryptBindUnmountVolume( stringList_t stx,const char * device,uid_t uid ) { stringList_t stl ; string_t xt ; string_t st ; string_t zt ; ssize_t index = -1 ; const char * f ; const char * g ; char * h = NULL ; int r = 1 ; int k ; int delete_stx = 0 ; /* * zuluCryptUserIsAMemberOfAGroup() is defined in security.c */ /* * root user is a member of all groups and hence is allowed */ int allowedUser = zuluCryptUserIsAMemberOfAGroup( uid,"zulumount" ) ; zuluCryptSecurityGainElevatedPrivileges() ; if( stx == StringListVoid ){ /* * zuluCryptGetMoutedListFromMountInfo() is defined in ../lib/process_mountinfo.c */ stx = zuluCryptGetMoutedListFromMountInfo() ; delete_stx = 1 ; } if( StringPrefixEqual( device,"/dev/loop" ) ){ /* * zuluCryptLoopDeviceAddress_2() is defined in ../lib/create_loop_device.c */ st = zuluCryptLoopDeviceAddress_2( device ) ; /* * Add a space at the end of the device name to make sure we check the full device name to avoid possible collisions * that may exist if one device is named "/home/abc" and another "/home/abcdef" */ zt = StringListHasStartSequence_1( stx,StringAppend( st," " ) ) ; StringRemoveRight( st,1 ) ; device = h = StringDeleteHandle( &st ) ; }else{ /* * Add a space at the end of the device name to make sure we check the full device name to avoid possible collisions * that may exist if one device is named "/dev/sdc1" and another "/dev/sdc12" */ st = String( device ) ; zt = StringListHasStartSequence_1( stx,StringAppend( st," " ) ) ; StringDelete( &st ) ; } if( zt == StringVoid ){ /* * The volume does not appear to be mounted */ r = 1 ; }else{ stl = StringListStringSplit( zt,' ' ) ; xt = StringListCopyStringAtSecondPlace( stl ) ; StringListDelete( &stl ) ; st = StringCopy( xt ) ; /* * zuluCryptDecodeMountEntry() is defined in ../lib/mount_volume.c * g will contain something like "/run/media/private/$USER/sdc1" */ g = zuluCryptDecodeMountEntry( st ) ; if( allowedUser ){ /* * a privileged user is attempting to unmount a shared mount point,allow them */ k = 1 ; }else{ /* * a non privileged user is attempting to unmount a shared mount point,allow them only if * they are the one that created it */ /* * zuluCryptSecurityMountPointPrefixMatch() is defined in ./security.c */ k = zuluCryptMountPointPrefixMatch( g,uid,NULL ) ; } StringDelete( &st ) ; if( k != 1 ){ /* * One none privileged user is attempting to unmount a bind mount from another use,disallow it */ r = 4 ; }else{ index = StringLastIndexOfChar( xt,'/' ) + 1 ; StringRemoveLeft( xt,index ) ; StringPrepend( xt,"/run/media/public/" ) ; /* * f will now contain something like "/run/media/public/sdc1" * space character is added before checking to avoid possible collisions * as explained in above comments */ f = StringAppend( xt," " ) ; zt = StringListHasSequence_1( stx,f ) ; f = StringRemoveRight( xt,1 ) ; if( zt == StringVoid ){ /* * volume is not shared */ }else{ /* * volume is shared,try to unmount it * a volume is assumed to be shared if its device path in mountinfo has two mount points,one * in /run/media/private/$USER and the other in /run/media/public/ */ if( StringStartsWith( zt,device ) ){ f = zuluCryptDecodeMountEntry( xt ) ; /* * good,the device associated with the shared mount is the same as that of the * private mount,try to unmount it. */ r = 3 ; for( k = 0 ; k < 3 ; k++ ){ /* * try to unmount 3 times before giving up */ if( umount( f ) == 0 ){ rmdir( f ) ; r = 0 ; break ; }else{ sleep( 1 ) ; } } }else{ /* * i dont see how we will get here,we shouldnt */ r = 0 ; } } } StringDelete( &xt ) ; } if( delete_stx ){ StringListDelete( &stx ) ; } StringFree( h ) ; zuluCryptSecurityDropElevatedPrivileges() ; return r ; }
stringList_t zuluCryptOpenedVolumesList( uid_t uid ) { const char * e ; const char * c ; const char * d ; const char * t ; char * f ; char * g ; StringListIterator it ; StringListIterator end ; ssize_t k ; string_t q ; string_t z ; string_t j ; stringList_t stx ; stringList_t list = StringListVoid ; stringList_t stl = zuluCryptGetMoutedList() ; if( uid ) { ; } /* * zuluCryptMapperPrefix() is defined in create_mapper_name.c */ j = String_1( zuluCryptMapperPrefix(),"/zuluCrypt-",NULL ) ; /* * t will probably contain "/dev/mapper/zuluCrypt-" */ t = StringContent( j ) ; StringListGetIterators( stl,&it,&end ) ; while( it != end ) { c = StringContent( *it ) ; it++ ; if( StringPrefixNotEqual( c,t ) ) { /* * we only care about zuluCrypt volumes and these volumes that we care about starts with * "/dev/mapper/zuluCrypt-" */ continue ; } if( StringHasComponent( c,"/run/media/public/" ) ) { /* * dont show mirror images due to bind mounts */ continue ; } stx = StringListSplit( c,' ' ) ; e = StringListContentAtFirstPlace( stx ) ; k = StringHasComponent_1( e,"-UUID-" ) ; if( k != -1 ) { q = StringListStringAtFirstPlace( stx ) ; /* * zuluCryptDecodeMountEntry() is defined in mount_volume.c */ d = zuluCryptDecodeMountEntry( StringListStringAtSecondPlace( stx ) ) ; /* * zuluCryptGetVolumeTypeFromMapperPath() is defined in status.c */ f = zuluCryptGetVolumeTypeFromMapperPath( StringContent( q ) ) ; e = StringSubChar( q,StringLastIndexOfChar( q,'-' ),'\0' ) + k + 6 ; z = String_1( "UUID=\"",e,"\"\t",d,"\t",f,NULL ) ; list = StringListAppendString_1( list,&z ) ; StringFree( f ) ; } else { /* * zuluCryptVolumeDeviceName() is defined in status.c */ g = zuluCryptVolumeDeviceName( e ) ; if( g != NULL ) { d = zuluCryptDecodeMountEntry( StringListStringAtSecondPlace( stx ) ) ; /* * zuluCryptGetVolumeTypeFromMapperPath() is defined in status.c */ f = zuluCryptGetVolumeTypeFromMapperPath( StringListContentAtFirstPlace( stx ) ) ; z = String_1( g,"\t",d,"\t",f,NULL ) ; list = StringListAppendString_1( list,&z ) ; StringFree( f ) ; StringFree( g ) ; } } StringListDelete( &stx ) ; } StringListDelete( &stl ) ; StringDelete( &j ) ; return list ; }
stringList_t zuluCryptPartitions( int option,uid_t uid ) { const char * device ; const char * e ; stringList_t non_system = StringListVoid ; stringList_t system = StringListVoid ; string_t st ; stringList_t p ; stringList_t stl = zuluCryptVolumeList() ; StringListIterator it ; StringListIterator end ; if( stl == StringListVoid ){ return StringListVoid ; } if( option == ZULUCRYPTallPartitions ){ return _remove_btfs_multiple_devices( stl ) ; } non_system = stl ; zuluCryptSecurityGainElevatedPrivileges() ; /* * zuluCryptGetFstabList() is defined in ../lib/parse_fstab.c */ stl = zuluCryptGetFstabList( uid ) ; zuluCryptSecurityDropElevatedPrivileges() ; StringListGetIterators( stl,&it,&end ) ; /* * gather an initial list of system and non system partitions by comparing entries in "/etc/fstab" and "/proc/partitions" * fstab entries makes an initial list of system partitions. * the difference btw list in "/proc/partitions" and "/etc/fstab" makes an initial list of non system partitions. */ while( it != end ){ st = *it ; it++ ; if( StringStartsWith( st,"/" ) ){ device = StringReplaceChar_1( st,0,' ','\0' ) ; system = StringListAppend( system,device ) ; StringListRemoveString( non_system,device ) ; } } StringListDelete( &stl ) ; /* * read entried from "crypttab" and then add them to "system" if absent in that list and remove them from "non system" if present * in that list */ p = zuluCryptGetPartitionFromCrypttab() ; if( p != StringListVoid ){ StringListGetIterators( p,&it,&end ) ; while( it != end ){ device = StringContent( *it ) ; it++ ; StringListAppendIfAbsent( system,device ) ; StringListRemoveIfPresent( non_system,device ) ; } StringListDelete( &p ) ; } /* * read entried from "zuluCrypt-system" and then add them to "system" if absent in that list and remove them from "non system" if present * in that list */ p = zuluCryptGetPartitionFromConfigFile( "/etc/zuluCrypt-system" ) ; if( p == StringListVoid ){ /* * This is the new path since zuluCrypt 4.6.9 */ p = zuluCryptGetPartitionFromConfigFile( "/etc/zuluCrypt/system_volumes.list" ) ; } if( p != StringListVoid ){ StringListGetIterators( p,&it,&end ) ; while( it != end ){ device = StringContent( *it ) ; it++ ; StringListAppendIfAbsent( system,device ) ; StringListRemoveIfPresent( non_system,device ) ; } StringListDelete( &p ) ; } /* * At this point: * "system" contains system devices gathered from fstab,zuluCrypt-system and crypttab * "non_system" contains non system devices gathered from /proc/partitions minus system partitions. */ StringListGetIterators( non_system,&it,&end ) ; /* * now we consult udev if enabled and we move partition in the "non system" list to "system" list if udev think they are system */ while( it != end ){ e = StringContent( *it ) ; if( _zuluCryptCheckSYSifDeviceIsSystem( e ) ){ StringListAppendIfAbsent( system,e ) ; StringListRemoveAt_1( non_system,it,&end ) ; }else{ it++ ; } } /* * Now we read from a config file that contains devices that are not to be considered system and remove them from * the system list if present in that list and add them to non system list if absent in that list */ p = zuluCryptGetPartitionFromConfigFile( "/etc/zuluCrypt-nonsystem" ) ; if( p == StringListVoid ){ /* * This is the new path since zuluCrypt 4.6.9 */ p = zuluCryptGetPartitionFromConfigFile( "/etc/zuluCrypt/nonsystem_volumes.list" ) ; } if( p != StringListVoid ){ StringListGetIterators( p,&it,&end ) ; while( it != end ){ device = StringContent( *it ) ; it++ ; StringListRemoveString( system,device ) ; StringListAppendIfAbsent( non_system,device ) ; } StringListDelete( &p ) ; } if( option == ZULUCRYPTsystemPartitions ){ StringListDelete( &non_system ) ; return _remove_btfs_multiple_devices( system ) ; }else{ StringListDelete( &system ) ; return _remove_btfs_multiple_devices( non_system ) ; } }
u_int64_t zuluCryptGetVolumeSize( const char * device ) { stringList_t stl = StringListVoid ; StringListIterator it ; StringListIterator end ; string_t xt ; const char * e ; u_int64_t r = 0 ; blkid_probe blkid = blkid_new_probe_from_filename( device ) ; if( blkid == NULL ){ return 0 ; } e = NULL ; blkid_do_probe( blkid ) ; blkid_probe_lookup_value( blkid,"TYPE",&e,NULL ) ; if( StringsAreNotEqual( e,"btrfs" ) ){ r = blkid_probe_get_size( blkid ) ; blkid_free_probe( blkid ) ; return r ; }else{ /* * we got a btrfs volume,this device could be one among a bunch of devices that makes the btfs volume. * iterate through all known devices and add their sizes to this device if they are a part of the same * btrfs volume. */ e = NULL ; if( blkid_probe_lookup_value( blkid,"UUID",&e,NULL ) == 0 ){ xt = String( e ) ; }else{ xt = StringVoid ; } blkid_free_probe( blkid ) ; if( xt == StringVoid ){ return 0 ; }else{ /* * zuluCryptVolumeList() is defined in this source file */ stl = zuluCryptVolumeList() ; zuluCryptSecurityGainElevatedPrivileges() ; StringListGetIterators( stl,&it,&end ) ; while( it != end ){ blkid = blkid_new_probe_from_filename( StringContent( *it ) ) ; it++ ; if( blkid != NULL ){ blkid_do_probe( blkid ) ; e = NULL ; if( blkid_probe_lookup_value( blkid,"UUID",&e,NULL ) == 0 ){ if( StringEqual( xt,e ) ){ r += blkid_probe_get_size( blkid ) ; } } blkid_free_probe( blkid ) ; } } StringDelete( &xt ) ; StringListDelete( &stl ) ; return r ; } } }
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 zuluCryptUnmountVolume( const char * device,char ** m_point ) { int h = 3 ; char * e ; size_t s ; stringList_t stl ; StringListIterator it ; StringListIterator end ; ssize_t r ; string_t st ; string_t xt ; if( StringPrefixEqual( device,"/dev/loop" ) ){ /* * zuluCryptLoopDeviceAddress() is defined in create_loop_device.c */ e = zuluCryptLoopDeviceAddress( device ) ; if( e == NULL ){ return h ; }else{ stl = _get_mount_entries( e ) ; StringFree( e ) ; } }else{ stl = _get_mount_entries( device ) ; } s = StringListSize( stl ) ; if( s == 0 ){ /* * volume appear to not be mounted. */ }else if( s == 1 ){ /* * there is only one mount point for the volume,unmount it normally */ h = _zuluCryptUnmountVolume_0( StringListStringAtFirstPlace( stl ),m_point ) ; }else{ /* * There are multiple mount points for the same volume. * * Try to figure out which one among the mount points is ours and then try * first to unmount the rest of them. */ r = StringListHasSequence( stl," /run/media/private/" ) ; if( r == -1 ){ /* * Probable reason for getting here is if a user use a home mount point path, * we dont know the path because we dont know the user we are serving * and hence we bail out with an error. */ h = 10 ; }else{ /* * We got our mount point,take it out of the list to use it last */ st = StringListDetachAt( stl,r ) ; StringListGetIterators( stl,&it,&end ) ; while( it != end ){ xt = *it ; it++ ; if( _zuluCryptUnmountVolume_0( xt,NULL ) != 0 ){ /* * Failed to unmount one of the extra mount points, * bail out with an error. */ h = 10 ; break ; } } if( h != 10 ){ /* * Attempt to unmount our mount point last. */ h = _zuluCryptUnmountVolume_0( st,m_point ) ; } StringDelete( &st ) ; } } if( h != 0 && h != 3 && h != 4 && h != 1 && h != 10 ){ h = 2 ; } StringListDelete( &stl ) ; return h ; }
static int _replace_truecrypt_key( const tcrypt_opts * opts ) { info_t info ; string_t st = StringVoid ; string_t xt = StringVoid ; int r ; stringList_t stl ; memset( &info,'\0',sizeof( info_t ) ) ; stl = veraCryptVolumePIMValue( &info,opts->type ) ; info.device = opts->device ; /* * zuluCryptCreateKeyFile() is defined in ../lib/open_tcrypt.c */ if( opts->existing_key_is_keyfile ){ info.header_key_source = "keyfiles" ; st = zuluCryptCreateKeyFile( opts->existing_key,opts->existing_key_size,"add-tcrypt-1" ) ; info.header_key = StringContent( st ) ; }else{ info.header_key_source = "passphrase" ; info.header_key = opts->existing_key ; } if( opts->new_key_is_keyfile ){ info.header_new_key_source = "new_keyfiles" ; st = zuluCryptCreateKeyFile( opts->new_key,opts->new_key_size,"add-tcrypt-2" ) ; info.header_new_key = StringContent( st ) ; }else{ info.header_new_key_source = "new_passphrase" ; info.header_new_key = opts->new_key ; } info.rng = "/dev/urandom" ; /* * zuluCryptModifyTcryptHeader() is defined in ../lib/create_tcrypt.c */ r = zuluCryptModifyTcryptHeader( &info ) ; /* * zuluCryptDeleteFile_1() is defined in ../lib/file_path_security.c */ if( st != StringVoid ){ zuluCryptDeleteFile_1( st ) ; StringDelete( &st ) ; } if( xt != StringVoid ){ zuluCryptDeleteFile_1( xt ) ; StringDelete( &xt ) ; } StringListDelete( &stl ) ; if( r == 0 ){ return 0 ; }else{ return 1 ; } }
int zuluCryptBindMountVolume( const char * device,string_t z_path,unsigned long flags ) { struct stat st ; string_t path ; string_t tmp ; ssize_t index = StringLastIndexOfChar( z_path,'/' ) ; const char * o_path = StringContent( z_path ) ; const char * m_path ; const char * e ; int xt ; stringList_t stl ; mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH | S_IROTH ; if( index == -1 ){ return 1 ; } if( device ){;} zuluCryptSecurityGainElevatedPrivileges() ; /* * zuluCryptGetMoutedListFromMountInfo() is defined in ../lib/process_mountinfo.c */ stl = zuluCryptGetMoutedListFromMountInfo() ; path = String( "/run/media/public/" ) ; m_path = StringAppend( path,o_path + index + 1 ) ; #define path_does_not_exist( x ) stat( x,&st ) != 0 #define path_does_exist( x ) stat( x,&st ) == 0 if( path_does_not_exist( "/run" ) ){ mkdir( "/run",mode ) ; _chown( "/run",0,0 ) ; } if( path_does_not_exist( "/run/media" ) ){ mkdir( "/run/media",mode ) ; _chown( "/run/media",0,0 ) ; } if( path_does_not_exist( "/run/media/public" ) ){ mkdir( "/run/media/public",mode ) ; _chown( "/run/media/public",0,0 ) ; } if( path_does_exist( m_path ) ){ /* * bind mount point exists,this will happen if the mount point is already taken or a mount point folder * was not autodeleted for some reason */ tmp = StringCopy( path ) ; e = StringAppend( tmp," " ) ; if( StringListHasSequence( stl,e ) != -1 ){ /* * An attempt is made to bind mount on a path already bind mounted path,dont attempt to mount */ xt = 1 ; }else{ /* * the mount point folder is there for some reason but is not being used. */ xt = mount( o_path,m_path,"",flags|MS_BIND,"" ) ; } StringDelete( &tmp ) ; }else{ mkdir( m_path,S_IRWXU | S_IRWXG | S_IRWXG ) ; _chown( m_path,0,0 ) ; xt = mount( o_path,m_path,"",flags|MS_BIND,"" ) ; if( xt != 0 ){ rmdir( m_path ) ; } } StringListDelete( &stl ) ; StringDelete( &path ) ; zuluCryptSecurityDropElevatedPrivileges() ; return xt ; }