const char * StringPrependChar( string_t st,char c ) { char s[ 2 ] ; s[ 1 ] = '\0' ; s[ 0 ] = c ; return StringPrepend( st,s ) ; }
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 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 ) ; } }
static char * _get_type_from_udev( const char * mapper ) { string_t st = _get_mapper_property_from_udev( mapper,"dm-uuid-CRYPT-",TYPE ) ; if( st == StringVoid ){ return StringCopy_2( "Nil" ) ; }else{ StringPrepend( st,"crypto_" ) ; return StringDeleteHandle( &st ) ; } }
const char * StringPrependMultipleString( string_t st,... ) { string_t entry ; va_list list ; va_start( list,st ) ; while( 1 ){ entry = va_arg( list,string_t ) ; if( entry == NULL ){ break ; } StringPrepend( st,entry->string ) ; } va_end( list ) ; return st->string ; }
const char * StringMultiplePrepend( string_t st,... ) { const char * entry ; va_list list ; va_start( list,st ) ; while( 1 ){ entry = va_arg( list,const char * ) ; if( entry == END ){ break ; } StringPrepend( st,entry ) ; } va_end( list ) ; return st->string ; }
void zuluCryptFileSystemProperties( string_t p,const char * mapper,const char * m_point ) { const char * e ; blkid_probe blkid ; struct statvfs vfs ; u_int64_t total ; u_int64_t used ; u_int64_t unused ; u_int64_t block_size ; char buff[ SIZE ] ; char * buffer = buff ; string_t q ; ssize_t index ; struct stat statstr ; blkid = blkid_new_probe_from_filename( mapper ) ; if( blkid == NULL ){ return ; } blkid_do_probe( blkid ) ; if( blkid_probe_lookup_value( blkid,"TYPE",&e,NULL ) == 0 ){ StringMultipleAppend( p,"\n file system:\t",e,NULL ) ; }else{ StringAppend( p,"\n file system:\tNil" ) ; } blkid_free_probe( blkid ) ; if( statvfs( m_point,&vfs ) != 0 ){ return ; } block_size = vfs.f_frsize ; total = block_size * vfs.f_blocks ; unused = block_size * vfs.f_bavail ; used = total - unused ; zuluCryptFormatSize( total,buffer,SIZE ) ; StringMultipleAppend( p,"\n total space:\t",buffer,NULL ) ; zuluCryptFormatSize( used,buffer,SIZE ) ; StringMultipleAppend( p,"\n used space:\t",buffer,NULL ) ; zuluCryptFormatSize( unused,buffer,SIZE ) ; StringMultipleAppend( p,"\n free space:\t",buffer,NULL ) ; if( used == total ){ StringAppend( p,"\n used%: \t100%\n" ) ; }else if( used == 0 ){ StringAppend( p,"\n used%: \t0%\n" ) ; }else{ snprintf( buff,SIZE,"%.2f%%",100 * ( ( float ) used / ( float ) total ) ) ; StringMultipleAppend( p,"\n used%: \t",buff,"\n",NULL ) ; } buffer = zuluCryptGetUUIDFromMapper( mapper ) ; StringAppend( p,buffer ) ; StringFree( buffer ) ; StringMultipleAppend( p,"\n mount point1:\t",m_point,NULL ) ; q = String( m_point ) ; index = StringLastIndexOfChar( q,'/' ) ; if( index == -1 ){ StringAppend( p,"\n mount point2:\tNil" ) ; }else{ StringRemoveLeft( q,index ) ; e = StringPrepend( q,"/run/media/public" ) ; if( stat( e,&statstr ) == 0 ){ StringMultipleAppend( p,"\n mount point2:\t",e,NULL ) ; }else{ StringAppend( p,"\n mount point2:\tNil" ) ; } } StringDelete( &q ) ; }
const char * StringPrependString( string_t st,string_t xt ) { return StringPrepend( st,xt->string ) ; }
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 ; }
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; }