Browse Source

Implemented:
Make statistic view more presentable e.g. a table
Add an about field to the menu
Let the user decide about location and format of the exported log file
Show user the location of exported log files
Notify user that the data has been deleted
Notify user about the status of the database upload
Notify user about first attack in notification bar
A Session is finished when the application and is terminated or the wifi
changes
When the wifi changes stop active listener and handler

Bugs fixes(fixed on Android 2.2.1):
When you rotate the device the app crashes.
Switching between windows/apps terminates a current session. (the
session should only terminated when the app crashes/closed)

lp-tu 10 years ago
parent
commit
06f5cf1fdd

+ 10 - 3
AndroidManifest.xml

@@ -21,7 +21,8 @@
         android:theme="@style/AppTheme" >
         <activity
             android:name="de.tudarmstadt.informatik.hostage.ui.MainActivity"
-            android:label="@string/app_name" >
+            android:label="@string/app_name" 
+            android:configChanges="keyboardHidden|orientation|screenSize">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
@@ -33,15 +34,21 @@
         </activity>
        	<activity
             android:name="de.tudarmstadt.informatik.hostage.ui.ViewLogTable"
-            android:label="@string/logFile" >
+            android:label="@string/database" >
         </activity>
         
        	<activity
             android:name="de.tudarmstadt.informatik.hostage.ui.SettingsActivity"
             android:label="@string/settings" >
         </activity>
+        
+       	<activity
+            android:name="de.tudarmstadt.informatik.hostage.ui.AboutActivity"
+            android:label="@string/action_about" >
+        </activity>
 
-        <service android:name="de.tudarmstadt.informatik.hostage.HoneyService" >
+        <service 
+            android:name="de.tudarmstadt.informatik.hostage.HoneyService" >
         </service>
     </application>
 

BIN
res/drawable-hdpi/icon_service_green.png


BIN
res/drawable-hdpi/icon_service_red.png


BIN
res/drawable-hdpi/icon_service_yellow.png


+ 79 - 0
res/layout/activity_about.xml

@@ -0,0 +1,79 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:paddingBottom="@dimen/activity_vertical_margin"
+    android:paddingLeft="@dimen/activity_horizontal_margin"
+    android:paddingRight="@dimen/activity_horizontal_margin"
+    android:paddingTop="@dimen/activity_vertical_margin" >
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical" >
+        
+        <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal" >
+
+        <TextView
+            android:id="@+id/text_version"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:text="@string/text_version" />
+        
+        <TextView
+            android:id="@+id/version"
+            android:paddingLeft="2dp"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:text="" />
+        
+        </LinearLayout>
+
+        <TextView
+            android:id="@+id/text_description"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:paddingTop="@dimen/activity_vertical_margin"
+            android:text="@string/description" />
+
+        <TextView
+            android:id="@+id/text_authors"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+	 		android:paddingTop="@dimen/activity_vertical_margin"
+            android:text="@string/authors" />
+
+        <TextView
+            android:id="@+id/text_author_1"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/authors_m" />
+               
+        <TextView
+            android:id="@+id/text_author_2"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/authors_w" />
+                
+         <TextView
+            android:id="@+id/text_author_3"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/authors_l" />
+                        
+         <TextView
+            android:id="@+id/text_author_4"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/authors_j" />
+
+    </LinearLayout>
+    
+</LinearLayout>

+ 15 - 7
res/layout/activity_viewlog.xml

@@ -15,13 +15,19 @@
         android:text="@string/statistics"
         android:textAppearance="?android:attr/textAppearanceLarge" />
 
-    <LinearLayout
-        android:id="@+id/layoutContainer"
-        android:layout_width="match_parent"
+    <HorizontalScrollView
+        android:layout_width="fill_parent"
         android:layout_height="wrap_content"
-        android:orientation="vertical"
-        android:paddingLeft="@dimen/activity_horizontal_margin" >
-    </LinearLayout>
+        android:scrollbars="none" >
+
+        <TableLayout
+            android:id="@+id/layoutContainer"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:orientation="vertical" >
+        </TableLayout>
+        
+    </HorizontalScrollView>
 
     <LinearLayout
         android:layout_width="match_parent"
@@ -39,6 +45,7 @@
             android:id="@+id/textFirstAttackValue"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:paddingLeft="2dp"
             android:text=""
             android:textAppearance="?android:attr/textAppearanceMedium" />
     </LinearLayout>
@@ -59,6 +66,7 @@
             android:id="@+id/textLastAttackValue"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:paddingLeft="2dp"
             android:text=""
             android:textAppearance="?android:attr/textAppearanceMedium" />
     </LinearLayout>
@@ -67,7 +75,7 @@
         android:id="@+id/textLogFile"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:text="@string/logFile"
+        android:text="@string/log_actions"
         android:textAppearance="?android:attr/textAppearanceLarge" />
 
     <LinearLayout

+ 6 - 0
res/menu/main.xml

@@ -5,5 +5,11 @@
         android:orderInCategory="100"
         android:showAsAction="never"
         android:title="@string/action_settings"/>
+    
+    <item
+        android:id="@+id/action_about"
+        android:orderInCategory="100"
+        android:showAsAction="never"
+        android:title="@string/action_about"/>
 
 </menu>

+ 5 - 0
res/values/colors.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    	<color name="light_grey">#FFC0C0C0</color>
+        <color name="dark_grey">#FF808080</color>
+</resources>

+ 9 - 0
res/values/export_formats.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <string-array name="format">
+        <item>DEFAULT</item>
+        <item>JSON</item>
+    </string-array>
+
+</resources>

+ 2 - 3
res/values/protocols.xml

@@ -2,13 +2,12 @@
 <resources>
 
     <string-array name="protocols">
-        <item>ECHO</item>
         <item>FTP</item>
         <item>HTTP</item>
-        <item>TELNET</item>
-        <item>MySQL</item>
         <item>SMB</item>
         <item>SSH</item>
+        <item>TELNET</item>
+        <item>MySQL</item>
     </string-array>
 
 </resources>

+ 7 - 3
res/values/strings.xml

@@ -3,6 +3,7 @@
 
     <string name="app_name">HOsTaGe</string>
     <string name="action_settings">Settings</string>
+    <string name="action_about">About</string>
     <string name="capital_on">ON</string>
     <string name="capital_off">OFF</string>
     <string name="status">Status</string>
@@ -15,10 +16,13 @@
     <string name="services">Services</string>
     <string name="connections">Recorded connections:</string>
     <string name="statistics">Statistics</string>
-	<string name="logFile">Log File</string>
+    <string name="database">Database</string>    
+	<string name="log_actions">Actions</string>
 	<string name="firstAttack">First Attack:</string>
 	<string name="lastAttack">Last Attack:</string>
-	
-
+	<string name="clear">Clear</string>
+	<string name="cancel">Cancel</string>
+	<string name="dialog_clear_database">Clear all data?</string>	
+	<string name="export_dialog_title">Choose Export Format</string>		
 
 </resources>

+ 12 - 0
res/values/strings_about.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+	<string name="text_version">Version: </string>
+	<string name="description">HOsTaGe is an open source low interaction honeypot, design by a group of students from the TU Darmstadt under the direction of Shankar Karuppayah.</string>
+	<string name="authors">Authors</string>
+	<string name="authors_m">Mihai Plasoianu </string>
+	<string name="authors_l">Lars Pandikow</string>
+	<string name="authors_w">Wulf Pfeiffer</string>
+	<string name="authors_j">Jan Muskalla</string>	
+	
+</resources>

+ 6 - 8
res/values/strings_preferences.xml

@@ -4,18 +4,16 @@
 	<string name="settings">Settings</string>
 	<string name="pref_alarm">Set Sound</string>
 	<string name="pref_alarm_default">VIBRATION</string>
+	<string name="pref_alarm_summ">Select Notification Sound</string>
 	<string name="pref_storage">External Storage</string>
 	<string name="pref_external_storage_title">External Storage</string>
-	<string name="pref_external_storage_summ">Save Log File on SD-Card</string>
+	<string name="pref_external_storage_summ">Export Log File to SD-Card</string>
+	<string name="pref_external_location_title">External Location</string>
 	<string name="pref_notification">Notification</string>
 	<string name="pref_vibration">Vibration</string>
 	<string name="pref_vibration_summ">Enable Vibration</string>
-	<string name="pref_tracing">TraCINg</string>
-	<string name="pref_upload">Upload Log File</string>	
-	<string name="pref_upload_summ">Enable Upload of Log File to TraCINg</string>
-	<string name="pref_upload_connection">Connection</string>	
-	<string name="pref_upload_connection_summ">Choose connection for upload</string>
-
-	
+	<string name="pref_upload">Upload of Records</string>	
+	<string name="pref_upload_server">Server address</string>	
+	<string name="pref_upload_server_summ">Enter server address for upload</string>	
 	
 </resources>

+ 16 - 16
res/xml/preferences.xml

@@ -7,22 +7,22 @@
             android:key="pref_external_storage"
             android:summary="@string/pref_external_storage_summ"
             android:title="@string/pref_external_storage_title" />
+        
+        <EditTextPreference
+            android:key="pref_external_location"
+            android:dependency="pref_external_storage"
+            android:title="@string/pref_external_location_title"
+            android:defaultValue="/HOsTaGe/LogFiles/"
+            />
+        
     </PreferenceCategory>
-    <PreferenceCategory android:title="@string/pref_tracing" >
-        <CheckBoxPreference
-            android:defaultValue="true"
-            android:key="pref_upload"
-            android:summary="@string/pref_upload_summ"
-            android:title="@string/pref_upload" />
-
-        <ListPreference
-            android:defaultValue="WIFI"
-            android:dependency="pref_upload"
-            android:entries="@array/upload_entries"
-            android:entryValues="@array/upload_values"
-            android:key="pref_upload_"
-            android:summary="@string/pref_upload_connection_summ"
-            android:title="@string/pref_upload_connection" />
+    <PreferenceCategory android:title="@string/pref_upload" >
+        <EditTextPreference
+            android:key="pref_upload_server"
+            android:defaultValue="https://ssi.cased.de"
+            android:summary="@string/pref_upload_server_summ"
+            android:title="@string/pref_upload_server" />
+        
     </PreferenceCategory>
     <PreferenceCategory android:title="@string/pref_notification" >
         <CheckBoxPreference
@@ -37,7 +37,7 @@
             android:ringtoneType="notification"
             android:showDefault="true"
             android:showSilent="true"
-            android:summary="Select Notification Sound"
+            android:summary="@string/pref_alarm_summ"
             android:title="@string/pref_alarm" />
     </PreferenceCategory>
 

+ 7 - 8
src/de/tudarmstadt/informatik/hostage/HoneyListener.java

@@ -8,7 +8,6 @@ import java.util.Iterator;
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
-import android.widget.Toast;
 import de.tudarmstadt.informatik.hostage.handler.AbstractHandler;
 import de.tudarmstadt.informatik.hostage.handler.ByteArrayHandlerImpl;
 import de.tudarmstadt.informatik.hostage.handler.StringHandlerImpl;
@@ -45,7 +44,7 @@ public class HoneyListener implements Runnable {
 	public HoneyListener(HoneyService service, Protocol protocol) {
 		this.service = service;
 		this.protocol = protocol;
-        pref = service.getApplicationContext().getSharedPreferences(MainActivity.PREF_NAME, Context.MODE_PRIVATE);
+        pref = service.getApplicationContext().getSharedPreferences(MainActivity.SESSION_DATA, Context.MODE_PRIVATE);
         editor = pref.edit();
 	}
 
@@ -64,10 +63,10 @@ public class HoneyListener implements Runnable {
 			server = new MyServerSocketFactory().createServerSocket(protocol
 					.getPort());
 			(this.thread = new Thread(this)).start();
-			running = true;
 	    	editor.putBoolean(protocol + MainActivity.LISTENER, true);
 	    	editor.commit();
-			service.notifyUI(MainActivity.LISTENER);
+			service.notifyUI(protocol.toString(), MainActivity.LISTENER);
+			running = true;
 		} catch (Exception e) {
 			e.printStackTrace();
 		}
@@ -75,12 +74,12 @@ public class HoneyListener implements Runnable {
 
 	public void stop() {
 		try {
-			thread.interrupt();
 			server.close();
-			running = false;
+			thread.interrupt();
 	    	editor.putBoolean(protocol + MainActivity.LISTENER, false);
 	    	editor.commit();
-			service.notifyUI(MainActivity.LISTENER);
+			service.notifyUI(protocol.toString(), MainActivity.LISTENER);
+			running = false;
 		} catch (Exception e) {
 			e.printStackTrace();
 		}
@@ -107,7 +106,7 @@ public class HoneyListener implements Runnable {
 	    	int handlerCount = pref.getInt(protocol + MainActivity.HANDLER_COUNT, 0);
 	    	editor.putInt(protocol + MainActivity.HANDLER_COUNT, handlerCount + 1);
 	    	editor.commit();    
-	    	service.notifyUI(MainActivity.HANDLER_COUNT);
+	    	service.notifyUI(protocol.toString(), MainActivity.HANDLER_COUNT);
 		} catch (Exception e) {
 			e.printStackTrace();
 		}

+ 150 - 20
src/de/tudarmstadt/informatik/hostage/HoneyService.java

@@ -7,18 +7,27 @@ import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.app.Service;
+import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
 import android.net.Uri;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
 import android.os.Binder;
 import android.os.IBinder;
 import android.preference.PreferenceManager;
 import android.support.v4.app.NotificationCompat;
 import android.support.v4.app.TaskStackBuilder;
 import android.support.v4.content.LocalBroadcastManager;
+import android.util.Log;
 import android.widget.Toast;
+import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
+import de.tudarmstadt.informatik.hostage.logging.DatabaseHandler;
 import de.tudarmstadt.informatik.hostage.logging.Logger;
 import de.tudarmstadt.informatik.hostage.logging.SQLLogger;
 import de.tudarmstadt.informatik.hostage.protocol.Protocol;
@@ -27,6 +36,10 @@ import de.tudarmstadt.informatik.hostage.ui.MainActivity;
 public class HoneyService extends Service {
 
 	private ArrayList<HoneyListener> listeners = new ArrayList<HoneyListener>();
+	private NotificationCompat.Builder builder;
+	private SharedPreferences pref;
+	Editor editor;
+	private boolean stopped = false;
 
 	public List<HoneyListener> getListeners() {
 		return listeners;
@@ -48,6 +61,8 @@ public class HoneyService extends Service {
 
 	@Override
 	public IBinder onBind(Intent intent) {
+		NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+		mNotificationManager.cancel(2);
 		return mBinder;
 	}
 
@@ -55,10 +70,13 @@ public class HoneyService extends Service {
 	public void onCreate() {
 		super.onCreate();
 		log = new SQLLogger(getApplicationContext());
+		pref = getSharedPreferences(MainActivity.SESSION_DATA, Context.MODE_PRIVATE);
+		editor = pref.edit();
 		createNotification();
 		for (Protocol protocol : getProtocolArray()) {
 			listeners.add(new HoneyListener(this, protocol));
 		}
+		registerNetReceiver();
 	}
 	
     @Override
@@ -66,26 +84,114 @@ public class HoneyService extends Service {
         // We want this service to continue running until it is explicitly
         // stopped, so return sticky.
         return START_STICKY;
-    }
-	
+    }	
 
 	@Override
 	public void onDestroy() {
 		cancelNotification();
 		super.onDestroy();
+		unregisterNetReceiver();
+	}
+	
+	// Delete session data
+	private void deleteSessionData(){
+    	editor.clear();
+    	editor.commit();
+	}
+	
+	private void registerNetReceiver() {
+	    // register BroadcastReceiver on network state changes	    
+		IntentFilter intent = new IntentFilter();
+	    intent.addAction(ConnectivityManager.CONNECTIVITY_ACTION); //"android.net.conn.CONNECTIVITY_CHANGE"
+	    registerReceiver(netReceiver, intent);
 	}
 
+	private void unregisterNetReceiver() {
+		unregisterReceiver(netReceiver);
+	}
+	
+	private void mStopSelf(){
+		stopped = true;
+		stopSelf();	
+	}
+
+	private BroadcastReceiver netReceiver = new BroadcastReceiver() {
+		@Override
+		public void onReceive(Context context, Intent intent) {
+				String bssid_old = pref.getString(MainActivity.BSSID, "");
+				String bssid_new = HelperUtils.getBSSID(context);
+				Log.i("HoneyService", "Connection changed");
+
+				if(!stopped && (bssid_new == null || !bssid_new.equals(bssid_old))){
+					Log.i("HoneyService", "Connection lost");
+					wifiChangeNotification();
+					stopListeners();
+					deleteSessionData();
+					notifyUI("SERVICE", "STOPPED");
+					mStopSelf();
+				}
+		}
+	};	
+
 	private void createNotification() {
-		NotificationCompat.Builder builder = new NotificationCompat.Builder(
-				this).setSmallIcon(R.drawable.ic_launcher)
+		DatabaseHandler dbh = new DatabaseHandler(this);
+		boolean activeHandlers = false;
+		boolean bssidSeen = false;
+		
+		for(String protocol : getResources().getStringArray(R.array.protocols)){
+			int handlerCount = pref.getInt(protocol + MainActivity.HANDLER_COUNT, 0);
+			if(handlerCount > 0){
+				activeHandlers = true;
+			}
+			if(dbh.bssidSeen(protocol, HelperUtils.getBSSID(getApplicationContext()))){
+				bssidSeen = true;
+			}
+		}
+		builder = new NotificationCompat.Builder(this)
+										.setContentTitle(getString(R.string.app_name))
+										.setWhen(System.currentTimeMillis());	
+		if(activeHandlers){
+			builder.setSmallIcon(R.drawable.icon_service_red);
+			builder.setContentText("Network is infected!");
+		} else if(bssidSeen){
+			builder.setSmallIcon(R.drawable.icon_service_yellow);
+			builder.setContentText("Network has been infected in previous session!");
+		} else{
+			builder.setSmallIcon(R.drawable.icon_service_green);
+			builder.setContentText("Everything looks fine!");
+		}				
+		TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
+		stackBuilder.addParentStack(MainActivity.class);
+		stackBuilder.addNextIntent(new Intent(this, MainActivity.class));
+		PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
+				PendingIntent.FLAG_UPDATE_CURRENT);
+		builder.setContentIntent(resultPendingIntent);
+		NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+		mNotificationManager.notify(1, builder.build());
+	}
+	
+	private void updateNotification() {
+		SharedPreferences defaultPref = PreferenceManager.getDefaultSharedPreferences(this);
+		String strRingtonePreference = defaultPref.getString("pref_notification_sound", "content://settings/system/notification_sound");  
+		Log.i("HoneyService", "Ringtone: " + strRingtonePreference);
+		builder = new NotificationCompat.Builder(this)
 				.setContentTitle(getString(R.string.app_name))
-				.setContentText("Honeypot up and running!");
+				.setTicker("Honeypot under attack!")
+				.setContentText("Network is infected!")
+				.setSmallIcon(R.drawable.icon_service_red)
+				.setWhen(System.currentTimeMillis())
+				.setSound(Uri.parse(strRingtonePreference)); 
 		TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
 		stackBuilder.addParentStack(MainActivity.class);
 		stackBuilder.addNextIntent(new Intent(this, MainActivity.class));
 		PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
 				PendingIntent.FLAG_UPDATE_CURRENT);
 		builder.setContentIntent(resultPendingIntent);
+		Log.i("HoneyService", "Vibrating: " + defaultPref.getBoolean("pref_vibration", false));
+		if(defaultPref.getBoolean("pref_vibration", false)){
+			builder.setVibrate(new long[]{100, 200, 100, 200});
+		} 
+
 		NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
 		mNotificationManager.notify(1, builder.build());
 	}
@@ -94,6 +200,31 @@ public class HoneyService extends Service {
 		NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
 		mNotificationManager.cancel(1);
 	}
+	
+	private void wifiChangeNotification(){
+		SharedPreferences defaultPref = PreferenceManager.getDefaultSharedPreferences(this);
+		String strRingtonePreference = defaultPref.getString("pref_notification_sound", "content://settings/system/notification_sound");  
+		
+		NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
+						  .setContentTitle(getString(R.string.app_name))
+						  .setWhen(System.currentTimeMillis())
+						  .setTicker("HOsTaGe stopped due Connection change!")
+						  .setContentText("HOsTaGe stopped due Connection change!")
+						  .setSmallIcon(R.drawable.ic_launcher)
+						  .setAutoCancel(true)
+						  .setSound(Uri.parse(strRingtonePreference)); 
+		if(defaultPref.getBoolean("pref_vibration", true)){
+			builder.setVibrate(new long[]{100, 200, 100, 200});
+		}
+		TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
+		stackBuilder.addParentStack(MainActivity.class);
+		stackBuilder.addNextIntent(new Intent(this, MainActivity.class));
+		PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
+				PendingIntent.FLAG_UPDATE_CURRENT);
+		builder.setContentIntent(resultPendingIntent);
+		NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+		mNotificationManager.notify(2, builder.build());
+	}
 
 	private ArrayList<Protocol> getProtocolArray() {
 		String[] protocols = getResources().getStringArray(R.array.protocols);
@@ -109,7 +240,6 @@ public class HoneyService extends Service {
 				e.printStackTrace();
 			}
 		}
-
 		return protocolArray;
 	}
 	
@@ -123,18 +253,10 @@ public class HoneyService extends Service {
 
 	// IPC
 	
-	public void notifyUI(String key) {
+	public void notifyUI(String protocol, String key) {
 		// Send Notification
-		SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
 		if (key.equals(MainActivity.HANDLER_COUNT)){
-			NotificationManager nManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); 
-			Notification notification = new Notification();
-			String strRingtonePreference = pref.getString("pref_notification_sound", "DEFAULT_SOUND");  
-			notification.sound = Uri.parse(strRingtonePreference); 
-			if(pref.getBoolean("pref_vibration", true)){
-				notification.vibrate = new long[]{100, 200, 100, 200};
-			}
-			nManager.notify(0, notification);
+			updateNotification();
 		}
 		// Inform UI of Preference Change
 		Intent intent = new Intent(MainActivity.BROADCAST);
@@ -144,14 +266,18 @@ public class HoneyService extends Service {
 
 	public void startListeners() {
 		for (HoneyListener listener : listeners) {
-			listener.start();
+			if(!listener.isRunning()){
+				listener.start();
+			}
 		}
 		Toast.makeText(getApplicationContext(), "SERVICES STARTED!", Toast.LENGTH_SHORT).show();
 	}
 
 	public void stopListeners() {
 		for (HoneyListener listener : listeners) {
-			listener.stop();
+			if(listener.isRunning()){
+				listener.stop();
+			}
 		}
 		Toast.makeText(getApplicationContext(), "SERVICES STOPPED!", Toast.LENGTH_SHORT).show();
 	}
@@ -159,7 +285,9 @@ public class HoneyService extends Service {
 	public void startListener(String protocolName) {
 		for (HoneyListener listener : listeners) {
 			if (listener.getProtocolName().equals(protocolName)) {
-				listener.start();
+				if(!listener.isRunning()){
+					listener.start();
+				}
 			}
 		}
 		Toast.makeText(getApplicationContext(), protocolName + " SERVICE STARTED!", Toast.LENGTH_SHORT).show();
@@ -168,7 +296,9 @@ public class HoneyService extends Service {
 	public void stopListener(String protocolName) {
 		for (HoneyListener listener : listeners) {
 			if (listener.getProtocolName().equals(protocolName)) {
-				listener.stop();
+				if(listener.isRunning()){
+					listener.stop();
+				}
 			}
 		}
 		Toast.makeText(getApplicationContext(), protocolName + " SERVICE STOPPED!", Toast.LENGTH_SHORT).show();

+ 34 - 0
src/de/tudarmstadt/informatik/hostage/commons/GetExternalIPTask.java

@@ -0,0 +1,34 @@
+package de.tudarmstadt.informatik.hostage.commons;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.util.EntityUtils;
+import org.json.JSONObject;
+
+import android.os.AsyncTask;
+
+public class GetExternalIPTask extends AsyncTask<String, Void, String> {
+	 @Override
+    protected String doInBackground(String... url) {
+   	 String ipAddress = null;
+			try {
+				HttpClient httpclient = new DefaultHttpClient();
+				HttpGet httpget = new HttpGet(url[0]);
+				HttpResponse response;
+
+				response = httpclient.execute(httpget);
+
+				HttpEntity entity = response.getEntity();
+				entity.getContentLength();
+				String str = EntityUtils.toString(entity);
+				JSONObject json_data = new JSONObject(str);
+				ipAddress = json_data.getString("ip");
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+	return ipAddress;
+    }
+}

+ 30 - 14
src/de/tudarmstadt/informatik/hostage/commons/HelperUtils.java

@@ -3,6 +3,7 @@ package de.tudarmstadt.informatik.hostage.commons;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.security.KeyStore;
+import java.util.concurrent.ExecutionException;
 
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
@@ -23,14 +24,20 @@ import org.apache.http.protocol.HTTP;
 import org.apache.http.util.EntityUtils;
 import org.json.JSONObject;
 
+import de.tudarmstadt.informatik.hostage.R;
 import de.tudarmstadt.informatik.hostage.net.MySSLSocketFactory;
+import de.tudarmstadt.informatik.hostage.ui.MainActivity;
 import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 import android.os.Environment;
 import android.text.TextUtils;
+import android.util.Log;
+import android.widget.TextView;
 
 public final class HelperUtils {
 
@@ -86,6 +93,7 @@ public final class HelperUtils {
 							unpackInetAddress(connectionInfo.getIpAddress()))
 							.getHostAddress();
 				} catch (UnknownHostException e) {
+					e.printStackTrace();
 				}
 			}
 		}
@@ -100,23 +108,30 @@ public final class HelperUtils {
 
 	public static String getExternalIP(Context context) {
 		String ipAddress = null;
+		GetExternalIPTask task = new GetExternalIPTask();
+		task.execute(new String[]{"http://ip2country.sourceforge.net/ip2c.php?format=JSON"});
 		try {
-			HttpClient httpclient = new DefaultHttpClient();
-			HttpGet httpget = new HttpGet(
-					"http://ip2country.sourceforge.net/ip2c.php?format=JSON");
-			HttpResponse response;
-
-			response = httpclient.execute(httpget);
-
-			HttpEntity entity = response.getEntity();
-			entity.getContentLength();
-			String str = EntityUtils.toString(entity);
-			JSONObject json_data = new JSONObject(str);
-			ipAddress = json_data.getString("ip");
-		} catch (Exception e) {
+			ipAddress =  task.get();
+		} catch (InterruptedException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (ExecutionException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
 		}
 		return ipAddress;
 	}
+	 
+	
+	public static void updateConnectionInfo(Context context) {	
+		SharedPreferences pref = context.getSharedPreferences(MainActivity.SESSION_DATA, Context.MODE_PRIVATE);
+		Editor editor = pref.edit();
+		editor.putString(MainActivity.SSID, getSSID(context));
+		editor.putString(MainActivity.BSSID, getBSSID(context));
+		editor.putString(MainActivity.INTERNAL_IP, getInternalIP(context));
+		editor.putString(MainActivity.EXTERNAL_IP, getExternalIP(context));
+		editor.commit();
+	}	
 
 	/* Checks if external storage is available for read and write */
 	public static boolean isExternalStorageWritable() {
@@ -150,11 +165,12 @@ public final class HelperUtils {
 
 			return new DefaultHttpClient(ccm, params);
 		} catch (Exception e) {
+			e.printStackTrace();
 			return new DefaultHttpClient();
 		}
 	}
 	
-	public static byte[] concat(byte[]... bytes) {
+		public static byte[] concat(byte[]... bytes) {
 		int newSize = 0;
 		for (byte[] b : bytes)
 			newSize += b.length;

+ 30 - 13
src/de/tudarmstadt/informatik/hostage/logging/DatabaseHandler.java

@@ -11,6 +11,7 @@ import android.content.Context;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteOpenHelper;
+import android.util.Log;
 
 public class DatabaseHandler extends SQLiteOpenHelper {
 
@@ -116,15 +117,15 @@ public class DatabaseHandler extends SQLiteOpenHelper {
 
 	// Getting single record
 	public Record getRecord(int id) {
+		String selectQuery = "SELECT  * FROM " + TABLE_RECORDS + " WHERE " + KEY_ID + " = " + id;
 		SQLiteDatabase db = this.getReadableDatabase();
 
-		Cursor cursor = db.query(TABLE_RECORDS, null,
-				KEY_ID + "=?", new String[] { String.valueOf(id) }, null, null,
-				null, null);
-		if (cursor != null)
-			cursor.moveToFirst();
-
-		Record record = createRecord(cursor);
+		Cursor cursor = db.rawQuery(selectQuery, null);
+		Record record = null;
+		if (cursor.moveToFirst()){
+			record = createRecord(cursor);
+			Log.i("DatabaseHandler", record == null ? "null" : "not null");
+		} 
 		
         cursor.close();
 		db.close();
@@ -195,7 +196,7 @@ public class DatabaseHandler extends SQLiteOpenHelper {
     }
     
 	// Getting first Record for each AttackId
-    public ArrayList<Record> getRecordOfEachAtack() {
+    public ArrayList<Record> getRecordOfEachAttack() {
     	ArrayList<Record> recordList = new ArrayList<Record>();
         String selectQuery = "SELECT  * FROM " + TABLE_RECORDS + " GROUP BY " + KEY_ATTACK_ID;
         SQLiteDatabase db = this.getReadableDatabase();
@@ -216,10 +217,10 @@ public class DatabaseHandler extends SQLiteOpenHelper {
         return recordList;
     }
     
-	// Getting first Record for each AttackId
-    public ArrayList<Record> getRecordOfEachAtack(int id) {
+	// Getting first Record for each AttackId greater than a given id
+    public ArrayList<Record> getRecordOfEachAttack(int attack_id) {
     	ArrayList<Record> recordList = new ArrayList<Record>();
-        String selectQuery = "SELECT  * FROM " + TABLE_RECORDS + " WHERE " + KEY_ATTACK_ID + " > " + id + " GROUP BY " + KEY_ATTACK_ID;
+        String selectQuery = "SELECT  * FROM " + TABLE_RECORDS + " WHERE " + KEY_ATTACK_ID + " > " + attack_id + " GROUP BY " + KEY_ATTACK_ID;
         SQLiteDatabase db = this.getReadableDatabase();
         Cursor cursor = db.rawQuery(selectQuery, null);
 		
@@ -238,6 +239,23 @@ public class DatabaseHandler extends SQLiteOpenHelper {
         return recordList;
     }
     
+	// Getting first Record for each AttackId greater than a given id
+    public Record getRecordOfAttackId(int attack_id) {
+        String selectQuery = "SELECT  * FROM " + TABLE_RECORDS + " WHERE " + KEY_ATTACK_ID + " = " + attack_id + " GROUP BY " + KEY_ATTACK_ID;
+        SQLiteDatabase db = this.getReadableDatabase();
+        Cursor cursor = db.rawQuery(selectQuery, null);
+        Record record = null;
+        
+		if (cursor.moveToFirst()) {
+				record = createRecord(cursor);
+		}
+        cursor.close();
+ 
+        // return count
+        db.close();
+        return record;
+    }
+    
     public boolean bssidSeen(String protocol, String BSSID){
         String countQuery = "SELECT  * FROM " + TABLE_RECORDS + " WHERE " + KEY_PROTOCOL + " = " + "'" + protocol + "'" + " AND " + KEY_BSSID + " = " + "'" + BSSID + "'";
         SQLiteDatabase db = this.getReadableDatabase();
@@ -245,8 +263,7 @@ public class DatabaseHandler extends SQLiteOpenHelper {
         int result = cursor.getCount();
         cursor.close();
         db.close();
-        return result > 0;
-        
+        return result > 0;        
     }
     
     //Delete all Data from Database

+ 12 - 4
src/de/tudarmstadt/informatik/hostage/logging/Record.java

@@ -158,15 +158,23 @@ public class Record implements Serializable {
 
 	@Override
 	public String toString() {
-		return String.format("%s [%d,%s:%d,%s:%d,%s]",
+		return String.format("%d %s [%d,%s:%d,%s:%d,%s]", attack_id,
 				((type == TYPE.SEND) ? "SEND" : "RECEIVE"), timestamp,
 				localIP.getHostAddress(), localPort, remoteIP.getHostAddress(),
 				remotePort, packet);
 	}
 	
-	public String toStringJson(){
-		return String.format("{ \"src\":{\"IP\": %s, \"Port\": %d} \"dst\": {\"IP\": %s, \"Port\": %d} \"type\": 0 \"name\": \"HOsTaGe\" }", localIP.getHostAddress(), localPort, remoteIP.getHostAddress(),
-				remotePort);
+	public String toString(int format){
+		// Choose String Format
+		// Add additional case for your own Format. Also add format Name to /res/values/export_formats/
+		switch (format){
+			case 1: 
+				return String.format("{ \"src\":{\"IP\": %s, \"Port\": %d} \"dst\": {\"IP\": %s, \"Port\": %d} \"type\": 0 \"name\": \"HOsTaGe\" }", localIP.getHostAddress(), localPort, remoteIP.getHostAddress(),
+					remotePort);
+			default:
+				return toString();
+		}
+
 	}
 	
 }

+ 83 - 43
src/de/tudarmstadt/informatik/hostage/logging/SQLLogger.java

@@ -2,45 +2,62 @@ package de.tudarmstadt.informatik.hostage.logging;
 
 import java.io.File;
 import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
 import java.util.ArrayList;
 
-import org.apache.http.client.ClientProtocolException;
 import org.apache.http.client.HttpClient;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.entity.StringEntity;
 
+import de.tudarmstadt.informatik.hostage.R;
 import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
+import de.tudarmstadt.informatik.hostage.ui.MainActivity;
+import de.tudarmstadt.informatik.hostage.ui.ViewLog;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
 import android.content.Context;
+import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
 import android.os.Environment;
 import android.preference.PreferenceManager;
+import android.support.v4.app.NotificationCompat;
+import android.support.v4.app.TaskStackBuilder;
 import android.widget.Toast;
 
 public class SQLLogger implements Logger{
 	Context context;
 	DatabaseHandler dbh;
+	public static final int JSON = 0x02;
+	private int progressMax;
+	private int lastUploadedAttackId;
+	private NotificationCompat.Builder builder;
+	private NotificationManager mNotifyManager;
+	SharedPreferences pref;
+	Editor editor;
 	
 	public SQLLogger(Context context){
 		this.context = context;
-		dbh = new DatabaseHandler(context);		
+		dbh = new DatabaseHandler(context);	
+		pref = PreferenceManager.getDefaultSharedPreferences(context);
+		editor = pref.edit();
 	}
 
 	public synchronized void write(Record record) {
 		dbh.addRecord(record);
 	}
 	
-	public void exportDatabase(String format){
+	public void exportDatabase(int format){
 		try {
 			FileOutputStream log;
-			SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
-			if(pref.getBoolean("pref_external_storage", false)){
-				//TODO Fehlermeldung wenn keine SD karte gefunden werden kann
-				File root = Environment.getExternalStorageDirectory();
-				if(root != null && HelperUtils.isExternalStorageWritable()){
-					File file = new File(root, "hostage_" + format + "_" + System.currentTimeMillis() + ".log");
+			String filename = "hostage_" + format + "_" + System.currentTimeMillis() + ".log";
+			boolean externalStorage = pref.getBoolean("pref_external_storage", false);
+			String externalLocation = pref.getString("pref_external_location", "");
+			if(externalStorage){
+				String root = Environment.getExternalStorageDirectory().toString();
+				if(root != null && HelperUtils.isExternalStorageWritable()){					
+					File dir = new File(root + externalLocation);
+					dir.mkdirs();
+					File file = new File(dir, filename);
 					log = new FileOutputStream(file);
 				}else {
 					Toast.makeText(context, "Could not write to SD Card", Toast.LENGTH_SHORT).show();
@@ -53,51 +70,74 @@ public class SQLLogger implements Logger{
 			
 			ArrayList<Record> records = dbh.getAllRecords();
 			for(Record record : records){
-				if(format.equals("JSON")){
-					log.write((record.toStringJson() + "\n").getBytes());
-				}else {
-					log.write((record.toString() + "\n").getBytes());
-				}
+					log.write((record.toString(format) + "\n").getBytes());
 			}
 			log.flush();
 			log.close();
+			Toast.makeText(context, externalStorage ? filename + " saved on external memory! " + externalLocation : filename + " saved on internal memory!", Toast.LENGTH_SHORT).show();
 		} catch (Exception e) {
+			Toast.makeText(context, "Could not write to SD Card", Toast.LENGTH_SHORT).show();
 			e.printStackTrace();
 		}	
 	}	
 	
-	public void uploadDatabase(){
-		SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
-		Editor editor = pref.edit();
-		int lastUploadedAttackId = pref.getInt("LAST_UPLOADED_ATTACK_ID", -1);
+	public void uploadDatabase(){		
+		lastUploadedAttackId = pref.getInt("LAST_UPLOADED_ATTACK_ID", -1);
 		int currentAttackCount = dbh.getAttackCount();
-		if(lastUploadedAttackId == currentAttackCount || currentAttackCount == 0){
+		if(lastUploadedAttackId == currentAttackCount -1){
+			Toast.makeText(context, "All data have already been uploaded.", Toast.LENGTH_SHORT).show();
 			return;
 		}
+		// Show Upload Notification
+		builder = new NotificationCompat.Builder(context)
+							.setContentTitle(context.getString(R.string.app_name))
+							.setContentText("Upload in progress...")
+							.setTicker("Uploading Data...")
+							.setSmallIcon(R.drawable.ic_launcher)	
+							.setWhen(System.currentTimeMillis());	
+		TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
+		stackBuilder.addParentStack(MainActivity.class);
+		stackBuilder.addNextIntent(new Intent());
+		PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
+				PendingIntent.FLAG_UPDATE_CURRENT);
+		builder.setContentIntent(resultPendingIntent);
+		builder.setAutoCancel(true);
+		builder.setOnlyAlertOnce(false);
+		mNotifyManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
+		mNotifyManager.notify(2, builder.build());
+		new Thread(new Runnable() {
 
-		HttpClient httpclient = HelperUtils.createHttpClient();
-		ArrayList<Record> recordList = dbh.getRecordOfEachAtack(lastUploadedAttackId + 1);
-		try {
-			HttpPost httppost;
-			for(Record record: recordList){
-				httppost = new HttpPost("https://ssi.cased.de");
-				StringEntity se = new StringEntity(record.toStringJson());
-				httppost.setEntity(se);
-				httpclient.execute(httppost);
-			}
-		} catch (UnsupportedEncodingException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		} catch (ClientProtocolException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-		catch (IOException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}		
+			  public void run() {				  
+					HttpClient httpclient = HelperUtils.createHttpClient();
+					ArrayList<Record> recordList = dbh.getRecordOfEachAttack(lastUploadedAttackId + 1);
+					progressMax = recordList.size();		
+					try {
+							HttpPost httppost;
+							int progressBarStatus = 1;
+							for(Record record: recordList){
+								httppost = new HttpPost(pref.getString("pref_upload", "https://ssi.cased.de"));
+								StringEntity se = new StringEntity(record.toString(JSON));
+								httppost.setEntity(se);
+								httpclient.execute(httppost);
+								builder.setProgress(progressMax, progressBarStatus, false);
+								progressBarStatus++;
+			                     // Update the progress bar
+								mNotifyManager.notify(2, builder.build());
+							}
+						} catch (Exception e) {
+							// TODO Auto-generated catch block
+							e.printStackTrace();
+						}	
+					// When the loop is finished, updates the notification
+		            builder.setContentText("Upload complete")
+		            	   .setTicker("Upload complete")
+		            // Removes the progress bar
+		                   .setProgress(0,0,false);
+		            mNotifyManager.notify(2, builder.build());
+
+			}}).start();
 		editor.putInt("LAST_UPLOADED_ATTACK_ID",currentAttackCount - 1);
-		editor.commit();
+		editor.commit();				
 	}
 	
 	public int getAttackCount(){

+ 29 - 0
src/de/tudarmstadt/informatik/hostage/ui/AboutActivity.java

@@ -0,0 +1,29 @@
+package de.tudarmstadt.informatik.hostage.ui;
+
+import de.tudarmstadt.informatik.hostage.R;
+import android.app.Activity;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Bundle;
+import android.widget.TextView;
+
+public class AboutActivity extends Activity{
+
+	@Override
+	protected void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.activity_about);
+
+		PackageInfo pInfo;
+		try {
+			pInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
+			String version = pInfo.versionName;
+	        TextView versionTextView = (TextView) findViewById(R.id.version);
+	        versionTextView.setText(version);
+		} catch (NameNotFoundException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+
+	}
+}

+ 44 - 28
src/de/tudarmstadt/informatik/hostage/ui/MainActivity.java

@@ -46,9 +46,13 @@ import de.tudarmstadt.informatik.hostage.logging.DatabaseHandler;
 public class MainActivity extends Activity {
 
 	public static final String BROADCAST = "de.tudarmstadt.informatik.hostage.BROADCAST";
-	public static final String PREF_NAME = "de.tudarmstadt.informatik.hostage.SESSION_DATA";
+	public static final String SESSION_DATA = "de.tudarmstadt.informatik.hostage.SESSION_DATA";
 	public static final String LISTENER = "_LISTENER";
 	public static final String HANDLER_COUNT = "_HANDLER_COUNT";
+	public static final String SSID = "SSID";
+	public static final String BSSID = "BSSID";
+	public static final String INTERNAL_IP = "INTERNAL_IP";
+	public static final String EXTERNAL_IP = "EXTERNAL_IP";
 
 	public static final int LIGHT_GREY = 0x01;
 	public static final int LIGHT_GREEN = 0x02;
@@ -56,6 +60,7 @@ public class MainActivity extends Activity {
 	public static final int LIGHT_YELLOW = 0x04;
 
 	private HoneyService mService;
+	private boolean serviceBound;
 	private SharedPreferences pref;
 	private Editor editor;
 	private DatabaseHandler dbh;
@@ -80,7 +85,7 @@ public class MainActivity extends Activity {
 
 		initViewAnimator();
 		initListView();
-		pref = getSharedPreferences(MainActivity.PREF_NAME, Context.MODE_PRIVATE);
+		pref = getSharedPreferences(MainActivity.SESSION_DATA, Context.MODE_PRIVATE);
 		dbh = new DatabaseHandler(getApplicationContext());
 		editor = pref.edit();
 	}
@@ -97,9 +102,14 @@ public class MainActivity extends Activity {
 	    switch (item.getItemId()) {
 	        case R.id.action_settings:
 	            startActivity(new Intent(this, SettingsActivity.class));
+	            break;
+	        case R.id.action_about:
+	            startActivity(new Intent(this, AboutActivity.class));
+	            break;
 	        default:
-	            return super.onOptionsItemSelected(item);
+	            ;
 	    }
+        return super.onOptionsItemSelected(item);
 	}
 
 	@Override
@@ -110,6 +120,8 @@ public class MainActivity extends Activity {
 		if (isServiceRunning()) {
 			bindService(getServiceIntent(), mConnection, BIND_AUTO_CREATE);
 		}
+		updateUI();
+		updateConnectionInfo();
 	}
 
 	@Override
@@ -130,13 +142,6 @@ public class MainActivity extends Activity {
 		}
 	}
 
-	@Override
-	protected void onResume() {
-		super.onResume();
-		updateConnectionInfo();
-	}
-
-
 	public void buttonOnOffClick(View view) {
 		if (((ToggleButton) view).isChecked()) {
 			if (isParanoid()) {
@@ -153,14 +158,24 @@ public class MainActivity extends Activity {
 
 	private void startAndBind() {
 		startService(getServiceIntent());
+		bindService();
+	}
+	
+	private void bindService(){
 		bindService(getServiceIntent(), mConnection, BIND_AUTO_CREATE);
+		serviceBound = true;
 	}
 
 	private void stopAndUnbind() {
-		unbindService(mConnection);
+		unbindService();
 		stopService(getServiceIntent());
 	}
 	
+	private void unbindService(){
+		unbindService(mConnection);
+		serviceBound = false;
+	}
+	
 	private ServiceConnection mConnection = new ServiceConnection() {
 
 		@Override
@@ -168,11 +183,10 @@ public class MainActivity extends Activity {
 			mService = ((LocalBinder) service).getService();
 			if(protocolClicked != null && protocolClicked.equals("PANIC")){
 				mService.startListeners();
-			}else{
+			}else if (protocolClicked != null){
 				mService.toggleListener(protocolClicked);
 			}
 			protocolClicked = null;
-			updateUI();
 		}
 
 		@Override
@@ -219,8 +233,9 @@ public class MainActivity extends Activity {
 						.getItem(position)).get("protocol");
 				if (isServiceRunning()) {
 					mService.toggleListener(protocolName);	
-					if(!mService.hasRunningListeners())
+					if(!mService.hasRunningListeners()){
 						stopAndUnbind();
+					}
 				}else{
 					protocolClicked = protocolName;
 					startAndBind();
@@ -262,27 +277,26 @@ public class MainActivity extends Activity {
 	};
 
 	private void registerNetReceiver() {
-	    // register BroadcastReceiver on network state changes
-	    final IntentFilter intent = new IntentFilter();
-	    intent.addAction(android.net.ConnectivityManager.CONNECTIVITY_ACTION); //"android.net.conn.CONNECTIVITY_CHANGE"
+	    // register BroadcastReceiver on network state changes	    
+		IntentFilter intent = new IntentFilter();
+	    intent.addAction(ConnectivityManager.CONNECTIVITY_ACTION); //"android.net.conn.CONNECTIVITY_CHANGE"
 	    registerReceiver(netReceiver, intent);
 	}
 
 	private void unregisterNetReceiver() {
-		LocalBroadcastManager.getInstance(this).unregisterReceiver(netReceiver);
+		unregisterReceiver(netReceiver);
 	}
 
 	private BroadcastReceiver netReceiver = new BroadcastReceiver() {
 		@Override
 		public void onReceive(Context context, Intent intent) {
-			if (isServiceRunning()) {
+			String bssid_old = pref.getString(BSSID, "");
+			String bssid_new = HelperUtils.getBSSID(context);
+			if ((bssid_new == null || !bssid_new.equals(bssid_old)) && serviceBound) {
 				Toast.makeText(getApplicationContext(),"Connection changed! Services stopped!", Toast.LENGTH_LONG).show();
-				mService.stopListeners();
-				stopAndUnbind();
-			}
-			deleteSessionData();
+				unbindService();
+			}	
 			updateConnectionInfo();
-			updateUI();
 		}
 	};	
 
@@ -397,10 +411,12 @@ public class MainActivity extends Activity {
 		TextView internalIPView = (TextView) findViewById(R.id.textViewInternalIPValue);
 		TextView externalIPView = (TextView) findViewById(R.id.textViewExternalIPValue);
 		
-		String ssid = HelperUtils.getSSID(this);
-		String bssid = HelperUtils.getBSSID(this);
-		String internalIP = HelperUtils.getInternalIP(this);
-		String externalIP = HelperUtils.getExternalIP(this);
+		HelperUtils.updateConnectionInfo(this);
+		
+		String ssid = pref.getString(SSID, "-");
+		String bssid = pref.getString(BSSID, "-");
+		String internalIP = pref.getString(INTERNAL_IP, "-");
+		String externalIP = pref.getString(EXTERNAL_IP, "-");
 
 		if (ssid != null)
 			ssidView.setText(ssid);

+ 34 - 2
src/de/tudarmstadt/informatik/hostage/ui/SettingsActivity.java

@@ -1,13 +1,45 @@
 package de.tudarmstadt.informatik.hostage.ui;
 
 import de.tudarmstadt.informatik.hostage.R;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
 import android.os.Bundle;
+import android.preference.EditTextPreference;
+import android.preference.Preference;
 import android.preference.PreferenceActivity;
 
-public class SettingsActivity extends PreferenceActivity {
+public class SettingsActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener {
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        addPreferencesFromResource(R.xml.preferences);        
+        addPreferencesFromResource(R.xml.preferences);       
+        Preference pref = findPreference("pref_external_location");
+        EditTextPreference etp = (EditTextPreference) pref;
+        pref.setSummary(etp.getText());
+        
+        pref = findPreference("pref_upload_server");
+        etp = (EditTextPreference) pref;
+        pref.setSummary(etp.getText());
+    }    
+
+    protected void onResume() {
+        super.onResume();
+        getPreferenceScreen().getSharedPreferences()
+                .registerOnSharedPreferenceChangeListener(this);
+    }
+
+    protected void onPause() {
+        super.onPause();
+        getPreferenceScreen().getSharedPreferences()
+                .unregisterOnSharedPreferenceChangeListener(this);
+    }
+
+    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
+            String key) {
+    	if(key.equals("pref_external_location") || key.equals("pref_upload_server")){
+            Preference pref = findPreference(key);
+            EditTextPreference etp = (EditTextPreference) pref;
+            pref.setSummary(etp.getText());
+        }
     }
 }

+ 83 - 32
src/de/tudarmstadt/informatik/hostage/ui/ViewLog.java

@@ -1,38 +1,40 @@
 package de.tudarmstadt.informatik.hostage.ui;
 
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Date;
 import java.util.HashMap;
 
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.entity.StringEntity;
-
 import de.tudarmstadt.informatik.hostage.R;
-import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
 import de.tudarmstadt.informatik.hostage.logging.DatabaseHandler;
-import de.tudarmstadt.informatik.hostage.logging.Record;
 import de.tudarmstadt.informatik.hostage.logging.SQLLogger;
+import android.annotation.SuppressLint;
 import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
 import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.os.Build;
 import android.os.Bundle;
+import android.support.v4.app.FragmentTransaction;
 import android.util.Log;
+import android.view.Gravity;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
 import android.widget.LinearLayout;
+import android.widget.TableLayout;
+import android.widget.TableRow;
 import android.widget.TextView;
 import android.widget.Toast;
 
 public class ViewLog extends Activity {
 
-	HashMap<String, TextView> statisticCounter;
 	DatabaseHandler dbh;
+    private final Context context = this;
 
 	@Override
 	protected void onCreate(Bundle savedInstanceState) {
@@ -60,8 +62,16 @@ public class ViewLog extends Activity {
 	}
 
 	public void exportDatabase(View view){
-		SQLLogger log = new SQLLogger(this);
-		log.exportDatabase("DEFAULT");
+	    AlertDialog.Builder builder = new AlertDialog.Builder(this);
+	    builder.setTitle(R.string.export_dialog_title);
+	    builder.setItems(R.array.format, new DialogInterface.OnClickListener() {
+	               public void onClick(DialogInterface dialog, int position) {
+	            	   SQLLogger logger = new SQLLogger(context);
+	            	   logger.exportDatabase(position);
+	           }
+	    });
+	    builder.create();
+	    builder.show();
 	}
 	
 	public void uploadDatabase(View view){
@@ -73,45 +83,86 @@ public class ViewLog extends Activity {
 		startActivity(new Intent(this, ViewLogTable.class));
 	}
 	
-	public void deleteLog(View view){		
-		dbh.clearData();
+	@SuppressLint("NewApi")
+	public void deleteLog(View view){	
+        AlertDialog.Builder builder = new AlertDialog.Builder(this);
+
+        builder.setMessage(R.string.dialog_clear_database)
+               .setPositiveButton(R.string.clear, new DialogInterface.OnClickListener() {
+                   public void onClick(DialogInterface dialog, int id) {
+                	   // Clear all Data
+               			dbh.clearData();
+               			SharedPreferences pref = getSharedPreferences(MainActivity.SESSION_DATA, Context.MODE_PRIVATE);
+               			Editor editor = pref.edit();
+               	    	editor.clear();
+               	    	editor.commit();
+               			Toast.makeText(getApplicationContext(), "Database cleared!", Toast.LENGTH_SHORT).show();
+               			// Recreate the activity
+               	        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+               	            recreate();
+               	        } else{
+               	        	Intent intent = getIntent();
+               	        	finish();
+               	        	startActivity(intent);
+               	        }
+                   }
+               })
+               .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+                   public void onClick(DialogInterface dialog, int id) {
+                       // User cancelled the dialog
+                   }
+               });
+        // Create the AlertDialog object
+        builder.create();
+        builder.show();
 	}
 
 	private void initStatistic() {
-		LinearLayout container = (LinearLayout) findViewById(R.id.layoutContainer);
-		statisticCounter = new HashMap<String, TextView>();
+		TableLayout table = (TableLayout) findViewById(R.id.layoutContainer);
+
 
 		ArrayList<String> protocols = new ArrayList<String>();
 		protocols.add("Total");
 		protocols.addAll(Arrays.asList(getResources().getStringArray(
 				R.array.protocols)));
-
+		
+		TableRow tableHeader = new TableRow(this);
+		TableRow tableContent = new TableRow(this);
+		tableHeader.setBackgroundResource(R.color.dark_grey);
+		tableContent.setBackgroundResource(R.color.light_grey);
+		
+		
 		for (String protocol : protocols) {
-			LinearLayout containerRow = new LinearLayout(this);
-			TextView text = new TextView(this);
-			text.setText("-" + protocol + ": ");
-			text.setTextAppearance(this, android.R.style.TextAppearance_Medium);
-			containerRow.addView(text);
-			text = new TextView(this);
-			text.setTextAppearance(this, android.R.style.TextAppearance_Medium);
-			containerRow.addView(text);
+			TextView protocolName = new TextView(this);
+			protocolName.setText(protocol);
+			protocolName.setTextAppearance(this, android.R.style.TextAppearance_Medium);
+			protocolName.setPadding(3, 0, 3, 0);
+			tableHeader.addView(protocolName);
+			TextView value = new TextView(this);
+			value.setTextAppearance(this, android.R.style.TextAppearance_Medium);
+			value.setGravity(Gravity.CENTER);
+			tableContent.addView(value);
 			if(protocol.equals("Total")){
-				text.setText("" + dbh.getAttackCount());
+				value.setText("" + dbh.getAttackCount());
 			}else{
-				text.setText("" + dbh.getAttackPerProtokolCount(protocol));
-			}
-			statisticCounter.put(protocol, text);
-			container.addView(containerRow);
+				value.setText("" + dbh.getAttackPerProtokolCount(protocol));
+			}		
 		}
+		table.addView(tableHeader);
+		table.addView(tableContent);	
 		
+		setFirstAndLastAttack();
+	}
+	
+	private void setFirstAndLastAttack(){
 		int attackCount = dbh.getRecordCount();
 		if(attackCount > 0){
 			SimpleDateFormat sdf = new SimpleDateFormat("MMM dd,yyyy HH:mm");
-	        Date resultdate = new Date(dbh.getRecord(1).getTimestamp());
+	        Date resultdate = new Date(dbh.getRecordOfAttackId(0).getTimestamp());
 	        TextView text = (TextView) findViewById(R.id.textFirstAttackValue);
 	        text.setText(sdf.format(resultdate));
 	        text = (TextView) findViewById(R.id.textLastAttackValue);
-	        resultdate = new Date(dbh.getRecord( dbh.getRecordCount()).getTimestamp());
+	        resultdate = new Date(dbh.getRecordOfAttackId(dbh.getAttackCount() - 1).getTimestamp());
 	        text.setText(sdf.format(resultdate));
 		} else {
 	        TextView text = (TextView) findViewById(R.id.textFirstAttackValue);