int zuluCryptOpenPlain_1( const open_struct_t * opt ) { int mode ; string_t st ; int fd ; int r ; if( StringPrefixEqual( opt->device,"/dev/" ) ){ return _open_plain( opt->device,opt ) ; }else{ if( StringHasComponent( opt->m_opts,"ro" ) ){ mode = O_RDONLY ; }else{ mode = O_RDWR ; } /* * zuluCryptAttachLoopDeviceToFile() is defined in ./create_loop.c */ if( zuluCryptAttachLoopDeviceToFile( opt->device,mode,&fd,&st ) ){ r = _open_plain( StringContent( st ),opt ) ; StringDelete( &st ) ; close( fd ) ; return r ; }else{ return 2 ; } } }
static int mount_point_prefix_match_0( const char * m_path,uid_t uid,string_t * m_point,int home_prefix ) { int st ; /* * zuluCryptGetUserName() is defined in ../lib/user_home_path.c */ string_t uname ; /* * below constant are set in ../constants.h */ const char * str ; if( home_prefix ){ uname = zuluCryptGetUserHomePath( uid ) ; str = StringContent( uname ) ; }else{ uname = zuluCryptGetUserName( uid ) ; StringPrepend( uname,"/run/media/private/" ) ; str = StringAppendChar( uname,'/' ) ; } st = StringPrefixEqual( m_path,str ) ; if( m_point ){ *m_point = uname ; }else{ StringDelete( &uname ) ; } return st ; }
static void _get_result( arguments * args ) { string_t st ; int fd ; const char * device = args->opts->device ; if( StringPrefixEqual( device,"/dev/" ) ){ _get_result_0( device,args ) ; }else{ /* * zuluCryptAttachLoopDeviceToFile() is defined in create_loop_device.c */ if( zuluCryptAttachLoopDeviceToFile( device,args->opts->open_mode,&fd,&st ) ){ _get_result_0( StringContent( st ),args ) ; StringDelete( &st ) ; close( fd ) ; }else{ _get_error( args ) ; } } }
static void _device_info( string_t p,const char * device ) { char * path ; if( device == NULL ){ StringMultipleAppend( p,"\n device: \t","Nil","\n loop: \t","Nil",NULL ) ; }else if( StringPrefixEqual( device,"/dev/loop" ) ){ path = zuluCryptLoopDeviceAddress_1( device ) ; if( path != NULL ){ StringMultipleAppend( p,"\n device: \t",device,"\n loop: \t",path,NULL ) ; StringFree( path ) ; }else{ StringMultipleAppend( p,"\n device: \t",device,"\n loop: \tNil",NULL ) ; } }else{ /* * zuluCryptResolvePath() is defined in resolve_path.c */ path = zuluCryptResolvePath( device ) ; StringMultipleAppend( p,"\n device: \t",path,"\n loop: \tNil",NULL ) ; StringFree( path ) ; } }
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 ) ; } } }
int zuluCryptCreateTCrypt( const char * device,const char * file_system,const char * rng, const char * key,size_t key_len,int key_source, u_int64_t hidden_volume_size, const char * file_system_h,const char * key_h,size_t key_len_h,int key_source_h ) { int fd ; string_t q = StringVoid ; int r ; if( StringPrefixEqual( device,"/dev/" ) ){ r = _create_tcrypt_volume( device,file_system,rng,key,key_len,key_source, hidden_volume_size,file_system_h,key_h,key_len_h,key_source_h ) ; }else{ /* * zuluCryptAttachLoopDeviceToFile() is defined in create_loop_device.c */ if( zuluCryptAttachLoopDeviceToFile( device,O_RDWR,&fd,&q ) ){ device = StringContent( q ) ; r = _create_tcrypt_volume( device,file_system,rng,key,key_len,key_source, hidden_volume_size,file_system_h,key_h,key_len_h,key_source_h ) ; close( fd ) ; StringDelete( &q ) ; }else{ r = 3 ; } } return r ; }
string_t zuluCryptResolvePath_2( const char * path ) { if( StringPrefixEqual( path,"/dev/loop" ) ){ return String( path ) ; }else{ return zuluCryptResolvePath_1( path ) ; } }
char * zuluCryptResolvePath_4( const char * path ) { if( StringPrefixEqual( path,"/dev/loop" ) ){ return StringCopy_2( path ) ; }else{ return zuluCryptResolvePath( path ) ; } }
int zuluCryptPathDoesNotStartsWith( const char * path,const char * start ) { int st = 0; char * p = canonicalize_path( path ) ; if( p != NULL ){ st = StringPrefixEqual( p,start ) ; free( p ) ; } return st == 0 ; }
char * zuluCryptResolvePath_3( const char * path ) { if( StringPrefixEqual( path,"/dev/loop" ) ){ /* * zuluCryptLoopDeviceAddress_1() is defined in create_loop_device.c */ return zuluCryptLoopDeviceAddress_1( path ) ; }else{ return zuluCryptResolvePath( path ) ; } }
/* * 1-permissions denied * 2-invalid path * 3-shenanigans * 4-common error */ static int path_is_accessible( const char * path,uid_t uid,int action ) { int st ; char * e ; if( uid ){;} if( StringPrefixEqual( path,"/dev/shm/" ) ){ return 4 ; } if( StringPrefixEqual( path,"/dev/" ) ){ if( StringPrefixEqual( path,"/dev/loop" ) ){ /* * zuluCryptLoopDeviceAddress_1() is defined in ../zuluCrypt-cli/create_loop_device.c */ e = zuluCryptLoopDeviceAddress_1( path ) ; if( e != NULL ){ st = has_device_access( e,action ) ; StringFree( e ) ; }else{ return 4 ; } }else{ zuluCryptSecurityGainElevatedPrivileges() ; st = has_device_access( path,action ) ; zuluCryptSecurityDropElevatedPrivileges() ; } return st ; }else{ zuluCryptSecurityDropElevatedPrivileges() ; return has_device_access( path,action ) ; } }
int zuluMountCryptoUMount( ARGS * args ) { const char * device = args->device ; const char * UUID = args->uuid ; uid_t uid = args->uid ; const char * mapping_name ; char * path = NULL ; int st ; string_t str = StringVoid ; if( UUID == NULL ){ if( StringPrefixEqual( device,"/dev/loop" ) ){ /* * zuluCryptLoopDeviceAddress_1() is defined in ../zuluCrypt-cli/create_loop_device.c */ path = zuluCryptLoopDeviceAddress_1( device ) ; if( path == NULL ){ return 20 ; }else{ device = path ; } } mapping_name = device + StringLastIndexOfChar_1( device,'/' ) + 1 ; }else{ str = String( UUID ) ; StringRemoveString( str,"\"" ) ; mapping_name = StringSubChar( str,4,'-' ) ; } /* * zuluCryptEXECloseVolume() is defined in ../zuluCrypt-cli/bin/close_volume.c */ st = zuluCryptEXECloseVolume( device,mapping_name,uid ) ; StringDelete( &str ) ; StringFree( path ) ; return st ; }
char * zuluCryptResolvePath( const char * path ) { char * e ; char * f ; if( StringsAreEqual( path,"/dev/root" ) ){ e = _zuluCryptResolveDevRoot() ; if( e == NULL ){ return StringCopy_2( path ) ; }else{ return e ; } }else if( StringPrefixEqual( path,"/dev/disk/by-" ) ){ /* * zuluCryptRealPath() is defined in real_path.c */ e = zuluCryptRealPath( path ) ; if( e == NULL ){ return StringCopy_2( path ) ; }else{ if( StringPrefixEqual( e,"/dev/mapper/" ) ){ f = _convert_if_path_is_lvm( e ) ; StringFree( e ) ; return f ; }else{ return e ; } } }else if( StringPrefixEqual( path,"/dev/mapper/" ) ){ return _convert_if_path_is_lvm( path ) ; }else if( StringPrefixEqual( path,"/dev/md" ) ){ return zuluCryptResolveMDPath( path ) ; }else if( StringPrefixEqual( path,"/dev/dm-" ) ){ return zuluCryptResolveDMPath( path ) ; }else if( StringPrefixEqual( path,"/dev/loop" ) ){ /* * zuluCryptLoopDeviceAddress() is defined in create_loop_device.c */ return zuluCryptLoopDeviceAddress( path ) ; }else{ return StringCopy_2( path ) ; } }
int zuluCryptPartitionIsSystemPartition( const char * device,uid_t uid ) { char * dev ; int r ; if( StringPrefixEqual( device,"/dev/loop" ) ){ /* * zuluCryptLoopDeviceAddress_1() is defined in ../lib/create_loop_device.c */ dev = zuluCryptLoopDeviceAddress_1( device ) ; if( dev == NULL ){ return 0 ; }else{ r = _zuluCryptPartitionIsSystemPartition( dev,uid ) ; StringFree( dev ) ; return r ; } }else{ return _zuluCryptPartitionIsSystemPartition( device,uid ) ; } }
static string_t _create_mount_point_1( const char * device,uid_t uid,string_t path,int need_privileges ) { string_t st ; char * loop_path = NULL ; if( StringPrefixEqual( device,"/dev/loop" ) ){ /* * zuluCryptLoopDeviceAddress_1() is defined in ../lib/create_loop_device.c */ device = loop_path = zuluCryptLoopDeviceAddress_1( device ) ; } StringMultipleAppend( path,device + StringLastIndexOfChar_1( device,'/' ) + 1,NULL ) ; st = _create_path( uid,path,need_privileges ) ; StringFree( loop_path ) ; return st ; }
int zuluCryptAddKey( const char * device,const char * existingkey,size_t existingkey_size,const char * newkey,size_t newkey_size ) { string_t st ; int fd ; int r ; if( StringPrefixEqual( device,"/dev/" ) ){ return _add_key( device,existingkey,existingkey_size,newkey,newkey_size ) ; }else{ /* * zuluCryptAttachLoopDeviceToFile() is defined in ./create_loop.c */ if( zuluCryptAttachLoopDeviceToFile( device,O_RDWR,&fd,&st ) ){ r = _add_key( StringContent( st ),existingkey,existingkey_size,newkey,newkey_size ) ; StringDelete( &st ) ; close( fd ) ; return r ; }else{ return 1 ; } } }
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" ) ; } } }
int zuluCryptRemoveKey( const char * device ,const char * pass,size_t pass_size ) { string_t st ; int fd ; int r ; if( StringPrefixEqual( device,"/dev/" ) ){ return _remove_key( device,pass,pass_size ) ; }else{ /* * zuluCryptAttachLoopDeviceToFile() is defined in ./create_loop.c */ if( zuluCryptAttachLoopDeviceToFile( device,O_RDWR,&fd,&st ) ){ r = _remove_key( StringContent( st ),pass,pass_size ) ; StringDelete( &st ) ; close( fd ) ; return r ; }else{ return 2 ; } } }
char * zuluCryptEmptySlots( const char * device ) { string_t st ; int fd ; char * r ; if( StringPrefixEqual( device,"/dev/" ) ){ return _empty_slots( device ) ; }else{ /* * zuluCryptAttachLoopDeviceToFile() is defined in ./create_loop.c */ if( zuluCryptAttachLoopDeviceToFile( device,O_RDONLY,&fd,&st ) ){ r = _empty_slots( StringContent( st ) ) ; StringDelete( &st ) ; close( fd ) ; return r ; }else{ return NULL ; } } }
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 char * _device_path( const char * device ) { char * path ; if( StringPrefixEqual( device,"/dev/loop" ) ){ zuluCryptSecurityGainElevatedPrivileges() ; /* * zuluCryptLoopDeviceAddress_1() is defined in ../zuluCrypt-cli/create_loop_device.c */ path = zuluCryptLoopDeviceAddress_1( device ) ; zuluCryptSecurityDropElevatedPrivileges() ; if( path == NULL ){ return StringCopy_2( device ) ; }else{ return path ; } }else{ return StringCopy_2( device ) ; } }
static int _zuluCryptCheckSYSifDeviceIsSystem( const char * device ) { /* * UDEV_SUPPORT is set at configure time by "-DUDEVSUPPORT=true" option,the option being absent equals "-DUDEVSUPPORT=false" * To set the option, configure with "-DUDEVSUPPORT=true" */ #if UDEV_SUPPORT /* * udev support is enabled */ int r ; size_t e ; ssize_t k ; string_t xt ; string_t st ; char dev[ PATH_MAX + 1 ] ; const char * path ; if( StringPrefixNotEqual( device,"/dev/" ) ){ /* * udev doesnt work with path to image files so return early */ return 0 ; } if( StringPrefixEqual( device,"/dev/loop" ) ){ /* * udev thinks all loop devices are system devices and we disagree and hence we return early */ return 0 ; } path = realpath( device,dev ) ; if( path != NULL ){ st = String( path ) ; }else{ st = String( device ) ; } if( StringStartsWithAtLeastOne( st,"/dev/sd","/dev/hd",NULL ) ){ /* * this path will convert something like: "/dev/sdc12" to "/dev/sdc" */ StringRemoveDigits( st ) ; }else if( StringStartsWith( st,"/dev/mmc" ) ){ /* * device path will be something like "/dev/mmcblk0p2" and what we want to do * is cut off the string from p to end iwth "/dev/mmcblk0" */ k = StringIndexOfChar( st,0,'p' ) ; if( k != -1 ){ e = StringLength( st ) - ( size_t )k ; StringRemoveRight( st,e ) ; } } StringReplaceString( st,"/dev/","/sys/block/" ) ; path = StringAppend( st,"/removable" ) ; /* * path will be something like "/sys/block/sda/removable" */ xt = StringGetFromVirtualFile( path ) ; StringDelete( &st ) ; if( xt == StringVoid ){ return 0 ; }else{ r = StringEqual( xt,"0\n" ) ; StringDelete( &xt ) ; return r ; } #else if( device ){;} /* * udev support is disabled */ return 0 ; #endif }
void zuluCryptPrintPartitionProperties( const char * device ) { #define SIZE 64 char buffer[ SIZE ] ; const char * e ; u_int64_t size ; blkid_probe blkid ; zuluCryptSecurityGainElevatedPrivileges() ; if( StringPrefixEqual( device,"/dev/loop" ) ){ /* * zuluCryptLoopDeviceAddress_1() is defined in ../lib/create_loop_device.c */ e = zuluCryptLoopDeviceAddress_1( device ) ; if( e != NULL ){ printf( "%s\t",e ) ; StringFree( e ) ; }else{ printf( "%s\t",device ) ; } }else{ printf( "%s\t",device ) ; } size = zuluCryptGetVolumeSize( device ) ; blkid = blkid_new_probe_from_filename( device ) ; if( blkid == NULL ){ printf( "Nil\tNil\tNil\tNil\n" ) ; }else{ /* * zuluCryptFormatSize() is defined in ../lib/status.c */ zuluCryptFormatSize( size,buffer,SIZE ) ; printf( "%s\t",buffer ) ; blkid_do_probe( blkid ) ; if( blkid_probe_lookup_value( blkid,"LABEL",&e,NULL ) == 0 ){ printf( "%s\t",e ) ; }else{ printf( "Nil\t" ) ; } if( blkid_probe_lookup_value( blkid,"TYPE",&e,NULL ) == 0 ){ printf( "%s\t",e ) ; }else{ printf( "Nil\t" ) ; } if( blkid_probe_lookup_value( blkid,"UUID",&e,NULL ) == 0 ){ printf( "%s\n",e ) ; }else{ printf( "Nil\n" ) ; } blkid_free_probe( blkid ) ; } zuluCryptSecurityDropElevatedPrivileges() ; }
int zuluCryptGetDeviceFileProperties( const char * file,int * fd_path,int * fd_loop,char ** dev,uid_t uid ) { int st = 100 ; int xt = 0 ; int lfd ; const char * dev_1 = NULL ; string_t st_dev = StringVoid ; struct stat stat_st ; struct stat stat_st_1 ; /* * try to open the device with user privileges */ seteuid( uid ) ; *dev = NULL ; *fd_path = open( file,O_RDONLY ) ; if( *fd_path != -1 ){ fstat( *fd_path,&stat_st ) ; fcntl( *fd_path,F_SETFD,FD_CLOEXEC ) ; /* * A user has access to the device.They should get here only with paths to files they have access to. * Allow access to files only */ if( S_ISREG( stat_st.st_mode ) ){ /* * we can open file in read mode,let see if we can in write mode too */ lfd = open( file,O_RDWR ) ; if( lfd != -1 ){ /* * we can open the file in read write mode */ fstat( lfd,&stat_st_1 ) ; fcntl( lfd,F_SETFD,FD_CLOEXEC ) ; /* * check to make sure the file we got earlier is the same one we got now. * ie check to make sure the file wasnt changed btw calls. */ if( stat_st.st_dev == stat_st_1.st_dev && stat_st.st_ino == stat_st_1.st_ino ){ close( *fd_path ) ; *fd_path = lfd ; seteuid( 0 ) ; /* * zuluCryptAttachLoopDeviceToFileUsingFileDescriptor() is defined in ./create_loop_device.c */ xt = zuluCryptAttachLoopDeviceToFileUsingFileDescriptor( *fd_path,fd_loop,O_RDWR,&st_dev ) ; seteuid( uid ) ; *dev = StringDeleteHandle( &st_dev ) ; } }else{ /* * we can not open the file in write mode,continue with read only access */ seteuid( 0 ) ; /* * zuluCryptAttachLoopDeviceToFileUsingFileDescriptor() is defined in ./create_loop_device.c */ xt = zuluCryptAttachLoopDeviceToFileUsingFileDescriptor( *fd_path,fd_loop,O_RDONLY,&st_dev ) ; seteuid( uid ) ; *dev = StringDeleteHandle( &st_dev ) ; } if( xt != 1 ){ st = 100 ; close( *fd_path ) ; *fd_path = -1 ; }else{ dev_1 = zuluCryptGetFileNameFromFileDescriptor( *fd_path ) ; if( StringPrefixEqual( dev_1,"/dev/shm/" ) ){ st =1 ; close( *fd_path ) ; *fd_path = -1 ; }else{ st = 0 ; } StringFree( dev_1 ) ; } }else{ if( S_ISBLK( stat_st.st_mode ) ){ if( uid == 0 ) { /* * we got a block device and we are root,accept it */ *dev = zuluCryptGetFileNameFromFileDescriptor( *fd_path ) ; st = 0 ; }else{ /* * odd,normal user has access to a block device,allow it only if the * device is in "/dev/" but not in "/dev/shm" */ *dev = zuluCryptGetFileNameFromFileDescriptor( *fd_path ) ; if( StringPrefixEqual( *dev,"/dev/shm/" ) ){ st = 1 ; }else if( StringPrefixEqual( *dev,"/dev/" ) ){ st = 0 ; } } }else if( S_ISDIR( stat_st.st_mode ) ){ st = 2 ; }else{ /* * whatever it is,it cant be good,reject it */ st = 100 ; } close( *fd_path ) ; *fd_path = -1 ; } }else{ /* * failed to open above with users privileges,try to open the device with root's privileges. * We should only accept block devices in "/dev/" but not in "/dev/shm". */ seteuid( 0 ) ; *fd_path = open( file,O_RDONLY ) ; if( *fd_path != -1 ){ fstat( *fd_path,&stat_st ) ; /* * zuluCryptGetFileNameFromFileDescriptor() is defined in ./create_loop_device.c */ *dev = zuluCryptGetFileNameFromFileDescriptor( *fd_path ) ; if( S_ISBLK( stat_st.st_mode ) ){ if( StringPrefixEqual( *dev,"/dev/shm/" ) ){ /* * we do not support this path */ st = 1 ; }else if( StringPrefixEqual( *dev,"/dev/" ) ){ /* * got a block device,accept it */ st = 0 ; }else{ /* * reject others */ st = 100 ; } }else{ /* * whatever it is,it cant be good,reject it */ st = 100 ; } /* * We are closing the file because we dont need to hold on to it as paths in "/dev/" can not be moved under us by * normal users. */ close( *fd_path ) ; *fd_path = -1 ; }else{ /* * invalid path or something i dont know,reject */ st = 100 ; } seteuid( uid ) ; } return _check_if_device_is_supported( st,uid,dev ) ; }
static int _open_tcrypt_volume( const char * device,const open_struct_t * opts ) { tc_api_task task ; int r = !TC_OK ; size_t i ; size_t k ; const char * const * z ; const char * e ; string_t st = StringVoid ; if( tc_api_initialize() ){ task = tc_api_task_init( "map" ) ; if( tc_api_task_initialized( task ) ){ tc_api_task_set( task,"veracrypt_mode",opts->veraCrypt_volume ) ; tc_api_task_set( task,"map_name",opts->mapper_name ) ; if( StringHasComponent( opts->m_opts,"ro" ) ){ tc_api_task_set( task,"read_only" ) ; } if( opts->tcrypt_system ){ if( StringPrefixEqual( device,"/dev/sd" ) || StringPrefixEqual( device,"/dev/hd" ) ){ st = String( device ) ; e = StringRemoveDigits( st ) ; tc_api_task_set( task,"dev",e ) ; tc_api_task_set( task,"sys",e ) ; }else{ tc_api_task_set( task,"dev",device ) ; tc_api_task_set( task,"sys",device ) ; } }else{ tc_api_task_set( task,"dev",device ) ; } k = opts->tcrypt_keyfiles_count ; z = opts->tcrypt_keyfiles ; tc_api_task_set( task,"passphrase",opts->key ) ; for( i = 0 ; i < k ; i++ ){ tc_api_task_set( task,"keyfiles",*( z + i ) ) ; } r = tc_api_task_do( task ) ; tc_api_task_uninit( task ) ; StringDelete( &st ) ; } tc_api_uninit() ; } return r ; }
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 zuluMountCryptoMount( ARGS * args ) { const char * type = args->type ; const char * offset = args->offset ; const char * device = args->device ; const char * UUID = args->uuid ; const char * mode = args->m_opts ; uid_t uid = args->uid ; const char * key = args->key ; const char * key_source = args->key_source ; const char * m_point = args->m_point ; const char * fs_opts = args->fs_opts ; int mount_point_option = args->mpo ; int share = args->share ; int st ; /* * the struct is declared in ../zuluCrypt-cli/bin/libzuluCrypt-exe.h */ struct_opts opts ; const char * mapping_name ; char * path = NULL ; string_t str = StringVoid ; if( UUID == NULL ){ if( StringPrefixEqual( device,"/dev/loop" ) ){ /* * zuluCryptLoopDeviceAddress_1() is defined in ../zuluCrypt-cli/create_loop_device.c */ path = zuluCryptLoopDeviceAddress_1( device ) ; if( path == NULL ){ return 20 ; }else{ mapping_name = path + StringLastIndexOfChar_1( path,'/' ) + 1 ; } }else{ mapping_name = device + StringLastIndexOfChar_1( device,'/' ) + 1 ; } }else{ str = String( UUID ) ; StringRemoveString( str,"\"" ) ; mapping_name = StringReplaceString( str,"UUID=","UUID-" ) ; } /* * zuluCryptEXEGetOptsSetDefault() is defined in ../zuluCrypt-cli/bin/get_opts.c */ zuluCryptEXEGetOptsSetDefault( &opts ) ; if( StringPrefixEqual( key_source,"-G" ) ){ opts.plugin_path = key ; } opts.mount_point = m_point ; opts.device = device ; opts.m_opts = mode ; opts.key = key ; opts.key_source = key_source ; opts.mount_point_option = mount_point_option ; opts.share = share ; opts.fs_opts = fs_opts ; opts.env = StringListStringArray( args->env ) ; opts.offset = offset ; opts.type = type ; memcpy( opts.tcrypt_multiple_keyfiles,args->tcrypt_multiple_keyfiles, sizeof( args->tcrypt_multiple_keyfiles ) ) ; /* * zuluCryptEXEOpenVolume() is defined in ../zuluCrypt-cli/bin/open_volume.c */ st = zuluCryptEXEOpenVolume( &opts,mapping_name,uid ) ; StringDelete( &str ) ; StringFree( opts.env ) ; StringFree( path ) ; return st ; }
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 ; }
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 ; }
int zuluMountUMount( ARGS * args ) { const char * device = args->device ; uid_t uid = args->uid ; char * loop_device ; char * m_point = NULL ; int status ; string_t st = StringVoid ; const char * dev = NULL ; const char * errorMsg = gettext( "\ ERROR: You can not umount volumes out of \"%s\" since you are not root and do not belong to group \"zulumount\"\n" ) ; string_t xt ; if( StringPrefixEqual( device,"/dev/loop" ) ){ /* * zuluCryptLoopDeviceAddress() is defined in ../zuluCrypt-cli/lib/create_loop_devices.c */ loop_device = zuluCryptLoopDeviceAddress( device ) ; if( loop_device == NULL ){ /* * the error msg is a lie,but its harmless since the user will most likely never see it as * this code path will not be passed. */ return _zuluExit( 100,StringVoid,m_point,gettext( "ERROR: Device does not appear to be mounted" ) ) ; }else{ st = StringInherit( &loop_device ) ; dev = StringContent( st ) ; /* * zuluCryptGetMountPointFromPath() is defined in defined in ../zuluCrypt-cli/lib/process_mountinfo.c */ m_point = zuluCryptGetMountPointFromPath( dev ) ; if( m_point == NULL ){ return _zuluExit( 100,st,m_point,gettext( "ERROR: Device does not appear to be mounted" ) ) ; } } }else{ /* * zuluCryptGetMountPointFromPath() is defined in defined in ../zuluCrypt-cli/lib/process_mountinfo.c */ m_point = zuluCryptGetMountPointFromPath( device ) ; if( m_point == NULL ){ return _zuluExit( 100,st,m_point,gettext( "ERROR: Device does not appear to be mounted" ) ) ; } } /* * zuluCryptMountPointPrefixMatch() is defined in ../zuluCrypt-cli/bin/create_mount_point.c */ if( zuluCryptMountPointPrefixMatch( m_point,uid,&xt ) ){ StringDelete( &xt ) ; }else{ /* * zuluCryptUserIsAMemberOfAGroup() is defined in ../zuluCrypt-cli/bin/security.c */ if( zuluCryptUserIsAMemberOfAGroup( uid,"zulumount" ) ){ StringDelete( &xt ) ; }else{ printf( errorMsg,StringContent( xt ) ) ; StringDelete( &xt ) ; return _zuluExit( 101,st,m_point,NULL ) ; } } StringFree( m_point ) ; m_point = NULL ; /* * zuluCryptBindUnmountVolume() is defined in ../zuluCrypt-cli/bin/bind.c */ switch( zuluCryptBindUnmountVolume( StringListVoid,device,uid ) ){ case 3 : return _zuluExit( 107,st,m_point,gettext( "ERROR: Shared mount point appear to be busy" ) ) ; case 4 : return _zuluExit( 108,st,m_point,gettext( "ERROR: Shared mount point appear to belong to a different user" ) ) ; case 5 : return _zuluExit( 109,st,m_point,gettext( "ERROR: Shared mount point appear to be in an ambiguous state,advice to unmount manually" ) ) ; default: ; } /* * zuluCryptSecurityGainElevatedPrivileges() is defined in ../zuluCrypt-cli/bin/security.c */ zuluCryptSecurityGainElevatedPrivileges() ; /* * zuluCryptUnmountVolume() is defined in ../zuluCrypt-cli/lib/unmount_volume.c */ status = zuluCryptUnmountVolume( device,&m_point ) ; /* * zuluCryptSecurityDropElevatedPrivileges() is defined in ../zuluCrypt-cli/bin/security.c */ zuluCryptSecurityDropElevatedPrivileges() ; if( status == 0 ){ if( m_point != NULL ){ /* * zuluCryptReuseMountPoint() is defined in ../zuluCrypt-cli/bin/create_mount_point.c */ if( !zuluCryptReuseMountPoint() ){ zuluCryptSecurityGainElevatedPrivileges() ; rmdir( m_point ) ; zuluCryptSecurityDropElevatedPrivileges() ; } } return _zuluExit( 0,st,m_point,gettext( "SUCCESS: umount complete successfully" ) ) ; }else{ switch( status ) { case 1 : return _zuluExit( 103,st,m_point,gettext( "ERROR: Device does not exist" ) ) ; case 2 : return _zuluExit( 104,st,m_point,gettext( "ERROR: Failed to unmount,the mount point and/or one or more files are in use" ) ) ; case 4 : return _zuluExit( 105,st,m_point,gettext( "ERROR: Failed to unmount,could not get a lock on /etc/mtab~" ) ) ; case 10: return _zuluExit( 107,st,m_point,gettext( "ERROR: Failed to unmount,multiple mount points for the volume detected" ) ) ; break ; default: return _zuluExit( 106,st,m_point,gettext( "ERROR: Failed to unmount the partition" ) ) ; } } }