char * zuluCryptGetLoopDeviceAddress( const char * device ) { char * z = NULL ; const char * e ; string_t st = StringVoid ; string_t xt = StringVoid ; int i ; int r ; z = zuluCryptLoopDeviceAddress_1( device ) ; if( z == NULL ){ return NULL ; }else{ st = String( "" ) ; for( i = 0 ; i < 255 ; i++ ){ StringReplace( st,"/sys/block/loop" ) ; StringAppendInt( st,i ) ; xt = StringGetFromVirtualFile( StringAppend( st,"/loop/backing_file" ) ) ; e = StringRemoveRight( xt,1 ) ; r = StringsAreEqual( e,z ) ; StringDelete( &xt ) ; if( r ){ StringReplace( st,"/dev/loop" ) ; e = StringAppendInt( st,i ) ; if( StringsAreNotEqual( device,e ) ){ break ; } }else{ StringReset( st ) ; } } StringFree( z ) ; if( StringIsEmpty( st ) ){ StringDelete( &st ) ; return NULL ; }else{ return StringDeleteHandle( &st ) ; } } }
/* * this function return a secured file path to be used to create a file at the path */ static const char * _secure_file_path_1( void ) { string_t st_path = _create_work_directory() ; StringAppend( st_path,"1-" ) ; StringAppendInt( st_path,syscall( SYS_gettid ) ) ; return StringDeleteHandle( &st_path ) ; }
/* * 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 ; }
static int open_loop_device_1( string_t * loop_device ) { string_t st = String( "" ) ; int i ; int fd ; const char * path ; struct loop_info64 l_info ; int r = 0 ; for( i = 0 ; i < 255 ; i++ ){ StringReplace( st,"/dev/loop" ) ; path = StringAppendInt( st,i ) ; fd = open( path,O_RDONLY ) ; if( fd == -1 ){ r = 0 ; break ; } if( ioctl( fd,LOOP_GET_STATUS64,&l_info ) != 0 ){ if( errno == ENXIO) { *loop_device = StringCopy( st ) ; close( fd ) ; r = 1 ; break ; } } close( fd ) ; } StringDelete( &st ) ; return r ; }
char * zuluCryptGetALoopDeviceAssociatedWithAnImageFile( const char * path ) { int i ; string_t st = String( "" ) ; const char * e ; char * f ; for( i = 0 ; i < 255 ; i++ ){ StringReplace( st,"/dev/loop" ) ; e = StringAppendInt( st,i ) ; f = zuluCryptLoopDeviceAddress_1( e ) ; if( StringsAreEqual( path,f ) ){ StringFree( f ) ; return StringDeleteHandle( &st ) ; }else{ StringFree( f ) ; } } StringDelete( &st ) ; return NULL ; }
static int _create_volume( const char * dev,const char * fs,const char * type,const char * pass,size_t pass_size,const char * rng ) { size_t len ; int status ; string_t m = StringVoid ; const char * device_mapper ; const char * mapper ; if ( zuluCryptPathIsNotValid( dev ) ){ return 1 ; } m = String( crypt_get_dir() ) ; len = StringLength( m ) ; StringAppend( m,"/zuluCrypt-" ) ; device_mapper = StringAppendInt( m,syscall( SYS_gettid ) ) ; mapper = device_mapper + len + 1 ; if( StringsAreEqual( type,"luks" ) ){ if( StringsAreNotEqual( rng,"/dev/random" ) ){ if( StringsAreNotEqual( rng,"/dev/urandom" ) ){ return zuluExit( 2,m ) ; } } if( zuluCryptCreateLuks( dev,pass,pass_size,rng ) != 0 ){ return zuluExit( 3,m ) ; } if( zuluCryptOpenLuks( dev,mapper,"rw",pass,pass_size ) != 0 ){ return zuluExit( 3,m ) ; } }else if( StringsAreEqual( type,"plain") ){ if( zuluCryptOpenPlain( dev,mapper,"rw",pass,pass_size ) != 0 ){ return zuluExit( 3,m ) ; } }else{ return zuluExit( 2,m ) ; } status = zuluCryptCreateFileSystemInAVolume( fs,device_mapper ) ; /* * zuluCryptCloseMapper() is defined in close_mapper.c */ zuluCryptCloseMapper( device_mapper ); if( status == 0 ){ return zuluExit( 0,m ) ; }else{ return zuluExit( 3,m ) ; } }
static int _create_file_system( const char * device,const char * fs,int key_source, const char * key,size_t key_len,int volume_type ) { string_t m = StringVoid ; int r ; const char * device_mapper ; const char * mapper ; size_t len ; m = String( crypt_get_dir() ) ; len = StringLength( m ) ; StringAppend( m,"/zuluCrypt-" ) ; device_mapper = StringAppendInt( m,syscall( SYS_gettid ) ) ; mapper = device_mapper + len + 1 ; /* * zuluCryptOpenTcrypt() is defined in open_tcrypt.c */ if( zuluCryptOpenTcrypt( device,mapper,key,key_len,key_source,volume_type,NULL,0,0,NULL ) == 0 ){ /* * zuluCryptCreateFileSystemInAVolume() is defined in create_volume.c */ if( zuluCryptCreateFileSystemInAVolume( fs,device_mapper ) == 0 ){ r = 0 ; }else{ r = 3 ; } /* * zuluCryptCloseMapper() is defined in close_mapper.c */ zuluCryptCloseMapper( device_mapper ) ; }else{ r = 3 ; } StringDelete( &m ) ; return r ; }
char * zuluCryptGetFileNameFromFileDescriptor( int fd ) { char * e ; char * c ; string_t xt = String( "/proc/self/fd/" ) ; e = zuluCryptRealPath( StringAppendInt( xt,fd ) ) ; /* * zuluCryptResolvePath_4() is defined in resolve_paths.c */ c = zuluCryptResolvePath_4( e ) ; StringFree( e ) ; StringDelete( &xt ) ; return c ; }
string_t zuluCryptCreateKeyFile( const char * key,size_t key_len,const char * fileName ) { string_t st = StringVoid ; int fd ; const char * file ; struct stat statstr ; if( key == NULL || key_len == 0 || fileName == NULL ){ return StringVoid ; } #define path_does_not_exist( x ) stat( x,&statstr ) != 0 if( path_does_not_exist( "/run" ) ){ mkdir( "/run",S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH | S_IROTH ) ; chown( "/run",0,0 ) ; } if( path_does_not_exist( "/run/zuluCrypt" ) ){ mkdir( "/run/zuluCrypt",S_IRWXU ) ; chown( "/run/zuluCrypt",0,0 ) ; } st = String_1( "/run/zuluCrypt/",fileName,NULL ) ; file = StringAppendInt( st,syscall( SYS_gettid ) ) ; fd = open( file,O_WRONLY | O_CREAT,S_IRUSR | S_IWUSR | S_IRGRP |S_IROTH ) ; if( fd == -1 ){ StringDelete( &st ) ; }else{ write( fd,key,key_len ) ; close( fd ) ; chown( file,0,0 ) ; chmod( file,S_IRWXU ) ; } return st ; }
static int open_loop_device( string_t * loop_device ) { int devnr ; int fd_loop ; fd_loop = open( "/dev/loop-control",O_RDONLY ) ; if( fd_loop == -1 ){ return open_loop_device_1( loop_device ) ; }else{ devnr = ioctl( fd_loop,LOOP_CTL_GET_FREE ) ; close( fd_loop ) ; if( devnr < 0 ){ return open_loop_device_1( loop_device ) ; }else{ *loop_device = String( "/dev/loop" ) ; StringAppendInt( *loop_device,devnr ) ; return 1 ; } } }
static stringList_t _add_entry( stringList_t stx,stringList_t tmp,string_t ( *function )( const vInfo * ), char * const ** entry,size_t * entry_len ) { string_t st ; u_int64_t e ; vInfo volumeInfo ; StringListStringArray_1( entry,entry_len,tmp ) ; volumeInfo.device = *( *entry + *entry_len - 2 ) ; volumeInfo.mountPoint = *( *entry + 4 ) ; volumeInfo.fileSystem = *( *entry + *entry_len - 3 ) ; volumeInfo.mountOptions = *( *entry + 5 ) ; volumeInfo.rootPath = *( *entry + 3 ) ; if( StringsAreEqual( volumeInfo.fileSystem,"fuse.encfs" ) ) { st = StringListStringAt( tmp,*entry_len - 2 ) ; StringReset( st ) ; e = StringJenkinsOneAtATimeHash( volumeInfo.mountPoint ) ; volumeInfo.device = StringAppendInt( st,e ) ; } if( _valid_entry( &volumeInfo ) ) { st = function( &volumeInfo ) ; stx = StringListAppendString_1( stx,&st ) ; } return stx ; }
static string_t set_mount_options( m_struct * mst ) { /* * zuluCryptGetMountOptionsFromFstab() is defined in parse_fstab.c */ string_t opt = zuluCryptGetMountOptionsFromFstab( mst->device,MOUNTOPTIONS,mst->uid ) ; int fsFamily = fs_family( mst->fs ) ; const char * f[] = { "nouser","users","user","defaults","noauto","auto","nodev","dev", "noexec","exec","nosuid","suid","bind","mandlock","move","noatime","nodiratime","remount","silent", "synchronous",NULL } ; const char ** z = f ; const char * e ; if( opt == StringVoid ){ opt = String( "" ) ; StringAppend( opt,mst->fs_flags ) ; }else{ if( StringContains( opt,"ro" ) ){ mst->m_flags |= MS_RDONLY ; } StringMultipleAppend( opt,",",mst->fs_flags,END ) ; } _get_file_system_options_from_config_file( mst->device,opt ) ; if( fsFamily == 1 ){ if( !StringContains( opt,"dmask=" ) ){ StringAppend( opt,",dmask=0000" ) ; } if( !StringContains( opt,"umask=" ) ){ StringAppend( opt,",umask=0000" ) ; } if( !StringContains( opt,"uid=" ) ){ StringAppend( opt,",uid=" ) ; StringAppendInt( opt,mst->uid ) ; } if( !StringContains( opt,"gid=" ) ){ StringAppend( opt,",gid=" ) ; StringAppendInt( opt,mst->uid ) ; } if( !StringContains( opt,"fmask=" ) ){ StringAppend( opt,",fmask=0111" ) ; } if( StringsAreEqual( mst->fs,"vfat" ) ){ if( !StringContains( opt,"flush" ) ){ StringAppend( opt,",flush" ) ; } if( !StringContains( opt,"shortname=" ) ){ StringAppend( opt,",shortname=mixed" ) ; } } }else if( fsFamily == 2 ){ if( !StringContains( opt,"uid=" ) ){ StringAppend( opt,",uid=" ) ; StringAppendInt( opt,mst->uid ) ; } if( !StringContains( opt,"gid=" ) ){ StringAppend( opt,",gid=" ) ; StringAppendInt( opt,mst->uid ) ; } }else if( fsFamily == 3 ){ mst->m_flags |= MS_RDONLY ; }else{ /* * ext file systems and raiserfs among others go here * we dont set any options for them. */ ; } /* * remove mount options to leave only file system options */ while( 1 ){ e = *z ; z++ ; if( e == NULL ){ break ; }else{ StringRemoveString( opt,e ) ; } } /* * remove below two now because we are going to add them below,reason for removing them * and readding them is because we want to make sure they are at the beginning of the string */ StringRemoveString( opt,"ro" ) ; StringRemoveString( opt,"rw" ) ; if( mst->m_flags & MS_RDONLY ){ StringPrepend( opt,"ro," ) ; }else{ StringPrepend( opt,"rw," ) ; } mst->opts = _remove_duplicates( opt ) ; return opt; }