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 ; }
static stringList_t _get_mount_entries( const char * device ) { /* * zuluCryptGetMountEntry() is defined in mountinfo.c */ stringList_t stl = zuluCryptGetMoutedList() ; StringListIterator it ; StringListIterator end ; string_t st = String_1( device," ",NULL ) ; StringListGetIterators( stl,&it,&end ) ; while( it != end ){ if( StringStartsWith_1( *it,st ) ){ it++ ; }else{ StringListRemoveAt_1( stl,it,&end ) ; } } StringDelete( &st ) ; return stl ; }
static void _print_list( stringList_t stl ) { const char * e ; char * z ; StringListIterator it ; StringListIterator end ; StringListGetIterators( stl,&it,&end ) ; while( it != end ){ e = StringContent( *it ) ; it++ ; if( StringPrefixEqual( e,"/dev/loop" ) ){ /* * zuluCryptLoopDeviceAddress_1() is defined in ../lib/create_loop_device.c */ z = zuluCryptLoopDeviceAddress_1( e ) ; if( z != NULL ){ puts( z ) ; StringFree( z ) ; }else{ puts( e ) ; } }else{ puts( e ) ; } } }
/* * 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 ; }
void zuluCryptSecurityLockMemory( stringList_t stl ) { StringListIterator it ; StringListIterator end ; string_t st ; StringListGetIterators( stl,&it,&end ) ; while( it != end ){ st = *it ; it++ ; mlock( StringContent( st ),StringLength( st ) ) ; } }
/* * This routine will remove root addresses of a device if the device is found to contain partitions * and will leave the root path if the device is found to not contains partitions. * * Example: * A device with only "/dev/sdc" path will be left alone. * A device with "/dev/sdc" path together with "/dev/sdc1","/dev/sdc2","/dev/sdcN" will cause the * "/dev/sdc" path to be dropped. * * The rationale is that there is nothing useful in the root path if it has partitions beacuse all * useful contents are in partitions.A device with no partitions probably means the useful content is * on the root path */ static stringList_t _remove_root_devices( stringList_t stl ) { StringListIterator it ; StringListIterator end ; StringListGetIterators( stl,&it,&end ) ; while( it != end ){ if( _not_removed( stl,it,&end ) ){ it++ ; } } return stl ; }
void zuluCryptDeleteKeyFiles( stringList_t stl ) { StringListIterator it ; StringListIterator end ; StringListGetIterators( stl,&it,&end ) ; zuluCryptSecurityGainElevatedPrivileges() ; while( it != end ){ /* * zuluCryptDeleteFile_1() is defined in ../lib/file_path_security.c */ zuluCryptDeleteFile_1( *it ) ; it++ ; } zuluCryptSecurityDropElevatedPrivileges() ; }
void zuluCryptSecuritySanitizeTheEnvironment( uid_t uid,stringList_t * stx ) { extern char ** environ ; const char ** env = ( const char ** ) environ ; ssize_t index ; stringList_t stl = StringListVoid ; string_t st ; StringListIterator it ; StringListIterator end ; if( uid ){;} /* * First,we make a copy of the enviromental varibales * Second,we clear the enviromental variable because we dont want it * Third,we return a copy of the enviromental variable because we want to pass it along * the plugins */ while( *env ){ stl = StringListAppend( stl,*env ) ; env++ ; } StringListGetIterators( stl,&it,&end ) ; while( it != end ){ st = *it ; it++ ; index = StringIndexOfChar( st,0,'=' ) ; if( index >= 0 ){ unsetenv( StringSubChar( st,index,'\0' ) ) ; StringSubChar( st,index,'=' ) ; } } *stx = stl ; }
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 ; }
void zuluCryptSecurityUnlockMemory( stringList_t stl ) { StringListIterator it ; StringListIterator end ; string_t st ; void * e ; size_t f ; StringListGetIterators( stl,&it,&end ) ; while( it != end ){ st = *it ; it++ ; if( st != StringVoid ){ e = ( void * )StringContent( st ) ; f = StringLength( st ) ; memset( e,'\0',f ) ; munlock( e,f ) ; } } }
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 ) ; }
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 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 ; }
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 ; }
/* * It is possible for a btrfs volume to cover multiple volumes and this routine * keeps only the first one seen and removes the rest. */ static stringList_t _remove_btfs_multiple_devices( stringList_t stl ) { stringList_t stx = StringListVoid ; stringList_t stz = StringListVoid ; StringListIterator it ; StringListIterator end ; string_t st ; const char * e ; blkid_probe blkid ; StringListGetIterators( stl,&it,&end ) ; zuluCryptSecurityGainElevatedPrivileges() ; while( it != end ){ st = *it ; it++ ; blkid = blkid_new_probe_from_filename( StringContent( st ) ) ; if( blkid != NULL ){ e = NULL ; blkid_do_probe( blkid ) ; blkid_probe_lookup_value( blkid,"TYPE",&e,NULL ) ; if( StringsAreEqual( e,"btrfs" ) ){ e = NULL ; blkid_probe_lookup_value( blkid,"UUID",&e,NULL ) ; if( StringListHasNoEntry( stx,e ) ){ /* * we got a btrfs volume with UUID we do not know about, * This will be the only device with this btrfs UUID we support and * all device operations must happen through this device and this device only. */ stz = StringListAppendString( stz,st ) ; stx = StringListAppend( stx,e ) ; }else{ /* * we already know this UUID and this device is not supported.Any operation on this * device should fail. */ } }else{ /* * not a btrfs volume */ stz = StringListAppendString( stz,st ) ; } blkid_free_probe( blkid ) ; }else{ stz = StringListAppendString( stz,st ) ; } } zuluCryptSecurityDropElevatedPrivileges() ; StringListMultipleDelete( &stl,&stx,NULL ) ; return stz ; }
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 ; } } }
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 ) ; } }
static stringList_t _zuluCryptVolumeList_0( int resolve_loop_devices ) { const char * device ; const char * e ; ssize_t index ; StringListIterator it ; StringListIterator end ; stringList_t stz = StringListVoid ; stringList_t stl = StringListVoid ; stringList_t stl_1 = StringListVoid ; string_t st = StringGetFromVirtualFile( "/proc/partitions" ) ; string_t st_1 = String( "/dev/" ) ; stl = StringListStringSplit( st,'\n' ) ; StringDelete( &st ) ; if( stl == StringListVoid ){ return StringListVoid ; } StringListGetIterators( stl,&it,&end ) ; /* * skip the first entry */ it++ ; zuluCryptSecurityGainElevatedPrivileges() ; while( it != end ){ st = *it ; it++ ; index = StringLastIndexOfChar( st,' ' ) ; if( index != -1 ){ e = StringContent( st ) + index + 1 ; device = StringAppendAt( st_1,5,e ) ; if( _supported_device( device ) ){ if( StringPrefixEqual( device,"/dev/loop" ) ){ /* * zuluCryptLoopDeviceAddress_1() id defined in ../lib/create_loop_device.c */ e = zuluCryptLoopDeviceAddress_1( device ) ; if( StringListHasNoEntry( stz,e ) ){ /* * Here we only keep one loop device if the volume file has * more than one loop device */ if( resolve_loop_devices ){ stl_1 = StringListAppend( stl_1,e ) ; }else{ stl_1 = StringListAppend( stl_1,device ) ; } stz = StringListAppend( stz,e ) ; } StringFree( e ) ; }else{ stl_1 = StringListAppendIfAbsent( stl_1,device ) ; } } } } zuluCryptSecurityDropElevatedPrivileges() ; StringListMultipleDelete( &stl,&stz,NULL ) ; StringDelete( &st_1 ) ; return _zuluCryptAddLVMVolumes( _zuluCryptAddMDRAIDVolumes( _remove_root_devices( stl_1 ) ) ) ; }