Browse Source

merged hostage v1 changes

Alexander Brakowski 10 years ago
parent
commit
4f236c8686
48 changed files with 1587 additions and 1303 deletions
  1. 7 4
      AndroidManifest.xml
  2. 4 0
      README.md
  3. 20 0
      phpsync/pull.php
  4. 27 0
      phpsync/push.php
  5. 3 0
      res/values/strings_preferences.xml
  6. 77 71
      res/xml/preferences.xml
  7. 6 0
      res/xml/settings_preferences.xml
  8. 54 12
      src/de/tudarmstadt/informatik/hostage/ConnectionGuard.java
  9. 1 0
      src/de/tudarmstadt/informatik/hostage/ConnectionRegister.java
  10. 27 8
      src/de/tudarmstadt/informatik/hostage/Handler.java
  11. 0 6
      src/de/tudarmstadt/informatik/hostage/Hostage.java
  12. 77 11
      src/de/tudarmstadt/informatik/hostage/Listener.java
  13. 0 14
      src/de/tudarmstadt/informatik/hostage/commons/HelperUtils.java
  14. 177 173
      src/de/tudarmstadt/informatik/hostage/location/MyLocationManager.java
  15. 83 53
      src/de/tudarmstadt/informatik/hostage/logging/AttackRecord.java
  16. 107 0
      src/de/tudarmstadt/informatik/hostage/logging/LogExport.java
  17. 45 10
      src/de/tudarmstadt/informatik/hostage/logging/Logger.java
  18. 3 1
      src/de/tudarmstadt/informatik/hostage/logging/MessageRecord.java
  19. 3 0
      src/de/tudarmstadt/informatik/hostage/logging/NetworkRecord.java
  20. 4 0
      src/de/tudarmstadt/informatik/hostage/logging/Record.java
  21. 4 0
      src/de/tudarmstadt/informatik/hostage/logging/SyncInfoRecord.java
  22. 5 0
      src/de/tudarmstadt/informatik/hostage/persistence/HostageDBContract.java
  23. 52 4
      src/de/tudarmstadt/informatik/hostage/persistence/HostageDBOpenHelper.java
  24. 77 67
      src/de/tudarmstadt/informatik/hostage/protocol/SMB.java
  25. 42 10
      src/de/tudarmstadt/informatik/hostage/protocol/smbutils/NBDS.java
  26. 6 1
      src/de/tudarmstadt/informatik/hostage/protocol/smbutils/NBDSType.java
  27. 94 79
      src/de/tudarmstadt/informatik/hostage/protocol/smbutils/NBNS.java
  28. 27 0
      src/de/tudarmstadt/informatik/hostage/protocol/smbutils/NBNSService.java
  29. 6 0
      src/de/tudarmstadt/informatik/hostage/protocol/smbutils/NBNSType.java
  30. 69 0
      src/de/tudarmstadt/informatik/hostage/protocol/smbutils/NBSS.java
  31. 177 77
      src/de/tudarmstadt/informatik/hostage/protocol/smbutils/NMB.java
  32. 37 17
      src/de/tudarmstadt/informatik/hostage/protocol/smbutils/NMBStringCoder.java
  33. 24 18
      src/de/tudarmstadt/informatik/hostage/protocol/smbutils/SMBPacket.java
  34. 18 0
      src/de/tudarmstadt/informatik/hostage/sync/SyncMessage.java
  35. 35 4
      src/de/tudarmstadt/informatik/hostage/sync/bluetooth/BluetoothSyncActivity.java
  36. 0 29
      src/de/tudarmstadt/informatik/hostage/sync/bluetooth/BluetoothSyncService.java
  37. 7 3
      src/de/tudarmstadt/informatik/hostage/sync/bluetooth/ClientThread.java
  38. 11 7
      src/de/tudarmstadt/informatik/hostage/sync/bluetooth/CommunicationThread.java
  39. 8 4
      src/de/tudarmstadt/informatik/hostage/sync/bluetooth/ServerThread.java
  40. 55 7
      src/de/tudarmstadt/informatik/hostage/sync/nfc/NFCSync.java
  41. 4 0
      src/de/tudarmstadt/informatik/hostage/sync/tracing/TracingSyncActivity.java
  42. 4 0
      src/de/tudarmstadt/informatik/hostage/sync/tracing/TracingSyncResultReciever.java
  43. 89 54
      src/de/tudarmstadt/informatik/hostage/sync/tracing/TracingSyncService.java
  44. 2 2
      src/de/tudarmstadt/informatik/hostage/ui/PlayGroundActivity.java
  45. 0 544
      src/de/tudarmstadt/informatik/hostage/ui/ViewLog.java
  46. 2 2
      src/de/tudarmstadt/informatik/hostage/ui/ViewLogTable.java
  47. 0 6
      src/de/tudarmstadt/informatik/hostage/ui2/fragment/HomeFragment.java
  48. 7 5
      src/de/tudarmstadt/informatik/hostage/ui2/fragment/RecordOverviewFragment.java

+ 7 - 4
AndroidManifest.xml

@@ -46,16 +46,19 @@
             android:name="de.tudarmstadt.informatik.hostage.ui2.activity.MainActivity"
             android:configChanges="keyboardHidden|orientation|screenSize"
             android:label="@string/app_name"
-            android:screenOrientation="portrait" >
-            <intent-filter>
+            android:screenOrientation="portrait" > 
+           	<intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
+            </intent-filter>  
+  
         </activity>
         <activity
             android:name="de.tudarmstadt.informatik.hostage.ui.MainActivity"
             android:configChanges="keyboardHidden|orientation|screenSize"
             android:label="@string/app_name" >
+ 
+       
         </activity>
         <activity
             android:name="de.tudarmstadt.informatik.hostage.ui.ViewLog"
@@ -87,7 +90,7 @@
             android:theme="@android:style/Theme.Dialog" >
         </activity>
         <activity
-            android:name="de.tudarmstadt.informatik.hostage.sync.bluetooth.BluetoothSync"
+            android:name="de.tudarmstadt.informatik.hostage.sync.bluetooth.BluetoothSyncActivity"
             android:label="@string/gui_bluetooth"
             android:theme="@android:style/Theme.Dialog" >
         </activity>

+ 4 - 0
README.md

@@ -6,6 +6,10 @@ Copyright (C) 2013  Mihai Plasoianu, Wulf Pfeiffer, Lars Pandikow
 Features of HoneyRJ were inspiration for this project.
 http://www.cse.wustl.edu/~jain/cse571-09/ftp/honey/manual.html
 
+Encryption for the SSH protocol were taken from Ganymed SSH-2
+and slightly modified.
+http://code.google.com/p/ganymed-ssh-2/
+
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or

+ 20 - 0
phpsync/pull.php

@@ -0,0 +1,20 @@
+<?php
+$bssid = $_POST ["bssid"];
+$timestamp = $_POST ["timestamp"];
+
+$username = "hostage";
+$password = "hostageDB";
+$hostname = "localhost";
+
+$dbhandle = mysql_connect ( $hostname, $username, $password ) or die ( "Unable to connect to MySQL" );
+
+$result = mysql_query ( "SELECT * FROM `hostage`.`sync` WHERE `bssid` = " . $bssid . " AND `timestamp` > " . $timestamp );
+
+if (! $result) {
+	die ( 'Could not select record: ' . mysql_error () );
+}
+
+while ( $row = mysql_fetch_array ( $result ) ) {
+	echo json_encode ( $row );
+}
+?>

+ 27 - 0
phpsync/push.php

@@ -0,0 +1,27 @@
+<?php
+$json = json_decode ( $_POST ["record"], true );
+
+$values = array ();
+$i = 0;
+$line = "(";
+foreach ( $json as $key => $value ) {
+	$line = $line . "'" . $value . "',";
+}
+$line = substr ( $line, 0, strlen ( $line ) - 1 ) . ")";
+$values [$i] = $line;
+++ $i;
+
+$values = implode ( ",", $values );
+
+$username = "hostage";
+$password = "hostageDB";
+$hostname = "localhost";
+
+$dbhandle = mysql_connect ( $hostname, $username, $password ) or die ( "Unable to connect to MySQL" );
+
+$result = mysql_query ( "INSERT INTO `hostage`.`sync` (`bssid`, `ssid`, `longitude`, `latitude`, `timestamp`, `attacks`, `portscans`) VALUES " . $values );
+
+if (! $result) {
+	die ( 'Could not insert record: ' . mysql_error () );
+}
+?>

+ 3 - 0
res/values/strings_preferences.xml

@@ -30,5 +30,8 @@
 	<string name="pref_location_time_default">60000</string>
 	<string name="pref_location_retries">Retries</string>
 	<string name="pref_location_retries_default">3</string>
+	<string name="pref_auto_synchronize_title">Auto Synchronization</string>
+	<string name="pref_auto_synchronize_summ">Enable auto synchronization of log data</string>
+	
 	
 </resources>

+ 77 - 71
res/xml/preferences.xml

@@ -1,72 +1,78 @@
-<?xml version="1.0" encoding="utf-8"?>
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
-
-    <PreferenceCategory android:title="@string/pref_storage" >
-        <CheckBoxPreference
-            android:defaultValue="false"
-            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:defaultValue="/HosTaGe/LogFiles/"
-            android:title="@string/pref_external_location_title"
-            />
-        
-    </PreferenceCategory>
-    <PreferenceCategory android:title="@string/pref_upload" >
-        <EditTextPreference
-            android:key="pref_upload_server"
-            android:defaultValue="https://ssi.cased.de"
-            android:title="@string/pref_upload_server" />
-        
-    </PreferenceCategory>
-    <PreferenceCategory android:title="@string/pref_notification" >
-        <CheckBoxPreference
-            android:defaultValue="true"
-            android:key="pref_vibration"
-            android:summary="@string/pref_vibration_summ"
-            android:title="@string/pref_vibration" />
-
-        <RingtonePreference
-            android:defaultValue="content://settings/system/notification_sound"
-            android:key="pref_notification_sound"
-            android:ringtoneType="notification"
-            android:showDefault="true"
-            android:showSilent="true"
-            android:summary="@string/pref_alarm_summ"
-            android:title="@string/pref_alarm" />
-    </PreferenceCategory>
-    <PreferenceCategory android:title="@string/pref_connection_settings" >
-        <EditTextPreference
-            android:key="pref_max_connections"
-            android:defaultValue="@string/pref_max_connections_default"
-            android:title="@string/pref_max_connections" />
-
-          <EditTextPreference
-            android:key="pref_timeout"
-            android:defaultValue="@string/pref_timeout_default"
-            android:title="@string/pref_timeout" />
-
-          <EditTextPreference
-            android:key="pref_sleeptime"
-            android:defaultValue="@string/pref_sleeptime_default"
-            android:title="@string/pref_sleeptime" />
-    </PreferenceCategory>
-        <PreferenceCategory android:title="@string/pref_location_settings" >
-        <EditTextPreference
-            android:key="pref_location_time"
-            android:defaultValue="@string/pref_location_time_default"
-            android:title="@string/pref_location_time" />
-
-          <EditTextPreference
-            android:key="pref_location_retries"
-            android:defaultValue="@string/pref_location_retries_default"
-            android:title="@string/pref_location_retries" />
-
-    </PreferenceCategory>
-
-
+<?xml version="1.0" encoding="utf-8"?>
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <PreferenceCategory android:title="@string/pref_storage" >
+        <CheckBoxPreference
+            android:defaultValue="false"
+            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:defaultValue="/HosTaGe/LogFiles/"
+            android:title="@string/pref_external_location_title"
+            />
+        
+    </PreferenceCategory>
+    <PreferenceCategory android:title="@string/pref_upload" >
+         <CheckBoxPreference
+            android:defaultValue="false"
+            android:key="pref_auto_synchronize"
+            android:summary="@string/pref_auto_synchronize_summ"
+            android:title="@string/pref_auto_synchronize_title" />
+                
+        <EditTextPreference
+            android:key="pref_upload_server"
+            android:defaultValue="https://ssi.cased.de"
+            android:title="@string/pref_upload_server" />
+        
+    </PreferenceCategory>
+    <PreferenceCategory android:title="@string/pref_notification" >
+        <CheckBoxPreference
+            android:defaultValue="true"
+            android:key="pref_vibration"
+            android:summary="@string/pref_vibration_summ"
+            android:title="@string/pref_vibration" />
+
+        <RingtonePreference
+            android:defaultValue="content://settings/system/notification_sound"
+            android:key="pref_notification_sound"
+            android:ringtoneType="notification"
+            android:showDefault="true"
+            android:showSilent="true"
+            android:summary="@string/pref_alarm_summ"
+            android:title="@string/pref_alarm" />
+    </PreferenceCategory>
+    <PreferenceCategory android:title="@string/pref_connection_settings" >
+        <EditTextPreference
+            android:key="pref_max_connections"
+            android:defaultValue="@string/pref_max_connections_default"
+            android:title="@string/pref_max_connections" />
+
+          <EditTextPreference
+            android:key="pref_timeout"
+            android:defaultValue="@string/pref_timeout_default"
+            android:title="@string/pref_timeout" />
+
+          <EditTextPreference
+            android:key="pref_sleeptime"
+            android:defaultValue="@string/pref_sleeptime_default"
+            android:title="@string/pref_sleeptime" />
+    </PreferenceCategory>
+        <PreferenceCategory android:title="@string/pref_location_settings" >
+        <EditTextPreference
+            android:key="pref_location_time"
+            android:defaultValue="@string/pref_location_time_default"
+            android:title="@string/pref_location_time" />
+
+          <EditTextPreference
+            android:key="pref_location_retries"
+            android:defaultValue="@string/pref_location_retries_default"
+            android:title="@string/pref_location_retries" />
+
+    </PreferenceCategory>
+
+
 </PreferenceScreen>

+ 6 - 0
res/xml/settings_preferences.xml

@@ -25,6 +25,12 @@
 				/>
 	</PreferenceCategory>
 	<PreferenceCategory android:title="@string/pref_upload" >
+		<CheckBoxPreference
+			android:defaultValue="false"
+			android:key="pref_auto_synchronize"
+			android:summary="@string/pref_auto_synchronize_summ"
+			android:title="@string/pref_auto_synchronize_title" />
+
 		<EditTextPreference
 				android:key="pref_upload_server"
 				android:defaultValue="https://ssi.cased.de"

+ 54 - 12
src/de/tudarmstadt/informatik/hostage/ConnectionGuard.java

@@ -1,7 +1,12 @@
 package de.tudarmstadt.informatik.hostage;
 
-import de.tudarmstadt.informatik.hostage.logging.Logger;
+import android.util.Log;
 
+/**
+ * Class used to detect port scans. 
+ * We assume a port scan if at least 2 different ports get a connection in a small amount of time.
+ *
+ */
 public class ConnectionGuard {
 
 	private final static ConnectionGuard INSTANCE = new ConnectionGuard();
@@ -9,23 +14,60 @@ public class ConnectionGuard {
 	private ConnectionGuard() {
 	}
 
-	private final static long ONE_SECOND_IN_NANOSECONDS = 1000000000;
+	/**
+	 * Intervall between 2 connection in wich we assume a port scan
+	 */
+	public final static long ONE_SECOND_IN_NANOSECONDS = 1000000000;
 
 	private static long lastTimestamp = 0;
 	private static String lastIP = "";
-	private static String lastProtocol = "";
+	private static int lastPort = 0;
 
-	public static void registerConnection(String protocol, String ip) {
-		long timestamp = System.nanoTime();
+	/**
+	 * Register a connection for port scan detection. Stores information about the last connection.
+	 * @param port The local port used for communication.
+	 * @param ip The IP address of the remote device.
+	 * @return True if a port scan has been detected.
+	 */
+	public synchronized static boolean registerConnection(int port, String ip) {
+		long timestamp = System.nanoTime();		
+		boolean result = detectedPortscan(port, ip, timestamp);
+		
+		lastTimestamp = timestamp;
+		lastIP = ip;
+		lastPort = port;
+		return result;
+	}
+	
+	/**
+	 * Check if the new connection is part of a port scan attack.
+	 * @param port The local port used for communication.
+	 * @param ip The IP address of the remote device.
+	 * @return True if a port scan has been detected.
+	 */
+	public synchronized static boolean detectedPortscan(int port, String ip){
+		return detectedPortscan(port, ip, System.nanoTime());
+	}
+	
+	/**
+	 * Check if the new connection is part of a port scan attack.
+	 * @param port The local port used for communication.
+	 * @param ip The IP address of the remote device.
+	 * @param timestamp Time stamp of connection
+	 * @return True if a port scan has been detected.
+	 */
+	private synchronized static boolean detectedPortscan(int port, String ip, long timestamp) {
+		Log.i("Alte Werte:", "LastTime: " + lastTimestamp + " ,LastIP: " + lastIP + ", lastPort:" + port);
+		Log.i("Alte Werte:", "Time: " + timestamp + " ,IP: " + ip + ", Port:" + port);
+		boolean result = false;
 		boolean firstConnection = (lastTimestamp == 0);
 		boolean belowThreshold = ((timestamp - lastTimestamp) < ONE_SECOND_IN_NANOSECONDS);
-		boolean sameIP = (lastIP == ip);
-		boolean sameProtocol = (lastProtocol == protocol);
-		if (!firstConnection && sameIP && belowThreshold && !sameProtocol) {
-//TODO LOG PORTSCAN			Logger.logPortscan(Hostage.getContext(), System.currentTimeMillis(), ip);
+		boolean sameIP = (lastIP.equals(ip));
+		boolean samePort = (lastPort == port);
+		if (!firstConnection && sameIP && belowThreshold && !samePort) {
+			result = true;
 		}
-		lastTimestamp = timestamp;
-		lastIP = ip;
-		lastProtocol = protocol;
+		
+		return result;
 	}
 }

+ 1 - 0
src/de/tudarmstadt/informatik/hostage/ConnectionRegister.java

@@ -8,6 +8,7 @@ import android.preference.PreferenceManager;
  * Saves the amount of active connections and limits them to a specific number.
  * 
  * @author Wulf Pfeiffer
+ * @author Lars Pandikow
  */
 public class ConnectionRegister {
 

+ 27 - 8
src/de/tudarmstadt/informatik/hostage/Handler.java

@@ -7,6 +7,7 @@ import java.net.Socket;
 import java.util.List;
 
 import android.content.Context;
+import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
 import android.preference.PreferenceManager;
@@ -22,6 +23,7 @@ import de.tudarmstadt.informatik.hostage.nio.Writer;
 import de.tudarmstadt.informatik.hostage.protocol.GHOST;
 import de.tudarmstadt.informatik.hostage.protocol.Protocol;
 import de.tudarmstadt.informatik.hostage.protocol.Protocol.TALK_FIRST;
+import de.tudarmstadt.informatik.hostage.sync.tracing.TracingSyncService;
 import de.tudarmstadt.informatik.hostage.wrapper.Packet;
 
 /**
@@ -29,6 +31,7 @@ import de.tudarmstadt.informatik.hostage.wrapper.Packet;
  * 
  * @author Mihai Plasoianu
  * @author Wulf Pfeiffer
+ * @author Lars Pandikow
  */
 public class Handler implements Runnable {
 
@@ -39,12 +42,16 @@ public class Handler implements Runnable {
 	protected Protocol protocol;
 	private Socket client;
 	protected Thread thread;
+	
+	SharedPreferences pref; 
 
 	private int attack_id;
 	private int message_id = 0;
 	private String externalIP;
 	private String BSSID;
 	private String SSID;
+	
+	private boolean logged;
 
 	private Listener listener;
 
@@ -71,7 +78,7 @@ public class Handler implements Runnable {
 		}
 		this.client = client;
 		this.thread = new Thread(this);
-		SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(service);
+		pref = PreferenceManager.getDefaultSharedPreferences(service);
 		TIMEOUT = pref.getInt("timeout", 30) * 1000;
 		getAndIncrementAttackID(pref);
 		SharedPreferences connInfo = service.getSharedPreferences(service.getString(R.string.connection_info), Context.MODE_PRIVATE);
@@ -79,10 +86,8 @@ public class Handler implements Runnable {
 		SSID = connInfo.getString(service.getString(R.string.connection_info_ssid), null);
 		externalIP = connInfo.getString(service.getString(R.string.connection_info_external_ip), null);
 		setSoTimeout(client);
-		Logger.log(Hostage.getContext(), createNetworkRecord());
-		Logger.log(Hostage.getContext(), createAttackRecord());
-		thread.start();
-		
+		logged = false;
+		thread.start();		
 	}
 
 	/**
@@ -103,10 +108,15 @@ public class Handler implements Runnable {
 		thread.interrupt();
 		try {
 			client.close();
-			Log.i("HoneyHandler", "Socket closed: " + client.isClosed());
 		} catch (Exception e) {
 			
 		} 
+		boolean upload = pref.getBoolean("pref_auto_synchronize", false);
+		if(upload){
+			Intent intent = new Intent(service, TracingSyncService.class);
+			intent.setAction(TracingSyncService.ACTION_START_SYNC);
+			service.startService(intent);
+		}
 		//TODO kann ConcurrentModificationException auslösen, da über collection iteriert wird während elemente entfernt werden
 		listener.refreshHandlers();
 	}
@@ -221,6 +231,15 @@ public class Handler implements Runnable {
 		}
 		return record;
 	}
+	
+	private void log(TYPE type, String packet){
+		if(!logged){
+			Logger.log(Hostage.getContext(), createNetworkRecord());
+			Logger.log(Hostage.getContext(), createAttackRecord());
+			logged = true;
+		}
+		Logger.log(Hostage.getContext(), createMessageRecord(type, packet));
+	}
 
 	/**
 	 * Communicates with a client using the corresponding protocol
@@ -241,7 +260,7 @@ public class Handler implements Runnable {
 			outputLine = protocol.processMessage(null);
 			writer.write(outputLine);
 			for (Packet o : outputLine) {
-				Logger.log(Hostage.getContext(), createMessageRecord(TYPE.SEND, o.toString()));
+				log(TYPE.SEND, o.toString());
 			}
 		}
 		while (!thread.isInterrupted() && (inputLine = reader.read()) != null) {
@@ -250,7 +269,7 @@ public class Handler implements Runnable {
 			if (outputLine != null) {
 				writer.write(outputLine);
 				for (Packet o : outputLine) {
-					Logger.log(Hostage.getContext(), createMessageRecord(TYPE.SEND, o.toString()));
+					log(TYPE.SEND, o.toString());
 				}
 			}
 			if (protocol.isClosed()) {

+ 0 - 6
src/de/tudarmstadt/informatik/hostage/Hostage.java

@@ -1,9 +1,5 @@
 package de.tudarmstadt.informatik.hostage;
 
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-import java.net.Socket;
-import java.security.SecureRandom;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.LinkedList;
@@ -40,7 +36,6 @@ import android.widget.Toast;
 import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
 import de.tudarmstadt.informatik.hostage.location.MyLocationManager;
 import de.tudarmstadt.informatik.hostage.persistence.HostageDBOpenHelper;
-import de.tudarmstadt.informatik.hostage.protocol.HTTP;
 import de.tudarmstadt.informatik.hostage.protocol.Protocol;
 import de.tudarmstadt.informatik.hostage.ui2.activity.MainActivity;
 
@@ -67,7 +62,6 @@ public class Hostage extends Service {
 	/**
 	 * Task to find out the external IP.
 	 * 
-	 * @author Lars Pandikow
 	 */
 	private class SetExternalIPTask extends AsyncTask<String, Void, String> {
 		@Override

+ 77 - 11
src/de/tudarmstadt/informatik/hostage/Listener.java

@@ -13,8 +13,15 @@ import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLSocket;
 import javax.net.ssl.SSLSocketFactory;
 
-import android.os.AsyncTask;
-
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.preference.PreferenceManager;
+import android.util.Log;
+import de.tudarmstadt.informatik.hostage.location.MyLocationManager;
+import de.tudarmstadt.informatik.hostage.logging.AttackRecord;
+import de.tudarmstadt.informatik.hostage.logging.Logger;
+import de.tudarmstadt.informatik.hostage.logging.NetworkRecord;
 import de.tudarmstadt.informatik.hostage.net.MyServerSocketFactory;
 import de.tudarmstadt.informatik.hostage.protocol.HTTP;
 import de.tudarmstadt.informatik.hostage.protocol.Protocol;
@@ -171,16 +178,34 @@ public class Listener implements Runnable {
 	private void addHandler() {
 		if (conReg.isConnectionFree()) {
 			try {
-				Socket client = server.accept();
-				ConnectionGuard.registerConnection(this.getProtocolName(), client.getInetAddress().getHostAddress());
-				conReg.newOpenConnection();
-				if (protocol.isSecure()) {
-					startSecureHandler(client);
-				} else {
-					startHandler(client);
-				}
+				final Socket client = server.accept();
+				new Thread( new Runnable() {
+				    @Override
+				    public void run() {
+				    	try {
+				    		String ip = client.getInetAddress().getHostAddress();
+				    		if (ConnectionGuard.registerConnection(port, ip)){
+				    			return;
+				    		}
+				    		Log.i("sda", "pause");
+				    		Thread.sleep(999);
+				    		if(ConnectionGuard.detectedPortscan(port, ip)){
+				    			logPortscan(client, System.currentTimeMillis());
+				    		}else{
+								if (protocol.isSecure()) {
+									startSecureHandler(client);
+								} else {
+									startHandler(client);
+								}				  
+								conReg.newOpenConnection();
+				    		}							
+							
+				    	} catch (Exception e) {
+				    		e.printStackTrace();
+				    	}
+				    }
+				}).start();
 			} catch (Exception e) {
-				if(server.isClosed()) return;
 				e.printStackTrace();
 			}
 		}
@@ -227,5 +252,46 @@ public class Listener implements Runnable {
 		SSLSocket sslClient = (SSLSocket) factory.createSocket(client, null, client.getPort(), false);
 		sslClient.setUseClientMode(false);
 		handlers.add(newInstance(service, this, protocol.getClass().newInstance(), sslClient));
+	}	
+	
+	/**
+	 * Logs a port scan attack
+	 * @param client The socket on which a port scan has been detected.
+	 * @param timestamp Timestamp when the portscan has been detected.
+	 */
+	private void logPortscan(Socket client, long timestamp){
+		SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(service);
+		SharedPreferences connInfo = service.getSharedPreferences(service.getString(R.string.connection_info), Context.MODE_PRIVATE);
+
+		Editor editor = pref.edit();
+		int attack_id = pref.getInt("ATTACK_ID_COUNTER", 0);
+		editor.putInt("ATTACK_ID_COUNTER", attack_id + 1);
+		editor.commit();
+		
+		AttackRecord attackRecord = new AttackRecord();
+		attackRecord.setAttack_id(attack_id);			
+		attackRecord.setProtocol("PORTSCAN");
+		attackRecord.setExternalIP(connInfo.getString(service.getString(R.string.connection_info_external_ip), null));
+		attackRecord.setLocalIP(client.getLocalAddress().getHostAddress());
+		attackRecord.setLocalPort(0);
+		attackRecord.setRemoteIP(client.getInetAddress().getHostAddress());
+		attackRecord.setRemotePort(client.getPort());
+		attackRecord.setBssid(connInfo.getString(service.getString(R.string.connection_info_bssid), null));
+		
+		NetworkRecord networkRecord = new NetworkRecord();
+		networkRecord.setBssid(connInfo.getString(service.getString(R.string.connection_info_bssid), null));		
+		networkRecord.setSsid(connInfo.getString(service.getString(R.string.connection_info_ssid), null));		
+		if (MyLocationManager.getNewestLocation() != null) {
+			networkRecord.setLatitude(MyLocationManager.getNewestLocation().getLatitude());
+			networkRecord.setLongitude(MyLocationManager.getNewestLocation().getLongitude());
+			networkRecord.setAccuracy(MyLocationManager.getNewestLocation().getAccuracy());
+			networkRecord.setTimestampLocation(MyLocationManager.getNewestLocation().getTime());
+		} else {
+			networkRecord.setLatitude(0.0);
+			networkRecord.setLongitude(0.0);
+			networkRecord.setAccuracy(Float.MAX_VALUE);
+			networkRecord.setTimestampLocation(0);
+		}
+		Logger.logPortscan(Hostage.getContext(), attackRecord, networkRecord, timestamp);
 	}
 }

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

@@ -340,20 +340,6 @@ public final class HelperUtils {
 		return bytes;
 	}
 
-	/**
-	 * Checks if external storage is available for read and write.
-	 * 
-	 * @return True if external storage is available for read and write, else
-	 *         false.
-	 */
-	public static boolean isExternalStorageWritable() {
-		String state = Environment.getExternalStorageState();
-		if (Environment.MEDIA_MOUNTED.equals(state)) {
-			return true;
-		}
-		return false;
-	}
-
 	/**
 	 * Generates a random byte[] of a specified size
 	 * 

+ 177 - 173
src/de/tudarmstadt/informatik/hostage/location/MyLocationManager.java

@@ -1,173 +1,177 @@
-package de.tudarmstadt.informatik.hostage.location;
-
-import java.util.Timer;
-import java.util.TimerTask;
-
-import android.content.Context;
-import android.location.Location;
-import android.location.LocationListener;
-import android.location.LocationManager;
-import android.os.Bundle;
-import android.util.Log;
-
-public class MyLocationManager {
-
-	class StopTask extends TimerTask {
-		@Override
-		public void run() {
-			stopUpdates();
-		}
-	}
-
-	private LocationManager locationManager;
-	/**
-	 * Static variable that always holds the newest location update.
-	 */
-	private static Location newestLocation = null;
-
-	private static final int TWO_MINUTES = 1000 * 60 * 2;
-
-	public static Location getNewestLocation() {
-		return newestLocation;
-	}
-
-	// Define a listener that responds to location updates
-	LocationListener locationListener = new LocationListener() {
-		@Override
-		public void onLocationChanged(Location location) {
-			Log.i("MyLocationManager",
-					location.getLatitude() + " " + location.getLongitude()
-							+ " " + location.getAccuracy());
-
-			// Called when a new location is found by the network location
-			// provider.
-			if (isBetterLocation(location, newestLocation)) {
-				newestLocation = location;
-			}
-		}
-
-		@Override
-		public void onProviderDisabled(String provider) {
-		}
-
-		@Override
-		public void onProviderEnabled(String provider) {
-		}
-
-		@Override
-		public void onStatusChanged(String provider, int status, Bundle extras) {
-		}
-	};
-
-	public MyLocationManager(Context context) {
-		// Acquire a reference to the system Location Manager
-		locationManager = (LocationManager) context
-				.getSystemService(Context.LOCATION_SERVICE);
-		newestLocation = locationManager
-				.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
-	}
-
-	/**
-	 * Starts updating the location data for the given amount of time. Calls
-	 * itself recursive if no location data has been found yet and there are
-	 * still attempts left.
-	 * 
-	 * @param time
-	 *            Time to update location data
-	 * @param attempts
-	 *            Remaining attempts for recieving location data
-	 */
-	public void getUpdates(long time, int attempts) {
-		startUpdates();
-		attempts--;
-		Timer timer1 = new Timer();
-		timer1.schedule(new StopTask(), time);
-		if (newestLocation == null && attempts > 0)
-			getUpdates(time, attempts);
-	}
-
-	/**
-	 * Start updating
-	 * {@link de.tudarmstadt.informatik.hostage.location.MyLocationManager#newestLocatio
-	 * newestLocation} if a location provider is enabled and available.
-	 */
-	public void startUpdates() {
-		boolean gpsEnabled = false;
-		boolean networkEnabled = false;
-		// exceptions will be thrown if provider is not permitted.
-		try {
-			gpsEnabled = locationManager
-					.isProviderEnabled(LocationManager.GPS_PROVIDER);
-		} catch (Exception ex) {
-		}
-		try {
-			networkEnabled = locationManager
-					.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
-		} catch (Exception ex) {
-		}
-
-		// don't start listeners if no provider is enabled
-		if (!gpsEnabled && !networkEnabled)
-			return;
-
-		// Register the listener with the Location Manager to receive location
-		// updates
-		if (gpsEnabled)
-			locationManager.requestLocationUpdates(
-					LocationManager.GPS_PROVIDER, 0, 0, locationListener);
-		if (networkEnabled)
-			locationManager.requestLocationUpdates(
-					LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
-	}
-
-	public void stopUpdates() {
-		locationManager.removeUpdates(locationListener);
-	}
-
-	/**
-	 * Determines whether one Location reading is better than the current
-	 * Location fix
-	 * 
-	 * @param location
-	 *            The new Location that you want to evaluate
-	 * @param currentBestLocation
-	 *            The current Location fix, to which you want to compare the new
-	 *            one
-	 */
-	private boolean isBetterLocation(Location location,
-			Location currentBestLocation) {
-		if (currentBestLocation == null) {
-			// A new location is always better than no location
-			return true;
-		}
-
-		// Check whether the new location fix is newer or older
-		long timeDelta = location.getTime() - currentBestLocation.getTime();
-		boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
-		boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
-
-		// If it's been more than two minutes since the current location, use
-		// the new location
-		// because the user has likely moved
-		if (isSignificantlyNewer) {
-			return true;
-			// If the new location is more than two minutes older, it must be
-			// worse
-		} else if (isSignificantlyOlder) {
-			return false;
-		}
-
-		// Check whether the new location fix is more or less accurate
-		int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation
-				.getAccuracy());
-		boolean isMoreAccurate = accuracyDelta < 0;
-
-		// Determine location quality using a combination of timeliness and
-		// accuracy
-		if (isMoreAccurate) {
-			return true;
-		}
-
-		return false;
-	}
-}
+package de.tudarmstadt.informatik.hostage.location;
+
+import java.util.Timer;
+import java.util.TimerTask;
+
+import android.content.Context;
+import android.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
+import android.os.Bundle;
+
+/**
+ * This Class is used to get Location data. You can get the last found Location or start searching for new location data.
+ * @author Lars Pandikow
+ */
+public class MyLocationManager {
+
+	/**
+	 * TimerTask to stop updates after a given time.
+	 */
+	class StopTask extends TimerTask {
+		@Override
+		public void run() {
+			stopUpdates();
+		}
+	}
+
+	private LocationManager locationManager;
+	/**
+	 * Static variable that always holds the newest location update.
+	 */
+	private static Location newestLocation = null;
+
+	private static final int TWO_MINUTES = 1000 * 60 * 2;
+
+	public static Location getNewestLocation() {
+		return newestLocation;
+	}
+
+	// Define a listener that responds to location updates
+	LocationListener locationListener = new LocationListener() {
+		@Override
+		public void onLocationChanged(Location location) {
+			// Called when a new location is found by the network location
+			// provider.
+			if (isBetterLocation(location, newestLocation)) {
+				newestLocation = location;
+			}
+		}
+
+		@Override
+		public void onProviderDisabled(String provider) {
+		}
+
+		@Override
+		public void onProviderEnabled(String provider) {
+		}
+
+		@Override
+		public void onStatusChanged(String provider, int status, Bundle extras) {
+		}
+	};
+
+	public MyLocationManager(Context context) {
+		// Acquire a reference to the system Location Manager
+		locationManager = (LocationManager) context
+				.getSystemService(Context.LOCATION_SERVICE);
+		newestLocation = locationManager
+				.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
+	}
+
+	/**
+	 * Starts updating the location data for the given amount of time. Calls
+	 * itself recursive if no location data has been found yet and there are
+	 * still attempts left.
+	 * 
+	 * @param time
+	 *            Time to update location data
+	 * @param attempts
+	 *            Remaining attempts for recieving location data
+	 */
+	public void getUpdates(long time, int attempts) {
+		startUpdates();
+		attempts--;
+		Timer timer1 = new Timer();
+		timer1.schedule(new StopTask(), time);
+		if (newestLocation == null && attempts > 0)
+			getUpdates(time, attempts);
+	}
+
+	/**
+	 * Start updating
+	 * {@link de.tudarmstadt.informatik.hostage.location.MyLocationManager#newestLocatio
+	 * newestLocation} if a location provider is enabled and available.
+	 */
+	public void startUpdates() {
+		boolean gpsEnabled = false;
+		boolean networkEnabled = false;
+		// exceptions will be thrown if provider is not permitted.
+		try {
+			gpsEnabled = locationManager
+					.isProviderEnabled(LocationManager.GPS_PROVIDER);
+		} catch (Exception ex) {
+		}
+		try {
+			networkEnabled = locationManager
+					.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
+		} catch (Exception ex) {
+		}
+
+		// don't start listeners if no provider is enabled
+		if (!gpsEnabled && !networkEnabled)
+			return;
+
+		// Register the listener with the Location Manager to receive location updates
+		if (gpsEnabled)
+			locationManager.requestLocationUpdates(
+					LocationManager.GPS_PROVIDER, 0, 0, locationListener);
+		if (networkEnabled)
+			locationManager.requestLocationUpdates(
+					LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
+	}
+
+	/**
+	 * Stop updating the location.
+	 */
+	public void stopUpdates() {
+		locationManager.removeUpdates(locationListener);
+	}
+
+	/**
+	 * Determines whether one Location reading is better than the current
+	 * Location fix
+	 * 
+	 * @param location
+	 *            The new Location that you want to evaluate
+	 * @param currentBestLocation
+	 *            The current Location fix, to which you want to compare the new
+	 *            one
+	 */
+	private boolean isBetterLocation(Location location,
+			Location currentBestLocation) {
+		if (currentBestLocation == null) {
+			// A new location is always better than no location
+			return true;
+		}
+
+		// Check whether the new location fix is newer or older
+		long timeDelta = location.getTime() - currentBestLocation.getTime();
+		boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
+		boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
+
+		// If it's been more than two minutes since the current location, use
+		// the new location
+		// because the user has likely moved
+		if (isSignificantlyNewer) {
+			return true;
+			// If the new location is more than two minutes older, it must be
+			// worse
+		} else if (isSignificantlyOlder) {
+			return false;
+		}
+
+		// Check whether the new location fix is more or less accurate
+		int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation
+				.getAccuracy());
+		boolean isMoreAccurate = accuracyDelta < 0;
+
+		// Determine location quality using a combination of timeliness and
+		// accuracy
+		if (isMoreAccurate) {
+			return true;
+		}
+
+		return false;
+	}
+}

+ 83 - 53
src/de/tudarmstadt/informatik/hostage/logging/AttackRecord.java

@@ -5,10 +5,13 @@ import java.io.Serializable;
 import android.os.Parcel;
 import android.os.Parcelable;
 
-public class AttackRecord implements Parcelable, Serializable{
-	
+/**
+ * Holds all necessary information about a single attack.
+ */
+public class AttackRecord implements Parcelable, Serializable {
+
 	private static final long serialVersionUID = 6111024905373724227L;
-	
+
 	private long attack_id;
 	private String bssid;
 	private String protocol;
@@ -17,155 +20,182 @@ public class AttackRecord implements Parcelable, Serializable{
 	private String remoteIP;
 	private int remotePort;
 	private String externalIP;
-	
-	
-    public static final Parcelable.Creator<AttackRecord> CREATOR = new Parcelable.Creator<AttackRecord>() {
-    	@Override
-        public AttackRecord createFromParcel(Parcel source) {
-                    return new AttackRecord(source);
-            }
-
-            @Override
-            public AttackRecord[] newArray(int size) {
-            	return new AttackRecord[size];
-            }
-    };
-
-    public AttackRecord() {
-
-    }
-
-    public AttackRecord(Parcel source) {
-            this.attack_id = source.readLong();
-            this.protocol = source.readString();
-            this.localIP = source.readString();
-            this.localPort = source.readInt();
-            this.remoteIP = source.readString();
-            this.remotePort = source.readInt();
-            this.externalIP = source.readString();
-            this.bssid = source.readString();
-    }
-	
+
+	public static final Parcelable.Creator<AttackRecord> CREATOR = new Parcelable.Creator<AttackRecord>() {
+		@Override
+		public AttackRecord createFromParcel(Parcel source) {
+			return new AttackRecord(source);
+		}
+
+		@Override
+		public AttackRecord[] newArray(int size) {
+			return new AttackRecord[size];
+		}
+	};
+
+	public AttackRecord() {
+
+	}
+
+	public AttackRecord(Parcel source) {
+		this.attack_id = source.readLong();
+		this.protocol = source.readString();
+		this.localIP = source.readString();
+		this.localPort = source.readInt();
+		this.remoteIP = source.readString();
+		this.remotePort = source.readInt();
+		this.externalIP = source.readString();
+		this.bssid = source.readString();
+	}
+
 	@Override
 	public int describeContents() {
 		return 0;
 	}
-	
+
 	@Override
 	public void writeToParcel(Parcel dest, int flags) {
-        dest.writeLong(attack_id);
-        dest.writeString(protocol);
-        dest.writeString(localIP);
-        dest.writeInt(localPort);
-        dest.writeString(remoteIP);
-        dest.writeInt(remotePort);
-        dest.writeString(externalIP);
-        dest.writeString(bssid);
+		dest.writeLong(attack_id);
+		dest.writeString(protocol);
+		dest.writeString(localIP);
+		dest.writeInt(localPort);
+		dest.writeString(remoteIP);
+		dest.writeInt(remotePort);
+		dest.writeString(externalIP);
+		dest.writeString(bssid);
 	}
-	
+
 	/**
 	 * @return the attack_id
 	 */
 	public long getAttack_id() {
 		return attack_id;
 	}
+
 	/**
-	 * @param attack_id the attack_id to set
+	 * @param attack_id
+	 *            the attack_id to set
 	 */
 	public void setAttack_id(long attack_id) {
 		this.attack_id = attack_id;
 	}
+
 	/**
 	 * @return the bssid
 	 */
 	public String getBssid() {
 		return bssid;
 	}
+
 	/**
-	 * @param bssid the bssid to set
+	 * @param bssid
+	 *            the bssid to set
 	 */
 	public void setBssid(String bssid) {
 		this.bssid = bssid;
 	}
+
 	/**
 	 * @return the protocol
 	 */
 	public String getProtocol() {
 		return protocol;
 	}
+
 	/**
-	 * @param protocol the protocol to set
+	 * @param protocol
+	 *            the protocol to set
 	 */
 	public void setProtocol(String protocol) {
 		this.protocol = protocol;
 	}
+
 	/**
 	 * @return the localIP
 	 */
 	public String getLocalIP() {
 		return localIP;
 	}
+
 	/**
-	 * @param localIP the localIP to set
+	 * @param localIP
+	 *            the localIP to set
 	 */
 	public void setLocalIP(String localIP) {
 		this.localIP = localIP;
 	}
+
 	/**
 	 * @return the localPort
 	 */
 	public int getLocalPort() {
 		return localPort;
 	}
+
 	/**
-	 * @param localPort the localPort to set
+	 * @param localPort
+	 *            the localPort to set
 	 */
 	public void setLocalPort(int localPort) {
 		this.localPort = localPort;
 	}
+
 	/**
 	 * @return the remoteIP
 	 */
 	public String getRemoteIP() {
 		return remoteIP;
 	}
+
 	/**
-	 * @param remoteIP the remoteIP to set
+	 * @param remoteIP
+	 *            the remoteIP to set
 	 */
 	public void setRemoteIP(String remoteIP) {
 		this.remoteIP = remoteIP;
 	}
+
 	/**
 	 * @return the remotePort
 	 */
 	public int getRemotePort() {
 		return remotePort;
 	}
+
 	/**
-	 * @param remotePort the remotePort to set
+	 * @param remotePort
+	 *            the remotePort to set
 	 */
 	public void setRemotePort(int remotePort) {
 		this.remotePort = remotePort;
 	}
+
 	/**
 	 * @return the externalIP
 	 */
 	public String getExternalIP() {
 		return externalIP;
 	}
+
 	/**
-	 * @param externalIP the externalIP to set
+	 * @param externalIP
+	 *            the externalIP to set
 	 */
 	public void setExternalIP(String externalIP) {
 		this.externalIP = externalIP;
 	}
-	
-	//TEMP ZU TEST
+
+	// TEMP ZU TEST
 	@Override
-	public String toString(){
+	public String toString() {
 		return String
 				.format("{ \"sensor\":{\"type\": \"Honeypot\", \"name\": \"HosTaGe\"}, \"type\": \"%s server access\", \"src\":{\"ip\": \"%s\", \"port\": %d}, \"dst\":{\"ip\": \"%s\", \"port\": %d} }",
 						getProtocol(), getRemoteIP(), getRemotePort(), getExternalIP(), getLocalPort());
 	}
 
+	public String toJSON() {
+		return String.format("{\"bssid\":\"%s\",\"ssid\":\"%s\",\"latitude\":%d,\"longitude\":%d,\"timestamp\":%d,\"attacks\":%d,\"portscans\":%d}", "bssid",
+				"ssid", 23, 32, 123456, 22, 2);
+	}
+
 }

+ 107 - 0
src/de/tudarmstadt/informatik/hostage/logging/LogExport.java

@@ -0,0 +1,107 @@
+package de.tudarmstadt.informatik.hostage.logging;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.util.ArrayList;
+
+import android.app.IntentService;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Environment;
+import android.preference.PreferenceManager;
+import android.widget.Toast;
+import de.tudarmstadt.informatik.hostage.logging.formatter.Formatter;
+import de.tudarmstadt.informatik.hostage.persistence.HostageDBOpenHelper;
+
+/**
+ * The LogExport is used to write a text representation of all logs in the database.
+ * The Service runs in its own worker thread.
+ * @author Lars Pandikow
+ */
+public class LogExport extends IntentService{
+	
+	public static final String ACTION_EXPORT_DATABASE = "de.tudarmstadt.informatik.hostage.logging.ACTION_EXPORT_DATABASE";
+	
+	SharedPreferences pref;
+	HostageDBOpenHelper dbh;
+	
+	public LogExport() {
+		super(LogExport.class.getName());
+
+	}
+	
+	@Override
+	public void onCreate() {
+		super.onCreate();
+		pref = PreferenceManager.getDefaultSharedPreferences(this);
+		dbh = new HostageDBOpenHelper(this);
+	}
+	
+	/**
+	 * The IntentService calls this method from the default worker thread with
+	 * the intent that started the service. When this method returns, IntentService
+	 * stops the service, as appropriate.
+	 */
+	@Override
+	protected void onHandleIntent(Intent intent) {
+		if (intent != null) {
+			final String action = intent.getAction();
+			if (ACTION_EXPORT_DATABASE.equals(action)) {
+				exportDatabase(null);
+			}
+
+		}	
+	}
+	
+	/**
+	 * Exports all records in a given format. Before exporting checks export
+	 * location from preferences.
+	 * 
+	 * @param format
+	 *            Integer coded export format
+	 * @see Record#toString(int)
+	 */
+	private void exportDatabase(Formatter format) {
+		
+		try {
+			FileOutputStream log;
+			String filename = "hostage_" + format + "_"+ System.currentTimeMillis() + ".log";
+			String externalLocation = pref.getString("pref_external_location", "");
+			String root = Environment.getExternalStorageDirectory().toString();
+			if (root != null && isExternalStorageWritable()) {
+				File dir = new File(root + externalLocation);
+				dir.mkdirs();
+				File file = new File(dir, filename);
+				log = new FileOutputStream(file);
+			} else {
+				Toast.makeText(this, "Could not write to SD Card",Toast.LENGTH_SHORT).show();
+				return;
+			}
+
+			ArrayList<Record> records = dbh.getAllRecords();
+			for (Record record : records) {
+				log.write((record.toString(format)).getBytes());
+			}
+			log.flush();
+			log.close();
+			Toast.makeText(this, filename + " saved on external memory! ", Toast.LENGTH_LONG).show();
+		} catch (Exception e) {
+			Toast.makeText(this, "Could not write to SD Card", Toast.LENGTH_SHORT).show();
+			e.printStackTrace();
+		}
+	}
+	
+	/**
+	 * Checks if external storage is available for read and write.
+	 * 
+	 * @return True if external storage is available for read and write, else
+	 *         false.
+	 */
+	public boolean isExternalStorageWritable() {
+		String state = Environment.getExternalStorageState();
+		if (Environment.MEDIA_MOUNTED.equals(state)) {
+			return true;
+		}
+		return false;
+	}
+}

+ 45 - 10
src/de/tudarmstadt/informatik/hostage/logging/Logger.java

@@ -7,6 +7,11 @@ import android.os.Parcelable;
 import de.tudarmstadt.informatik.hostage.logging.MessageRecord.TYPE;
 import de.tudarmstadt.informatik.hostage.persistence.HostageDBOpenHelper;
 
+/**
+ * The Logger is used to write the database in dedicated worker threads and implements a message queue.
+ * @author Mihai Plasoianu
+ * @author Lars Pandikow
+ */
 public class Logger extends IntentService {
 
 	private static final String ACTION_LOG_MESSAGE = "de.tudarmstadt.informatik.hostage.action.LOG_MESSAGE";
@@ -15,8 +20,14 @@ public class Logger extends IntentService {
 	private static final String ACTION_LOG_PORTSCAN = "de.tudarmstadt.informatik.hostage.action.LOG_PORTSCAN";
 
 	private static final String EXTRA_RECORD = "de.tudarmstadt.informatik.hostage.extra.RECORD";
+	private static final String EXTRA_RECORD2 = "de.tudarmstadt.informatik.hostage.extra.RECORD2";
 	private static final String EXTRA_TIMESTAMP = "de.tudarmstadt.informatik.hostage.extra.TIMESTAMP";
 
+	/**
+	 * Adds a single MessageRecord to the Database.
+	 * @param context Context needed to access database
+	 * @param record The MessageRecord to be added
+	 */
 	public static void log(Context context, MessageRecord record) {
 		Intent intent = new Intent(context, Logger.class);
 		intent.setAction(ACTION_LOG_MESSAGE);
@@ -24,6 +35,11 @@ public class Logger extends IntentService {
 		context.startService(intent);
 	}
 	
+	/**
+	 * Adds a single AttackRecord to the Database.
+	 * @param context Context needed to access database
+	 * @param record The AttackRecord to be added
+	 */
 	public static void log(Context context, AttackRecord record) {
 		Intent intent = new Intent(context, Logger.class);
 		intent.setAction(ACTION_LOG_ATTACK);
@@ -31,6 +47,11 @@ public class Logger extends IntentService {
 		context.startService(intent);
 	}
 	
+	/**
+	 * Adds a single NetworkRecord to the Database.
+	 * @param context Context needed to access database
+	 * @param record The NetworkRecord to be added
+	 */
 	public static void log(Context context, NetworkRecord record) {
 		Intent intent = new Intent(context, Logger.class);
 		intent.setAction(ACTION_LOG_NETWORK);
@@ -38,10 +59,18 @@ public class Logger extends IntentService {
 		context.startService(intent);
 	}
 	
-	public static void logPortscan(Context context, AttackRecord record, long timestamp){
+	/**
+	 * Adds a port scan entry to the database
+	 * @param context Context needed to access database
+	 * @param attackRecord AttackRecord containing the attack information of the port scan
+	 * @param netRecord NetworkRecord containing the network information of the port scan
+	 * @param timestamp Timestamp of the port scan
+	 */
+	public static void logPortscan(Context context, AttackRecord attackRecord, NetworkRecord netRecord, long timestamp){
 		Intent intent = new Intent(context, Logger.class);
 		intent.setAction(ACTION_LOG_PORTSCAN);
-		intent.putExtra(EXTRA_RECORD, (Parcelable)record);
+		intent.putExtra(EXTRA_RECORD, (Parcelable)attackRecord);
+		intent.putExtra(EXTRA_RECORD2, (Parcelable)netRecord);
 		intent.putExtra(EXTRA_TIMESTAMP, timestamp);
 		context.startService(intent);
 	}
@@ -69,6 +98,9 @@ public class Logger extends IntentService {
 		mDbHelper.updateNetworkInformation(record);
 	}
 
+	/**
+	 * Method to handle the Intent createt by the public interface.
+	 */
 	@Override
 	protected void onHandleIntent(Intent intent) {
 		if (intent != null) {
@@ -83,14 +115,17 @@ public class Logger extends IntentService {
 				final NetworkRecord record = intent.getParcelableExtra(EXTRA_RECORD);
 				handleActionLog(record);
 			}else if(ACTION_LOG_PORTSCAN.equals(action)){
-				final AttackRecord record = intent.getParcelableExtra(EXTRA_RECORD);
-				handleActionLog(record);
-				MessageRecord mRecord = new MessageRecord();
-				mRecord.setAttack_id(record.getAttack_id());
-				mRecord.setId(0);
-				mRecord.setPacket("");
-				mRecord.setTimestamp(intent.getLongExtra(EXTRA_TIMESTAMP, 0));
-				mRecord.setType(TYPE.RECEIVE);
+				final AttackRecord attackRecord = intent.getParcelableExtra(EXTRA_RECORD);
+				final NetworkRecord networkRecord = intent.getParcelableExtra(EXTRA_RECORD2);
+				MessageRecord messageRecord = new MessageRecord();
+				messageRecord.setAttack_id(attackRecord.getAttack_id());
+				messageRecord.setId(0);
+				messageRecord.setPacket("");
+				messageRecord.setTimestamp(intent.getLongExtra(EXTRA_TIMESTAMP, 0));
+				messageRecord.setType(TYPE.RECEIVE);
+				handleActionLog(attackRecord);
+				handleActionLog(networkRecord);
+				handleActionLog(messageRecord);
 			}
 		}
 	}

+ 3 - 1
src/de/tudarmstadt/informatik/hostage/logging/MessageRecord.java

@@ -5,7 +5,9 @@ import java.io.Serializable;
 import android.os.Parcel;
 import android.os.Parcelable;
 
-
+/**
+ * Holds all necessary information about a single message exchanged during an attack.
+ */
 public class MessageRecord implements Parcelable, Serializable{
 	
 	private static final long serialVersionUID = -5936572995202342935L;

+ 3 - 0
src/de/tudarmstadt/informatik/hostage/logging/NetworkRecord.java

@@ -5,6 +5,9 @@ import java.io.Serializable;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+/**
+ * Holds all necessary information about a single network.
+ */
 public class NetworkRecord implements Parcelable, Serializable{	
 	
 	private static final long serialVersionUID = -1586629159904177836L;

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

@@ -3,6 +3,10 @@ package de.tudarmstadt.informatik.hostage.logging;
 import de.tudarmstadt.informatik.hostage.logging.MessageRecord.TYPE;
 import de.tudarmstadt.informatik.hostage.logging.formatter.Formatter;
 
+/**
+ * Record that holds all information of a message including full attack and network information.
+ * This class should be avoided but is necessary due to inter group complications.
+ */
 public class Record {
 
 	//

+ 4 - 0
src/de/tudarmstadt/informatik/hostage/logging/SyncInfoRecord.java

@@ -2,6 +2,10 @@ package de.tudarmstadt.informatik.hostage.logging;
 
 import java.io.Serializable;
 
+/**
+ * Holds the Information a specific device gathered about a network identified by its BSSID.
+ * @author Lars Pandikow
+ */
 public class SyncInfoRecord implements Serializable{	
 
 	private static final long serialVersionUID = 7156818788190434192L;

+ 5 - 0
src/de/tudarmstadt/informatik/hostage/persistence/HostageDBContract.java

@@ -2,6 +2,11 @@ package de.tudarmstadt.informatik.hostage.persistence;
 
 import android.provider.BaseColumns;
 
+/**
+ * Contract class defines names for the {@link HostageDBOpenHelper}.
+ * @author Mihai Plasoianu
+ * @author Lars Pandikow
+ */
 public final class HostageDBContract {
 
 	public static abstract class NetworkEntry implements BaseColumns {

+ 52 - 4
src/de/tudarmstadt/informatik/hostage/persistence/HostageDBOpenHelper.java

@@ -27,6 +27,12 @@ import de.tudarmstadt.informatik.hostage.persistence.HostageDBContract.SyncDevic
 import de.tudarmstadt.informatik.hostage.persistence.HostageDBContract.SyncInfoEntry;
 import de.tudarmstadt.informatik.hostage.ui.LogFilter;
 
+/**
+ * Database Helper class to create, read and write the database.
+ * @author Mihai Plasoianu
+ * @author Lars Pandikow
+ *
+ */
 public class HostageDBOpenHelper extends SQLiteOpenHelper {
 
 	private static final String DATABASE_NAME = "hostage.db";
@@ -625,6 +631,10 @@ public class HostageDBOpenHelper extends SQLiteOpenHelper {
 		return ssid;
 	}
 	
+	/**
+	 * Gets all network related data stored in the database
+	 * @return An ArrayList with an Network for all Entry in the network table.
+	 */
 	public synchronized ArrayList<NetworkRecord> getNetworkInformation() {
 		String selectQuery = "SELECT  * FROM " + NetworkEntry.TABLE_NAME;
 		SQLiteDatabase db = this.getReadableDatabase();
@@ -651,13 +661,24 @@ public class HostageDBOpenHelper extends SQLiteOpenHelper {
 		return networkInformation;
 	}
 
-	public void updateNetworkInformation(ArrayList<NetworkRecord> networkInformation) {
-		Log.i("DatabaseHandler", "Starte updating");
+	/**
+	 * Updates the network table with the information contained in the parameter.
+	 * @param networkInformation ArrayList of {@link NetworkRecord NetworkRecords}
+	 * @see  {@link HostageDBOpenHelper#updateNetworkInformation(NetworkRecord record)}
+	 */
+	public void updateNetworkInformation(ArrayList<NetworkRecord> networkInformation) {;
 		for (NetworkRecord record : networkInformation) {
 			updateNetworkInformation(record);
 		}
 	}
 
+	/**
+	 * Updated the network table with a new {@link NetworkRecord}.
+	 * If information about this BSSID are already in the database, 
+	 * the table will only be updated if the new {@link NetworkRecord } 
+	 * has a newer location time stamp.
+	 * @param record The new {@link NetworkRecord}.
+	 */
 	public void updateNetworkInformation(NetworkRecord record) {
 		SQLiteDatabase db = this.getReadableDatabase();
 		String bssid = record.getBssid();
@@ -678,6 +699,24 @@ public class HostageDBOpenHelper extends SQLiteOpenHelper {
 	}
 	
 	
+	/**
+	 * Updates the the timestamp of a single device id
+	 * @param devices The Device id
+	 * @param timestamp The synchronization timestamp
+	 */
+	public void updateSyncDevice(String devices, long timestamp){
+		SQLiteDatabase db = this.getReadableDatabase();		
+		ContentValues deviceValues = new ContentValues();
+		deviceValues.put(SyncDeviceEntry.COLUMN_NAME_DEVICE_ID, devices);
+		deviceValues.put(SyncDeviceEntry.COLUMN_NAME_DEVICE_TIMESTAMP, timestamp);
+		db.insertWithOnConflict(SyncDeviceEntry.TABLE_NAME, null, deviceValues, SQLiteDatabase.CONFLICT_REPLACE);
+		db.close();
+	}
+	
+	/**
+	 * Updates the Timestamps of synchronization devices from a HashMap.
+	 * @param devices HashMap of device ids and their synchronization timestamps.
+	 */
 	public void updateSyncDevices(HashMap<String, Long> devices){
 		SQLiteDatabase db = this.getReadableDatabase();		
 		for(String key : devices.keySet()){
@@ -736,13 +775,22 @@ public class HostageDBOpenHelper extends SQLiteOpenHelper {
 		return syncInfo;
 	}	
 	
-	
+	/**
+	 * Updates the sync_info table with the information contained in the parameter.
+	 * @param networkInformation ArrayList of {@link SyncInfoRecord SyncInfoRecords}
+	 * @see  {@link HostageDBOpenHelper#updateSyncInfo(SyncInfoRecord syncInfo)}
+	 */
 	public synchronized void updateSyncInfo(ArrayList<SyncInfoRecord> syncInfo){
 		for(SyncInfoRecord info : syncInfo){
 			updateSyncInfo(info);
 		}
 	}
 	
+	/**
+	 * Updated the network table with a new {@link SyncInfoRecord}.
+	 * Conflicting rows will be replaced.
+	 * @param syncInfo The new {@link NetworkRecord}.
+	 */
 	public synchronized void updateSyncInfo(SyncInfoRecord syncInfo){
 		SQLiteDatabase db = this.getReadableDatabase();
 		ContentValues syncValues = new ContentValues();
@@ -887,7 +935,7 @@ public class HostageDBOpenHelper extends SQLiteOpenHelper {
 
 		return record;
 	}
-
+		
 	/**
 	 * Gets all received {@link Record Records} for the specified information in
 	 * the LogFilter ordered by date.

+ 77 - 67
src/de/tudarmstadt/informatik/hostage/protocol/SMB.java

@@ -6,6 +6,7 @@ import java.util.List;
 
 import de.tudarmstadt.informatik.hostage.Hostage;
 import de.tudarmstadt.informatik.hostage.R;
+import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
 import de.tudarmstadt.informatik.hostage.protocol.smbutils.NBNS;
 import de.tudarmstadt.informatik.hostage.protocol.smbutils.NMB;
 import de.tudarmstadt.informatik.hostage.protocol.smbutils.SMBPacket;
@@ -16,7 +17,7 @@ import de.tudarmstadt.informatik.hostage.wrapper.Packet;
  * Request, Session Setup AndX Request, Tree Connect AndX Request, NT Create
  * AndX Request, Bind, NetShareEnumAll, Close Request, Tree Disconnect Request,
  * Echo Request, Trans2 Request.
- * 
+ *
  * @author Wulf Pfeiffer
  */
 public class SMB implements Protocol {
@@ -30,12 +31,13 @@ public class SMB implements Protocol {
 	private static final byte SMB_COM_SESSION_SETUP_ANDX = 0x73;
 	private static final byte SMB_COM_TREE_CONNECT_ANDX = 0x75;
 	private static final byte SMB_COM_NT_CREATE_ANDX = (byte) 0xA2;
-	
+
 	/**
 	 * Denotes in which state the protocol is right now
 	 */
 	private STATE state = STATE.NONE;
 	private byte[] lastMessage;
+	private NMB nmb;
 
 	// version stuff
 	private String[][] possibleSmbVersions = {
@@ -46,28 +48,33 @@ public class SMB implements Protocol {
 			{ "Unix", "Samba" },
 			{ "Windows 2002 Service Pack 2", "Windows 2002 5.1" }
 	};
-	
+
 	/**
 	 * Represents the states of the protocol
 	 */
 	private static enum STATE {
 		NONE, CONNECTED, AUTHENTICATED, LISTING, DISCONNECTED, CLOSED
 	}
-	
+
 	public void setIP(String ip) {
-		/*new NMB(ip, "ABCDEFG", "WORKGROUPA").start();*/
+//		TODO if porthack is working for UDP uncomment
+//		nmb = new NMB(ip, new String(serverName), workgroup);
+//		nmb.start();
 	}
 
 	private String[] initServerVersion() {
-		System.out.println("hi");
 		String sharedPreferencePath = Hostage.getContext().getString(
 				R.string.shared_preference_path);
-		System.out.println(sharedPreferencePath);
 		String profile = Hostage
 				.getContext()
 				.getSharedPreferences(sharedPreferencePath,
 						Hostage.MODE_PRIVATE).getString("os", "");
-		System.out.println(profile);
+		if(profile.equals("Windows XP")) {
+			workgroup = "MSHOME";
+		} else {
+			workgroup = "WORKGROUP";
+		}
+
 		if (profile.equals("Windows 7")) {
 			return possibleSmbVersions[0];
 		} else if (profile.equals("Windows 8")) {
@@ -84,10 +91,13 @@ public class SMB implements Protocol {
 			return possibleSmbVersions[new SecureRandom().nextInt(possibleSmbVersions.length)];
 		}
 	}
-	
+
 	//required to be declared down here, do not change position over initServerVersion() and possibleServerVersions!!
 	private String[] serverVersion = initServerVersion();
-	private SMBPacket smbPacket = new SMBPacket(serverVersion);
+	private static byte[] serverName = HelperUtils.fillWithZero(HelperUtils
+			.getRandomString(16, true).getBytes());
+	private static String workgroup;
+	private SMBPacket smbPacket = new SMBPacket(serverVersion, new String(serverName), workgroup);
 
 	@Override
 	public int getPort() {
@@ -114,67 +124,67 @@ public class SMB implements Protocol {
 		List<Packet> responsePackets = new ArrayList<Packet>();
 
 		switch (state) {
-		case NONE:
-			if (smbCommand == SMB_COM_NEGOTIATE) {
-				state = STATE.CONNECTED;
-				response = smbPacket.getNego();
-			} else {
-				state = STATE.DISCONNECTED;
-				response = smbPacket.getTreeDisc();
-			}
-			break;
-		case CONNECTED:
-			if (smbCommand == SMB_COM_SESSION_SETUP_ANDX) {
-				response = smbPacket.getSessSetup();
-			} else if (smbCommand == SMB_COM_TREE_CONNECT_ANDX) {
-				state = STATE.AUTHENTICATED;
-				response = smbPacket.getTreeCon();
-			} else {
-				state = STATE.DISCONNECTED;
-				response = smbPacket.getTreeDisc();
-			}
-			break;
-		case AUTHENTICATED:
-			if (smbCommand == SMB_COM_NT_CREATE_ANDX) {
-				state = STATE.LISTING;
-				response = smbPacket.getNTCreate();
-			} else if (smbCommand == SMB_COM_ECHO) {
-				response = smbPacket.getEcho();
-			} else if (smbCommand == SMB_COM_TRANSACTION2) {
-				response = smbPacket.getTrans2();
-			} else if (smbCommand == SMB_COM_CLOSE) {
-				response = smbPacket.getClose();
-			} else if (smbCommand == SMB_COM_TREE_DISCONNECT) {
+			case NONE:
+				if (smbCommand == SMB_COM_NEGOTIATE) {
+					state = STATE.CONNECTED;
+					response = smbPacket.getNego();
+				} else {
+					state = STATE.DISCONNECTED;
+					response = smbPacket.getTreeDisc();
+				}
+				break;
+			case CONNECTED:
+				if (smbCommand == SMB_COM_SESSION_SETUP_ANDX) {
+					response = smbPacket.getSessSetup();
+				} else if (smbCommand == SMB_COM_TREE_CONNECT_ANDX) {
+					state = STATE.AUTHENTICATED;
+					response = smbPacket.getTreeCon();
+				} else {
+					state = STATE.DISCONNECTED;
+					response = smbPacket.getTreeDisc();
+				}
+				break;
+			case AUTHENTICATED:
+				if (smbCommand == SMB_COM_NT_CREATE_ANDX) {
+					state = STATE.LISTING;
+					response = smbPacket.getNTCreate();
+				} else if (smbCommand == SMB_COM_ECHO) {
+					response = smbPacket.getEcho();
+				} else if (smbCommand == SMB_COM_TRANSACTION2) {
+					response = smbPacket.getTrans2();
+				} else if (smbCommand == SMB_COM_CLOSE) {
+					response = smbPacket.getClose();
+				} else if (smbCommand == SMB_COM_TREE_DISCONNECT) {
+					state = STATE.CLOSED;
+					response = smbPacket.getTreeDisc();
+				} else {
+					state = STATE.DISCONNECTED;
+					response = smbPacket.getTreeDisc();
+				}
+				break;
+			case LISTING:
+				if (smbCommand == SMB_COM_TRANSACTION) {
+					response = smbPacket.getTrans();
+				} else if (smbCommand == SMB_COM_CLOSE) {
+					response = smbPacket.getClose();
+				} else if (smbCommand == SMB_COM_TREE_DISCONNECT) {
+					state = STATE.CLOSED;
+					response = smbPacket.getTreeDisc();
+				} else if (smbCommand == SMB_COM_NEGOTIATE) {
+					state = STATE.CONNECTED;
+					response = smbPacket.getNego();
+				} else {
+					state = STATE.DISCONNECTED;
+					response = smbPacket.getTreeDisc();
+				}
+				break;
+			case DISCONNECTED:
 				state = STATE.CLOSED;
 				response = smbPacket.getTreeDisc();
-			} else {
-				state = STATE.DISCONNECTED;
-				response = smbPacket.getTreeDisc();
-			}
-			break;
-		case LISTING:
-			if (smbCommand == SMB_COM_TRANSACTION) {
-				response = smbPacket.getTrans();
-			} else if (smbCommand == SMB_COM_CLOSE) {
-				response = smbPacket.getClose();
-			} else if (smbCommand == SMB_COM_TREE_DISCONNECT) {
+				break;
+			default:
 				state = STATE.CLOSED;
 				response = smbPacket.getTreeDisc();
-			} else if (smbCommand == SMB_COM_NEGOTIATE) {
-				state = STATE.CONNECTED;
-				response = smbPacket.getNego();
-			} else {
-				state = STATE.DISCONNECTED;
-				response = smbPacket.getTreeDisc();
-			}
-			break;
-		case DISCONNECTED:
-			state = STATE.CLOSED;
-			response = smbPacket.getTreeDisc();
-			break;
-		default:
-			state = STATE.CLOSED;
-			response = smbPacket.getTreeDisc();
 		}
 		responsePackets.add(new Packet(response, toString()));
 		return responsePackets;

+ 42 - 10
src/de/tudarmstadt/informatik/hostage/protocol/smbutils/NBDS.java

@@ -4,30 +4,44 @@ import java.nio.ByteBuffer;
 
 import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
 
-
+/**
+ * NetBIOS Datagram Service.
+ * @author Wulf Pfeiffer
+ */
 public class NBDS {
 	
+	private String dst;
 	private byte[] type;
 	private byte[] flags;
-	private byte[] id;
+	private byte[] transactID;
 	private byte[] srcIP;
 	private byte[] srcPort;
 	private byte[] length;
 	private byte[] offset;
 	private byte[] srcName;
 	private byte[] dstName;
+	private int nbdstype;
 	private SMBPacket smb;
 	
-	public NBDS(byte[] transactID, byte[] addr, String src, String dst, int nbdstype) {
-		this.type = new byte[]{0x11};
+	public NBDS(byte[] addr, String src, String dst) {
+		this.dst = dst;
+		type = new byte[]{0x11};
 		flags = new byte[]{0x0a};
-		id = transactID;
 		srcIP = addr;
 		srcPort = new byte[]{0x00, (byte) 0x8a};
 		offset = new byte[]{0x00, 0x00};
 		length = new byte[2];
 		srcName = NMBStringCoder.wrapNBNSName(NMBStringCoder.encodeNBNSName(src.getBytes()), NBNSService.WORKSTATION);
-		if (nbdstype == NBDSType.REQUEST_ANNOUNCEMENT || nbdstype == NBDSType.LOCAL_MASTER_ANNOUNCEMENT_ALL) {
+		smb = new SMBPacket(null, src, dst);
+	}
+	
+	/**
+	 * Prepares the content for the next packet.
+	 */
+	private void preparePacket() {
+		transactID = NMB.getAndIncTransactID();
+		if (nbdstype == NBDSType.REQUEST_ANNOUNCEMENT || nbdstype == NBDSType.LOCAL_MASTER_ANNOUNCEMENT_ALL 
+				|| nbdstype == NBDSType.LOCAL_MASTER_ANNOUNCEMENT) {
 			dstName = NMBStringCoder.wrapNBNSName(NMBStringCoder.encodeNBNSName(dst.getBytes()), NBNSService.BROWSER_ELECTION);
 		} else if (nbdstype == NBDSType.DOMAIN_ANNOUNCEMENT) {
 			dstName = HelperUtils.concat(new byte[]{0x20, 0x41, 0x42, 0x41, 0x43}, NMBStringCoder.encodeNBNSName("__MSBROWSE__".getBytes()),
@@ -35,17 +49,35 @@ public class NBDS {
 		} else {
 			dstName = NMBStringCoder.wrapNBNSName(NMBStringCoder.encodeNBNSName(dst.getBytes()), NBNSService.LOCAL_MASTER_BROWSER);
 		}
-		smb = new SMBPacket(null);
-		smb.prepareNextResponse(nbdstype, src, dst);
+		smb.prepareNextResponse(nbdstype);
 		byte[] buffer = HelperUtils.concat(srcName, dstName, smb.getTrans());
 		byte[] lengthBuffer = ByteBuffer.allocate(4).putInt(buffer.length).array();
 		length[0] = lengthBuffer[2];
 		length[1] = lengthBuffer[3];
 	}
 	
-	public byte[] getBytes() {
-		return HelperUtils.concat(type, flags, id, srcIP, srcPort, length,
+	/**
+	 * @return next Packet.
+	 */
+	public byte[] getNextPacket() {
+		preparePacket();
+		return getBytes();
+	}
+	
+	/**
+	 * @return content of the packet.
+	 */
+	private byte[] getBytes() {
+		return HelperUtils.concat(type, flags, transactID, srcIP, srcPort, length,
 				offset, srcName, dstName, smb.getTrans());
 	}
 
+	/**
+	 * Set the NBDSType.
+	 * @param nbdstype.
+	 */
+	public void setNbdstype(int nbdstype) {
+		this.nbdstype = nbdstype;
+	}
+	
 }

+ 6 - 1
src/de/tudarmstadt/informatik/hostage/protocol/smbutils/NBDSType.java

@@ -1,7 +1,11 @@
 package de.tudarmstadt.informatik.hostage.protocol.smbutils;
 
+/**
+ * NetBios Datagram Service types.
+ * @author Wulf Pfeiffer.
+ */
 public class NBDSType {
-	
+
 	public static final int HOST_ANNOUNCEMENT = 0;
 	public static final int HOST_ANNOUNCEMENT_WITH_SERVICES = 1;
 	public static final int BROWSER = 2;
@@ -9,4 +13,5 @@ public class NBDSType {
 	public static final int LOCAL_MASTER_ANNOUNCEMENT_ALL = 4;
 	public static final int DOMAIN_ANNOUNCEMENT = 5;
 	public static final int LOCAL_MASTER_ANNOUNCEMENT = 6;
+
 }

+ 94 - 79
src/de/tudarmstadt/informatik/hostage/protocol/smbutils/NBNS.java

@@ -4,7 +4,10 @@ import java.nio.ByteBuffer;
 
 import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
 
-
+/**
+ * NetBIOS Name Service.
+ * @author Wulf Pfeiffer
+ */
 public class NBNS {
 	
 	private byte[] transactID;
@@ -20,43 +23,15 @@ public class NBNS {
 	private int type;
 	private int service;
 	
-	public NBNS(byte[] packet) {
-		transactID = new byte[]{packet[0], packet[1]};
-		flags = new byte[]{packet[2], packet[3]};
-		questions = new byte[]{packet[4], packet[5]};
-		answerRRs = new byte[]{packet[6], packet[7]};
-		authorityRRs = new byte[]{packet[8], packet[9]};
-		additionalRRs = new byte[]{packet[10], packet[11]};
-		int length = 0;
-		for (int i = 12; i < packet.length; i++, length++) {
-			if (packet[i] == 0x01) {
-				length++;
-				break;
-			}
-		}
-		payload = new byte[length];
-		for (int i = 0; i < payload.length; i++) {
-			payload[i] = packet[i+12];
-		}
-		additional = new byte[packet.length-12-length];
-		for (int i = 0; i < additional.length; i++) {
-			additional[i] = packet[i+12+length];
-		}
-	}
-	
-	public NBNS(byte[] transactID, String addr) {
-		this.transactID = transactID;
-		addressToBytes(addr);
-	}
-	
-	public NBNS(byte[] transactID, int type, int service, String name, String addr) {
-		this(transactID, addr);
-		this.type = type;
-		this.service = service;
-		setName(name);
+	public NBNS(byte[] addr) {
+		this.addr = addr;
 	}
 	
+	/**
+	 * Prepares the content for the next packet regarding of the set type.
+	 */
 	private void preparePacket() {
+		transactID = NMB.getAndIncTransactID();
 		switch (type) {
 		case NBNSType.REGISTRATION_UNIQUE:
 			prepareRegistrationPacket();
@@ -74,6 +49,9 @@ public class NBNS {
 		}
 	}
 	
+	/**
+	 * Prepares the content for the next registration packet.
+	 */
 	private void prepareRegistrationPacket() {
 		flags = new byte[]{0x29, 0x10};
 		questions = new byte[]{0x00, 0x01};
@@ -84,6 +62,9 @@ public class NBNS {
 		additional = getAdditionalRecords();
 	}
 	
+	/**
+	 * Prepares the content for the next name query packet.
+	 */
 	private void prepareNameQueryPacket() {
 		flags = new byte[] {0x01, 0x10};
 		questions = new byte[]{0x00, 0x01};
@@ -93,6 +74,9 @@ public class NBNS {
 		payload = getPayload();
 	}
 	
+	/**
+	 * Prepares the content for the next MSBROWSE registration packet.
+	 */
 	private void prepareRegistrationMsBrowse() {
 		flags = new byte[]{0x29, 0x10};
 		questions = new byte[]{0x00, 0x01};
@@ -104,39 +88,55 @@ public class NBNS {
 		additional = getAdditionalRecords();
 	}
 	
+	/**
+	 * Prepares the content for the next response packet.
+	 */
+	public void prepareResponsePacket(byte[] packet, byte[] myAddr) {
+		this.transactID = new byte[]{packet[0], packet[1]};
+		flags = new byte[]{(byte) 0x85, (byte) 0x80};
+		questions = new byte[]{0x00, 0x00};
+		answerRRs = new byte[]{0x00, 0x01};
+		authorityRRs = new byte[]{0x00, 0x00};
+		additionalRRs = new byte[]{0x00, 0x00};
+		byte[] nameBytes = new byte[32]; 
+		System.arraycopy(packet, 13, nameBytes, 0, 32);
+		String name = NMBStringCoder.decodeNBNSName(nameBytes);
+		byte[] query = new byte[50];
+		System.arraycopy(packet, 12, query, 0, 38);
+		// time to live
+		query[38] = 0x00;
+		query[39] = 0x00;
+		query[40] = 0x02;
+		query[41] = 0x58;
+		// data length
+		query[42] = 0x00;
+		query[43] = 0x06;
+		// name flags
+		query[44] = (byte) 0x80;
+		query[45] = 0x00;
+		// addr
+		query[46] = myAddr[0];
+		query[47] = myAddr[1];
+		query[48] = myAddr[2];
+		query[49] = myAddr[3];
+		payload = query;
+	}
+	
+	/**
+	 * Builds the payload for the packet.
+	 * @return payload.
+	 */
 	private byte[] getPayload() {
 		byte[] payload = NMBStringCoder.wrapNBNSName(this.name, service);
 		byte[] type = {0x00, 0x20};
 		byte[] nbnsclass = {0x00, 0x01};
 		return HelperUtils.concat(payload, type, nbnsclass);
 	}
-		
-	private void addressToBytes(String addrString) {
-		String[] addrParts = addrString.split("\\.");
-		addr = new byte[4];
-		addr[0] = (byte)Integer.parseInt(addrParts[0]);
-		addr[1] = (byte)Integer.parseInt(addrParts[1]);
-		addr[2] = (byte)Integer.parseInt(addrParts[2]);
-		addr[3] = (byte)Integer.parseInt(addrParts[3]);
-	}
-	
-	public static byte[] getServiceBytes(int service) {
-		switch (service) {
-		case NBNSService.SERVER:
-			return new byte[]{0x43, 0x41};
-		case NBNSService.MESSENGER:
-			return new byte[]{0x41, 0x44};
-		case NBNSService.WORKSTATION:
-			return new byte[]{0x41, 0x41};
-		case NBNSService.BROWSER_ELECTION:
-			return new byte[]{0x42, 0x4f};
-		case NBNSService.LOCAL_MASTER_BROWSER:
-			return new byte[]{0x42, 0x4e};
-		default:
-			return new byte[]{0x43, 0x41};
-		}
-	}
 
+	/**
+	 * Builds the additional records field.
+	 * @return additional records.
+	 */
 	private byte[] getAdditionalRecords() {
 		byte[] name = {(byte) 0xc0, 0x0c};
 		byte[] type = {0x00, 0x20};
@@ -148,43 +148,58 @@ public class NBNS {
 		return HelperUtils.concat(name, type, nbnsclass, timeToLive, length, nameFlags, addr);
 	}
 	
+	/**
+	 * Returns the next packet.
+	 * Use only after the name, type and service were set.
+	 * @return next packet.
+	 */
 	public byte[] getNextPacket() {
 		preparePacket();
-		transactID[1] += 0x01;
+		return getBytes();
+	}
+	
+	/**
+	 * Returns the next response packet.
+	 * @param packet request packet.
+	 * @param myAddr your current ip in bytes.
+	 * @return next response packet.
+	 */
+	public byte[] getNextResponse(byte[] packet, byte[] myAddr) {
+		prepareResponsePacket(packet, myAddr);
 		return getBytes();
 	}
 
-	public byte[] getBytes() {
+	/**
+	 * Returns the content of the packet in bytes.
+	 * @return packet content.
+	 */
+	private byte[] getBytes() {
 		return HelperUtils.concat(transactID, flags, questions, answerRRs, authorityRRs, additionalRRs, payload, additional);
 	}
 
+	/**
+	 * Set the name for the payload.
+	 * @param name.
+	 */
 	public void setName(String name) {
 		this.name = name.getBytes();
 		this.name = NMBStringCoder.encodeNBNSName(this.name);
 	}
 
+	/**
+	 * Set the NBNSType.
+	 * @param type NBNSType.
+	 */
 	public void setType(int type) {
 		this.type = type;
 	}
 
+	/**
+	 * Set the NBNSService.
+	 * @param service NBNSService.
+	 */
 	public void setService(int service) {
 		this.service = service;
 	}
 
-	public byte[] getAndIncTransactID() {
-		byte[] response = new byte[2];
-		response[0] = transactID[0];
-		response[1] = transactID[1];
-		transactID[1] += 0x01;
-		return response;
-	}
-
-	public byte[] getAddr() {
-		return addr;
-	}
-
-	public byte[] getName() {
-		return name;
-	}
-	
 }

+ 27 - 0
src/de/tudarmstadt/informatik/hostage/protocol/smbutils/NBNSService.java

@@ -1,10 +1,37 @@
 package de.tudarmstadt.informatik.hostage.protocol.smbutils;
 
+/**
+ * NetBios Name Service services.
+ * @author Wulf Pfeiffer.
+ */
 public class NBNSService {
+
 	public static final int SERVER = 0;
 	public static final int MESSENGER = 1;
 	public static final int WORKSTATION = 2;
 	public static final int BROWSER_ELECTION = 3;
 	public static final int LOCAL_MASTER_BROWSER = 4;
 	public static final int BROWSER = 5;
+
+	/**
+	 * Returns the proper bytes that are used in the wrapping of netbios names for the NBNSService.
+	 * @param service NBNSService.
+	 * @return bytes.
+	 */
+	public static byte[] getServiceBytes(int service) {
+		switch (service) {
+		case NBNSService.SERVER:
+			return new byte[]{0x43, 0x41};
+		case NBNSService.MESSENGER:
+			return new byte[]{0x41, 0x44};
+		case NBNSService.WORKSTATION:
+			return new byte[]{0x41, 0x41};
+		case NBNSService.BROWSER_ELECTION:
+			return new byte[]{0x42, 0x4f};
+		case NBNSService.LOCAL_MASTER_BROWSER:
+			return new byte[]{0x42, 0x4e};
+		default:
+			return new byte[]{0x43, 0x41};
+		}
+	}
 }

+ 6 - 0
src/de/tudarmstadt/informatik/hostage/protocol/smbutils/NBNSType.java

@@ -1,8 +1,14 @@
 package de.tudarmstadt.informatik.hostage.protocol.smbutils;
 
+/**
+ * NetBios Name Service types.
+ * @author Wulf Pfeiffer.
+ */
 public class NBNSType {
+
 	public static final int REGISTRATION_UNIQUE = 0;
 	public static final int REGISTRATION_GROUP = 1;
 	public static final int NAME_QUERY = 2;
 	public static final int REGISTRATION_MSBROWSE = 3;
+
 }

+ 69 - 0
src/de/tudarmstadt/informatik/hostage/protocol/smbutils/NBSS.java

@@ -0,0 +1,69 @@
+package de.tudarmstadt.informatik.hostage.protocol.smbutils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.List;
+
+import de.tudarmstadt.informatik.hostage.nio.Reader;
+import de.tudarmstadt.informatik.hostage.nio.Writer;
+import de.tudarmstadt.informatik.hostage.protocol.Protocol.TALK_FIRST;
+import de.tudarmstadt.informatik.hostage.protocol.SMB;
+import de.tudarmstadt.informatik.hostage.wrapper.Packet;
+
+/**
+ * NetBIOS Session Service.
+ * @author Wulf Pfeiffer
+ */
+public class NBSS extends Thread {
+	
+	private int nbssPort;
+	private ServerSocket nbssServer;
+	private Socket nbssSocket;
+	private Reader reader;
+	private Writer writer;
+	private SMB smb;
+	
+	@Override
+	public void run() {
+		try {
+			nbssPort = 139;
+			nbssServer = new ServerSocket(nbssPort);
+			nbssSocket = nbssServer.accept();
+			smb = new SMB();
+			talkToClient(nbssSocket.getInputStream(), nbssSocket.getOutputStream());
+			
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+	
+	/**
+	 * Used for communicating with a client.
+	 * @param in
+	 * @param out
+	 * @throws IOException
+	 */
+	private void talkToClient(InputStream in, OutputStream out) throws IOException {
+		reader = new Reader(in, smb.toString());
+		writer = new Writer(out);
+		Packet inputLine;
+		List<Packet> outputLine;
+		if (smb.whoTalksFirst() == TALK_FIRST.SERVER) {
+			outputLine = smb.processMessage(null);
+			writer.write(outputLine);
+		}
+		while (!isInterrupted() && (inputLine = reader.read()) != null) {
+			outputLine = smb.processMessage(inputLine);
+			if (outputLine != null) {
+				writer.write(outputLine);
+			}
+			if (smb.isClosed()) {
+				break;
+			}
+		}
+	}
+	
+}

+ 177 - 77
src/de/tudarmstadt/informatik/hostage/protocol/smbutils/NMB.java

@@ -4,11 +4,17 @@ import java.io.IOException;
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 import java.net.InetAddress;
+import java.net.SocketException;
 import java.net.SocketTimeoutException;
 import java.net.UnknownHostException;
 
-import de.tudarmstadt.informatik.hostage.net.MyDatagramSocketFactory;
+import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
 
+/**
+ * NetBIOS.
+ * Used to registrate computers and workgroups in a windows network.
+ * @author Wulf Pfeiffer
+ */
 public class NMB extends Thread {
 	
 	private DatagramSocket nbnsSocket;
@@ -23,23 +29,46 @@ public class NMB extends Thread {
 	private String workgroup;
 	private NBNS nbns;
 	private NBDS nbds;
-	private volatile boolean smbRunning;
-	private Receiver receiver;
+	private boolean isMaster;
+	private byte[] addr = new byte[4]; 
+	private static byte[] transactID = HelperUtils.randomBytes(2);
 	
 	public NMB(String ip, String username, String workgroup) {
 		try {
-			smbRunning = true;
+			isMaster = false;
 			this.username = username;
 			this.workgroup = workgroup;
 			this.ip = ip;
 			ipParts = ip.split("\\.");
 			String newHostAddr = ipParts[0] + "." + ipParts[1] + "." + ipParts[2] + ".255";
 			dst = InetAddress.getByName(newHostAddr);
+			addr = addressToBytes(ip);
+			nbns = new NBNS(addr);
+			nbds = new NBDS(addr, username, workgroup);
 		} catch (UnknownHostException e) {
 			e.printStackTrace();
 		}
 	}
 	
+	/**
+	 * Converts an ip address string into a byte array of length 4.
+	 * @param addrString ip address.
+	 * @return 4 byte ip address.
+	 */
+	private byte[] addressToBytes(String addrString) {
+		String[] addrParts = addrString.split("\\.");
+		byte[] newAddr = new byte[4];
+		newAddr[0] = (byte)Integer.parseInt(addrParts[0]);
+		newAddr[1] = (byte)Integer.parseInt(addrParts[1]);
+		newAddr[2] = (byte)Integer.parseInt(addrParts[2]);
+		newAddr[3] = (byte)Integer.parseInt(addrParts[3]);
+		return newAddr;
+	}
+	
+	/**
+	 * Sends a NBNS packet.
+	 * @param nbns packet.
+	 */
 	private void sendPacket(NBNS nbns) {
 		try {
 			byte[] packetBytes = nbns.getNextPacket();
@@ -50,9 +79,13 @@ public class NMB extends Thread {
 		}
 	}
 	
+	/**
+	 * Sends a NBDS packet.
+	 * @param nbds packet.
+	 */
 	private void sendPacket(NBDS nbds) {
 		try {
-			byte[] packetBytes = nbds.getBytes();
+			byte[] packetBytes = nbds.getNextPacket();
 			packet = new DatagramPacket(packetBytes, packetBytes.length, dst, nbdsPort);
 			nbdsSocket.send(packet);
 		} catch (IOException e) {
@@ -60,13 +93,21 @@ public class NMB extends Thread {
 		}
 	}
 	
+	/**
+	 * Sends the required packets for user and workgroup registration.
+	 */
 	private void registrate() {
 		registrateUser();
 		registrateGroup();
 	}
 	
+	/**
+	 * Sends the required packets for user registration.
+	 */
 	private void registrateUser() {
-		nbns = new NBNS(new byte[]{0x50, 0x00}, NBNSType.REGISTRATION_UNIQUE, NBNSService.SERVER, username, ip);
+		nbns.setType(NBNSType.REGISTRATION_UNIQUE);
+		nbns.setService(NBNSService.SERVER);
+		nbns.setName(username);
 		sendPacket(nbns);
 		
 		nbns.setService(NBNSService.MESSENGER);
@@ -76,6 +117,9 @@ public class NMB extends Thread {
 		sendPacket(nbns);
 	}
 	
+	/**
+	 * Sends the required packets for workgroup registration.
+	 */
 	private void registrateGroup() {
 		nbns.setName(workgroup);
 		nbns.setType(NBNSType.REGISTRATION_GROUP);
@@ -85,11 +129,17 @@ public class NMB extends Thread {
 		sendPacket(nbns);
 	}
 	
+	/*
+	 * Sends the browser election request.
+	 */
 	private void browserElection() {
-		nbds = new NBDS(nbns.getAndIncTransactID(), nbns.getAddr(), username, workgroup, NBDSType.BROWSER);
+		nbds.setNbdstype(NBDSType.BROWSER);
 		sendPacket(nbds);
 	}
 	
+	/**
+	 * Sends the required packets for MSBROWSE registration.
+	 */
 	private void registrateMsBrowse() {
 		nbns.setName("__MSBROWSE__");
 		nbns.setType(NBNSType.REGISTRATION_MSBROWSE);
@@ -97,6 +147,9 @@ public class NMB extends Thread {
 		sendPacket(nbns);
 	}
 	
+	/**
+	 * Sends the required packets for local master registration.
+	 */
 	private void registrateLocalMaster() {
 		nbns.setName(workgroup);
 		nbns.setType(NBNSType.REGISTRATION_UNIQUE);
@@ -104,122 +157,169 @@ public class NMB extends Thread {
 		sendPacket(nbns);
 	}
 	
+	/**
+	 * Sends the required packets for host announcement with services.
+	 */
 	private void announceHost() {
-		nbds = new NBDS(nbns.getAndIncTransactID(), nbns.getAddr(), username, workgroup, NBDSType.HOST_ANNOUNCEMENT_WITH_SERVICES);
+		nbds.setNbdstype(NBDSType.HOST_ANNOUNCEMENT_WITH_SERVICES);
 		sendPacket(nbds);
 	}
 	
+	/**
+	 * Sends the required packets for a name query.
+	 */
 	private void queryName() {
 		nbns.setType(NBNSType.NAME_QUERY);
 		nbns.setService(NBNSService.LOCAL_MASTER_BROWSER);
 		sendPacket(nbns);
 	}
 	
+	/**
+	 * Sends the required packets for a request announcement
+	 */
 	private void requestAnnouncement() {
-		nbds = new NBDS(nbns.getAndIncTransactID(), nbns.getAddr(), username, workgroup, NBDSType.REQUEST_ANNOUNCEMENT);
+		nbds.setNbdstype(NBDSType.REQUEST_ANNOUNCEMENT);
 		sendPacket(nbds);
 	}
 	
+	/**
+	 * Sends the required packets for a local master announcement to all.
+	 */
 	private void localMasterAnnouncementAll() {
-		nbds = new NBDS(nbns.getAndIncTransactID(), nbns.getAddr(), username, workgroup, NBDSType.LOCAL_MASTER_ANNOUNCEMENT_ALL);
+		nbds.setNbdstype(NBDSType.LOCAL_MASTER_ANNOUNCEMENT_ALL);
 		sendPacket(nbds);
 	}
 	
+	/**
+	 * Sends the required packets for a domain announcement.
+	 */
 	private void domainAnnouncement() {
-		nbds = new NBDS(nbns.getAndIncTransactID(), nbns.getAddr(), username, workgroup, NBDSType.DOMAIN_ANNOUNCEMENT);
+		nbds.setNbdstype(NBDSType.DOMAIN_ANNOUNCEMENT);
 		sendPacket(nbds);
 	}
 	
+	/**
+	 * Sends the required packets for a local master announcement.
+	 */
 	private void localMasterAnnouncement() {
-		nbds = new NBDS(nbns.getAndIncTransactID(), nbns.getAddr(), username, workgroup, NBDSType.LOCAL_MASTER_ANNOUNCEMENT);
+		nbds.setNbdstype(NBDSType.LOCAL_MASTER_ANNOUNCEMENT);
 		sendPacket(nbds);
 	}
 
 	@Override
-	public void run() {		
+	public void run() {
+		NBSS nbss = new NBSS();
+		nbss.start();
 		try {
-			nbnsSocket = new MyDatagramSocketFactory().createDatagramSocket(nbnsPort);
-			nbnsSocket.connect(dst, nbnsPort);
-			nbdsSocket = new MyDatagramSocketFactory().createDatagramSocket(nbdsPort);
-			nbdsSocket.connect(dst, nbdsPort);
-		} catch (IOException e) {
+			nbnsSocket = new DatagramSocket(nbnsPort);
+			nbdsSocket = new DatagramSocket(nbdsPort);
+		} catch (SocketException e) {
 			e.printStackTrace();
 		}
 		
 		registrate();
-		receiver = new Receiver();
-		receiver.start();
 		announceHost();
 		queryName();
+		checkForAnswers();
 		
-		registrate();
-		queryName();
-		
-		registrate();
-		queryName();
-		
-		registrate();
-		queryName();	
-		
-		browserElection();
-		browserElection();
-		browserElection();
-		browserElection();
-		
-		registrateMsBrowse();
-		registrateMsBrowse();
-		registrateMsBrowse();
-		registrateMsBrowse();
-		
-		registrateLocalMaster();
-		registrateLocalMaster();
-		registrateLocalMaster();
-		registrateLocalMaster();
-		
-		requestAnnouncement();
-		localMasterAnnouncementAll();
-		domainAnnouncement();
-		
-//		// domain/workgroup announcement
-//		// local master announcmen
+		if (isMaster) {
+			registrate();
+			queryName();
+			
+			registrate();
+			queryName();
+			
+			registrate();
+			queryName();	
+			
+			browserElection();
+			browserElection();
+			browserElection();
+			browserElection();
+			
+			registrateMsBrowse();
+			registrateMsBrowse();
+			registrateMsBrowse();
+			registrateMsBrowse();
+			
+			registrateLocalMaster();
+			registrateLocalMaster();
+			registrateLocalMaster();
+			registrateLocalMaster();
+			
+			requestAnnouncement();
+			localMasterAnnouncementAll();
+			domainAnnouncement();
+			localMasterAnnouncement();
+		}
 		
 		announceHost();	
 		
+//		talk();
+		
 		nbnsSocket.close();
 		nbdsSocket.close();
 	}
+		
+	private byte[] buffer = new byte[2048];
+	private boolean masterAnswered = false;
+	private DatagramPacket receive = new DatagramPacket(buffer, buffer.length);
 
-	public synchronized void setSmbRunning(boolean smbRunning) {
-		this.smbRunning = smbRunning;
+	/**
+	 * Check if the specified workgroup is already existing.
+	 * If someone answers on your register messages there is already a master.
+	 */
+	private void checkForAnswers() {
+		try {
+			nbnsSocket.setSoTimeout(1000);
+			try {
+				while (!masterAnswered) {
+					nbnsSocket.receive(receive);					
+					if (!(receive.getAddress().toString().equals("/"+ip))) {
+						masterAnswered = true;
+						isMaster = false;
+					}
+					
+				}
+			} catch (SocketTimeoutException e) {
+				isMaster = true;
+				e.printStackTrace();
+			}
+		} catch (IOException e) {
+			isMaster = true;
+			e.printStackTrace();
+		}
+	}	
+
+	/**
+	 * Returns the current transactID and increases it by one.
+	 * @return transactID.
+	 */
+	public static byte[] getAndIncTransactID() {
+		transactID[1]++;
+		if (transactID[1] == 0x00) {
+			transactID[0]++;
+		}
+		return transactID;
 	}
 	
-	private class Receiver extends Thread {
-		
-		private DatagramPacket packet;
-		private byte[] buffer;
-		private boolean masterAnswered = false;
-		
-		public Receiver() {
-			buffer = new byte[2048];
-			packet = new DatagramPacket(buffer, buffer.length);
+	/**
+	 * Handling requests after initial registration
+	 */
+	private void talk() {
+		try {
+			nbnsSocket.setSoTimeout(0);
+		} catch (SocketException e) {
+			e.printStackTrace();
 		}
-		
-		@Override
-		public void run() {
+		DatagramPacket request = new DatagramPacket(buffer, buffer.length);
+		DatagramPacket response = new DatagramPacket(buffer, buffer.length);
+		while (true) {
 			try {
-				nbnsSocket.setSoTimeout(1000);
-				try {
-					while (!masterAnswered) {
-						nbnsSocket.receive(packet);
-						if (!(packet.getAddress().toString().equals("/"+ip))) {
-							masterAnswered = true;
-							setSmbRunning(false);
-						}
-					}
-				} catch (SocketTimeoutException e) {
-					setSmbRunning(false);
-					e.printStackTrace();
-				}	
+				nbnsSocket.receive(request);
+				byte[] resp = nbns.getNextResponse(request.getData(), addressToBytes(ip));
+				response = new DatagramPacket(resp, resp.length, request.getAddress(), nbnsPort);
+				nbnsSocket.send(response);
 			} catch (IOException e) {
 				e.printStackTrace();
 			}

+ 37 - 17
src/de/tudarmstadt/informatik/hostage/protocol/smbutils/NMBStringCoder.java

@@ -2,31 +2,44 @@ package de.tudarmstadt.informatik.hostage.protocol.smbutils;
 
 import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
 
-
+/**
+ * Used to encode and decode a String into a byte array so that they can be used in NetBIOS.
+ * @author Wulf Pfeiffer
+ */
 public class NMBStringCoder {
 
+	/**
+	 * Decodes a netbios name as byte array to its proper String value.
+	 * @param name bytes.
+	 * @return String.
+	 */
 	public static String decodeNBNSName(byte[] name) {
 		byte a_ascii = (byte) 'A';
 		byte[] reducedA = new byte[name.length];
 		for (int i = 0; i < name.length; i++) {
-			reducedA[i] = (byte)(name[i] - a_ascii);
+			reducedA[i] = (byte) (name[i] - a_ascii);
 		}
 		byte[] converted = new byte[reducedA.length / 2];
-		for (int i = 0, j = 0; i < name.length && j < converted.length; i+=2, j++) {
-			byte b1 = (byte) (reducedA[i]<<4);
-			byte b2 = reducedA[i+1];
+		for (int i = 0, j = 0; i < name.length && j < converted.length; i += 2, j++) {
+			byte b1 = (byte) (reducedA[i] << 4);
+			byte b2 = reducedA[i + 1];
 			converted[j] = (byte) (b1 | b2);
 		}
 		return new String(converted);
 	}
-	
+
+	/**
+	 * Encodes a String into its netbios name as byte array.
+	 * @param name.
+	 * @return netbios name.
+	 */
 	public static byte[] encodeNBNSName(byte[] name) {
 		byte a_ascii = (byte) 'A';
 		byte[] bytes = name;
 		byte[] converted = new byte[bytes.length * 2];
-		for (int i = 0, j = 0; i < bytes.length && j < converted.length; i++, j+=2) {
-			converted[j] = (byte)(bytes[i]>>4);
-			converted[j+1] = (byte)(bytes[i] & 0x0F);
+		for (int i = 0, j = 0; i < bytes.length && j < converted.length; i++, j += 2) {
+			converted[j] = (byte) (bytes[i] >> 4);
+			converted[j + 1] = (byte) (bytes[i] & 0x0F);
 		}
 		byte[] addedA = new byte[converted.length];
 		for (int i = 0; i < converted.length; i++) {
@@ -34,25 +47,32 @@ public class NMBStringCoder {
 		}
 		return addedA;
 	}
-	
+
+	/**
+	 * Wraps a NetBIOS name with the required start and end bytes and some more informations.
+	 * @param name netbios name.
+	 * @param service NBNDSService.
+	 * @return wrapped content.
+	 */
 	public static byte[] wrapNBNSName(byte[] name, int service) {
-		byte[] nameStart = {0x20};
+		byte[] nameStart = { 0x20 };
 		byte[] namePadding = null;
 		if (name.length < 32) {
 			int paddingLen = 32 - name.length;
 			namePadding = new byte[paddingLen];
-			for (int i = 0; i < namePadding.length; i+=2) {
-				if (i == namePadding.length-2) {
-					byte[] serviceBytes = NBNS.getServiceBytes(service);
+			for (int i = 0; i < namePadding.length; i += 2) {
+				if (i == namePadding.length - 2) {
+					byte[] serviceBytes = NBNSService.getServiceBytes(service);
 					namePadding[i] = serviceBytes[0];
-					namePadding[i+1] = serviceBytes[1];
+					namePadding[i + 1] = serviceBytes[1];
 				} else {
 					namePadding[i] = 0x43;
-					namePadding[i+1] = 0x041;
+					namePadding[i + 1] = 0x041;
 				}
 			}
 		}
-		byte[] nameEnd = {0x00};
+		byte[] nameEnd = { 0x00 };
 		return HelperUtils.concat(nameStart, name, namePadding, nameEnd);
 	}
+
 }

+ 24 - 18
src/de/tudarmstadt/informatik/hostage/protocol/smbutils/SMBPacket.java

@@ -5,8 +5,6 @@ import java.util.Calendar;
 import java.util.GregorianCalendar;
 import java.util.TimeZone;
 
-import javax.net.ssl.HostnameVerifier;
-
 import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
 
 /**
@@ -17,8 +15,7 @@ import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
 public class SMBPacket {
 	
 	private String[] serverVersion;
-	private static byte[] serverName = HelperUtils.fillWithZero(HelperUtils
-			.getRandomString(16, true).getBytes());
+	private static byte[] serverName;
 	private byte[] message = null;
 	private static final byte[] serverGUID = HelperUtils.randomBytes(16);
 	private boolean authenticateNext = false;
@@ -38,14 +35,16 @@ public class SMBPacket {
 	private byte[] multiplexID = new byte[2];
 	
 	//special nbds stuff
-	private byte[] workgroup;
+	private static byte[] workgroup;
 	private int type;
 	
-	public SMBPacket(String[] serverVersion) {
+	public SMBPacket(String[] serverVersion, String serverName, String workgroup) {
 		this.serverVersion = serverVersion;
+		SMBPacket.serverName = serverName.getBytes();
+		SMBPacket.workgroup = workgroup.getBytes();
 	}
 	
-	public void prepareNextResponse(int type, String serverName, String workgroup) {
+	public void prepareNextResponse(int type) {
 		serverComp = new byte[] { (byte) 0xff, 0x53, 0x4d, 0x42 };
 		smbCommand = new byte[] { 0x25 };
 		ntStat = new byte[] { 0x00, 0x00, 0x00, 0x00 };
@@ -59,9 +58,7 @@ public class SMBPacket {
 		processID = new byte[] { 0x00, 0x00 };
 		userID = new byte[] { 0x00, 0x00 };
 		multiplexID = new byte[] { 0x00, 0x00 };
-		this.workgroup = workgroup.getBytes();
 		this.type = type;
-		SMBPacket.serverName = serverName.getBytes();
 	}
 	
 	public void prepareNextResponse(byte[] message) {
@@ -449,7 +446,7 @@ public class SMBPacket {
 		if (transSub[0] == (byte) 0xff) { // for NMB in host announcement, NOT smb protocol
 			byte[] wordCount = { 0x11 };
 			byte[] totalParamCount = { 0x00, 0x00 };
-			byte[] totalDataCount = new byte[2]; //TODO
+			byte[] totalDataCount = new byte[2];
 			byte[] maxParamCount = { 0x00, 0x00 };
 			byte[] maxDataCount = { 0x00, 0x00 };
 			byte[] maxSetupCount = { 0x00 };
@@ -459,7 +456,7 @@ public class SMBPacket {
 			byte[] reserved2 = { 0x00, 0x00 };
 			byte[] paramCount = { 0x00, 0x00 };
 			byte[] paramOffset = { 0x00, 0x00 };
-			byte[] dataCount = new byte[2]; //TODO
+			byte[] dataCount = new byte[2];
 			byte[] dataOffset = { 0x56, 0x00 };
 			byte[] setupCount = { 0x03 };
 			byte[] reserved3 = { 0x00 };
@@ -468,20 +465,19 @@ public class SMBPacket {
 			byte[] opcode = new byte[]{0x01, 0x00};
 			byte[] priority = new byte[]{0x01, 0x00};
 			byte[] smbclass = new byte[]{0x02, 0x00};
-			byte[] size = new byte[2]; //TODO
+			byte[] size = new byte[2];
 			byte[] name = HelperUtils.concat("\\MAILSLOT\\BROWSE".getBytes(), new byte[]{0x00}); 
 			
 			byte[] windowsBrowser = null;
-			if (type == NBDSType.HOST_ANNOUNCEMENT_WITH_SERVICES || type == NBDSType.HOST_ANNOUNCEMENT
-					|| type == NBDSType.LOCAL_MASTER_ANNOUNCEMENT_ALL || type == NBDSType.DOMAIN_ANNOUNCEMENT) {
-				windowsBrowser = getAnnouncement();
-			} else if (type == NBDSType.BROWSER) {
+			if (type == NBDSType.BROWSER) {
 				windowsBrowser = getBrowser();
 			} else if (type == NBDSType.REQUEST_ANNOUNCEMENT) {
 				byte[] command = {0x02};
 				byte[] unusedFlags = {0x01, 0x00};
 				byte[] responseCompName = serverName;
 				windowsBrowser = HelperUtils.concat(command, unusedFlags, responseCompName);
+			} else {
+				windowsBrowser = getAnnouncement();
 			}
 
 			byte[] buffer = ByteBuffer.allocate(4).putInt(windowsBrowser.length).array();
@@ -629,10 +625,14 @@ public class SMBPacket {
 		return transSub;
 	}
 	
+	/**
+	 * For NBNS only.
+	 * @return announcement packet.
+	 */
 	private byte[] getAnnouncement() {
 		//Microsoft Windows Browser
 		byte[] command = null;
-		if(type == NBDSType.LOCAL_MASTER_ANNOUNCEMENT_ALL) {
+		if(type == NBDSType.LOCAL_MASTER_ANNOUNCEMENT_ALL || type == NBDSType.LOCAL_MASTER_ANNOUNCEMENT) {
 			command = new byte[]{0x0f};
 		} else if (type == NBDSType.DOMAIN_ANNOUNCEMENT) {
 			command = new byte[]{0x0c};
@@ -647,6 +647,8 @@ public class SMBPacket {
 			updatePeriodicity = new byte[]{0x00, 0x00, 0x00, 0x00};
 		} else if (type == NBDSType.LOCAL_MASTER_ANNOUNCEMENT_ALL || type == NBDSType.DOMAIN_ANNOUNCEMENT) {
 			updatePeriodicity = new byte[]{(byte) 0xc0, (byte) 0xd4, 0x01, 0x00};
+		} else if (type == NBDSType.LOCAL_MASTER_ANNOUNCEMENT) {
+			updatePeriodicity = new byte[]{0x00, 0x00, 0x00, 0x00};
 		}
 		byte[] hostName = null;
 		if (type == NBDSType.DOMAIN_ANNOUNCEMENT) {
@@ -662,7 +664,7 @@ public class SMBPacket {
 		byte[] serverType = null;
 		if (type == NBDSType.HOST_ANNOUNCEMENT_WITH_SERVICES || type == NBDSType.LOCAL_MASTER_ANNOUNCEMENT_ALL) {
 			serverType = new byte[]{0x03, (byte) 0x9a, (byte) 0x81, 0x00};
-		} else if (type == NBDSType.HOST_ANNOUNCEMENT) {
+		} else if (type == NBDSType.HOST_ANNOUNCEMENT || type == NBDSType.LOCAL_MASTER_ANNOUNCEMENT) {
 			serverType = new byte[]{0x00, 0x00, 0x00, 0x00};
 		} else if (type == NBDSType.DOMAIN_ANNOUNCEMENT) {
 			serverType = new byte[]{0x00, 0x10, 0x00, (byte) 0x80};
@@ -682,6 +684,10 @@ public class SMBPacket {
 				signature, hostComment);
 	}
 	
+	/**
+	 * For NBNS only.
+	 * @return MicrosoftBrowser part in NetBIOS packets.
+	 */
 	private byte[] getBrowser() {
 		byte[] command = {0x08};
 		byte[] electionVersion = {0x01};

+ 18 - 0
src/de/tudarmstadt/informatik/hostage/sync/SyncMessage.java

@@ -2,6 +2,10 @@ package de.tudarmstadt.informatik.hostage.sync;
 
 import java.io.Serializable;
 
+/**
+ * Message class for synchronization between devices.
+ * @author Lars Pandikow
+ */
 public class SyncMessage implements Serializable{
 	
 
@@ -20,20 +24,34 @@ public class SyncMessage implements Serializable{
 		this.payload = payload;
 	}
 
+	/**
+	 * @return the message_code
+	 */
 	public int getMessage_code() {
 		return message_code;
 	}
 
+	/**
+	 * @param message_code the message_code to set
+	 */
 	public void setMessage_code(int message_code) {
 		this.message_code = message_code;
 	}
 
+	/**
+	 * @return the payload
+	 */
 	public Object getPayload() {
 		return payload;
 	}
 
+	/**
+	 * @param payload the payload to set
+	 */
 	public void setPayload(Object payload) {
 		this.payload = payload;
 	}
 
+
+
 }

+ 35 - 4
src/de/tudarmstadt/informatik/hostage/sync/bluetooth/BluetoothSync.java → src/de/tudarmstadt/informatik/hostage/sync/bluetooth/BluetoothSyncActivity.java

@@ -23,7 +23,13 @@ import android.widget.TextView;
 import android.widget.AdapterView.OnItemClickListener;
 import de.tudarmstadt.informatik.hostage.R;
 
-public class BluetoothSync extends Activity{	
+/**
+ * Activity that allows the user to choose a bluetooth device to 
+ * synchronize with and informs about the status of the synchronization.
+ *
+ * @author Lars Pandikow
+ */
+public class BluetoothSyncActivity extends Activity{	
 	
 	public static final int CONNECTING = 0x0;
     public static final int CONNECTION_ESTABLISHED = 0x1;
@@ -89,6 +95,9 @@ public class BluetoothSync extends Activity{
 		}
 	}
 	
+	/**
+	 * Starts discorvry of bluetooth devices.
+	 */
 	private void chooseDevice(){
 		arrayAdapter.clear();
 		if (!mBluetoothAdapter.startDiscovery())
@@ -98,6 +107,10 @@ public class BluetoothSync extends Activity{
 		setContentView(layout);
 	}
 
+	/**
+	 * Start a ServerThread to listen for incomming connections
+	 * @see ServerThread
+	 */
 	private void startConnectionListener() {
 		Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
 		discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
@@ -107,7 +120,11 @@ public class BluetoothSync extends Activity{
 		serverThread.start();
 	}
 		
-
+	/**
+	 * Called when a connection has been established.
+	 * Starts a {@link CommunicationThread} for communication.
+	 * @param socket The socket of the connection.
+	 */
 	protected void manageConnectedSocket(BluetoothSocket socket) {
 		mBluetoothAdapter.cancelDiscovery();
 		unregisterBroadcastReceiver();
@@ -120,7 +137,9 @@ public class BluetoothSync extends Activity{
 		commThread.start();
 	}
 
-	// Create a BroadcastReceiver for ACTION_FOUND
+	/**
+	 * BroadcastReciever listens for state changes of bluetooth and discovery of new devices.
+	 */
 	private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
 		@Override
 		public void onReceive(Context context, Intent intent) {
@@ -149,7 +168,9 @@ public class BluetoothSync extends Activity{
 	private boolean mRecieverRegistered = false;
 
 
-	// Register the BroadcastReceiver
+	/**
+	 *  Register the BroadcastReceiver
+	 */
 	private void registerBroadcastReceiver() {
 		IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
 		filter.addAction(BluetoothAdapter. ACTION_STATE_CHANGED);
@@ -157,11 +178,18 @@ public class BluetoothSync extends Activity{
 		mRecieverRegistered = true;
 	}
 	
+	/**
+	 *  Unregister the BroadcastReceiver
+	 */
 	private void unregisterBroadcastReceiver(){
 		unregisterReceiver(mReceiver);
 		mRecieverRegistered = false;
 	}
 	
+	/**
+	 * Creates the list of bluetooth devices. 
+	 * Starts a {@link ClientThread} to establish connection when a device is clicked.
+	 */
 	private void setLayoutElement(){
 		mInfoText = (TextView) findViewById(R.id.bluetoothInfoText);
 		layout = (LinearLayout) findViewById(R.id.bluetoothLayout);
@@ -180,6 +208,9 @@ public class BluetoothSync extends Activity{
 		});		
 	}	
 	
+	/**
+	 * Handles message sent from the background threads and updates UI.
+	 */
 	private Handler mHandler = new Handler() {
 
         @Override

+ 0 - 29
src/de/tudarmstadt/informatik/hostage/sync/bluetooth/BluetoothSyncService.java

@@ -1,29 +0,0 @@
-package de.tudarmstadt.informatik.hostage.sync.bluetooth;
-
-import android.app.IntentService;
-import android.bluetooth.BluetoothAdapter;
-import android.content.Intent;
-
-public class BluetoothSyncService extends IntentService {
-	
-	private ServerThread serverThread;	
-	private ClientThread clientThread;
-	private CommunicationThread commThread;
-	
-	private BluetoothAdapter mBluetoothAdapter;
-	
-	
-	public BluetoothSyncService() {
-		super("BluetoothSyncService");
-		
-	}
-
-	@Override
-	protected void onHandleIntent(Intent intent) {
-		// TODO Auto-generated method stub
-		
-	}
-
-
-	
-}

+ 7 - 3
src/de/tudarmstadt/informatik/hostage/sync/bluetooth/ClientThread.java

@@ -7,6 +7,10 @@ import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothSocket;
 import android.os.Handler;
 
+/**
+ * Thread used to connect to a remote bluetooth device.
+ * @author Lars Pandikow
+ */
 public class ClientThread extends Thread {
 	private final BluetoothSocket socket;
 	private final Handler mHandler;
@@ -15,7 +19,7 @@ public class ClientThread extends Thread {
 		mHandler = handler;
 		BluetoothSocket tmp = null;
 		try {
-			tmp = device.createRfcommSocketToServiceRecord(BluetoothSync.serviceUUID);
+			tmp = device.createRfcommSocketToServiceRecord(BluetoothSyncActivity.serviceUUID);
 		} catch (IOException e) {
 		}
 		socket = tmp;
@@ -34,9 +38,9 @@ public class ClientThread extends Thread {
 
 		try {
 			socket.connect();
-			mHandler.obtainMessage(BluetoothSync.CONNECTION_ESTABLISHED, socket).sendToTarget();
+			mHandler.obtainMessage(BluetoothSyncActivity.CONNECTION_ESTABLISHED, socket).sendToTarget();
 		} catch (IOException connectException) {
-			mHandler.obtainMessage(BluetoothSync.CONNECTION_FAILED).sendToTarget();
+			mHandler.obtainMessage(BluetoothSyncActivity.CONNECTION_FAILED).sendToTarget();
 			// Unable to connect; close the socket and get out
 			try {
 				socket.close();

+ 11 - 7
src/de/tudarmstadt/informatik/hostage/sync/bluetooth/CommunicationThread.java

@@ -19,6 +19,10 @@ import android.content.Context;
 import android.os.Handler;
 import android.util.Log;
 
+/**
+ * CommunicationThread is responsible for the exchange of synchronization messages between devices.
+ * @author Lars Pandikow
+ */
 public class CommunicationThread extends Thread {
 	private final Context context;
 	private final BluetoothSocket mmSocket;
@@ -43,7 +47,7 @@ public class CommunicationThread extends Thread {
 			tmpOut = new ObjectOutputStream(socket.getOutputStream());
 			tmpIn = new ObjectInputStream(socket.getInputStream());
 		} catch (IOException e) {
-			mHandler.obtainMessage(BluetoothSync.CONNECTION_FAILED).sendToTarget();
+			mHandler.obtainMessage(BluetoothSyncActivity.CONNECTION_FAILED).sendToTarget();
 			e.printStackTrace();
 		}
 
@@ -117,24 +121,24 @@ public class CommunicationThread extends Thread {
 			case SyncMessage.SYNC_RESPONSE_NET_INFO:
 				ArrayList<NetworkRecord> netInfo = (ArrayList<NetworkRecord>) message.getPayload();
 				mdbh.updateNetworkInformation(netInfo);	
-				mHandler.obtainMessage(BluetoothSync.SYNC_SUCCESSFUL).sendToTarget();	
+				mHandler.obtainMessage(BluetoothSyncActivity.SYNC_SUCCESSFUL).sendToTarget();	
 				break;			
 			case SyncMessage.SYNC_RESPONSE_SYNC_INFO:
 				ArrayList<SyncInfoRecord> syncInfo_new = (ArrayList<SyncInfoRecord>) message.getPayload();
 				mdbh.updateSyncInfo(syncInfo_new);
 				break;
-			default: 
-				//TODO DEFAULT WITH UNKNOWN MESSAGE CODE;
 		}		
 	}
 	
-	/* Call this from the main activity to send data to the remote device */
+	/**
+	 * Send a message to the remote device.
+	 * @param message The message to send.
+	 */
 	public void write(SyncMessage message) {
 		try {
 			objectOuput.writeObject(message);
-//TODO NACHRICHT SCHICKEN?			mHandler.obtainMessage(BluetoothSync.MESSAGE_SENT).sendToTarget();
 		} catch (IOException e) {
-			mHandler.obtainMessage(BluetoothSync.CONNECTION_FAILED).sendToTarget();
+			mHandler.obtainMessage(BluetoothSyncActivity.CONNECTION_FAILED).sendToTarget();
 			e.printStackTrace();
 		}
 	}

+ 8 - 4
src/de/tudarmstadt/informatik/hostage/sync/bluetooth/ServerThread.java

@@ -7,6 +7,10 @@ import android.bluetooth.BluetoothServerSocket;
 import android.bluetooth.BluetoothSocket;
 import android.os.Handler;
 
+/**
+ * Thread listens for incomming connections.
+ * @author Lars Pandikow
+ */
 public class ServerThread extends Thread {
 	private final BluetoothServerSocket serverSocket;
 	private final Handler mHandler;
@@ -15,9 +19,9 @@ public class ServerThread extends Thread {
 		BluetoothServerSocket tmp = null;
 		mHandler = handler;
 		try {
-			tmp = BluetoothAdapter.getDefaultAdapter().listenUsingRfcommWithServiceRecord(app_name, BluetoothSync.serviceUUID);
+			tmp = BluetoothAdapter.getDefaultAdapter().listenUsingRfcommWithServiceRecord(app_name, BluetoothSyncActivity.serviceUUID);
 		} catch (IOException e) {
-			mHandler.obtainMessage(BluetoothSync.CONNECTION_FAILED).sendToTarget();
+			mHandler.obtainMessage(BluetoothSyncActivity.CONNECTION_FAILED).sendToTarget();
 		}
 		serverSocket = tmp;
 	}
@@ -38,13 +42,13 @@ public class ServerThread extends Thread {
 				socket = serverSocket.accept();
 			} catch (IOException e) {
 				e.printStackTrace();
-				mHandler.obtainMessage(BluetoothSync.CONNECTION_FAILED).sendToTarget();
+				mHandler.obtainMessage(BluetoothSyncActivity.CONNECTION_FAILED).sendToTarget();
 				break;
 			}
 
 			if (socket != null) {
 				// Do work to manage the connection (in a separate thread)
-				mHandler.obtainMessage(BluetoothSync.CONNECTION_ESTABLISHED, socket).sendToTarget();
+				mHandler.obtainMessage(BluetoothSyncActivity.CONNECTION_ESTABLISHED, socket).sendToTarget();
 				try {
 					serverSocket.close();
 				} catch (IOException e) {

+ 55 - 7
src/de/tudarmstadt/informatik/hostage/sync/nfc/NFCSync.java

@@ -22,6 +22,9 @@ import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+
 import android.annotation.TargetApi;
 import android.app.Activity;
 import android.content.Intent;
@@ -41,20 +44,27 @@ import android.widget.TextView;
 import android.widget.Toast;
 import de.tudarmstadt.informatik.hostage.R;
 import de.tudarmstadt.informatik.hostage.logging.NetworkRecord;
+import de.tudarmstadt.informatik.hostage.logging.SyncInfoRecord;
 import de.tudarmstadt.informatik.hostage.persistence.HostageDBOpenHelper;
+import de.tudarmstadt.informatik.hostage.sync.tracing.TracingSyncService;
 
 @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
 public class NFCSync extends Activity implements CreateNdefMessageCallback, OnNdefPushCompleteCallback {
 	NfcAdapter mNfcAdapter;
 	TextView mInfoText;
-	private static final int MESSAGE_SENT = 1;
+	private static final int MESSAGE_SENT = 0x1;
+	private static final int SYNC_SUCCESSFUL = 0x2;
 
 	private final Handler mHandler = new Handler() {
 		@Override
 		public void handleMessage(Message msg) {
 			switch (msg.what) {
 			case MESSAGE_SENT:
-				Toast.makeText(getApplicationContext(), "Message sent!", Toast.LENGTH_LONG).show();
+				mInfoText.setText("Synchronization data sent, wait for data.");
+				Log.i("NFC", "Message sent!");
+				break;
+			case SYNC_SUCCESSFUL:
+				mInfoText.setText("Synchronization successfull!");
 				Log.i("NFC", "Message sent!");
 				break;
 			}
@@ -71,6 +81,8 @@ public class NFCSync extends Activity implements CreateNdefMessageCallback, OnNd
 		mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
 		if (mNfcAdapter == null) {
 			mInfoText.setText("NFC is not available on this device.");
+		} else if(!mNfcAdapter.isEnabled()){
+			mInfoText.setText("Enable Android Beam before synchronizing.");
 		} else {
 			mInfoText.setText("Hold phones together to synchronize.");
 			// Register callback to set NDEF message
@@ -88,12 +100,17 @@ public class NFCSync extends Activity implements CreateNdefMessageCallback, OnNd
 		// Get Networkdata
 		HostageDBOpenHelper dbh = new HostageDBOpenHelper(this);
 		ArrayList<NetworkRecord> localNetworkInformation = dbh.getNetworkInformation();
+		HashMap<String, Long> devices_local = dbh.getSyncDevices();
+		ArrayList<SyncInfoRecord> syncInfo = dbh.getSyncInfo();
+		
 		Log.i("NFC", "Creating Message");
 		NdefMessage msg = null;
 		try {
-			msg = new NdefMessage(NdefRecord.createMime("application/de.tudarmstadt.informatik.hostage", serialize(localNetworkInformation))
+			NdefRecord netData = NdefRecord.createMime("application/de.tudarmstadt.informatik.hostage", serialize(localNetworkInformation));
+			NdefRecord deviceData = NdefRecord.createMime("application/de.tudarmstadt.informatik.hostage", serialize(devices_local));
+			NdefRecord syncData = NdefRecord.createMime("application/de.tudarmstadt.informatik.hostage", serialize(syncInfo));
+			msg = new NdefMessage(netData, deviceData, syncData);
 					
-			);
 		} catch (IOException e) {
 			e.printStackTrace();
 		}
@@ -135,13 +152,44 @@ public class NFCSync extends Activity implements CreateNdefMessageCallback, OnNd
 		// only one message sent during the beam
 		NdefMessage msg = (NdefMessage) rawMsgs[0];
 		// record 0 contains the MIME type, record 1 is the AAR, if present
-		Object object;
+		Object netData;
+		Object deviceData;
+		Object syncData;
 		Log.i("NFC", "Getting Message!");
 		try {
-			object = deserialize(msg.getRecords()[0].getPayload());
-			ArrayList<NetworkRecord> remoteNetworkInformation = (ArrayList<NetworkRecord>) object;
 			HostageDBOpenHelper dbh = new HostageDBOpenHelper(this);
+			netData = deserialize(msg.getRecords()[0].getPayload());
+			deviceData = deserialize(msg.getRecords()[1].getPayload());
+			syncData = deserialize(msg.getRecords()[2].getPayload());
+			ArrayList<NetworkRecord> remoteNetworkInformation = (ArrayList<NetworkRecord>) netData;
+			HashMap<String, Long> devices_remote = (HashMap<String, Long>) deviceData;
+			HashMap<String, Long> devices_local = dbh.getSyncDevices();
+			ArrayList<SyncInfoRecord> syncInfo = (ArrayList<SyncInfoRecord>) syncData;
+			
+			long tracing_timestamp = 0;
+			if(devices_local.containsKey(TracingSyncService.REMOTE_DEVICE))
+				tracing_timestamp = devices_local.get(TracingSyncService.REMOTE_DEVICE);				
+				
+			for(Iterator<String> i = devices_remote.keySet().iterator(); i.hasNext(); ){
+				String key = i.next();
+				if((devices_local.containsKey(key) && devices_local.get(key) >= devices_remote.get(key)) 
+				    || (tracing_timestamp > devices_remote.get(key))){
+					i.remove();
+				}
+			}
+
+			
+			for ( Iterator<SyncInfoRecord> i = syncInfo.iterator(); i.hasNext(); ){
+				SyncInfoRecord info = i.next();
+				if(devices_remote.containsKey(info.getDeviceID())){
+					i.remove();
+				}				    
+			}	
+			
+			dbh.updateSyncDevices(devices_remote);
+			dbh.updateSyncInfo(syncInfo);
 			dbh.updateNetworkInformation(remoteNetworkInformation);
+			mHandler.obtainMessage(SYNC_SUCCESSFUL).sendToTarget();
 		} catch (ClassNotFoundException e) {
 			e.printStackTrace();
 		} catch (IOException e) {

+ 4 - 0
src/de/tudarmstadt/informatik/hostage/sync/tracing/TracingSyncActivity.java

@@ -7,6 +7,10 @@ import android.os.Bundle;
 import android.os.Handler;
 import android.widget.TextView;
 
+/**
+ * Starts a synchronization service and shows the progress of the synchronization.
+ * @author Lars Pandikow
+ */
 public class TracingSyncActivity extends Activity implements TracingSyncResultReciever.Receiver{
 	
 	TextView mInfoText;

+ 4 - 0
src/de/tudarmstadt/informatik/hostage/sync/tracing/TracingSyncResultReciever.java

@@ -4,6 +4,10 @@ import android.os.Bundle;
 import android.os.Handler;
 import android.os.ResultReceiver;
  
+/**
+ * Helper Class to send messages from {@link TracingSyncService} to {@link TracingSyncActivity}.
+ * @author Lars Pandikow
+ */
 public class TracingSyncResultReciever extends ResultReceiver {
     private Receiver mReceiver;
  

+ 89 - 54
src/de/tudarmstadt/informatik/hostage/sync/tracing/TracingSyncService.java

@@ -1,5 +1,11 @@
 package de.tudarmstadt.informatik.hostage.sync.tracing;
 
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.net.HttpURLConnection;
+import java.net.URL;
 import java.security.KeyStore;
 import java.util.ArrayList;
 
@@ -32,25 +38,29 @@ import de.tudarmstadt.informatik.hostage.logging.AttackRecord;
 import de.tudarmstadt.informatik.hostage.net.MySSLSocketFactory;
 import de.tudarmstadt.informatik.hostage.persistence.HostageDBOpenHelper;
 
-public class TracingSyncService extends IntentService{
-	
+/**
+ * Service that synchronizes with a specified remote server.
+ * 
+ * @author Lars Pandikow
+ */
+public class TracingSyncService extends IntentService {
+
 	public static final String REMOTE_DEVICE = "de.tudarmstadt.informatik.hostage.REMOTE_DEVICE";
-	
+
 	public static final String ACTION_START_SYNC = "de.tudarmstadt.informatik.hostage.ACTION_START_SYNC";
 	public static final String EXTRA_RECEIVER = "de.tudarmstadt.informatik.hostage.EXTRA_HANDLER";
-	
+
 	public static final String UPLOAD_SIZE = "de.tudarmstadt.informatik.hostage.UPLOAD_SIZE";
 	public static final String UPLOAD_PROGRESS = "de.tudarmstadt.informatik.hostage.UPLOAD_PROGRESS";
-	
+
 	public static final int RECORD_UPLOADED = 0x00;
 	public static final int SYNC_COMPLETE = 0x01;
-	
-	
+
 	private HttpClient httpClient;
 	private ResultReceiver receiver;
-	
+
 	HostageDBOpenHelper dbh;
-	
+
 	SharedPreferences pref;
 	Editor editor;
 
@@ -58,7 +68,6 @@ public class TracingSyncService extends IntentService{
 		super(TracingSyncService.class.getName());
 
 	}
-	
 
 	@Override
 	public void onCreate() {
@@ -70,8 +79,8 @@ public class TracingSyncService extends IntentService{
 
 	/**
 	 * The IntentService calls this method from the default worker thread with
-	 * the intent that started the service. When this method returns, IntentService
-	 * stops the service, as appropriate.
+	 * the intent that started the service. When this method returns,
+	 * IntentService stops the service, as appropriate.
 	 */
 	@Override
 	protected void onHandleIntent(Intent intent) {
@@ -79,84 +88,115 @@ public class TracingSyncService extends IntentService{
 			final String action = intent.getAction();
 			if (ACTION_START_SYNC.equals(action)) {
 				receiver = intent.getParcelableExtra(EXTRA_RECEIVER);
-				uploadNewRecords();
-				getRemoteData();
-				//TODO add: dbh.clearSyncInfos();
-				if(receiver != null){
+				syncNewRecords();
+				dbh.clearSyncInfos();
+				if (receiver != null) {
 					receiver.send(SYNC_COMPLETE, null);
 				}
 			}
 
-		}	
-	}	
-	
-	
+		}
+	}
+
 	/**
 	 * Uploads all new Records to a server, specified in the settings.
 	 */
-	private void uploadNewRecords() {
+	private void syncNewRecords() {
 		int lastUploadedAttackId = pref.getInt("LAST_UPLOADED_ATTACK_ID", -1);
-		String serverAddress = pref.getString("pref_upload", "https://ssi.cased.de");	
+		// String serverAddress = pref.getString("pref_upload",
+		// "https://ssi.cased.de");
+		String serverAddress = "http://87.230.23.240/hostage/push.php";
 		ArrayList<AttackRecord> recordList = dbh.getRecordOfEachAttack(lastUploadedAttackId);
 		int size = recordList.size();
 		int offset = 1;
-		for(AttackRecord record: recordList){
+		for (AttackRecord record : recordList) {
 			editor.putInt("LAST_UPLOADED_ATTACK_ID", lastUploadedAttackId + offset);
 			editor.commit();
-			
+
 			boolean success = uploadSingleRecord(record, serverAddress);
-			Log.i("Tracing upload", "Upload of record: " + offset +"/" + size + ((success) ? " successful.": " failed."));
-			if(receiver != null){
+			Log.i("Tracing upload", "Upload of record: " + offset + "/" + size + ((success) ? " successful." : " failed."));
+			if (receiver != null) {
 				Bundle data = new Bundle();
-				data.putInt(UPLOAD_SIZE, size); 
+				data.putInt(UPLOAD_SIZE, size);
 				data.putInt(UPLOAD_PROGRESS, offset);
 				receiver.send(RECORD_UPLOADED, data);
 			}
-			offset++;			
+			offset++;
+
+			// TODO pull
+			// getRemoteData(record.getBssid(), record.getTimestamp());
 		}
-	}	
-	
+	}
+
 	/**
 	 * Uploads a single Record to a server, specified in the settings.
 	 * 
-	 * @param record The Record to upload.
+	 * @param record
+	 *            The Record to upload.
 	 * @serverAddress Address of the target server
 	 * @return True if the upload was successful, else false.
 	 */
 	private boolean uploadSingleRecord(AttackRecord record, String serverAddress) {
-		// Create a https client. Uses MySSLSocketFactory to accept all certificates
+		// Create a https client. Uses MySSLSocketFactory to accept all
+		// certificates
 		HttpPost httppost;
 		try {
 			httpClient = createHttpClient();
 			// Create HttpPost
 			httppost = new HttpPost(serverAddress);
 			// Create JSON String of Record
-			//TODO FIX ME
-			//StringEntity se = new StringEntity( record.toString(TraCINgFormatter.getInstance()) );
-			StringEntity se = new StringEntity(record.toString());
+			// TODO StringEntity se = new
+			// StringEntity(record.toString(TraCINgFormatter.getInstance()));
+			StringEntity se = new StringEntity("record=" + record.toJSON()); // FIXME
+			httppost.addHeader("content-type", "application/x-www-form-urlencoded");
 			httppost.setEntity(se);
 			// Execute HttpPost
 			HttpResponse response = httpClient.execute(httppost);
-			Log.i("TracingSyncService", "Status Code: " + response.getStatusLine().getStatusCode()); 
+			Log.i("TracingSyncService", "Status Code: " + response.getStatusLine().getStatusCode());
 		} catch (Exception e) {
 			e.printStackTrace();
 			return false;
 		}
 		return true;
 	}
-	
+
 	/**
-	 * Uploads a single Record to a server, specified in the settings.
-	 * 
-	 * @param record
-	 *            The Record to upload.
-	 * @return True if the upload was successful, else false.
+	 * Gets the data from the server and updates the database.
 	 */
-	private void getRemoteData() {
-		//TODO GET DATA FROM SERVER
-		//TODO SAVE DATA IN DATABASE
+	private void getRemoteData(String bssid, long timestamp) {
+		HttpURLConnection connection;
+		OutputStreamWriter request = null;
+		URL url = null;
+		String response = null;
+		String parameters = "bssid=" + bssid + "timestamp=" + timestamp;
+		try {
+			url = new URL("http://87.230.23.240/hostage/pull.php");
+			connection = (HttpURLConnection) url.openConnection();
+			connection.setDoOutput(true);
+			connection.setRequestProperty("content-type", "application/x-www-form-urlencoded");
+			connection.setRequestMethod("POST");
+
+			request = new OutputStreamWriter(connection.getOutputStream());
+			request.write(parameters);
+			request.flush();
+			request.close();
+			String line = "";
+
+			InputStreamReader isr = new InputStreamReader(connection.getInputStream());
+			BufferedReader reader = new BufferedReader(isr);
+			StringBuilder sb = new StringBuilder();
+			while ((line = reader.readLine()) != null) {
+				sb.append(line);
+			}
+			response = sb.toString();
+			isr.close();
+			reader.close();
+			Log.d("TEST", response);
+		} catch (IOException e) {
+			Log.i("NetworkTest", "Network Error: " + e);
+		}
 	}
-	
+
 	/**
 	 * Creates a HttpClient with an own SSL Socket.
 	 * 
@@ -165,8 +205,7 @@ public class TracingSyncService extends IntentService{
 	 */
 	private HttpClient createHttpClient() {
 		try {
-			KeyStore trustStore = KeyStore.getInstance(KeyStore
-					.getDefaultType());
+			KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
 			trustStore.load(null, null);
 
 			SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
@@ -177,12 +216,10 @@ public class TracingSyncService extends IntentService{
 			HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
 
 			SchemeRegistry registry = new SchemeRegistry();
-			registry.register(new Scheme("http", PlainSocketFactory
-					.getSocketFactory(), 80));
+			registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
 			registry.register(new Scheme("https", sf, 443));
 
-			ClientConnectionManager ccm = new ThreadSafeClientConnManager(
-					params, registry);
+			ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
 
 			return new DefaultHttpClient(ccm, params);
 		} catch (Exception e) {
@@ -191,6 +228,4 @@ public class TracingSyncService extends IntentService{
 		}
 	}
 
-
-
 }

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

@@ -19,7 +19,7 @@ import de.tudarmstadt.informatik.hostage.logging.NetworkRecord;
 import de.tudarmstadt.informatik.hostage.logging.SyncInfoRecord;
 import de.tudarmstadt.informatik.hostage.persistence.HostageDBContract;
 import de.tudarmstadt.informatik.hostage.persistence.HostageDBOpenHelper;
-import de.tudarmstadt.informatik.hostage.sync.bluetooth.BluetoothSync;
+import de.tudarmstadt.informatik.hostage.sync.bluetooth.BluetoothSyncActivity;
 import de.tudarmstadt.informatik.hostage.sync.nfc.NFCSync;
 import de.tudarmstadt.informatik.hostage.sync.tracing.TracingSyncActivity;
 
@@ -55,7 +55,7 @@ public class PlayGroundActivity extends Activity {
 	}
 
 	public void syncData(View view) {
-		startActivity(new Intent(this, BluetoothSync.class));
+		startActivity(new Intent(this, BluetoothSyncActivity.class));
 	}
 
 	private String createRandomBSSID() {

+ 0 - 544
src/de/tudarmstadt/informatik/hostage/ui/ViewLog.java

@@ -1,544 +0,0 @@
-package de.tudarmstadt.informatik.hostage.ui;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.Locale;
-
-import android.annotation.SuppressLint;
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.DatePickerDialog;
-import android.app.Dialog;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-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.os.Environment;
-import android.preference.PreferenceManager;
-import android.support.v4.app.NotificationCompat;
-import android.support.v4.app.TaskStackBuilder;
-import android.util.Log;
-import android.view.Gravity;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.DatePicker;
-import android.widget.TableLayout;
-import android.widget.TableRow;
-import android.widget.TextView;
-import android.widget.TimePicker;
-import android.widget.Toast;
-import de.tudarmstadt.informatik.hostage.R;
-import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
-import de.tudarmstadt.informatik.hostage.logging.Record;
-import de.tudarmstadt.informatik.hostage.logging.formatter.TraCINgFormatter;
-
-/**
- * ViewLog shows Statistics about the recorded Attacks. It also offers the user
- * several options to perform actions with the database. This includes:<br>
- * - show records,<br>
- * - export records,<br>
- * - upload records,<br>
- * - and delete records.
- * 
- * @author Lars Pandikow
- */
-public class ViewLog extends Activity {
-
-	private final SimpleDateFormat sdf = new SimpleDateFormat(
-			"MMM dd,yyyy HH:mm", Locale.US);
-
-	private SharedPreferences pref;
-	private Editor editor;
-
-	/**
-	 * Creates a Dialog that lets the user decide which criteria he want to use
-	 * to delete records. Then calls the corresponding method.<br>
-	 * The possible criteria are coded in /res/values/arrays.xml To add a
-	 * criteria add a String to the array and extend the switch statement.
-	 * 
-	 * @param view
-	 *            View elements which triggers the method call.
-	 * @see ViewLog#deleteByBSSID()
-	 * @see ViewLog#deleteByDate()
-	 * @see ViewLog#deleteAll()
-	 */
-	public void deleteLog(View view) {
-		AlertDialog.Builder builder = new AlertDialog.Builder(this);
-		builder.setTitle(R.string.gui_delete_dialog_title);
-		builder.setItems(R.array.delete_criteria,
-				new DialogInterface.OnClickListener() {
-					@Override
-					public void onClick(DialogInterface dialog, int position) {
-						switch (position) {
-						case 0:
-							deleteByBSSID();
-							break;
-						case 1:
-							deleteByDate();
-							break;
-						case 2:
-							deleteAll();
-						}
-					}
-				});
-		builder.create();
-		builder.show();
-	}
-
-	/**
-	 * Creates a Dialog to choose export format. Then calls
-	 * {@link ViewLog#exportDatabase(int)}
-	 * 
-	 * @param view
-	 *            View elements which triggers the method call.
-	 */
-	public void exportDatabase(View view) {
-		AlertDialog.Builder builder = new AlertDialog.Builder(this);
-		builder.setTitle(R.string.gui_export_dialog_title);
-		builder.setItems(R.array.format, new DialogInterface.OnClickListener() {
-			@Override
-			public void onClick(DialogInterface dialog, int position) {
-				exportDatabase(position);
-			}
-		});
-		builder.create();
-		builder.show();
-	}
-
-	@Override
-	public boolean onCreateOptionsMenu(Menu menu) {
-		getMenuInflater().inflate(R.menu.main, menu);
-		return true;
-	}
-
-	@Override
-	public boolean onOptionsItemSelected(MenuItem item) {
-		// Handle item selection
-		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);
-	}
-
-	/**
-	 * Starts a ViewLogTable Activity.
-	 * 
-	 * @param view
-	 *            View elements which triggers the method call.
-	 * @see ViewLogTable
-	 */
-	public void showLog(View view) {
-		startActivity(new Intent(this, ViewLogTable.class));
-		// TODO Delete
-
-	}
-
-	/**
-	 * Uploads a JSON Representation of each attack to a server, specified in
-	 * the preferences.<br>
-	 * The method only uploads information about attacks that have net been
-	 * uploaded yet.<br>
-	 * The local and remote IP of each record will be replaced with the external
-	 * IP of then device at the time of the upload. For the Upload it uses a
-	 * HttpPost with a HttpsClient, which does not validate any certificates.<br>
-	 * The Upload runs in its own Thread.<br>
-	 * While uploading the method also creates a notification to inform the user
-	 * about the status of the upload.<br>
-	 * <b>Only uploads Records with a external IP that is not null!
-	 * 
-	 * @param view
-	 *            View elements which triggers the method call.
-	 * @see de.tudarmstadt.informatik.hostage.net.MySSLSocketFactory
-	 */
-	public void uploadDatabase(View view) {
-		// Create a Notification
-		final NotificationCompat.Builder builder;
-		final NotificationManager mNotifyManager;
-		final int lastUploadedAttackId = pref.getInt("LAST_UPLOADED_ATTACK_ID",
-				-1);
-		int currentAttackId = pref.getInt("ATTACK_ID_COUNTER", 0);
-		// Check if there are new records to upload
-		if (lastUploadedAttackId == currentAttackId - 1) {
-			// Inform user that no upload is necessary
-			Toast.makeText(this, "All data have already been uploaded.",
-					Toast.LENGTH_SHORT).show();
-			return;
-		}
-		// Build and show Upload Notification in notification bar
-		builder = new NotificationCompat.Builder(this)
-				.setContentTitle(this.getString(R.string.app_name))
-				.setContentText("Upload in progress...")
-				.setTicker("Uploading Data...")
-				.setSmallIcon(R.drawable.ic_launcher)
-				.setWhen(System.currentTimeMillis());
-		TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
-		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) getSystemService(Context.NOTIFICATION_SERVICE);
-		mNotifyManager.notify(2, builder.build());
-		final Context context = this;
-		// Create a new Thread for upload
-		new Thread(new Runnable() {
-			@Override
-			public void run() {
-				// get RecordList
-				ArrayList<Record> recordList = null;// logger.getRecordOfEachAttack(lastUploadedAttackId);
-				final int progressMax = recordList.size();
-				Log.i("SQLLogger", "Logs to upload: " + progressMax);
-
-				int progressBarStatus = 0;
-				int retry_counter = 0;
-				while (progressBarStatus < progressMax) {
-					Record record = recordList.get(progressBarStatus);
-					// Only upload records with a saved external ip
-					if (record.getExternalIP() != null) {
-						retry_counter = 0;
-						if (HelperUtils.uploadSingleRecord(context, record)) {
-							// Update Notification progress bar
-							progressBarStatus++;
-							builder.setProgress(progressMax, progressBarStatus,
-									false);
-							// Update the progress bar
-							mNotifyManager.notify(2, builder.build());
-						} else {
-							retry_counter++;
-							if (retry_counter == 3) {
-								retry_counter = 0;
-								progressBarStatus++;
-							}
-						}
-					}
-				}
-
-				if (progressBarStatus == progressMax) {
-					// 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", currentAttackId - 1);
-		editor.commit();
-	}
-
-	/**
-	 * Shows a Dialog to confirm that the database should be cleared. If
-	 * confirmed {@link SQLLogger#clearData()} is called.
-	 * 
-	 * @see ILogger#clearData()
-	 */
-	private void deleteAll() {
-		AlertDialog.Builder builder = new AlertDialog.Builder(this);
-		builder.setMessage(R.string.gui_dialog_clear_database)
-				.setPositiveButton(R.string.gui_clear,
-						new DialogInterface.OnClickListener() {
-							@Override
-							@SuppressLint("NewApi")
-							public void onClick(DialogInterface dialog, int id) {
-								// Clear all Data
-								// logger.clearData();
-								editor.putInt("ATTACK_ID_COUNTER", 0);
-								editor.putInt("LAST_UPLOADED_ATTACK_ID", -1);
-								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.gui_cancel,
-						new DialogInterface.OnClickListener() {
-							@Override
-							public void onClick(DialogInterface dialog, int id) {
-								// User cancelled the dialog
-							}
-						});
-		// Create the AlertDialog object
-		builder.create();
-		builder.show();
-	}
-
-	/**
-	 * Shows a List with all recorded BSSIDs. If a BSSID is selected the method
-	 * calls {@link ILogger#deleteByBSSID(String)} to delete all records with
-	 * the chosen BSSID
-	 * 
-	 * @see ILogger#deleteByBSSID
-	 */
-	private void deleteByBSSID() {
-		AlertDialog.Builder builder = new AlertDialog.Builder(this);
-		final String[] bssidArray = null;// logger.getAllBSSIDS();
-		final String[] strings = new String[bssidArray.length];
-		for (int i = 0; i < bssidArray.length; i++) {
-			strings[i] = bssidArray[i] + " (" // + logger.getSSID(bssidArray[i])
-					+ ")";
-		}
-		builder.setTitle(R.string.gui_delete_dialog_title);
-		builder.setItems(strings, new DialogInterface.OnClickListener() {
-			@Override
-			@SuppressLint("NewApi")
-			public void onClick(DialogInterface dialog, int position) {
-
-				// logger.deleteByBSSID(bssidArray[position]);
-				Toast.makeText(
-						getApplicationContext(),
-						"All entries with bssid '" + bssidArray[position]
-								+ "' deleted.", Toast.LENGTH_SHORT).show();
-				if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
-					recreate();
-				} else {
-					Intent intent = getIntent();
-					finish();
-					startActivity(intent);
-				}
-			}
-		});
-		builder.create();
-		builder.show();
-	}
-
-	/**
-	 * Creates a DatePicking Dialog where the user can choose a date. Afterwards
-	 * {@link ViewLog#deleteByDate(int, int, int)} is called.
-	 */
-	private void deleteByDate() {
-		showDialog(0);
-	}
-
-	/**
-	 * Shows a Dialog with the given date and ask him to confirm deleting
-	 * records that are older than the shown date. When the user confirms
-	 * {@link ILogger#deleteByDate(long)} is called with a long representation
-	 * of the Date. If the user cancels the Dialog nothing happens and the
-	 * dialog disappears.
-	 * 
-	 * @param year
-	 * @param monthOfYear
-	 * @param dayOfMonth
-	 */
-	private void deleteByDate(int year, int monthOfYear, int dayOfMonth) {
-		TimePicker timePicker = new TimePicker(this);
-		final Calendar calendar = Calendar.getInstance();
-		calendar.set(year, monthOfYear, dayOfMonth,
-				timePicker.getCurrentHour(), timePicker.getCurrentMinute(), 0);
-		AlertDialog.Builder builder = new AlertDialog.Builder(this);
-		builder.setTitle(R.string.gui_dialog_clear_database_date)
-				.setMessage(sdf.format(calendar.getTime()))
-				.setPositiveButton(R.string.gui_delete,
-						new DialogInterface.OnClickListener() {
-							@Override
-							@SuppressLint("NewApi")
-							public void onClick(DialogInterface dialog, int id) {
-								long time = calendar.getTimeInMillis();
-								// Delete Data
-								// logger.deleteByDate(time);
-								Toast.makeText(getApplicationContext(),
-										"Data sets deleted!",
-										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.gui_cancel,
-						new DialogInterface.OnClickListener() {
-							@Override
-							public void onClick(DialogInterface dialog, int id) {
-								// User cancelled the dialog
-							}
-						});
-		// Create the AlertDialog object
-		builder.create();
-		builder.show();
-	}
-
-	/**
-	 * Exports all records in a given format. Before exporting checks export
-	 * location from preferences.
-	 * 
-	 * @param format
-	 *            Integer coded export format
-	 * @see Record#toString(int)
-	 */
-	private void exportDatabase(int format) {
-		try {
-			FileOutputStream 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(this, "Could not write to SD Card",
-							Toast.LENGTH_SHORT).show();
-					return;
-				}
-
-			} else {
-				log = this.openFileOutput(
-						"hostage_" + format + "_" + System.currentTimeMillis()
-								+ ".log", Context.MODE_PRIVATE);
-			}
-
-			ArrayList<Record> records = null;// logger.getAllRecords();
-			for (Record record : records) {
-				log.write((record.toString((format == 1) ? TraCINgFormatter
-						.getInstance() : null)).getBytes());
-			}
-			log.flush();
-			log.close();
-			Toast.makeText(
-					this,
-					externalStorage ? filename + " saved on external memory! "
-							+ externalLocation : filename
-							+ " saved on internal memory!", Toast.LENGTH_LONG)
-					.show();
-		} catch (Exception e) {
-			Toast.makeText(this, "Could not write to SD Card",
-					Toast.LENGTH_SHORT).show();
-			e.printStackTrace();
-		}
-	}
-
-	/**
-	 * Initializes the Statistics. Creates a table row for every protocol and
-	 * checks the dabase for the attack count. Calls
-	 * {@link ViewLog#setFirstAndLastAttack()} to set the TextViews.
-	 * 
-	 * @see ILogger#getAttackCount()
-	 * @see ILogger#getAttackPerProtocolCount(String)
-	 */
-	private void initStatistic() {
-		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)));
-
-		for (String protocol : protocols) {
-			TableRow row = new TableRow(this);
-			TextView protocolName = new TextView(this);
-			protocolName.setBackgroundResource(R.color.dark_grey);
-			protocolName.setText(protocol);
-			protocolName.setTextAppearance(this,
-					android.R.style.TextAppearance_Medium);
-			protocolName.setPadding(6, 0, 0, 0);
-			row.addView(protocolName);
-			TextView value = new TextView(this);
-			value.setBackgroundResource(R.color.light_grey);
-			value.setTextAppearance(this, android.R.style.TextAppearance_Medium);
-			value.setGravity(Gravity.RIGHT);
-			value.setPadding(3, 0, 3, 0);
-			row.addView(value);
-			if (protocol.equals("Total")) {
-				value.setText(""); // + logger.getAttackCount());
-			} else {
-				value.setText("");// +
-									// logger.getAttackPerProtocolCount(protocol));
-			}
-			table.addView(row);
-		}
-		setFirstAndLastAttack();
-	}
-
-	/**
-	 * Sets the TextViews for first and last attack.
-	 * 
-	 * @see ILogger#getSmallestAttackId()
-	 * @see ILogger#getHighestAttackId()
-	 * @see ILogger#getRecordOfAttackId(long)
-	 */
-	private void setFirstAndLastAttack() {
-		Record firstAttack = null;// logger.getRecordOfAttackId(logger.getSmallestAttackId());
-		Record lastAttack = null;// logger.getRecordOfAttackId(logger.getHighestAttackId());
-		if (firstAttack != null) {
-			Date resultdate = new Date(firstAttack.getTimestamp());
-			TextView text = (TextView) findViewById(R.id.textFirstAttackValue);
-			text.setText(sdf.format(resultdate));
-			text = (TextView) findViewById(R.id.textLastAttackValue);
-			resultdate = new Date(lastAttack.getTimestamp());
-			text.setText(sdf.format(resultdate));
-		} else {
-			TextView text = (TextView) findViewById(R.id.textFirstAttackValue);
-			text.setText("-");
-			text = (TextView) findViewById(R.id.textLastAttackValue);
-			text.setText("-");
-		}
-	}
-
-	@Override
-	protected void onCreate(Bundle savedInstanceState) {
-		super.onCreate(savedInstanceState);
-		setContentView(R.layout.activity_viewlog);
-		pref = PreferenceManager.getDefaultSharedPreferences(this);
-		editor = pref.edit();
-		initStatistic();
-	}
-
-	@Override
-	protected Dialog onCreateDialog(int id) {
-		switch (id) {
-		case 0:
-			final Calendar cal = Calendar.getInstance();
-			int pYear = cal.get(Calendar.YEAR);
-			int pMonth = cal.get(Calendar.MONTH);
-			int pDay = cal.get(Calendar.DAY_OF_MONTH);
-			return new DatePickerDialog(this,
-					new DatePickerDialog.OnDateSetListener() {
-						@Override
-						public void onDateSet(DatePicker view, int year,
-								int monthOfYear, int dayOfMonth) {
-							deleteByDate(year, monthOfYear, dayOfMonth);
-						}
-					}, pYear, pMonth, pDay);
-		}
-		return null;
-	}
-}

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

@@ -19,7 +19,7 @@ public class ViewLogTable extends Activity {
 	@Override
 	protected void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
-		/*HostageDBOpenHelper dbh = new HostageDBOpenHelper(getBaseContext());
+		HostageDBOpenHelper dbh = new HostageDBOpenHelper(getBaseContext());
 		StringBuffer log = new StringBuffer();
 		// Create a log entry for every attack in the Database
 		for (Record record : dbh.getAllRecords()) {
@@ -31,7 +31,7 @@ public class ViewLogTable extends Activity {
 		text.setText(log);
 		text.setTextAppearance(this, android.R.style.TextAppearance_Medium);
 		scroll.addView(text);
-		setContentView(scroll);*/
+		setContentView(scroll);
 	}
 
 }

+ 0 - 6
src/de/tudarmstadt/informatik/hostage/ui2/fragment/HomeFragment.java

@@ -18,9 +18,6 @@ import android.content.SharedPreferences;
 import android.os.Bundle;
 import android.support.v4.content.LocalBroadcastManager;
 import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.CompoundButton;
@@ -28,13 +25,10 @@ import android.widget.ImageView;
 import android.widget.Switch;
 import android.widget.TextView;
 
-import de.tudarmstadt.informatik.hostage.Hostage;
 import de.tudarmstadt.informatik.hostage.R;
 import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
 import de.tudarmstadt.informatik.hostage.persistence.ProfileManager;
 import de.tudarmstadt.informatik.hostage.model.Profile;
-import de.tudarmstadt.informatik.hostage.sync.bluetooth.BluetoothSync;
-import de.tudarmstadt.informatik.hostage.model.Profile;
 import de.tudarmstadt.informatik.hostage.persistence.HostageDBOpenHelper;
 import de.tudarmstadt.informatik.hostage.ui.LogFilter;
 import de.tudarmstadt.informatik.hostage.ui2.activity.MainActivity;

+ 7 - 5
src/de/tudarmstadt/informatik/hostage/ui2/fragment/RecordOverviewFragment.java

@@ -41,12 +41,13 @@ import java.util.Random;
 import de.tudarmstadt.informatik.hostage.R;
 import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
 import de.tudarmstadt.informatik.hostage.logging.AttackRecord;
+import de.tudarmstadt.informatik.hostage.logging.LogExport;
 import de.tudarmstadt.informatik.hostage.logging.MessageRecord;
 import de.tudarmstadt.informatik.hostage.logging.NetworkRecord;
 import de.tudarmstadt.informatik.hostage.logging.Record;
 import de.tudarmstadt.informatik.hostage.logging.formatter.TraCINgFormatter;
 import de.tudarmstadt.informatik.hostage.persistence.HostageDBOpenHelper;
-import de.tudarmstadt.informatik.hostage.sync.bluetooth.BluetoothSync;
+import de.tudarmstadt.informatik.hostage.sync.bluetooth.BluetoothSyncActivity;
 import de.tudarmstadt.informatik.hostage.sync.nfc.NFCSync;
 import de.tudarmstadt.informatik.hostage.sync.tracing.TracingSyncActivity;
 import de.tudarmstadt.informatik.hostage.ui.LogFilter;
@@ -351,7 +352,7 @@ public class RecordOverviewFragment extends UpNavigatibleFragment implements Che
 					public void onClick(DialogInterface dialog, int position) {
 						switch(position){
 							case 0:
-								getActivity().startActivity(new Intent(getActivity(), BluetoothSync.class));
+								getActivity().startActivity(new Intent(getActivity(), BluetoothSyncActivity.class));
 								break;
 							case 1:
 								getActivity().startActivity(new Intent(getActivity(), NFCSync.class));
@@ -374,7 +375,8 @@ public class RecordOverviewFragment extends UpNavigatibleFragment implements Che
 				builderExport.setItems(R.array.format, new DialogInterface.OnClickListener() {
 					@Override
 					public void onClick(DialogInterface dialog, int position) {
-						RecordOverviewFragment.this.exportDatabase(position);
+						//RecordOverviewFragment.this.exportDatabase(position);
+						RecordOverviewFragment.this.getActivity().startService(new Intent(getActivity(), LogExport.class));
 					}
 				});
 				builderExport.create();
@@ -386,7 +388,7 @@ public class RecordOverviewFragment extends UpNavigatibleFragment implements Che
 		return false;
 	}
 
-	private void exportDatabase(int format) {
+	/*private void exportDatabase(int format) {
 		try {
 			FileOutputStream log;
 			String filename = "hostage_" + format + "_" + System.currentTimeMillis() + ".log";
@@ -424,7 +426,7 @@ public class RecordOverviewFragment extends UpNavigatibleFragment implements Che
 					Toast.LENGTH_SHORT).show();
 			e.printStackTrace();
 		}
-	}
+	}*/
 
 	/*****************************
 	 *