/* * Below function copies a secured file from secured location to a user owned and managed location. * The source file will be deleted when the copy is done. */ static int _secure_copy_file( const char * source,const char * dest,uid_t uid ) { int st = 4 ; int fd_source ; int fd_dest ; size_t len ; char buffer[ SIZE ] ; zuluCryptSecurityDropElevatedPrivileges() ; fd_dest = open( dest,O_WRONLY | O_CREAT,S_IRUSR | S_IWUSR | S_IRGRP |S_IROTH ) ; if( fd_dest == -1 ){ zuluCryptSecurityGainElevatedPrivileges() ; zuluCryptDeleteFile( source ) ; zuluCryptSecurityDropElevatedPrivileges() ; return 6 ; } zuluCryptSecurityGainElevatedPrivileges() ; fd_source = open( source,O_RDONLY ) ; if( fd_source != -1 ){ while( 1 ){ len = read( fd_source,buffer,SIZE ) ; if( len < SIZE ){ ignore_result( write( fd_dest,buffer,len ) ) ; break ; }else{ ignore_result( write( fd_dest,buffer,len ) ) ; } } ignore_result( chmod( dest,S_IRUSR ) ) ; ignore_result( chown( dest,uid,uid ) ) ; st = 0 ; } /* * zuluCryptDeleteFile() is defined in ../lib/file_path_security.c */ zuluCryptDeleteFile( source ) ; zuluCryptSecurityDropElevatedPrivileges() ; return st ; }
void zuluCryptCheckInvalidKey( const char * device ) { char * d ; const char * c ; int e = 0 ; zuluCryptSecurityGainElevatedPrivileges() ; /* * zuluCryptEmptySlots() is defined in ../lib/empty_slots.c */ d = zuluCryptEmptySlots( device ) ; zuluCryptSecurityDropElevatedPrivileges() ; if( d == NULL ){ /* * we got here because the volume is either not luks based or the path is invalid */ ; }else{ c = d - 1 ; while( *++c ){ if( *c == '2' ){ fprintf( stderr,"WARNING: key slot number: %d is corrupted\n",e ) ; } e++ ; } free( d ) ; } }
int zuluCryptEXEVolumeInfo( const char * mapper,const char * device,uid_t uid ) { char * output ; int xt ; /* * ZULUCRYPTlongMapperPath is set in ../constants.h * zuluCryptCreateMapperName() is defined at ../lib/create_mapper_name.c */ string_t p = zuluCryptCreateMapperName( device,mapper,uid,ZULUCRYPTlongMapperPath ) ; zuluCryptSecurityGainElevatedPrivileges() ; /* *zuluCryptVolumeStatus() is defined in ../lib/status.c */ output = zuluCryptVolumeStatus( StringContent( p ) ) ; zuluCryptSecurityDropElevatedPrivileges() ; if( output != NULL ){ printf( "%s\n",output ) ; StringFree( output ) ; xt = 0 ; }else{ printf( gettext( "ERROR: Could not get volume properties,volume is not open or was opened by a different user\n" ) ) ; xt = 2 ; } StringDelete( &p ) ; return xt ; }
/* * Below function copies a file owned and managed by a user to a secured location so that it can be accessed securely. */ static int _secure_file_path( const char ** path,const char * source ) { int fd_source ; int fd_temp ; char buffer[ SIZE ] ; size_t len ; const char * temp_path ; struct stat ststr ; string_t st_path = _create_work_directory() ; StringAppend( st_path,"0-" ) ; temp_path = StringAppendInt( st_path,syscall( SYS_gettid ) ) ; zuluCryptSecurityDropElevatedPrivileges() ; fd_source = open( source,O_RDONLY ) ; if( fd_source == -1 ){ StringDelete( &st_path ) ; return 0 ; } fstat( fd_source,&ststr ) ; if( ststr.st_size >= 3145728 ){ /* * headers are less than 3MB so we obvious have a wrong file */ StringDelete( &st_path ) ; return 0 ; } zuluCryptSecurityGainElevatedPrivileges() ; fd_temp = open( temp_path,O_WRONLY | O_CREAT,S_IRUSR | S_IWUSR | S_IRGRP |S_IROTH ) ; if( fd_temp == -1 ){ close( fd_source ) ; StringDelete( &st_path ) ; return 0 ; } while( 1 ){ len = read( fd_source,buffer,SIZE ) ; if( len < SIZE ){ write( fd_temp,buffer,len ) ; break ; }else{ write( fd_temp,buffer,len ) ; } } close( fd_source ) ; close( fd_temp ) ; zuluCryptSecurityDropElevatedPrivileges() ; *path = StringDeleteHandle( &st_path ) ; return 1 ; }
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 ; }
/* * Below function creates a secured folder path,ie a folder path a normal user has no access to */ static string_t _create_work_directory( void ) { /* * ZULUCRYPTtempFolder and ZULUCRYPtmountMiniPath are set in ../constants.h */ const char * temp_path = "/run/zuluCrypt/" ; struct stat xt ; mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH | S_IROTH ; zuluCryptSecurityGainElevatedPrivileges() ; #define path_does_not_exist( x ) stat( x,&xt ) != 0 if( path_does_not_exist( "/run" ) ){ mkdir( "/run",mode ) ; chown( "/run",0,0 ) ; } if( path_does_not_exist( temp_path ) ){ mkdir( temp_path,S_IRWXU ) ; chown( temp_path,0,0 ) ; } zuluCryptSecurityDropElevatedPrivileges() ; return String( temp_path ) ; }
/* * Its not possible to add more keys to a volume with no empty slots or to a non luks volume * * This function checks if a volume is luks and if it has atleast one empty slot. */ static int _zuluCryptCheckEmptySlots( const char * device ) { int status = 0 ; char * c ; char * d ; zuluCryptSecurityGainElevatedPrivileges() ; /* * zuluCryptEmptySlots() is defined in ../lib/empty_slots.c */ c = zuluCryptEmptySlots( device ) ; zuluCryptSecurityDropElevatedPrivileges() ; if( c == NULL ){ /* * we got here because the volume is either not luks based or the path is invalid */ status = 1 ; }else{ d = c - 1 ; while( *++d ){ if( *d == '0' ){ status = 2 ; break ; } } free( c ) ; } return status ; }
static int _zuluCryptExECheckEmptySlots( const char * device ) { int status = 0 ; char * c ; char * d ; zuluCryptSecurityGainElevatedPrivileges() ; c = zuluCryptEmptySlots( device ) ; zuluCryptSecurityDropElevatedPrivileges() ; if( c == NULL ){ return 1 ; } d = c - 1 ; while( *++d ){ if( *d == '3' ){ status = 3 ; break ; } } StringFree( c ) ; return status ; }
static string_t create_mount_point( const char * device,const char * label,uid_t uid ) { const char * m_point ; string_t path ; struct stat st ; mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH | S_IROTH ; zuluCryptSecurityGainElevatedPrivileges() ; path = zuluCryptGetUserName( uid ) ; #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 ) ; }else{ _chmod( "/run",st.st_mode | S_IXOTH | S_IROTH ) ; } _chown( "/run",0,0 ) ; if( path_does_not_exist( "/run/media" ) ){ mkdir( "/run/media",mode ) ; }else{ _chmod( "/run/media",st.st_mode | S_IXOTH | S_IROTH ) ; } _chown( "/run/media",0,0 ) ; if( path_does_not_exist( "/run/media/private" ) ){ mkdir( "/run/media/private",mode ) ; }else{ _chmod( "/run/media/private",st.st_mode | S_IXOTH | S_IROTH ) ; } _chown( "/run/media/private",0,0 ) ; m_point = StringPrepend( path,"/run/media/private/" ) ; if( path_does_not_exist( m_point ) ){ mkdir( m_point,S_IRUSR | S_IXUSR ) ; _chown( m_point,uid,uid ) ; }else{ _chown( m_point,uid,uid ) ; _chmod( m_point,S_IRUSR | S_IXUSR ) ; } zuluCryptSecurityDropElevatedPrivileges() ; StringAppendChar( path,'/' ) ; if( label == NULL ){ return _create_default_mount_point( device,uid,path ) ; }else{ return _create_custom_mount_point( label,uid,path ) ; } }
int zuluCryptEXECloseVolume( const char * dev,const char * mapping_name,uid_t uid ) { int st ; int i ; string_t p = StringVoid ; char * m_point = NULL ; struct stat xt ; const char * mapper ; /* * ZULUCRYPTlongMapperPath is set in ../constants.h * zuluCryptCreateMapperName() defined in ../lib/create_mapper_name.c */ p = zuluCryptCreateMapperName( dev,mapping_name,uid,ZULUCRYPTlongMapperPath ) ; mapper = StringContent( p ) ; if( stat( mapper,&xt ) != 0 ){ return zuluExit( 1,p ) ; } /* * zuluCryptBindUnmountVolume() is defined in ./bind.c */ switch( zuluCryptBindUnmountVolume( StringListVoid,mapper,uid ) ){ case 3 : return zuluExit( 7,p ) ; case 4 : return zuluExit( 8,p ) ; case 5 : return zuluExit( 9,p ) ; default: ; } zuluCryptSecurityGainElevatedPrivileges() ; /* * zuluCryptCloseVolume() is defined in ../lib/close_volume.c */ st = zuluCryptCloseVolume( mapper,&m_point ) ; if( st == 0 && m_point != NULL ){ for( i = 0 ; i < 2 ; i++ ){ if( rmdir( m_point ) == 0 ){ break ; }else{ sleep( 1 ) ; } } StringFree( m_point ) ; } zuluCryptSecurityDropElevatedPrivileges() ; return zuluExit( st,p ) ; }
static int create_group( const char * groupname ) { process_t p ; int r ; zuluCryptSecurityGainElevatedPrivileges() ; p = Process( ZULUCRYPTgroupadd,"-f",groupname,NULL ) ; ProcessStart( p ) ; r = ProcessWaitUntilFinished( &p ) ; zuluCryptSecurityDropElevatedPrivileges(); return r == 0 ; }
/* * open_volume function below can be devided into two, the first part is before the mount point folder is created and the * other part is after. This function is called after the mount point is created to see if it the mount point folder * should be removed first before calling the above function.The above function is called directly when "open_volume" * function is to be exited before the mount point is created. * */ static int zuluExit_1( int st,const struct_opts * opts,const char * device,const char * m_point,stringList_t stl ) { if( opts->open_mount && st != 0 ){ zuluCryptSecurityGainElevatedPrivileges() ; rmdir( m_point ) ; zuluCryptSecurityDropElevatedPrivileges() ; } return zuluExit( st,device,m_point,stl ) ; }
static int _open_volume( const open_struct_t * volume ) { int r ; zuluCryptSecurityGainElevatedPrivileges() ; /* * zuluCryptOpenVolume_2() is defined in ../lib/open_volume.c */ r = zuluCryptOpenVolume_2( volume ) ; zuluCryptSecurityDropElevatedPrivileges() ; return r ; }
char * zuluCryptUUIDFromPath( const char * device ) { char * c ; zuluCryptSecurityGainElevatedPrivileges() ; /* * zuluCryptUUIDFromPath_1() is defined in ../lib/blkid_evaluate_tag.c */ c = zuluCryptUUIDFromPath_1( device ) ; zuluCryptSecurityDropElevatedPrivileges() ; return c ; }
/* * Its not possible to add more keys to a volume with no empty slots or to a non luks volume * * This function checks if a volume is luks and if it has atleast one empty slot. */ static int _zuluCryptCheckEmptySlots( const char * device ) { int r = 0 ; char * c ; char * d ; zuluCryptSecurityGainElevatedPrivileges() ; /* * zuluCryptVolumeIsLuks() is defined in ../lib/is_luks.c */ if( zuluCryptVolumeIsLuks( device ) ){ /* * zuluCryptEmptySlots() is defined in ../lib/empty_slots.c */ c = zuluCryptEmptySlots( device ) ; if( c == NULL ){ /* * we shouldnt get here */ r = 1 ; }else{ d = c - 1 ; while( *++d ){ if( *d == '0' ){ r = 2 ; break ; } } StringFree( c ) ; } }else{ /* * volume is not a LUKS volume,assuming its a TrueCrypt volume */ r = 2 ; } zuluCryptSecurityDropElevatedPrivileges() ; return r ; }
void zuluCryptPrepareSocketPath( uid_t uid ) { string_t st = zuluCryptGetUserHomePath( uid ) ; const char * e = StringAppend( st,"/.zuluCrypt-socket" ) ; zuluCryptSecurityGainElevatedPrivileges() ; mkdir( e,0777 ) ; if( chown( e,uid,uid ) ){} if( chmod( e,0777 ) ){} zuluCryptSecurityDropElevatedPrivileges() ; StringDelete( &st ) ; }
static int _save_header( const struct_opts * opts,const char * path,uid_t uid ) { int st = 4 ; const char * temp_path = _secure_file_path_1() ; zuluCryptSecurityGainElevatedPrivileges() ; if( zuluCryptVolumeIsLuks( opts->device ) ){ st = _save_luks_header( opts,temp_path,path,uid ) ; }else{ st = _save_truecrypt_header( opts,temp_path,path,uid ) ; } zuluCryptSecurityDropElevatedPrivileges() ; StringFree( temp_path ) ; return st ; }
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() ; }
char * zuluCryptEvaluateDeviceTags( const char * tag,const char * path ) { char * r ; zuluCryptSecurityGainElevatedPrivileges() ; /* * zuluCryptDeviceFromUUID() is defined in ../lib/blkid_evaluate_tag.c * zuluCryptDeviceFromLabel() is defined in ../lib/blkid_evaluate_tag.c */ if( StringsAreEqual( tag,"UUID" ) ){ r = zuluCryptDeviceFromUUID( path ) ; }else{ r = zuluCryptDeviceFromLabel( path ) ; } zuluCryptSecurityDropElevatedPrivileges() ; return r ; }
stringList_t zuluCryptCreateKeyFiles( const char * const * list,int s ) { #define buffer_size 32 char buffer[ buffer_size ] ; const char * e ; int i ; stringList_t stz = StringListVoid ; string_t xt ; string_t zt ; for( i = 0 ; list[ i ] != NULL ; i++ ){ e = *( list + i ) ; zuluCryptSecurityDropElevatedPrivileges() ; /* * TrueCrypt only uses the first 1MB of keyfile. */ if( StringGetFromFile_3( &xt,e,0,1048576 ) == 0 ){ zuluCryptSecurityGainElevatedPrivileges() ; e = StringIntToString_1( buffer,buffer_size,i + s ) ; /* * zuluCryptCreateKeyFile_1() is defined in ../lib/open_tcrypt.c */ zt = zuluCryptCreateKeyFile_1( xt,e ) ; StringDelete( &xt ) ; stz = StringListAppendString_1( stz,&zt ) ; } } zuluCryptSecurityDropElevatedPrivileges() ; return stz ; }
static void _printResult( const char * device,const char * m_point ) { char * e ; zuluCryptSecurityGainElevatedPrivileges() ; /* * zuluCryptGetVolumeTypeFromMapperPath() is defined in ../lib/status.c */ e = zuluCryptGetVolumeTypeFromMapperPath( device ) ; zuluCryptSecurityDropElevatedPrivileges() ; if( StringHasComponent( e,"LUKS" ) ){ printf( gettext( "SUCCESS: %s volume opened successfully\n" ),"luks" ) ; }else if( StringHasComponent( e,"PLAIN" ) ){ printf( gettext( "SUCCESS: %s volume opened successfully\n" ),"plain" ) ; }else if( StringHasComponent( e,"TCRYPT" ) ){ printf( gettext( "SUCCESS: %s volume opened successfully\n" ),"tcrypt" ) ; }else if( StringHasComponent( e,"VCRYPT" ) ){ printf( gettext( "SUCCESS: %s volume opened successfully\n" ),"vcrypt" ) ; }else{ printf( gettext( "SUCCESS: volume opened successfully\n" ) ) ; } StringFree( e ) ; if( m_point != NULL ){ printf( gettext( "volume mounted at: %s\n" ),m_point ) ; } }
static string_t _create_path( uid_t uid,string_t path,int need_privileges ) { string_t st = StringVoid ; const char * m_point = StringContent( path ) ; if( m_point != NULL ){ if( need_privileges ){ zuluCryptSecurityGainElevatedPrivileges() ; st = _create_path_0( m_point,uid,path ) ; zuluCryptSecurityDropElevatedPrivileges() ; }else{ st = _create_path_0( m_point,uid,path ) ; } } return st ; }
/* * 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 ) ; } }
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 ) ; } }
/* * get_pass_from_file function is defined at get_pass_from_file.c * */ int zuluCryptEXEAddKey( const struct_opts * opts,uid_t uid ) { const char * device = opts->device ; const char * keyType1 = opts->existing_key_source ; const char * existingKey = opts->existing_key ; const char * keyType2 = opts->new_key_source ; const char * newKey = opts->new_key ; /* * 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 * presentKey = &stringArray[ 0 ] ; string_t * newKey_1 = &stringArray[ 1 ] ; string_t * newKey_2 = &stringArray[ 2 ] ; string_t * ek = &stringArray[ 3 ] ; string_t * nk = &stringArray[ 4 ] ; const char * key1 = NULL ; const char * key2 = NULL ; size_t len1 = 0 ; size_t len2 = 0 ; int status = 0 ; tcrypt_opts tcrypt ; memset( &tcrypt,'\0',sizeof( tcrypt_opts ) ) ; /* * zuluCryptPartitionIsSystemPartition() is defined in ./partitions.c */ if( zuluCryptPartitionIsSystemPartition( device,uid ) ){ if( !zuluCryptUserIsAMemberOfAGroup( uid,"zulucrypt" ) ){ return zuluExit( 4,stl ) ; } } /* * zuluCryptSecurityDeviceIsWritable() 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 ) ; } switch( _zuluCryptCheckEmptySlots( device ) ){ case 0 : return zuluExit( 6,stl ) ; case 1 : return zuluExit( 2,stl ) ; case 2 : /* no complains,continue */ ; } if( keyType1 == NULL && keyType2 == NULL ){ switch( zuluGetKeys( presentKey,newKey_1,newKey_2 ) ){ case 1 : return zuluExit( 7,stl ) ; case 2 : return zuluExit( 8,stl ) ; } if( StringEqualString( *newKey_1,*newKey_2 ) ){ key1 = StringContent( *presentKey ) ; len1 = StringLength ( *presentKey ) ; key2 = StringContent( *newKey_1 ) ; len2 = StringLength ( *newKey_1 ) ; }else{ return zuluExit( 9,stl ) ; } }else{ if( newKey == NULL || existingKey == NULL ){ return zuluExit( 10,stl ) ; } if( StringsAreEqual( keyType1,"-f" ) ){ /* * this function is defined at "path_access.c" */ switch( zuluCryptGetPassFromFile( existingKey,uid,ek ) ){ case 1 : return zuluExit( 11,stl ) ; case 4 : return zuluExit( 12,stl ) ; case 2 : return zuluExit( 13,stl ) ; case 5 : return zuluExit( 14,stl ) ; } key1 = StringContent( *ek ) ; len1 = StringLength( *ek ) ; if( StringHasNoComponent( existingKey,"/.zuluCrypt-socket" ) ){ tcrypt.existing_key_is_keyfile = 1 ; } } if( StringsAreEqual( keyType2,"-f" ) ){ /* * this function is defined at "path_access.c" */ switch( zuluCryptGetPassFromFile( newKey,uid,nk ) ){ case 1 : return zuluExit( 11,stl ) ; case 4 : return zuluExit( 12,stl ) ; case 2 : return zuluExit( 13,stl ) ; case 5 : return zuluExit( 14,stl ) ; } key2 = StringContent( *nk ) ; len2 = StringLength( *nk ) ; if( StringHasNoComponent( newKey,"/.zuluCrypt-socket" ) ){ tcrypt.new_key_is_keyfile = 1 ; } } if( StringsAreEqual( keyType1,"-f" ) && StringsAreEqual( keyType2,"-f" ) ){ ; }else if( StringsAreEqual( keyType1,"-p" ) && StringsAreEqual( keyType2,"-p" ) ){ key1 = existingKey ; len1 = StringSize( existingKey ) ; key2 = newKey ; len2 = StringSize( newKey ) ; }else if( StringsAreEqual( keyType1,"-p" ) && StringsAreEqual( keyType2,"-f" ) ){ key1 = existingKey ; len1 = StringSize( existingKey ) ; }else if( StringsAreEqual( keyType1,"-f" ) && StringsAreEqual( keyType2,"-p" ) ){ key2 = newKey ; len2 = StringSize( newKey ) ; }else{ return zuluExit( 10,stl ) ; } } zuluCryptSecurityLockMemory( stl ) ; zuluCryptSecurityGainElevatedPrivileges() ; /* * zuluCryptVolumeIsLuks() is defined in ../lib/is_luks.c */ if( zuluCryptVolumeIsLuks( device ) ){ /* * zuluCryptAddKey() is defined in ../lib/add_key.c */ status = zuluCryptAddKey( device,key1,len1,key2,len2 ) ; }else{ tcrypt.device = device ; tcrypt.existing_key = key1 ; tcrypt.existing_key_size = len1 ; tcrypt.new_key = key2 ; tcrypt.new_key_size = len2 ; status = _replace_truecrypt_key( &tcrypt ) ; } zuluCryptSecurityDropElevatedPrivileges() ; return zuluExit( status,stl ) ; }
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 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 ; }
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" ) ) ; } } }
static int _modify_tcrypt( info_t * info,const struct_opts * opts ) { int k = 4 ; int r ; string_t st = StringVoid ; string_t xt = StringVoid ; if( StringsAreEqual( opts->key_source,"-p" ) ){ info->header_key = opts->key ; info->header_key_source = "passphrase" ; info->header_new_key_source = "new_passphrase" ; }else if( opts->key == NULL && StringsAreNotEqual( opts->key_source,"-f" ) ){ st = info->getKey( &r ) ; if( r ){ info->key = StringContent( st ) ; info->header_key = info->key ; info->header_key_source = "passphrase" ; info->header_new_key_source = "new_passphrase" ; }else{ return zuluExit_1( k,st,xt ) ; } }else{ /* * function is defined at "path_access.c" */ zuluCryptGetPassFromFile( opts->key,info->uid,&st ) ; zuluCryptSecurityGainElevatedPrivileges() ; if( st == StringVoid ){ return zuluExit_1( k,st,xt ) ; }else{ if( StringHasComponent( opts->key,".zuluCrypt-socket" ) ){ info->key = StringContent( st ) ; info->header_key = info->key ; info->header_key_source = "passphrase" ; info->header_new_key_source = "new_passphrase" ; }else{ xt = zuluCryptCreateKeyFile( StringContent( st ),StringLength( st ),"tcrypt-bk-" ) ; if( xt == StringVoid ){ return zuluExit_1( k,st,xt ) ; }else{ info->key = StringContent( xt ) ; info->header_key = info->key ; info->header_key_source = "keyfiles" ; info->header_new_key_source = "new_keyfiles" ; } } } } /* * zuluCryptModifyTcryptHeader() is defined in ../lib/create_tcrypt.c */ k = zuluCryptModifyTcryptHeader( info ) ; if( xt != StringVoid ){ /* * zuluCryptDeleteFile() is defined in ../lib/file_path_security.c */ zuluCryptDeleteFile( StringContent( xt ) ) ; } return zuluExit_1( k,st,xt ) ; }