123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561 |
- package de.tudarmstadt.informatik.hostage.persistence;
- import org.json.JSONArray;
- import org.json.JSONException;
- import org.json.JSONObject;
- import android.content.Context;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.StreamCorruptedException;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Collection;
- import java.util.HashMap;
- import java.util.LinkedList;
- import java.util.List;
- import java.util.Map;
- import java.util.Random;
- import de.tudarmstadt.informatik.hostage.R;
- import de.tudarmstadt.informatik.hostage.model.Profile;
- import de.tudarmstadt.informatik.hostage.ui2.activity.MainActivity;
- import de.tudarmstadt.informatik.hostage.ui2.adapter.ProfileManagerListAdapter;
- /**
- * The profile manager is responsible for persisting and deleting profiles
- *
- * @author Alexander Brakowski
- * @created 10.02.14 20:24
- */
- public class ProfileManager {
- /**
- * The singleton instance holder
- */
- private static ProfileManager INSTANCE = null;
- /**
- * An list adapter, which the profile manager informs about data changes
- */
- private ProfileManagerListAdapter mProfileListAdapter = null;
- /**
- * Holds a reference to the currently active profile
- */
- private Profile mCurrentActivatedProfile = null;
- /**
- * Holds a reference to the random profile
- */
- private Profile mRandomProfile = null;
- /**
- * The profiles are being serialized and persisted into this file
- */
- private static final String PERSIST_FILENAME = "hostage_profiles.json";
- /**
- * Hold the current profile id, it will be incremented each time a new profile is added.
- * The new profile will get the newly incremented value as an id.
- */
- public int mIncrementValue = 1;
- /**
- * Holds all the available profiles. The key in the map is the ID of the profile.
- */
- public HashMap<Integer, Profile> mProfiles;
- /**
- * Since the profile manager should only have one instance in the whole app, we are using the singleton pattern.
- * This method creates a new instance of the profile manager, if no instance already exists, and returns it.
- *
- * @return the singleton instance
- */
- public static ProfileManager getInstance(){
- if(INSTANCE == null){
- INSTANCE = new ProfileManager();
- }
- if(INSTANCE.getNumberOfProfiles() == 0){
- INSTANCE.loadData();
- }
- return INSTANCE;
- }
- /**
- * A private constructor, that can/should only be called by getInstance, since we want to enforce the usage of the singleton.
- */
- private ProfileManager(){
- mProfiles = new HashMap<Integer, Profile>();
- }
- /**
- * Reads all data from an inputstream and appends it to a string
- *
- * @param is The input stream to read the data from
- * @return the whole data from the input stream as an string
- */
- public String readAll( final InputStream is ) {
- if( null == is ) {
- return "";
- }
- StringBuilder sb = new StringBuilder();
- int rc;
- try {
- while( (rc = is.read()) >= 0 ){
- sb.append( (char) rc );
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- return sb.toString();
- }
- /**
- * Reads all the data of the the profiles, that were persisted and unserializes them.
- *
- * The profiles were serialized into JSON and persisted into the android private file.
- * See {@see ProfileManager#persistData}.
- */
- public void loadData(){
- try {
- FileInputStream fin = MainActivity.getContext().openFileInput(PERSIST_FILENAME);
- JSONArray arr = new JSONArray(readAll(fin));
- fin.close();
- for(int i=0; i<arr.length(); i++){
- JSONObject obj = arr.getJSONObject(i);
- Profile p = new Profile();
- p.fromJSON(obj);
- mProfiles.put(p.mId, p);
- if(p.mId > mIncrementValue){
- mIncrementValue = p.mId;
- }
- if(p.mActivated){
- this.mCurrentActivatedProfile = p;
- }
- if(p.mIsRandom){
- this.mRandomProfile = p;
- }
- }
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (StreamCorruptedException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- } catch (JSONException e) {
- e.printStackTrace();
- } finally {
- if(mProfiles.size() == 0){
- this.fillWithDefaultData();
- }
- if(this.mRandomProfile != null){
- randomizeProtocols(mRandomProfile);
- }
- }
- }
- /**
- * All the profiles that are hold by the profile manager are being serialized into JSON and then written into an private android file.
- */
- public void persistData(){
- try {
- FileOutputStream fout = MainActivity.getContext().openFileOutput(PERSIST_FILENAME, Context.MODE_PRIVATE);
- JSONArray arr = new JSONArray();
- for(Profile p: mProfiles.values()){
- arr.put(p.toJSON());
- }
- fout.write(arr.toString().getBytes());
- fout.close();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- /**
- * Retrieves all the profiles as an List
- * @return a list that holds all the profiles
- */
- public List<Profile> getProfilesList(){
- return new ArrayList<Profile>(getProfilesCollection());
- }
- /**
- * Retrieves all the profiles as an collection
- * @return a collection of all the profiles
- */
- public Collection<Profile> getProfilesCollection(){
- if(mProfiles.size() == 0 || mProfiles == null){
- this.loadData();
- }
- return mProfiles.values();
- }
- /**
- * Retrieves an map of all the profiles. The key in the map is the ID of an profile.
- * @return a map of profiles
- */
- public Map<Integer, Profile> getMapProfiles(){
- return mProfiles;
- }
- /**
- * Activates and deactivates protocols randomly in the given profile
- *
- * @param profile the profile to randomize the protocols for
- */
- public void randomizeProtocols(Profile profile){
- LinkedList<String> protocols = new LinkedList<String>(Arrays.asList(MainActivity.getContext().getResources().getStringArray(R.array.protocols)));
- protocols.remove("GHOST");
- profile.mActiveProtocols.clear();
- Random rand = new Random();
- int numberOfProtocolsToActivate = rand.nextInt(protocols.size()) + 1;
- while(numberOfProtocolsToActivate-- > 0){
- int randomIndex = rand.nextInt(protocols.size());
- String protocol = protocols.get(randomIndex);
- profile.mActiveProtocols.put(protocol, true);
- protocols.remove(protocol);
- }
- persistData();
- }
- /**
- * Adds or updates a given profile.
- *
- * @param profile the profile to persist
- * @return the id the profile was assigned to
- */
- public int persistProfile(Profile profile){
- if(profile.mId == -1){
- profile.mId = ++mIncrementValue;
- }
- mProfiles.put(profile.mId, profile);
- this.persistData();
- if(this.mProfileListAdapter != null){
- this.mProfileListAdapter.notifyDataSetChanged();
- }
- return profile.mId;
- }
- /**
- * Retrieves the profile with the given id
- *
- * @param id the id of the profile
- * @return the profile
- */
- public Profile getProfile(int id){
- if(mProfiles.size() == 0){
- loadData();
- }
- if(this.mProfiles.containsKey(id)){
- return this.mProfiles.get(id);
- }
- return null;
- }
- /**
- * Adds a profile
- *
- * @param profile the profile to add
- */
- public void addProfile(Profile profile){
- this.addProfile(profile, true);
- }
- /**
- * Adds a given profile to the profile manager.
- *
- * @param profile the profile to add
- * @param persist true, if the profile should also be persisted immediatly,
- * false, if the profile should just be added internally without being persisted
- * (Note: you can still call persistData later to persist all the profiles)
- */
- public void addProfile(Profile profile, boolean persist){
- if(profile.mId == -1){
- profile.mId = ++mIncrementValue;
- }
- mProfiles.put(profile.mId, profile);
- if(persist){
- persistData();
- }
- if(this.mProfileListAdapter != null){
- this.mProfileListAdapter.add(profile);
- this.mProfileListAdapter.notifyDataSetChanged();
- }
- }
- /**
- * Deletes a given profile. These changes will be persisted immediatly.
- *
- * @param profile the profile to delete
- */
- public void deleteProfile(Profile profile){
- if(this.mProfiles.containsKey(profile.mId)){
- Profile p = getProfile(profile.mId);
- this.mProfiles.remove(profile.mId);
- if(p.mActivated || this.mCurrentActivatedProfile.mId == p.mId){
- mCurrentActivatedProfile = mRandomProfile;
- mRandomProfile.mActivated = true;
- }
- this.persistData();
- //this.dbh.deleteProfile(profile.mId);
- if(this.mProfileListAdapter != null){
- this.mProfileListAdapter.remove(profile);
- this.mProfileListAdapter.notifyDataSetChanged();
- }
- }
- }
- /**
- * Removes all profiles.
- */
- public void clearProfiles(){
- mProfiles.clear();
- persistData();
- }
- /**
- * Makes a given profile active.
- *
- * @param profile the profile to activate
- */
- public void activateProfile(Profile profile){
- if(profile.equals(this.mCurrentActivatedProfile)) return;
- if(this.mCurrentActivatedProfile != null){
- this.mCurrentActivatedProfile.mActivated = false;
- this.persistProfile(this.mCurrentActivatedProfile);
- }
- profile.mActivated = true;
- this.mCurrentActivatedProfile = profile;
- this.mProfiles.put(profile.mId, profile);
- persistData();
- }
- /**
- * Checks if the "random" profile is currently active
- *
- * @return true, if active
- * false, otherwise
- */
- public boolean isRandomActive(){
- return this.mCurrentActivatedProfile.equals(this.mRandomProfile);
- }
- /**
- * Retrieves the "random" profile
- *
- * @return the "random" profile
- */
- public Profile getRandomProfile(){
- return this.mRandomProfile;
- }
- /**
- * Retrieves the currently active profile
- *
- * @return the active profile
- */
- public Profile getCurrentActivatedProfile(){
- return mCurrentActivatedProfile;
- }
- /**
- * Sets the list adapter that should also be managed by the profile manager
- *
- * @param profileListAdapter the list adapter to manage
- */
- public void setProfileListAdapter(ProfileManagerListAdapter profileListAdapter){
- this.mProfileListAdapter = profileListAdapter;
- }
- /**
- * Retrieves the list adapter, that is being managed by the profile manager
- * @return the list adapter
- */
- public ProfileManagerListAdapter getProfileListAdapter(){
- return this.mProfileListAdapter;
- }
- /**
- * Retrieves the number of profiles
- *
- * @return the number of profiles
- */
- public int getNumberOfProfiles(){
- return mProfiles.size();
- }
- /**
- * Fills the profiles manager with default profiles
- */
- public void fillWithDefaultData(){
- Profile windowsVista = new Profile(
- 0,
- "Windows Vista",
- "This profile will imitate a Windows Vista machine",
- R.drawable.ic_profile_vista,
- false
- );
- windowsVista.mActiveProtocols.put("ECHO", true);
- windowsVista.mActiveProtocols.put("TELNET", true);
- this.addProfile(windowsVista, false);
- Profile windowsXP = new Profile(
- 1,
- "Windows XP",
- "This profile will activate Windows XP typical services",
- R.drawable.ic_profile_xp,
- false
- );
- windowsXP.mActiveProtocols.put("ECHO", true);
- windowsXP.mActiveProtocols.put("TELNET", true);
- windowsXP.mActiveProtocols.put("MySQL", true);
- this.addProfile(windowsXP, false);
- Profile serverHTTP = new Profile(
- 2,
- "Webserver HTTP",
- "This profile will imitate a simple webserver, which just supports the HTTP protocol",
- R.drawable.ic_profile_apache,
- false
- );
- serverHTTP.mActiveProtocols.put("HTTP", true);
- this.addProfile(serverHTTP, false);
- Profile serverWeb = new Profile(
- 3,
- "Webserver",
- "This profile will imitate a simple webserver, which supports both the HTTP and HTTPS protocol",
- R.drawable.ic_profile_apache,
- false
- );
- serverWeb.mActiveProtocols.put("HTTP", true);
- serverWeb.mActiveProtocols.put("HTTPS", true);
- this.addProfile(serverWeb, false);
- Profile unixMachine = new Profile(
- 4,
- "Unix",
- "This profile monitors unix typical services",
- R.drawable.ic_profile_unix,
- false
- );
- unixMachine.mActiveProtocols.put("SSH", true);
- unixMachine.mActiveProtocols.put("ECHO", true);
- this.addProfile(unixMachine, false);
- Profile linuxMachine = new Profile(
- 5,
- "Linux",
- "This profile will imitate a linux machine by monitoring linux typical services",
- R.drawable.ic_profile_linux,
- false
- );
- linuxMachine.mActiveProtocols.put("SSH", true);
- linuxMachine.mActiveProtocols.put("TELNET", true);
- linuxMachine.mActiveProtocols.put("ECHO", true);
- linuxMachine.mActiveProtocols.put("SMB", true);
- this.addProfile(linuxMachine, false);
- Profile voipServer = new Profile(
- 6,
- "VOIP Server",
- "This profile imitates a VOIP Server by monitoring the SIP service",
- R.drawable.ic_profile_asterisks,
- false
- );
- voipServer.mActiveProtocols.put("SIP", true);
- this.addProfile(voipServer, false);
- Profile randomProfile = new Profile(
- 7,
- "Random",
- "This profile monitors services randomly",
- R.drawable.ic_launcher,
- false
- );
- randomProfile.mIsRandom = true;
- this.addProfile(randomProfile, false);
- Profile paranoidProfile = new Profile(
- 8,
- "Paranoid",
- "This profile monitors all available services",
- R.drawable.ic_profile_paranoid,
- false
- );
- for(String protocol: MainActivity.context.getResources().getStringArray(R.array.protocols)){
- if(protocol.equals("GHOST")) continue;
- paranoidProfile.mActiveProtocols.put(protocol, true);
- }
- paranoidProfile.mActivated = true;
- this.addProfile(paranoidProfile, false);
- mIncrementValue = 8;
- this.mCurrentActivatedProfile = paranoidProfile;
- persistData();
- }
- }
|