char * zuluCryptLoopDeviceAddress_1( const char * device )
{
	int fd ;
	char * path ;
	struct loop_info64 l_info ;

	string_t st = String_1( "/sys/block/",device + 5,"/loop/backing_file",NULL ) ;

	string_t xt = _StringGetFromVirtualFile( &st ) ;

	if( xt == StringVoid ){

		memset( &l_info,'\0',sizeof( struct loop_info64 ) ) ;

		fd = open( device,O_RDONLY ) ;

		ioctl( fd,LOOP_GET_STATUS64,&l_info ) ;

		path = zuluCryptRealPath( ( char * ) l_info.lo_file_name ) ;

		close( fd ) ;

		st = String( path ) ;

		StringFree( path ) ;

		_clean_loop_path( st ) ;
		return StringDeleteHandle( &st ) ; ;
	}else{
		_clean_loop_path( xt ) ;
		return StringDeleteHandle( &xt ) ;
	}
}
/*
 * 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 ;
}
示例#4
0
char * zuluCryptVolumeStatus( const char * mapper )
{
	char * path ;

	string_t p ;

	if( zuluCryptTrueCryptOrVeraCryptVolume( mapper ) ){

		p = _get_crypto_info_from_tcplay( mapper ) ;
	}else{
		p = _get_crypto_info_from_cryptsetup( mapper ) ;
	}

	if( p == StringVoid ){

		return NULL ;
	}else{
		/*
		 * zuluCryptGetMountPointFromPath() is defined in ./process_mountinfo.c
		 */
		path = zuluCryptGetMountPointFromPath( mapper ) ;

		if( path != NULL ){

			zuluCryptFileSystemProperties( p,mapper,path ) ;
			StringFree( path ) ;
		}

		return StringDeleteHandle( &p ) ;
	}
}
示例#5
0
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 ;
}
示例#6
0
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 ) ;
		}
	}
}
示例#7
0
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 ) ;
	}
}
示例#8
0
static char * _empty_slots( const char * device,const resolve_path_t * opts )
{
	struct crypt_device * cd;

	int j ;
	int k ;
	const char * type ;

	string_t p ;

	if( opts ){;}

	if( crypt_init( &cd,device ) != 0 ){
		return zuluExit( NULL,NULL ) ;
	}
	if( crypt_load( cd,NULL,NULL ) != 0 ){
		return zuluExit( NULL,cd ) ;
	}

	type = crypt_get_type( cd ) ;

	if( type == NULL ){
		return zuluExit( NULL,cd ) ;
	}

	k = crypt_keyslot_max( type ) ;

	if( k < 0 ){
		return zuluExit( NULL,cd ) ;
	}

	p = StringEmpty() ;

	for( j = 0 ; j < k ; j++ ){
		switch( crypt_keyslot_status( cd,j ) ){
			case CRYPT_SLOT_INACTIVE   : StringAppend( p,"0" ) ; break ;
			case CRYPT_SLOT_ACTIVE     : StringAppend( p,"1" ) ; break ;
			case CRYPT_SLOT_INVALID    : StringAppend( p,"2" ) ; break ;
			case CRYPT_SLOT_ACTIVE_LAST: StringAppend( p,"3" ) ; break ;
			default : ;
		}
	}

	return zuluExit( StringDeleteHandle( &p ),cd ) ;
}
示例#9
0
char * zuluCryptGetUUIDFromMapper( const char * mapper )
{
	string_t uuid ;
	struct crypt_device * cd ;

	const char * id ;
	const char * e = " UUID:   \t\"Nil\"" ;

	char * f ;

	if( crypt_init_by_name( &cd,mapper ) < 0 ){

		uuid = String( e ) ;
	}else{
		id = crypt_get_uuid( cd ) ;

		if( id == NULL ){

			/*
			 * Either not a LUKS volume or a LUKS volume but with a detached header.
			 * consult udev to see if it can sort this volume out.
			 */

			f = _get_uuid_from_udev( mapper ) ;

			if( f == NULL ){

				uuid = String( e ) ;
			}else{
				uuid = String_1( " UUID:   \t\"",f,"\"",NULL ) ;
				StringFree( f ) ;
			}

		}else{
			uuid = String_1( " UUID:   \t\"",id,"\"",NULL ) ;
		}

		crypt_free( cd ) ;
	}

	return StringDeleteHandle( &uuid ) ;
}
示例#10
0
char * zuluCryptGetMountPointFromPath( const char * path )
{
    string_t st = zuluCryptGetMountEntry( path ) ;
    stringList_t stl ;

    if( st == StringVoid ) {
        return NULL ;
    } else {
        stl = StringListStringSplit( st,' ' ) ;
        StringDelete( &st ) ;
        if( stl == StringListVoid ) {
            return NULL ;
        } else {
            st = StringListCopyStringAtSecondPlace( stl ) ;
            StringListDelete( &stl ) ;
            zuluCryptDecodeMountEntry( st ) ;
            return StringDeleteHandle( &st ) ;
        }
    }
}
示例#11
0
char * zuluCryptGetVolumeTypeFromMapperPath( const char * mapper )
{
	struct crypt_device * cd ;
	const char * type ;
	char * r ;
	string_t st ;

	if( StringPrefixNotEqual( mapper,crypt_get_dir() ) ){

		return StringCopy_2( "Nil" ) ;
	}

	if( crypt_init_by_name( &cd,mapper ) < 0 ){

		return StringCopy_2( "Nil" ) ;
	}

	type = crypt_get_type( cd ) ;

	if( type == NULL ){

		if( StringHasComponent( mapper,"veracrypt" ) ){

			r = StringCopy_2( "crypto_VCRYPT" ) ;

		}else if( StringHasComponent( mapper,"truecrypt" ) ){

			r = StringCopy_2( "crypto_TCRYPT" ) ;
		}else{
			r = _get_type_from_udev( mapper ) ;
		}
	}else{
		st = String_1( "crypto_",type,NULL ) ;
		r = StringDeleteHandle( &st ) ;
	}

	crypt_free( cd ) ;
	return r ;
}
示例#12
0
static char * _convert_if_path_is_lvm( const char * path )
{
	string_t st = zuluCryptConvertIfPathIsLVM( path ) ;
	return StringDeleteHandle( &st ) ;
}
示例#13
0
char * zuluCryptResolveMDPath( const char * path )
{
	string_t st = zuluCryptResolveMDPath_1( path ) ;
	return StringDeleteHandle( &st ) ;
}
示例#14
0
static char * _get_uuid_from_udev( const char * mapper )
{
	string_t st = _get_mapper_property_from_udev( mapper,"dm-uuid-CRYPT-LUKS",UUID ) ;
	return StringDeleteHandle( &st ) ;
}
示例#15
0
int zuluCryptGetDeviceFileProperties( const char * file,int * fd_path,int * fd_loop,char ** dev,uid_t uid )
{
	int st = 100 ;
	int xt = 0 ;
	int lfd ;

	const char * dev_1 = NULL ;
	string_t st_dev = StringVoid ;

	struct stat stat_st ;
	struct stat stat_st_1 ;
	/*
	 * try to open the device with user privileges
	 */
	seteuid( uid ) ;

	*dev = NULL ;

	*fd_path = open( file,O_RDONLY ) ;

	if( *fd_path != -1 ){
		fstat( *fd_path,&stat_st ) ;
		fcntl( *fd_path,F_SETFD,FD_CLOEXEC ) ;
		/*
		 * A user has access to the device.They should get here only with paths to files they have access to.
		 * Allow access to files only
		 */
		if( S_ISREG( stat_st.st_mode ) ){
			/*
			 * we can open file in read mode,let see if we can in write mode too
			 */
			lfd = open( file,O_RDWR ) ;
			if( lfd != -1 ){
				/*
				 * we can open the file in read write mode
				 */
				fstat( lfd,&stat_st_1 ) ;
				fcntl( lfd,F_SETFD,FD_CLOEXEC ) ;

				/*
				 * check to make sure the file we got earlier is the same one we got now.
				 * ie check to make sure the file wasnt changed btw calls.
				 */
				if( stat_st.st_dev == stat_st_1.st_dev && stat_st.st_ino == stat_st_1.st_ino ){
					close( *fd_path ) ;
					*fd_path = lfd ;
					seteuid( 0 ) ;
					/*
					 * zuluCryptAttachLoopDeviceToFileUsingFileDescriptor() is defined in ./create_loop_device.c
					 */
					xt = zuluCryptAttachLoopDeviceToFileUsingFileDescriptor( *fd_path,fd_loop,O_RDWR,&st_dev ) ;
					seteuid( uid ) ;
					*dev = StringDeleteHandle( &st_dev ) ;
				}
			}else{
				/*
				 * we can not open the file in write mode,continue with read only access
				 */
				seteuid( 0 ) ;
				/*
				 * zuluCryptAttachLoopDeviceToFileUsingFileDescriptor() is defined in ./create_loop_device.c
				 */
				xt = zuluCryptAttachLoopDeviceToFileUsingFileDescriptor( *fd_path,fd_loop,O_RDONLY,&st_dev ) ;
				seteuid( uid ) ;
				*dev = StringDeleteHandle( &st_dev ) ;
			}
			if( xt != 1 ){
				st = 100 ;
				close( *fd_path ) ;
				*fd_path = -1 ;
			}else{
				dev_1 = zuluCryptGetFileNameFromFileDescriptor( *fd_path ) ;
				if( StringPrefixEqual( dev_1,"/dev/shm/" ) ){
					st =1 ;
					close( *fd_path ) ;
					*fd_path = -1 ;
				}else{
					st = 0 ;
				}
				StringFree( dev_1 ) ;
			}
		}else{
			if( S_ISBLK( stat_st.st_mode ) ){
				if( uid == 0 ) {
					/*
					 * we got a block device and we are root,accept it
					 */
					*dev = zuluCryptGetFileNameFromFileDescriptor( *fd_path ) ;
					st = 0 ;
				}else{
					/*
					 * odd,normal user has access to a block device,allow it only if the
					 * device is in "/dev/" but not in "/dev/shm"
					 */
					*dev = zuluCryptGetFileNameFromFileDescriptor( *fd_path ) ;
					if( StringPrefixEqual( *dev,"/dev/shm/" ) ){
						st = 1 ;
					}else if( StringPrefixEqual( *dev,"/dev/" ) ){
						st = 0 ;
					}
				}
			}else if( S_ISDIR( stat_st.st_mode ) ){
				st = 2 ;
			}else{
				/*
				 * whatever it is,it cant be good,reject it
				 */
				st = 100 ;
			}
			close( *fd_path ) ;
			*fd_path = -1 ;
		}
	}else{
		/*
		 * failed to open above with users privileges,try to open the device with root's privileges.
		 * We should only accept block devices in "/dev/" but not in "/dev/shm".
		 */
		seteuid( 0 ) ;

		*fd_path = open( file,O_RDONLY ) ;

		if( *fd_path != -1 ){
			fstat( *fd_path,&stat_st ) ;
			/*
			 * zuluCryptGetFileNameFromFileDescriptor() is defined in ./create_loop_device.c
			 */
			*dev = zuluCryptGetFileNameFromFileDescriptor( *fd_path ) ;

			if( S_ISBLK( stat_st.st_mode ) ){
				if( StringPrefixEqual( *dev,"/dev/shm/" ) ){
					/*
					* we do not support this path
					*/
					st = 1 ;
				}else if( StringPrefixEqual( *dev,"/dev/" ) ){
					/*
					* got a block device,accept it
					*/
					st = 0 ;
				}else{
					/*
					* reject others
					*/
					st = 100 ;
				}
			}else{
				/*
				 * whatever it is,it cant be good,reject it
				 */
				st = 100 ;
			}
			/*
			 * We are closing the file because we dont need to hold on to it as paths in "/dev/" can not be moved under us by
			 * normal users.
			 */
			close( *fd_path ) ;
			*fd_path = -1 ;
		}else{
			/*
			 * invalid path or something i dont know,reject
			 */
			st = 100 ;
		}

		seteuid( uid ) ;
	}

	return _check_if_device_is_supported( st,uid,dev ) ;
}
示例#16
0
char * zuluCryptLoopDeviceAddress( const char * device )
{
	string_t st = zuluCryptLoopDeviceAddress_2( device ) ;
	return StringDeleteHandle( &st ) ;
}
示例#17
0
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 ;
}