Browse Source

refactoring...
bug found - byte[] to String conversion only supports chars up to 0x7F
(byte -128..127 but 0xFF=255) - replaced occurence in class Packet.
protocol type (byte[]/String) now irrelevant at compile-time.
updated p Makefile (added arm, x86, mips support)

Mihai Plasoianu 10 years ago
parent
commit
e28cec663a
49 changed files with 4309 additions and 4072 deletions
  1. 6 4
      native/Makefile
  2. BIN
      native/p
  3. 14 18
      native/p.c
  4. BIN
      native/p.o
  5. 41 28
      src/de/tudarmstadt/informatik/hostage/ConnectionRegister.java
  6. 95 92
      src/de/tudarmstadt/informatik/hostage/HoneyHandler.java
  7. 94 85
      src/de/tudarmstadt/informatik/hostage/HoneyListener.java
  8. 383 334
      src/de/tudarmstadt/informatik/hostage/HoneyService.java
  9. 209 206
      src/de/tudarmstadt/informatik/hostage/commons/HelperUtils.java
  10. 0 57
      src/de/tudarmstadt/informatik/hostage/io/ByteArrayReaderWriter.java
  11. 0 28
      src/de/tudarmstadt/informatik/hostage/io/ReaderWriter.java
  12. 0 48
      src/de/tudarmstadt/informatik/hostage/io/StringReaderWriter.java
  13. 6 6
      src/de/tudarmstadt/informatik/hostage/logging/LogResultReceiver.java
  14. 99 99
      src/de/tudarmstadt/informatik/hostage/logging/Logger.java
  15. 149 116
      src/de/tudarmstadt/informatik/hostage/logging/MyLocationManager.java
  16. 105 105
      src/de/tudarmstadt/informatik/hostage/logging/Record.java
  17. 315 331
      src/de/tudarmstadt/informatik/hostage/logging/UglyDbHelper.java
  18. 3 3
      src/de/tudarmstadt/informatik/hostage/logging/formatter/DefaultFormatter.java
  19. 3 3
      src/de/tudarmstadt/informatik/hostage/logging/formatter/TraCINgFormatter.java
  20. 12 12
      src/de/tudarmstadt/informatik/hostage/logging/formatter/protocol/ProtocolFormatter.java
  21. 13 13
      src/de/tudarmstadt/informatik/hostage/logging/formatter/protocol/SMB.java
  22. 41 41
      src/de/tudarmstadt/informatik/hostage/logging/formatter/protocol/TELNET.java
  23. 11 9
      src/de/tudarmstadt/informatik/hostage/net/MySSLSocketFactory.java
  24. 25 26
      src/de/tudarmstadt/informatik/hostage/net/MyServerSocketFactory.java
  25. 27 0
      src/de/tudarmstadt/informatik/hostage/nio/Reader.java
  26. 25 0
      src/de/tudarmstadt/informatik/hostage/nio/Writer.java
  27. 10 15
      src/de/tudarmstadt/informatik/hostage/protocol/ECHO.java
  28. 30 32
      src/de/tudarmstadt/informatik/hostage/protocol/FTP.java
  29. 21 24
      src/de/tudarmstadt/informatik/hostage/protocol/GHOST.java
  30. 126 122
      src/de/tudarmstadt/informatik/hostage/protocol/HTTP.java
  31. 11 11
      src/de/tudarmstadt/informatik/hostage/protocol/HTTPS.java
  32. 68 71
      src/de/tudarmstadt/informatik/hostage/protocol/MySQL.java
  33. 33 32
      src/de/tudarmstadt/informatik/hostage/protocol/Protocol.java
  34. 9 14
      src/de/tudarmstadt/informatik/hostage/protocol/SIP.java
  35. 643 527
      src/de/tudarmstadt/informatik/hostage/protocol/SMB.java
  36. 364 332
      src/de/tudarmstadt/informatik/hostage/protocol/SSH.java
  37. 5 2
      src/de/tudarmstadt/informatik/hostage/protocol/SSLProtocol.java
  38. 100 81
      src/de/tudarmstadt/informatik/hostage/protocol/TELNET.java
  39. 244 214
      src/de/tudarmstadt/informatik/hostage/sync/BluetoothSync.java
  40. 127 124
      src/de/tudarmstadt/informatik/hostage/sync/NFCSync.java
  41. 28 28
      src/de/tudarmstadt/informatik/hostage/system/P.java
  42. 9 6
      src/de/tudarmstadt/informatik/hostage/ui/AboutActivity.java
  43. 2 0
      src/de/tudarmstadt/informatik/hostage/ui/ListViewAdapter.java
  44. 353 339
      src/de/tudarmstadt/informatik/hostage/ui/MainActivity.java
  45. 60 57
      src/de/tudarmstadt/informatik/hostage/ui/PlayGroundActivity.java
  46. 176 139
      src/de/tudarmstadt/informatik/hostage/ui/SettingsActivity.java
  47. 179 170
      src/de/tudarmstadt/informatik/hostage/ui/ViewLog.java
  48. 1 1
      src/de/tudarmstadt/informatik/hostage/ui/ViewLogTable.java
  49. 34 67
      src/de/tudarmstadt/informatik/hostage/wrapper/Packet.java

+ 6 - 4
native/Makefile

@@ -1,15 +1,17 @@
-CC = arm-linux-androideabi-gcc
+arm: CC = arm-linux-androideabi-gcc
+x86: CC = i686-linux-android-gcc
+mips: CC = mipsel-linux-android-gcc
 CFLAGS = -Wall -g
 LDFLAGS = -llog
 SRC = p.c
 OBJ = $(SRC:.c=.o)
 EXE = p
- 
-all: $(SRC) $(EXE)
+
+arm x86 mips: $(SRC) $(EXE)
 
 $(EXE): $(OBJ)
 	$(CC) -o $@ $^ $(LDFLAGS)
- 
+
 %.o: %.c
 	$(CC) -o $@ -c $< $(CFLAGS)
 

BIN
native/p


+ 14 - 18
native/p.c

@@ -1,25 +1,21 @@
+#include <android/log.h>
+#include <errno.h>
+#include <netinet/in.h>
 #include <stdlib.h>
-#include <unistd.h>
 #include <string.h>
-
 #include <sys/socket.h>
 #include <sys/types.h>
 #include <sys/uio.h>
 #include <sys/un.h>
-#include <netinet/in.h>
-
-#include <errno.h>
-
-#include <android/log.h>
+#include <unistd.h>
 
 #define  LOG_TAG "hostage: p"
-#define  LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
-#define  LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__)
+#define  LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
 #define  LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
 
 #define CONTROLLEN CMSG_LEN(sizeof(int))
 
-char *socket_path = "hostage";
+#define UNIX_PATH "hostage"
 
 int ipc_sock() {
 	int fd;
@@ -32,10 +28,10 @@ int ipc_sock() {
 
 	memset(&addr, 0, sizeof(addr));
 	addr.sun_family = AF_UNIX;
-	strncpy(&addr.sun_path[1], socket_path, strlen(socket_path));
+	strncpy(&addr.sun_path[1], UNIX_PATH, strlen(UNIX_PATH));
 
 	if (connect(fd, (struct sockaddr*) &addr,
-			sizeof(sa_family_t) + strlen(socket_path) + 1) == -1) {
+			sizeof(sa_family_t) + strlen(UNIX_PATH) + 1) == -1) {
 		LOGE("Unable to connect local socket: %d", errno);
 		return -1;
 	}
@@ -58,9 +54,9 @@ int net_sock(int port) {
 	addr.sin_addr.s_addr = INADDR_ANY;
 	addr.sin_port = htons(port);
 
-	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1){ 
-		LOGE("Unable to set socketopt: %d", errno); 
-		return -1; 
+	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1) {
+		LOGE("Unable to set socket options: %d", errno);
+		return -1;
 	}
 
 	if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
@@ -121,18 +117,18 @@ int main(int argc, char *argv[]) {
 		close(ipc_fd);
 		exit(EXIT_FAILURE);
 	}
-	LOGI("ipc_fd: %d", ipc_fd);
+	LOGD("ipc_fd: %d", ipc_fd);
 
 	if ((net_fd = net_sock(port)) == -1) {
 		close(ipc_fd);
 		close(net_fd);
 		exit(EXIT_FAILURE);
 	}
-	LOGI("net_fd: %d", net_fd);
+	LOGD("net_fd: %d", net_fd);
 
 	int status;
 	status = send_fd(ipc_fd, net_fd);
-	LOGI("send_fd: %d", status);
+	LOGD("send_fd: %d", status);
 
 	close(ipc_fd);
 	close(net_fd);

BIN
native/p.o


+ 41 - 28
src/de/tudarmstadt/informatik/hostage/ConnectionRegister.java

@@ -5,73 +5,86 @@ import android.content.SharedPreferences;
 import android.preference.PreferenceManager;
 
 /**
- *  Saves the amount of active connections and limits them to a specific number.  
+ * Saves the amount of active connections and limits them to a specific number.
+ * 
  * @author Wulf Pfeiffer
  */
 public class ConnectionRegister {
-	
+
 	/** Active connections . **/
 	private static int openConnections = 0;
 	/** Context in which ConnectionRegister is created. **/
 	private Context context;
-	
+
 	/**
 	 * Constructor sets context.
-	 * @param context Context in which ConnectionRegister is created.
+	 * 
+	 * @param context
+	 *            Context in which ConnectionRegister is created.
 	 */
-	public ConnectionRegister(Context context){
+	public ConnectionRegister(Context context) {
 		this.context = context;
 	}
-	
-	/** 
+
+	/**
+	 * Deregisters a active connection if at least one active connection is
+	 * registered.
+	 * 
+	 * @return true if the connection has been successfully unregistered, else
+	 *         false.
+	 */
+	public boolean closeConnection() {
+		if (openConnections > 0) {
+			openConnections--;
+			return true;
+		} else {
+			return false;
+		}
+	}
+
+	/**
 	 * Returns the maximum number of active connections.
+	 * 
 	 * @return maximum number of active connections.
 	 */
 	public int getMaxConnections() {
-		SharedPreferences defaultPref = PreferenceManager.getDefaultSharedPreferences(context);		
+		SharedPreferences defaultPref = PreferenceManager
+				.getDefaultSharedPreferences(context);
 		return defaultPref.getInt("max_connections", 5);
 	}
-	
+
 	/**
 	 * Returns the number of active connections.
+	 * 
 	 * @return number of active connections.
 	 */
 	public int getOpenConnections() {
 		return openConnections;
 	}
-	
+
 	/**
 	 * Returns if there are new connections allowed or not.
+	 * 
 	 * @return true if a new connection is allowed, else false.
 	 */
 	public boolean isConnectionFree() {
-		return getMaxConnections() == 0 || openConnections < getMaxConnections();
+		return getMaxConnections() == 0
+				|| openConnections < getMaxConnections();
 	}
-	
+
 	/**
 	 * Registers a new active connection if there are connections allowed.
-	 * @return true if a new connection has been successfully registered, else false.
+	 * 
+	 * @return true if a new connection has been successfully registered, else
+	 *         false.
 	 */
 	public boolean newOpenConnection() {
-		if(isConnectionFree()) {
+		if (isConnectionFree()) {
 			openConnections++;
 			return true;
 		} else {
 			return false;
 		}
 	}
-	
-	/**
-	 * Deregisters a active connection if at least one active connection is registered.
-	 * @return true if the connection has been successfully unregistered, else false.
-	 */
-	public boolean closeConnection() {
-		if(openConnections > 0) {
-			openConnections--;
-			return true;
-		} else {
-			return false;
-		}
-	}
-	
+
 }

+ 95 - 92
src/de/tudarmstadt/informatik/hostage/HoneyHandler.java

@@ -11,13 +11,12 @@ import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
 import android.preference.PreferenceManager;
 import android.util.Log;
-import de.tudarmstadt.informatik.hostage.io.ByteArrayReaderWriter;
-import de.tudarmstadt.informatik.hostage.io.ReaderWriter;
-import de.tudarmstadt.informatik.hostage.io.StringReaderWriter;
 import de.tudarmstadt.informatik.hostage.logging.Logger;
 import de.tudarmstadt.informatik.hostage.logging.MyLocationManager;
 import de.tudarmstadt.informatik.hostage.logging.Record;
 import de.tudarmstadt.informatik.hostage.logging.Record.TYPE;
+import de.tudarmstadt.informatik.hostage.nio.Reader;
+import de.tudarmstadt.informatik.hostage.nio.Writer;
 import de.tudarmstadt.informatik.hostage.protocol.Protocol;
 import de.tudarmstadt.informatik.hostage.protocol.Protocol.TALK_FIRST;
 import de.tudarmstadt.informatik.hostage.wrapper.Packet;
@@ -32,11 +31,6 @@ public class HoneyHandler implements Runnable {
 
 	/** Time until the socket throws a time out. The time is in milliseconds. */
 	private int TIMEOUT;
-	/**
-	 * Time that a inputstream waits if no content is available to read again
-	 * from stream.
-	 */
-	private int SLEEPTIME;
 
 	private HoneyService service;
 	protected Protocol protocol;
@@ -71,32 +65,52 @@ public class HoneyHandler implements Runnable {
 		this.protocol = protocol;
 		this.client = client;
 		this.thread = new Thread(this);
-		SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(service);
-		SLEEPTIME = pref.getInt("sleeptime", 1); // 1 ms already removes ressource leak
+		SharedPreferences pref = PreferenceManager
+				.getDefaultSharedPreferences(service);
 		TIMEOUT = pref.getInt("timeout", 30) * 1000;
 		// TODO ThreadSicher?
 		getAndIncrementAttackID(pref);
-		SharedPreferences connInfo = service.getSharedPreferences(service.getString(R.string.connection_info), Context.MODE_PRIVATE);
-		BSSID = connInfo.getString(service.getString(R.string.connection_info_bssid), null);
-		SSID = connInfo.getString(service.getString(R.string.connection_info_ssid), null);
-		externalIP = connInfo.getString(service.getString(R.string.connection_info_external_ip), null);
+		SharedPreferences connInfo = service.getSharedPreferences(
+				service.getString(R.string.connection_info),
+				Context.MODE_PRIVATE);
+		BSSID = connInfo.getString(
+				service.getString(R.string.connection_info_bssid), null);
+		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);
 		thread.start();
 	}
 
 	/**
-	 * Set the timeout of the socket to the hard coded time out variable.
+	 * Determines if the interrupt flag of the thread is set.
 	 * 
-	 * @param client
-	 *            The socket
-	 * @see #TIMEOUT
+	 * @return True when the flag is set, else false.
 	 */
-	private void setSoTimeout(Socket client) {
+	public boolean isTerminated() {
+		return thread.isInterrupted();
+	}
+
+	/**
+	 * Sets the interrupt flag of the thread and tries to close the socket.
+	 */
+	public void kill() {
+		service.notifyUI(
+				this.getClass().getName(),
+				new String[] { service.getString(R.string.broadcast_started),
+						protocol.toString(),
+						Integer.toString(listener.getPort()) });
+		thread.interrupt();
 		try {
-			client.setSoTimeout(TIMEOUT);
+			client.close();
+			Log.i("HoneyHandler", "Socket closed: " + client.isClosed());
 		} catch (Exception e) {
 			e.printStackTrace();
+		} finally {
+
 		}
+		listener.refreshHandlers();
 	}
 
 	/**
@@ -106,7 +120,11 @@ public class HoneyHandler implements Runnable {
 	 */
 	@Override
 	public void run() {
-		service.notifyUI(this.getClass().getName(), new String[]{service.getString(R.string.broadcast_started), protocol.toString(), Integer.toString(listener.getPort())});
+		service.notifyUI(
+				this.getClass().getName(),
+				new String[] { service.getString(R.string.broadcast_started),
+						protocol.toString(),
+						Integer.toString(listener.getPort()) });
 		InputStream in;
 		OutputStream out;
 		try {
@@ -120,73 +138,32 @@ public class HoneyHandler implements Runnable {
 	}
 
 	/**
-	 * Sets the interrupt flag of the thread and tries to close the socket.
-	 */
-	public void kill() {
-		service.notifyUI(this.getClass().getName(), new String[]{service.getString(R.string.broadcast_started),protocol.toString() ,Integer.toString(listener.getPort())});
-		thread.interrupt();
-		try {
-			client.close();
-			Log.i("HoneyHandler", "Socket closed: " + client.isClosed());
-		} catch (Exception e) {
-			e.printStackTrace();
-		} finally {
-
-		}
-		listener.refreshHandlers();
-	}
-
-	/**
-	 * Determines if the interrupt flag of the thread is set.
+	 * Gets attack ID for the attack. Also increases the attack ID counter by
+	 * one. Method is synchronized for thread safety.
 	 * 
-	 * @return True when the flag is set, else false.
+	 * @param pref
+	 *            The default SharedPreference of the application
+	 * @return Unique integer attack ID
 	 */
-	public boolean isTerminated() {
-		return thread.isInterrupted();
+	private synchronized void getAndIncrementAttackID(SharedPreferences pref) {
+		Editor editor = pref.edit();
+		attack_id = pref.getInt("ATTACK_ID_COUNTER", 0);
+		editor.putInt("ATTACK_ID_COUNTER", attack_id + 1);
+		editor.commit();
 	}
 
 	/**
-	 * Communicates with a client using the corresponding protocol
-	 * implementation.
+	 * Set the timeout of the socket to the hard coded time out variable.
 	 * 
-	 * @param in
-	 *            InputStream of the socket.
-	 * @param out
-	 *            OutputStream of the socket.
-	 * @throws IOException
+	 * @param client
+	 *            The socket
+	 * @see #TIMEOUT
 	 */
-	protected void talkToClient(InputStream in, OutputStream out)
-			throws IOException {
-		ReaderWriter stream;
-		if (protocol.getType().equals(byte[].class)) {
-			stream = new ByteArrayReaderWriter(in, out, SLEEPTIME);
-		} else {
-			stream = new StringReaderWriter(in, out);
-		}
-		Packet inputLine;
-		List<Packet> outputLine;
-		if (protocol.whoTalksFirst() == TALK_FIRST.SERVER) {
-			outputLine = protocol.processMessage(null);
-			stream.write(outputLine);
-			for (Packet o : outputLine) {
-				Logger.log(HoneyService.getContext(),
-						createRecord(TYPE.SEND, o.toString()));
-			}
-		}
-		while (!thread.isInterrupted() && (inputLine = stream.read()) != null) {
-			outputLine = protocol.processMessage(inputLine);
-			Logger.log(HoneyService.getContext(),
-					createRecord(TYPE.RECEIVE, inputLine.toString()));
-			if (outputLine != null) {
-				stream.write(outputLine);
-				for (Packet o : outputLine) {
-					Logger.log(HoneyService.getContext(),
-							createRecord(TYPE.SEND, o.toString()));
-				}
-			}
-			if (protocol.isClosed()) {
-				break;
-			}
+	private void setSoTimeout(Socket client) {
+		try {
+			client.setSoTimeout(TIMEOUT);
+		} catch (Exception e) {
+			e.printStackTrace();
 		}
 	}
 
@@ -209,7 +186,7 @@ public class HoneyHandler implements Runnable {
 		record.setExternalIP(externalIP);
 		record.setLocalIP(client.getLocalAddress().getHostAddress());
 		record.setLocalHost(client.getLocalAddress().getHostName());
-		record.setLocalPort(protocol.getDefaultPort());
+		record.setLocalPort(protocol.getPort());
 		record.setRemoteIP(client.getInetAddress().getHostAddress());
 		record.setRemoteHost(client.getInetAddress().getHostName());
 		record.setRemotePort(client.getPort());
@@ -235,17 +212,43 @@ public class HoneyHandler implements Runnable {
 	}
 
 	/**
-	 * Gets attack ID for the attack. Also increases the attack ID counter by
-	 * one. Method is synchronized for thread safety.
+	 * Communicates with a client using the corresponding protocol
+	 * implementation.
 	 * 
-	 * @param pref
-	 *            The default SharedPreference of the application
-	 * @return Unique integer attack ID
+	 * @param in
+	 *            InputStream of the socket.
+	 * @param out
+	 *            OutputStream of the socket.
+	 * @throws IOException
 	 */
-	private synchronized void getAndIncrementAttackID(SharedPreferences pref) {
-		Editor editor = pref.edit();
-		attack_id = pref.getInt("ATTACK_ID_COUNTER", 0);
-		editor.putInt("ATTACK_ID_COUNTER", attack_id + 1);
-		editor.commit();
+	protected void talkToClient(InputStream in, OutputStream out)
+			throws IOException {
+		Reader reader = new Reader(in);
+		Writer writer = new Writer(out);
+		Packet inputLine;
+		List<Packet> outputLine;
+		if (protocol.whoTalksFirst() == TALK_FIRST.SERVER) {
+			outputLine = protocol.processMessage(null);
+			writer.write(outputLine);
+//			for (Packet o : outputLine) {
+//				Logger.log(HoneyService.getContext(),
+//						createRecord(TYPE.SEND, o.toString()));
+//			}
+		}
+		while (!thread.isInterrupted() && (inputLine = reader.read()) != null) {
+			outputLine = protocol.processMessage(inputLine);
+//			Logger.log(HoneyService.getContext(),
+//					createRecord(TYPE.RECEIVE, inputLine.toString()));
+			if (outputLine != null) {
+				writer.write(outputLine);
+//				for (Packet o : outputLine) {
+//					Logger.log(HoneyService.getContext(),
+//							createRecord(TYPE.SEND, o.toString()));
+//				}
+			}
+			if (protocol.isClosed()) {
+				break;
+			}
+		}
 	}
 }

+ 94 - 85
src/de/tudarmstadt/informatik/hostage/HoneyListener.java

@@ -17,8 +17,7 @@ import de.tudarmstadt.informatik.hostage.protocol.SSLProtocol;
  * Protocol listener class:<br>
  * Creates a Socket on the port of a given protocol and listens for incoming
  * connections.<br>
- * For each connection creates a Socket and instantiate an
- * {@link HoneyHandler}.
+ * For each connection creates a Socket and instantiate an {@link HoneyHandler}.
  * 
  * @author Mihai Plasoianu
  * 
@@ -27,34 +26,16 @@ public class HoneyListener implements Runnable {
 
 	private ArrayList<HoneyHandler> handlers = new ArrayList<HoneyHandler>();
 
-	/**
-	 * Determines the amount of active handlers.
-	 * 
-	 * @return The number of active handlers.
-	 */
-	public int getHandlerCount() {
-		return handlers.size();
-	}
-
 	private Protocol protocol;
+
 	private ServerSocket server;
 	private Thread thread;
 	private int port;
-
 	private HoneyService service;
-	private ConnectionRegister conReg;
 
+	private ConnectionRegister conReg;
 	private boolean running = false;
 
-	/**
-	 * Determines if the service is running.
-	 * 
-	 * @return True if the service is running, else false.
-	 */
-	public boolean isRunning() {
-		return running;
-	}
-
 	/**
 	 * Constructor for the class. Instantiate class variables.
 	 * 
@@ -66,10 +47,10 @@ public class HoneyListener implements Runnable {
 	public HoneyListener(HoneyService service, Protocol protocol) {
 		this.service = service;
 		this.protocol = protocol;
-		port = protocol.getDefaultPort();
+		port = protocol.getPort();
 		conReg = new ConnectionRegister(service);
 	}
-	
+
 	public HoneyListener(HoneyService service, Protocol protocol, int port) {
 		this.service = service;
 		this.protocol = protocol;
@@ -77,6 +58,57 @@ public class HoneyListener implements Runnable {
 		conReg = new ConnectionRegister(service);
 	}
 
+	/**
+	 * Determines the amount of active handlers.
+	 * 
+	 * @return The number of active handlers.
+	 */
+	public int getHandlerCount() {
+		return handlers.size();
+	}
+
+	/**
+	 * Return the port number on which the listener listening.
+	 * 
+	 * @return Used port number.
+	 */
+	public int getPort() {
+		return port;
+	}
+
+	/**
+	 * Determine the name of the protocol the listener is running on.
+	 * 
+	 * @return Name of the protocol
+	 */
+	public String getProtocolName() {
+		return protocol.toString();
+	}
+
+	/**
+	 * Determines if the service is running.
+	 * 
+	 * @return True if the service is running, else false.
+	 */
+	public boolean isRunning() {
+		return running;
+	}
+
+	/**
+	 * Remove all terminated handlers from its internal ArrayList.
+	 */
+	public void refreshHandlers() {
+		for (Iterator<HoneyHandler> iterator = handlers.iterator(); iterator
+				.hasNext();) {
+			HoneyHandler handler = iterator.next();
+			if (handler.isTerminated()) {
+				conReg.closeConnection();
+				iterator.remove();
+			}
+		}
+	}
+
+	@Override
 	public void run() {
 		while (!thread.isInterrupted()) {
 			addHandler();
@@ -93,10 +125,15 @@ public class HoneyListener implements Runnable {
 	public boolean start() {
 		try {
 			server = new MyServerSocketFactory().createServerSocket(port);
-			if(server == null) return false;
-			(this.thread = new Thread(this)).start();			
+			if (server == null)
+				return false;
+			(this.thread = new Thread(this)).start();
 			running = true;
-			service.notifyUI(this.getClass().getName(), new String[]{service.getString(R.string.broadcast_started), protocol.toString(), Integer.toString(port)});
+			service.notifyUI(
+					this.getClass().getName(),
+					new String[] {
+							service.getString(R.string.broadcast_started),
+							protocol.toString(), Integer.toString(port) });
 			return true;
 		} catch (Exception e) {
 			e.printStackTrace();
@@ -113,44 +150,16 @@ public class HoneyListener implements Runnable {
 			server.close();
 			thread.interrupt();
 			running = false;
-			service.notifyUI(this.getClass().getName(), new String[]{service.getString(R.string.broadcast_stopped), protocol.toString(), Integer.toString(port)});
+			service.notifyUI(
+					this.getClass().getName(),
+					new String[] {
+							service.getString(R.string.broadcast_stopped),
+							protocol.toString(), Integer.toString(port) });
 		} catch (Exception e) {
 			e.printStackTrace();
 		}
 	}
 
-	/**
-	 * Determine the name of the protocol the listener is running on.
-	 * 
-	 * @return Name of the protocol
-	 */
-	public String getProtocolName() {
-		return protocol.toString();
-	}
-	
-	/**
-	 * Return the port number on which the listener listening.
-	 * 
-	 * @return Used port number.
-	 */
-	public int getPort() {
-		return port;
-	}
-
-	/**
-	 * Remove all terminated handlers from its internal ArrayList.
-	 */
-	public void refreshHandlers() {
-		for (Iterator<HoneyHandler> iterator = handlers.iterator(); iterator
-				.hasNext();) {
-			HoneyHandler handler = iterator.next();
-			if (handler.isTerminated()) {
-				conReg.closeConnection();
-				iterator.remove();
-			}
-		}
-	}
-
 	/**
 	 * Waits for an incoming connection, accepts it and starts a
 	 * {@link HoneyHandler}
@@ -172,21 +181,22 @@ public class HoneyListener implements Runnable {
 	}
 
 	/**
-	 * Creates a SSLSocket out of the given socket and starts a
-	 * {@link HoneyHandler}.
+	 * Creates a new instance of an {@link HoneyHandler}.
 	 * 
+	 * @param service
+	 *            The background service
+	 * @param listener
+	 *            The listener that created the handler
+	 * @param protocol
+	 *            The Protocol the handler will run on
 	 * @param client
-	 *            The socket with the accepted connection.
-	 * @throws Exception
+	 *            The Socket the handler uses
+	 * @return A Instance of a {@link HoneyHandler} with the specified
+	 *         parameter.
 	 */
-	private void startSecureHandler(Socket client) throws Exception {
-		SSLContext sslContext = ((SSLProtocol) protocol).getSSLContext();
-		SSLSocketFactory factory = sslContext.getSocketFactory();
-		SSLSocket sslClient = (SSLSocket) factory.createSocket(client, null,
-				client.getPort(), false);
-		sslClient.setUseClientMode(false);
-		handlers.add(newInstance(service, this, protocol.getClass()
-				.newInstance(), sslClient));
+	private HoneyHandler newInstance(HoneyService service,
+			HoneyListener listener, Protocol protocol, Socket client) {
+		return new HoneyHandler(service, listener, protocol, client);
 	}
 
 	/**
@@ -202,21 +212,20 @@ public class HoneyListener implements Runnable {
 	}
 
 	/**
-	 * Creates a new instance of an {@link HoneyHandler}.
+	 * Creates a SSLSocket out of the given socket and starts a
+	 * {@link HoneyHandler}.
 	 * 
-	 * @param service
-	 *            The background service
-	 * @param listener
-	 *            The listener that created the handler
-	 * @param protocol
-	 *            The Protocol the handler will run on
 	 * @param client
-	 *            The Socket the handler uses
-	 * @return A Instance of a {@link HoneyHandler} with the specified
-	 *         parameter.
+	 *            The socket with the accepted connection.
+	 * @throws Exception
 	 */
-	private HoneyHandler newInstance(HoneyService service,
-			HoneyListener listener, Protocol protocol, Socket client) {
-		return new HoneyHandler(service, listener, protocol, client);
+	private void startSecureHandler(Socket client) throws Exception {
+		SSLContext sslContext = ((SSLProtocol) protocol).getSSLContext();
+		SSLSocketFactory factory = sslContext.getSocketFactory();
+		SSLSocket sslClient = (SSLSocket) factory.createSocket(client, null,
+				client.getPort(), false);
+		sslClient.setUseClientMode(false);
+		handlers.add(newInstance(service, this, protocol.getClass()
+				.newInstance(), sslClient));
 	}
 }

+ 383 - 334
src/de/tudarmstadt/informatik/hostage/HoneyService.java

@@ -55,106 +55,106 @@ import de.tudarmstadt.informatik.hostage.ui.MainActivity;
  */
 public class HoneyService extends Service {
 
-	private static Context context;
+	public class LocalBinder extends Binder {
+		public HoneyService getService() {
+			return HoneyService.this;
+		}
+	}
 
 	/**
-	 * Returns the application context.
+	 * Task for accuiring a qotd from one of four possible servers.
 	 * 
-	 * @return context.
+	 * @author Wulf Pfeiffer
 	 */
-	public static Context getContext() {
-		return HoneyService.context;
-	}
-
-	private LinkedList<Protocol> implementedProtocols;
-	private ArrayList<HoneyListener> listeners = new ArrayList<HoneyListener>();
-	private NotificationCompat.Builder builder;
-	private SharedPreferences connectionInfo;
-	private Editor connectionInfoEditor;
-
-	public List<HoneyListener> getListeners() {
-		return listeners;
-	}
-
-	private final IBinder mBinder = new LocalBinder();
+	private class QotdTask extends AsyncTask<String, Void, String> {
+		@Override
+		protected String doInBackground(String... unused) {
+			String[] sources = new String[] { "djxmmx.net", "ota.iambic.com",
+					"alpha.mike-r.com", "electricbiscuit.org" };
+			SecureRandom rndm = new SecureRandom();
+			StringBuffer sb = new StringBuffer();
+			try {
+				Socket client = new Socket(sources[rndm.nextInt(4)], 17);
+				BufferedReader in = new BufferedReader(new InputStreamReader(
+						client.getInputStream()));
+				while (!in.ready())
+					;
+				while (in.ready()) {
+					sb.append(in.readLine());
+				}
+				in.close();
+				client.close();
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+			return sb.toString();
+		}
 
-	public class LocalBinder extends Binder {
-		public HoneyService getService() {
-			return HoneyService.this;
+		@Override
+		protected void onPostExecute(String result) {
+			if (result != null)
+				HTTP.setHtmlDocumentContent(result);
 		}
 	}
 
-	@Override
-	public IBinder onBind(Intent intent) {
-		return mBinder;
-	}
+	/**
+	 * Task to find out the external IP.
+	 * 
+	 * @author Lars Pandikow
+	 */
+	private class SetExternalIPTask extends AsyncTask<String, Void, String> {
+		@Override
+		protected String doInBackground(String... url) {
+			String ipAddress = null;
+			try {
+				HttpClient httpclient = new DefaultHttpClient();
+				HttpGet httpget = new HttpGet(url[0]);
+				HttpResponse response;
 
-	@Override
-	public void onCreate() {
-		super.onCreate();
-		HoneyService.context = getApplicationContext();
-		implementedProtocols = getImplementedProtocols();
-		connectionInfo = getSharedPreferences(getString(R.string.connection_info), Context.MODE_PRIVATE);
-		connectionInfoEditor = connectionInfo.edit();
-		createNotification();
-		registerNetReceiver();
-		updateConnectionInfo();
-		getLocationData();
-		
-		String sharedPreferencePath = getString(R.string.shared_preference_path);
-		boolean useQotd = getSharedPreferences(sharedPreferencePath , MODE_PRIVATE).getBoolean("useQotd", true);
-		if(useQotd) {
-			new QotdTask().execute(new String[] {});
+				response = httpclient.execute(httpget);
+
+				HttpEntity entity = response.getEntity();
+				entity.getContentLength();
+				String str = EntityUtils.toString(entity);
+				JSONObject json_data = new JSONObject(str);
+				ipAddress = json_data.getString("ip");
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+			return ipAddress;
 		}
-	}
 
-	@Override
-	public int onStartCommand(Intent intent, int flags, int startId) {
-		// We want this service to continue running until it is explicitly
-		// stopped, so return sticky.
-		return START_STICKY;
+		@Override
+		protected void onPostExecute(String result) {
+			connectionInfoEditor.putString(
+					getString(R.string.connection_info_external_ip), result);
+			connectionInfoEditor.commit();
+			notifyUI(this.getClass().getName(),
+					new String[] { getString(R.string.broadcast_connectivity) });
+		}
 	}
 
-	@Override
-	public void onDestroy() {
-		cancelNotification();
-		unregisterNetReceiver();
-		super.onDestroy();
-	}
+	private static Context context;
 
 	/**
-	 * Starts an Instance of MyLocationManager to set the location within this
-	 * class.
+	 * Returns the application context.
+	 * 
+	 * @return context.
 	 */
-	private void getLocationData() {
-		MyLocationManager locationManager = new MyLocationManager(this);
-		locationManager.getUpdates(60 * 1000, 3);
+	public static Context getContext() {
+		return HoneyService.context;
 	}
 
-	/**
-	 * Deletes all session related data.
-	 */
-	private void deleteConnectionData() {
-		connectionInfoEditor.clear();
-		connectionInfoEditor.commit();
-	}
+	private LinkedList<Protocol> implementedProtocols;
+	private ArrayList<HoneyListener> listeners = new ArrayList<HoneyListener>();
 
-	/**
-	 * Register broadcast receiver for connectivity changes
-	 */
-	private void registerNetReceiver() {
-		// register BroadcastReceiver on network state changes
-		IntentFilter intent = new IntentFilter();
-		intent.addAction(ConnectivityManager.CONNECTIVITY_ACTION); // "android.net.conn.CONNECTIVITY_CHANGE"
-		registerReceiver(netReceiver, intent);
-	}
+	private NotificationCompat.Builder builder;
 
-	/**
-	 * Unregister broadcast receiver for connectivity changes
-	 */
-	private void unregisterNetReceiver() {
-		unregisterReceiver(netReceiver);
-	}
+	private SharedPreferences connectionInfo;
+
+	private Editor connectionInfoEditor;
+
+	private final IBinder mBinder = new LocalBinder();
 
 	/**
 	 * Receiver for connectivity change broadcast.
@@ -164,76 +164,55 @@ public class HoneyService extends Service {
 	private BroadcastReceiver netReceiver = new BroadcastReceiver() {
 		@Override
 		public void onReceive(Context context, Intent intent) {
-			String bssid_old = connectionInfo.getString(getString(R.string.connection_info_bssid), "");
+			String bssid_old = connectionInfo.getString(
+					getString(R.string.connection_info_bssid), "");
 			String bssid_new = HelperUtils.getBSSID(context);
 			if (bssid_new == null || !bssid_new.equals(bssid_old)) {
 				deleteConnectionData();
 				updateConnectionInfo();
 				getLocationData();
-				notifyUI(this.getClass().getName(), new String[]{getString(R.string.broadcast_connectivity)});
+				notifyUI(
+						this.getClass().getName(),
+						new String[] { getString(R.string.broadcast_connectivity) });
 			}
 		}
 	};
-	
 
-	/**
-	 * Notifies the GUI about a event.
-	 * 
-	 * @param sender
-	 *            Source where the event took place.
-	 * @param key
-	 *            Detailed information about the event.
-	 */
-	public void notifyUI(String sender, String[] values) {
-		createNotification();
-		// Send Notification
-		if (sender.equals(HoneyHandler.class.getName()) && values[0].equals(R.string.broadcast_started)) {
-			attackNotification();
-		}
-		// Inform UI of Preference Change
-		Intent intent = new Intent(getString(R.string.broadcast));
-		intent.putExtra("SENDER", sender);
-		intent.putExtra("VALUES", values);
-		Log.i("Sender" ,sender);
-		LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
+	public List<HoneyListener> getListeners() {
+		return listeners;
 	}
-	
-
 
 	/**
-	 * Returns an LinkedList<String> with the names of all implemented protocols.
+	 * Determines the number of active connections for a protocol running on its
+	 * default port.
 	 * 
-	 * @return ArrayList of
-	 *         {@link de.tudarmstadt.informatik.hostage.protocol.Protocol
-	 *         Protocol}
+	 * @param protocolName
+	 *            The protocol name
+	 * @return Number of active connections
 	 */
-	private LinkedList<Protocol> getImplementedProtocols() {
-		String[] protocols = getResources().getStringArray(R.array.protocols);
-		String packageName = Protocol.class.getPackage().getName();
-		LinkedList<Protocol> implementedProtocols = new LinkedList<Protocol>();
-
-		for (String protocol : protocols) {
-			try {
-				implementedProtocols.add((Protocol) Class.forName(String.format("%s.%s", packageName, protocol)).newInstance());
-			} catch (Exception e) {
-				e.printStackTrace();
-			}
-		}
-		return implementedProtocols;
+	public int getNumberOfActiveConnections(String protocolName) {
+		int port = getDefaultPort(protocolName);
+		return getNumberOfActiveConnections(protocolName, port);
 	}
-	
+
 	/**
-	 * Returns the default port number, if the protocol is implemented.
-	 * @param protocolName The name of the protocol
-	 * @return Returns the default port number, if the protocol is implemented. Else returns -1.
+	 * Determines the number of active connections for a protocol running on the
+	 * given port.
+	 * 
+	 * @param protocolName
+	 *            The protocol name
+	 * @param port
+	 *            Specific port
+	 * @return Number of active connections
 	 */
-	private int getDefaultPort(String protocolName){
-		for (Protocol protocol : implementedProtocols) {
-			if(protocolName.equals(protocol.toString())){
-				return protocol.getDefaultPort();
+	public int getNumberOfActiveConnections(String protocolName, int port) {
+		for (HoneyListener listener : listeners) {
+			if (listener.getProtocolName().equals(protocolName)
+					&& listener.getPort() == port) {
+				return listener.getHandlerCount();
 			}
 		}
-		return -1;
+		return 0;
 	}
 
 	/**
@@ -248,106 +227,106 @@ public class HoneyService extends Service {
 		}
 		return false;
 	}
-	
+
 	/**
-	 * Determines if a protocol with the given name is running on its default port.
-	 * @param protocolName The protocol name
+	 * Determines if a protocol with the given name is running on its default
+	 * port.
+	 * 
+	 * @param protocolName
+	 *            The protocol name
 	 * @return True if protocol is running, else false.
 	 */
-	public boolean isRunning(String protocolName){
+	public boolean isRunning(String protocolName) {
 		int port = getDefaultPort(protocolName);
 		return isRunning(protocolName, port);
 	}
-	
+
 	/**
-	 * Determines if a protocol with the given name is running on the given port.
-	 * @param protocolName The protocol name
-	 * @param port Specific port
+	 * Determines if a protocol with the given name is running on the given
+	 * port.
+	 * 
+	 * @param protocolName
+	 *            The protocol name
+	 * @param port
+	 *            Specific port
 	 * @return True if protocol is running, else false.
 	 */
-	public boolean isRunning(String protocolName, int port){
+	public boolean isRunning(String protocolName, int port) {
 		for (HoneyListener listener : listeners) {
-			if (listener.getProtocolName().equals(protocolName) && listener.getPort() == port) {
+			if (listener.getProtocolName().equals(protocolName)
+					&& listener.getPort() == port) {
 				return listener.isRunning();
 			}
-		}	
+		}
 		return false;
 	}
-	
-	/**
-	 * Determines the number of active connections for a protocol running on its default port.
-	 * @param protocolName The protocol name
-	 * @return Number of active connections
-	 */
-	public int getNumberOfActiveConnections(String protocolName){
-		int port = getDefaultPort(protocolName);
-		return getNumberOfActiveConnections(protocolName, port);
-	}
-	
-	/**
-	 * Determines the number of active connections for a protocol running on the given port.
-	 * @param protocolName The protocol name
-	 * @param port Specific port
-	 * @return Number of active connections
-	 */
-	public int getNumberOfActiveConnections(String protocolName, int port){
-		for (HoneyListener listener : listeners) {
-			if (listener.getProtocolName().equals(protocolName) && listener.getPort() == port) {
-				return listener.getHandlerCount();
-			}
-		}	
-		return 0;
-	}
 
 	/**
-	 * Creates a Listener for a given protocol on a specific port. 
-	 * After creation the Listener is not started.
-	 * Checks if the protocol is implemented first.
+	 * Notifies the GUI about a event.
 	 * 
-	 * @param protocolName Name of the protocol
-	 * @param port Port on which to start the Listener
-	 * @return Returns the created HoneyListener, if creation failed returns null.
+	 * @param sender
+	 *            Source where the event took place.
+	 * @param key
+	 *            Detailed information about the event.
 	 */
-	private HoneyListener createListener(String protocolName, int port){
-		for(Protocol protocol : implementedProtocols){
-			if(protocolName.equals(protocol.toString())){
-				HoneyListener listener = new HoneyListener(this, protocol, port);
-				listeners.add(listener);
-				return listener;
-			} 
+	public void notifyUI(String sender, String[] values) {
+		createNotification();
+		// Send Notification
+		if (sender.equals(HoneyHandler.class.getName())
+				&& values[0].equals(R.string.broadcast_started)) {
+			attackNotification();
 		}
-		return null;
+		// Inform UI of Preference Change
+		Intent intent = new Intent(getString(R.string.broadcast));
+		intent.putExtra("SENDER", sender);
+		intent.putExtra("VALUES", values);
+		Log.i("Sender", sender);
+		LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
 	}
 
-	/**
-	 * Starts all listeners which are not already running.
-	 */
-	public void startListeners() {
-		for (HoneyListener listener : listeners) {
-			if (!listener.isRunning()) {
-				listener.start();
-			}
-		}
-		Toast.makeText(getApplicationContext(), "SERVICES STARTED!",
-				Toast.LENGTH_SHORT).show();
+	@Override
+	public IBinder onBind(Intent intent) {
+		return mBinder;
 	}
 
-	/**
-	 * Stops all running listeners.
-	 */
-	public void stopListeners() {
-		for (HoneyListener listener : listeners) {
-			if (listener.isRunning()) {
-				listener.stop();
-			}
+	@Override
+	public void onCreate() {
+		super.onCreate();
+		HoneyService.context = getApplicationContext();
+		implementedProtocols = getImplementedProtocols();
+		connectionInfo = getSharedPreferences(
+				getString(R.string.connection_info), Context.MODE_PRIVATE);
+		connectionInfoEditor = connectionInfo.edit();
+		createNotification();
+		registerNetReceiver();
+		updateConnectionInfo();
+		getLocationData();
+
+		String sharedPreferencePath = getString(R.string.shared_preference_path);
+		boolean useQotd = getSharedPreferences(sharedPreferencePath,
+				MODE_PRIVATE).getBoolean("useQotd", true);
+		if (useQotd) {
+			new QotdTask().execute(new String[] {});
 		}
-		Toast.makeText(getApplicationContext(), "SERVICES STOPPED!",
-				Toast.LENGTH_SHORT).show();
+	}
+
+	@Override
+	public void onDestroy() {
+		cancelNotification();
+		unregisterNetReceiver();
+		super.onDestroy();
+	}
+
+	@Override
+	public int onStartCommand(Intent intent, int flags, int startId) {
+		// We want this service to continue running until it is explicitly
+		// stopped, so return sticky.
+		return START_STICKY;
 	}
 
 	/**
-	 * Starts the listener for the specified protocol. 
-	 * Creates a new HoneyService if no matching HoneyListener is found.
+	 * Starts the listener for the specified protocol. Creates a new
+	 * HoneyService if no matching HoneyListener is found.
 	 * 
 	 * @param protocolName
 	 *            Name of the protocol that should be started.
@@ -355,40 +334,63 @@ public class HoneyService extends Service {
 	public boolean startListener(String protocolName) {
 		return startListener(protocolName, getDefaultPort(protocolName));
 	}
-	
+
 	/**
-	 * Starts the listener for the specified protocol and port.
-	 * Creates a new HoneyService if no matching HoneyListener is found.
+	 * Starts the listener for the specified protocol and port. Creates a new
+	 * HoneyService if no matching HoneyListener is found.
 	 * 
 	 * @param protocolName
 	 *            Name of the protocol that should be started.
-	 * @param port The port number in which the listener should run.
+	 * @param port
+	 *            The port number in which the listener should run.
 	 */
 	public boolean startListener(String protocolName, int port) {
 		for (HoneyListener listener : listeners) {
-			if (listener.getProtocolName().equals(protocolName) && listener.getPort() == port) {
+			if (listener.getProtocolName().equals(protocolName)
+					&& listener.getPort() == port) {
 				if (!listener.isRunning()) {
-					if(listener.start()){
-						Toast.makeText(getApplicationContext(),protocolName + " SERVICE STARTED!", Toast.LENGTH_SHORT).show();
+					if (listener.start()) {
+						Toast.makeText(getApplicationContext(),
+								protocolName + " SERVICE STARTED!",
+								Toast.LENGTH_SHORT).show();
 						return true;
 					}
-					Toast.makeText(getApplicationContext(),protocolName + " SERVICE COULD NOT BE STARTED!", Toast.LENGTH_SHORT).show();
+					Toast.makeText(getApplicationContext(),
+							protocolName + " SERVICE COULD NOT BE STARTED!",
+							Toast.LENGTH_SHORT).show();
 					return false;
 				}
-				
+
 			}
 		}
 		HoneyListener listener = createListener(protocolName, port);
-		if(listener != null){
-			if(listener.start()){
-				Toast.makeText(getApplicationContext(), protocolName + " SERVICE STARTED!", Toast.LENGTH_SHORT).show();
+		if (listener != null) {
+			if (listener.start()) {
+				Toast.makeText(getApplicationContext(),
+						protocolName + " SERVICE STARTED!", Toast.LENGTH_SHORT)
+						.show();
 				return true;
 			}
-		}	
-		Toast.makeText(getApplicationContext(),protocolName + " SERVICE COULD NOT BE STARTED!", Toast.LENGTH_SHORT).show();
+		}
+		Toast.makeText(getApplicationContext(),
+				protocolName + " SERVICE COULD NOT BE STARTED!",
+				Toast.LENGTH_SHORT).show();
 		return false;
 	}
 
+	/**
+	 * Starts all listeners which are not already running.
+	 */
+	public void startListeners() {
+		for (HoneyListener listener : listeners) {
+			if (!listener.isRunning()) {
+				listener.start();
+			}
+		}
+		Toast.makeText(getApplicationContext(), "SERVICES STARTED!",
+				Toast.LENGTH_SHORT).show();
+	}
+
 	/**
 	 * Stops the listener for the specified protocol.
 	 * 
@@ -398,119 +400,102 @@ public class HoneyService extends Service {
 	public void stopListener(String protocolName) {
 		stopListener(protocolName, getDefaultPort(protocolName));
 	}
-	
+
 	/**
 	 * Stops the listener for the specified protocol.
 	 * 
 	 * @param protocolName
 	 *            Name of the protocol that should be stopped.
-	 * @param port The port number in which the listener is running.
+	 * @param port
+	 *            The port number in which the listener is running.
 	 */
 	public void stopListener(String protocolName, int port) {
 		for (HoneyListener listener : listeners) {
-			if (listener.getProtocolName().equals(protocolName) && listener.getPort() == port) {
+			if (listener.getProtocolName().equals(protocolName)
+					&& listener.getPort() == port) {
 				if (listener.isRunning()) {
 					listener.stop();
 				}
 			}
 		}
-		Toast.makeText(getApplicationContext(), protocolName + " SERVICE STOPPED!", Toast.LENGTH_SHORT).show();
+		Toast.makeText(getApplicationContext(),
+				protocolName + " SERVICE STOPPED!", Toast.LENGTH_SHORT).show();
 	}
 
 	/**
-	 * Task for accuiring a qotd from one of four possible servers.
-	 * 
-	 * @author Wulf Pfeiffer
+	 * Stops all running listeners.
 	 */
-	private class QotdTask extends AsyncTask<String, Void, String> {
-		@Override
-		protected String doInBackground(String... unused) {
-			String[] sources = new String[] { "djxmmx.net", "ota.iambic.com",
-					"alpha.mike-r.com", "electricbiscuit.org" };
-			SecureRandom rndm = new SecureRandom();
-			StringBuffer sb = new StringBuffer();
-			try {
-				Socket client = new Socket(sources[rndm.nextInt(4)], 17);
-				BufferedReader in = new BufferedReader(new InputStreamReader(
-						client.getInputStream()));
-				while (!in.ready())
-					;
-				while (in.ready()) {
-					sb.append(in.readLine());
-				}
-				in.close();
-				client.close();
-			} catch (Exception e) {
-				e.printStackTrace();
+	public void stopListeners() {
+		for (HoneyListener listener : listeners) {
+			if (listener.isRunning()) {
+				listener.stop();
 			}
-			return sb.toString();
 		}
+		Toast.makeText(getApplicationContext(), "SERVICES STOPPED!",
+				Toast.LENGTH_SHORT).show();
+	}
 
-		@Override
-		protected void onPostExecute(String result) {
-			if (result != null)
-				HTTP.setHtmlDocumentContent(result);
+	/**
+	 * Updates the notification when a attack is registered.
+	 */
+	private void attackNotification() {
+		SharedPreferences defaultPref = PreferenceManager
+				.getDefaultSharedPreferences(this);
+		String strRingtonePreference = defaultPref.getString(
+				"pref_notification_sound",
+				"content://settings/system/notification_sound");
+		builder = new NotificationCompat.Builder(this)
+				.setContentTitle(getString(R.string.app_name))
+				.setTicker("Honeypot under attack!")
+				.setContentText("Honeypot under attack!")
+				.setSmallIcon(R.drawable.ic_service_red).setAutoCancel(true)
+				.setWhen(System.currentTimeMillis())
+				.setSound(Uri.parse(strRingtonePreference));
+		TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
+		stackBuilder.addParentStack(MainActivity.class);
+		stackBuilder.addNextIntent(new Intent(this, MainActivity.class));
+		PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
+				PendingIntent.FLAG_UPDATE_CURRENT);
+		builder.setContentIntent(resultPendingIntent);
+		if (defaultPref.getBoolean("pref_vibration", false)) {
+			builder.setVibrate(new long[] { 100, 200, 100, 200 });
 		}
-	};
-	
+
+		NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+		mNotificationManager.notify(2, builder.build());
+	}
+
 	/**
-	 * Updates the connection info and saves them in the the SharedPreferences
-	 * for session data.
-	 * 
-	 * @param context
-	 *            Needs a context to get system recourses.
-	 * @see MainActivity#CONNECTION_INFO
+	 * Cancels the Notification
 	 */
-	private void updateConnectionInfo() {
-		SharedPreferences pref = context.getSharedPreferences(
-				getString(R.string.connection_info), Context.MODE_PRIVATE);
-		Editor editor = pref.edit();
-		editor.putString(getString(R.string.connection_info_ssid), HelperUtils.getSSID(context));
-		editor.putString(getString(R.string.connection_info_bssid), HelperUtils.getBSSID(context));
-		editor.putString(getString(R.string.connection_info_internal_ip),
-				HelperUtils.getInternalIP(context));
-		editor.commit();
-		SetExternalIPTask async = new SetExternalIPTask();
-		async.execute(new String[] { "http://ip2country.sourceforge.net/ip2c.php?format=JSON" });
+	private void cancelNotification() {
+		NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+		mNotificationManager.cancel(1);
 	}
-	
+
 	/**
-	 * Task to find out the external IP.
+	 * Creates a Listener for a given protocol on a specific port. After
+	 * creation the Listener is not started. Checks if the protocol is
+	 * implemented first.
 	 * 
-	 * @author Lars Pandikow
+	 * @param protocolName
+	 *            Name of the protocol
+	 * @param port
+	 *            Port on which to start the Listener
+	 * @return Returns the created HoneyListener, if creation failed returns
+	 *         null.
 	 */
-	private class SetExternalIPTask extends AsyncTask<String, Void, String> {
-		@Override
-		protected String doInBackground(String... url) {
-			String ipAddress = null;
-			try {
-				HttpClient httpclient = new DefaultHttpClient();
-				HttpGet httpget = new HttpGet(url[0]);
-				HttpResponse response;
-
-				response = httpclient.execute(httpget);
-
-				HttpEntity entity = response.getEntity();
-				entity.getContentLength();
-				String str = EntityUtils.toString(entity);
-				JSONObject json_data = new JSONObject(str);
-				ipAddress = json_data.getString("ip");
-			} catch (Exception e) {
-				e.printStackTrace();
+	private HoneyListener createListener(String protocolName, int port) {
+		for (Protocol protocol : implementedProtocols) {
+			if (protocolName.equals(protocol.toString())) {
+				HoneyListener listener = new HoneyListener(this, protocol, port);
+				listeners.add(listener);
+				return listener;
 			}
-			return ipAddress;
 		}
+		return null;
+	}
 
-		@Override
-		protected void onPostExecute(String result) {
-			connectionInfoEditor.putString(getString(R.string.connection_info_external_ip), result);
-			connectionInfoEditor.commit();
-			notifyUI(this.getClass().getName(), new String[]{getString(R.string.broadcast_connectivity)});
-		}
-	};
-	
-	// Notifications
-	
 	/**
 	 * Creates a Notification in the notification bar.
 	 */
@@ -521,19 +506,20 @@ public class HoneyService extends Service {
 		boolean listening = false;
 
 		for (HoneyListener listener : listeners) {
-			if(listener.isRunning())
+			if (listener.isRunning())
 				listening = true;
 			if (listener.getHandlerCount() > 0) {
 				activeHandlers = true;
 			}
-			if (dbh.bssidSeen(listener.getProtocolName(), HelperUtils.getBSSID(getApplicationContext()))) {
+			if (dbh.bssidSeen(listener.getProtocolName(),
+					HelperUtils.getBSSID(getApplicationContext()))) {
 				bssidSeen = true;
 			}
 		}
 		builder = new NotificationCompat.Builder(this).setContentTitle(
 				getString(R.string.app_name)).setWhen(
 				System.currentTimeMillis());
-		if(!listening){
+		if (!listening) {
 			builder.setSmallIcon(R.drawable.ic_launcher);
 			builder.setContentText("HosTaGe is not active.");
 		} else if (activeHandlers) {
@@ -542,10 +528,10 @@ public class HoneyService extends Service {
 		} else if (bssidSeen) {
 			builder.setSmallIcon(R.drawable.ic_service_yellow);
 			builder.setContentText("Network has been infected in previous session!");
-		} else{
+		} else {
 			builder.setSmallIcon(R.drawable.ic_service_green);
 			builder.setContentText("Everything looks fine!");
-		} 
+		}
 		TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
 		stackBuilder.addParentStack(MainActivity.class);
 		stackBuilder.addNextIntent(new Intent(this, MainActivity.class));
@@ -558,41 +544,104 @@ public class HoneyService extends Service {
 	}
 
 	/**
-	 * Updates the notification when a attack is registered.
+	 * Deletes all session related data.
 	 */
-	private void attackNotification() {
-		SharedPreferences defaultPref = PreferenceManager
-				.getDefaultSharedPreferences(this);
-		String strRingtonePreference = defaultPref.getString(
-				"pref_notification_sound",
-				"content://settings/system/notification_sound");
-		builder = new NotificationCompat.Builder(this)
-				.setContentTitle(getString(R.string.app_name))
-				.setTicker("Honeypot under attack!")
-				.setContentText("Honeypot under attack!")
-				.setSmallIcon(R.drawable.ic_service_red).setAutoCancel(true)
-				.setWhen(System.currentTimeMillis())
-				.setSound(Uri.parse(strRingtonePreference));
-		TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
-		stackBuilder.addParentStack(MainActivity.class);
-		stackBuilder.addNextIntent(new Intent(this, MainActivity.class));
-		PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
-				PendingIntent.FLAG_UPDATE_CURRENT);
-		builder.setContentIntent(resultPendingIntent);
-		if (defaultPref.getBoolean("pref_vibration", false)) {
-			builder.setVibrate(new long[] { 100, 200, 100, 200 });
+	private void deleteConnectionData() {
+		connectionInfoEditor.clear();
+		connectionInfoEditor.commit();
+	}
+
+	/**
+	 * Returns the default port number, if the protocol is implemented.
+	 * 
+	 * @param protocolName
+	 *            The name of the protocol
+	 * @return Returns the default port number, if the protocol is implemented.
+	 *         Else returns -1.
+	 */
+	private int getDefaultPort(String protocolName) {
+		for (Protocol protocol : implementedProtocols) {
+			if (protocolName.equals(protocol.toString())) {
+				return protocol.getPort();
+			}
 		}
+		return -1;
+	};
 
-		NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
-		mNotificationManager.notify(2, builder.build());
+	/**
+	 * Returns an LinkedList<String> with the names of all implemented
+	 * protocols.
+	 * 
+	 * @return ArrayList of
+	 *         {@link de.tudarmstadt.informatik.hostage.protocol.Protocol
+	 *         Protocol}
+	 */
+	private LinkedList<Protocol> getImplementedProtocols() {
+		String[] protocols = getResources().getStringArray(R.array.protocols);
+		String packageName = Protocol.class.getPackage().getName();
+		LinkedList<Protocol> implementedProtocols = new LinkedList<Protocol>();
+
+		for (String protocol : protocols) {
+			try {
+				implementedProtocols.add((Protocol) Class.forName(
+						String.format("%s.%s", packageName, protocol))
+						.newInstance());
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		}
+		return implementedProtocols;
 	}
 
 	/**
-	 * Cancels the Notification
+	 * Starts an Instance of MyLocationManager to set the location within this
+	 * class.
 	 */
-	private void cancelNotification() {
-		NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
-		mNotificationManager.cancel(1);
+	private void getLocationData() {
+		MyLocationManager locationManager = new MyLocationManager(this);
+		locationManager.getUpdates(60 * 1000, 3);
+	};
+
+	// Notifications
+
+	/**
+	 * Register broadcast receiver for connectivity changes
+	 */
+	private void registerNetReceiver() {
+		// register BroadcastReceiver on network state changes
+		IntentFilter intent = new IntentFilter();
+		intent.addAction(ConnectivityManager.CONNECTIVITY_ACTION); // "android.net.conn.CONNECTIVITY_CHANGE"
+		registerReceiver(netReceiver, intent);
+	}
+
+	/**
+	 * Unregister broadcast receiver for connectivity changes
+	 */
+	private void unregisterNetReceiver() {
+		unregisterReceiver(netReceiver);
+	}
+
+	/**
+	 * Updates the connection info and saves them in the the SharedPreferences
+	 * for session data.
+	 * 
+	 * @param context
+	 *            Needs a context to get system recourses.
+	 * @see MainActivity#CONNECTION_INFO
+	 */
+	private void updateConnectionInfo() {
+		SharedPreferences pref = context.getSharedPreferences(
+				getString(R.string.connection_info), Context.MODE_PRIVATE);
+		Editor editor = pref.edit();
+		editor.putString(getString(R.string.connection_info_ssid),
+				HelperUtils.getSSID(context));
+		editor.putString(getString(R.string.connection_info_bssid),
+				HelperUtils.getBSSID(context));
+		editor.putString(getString(R.string.connection_info_internal_ip),
+				HelperUtils.getInternalIP(context));
+		editor.commit();
+		SetExternalIPTask async = new SetExternalIPTask();
+		async.execute(new String[] { "http://ip2country.sourceforge.net/ip2c.php?format=JSON" });
 	}
 
 }

+ 209 - 206
src/de/tudarmstadt/informatik/hostage/commons/HelperUtils.java

@@ -43,104 +43,71 @@ import de.tudarmstadt.informatik.hostage.net.MySSLSocketFactory;
 public final class HelperUtils {
 
 	/**
-	 * Gets SSID of the wireless network.
+	 * Converts a byte array into a hexadecimal String, e.g. {0x00, 0x01} to
+	 * "00, 01".
 	 * 
-	 * @param context
-	 *            Needs a context to get system recourses
-	 * @return SSID of wireless network if connected, else null.
+	 * @param bytes
+	 *            that will be converted.
+	 * @return converted String.
 	 */
-	public static String getSSID(Context context) {
-		String ssid = null;
-		ConnectivityManager connManager = (ConnectivityManager) context
-				.getSystemService(Context.CONNECTIVITY_SERVICE);
-		NetworkInfo networkInfo = connManager
-				.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
-		if (networkInfo != null && networkInfo.isConnected()) {
-			final WifiManager wifiManager = (WifiManager) context
-					.getSystemService(Context.WIFI_SERVICE);
-			final WifiInfo connectionInfo = wifiManager.getConnectionInfo();
-			if (connectionInfo != null
-					&& !TextUtils.isEmpty(connectionInfo.getSSID())) {
-				ssid = connectionInfo.getSSID();
-			}
+	public static String bytesToHexString(byte[] bytes) {
+		char[] hexArray = "0123456789ABCDEF".toCharArray();
+		int v;
+		StringBuffer buffer = new StringBuffer();
+		for (int j = 0; j < bytes.length; j++) {
+			v = bytes[j] & 0xFF;
+			buffer.append(hexArray[v >>> 4]);
+			buffer.append(hexArray[v & 0x0F]);
+			if (j < bytes.length - 1)
+				buffer.append(", ");
 		}
-		return ssid;
+		return buffer.toString();
 	}
 
 	/**
-	 * Gets BSSID of the wireless network.
+	 * Converts a byte[] to a String, but only characters in ASCII between 32
+	 * and 127
 	 * 
-	 * @param context
-	 *            Needs a context to get system recourses.
-	 * @return BSSID of wireless network if connected, else null.
+	 * @param bytes
+	 *            that are converted
+	 * @return converted String
 	 */
-	public static String getBSSID(Context context) {
-		String bssid = null;
-		ConnectivityManager connManager = (ConnectivityManager) context
-				.getSystemService(Context.CONNECTIVITY_SERVICE);
-		NetworkInfo networkInfo = connManager
-				.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
-		if (networkInfo != null && networkInfo.isConnected()) {
-			final WifiManager wifiManager = (WifiManager) context
-					.getSystemService(Context.WIFI_SERVICE);
-			final WifiInfo connectionInfo = wifiManager.getConnectionInfo();
-			if (connectionInfo != null
-					&& !TextUtils.isEmpty(connectionInfo.getSSID())) {
-				bssid = connectionInfo.getBSSID();
+	public static String byteToStr(byte[] bytes) {
+		char[] chars = new char[bytes.length];
+		for (int i = 0, j = 0; i < bytes.length && j < chars.length; i++) {
+			if (isLetter((char) bytes[i])) {
+				chars[j] = (char) bytes[i];
+				j++;
 			}
 		}
-		return bssid;
+		return new String(chars);
 	}
 
 	/**
-	 * Gets internal IP address of the device in a wireless network.
+	 * Concatenates several byte arrays.
 	 * 
-	 * @param context
-	 *            Needs a context to get system recourses.
-	 * @return internal IP of the device in a wireless network if connected,
-	 *         else null.
+	 * @param bytes
+	 *            The byte arrays.
+	 * @return A single byte arrays containing all the bytes from the given
+	 *         arrays in the order they are given.
 	 */
-	public static String getInternalIP(Context context) {
-		String ipAddress = null;
-		ConnectivityManager connManager = (ConnectivityManager) context
-				.getSystemService(Context.CONNECTIVITY_SERVICE);
-		NetworkInfo networkInfo = connManager
-				.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
-		if (networkInfo != null && networkInfo.isConnected()) {
-			final WifiManager wifiManager = (WifiManager) context
-					.getSystemService(Context.WIFI_SERVICE);
-			final WifiInfo connectionInfo = wifiManager.getConnectionInfo();
-			if (connectionInfo != null) {
-				try {
-					ipAddress = InetAddress.getByAddress(
-							unpackInetAddress(connectionInfo.getIpAddress()))
-							.getHostAddress();
-				} catch (UnknownHostException e) {
-					e.printStackTrace();
-				}
-			}
-		}
-		return ipAddress;
-	}
-
-	private static byte[] unpackInetAddress(int bytes) {
-		return new byte[] { (byte) ((bytes) & 0xff),
-				(byte) ((bytes >>> 8) & 0xff), (byte) ((bytes >>> 16) & 0xff),
-				(byte) ((bytes >>> 24) & 0xff) };
-	}
+	public static byte[] concat(byte[]... bytes) {
+		int newSize = 0;
+		for (byte[] b : bytes)
+			if (b != null)
+				newSize += b.length;
+		byte[] dst = new byte[newSize];
 
-	/**
-	 * 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;
+		int currentPos = 0;
+		int newPos;
+		for (byte[] b : bytes) {
+			if (b != null) {
+				newPos = b.length;
+				System.arraycopy(b, 0, dst, currentPos, newPos);
+				currentPos += newPos;
+			}
 		}
-		return false;
+		return dst;
 	}
 
 	/**
@@ -178,112 +145,136 @@ public final class HelperUtils {
 	}
 
 	/**
-	 * Uploads a single Record to a server, specified in the settings.
+	 * Puts a 0x00 byte between each byte in a byte array.
 	 * 
-	 * @param record
-	 *            The Record to upload.
-	 * @return True if the upload was successful, else false.
+	 * @param bytes
+	 *            that need to be filled with 0x00.
+	 * @return filled byte array.
 	 */
-	public static boolean uploadSingleRecord(Context context, Record record) {
-		// Create a https client. Uses MySSLSocketFactory to accept all
-		// certificates
-		HttpClient httpclient = HelperUtils.createHttpClient();
-		HttpPost httppost;
-		try {
-			// Create HttpPost
-			httppost = new HttpPost(PreferenceManager
-					.getDefaultSharedPreferences(context).getString(
-							"pref_upload", "https://ssi.cased.de"));
-			// Create JSON String of Record
-			StringEntity se = new StringEntity(record.toString(TraCINgFormatter
-					.getInstance()));
-			httppost.setEntity(se);
-			// Execute HttpPost
-			httpclient.execute(httppost);
-		} catch (Exception e) {
-			e.printStackTrace();
-			return false;
+	public static byte[] fillWithZero(byte[] bytes) {
+		byte[] newBytes = new byte[(bytes.length * 2)];
+		for (int i = 0, j = 0; i < bytes.length && j < newBytes.length; i++, j = j + 2) {
+			newBytes[j] = bytes[i];
+			newBytes[j + 1] = 0x00;
 		}
-		return true;
+		return newBytes;
 	}
 
 	/**
-	 * Concatenates several byte arrays.
+	 * Puts a 0x00 byte between each byte and another 2 0x00 bytes at the end of
+	 * a byte array.
 	 * 
 	 * @param bytes
-	 *            The byte arrays.
-	 * @return A single byte arrays containing all the bytes from the given
-	 *         arrays in the order they are given.
+	 *            that need to be filled with 0x00.
+	 * @return filled byte array.
 	 */
-	public static byte[] concat(byte[]... bytes) {
-		int newSize = 0;
-		for (byte[] b : bytes)
-			if (b != null)
-				newSize += b.length;
-		byte[] dst = new byte[newSize];
+	public static byte[] fillWithZeroExtended(byte[] bytes) {
+		byte[] zeroBytes = fillWithZero(bytes);
+		byte[] newBytes = new byte[zeroBytes.length + 2];
+		newBytes = HelperUtils.concat(zeroBytes, new byte[] { 0x00, 0x00 });
+		return newBytes;
+	}
 
-		int currentPos = 0;
-		int newPos;
-		for (byte[] b : bytes) {
-			if (b != null) {
-				newPos = b.length;
-				System.arraycopy(b, 0, dst, currentPos, newPos);
-				currentPos += newPos;
+	/**
+	 * Gets BSSID of the wireless network.
+	 * 
+	 * @param context
+	 *            Needs a context to get system recourses.
+	 * @return BSSID of wireless network if connected, else null.
+	 */
+	public static String getBSSID(Context context) {
+		String bssid = null;
+		ConnectivityManager connManager = (ConnectivityManager) context
+				.getSystemService(Context.CONNECTIVITY_SERVICE);
+		NetworkInfo networkInfo = connManager
+				.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+		if (networkInfo != null && networkInfo.isConnected()) {
+			final WifiManager wifiManager = (WifiManager) context
+					.getSystemService(Context.WIFI_SERVICE);
+			final WifiInfo connectionInfo = wifiManager.getConnectionInfo();
+			if (connectionInfo != null
+					&& !TextUtils.isEmpty(connectionInfo.getSSID())) {
+				bssid = connectionInfo.getBSSID();
 			}
 		}
-		return dst;
+		return bssid;
 	}
 
 	/**
-	 * Converts a byte[] to a String, but only characters in ASCII between 32
-	 * and 127
+	 * Gets internal IP address of the device in a wireless network.
 	 * 
-	 * @param bytes
-	 *            that are converted
-	 * @return converted String
+	 * @param context
+	 *            Needs a context to get system recourses.
+	 * @return internal IP of the device in a wireless network if connected,
+	 *         else null.
 	 */
-	public static String byteToStr(byte[] bytes) {
-		char[] chars = new char[bytes.length];
-		for (int i = 0, j = 0; i < bytes.length && j < chars.length; i++) {
-			if (isLetter((char) bytes[i])) {
-				chars[j] = (char) bytes[i];
-				j++;
+	public static String getInternalIP(Context context) {
+		String ipAddress = null;
+		ConnectivityManager connManager = (ConnectivityManager) context
+				.getSystemService(Context.CONNECTIVITY_SERVICE);
+		NetworkInfo networkInfo = connManager
+				.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+		if (networkInfo != null && networkInfo.isConnected()) {
+			final WifiManager wifiManager = (WifiManager) context
+					.getSystemService(Context.WIFI_SERVICE);
+			final WifiInfo connectionInfo = wifiManager.getConnectionInfo();
+			if (connectionInfo != null) {
+				try {
+					ipAddress = InetAddress.getByAddress(
+							unpackInetAddress(connectionInfo.getIpAddress()))
+							.getHostAddress();
+				} catch (UnknownHostException e) {
+					e.printStackTrace();
+				}
 			}
 		}
-		return new String(chars);
+		return ipAddress;
 	}
 
 	/**
-	 * Determines if a character is in ASCII between 32 and 126
+	 * Produces a random String. The String can be of random length (minimum 1)
+	 * with a maximum length, or it can be forced to have the length that was
+	 * given.
 	 * 
-	 * @param character
-	 *            that is checked
-	 * @return true if the character is between 32 and 126, else false
+	 * @param length
+	 *            maximal / forced length of String.
+	 * @param forceLength
+	 *            forces the String to be exact the given length instead of
+	 *            maximum
+	 * @return random String.
 	 */
-	private static boolean isLetter(char character) {
-		return (character > 31 && character < 127);
+	public static String getRandomString(int length, boolean forceLength) {
+		SecureRandom rndm = new SecureRandom();
+		char[] c = new char[forceLength ? length : rndm.nextInt(length - 1) + 1];
+		for (int i = 0; i < c.length; i++) {
+			c[i] = (char) (rndm.nextInt(95) + 32);
+		}
+		return new String(c);
 	}
 
 	/**
-	 * Converts a byte array into a hexadecimal String, e.g. {0x00, 0x01} to
-	 * "00, 01".
+	 * Gets SSID of the wireless network.
 	 * 
-	 * @param bytes
-	 *            that will be converted.
-	 * @return converted String.
+	 * @param context
+	 *            Needs a context to get system recourses
+	 * @return SSID of wireless network if connected, else null.
 	 */
-	public static String bytesToHexString(byte[] bytes) {
-		char[] hexArray = "0123456789ABCDEF".toCharArray();
-		int v;
-		StringBuffer buffer = new StringBuffer();
-		for (int j = 0; j < bytes.length; j++) {
-			v = bytes[j] & 0xFF;
-			buffer.append(hexArray[v >>> 4]);
-			buffer.append(hexArray[v & 0x0F]);
-			if (j < bytes.length - 1)
-				buffer.append(", ");
+	public static String getSSID(Context context) {
+		String ssid = null;
+		ConnectivityManager connManager = (ConnectivityManager) context
+				.getSystemService(Context.CONNECTIVITY_SERVICE);
+		NetworkInfo networkInfo = connManager
+				.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+		if (networkInfo != null && networkInfo.isConnected()) {
+			final WifiManager wifiManager = (WifiManager) context
+					.getSystemService(Context.WIFI_SERVICE);
+			final WifiInfo connectionInfo = wifiManager.getConnectionInfo();
+			if (connectionInfo != null
+					&& !TextUtils.isEmpty(connectionInfo.getSSID())) {
+				ssid = connectionInfo.getSSID();
+			}
 		}
-		return buffer.toString();
+		return ssid;
 	}
 
 	/**
@@ -304,54 +295,31 @@ public final class HelperUtils {
 	}
 
 	/**
-	 * Produces a random String. The String can be of random length (minimum 1) with a
-	 * maximum length, or it can be forced to have the length that was given.
+	 * Checks if external storage is available for read and write.
 	 * 
-	 * @param length
-	 *            maximal / forced length of String.
-	 * @param forceLength
-	 *            forces the String to be exact the given length instead of
-	 *            maximum
-	 * @return random String.
+	 * @return True if external storage is available for read and write, else
+	 *         false.
 	 */
-	public static String getRandomString(int length, boolean forceLength) {
-		SecureRandom rndm = new SecureRandom();
-		char[] c = new char[forceLength ? length : rndm.nextInt(length-1)+1];
-		for (int i = 0; i < c.length; i++) {
-			c[i] = (char) (rndm.nextInt(95) + 32);
+	public static boolean isExternalStorageWritable() {
+		String state = Environment.getExternalStorageState();
+		if (Environment.MEDIA_MOUNTED.equals(state)) {
+			return true;
 		}
-		return new String(c);
-	}
-
-	/**
-	 * Puts a 0x00 byte between each byte and another 2 0x00 bytes at the end of
-	 * a byte array.
-	 * 
-	 * @param bytes
-	 *            that need to be filled with 0x00.
-	 * @return filled byte array.
-	 */
-	public static byte[] fillWithZeroExtended(byte[] bytes) {
-		byte[] zeroBytes = fillWithZero(bytes);
-		byte[] newBytes = new byte[zeroBytes.length + 2];
-		newBytes = HelperUtils.concat(zeroBytes, new byte[] { 0x00, 0x00 });
-		return newBytes;
+		return false;
 	}
 
 	/**
-	 * Puts a 0x00 byte between each byte in a byte array.
+	 * Generates a random byte[] of a specified size
 	 * 
-	 * @param bytes
-	 *            that need to be filled with 0x00.
-	 * @return filled byte array.
+	 * @param size
+	 *            of the byte[]
+	 * @return random byte[]
 	 */
-	public static byte[] fillWithZero(byte[] bytes) {
-		byte[] newBytes = new byte[(bytes.length * 2)];
-		for (int i = 0, j = 0; i < bytes.length && j < newBytes.length; i++, j = j + 2) {
-			newBytes[j] = bytes[i];
-			newBytes[j + 1] = 0x00;
-		}
-		return newBytes;
+	public static byte[] randomBytes(int size) {
+		byte[] bytes = new byte[size];
+		SecureRandom rdm = new SecureRandom();
+		rdm.nextBytes(bytes);
+		return bytes;
 	}
 
 	/**
@@ -369,16 +337,51 @@ public final class HelperUtils {
 		}
 		return tmp;
 	}
-	
+
 	/**
-	 * Generates a random byte[] of a specified size
-	 * @param size of the byte[]
-	 * @return random byte[]
+	 * 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.
 	 */
-	public static byte[] randomBytes(int size) {
-		byte[] bytes = new byte[size];
-		SecureRandom rdm = new SecureRandom();
-		rdm.nextBytes(bytes);
-		return bytes;		
+	public static boolean uploadSingleRecord(Context context, Record record) {
+		// Create a https client. Uses MySSLSocketFactory to accept all
+		// certificates
+		HttpClient httpclient = HelperUtils.createHttpClient();
+		HttpPost httppost;
+		try {
+			// Create HttpPost
+			httppost = new HttpPost(PreferenceManager
+					.getDefaultSharedPreferences(context).getString(
+							"pref_upload", "https://ssi.cased.de"));
+			// Create JSON String of Record
+			StringEntity se = new StringEntity(record.toString(TraCINgFormatter
+					.getInstance()));
+			httppost.setEntity(se);
+			// Execute HttpPost
+			httpclient.execute(httppost);
+		} catch (Exception e) {
+			e.printStackTrace();
+			return false;
+		}
+		return true;
+	}
+
+	/**
+	 * Determines if a character is in ASCII between 32 and 126
+	 * 
+	 * @param character
+	 *            that is checked
+	 * @return true if the character is between 32 and 126, else false
+	 */
+	private static boolean isLetter(char character) {
+		return (character > 31 && character < 127);
+	}
+
+	private static byte[] unpackInetAddress(int bytes) {
+		return new byte[] { (byte) ((bytes) & 0xff),
+				(byte) ((bytes >>> 8) & 0xff), (byte) ((bytes >>> 16) & 0xff),
+				(byte) ((bytes >>> 24) & 0xff) };
 	}
 }

+ 0 - 57
src/de/tudarmstadt/informatik/hostage/io/ByteArrayReaderWriter.java

@@ -1,57 +0,0 @@
-package de.tudarmstadt.informatik.hostage.io;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.List;
-
-import de.tudarmstadt.informatik.hostage.wrapper.Packet;
-
-/**
- * Handles the reading and writing of the socket in- and outputstream for byte arrays
- * @author Mihai Plasoianu
- * @author Wulf Pfeiffer
- */
-public class ByteArrayReaderWriter implements ReaderWriter {
-
-	private BufferedInputStream in;
-	private BufferedOutputStream out;
-	private int SLEEPTIME;
-
-	/**
-	 * Constructor
-	 * @param in inputstream of socket
-	 * @param out outputstream of socket
-	 * @param SLEEPTIME time until timeout
-	 */
-	public ByteArrayReaderWriter(InputStream in, OutputStream out, int SLEEPTIME) {
-		this.in = new BufferedInputStream(in);
-		this.out = new BufferedOutputStream(out);
-		this.SLEEPTIME = SLEEPTIME;
-	}
-
-	
-	public Packet read() throws IOException {
-		int availableBytes;
-		while((availableBytes = in.available()) <= 0) {
-			try {
-				Thread.sleep(SLEEPTIME);
-			} catch (InterruptedException e) {
-				e.printStackTrace();
-			}
-		}
-		byte[] buffer = new byte[availableBytes];
-		in.read(buffer);
-		return new Packet(buffer);
-	}
-
-	
-	public void write(List<Packet> outputLine) throws IOException {
-		for (Packet o : outputLine) {
-			out.write(o.getMessage());
-			out.flush();
-		}
-	}
-}

+ 0 - 28
src/de/tudarmstadt/informatik/hostage/io/ReaderWriter.java

@@ -1,28 +0,0 @@
-package de.tudarmstadt.informatik.hostage.io;
-
-import java.io.IOException;
-import java.util.List;
-
-import de.tudarmstadt.informatik.hostage.wrapper.Packet;
-/**
- * Interface for a generic class that offers methods for read and write.
- * Is used to abstract the implementation details for String and Byte protocols.
- * @author Mihai Plasoianu 
- * @author Wulf Pfeiffer
- */
-public interface ReaderWriter {
-	/**
-	 * Method to read from a medium.
-	 * @return Returns the output.
-	 * @throws IOException
-	 */
-	Packet read() throws IOException;
-
-	/**
-	 * Method to write to a medium.
-	 * @param outputLine The input to write.
-	 * @throws IOException
-	 */
-	void write(List<Packet> outputLine) throws IOException;
-
-}

+ 0 - 48
src/de/tudarmstadt/informatik/hostage/io/StringReaderWriter.java

@@ -1,48 +0,0 @@
-package de.tudarmstadt.informatik.hostage.io;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.util.List;
-
-import de.tudarmstadt.informatik.hostage.wrapper.Packet;
-
-/**
- * Handles the reading and writing of the socket in- and outputstream for strings
- * @author Mihai Plasoianu
- * @author Wulf Pfeiffer
- */
-public class StringReaderWriter implements ReaderWriter {
-
-	private BufferedReader in;
-	private BufferedWriter out;
-
-	/**
-	 * Constructor
-	 * @param in inputstream
-	 * @param out outputstream
-	 */
-	public StringReaderWriter(InputStream in, OutputStream out) {
-		this.in = new BufferedReader(new InputStreamReader(in));
-		this.out = new BufferedWriter(new OutputStreamWriter(out));
-
-	}
-
-	
-	public Packet read() throws IOException {
-		return new Packet(in.readLine());
-	}
-
-	
-	public void write(List<Packet> outputLine) throws IOException {
-		for (Packet o : outputLine) {
-			out.write(o + "\n");
-			out.flush();
-		}
-	}
-
-}

+ 6 - 6
src/de/tudarmstadt/informatik/hostage/logging/LogResultReceiver.java

@@ -6,18 +6,18 @@ import android.os.ResultReceiver;
 
 public class LogResultReceiver extends ResultReceiver {
 
-	private Receiver mReceiver;
-
-	public void setReceiver(Receiver receiver) {
-		mReceiver = receiver;
+	public interface Receiver {
+		public void onReceiveResult(int resultCode, Bundle resultData);
 	}
 
+	private Receiver mReceiver;
+
 	public LogResultReceiver(Handler handler) {
 		super(handler);
 	}
 
-	public interface Receiver {
-		public void onReceiveResult(int resultCode, Bundle resultData);
+	public void setReceiver(Receiver receiver) {
+		mReceiver = receiver;
 	}
 
 	@Override

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

@@ -38,34 +38,36 @@ public class Logger extends IntentService {
 
 	private static final String RESULT_RECEIVER = "de.tudarmstadt.informatik.hostage.RESULT_RECEIVER";
 
-	public static void log(Context context, Record record) {
+	public static void deleteAll(Context context) {
 		Intent intent = new Intent(context, Logger.class);
-		intent.setAction(ACTION_LOG);
-		intent.putExtra(EXTRA_RECORD, record);
+		intent.setAction(ACTION_CLEAR_ALL);
 		context.startService(intent);
 	}
 
-	public static void getAllRecords(Context context, ResultReceiver receiver) {
+	public static void deleteByBssid(Context context, String bssid) {
 		Intent intent = new Intent(context, Logger.class);
-		intent.setAction(ACTION_GET_RECORD_ALL);
-		intent.putExtra(RESULT_RECEIVER, receiver);
+		intent.setAction(ACTION_CLEAR_BSSID);
+		intent.putExtra(EXTRA_BSSID, bssid);
 		context.startService(intent);
 	}
 
-	public static void getRecordOfEachAttack(Context context,
-			int lastUploadedAttackId, ResultReceiver receiver) {
+	public static void deleteByDate(Context context, long time) {
 		Intent intent = new Intent(context, Logger.class);
-		intent.setAction(ACTION_GET_RECORD_EACH);
-		intent.putExtra(EXTRA_PRIMITIVE, lastUploadedAttackId);
+		intent.setAction(ACTION_CLEAR_DATE);
+		intent.putExtra(EXTRA_PRIMITIVE, time);
+		context.startService(intent);
+	}
+
+	public static void getAllBssids(Context context, ResultReceiver receiver) {
+		Intent intent = new Intent(context, Logger.class);
+		intent.setAction(ACTION_GET_BSSID_ALL);
 		intent.putExtra(RESULT_RECEIVER, receiver);
 		context.startService(intent);
 	}
 
-	public static void getRecordOfAttackId(Context context, long attack_id,
-			ResultReceiver receiver) {
+	public static void getAllRecords(Context context, ResultReceiver receiver) {
 		Intent intent = new Intent(context, Logger.class);
-		intent.setAction(ACTION_GET_RECORD_ID);
-		intent.putExtra(EXTRA_PRIMITIVE, attack_id);
+		intent.setAction(ACTION_GET_RECORD_ALL);
 		intent.putExtra(RESULT_RECEIVER, receiver);
 		context.startService(intent);
 	}
@@ -86,33 +88,34 @@ public class Logger extends IntentService {
 		context.startService(intent);
 	}
 
-	public static void getMinAttackId(Context context, ResultReceiver receiver) {
+	public static void getMaxAttackId(Context context, ResultReceiver receiver) {
 		Intent intent = new Intent(context, Logger.class);
-		intent.setAction(ACTION_GET_ATTACK_MIN);
+		intent.setAction(ACTION_GET_ATTACK_MAX);
 		intent.putExtra(RESULT_RECEIVER, receiver);
 		context.startService(intent);
 	}
 
-	public static void getMaxAttackId(Context context, ResultReceiver receiver) {
+	public static void getMinAttackId(Context context, ResultReceiver receiver) {
 		Intent intent = new Intent(context, Logger.class);
-		intent.setAction(ACTION_GET_ATTACK_MAX);
+		intent.setAction(ACTION_GET_ATTACK_MIN);
 		intent.putExtra(RESULT_RECEIVER, receiver);
 		context.startService(intent);
 	}
 
-	public static void isBssidSeen(Context context, String protocol,
-			String bssid, ResultReceiver receiver) {
+	public static void getRecordOfAttackId(Context context, long attack_id,
+			ResultReceiver receiver) {
 		Intent intent = new Intent(context, Logger.class);
-		intent.setAction(ACTION_IS_BSSID_SEEN);
-		intent.putExtra(EXTRA_PROTOCOL, protocol);
-		intent.putExtra(EXTRA_BSSID, bssid);
+		intent.setAction(ACTION_GET_RECORD_ID);
+		intent.putExtra(EXTRA_PRIMITIVE, attack_id);
 		intent.putExtra(RESULT_RECEIVER, receiver);
 		context.startService(intent);
 	}
 
-	public static void getAllBssids(Context context, ResultReceiver receiver) {
+	public static void getRecordOfEachAttack(Context context,
+			int lastUploadedAttackId, ResultReceiver receiver) {
 		Intent intent = new Intent(context, Logger.class);
-		intent.setAction(ACTION_GET_BSSID_ALL);
+		intent.setAction(ACTION_GET_RECORD_EACH);
+		intent.putExtra(EXTRA_PRIMITIVE, lastUploadedAttackId);
 		intent.putExtra(RESULT_RECEIVER, receiver);
 		context.startService(intent);
 	}
@@ -126,23 +129,20 @@ public class Logger extends IntentService {
 		context.startService(intent);
 	}
 
-	public static void deleteByDate(Context context, long time) {
-		Intent intent = new Intent(context, Logger.class);
-		intent.setAction(ACTION_CLEAR_DATE);
-		intent.putExtra(EXTRA_PRIMITIVE, time);
-		context.startService(intent);
-	}
-
-	public static void deleteByBssid(Context context, String bssid) {
+	public static void isBssidSeen(Context context, String protocol,
+			String bssid, ResultReceiver receiver) {
 		Intent intent = new Intent(context, Logger.class);
-		intent.setAction(ACTION_CLEAR_BSSID);
+		intent.setAction(ACTION_IS_BSSID_SEEN);
+		intent.putExtra(EXTRA_PROTOCOL, protocol);
 		intent.putExtra(EXTRA_BSSID, bssid);
+		intent.putExtra(RESULT_RECEIVER, receiver);
 		context.startService(intent);
 	}
 
-	public static void deleteAll(Context context) {
+	public static void log(Context context, Record record) {
 		Intent intent = new Intent(context, Logger.class);
-		intent.setAction(ACTION_CLEAR_ALL);
+		intent.setAction(ACTION_LOG);
+		intent.putExtra(EXTRA_RECORD, record);
 		context.startService(intent);
 	}
 
@@ -158,6 +158,69 @@ public class Logger extends IntentService {
 		mDbHelper = new UglyDbHelper(getApplicationContext());
 	}
 
+	private boolean handleActionBssidSeen(String protocol, String bssid) {
+		return mDbHelper.bssidSeen(protocol, bssid);
+	}
+
+	/**
+	 * Delete all records.
+	 */
+	private void handleActionDeleteAll() {
+		mDbHelper.clearData();
+	}
+
+	private void handleActionDeleteByBssid(String bssid) {
+		mDbHelper.deleteByBSSID(bssid);
+	}
+
+	private void handleActionDeleteByDate(long time) {
+		mDbHelper.deleteByDate(time);
+	}
+
+	private String[] handleActionGetAllBssids() {
+		return mDbHelper.getAllBSSIDS();
+	}
+
+	private ArrayList<Record> handleActionGetAllRecords() {
+		return mDbHelper.getAllRecords();
+	}
+
+	private int handleActionGetAttackCount() {
+		return mDbHelper.getAttackCount();
+	}
+
+	private int handleActionGetAttackPerProtocolCount(String protocol) {
+		return mDbHelper.getAttackPerProtocolCount(protocol);
+	}
+
+	private long handleActionGetMaxAttackId() {
+		return mDbHelper.getHighestAttackId();
+	}
+
+	private long handleActionGetMinAttackId() {
+		return mDbHelper.getSmallestAttackId();
+	}
+
+	private Record handleActionGetRecordOfAttackId(long attack_id) {
+		return mDbHelper.getRecordOfAttackId(attack_id);
+	}
+
+	private ArrayList<Record> handleActionGetRecordOfEachAttack(
+			int lastUploadedAttackId) {
+		return mDbHelper.getRecordOfEachAttack(lastUploadedAttackId);
+	}
+
+	private String handleActionGetSsid(String bssid) {
+		return mDbHelper.getSSID(bssid);
+	}
+
+	/**
+	 * Log a record.
+	 */
+	private void handleActionLog(Record record) {
+		mDbHelper.addRecord(record);
+	}
+
 	@Override
 	protected void onHandleIntent(Intent intent) {
 		if (intent != null) {
@@ -255,67 +318,4 @@ public class Logger extends IntentService {
 		}
 	}
 
-	/**
-	 * Log a record.
-	 */
-	private void handleActionLog(Record record) {
-		mDbHelper.addRecord(record);
-	}
-
-	private ArrayList<Record> handleActionGetAllRecords() {
-		return mDbHelper.getAllRecords();
-	}
-
-	private ArrayList<Record> handleActionGetRecordOfEachAttack(
-			int lastUploadedAttackId) {
-		return mDbHelper.getRecordOfEachAttack(lastUploadedAttackId);
-	}
-
-	private Record handleActionGetRecordOfAttackId(long attack_id) {
-		return mDbHelper.getRecordOfAttackId(attack_id);
-	}
-
-	private int handleActionGetAttackCount() {
-		return mDbHelper.getAttackCount();
-	}
-
-	private int handleActionGetAttackPerProtocolCount(String protocol) {
-		return mDbHelper.getAttackPerProtocolCount(protocol);
-	}
-
-	private long handleActionGetMinAttackId() {
-		return mDbHelper.getSmallestAttackId();
-	}
-
-	private long handleActionGetMaxAttackId() {
-		return mDbHelper.getHighestAttackId();
-	}
-
-	private boolean handleActionBssidSeen(String protocol, String bssid) {
-		return mDbHelper.bssidSeen(protocol, bssid);
-	}
-
-	private String[] handleActionGetAllBssids() {
-		return mDbHelper.getAllBSSIDS();
-	}
-
-	private String handleActionGetSsid(String bssid) {
-		return mDbHelper.getSSID(bssid);
-	}
-
-	private void handleActionDeleteByDate(long time) {
-		mDbHelper.deleteByDate(time);
-	}
-
-	private void handleActionDeleteByBssid(String bssid) {
-		mDbHelper.deleteByBSSID(bssid);
-	}
-
-	/**
-	 * Delete all records.
-	 */
-	private void handleActionDeleteAll() {
-		mDbHelper.clearData();
-	}
-
 }

+ 149 - 116
src/de/tudarmstadt/informatik/hostage/logging/MyLocationManager.java

@@ -11,130 +11,163 @@ 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 Location newestLocation = null;
+
 	private static final int TWO_MINUTES = 1000 * 60 * 2;
 
-	
-	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);
+	public static Location getNewestLocation() {
+		return newestLocation;
 	}
 
 	// Define a listener that responds to location updates
 	LocationListener locationListener = new LocationListener() {
-	    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;
-	      }
-	    }
-
-	    public void onStatusChanged(String provider, int status, Bundle extras) {}
-
-	    public void onProviderEnabled(String provider) {}
-
-	    public void onProviderDisabled(String provider) {}
-	  };
-	
-
-
-	  /** 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;
-	  }
-	  
-	  /**
-	   * Start updating {@link de.tudarmstadt.informatik.hostage.logging.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);
-	  }
-	  
-	  /**
-	   * 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);
-	  }
-	   
-	  class StopTask extends TimerTask {
-	        public void run() {
-	        	 stopUpdates();
-	        }
-	    }
-	  
-	  public void stopUpdates(){
-		  locationManager.removeUpdates(locationListener);
-	  }
-
-	  public static Location getNewestLocation(){
-		  return newestLocation;
-	  }
+		@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.logging.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;
+	}
 }

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

@@ -47,39 +47,6 @@ public class Record implements Parcelable {
 	private double longitude;
 	private float accuracy;
 
-	@Override
-	public int describeContents() {
-		return 0;
-	}
-
-	@Override
-	public void writeToParcel(Parcel dest, int flags) {
-		// attack
-		dest.writeInt(id);
-		dest.writeLong(attack_id);
-		dest.writeLong(timestamp);
-		dest.writeString(protocol);
-		dest.writeString(type.name());
-		dest.writeString(packet);
-
-		// network
-		dest.writeString(localIP);
-		dest.writeString(localHost);
-		dest.writeInt(localPort);
-		dest.writeString(remoteIP);
-		dest.writeString(remoteHost);
-		dest.writeInt(remotePort);
-		dest.writeString(externalIP);
-		dest.writeString(bssid);
-		dest.writeString(ssid);
-
-		// location
-		dest.writeLong(timestampLocation);
-		dest.writeDouble(latitude);
-		dest.writeDouble(longitude);
-		dest.writeFloat(accuracy);
-	}
-
 	public static final Parcelable.Creator<Record> CREATOR = new Parcelable.Creator<Record>() {
 
 		@Override
@@ -123,156 +90,161 @@ public class Record implements Parcelable {
 		this.accuracy = source.readFloat();
 	}
 
-	public int getId() {
-		return id;
+	@Override
+	public int describeContents() {
+		return 0;
 	}
 
-	public void setId(int id) {
-		this.id = id;
+	public float getAccuracy() {
+		return accuracy;
 	}
 
 	public long getAttack_id() {
 		return attack_id;
 	}
 
-	public void setAttack_id(long attack_id) {
-		this.attack_id = attack_id;
+	public String getBssid() {
+		return bssid;
 	}
 
-	public long getTimestamp() {
-		return timestamp;
+	public String getExternalIP() {
+		return externalIP;
 	}
 
-	public void setTimestamp(long timestamp) {
-		this.timestamp = timestamp;
+	public int getId() {
+		return id;
 	}
 
-	public String getProtocol() {
-		return protocol;
+	public double getLatitude() {
+		return latitude;
 	}
 
-	public void setProtocol(String protocol) {
-		this.protocol = protocol;
+	public String getLocalHost() {
+		return localHost;
 	}
 
-	public TYPE getType() {
-		return type;
+	public String getLocalIP() {
+		return localIP;
 	}
 
-	public void setType(TYPE type) {
-		this.type = type;
+	public int getLocalPort() {
+		return localPort;
+	}
+
+	public double getLongitude() {
+		return longitude;
 	}
 
 	public String getPacket() {
 		return packet;
 	}
 
-	public void setPacket(String packet) {
-		this.packet = packet;
+	public String getProtocol() {
+		return protocol;
 	}
 
-	public String getLocalIP() {
-		return localIP;
+	public String getRemoteHost() {
+		return remoteHost;
 	}
 
-	public void setLocalIP(String localIP) {
-		this.localIP = localIP;
+	public String getRemoteIP() {
+		return remoteIP;
 	}
 
-	public String getLocalHost() {
-		return localHost;
+	public int getRemotePort() {
+		return remotePort;
 	}
 
-	public void setLocalHost(String localHost) {
-		this.localHost = localHost;
+	public String getSsid() {
+		return ssid;
 	}
 
-	public int getLocalPort() {
-		return localPort;
+	public long getTimestamp() {
+		return timestamp;
 	}
 
-	public void setLocalPort(int localPort) {
-		this.localPort = localPort;
+	public long getTimestampLocation() {
+		return timestampLocation;
 	}
 
-	public String getRemoteIP() {
-		return remoteIP;
+	public TYPE getType() {
+		return type;
 	}
 
-	public void setRemoteIP(String remoteIP) {
-		this.remoteIP = remoteIP;
+	public void setAccuracy(float accuracy) {
+		this.accuracy = accuracy;
 	}
 
-	public String getRemoteHost() {
-		return remoteHost;
+	public void setAttack_id(long attack_id) {
+		this.attack_id = attack_id;
 	}
 
-	public void setRemoteHost(String remoteHost) {
-		this.remoteHost = remoteHost;
+	public void setBssid(String bssid) {
+		this.bssid = bssid;
 	}
 
-	public int getRemotePort() {
-		return remotePort;
+	public void setExternalIP(String externalIP) {
+		this.externalIP = externalIP;
 	}
 
-	public void setRemotePort(int remotePort) {
-		this.remotePort = remotePort;
+	public void setId(int id) {
+		this.id = id;
 	}
 
-	public String getExternalIP() {
-		return externalIP;
+	public void setLatitude(double latitude) {
+		this.latitude = latitude;
 	}
 
-	public void setExternalIP(String externalIP) {
-		this.externalIP = externalIP;
+	public void setLocalHost(String localHost) {
+		this.localHost = localHost;
 	}
 
-	public String getBssid() {
-		return bssid;
+	public void setLocalIP(String localIP) {
+		this.localIP = localIP;
 	}
 
-	public void setBssid(String bssid) {
-		this.bssid = bssid;
+	public void setLocalPort(int localPort) {
+		this.localPort = localPort;
 	}
 
-	public String getSsid() {
-		return ssid;
+	public void setLongitude(double longitude) {
+		this.longitude = longitude;
 	}
 
-	public void setSsid(String ssid) {
-		this.ssid = ssid;
+	public void setPacket(String packet) {
+		this.packet = packet;
 	}
 
-	public long getTimestampLocation() {
-		return timestampLocation;
+	public void setProtocol(String protocol) {
+		this.protocol = protocol;
 	}
 
-	public void setTimestampLocation(long timestampLocation) {
-		this.timestampLocation = timestampLocation;
+	public void setRemoteHost(String remoteHost) {
+		this.remoteHost = remoteHost;
 	}
 
-	public double getLatitude() {
-		return latitude;
+	public void setRemoteIP(String remoteIP) {
+		this.remoteIP = remoteIP;
 	}
 
-	public void setLatitude(double latitude) {
-		this.latitude = latitude;
+	public void setRemotePort(int remotePort) {
+		this.remotePort = remotePort;
 	}
 
-	public double getLongitude() {
-		return longitude;
+	public void setSsid(String ssid) {
+		this.ssid = ssid;
 	}
 
-	public void setLongitude(double longitude) {
-		this.longitude = longitude;
+	public void setTimestamp(long timestamp) {
+		this.timestamp = timestamp;
 	}
 
-	public float getAccuracy() {
-		return accuracy;
+	public void setTimestampLocation(long timestampLocation) {
+		this.timestampLocation = timestampLocation;
 	}
 
-	public void setAccuracy(float accuracy) {
-		this.accuracy = accuracy;
+	public void setType(TYPE type) {
+		this.type = type;
 	}
 
 	@Override
@@ -287,4 +259,32 @@ public class Record implements Parcelable {
 		return formatter.format(this);
 	}
 
+	@Override
+	public void writeToParcel(Parcel dest, int flags) {
+		// attack
+		dest.writeInt(id);
+		dest.writeLong(attack_id);
+		dest.writeLong(timestamp);
+		dest.writeString(protocol);
+		dest.writeString(type.name());
+		dest.writeString(packet);
+
+		// network
+		dest.writeString(localIP);
+		dest.writeString(localHost);
+		dest.writeInt(localPort);
+		dest.writeString(remoteIP);
+		dest.writeString(remoteHost);
+		dest.writeInt(remotePort);
+		dest.writeString(externalIP);
+		dest.writeString(bssid);
+		dest.writeString(ssid);
+
+		// location
+		dest.writeLong(timestampLocation);
+		dest.writeDouble(latitude);
+		dest.writeDouble(longitude);
+		dest.writeFloat(accuracy);
+	}
+
 }

+ 315 - 331
src/de/tudarmstadt/informatik/hostage/logging/UglyDbHelper.java

@@ -59,66 +59,33 @@ public class UglyDbHelper extends SQLiteOpenHelper {
 	public static final String KEY_ACCURACY = "accuracy";
 
 	// Database sql create statements
-	private static final String CREATE_RECORD_TABLE = 
-			"CREATE TABLE " + TABLE_RECORDS + "(" 
-		   + KEY_ID + " INTEGER NOT NULL," 
-		   + KEY_ATTACK_ID + " INTEGER NOT NULL," 
-		   + KEY_TYPE + " TEXT," 
-		   + KEY_TIME + " INTEGER," 
-		   + KEY_PACKET + " TEXT," 
-		   + "FOREIGN KEY(" + KEY_ATTACK_ID + ") REFERENCES " + TABLE_ATTACK_INFO + "(" + KEY_ATTACK_ID + ")," 
-		   + "PRIMARY KEY(" + KEY_ID + ", " + KEY_ATTACK_ID + ")" 
-		   + ")";
-
-	private static final String CREATE_ATTACK_INFO_TABLE = 
-			"CREATE TABLE " + TABLE_ATTACK_INFO + "(" 
-		   + KEY_ATTACK_ID + " INTEGER PRIMARY KEY,"
-		   + KEY_PROTOCOL + " TEXT," 
-		   + KEY_EXTERNAL_IP + " TEXT,"
-		   + KEY_LOCAL_IP + " BLOB," 
-		   + KEY_LOCAL_HOSTNAME + " TEXT,"
-		   + KEY_LOCAL_PORT + " INTEGER," 
-		   + KEY_REMOTE_IP + " BLOB," 
-		   + KEY_REMOTE_HOSTNAME + " TEXT,"
-		   + KEY_REMOTE_PORT + " INTEGER," 
-		   + KEY_BSSID + " TEXT,"
-		   + "FOREIGN KEY(" + KEY_BSSID + ") REFERENCES " + TABLE_BSSIDS + "(" + KEY_BSSID + ")"
-		   + ")";
-
-	private static final String CREATE_BSSID_TABLE = 
-			"CREATE TABLE " + TABLE_BSSIDS + "(" 
-	       + KEY_BSSID + " TEXT PRIMARY KEY," 
-	       + KEY_SSID + " TEXT," 
-	       + KEY_LATITUDE + " INTEGER," 
-	       + KEY_LONGITUDE + " INTEGER,"
-	       + KEY_ACCURACY + " INTEGER," 
-	       + KEY_TIME + " INTEGER"
-	       + ")";
+	private static final String CREATE_RECORD_TABLE = "CREATE TABLE "
+			+ TABLE_RECORDS + "(" + KEY_ID + " INTEGER NOT NULL,"
+			+ KEY_ATTACK_ID + " INTEGER NOT NULL," + KEY_TYPE + " TEXT,"
+			+ KEY_TIME + " INTEGER," + KEY_PACKET + " TEXT," + "FOREIGN KEY("
+			+ KEY_ATTACK_ID + ") REFERENCES " + TABLE_ATTACK_INFO + "("
+			+ KEY_ATTACK_ID + ")," + "PRIMARY KEY(" + KEY_ID + ", "
+			+ KEY_ATTACK_ID + ")" + ")";
+
+	private static final String CREATE_ATTACK_INFO_TABLE = "CREATE TABLE "
+			+ TABLE_ATTACK_INFO + "(" + KEY_ATTACK_ID + " INTEGER PRIMARY KEY,"
+			+ KEY_PROTOCOL + " TEXT," + KEY_EXTERNAL_IP + " TEXT,"
+			+ KEY_LOCAL_IP + " BLOB," + KEY_LOCAL_HOSTNAME + " TEXT,"
+			+ KEY_LOCAL_PORT + " INTEGER," + KEY_REMOTE_IP + " BLOB,"
+			+ KEY_REMOTE_HOSTNAME + " TEXT," + KEY_REMOTE_PORT + " INTEGER,"
+			+ KEY_BSSID + " TEXT," + "FOREIGN KEY(" + KEY_BSSID
+			+ ") REFERENCES " + TABLE_BSSIDS + "(" + KEY_BSSID + ")" + ")";
+
+	private static final String CREATE_BSSID_TABLE = "CREATE TABLE "
+			+ TABLE_BSSIDS + "(" + KEY_BSSID + " TEXT PRIMARY KEY," + KEY_SSID
+			+ " TEXT," + KEY_LATITUDE + " INTEGER," + KEY_LONGITUDE
+			+ " INTEGER," + KEY_ACCURACY + " INTEGER," + KEY_TIME + " INTEGER"
+			+ ")";
 
 	public UglyDbHelper(Context context) {
 		super(context, DATABASE_NAME, null, DATABASE_VERSION);
 	}
 
-	// Creating Tables
-	@Override
-	public void onCreate(SQLiteDatabase db) {
-		db.execSQL(CREATE_BSSID_TABLE);
-		db.execSQL(CREATE_ATTACK_INFO_TABLE);
-		db.execSQL(CREATE_RECORD_TABLE);
-	}
-
-	// Upgrading database
-	@Override
-	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
-		// Drop older table if existed
-		db.execSQL("DROP TABLE IF EXISTS " + TABLE_RECORDS);
-		db.execSQL("DROP TABLE IF EXISTS " + TABLE_ATTACK_INFO);
-		db.execSQL("DROP TABLE IF EXISTS " + TABLE_BSSIDS);
-		
-		// Create tables again
-		onCreate(db);
-	}
-
 	/**
 	 * Adds a given {@link Record} to the database.
 	 * 
@@ -145,7 +112,8 @@ public class UglyDbHelper extends SQLiteOpenHelper {
 		attackValues.put(KEY_LOCAL_PORT, record.getLocalPort());
 		attackValues.put(KEY_REMOTE_IP, record.getRemoteIP()); // Log Remote IP
 		attackValues.put(KEY_REMOTE_HOSTNAME, record.getRemoteHost());
-		attackValues.put(KEY_REMOTE_PORT, record.getRemotePort()); // Log Remote Port
+		attackValues.put(KEY_REMOTE_PORT, record.getRemotePort()); // Log Remote
+																	// Port
 		attackValues.put(KEY_BSSID, record.getBssid());
 
 		ContentValues recordValues = new ContentValues();
@@ -165,169 +133,128 @@ public class UglyDbHelper extends SQLiteOpenHelper {
 	}
 
 	/**
-	 * Creates a {@link Record} from a Cursor. If the cursor does not show to a
-	 * valid data structure a runtime exception is thrown.
+	 * Determines if a network with given BSSID has already been recorded as
+	 * malicious.
 	 * 
-	 * @param cursor
-	 * @return Returns the created {@link Record} .
+	 * @param BSSID
+	 *            The BSSID of the network.
+	 * @return True if an attack has been recorded in a network with the given
+	 *         BSSID, else false.
 	 */
-	private Record createRecord(Cursor cursor) {
-		Record record = new Record();
-		record.setId(Integer.parseInt(cursor.getString(0)));
-		record.setAttack_id(cursor.getLong(1));
-		record.setType(cursor.getString(2).equals("SEND") ? TYPE.SEND : TYPE.RECEIVE);
-		record.setTimestamp(cursor.getLong(3));
-		record.setPacket(cursor.getString(4));
-		record.setProtocol(cursor.getString(5));
-		record.setExternalIP(cursor.getString(6));
-		
-		record.setLocalIP(cursor.getString(7));
-		record.setLocalHost(cursor.getString(8));
-		record.setLocalPort(Integer.parseInt(cursor.getString(9)));
-		
-		record.setRemoteIP(cursor.getString(10));
-		record.setRemoteHost(cursor.getString(11));
-		record.setRemotePort(Integer.parseInt(cursor.getString(12)));
-		
-		record.setBssid(cursor.getString(13));
-		record.setSsid(cursor.getString(14));
-		record.setLatitude(Double.parseDouble(cursor.getString(15)));
-		record.setLongitude(Double.parseDouble(cursor.getString(16)));
-		record.setAccuracy(Float.parseFloat(cursor.getString(17)));
-		record.setTimestampLocation(cursor.getLong(18));
-
-		return record;
+	public boolean bssidSeen(String BSSID) {
+		String countQuery = "SELECT  * FROM " + TABLE_BSSIDS + " WHERE "
+				+ KEY_BSSID + " = " + "'" + BSSID + "'";
+		SQLiteDatabase db = this.getReadableDatabase();
+		Cursor cursor = db.rawQuery(countQuery, null);
+		int result = cursor.getCount();
+		cursor.close();
+		db.close();
+		return result > 0;
 	}
 
 	/**
-	 * Gets a single {@link Record} with the given ID from the database.
+	 * Determines if an attack has been recorded on a specific protocol in a
+	 * network with a given BSSID.
 	 * 
-	 * @param id
-	 *            The ID of the {@link Record};
-	 * @return The {@link Record}.
+	 * @param protocol
+	 *            The
+	 *            {@link de.tudarmstadt.informatik.hostage.protocol.Protocol
+	 *            Protocol} to inspect.
+	 * @param BSSID
+	 *            The BSSID of the network.
+	 * @return True if an attack on the given protocol has been recorded in a
+	 *         network with the given BSSID, else false.
 	 */
-	public Record getRecord(int id) {
-		String selectQuery = "SELECT  * FROM " + TABLE_RECORDS
-						  + " NATURAL JOIN " + TABLE_ATTACK_INFO 
-						  + " NATURAL JOIN "+ TABLE_BSSIDS 
-						  + " WHERE " + KEY_ID + " = " + id;
+	public boolean bssidSeen(String protocol, String BSSID) {
+		String countQuery = "SELECT  * FROM " + TABLE_ATTACK_INFO
+				+ " NATURAL JOIN " + TABLE_BSSIDS + " WHERE " + KEY_PROTOCOL
+				+ " = " + "'" + protocol + "'" + " AND " + KEY_BSSID + " = "
+				+ "'" + BSSID + "'";
 		SQLiteDatabase db = this.getReadableDatabase();
-
-		Cursor cursor = db.rawQuery(selectQuery, null);
-		Record record = null;
-		if (cursor.moveToFirst()) {
-			record = createRecord(cursor);
-		}
-
+		Cursor cursor = db.rawQuery(countQuery, null);
+		int result = cursor.getCount();
 		cursor.close();
 		db.close();
-		// return contact
-		return record;
+		return result > 0;
 	}
 
 	/**
-	 * Gets all {@link Record Records} saved in the database.
-	 * 
-	 * @return A ArrayList of all the {@link Record Records} in the Database.
+	 * Deletes all records from {@link #TABLE_RECORDS}.
 	 */
-	public ArrayList<Record> getAllRecords() {
-		ArrayList<Record> recordList = new ArrayList<Record>();
-		// Select All Query
-		String selectQuery = "SELECT  * FROM " + TABLE_RECORDS
-						  + " NATURAL JOIN " + TABLE_ATTACK_INFO 
-						  + " NATURAL JOIN " + TABLE_BSSIDS;
-
-		SQLiteDatabase db = this.getWritableDatabase();
-		Cursor cursor = db.rawQuery(selectQuery, null);
-
-		Log.i("Database", "Start loop");
-		// looping through all rows and adding to list
-		if (cursor.moveToFirst()) {
-			do {
-				Log.i("Database", "Add Record");
-				Record record = createRecord(cursor);
-				// Adding record to list
-				recordList.add(record);
-			} while (cursor.moveToNext());
-		}
-		cursor.close();
+	public void clearData() {
+		SQLiteDatabase db = this.getReadableDatabase();
+		db.delete(TABLE_RECORDS, null, null);
+		db.delete(TABLE_ATTACK_INFO, null, null);
 		db.close();
-		// return record list
-		return recordList;
 	}
 
 	/**
-	 * Gets a single {@link Record} with the given attack id from the database.
+	 * Deletes all records from {@link #TABLE_RECORDS} with a specific BSSID.
 	 * 
-	 * @param attack_id
-	 *            The attack id of the {@link Record};
-	 * @return The {@link Record}.
+	 * @param bssid
+	 *            The BSSID to match against.
 	 */
-	public Record getRecordOfAttackId(long attack_id) {
-		String selectQuery = "SELECT  * FROM " + TABLE_RECORDS
-						  + " NATURAL JOIN " + TABLE_ATTACK_INFO 
-						  + " NATURAL JOIN " + TABLE_BSSIDS 
-						  + " WHERE " + KEY_ATTACK_ID + " = " + attack_id 
-						  + " GROUP BY " + KEY_ATTACK_ID;
+	public void deleteByBSSID(String bssid) {
 		SQLiteDatabase db = this.getReadableDatabase();
-		Cursor cursor = db.rawQuery(selectQuery, null);
-		Record record = null;
-
-		if (cursor.moveToFirst()) {
-			record = createRecord(cursor);
-		}
-		cursor.close();
+		db.delete(TABLE_RECORDS, KEY_BSSID + " = ?", new String[] { bssid });
+		db.delete(TABLE_ATTACK_INFO, KEY_BSSID + " = ?", new String[] { bssid });
+		db.close();
+	}
 
-		// return record list
+	// TODO Delete statement �berarbeiten
+	/**
+	 * Deletes all records from {@link #TABLE_RECORDS} with a time stamp smaller
+	 * then the given
+	 * 
+	 * @param date
+	 *            A Date represented in milliseconds.
+	 */
+	public void deleteByDate(long date) {
+		SQLiteDatabase db = this.getReadableDatabase();
+		String deleteQuery = "DELETE  FROM " + TABLE_RECORDS + " WHERE "
+				+ KEY_TIME + " < " + date;
+		// TODO Delete statement �berarbeiten
+		// String deleteQuery2 = "DELETE "
+		db.execSQL(deleteQuery);
 		db.close();
-		return record;
 	}
 
 	/**
-	 * Gets all received {@link Record Records} for every attack identified by
-	 * its attack id and ordered by date.
+	 * Returns a String array with all BSSIDs stored in the database.
 	 * 
-	 * @return A ArrayList with all received {@link Record Records} for each
-	 *         attack id in the Database.
+	 * @return String[] of all recorded BSSIDs.
 	 */
-	public ArrayList<Record> getAllReceivedRecordsOfEachAttack() {
-		ArrayList<Record> recordList = new ArrayList<Record>();
-		String selectQuery = "SELECT  * FROM " + TABLE_RECORDS
-						  + " NATURAL JOIN " + TABLE_ATTACK_INFO 
-						  + " NATURAL JOIN " + TABLE_BSSIDS 
-						  + " WHERE " + KEY_TYPE + "='RECEIVE'" 
-						  + " ORDER BY " + KEY_TIME;
+	public String[] getAllBSSIDS() {
+		String selectQuery = "SELECT  * FROM " + TABLE_BSSIDS;
 		SQLiteDatabase db = this.getReadableDatabase();
 		Cursor cursor = db.rawQuery(selectQuery, null);
-
+		String[] bssidList = new String[cursor.getCount()];
+		int counter = 0;
 		// looping through all rows and adding to list
 		if (cursor.moveToFirst()) {
 			do {
-				Record record = createRecord(cursor);
-				// Adding record to list
-				recordList.add(record);
+				bssidList[counter] = cursor.getString(0);
+				counter++;
 			} while (cursor.moveToNext());
 		}
 		cursor.close();
-
-		// return record list
 		db.close();
-		return recordList;
+		return bssidList;
 	}
 
 	/**
-	 * Gets a representative {@link Record} for every attack identified by its
-	 * attack id.
+	 * Gets all received {@link Record Records} for every attack identified by
+	 * its attack id and ordered by date.
 	 * 
-	 * @return A ArrayList with one {@link Record Records} for each attack id in
-	 *         the Database.
+	 * @return A ArrayList with all received {@link Record Records} for each
+	 *         attack id in the Database.
 	 */
-	public ArrayList<Record> getRecordOfEachAttack() {
+	public ArrayList<Record> getAllReceivedRecordsOfEachAttack() {
 		ArrayList<Record> recordList = new ArrayList<Record>();
 		String selectQuery = "SELECT  * FROM " + TABLE_RECORDS
-						  + " NATURAL JOIN " + TABLE_ATTACK_INFO 
-						  + " NATURAL JOIN " + TABLE_BSSIDS 
-						  + " GROUP BY " + KEY_ATTACK_ID;
+				+ " NATURAL JOIN " + TABLE_ATTACK_INFO + " NATURAL JOIN "
+				+ TABLE_BSSIDS + " WHERE " + KEY_TYPE + "='RECEIVE'"
+				+ " ORDER BY " + KEY_TIME;
 		SQLiteDatabase db = this.getReadableDatabase();
 		Cursor cursor = db.rawQuery(selectQuery, null);
 
@@ -347,56 +274,36 @@ public class UglyDbHelper extends SQLiteOpenHelper {
 	}
 
 	/**
-	 * Gets a representative {@link Record} for every attack with a higher
-	 * attack id than the specified.
+	 * Gets all {@link Record Records} saved in the database.
 	 * 
-	 * @param attack_id
-	 *            The attack id to match the query against.
-	 * @return A ArrayList with one {@link Record Records} for each attack id
-	 *         higher than the given.
+	 * @return A ArrayList of all the {@link Record Records} in the Database.
 	 */
-	public ArrayList<Record> getRecordOfEachAttack(long attack_id) {
+	public ArrayList<Record> getAllRecords() {
 		ArrayList<Record> recordList = new ArrayList<Record>();
+		// Select All Query
 		String selectQuery = "SELECT  * FROM " + TABLE_RECORDS
-						  + " NATURAL JOIN " + TABLE_ATTACK_INFO 
-						  + " NATURAL JOIN " + TABLE_BSSIDS 
-						  + " WHERE " + KEY_ATTACK_ID + " > " + attack_id 
-						  + " GROUP BY " + KEY_ATTACK_ID;
-		SQLiteDatabase db = this.getReadableDatabase();
+				+ " NATURAL JOIN " + TABLE_ATTACK_INFO + " NATURAL JOIN "
+				+ TABLE_BSSIDS;
+
+		SQLiteDatabase db = this.getWritableDatabase();
 		Cursor cursor = db.rawQuery(selectQuery, null);
 
+		Log.i("Database", "Start loop");
 		// looping through all rows and adding to list
 		if (cursor.moveToFirst()) {
 			do {
+				Log.i("Database", "Add Record");
 				Record record = createRecord(cursor);
 				// Adding record to list
 				recordList.add(record);
 			} while (cursor.moveToNext());
 		}
 		cursor.close();
-
-		// return count
 		db.close();
+		// return record list
 		return recordList;
 	}
 
-	/**
-	 * Determines the number of {@link Record Records} in the database.
-	 * 
-	 * @return The number of {@link Record Records} in the database.
-	 */
-	public int getRecordCount() {
-		String countQuery = "SELECT  * FROM " + TABLE_RECORDS;
-		SQLiteDatabase db = this.getReadableDatabase();
-		Cursor cursor = db.rawQuery(countQuery, null);
-		int result = cursor.getCount();
-		cursor.close();
-
-		// return count
-		db.close();
-		return result;
-	}
-
 	/**
 	 * Determines the number of different attack_ids in the database.
 	 * 
@@ -437,28 +344,6 @@ public class UglyDbHelper extends SQLiteOpenHelper {
 		return result;
 	}
 
-	/**
-	 * Determines the smallest attack id stored in the database.
-	 * 
-	 * @return The smallest attack id stored in the database.
-	 */
-	public long getSmallestAttackId() {
-		String selectQuery = "SELECT MIN(" + KEY_ATTACK_ID + ") FROM "
-				+ TABLE_ATTACK_INFO;
-		SQLiteDatabase db = this.getReadableDatabase();
-		Cursor cursor = db.rawQuery(selectQuery, null);
-		int result;
-
-		if (cursor.moveToFirst()) {
-			result = cursor.getInt(0);
-		} else {
-			result = -1;
-		}
-		cursor.close();
-		db.close();
-		return result;
-	}
-
 	/**
 	 * Determines the highest attack id stored in the database.
 	 * 
@@ -481,164 +366,235 @@ public class UglyDbHelper extends SQLiteOpenHelper {
 		return result;
 	}
 
-	/**
-	 * Determines if a network with given BSSID has already been recorded as
-	 * malicious.
-	 * 
-	 * @param BSSID
-	 *            The BSSID of the network.
-	 * @return True if an attack has been recorded in a network with the given
-	 *         BSSID, else false.
+	public ArrayList<HashMap<String, Object>> getNetworkInformation() {
+		String selectQuery = "SELECT  * FROM " + TABLE_BSSIDS;
+		SQLiteDatabase db = this.getReadableDatabase();
+		Cursor cursor = db.rawQuery(selectQuery, null);
+
+		ArrayList<HashMap<String, Object>> networkInformation = new ArrayList<HashMap<String, Object>>();
+
+		// looping through all rows and adding to list
+		if (cursor.moveToFirst()) {
+			do {
+				HashMap<String, Object> values = new HashMap<String, Object>();
+				values.put(KEY_BSSID, cursor.getString(0));
+				values.put(KEY_SSID, cursor.getString(1));
+				values.put(KEY_LATITUDE,
+						Double.parseDouble(cursor.getString(2)));
+				values.put(KEY_LONGITUDE,
+						Double.parseDouble(cursor.getString(3)));
+				values.put(KEY_ACCURACY, Float.parseFloat(cursor.getString(4)));
+				values.put(KEY_TIME, cursor.getLong(5));
+				networkInformation.add(values);
+			} while (cursor.moveToNext());
+		}
+
+		cursor.close();
+		db.close();
+		return networkInformation;
+	}
+
+	/**
+	 * Gets a single {@link Record} with the given ID from the database.
+	 * 
+	 * @param id
+	 *            The ID of the {@link Record};
+	 * @return The {@link Record}.
 	 */
-	public boolean bssidSeen(String BSSID) {
-		String countQuery = "SELECT  * FROM " + TABLE_BSSIDS + " WHERE "
-				+ KEY_BSSID + " = " + "'" + BSSID + "'";
+	public Record getRecord(int id) {
+		String selectQuery = "SELECT  * FROM " + TABLE_RECORDS
+				+ " NATURAL JOIN " + TABLE_ATTACK_INFO + " NATURAL JOIN "
+				+ TABLE_BSSIDS + " WHERE " + KEY_ID + " = " + id;
 		SQLiteDatabase db = this.getReadableDatabase();
-		Cursor cursor = db.rawQuery(countQuery, null);
-		int result = cursor.getCount();
+
+		Cursor cursor = db.rawQuery(selectQuery, null);
+		Record record = null;
+		if (cursor.moveToFirst()) {
+			record = createRecord(cursor);
+		}
+
 		cursor.close();
 		db.close();
-		return result > 0;
+		// return contact
+		return record;
 	}
 
 	/**
-	 * Determines if an attack has been recorded on a specific protocol in a
-	 * network with a given BSSID.
+	 * Determines the number of {@link Record Records} in the database.
 	 * 
-	 * @param protocol
-	 *            The
-	 *            {@link de.tudarmstadt.informatik.hostage.protocol.Protocol
-	 *            Protocol} to inspect.
-	 * @param BSSID
-	 *            The BSSID of the network.
-	 * @return True if an attack on the given protocol has been recorded in a
-	 *         network with the given BSSID, else false.
+	 * @return The number of {@link Record Records} in the database.
 	 */
-	public boolean bssidSeen(String protocol, String BSSID) {
-		String countQuery = "SELECT  * FROM " + TABLE_ATTACK_INFO
-				+ " NATURAL JOIN " + TABLE_BSSIDS + " WHERE " + KEY_PROTOCOL
-				+ " = " + "'" + protocol + "'" + " AND " + KEY_BSSID + " = "
-				+ "'" + BSSID + "'";
+	public int getRecordCount() {
+		String countQuery = "SELECT  * FROM " + TABLE_RECORDS;
 		SQLiteDatabase db = this.getReadableDatabase();
 		Cursor cursor = db.rawQuery(countQuery, null);
 		int result = cursor.getCount();
 		cursor.close();
+
+		// return count
 		db.close();
-		return result > 0;
+		return result;
 	}
 
 	/**
-	 * Returns a String array with all BSSIDs stored in the database.
+	 * Gets a single {@link Record} with the given attack id from the database.
 	 * 
-	 * @return String[] of all recorded BSSIDs.
+	 * @param attack_id
+	 *            The attack id of the {@link Record};
+	 * @return The {@link Record}.
 	 */
-	public String[] getAllBSSIDS() {
-		String selectQuery = "SELECT  * FROM " + TABLE_BSSIDS;
+	public Record getRecordOfAttackId(long attack_id) {
+		String selectQuery = "SELECT  * FROM " + TABLE_RECORDS
+				+ " NATURAL JOIN " + TABLE_ATTACK_INFO + " NATURAL JOIN "
+				+ TABLE_BSSIDS + " WHERE " + KEY_ATTACK_ID + " = " + attack_id
+				+ " GROUP BY " + KEY_ATTACK_ID;
 		SQLiteDatabase db = this.getReadableDatabase();
 		Cursor cursor = db.rawQuery(selectQuery, null);
-		String[] bssidList = new String[cursor.getCount()];
-		int counter = 0;
-		// looping through all rows and adding to list
+		Record record = null;
+
 		if (cursor.moveToFirst()) {
-			do {
-				bssidList[counter] = cursor.getString(0);
-				counter++;
-			} while (cursor.moveToNext());
+			record = createRecord(cursor);
 		}
 		cursor.close();
+
+		// return record list
 		db.close();
-		return bssidList;
+		return record;
 	}
 
 	/**
-	 * Gets the last recorded SSID to a given BSSID.
+	 * Gets a representative {@link Record} for every attack identified by its
+	 * attack id.
 	 * 
-	 * @param bssid
-	 *            The BSSID to match against.
-	 * @return A String of the last SSID or null if the BSSID is not in the
-	 *         database.
+	 * @return A ArrayList with one {@link Record Records} for each attack id in
+	 *         the Database.
 	 */
-	public String getSSID(String bssid) {
-		String selectQuery = "SELECT " + KEY_SSID + " FROM " + TABLE_BSSIDS
-				+ " WHERE " + KEY_BSSID + " = " + "'" + bssid + "'";
+	public ArrayList<Record> getRecordOfEachAttack() {
+		ArrayList<Record> recordList = new ArrayList<Record>();
+		String selectQuery = "SELECT  * FROM " + TABLE_RECORDS
+				+ " NATURAL JOIN " + TABLE_ATTACK_INFO + " NATURAL JOIN "
+				+ TABLE_BSSIDS + " GROUP BY " + KEY_ATTACK_ID;
 		SQLiteDatabase db = this.getReadableDatabase();
 		Cursor cursor = db.rawQuery(selectQuery, null);
-		String ssid = null;
+
+		// looping through all rows and adding to list
 		if (cursor.moveToFirst()) {
-			ssid = cursor.getString(0);
+			do {
+				Record record = createRecord(cursor);
+				// Adding record to list
+				recordList.add(record);
+			} while (cursor.moveToNext());
 		}
 		cursor.close();
+
+		// return record list
 		db.close();
-		return ssid;
+		return recordList;
 	}
 
 	/**
-	 * Deletes all records from {@link #TABLE_RECORDS} with a specific BSSID.
+	 * Gets a representative {@link Record} for every attack with a higher
+	 * attack id than the specified.
 	 * 
-	 * @param bssid
-	 *            The BSSID to match against.
+	 * @param attack_id
+	 *            The attack id to match the query against.
+	 * @return A ArrayList with one {@link Record Records} for each attack id
+	 *         higher than the given.
 	 */
-	public void deleteByBSSID(String bssid) {
+	public ArrayList<Record> getRecordOfEachAttack(long attack_id) {
+		ArrayList<Record> recordList = new ArrayList<Record>();
+		String selectQuery = "SELECT  * FROM " + TABLE_RECORDS
+				+ " NATURAL JOIN " + TABLE_ATTACK_INFO + " NATURAL JOIN "
+				+ TABLE_BSSIDS + " WHERE " + KEY_ATTACK_ID + " > " + attack_id
+				+ " GROUP BY " + KEY_ATTACK_ID;
 		SQLiteDatabase db = this.getReadableDatabase();
-		db.delete(TABLE_RECORDS, KEY_BSSID + " = ?", new String[] { bssid });
-		db.delete(TABLE_ATTACK_INFO, KEY_BSSID + " = ?", new String[] { bssid });
+		Cursor cursor = db.rawQuery(selectQuery, null);
+
+		// looping through all rows and adding to list
+		if (cursor.moveToFirst()) {
+			do {
+				Record record = createRecord(cursor);
+				// Adding record to list
+				recordList.add(record);
+			} while (cursor.moveToNext());
+		}
+		cursor.close();
+
+		// return count
 		db.close();
+		return recordList;
 	}
 
-	// TODO Delete statement �berarbeiten
 	/**
-	 * Deletes all records from {@link #TABLE_RECORDS} with a time stamp smaller
-	 * then the given
+	 * Determines the smallest attack id stored in the database.
 	 * 
-	 * @param date
-	 *            A Date represented in milliseconds.
+	 * @return The smallest attack id stored in the database.
 	 */
-	public void deleteByDate(long date) {
+	public long getSmallestAttackId() {
+		String selectQuery = "SELECT MIN(" + KEY_ATTACK_ID + ") FROM "
+				+ TABLE_ATTACK_INFO;
 		SQLiteDatabase db = this.getReadableDatabase();
-		String deleteQuery = "DELETE  FROM " + TABLE_RECORDS + " WHERE "
-				+ KEY_TIME + " < " + date;
-		// TODO Delete statement �berarbeiten
-		// String deleteQuery2 = "DELETE "
-		db.execSQL(deleteQuery);
+		Cursor cursor = db.rawQuery(selectQuery, null);
+		int result;
+
+		if (cursor.moveToFirst()) {
+			result = cursor.getInt(0);
+		} else {
+			result = -1;
+		}
+		cursor.close();
 		db.close();
+		return result;
 	}
 
 	/**
-	 * Deletes all records from {@link #TABLE_RECORDS}.
+	 * Gets the last recorded SSID to a given BSSID.
+	 * 
+	 * @param bssid
+	 *            The BSSID to match against.
+	 * @return A String of the last SSID or null if the BSSID is not in the
+	 *         database.
 	 */
-	public void clearData() {
+	public String getSSID(String bssid) {
+		String selectQuery = "SELECT " + KEY_SSID + " FROM " + TABLE_BSSIDS
+				+ " WHERE " + KEY_BSSID + " = " + "'" + bssid + "'";
 		SQLiteDatabase db = this.getReadableDatabase();
-		db.delete(TABLE_RECORDS, null, null);
-		db.delete(TABLE_ATTACK_INFO, null, null);
+		Cursor cursor = db.rawQuery(selectQuery, null);
+		String ssid = null;
+		if (cursor.moveToFirst()) {
+			ssid = cursor.getString(0);
+		}
+		cursor.close();
 		db.close();
+		return ssid;
 	}
 
-	public ArrayList<HashMap<String, Object>> getNetworkInformation() {
-		String selectQuery = "SELECT  * FROM " + TABLE_BSSIDS;
-		SQLiteDatabase db = this.getReadableDatabase();
-		Cursor cursor = db.rawQuery(selectQuery, null);
+	// Creating Tables
+	@Override
+	public void onCreate(SQLiteDatabase db) {
+		db.execSQL(CREATE_BSSID_TABLE);
+		db.execSQL(CREATE_ATTACK_INFO_TABLE);
+		db.execSQL(CREATE_RECORD_TABLE);
+	}
 
-		ArrayList<HashMap<String, Object>> networkInformation = new ArrayList<HashMap<String, Object>>();
+	// Upgrading database
+	@Override
+	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+		// Drop older table if existed
+		db.execSQL("DROP TABLE IF EXISTS " + TABLE_RECORDS);
+		db.execSQL("DROP TABLE IF EXISTS " + TABLE_ATTACK_INFO);
+		db.execSQL("DROP TABLE IF EXISTS " + TABLE_BSSIDS);
 
-		// looping through all rows and adding to list
-		if (cursor.moveToFirst()) {
-			do {
-				HashMap<String, Object> values = new HashMap<String, Object>();
-				values.put(KEY_BSSID, cursor.getString(0));
-				values.put(KEY_SSID, cursor.getString(1));
-				values.put(KEY_LATITUDE,
-						Double.parseDouble(cursor.getString(2)));
-				values.put(KEY_LONGITUDE,
-						Double.parseDouble(cursor.getString(3)));
-				values.put(KEY_ACCURACY, Float.parseFloat(cursor.getString(4)));
-				values.put(KEY_TIME, cursor.getLong(5));
-				networkInformation.add(values);
-			} while (cursor.moveToNext());
-		}
+		// Create tables again
+		onCreate(db);
+	}
 
-		cursor.close();
-		db.close();
-		return networkInformation;
+	public void updateNetworkInformation(
+			ArrayList<HashMap<String, Object>> networkInformation) {
+		Log.i("DatabaseHandler", "Starte updating");
+		for (HashMap<String, Object> values : networkInformation) {
+			updateNetworkInformation(values);
+		}
 	}
 
 	public void updateNetworkInformation(
@@ -673,11 +629,39 @@ public class UglyDbHelper extends SQLiteOpenHelper {
 		db.close();
 	}
 
-	public void updateNetworkInformation(
-			ArrayList<HashMap<String, Object>> networkInformation) {
-		Log.i("DatabaseHandler", "Starte updating");
-		for (HashMap<String, Object> values : networkInformation) {
-			updateNetworkInformation(values);
-		}
+	/**
+	 * Creates a {@link Record} from a Cursor. If the cursor does not show to a
+	 * valid data structure a runtime exception is thrown.
+	 * 
+	 * @param cursor
+	 * @return Returns the created {@link Record} .
+	 */
+	private Record createRecord(Cursor cursor) {
+		Record record = new Record();
+		record.setId(Integer.parseInt(cursor.getString(0)));
+		record.setAttack_id(cursor.getLong(1));
+		record.setType(cursor.getString(2).equals("SEND") ? TYPE.SEND
+				: TYPE.RECEIVE);
+		record.setTimestamp(cursor.getLong(3));
+		record.setPacket(cursor.getString(4));
+		record.setProtocol(cursor.getString(5));
+		record.setExternalIP(cursor.getString(6));
+
+		record.setLocalIP(cursor.getString(7));
+		record.setLocalHost(cursor.getString(8));
+		record.setLocalPort(Integer.parseInt(cursor.getString(9)));
+
+		record.setRemoteIP(cursor.getString(10));
+		record.setRemoteHost(cursor.getString(11));
+		record.setRemotePort(Integer.parseInt(cursor.getString(12)));
+
+		record.setBssid(cursor.getString(13));
+		record.setSsid(cursor.getString(14));
+		record.setLatitude(Double.parseDouble(cursor.getString(15)));
+		record.setLongitude(Double.parseDouble(cursor.getString(16)));
+		record.setAccuracy(Float.parseFloat(cursor.getString(17)));
+		record.setTimestampLocation(cursor.getLong(18));
+
+		return record;
 	}
 }

+ 3 - 3
src/de/tudarmstadt/informatik/hostage/logging/formatter/DefaultFormatter.java

@@ -7,13 +7,13 @@ public class DefaultFormatter extends Formatter {
 
 	private static DefaultFormatter INSTANCE = new DefaultFormatter();
 
-	private DefaultFormatter() {
-	}
-
 	public static DefaultFormatter getInstance() {
 		return INSTANCE;
 	}
 
+	private DefaultFormatter() {
+	}
+
 	@Override
 	public synchronized String format(Record record) {
 		ProtocolFormatter formatter = ProtocolFormatter.getFormatter(record

+ 3 - 3
src/de/tudarmstadt/informatik/hostage/logging/formatter/TraCINgFormatter.java

@@ -6,13 +6,13 @@ public class TraCINgFormatter extends Formatter {
 
 	private static TraCINgFormatter INSTANCE = new TraCINgFormatter();
 
-	private TraCINgFormatter() {
-	}
-
 	public static TraCINgFormatter getInstance() {
 		return INSTANCE;
 	}
 
+	private TraCINgFormatter() {
+	}
+
 	@Override
 	public synchronized String format(Record record) {
 		return String

+ 12 - 12
src/de/tudarmstadt/informatik/hostage/logging/formatter/protocol/ProtocolFormatter.java

@@ -10,18 +10,6 @@ package de.tudarmstadt.informatik.hostage.logging.formatter.protocol;
  */
 public class ProtocolFormatter {
 
-	/**
-	 * Formats the content of packet. The packet content is represented as
-	 * string or hex, depending on the protocol.
-	 * 
-	 * @param packet
-	 *            Packet to format.
-	 * @return Formatted string.
-	 */
-	public String format(String packet) {
-		return packet;
-	}
-
 	/**
 	 * Loads a protocol formatter for a protocol. Load a class matching
 	 * {protocol} located in logging.formatter.protocol, default formatter
@@ -42,4 +30,16 @@ public class ProtocolFormatter {
 		}
 	}
 
+	/**
+	 * Formats the content of packet. The packet content is represented as
+	 * string or hex, depending on the protocol.
+	 * 
+	 * @param packet
+	 *            Packet to format.
+	 * @return Formatted string.
+	 */
+	public String format(String packet) {
+		return packet;
+	}
+
 }

+ 13 - 13
src/de/tudarmstadt/informatik/hostage/logging/formatter/protocol/SMB.java

@@ -23,6 +23,19 @@ public class SMB extends ProtocolFormatter {
 		return buffer.toString();
 	}
 
+	/**
+	 * Returns the content of a packet with command code 0x72.
+	 * 
+	 * @param packet
+	 *            content as byte array.
+	 * @return content as String.
+	 */
+	private String get0x72content(byte[] packet) {
+		byte[] content = new byte[packet.length - 39];
+		System.arraycopy(packet, 39, content, 0, content.length);
+		return HelperUtils.byteToStr(content);
+	}
+
 	/**
 	 * Checks command code for its command code and returns the name of this
 	 * command.
@@ -209,17 +222,4 @@ public class SMB extends ProtocolFormatter {
 		}
 	}
 
-	/**
-	 * Returns the content of a packet with command code 0x72.
-	 * 
-	 * @param packet
-	 *            content as byte array.
-	 * @return content as String.
-	 */
-	private String get0x72content(byte[] packet) {
-		byte[] content = new byte[packet.length - 39];
-		System.arraycopy(packet, 39, content, 0, content.length);
-		return HelperUtils.byteToStr(content);
-	}
-
 }

+ 41 - 41
src/de/tudarmstadt/informatik/hostage/logging/formatter/protocol/TELNET.java

@@ -17,47 +17,6 @@ public class TELNET extends ProtocolFormatter {
 		return options + content;
 	}
 
-	/**
-	 * Checks a packet for option commands and returns their names as Strings.
-	 * 
-	 * @param bytes
-	 *            that are checked.
-	 * @return names of the option commands as String.
-	 */
-	private String checkForOptions(byte[] bytes) {
-		StringBuffer options = new StringBuffer();
-		for (int i = 0; i < bytes.length; i++) {
-			if (bytes[i] == (byte) 0xff && i + 2 < bytes.length) {
-				options.append(checkMode(bytes[i + 1]));
-				// option name
-				options.append(checkCommand(bytes[i + 2]));
-			}
-		}
-		return options.toString();
-	}
-
-	/**
-	 * Checks a byte for its mode value.
-	 * 
-	 * @param b
-	 *            byte that is checked.
-	 * @return name of the mode.
-	 */
-	private String checkMode(byte b) {
-		switch (b) {
-		case (byte) 0xfb:
-			return " WILL ";
-		case (byte) 0xfc:
-			return " WON'T ";
-		case (byte) 0xfd:
-			return " DO ";
-		case (byte) 0xfe:
-			return " DON'T ";
-		default:
-			return " unkown command ";
-		}
-	}
-
 	/**
 	 * Checks a byte for its command value.
 	 * 
@@ -146,4 +105,45 @@ public class TELNET extends ProtocolFormatter {
 		}
 	}
 
+	/**
+	 * Checks a packet for option commands and returns their names as Strings.
+	 * 
+	 * @param bytes
+	 *            that are checked.
+	 * @return names of the option commands as String.
+	 */
+	private String checkForOptions(byte[] bytes) {
+		StringBuffer options = new StringBuffer();
+		for (int i = 0; i < bytes.length; i++) {
+			if (bytes[i] == (byte) 0xff && i + 2 < bytes.length) {
+				options.append(checkMode(bytes[i + 1]));
+				// option name
+				options.append(checkCommand(bytes[i + 2]));
+			}
+		}
+		return options.toString();
+	}
+
+	/**
+	 * Checks a byte for its mode value.
+	 * 
+	 * @param b
+	 *            byte that is checked.
+	 * @return name of the mode.
+	 */
+	private String checkMode(byte b) {
+		switch (b) {
+		case (byte) 0xfb:
+			return " WILL ";
+		case (byte) 0xfc:
+			return " WON'T ";
+		case (byte) 0xfd:
+			return " DO ";
+		case (byte) 0xfe:
+			return " DON'T ";
+		default:
+			return " unkown command ";
+		}
+	}
+
 }

+ 11 - 9
src/de/tudarmstadt/informatik/hostage/net/MySSLSocketFactory.java

@@ -16,6 +16,7 @@ import javax.net.ssl.TrustManager;
 import javax.net.ssl.X509TrustManager;
 
 import org.apache.http.conn.ssl.SSLSocketFactory;
+
 /**
  * SocketFactory to create a SSL socket that accepts every certificate.
  */
@@ -28,17 +29,18 @@ public class MySSLSocketFactory extends SSLSocketFactory {
 		super(truststore);
 
 		TrustManager tm = new X509TrustManager() {
-			
+
+			@Override
 			public void checkClientTrusted(X509Certificate[] chain,
 					String authType) throws CertificateException {
 			}
 
-			
+			@Override
 			public void checkServerTrusted(X509Certificate[] chain,
 					String authType) throws CertificateException {
 			}
 
-			
+			@Override
 			public X509Certificate[] getAcceptedIssuers() {
 				return null;
 			}
@@ -47,15 +49,15 @@ public class MySSLSocketFactory extends SSLSocketFactory {
 		sslContext.init(null, new TrustManager[] { tm }, null);
 	}
 
-	
+	@Override
+	public Socket createSocket() throws IOException {
+		return sslContext.getSocketFactory().createSocket();
+	}
+
+	@Override
 	public Socket createSocket(Socket socket, String host, int port,
 			boolean autoClose) throws IOException, UnknownHostException {
 		return sslContext.getSocketFactory().createSocket(socket, host, port,
 				autoClose);
 	}
-
-	
-	public Socket createSocket() throws IOException {
-		return sslContext.getSocketFactory().createSocket();
-	}
 }

+ 25 - 26
src/de/tudarmstadt/informatik/hostage/net/MyServerSocketFactory.java

@@ -10,12 +10,14 @@ import java.net.SocketImpl;
 
 import javax.net.ServerSocketFactory;
 
-import de.tudarmstadt.informatik.hostage.system.PrivilegedPort;
+import de.tudarmstadt.informatik.hostage.system.P;
 import de.tudarmstadt.informatik.hostage.ui.MainActivity;
 
 /**
- * Server Socket Factory using the porthack.
+ * Server Socket Factory using file descriptors.
+ * 
  * @author Mihai Plasoianu
+ * @author Lars Pandikow
  */
 public class MyServerSocketFactory extends ServerSocketFactory {
 
@@ -26,15 +28,13 @@ public class MyServerSocketFactory extends ServerSocketFactory {
 	@Override
 	public ServerSocket createServerSocket(int port) throws IOException {
 		ServerSocket socket = null;
-		if(port > 1023){
+		if (port > 1023) {
 			socket = new ServerSocket();
-			// Set SO_REUSEADDRESS before port is bound
 			socket.setReuseAddress(true);
 			socket.bind(new InetSocketAddress(port));
-		} else if(MainActivity.porthackInstalled){
-			FileDescriptor fd = new PrivilegedPort(port).bindAndGetFD();			
+		} else if (MainActivity.porthackInstalled) {
+			FileDescriptor fd = new P(port).bindAndGetFD();
 			socket = new ServerSocket();
-			
 			try {
 				SocketImpl impl = getImpl(socket);
 				injectFD(fd, impl);
@@ -44,10 +44,27 @@ public class MyServerSocketFactory extends ServerSocketFactory {
 				e.printStackTrace();
 			}
 		}
-		
 		return socket;
 	}
 
+	/**
+	 * Must override.
+	 */
+	@Override
+	public ServerSocket createServerSocket(int port, int backlog)
+			throws IOException {
+		return createServerSocket(port);
+	}
+
+	/**
+	 * Must override.
+	 */
+	@Override
+	public ServerSocket createServerSocket(int port, int backlog,
+			InetAddress iAddress) throws IOException {
+		return createServerSocket(port);
+	}
+
 	/**
 	 * Extracts the SocketImpl out of a ServerSocket.
 	 */
@@ -89,22 +106,4 @@ public class MyServerSocketFactory extends ServerSocketFactory {
 		boundField.set(socket, true);
 	}
 
-	/**
-	 * Must override.
-	 */
-	@Override
-	public ServerSocket createServerSocket(int port, int backlog)
-			throws IOException {
-		return createServerSocket(port);
-	}
-
-	/**
-	 * Must override.
-	 */
-	@Override
-	public ServerSocket createServerSocket(int port, int backlog,
-			InetAddress iAddress) throws IOException {
-		return createServerSocket(port);
-	}
-
 }

+ 27 - 0
src/de/tudarmstadt/informatik/hostage/nio/Reader.java

@@ -0,0 +1,27 @@
+package de.tudarmstadt.informatik.hostage.nio;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import de.tudarmstadt.informatik.hostage.wrapper.Packet;
+
+public class Reader {
+
+	BufferedInputStream in;
+
+	public Reader(InputStream in) {
+		this.in = new BufferedInputStream(in);
+	}
+
+	public Packet read() throws IOException {
+		ByteArrayOutputStream payload = new ByteArrayOutputStream();
+		do {
+			payload.write(in.read());
+			Thread.yield();
+		} while (in.available() > 0);
+		return new Packet(payload.toByteArray());
+	}
+
+}

+ 25 - 0
src/de/tudarmstadt/informatik/hostage/nio/Writer.java

@@ -0,0 +1,25 @@
+package de.tudarmstadt.informatik.hostage.nio;
+
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.List;
+
+import de.tudarmstadt.informatik.hostage.wrapper.Packet;
+
+public class Writer {
+
+	BufferedOutputStream out;
+
+	public Writer(OutputStream out) {
+		this.out = new BufferedOutputStream(out);
+	}
+
+	public void write(List<Packet> packets) throws IOException {
+		for (Packet packet : packets) {
+			out.write(packet.getBytes());
+			out.write('\n');
+		}
+		out.flush();
+	}
+}

+ 10 - 15
src/de/tudarmstadt/informatik/hostage/protocol/ECHO.java

@@ -13,22 +13,10 @@ import de.tudarmstadt.informatik.hostage.wrapper.Packet;
 public class ECHO implements Protocol {
 
 	@Override
-	public int getDefaultPort() {
+	public int getPort() {
 		return 7;
 	}
 
-	@Override
-	public TALK_FIRST whoTalksFirst() {
-		return TALK_FIRST.CLIENT;
-	}
-
-	@Override
-	public List<Packet> processMessage(Packet requestPacket) {
-		List<Packet> responsePackets = new ArrayList<Packet>();
-		responsePackets.add(requestPacket);
-		return responsePackets;
-	}
-
 	@Override
 	public boolean isClosed() {
 		return true;
@@ -40,8 +28,10 @@ public class ECHO implements Protocol {
 	}
 
 	@Override
-	public Class<byte[]> getType() {
-		return byte[].class;
+	public List<Packet> processMessage(Packet requestPacket) {
+		List<Packet> responsePackets = new ArrayList<Packet>();
+		responsePackets.add(requestPacket);
+		return responsePackets;
 	}
 
 	@Override
@@ -49,4 +39,9 @@ public class ECHO implements Protocol {
 		return "ECHO";
 	}
 
+	@Override
+	public TALK_FIRST whoTalksFirst() {
+		return TALK_FIRST.CLIENT;
+	}
+
 }

+ 30 - 32
src/de/tudarmstadt/informatik/hostage/protocol/FTP.java

@@ -6,13 +6,13 @@ import java.util.List;
 import de.tudarmstadt.informatik.hostage.wrapper.Packet;
 
 /**
- * FTP protocol.
- * Implementation of RFC document 959.
- * It can handle the following requests: USER, PASS, QUIT.
+ * FTP protocol. Implementation of RFC document 959. It can handle the following
+ * requests: USER, PASS, QUIT.
+ * 
  * @author Wulf Pfeiffer
  */
 public class FTP implements Protocol {
-	
+
 	/**
 	 * Represents the states of the protocol
 	 */
@@ -24,15 +24,33 @@ public class FTP implements Protocol {
 	 * Denotes in which state the protocol is right now
 	 */
 	private STATE state = STATE.NONE;
-	
+
+	// commands
+	private static final String REPLY_CODE_220 = "220 Service ready for new user.";
+
+	private static final String REPLY_CODE_221 = "221 Service closing control connection.";
+
+	private static final String REPLY_CODE_230 = "230 User logged in.";
+
+	private static final String REPLY_CODE_331 = "331 User name ok, need password.";
+	private static final String REPLY_CODE_332 = "332 Need account for login.";
+	private static final String REPLY_CODE_421 = "421 Service not available, closing control connection.";
+	private static final String REPLY_CODE_500 = "500 Syntax error, command unrecognized.";
+	private static final String REPLY_CODE_501 = "501 Syntax error in parameters or arguments";
+
 	@Override
-	public int getDefaultPort() {
+	public int getPort() {
 		return 21;
 	}
 
 	@Override
-	public TALK_FIRST whoTalksFirst() {
-		return TALK_FIRST.SERVER;
+	public boolean isClosed() {
+		return state == STATE.CLOSED;
+	}
+
+	@Override
+	public boolean isSecure() {
+		return false;
 	}
 
 	@Override
@@ -91,35 +109,15 @@ public class FTP implements Protocol {
 		}
 		return responsePackets;
 	}
-	
-	//commands
-	private static final String REPLY_CODE_220 = "220 Service ready for new user.";
-	private static final String REPLY_CODE_221 = "221 Service closing control connection.";
-	private static final String REPLY_CODE_230 = "230 User logged in.";
-	private static final String REPLY_CODE_331 = "331 User name ok, need password.";
-	private static final String REPLY_CODE_332 = "332 Need account for login.";
-	private static final String REPLY_CODE_421 = "421 Service not available, closing control connection.";
-	private static final String REPLY_CODE_500 = "500 Syntax error, command unrecognized.";
-	private static final String REPLY_CODE_501 = "501 Syntax error in parameters or arguments";
-
-	@Override
-	public boolean isClosed() {
-		return state == STATE.CLOSED;
-	}
 
 	@Override
-	public boolean isSecure() {
-		return false;
-	}
-
-	@Override
-	public Class<String> getType() {
-		return String.class;
+	public String toString() {
+		return "FTP";
 	}
 
 	@Override
-	public String toString() {
-		return "FTP";
+	public TALK_FIRST whoTalksFirst() {
+		return TALK_FIRST.SERVER;
 	}
 
 }

+ 21 - 24
src/de/tudarmstadt/informatik/hostage/protocol/GhostProtocol.java → src/de/tudarmstadt/informatik/hostage/protocol/GHOST.java

@@ -17,18 +17,29 @@ import de.tudarmstadt.informatik.hostage.wrapper.Packet;
  * 
  * @author Wulf Pfeiffer
  */
-public class GhostProtocol implements Protocol {
+public class GHOST implements Protocol {
 
 	private boolean isClosed = false;
 
+	private Socket mirroredConnection;
+
+	private BufferedInputStream mirrorInputStream;
+
+	private BufferedOutputStream mirrorOutputStream;
+
 	@Override
-	public int getDefaultPort() {
+	public int getPort() {
 		return 5050; // TODO dynamic port / whats the default!? (1433)
 	}
 
 	@Override
-	public TALK_FIRST whoTalksFirst() {
-		return TALK_FIRST.CLIENT;
+	public boolean isClosed() {
+		return isClosed;
+	}
+
+	@Override
+	public boolean isSecure() {
+		return false;
 	}
 
 	@Override
@@ -36,7 +47,7 @@ public class GhostProtocol implements Protocol {
 		List<Packet> responsePackets = new ArrayList<Packet>();
 		try {
 			if (mirroredConnection == null) {
-				mirroredConnection = new Socket("192.168.178.86", 5050); // TODO
+				mirroredConnection = new Socket("192.168.178.86", 5050); // FIXME
 				mirrorInputStream = new BufferedInputStream(
 						mirroredConnection.getInputStream());
 				mirrorOutputStream = new BufferedOutputStream(
@@ -50,7 +61,7 @@ public class GhostProtocol implements Protocol {
 				isClosed = true;
 			}
 
-			mirrorOutputStream.write(requestPacket.getMessage());
+			mirrorOutputStream.write(requestPacket.getBytes());
 			mirrorOutputStream.flush();
 
 			int availableBytes;
@@ -70,27 +81,13 @@ public class GhostProtocol implements Protocol {
 		return responsePackets;
 	}
 
-	@Override
-	public boolean isClosed() {
-		return isClosed;
-	}
-
-	@Override
-	public boolean isSecure() {
-		return false;
-	}
-
-	@Override
-	public Class<byte[]> getType() {
-		return byte[].class;
-	}
-
 	@Override
 	public String toString() {
 		return "GhostProtocol";
 	}
 
-	private Socket mirroredConnection;
-	private BufferedInputStream mirrorInputStream;
-	private BufferedOutputStream mirrorOutputStream;
+	@Override
+	public TALK_FIRST whoTalksFirst() {
+		return TALK_FIRST.CLIENT;
+	}
 }

+ 126 - 122
src/de/tudarmstadt/informatik/hostage/protocol/HTTP.java

@@ -11,26 +11,122 @@ import java.util.TimeZone;
 import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
 import de.tudarmstadt.informatik.hostage.wrapper.Packet;
 
-
 /**
- * HTTP protocol.
- * Implementation of RFC document 1945.
- * It can handle the following requests: GET, HEAD, TRACE, POST, DELETE.
- * For all other requests '400 Bad Request' will be replied.
+ * HTTP protocol. Implementation of RFC document 1945. It can handle the
+ * following requests: GET, HEAD, TRACE, POST, DELETE. For all other requests
+ * '400 Bad Request' will be replied.
+ * 
  * @author Wulf Pfeiffer
  */
 public class HTTP implements Protocol {
-	
+
+	/**
+	 * Get the current time in html header format.
+	 * 
+	 * @return the formatted server time.
+	 */
+	private static String getServerTime() {
+		Calendar calendar = Calendar.getInstance();
+		SimpleDateFormat dateFormat = new SimpleDateFormat(
+				"EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
+		dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
+		return dateFormat.format(calendar.getTime());
+	}
+
+	/** Whole request that was sent by the client */
+	private String request = "";
+
+	// version stuff
+	private static String[][][] possibleHttpVersions = {
+			{
+					{ "Apache/2.0." },
+					{ "28", "32", "35", "36", "39", "40", "42", "43", "44",
+							"45", "46", "47", "48", "49", "50", "51", "52",
+							"53", "54", "55", "58", "59", "61", "63", "64",
+							"65" } },
+			{
+					{ "Apache/2.2." },
+					{ "0", "2", "3", "4", "6", "8", "9", "10", "11", "12",
+							"13", "14", "15", "16", "17", "18", "19", "20",
+							"21", "22", "23", "24", "25" } },
+			{ { "Apache/2.3." },
+					{ "4", "5", "6", "8", "10", "11", "12", "14", "15", "16" } },
+			{ { "Apache/2.4." }, { "1", "2", "3", "4", "6" } } };
+
+	private static String serverVersion = initServerVersion();
+
+	private static String initServerVersion() {
+		SecureRandom rndm = new SecureRandom();
+		int majorVersion = rndm.nextInt(possibleHttpVersions.length);
+		return possibleHttpVersions[majorVersion][0][0]
+				+ possibleHttpVersions[majorVersion][1][rndm
+						.nextInt(possibleHttpVersions[majorVersion][1].length)];
+	}
+
+	private String httpVersion = "HTTP/1.1";
+
+	private static String htmlDocumentContent = HelperUtils.getRandomString(32,
+			false);
+
+	// request codes
+	private static final String OPTIONS = "OPTIONS";
+
+	private static final String GET = "GET";
+	private static final String HEAD = "HEAD";
+
+	private static final String POST = "POST";
+
+	private static final String PUT = "PUT";
+	private static final String DELETE = "DELETE";
+	private static final String TRACE = "TRACE";
+	private static final String CONNECT = "CONNECT";
+	private static final String STATUS_CODE_200 = "200 OK\r\n";
+	private static final String STATUS_CODE_400 = "400 Bad Request\r\n";
+	private static final String STATUS_CODE_505 = "505 HTTP Version not supported\r\n";
+
+	/**
+	 * Sets the html document content for HTTP and HTTPS.
+	 * 
+	 * @param htmlDocumentContent
+	 */
+	public static void setHtmlDocumentContent(String htmlDocumentContent) {
+		HTTP.htmlDocumentContent = htmlDocumentContent;
+	}
+
+	// html header pre and suffix
+	private String headerPrefix = "Date: " + getServerTime() + "\r\n"
+			+ "Server: " + serverVersion + " \r\n"
+			+ "Vary: Accept-Encoding\r\n" + "Content-Length: ";
+	private String headerSuffix = "\r\n" + "Keep-Alive: timeout=5, max=100\r\n"
+			+ "Connection: Keep-Alive\r\n" + "Content-Type: text/html\r\n"
+			+ "\r\n";
+	// html website
+	private String htmlDocument = "<!doctype html>\n" + "<html lang=\"en\">\n"
+			+ "<head>\n" + "<meta charset=\"UTF-8\">\n" + "<title>"
+			+ htmlDocumentContent + "</title>\n" + "<body>"
+			+ htmlDocumentContent + "</body>\n" + "</head>\n" + "</html>";
+
+	// html error pre and suffix
+	private String errorHtmlPrefix = "<!doctype html>\n"
+			+ "<html lang=\"en\">\n" + "<head>\n"
+			+ "<meta charset=\"UTF-8\">\n" + "<title>";
+	private String errorHtmlSuffix = "</title>\n" + "</head>\n" + "</html>";
+
 	@Override
-	public int getDefaultPort() {
+	public int getPort() {
 		return 80;
 	}
 
 	@Override
-	public TALK_FIRST whoTalksFirst() {
-		return TALK_FIRST.CLIENT;
+	public boolean isClosed() {
+		return true;
+	}
+
+	@Override
+	public boolean isSecure() {
+		return false;
 	}
-	
+
 	@Override
 	public List<Packet> processMessage(Packet requestPacket) {
 		String request = null;
@@ -40,23 +136,23 @@ public class HTTP implements Protocol {
 		List<Packet> responsePackets = new ArrayList<Packet>();
 		this.request = request;
 
-		if(!request.contains(httpVersion)){
+		if (!request.contains(httpVersion)) {
 			responsePackets.add(buildPacket(STATUS_CODE_505, ""));
-		} else if(request.contains(GET)) {
+		} else if (request.contains(GET)) {
 			responsePackets.add(buildPacket(STATUS_CODE_200, GET));
-		} else if(request.contains(HEAD)) {
+		} else if (request.contains(HEAD)) {
 			responsePackets.add(buildPacket(STATUS_CODE_200, HEAD));
-		} else if(request.contains(TRACE)){
+		} else if (request.contains(TRACE)) {
 			responsePackets.add(buildPacket(STATUS_CODE_200, TRACE));
-		} else if(request.contains(OPTIONS)){
+		} else if (request.contains(OPTIONS)) {
 			responsePackets.add(buildPacket(STATUS_CODE_400, OPTIONS));
-		} else if(request.contains(POST)){
+		} else if (request.contains(POST)) {
 			responsePackets.add(buildPacket(STATUS_CODE_200, POST));
-		} else if(request.contains(PUT)){
+		} else if (request.contains(PUT)) {
 			responsePackets.add(buildPacket(STATUS_CODE_400, PUT));
-		} else if(request.contains(DELETE)){
+		} else if (request.contains(DELETE)) {
 			responsePackets.add(buildPacket(STATUS_CODE_200, DELETE));
-		} else if(request.contains(CONNECT)){
+		} else if (request.contains(CONNECT)) {
 			responsePackets.add(buildPacket(STATUS_CODE_400, CONNECT));
 		} else {
 			responsePackets.add(buildPacket(STATUS_CODE_400, ""));
@@ -65,29 +161,22 @@ public class HTTP implements Protocol {
 	}
 
 	@Override
-	public boolean isClosed() {
-		return true;
-	}
-
-	@Override
-	public boolean isSecure() {
-		return false;
-	}
-
-	@Override
-	public Class<String> getType() {
-		return String.class;
+	public String toString() {
+		return "HTTP";
 	}
 
 	@Override
-	public String toString() {
-		return "HTTP";
+	public TALK_FIRST whoTalksFirst() {
+		return TALK_FIRST.CLIENT;
 	}
 
 	/**
 	 * Builds a html response that can be sent
-	 * @param code response code that was determined
-	 * @param type request type that was sent by the client
+	 * 
+	 * @param code
+	 *            response code that was determined
+	 * @param type
+	 *            request type that was sent by the client
 	 * @return the html response
 	 */
 	private Packet buildPacket(String code, String type) {
@@ -102,92 +191,7 @@ public class HTTP implements Protocol {
 			document = errorHtmlPrefix + " " + code + errorHtmlSuffix;
 		}
 
-		return new Packet(httpVersion + " " + code + headerPrefix + document.length() + headerSuffix + document);
-	}
-	
-	/**
-	 * Get the current time in html header format.
-	 * @return the formatted server time.
-	 */
-	private static String getServerTime() {
-	    Calendar calendar = Calendar.getInstance();
-	    SimpleDateFormat dateFormat = new SimpleDateFormat(
-	        "EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
-	    dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
-	    return dateFormat.format(calendar.getTime());
-	}
-
-	/** Whole request that was sent by the client */
-	private String request	= "";
-	//version stuff
-	private static String[][][] possibleHttpVersions = {
-		{{"Apache/2.0."},{"28","32","35","36","39","40","42","43","44","45","46","47","48","49","50","51","52","53","54","55","58","59","61","63","64","65"}},
-		{{"Apache/2.2."},{"0","2","3","4","6","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25"}},
-		{{"Apache/2.3."},{"4","5","6","8","10","11","12","14","15","16"}},
-		{{"Apache/2.4."},{"1","2","3","4","6"}}
-	};
-	private static String initServerVersion() {
-		SecureRandom rndm = new SecureRandom();
-		int majorVersion = rndm.nextInt(possibleHttpVersions.length);
-		return possibleHttpVersions[majorVersion][0][0] + possibleHttpVersions[majorVersion][1][rndm.nextInt(possibleHttpVersions[majorVersion][1].length)];
-	}
-	private String httpVersion	= "HTTP/1.1";
-	private static String serverVersion = initServerVersion();
-	private static String htmlDocumentContent = HelperUtils.getRandomString(32, false);
-	//request codes
-	private static final String OPTIONS	= "OPTIONS";
-	private static final String GET 	= "GET";
-	private static final String HEAD 	= "HEAD";
-	private static final String POST	= "POST";
-	private static final String PUT		= "PUT";
-	private static final String DELETE	= "DELETE";
-	private static final String TRACE	= "TRACE";
-	private static final String CONNECT	= "CONNECT";
-	
-	private static final String STATUS_CODE_200	= "200 OK\r\n";
-	private static final String STATUS_CODE_400	= "400 Bad Request\r\n";
-	private static final String STATUS_CODE_505	= "505 HTTP Version not supported\r\n";
-	
-	//html header pre and suffix
-	private String headerPrefix =				
-			"Date: " + getServerTime() + "\r\n" +
-			"Server: " + serverVersion + " \r\n" +
-			"Vary: Accept-Encoding\r\n" +
-			"Content-Length: ";
-	private String headerSuffix =
-			"\r\n" +	
-			"Keep-Alive: timeout=5, max=100\r\n" +
-			"Connection: Keep-Alive\r\n" +
-			"Content-Type: text/html\r\n" +
-			"\r\n";
-	//html website
-	private String htmlDocument = 
-			"<!doctype html>\n" +
-			"<html lang=\"en\">\n" +
-			"<head>\n" +
-			"<meta charset=\"UTF-8\">\n" +
-			"<title>" + htmlDocumentContent + "</title>\n" +
-			"<body>" + htmlDocumentContent + "</body>\n" +
-			"</head>\n" +
-			"</html>";
-	//html error pre and suffix
-	private String errorHtmlPrefix =
-			"<!doctype html>\n" +
-			"<html lang=\"en\">\n" +
-			"<head>\n" +
-			"<meta charset=\"UTF-8\">\n" +
-			"<title>";
-	private String errorHtmlSuffix =
-			"</title>\n" +
-			"</head>\n" +
-			"</html>";
-
-	/**
-	 * Sets the html document content for HTTP and HTTPS.
-	 * 
-	 * @param htmlDocumentContent
-	 */
-	public static void setHtmlDocumentContent(String htmlDocumentContent) {
-		HTTP.htmlDocumentContent = htmlDocumentContent;
+		return new Packet(httpVersion + " " + code + headerPrefix
+				+ document.length() + headerSuffix + document);
 	}
 }

+ 11 - 11
src/de/tudarmstadt/informatik/hostage/protocol/HTTPS.java

@@ -15,20 +15,10 @@ import de.tudarmstadt.informatik.hostage.HoneyService;
 public class HTTPS extends HTTP implements SSLProtocol {
 
 	@Override
-	public int getDefaultPort() {
+	public int getPort() {
 		return 443;
 	}
 
-	@Override
-	public boolean isSecure() {
-		return true;
-	}
-
-	@Override
-	public String toString() {
-		return "HTTPS";
-	}
-
 	@Override
 	public SSLContext getSSLContext() {
 		String keyStoreName = "https_cert.bks";
@@ -56,4 +46,14 @@ public class HTTPS extends HTTP implements SSLProtocol {
 		return sslContext;
 	}
 
+	@Override
+	public boolean isSecure() {
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "HTTPS";
+	}
+
 }

+ 68 - 71
src/de/tudarmstadt/informatik/hostage/protocol/MySQL.java

@@ -29,11 +29,45 @@ public class MySQL implements Protocol {
 	/** last request from client */
 	private byte[] lastReceivedMessage;
 
+	// version stuff
+	private static String[][][] possibleMysqlVersions = {
+			{ { "5.7." }, { "1", "2" } },
+			{
+					{ "5.6." },
+					{ "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12",
+							"13", "14" } },
+			{ { "5.5." }, { "27", "28", "29", "30", "31", "32", "33", "34" } } };
+
+	private static String serverVersion = initMysqlVersion();
+
+	private static String initMysqlVersion() {
+		SecureRandom rndm = new SecureRandom();
+		int majorVersion = rndm.nextInt(possibleMysqlVersions.length);
+		return possibleMysqlVersions[majorVersion][0][0]
+				+ possibleMysqlVersions[majorVersion][1][rndm
+						.nextInt(possibleMysqlVersions[majorVersion][1].length)];
+	}
+
+	@Override
+	public int getPort() {
+		return 3306;
+	}
+
+	@Override
+	public boolean isClosed() {
+		return state == STATE.CLOSED;
+	}
+
+	@Override
+	public boolean isSecure() {
+		return false;
+	}
+
 	@Override
 	public List<Packet> processMessage(Packet requestPacket) {
 		byte[] request = null;
 		if (requestPacket != null) {
-			request = requestPacket.getMessage();
+			request = requestPacket.getBytes();
 		}
 		List<Packet> responsePackets = new ArrayList<Packet>();
 		if (request != null)
@@ -63,55 +97,14 @@ public class MySQL implements Protocol {
 		return responsePackets;
 	}
 
-	@Override
-	public TALK_FIRST whoTalksFirst() {
-		return TALK_FIRST.SERVER;
-	}
-
 	@Override
 	public String toString() {
 		return "MySQL";
 	}
 
 	@Override
-	public int getDefaultPort() {
-		return 3306;
-	}
-
-	@Override
-	public boolean isClosed() {
-		return state == STATE.CLOSED;
-	}
-
-	@Override
-	public boolean isSecure() {
-		return false;
-	}
-
-	@Override
-	public Class<byte[]> getType() {
-		return byte[].class;
-	}
-
-	/**
-	 * Wraps the response packet with the packet length and number
-	 * 
-	 * @param response
-	 *            that is wrapped
-	 * @return wrapped packet
-	 */
-	private Packet wrapPacket(byte[] response) {
-		byte[] buffer = ByteBuffer.allocate(4).putInt(response.length).array();
-		byte[] packetLength = { buffer[3], buffer[2], buffer[1] };
-		byte[] packetNumber = new byte[1];
-		if (lastReceivedMessage != null)
-			packetNumber[0] = (byte) (lastReceivedMessage[3] + 1);
-		else
-			packetNumber[0] = 0x00;
-
-		byte[] wrappedResponse = HelperUtils.concat(packetLength, packetNumber,
-				response);
-		return new Packet(wrappedResponse);
+	public TALK_FIRST whoTalksFirst() {
+		return TALK_FIRST.SERVER;
 	}
 
 	/**
@@ -141,20 +134,6 @@ public class MySQL implements Protocol {
 		return wrapPacket(response);
 	}
 
-	/**
-	 * Builds the ok-response packet
-	 * 
-	 * @return ok-response packet
-	 */
-	private Packet responseOK() {
-		byte[] affectedRows = { 0x00, 0x00, 0x00 };
-		byte[] status = { 0x02, 0x00 };
-		byte[] warnings = { 0x00, 0x00 };
-
-		byte[] response = HelperUtils.concat(affectedRows, status, warnings);
-		return wrapPacket(response);
-	}
-
 	/**
 	 * Builds the error-response packet
 	 * 
@@ -172,20 +151,38 @@ public class MySQL implements Protocol {
 		return wrapPacket(response);
 	}
 
-	// version stuff
-	private static String[][][] possibleMysqlVersions = {
-	 {{"5.7."},{"1","2"}},
-	 {{"5.6."},{"2","3","4","5","6","7","8","9","10","11","12","13","14"}},
-	 {{"5.5."},{"27","28","29","30","31","32","33","34"}}
-	};
+	/**
+	 * Builds the ok-response packet
+	 * 
+	 * @return ok-response packet
+	 */
+	private Packet responseOK() {
+		byte[] affectedRows = { 0x00, 0x00, 0x00 };
+		byte[] status = { 0x02, 0x00 };
+		byte[] warnings = { 0x00, 0x00 };
 
-	private static String initMysqlVersion() {
-		SecureRandom rndm = new SecureRandom();
-		int majorVersion = rndm.nextInt(possibleMysqlVersions.length);
-		return possibleMysqlVersions[majorVersion][0][0]
-				+ possibleMysqlVersions[majorVersion][1][rndm
-						.nextInt(possibleMysqlVersions[majorVersion][1].length)];
+		byte[] response = HelperUtils.concat(affectedRows, status, warnings);
+		return wrapPacket(response);
 	}
 
-	private static String serverVersion = initMysqlVersion();
+	/**
+	 * Wraps the response packet with the packet length and number
+	 * 
+	 * @param response
+	 *            that is wrapped
+	 * @return wrapped packet
+	 */
+	private Packet wrapPacket(byte[] response) {
+		byte[] buffer = ByteBuffer.allocate(4).putInt(response.length).array();
+		byte[] packetLength = { buffer[3], buffer[2], buffer[1] };
+		byte[] packetNumber = new byte[1];
+		if (lastReceivedMessage != null)
+			packetNumber[0] = (byte) (lastReceivedMessage[3] + 1);
+		else
+			packetNumber[0] = 0x00;
+
+		byte[] wrappedResponse = HelperUtils.concat(packetLength, packetNumber,
+				response);
+		return new Packet(wrappedResponse);
+	}
 }

+ 33 - 32
src/de/tudarmstadt/informatik/hostage/protocol/Protocol.java

@@ -5,61 +5,62 @@ import java.util.List;
 import de.tudarmstadt.informatik.hostage.wrapper.Packet;
 
 /**
- * Interface for protocols that are used by the application.
+ * Protocol interface.
+ * 
  * @author Mihai Plasoianu
  * @author Wulf Pfeiffer
  */
 public interface Protocol {
 
-	/**
-	 * Represents who starts the communication once the connection is established.
-	 */
 	public static enum TALK_FIRST {
 		SERVER, CLIENT
 	};
 
 	/**
-	 * Returns the default port on which the protocol is running.
-	 * @return the default port used by the protocol (range: 0-65535)
-	 */
-	int getDefaultPort();
-
-	/**
-	 * Returns who starts the communication (server or client)
-	 * @return TALK_FIRST.server if the server starts or TALK_FIRST.client if the client starts.
+	 * Returns the port on which the protocol is running.
+	 * 
+	 * @return The port used by the protocol (1-65535)
 	 */
-	TALK_FIRST whoTalksFirst();
+	int getPort();
 
 	/**
-	 * Determines the next message that is sent by the server.
-	 * @param packet last message that was sent by the client.
-	 * @return next message that will be sent.
-	 */
-	List<Packet> processMessage(Packet packet);
-
-	/**
-	 * Returns whether the communication is ended and the connection should be closed or not.
-	 * @return true if the connection should be closed, else false.
+	 * Returns whether the communication is ended and the connection should be
+	 * closed or not.
+	 * 
+	 * @return true if the connection should be closed, false otherwise.
 	 */
 	boolean isClosed();
 
 	/**
-	 * Returns if the protocol uses SSL/TLS connection or not.
-	 * @return true if SSL/TLS is used, else false.
+	 * Returns whether the protocol uses a secure connection or not.
+	 * 
+	 * @return true if SSL/TLS is used, false otherwise.
 	 */
 	boolean isSecure();
 
 	/**
-	 * Returns what type the protocol is using, Strings or ByteArrays.
-	 * @return the class that the protocol is using.
+	 * Determines the next response.
+	 * 
+	 * @param message
+	 *            Last message received from the client.
+	 * @return Message to be sent to the client.
 	 */
-	Class<? extends Object> getType();
-	
+	List<Packet> processMessage(Packet message);
+
 	/**
 	 * Returns the name of the protocol.
-	 * @return name of the protocol
+	 * 
+	 * @return String representation of the protocol.
 	 */
-	@Override 
+	@Override
 	String toString();
-	
-}
+
+	/**
+	 * Specifies who starts the communication once the connection is
+	 * established.
+	 * 
+	 * @return A value in TALK_FIRST.
+	 */
+	TALK_FIRST whoTalksFirst();
+
+}

+ 9 - 14
src/de/tudarmstadt/informatik/hostage/protocol/SIP.java

@@ -7,21 +7,10 @@ import de.tudarmstadt.informatik.hostage.wrapper.Packet;
 public class SIP implements Protocol {
 
 	@Override
-	public int getDefaultPort() {
+	public int getPort() {
 		return 5060;
 	}
 
-	@Override
-	public TALK_FIRST whoTalksFirst() {
-		return TALK_FIRST.CLIENT;
-	}
-
-	@Override
-	public List<Packet> processMessage(Packet packet) {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
 	@Override
 	public boolean isClosed() {
 		// TODO Auto-generated method stub
@@ -34,8 +23,14 @@ public class SIP implements Protocol {
 	}
 
 	@Override
-	public Class<byte[]> getType() {
-		return byte[].class;
+	public List<Packet> processMessage(Packet packet) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public TALK_FIRST whoTalksFirst() {
+		return TALK_FIRST.CLIENT;
 	}
 
 }

+ 643 - 527
src/de/tudarmstadt/informatik/hostage/protocol/SMB.java

@@ -8,16 +8,18 @@ import java.util.GregorianCalendar;
 import java.util.List;
 import java.util.TimeZone;
 
+import android.content.Context;
 import de.tudarmstadt.informatik.hostage.HoneyService;
 import de.tudarmstadt.informatik.hostage.R;
 import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
 import de.tudarmstadt.informatik.hostage.wrapper.Packet;
 
 /**
- * SMB protocol.
- * It can handle the following requests: Negotiate Protocol Request, Session Setup AndX Request, 
- * Tree Connect AndX Request, NT Create AndX Request, Bind, NetShareEnumAll, Close Request, 
- * Tree Disconnect Request, Echo Request, Trans2 Request.
+ * SMB protocol. It can handle the following requests: Negotiate Protocol
+ * 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 {
@@ -27,28 +29,164 @@ public class SMB implements Protocol {
 	private static enum STATE {
 		NONE, CONNECTED, AUTHENTICATED, LISTING, DISCONNECTED, CLOSED
 	}
-	
+
+	// version stuff
+	private static String[][] possibleSmbVersions = {
+			{ "Windows 7 Professional 7600", "Windows 7 Professional 6.1" },
+			{ "Windows 8 Enterprise 9200", "Windows 8 Enterprise 9200" },
+			{ "Windows Server 2008 R2 Enterprise 7600",
+					"Windows Server 2008 R2 Enterprise 6.1" },
+			{ "Windows Server 2012 Standard 6.2",
+					"Windows Server 2012 Standard 6.2" }, { "Unix", "Samba" } };
+
+	/**
+	 * Converts the current system time into a byte[] with windows specific time
+	 * 
+	 * @return current system time in windows format as byte[]
+	 */
+	private static byte[] getTimeInBytes() {
+		long time = System.currentTimeMillis();
+		Calendar calend = Calendar.getInstance();
+		calend.setTimeZone(TimeZone.getTimeZone("UTC"));
+		calend.set(1601, 0, 01, 00, 00, 00);
+		time -= calend.getTimeInMillis();
+		time *= 10000;
+
+		byte[] timeInWindowsBytes = new byte[8];
+		byte[] timeInBytes = ByteBuffer.allocate(8).putLong(time).array();
+
+		for (int i = 0, j = 7; i < 8 && j > -1; i++, j--) {
+			timeInWindowsBytes[i] = (byte) (timeInBytes[j] & 0xff);
+		}
+
+		return timeInWindowsBytes;
+	}
+
+	/**
+	 * Converts the current timezone into a byte[] with windows specific format
+	 * 
+	 * @return current timezone in windows format as byte[]
+	 */
+	private static byte[] getTimeZoneInBytes() {
+		Integer offset = new GregorianCalendar().getTimeZone().getRawOffset() / 1000 / 60; // get
+																							// current
+																							// timezone
+																							// offset
+																							// in
+																							// minutes
+		char[] offsetChars = Integer.toBinaryString(offset).toCharArray();
+		boolean invert = false;
+		for (int i = offsetChars.length - 1; i > -1; i--) {
+			if (!invert && offsetChars[i] == '1') {
+				invert = true;
+			} else if (invert) {
+				offsetChars[i] = (offsetChars[i] == '0') ? '1' : '0';
+			}
+		}
+		char[] extendedChars = new char[31];
+		for (int i = 0; i < extendedChars.length - offsetChars.length; i++) {
+			extendedChars[i] = '1';
+		}
+		for (int i = 0; i < offsetChars.length; i++) {
+			extendedChars[i + extendedChars.length - offsetChars.length] = offsetChars[i];
+		}
+		int timezone = Integer.parseInt(new String(extendedChars), 2);
+		byte[] timezoneBytes = new byte[2];
+		timezoneBytes[1] = (byte) (timezone >> 8);
+		timezoneBytes[0] = (byte) (timezone);
+		return timezoneBytes;
+	}
+
+	private static String[] initServerVersion() {
+		String sharedPreferencePath = HoneyService.getContext().getString(
+				R.string.shared_preference_path);
+		String profile = HoneyService
+				.getContext()
+				.getSharedPreferences(sharedPreferencePath,
+						Context.MODE_PRIVATE).getString("profile", "");
+		System.out.println(profile);
+		if (profile.equals("Windows 7")) {
+			return possibleSmbVersions[0];
+		} else if (profile.equals("Windows 8")) {
+			return possibleSmbVersions[1];
+		} else if (profile.equals("Windows Server 2008")) {
+			return possibleSmbVersions[2];
+		} else if (profile.equals("Windows Server 2012")) {
+			return possibleSmbVersions[3];
+		} else if (profile.equals("Linux")) {
+			return possibleSmbVersions[4];
+		} else {
+			return possibleSmbVersions[new SecureRandom()
+					.nextInt(possibleSmbVersions.length)];
+		}
+	}
+
 	/**
 	 * Denotes in which state the protocol is right now
 	 */
 	private STATE state = STATE.NONE;
 
 	private byte[] lastMessage;
-	
+
+	private static byte[] serverName = HelperUtils.fillWithZero(HelperUtils
+			.getRandomString(16, true).getBytes());
+
+	private static String[] serverVersion = initServerVersion();
+
+	private byte[] message = null;
+
+	private static final byte[] serverGUID = HelperUtils.randomBytes(16);
+
+	private boolean authenticateNext = false;
+
+	// components of a SMB packet
+	private byte[] serverComp = new byte[4];
+
+	private byte[] smbCommand = new byte[1];
+	private byte[] ntStat = new byte[4];
+
+	private byte[] smbFlags = new byte[1];
+	private byte[] smbFlags2 = new byte[2];
+	private byte[] processIDHigh = new byte[2];
+	private byte[] signature = new byte[8];
+	private byte[] reserved = new byte[2];
+	private byte[] treeID = new byte[2];
+	private byte[] processID = new byte[2];
+	private byte[] userID = new byte[2];
+	private byte[] multiplexID = new byte[2];
+	// message constants
+	private static final byte SMB_COM_CLOSE = 0x04;
+	private static final byte SMB_COM_TRANSACTION = 0x25;
+	private static final byte SMB_COM_ECHO = 0x2B;
+	private static final byte SMB_COM_TRANSACTION2 = 0x32;
+	private static final byte SMB_COM_TREE_DISCONNECT = 0x71;
+	private static final byte SMB_COM_NEGOTIATE = 0x72;
+
+	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;
+
 	@Override
-	public int getDefaultPort() {
+	public int getPort() {
 		return 445;
 	}
 
 	@Override
-	public TALK_FIRST whoTalksFirst() {
-		return TALK_FIRST.CLIENT;
+	public boolean isClosed() {
+		return (state == STATE.CLOSED);
+	}
+
+	@Override
+	public boolean isSecure() {
+		return false;
 	}
-	
+
 	@Override
 	public List<Packet> processMessage(Packet requestPacket) {
-		if(requestPacket != null)
-			lastMessage = requestPacket.getMessage();
+		if (requestPacket != null)
+			lastMessage = requestPacket.getBytes();
 		parseMessageHeader(lastMessage);
 		byte smbCommand = getSmbCommand();
 		List<Packet> responsePackets = new ArrayList<Packet>();
@@ -120,615 +258,593 @@ public class SMB implements Protocol {
 	}
 
 	@Override
-	public boolean isClosed() {
-		return (state == STATE.CLOSED);
-	}
-
-	@Override
-	public boolean isSecure() {
-		return false;
+	public String toString() {
+		return "SMB";
 	}
 
 	@Override
-	public Class<byte[]> getType() {
-		return byte[].class;
+	public TALK_FIRST whoTalksFirst() {
+		return TALK_FIRST.CLIENT;
 	}
 
-	@Override
-	public String toString() {
-		return "SMB";
+	/**
+	 * Evaluates what Dialects are offered by the client and which position the
+	 * used NT LM 0.12 dialect is at
+	 * 
+	 * @return position of the NT LM 0.12 dialect
+	 */
+	private byte[] evaluateDialect() {
+		byte[] dialectMsg = new byte[message.length - 39];
+		System.arraycopy(message, 39, dialectMsg, 0, message.length - 39);
+		short dialectNumber = 0;
+		for (int i = 0, start = 0; i < dialectMsg.length; i++) {
+			if (dialectMsg[i] == 0x00) {
+				byte[] dialect = new byte[i - start];
+				System.arraycopy(dialectMsg, start, dialect, 0, i - start);
+				if (HelperUtils.byteToStr(dialect).contains("NT LM 0.12")) {
+					return new byte[] { (byte) dialectNumber,
+							(byte) (dialectNumber >> 8) };
+				}
+				start = i + 1;
+				dialectNumber++;
+			}
+		}
+		return new byte[] { 0x00, 0x00 };
 	}
 
 	/**
-	 * Converts the current system time into a byte[] with windows specific time
-	 * @return current system time in windows format as byte[]
+	 * Builds the close packet
+	 * 
+	 * @return close packet
 	 */
-	private static byte[] getTimeInBytes() {
-		long time = System.currentTimeMillis();
-		Calendar calend = Calendar.getInstance();
-		calend.setTimeZone(TimeZone.getTimeZone("UTC"));
-		calend.set(1601, 0, 01, 00, 00, 00);
-		time -= calend.getTimeInMillis();
-		time *= 10000;
+	private Packet getClose() {
+		byte[] wordCount = { 0x00 };
+		byte[] byteCount = { 0x00, 0x00 };
 
-		byte[] timeInWindowsBytes = new byte[8];
-		byte[] timeInBytes = ByteBuffer.allocate(8).putLong(time).array();
+		smbCommand = new byte[] { 0x04 };
 
-		for (int i = 0, j = 7; i < 8 && j > -1; i++, j--) {
-			timeInWindowsBytes[i] = (byte) (timeInBytes[j] & 0xff);
-		}
+		byte[] response = HelperUtils.concat(wordCount, byteCount);
 
-		return timeInWindowsBytes;
+		return new Packet(wrapNetbios(wrapHeader(response)));
 	}
-	
+
 	/**
-	 * Converts the current timezone into a byte[] with windows specific format
-	 * @return current timezone in windows format as byte[]
+	 * Builds the DCERPC packet
+	 * 
+	 * @return DCERPC packet
 	 */
-	private static byte[] getTimeZoneInBytes() {
-		Integer offset = new GregorianCalendar().getTimeZone().getRawOffset() / 1000 / 60; // get current timezone offset in minutes
-		char[] offsetChars = Integer.toBinaryString(offset).toCharArray();
-		boolean invert = false;
-		for(int i = offsetChars.length-1; i > -1; i--) {
-			if(!invert && offsetChars[i] == '1') {
-				invert = true;
-			} else if(invert) {
-				offsetChars[i] = (offsetChars[i] == '0')? '1' : '0';
-			}
-		}
-		char[] extendedChars = new char[31];
-		for(int i = 0; i < extendedChars.length-offsetChars.length; i++) {
-			extendedChars[i] = '1';
-		}
-		for(int i = 0; i < offsetChars.length; i++) {
-			extendedChars[i+extendedChars.length-offsetChars.length] = offsetChars[i];
-		}
-		int timezone = (int) Integer.parseInt(new String(extendedChars), 2);
-		byte[] timezoneBytes = new byte[2];
-		timezoneBytes[1] = (byte) (timezone >> 8);
-		timezoneBytes[0] = (byte) (timezone);
-		return timezoneBytes;
-	}
+	private byte[] getDceRpc(byte[] transSub, int length) {
+		byte[] majorVersion = { 0x05 };
+		byte[] minorVersion = { 0x00 };
+		byte[] packetType = null;
+		byte[] packetFlags = { 0x03 };
+		byte[] dataRepres = { 0x10, 0x00, 0x00, 0x00 };
+		byte[] fragLength = null;
+		byte[] authLength = { 0x00, 0x00 };
+		byte[] callID = null;
+		byte[] response = null;
 
-	//version stuff
-	private static String[][] possibleSmbVersions = {
-		{"Windows 7 Professional 7600","Windows 7 Professional 6.1"},
-		{"Windows 8 Enterprise 9200", "Windows 8 Enterprise 9200"},
-		{"Windows Server 2008 R2 Enterprise 7600","Windows Server 2008 R2 Enterprise 6.1"},
-		{"Windows Server 2012 Standard 6.2", "Windows Server 2012 Standard 6.2"},
-		{"Unix", "Samba"}
-	};
-	private static String[] initServerVersion() {
-		String sharedPreferencePath = HoneyService.getContext().getString(R.string.shared_preference_path);
-		String profile = HoneyService.getContext().getSharedPreferences(sharedPreferencePath, HoneyService.MODE_PRIVATE).getString("profile", "");
-		System.out.println(profile);
-		if(profile.equals("Windows 7")) {
-			return possibleSmbVersions[0];
-		} else if(profile.equals("Windows 8")) {
-			return possibleSmbVersions[1];
-		} else if(profile.equals("Windows Server 2008")) {
-			return possibleSmbVersions[2];
-		} else if(profile.equals("Windows Server 2012")) {
-			return possibleSmbVersions[3];
-		} else if(profile.equals("Linux")) {
-			return possibleSmbVersions[4];
-		} else {
-			return possibleSmbVersions[new SecureRandom().nextInt(possibleSmbVersions.length)];
+		if (transSub[0] == 0x00 && transSub[1] == 0x0b) {
+			packetType = new byte[] { 0x0c };
+			fragLength = new byte[] { 0x44, 0x00 };
+			callID = new byte[] { 0x01, 0x00, 0x00, 0x00 };
+			byte[] maxXmitFrag = { (byte) 0xb8, 0x10 };
+			byte[] maxRecvFrag = { (byte) 0xb8, 0x10 };
+			byte[] assocGroup = { 0x4a, 0x41, 0x00, 0x00 };
+			byte[] scndryAddrLen = { 0x0d, 0x00 };
+			byte[] scndryAddr = { 0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c, 0x73,
+					0x72, 0x76, 0x73, 0x76, 0x63, 0x00, 0x00 };
+			byte[] numResults = { 0x01, 0x00, 0x00, 0x00 };
+			byte[] ctxItem = { 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, (byte) 0x88,
+					(byte) 0x8a, (byte) 0xeb, 0x1c, (byte) 0xc9, 0x11,
+					(byte) 0x9f, (byte) 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48,
+					0x60, 0x02, 0x00, 0x00, 0x00 };
+
+			response = HelperUtils.concat(majorVersion, minorVersion,
+					packetType, packetFlags, dataRepres, fragLength,
+					authLength, callID, maxXmitFrag, maxRecvFrag, assocGroup,
+					scndryAddrLen, scndryAddr, numResults, ctxItem);
+		} else if (transSub[0] == 0x00 && transSub[1] == 0x00) {
+			packetType = new byte[] { 0x02 };
+			byte[] tmp = ByteBuffer.allocate(4).putInt(length).array();
+			fragLength = new byte[] { tmp[3], tmp[2] };
+			callID = new byte[] { 0x02, 0x00, 0x00, 0x00 };
+			tmp = ByteBuffer.allocate(4).putInt(length - 24).array();
+			byte[] allocHint = new byte[] { tmp[3], tmp[2], tmp[1], tmp[0] };
+			byte[] contextID = { 0x00, 0x00 };
+			byte[] cancelCount = { 0x00, 0x00 };
+
+			response = HelperUtils.concat(majorVersion, minorVersion,
+					packetType, packetFlags, dataRepres, fragLength,
+					authLength, callID, allocHint, contextID, cancelCount);
 		}
+		return response;
 	}
-	
-	private static byte[] serverName		= HelperUtils.fillWithZero(HelperUtils.getRandomString(16, true).getBytes());
-	private static String[] serverVersion	= initServerVersion();
-		
-	private byte[] message						= null; 
-	private static final byte[] serverGUID		= HelperUtils.randomBytes(16);
-	private boolean authenticateNext			= false;
-	//components of a SMB packet
-	private byte[] serverComp 		= new byte[4];
-	private byte[] smbCommand		= new byte[1];
-	private byte[] ntStat 			= new byte[4];
-	private byte[] smbFlags			= new byte[1];	
-	private byte[] smbFlags2		= new byte[2];
-	private byte[] processIDHigh	= new byte[2];
-	private byte[] signature	 	= new byte[8];
-	private byte[] reserved			= new byte[2];
-	private byte[] treeID			= new byte[2];
-	private byte[] processID		= new byte[2];
-	private byte[] userID			= new byte[2];
-	private byte[] multiplexID		= new byte[2];
 
 	/**
-	 * Breaks a message from the client down into its components
-	 * @param message that is analyzed
-	 */
-	private void parseMessageHeader(byte[] message) {
-		this.message 	= message;
-		serverComp 		= new byte[]{message[4], message[5], message[6], message[7]};
-		smbCommand		= new byte[]{message[8]};
-		ntStat 			= new byte[]{message[9], message[10], message[11], message[12]};
-		smbFlags		= new byte[]{(byte) (message[13] | 0x80)};		// | 0x80 for mark response bit
-		smbFlags2		= new byte[]{message[14], message[15]};
-		processIDHigh	= new byte[]{message[16], message[17]};
-		signature	 	= new byte[]{message[18], message[19], message[20], message[21], message[22], message[23], message[24], message[25]};
-		reserved		= new byte[]{message[26], message[27]};
-		treeID			= new byte[]{message[28], message[29]};
-		processID		= new byte[]{message[30], message[31]};
-		userID			= new byte[]{message[32], message[33]};
-		multiplexID		= new byte[]{message[34], message[35]};
-	}
-	
-	/**
-	 * Wraps the Netbios header around a response
-	 * @param response that is wrapped
-	 * @return wrapped response
-	 */
-	private byte[] wrapNetbios(byte[] response) {
-		byte[] netbios = {0x00};
-		byte[] buffer = ByteBuffer.allocate(4).putInt(response.length).array();	// allocate(4) because int is 4 bytes long
-		byte[] netbiosLength = {buffer[1], buffer[2], buffer[3]};			// only bytes 1-3 needed, byte 0 is not needed
-		return HelperUtils.concat(netbios, netbiosLength, response);
-	}
-	
-	/**
-	 * Wraps the header around a response
-	 * @param response that is wrapped
-	 * @return wrapped response
+	 * Builds the echo packet
+	 * 
+	 * @return echo packet
 	 */
-	private byte[] wrapHeader(byte[] response) {
-		byte[] header = new byte[0];
-		return HelperUtils.concat(header, serverComp, smbCommand, ntStat, smbFlags, smbFlags2, processIDHigh, signature,
-								reserved, treeID, processID, userID, multiplexID, response);
+	private Packet getEcho() {
+		byte[] wordCount = { 0x01 };
+		byte[] echoSeq = { 0x01, 0x00 };
+		byte[] byteCount = { 0x10, 0x00 };
+		byte[] echoData = { (byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0,
+				(byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0,
+				(byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0,
+				(byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0 };
+		byte[] response = HelperUtils.concat(wordCount, echoSeq, byteCount,
+				echoData);
+		return new Packet(wrapNetbios(wrapHeader(response)));
 	}
-	
+
 	/**
 	 * Builds the negotiate packet
+	 * 
 	 * @return negotiate packet
 	 */
 	private Packet getNego() {
-		byte[] wordCount	= {0x11};
-		byte[] dialect		= evaluateDialect();		
-		byte[] secMode		= {0x03};
-		byte[] maxMpxC 		= {0x32, 0x00};
-		byte[] maxVcs		= {0x01, 0x00};
-		byte[] maxBufSize	= {0x04, 0x11, 0x00, 0x00};
-		byte[] maxRawBuf	= {0x00, 0x00, 0x01, 0x00};
-		byte[] sessionKey	= {0x00, 0x00, 0x00, 0x00};
-		byte[] capabilities	= {(byte) 0xfc, (byte) 0xe3, 0x01, (byte) 0x80};
-		byte[] sysTime		= getTimeInBytes();
-		byte[] timeZone		= getTimeZoneInBytes();
-		byte[] keyLength	= {0x00};
-		byte[] byteCount	= {0x3a, 0x00};			
-		byte[] guid			= serverGUID;
-		byte[] secBlob		= {0x60, 0x28, 0x06, 0x06};
-		byte[] oid			= {0x2b, 0x06, 0x01, 0x05, 0x05, 0x02};
-		byte[] protectNeg	= {(byte) 0xa0, 0x1e};
-		byte[] negToken		= {0x30, 0x1c, (byte) 0xa0, 0x1a, 0x30, 0x18};
-		byte[] mechType		= {0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, (byte) 0x82, 0x37, 0x02, 0x02, 0x1e};
-		byte[] mechType2	= {0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, (byte) 0x82, 0x37, 0x02, 0x02, 0x0a};
-		
-		byte[] response = HelperUtils.concat(wordCount, dialect, secMode, maxMpxC, maxVcs, maxBufSize, maxRawBuf,
-						sessionKey, capabilities, sysTime, timeZone, keyLength, byteCount, guid, secBlob, oid,
-						protectNeg, negToken, mechType, mechType2);
+		byte[] wordCount = { 0x11 };
+		byte[] dialect = evaluateDialect();
+		byte[] secMode = { 0x03 };
+		byte[] maxMpxC = { 0x32, 0x00 };
+		byte[] maxVcs = { 0x01, 0x00 };
+		byte[] maxBufSize = { 0x04, 0x11, 0x00, 0x00 };
+		byte[] maxRawBuf = { 0x00, 0x00, 0x01, 0x00 };
+		byte[] sessionKey = { 0x00, 0x00, 0x00, 0x00 };
+		byte[] capabilities = { (byte) 0xfc, (byte) 0xe3, 0x01, (byte) 0x80 };
+		byte[] sysTime = getTimeInBytes();
+		byte[] timeZone = getTimeZoneInBytes();
+		byte[] keyLength = { 0x00 };
+		byte[] byteCount = { 0x3a, 0x00 };
+		byte[] guid = serverGUID;
+		byte[] secBlob = { 0x60, 0x28, 0x06, 0x06 };
+		byte[] oid = { 0x2b, 0x06, 0x01, 0x05, 0x05, 0x02 };
+		byte[] protectNeg = { (byte) 0xa0, 0x1e };
+		byte[] negToken = { 0x30, 0x1c, (byte) 0xa0, 0x1a, 0x30, 0x18 };
+		byte[] mechType = { 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01,
+				(byte) 0x82, 0x37, 0x02, 0x02, 0x1e };
+		byte[] mechType2 = { 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01,
+				(byte) 0x82, 0x37, 0x02, 0x02, 0x0a };
+
+		byte[] response = HelperUtils.concat(wordCount, dialect, secMode,
+				maxMpxC, maxVcs, maxBufSize, maxRawBuf, sessionKey,
+				capabilities, sysTime, timeZone, keyLength, byteCount, guid,
+				secBlob, oid, protectNeg, negToken, mechType, mechType2);
 		return new Packet(wrapNetbios(wrapHeader(response)));
 	}
-	
+
 	/**
-	 * Evaluates what Dialects are offered by the client and which position the used NT LM 0.12 dialect is at
-	 * @return position of the NT LM 0.12 dialect
+	 * Builds the nt create packet
+	 * 
+	 * @return nt create packet
 	 */
-	private byte[] evaluateDialect() {
-		byte[] dialectMsg = new byte[message.length-39];
-		System.arraycopy(message, 39, dialectMsg, 0, message.length - 39);
-		short dialectNumber = 0;
-		for(int i = 0, start = 0; i < dialectMsg.length; i++) {
-			if(dialectMsg[i] == 0x00) {
-				byte[] dialect = new byte[i-start];
-				System.arraycopy(dialectMsg, start, dialect, 0, i-start);
-				if(HelperUtils.byteToStr(dialect).contains("NT LM 0.12")) {
-					return new byte[]{(byte)dialectNumber, (byte)(dialectNumber >> 8)};
-				}
-				start = i+1;
-				dialectNumber++;
-			}
-		}
-		return new byte[]{0x00, 0x00};
+	private Packet getNTCreate() {
+		byte[] wordCount = { 0x22 };
+		byte[] andXCommand = { (byte) 0xff };
+		byte[] reserved = { 0x00 };
+		byte[] andXOffset = { 0x67, 0x00 };
+		byte[] oplockLevel = { 0x00 };
+		byte[] fid = { (byte) 0x00, 0x40 };
+		byte[] createAction = { 0x01, 0x00, 0x00, 0x00 };
+		byte[] created = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+		byte[] lastAccess = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+		byte[] lastWrite = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+		byte[] change = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+		byte[] fileAttributes = { (byte) 0x80, 0x00, 0x00, 0x00 };
+		byte[] allocationSize = { 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00 };
+		byte[] endOfFile = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+		byte[] fileType = { 0x02, 0x00 };
+		byte[] ipcState = { (byte) 0xff, 0x05 };
+		byte[] isDirectory = { 0x00 };
+		byte[] byteCount = { 0x00, 0x00 };
+
+		byte[] response = HelperUtils.concat(wordCount, andXCommand, reserved,
+				andXOffset, oplockLevel, fid, createAction, created,
+				lastAccess, lastWrite, change, fileAttributes, allocationSize,
+				endOfFile, fileType, ipcState, isDirectory, byteCount);
+		return new Packet(wrapNetbios(wrapHeader(response)));
 	}
-	
+
 	/**
 	 * Builds the session setup packet
-	 * @ret	urn session setup packet
+	 * 
+	 * @ret urn session setup packet
 	 */
 	private Packet getSessSetup() {
-		if(authenticateNext) {
+		if (authenticateNext) {
 			return new Packet(getSetupAuth());
 		} else {
 			authenticateNext = true;
 			return new Packet(getSetupChal());
 		}
 	}
-	
+
+	/**
+	 * Builds the session setup packet for authentication required
+	 * 
+	 * @return session setup authentication packet
+	 */
+	private byte[] getSetupAuth() {
+		byte[] wordCount = { 0x04 };
+		byte[] andXCommand = { (byte) 0xff };
+		byte[] reserved = { 0x00 };
+		byte[] andXOffset = { (byte) 0xa2, 0x00 };
+		byte[] action = { 0x01, 0x00 };
+		byte[] secBlobLength;
+		byte[] byteCount;
+		byte[] secBlob = { (byte) 0xa1, 0x07, 0x30, 0x05, (byte) 0xa0, 0x03,
+				0x0a, 0x01, 0x00 };
+		byte[] nativOS = HelperUtils.fillWithZeroExtended(serverVersion[0]
+				.getBytes());
+		byte[] nativLanMngr = HelperUtils.fillWithZeroExtended(serverVersion[1]
+				.getBytes());
+
+		byte[] buffer = ByteBuffer.allocate(4).putInt(secBlob.length).array();
+		secBlobLength = new byte[] { buffer[3], buffer[2] };
+		buffer = ByteBuffer.allocate(4)
+				.putInt(secBlob.length + nativOS.length + nativLanMngr.length)
+				.array();
+		byteCount = new byte[] { buffer[3], buffer[2] };
+
+		byte[] response = HelperUtils.concat(wordCount, andXCommand, reserved,
+				andXOffset, action, secBlobLength, byteCount, secBlob, nativOS,
+				nativLanMngr);
+		return wrapNetbios(wrapHeader(response));
+	}
+
 	/**
 	 * Builds the session setup challange packet
+	 * 
 	 * @return session setup challange packet
 	 */
 	private byte[] getSetupChal() {
-		byte[] wordCount			= {0x04};
-		byte[] andXCommand			= {(byte) 0xff};
-		byte[] reserved				= {0x00};
-		byte[] andXOffset			= {0x60, 0x01};
-		byte[] action				= {0x00, 0x00};
+		byte[] wordCount = { 0x04 };
+		byte[] andXCommand = { (byte) 0xff };
+		byte[] reserved = { 0x00 };
+		byte[] andXOffset = { 0x60, 0x01 };
+		byte[] action = { 0x00, 0x00 };
 		byte[] secBlobLength;
 		byte[] byteCount;
-		byte[] secBlob				= {(byte) 0xa1, (byte) 0x81, (byte) 0xc4};
-		byte[] negToken				= {0x30, (byte) 0x81, (byte) 0xc1, (byte) 0xa0, 0x03, 0x0a, 0x01};
-		byte[] negResult			= {0x01};
-		byte[] negToken2			= {(byte) 0xa1, 0x0c, 0x06, 0x0a};
-		byte[] supportedMech		= {0x2b, 0x06, 0x01, 0x04, 0x01, (byte) 0x82, 0x37, 0x02, 0x02, 0x0a};
-		byte[] negToken3			= {(byte) 0xa2, (byte) 0x81, (byte) 0xab, 0x04, (byte) 0x81, (byte) 0xa8};
-		byte[] ntlmsspId			= {0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00};
-		byte[] nlmMsgType			= {0x02, 0x00, 0x00, 0x00};
-		byte[] buffer				= ByteBuffer.allocate(4).putInt(serverName.length).array();
-		byte[] targetNameLength		= new byte[]{buffer[3], buffer[2]};
-		byte[] targetNameMaxLength	= new byte[]{buffer[3], buffer[2]}; 
-		byte[] targetNameOffset		= {0x38, 0x00, 0x00, 0x00};
-		byte[] flags				= {0x15, (byte) 0x82, (byte) 0x8a, 0x60};
-		if(!serverVersion[0].contains("Unix")) {
+		byte[] secBlob = { (byte) 0xa1, (byte) 0x81, (byte) 0xc4 };
+		byte[] negToken = { 0x30, (byte) 0x81, (byte) 0xc1, (byte) 0xa0, 0x03,
+				0x0a, 0x01 };
+		byte[] negResult = { 0x01 };
+		byte[] negToken2 = { (byte) 0xa1, 0x0c, 0x06, 0x0a };
+		byte[] supportedMech = { 0x2b, 0x06, 0x01, 0x04, 0x01, (byte) 0x82,
+				0x37, 0x02, 0x02, 0x0a };
+		byte[] negToken3 = { (byte) 0xa2, (byte) 0x81, (byte) 0xab, 0x04,
+				(byte) 0x81, (byte) 0xa8 };
+		byte[] ntlmsspId = { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00 };
+		byte[] nlmMsgType = { 0x02, 0x00, 0x00, 0x00 };
+		byte[] buffer = ByteBuffer.allocate(4).putInt(serverName.length)
+				.array();
+		byte[] targetNameLength = new byte[] { buffer[3], buffer[2] };
+		byte[] targetNameMaxLength = new byte[] { buffer[3], buffer[2] };
+		byte[] targetNameOffset = { 0x38, 0x00, 0x00, 0x00 };
+		byte[] flags = { 0x15, (byte) 0x82, (byte) 0x8a, 0x60 };
+		if (!serverVersion[0].contains("Unix")) {
 			flags[3] = (byte) (flags[3] | 0x02);
 		}
-		byte[] challenge			= HelperUtils.randomBytes(8);
-		byte[] reserved2			= {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-		byte[] targetInfoLength		= {0x60, 0x00};
-		byte[] targetInfoMaxLength	= {0x60, 0x00};
-		byte[] targetInfoOffset		= {0x48, 0x00, 0x00, 0x00};
+		byte[] challenge = HelperUtils.randomBytes(8);
+		byte[] reserved2 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+		byte[] targetInfoLength = { 0x60, 0x00 };
+		byte[] targetInfoMaxLength = { 0x60, 0x00 };
+		byte[] targetInfoOffset = { 0x48, 0x00, 0x00, 0x00 };
 		byte[] version = null;
-		if(serverVersion[0].contains("Windows 7") || serverVersion[0].contains("Windows Server 2008")) {
-			version = new byte[]{0x06, 0x01, (byte) 0xb0, 0x1d, 0x00, 0x00, 0x00, 0x0f};
-		} else if(serverVersion[0].contains("Windows 8") || serverVersion[0].contains("Windows Server 2012")) {
-			version = new byte[]{0x06, 0x02, (byte) 0xf0, 0x23, 0x00, 0x00, 0x00, 0x0f};
+		if (serverVersion[0].contains("Windows 7")
+				|| serverVersion[0].contains("Windows Server 2008")) {
+			version = new byte[] { 0x06, 0x01, (byte) 0xb0, 0x1d, 0x00, 0x00,
+					0x00, 0x0f };
+		} else if (serverVersion[0].contains("Windows 8")
+				|| serverVersion[0].contains("Windows Server 2012")) {
+			version = new byte[] { 0x06, 0x02, (byte) 0xf0, 0x23, 0x00, 0x00,
+					0x00, 0x0f };
 		}
 		// serverName
-		byte[] attributeNBDomain	= {0x02, 0x00, 0x10, 0x00};
-		// serverName	
-		byte[] attributeNBcomputer	= {0x01, 0x00, 0x10, 0x00};
-		// serverName	
-		byte[] attributeDNSDomain	= {0x04, 0x00, 0x10, 0x00};
+		byte[] attributeNBDomain = { 0x02, 0x00, 0x10, 0x00 };
 		// serverName
-		byte[] attributeDNScomputer	= {0x03, 0x00, 0x10, 0x00};
+		byte[] attributeNBcomputer = { 0x01, 0x00, 0x10, 0x00 };
 		// serverName
-		byte[] attributeTimeStamp   = {0x07, 0x00, 0x08, 0x00};
+		byte[] attributeDNSDomain = { 0x04, 0x00, 0x10, 0x00 };
+		// serverName
+		byte[] attributeDNScomputer = { 0x03, 0x00, 0x10, 0x00 };
+		// serverName
+		byte[] attributeTimeStamp = { 0x07, 0x00, 0x08, 0x00 };
 		byte[] timeStamp = getTimeInBytes();
-		byte[] attributeEnd			= {0x00, 0x00, 0x00, 0x00};
-		secBlob						= HelperUtils.concat(secBlob, negToken, negResult, negToken2, supportedMech, negToken3,
-											ntlmsspId, nlmMsgType, targetNameLength, targetNameMaxLength, targetNameOffset,
-											flags, challenge, reserved2, targetInfoLength, targetInfoMaxLength, targetInfoOffset,
-											version, serverName, attributeNBDomain, serverName, attributeNBcomputer, serverName,
-											attributeDNSDomain, serverName, attributeDNScomputer, serverName, attributeTimeStamp,
-											timeStamp, attributeEnd);
-		byte[] nativOS				= HelperUtils.fillWithZeroExtended(serverVersion[0].getBytes());
-		byte[] nativLanMngr			= HelperUtils.fillWithZeroExtended(serverVersion[1].getBytes());
-		buffer						= ByteBuffer.allocate(4).putInt(secBlob.length).array();
-		secBlobLength				= new byte[]{buffer[3], buffer[2]};
-		buffer						= ByteBuffer.allocate(4).putInt(secBlob.length + nativOS.length + nativLanMngr.length).array();
-		byteCount					= new byte[]{buffer[3], buffer[2]};
-		
-		ntStat 					= new byte[]{0x16, 0x00, 0x00, (byte) 0xc0};
-		userID					= new byte[]{0x00, 0x08};
-		
-		byte[] response = HelperUtils.concat(wordCount, andXCommand, reserved, andXOffset, action, secBlobLength,
-											byteCount, secBlob, nativOS, nativLanMngr);
+		byte[] attributeEnd = { 0x00, 0x00, 0x00, 0x00 };
+		secBlob = HelperUtils.concat(secBlob, negToken, negResult, negToken2,
+				supportedMech, negToken3, ntlmsspId, nlmMsgType,
+				targetNameLength, targetNameMaxLength, targetNameOffset, flags,
+				challenge, reserved2, targetInfoLength, targetInfoMaxLength,
+				targetInfoOffset, version, serverName, attributeNBDomain,
+				serverName, attributeNBcomputer, serverName,
+				attributeDNSDomain, serverName, attributeDNScomputer,
+				serverName, attributeTimeStamp, timeStamp, attributeEnd);
+		byte[] nativOS = HelperUtils.fillWithZeroExtended(serverVersion[0]
+				.getBytes());
+		byte[] nativLanMngr = HelperUtils.fillWithZeroExtended(serverVersion[1]
+				.getBytes());
+		buffer = ByteBuffer.allocate(4).putInt(secBlob.length).array();
+		secBlobLength = new byte[] { buffer[3], buffer[2] };
+		buffer = ByteBuffer.allocate(4)
+				.putInt(secBlob.length + nativOS.length + nativLanMngr.length)
+				.array();
+		byteCount = new byte[] { buffer[3], buffer[2] };
+
+		ntStat = new byte[] { 0x16, 0x00, 0x00, (byte) 0xc0 };
+		userID = new byte[] { 0x00, 0x08 };
+
+		byte[] response = HelperUtils.concat(wordCount, andXCommand, reserved,
+				andXOffset, action, secBlobLength, byteCount, secBlob, nativOS,
+				nativLanMngr);
 		return wrapNetbios(wrapHeader(response));
 	}
-	
+
 	/**
-	 * Builds the session setup packet for authentication required
-	 * @return session setup authentication packet
+	 * Returns the command number from the current message
+	 * 
+	 * @return command number
 	 */
-	private byte[] getSetupAuth() {
-		byte[] wordCount		= {0x04};
-		byte[] andXCommand		= {(byte) 0xff};
-		byte[] reserved			= {0x00};
-		byte[] andXOffset		= {(byte) 0xa2, 0x00};
-		byte[] action			= {0x01, 0x00};
-		byte[] secBlobLength;
-		byte[] byteCount;
-		byte[] secBlob			= {(byte) 0xa1, 0x07, 0x30, 0x05, (byte) 0xa0, 0x03, 0x0a, 0x01, 0x00};
-		byte[] nativOS			= HelperUtils.fillWithZeroExtended(serverVersion[0].getBytes());
-		byte[] nativLanMngr		= HelperUtils.fillWithZeroExtended(serverVersion[1].getBytes());
-		
-		byte[] buffer				= ByteBuffer.allocate(4).putInt(secBlob.length).array();
-		secBlobLength				= new byte[]{buffer[3], buffer[2]};
-		buffer						= ByteBuffer.allocate(4).putInt(secBlob.length + nativOS.length + nativLanMngr.length).array();
-		byteCount					= new byte[]{buffer[3], buffer[2]};
-		
-		byte[] response = HelperUtils.concat(wordCount, andXCommand, reserved, andXOffset, action, secBlobLength,
-				byteCount, secBlob, nativOS, nativLanMngr);
-		return wrapNetbios(wrapHeader(response));
+	private byte getSmbCommand() {
+		return smbCommand[0];
 	}
-	
+
 	/**
-	 * Builds the tree connect packet
-	 * @return tree connect packet
+	 * Builds the trans packet
+	 * 
+	 * @return trans packet
 	 */
-	private Packet getTreeCon() {
-		String str 			= HelperUtils.byteToStr(message);
-		byte[] wordCount	= {0x00};
-		byte[] andXCommand	= {0x00, 0x00};
-		byte[] response 	= null;
-		if(str.contains("IPC$") || str.contains("C$")) {
-			wordCount			= new byte[] {0x07};
-			andXCommand			= new byte[] {(byte) 0xff};
-			byte[] reserved				= {0x00};
-			byte[] andXOffset			= {0x38, 0x00};
-			byte[] optionalSupport		= {0x01, 0x00};
-			byte[] maxShareAccess		= {(byte) 0xff, (byte) 0xff, 0x1f, 0x00};
-			byte[] guestMaxShareAccess	= {(byte) 0xff, (byte) 0xff, 0x1f, 0x00};
-			byte[] byteCount			= {0x07, 0x00};
-			byte[] service				= {0x49, 0x50, 0x43, 0x00};
-			byte[] extraParameters		= {0x00, 0x00, 0x00};
-		
-			treeID						= new byte[]{0x00, 0x08};
-						
-			response = HelperUtils.concat(wordCount, andXCommand, reserved, andXOffset, optionalSupport, maxShareAccess,
-											guestMaxShareAccess, byteCount, service, extraParameters);
-		} else if(str.contains("ADMIN$")) {
-			ntStat = new byte[] {0x22, 0x00, 0x00, (byte) 0xc0};
-			response = HelperUtils.concat(wordCount, andXCommand);
-		} else {
-			ntStat = new byte[] {(byte) 0xcc, 0x00, 0x00, (byte) 0xc0};
-			response = HelperUtils.concat(wordCount, andXCommand);
+	private Packet getTrans() {
+		byte[] transSub = getTransSub();
+		byte[] response = null;
+		if (transSub[0] == 0x00 && transSub[1] == 0x0b) { // bind_ack
+			byte[] wordCount = { 0x0a };
+			byte[] totalParamCount = { 0x00, 0x00 };
+			byte[] totalDataCount = { 0x44, 0x00 };
+			byte[] reserved = { 0x00, 0x00 };
+			byte[] paramCount = { 0x00, 0x00 };
+			byte[] paramOffset = { 0x38, 0x00 };
+			byte[] paramDisplace = { 0x00, 0x00 };
+			byte[] dataCount = { 0x44, 0x00 };
+			byte[] dataOffset = { 0x38, 0x00 };
+			byte[] dataDisplace = { 0x00, 0x00 };
+			byte[] setupCount = { 0x00 };
+			byte[] reserved2 = { 0x00 };
+			byte[] byteCount = { 0x45, 0x00 };
+			byte[] padding = { 0x00 };
+
+			byte[] dcerpc = getDceRpc(transSub, 0);
+
+			response = HelperUtils.concat(wordCount, totalParamCount,
+					totalDataCount, reserved, paramCount, paramOffset,
+					paramDisplace, dataCount, dataOffset, dataDisplace,
+					setupCount, reserved2, byteCount, padding, dcerpc);
+
+		} else if (transSub[0] == 0x00 && transSub[1] == 0x00) { // netShareEnumAll
+			byte[] wordCount = { 0x0a };
+			byte[] totalParamCount = { 0x00, 0x00 };
+			byte[] totalDataCount = { 0x20, 0x01 };
+			byte[] reserved = { 0x00, 0x00 };
+			byte[] paramCount = { 0x00, 0x00 };
+			byte[] paramOffset = { 0x38, 0x00 };
+			byte[] paramDisplace = { 0x00, 0x00 };
+			byte[] dataCount = { 0x20, 0x01 };
+			byte[] dataOffset = { 0x38, 0x00 };
+			byte[] dataDisplace = { 0x00, 0x00 };
+			byte[] setupCount = { 0x00 };
+			byte[] reserved2 = { 0x00 };
+			byte[] byteCount = new byte[2]/* = {0x21, 0x01} */;
+			byte[] padding = { 0x00 };
+
+			byte[] dcerpc = new byte[24];
+
+			byte[] levelPointer = { 0x01, 0x00, 0x00, 0x00 };
+			byte[] ctr = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00 };
+			byte[] ctr1 = { 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00,
+					0x03, 0x00, 0x00, 0x00 };
+			byte[] array1Pointer = { 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+					(byte) 0x80, 0x0c, 0x00, 0x02, 0x00 };
+			byte[] array2Pointer = { 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+					(byte) 0x80, 0x14, 0x00, 0x02, 0x00 };
+			byte[] array3Pointer = { 0x18, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00,
+					(byte) 0x80, 0x1c, 0x00, 0x02, 0x00 };
+			byte[] array1 = { 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+					0x07, 0x00, 0x00, 0x00, 0x41, 0x00, 0x44, 0x00, 0x4d, 0x00,
+					0x49, 0x00, 0x4e, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,
+					0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00,
+					0x00, 0x00, 0x52, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x6f, 0x00,
+					0x74, 0x00, 0x65, 0x00, 0x20, 0x00, 0x41, 0x00, 0x64, 0x00,
+					0x6d, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x00, 0x00 };
+			byte[] array2 = { 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+					0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x43, 0x00, 0x24, 0x00,
+					0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00,
+					0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x44, 0x00, 0x65, 0x00,
+					0x66, 0x00, 0x61, 0x00, 0x75, 0x00, 0x6c, 0x00, 0x74, 0x00,
+					0x20, 0x00, 0x73, 0x00, 0x68, 0x00, 0x61, 0x00, 0x72, 0x00,
+					0x65, 0x00 };
+			byte[] array3 = { 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
+					0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x49, 0x00, 0x50, 0x00,
+					0x43, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00,
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
+					0x52, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x6f, 0x00, 0x74, 0x00,
+					0x65, 0x00, 0x20, 0x00, 0x49, 0x00, 0x50, 0x00, 0x43, 0x00,
+					0x00, 0x00 };
+			byte[] totalEntries = { 0x00, 0x00, 0x03, 0x00, 0x00, 0x00 };
+			byte[] referentID = { 0x20, 0x00, 0x02, 0x00 };
+			byte[] resumeHandle = { 0x00, 0x00, 0x00, 0x00 };
+			byte[] windowsError = { 0x00, 0x00, 0x00, 0x00 };
+			int tmp = padding.length + dcerpc.length + levelPointer.length
+					+ ctr.length + ctr1.length + array1Pointer.length
+					+ array2Pointer.length + array3Pointer.length
+					+ array1.length + array2.length + array3.length
+					+ totalEntries.length + referentID.length
+					+ resumeHandle.length + windowsError.length;
+			byte[] tmp2 = ByteBuffer.allocate(4).putInt(tmp).array();
+			byteCount = new byte[] { tmp2[3], tmp2[2] };
+			dcerpc = getDceRpc(transSub, tmp - 1);
+
+			response = HelperUtils.concat(wordCount, totalParamCount,
+					totalDataCount, reserved, paramCount, paramOffset,
+					paramDisplace, dataCount, dataOffset, dataDisplace,
+					setupCount, reserved2, byteCount, padding, dcerpc,
+					levelPointer, ctr, ctr1, array1Pointer, array2Pointer,
+					array3Pointer, array1, array2, array3, totalEntries,
+					referentID, resumeHandle, windowsError);
 		}
-		
-		return new Packet(wrapNetbios(wrapHeader(response)));
-	}
-	
-	/**
-	 * Builds the nt create packet
-	 * @return nt create packet
-	 */
-	private Packet getNTCreate() {
-		byte[] wordCount		= {0x22};
-		byte[] andXCommand		= {(byte) 0xff};
-		byte[] reserved			= {0x00};
-		byte[] andXOffset		= {0x67, 0x00};
-		byte[] oplockLevel		= {0x00};
-		byte[] fid				= {(byte) 0x00, 0x40};
-		byte[] createAction		= {0x01, 0x00, 0x00, 0x00};
-		byte[] created			= {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-		byte[] lastAccess		= {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-		byte[] lastWrite		= {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-		byte[] change			= {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-		byte[] fileAttributes	= {(byte) 0x80, 0x00, 0x00, 0x00};
-		byte[] allocationSize	= {0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-		byte[] endOfFile		= {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-		byte[] fileType			= {0x02, 0x00};
-		byte[] ipcState			= {(byte) 0xff, 0x05};
-		byte[] isDirectory		= {0x00};
-		byte[] byteCount		= {0x00, 0x00};
-		
-		byte[] response = HelperUtils.concat(wordCount, andXCommand, reserved, andXOffset, oplockLevel, fid,
-											createAction, created, lastAccess, lastWrite, change, fileAttributes, allocationSize,
-											endOfFile, fileType, ipcState, isDirectory, byteCount);
+
 		return new Packet(wrapNetbios(wrapHeader(response)));
 	}
-	
+
 	/**
-	 * Builds the trans packet
-	 * @return trans packet
+	 * Builds the trans2 packet
+	 * 
+	 * @return trans2 packet
 	 */
-	private Packet getTrans() {
-		byte[] transSub	= getTransSub();
+	private Packet getTrans2() {
 		byte[] response = null;
-		if(transSub[0] == 0x00 && transSub[1] == 0x0b) { //bind_ack
-			byte[] wordCount		= {0x0a};
-			byte[] totalParamCount	= {0x00,0x00};
-			byte[] totalDataCount	= {0x44,0x00};
-			byte[] reserved			= {0x00, 0x00};
-			byte[] paramCount		= {0x00, 0x00};
-			byte[] paramOffset		= {0x38, 0x00};
-			byte[] paramDisplace	= {0x00, 0x00};
-			byte[] dataCount		= {0x44, 0x00};
-			byte[] dataOffset		= {0x38, 0x00};
-			byte[] dataDisplace		= {0x00, 0x00};
-			byte[] setupCount		= {0x00};
-			byte[] reserved2		= {0x00};
-			byte[] byteCount		= {0x45, 0x00};
-			byte[] padding			= {0x00};
-			
-			byte[] dcerpc			= getDceRpc(transSub, 0); 
-			
-			response = HelperUtils.concat(wordCount, totalParamCount, totalDataCount, reserved, paramCount, paramOffset,
-												paramDisplace, dataCount, dataOffset, dataDisplace, setupCount, reserved2, byteCount, padding, dcerpc);
-			
-		} else if(transSub[0] == 0x00 && transSub[1] == 0x00) { //netShareEnumAll
-			byte[] wordCount		= {0x0a};
-			byte[] totalParamCount	= {0x00, 0x00};
-			byte[] totalDataCount	= {0x20, 0x01};
-			byte[] reserved			= {0x00, 0x00};
-			byte[] paramCount		= {0x00, 0x00};
-			byte[] paramOffset		= {0x38, 0x00};
-			byte[] paramDisplace	= {0x00, 0x00};
-			byte[] dataCount		= {0x20, 0x01};
-			byte[] dataOffset		= {0x38, 0x00};
-			byte[] dataDisplace		= {0x00, 0x00};
-			byte[] setupCount		= {0x00};
-			byte[] reserved2		= {0x00};
-			byte[] byteCount		= new byte[2]/*= {0x21, 0x01}*/;
-			byte[] padding			= {0x00};
-			
-			byte[] dcerpc			= new byte[24];
-			
-			byte[] levelPointer		= {0x01, 0x00, 0x00, 0x00};
-			byte[] ctr				= {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
-			byte[] ctr1				= {0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00};
-			byte[] array1Pointer	= {0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, (byte) 0x80, 0x0c, 0x00, 0x02, 0x00};
-			byte[] array2Pointer	= {0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, (byte) 0x80, 0x14, 0x00, 0x02, 0x00};
-			byte[] array3Pointer	= {0x18, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, (byte) 0x80, 0x1c, 0x00, 0x02, 0x00};
-			byte[] array1			= {0x07, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x41, 0x00, 0x44, 0x00, 0x4d, 0x00, 
-										0x49, 0x00, 0x4e, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 
-										0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x52, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x6f, 0x00, 0x74, 0x00, 
-										0x65, 0x00, 0x20, 0x00, 0x41, 0x00, 0x64, 0x00, 0x6d, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x00, 0x00};
-			byte[] array2			= {0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x43, 0x00, 
-										0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 
-										0x00, 0x00, 0x44, 0x00, 0x65, 0x00, 0x66, 0x00, 0x61, 0x00, 0x75, 0x00, 0x6c, 0x00, 0x74, 0x00, 
-										0x20, 0x00, 0x73, 0x00, 0x68, 0x00, 0x61, 0x00, 0x72, 0x00, 0x65, 0x00};
-			byte[] array3			= {0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 
-										0x00, 0x00, 0x49, 0x00, 0x50, 0x00, 0x43, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 
-									0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x52, 0x00, 0x65, 0x00, 0x6d, 0x00, 
-										0x6f, 0x00, 0x74, 0x00, 0x65, 0x00, 0x20, 0x00, 0x49, 0x00, 0x50, 0x00, 0x43, 0x00, 0x00, 0x00};
-			byte[] totalEntries		= {0x00, 0x00, 0x03, 0x00, 0x00, 0x00};
-			byte[] referentID		= {0x20, 0x00, 0x02, 0x00};
-			byte[] resumeHandle		= {0x00, 0x00, 0x00, 0x00};
-			byte[] windowsError		= {0x00, 0x00, 0x00, 0x00};
-			int tmp					= padding.length + dcerpc.length + levelPointer.length + ctr.length + ctr1.length
-										+ array1Pointer.length + array2Pointer.length + array3Pointer.length + array1.length
-										+ array2.length + array3.length + totalEntries.length + referentID.length + resumeHandle.length
-										+ windowsError.length;
-			byte[] tmp2				= ByteBuffer.allocate(4).putInt(tmp).array();
-			byteCount				= new byte[] {tmp2[3], tmp2[2]};
-			dcerpc					= getDceRpc(transSub, tmp-1);
-
-			response = HelperUtils.concat(wordCount, totalParamCount, totalDataCount, reserved, paramCount, paramOffset,
-											paramDisplace, dataCount, dataOffset, dataDisplace, setupCount, reserved2, byteCount, padding, dcerpc,
-											levelPointer, ctr, ctr1, array1Pointer, array2Pointer, array3Pointer, 
-											array1, array2, array3, totalEntries, referentID, resumeHandle, windowsError);	
-		}
-			
-		return new Packet(wrapNetbios(wrapHeader(response)));		
+		byte[] wordCount = { 0x00 };
+		byte[] andXCommand = { 0x00, 0x00 };
+		ntStat = new byte[] { 0x22, 0x00, 0x00, (byte) 0xc0 };
+		response = HelperUtils.concat(wordCount, andXCommand);
+		return new Packet(wrapNetbios(wrapHeader(response)));
 	}
-		
+
 	/**
-	 * Builds the DCERPC packet
-	 * @return DCERPC packet
+	 * Extracts the trans sub packet from message
+	 * 
+	 * @return trans sub packet
 	 */
-	private byte[] getDceRpc(byte[] transSub, int length) {
-		byte[] majorVersion	= {0x05};
-		byte[] minorVersion	= {0x00};
-		byte[] packetType	= null;
-		byte[] packetFlags	= {0x03};
-		byte[] dataRepres	= {0x10, 0x00, 0x00, 0x00};
-		byte[] fragLength	= null;
-		byte[] authLength	= {0x00, 0x00};
-		byte[] callID		= null;
-		byte[] response		= null;
-			
-		if(transSub[0] == 0x00 && transSub[1] == 0x0b) {
-			packetType	= new byte[]{0x0c};
-			fragLength	= new byte[]{0x44, 0x00};
-			callID		= new byte[]{0x01, 0x00, 0x00, 0x00};
-			byte[] maxXmitFrag		= {(byte) 0xb8, 0x10};
-			byte[] maxRecvFrag		= {(byte) 0xb8, 0x10};
-			byte[] assocGroup		= {0x4a, 0x41, 0x00, 0x00};
-			byte[] scndryAddrLen	= {0x0d, 0x00};
-			byte[] scndryAddr		= {0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c, 0x73, 0x72, 
-												0x76, 0x73, 0x76, 0x63, 0x00, 0x00};
-			byte[] numResults		= {0x01, 0x00, 0x00, 0x00};
-			byte[] ctxItem			= {0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, (byte) 0x88, (byte) 0x8a,
-												(byte) 0xeb, 0x1c, (byte) 0xc9, 0x11, (byte) 0x9f, (byte) 0xe8,
-												0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00,	0x00, 0x00};
-			
-			response = HelperUtils.concat(majorVersion, minorVersion, packetType, packetFlags, dataRepres,fragLength,
-					authLength, callID, maxXmitFrag, maxRecvFrag, assocGroup, scndryAddrLen, scndryAddr, numResults, ctxItem);
-		} else if(transSub[0] == 0x00 && transSub[1] == 0x00) {
-			packetType	= new byte[]{0x02};
-			byte[] tmp	= ByteBuffer.allocate(4).putInt(length).array();
-			fragLength	= new byte[]{tmp[3], tmp[2]};
-			callID		= new byte[]{0x02, 0x00, 0x00, 0x00};
-			tmp			= ByteBuffer.allocate(4).putInt(length-24).array();
-			byte[] allocHint	= new byte[]{tmp[3], tmp[2], tmp[1], tmp[0]};
-			byte[] contextID	= {0x00, 0x00};
-			byte[] cancelCount	= {0x00, 0x00};
-			
-			response = HelperUtils.concat(majorVersion, minorVersion, packetType, packetFlags, dataRepres,fragLength,
-					authLength, callID, allocHint, contextID, cancelCount);
-		}			
-		return response;
+	private byte[] getTransSub() {
+		byte[] transSub = new byte[2];
+		if (smbCommand[0] == 0x32)
+			transSub = new byte[] { message[66], message[65] };
+		else if (smbCommand[0] == 0x25)
+			transSub = new byte[] { 0x00, message[90] };
+		else
+			transSub = new byte[] { 0x00, 0x00 };
+		return transSub;
 	}
-	
+
 	/**
-	 * Builds the close packet
-	 * @return close packet
+	 * Builds the tree connect packet
+	 * 
+	 * @return tree connect packet
 	 */
-	private Packet getClose() {
-		byte[] wordCount	= {0x00};
-		byte[] byteCount	= {0x00, 0x00};
-		
-		smbCommand			= new byte[]{0x04};
-		
-		byte[] response = HelperUtils.concat(wordCount, byteCount);
-		
+	private Packet getTreeCon() {
+		String str = HelperUtils.byteToStr(message);
+		byte[] wordCount = { 0x00 };
+		byte[] andXCommand = { 0x00, 0x00 };
+		byte[] response = null;
+		if (str.contains("IPC$") || str.contains("C$")) {
+			wordCount = new byte[] { 0x07 };
+			andXCommand = new byte[] { (byte) 0xff };
+			byte[] reserved = { 0x00 };
+			byte[] andXOffset = { 0x38, 0x00 };
+			byte[] optionalSupport = { 0x01, 0x00 };
+			byte[] maxShareAccess = { (byte) 0xff, (byte) 0xff, 0x1f, 0x00 };
+			byte[] guestMaxShareAccess = { (byte) 0xff, (byte) 0xff, 0x1f, 0x00 };
+			byte[] byteCount = { 0x07, 0x00 };
+			byte[] service = { 0x49, 0x50, 0x43, 0x00 };
+			byte[] extraParameters = { 0x00, 0x00, 0x00 };
+
+			treeID = new byte[] { 0x00, 0x08 };
+
+			response = HelperUtils.concat(wordCount, andXCommand, reserved,
+					andXOffset, optionalSupport, maxShareAccess,
+					guestMaxShareAccess, byteCount, service, extraParameters);
+		} else if (str.contains("ADMIN$")) {
+			ntStat = new byte[] { 0x22, 0x00, 0x00, (byte) 0xc0 };
+			response = HelperUtils.concat(wordCount, andXCommand);
+		} else {
+			ntStat = new byte[] { (byte) 0xcc, 0x00, 0x00, (byte) 0xc0 };
+			response = HelperUtils.concat(wordCount, andXCommand);
+		}
+
 		return new Packet(wrapNetbios(wrapHeader(response)));
 	}
-	
+
 	/**
 	 * Builds the tree disconnect packet
+	 * 
 	 * @return tree disconnect packet
 	 */
 	private Packet getTreeDisc() {
-		byte[] wordCount	= {0x00};
-		byte[] byteCount	= {0x00, 0x00};
-		
+		byte[] wordCount = { 0x00 };
+		byte[] byteCount = { 0x00, 0x00 };
+
 		smbCommand[0] = 0x71;
-		
+
 		byte[] response = HelperUtils.concat(wordCount, byteCount);
-		
+
 		return new Packet(wrapNetbios(wrapHeader(response)));
 	}
-	
+
 	/**
-	 * Builds the echo packet
-	 * @return echo packet
+	 * Breaks a message from the client down into its components
+	 * 
+	 * @param message
+	 *            that is analyzed
 	 */
-	private Packet getEcho() {
-		byte[] wordCount	= {0x01};
-		byte[] echoSeq		= {0x01, 0x00};
-		byte[] byteCount	= {0x10, 0x00};
-		byte[] echoData		= {(byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0,
-								(byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0}; 
-		byte[] response = HelperUtils.concat(wordCount, echoSeq, byteCount, echoData);
-		return new Packet(wrapNetbios(wrapHeader(response)));
+	private void parseMessageHeader(byte[] message) {
+		this.message = message;
+		serverComp = new byte[] { message[4], message[5], message[6],
+				message[7] };
+		smbCommand = new byte[] { message[8] };
+		ntStat = new byte[] { message[9], message[10], message[11], message[12] };
+		smbFlags = new byte[] { (byte) (message[13] | 0x80) }; // | 0x80 for
+																// mark response
+																// bit
+		smbFlags2 = new byte[] { message[14], message[15] };
+		processIDHigh = new byte[] { message[16], message[17] };
+		signature = new byte[] { message[18], message[19], message[20],
+				message[21], message[22], message[23], message[24], message[25] };
+		reserved = new byte[] { message[26], message[27] };
+		treeID = new byte[] { message[28], message[29] };
+		processID = new byte[] { message[30], message[31] };
+		userID = new byte[] { message[32], message[33] };
+		multiplexID = new byte[] { message[34], message[35] };
 	}
-	
+
 	/**
-	 * Builds the trans2 packet
-	 * @return trans2 packet
+	 * Wraps the header around a response
+	 * 
+	 * @param response
+	 *            that is wrapped
+	 * @return wrapped response
 	 */
-	private Packet getTrans2() {
-		byte[] response = null;		
-		byte[] wordCount	= {0x00};
-		byte[] andXCommand	= {0x00, 0x00};
-		ntStat = new byte[] {0x22, 0x00, 0x00, (byte) 0xc0};
-		response = HelperUtils.concat(wordCount, andXCommand);
-		return new Packet(wrapNetbios(wrapHeader(response)));
-	}
-	
-	/**
-	 * Extracts the trans sub packet from message
-	 * @return trans sub packet
-	 */		
-	private byte[] getTransSub() {
-		byte[] transSub = new byte[2];
-		if(smbCommand[0] == 0x32) transSub = new byte[]{message[66], message[65]};
-		else if(smbCommand[0] == 0x25) transSub = new byte[]{0x00, message[90]};
-		else transSub = new byte[]{0x00, 0x00};
-		return transSub;
+	private byte[] wrapHeader(byte[] response) {
+		byte[] header = new byte[0];
+		return HelperUtils.concat(header, serverComp, smbCommand, ntStat,
+				smbFlags, smbFlags2, processIDHigh, signature, reserved,
+				treeID, processID, userID, multiplexID, response);
 	}
+
 	/**
-	 * Returns the command number from the current message
-	 * @return command number
+	 * Wraps the Netbios header around a response
+	 * 
+	 * @param response
+	 *            that is wrapped
+	 * @return wrapped response
 	 */
-	private byte getSmbCommand() {
-		return smbCommand[0];
+	private byte[] wrapNetbios(byte[] response) {
+		byte[] netbios = { 0x00 };
+		byte[] buffer = ByteBuffer.allocate(4).putInt(response.length).array(); // allocate(4)
+																				// because
+																				// int
+																				// is
+																				// 4
+																				// bytes
+																				// long
+		byte[] netbiosLength = { buffer[1], buffer[2], buffer[3] }; // only
+																	// bytes 1-3
+																	// needed,
+																	// byte 0 is
+																	// not
+																	// needed
+		return HelperUtils.concat(netbios, netbiosLength, response);
 	}
-	
-	//message constants
-	private static final byte SMB_COM_CLOSE                  = 0x04;
-	private static final byte SMB_COM_TRANSACTION            = 0x25;
-	private static final byte SMB_COM_ECHO                   = 0x2B;
-	private static final byte SMB_COM_TRANSACTION2           = 0x32;
-	private static final byte SMB_COM_TREE_DISCONNECT        = 0x71;
-	private static final byte SMB_COM_NEGOTIATE              = 0x72;
-	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;
-	
+
 }

+ 364 - 332
src/de/tudarmstadt/informatik/hostage/protocol/SSH.java

@@ -22,10 +22,11 @@ import de.tudarmstadt.informatik.hostage.ssh.util.TypesWriter;
 import de.tudarmstadt.informatik.hostage.wrapper.Packet;
 
 /**
- * SSH protocol.
- * Implementation of RFC documents 4250, 4251, 4252, 4253, 4254.
- * It can handle the following requests: Server Protocol, Key Exchange Init, Diffie-Hellman Key Exchange Init, New Keys,
- * Service Request, Connection Request, Channel Open Request, Channel Request.  
+ * SSH protocol. Implementation of RFC documents 4250, 4251, 4252, 4253, 4254.
+ * It can handle the following requests: Server Protocol, Key Exchange Init,
+ * Diffie-Hellman Key Exchange Init, New Keys, Service Request, Connection
+ * Request, Channel Open Request, Channel Request.
+ * 
  * @author Wulf Pfeiffer
  */
 public class SSH implements Protocol {
@@ -36,20 +37,134 @@ public class SSH implements Protocol {
 		NONE, SERVER_VERSION, CLIENT_VERSION, KEX_INIT, NEW_KEYS, USERAUTH, CONNECTION, CHANNEL, TERMINAL_CMD, TERMINAL_ENTER, CLOSED
 	}
 
+	/**
+	 * Converts a byte[] to int
+	 * 
+	 * @param bytes
+	 *            that are converted
+	 * @return converted byte[] as int
+	 */
+	private static int byteToInt(byte[] bytes) {
+		int convertedInteger = 0;
+		for (int i = 0; i < bytes.length; i++) {
+			convertedInteger <<= 8;
+			convertedInteger |= bytes[i] & 0xFF;
+		}
+		return convertedInteger;
+	}
+
+	private static String initSshType() {
+		SecureRandom rnd = new SecureRandom();
+		int majorVersion = rnd.nextInt(possibleSshTypes.length);
+		return "OpenSSH_"
+				+ possibleSshTypes[majorVersion][0][0]
+				+ possibleSshTypes[majorVersion][1][rnd
+						.nextInt(possibleSshTypes[majorVersion][1].length)];
+	}
+
 	/**
 	 * Denotes in which state the protocol is right now.
 	 */
 	private STATE state = STATE.NONE;
+
 	private boolean useEncryption = false;
 
+	// version stuff
+	private static String[][][] possibleSshTypes = {
+			{ { "3." }, { "4", "5", "6", "7", "8", "9" } },
+			{ { "4." }, { "0", "1", "2", "3", "4", "5", "6", "7", "9" } },
+			{ { "5." }, { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" } },
+			{ { "6." }, { "0", "1", "2", "3", "4" } } };
+
+	// server infos
+	private static String serverVersion = "SSH-2.0-";
+
+	private static String serverType = initSshType();
+
+	private static String serverName = HelperUtils.getRandomString(16, false);
+
+	private int packetNumber = 0;
+
+	private int recipientChannel;
+
+	private String userName;
+
+	private String terminalPrefix;
+
+	private StringBuffer command = new StringBuffer();
+
+	private SecureRandom random = new SecureRandom();
+
+	// SSH Parameters for Kex etc.
+	private byte[] V_S = (serverVersion + serverType).getBytes();
+
+	private byte[] V_C;
+
+	private byte[] I_S;
+
+	private byte[] I_C;
+
+	private byte[] e;
+
+	private BigInteger f;
+
+	private byte[] h;
+
+	private BigInteger k;
+
+	private byte[] K_S;
+
+	private byte[] signature;
+
+	// allowed algorithms for kexinit
+	private static final String KEX_ALG = "diffie-hellman-group1-sha1";
+
+	private static final String SERVER_ALG = "ssh-dss";
+
+	private static final String ENCRYPT_ALG_C = "3des-cbc";
+
+	private static final String ENCRYPT_ALG_S = "3des-cbc";
+
+	private static final String MAC_ALG_C = "hmac-sha1";
+	private static final String MAC_ALG_S = "hmac-sha1";
+	private static final String COMP_ALG_C = "none";
+	private static final String COMP_ALG_S = "none";
+	private int cipherBlockSize = 16;
+	// for en- and decryption
+	private DESede desEncryption;
+	private DESede desDecryption;
+	private CBCMode cbcEncryption;
+	private CBCMode cbcDecryption;
+
+	private MAC macEncryption;
+	// private MAC macDec;
+	// dsa private key
+	private final char[] dsaPem = ("-----BEGIN DSA PRIVATE KEY-----\n"
+			+ "MIIBugIBAAKBgQCDZ9R2vfCPwjv5vKF1igIv9drrZ7G0dhMkGT9AZTjgI34Qm4w0\n"
+			+ "0iWeCqO7SmqiaMIjbRIm91MeDed4ObAq4sAkqRE/2P4mTbzFx5KhEczRRiDoqQBX\n"
+			+ "xYa0yWKJpeZ94SGM6DEPuBTxKo0T4uMjbq2FzHL2FXT1/WoNCmRU6gFSiwIVAMK4\n"
+			+ "Epz3JiwDUbkSpLOjIqtEhJmVAoGAL6zlXRI4Q8iwvSDh0vDf1j9a5Aaaq+93LTjK\n"
+			+ "SwL4nvUWBl2Aa0vqu05ZS5rOD1I+/naLMg0fNgFJRhA03sl+12MI3a2HXJWXRSdj\n"
+			+ "m1Vq9cUXqiYrX6+iGfEaA/y9UO4ZPF6if6eLypXB8VuqjtjDCiMMsM6+qQki7L71\n"
+			+ "yN4M75ICgYAcFXUhN2zRug3JvwmGxW8gMgHquSiBnbx1582KGh2B/ukE/kOrbKYD\n"
+			+ "HUkBzolcm4x1Odq5apowlriFxY6zMQP615plIK4x9NaU6dvc/HoTkjzT5EYSMN39\n"
+			+ "eAGufJ0jrtIpKL4lP8o8yrAHfmbR7bjecWc0viTH0+OWlyVsex/bZAIUEKn310Li\n"
+			+ "v62Zs4hlDvhwvx8MQ+A=\n" + "-----END DSA PRIVATE KEY-----")
+			.toCharArray();
+
 	@Override
-	public int getDefaultPort() {
+	public int getPort() {
 		return 22;
 	}
 
 	@Override
-	public TALK_FIRST whoTalksFirst() {
-		return TALK_FIRST.SERVER;
+	public boolean isClosed() {
+		return (state == STATE.CLOSED);
+	}
+
+	@Override
+	public boolean isSecure() {
+		return false;
 	}
 
 	@Override
@@ -57,14 +172,15 @@ public class SSH implements Protocol {
 		List<Packet> responsePackets = new ArrayList<Packet>();
 		byte[] request = null;
 		if (requestPacket != null) {
-			request = requestPacket.getMessage();
+			request = requestPacket.getBytes();
 			if (useEncryption) {
 				request = decryptBytes(request);
 			}
 		}
 		switch (state) {
 		case NONE:
-			responsePackets.add(new Packet(serverVersion + serverType + "\r\n"));
+			responsePackets
+					.add(new Packet(serverVersion + serverType + "\r\n"));
 			state = STATE.SERVER_VERSION;
 			break;
 		case SERVER_VERSION:
@@ -114,87 +230,87 @@ public class SSH implements Protocol {
 	}
 
 	@Override
-	public boolean isClosed() {
-		return (state == STATE.CLOSED);
-	}
-
-	@Override
-	public boolean isSecure() {
-		return false;
-	}
-
-	@Override
-	public Class<byte[]> getType() {
-		return byte[].class;
+	public String toString() {
+		return "SSH";
 	}
 
 	@Override
-	public String toString() {
-		return "SSH";
+	public TALK_FIRST whoTalksFirst() {
+		return TALK_FIRST.SERVER;
 	}
 
 	/**
-	 * Wraps the packets with packet length and padding.
+	 * Channel Open Reply.
 	 * 
-	 * @param response
-	 *            content that is wrapped.
-	 * @return wrapped packet.
+	 * @param request
+	 *            from client.
+	 * @return Channel Open Reply.
 	 */
-	private Packet wrapPacket(byte[] response) {
-		int packetLength = 5 + response.length; // 4 byte packet length, 1 byte padding length, payload length
-		int paddingLengthCBS = cipherBlockSize
-				- (packetLength % cipherBlockSize);
-		int paddingLength8 = 8 - (packetLength % 8);
-		int paddingLength = paddingLengthCBS > paddingLength8 ? paddingLengthCBS
-				: paddingLength8;
-		if (paddingLength < 4)
-			paddingLength += cipherBlockSize;
-		packetLength = packetLength + paddingLength - 4; // add padding string length to packet length
+	private Packet channelOpenReply(byte[] request) {
+		if (!(HelperUtils.byteToStr(request).contains("session"))) {
+			return disconnectReply(2); // if contains "session" ok else disc
+		}
+		TypesReader tr = new TypesReader(request, 6);
+		TypesWriter tw = new TypesWriter();
+		try {
+			tr.readString();
+			recipientChannel = tr.readUINT32();
+			int senderChannel = recipientChannel;
+			int initialWindowSize = tr.readUINT32();
+			int maximumPacketSize = tr.readUINT32();
 
-		byte[] packetLen = ByteBuffer.allocate(4).putInt(packetLength).array();
-		byte[] paddingLen = { (byte) paddingLength };
-		byte[] paddingString = HelperUtils.randomBytes(paddingLength);
-		byte[] wrappedResponse = HelperUtils.concat(packetLen, paddingLen, response,
-				paddingString);
-		if (useEncryption) {
-			byte[] mac = createMac(wrappedResponse);
-			byte[] responseEnc = encryptBytes(wrappedResponse);
-			wrappedResponse = HelperUtils.concat(responseEnc, mac);
+			tw.writeByte(0x5b); // msgcode
+			tw.writeUINT32(recipientChannel);
+			tw.writeUINT32(senderChannel);
+			tw.writeUINT32(initialWindowSize);
+			tw.writeUINT32(maximumPacketSize);
+		} catch (IOException e) {
+			e.printStackTrace();
 		}
-		packetNumber++;
 
-		return new Packet(wrappedResponse);
+		return wrapPacket(tw.getBytes());
 	}
 
 	/**
-	 * Encrypts a request with triple DES.
+	 * Channel Success Reply.
 	 * 
 	 * @param request
-	 *            that is encrypted.
-	 * @return encrypted request.
+	 *            from client.
+	 * @return Channel Success Reply.
 	 */
-	private byte[] encryptBytes(byte[] bytes) {
-		byte[] responseEncrypted = new byte[bytes.length];
-		for (int i = 0; i < bytes.length; i += 8) {
-			cbcEncryption.transformBlock(bytes, i, responseEncrypted, i);
+	private Packet channelSuccessReply(byte[] request) {
+		if (!(HelperUtils.byteToStr(request)).contains("pty-req")) {
+			return disconnectReply(2);
 		}
-		return responseEncrypted;
+		TypesWriter tw = new TypesWriter();
+		tw.writeByte(0x63); // msgcode
+		tw.writeUINT32(recipientChannel);
+
+		return wrapPacket(tw.getBytes());
 	}
 
 	/**
-	 * Decrypts a request with triple DES.
+	 * Userauth ssh-connection reply.
 	 * 
 	 * @param request
-	 *            that is decrypted.
-	 * @return decrypted request.
+	 *            from the client.
+	 * @return ssh-connection reply.
 	 */
-	private byte[] decryptBytes(byte[] request) {
-		byte[] decryptedRequest = new byte[request.length
-				- ((request.length % 8 == 0) ? 0 : 20)];
-		for (int i = 0; i < decryptedRequest.length; i += 8) { // -12 wegen MAC
-			cbcDecryption.transformBlock(request, i, decryptedRequest, i);
+	private Packet connectionReply(byte[] request) {
+		if (request[5] != 0x32
+				&& !(HelperUtils.byteToStr(request).contains("ssh-connection"))) {
+			return disconnectReply(14);// disconnect because its not
+										// servicerequest ssh-connect
 		}
-		return decryptedRequest;
+		try {
+			TypesReader tr = new TypesReader(request, 6);
+			userName = tr.readString();
+			terminalPrefix = "[" + userName + "@" + serverName + "]$";
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		byte[] msgcode = { 0x34 };
+		return wrapPacket(msgcode);
 	}
 
 	/**
@@ -213,31 +329,19 @@ public class SSH implements Protocol {
 	}
 
 	/**
-	 * Builds the Kex Init packet that contains all the allowed algorithms by
-	 * the server.
+	 * Decrypts a request with triple DES.
 	 * 
-	 * @return Kex Init packet.
+	 * @param request
+	 *            that is decrypted.
+	 * @return decrypted request.
 	 */
-	private Packet kexInit() {
-		TypesWriter tw = new TypesWriter();
-		tw.writeByte(0x14);
-		tw.writeBytes(HelperUtils.randomBytes(16)); // cookie
-		tw.writeString(KEX_ALG);
-		tw.writeString(SERVER_ALG);
-		tw.writeString(ENCRYPT_ALG_C);
-		tw.writeString(ENCRYPT_ALG_S);
-		tw.writeString(MAC_ALG_C);
-		tw.writeString(MAC_ALG_S);
-		tw.writeString(COMP_ALG_C);
-		tw.writeString(COMP_ALG_S);
-		tw.writeBytes(new byte[] { 0x00, 0x00, 0x00, 0x00 }); // language client to server
-		tw.writeBytes(new byte[] { 0x00, 0x00, 0x00, 0x00 }); // language server to client
-		tw.writeByte(0x00); // no guess from server
-		tw.writeBytes(new byte[] { 0x00, 0x00, 0x00, 0x00 }); // reserved
-		byte[] response = tw.getBytes();
-		I_S = response;
-
-		return wrapPacket(response);
+	private byte[] decryptBytes(byte[] request) {
+		byte[] decryptedRequest = new byte[request.length
+				- ((request.length % 8 == 0) ? 0 : 20)];
+		for (int i = 0; i < decryptedRequest.length; i += 8) { // -12 wegen MAC
+			cbcDecryption.transformBlock(request, i, decryptedRequest, i);
+		}
+		return decryptedRequest;
 	}
 
 	/**
@@ -253,8 +357,7 @@ public class SSH implements Protocol {
 			dhx.serverInit(1, random);
 			dhx.setE(new BigInteger(e));
 			f = dhx.getF();
-			DSAPrivateKey dsa = (DSAPrivateKey) PEMDecoder
-					.decode(dsaPem, null);
+			DSAPrivateKey dsa = (DSAPrivateKey) PEMDecoder.decode(dsaPem, null);
 			K_S = DSASHA1Verify.encodeSSHDSAPublicKey(dsa.getPublicKey());
 			h = dhx.calculateH(V_C, V_S, I_C, I_S, K_S);
 			k = dhx.getK();
@@ -266,17 +369,21 @@ public class SSH implements Protocol {
 			tw.writeMPInt(f);
 			tw.writeString(signature, 0, signature.length);
 			response = tw.getBytes();
-			
+
 			// init for decryption and encryption
 			KeyMaterial km = KeyMaterial.create("SHA1", h, k, h, 24, 8, 20, 24,
-					8, 20); // alg, h, k, keylength, blocklength, maclength, keylength, blocklength, maclength
+					8, 20); // alg, h, k, keylength, blocklength, maclength,
+							// keylength, blocklength, maclength
 			desEncryption = new DESede();
 			desDecryption = new DESede();
 			desEncryption.init(true, km.enc_key_server_to_client);
 			desDecryption.init(false, km.enc_key_client_to_server);
-			cbcEncryption = new CBCMode(desEncryption, km.initial_iv_server_to_client, true);
-			cbcDecryption = new CBCMode(desDecryption, km.initial_iv_client_to_server, false);
-			macEncryption = new MAC("hmac-sha1", km.integrity_key_server_to_client);
+			cbcEncryption = new CBCMode(desEncryption,
+					km.initial_iv_server_to_client, true);
+			cbcDecryption = new CBCMode(desDecryption,
+					km.initial_iv_client_to_server, false);
+			macEncryption = new MAC("hmac-sha1",
+					km.integrity_key_server_to_client);
 		} catch (Exception e) {
 			e.printStackTrace();
 		}
@@ -285,110 +392,171 @@ public class SSH implements Protocol {
 	}
 
 	/**
-	 * New Keys response.
+	 * Disconnect Reply using the given number as reason code.
 	 * 
-	 * @return New Keys response.
+	 * @param reasonCode
+	 *            for disconnect reply. Must be between 1 and 15, default is 2.
+	 * @return Disconnect Reply.
 	 */
-	private Packet newKeys() {
-		byte[] msgCode = { 0x15 };
-		return wrapPacket(msgCode);
+	private Packet disconnectReply(int reasonCode) {
+		TypesWriter tw = new TypesWriter();
+		tw.writeByte(0x01);
+		switch (reasonCode) {
+		case 1:
+			tw.writeUINT32(1);
+			tw.writeString("SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT");
+			break;
+		case 7:
+			tw.writeUINT32(7);
+			tw.writeString("SSH_DISCONNECT_SERVICE_NOT_AVAILABLE");
+			break;
+		case 14:
+			tw.writeUINT32(14);
+			tw.writeString("SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE");
+			break;
+		default:
+			tw.writeUINT32(2);
+			tw.writeString("SSH_DISCONNECT_PROTOCOL_ERROR");
+			break;
+		}
+		return wrapPacket(tw.getBytes());
 	}
 
 	/**
-	 * Service ssh-userauth reply.
+	 * Encrypts a request with triple DES.
 	 * 
 	 * @param request
-	 *            from the client.
-	 * @return Service reply.
+	 *            that is encrypted.
+	 * @return encrypted request.
 	 */
-	private Packet serviceReply(byte[] request) {
-		byte[] message;
-		if (request[5] == 0x15) { // if newkeys request is included in the same packet
-			message = new byte[request.length - 16]; // remove it
-			System.arraycopy(request, 16, message, 0, request.length - 16);
-		} else {
-			message = request;
-		}
-		if (message[5] != 0x05
-				&& !(HelperUtils.byteToStr(message).contains("ssh-userauth"))) {
-			return disconnectReply(7); // disconnect because its not servicerequest ssh-userauth
+	private byte[] encryptBytes(byte[] bytes) {
+		byte[] responseEncrypted = new byte[bytes.length];
+		for (int i = 0; i < bytes.length; i += 8) {
+			cbcEncryption.transformBlock(bytes, i, responseEncrypted, i);
 		}
-		TypesWriter tw = new TypesWriter();
-		tw.writeByte(0x06);
-		tw.writeString("ssh-userauth");
-		return wrapPacket(tw.getBytes());
+		return responseEncrypted;
 	}
 
 	/**
-	 * Userauth ssh-connection reply.
+	 * Extracts the payload of a packet and writes it in I_C.
 	 * 
 	 * @param request
-	 *            from the client.
-	 * @return ssh-connection reply.
+	 *            packet of which the payload is extracted.
 	 */
-	private Packet connectionReply(byte[] request) {
-		if (request[5] != 0x32
-				&& !(HelperUtils.byteToStr(request).contains("ssh-connection"))) {
-			return disconnectReply(14);// disconnect because its not servicerequest ssh-connect
+	private void extractPayload(byte[] request) {
+		int position = 0;
+		if (request[5] != 0x14) {
+			position = 1;
+			for (int i = 0; i < request.length; i++, position++) {
+				if (request[i] == 0xa)
+					break;
+			}
 		}
-		try {
-			TypesReader tr = new TypesReader(request, 6);
-			userName = tr.readString();
-			terminalPrefix = "[" + userName + "@" + serverName + "]$";
-		} catch (IOException e) {
-			e.printStackTrace();
+		int packetLength = byteToInt(new byte[] { request[position],
+				request[1 + position], request[2 + position],
+				request[3 + position] });
+		int paddingLength = byteToInt(new byte[] { request[4 + position] });
+		byte[] payload = new byte[packetLength - paddingLength - 1];
+		for (int i = 5; i < packetLength - paddingLength - 1; i++) {
+			payload[i - 5] = request[i + position];
 		}
-		byte[] msgcode = { 0x34 };
-		return wrapPacket(msgcode);
+		I_C = payload;
 	}
 
 	/**
-	 * Channel Open Reply.
+	 * Extracts the public key from the DH Kex Request
 	 * 
 	 * @param request
-	 *            from client.
-	 * @return Channel Open Reply.
+	 *            containing the clients public key
 	 */
-	private Packet channelOpenReply(byte[] request) {
-		if (!(HelperUtils.byteToStr(request).contains("session"))) {
-			return disconnectReply(2); // if contains "session" ok else disc
+	private void extractPubKey(byte[] request) {
+		e = new byte[byteToInt(new byte[] { request[6], request[7], request[8],
+				request[9] })];
+		for (int i = 0; i < e.length; i++) {
+			e[i] = request[i + 10];
 		}
-		TypesReader tr = new TypesReader(request, 6);
-		TypesWriter tw = new TypesWriter();
-		try {
-			tr.readString();
-			recipientChannel = tr.readUINT32();
-			int senderChannel = recipientChannel;
-			int initialWindowSize = tr.readUINT32();
-			int maximumPacketSize = tr.readUINT32();
+	}
 
-			tw.writeByte(0x5b); // msgcode
-			tw.writeUINT32(recipientChannel);
-			tw.writeUINT32(senderChannel);
-			tw.writeUINT32(initialWindowSize);
-			tw.writeUINT32(maximumPacketSize);
-		} catch (IOException e) {
-			e.printStackTrace();
+	/**
+	 * Extracts the type of the client
+	 * 
+	 * @param request
+	 *            containing the clients type
+	 */
+	private void extractType(byte[] request) {
+		int length = 0;
+		for (int i = 0; i < request.length; i++, length++) {
+			if (request[i] == 0x0d)
+				break; // find the end of the type: '\r'
 		}
+		V_C = new byte[length];
+		System.arraycopy(request, 0, V_C, 0, length);
+	}
 
-		return wrapPacket(tw.getBytes());
+	/**
+	 * Builds the Kex Init packet that contains all the allowed algorithms by
+	 * the server.
+	 * 
+	 * @return Kex Init packet.
+	 */
+	private Packet kexInit() {
+		TypesWriter tw = new TypesWriter();
+		tw.writeByte(0x14);
+		tw.writeBytes(HelperUtils.randomBytes(16)); // cookie
+		tw.writeString(KEX_ALG);
+		tw.writeString(SERVER_ALG);
+		tw.writeString(ENCRYPT_ALG_C);
+		tw.writeString(ENCRYPT_ALG_S);
+		tw.writeString(MAC_ALG_C);
+		tw.writeString(MAC_ALG_S);
+		tw.writeString(COMP_ALG_C);
+		tw.writeString(COMP_ALG_S);
+		tw.writeBytes(new byte[] { 0x00, 0x00, 0x00, 0x00 }); // language client
+																// to server
+		tw.writeBytes(new byte[] { 0x00, 0x00, 0x00, 0x00 }); // language server
+																// to client
+		tw.writeByte(0x00); // no guess from server
+		tw.writeBytes(new byte[] { 0x00, 0x00, 0x00, 0x00 }); // reserved
+		byte[] response = tw.getBytes();
+		I_S = response;
+
+		return wrapPacket(response);
 	}
 
 	/**
-	 * Channel Success Reply.
+	 * New Keys response.
+	 * 
+	 * @return New Keys response.
+	 */
+	private Packet newKeys() {
+		byte[] msgCode = { 0x15 };
+		return wrapPacket(msgCode);
+	}
+
+	/**
+	 * Service ssh-userauth reply.
 	 * 
 	 * @param request
-	 *            from client.
-	 * @return Channel Success Reply.
+	 *            from the client.
+	 * @return Service reply.
 	 */
-	private Packet channelSuccessReply(byte[] request) {
-		if (!(HelperUtils.byteToStr(request)).contains("pty-req")) {
-			return disconnectReply(2);
+	private Packet serviceReply(byte[] request) {
+		byte[] message;
+		if (request[5] == 0x15) { // if newkeys request is included in the same
+									// packet
+			message = new byte[request.length - 16]; // remove it
+			System.arraycopy(request, 16, message, 0, request.length - 16);
+		} else {
+			message = request;
+		}
+		if (message[5] != 0x05
+				&& !(HelperUtils.byteToStr(message).contains("ssh-userauth"))) {
+			return disconnectReply(7); // disconnect because its not
+										// servicerequest ssh-userauth
 		}
 		TypesWriter tw = new TypesWriter();
-		tw.writeByte(0x63); // msgcode
-		tw.writeUINT32(recipientChannel);
-
+		tw.writeByte(0x06);
+		tw.writeString("ssh-userauth");
 		return wrapPacket(tw.getBytes());
 	}
 
@@ -402,7 +570,7 @@ public class SSH implements Protocol {
 		tw.writeByte(0x5e);
 		tw.writeUINT32(recipientChannel);
 		tw.writeString(terminalPrefix);
-		
+
 		return wrapPacket(tw.getBytes());
 	}
 
@@ -432,7 +600,8 @@ public class SSH implements Protocol {
 				command = new StringBuffer();
 			} else if (messsage.contains(new String(new char[] { '\u007F' }))
 					&& command.length() > 0) {
-				command = command.delete(command.length() - 1, command.length());
+				command = command
+						.delete(command.length() - 1, command.length());
 			} else {
 				command.append(messsage);
 			}
@@ -447,176 +616,39 @@ public class SSH implements Protocol {
 	}
 
 	/**
-	 * Disconnect Reply using the given number as reason code.
-	 * 
-	 * @param reasonCode
-	 *            for disconnect reply. Must be between 1 and 15, default is 2.
-	 * @return Disconnect Reply.
-	 */
-	private Packet disconnectReply(int reasonCode) {
-		TypesWriter tw = new TypesWriter();
-		tw.writeByte(0x01);
-		switch (reasonCode) {
-		case 1:
-			tw.writeUINT32(1);
-			tw.writeString("SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT");
-			break;
-		case 7:
-			tw.writeUINT32(7);
-			tw.writeString("SSH_DISCONNECT_SERVICE_NOT_AVAILABLE");
-			break;
-		case 14:
-			tw.writeUINT32(14);
-			tw.writeString("SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE");
-			break;
-		default:
-			tw.writeUINT32(2);
-			tw.writeString("SSH_DISCONNECT_PROTOCOL_ERROR");
-			break;
-		}
-		return wrapPacket(tw.getBytes());
-	}
-
-	/**
-	 * Extracts the type of the client
-	 * 
-	 * @param request
-	 *            containing the clients type
-	 */
-	private void extractType(byte[] request) {
-		int length = 0;
-		for (int i = 0; i < request.length; i++, length++) {
-			if (request[i] == 0x0d)
-				break; // find the end of the type: '\r'
-		}
-		V_C = new byte[length];
-		System.arraycopy(request, 0, V_C, 0, length);
-	}
-
-	/**
-	 * Extracts the payload of a packet and writes it in I_C.
-	 * 
-	 * @param request
-	 *            packet of which the payload is extracted.
-	 */
-	private void extractPayload(byte[] request) {
-		int position = 0;
-		if (request[5] != 0x14) {
-			position = 1;
-			for (int i = 0; i < request.length; i++, position++) {
-				if (request[i] == 0xa)
-					break;
-			}
-		}
-		int packetLength = byteToInt(new byte[] { request[position], request[1 + position], request[2 + position], request[3 + position] });
-		int paddingLength = byteToInt(new byte[] { request[4 + position] });
-		byte[] payload = new byte[packetLength - paddingLength - 1];
-		for (int i = 5; i < packetLength - paddingLength - 1; i++) {
-			payload[i - 5] = request[i + position];
-		}
-		I_C = payload;
-	}
-
-	/**
-	 * Extracts the public key from the DH Kex Request
+	 * Wraps the packets with packet length and padding.
 	 * 
-	 * @param request
-	 *            containing the clients public key
+	 * @param response
+	 *            content that is wrapped.
+	 * @return wrapped packet.
 	 */
-	private void extractPubKey(byte[] request) {
-		e = new byte[byteToInt(new byte[] { request[6], request[7], request[8],
-				request[9] })];
-		for (int i = 0; i < e.length; i++) {
-			e[i] = request[i + 10];
-		}
-	}
+	private Packet wrapPacket(byte[] response) {
+		int packetLength = 5 + response.length; // 4 byte packet length, 1 byte
+												// padding length, payload
+												// length
+		int paddingLengthCBS = cipherBlockSize
+				- (packetLength % cipherBlockSize);
+		int paddingLength8 = 8 - (packetLength % 8);
+		int paddingLength = paddingLengthCBS > paddingLength8 ? paddingLengthCBS
+				: paddingLength8;
+		if (paddingLength < 4)
+			paddingLength += cipherBlockSize;
+		packetLength = packetLength + paddingLength - 4; // add padding string
+															// length to packet
+															// length
 
-	/**
-	 * Converts a byte[] to int
-	 * 
-	 * @param bytes
-	 *            that are converted
-	 * @return converted byte[] as int
-	 */
-	private static int byteToInt(byte[] bytes) {
-		int convertedInteger = 0;
-		for (int i = 0; i < bytes.length; i++) {
-			convertedInteger <<= 8;
-			convertedInteger |= bytes[i] & 0xFF;
+		byte[] packetLen = ByteBuffer.allocate(4).putInt(packetLength).array();
+		byte[] paddingLen = { (byte) paddingLength };
+		byte[] paddingString = HelperUtils.randomBytes(paddingLength);
+		byte[] wrappedResponse = HelperUtils.concat(packetLen, paddingLen,
+				response, paddingString);
+		if (useEncryption) {
+			byte[] mac = createMac(wrappedResponse);
+			byte[] responseEnc = encryptBytes(wrappedResponse);
+			wrappedResponse = HelperUtils.concat(responseEnc, mac);
 		}
-		return convertedInteger;
-	}
-
-	// version stuff
-	private static String[][][] possibleSshTypes = {
-			{ { "3." }, { "4", "5", "6", "7", "8", "9" } },
-			{ { "4." }, { "0", "1", "2", "3", "4", "5", "6", "7", "9" } },
-			{ { "5." }, { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" } },
-			{ { "6." }, { "0", "1", "2", "3", "4" } } };
+		packetNumber++;
 
-	private static String initSshType() {
-		SecureRandom rnd = new SecureRandom();
-		int majorVersion = rnd.nextInt(possibleSshTypes.length);
-		return "OpenSSH_"
-				+ possibleSshTypes[majorVersion][0][0]
-				+ possibleSshTypes[majorVersion][1][rnd
-						.nextInt(possibleSshTypes[majorVersion][1].length)];
+		return new Packet(wrappedResponse);
 	}
-
-	// server infos
-	private static String serverVersion = "SSH-2.0-";
-	private static String serverType = initSshType();
-	private static String serverName = HelperUtils.getRandomString(16, false);
-	private int packetNumber = 0;
-	private int recipientChannel;
-	private String userName;
-	private String terminalPrefix;
-	private StringBuffer command = new StringBuffer();
-	private SecureRandom random = new SecureRandom();
-
-	// SSH Parameters for Kex etc.
-	private byte[] V_S = (serverVersion + serverType).getBytes();
-	private byte[] V_C;
-	private byte[] I_S;
-	private byte[] I_C;
-	private byte[] e;
-	private BigInteger f;
-	private byte[] h;
-	private BigInteger k;
-	private byte[] K_S;
-	private byte[] signature;
-
-	// allowed algorithms for kexinit
-	private static final String KEX_ALG			= "diffie-hellman-group1-sha1";
-	private static final String SERVER_ALG		= "ssh-dss";
-	private static final String ENCRYPT_ALG_C	= "3des-cbc";
-	private static final String ENCRYPT_ALG_S	= "3des-cbc";
-	private static final String MAC_ALG_C		= "hmac-sha1";
-	private static final String MAC_ALG_S		= "hmac-sha1";
-	private static final String COMP_ALG_C		= "none";
-	private static final String COMP_ALG_S		= "none";
-
-	private int cipherBlockSize = 16;
-
-	// for en- and decryption
-	private DESede desEncryption;
-	private DESede desDecryption;
-	private CBCMode cbcEncryption;
-	private CBCMode cbcDecryption;
-	private MAC macEncryption;
-	// private MAC macDec;
-
-	// dsa private key
-	private final char[] dsaPem = ("-----BEGIN DSA PRIVATE KEY-----\n"
-			+ "MIIBugIBAAKBgQCDZ9R2vfCPwjv5vKF1igIv9drrZ7G0dhMkGT9AZTjgI34Qm4w0\n"
-			+ "0iWeCqO7SmqiaMIjbRIm91MeDed4ObAq4sAkqRE/2P4mTbzFx5KhEczRRiDoqQBX\n"
-			+ "xYa0yWKJpeZ94SGM6DEPuBTxKo0T4uMjbq2FzHL2FXT1/WoNCmRU6gFSiwIVAMK4\n"
-			+ "Epz3JiwDUbkSpLOjIqtEhJmVAoGAL6zlXRI4Q8iwvSDh0vDf1j9a5Aaaq+93LTjK\n"
-			+ "SwL4nvUWBl2Aa0vqu05ZS5rOD1I+/naLMg0fNgFJRhA03sl+12MI3a2HXJWXRSdj\n"
-			+ "m1Vq9cUXqiYrX6+iGfEaA/y9UO4ZPF6if6eLypXB8VuqjtjDCiMMsM6+qQki7L71\n"
-			+ "yN4M75ICgYAcFXUhN2zRug3JvwmGxW8gMgHquSiBnbx1582KGh2B/ukE/kOrbKYD\n"
-			+ "HUkBzolcm4x1Odq5apowlriFxY6zMQP615plIK4x9NaU6dvc/HoTkjzT5EYSMN39\n"
-			+ "eAGufJ0jrtIpKL4lP8o8yrAHfmbR7bjecWc0viTH0+OWlyVsex/bZAIUEKn310Li\n"
-			+ "v62Zs4hlDvhwvx8MQ+A=\n" + "-----END DSA PRIVATE KEY-----")
-			.toCharArray();
 }

+ 5 - 2
src/de/tudarmstadt/informatik/hostage/protocol/SSLProtocol.java

@@ -1,14 +1,17 @@
 package de.tudarmstadt.informatik.hostage.protocol;
 
 import javax.net.ssl.SSLContext;
+
 /**
- * Interface for ssl protocols that are used by hostage
+ * Interface for secure protocols.
+ * 
  * @author Wulf Pfeiffer
  */
 public interface SSLProtocol extends Protocol {
 
 	/**
-	 * Returns the initialized SSL Context with the KeyManager and TrustManager that will be used
+	 * Returns the SSL Context to be used.
+	 * 
 	 * @return the used SSLContext
 	 */
 	SSLContext getSSLContext();

+ 100 - 81
src/de/tudarmstadt/informatik/hostage/protocol/TELNET.java

@@ -7,8 +7,8 @@ import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
 import de.tudarmstadt.informatik.hostage.wrapper.Packet;
 
 /**
- * TELNET protocol.
- * Implementation of RFC document 854.
+ * TELNET protocol. Implementation of RFC document 854.
+ * 
  * @author Wulf Pfeiffer
  */
 public class TELNET implements Protocol {
@@ -18,64 +18,102 @@ public class TELNET implements Protocol {
 	private static enum STATE {
 		NONE, OPEN, CLOSED, LOGIN, AUTHENTICATE, LOGGED_IN
 	};
-	
+
 	/**
 	 * Denotes in which state the protocol is right now
 	 */
 	private STATE state = STATE.NONE;
-	
+
+	/** user entered by the client */
+	private static byte[] user;
+
+	/** last command sent by the client */
+	private byte[] command;
+
+	/** name of the server */
+	private static String serverName = HelperUtils.getRandomString(16, false);
+
+	/** command line prefix */
+	private static byte[] sessionToken = null;
+
+	/** options requested by the server */
+	private static final byte[] optionRequest = { (byte) 0xff, (byte) 0xfb,
+			0x03, // will suppress go ahead
+			(byte) 0xff, (byte) 0xfb, 0x01 // will echo
+	};
+
+	// session token prefix, mid and suffix
+	private static final byte[] sessionPrefix = { 0x1b, 0x5d, 0x30, 0x3b };
+
+	private static final byte[] sessionMiddle = { 0x3a, 0x20, 0x7e, 0x07, 0x1b,
+			0x5b, 0x30, 0x31, 0x3b, 0x33, 0x32, 0x6d };
+
+	private static final byte[] sessionSuffix = { 0x1b, 0x5b, 0x30, 0x30, 0x6d,
+			0x20, 0x1b, 0x5b, 0x30, 0x31, 0x3b, 0x33, 0x34, 0x6d, 0x7e, 0x20,
+			0x24, 0x1b, 0x5b, 0x30, 0x30, 0x6d, 0x20 };
+
 	@Override
-	public int getDefaultPort() {
+	public int getPort() {
 		return 23;
 	}
 
 	@Override
-	public TALK_FIRST whoTalksFirst() {
-		return TALK_FIRST.SERVER;
+	public boolean isClosed() {
+		return (state == STATE.CLOSED);
+	}
+
+	@Override
+	public boolean isSecure() {
+		return false;
 	}
 
 	@Override
 	public List<Packet> processMessage(Packet requestPacket) {
 		byte[] request = null;
-		if(requestPacket != null) {
-			request = requestPacket.getMessage();
+		if (requestPacket != null) {
+			request = requestPacket.getBytes();
 		}
 		List<Packet> responsePackets = new ArrayList<Packet>();
-		
+
 		switch (state) {
 		case NONE:
 			responsePackets.add(new Packet(optionRequest));
 			state = STATE.OPEN;
 			break;
 		case OPEN:
-			if(request != null) {
+			if (request != null) {
 				responsePackets.add(new Packet(getOptionResponse(request)));
 				responsePackets.add(new Packet(serverName + " login: "));
 				state = STATE.LOGIN;
 			}
 			break;
 		case LOGIN:
-			if(request == null) break;
-			else if(checkForByte(request, (byte) 0x0d)) {
-				if(request.length > 2) {
-					byte[] buffer = new byte[request.length - 2]; 
-					System.arraycopy(request, 0, buffer, 0, request.length - 2); 
+			if (request == null)
+				break;
+			else if (checkForByte(request, (byte) 0x0d)) {
+				if (request.length > 2) {
+					byte[] buffer = new byte[request.length - 2];
+					System.arraycopy(request, 0, buffer, 0, request.length - 2);
 					user = HelperUtils.concat(user, buffer);
 					responsePackets.add(new Packet(buffer));
 				}
 				responsePackets.add(new Packet("\r\n"));
 				responsePackets.add(new Packet("Password: "));
 				state = STATE.AUTHENTICATE;
-				sessionToken = HelperUtils.concat(sessionPrefix, user, "@".getBytes(), serverName.getBytes(), sessionMiddle, user, "@".getBytes(), serverName.getBytes(), sessionSuffix);
+				sessionToken = HelperUtils.concat(sessionPrefix, user,
+						"@".getBytes(), serverName.getBytes(), sessionMiddle,
+						user, "@".getBytes(), serverName.getBytes(),
+						sessionSuffix);
 				break;
-			} else if (checkForByte(request, (byte) 0x7f) && user != null && user.length != 0) {
+			} else if (checkForByte(request, (byte) 0x7f) && user != null
+					&& user.length != 0) {
 				byte[] tmp = new byte[user.length - 1];
 				System.arraycopy(user, 0, tmp, 0, user.length - 1);
 				user = tmp;
 				responsePackets.add(new Packet("\b \b"));
 				break;
-			} else if (!checkForByte(request, (byte) 0xff)){
-				if(user == null)
+			} else if (!checkForByte(request, (byte) 0xff)) {
+				if (user == null)
 					user = request;
 				else
 					user = HelperUtils.concat(user, request);
@@ -83,45 +121,49 @@ public class TELNET implements Protocol {
 			}
 			break;
 		case AUTHENTICATE:
-			if(request == null) break;
-			else if(checkForByte(request, (byte) 0x0d)) {
+			if (request == null)
+				break;
+			else if (checkForByte(request, (byte) 0x0d)) {
 				responsePackets.add(new Packet("\r\n"));
 				responsePackets.add(new Packet(sessionToken));
 				state = STATE.LOGGED_IN;
 			} else if (checkForByte(request, (byte) 0x7f)) {
 				responsePackets.add(new Packet("\b \b"));
-			}			
+			}
 			break;
 		case LOGGED_IN:
-			if(request == null) break;
-			else if(checkForByte(request, (byte) 0x0d)) {
-				if(request.length > 2) {
-					byte[] buffer = new byte[request.length - 2]; 
-					System.arraycopy(request, 0, buffer, 0, request.length - 2); 
+			if (request == null)
+				break;
+			else if (checkForByte(request, (byte) 0x0d)) {
+				if (request.length > 2) {
+					byte[] buffer = new byte[request.length - 2];
+					System.arraycopy(request, 0, buffer, 0, request.length - 2);
 					command = HelperUtils.concat(command, buffer);
 					responsePackets.add(new Packet(buffer));
 				}
-				if(command == null) {
+				if (command == null) {
 					responsePackets.add(new Packet("\r\n"));
 					responsePackets.add(new Packet(sessionToken));
 				} else if (new String(command).contains("exit")) {
 					responsePackets.add(new Packet("\r\nlogout\r\n"));
 					state = STATE.CLOSED;
 				} else {
-					String bash = "\r\n-bash: " + new String(command)+ ": command not found";
+					String bash = "\r\n-bash: " + new String(command)
+							+ ": command not found";
 					responsePackets.add(new Packet(bash));
 					responsePackets.add(new Packet("\r\n"));
 					responsePackets.add(new Packet(sessionToken));
 					command = null;
 				}
-			} else if (checkForByte(request, (byte) 0x7f) && command != null && command.length != 0) {
+			} else if (checkForByte(request, (byte) 0x7f) && command != null
+					&& command.length != 0) {
 				byte[] tmp = new byte[command.length - 1];
 				System.arraycopy(command, 0, tmp, 0, command.length - 1);
 				command = tmp;
 				responsePackets.add(new Packet("\b \b"));
 				break;
-			} else if (!checkForByte(request, (byte) 0xff)){
-				if(command == null)
+			} else if (!checkForByte(request, (byte) 0xff)) {
+				if (command == null)
 					command = request;
 				else
 					command = HelperUtils.concat(command, request);
@@ -136,82 +178,59 @@ public class TELNET implements Protocol {
 		return responsePackets;
 	}
 
-	@Override
-	public boolean isClosed() {
-		return (state == STATE.CLOSED);
-	}
-
-	@Override
-	public boolean isSecure() {
-		return false;
-	}
-	
 	@Override
 	public String toString() {
 		return "TELNET";
 	}
-	
+
 	@Override
-	public Class<byte[]> getType() {
-		return byte[].class;
+	public TALK_FIRST whoTalksFirst() {
+		return TALK_FIRST.SERVER;
 	}
-	
+
 	/**
 	 * Checks a byte array for occurence of one byte.
-	 * @param bytes byte array that is checked.
-	 * @param b searched byte.
+	 * 
+	 * @param bytes
+	 *            byte array that is checked.
+	 * @param b
+	 *            searched byte.
 	 * @return true if the byte was found, else false.
 	 */
 	private boolean checkForByte(byte[] bytes, byte b) {
-		for(byte oneByte : bytes) {
-			if(oneByte == b) return true;
+		for (byte oneByte : bytes) {
+			if (oneByte == b)
+				return true;
 		}
 		return false;
 	}
 
 	/**
-	 * Determines which options that are requested by the client will be done and which not
-	 * @param request requested options
+	 * Determines which options that are requested by the client will be done
+	 * and which not
+	 * 
+	 * @param request
+	 *            requested options
 	 * @return accepted and unaccepted options
 	 */
 	private byte[] getOptionResponse(byte[] request) {
 		List<byte[]> responseList = new ArrayList<byte[]>();
 		byte[] requestInverse;
-		for(int i = 0; i < request.length - 2; i += 3) {
-			if(request[i] == (byte) 0xff && request[i+2] != 0x03 && request[i+2] != 0x01) {
+		for (int i = 0; i < request.length - 2; i += 3) {
+			if (request[i] == (byte) 0xff && request[i + 2] != 0x03
+					&& request[i + 2] != 0x01) {
 				requestInverse = new byte[3];
 				requestInverse[0] = request[i];
-				requestInverse[1] = request[i+1] == (byte) 0xfd ? (byte) 0xfc : (byte) 0xfe; 
-				requestInverse[2] = request[i+2];
+				requestInverse[1] = request[i + 1] == (byte) 0xfd ? (byte) 0xfc
+						: (byte) 0xfe;
+				requestInverse[2] = request[i + 2];
 				responseList.add(requestInverse);
-			}			
+			}
 		}
 		byte[] optionResponse = new byte[0];
-		for(byte[] response : responseList) {
+		for (byte[] response : responseList) {
 			optionResponse = HelperUtils.concat(optionResponse, response);
 		}
 		return optionResponse;
 	}
-
-
-	/** user entered by the client */
-	private static byte[] user;
-	/** last command sent by the client */
-	private byte[] command;
-	/** name of the server */
-	private static String serverName = HelperUtils.getRandomString(16, false);
-	/** command line prefix */
-	private static byte[] sessionToken = null;
-	
-	/** options requested by the server */
-	private static final byte[] optionRequest = {
-			(byte) 0xff, (byte) 0xfb, 0x03,	//will suppress go ahead
-			(byte) 0xff, (byte) 0xfb, 0x01 	//will echo
-	};
-	//session token prefix, mid and suffix
-	private static final byte[] sessionPrefix = {0x1b, 0x5d, 0x30, 0x3b};
-	private static final byte[] sessionMiddle = {0x3a, 0x20, 0x7e, 0x07, 0x1b, 0x5b, 0x30, 0x31, 
-			0x3b, 0x33, 0x32, 0x6d};	
-	private static final byte[] sessionSuffix = {0x1b, 0x5b, 0x30, 0x30, 0x6d, 0x20, 0x1b, 0x5b, 0x30, 0x31, 
-			0x3b, 0x33, 0x34, 0x6d, 0x7e, 0x20, 0x24, 0x1b, 0x5b, 0x30, 0x30, 0x6d, 0x20};
 }

+ 244 - 214
src/de/tudarmstadt/informatik/hostage/sync/BluetoothSync.java

@@ -21,255 +21,285 @@ import android.widget.ArrayAdapter;
 import de.tudarmstadt.informatik.hostage.R;
 import de.tudarmstadt.informatik.hostage.logging.UglyDbHelper;
 
-public class BluetoothSync{
-	
+public class BluetoothSync {
+
+	private class ClientThread extends Thread {
+		private final BluetoothSocket socket;
+
+		public ClientThread(BluetoothDevice device) {
+			BluetoothSocket tmp = null;
+			try {
+				tmp = device.createRfcommSocketToServiceRecord(serviceUUID);
+			} catch (IOException e) {
+			}
+			socket = tmp;
+		}
+
+		/** Will cancel an in-progress connection, and close the socket */
+		public void cancel() {
+			try {
+				socket.close();
+			} catch (IOException e) {
+			}
+		}
+
+		@Override
+		public void run() {
+
+			try {
+				socket.connect();
+			} catch (IOException connectException) {
+				// Unable to connect; close the socket and get out
+				try {
+					socket.close();
+				} catch (IOException closeException) {
+				}
+				return;
+			}
+
+			manageConnectedSocket(socket, CLIENT);
+		}
+	}
+
+	private class CommunicationThread extends Thread {
+		private final BluetoothSocket mmSocket;
+		private final ObjectInputStream objectInput;
+		private final ObjectOutputStream objectOuput;
+		private final int identifier;
+
+		public CommunicationThread(BluetoothSocket socket, int identifier) {
+			mmSocket = socket;
+			ObjectInputStream tmpIn = null;
+			ObjectOutputStream tmpOut = null;
+
+			// Get the input and output streams, using temp objects because
+			// member streams are final
+			try {
+				tmpOut = new ObjectOutputStream(socket.getOutputStream());
+				tmpIn = new ObjectInputStream(socket.getInputStream());
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+
+			objectInput = tmpIn;
+			objectOuput = tmpOut;
+			this.identifier = identifier;
+		}
+
+		/* Call this from the main activity to shutdown the connection */
+		public void cancel() {
+			try {
+				mmSocket.close();
+			} catch (IOException e) {
+			}
+		}
+
+		@Override
+		public void run() {
+			// Keep listening to the InputStream until an exception occurs
+			// while (true) {
+			try {
+				// TODO Ersetze dbh mit Logger
+				UglyDbHelper dbh = new UglyDbHelper(context);
+				ArrayList<HashMap<String, Object>> localNetworkInformation = dbh
+						.getNetworkInformation();
+				if (identifier == SERVER) {
+					// Read from the InputStream
+					ArrayList<HashMap<String, Object>> remoteNetworkInformation = (ArrayList<HashMap<String, Object>>) objectInput
+							.readObject();
+					;
+					dbh.updateNetworkInformation(remoteNetworkInformation);
+					objectOuput.writeObject(localNetworkInformation);
+				} else {
+					objectOuput.writeObject(localNetworkInformation);
+					// Read from the InputStream
+					ArrayList<HashMap<String, Object>> remoteNetworkInformation = (ArrayList<HashMap<String, Object>>) objectInput
+							.readObject();
+					dbh.updateNetworkInformation(remoteNetworkInformation);
+					mmSocket.close();
+				}
+			} catch (ClassNotFoundException e) {
+				e.printStackTrace();
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+			// }
+		}
+
+		/* Call this from the main activity to send data to the remote device */
+		public void write(ArrayList<HashMap<String, Object>> networkInformation) {
+			try {
+				objectOuput.writeObject(networkInformation);
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		}
+	}
+
+	private class ServerThread extends Thread {
+		private final BluetoothServerSocket serverSocket;
+
+		public ServerThread() {
+			BluetoothServerSocket tmp = null;
+			try {
+				tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(
+						context.getResources().getString(R.string.app_name),
+						serviceUUID);
+			} catch (IOException e) {
+			}
+			serverSocket = tmp;
+		}
+
+		/** Will cancel the listening socket, and cause the thread to finish */
+		public void cancel() {
+			try {
+				serverSocket.close();
+			} catch (IOException e) {
+			}
+		}
+
+		@Override
+		public void run() {
+			BluetoothSocket socket = null;
+			while (true) {
+				try {
+					socket = serverSocket.accept();
+				} catch (IOException e) {
+					e.printStackTrace();
+					break;
+				}
+
+				if (socket != null) {
+					// Do work to manage the connection (in a separate thread)
+					manageConnectedSocket(socket, SERVER);
+					try {
+						serverSocket.close();
+					} catch (IOException e) {
+						e.printStackTrace();
+					}
+					break;
+				}
+			}
+		}
+	}
+
 	private final UUID serviceUUID;
 	private final int SERVER = 0;
 	private final int CLIENT = 1;
+
 	private BluetoothAdapter mBluetoothAdapter;
 	private Context context;
+
 	private ArrayAdapter<String> arrayAdapter;
-	
-	private ServerThread serverThread;	
+
+	private ServerThread serverThread;
+
 	private AlertDialog ad;
-	
-	public BluetoothSync(Context context){
-		this.context = context;		
-		serviceUUID = UUID.fromString(context.getResources().getString(R.string.UUID));
+
+	// Create a BroadcastReceiver for ACTION_FOUND
+	private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+		@Override
+		public void onReceive(Context context, Intent intent) {
+			String action = intent.getAction();
+			// When discovery finds a device
+			if (BluetoothDevice.ACTION_FOUND.equals(action)) {
+				// Get the BluetoothDevice object from the Intent
+				BluetoothDevice device = intent
+						.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+				// Add the name and address to an array adapter to show in a
+				// ListView
+				arrayAdapter.add(device.getName() + "\n" + device.getAddress());
+				arrayAdapter.notifyDataSetChanged();
+			}
+		}
+	};
+
+	public BluetoothSync(Context context) {
+		this.context = context;
+		serviceUUID = UUID.fromString(context.getResources().getString(
+				R.string.UUID));
 		mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
 	}
 
-	public boolean syncData(){
-		if(!bluetoothAvaible())
+	public boolean syncData() {
+		if (!bluetoothAvaible())
 			return false;
 		syncDataPassive();
-		return syncDataActive();		
-	}
-	
-	private boolean syncDataActive() {
-		registerBroadcastReceiver();
-		arrayAdapter = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1);
-		//Start scanning for devices
-		if(!mBluetoothAdapter.startDiscovery())
-			return false;
-		
-		deviceDialog();
-		return true;
+		return syncDataActive();
 	}
-	
-	private void syncDataPassive(){		
-		Intent discoverableIntent = new
-		Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
-		discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
-		context.startActivity(discoverableIntent);
-		
-		serverThread = new ServerThread();
-		serverThread.start(); 
-	}
-	
-	private void manageConnectedSocket(BluetoothSocket socket, int identifier){
-		if(identifier == SERVER){
-			ad.dismiss();
-		}
-        mBluetoothAdapter.cancelDiscovery();
-        context.unregisterReceiver(mReceiver);
-		CommunicationThread commThread = new CommunicationThread(socket, identifier);
-		commThread.start();
-	}
-	
-	private boolean bluetoothAvaible(){		
+
+	private boolean bluetoothAvaible() {
 		if (mBluetoothAdapter == null) {
-		    // Device does not support Bluetooth
+			// Device does not support Bluetooth
 			return false;
 		}
 		if (!mBluetoothAdapter.isEnabled()) {
-		    Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
-		    context.startActivity(enableBtIntent);
-		    return false;
+			Intent enableBtIntent = new Intent(
+					BluetoothAdapter.ACTION_REQUEST_ENABLE);
+			context.startActivity(enableBtIntent);
+			return false;
 		}
 		return true;
 	}
 
-	// Create a BroadcastReceiver for ACTION_FOUND
-	private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-	    public void onReceive(Context context, Intent intent) {
-	        String action = intent.getAction();
-	        // When discovery finds a device
-	        if (BluetoothDevice.ACTION_FOUND.equals(action)) {
-	            // Get the BluetoothDevice object from the Intent
-	            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
-	            // Add the name and address to an array adapter to show in a ListView
-	            arrayAdapter.add(device.getName() + "\n" + device.getAddress());
-	           	arrayAdapter.notifyDataSetChanged();
-	        }
-	    }
-	};
-	
-	
-	// Register the BroadcastReceiver
-	private void registerBroadcastReceiver(){
-		IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
-		context.registerReceiver(mReceiver, filter); // Don't forget to unregister during onDestroy
-	}
-	
 	private void deviceDialog() {
 		AlertDialog.Builder builder = new AlertDialog.Builder(context);
-		//TODO in resources auslagern
+		// TODO in resources auslagern
 		builder.setTitle("Choose Device");
 		builder.setAdapter(arrayAdapter, new DialogInterface.OnClickListener() {
+			@Override
 			public void onClick(DialogInterface dialog, int position) {
 				String deviceInfo = arrayAdapter.getItem(position);
 				String mac = deviceInfo.substring(deviceInfo.indexOf("\n") + 1);
-				ClientThread clientThread = new ClientThread(mBluetoothAdapter.getRemoteDevice(mac));
-	            clientThread.start();
+				ClientThread clientThread = new ClientThread(mBluetoothAdapter
+						.getRemoteDevice(mac));
+				clientThread.start();
 			}
 		});
-//		builder.create();
+		// builder.create();
 		ad = builder.show();
 	}
-	
-	
-	private class ServerThread extends Thread {		
-		private final BluetoothServerSocket serverSocket;		
-		
-		public ServerThread() {
-			BluetoothServerSocket tmp = null;
-	        try {
-	            tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(context.getResources().getString(R.string.app_name), serviceUUID);
-	        } catch (IOException e) { }
-	        serverSocket = tmp;
-		}		
-		
-		public void run() {
-			BluetoothSocket socket = null;
-			while(true){
-				try {
-					socket = serverSocket.accept();
-				} catch (IOException e) {
-					e.printStackTrace();
-					break;
-				}
-				
-	            if (socket != null) {
-	                // Do work to manage the connection (in a separate thread)
-	                manageConnectedSocket(socket, SERVER);
-	                try {
-						serverSocket.close();
-					} catch (IOException e) {
-						e.printStackTrace();
-					}
-	                break;
-	            }				
-			}
+
+	private void manageConnectedSocket(BluetoothSocket socket, int identifier) {
+		if (identifier == SERVER) {
+			ad.dismiss();
 		}
-		
-	    /** Will cancel the listening socket, and cause the thread to finish */
-	    public void cancel() {
-	        try {
-	            serverSocket.close();
-	        } catch (IOException e) { }
-	    }
+		mBluetoothAdapter.cancelDiscovery();
+		context.unregisterReceiver(mReceiver);
+		CommunicationThread commThread = new CommunicationThread(socket,
+				identifier);
+		commThread.start();
 	}
-	
-	private class ClientThread extends Thread {
-	    private final BluetoothSocket socket;
-	 
-	    public ClientThread(BluetoothDevice device) {
-	        BluetoothSocket tmp = null;
-	        try {
-	            tmp = device.createRfcommSocketToServiceRecord(serviceUUID);
-	        } catch (IOException e) { }
-	        socket = tmp;
-	    }
-	 
-	    public void run() {   
-	        
-	        try {
-	        	socket.connect();
-	        } catch (IOException connectException) {
-	            // Unable to connect; close the socket and get out
-	            try {
-	            	socket.close();
-	            } catch (IOException closeException) { }
-	            return;
-	        }
-	 
-	        manageConnectedSocket(socket, CLIENT);
-	    }
-	 
-	    /** Will cancel an in-progress connection, and close the socket */
-	    public void cancel() {
-	        try {
-	        	socket.close();
-	        } catch (IOException e) { }
-	    }
+
+	// Register the BroadcastReceiver
+	private void registerBroadcastReceiver() {
+		IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
+		context.registerReceiver(mReceiver, filter); // Don't forget to
+														// unregister during
+														// onDestroy
 	}
-	
-	private class CommunicationThread extends Thread {
-	    private final BluetoothSocket mmSocket;
-	    private final ObjectInputStream  objectInput;
-	    private final ObjectOutputStream  objectOuput;
-	    private final int identifier;
-	 
-	    public CommunicationThread(BluetoothSocket socket, int identifier) {
-	        mmSocket = socket;
-	        ObjectInputStream  tmpIn = null;
-	        ObjectOutputStream tmpOut = null;
-	 
-	        // Get the input and output streams, using temp objects because
-	        // member streams are final
-	        try {
-	            tmpOut = new ObjectOutputStream(socket.getOutputStream());
-	            tmpIn = new ObjectInputStream(socket.getInputStream());
-	        } catch (IOException e) { e.printStackTrace();}
-	         
-	        objectInput = tmpIn;
-	        objectOuput = tmpOut;
-	        this.identifier = identifier;
-	    }
-	 
-	    public void run() {	 
-	        // Keep listening to the InputStream until an exception occurs
-//	        while (true) {
-	            try {
-	            	//TODO Ersetze dbh mit Logger
-	            	UglyDbHelper dbh = new UglyDbHelper(context);
-            		ArrayList<HashMap<String, Object>> localNetworkInformation = dbh.getNetworkInformation();
-	            	if(identifier == SERVER){
-		                // Read from the InputStream 
-		            	ArrayList<HashMap<String, Object>> remoteNetworkInformation = (ArrayList<HashMap<String, Object>>) objectInput.readObject();;
-		            	dbh.updateNetworkInformation(remoteNetworkInformation);
-		            	objectOuput.writeObject(localNetworkInformation); 		            	
-	            	}else{
-	    	        	objectOuput.writeObject(localNetworkInformation); 
-		                // Read from the InputStream
-		            	ArrayList<HashMap<String, Object>> remoteNetworkInformation = (ArrayList<HashMap<String, Object>>) objectInput.readObject();
-		            	dbh.updateNetworkInformation(remoteNetworkInformation);
-		            	mmSocket.close();
-	            	}
-	            } catch (ClassNotFoundException e) {
-					e.printStackTrace();
-				} catch (IOException e) {
-					e.printStackTrace();
-				}
-//	        }
-	    }
-	 
-	    /* Call this from the main activity to send data to the remote device */
-	    public void write(ArrayList<HashMap<String, Object>> networkInformation) {
-	    	try {
-				objectOuput.writeObject(networkInformation);
-			} catch (IOException e) {
-				e.printStackTrace();
-			} 
-	    }
-	 
-	    /* Call this from the main activity to shutdown the connection */
-	    public void cancel() {
-	        try {
-	            mmSocket.close();
-	        } catch (IOException e) { }
-	    }
+
+	private boolean syncDataActive() {
+		registerBroadcastReceiver();
+		arrayAdapter = new ArrayAdapter<String>(context,
+				android.R.layout.simple_list_item_1);
+		// Start scanning for devices
+		if (!mBluetoothAdapter.startDiscovery())
+			return false;
+
+		deviceDialog();
+		return true;
+	}
+
+	private void syncDataPassive() {
+		Intent discoverableIntent = new Intent(
+				BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
+		discoverableIntent.putExtra(
+				BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
+		context.startActivity(discoverableIntent);
+
+		serverThread = new ServerThread();
+		serverThread.start();
 	}
 
 }

+ 127 - 124
src/de/tudarmstadt/informatik/hostage/sync/NFCSync.java

@@ -16,6 +16,14 @@
 
 package de.tudarmstadt.informatik.hostage.sync;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+
 import android.annotation.TargetApi;
 import android.app.Activity;
 import android.content.Intent;
@@ -33,150 +41,145 @@ import android.os.Parcelable;
 import android.util.Log;
 import android.widget.TextView;
 import android.widget.Toast;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.util.ArrayList;
-import java.util.HashMap;
-
 import de.tudarmstadt.informatik.hostage.R;
 import de.tudarmstadt.informatik.hostage.logging.UglyDbHelper;
 
-
 @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;
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.activity_nfc);
-
-        mInfoText = (TextView) findViewById(R.id.textView);
-        // Check for available NFC Adapter
-        mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
-        if (mNfcAdapter == null) {
-            mInfoText = (TextView) findViewById(R.id.textView);
-            mInfoText.setText("NFC is not available on this device.");
-        } else {
-            // Register callback to set NDEF message
-            mNfcAdapter.setNdefPushMessageCallback(this, this);
-            // Register callback to listen for message-sent success
-            mNfcAdapter.setOnNdefPushCompleteCallback(this, this);
-        }
-    }
-
-    /**
-     * Implementation for the CreateNdefMessageCallback interface
-     */
-    @Override
-    public NdefMessage createNdefMessage(NfcEvent event) {
-    	// Get Networkdata
-    	UglyDbHelper dbh = new UglyDbHelper(this);
-		ArrayList<HashMap<String, Object>> localNetworkInformation = dbh.getNetworkInformation();
+		OnNdefPushCompleteCallback {
+	NfcAdapter mNfcAdapter;
+	TextView mInfoText;
+	private static final int MESSAGE_SENT = 1;
+
+	public static Object deserialize(byte[] data) throws IOException,
+			ClassNotFoundException {
+		ByteArrayInputStream in = new ByteArrayInputStream(data);
+		ObjectInputStream is = new ObjectInputStream(in);
+		return is.readObject();
+	}
+
+	public static byte[] serialize(Object obj) throws IOException {
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		ObjectOutputStream os = new ObjectOutputStream(out);
+		os.writeObject(obj);
+		return out.toByteArray();
+	}
+
+	/** This handler receives a message from onNdefPushComplete */
+	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();
+				Log.i("NFC", "Message sent!");
+				break;
+			}
+		}
+	};
+
+	/**
+	 * Implementation for the CreateNdefMessageCallback interface
+	 */
+	@Override
+	public NdefMessage createNdefMessage(NfcEvent event) {
+		// Get Networkdata
+		UglyDbHelper dbh = new UglyDbHelper(this);
+		ArrayList<HashMap<String, Object>> localNetworkInformation = dbh
+				.getNetworkInformation();
 		Log.i("NFC", "Creating Message");
-        NdefMessage msg = null;
+		NdefMessage msg = null;
 		try {
 			msg = new NdefMessage(NdefRecord.createMime(
-			        "application/de.tudarmstadt.informatik.hostage", serialize(localNetworkInformation))
-			 /**
-			  * The Android Application Record (AAR) is commented out. When a device
-			  * receives a push with an AAR in it, the application specified in the AAR
-			  * is guaranteed to run. The AAR overrides the tag dispatch system.
-			  * You can add it back in to guarantee that this
-			  * activity starts when receiving a beamed message. For now, this code
-			  * uses the tag dispatch system.
-			  */
-			  //,NdefRecord.createApplicationRecord("com.example.android.beam")
+					"application/de.tudarmstadt.informatik.hostage",
+					serialize(localNetworkInformation))
+			/**
+			 * The Android Application Record (AAR) is commented out. When a
+			 * device receives a push with an AAR in it, the application
+			 * specified in the AAR is guaranteed to run. The AAR overrides the
+			 * tag dispatch system. You can add it back in to guarantee that
+			 * this activity starts when receiving a beamed message. For now,
+			 * this code uses the tag dispatch system.
+			 */
+			// ,NdefRecord.createApplicationRecord("com.example.android.beam")
 			);
 		} catch (IOException e) {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
 		}
-        return msg;
-    }
-
-    /**
-     * Implementation for the OnNdefPushCompleteCallback interface
-     */
-    @Override
-    public void onNdefPushComplete(NfcEvent arg0) {
-        // A handler is needed to send messages to the activity when this
-        // callback occurs, because it happens from a binder thread
-        mHandler.obtainMessage(MESSAGE_SENT).sendToTarget();
-    }
-
-    /** This handler receives a message from onNdefPushComplete */
-    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();
-                Log.i("NFC", "Message sent!");
-                break;
-            }
-        }
-    };
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        // Check to see that the Activity started due to an Android Beam
-        if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
-            processIntent(getIntent());
-        }
-    }
-
-    @Override
-    public void onNewIntent(Intent intent) {
-        // onResume gets called after this to handle the intent
-        setIntent(intent);
-    }
-
-    /**
-     * Parses the NDEF Message from the intent and prints to the TextView
-     */
-    void processIntent(Intent intent) {
-        Parcelable[] rawMsgs = intent.getParcelableArrayExtra(
-                NfcAdapter.EXTRA_NDEF_MESSAGES);
-        // 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;
-    	Log.i("NFC", "Getting Message!");
+		return msg;
+	}
+
+	@Override
+	public void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.activity_nfc);
+
+		mInfoText = (TextView) findViewById(R.id.textView);
+		// Check for available NFC Adapter
+		mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
+		if (mNfcAdapter == null) {
+			mInfoText = (TextView) findViewById(R.id.textView);
+			mInfoText.setText("NFC is not available on this device.");
+		} else {
+			// Register callback to set NDEF message
+			mNfcAdapter.setNdefPushMessageCallback(this, this);
+			// Register callback to listen for message-sent success
+			mNfcAdapter.setOnNdefPushCompleteCallback(this, this);
+		}
+	}
+
+	/**
+	 * Implementation for the OnNdefPushCompleteCallback interface
+	 */
+	@Override
+	public void onNdefPushComplete(NfcEvent arg0) {
+		// A handler is needed to send messages to the activity when this
+		// callback occurs, because it happens from a binder thread
+		mHandler.obtainMessage(MESSAGE_SENT).sendToTarget();
+	}
+
+	@Override
+	public void onNewIntent(Intent intent) {
+		// onResume gets called after this to handle the intent
+		setIntent(intent);
+	}
+
+	// HELPER
+
+	@Override
+	public void onResume() {
+		super.onResume();
+		// Check to see that the Activity started due to an Android Beam
+		if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
+			processIntent(getIntent());
+		}
+	}
+
+	/**
+	 * Parses the NDEF Message from the intent and prints to the TextView
+	 */
+	void processIntent(Intent intent) {
+		Parcelable[] rawMsgs = intent
+				.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
+		// 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;
+		Log.i("NFC", "Getting Message!");
 		try {
 			object = deserialize(msg.getRecords()[0].getPayload());
-	    	ArrayList<HashMap<String, Object>> remoteNetworkInformation = (ArrayList<HashMap<String, Object>>) object;
-	    	UglyDbHelper dbh = new UglyDbHelper(this);
-	    	dbh.updateNetworkInformation(remoteNetworkInformation);
+			ArrayList<HashMap<String, Object>> remoteNetworkInformation = (ArrayList<HashMap<String, Object>>) object;
+			UglyDbHelper dbh = new UglyDbHelper(this);
+			dbh.updateNetworkInformation(remoteNetworkInformation);
 		} catch (ClassNotFoundException e) {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
 		} catch (IOException e) {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
-		}		
-    }
-    
-    //HELPER
-
-    public static byte[] serialize(Object obj) throws IOException {
-    	ByteArrayOutputStream out = new ByteArrayOutputStream();
-    	ObjectOutputStream os = new ObjectOutputStream(out);
-    	os.writeObject(obj);
-    	return out.toByteArray();
-    }
-    public static Object deserialize(byte[] data) throws IOException, ClassNotFoundException {
-    	ByteArrayInputStream in = new ByteArrayInputStream(data);
-    	ObjectInputStream is = new ObjectInputStream(in);
-    	return is.readObject();
-    }	
+		}
+	}
 
 }

+ 28 - 28
src/de/tudarmstadt/informatik/hostage/system/PrivilegedPort.java → src/de/tudarmstadt/informatik/hostage/system/P.java

@@ -6,10 +6,11 @@ import android.net.LocalServerSocket;
 import android.net.LocalSocket;
 
 /**
- * Port loaded with porthack with root rights
+ * Receives a file descriptor through a unix domain socket.
+ * 
  * @author Mihai Plasoianu
  */
-public class PrivilegedPort implements Runnable {
+public class P implements Runnable {
 
 	/**
 	 * Path for UDS in abstract namespace.
@@ -21,48 +22,47 @@ public class PrivilegedPort implements Runnable {
 	 */
 	private int port;
 
-	public PrivilegedPort(int port) {
+	public P(int port) {
 		this.port = port;
 	}
 
 	/**
-	 * Run porthack in separate Thread.
+	 * Start p, wait for connection and receive a file descriptor.
 	 */
-	
-	public void run() {
-		Process p;
+	public FileDescriptor bindAndGetFD() {
+		FileDescriptor fd = null;
 		try {
-			String command = String.format("/data/local/p %d", port);
-			p = Runtime.getRuntime().exec(new String[] { "su", "-c", command });
-			p.waitFor();
+			new Thread(this).start();
+			LocalServerSocket localServer = new LocalServerSocket(NAME);
+			LocalSocket localSocket = localServer.accept();
+			while (localSocket.getInputStream().read() != -1)
+				;
+			FileDescriptor[] fdArray;
+			fdArray = localSocket.getAncillaryFileDescriptors();
+			if (fdArray != null) {
+				fd = fdArray[0];
+			}
+			localSocket.close();
+			localServer.close();
 		} catch (Exception e) {
 			e.printStackTrace();
 		}
+		return fd;
 	}
 
 	/**
-	 * Start porthack, wait for connection through UDS and receive a file
-	 * descriptor for bound port.
+	 * Run p in separate Thread.
 	 */
-	public FileDescriptor bindAndGetFD() {
-		FileDescriptor fd = null;
+	@Override
+	public void run() {
+		Process p;
 		try {
-			new Thread(this).start();
-			LocalServerSocket lss = new LocalServerSocket(NAME);
-			LocalSocket ls = lss.accept();
-			while (ls.getInputStream().read() != -1)
-				;
-			FileDescriptor[] fdarr;
-			fdarr = ls.getAncillaryFileDescriptors();
-			if (fdarr != null) {
-				fd = fdarr[0];
-			}
-			ls.close();
-			lss.close();
+			String command = String.format("/data/local/p %d", port);
+			p = Runtime.getRuntime().exec(new String[] { "su", "-c", command });
+			p.waitFor();
 		} catch (Exception e) {
 			e.printStackTrace();
 		}
-		return fd;
 	}
 
-}
+}

+ 9 - 6
src/de/tudarmstadt/informatik/hostage/ui/AboutActivity.java

@@ -1,17 +1,20 @@
 package de.tudarmstadt.informatik.hostage.ui;
 
-import de.tudarmstadt.informatik.hostage.R;
 import android.app.Activity;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.os.Bundle;
 import android.widget.TextView;
+import de.tudarmstadt.informatik.hostage.R;
+
 /**
- * Shows a simple About View with application version, a small discription and authors of the project.
+ * Shows a simple About View with application version, a small discription and
+ * authors of the project.
+ * 
  * @author Lars Pandikow
- *
+ * 
  */
-public class AboutActivity extends Activity{
+public class AboutActivity extends Activity {
 
 	@Override
 	protected void onCreate(Bundle savedInstanceState) {
@@ -22,8 +25,8 @@ public class AboutActivity extends Activity{
 		try {
 			pInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
 			String version = pInfo.versionName;
-	        TextView versionTextView = (TextView) findViewById(R.id.version);
-	        versionTextView.setText(version);
+			TextView versionTextView = (TextView) findViewById(R.id.version);
+			versionTextView.setText(version);
 		} catch (NameNotFoundException e) {
 			e.printStackTrace();
 		}

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

@@ -10,8 +10,10 @@ import android.widget.BaseAdapter;
 import android.widget.ImageView;
 import android.widget.TextView;
 import de.tudarmstadt.informatik.hostage.R;
+
 /**
  * Custom ListViewAdapter to dynamically create a list of protocols.
+ * 
  * @author Mihai Plasoianu
  */
 public class ListViewAdapter extends BaseAdapter {

+ 353 - 339
src/de/tudarmstadt/informatik/hostage/ui/MainActivity.java

@@ -4,6 +4,7 @@ import java.io.BufferedReader;
 import java.io.InputStreamReader;
 import java.util.ArrayList;
 import java.util.HashMap;
+
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityManager.RunningServiceInfo;
@@ -104,19 +105,91 @@ public class MainActivity extends Activity implements Receiver {
 
 	private boolean isBssidSeen = false;
 
-	@Override
-	protected void onCreate(Bundle savedInstanceState) {
-		super.onCreate(savedInstanceState);
-		logResultReceiver = new LogResultReceiver(new Handler());
-		setContentView(R.layout.activity_main);
-		connectionInfo = getSharedPreferences(getString(R.string.connection_info), Context.MODE_PRIVATE);
-		
-		// Create dynamic view elements
-		initViewAnimator();
-		initListView();
-		// Initialize Class variables
-		checkRootAndPorthack();
-		startAndBind();
+	/**
+	 * Connection to bind the background service
+	 * 
+	 * @see HoneyService
+	 */
+	private ServiceConnection mConnection = new ServiceConnection() {
+		/**
+		 * After the service is bound, check which has been clicked and start
+		 * it.
+		 * 
+		 * @see android.content.ServiceConnection#onServiceConnected(android.content.ComponentName)
+		 */
+		@Override
+		public void onServiceConnected(ComponentName name, IBinder service) {
+			mService = ((LocalBinder) service).getService();
+			serviceBound = true;
+			updateUI();
+		}
+
+		/**
+		 * After the service is unbound, delete reference.
+		 * 
+		 * @see android.content.ServiceConnection#onServiceDisconnected(android.content.ComponentName)
+		 */
+		@Override
+		public void onServiceDisconnected(ComponentName name) {
+			mService = null;
+			serviceBound = false;
+		}
+
+	};
+
+	/**
+	 * Receiver for custom broadcast.
+	 * 
+	 * @see #BROADCAST
+	 */
+	private BroadcastReceiver mReceiver = new BroadcastReceiver() {
+		@Override
+		public void onReceive(Context context, Intent intent) {
+			// Update user interface.
+			updateUI();
+			updateConnectionInfText();
+		}
+	};
+
+	SimpleOnGestureListener simpleOnGestureListener = new SimpleOnGestureListener() {
+		@Override
+		public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
+				float velocityY) {
+			float sensitvity = 50;
+			if ((e1.getX() - e2.getX()) > sensitvity) {
+				swipeRightToLeft();
+			} else if ((e2.getX() - e1.getX()) > sensitvity) {
+				swipeLeftToRight();
+			}
+
+			return true;
+		}
+	};
+
+	/**
+	 * Called when User presses on/off button.
+	 * 
+	 * @param view
+	 */
+	public void buttonOnOffClick(View view) {
+		if (((ToggleButton) view).isChecked()) {
+			if (isParanoid()) {
+				String[] protocols = getResources().getStringArray(
+						R.array.protocols);
+				for (String protocol : protocols) {
+					mService.startListener(protocol);
+				}
+			} else {
+				if (mService.isRunning("SMB")) {
+					mService.stopListener("SMB");
+				} else {
+					mService.startListener("SMB");
+				}
+			}
+		} else {
+			mService.stopListeners();
+			stopAndUnbind();
+		}
 	}
 
 	@Override
@@ -140,66 +213,14 @@ public class MainActivity extends Activity implements Receiver {
 		return super.onOptionsItemSelected(item);
 	}
 
-	@Override
-	protected void onStart() {
-		super.onStart();
-		// Register Broadcast Receiver
-		registerReceiver();
-		logResultReceiver.setReceiver(this);
-		// Bind service if running, else check for connection change and delete
-		// sessionData
-		if (isServiceRunning()) {
-			bindService(getServiceIntent(), mConnection, BIND_AUTO_CREATE);
-		} 
-		// Update UI
-		updateConnectionInfText();
-	}
-
-	@Override
-	protected void onStop() {
-		// Unregister Broadcast Receiver
-		unregisterReceiver();
-		logResultReceiver.setReceiver(null);
-		super.onStop();
-	}
-
-	@Override
-	protected void onDestroy() {
-		// Unbind running service
-		if(!mService.hasRunningListeners()){
-			stopAndUnbind();
-		}
-		super.onDestroy();
-	}
-
 	@Override
 	public void onReceiveResult(int resultCode, Bundle resultData) {
 		isBssidSeen = resultData.getBoolean("result");
 	}
 
-	/**
-	 * Called when User presses on/off button.
-	 * 
-	 * @param view
-	 */
-	public void buttonOnOffClick(View view) {
-		if (((ToggleButton) view).isChecked()) {
-			if (isParanoid()) {
-				String[] protocols = getResources().getStringArray(R.array.protocols);
-				for(String protocol: protocols){
-					mService.startListener(protocol);	
-				}						
-			} else {
-				if(mService.isRunning("SMB")){
-					mService.stopListener("SMB");
-				}else{
-					mService.startListener("SMB");
-				}	
-			}
-		} else {
-			mService.stopListeners();
-			stopAndUnbind();
-		}
+	@Override
+	public boolean onTouchEvent(MotionEvent event) {
+		return gestureDetector.onTouchEvent(event);
 	}
 
 	/**
@@ -217,16 +238,6 @@ public class MainActivity extends Activity implements Receiver {
 		startActivity(new Intent(this, PlayGroundActivity.class));
 	}
 
-	/**
-	 * If mobile phone is connected to a wireless network starts the background
-	 * service ands binds itself to it. Else notifies the user that service
-	 * could not be started.
-	 */
-	private void startAndBind() {
-		startService(getServiceIntent());
-		bindService();
-	}
-
 	/**
 	 * Binds service to Activity
 	 * 
@@ -236,57 +247,6 @@ public class MainActivity extends Activity implements Receiver {
 		bindService(getServiceIntent(), mConnection, BIND_AUTO_CREATE);
 	}
 
-	/**
-	 * Stops service and unbinds it.
-	 * 
-	 * @see HoneyService
-	 */
-	private void stopAndUnbind() {
-		unbindService();
-		stopService(getServiceIntent());
-	}
-
-	/**
-	 * Unbinds service.
-	 * 
-	 * @see HoneyService
-	 */
-	private void unbindService() {
-		unbindService(mConnection);
-	}
-
-	/**
-	 * Connection to bind the background service
-	 * 
-	 * @see HoneyService
-	 */
-	private ServiceConnection mConnection = new ServiceConnection() {
-		/**
-		 * After the service is bound, check which has been clicked and start
-		 * it.
-		 * 
-		 * @see android.content.ServiceConnection#onServiceConnected(android.content.ComponentName)
-		 */
-		@Override
-		public void onServiceConnected(ComponentName name, IBinder service) {
-			mService = ((LocalBinder) service).getService();
-			serviceBound = true;
-			updateUI();
-		}
-
-		/**
-		 * After the service is unbound, delete reference.
-		 * 
-		 * @see android.content.ServiceConnection#onServiceDisconnected(android.content.ComponentName)
-		 */
-		@Override
-		public void onServiceDisconnected(ComponentName name) {
-			mService = null;
-			serviceBound = false;
-		}
-
-	};
-
 	/**
 	 * Checks if the phone ist rooted and if porthack is installed. Sets flags
 	 * {@link isRooted} and {@link porthackInstalled}
@@ -330,15 +290,6 @@ public class MainActivity extends Activity implements Receiver {
 		return new Intent(this, HoneyService.class);
 	}
 
-	/**
-	 * Checks if user selected paranoid mode.
-	 * 
-	 * @return True when paranoid mode is selected, else returns false.
-	 */
-	private boolean isParanoid() {
-		return ((CheckBox) findViewById(R.id.checkBoxParanoid)).isChecked();
-	}
-
 	/**
 	 * Initializes the ListView. Creating its contents dynamic from protocol
 	 * res/values/protocols.xml
@@ -370,15 +321,50 @@ public class MainActivity extends Activity implements Receiver {
 					int position, long id) {
 				String protocolName = (String) ((HashMap<?, ?>) adapter
 						.getItem(position)).get("protocol");
-				if(mService.isRunning(protocolName)){
+				if (mService.isRunning(protocolName)) {
 					mService.stopListener(protocolName);
-				}else{
+				} else {
 					mService.startListener(protocolName);
-				}				
+				}
 			}
 		});
 	}
-	
+
+	/**
+	 * Initializes variables for screen animation
+	 */
+	private void initViewAnimator() {
+		viewAnimator = (ViewAnimator) findViewById(R.id.viewAnimator);
+		gestureDetector = new GestureDetector(this, simpleOnGestureListener);
+
+		animFlipInLR = AnimationUtils.loadAnimation(this,
+				R.anim.in_left_to_right);
+		animFlipOutLR = AnimationUtils.loadAnimation(this,
+				R.anim.out_left_to_right);
+		animFlipInRL = AnimationUtils.loadAnimation(this,
+				R.anim.in_right_to_left);
+		animFlipOutRL = AnimationUtils.loadAnimation(this,
+				R.anim.out_right_to_left);
+	}
+
+	/**
+	 * Checks if user selected paranoid mode.
+	 * 
+	 * @return True when paranoid mode is selected, else returns false.
+	 */
+	private boolean isParanoid() {
+		return ((CheckBox) findViewById(R.id.checkBoxParanoid)).isChecked();
+	}
+
+	/**
+	 * Checks if a {@link HoneyService} instance is running.
+	 * 
+	 * @return True if {@link HoneyService} is running, else false.
+	 */
+	private boolean isServiceBound() {
+		return serviceBound;
+	}
+
 	/**
 	 * Checks if a {@link HoneyService} instance is running.
 	 * 
@@ -395,24 +381,66 @@ public class MainActivity extends Activity implements Receiver {
 		}
 		return false;
 	}
-	
+
 	/**
-	 * Checks if a {@link HoneyService} instance is running.
+	 * Register broadcast receiver for custom broadcast.
 	 * 
-	 * @return True if {@link HoneyService} is running, else false.
+	 * @see #BROADCAST
 	 */
-	private boolean isServiceBound() {
-		return serviceBound;
+	private void registerReceiver() {
+		LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver,
+				new IntentFilter(getString(R.string.broadcast)));
 	}
 
 	/**
-	 * Register broadcast receiver for custom broadcast.
+	 * If mobile phone is connected to a wireless network starts the background
+	 * service ands binds itself to it. Else notifies the user that service
+	 * could not be started.
+	 */
+	private void startAndBind() {
+		startService(getServiceIntent());
+		bindService();
+	}
+
+	/**
+	 * Stops service and unbinds it.
 	 * 
-	 * @see #BROADCAST
+	 * @see HoneyService
 	 */
-	private void registerReceiver() {
-		LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver,
-				new IntentFilter(getString(R.string.broadcast)));
+	private void stopAndUnbind() {
+		unbindService();
+		stopService(getServiceIntent());
+	}
+
+	/**
+	 * Called when a swipe to the Right is registered.
+	 */
+	private void swipeLeftToRight() {
+		if (viewAnimator.getDisplayedChild() == 1) {
+			viewAnimator.setInAnimation(animFlipInLR);
+			viewAnimator.setOutAnimation(animFlipOutLR);
+			viewAnimator.setDisplayedChild(0);
+		}
+	}
+
+	/**
+	 * Called when a swipe to the Left is registered.
+	 */
+	private void swipeRightToLeft() {
+		if (viewAnimator.getDisplayedChild() == 0) {
+			viewAnimator.setInAnimation(animFlipInRL);
+			viewAnimator.setOutAnimation(animFlipOutRL);
+			viewAnimator.setDisplayedChild(1);
+		}
+	}
+
+	/**
+	 * Unbinds service.
+	 * 
+	 * @see HoneyService
+	 */
+	private void unbindService() {
+		unbindService(mConnection);
 	}
 
 	/**
@@ -425,18 +453,132 @@ public class MainActivity extends Activity implements Receiver {
 	}
 
 	/**
-	 * Receiver for custom broadcast.
+	 * Gets Information about connection state and updates the GUI.
+	 */
+	private void updateConnectionInfText() {
+		TextView ssidView = (TextView) findViewById(R.id.textViewSSIDValue);
+		TextView bssidView = (TextView) findViewById(R.id.textViewBSSIDValue);
+		TextView internalIPView = (TextView) findViewById(R.id.textViewInternalIPValue);
+		TextView externalIPView = (TextView) findViewById(R.id.textViewExternalIPValue);
+
+		// externalIPView.setText("Loading...");
+
+		// Get connection information
+		String ssid = connectionInfo.getString(
+				getString(R.string.connection_info_ssid), null);
+		String bssid = connectionInfo.getString(
+				getString(R.string.connection_info_bssid), null);
+		String internalIP = connectionInfo.getString(
+				getString(R.string.connection_info_internal_ip), null);
+		String externalIP = connectionInfo.getString(
+				getString(R.string.connection_info_external_ip), null);
+
+		// Set text fields
+		if (ssid != null)
+			ssidView.setText(ssid);
+		else
+			ssidView.setText("-");
+
+		if (bssid != null)
+			bssidView.setText(bssid);
+		else
+			bssidView.setText("-");
+
+		if (internalIP != null)
+			internalIPView.setText(internalIP);
+		else
+			internalIPView.setText("-");
+
+		if (externalIP != null)
+			externalIPView.setText(externalIP);
+		else
+			externalIPView.setText("-");
+	}
+
+	/**
+	 * Sets the connections count for a given protocol.
 	 * 
-	 * @see #BROADCAST
+	 * @param connections
+	 *            New value for recorded connections.
+	 * @param protocolName
+	 *            Name of the protocol which should be updated.
 	 */
-	private BroadcastReceiver mReceiver = new BroadcastReceiver() {
-		@Override
-		public void onReceive(Context context, Intent intent) {
-			// Update user interface.
-			updateUI();
-			updateConnectionInfText();
+	private void updateProtocolConnections(int connections, String protocolName) {
+		for (int i = 0; i < adapter.getCount(); ++i) {
+			HashMap<String, String> d = ((HashMap<String, String>) adapter
+					.getItem(i));
+			if (d.get("protocol").equals(protocolName)) {
+				d.put("connections", String.valueOf(connections));
+			}
 		}
-	};
+		adapter.notifyDataSetChanged();
+	}
+
+	/**
+	 * Sets the light indicator for a given protocol.
+	 * 
+	 * @param light
+	 *            Integer code to set the light color.
+	 * @param protocolName
+	 *            Name of the protocol which should be updated.
+	 */
+	private void updateProtocolLight(int light, String protocolName) {
+		for (int i = 0; i < adapter.getCount(); ++i) {
+			HashMap<String, String> d = (HashMap<String, String>) adapter
+					.getItem(i);
+			if (d.get("protocol").equals(protocolName)) {
+				switch (light) {
+				case LIGHT_GREY:
+					d.put("light", String.valueOf(R.drawable.light_grey));
+					d.put("connections", "-");
+					break;
+				case LIGHT_GREEN:
+					d.put("light", String.valueOf(R.drawable.light_green));
+					break;
+				case LIGHT_RED:
+					d.put("light", String.valueOf(R.drawable.light_red));
+					break;
+				case LIGHT_YELLOW:
+					d.put("light", String.valueOf(R.drawable.light_yellow));
+					break;
+				}
+			}
+		}
+		adapter.notifyDataSetChanged();
+	}
+
+	/**
+	 * Sets the big light indicator.
+	 * 
+	 * @param light
+	 *            Integer code to set the light color.
+	 * @see #LIGHT_GREY
+	 * @see #LIGHT_GREEN
+	 * @see #LIGHT_RED
+	 * @see #LIGHT_YELLOW
+	 */
+	private void updateStatusLight(int light) {
+		switch (light) {
+		case LIGHT_GREY:
+			((ImageView) findViewById(R.id.imageViewLight))
+					.setImageResource(R.drawable.light_grey_large);
+			break;
+		case LIGHT_GREEN:
+			((ImageView) findViewById(R.id.imageViewLight))
+					.setImageResource(R.drawable.light_green_large);
+			break;
+		case LIGHT_RED:
+			((ImageView) findViewById(R.id.imageViewLight))
+					.setImageResource(R.drawable.light_red_large);
+			break;
+		case LIGHT_YELLOW:
+			((ImageView) findViewById(R.id.imageViewLight))
+					.setImageResource(R.drawable.light_yellow_large);
+			break;
+		}
+	}
+
+	/* ############# Help functions for animation ################## */
 
 	/**
 	 * Updates Information shown by the GUI.
@@ -445,29 +587,36 @@ public class MainActivity extends Activity implements Receiver {
 		boolean activeListeners = false;
 		boolean activeHandlers = false;
 		boolean yellowLight = false;
-		
+
 		// Check for all protocols if listeners are active and attacks have been
 		// recorded
 		// Update protocol lights and connection information.
 		for (String protocol : getResources().getStringArray(R.array.protocols)) {
-			if(isServiceBound()){
+			if (isServiceBound()) {
 				// Check if protocol is active
 				if (mService.isRunning(protocol)) {
 					activeListeners = true;
-					int handlerCount = mService.getNumberOfActiveConnections(protocol);
+					int handlerCount = mService
+							.getNumberOfActiveConnections(protocol);
 					// Check if attacks have been recorded in this session.
 					if (handlerCount > 0) {
 						activeHandlers = true;
 						updateProtocolLight(LIGHT_RED, protocol);
 						updateProtocolConnections(handlerCount, protocol);
 					} else {
-						// Check if the bssid of the wireless network has already
+						// Check if the bssid of the wireless network has
+						// already
 						// been recorded as infected.
 						Logger.isBssidSeen(getApplicationContext(), protocol,
 								HelperUtils.getBSSID(getApplicationContext()),
 								logResultReceiver);
 						UglyDbHelper dbh = new UglyDbHelper(this);
-						if (dbh.bssidSeen(protocol, connectionInfo.getString(getString(R.string.connection_info_bssid), null))) {
+						if (dbh.bssidSeen(
+								protocol,
+								connectionInfo
+										.getString(
+												getString(R.string.connection_info_bssid),
+												null))) {
 							updateProtocolLight(LIGHT_YELLOW, protocol);
 							yellowLight = true;
 						} else {
@@ -478,9 +627,9 @@ public class MainActivity extends Activity implements Receiver {
 				} else {
 					updateProtocolLight(LIGHT_GREY, protocol);
 				}
-			}else{
+			} else {
 				updateProtocolLight(LIGHT_GREY, protocol);
-			}				
+			}
 		}
 
 		// Update the big attack indicator.
@@ -505,187 +654,52 @@ public class MainActivity extends Activity implements Receiver {
 		}
 	}
 
-	/**
-	 * Sets the big light indicator.
-	 * 
-	 * @param light
-	 *            Integer code to set the light color.
-	 * @see #LIGHT_GREY
-	 * @see #LIGHT_GREEN
-	 * @see #LIGHT_RED
-	 * @see #LIGHT_YELLOW
-	 */
-	private void updateStatusLight(int light) {
-		switch (light) {
-		case LIGHT_GREY:
-			((ImageView) findViewById(R.id.imageViewLight))
-					.setImageResource(R.drawable.light_grey_large);
-			break;
-		case LIGHT_GREEN:
-			((ImageView) findViewById(R.id.imageViewLight))
-					.setImageResource(R.drawable.light_green_large);
-			break;
-		case LIGHT_RED:
-			((ImageView) findViewById(R.id.imageViewLight))
-					.setImageResource(R.drawable.light_red_large);
-			break;
-		case LIGHT_YELLOW:
-			((ImageView) findViewById(R.id.imageViewLight))
-					.setImageResource(R.drawable.light_yellow_large);
-			break;
-		}
-	}
+	@Override
+	protected void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		logResultReceiver = new LogResultReceiver(new Handler());
+		setContentView(R.layout.activity_main);
+		connectionInfo = getSharedPreferences(
+				getString(R.string.connection_info), Context.MODE_PRIVATE);
 
-	/**
-	 * Sets the light indicator for a given protocol.
-	 * 
-	 * @param light
-	 *            Integer code to set the light color.
-	 * @param protocolName
-	 *            Name of the protocol which should be updated.
-	 */
-	private void updateProtocolLight(int light, String protocolName) {
-		for (int i = 0; i < adapter.getCount(); ++i) {
-			HashMap<String, String> d = (HashMap<String, String>) adapter
-					.getItem(i);
-			if (d.get("protocol").equals(protocolName)) {
-				switch (light) {
-				case LIGHT_GREY:
-					d.put("light", String.valueOf(R.drawable.light_grey));
-					d.put("connections", "-");
-					break;
-				case LIGHT_GREEN:
-					d.put("light", String.valueOf(R.drawable.light_green));
-					break;
-				case LIGHT_RED:
-					d.put("light", String.valueOf(R.drawable.light_red));
-					break;
-				case LIGHT_YELLOW:
-					d.put("light", String.valueOf(R.drawable.light_yellow));
-					break;
-				}
-			}
-		}
-		adapter.notifyDataSetChanged();
+		// Create dynamic view elements
+		initViewAnimator();
+		initListView();
+		// Initialize Class variables
+		checkRootAndPorthack();
+		startAndBind();
 	}
 
-	/**
-	 * Sets the connections count for a given protocol.
-	 * 
-	 * @param connections
-	 *            New value for recorded connections.
-	 * @param protocolName
-	 *            Name of the protocol which should be updated.
-	 */
-	private void updateProtocolConnections(int connections, String protocolName) {
-		for (int i = 0; i < adapter.getCount(); ++i) {
-			HashMap<String, String> d = ((HashMap<String, String>) adapter
-					.getItem(i));
-			if (d.get("protocol").equals(protocolName)) {
-				d.put("connections", String.valueOf(connections));
-			}
+	@Override
+	protected void onDestroy() {
+		// Unbind running service
+		if (!mService.hasRunningListeners()) {
+			stopAndUnbind();
 		}
-		adapter.notifyDataSetChanged();
-	}
-
-	/**
-	 * Gets Information about connection state and updates the GUI.
-	 */
-	private void updateConnectionInfText() {
-		TextView ssidView = (TextView) findViewById(R.id.textViewSSIDValue);
-		TextView bssidView = (TextView) findViewById(R.id.textViewBSSIDValue);
-		TextView internalIPView = (TextView) findViewById(R.id.textViewInternalIPValue);
-		TextView externalIPView = (TextView) findViewById(R.id.textViewExternalIPValue);
-
-//		externalIPView.setText("Loading...");
-
-		// Get connection information
-		String ssid = connectionInfo.getString(getString(R.string.connection_info_ssid), null);
-		String bssid = connectionInfo.getString(getString(R.string.connection_info_bssid), null);
-		String internalIP = connectionInfo.getString(getString(R.string.connection_info_internal_ip), null);
-		String externalIP = connectionInfo.getString(getString(R.string.connection_info_external_ip), null);
-
-		// Set text fields
-		if (ssid != null)
-			ssidView.setText(ssid);
-		else
-			ssidView.setText("-");
-
-		if (bssid != null)
-			bssidView.setText(bssid);
-		else
-			bssidView.setText("-");
-
-		if (internalIP != null)
-			internalIPView.setText(internalIP);
-		else
-			internalIPView.setText("-");
-		
-		if (externalIP != null)
-			externalIPView.setText(externalIP);
-		else
-			externalIPView.setText("-");
+		super.onDestroy();
 	}
 
-	/* ############# Help functions for animation ################## */
-
 	@Override
-	public boolean onTouchEvent(MotionEvent event) {
-		return gestureDetector.onTouchEvent(event);
-	}
-
-	/**
-	 * Initializes variables for screen animation
-	 */
-	private void initViewAnimator() {
-		viewAnimator = (ViewAnimator) findViewById(R.id.viewAnimator);
-		gestureDetector = new GestureDetector(this, simpleOnGestureListener);
-
-		animFlipInLR = AnimationUtils.loadAnimation(this,
-				R.anim.in_left_to_right);
-		animFlipOutLR = AnimationUtils.loadAnimation(this,
-				R.anim.out_left_to_right);
-		animFlipInRL = AnimationUtils.loadAnimation(this,
-				R.anim.in_right_to_left);
-		animFlipOutRL = AnimationUtils.loadAnimation(this,
-				R.anim.out_right_to_left);
-	}
-
-	/**
-	 * Called when a swipe to the Left is registered.
-	 */
-	private void swipeRightToLeft() {
-		if (viewAnimator.getDisplayedChild() == 0) {
-			viewAnimator.setInAnimation(animFlipInRL);
-			viewAnimator.setOutAnimation(animFlipOutRL);
-			viewAnimator.setDisplayedChild(1);
+	protected void onStart() {
+		super.onStart();
+		// Register Broadcast Receiver
+		registerReceiver();
+		logResultReceiver.setReceiver(this);
+		// Bind service if running, else check for connection change and delete
+		// sessionData
+		if (isServiceRunning()) {
+			bindService(getServiceIntent(), mConnection, BIND_AUTO_CREATE);
 		}
+		// Update UI
+		updateConnectionInfText();
 	}
 
-	/**
-	 * Called when a swipe to the Right is registered.
-	 */
-	private void swipeLeftToRight() {
-		if (viewAnimator.getDisplayedChild() == 1) {
-			viewAnimator.setInAnimation(animFlipInLR);
-			viewAnimator.setOutAnimation(animFlipOutLR);
-			viewAnimator.setDisplayedChild(0);
-		}
+	@Override
+	protected void onStop() {
+		// Unregister Broadcast Receiver
+		unregisterReceiver();
+		logResultReceiver.setReceiver(null);
+		super.onStop();
 	}
 
-	SimpleOnGestureListener simpleOnGestureListener = new SimpleOnGestureListener() {
-		@Override
-		public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
-				float velocityY) {
-			float sensitvity = 50;
-			if ((e1.getX() - e2.getX()) > sensitvity) {
-				swipeRightToLeft();
-			} else if ((e2.getX() - e1.getX()) > sensitvity) {
-				swipeLeftToRight();
-			}
-
-			return true;
-		}
-	};
-	
 }

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

@@ -16,16 +16,27 @@ import de.tudarmstadt.informatik.hostage.logging.UglyDbHelper;
 import de.tudarmstadt.informatik.hostage.sync.BluetoothSync;
 import de.tudarmstadt.informatik.hostage.sync.NFCSync;
 
-public class PlayGroundActivity extends Activity{
-	
+public class PlayGroundActivity extends Activity {
+
 	BluetoothSync bs;
 
-	@Override
-	protected void onCreate(Bundle savedInstanceState) {
-		super.onCreate(savedInstanceState);
-		setContentView(R.layout.activity_playground);
-		bs = new BluetoothSync(this);
+	public void createNetworkData(View view) {
+		Random rnd = new Random();
+		ArrayList<HashMap<String, Object>> fakeNetInfo = new ArrayList<HashMap<String, Object>>();
+		for (int i = 0; i < 25; i++) {
+			HashMap<String, Object> network = new HashMap<String, Object>();
+			network.put(UglyDbHelper.KEY_BSSID, createRandomBSSID());
+			network.put(UglyDbHelper.KEY_SSID,
+					new BigInteger(130, rnd).toString(32));
+			network.put(UglyDbHelper.KEY_LATITUDE, rnd.nextDouble() * 360);
+			network.put(UglyDbHelper.KEY_LONGITUDE, rnd.nextDouble() * 360);
+			network.put(UglyDbHelper.KEY_ACCURACY, rnd.nextFloat());
+			network.put(UglyDbHelper.KEY_TIME, System.currentTimeMillis());
+			fakeNetInfo.add(network);
+		}
+
 		setNetworkInfoText();
+		new UglyDbHelper(this).updateNetworkInformation(fakeNetInfo);
 	}
 
 	@Override
@@ -33,64 +44,56 @@ public class PlayGroundActivity extends Activity{
 		getMenuInflater().inflate(R.menu.main, menu);
 		return true;
 	}
-	
-	private void setNetworkInfoText(){		
+
+	public void startNFC(View view) {
+		startActivity(new Intent(this, NFCSync.class));
+	}
+
+	public void syncData(View view) {
+		bs.syncData();
+	}
+
+	private String createRandomBSSID() {
+		Random rnd = new Random();
+		char[] symbols = new char[16];
+		for (int idx = 0; idx < 10; ++idx)
+			symbols[idx] = (char) ('0' + idx);
+		for (int idx = 10; idx < 16; ++idx)
+			symbols[idx] = (char) ('a' + idx - 10);
+
+		char[] buf = new char[17];
+		for (int i = 0; i < 18; i += 3) {
+			buf[i] = symbols[rnd.nextInt(symbols.length)];
+			buf[i + 1] = symbols[rnd.nextInt(symbols.length)];
+			if (i < 15) {
+				buf[i + 2] = ':';
+			}
+		}
+		return new String(buf);
+	}
+
+	private void setNetworkInfoText() {
 		UglyDbHelper dbh = new UglyDbHelper(this);
 		TextView bssids = (TextView) findViewById(R.id.textView1);
 		String text = "";
-		ArrayList<HashMap<String, Object>> netInfo = dbh.getNetworkInformation();
-		for(HashMap<String, Object> network : netInfo){
+		ArrayList<HashMap<String, Object>> netInfo = dbh
+				.getNetworkInformation();
+		for (HashMap<String, Object> network : netInfo) {
 			text = text + (String) network.get(UglyDbHelper.KEY_BSSID) + "\n"
-    					+ (String) network.get(UglyDbHelper.KEY_SSID) + "\n"
-    					+ (double)(Double) network.get(UglyDbHelper.KEY_LATITUDE) + "\n"
-    			 		+ (double)(Double) network.get(UglyDbHelper.KEY_LONGITUDE) + "\n"
-    			 		+ (float)(Float) network.get(UglyDbHelper.KEY_ACCURACY) + "\n"
-    			 		+ (long) (Long) network.get(UglyDbHelper.KEY_TIME) + "\n\n";			
+					+ (String) network.get(UglyDbHelper.KEY_SSID) + "\n"
+					+ network.get(UglyDbHelper.KEY_LATITUDE) + "\n"
+					+ network.get(UglyDbHelper.KEY_LONGITUDE) + "\n"
+					+ network.get(UglyDbHelper.KEY_ACCURACY) + "\n"
+					+ network.get(UglyDbHelper.KEY_TIME) + "\n\n";
 		}
 		bssids.setText(text);
 	}
-	public void syncData(View view){
-		bs.syncData();
-	}
-	
-	public void startNFC(View view){
-		startActivity(new Intent(this, NFCSync.class));
-	}
-	
-	public void createNetworkData(View view){
-		Random rnd = new Random();
-		ArrayList<HashMap<String, Object>> fakeNetInfo = new ArrayList<HashMap<String, Object>>();
-		for(int i = 0; i < 25; i++){
-			HashMap<String, Object> network = new HashMap<String, Object>();
-			network.put(UglyDbHelper.KEY_BSSID, createRandomBSSID());
-			network.put(UglyDbHelper.KEY_SSID, new BigInteger(130, rnd).toString(32));
-			network.put(UglyDbHelper.KEY_LATITUDE, rnd.nextDouble() * 360);
-			network.put(UglyDbHelper.KEY_LONGITUDE, rnd.nextDouble() * 360);
-			network.put(UglyDbHelper.KEY_ACCURACY, rnd.nextFloat());
-			network.put(UglyDbHelper.KEY_TIME, System.currentTimeMillis());
-			fakeNetInfo.add(network);
-		}
 
+	@Override
+	protected void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.activity_playground);
+		bs = new BluetoothSync(this);
 		setNetworkInfoText();
-		new UglyDbHelper(this).updateNetworkInformation(fakeNetInfo);
-	}
-	
-	private String createRandomBSSID(){
-		Random rnd = new Random();
-		char[] symbols = new char[16];
-	    for (int idx = 0; idx < 10; ++idx)
-	        symbols[idx] = (char) ('0' + idx);
-	    for (int idx = 10; idx < 16; ++idx)
-	        symbols[idx] = (char) ('a' + idx - 10);
-	      
-	    char[] buf = new char[17];
-	    for(int i = 0; i < 18; i += 3){	    	
-	    	buf[i] = symbols[rnd.nextInt(symbols.length)];
-	    	buf[i + 1] = symbols[rnd.nextInt(symbols.length)];
-	    	if(i < 15){
-		    	buf[i + 2] = ':';
-	    	}
-	    }
-	    return new String(buf);
 	}
 }

+ 176 - 139
src/de/tudarmstadt/informatik/hostage/ui/SettingsActivity.java

@@ -1,6 +1,5 @@
 package de.tudarmstadt.informatik.hostage.ui;
 
-import de.tudarmstadt.informatik.hostage.R;
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
 import android.os.Bundle;
@@ -9,149 +8,187 @@ import android.preference.Preference;
 import android.preference.PreferenceActivity;
 import android.preference.PreferenceManager;
 import android.widget.Toast;
+import de.tudarmstadt.informatik.hostage.R;
+
 /**
  * SettingsActivity creates the settings defined in /res/xml/preferences.xml.
+ * 
  * @author Lars Pandikow.
  */
-public class SettingsActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener {
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        addPreferencesFromResource(R.xml.preferences);  
-        //Set the value of the preference as the summary for the preference
-        Preference pref = findPreference("pref_external_location");
-        EditTextPreference etp = (EditTextPreference) pref;
-        pref.setSummary(etp.getText());
-        
-      //Set the value of the preference as the summary for the preference
-        pref = findPreference("pref_upload_server");
-        etp = (EditTextPreference) pref;
-        pref.setSummary(etp.getText());
-        
-        SharedPreferences defaultPref = PreferenceManager.getDefaultSharedPreferences(this);
-        //Set the value of the preference as the summary for the preference
-        pref = findPreference("pref_max_connections");
-        etp = (EditTextPreference) pref;
-        defaultPref.edit().putInt("max_connections", Integer.valueOf(etp.getText()).intValue()).commit();
-        pref.setSummary(etp.getText());
-        
-        //Set the value of the preference as the summary for the preference
-        pref = findPreference("pref_timeout");
-        etp = (EditTextPreference) pref;
-        defaultPref.edit().putInt("timeout", Integer.valueOf(etp.getText()).intValue()).commit();
-        pref.setSummary(etp.getText());
-        
-        //Set the value of the preference as the summary for the preference
-        pref = findPreference("pref_sleeptime");
-        etp = (EditTextPreference) pref;
-        defaultPref.edit().putInt("sleeptime", Integer.valueOf(etp.getText()).intValue()).commit();
-        pref.setSummary(etp.getText());
-        
-        //Set the value of the preference as the summary for the preference
-        pref = findPreference("pref_location_time");
-        etp = (EditTextPreference) pref;
-        defaultPref.edit().putInt("location_time", Integer.valueOf(etp.getText()).intValue()).commit();
-        pref.setSummary(etp.getText());
-        
-        //Set the value of the preference as the summary for the preference
-        pref = findPreference("pref_location_retries");
-        etp = (EditTextPreference) pref;
-        defaultPref.edit().putInt("location_retries", Integer.valueOf(etp.getText()).intValue()).commit();
-        pref.setSummary(etp.getText());
-    }    
+public class SettingsActivity extends PreferenceActivity implements
+		OnSharedPreferenceChangeListener {
+	@Override
+	public void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		addPreferencesFromResource(R.xml.preferences);
+		// Set the value of the preference as the summary for the preference
+		Preference pref = findPreference("pref_external_location");
+		EditTextPreference etp = (EditTextPreference) pref;
+		pref.setSummary(etp.getText());
+
+		// Set the value of the preference as the summary for the preference
+		pref = findPreference("pref_upload_server");
+		etp = (EditTextPreference) pref;
+		pref.setSummary(etp.getText());
+
+		SharedPreferences defaultPref = PreferenceManager
+				.getDefaultSharedPreferences(this);
+		// Set the value of the preference as the summary for the preference
+		pref = findPreference("pref_max_connections");
+		etp = (EditTextPreference) pref;
+		defaultPref
+				.edit()
+				.putInt("max_connections",
+						Integer.valueOf(etp.getText()).intValue()).commit();
+		pref.setSummary(etp.getText());
+
+		// Set the value of the preference as the summary for the preference
+		pref = findPreference("pref_timeout");
+		etp = (EditTextPreference) pref;
+		defaultPref.edit()
+				.putInt("timeout", Integer.valueOf(etp.getText()).intValue())
+				.commit();
+		pref.setSummary(etp.getText());
+
+		// Set the value of the preference as the summary for the preference
+		pref = findPreference("pref_sleeptime");
+		etp = (EditTextPreference) pref;
+		defaultPref.edit()
+				.putInt("sleeptime", Integer.valueOf(etp.getText()).intValue())
+				.commit();
+		pref.setSummary(etp.getText());
+
+		// Set the value of the preference as the summary for the preference
+		pref = findPreference("pref_location_time");
+		etp = (EditTextPreference) pref;
+		defaultPref
+				.edit()
+				.putInt("location_time",
+						Integer.valueOf(etp.getText()).intValue()).commit();
+		pref.setSummary(etp.getText());
+
+		// Set the value of the preference as the summary for the preference
+		pref = findPreference("pref_location_retries");
+		etp = (EditTextPreference) pref;
+		defaultPref
+				.edit()
+				.putInt("location_retries",
+						Integer.valueOf(etp.getText()).intValue()).commit();
+		pref.setSummary(etp.getText());
+	}
+
+	@Override
+	public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
+			String key) {
+		// Check which preference has been changed
+		if (key.equals("pref_external_location")) {
+			Preference pref = findPreference(key);
+			EditTextPreference etp = (EditTextPreference) pref;
+			String path = etp.getText();
+			// Check if the Path is valid
+			if (!path.startsWith("/"))
+				path = new String("/").concat(path);
+			if (!path.endsWith("/"))
+				path = path.concat(new String("/"));
+			if (!path.matches("/(([a-zA-Z_0-9])+/)*")) {
+				Toast.makeText(this,
+						"Path not valid. Must only contain a-zA-Z_0-9",
+						Toast.LENGTH_SHORT).show();
+				path = "/";
+				sharedPreferences.edit().putString(key, path).commit();
+			}
+			pref.setSummary(path);
+		} else if (key.equals("pref_upload_server")) {
+			Preference pref = findPreference(key);
+			EditTextPreference etp = (EditTextPreference) pref;
+			pref.setSummary(etp.getText());
+		} else if (key.equals("pref_max_connections")) {
+			Preference pref = findPreference(key);
+			EditTextPreference etp = (EditTextPreference) pref;
+			String value = etp.getText();
+			if (!value.matches("([0-9])+")) {
+				Toast.makeText(getApplicationContext(),
+						"Enter a valid number.", Toast.LENGTH_SHORT).show();
+				value = getResources().getString(
+						R.string.pref_max_connections_default);
+			}
+			sharedPreferences
+					.edit()
+					.putInt("max_connections",
+							Integer.valueOf(value).intValue()).commit();
+			pref.setSummary(value);
+		} else if (key.equals("pref_timeout")) {
+			Preference pref = findPreference(key);
+			EditTextPreference etp = (EditTextPreference) pref;
+			String value = etp.getText();
+			if (!value.matches("([0-9])+")) {
+				Toast.makeText(getApplicationContext(),
+						"Enter a valid number.", Toast.LENGTH_SHORT).show();
+				value = getResources().getString(R.string.pref_timeout_default);
+			}
+			sharedPreferences.edit()
+					.putInt("timeout", Integer.valueOf(value).intValue())
+					.commit();
+			pref.setSummary(value);
+		} else if (key.equals("pref_sleeptime")) {
+			Preference pref = findPreference(key);
+			EditTextPreference etp = (EditTextPreference) pref;
+			String value = etp.getText();
+			if (!value.matches("([0-9])+")) {
+				Toast.makeText(getApplicationContext(),
+						"Enter a valid number.", Toast.LENGTH_SHORT).show();
+				value = getResources().getString(
+						R.string.pref_sleeptime_default);
+			}
+			sharedPreferences.edit()
+					.putInt("sleeptime", Integer.valueOf(value).intValue())
+					.commit();
+			pref.setSummary(value);
+		} else if (key.equals("pref_location_time")) {
+			Preference pref = findPreference(key);
+			EditTextPreference etp = (EditTextPreference) pref;
+			String value = etp.getText();
+			if (!value.matches("([0-9])+")) {
+				Toast.makeText(getApplicationContext(),
+						"Enter a valid number.", Toast.LENGTH_SHORT).show();
+				value = getResources().getString(
+						R.string.pref_location_time_default);
+			}
+			sharedPreferences.edit()
+					.putInt("location_time", Integer.valueOf(value).intValue())
+					.commit();
+			pref.setSummary(value);
+		} else if (key.equals("pref_location_retries")) {
+			Preference pref = findPreference(key);
+			EditTextPreference etp = (EditTextPreference) pref;
+			String value = etp.getText();
+			if (!value.matches("([0-9])+")) {
+				Toast.makeText(getApplicationContext(),
+						"Enter a valid number.", Toast.LENGTH_SHORT).show();
+				value = getResources().getString(
+						R.string.pref_location_retries_default);
+			}
+			sharedPreferences
+					.edit()
+					.putInt("location_retries",
+							Integer.valueOf(value).intValue()).commit();
+			pref.setSummary(value);
+		}
 
-    protected void onResume() {
-    	// register a listener to catch preference changes
-        super.onResume();
-        getPreferenceScreen().getSharedPreferences()
-                .registerOnSharedPreferenceChangeListener(this);
-    }
+	}
 
-    protected void onPause() {
-        super.onPause();
-        getPreferenceScreen().getSharedPreferences()
-                .unregisterOnSharedPreferenceChangeListener(this);
-    }
+	@Override
+	protected void onPause() {
+		super.onPause();
+		getPreferenceScreen().getSharedPreferences()
+				.unregisterOnSharedPreferenceChangeListener(this);
+	}
 
-    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
-            String key) {
-    	// Check which preference has been changed
-    	if(key.equals("pref_external_location")){
-            Preference pref = findPreference(key);
-            EditTextPreference etp = (EditTextPreference) pref;
-            String path = etp.getText();
-            //Check if the Path is valid
-            if(!path.startsWith("/"))
-            	path = new String("/").concat(path);
-            if(!path.endsWith("/"))
-            	path = path.concat(new String("/"));
-            if (!path.matches("/(([a-zA-Z_0-9])+/)*")){
-            	Toast.makeText(this, "Path not valid. Must only contain a-zA-Z_0-9", Toast.LENGTH_SHORT).show();
-            	path = "/";
-            	sharedPreferences.edit().putString(key, path).commit();            	
-            }
-            pref.setSummary(path);
-        }
-    	else if(key.equals("pref_upload_server")){
-            Preference pref = findPreference(key);
-            EditTextPreference etp = (EditTextPreference) pref;
-            pref.setSummary(etp.getText());
-        }
-    	else if(key.equals("pref_max_connections")){
-    		Preference pref = findPreference(key);
-    		EditTextPreference etp = (EditTextPreference) pref;
-    		String value = etp.getText();
-    		if(!value.matches("([0-9])+")){
-    			Toast.makeText(getApplicationContext(), "Enter a valid number.", Toast.LENGTH_SHORT).show();
-    			value = getResources().getString(R.string.pref_max_connections_default);
-    		}
-        	sharedPreferences.edit().putInt("max_connections", Integer.valueOf(value).intValue()).commit();
-    		pref.setSummary(value);
-    	}
-    	else if(key.equals("pref_timeout")){
-    		Preference pref = findPreference(key);
-    		EditTextPreference etp = (EditTextPreference) pref;
-    		String value = etp.getText();
-    		if(!value.matches("([0-9])+")){
-    			Toast.makeText(getApplicationContext(), "Enter a valid number.", Toast.LENGTH_SHORT).show();
-    			value = getResources().getString(R.string.pref_timeout_default);
-    		}
-        	sharedPreferences.edit().putInt("timeout", Integer.valueOf(value).intValue()).commit();
-    		pref.setSummary(value);
-    	}
-    	else if(key.equals("pref_sleeptime")){
-    		Preference pref = findPreference(key);
-    		EditTextPreference etp = (EditTextPreference) pref;
-    		String value = etp.getText();
-    		if(!value.matches("([0-9])+")){
-    			Toast.makeText(getApplicationContext(), "Enter a valid number.", Toast.LENGTH_SHORT).show();
-    			value = getResources().getString(R.string.pref_sleeptime_default);
-    		}
-        	sharedPreferences.edit().putInt("sleeptime", Integer.valueOf(value).intValue()).commit();
-    		pref.setSummary(value);
-    	}
-    	else if(key.equals("pref_location_time")){
-    		Preference pref = findPreference(key);
-    		EditTextPreference etp = (EditTextPreference) pref;
-    		String value = etp.getText();
-    		if(!value.matches("([0-9])+")){
-    			Toast.makeText(getApplicationContext(), "Enter a valid number.", Toast.LENGTH_SHORT).show();
-    			value = getResources().getString(R.string.pref_location_time_default);
-    		}
-        	sharedPreferences.edit().putInt("location_time", Integer.valueOf(value).intValue()).commit();
-    		pref.setSummary(value);
-    	}
-    	else if(key.equals("pref_location_retries")){
-    		Preference pref = findPreference(key);
-    		EditTextPreference etp = (EditTextPreference) pref;
-    		String value = etp.getText();
-    		if(!value.matches("([0-9])+")){
-    			Toast.makeText(getApplicationContext(), "Enter a valid number.", Toast.LENGTH_SHORT).show();
-    			value = getResources().getString(R.string.pref_location_retries_default);
-    		}
-        	sharedPreferences.edit().putInt("location_retries", Integer.valueOf(value).intValue()).commit();
-    		pref.setSummary(value);
-    	}
-    	 
-    }
+	@Override
+	protected void onResume() {
+		// register a listener to catch preference changes
+		super.onResume();
+		getPreferenceScreen().getSharedPreferences()
+				.registerOnSharedPreferenceChangeListener(this);
+	}
 }

+ 179 - 170
src/de/tudarmstadt/informatik/hostage/ui/ViewLog.java

@@ -61,13 +61,59 @@ public class ViewLog extends Activity {
 	private SharedPreferences pref;
 	private Editor editor;
 
-	@Override
-	protected void onCreate(Bundle savedInstanceState) {
-		super.onCreate(savedInstanceState);
-		setContentView(R.layout.activity_viewlog);
-		pref = PreferenceManager.getDefaultSharedPreferences(this);
-		editor = pref.edit();
-		initStatistic();
+	/**
+	 * 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
@@ -92,79 +138,16 @@ public class ViewLog extends Activity {
 	}
 
 	/**
-	 * Creates a Dialog to choose export format. Then calls
-	 * {@link ViewLog#exportDatabase(int)}
+	 * Starts a ViewLogTable Activity.
 	 * 
 	 * @param view
 	 *            View elements which triggers the method call.
+	 * @see ViewLogTable
 	 */
-	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() {
-			public void onClick(DialogInterface dialog, int position) {
-				exportDatabase(position);
-			}
-		});
-		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);
-			}
+	public void showLog(View view) {
+		startActivity(new Intent(this, ViewLogTable.class));
+		// TODO Delete
 
-			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();
-		}
 	}
 
 	/**
@@ -218,6 +201,7 @@ public class ViewLog extends Activity {
 		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);
@@ -263,48 +247,45 @@ public class ViewLog extends Activity {
 	}
 
 	/**
-	 * 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
-
-	}
-
-	/**
-	 * 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.
+	 * Shows a Dialog to confirm that the database should be cleared. If
+	 * confirmed {@link SQLLogger#clearData()} is called.
 	 * 
-	 * @param view
-	 *            View elements which triggers the method call.
-	 * @see ViewLog#deleteByBSSID()
-	 * @see ViewLog#deleteByDate()
-	 * @see ViewLog#deleteAll()
+	 * @see ILogger#clearData()
 	 */
-	public void deleteLog(View view) {
+	private void deleteAll() {
 		AlertDialog.Builder builder = new AlertDialog.Builder(this);
-		builder.setTitle(R.string.gui_delete_dialog_title);
-		builder.setItems(R.array.delete_criteria,
-				new DialogInterface.OnClickListener() {
-					public void onClick(DialogInterface dialog, int position) {
-						switch (position) {
-						case 0:
-							deleteByBSSID();
-							break;
-						case 1:
-							deleteByDate();
-							break;
-						case 2:
-							deleteAll();
-						}
-					}
-				});
+		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();
 	}
@@ -326,6 +307,7 @@ public class ViewLog extends Activity {
 		}
 		builder.setTitle(R.string.gui_delete_dialog_title);
 		builder.setItems(strings, new DialogInterface.OnClickListener() {
+			@Override
 			@SuppressLint("NewApi")
 			public void onClick(DialogInterface dialog, int position) {
 
@@ -355,25 +337,6 @@ public class ViewLog extends Activity {
 		showDialog(0);
 	}
 
-	@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() {
-						public void onDateSet(DatePicker view, int year,
-								int monthOfYear, int dayOfMonth) {
-							deleteByDate(year, monthOfYear, dayOfMonth);
-						}
-					}, pYear, pMonth, pDay);
-		}
-		return null;
-	}
-
 	/**
 	 * 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
@@ -395,6 +358,7 @@ public class ViewLog extends Activity {
 				.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();
@@ -415,6 +379,7 @@ public class ViewLog extends Activity {
 						})
 				.setNegativeButton(R.string.gui_cancel,
 						new DialogInterface.OnClickListener() {
+							@Override
 							public void onClick(DialogInterface dialog, int id) {
 								// User cancelled the dialog
 							}
@@ -425,45 +390,60 @@ public class ViewLog extends Activity {
 	}
 
 	/**
-	 * Shows a Dialog to confirm that the database should be cleared. If
-	 * confirmed {@link SQLLogger#clearData()} is called.
+	 * Exports all records in a given format. Before exporting checks export
+	 * location from preferences.
 	 * 
-	 * @see ILogger#clearData()
+	 * @param format
+	 *            Integer coded export format
+	 * @see Record#toString(int)
 	 */
-	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() {
-							@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() {
-							public void onClick(DialogInterface dialog, int id) {
-								// User cancelled the dialog
-							}
-						});
-		// Create the AlertDialog object
-		builder.create();
-		builder.show();
+	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();
+		}
 	}
 
 	/**
@@ -532,4 +512,33 @@ public class ViewLog extends Activity {
 			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;
+	}
 }

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

@@ -4,8 +4,8 @@ import android.app.Activity;
 import android.os.Bundle;
 import android.widget.ScrollView;
 import android.widget.TextView;
-import de.tudarmstadt.informatik.hostage.logging.UglyDbHelper;
 import de.tudarmstadt.informatik.hostage.logging.Record;
+import de.tudarmstadt.informatik.hostage.logging.UglyDbHelper;
 
 /**
  * Creates a simple log view. Shows the Information for every attack. The format

+ 34 - 67
src/de/tudarmstadt/informatik/hostage/wrapper/Packet.java

@@ -1,91 +1,58 @@
 package de.tudarmstadt.informatik.hostage.wrapper;
 
-import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
-
 /**
- * Wrapper class for IO content.
- * @author Wulf Pfeiffer
+ * Wrapper class for the payload of a network packet.
+ * 
+ * @author Mihai Plasoianu
  */
 public class Packet {
 
-	private byte[] message		= null;
-	private boolean isStringMsg	= false;
-	private boolean isByteMsg	= false;
-
-	/**
-	 * Constructor.
-	 */
-	public Packet() {
-		message = null;
-	}
-	
-	/**
-	 * Constructor.
-	 * If Packet is created with a String value, it is marked with a boolean.
-	 * @param message
-	 */
-	public Packet(String message) {
-		this.message	= message.getBytes();
-		isStringMsg		= true;
-	}
-	
-	/**
-	 * Constructor.
-	 * If Packet is created with a byte[] value, it is marked with a boolean.
-	 * @param message
-	 */
-	public Packet(byte[] message) {
-		this.message	= message;
-		isByteMsg		= true;
-	}
+	private byte[] payload;
 
 	/**
-	 * Returns the message value as byte[].
-	 * @return message value
+	 * Constructs Packet from byte[]
+	 * 
+	 * @param payload
+	 *            The byte[] payload
 	 */
-	public byte[] getMessage() {
-		return message;
+	public Packet(byte[] payload) {
+		this.payload = payload;
 	}
 
 	/**
-	 * Returns the class which the Packet was created with.
-	 * If the string constructor was used it returns String.class.
-	 * If the byte[] constructor was used it returns byte[].class.
-	 * Else it returns null.
-	 * @return class which the Packet was created with.
+	 * Constructs Packet from String
+	 * 
+	 * @param payload
+	 *            The String payload
 	 */
-	public Class<? extends Object> getType() {
-		if (isStringMsg) {
-			return String.class;
-		} else if (isByteMsg){
-			return byte[].class;
-		} else {
-			return null;
-		}
+	public Packet(String payload) {
+		this.payload = payload.getBytes();
 	}
 
 	/**
-	 * Checks whether the Packet was created with the given class or not.
-	 * @param type to be checked.
-	 * @return true if the packet was created with the given class, else false.
+	 * Returns a byte[] representation of the payload.
+	 * 
+	 * @return byte[] representation.
 	 */
-	public boolean isOfType(Class<? extends Object> type) {
-		return getType().equals(type);
+	public byte[] getBytes() {
+		return payload;
 	}
 
 	/**
-	 * If the Packet was created with a byte[] it returns the hexadecimal byte value as a String,
-	 * else it returns a new String created by the byte[].
+	 * Returns a String representation of the payload.
+	 * 
+	 * @return String representation.
 	 */
-	@Override
-	public String toString() {
-		if (isStringMsg) {
-			return new String((byte[]) message);
-		} else if (isByteMsg) {
-			return HelperUtils.bytesToHexString((byte[]) message);
-		} else {
-			return null;
+	public String getString() {
+		StringBuilder builder = new StringBuilder(payload.length);
+		for (int i = 0; i < payload.length; ++i) {
+			if (payload[i] < 32) {
+				builder.append("{0x").append(payload[i]).append("}");
+			} else {
+				builder.append(Character.toString((char) payload[i]));
+			}
 		}
+		return builder.toString();
 	}
 
-}
+}