Exemplo n.º 1
0
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 ) ;
	}
}
Exemplo n.º 2
0
static string_t _resolve_path_2( const vInfo * e )
{
    /*
     * zuluCryptResolvePath_2() is defined in resolve_paths.c
     */
    string_t st = zuluCryptResolvePath_2( e->device ) ;
    StringMultipleAppend( st," ",e->mountPoint," ",e->fileSystem," ",e->mountOptions,NULL ) ;
    return st ;
}
Exemplo n.º 3
0
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 ;
}
Exemplo n.º 4
0
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 ) ;
}
Exemplo n.º 5
0
static string_t _get_crypto_info_from_tcplay( const char * mapper )
{
	int key_size ;

	int ro ;

	int64_t offset ;

	tc_api_task task ;

	char buff[ SIZE ] ;
	char * buffer = buff ;

	const char * z ;

	string_t p = StringVoid ;

	string_t q ;

	if( tc_api_initialize() ){

		if( tc_api_task_initialize( &task,"info_mapped" ) ){

			p = String( mapper ) ;

			mapper = mapper + StringLastIndexOfChar_1( mapper,'/' ) + 1 ;

			tc_api_task_set( task,"map_name",mapper ) ;

			tc_api_task_do( task ) ;

			tc_api_task_info_get( task,"status",sizeof( buff ),buff ) ;

			StringMultipleAppend( p," is ",buff,".",NULL ) ;

			if( StringAtLeastOneMatch_1( buff,"active","active and is in use",NULL ) ){

				tc_api_task_info_get( task,"type",sizeof( buff ),buff ) ;

				q = String( buff ) ;

				StringMultipleAppend( p," \n type:   \t",StringToLowerCase( q ),NULL ) ;

				StringDelete( &q ) ;

				tc_api_task_info_get( task,"cipher",sizeof( buff ),buff ) ;

				/*
				 * zuluCryptConvertCipher() is defined in create_tcrypt.c
				 */
				StringMultipleAppend( p,"\n cipher:\t",zuluCryptConvertCipher( buff ),"-xts-plain64",NULL ) ;

				tc_api_task_info_get( task,"key_bits",sizeof( key_size ),&key_size ) ;

				z = StringIntToString_1( buffer,SIZE,key_size ) ;

				StringMultipleAppend( p,"\n keysize:\t",z," bits",NULL ) ;

				tc_api_task_info_get( task,"iv_offset",sizeof( offset ),&offset ) ;

				z = StringIntToString_1( buffer,SIZE,offset / 512 ) ;

				StringMultipleAppend( p,"\n offset:\t",z," sectors",NULL ) ;

				zuluCryptFormatSize( offset,buffer,SIZE ) ;

				StringMultipleAppend( p," / ",buffer,NULL ) ;

				tc_api_task_info_get( task,"device",sizeof( buff ),buff ) ;

				_device_info( p,buff ) ;

				tc_api_task_info_get( task,"mode",sizeof( ro ),&ro ) ;

				if( ro ){

					StringAppend( p,"\n mode:   \tread only" ) ;
				}else{
					StringAppend( p,"\n mode:   \tread and write" ) ;
				}

				StringAppend( p,"\n active slots:\tNil" ) ;
			}

			tc_api_task_uninit( task ) ;
		}

		tc_api_uninit() ;
	}

	return p ;
}
Exemplo n.º 6
0
static string_t _get_crypto_info_from_cryptsetup( const char * mapper )
{
	char buff[ SIZE ] ;
	char * buffer = buff ;

	const char * z ;
	const char * type ;

	uint64_t e ;

	string_t q ;
	string_t p ;

	int k ;
	int i = 0 ;
	int j ;

	crypt_status_info info ;

	struct crypt_device * cd ;

	struct crypt_active_device cad ;

	if( crypt_init_by_name( &cd,mapper ) != 0 ){

		return StringVoid ;
	}

	p = String( mapper ) ;

	info = crypt_status( cd,mapper ) ;

	switch( info ){
	case CRYPT_INACTIVE :
		StringAppend( p," is inactive.\n" ) ;
		break ;
	case CRYPT_INVALID  :
		StringAppend( p," is invalid.\n" ) ;
		break ;
	case CRYPT_ACTIVE   :
		StringAppend( p," is active.\n" ) ;
		break ;
	case CRYPT_BUSY     :
		StringAppend( p," is active and is in use.\n" ) ;
		break ;
	default :
		StringAppend( p," is invalid.\n" ) ;
	}

	if( info == CRYPT_ACTIVE || info == CRYPT_BUSY ){

		StringAppend( p," type:   \t" ) ;

		type = crypt_get_type( cd ) ;

		if( type != NULL ){

			q = String( type ) ;
			StringAppend( p,StringToLowerCase( q ) ) ;
			StringDelete( &q ) ;
		}else{
			q = _get_type_from_udev_1( mapper ) ;

			StringAppendString( p,q ) ;

			StringDelete( &q ) ;
		}

		z = crypt_get_cipher( cd ) ;

		if( z != NULL ){

			StringMultipleAppend( p,"\n cipher:\t",z,"-",NULL ) ;
		}else{
			StringAppend( p,"\n cipher:\tNil-" ) ;
		}

		z = crypt_get_cipher_mode( cd ) ;

		if( z != NULL ){

			StringAppend( p,z ) ;
		}else{
			StringAppend( p,"Nil" ) ;
		}

		z = StringIntToString_1( buffer,SIZE,8 * crypt_get_volume_key_size( cd ) ) ;
		StringMultipleAppend( p,"\n keysize:\t",z," bits",NULL ) ;

		e = crypt_get_data_offset( cd ) ;

		z = StringIntToString_1( buffer,SIZE,e ) ;
		StringMultipleAppend( p,"\n offset:\t",z," sectors",NULL ) ;

		zuluCryptFormatSize( e * 512,buffer,SIZE ) ;
		StringMultipleAppend( p," / ",buffer,NULL ) ;

		_device_info( p,crypt_get_device_name( cd ) ) ;

		crypt_get_active_device( NULL,mapper,&cad ) ;

		if( cad.flags == 1 ){

			StringAppend( p,"\n mode:   \tread only" ) ;
		}else{
			StringAppend( p,"\n mode:   \tread and write" ) ;
		}

		k = crypt_keyslot_max( crypt_get_type( cd ) ) ;

		if( k > 0 ){

			i = 0 ;

			for( j = 0 ; j < k ; j++ ){

				switch( crypt_keyslot_status( cd,j ) ){

					case CRYPT_SLOT_ACTIVE_LAST : i++ ; break ;
					case CRYPT_SLOT_ACTIVE      : i++ ; break ;
					default : ;
				}
			}

			StringMultipleAppend( p,"\n active slots:\t",StringIntToString_1( buffer,SIZE,i ),NULL ) ;

			StringMultipleAppend( p," / ",StringIntToString_1( buffer,SIZE,k ),NULL ) ;
		}else{
			StringAppend( p,"\n active slots:\tNil" ) ;
		}
	}

	crypt_free( cd ) ;

	return p ;
}
Exemplo n.º 7
0
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 ) ;
}
Exemplo n.º 8
0
int zuluCryptOpenVolume( const char * dev,const char * mapper,
			 const char * m_point,uid_t id,unsigned long m_opts,
			 const char * fs_opts,const char * pass,size_t pass_size ) 
{
	int h ;
	string_t p = StringVoid ;
	string_t q = StringVoid ;
	int lmode ;
	int fd ;
	const char * mode ;
	const char * mapper_1 ;
	/*
	 * zuluCryptPathIsNotValid() is defined in is_path_valid.c
	 */
	if( zuluCryptPathIsNotValid( dev ) ){
		return 3 ;
	}
	
	/*
	 * zuluCryptMapperPrefix() is defined in create_mapper_name.c
	 */
	p = String( zuluCryptMapperPrefix() ) ;
	
	mapper_1 = StringMultipleAppend( p,"/",mapper,END ) ;

	/*
	 * zuluCryptPathIsValid() is defined in is_path_valid.c
	 */
	if( zuluCryptPathIsValid( mapper_1 ) ){
		return zuluExit( 2,p ) ;
	}
	if( m_opts & MS_RDONLY ){
		lmode = O_RDONLY ;
		mode = "ro" ;
	}else{
		lmode = O_RDWR ;
		mode = "rw" ;
	}
	
	if( StringPrefixMatch( dev,"/dev/",5 ) ){
		h = _open_mapper( dev,mapper,mode,pass,pass_size ) ;
	}else{
		/*
		 * zuluCryptAttachLoopDeviceToFile() is defined in create_loop_device.c
		 */
		if( zuluCryptAttachLoopDeviceToFile( dev,lmode,&fd,&q ) ){
			dev = StringContent( q ) ;
			h = _open_mapper( dev,mapper,mode,pass,pass_size ) ;
			close( fd ) ;
			StringDelete( &q ) ;
		}else{
			h = 1 ;
		}
	}

	switch( h ){
		case 1 : return zuluExit( 4,p ) ;
		case 2 : return zuluExit( 8,p ) ; 
		case 3 : return zuluExit( 3,p ) ;
	}
		
	if( m_point != NULL ){
		/*
		 * zuluCryptMountVolume() is defined in mount_volume.c
		 */
		h = zuluCryptMountVolume( mapper_1,m_point,m_opts,fs_opts,id ) ;
	
		if( h != 0 ){
			/*
			 * zuluCryptCloseMapper() is defined in close_mapper.c
			 */
			if( zuluCryptCloseMapper( mapper_1 ) != 0 ){
				h = 15 ;
			}
		}
	}
	
	return zuluExit( h,p ) ;
}
Exemplo n.º 9
0
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;
}
Exemplo n.º 10
0
int zuluCryptEXEOpenVolume( const struct_opts * opts,const char * mapping_name,uid_t uid )
{
	int share                = opts->share ;
	int open_mount           = opts->open_mount ;
	const char * device      = opts->device ;
	const char * mount_point = opts->mount_point ;
	const char * m_opts      = opts->m_opts ;
	const char * source      = opts->key_source ;
	const char * pass        = opts->key ;
	const char * plugin_path = opts->plugin_path ;
	const char * fs_opts     = opts->fs_opts ;
	const char * offset      = opts->offset ;
	const char * const * tcrypt_keyfiles = opts->tcrypt_multiple_keyfiles ;
	/*
	 * 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,6 ) ;
	string_t * passphrase  =  &stringArray[ 0 ] ;
	string_t * m_name      =  &stringArray[ 1 ] ;
	string_t * data        =  &stringArray[ 2 ] ;
	string_t * m_point     =  &stringArray[ 3 ] ;
	string_t * mapper      =  &stringArray[ 4 ] ;
	string_t * mapper_path =  &stringArray[ 5 ] ;

	const char * key = NULL ;
	const char * mapper_name ;
	const char * e ;

	size_t key_len = 0 ;
	int st = 0 ;

	stringList_t stz ;
	tvcrypt v_info ;

	unsigned long m_flags ;

	int tcrypt_keyfile  = 0 ;

	const char * uuid ;
	char * device_path ;

	/*
	 * open_struct_t is declared in ../lib/include.h
	 */
	open_struct_t volume ;

	struct stat statstr ;

	/*
	 * zuluCryptVolumeIsInSystemVolumeList() is defined in volumes.c
	 */
	if( zuluCryptVolumeIsInSystemVolumeList( device ) ){
		/*
		 * check permissions only if volume is explicity mentioned as system.
		 * This is an exception to avoid some udev bad behaviors on udev enabled build
		 */
		if( !zuluCryptUserIsAMemberOfAGroup( uid,"zulucrypt" ) ){
			return zuluExit( 22,device,mount_point,stl ) ;
		}
	}
	if( m_opts == NULL ){

		m_opts = "rw" ;
	}
	/*
	 * zuluCryptMountFlagsAreNotCorrect() is defined in ./mount_flags.c
	 */
	if( zuluCryptMountFlagsAreNotCorrect( m_opts,uid,&m_flags ) ){

		return zuluExit( 5,device,mount_point,stl ) ;
	}
	if( StringHasComponent( m_opts,"rw" ) ){
		/*
		 * zuluCryptSecurityDeviceIsWritable() is defined in path_access.c
		 */
		st = zuluCryptCanOpenPathForWriting( device,uid ) ;
	}else{
		/*
		 * zuluCryptSecurityDeviceIsReadable() is defined in path_access.c
		 */
		st = zuluCryptCanOpenPathForReading( device,uid ) ;
	}

	/*
	 * 1-permissions denied
	 * 2-invalid path
	 * 3-shenanigans
	 * 4-common error
	 */
	switch( st ){

		case 0 :  break ;
		case 1 :  return zuluExit( 6,device,mount_point,stl ) ;
		case 2 :  return zuluExit( 6,device,mount_point,stl ) ;
		case 3 :  return zuluExit( 6,device,mount_point,stl ) ;
		case 4 :  return zuluExit( 6,device,mount_point,stl ) ;
		default:  return zuluExit( 6,device,mount_point,stl ) ;
	}

	if( open_mount ){
		/*
		* zuluCryptCreateMountPoint() is defined in create_mount_point.c
		*/
		*m_point = zuluCryptCreateMountPoint( device,mount_point,m_opts,uid ) ;

		mount_point = StringContent( *m_point ) ;

		if( mount_point == NULL ){

			return zuluExit( 9,device,mount_point,stl ) ;
		}
	}else{
		if( uid != 0 ){

			return zuluExit( 7,device,mount_point,stl ) ;
		}
		if( mount_point != NULL ){

			return zuluExit( 8,device,mount_point,stl ) ;
		}
	}

	if( share ){
		/*
		 * zuluCryptBindSharedMountPointPathTaken() is defined in bind.c
		 */
		if( zuluCryptBindSharedMountPointPathTaken( *m_point ) ){

			return zuluExit_1( 10,opts,device,mount_point,stl ) ;
		}
	}

	/*
	 * zuluCryptCreateMapperName() is defined in ../lib/create_mapper_name.c
	 */
	*m_name = zuluCryptCreateMapperName( device,mapping_name,uid,ZULUCRYPTshortMapperPath ) ;

	*mapper = StringCopy( *m_name ) ;
	mapper_name = StringContent( *m_name ) ;

	*mapper_path = String( zuluCryptMapperPrefix() ) ;
	e = StringMultipleAppend( *mapper_path,"/",mapper_name,NULL ) ;

	if( stat( e,&statstr ) == 0 ){

		return zuluExit_1( 11,opts,device,mount_point,stl ) ;
	}

	if( plugin_path != NULL ){
		/*
		 * zuluCryptUUIDFromPath() is defined in path_access.c
		 */
		uuid = zuluCryptUUIDFromPath( device ) ;

		device_path = _device_path( device ) ;
		/*
		 * zuluCryptPluginManagerGetKeyFromModule is defined in ../pluginManager/zuluCryptPluginManager.c
		 */
		*passphrase = zuluCryptPluginManagerGetKeyFromModule( device_path,plugin_path,uuid,uid,opts,&st ) ;

		StringFree( device_path ) ;
		StringFree( uuid ) ;

		if( st != 0 || *passphrase == StringVoid ){

			return zuluExit_1( 12,opts,device,mount_point,stl ) ;
		}

		key_len = StringLength( *passphrase ) ;
		key = StringContent( *passphrase ) ;

		zuluCryptSecurityLockMemory_1( *passphrase ) ;

	}else if( source == NULL && tcrypt_keyfiles[ 0 ] == 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_1( 13,opts,device,mount_point,stl ) ;
			case 2 : return zuluExit_1( 14,opts,device,mount_point,stl ) ;
		}

		printf( "\n" ) ;
		key = StringContent( *passphrase ) ;
		key_len = StringLength( *passphrase ) ;

		zuluCryptSecurityLockMemory_1( *passphrase ) ;
	}else{
		if( source == NULL || pass == NULL ){

			if( tcrypt_keyfiles == NULL ){

				return zuluExit_1( 15,opts,device,mount_point,stl ) ;
			}
		}
		if( StringsAreEqual( source,"-p" ) ){

			key = pass ;
			key_len = StringSize( pass ) ;

		}else if( StringsAreEqual( source,"-f" ) ){

			if( StringHasNoComponent( pass,"/.zuluCrypt-socket" ) ){

				tcrypt_keyfile = 1 ;
			}
			/*
			 * function is defined at "path_access.c"
			 */
			switch( zuluCryptGetPassFromFile( pass,uid,data ) ){

				case 1 : return zuluExit_1( 16,opts,device,mount_point,stl ) ;
				case 2 : return zuluExit_1( 17,opts,device,mount_point,stl ) ;
				case 4 : return zuluExit_1( 18,opts,device,mount_point,stl ) ;
				case 5 : return zuluExit_1( 19,opts,device,mount_point,stl ) ;
			}
			key = StringContent( *data ) ;
			key_len = StringLength( *data ) ;

			zuluCryptSecurityLockMemory_1( *data ) ;
		}
	}

	memset( &volume,'\0',sizeof( open_struct_t ) ) ;

	if( key != NULL ){

		volume.key     = key ;
		volume.key_len = key_len ;
	}else{
		volume.key     = "" ;
		volume.key_len = 0 ;
	}

	volume.device      = device ;
	volume.offset      = offset ;
	volume.mapper_name = mapper_name ;
	volume.m_point     = mount_point ;
	volume.fs_opts     = fs_opts ;
	volume.uid         = uid ;
	volume.m_opts      = m_opts ;
	volume.m_flags     = m_flags ;

	/*
	 * zuluCryptTrueCryptVeraCryptVolumeInfo() is defined in this source file.
	 */
	zuluCryptTrueCryptVeraCryptVolumeInfo( opts->type,&v_info ) ;

	volume.iteration_count = v_info.iteration_count ;

	volume.veraCrypt_volume = StringAtLeastOneMatch( v_info.type,"vcrypt","veracrypt","vera",NULL ) ;

	StringDelete( &v_info.type ) ;

	plugin_path = plugin_path + StringLastIndexOfChar_1( plugin_path,'/' ) + 1 ;

	volume.luks_detached_header = StringHasComponent( plugin_path,"luks" ) ;

	volume.general_detached_header = StringHasComponent( plugin_path,"generic_header" ) ;

	if( tcrypt_keyfile ){

		volume.key_source = TCRYPT_KEYFILE ;
	}

	if( tcrypt_keyfiles[ 0 ] != NULL ){

		/*
		 * Here, we take a list of keyfiles supplied by the user and then copy them to a safe
		 * location at "/run/zuluCrypt" and then we pass these safe copies to cryptsetup.
		 *
		 * The idea is not to let cryptsetup, a privileged process handle user managed files.
		 */

		stz = zuluCryptCreateKeyFiles( tcrypt_keyfiles,0 ) ;

		volume.tcrypt_keyfiles_count = StringListSize( stz ) ;
		volume.tcrypt_keyfiles       = StringListStringArray_0( stz ) ;

		st = _open_volume( &volume ) ;

		zuluCryptDeleteKeyFiles( stz ) ;

		StringFree( volume.tcrypt_keyfiles ) ;
		StringListDelete( &stz ) ;
	}else{
		st = _open_volume( &volume ) ;
	}

	/*
	 * below two return values comes from ../lib/mount_volume.c
	 */
	if( st == -1 ){
		st = 20 ;
	}
	if( st == 12 ){
		st = 21 ;
	}
	if( st == 8 || st == 3 ){
		st = 3 ;
	}

	device = StringMultiplePrepend( *mapper,"/",zuluCryptMapperPrefix(),NULL ) ;

	if( st == 0 && share ){

		/*
		 * user wish to share the mount point bind the mount point to a publicly accessed path at /run/media/public/
		 */
		/*
		 * zuluCryptBindMountVolume() is defined in ../zuluCrypt-cli/bin/bind.c
		 */
		zuluCryptBindMountVolume( device,*m_point,m_flags ) ;
	}

	/*
	 * zuluCryptCheckInvalidKey() is defined in check_invalid_key.c
	 */
	zuluCryptCheckInvalidKey( opts->device ) ;
	return zuluExit_1( st,opts,device,mount_point,stl ) ;
}