"Fossies" - the Fresh Open Source Software Archive

Member "zuluCrypt-5.7.1/zuluCrypt-cli/lib/mount_volume.c" (15 Jan 2020, 11718 Bytes) of package /linux/misc/zuluCrypt-5.7.1.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "mount_volume.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 5.7.0_vs_5.7.1.

    1 /*
    2  *
    3  *  Copyright (c) 2011-2015
    4  *  name : Francis Banyikwa
    5  *  email: mhogomchungu@gmail.com
    6  *  This program is free software: you can redistribute it and/or modify
    7  *  it under the terms of the GNU General Public License as published by
    8  *  the Free Software Foundation, either version 2 of the License, or
    9  *  (at your option) any later version.
   10  *
   11  *  This program is distributed in the hope that it will be useful,
   12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14  *  GNU General Public License for more details.
   15  *
   16  *  You should have received a copy of the GNU General Public License
   17  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
   18  */
   19 
   20 #include "includes.h"
   21 
   22 #include <sys/mount.h>
   23 #include <blkid/blkid.h>
   24 #include <stdlib.h>
   25 #include <unistd.h>
   26 #include <sys/types.h>
   27 #include <sys/stat.h>
   28 #include <sys/wait.h>
   29 #include <fcntl.h>
   30 
   31 /*
   32  * These functions are moved to parse_fstab.c
   33  *
   34  * string_t zuluCryptGetFstabEntry( const char * device )
   35  * string_t zuluCryptGetMountOptionsFromFstab( const char * device,int pos )
   36  * stringList_t zuluCryptGetFstabEntryList( const char * device )
   37  */
   38 
   39 typedef enum { FAT_FAMILY_FS,OTHER_FAMILY_FS,READ_ONLY_FS,DEFAULT_FS_TYPE } FS_TYPE ;
   40 
   41 static int zuluExit( int st,int fd,string_t x,string_t y,string_t z )
   42 {
   43     StringMultipleDelete( &x,&y,&z,NULL ) ;
   44 
   45     if( fd != -1 ){
   46 
   47         close( fd ) ;
   48     }
   49 
   50     return st ;
   51 }
   52 
   53 static FS_TYPE fs_family( const char * fs )
   54 {
   55     if( StringAtLeastOneMatch_1( fs,"ntfs","vfat","fat","msdos","umsdos","exfat",NULL ) ){
   56 
   57         return FAT_FAMILY_FS ;
   58 
   59     }else if( StringAtLeastOneMatch_1( fs,"affs","hfs",NULL ) ){
   60 
   61         return OTHER_FAMILY_FS ;
   62 
   63     }else if( StringAtLeastOneMatch_1( fs,"iso9660","udf","squashfs",NULL ) ){
   64 
   65         return READ_ONLY_FS ;
   66     }else{
   67         return DEFAULT_FS_TYPE ;
   68     }
   69 }
   70 
   71 /*
   72  * custom options per file system
   73  */
   74 static void _get_file_system_options_from_config_file_1( const char * fs,string_t st )
   75 {
   76     const char * e ;
   77 
   78     StringListIterator it  ;
   79     StringListIterator end ;
   80 
   81     string_t zt ;
   82     string_t xt = StringGetFromFile( "/etc/zuluCrypt/generic_fs_options" ) ;
   83 
   84     stringList_t stl = StringListStringSplit( xt,'\n' ) ;
   85 
   86     stringList_t stz ;
   87 
   88     StringDelete( &xt ) ;
   89 
   90     StringListGetIterators( stl,&it,&end ) ;
   91 
   92     while( it != end  ){
   93 
   94         zt = *it ;
   95 
   96         it++ ;
   97 
   98         if( StringStartsWith( zt,fs ) ){
   99 
  100             stz = StringListStringSplit( zt,' ' ) ;
  101 
  102             e = StringListContentAtSecondPlace( stz ) ;
  103 
  104             StringMultipleAppend( st,",",e,NULL ) ;
  105 
  106             StringListDelete( &stz ) ;
  107 
  108             break ;
  109         }
  110     }
  111 
  112     StringListDelete( &stl ) ;
  113 }
  114 
  115 /*
  116  * custom options per volume set through file system's UUID
  117  */
  118 static void _get_file_system_options_from_config_file( const char * device,string_t st )
  119 {
  120     char * f ;
  121     const char * e ;
  122 
  123     StringListIterator it  ;
  124     StringListIterator end ;
  125 
  126     string_t xt = StringGetFromFile( "/etc/zuluCrypt/fs_options" ) ;
  127 
  128     stringList_t stl = StringListStringSplit( xt,'\n' ) ;
  129 
  130     stringList_t stz ;
  131 
  132     StringDelete( &xt ) ;
  133 
  134     /*
  135      * zuluCryptUUIDFromPath_1() is defined in resolve_paths.c
  136      */
  137     f = zuluCryptUUIDFromPath_1( device ) ;
  138 
  139     StringListGetIterators( stl,&it,&end ) ;
  140 
  141     while( it != end  ){
  142 
  143         e = StringRemoveString( *it,"\"" ) ;
  144 
  145         it++ ;
  146 
  147         if( StringPrefixMatch( e,"UUID=",5 ) ){
  148 
  149             if( StringPrefixEqual( e + 5,f ) ){
  150 
  151                 stz = StringListSplit( e,' ' ) ;
  152 
  153                 e = StringListContentAtSecondPlace( stz ) ;
  154 
  155                 StringMultipleAppend( st,",",e,NULL ) ;
  156 
  157                 StringListDelete( &stz ) ;
  158 
  159                 break ;
  160             }
  161         }
  162     }
  163 
  164     StringListDelete( &stl ) ;
  165     StringFree( f ) ;
  166 }
  167 
  168 static const char * _remove_duplicates( string_t st )
  169 {
  170     const char ** z = StringPointer( st ) ;
  171 
  172     while( StringHasComponent( *z,",," ) ){
  173 
  174         StringReplaceString( st,",,","," ) ;
  175     }
  176 
  177     if( StringEndsWithChar( st,',' ) ){
  178 
  179         return StringRemoveRight( st,1 ) ;
  180     }else{
  181         return StringContent( st ) ;
  182     }
  183 }
  184 
  185 static string_t set_mount_options( m_struct * mst )
  186 {
  187     /*
  188      * zuluCryptGetMountOptionsFromFstab() is defined in parse_fstab.c
  189      */
  190     string_t opt = zuluCryptGetMountOptionsFromFstab( mst->device,MOUNTOPTIONS,mst->uid ) ;
  191 
  192     FS_TYPE fsFamily = fs_family( mst->fs ) ;
  193 
  194     const char * f[] = { "nouser","users","user","defaults","noauto","auto","nodev","dev",
  195         "noexec","exec","nosuid","suid","bind","mandlock","move","noatime","nodiratime","remount","silent",
  196         "synchronous",NULL } ;
  197 
  198     const char ** z = f ;
  199     const char * e ;
  200 
  201     if( opt == StringVoid ){
  202 
  203         if( mst->fs_flags != NULL ){
  204 
  205             opt = String( mst->fs_flags ) ;
  206         }else{
  207             opt = StringEmpty() ;
  208         }
  209     }else{
  210         if( StringContains( opt,"ro" ) ){
  211 
  212             mst->m_flags |= MS_RDONLY ;
  213         }
  214 
  215         StringMultipleAppend( opt,",",mst->fs_flags,NULL ) ;
  216     }
  217 
  218     _get_file_system_options_from_config_file_1( mst->fs,opt ) ;
  219 
  220     _get_file_system_options_from_config_file( mst->device,opt ) ;
  221 
  222     if( fsFamily == FAT_FAMILY_FS ){
  223 
  224         if( StringDoesNotContain( opt,"dmask=" ) ){
  225 
  226             StringAppend( opt,",dmask=0000" ) ;
  227         }
  228         if( StringDoesNotContain( opt,"umask=" ) ){
  229 
  230             StringAppend( opt,",umask=0000" ) ;
  231         }
  232         if( StringDoesNotContain( opt,"uid=" ) ){
  233 
  234             StringAppend( opt,",uid=" ) ;
  235             StringAppendInt( opt,mst->uid ) ;
  236         }
  237         if( StringDoesNotContain( opt,"gid=" ) ){
  238 
  239             StringAppend( opt,",gid=" ) ;
  240             StringAppendInt( opt,mst->uid ) ;
  241         }
  242         if( StringDoesNotContain( opt,"fmask=" ) ){
  243 
  244             StringAppend( opt,",fmask=0111" ) ;
  245         }
  246         if( StringsAreEqual( mst->fs,"vfat" ) ){
  247 
  248             if( StringDoesNotContain( opt,"flush" ) ){
  249 
  250                 StringAppend( opt,",flush" ) ;
  251             }
  252             if( StringDoesNotContain( opt,"shortname=" ) ){
  253 
  254                 StringAppend( opt,",shortname=mixed" ) ;
  255             }
  256         }
  257         if( StringsAreEqual( mst->fs,"ntfs" ) ){
  258 
  259             if( StringDoesNotContain( opt,"big_writes" ) ){
  260 
  261                 StringAppend( opt,",big_writes" ) ;
  262             }
  263         }
  264     }else if( fsFamily == OTHER_FAMILY_FS ){
  265 
  266         if( StringDoesNotContain( opt,"uid=" ) ){
  267 
  268             StringAppend( opt,",uid=" ) ;
  269             StringAppendInt( opt,mst->uid ) ;
  270         }
  271         if( StringDoesNotContain( opt,"gid=" ) ){
  272 
  273             StringAppend( opt,",gid=" ) ;
  274             StringAppendInt( opt,mst->uid ) ;
  275         }
  276     }else if( fsFamily == READ_ONLY_FS ){
  277 
  278         mst->m_flags |= MS_RDONLY ;
  279     }else{
  280         /*
  281          * ext file systems and raiserfs among others go here
  282          * we dont set any options for them.
  283          */
  284         ;
  285     }
  286 
  287     /*
  288      * remove mount options to leave only file system options
  289      */
  290     while( 1 ){
  291         e = *z ;
  292         z++ ;
  293         if( e == NULL ){
  294             break ;
  295         }else{
  296             StringRemoveString( opt,e ) ;
  297         }
  298     }
  299     /*
  300      * remove below two now because we are going to add them below,reason for removing them
  301      * and readding them is because we want to make sure they are at the beginning of the string
  302      */
  303     StringRemoveString( opt,"ro" ) ;
  304     StringRemoveString( opt,"rw" ) ;
  305 
  306     if( mst->m_flags & MS_RDONLY ){
  307 
  308         StringPrepend( opt,"ro," ) ;
  309     }else{
  310         StringPrepend( opt,"rw," ) ;
  311     }
  312 
  313     mst->opts = _remove_duplicates( opt ) ;
  314     return opt ;
  315 }
  316 
  317 static const char * _mount_options( unsigned long flags,string_t st )
  318 {
  319     if( flags & MS_NODEV ){
  320         StringAppend( st,",nodev" ) ;
  321     }
  322     if( flags & MS_NOEXEC ){
  323         StringAppend( st,",noexec" ) ;
  324     }
  325     if( flags & MS_NOSUID ){
  326         StringAppend( st,",nosuid" ) ;
  327     }
  328     if( flags & MS_BIND ){
  329         StringAppend( st,",bind" ) ;
  330     }
  331     if( flags & MS_MANDLOCK ){
  332         StringAppend( st,",mandlock" ) ;
  333     }
  334     if( flags & MS_MOVE ){
  335         StringAppend( st,",move" ) ;
  336     }
  337     if( flags & MS_NOATIME ){
  338         StringAppend( st,",noatime" ) ;
  339     }
  340     if( flags & MS_NODIRATIME ){
  341         StringAppend( st,",nodiratime" ) ;
  342     }
  343     if( flags & MS_RELATIME  ){
  344         StringAppend( st,",relatime" ) ;
  345     }
  346     if( flags & MS_REMOUNT ){
  347         StringAppend( st,",remount" ) ;
  348     }
  349     if( flags & MS_SILENT ){
  350         StringAppend( st,",silent" ) ;
  351     }
  352     if( flags & MS_STRICTATIME ){
  353         StringAppend( st,",strictatime" ) ;
  354     }
  355     if( flags & MS_SYNCHRONOUS ){
  356         StringAppend( st,",synchronous" ) ;
  357     }
  358 
  359     return _remove_duplicates( st ) ;
  360 }
  361 
  362 static int _mount_FUSEfs( const m_struct * mst,string_t st )
  363 {
  364     const char * opts = _mount_options( mst->m_flags,st ) ;
  365 
  366     process_t p = Process( ZULUCRYPTmount,NULL ) ;
  367 
  368     if( StringsAreEqual( mst->fs,"ntfs" ) ){
  369 
  370         if( StringHasComponent( opts,"ignore_case" ) ){
  371 
  372             ProcessSetArgumentList( p,"-n","-t","lowntfs-3g","-o",opts,mst->device,mst->m_point,NULL ) ;
  373         }else{
  374             ProcessSetArgumentList( p,"-n","-t","ntfs-3g","-o",opts,mst->device,mst->m_point,NULL ) ;
  375         }
  376     }else{
  377         ProcessSetArgumentList( p,"-t",mst->fs,"-o",opts,mst->device,mst->m_point,NULL ) ;
  378     }
  379 
  380     ProcessStart( p ) ;
  381 
  382     return ProcessWaitUntilFinished( &p ) ;
  383 }
  384 
  385 static int _mount( const m_struct * mst,string_t st )
  386 {
  387     int h = mount( mst->device,mst->m_point,mst->fs,mst->m_flags,mst->opts + 3 ) ;
  388 
  389     if( st ){;}
  390 
  391     if( h == 0 && mst->m_flags != MS_RDONLY ){
  392 
  393         chmod( mst->m_point,S_IRWXU|S_IRWXG|S_IRWXO ) ;
  394     }
  395 
  396     return h ;
  397 }
  398 
  399 static int _mount_volume( int ( *function )( const m_struct *,string_t ),
  400               const m_struct * m,string_t st )
  401 {
  402     int e = function( m,st ) ;
  403 
  404     if( e != 0 ){
  405 
  406         /*
  407          * mount failed for some reason,wait 2 second and then try again
  408          */
  409         sleep( 2 ) ;
  410 
  411         e = function( m,st ) ;
  412     }
  413 
  414     return e ;
  415 }
  416 
  417 const char * zuluCryptDecodeMountEntry( string_t st )
  418 {
  419     StringReplaceString( st,"\\012","\n" ) ;
  420     StringReplaceString( st,"\\040"," " ) ;
  421     StringReplaceString( st,"\\134","\\" ) ;
  422     return StringReplaceString( st,"\\011","\\t" ) ;
  423 }
  424 
  425 const char * zuluCryptEncodeMountEntry( string_t st )
  426 {
  427     StringReplaceString( st,"\\","\\134" ) ;
  428     StringReplaceString( st,"\n","\\012" ) ;
  429     StringReplaceString( st," ","\\040" ) ;
  430     return StringReplaceString( st,"\\t","\\011" ) ;
  431 }
  432 
  433 int zuluCryptMountVolume( const char * path,const char * m_point,unsigned long mount_opts,const char * fs_opts,uid_t uid )
  434 {
  435     int h ;
  436 
  437     string_t opts = StringVoid ;
  438     string_t fs   = StringVoid ;
  439     string_t loop = StringVoid ;
  440 
  441     int fd = -1 ;
  442 
  443     m_struct mst ;
  444     mst.device = path ;
  445     mst.m_point = m_point ;
  446     mst.uid = uid ;
  447     mst.m_flags = mount_opts ;
  448 
  449     int bitLockerVolumeUsingDislocker = zuluCryptIsDislockerMapperPath( path ) ;
  450 
  451     if( bitLockerVolumeUsingDislocker ) {
  452 
  453         fs = zuluCryptBitLockerVolumeFS( path ) ;
  454     }else{
  455         /*
  456          * zuluCryptGetFileSystemFromDevice() is defined in blkid_evaluate_tag.c
  457          */
  458         fs = zuluCryptGetFileSystemFromDevice( path ) ;
  459     }
  460 
  461     if( StringsAreEqual_2( fs,"Nil" ) || fs == StringVoid ){
  462 
  463         /*
  464          * failed to read file system,probably because the volume does have any or
  465          * a plain volume was opened with a wrong key
  466          */
  467         return zuluExit( 4,fd,opts,fs,loop ) ;
  468     }
  469 
  470     if( StringStartsWith( fs,"crypto" ) ){
  471 
  472         /*
  473          * we cant mount an encrypted volume, exiting
  474          */
  475         return zuluExit( 4,fd,opts,fs,loop ) ;
  476     }
  477 
  478     /*
  479      * zuluCryptMountHasNotAllowedFileSystemOptions() is defined in ./mount_fs_options.c
  480      */
  481     if( zuluCryptMountHasNotAllowedFileSystemOptions( uid,fs_opts,fs ) ){
  482 
  483         return zuluExit( -1,fd,opts,fs,loop ) ;
  484     }
  485 
  486     mst.fs_flags = fs_opts ;
  487     mst.fs = StringContent( fs ) ;
  488     opts = set_mount_options( &mst ) ;
  489 
  490     if( StringPrefixNotEqual( path,"/dev/" ) || bitLockerVolumeUsingDislocker ){
  491         /*
  492          * zuluCryptAttachLoopDeviceToFile() is defined in ./create_loop_device.c
  493          */
  494         if( zuluCryptAttachLoopDeviceToFile( mst.device,O_RDWR,&fd,&loop ) ){
  495             mst.device = StringContent( loop ) ;
  496         }else{
  497             return zuluExit( -1,fd,opts,fs,loop ) ;
  498         }
  499     }
  500 
  501     /*
  502      * zuluCryptFileSystemIsFUSEbased() is defined in blkid_evaluate_tag.c
  503      */
  504     if( zuluCryptFileSystemIsFUSEbased( path ) ){
  505 
  506         /*
  507          * These file systems dont see to work with mount() command for some reason.
  508          * Them being FUSE based could be a reason.
  509          */
  510 
  511         switch( _mount_volume( _mount_FUSEfs,&mst,opts ) ){
  512 
  513             case 0  : return zuluExit( 0,fd,opts,fs,loop )  ;
  514             case 16 : return zuluExit( 12,fd,opts,fs,loop ) ;
  515             case 32 : return zuluExit( -1,fd,opts,fs,loop ) ;
  516             default : return zuluExit( 1,fd,opts,fs,loop )  ;
  517         }
  518     }else{
  519         h = _mount_volume( _mount,&mst,opts ) ;
  520     }
  521 
  522     return zuluExit( h,fd,opts,fs,loop ) ;
  523 }