static void GBACheatDumpDirectives(struct mCheatSet* set, struct StringList* directives) { struct GBACheatSet* cheats = (struct GBACheatSet*) set; // TODO: Check previous directives size_t d; for (d = 0; d < StringListSize(directives); ++d) { free(*StringListGetPointer(directives, d)); } StringListClear(directives); char** directive; switch (cheats->gsaVersion) { case 1: directive = StringListAppend(directives); *directive = strdup("GSAv1"); break; case 2: directive = StringListAppend(directives); *directive = strdup("GSAv1 raw"); break; case 3: directive = StringListAppend(directives); *directive = strdup("PARv3"); break; case 4: directive = StringListAppend(directives); *directive = strdup("PARv3 raw"); break; } }
static inline int _check_options( const char ** e,stringList_t stl ) { while( *e != NULL ){ StringListRemoveIfStringContains( stl,*e ) ; e++ ; } return StringListSize( stl ) > 0 ; }
bool mCheatSaveFile(struct mCheatDevice* device, struct VFile* vf) { static const char lineStart[3] = "# "; static const char lineEnd = '\n'; struct StringList directives; StringListInit(&directives, 4); size_t i; for (i = 0; i < mCheatSetsSize(&device->cheats); ++i) { struct mCheatSet* set = *mCheatSetsGetPointer(&device->cheats, i); set->dumpDirectives(set, &directives); if (!set->enabled) { static const char* disabledDirective = "!disabled\n"; vf->write(vf, disabledDirective, strlen(disabledDirective)); } size_t d; for (d = 0; d < StringListSize(&directives); ++d) { char directive[64]; ssize_t len = snprintf(directive, sizeof(directive) - 1, "!%s\n", *StringListGetPointer(&directives, d)); if (len > 1) { vf->write(vf, directive, (size_t) len > sizeof(directive) ? sizeof(directive) : len); } } vf->write(vf, lineStart, 2); if (set->name) { vf->write(vf, set->name, strlen(set->name)); } vf->write(vf, &lineEnd, 1); size_t c; for (c = 0; c < StringListSize(&set->lines); ++c) { const char* line = *StringListGetPointer(&set->lines, c); vf->write(vf, line, strlen(line)); vf->write(vf, &lineEnd, 1); } } size_t d; for (d = 0; d < StringListSize(&directives); ++d) { free(*StringListGetPointer(&directives, d)); } StringListClear(&directives); StringListDeinit(&directives); return true; }
void mCheatSetDeinit(struct mCheatSet* set) { mCheatListDeinit(&set->list); size_t i; for (i = 0; i < StringListSize(&set->lines); ++i) { free(*StringListGetPointer(&set->lines, i)); } if (set->name) { free(set->name); } set->deinit(set); free(set); }
static void GBACheatParseDirectives(struct mCheatSet* set, const struct StringList* directives) { struct GBACheatSet* cheats = (struct GBACheatSet*) set; size_t d; for (d = 0; d < StringListSize(directives); ++d) { const char* directive = *StringListGetConstPointer(directives, d); if (strcmp(directive, "GSAv1") == 0) { GBACheatSetGameSharkVersion(cheats, 1); continue; } if (strcmp(directive, "PARv3") == 0) { GBACheatSetGameSharkVersion(cheats, 3); continue; } } }
void GBACheatSetDeinit(struct GBACheatSet* set) { GBACheatListDeinit(&set->list); size_t i; for (i = 0; i < StringListSize(&set->lines); ++i) { free(*StringListGetPointer(&set->lines, i)); } if (set->name) { free(set->name); } if (set->hook) { --set->hook->refs; if (set->hook->refs == 0) { free(set->hook); } } }
bool GBACheatSaveFile(struct GBACheatDevice* device, struct VFile* vf) { static const char lineStart[3] = "# "; static const char lineEnd = '\n'; struct GBACheatHook* lastHook = 0; size_t i; for (i = 0; i < GBACheatSetsSize(&device->cheats); ++i) { struct GBACheatSet* set = *GBACheatSetsGetPointer(&device->cheats, i); if (lastHook && set->hook != lastHook) { static const char* resetDirective = "!reset\n"; vf->write(vf, resetDirective, strlen(resetDirective)); } switch (set->gsaVersion) { case 1: { static const char* versionDirective = "!GSAv1\n"; vf->write(vf, versionDirective, strlen(versionDirective)); break; } case 3: { static const char* versionDirective = "!PARv3\n"; vf->write(vf, versionDirective, strlen(versionDirective)); break; } default: break; } lastHook = set->hook; if (!set->enabled) { static const char* disabledDirective = "!disabled\n"; vf->write(vf, disabledDirective, strlen(disabledDirective)); } vf->write(vf, lineStart, 2); if (set->name) { vf->write(vf, set->name, strlen(set->name)); } vf->write(vf, &lineEnd, 1); size_t c; for (c = 0; c < StringListSize(&set->lines); ++c) { const char* line = *StringListGetPointer(&set->lines, c); vf->write(vf, line, strlen(line)); vf->write(vf, &lineEnd, 1); } } return true; }
void zuluCryptTrueCryptVeraCryptVolumeInfo( const char * type,tvcrypt * e ) { stringList_t stl = StringListSplit( type,'.' ) ; size_t p = StringListSize( stl ) ; const char * q ; memset( e,'\0',sizeof( tvcrypt ) ) ; if( p > 0 ){ e->type = StringListCopyStringAtFirstPlace( stl ) ; if( p > 1 ){ q = StringListContentAtSecondPlace( stl ) ; e->iteration_count = ( int )StringConvertToInt( q ) ; } } StringListDelete( &stl ) ; }
int zuluCryptUnmountVolume( const char * device,char ** m_point ) { int h = 3 ; char * e ; size_t s ; stringList_t stl ; StringListIterator it ; StringListIterator end ; ssize_t r ; string_t st ; string_t xt ; if( StringPrefixEqual( device,"/dev/loop" ) ){ /* * zuluCryptLoopDeviceAddress() is defined in create_loop_device.c */ e = zuluCryptLoopDeviceAddress( device ) ; if( e == NULL ){ return h ; }else{ stl = _get_mount_entries( e ) ; StringFree( e ) ; } }else{ stl = _get_mount_entries( device ) ; } s = StringListSize( stl ) ; if( s == 0 ){ /* * volume appear to not be mounted. */ }else if( s == 1 ){ /* * there is only one mount point for the volume,unmount it normally */ h = _zuluCryptUnmountVolume_0( StringListStringAtFirstPlace( stl ),m_point ) ; }else{ /* * There are multiple mount points for the same volume. * * Try to figure out which one among the mount points is ours and then try * first to unmount the rest of them. */ r = StringListHasSequence( stl," /run/media/private/" ) ; if( r == -1 ){ /* * Probable reason for getting here is if a user use a home mount point path, * we dont know the path because we dont know the user we are serving * and hence we bail out with an error. */ h = 10 ; }else{ /* * We got our mount point,take it out of the list to use it last */ st = StringListDetachAt( stl,r ) ; StringListGetIterators( stl,&it,&end ) ; while( it != end ){ xt = *it ; it++ ; if( _zuluCryptUnmountVolume_0( xt,NULL ) != 0 ){ /* * Failed to unmount one of the extra mount points, * bail out with an error. */ h = 10 ; break ; } } if( h != 10 ){ /* * Attempt to unmount our mount point last. */ h = _zuluCryptUnmountVolume_0( st,m_point ) ; } StringDelete( &st ) ; } } if( h != 0 && h != 3 && h != 4 && h != 1 && h != 10 ){ h = 2 ; } StringListDelete( &stl ) ; return h ; }
bool mCheatParseFile(struct mCheatDevice* device, struct VFile* vf) { char cheat[MAX_LINE_LENGTH]; struct mCheatSet* set = NULL; struct mCheatSet* newSet; bool nextDisabled = false; struct StringList directives; StringListInit(&directives, 4); while (true) { size_t i = 0; ssize_t bytesRead = vf->readline(vf, cheat, sizeof(cheat)); rtrim(cheat); if (bytesRead == 0) { break; } if (bytesRead < 0) { StringListDeinit(&directives); return false; } while (isspace((int) cheat[i])) { ++i; } switch (cheat[i]) { case '#': do { ++i; } while (isspace((int) cheat[i])); newSet = device->createSet(device, &cheat[i]); newSet->enabled = !nextDisabled; nextDisabled = false; if (set) { mCheatAddSet(device, set); } if (set) { newSet->copyProperties(newSet, set); } newSet->parseDirectives(newSet, &directives); set = newSet; break; case '!': do { ++i; } while (isspace((int) cheat[i])); if (strcasecmp(&cheat[i], "disabled") == 0) { nextDisabled = true; break; } if (strcasecmp(&cheat[i], "reset") == 0) { size_t d; for (d = 0; d < StringListSize(&directives); ++d) { free(*StringListGetPointer(&directives, d)); } StringListClear(&directives); break; } *StringListAppend(&directives) = strdup(&cheat[i]); break; default: if (!set) { set = device->createSet(device, NULL); set->enabled = !nextDisabled; nextDisabled = false; } mCheatAddLine(set, cheat, 0); break; } } if (set) { mCheatAddSet(device, set); } size_t d; for (d = 0; d < StringListSize(&directives); ++d) { free(*StringListGetPointer(&directives, d)); } StringListClear(&directives); StringListDeinit(&directives); return true; }
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 ) ; }