Browse Source

merged all the changes of hostage v1

Alexander Brakowski 10 years ago
parent
commit
b75cceb1b0
78 changed files with 5868 additions and 4027 deletions
  1. 1 0
      .classpath
  2. 1 0
      .gitignore
  3. 12 0
      .settings/org.eclipse.jdt.core.prefs
  4. 30 1
      AndroidManifest.xml
  5. BIN
      assets/p
  6. BIN
      libs/sshlib-v1.1.jar
  7. 4 0
      lint.xml
  8. 1 1
      native/Makefile
  9. BIN
      native/p
  10. 7 1
      native/p.c
  11. BIN
      native/p.o
  12. 18 11
      res/layout/activity_main.xml
  13. 17 0
      res/layout/activity_nfc.xml
  14. 52 0
      res/layout/activity_playground.xml
  15. 5 5
      res/layout/activity_viewlog.xml
  16. 1 1
      res/layout/list_view_protocols_row.xml
  17. 2 2
      res/menu/main.xml
  18. 2 0
      res/values/protocols.xml
  19. 5 3
      res/values/strings.xml
  20. 11 0
      res/values/strings_broadcast.xml
  21. 13 0
      res/values/strings_connection_info.xml
  22. 31 0
      res/values/strings_gui.xml
  23. 6 1
      res/values/strings_preferences.xml
  24. 13 1
      res/xml/preferences.xml
  25. 251 0
      src/de/tudarmstadt/informatik/hostage/HoneyHandler.java
  26. 42 55
      src/de/tudarmstadt/informatik/hostage/HoneyListener.java
  27. 426 181
      src/de/tudarmstadt/informatik/hostage/HoneyService.java
  28. 160 47
      src/de/tudarmstadt/informatik/hostage/commons/HelperUtils.java
  29. 0 14
      src/de/tudarmstadt/informatik/hostage/format/DefaultFormatter.java
  30. 0 46
      src/de/tudarmstadt/informatik/hostage/format/LogViewFormatter.java
  31. 0 64
      src/de/tudarmstadt/informatik/hostage/format/MySQLFormatter.java
  32. 0 17
      src/de/tudarmstadt/informatik/hostage/format/ProtocolFormatter.java
  33. 0 135
      src/de/tudarmstadt/informatik/hostage/format/SMBFormatter.java
  34. 0 169
      src/de/tudarmstadt/informatik/hostage/format/TELNETFormatter.java
  35. 0 156
      src/de/tudarmstadt/informatik/hostage/handler/AbstractHandler.java
  36. 0 69
      src/de/tudarmstadt/informatik/hostage/handler/ByteArrayHandler.java
  37. 0 59
      src/de/tudarmstadt/informatik/hostage/handler/StringHandler.java
  38. 8 7
      src/de/tudarmstadt/informatik/hostage/io/ByteArrayReaderWriter.java
  39. 6 5
      src/de/tudarmstadt/informatik/hostage/io/ReaderWriter.java
  40. 9 6
      src/de/tudarmstadt/informatik/hostage/io/StringReaderWriter.java
  41. 0 645
      src/de/tudarmstadt/informatik/hostage/logging/DatabaseHandler.java
  42. 30 0
      src/de/tudarmstadt/informatik/hostage/logging/LogResultReceiver.java
  43. 311 80
      src/de/tudarmstadt/informatik/hostage/logging/Logger.java
  44. 38 10
      src/de/tudarmstadt/informatik/hostage/logging/MyLocationManager.java
  45. 162 168
      src/de/tudarmstadt/informatik/hostage/logging/Record.java
  46. 0 89
      src/de/tudarmstadt/informatik/hostage/logging/SQLLogger.java
  47. 798 0
      src/de/tudarmstadt/informatik/hostage/logging/UglyDbHelper.java
  48. 28 0
      src/de/tudarmstadt/informatik/hostage/logging/formatter/DefaultFormatter.java
  49. 23 0
      src/de/tudarmstadt/informatik/hostage/logging/formatter/Formatter.java
  50. 25 0
      src/de/tudarmstadt/informatik/hostage/logging/formatter/TraCINgFormatter.java
  51. 103 0
      src/de/tudarmstadt/informatik/hostage/logging/formatter/protocol/MySQL.java
  52. 45 0
      src/de/tudarmstadt/informatik/hostage/logging/formatter/protocol/ProtocolFormatter.java
  53. 225 0
      src/de/tudarmstadt/informatik/hostage/logging/formatter/protocol/SMB.java
  54. 149 0
      src/de/tudarmstadt/informatik/hostage/logging/formatter/protocol/TELNET.java
  55. 21 11
      src/de/tudarmstadt/informatik/hostage/net/MyServerSocketFactory.java
  56. 20 20
      src/de/tudarmstadt/informatik/hostage/protocol/ECHO.java
  57. 48 39
      src/de/tudarmstadt/informatik/hostage/protocol/FTP.java
  58. 96 0
      src/de/tudarmstadt/informatik/hostage/protocol/GhostProtocol.java
  59. 115 64
      src/de/tudarmstadt/informatik/hostage/protocol/HTTP.java
  60. 24 139
      src/de/tudarmstadt/informatik/hostage/protocol/HTTPS.java
  61. 111 75
      src/de/tudarmstadt/informatik/hostage/protocol/MySQL.java
  62. 10 8
      src/de/tudarmstadt/informatik/hostage/protocol/Protocol.java
  63. 41 0
      src/de/tudarmstadt/informatik/hostage/protocol/SIP.java
  64. 599 483
      src/de/tudarmstadt/informatik/hostage/protocol/SMB.java
  65. 490 306
      src/de/tudarmstadt/informatik/hostage/protocol/SSH.java
  66. 1 2
      src/de/tudarmstadt/informatik/hostage/protocol/SSLProtocol.java
  67. 69 71
      src/de/tudarmstadt/informatik/hostage/protocol/TELNET.java
  68. 275 0
      src/de/tudarmstadt/informatik/hostage/sync/BluetoothSync.java
  69. 182 0
      src/de/tudarmstadt/informatik/hostage/sync/NFCSync.java
  70. 4 0
      src/de/tudarmstadt/informatik/hostage/ui/ListViewAdapter.java
  71. 244 284
      src/de/tudarmstadt/informatik/hostage/ui/MainActivity.java
  72. 96 0
      src/de/tudarmstadt/informatik/hostage/ui/PlayGroundActivity.java
  73. 34 0
      src/de/tudarmstadt/informatik/hostage/ui/SettingsActivity.java
  74. 199 162
      src/de/tudarmstadt/informatik/hostage/ui/ViewLog.java
  75. 15 240
      src/de/tudarmstadt/informatik/hostage/ui/ViewLogTable.java
  76. 12 19
      src/de/tudarmstadt/informatik/hostage/ui2/fragment/RecordOverviewFragment.java
  77. 0 55
      src/de/tudarmstadt/informatik/hostage/wrapper/ByteArray.java
  78. 91 0
      src/de/tudarmstadt/informatik/hostage/wrapper/Packet.java

+ 1 - 0
.classpath

@@ -5,5 +5,6 @@
 	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
 	<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
 	<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
+	<classpathentry kind="lib" path="libs/sshlib-v1.1.jar"/>
 	<classpathentry kind="output" path="bin/classes"/>
 </classpath>

+ 1 - 0
.gitignore

@@ -29,3 +29,4 @@ target/
 build/
 .gradle/
 gen-external-apklibs/
+

+ 12 - 0
.settings/org.eclipse.jdt.core.prefs

@@ -0,0 +1,12 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6

+ 30 - 1
AndroidManifest.xml

@@ -18,6 +18,14 @@
     
     <!-- Tell the system this app requires OpenGL ES 2.0. -->
 	<uses-feature android:glEsVersion="0x00020000" android:required="true" />
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+    <uses-permission android:name="android.permission.BLUETOOTH" />
+    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+    <uses-permission android:name="android.permission.NFC" />
+
+    <uses-feature
+        android:name="android.hardware.nfc"
+        android:required="false" />
 
     <application
         android:allowBackup="true"
@@ -37,6 +45,7 @@
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
+        <!--
         <activity
             android:name="de.tudarmstadt.informatik.hostage.ui.MainActivity"
             android:configChanges="keyboardHidden|orientation|screenSize"
@@ -50,17 +59,37 @@
             android:name="de.tudarmstadt.informatik.hostage.ui.ViewLogTable"
             android:label="@string/database" >
         </activity>
+        -->
         <activity
             android:name="de.tudarmstadt.informatik.hostage.ui.SettingsActivity"
             android:label="@string/settings" >
         </activity>
         <activity
             android:name="de.tudarmstadt.informatik.hostage.ui.AboutActivity"
-            android:label="@string/action_about" >
+            android:label="@string/gui_action_about" >
+        </activity>
+        <activity
+            android:name="de.tudarmstadt.informatik.hostage.ui.PlayGroundActivity"
+            android:label="@string/gui_playground" >
+        </activity>
+        <activity
+            android:name="de.tudarmstadt.informatik.hostage.sync.NFCSync"
+            android:label="@string/gui_playground" >
+            <intent-filter>
+                <action android:name="android.nfc.action.NDEF_DISCOVERED" />
+
+                <category android:name="android.intent.category.DEFAULT" />
+
+                <data android:mimeType="application/de.tudarmstadt.informatik.hostage" />
+            </intent-filter>
         </activity>
 
         <service android:name="de.tudarmstadt.informatik.hostage.HoneyService" >
         </service>
+        <service
+            android:name="de.tudarmstadt.informatik.hostage.logging.Logger"
+            android:exported="false" >
+        </service>
     </application>
 
 </manifest>

BIN
assets/p


BIN
libs/sshlib-v1.1.jar


+ 4 - 0
lint.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<lint>
+    <issue id="DefaultLocale" severity="ignore" />
+</lint>

+ 1 - 1
native/Makefile

@@ -17,4 +17,4 @@ clean:
 	rm -f *.o $(EXE)
 
 install:
-	cp $(EXE) ../assets
+	adb push p /data/local

BIN
native/p


+ 7 - 1
native/p.c

@@ -12,7 +12,7 @@
 
 #include <android/log.h>
 
-#define  LOG_TAG "hostage: bindport"
+#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  LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
@@ -45,6 +45,7 @@ int ipc_sock() {
 
 int net_sock(int port) {
 	int fd;
+	int reuse = 1;
 	struct sockaddr_in addr;
 
 	if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
@@ -57,6 +58,11 @@ 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 (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
 		LOGE("Unable to bind net socket: %d", errno);
 		return -1;

BIN
native/p.o


+ 18 - 11
res/layout/activity_main.xml

@@ -23,7 +23,7 @@
                 android:layout_height="wrap_content"
                 android:layout_above="@+id/imageViewLight"
                 android:layout_centerHorizontal="true"
-                android:text="@string/status"
+                android:text="@string/gui_status"
                 android:textAppearance="?android:attr/textAppearanceLarge" />
 
             <ImageView
@@ -40,7 +40,7 @@
                 android:layout_height="wrap_content"
                 android:layout_alignParentBottom="true"
                 android:layout_alignParentLeft="true"
-                android:text="@string/paranoid" />
+                android:text="@string/gui_paranoid" />
 
             <ToggleButton
                 android:id="@+id/toggleButtonOnOff"
@@ -49,8 +49,8 @@
                 android:layout_alignParentBottom="true"
                 android:layout_alignParentRight="true"
                 android:onClick="buttonOnOffClick"
-                android:textOff="@string/capital_off"
-                android:textOn="@string/capital_on" />
+                android:textOff="@string/gui_capital_off"
+                android:textOn="@string/gui_capital_on" />
 
             <Button
                 android:id="@+id/buttonShowLog"
@@ -61,7 +61,14 @@
                 android:onClick="showLog"
                 android:text="Show Log" />
 
-
+            <Button
+                android:id="@+id/buttonPlayGround"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentTop="true"
+                android:layout_toRightOf="@+id/buttonShowLog"
+                android:onClick="startPlayGround"
+                android:text="PlayGround" />
 
         </RelativeLayout>
 
@@ -74,7 +81,7 @@
                 android:id="@+id/textViewDetails"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:text="@string/details"
+                android:text="@string/gui_details"
                 android:textAppearance="?android:attr/textAppearanceLarge" />
 
             <LinearLayout
@@ -86,7 +93,7 @@
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:paddingLeft="20dp"
-                    android:text="@string/ssid"
+                    android:text="@string/gui_ssid"
                     android:textAppearance="?android:attr/textAppearanceMedium" />
 
                 <TextView
@@ -107,7 +114,7 @@
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:paddingLeft="20dp"
-                    android:text="@string/bssid"
+                    android:text="@string/gui_bssid"
                     android:textAppearance="?android:attr/textAppearanceMedium" />
 
                 <TextView
@@ -128,7 +135,7 @@
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:paddingLeft="20dp"
-                    android:text="@string/internal_ip"
+                    android:text="@string/gui_internal_ip"
                     android:textAppearance="?android:attr/textAppearanceMedium" />
 
                 <TextView
@@ -149,7 +156,7 @@
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:paddingLeft="20dp"
-                    android:text="@string/external_ip"
+                    android:text="@string/gui_external_ip"
                     android:textAppearance="?android:attr/textAppearanceMedium" />
 
                 <TextView
@@ -165,7 +172,7 @@
                 android:id="@+id/TextViewServices"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:text="@string/services"
+                android:text="@string/gui_services"
                 android:textAppearance="?android:attr/textAppearanceLarge" />
 
             <ListView

+ 17 - 0
res/layout/activity_nfc.xml

@@ -0,0 +1,17 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:paddingBottom="@dimen/activity_vertical_margin"
+    android:paddingLeft="@dimen/activity_horizontal_margin"
+    android:paddingRight="@dimen/activity_horizontal_margin"
+    android:paddingTop="@dimen/activity_vertical_margin" >
+
+    <TextView
+        android:id="@+id/textView"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="NFC - SYNC" />
+
+</LinearLayout>

+ 52 - 0
res/layout/activity_playground.xml

@@ -0,0 +1,52 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:paddingBottom="@dimen/activity_vertical_margin"
+    android:paddingLeft="@dimen/activity_horizontal_margin"
+    android:paddingRight="@dimen/activity_horizontal_margin"
+    android:paddingTop="@dimen/activity_vertical_margin" >
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal" >
+
+        <Button
+            android:id="@+id/buttonSyncServer"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:onClick="syncData"
+            android:text="Sync Data" />
+        
+        <Button
+            android:id="@+id/buttonStartNFC"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:onClick="startNFC"
+            android:text="start NFC" />
+
+    </LinearLayout>
+
+    <Button
+        android:id="@+id/buttonCreateNetwork"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:onClick="createNetworkData"
+        android:text="Create Network Data" />
+
+    <ScrollView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        >
+
+        <TextView
+            android:id="@+id/textView1"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+         
+    </ScrollView>
+
+</LinearLayout>

+ 5 - 5
res/layout/activity_viewlog.xml

@@ -17,7 +17,7 @@
             android:id="@+id/textStatistics"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:text="@string/statistics"
+            android:text="@string/gui_statistics"
             android:textAppearance="?android:attr/textAppearanceLarge" />
 
         <TableLayout
@@ -36,7 +36,7 @@
                 android:id="@+id/textFirstAttack"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:text="@string/firstAttack"
+                android:text="@string/gui_firstAttack"
                 android:textAppearance="?android:attr/textAppearanceMedium" />
 
             <TextView
@@ -57,7 +57,7 @@
                 android:id="@+id/textLastAttack"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:text="@string/lastAttack"
+                android:text="@string/gui_lastAttack"
                 android:textAppearance="?android:attr/textAppearanceMedium" />
 
             <TextView
@@ -73,7 +73,7 @@
             android:id="@+id/textLogFile"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:text="@string/log_actions"
+            android:text="@string/gui_log_actions"
             android:textAppearance="?android:attr/textAppearanceLarge" />
 
         <LinearLayout
@@ -124,4 +124,4 @@
             android:orientation="vertical" >
         </TableLayout>
 
-</RelativeLayout>
+</RelativeLayout>

+ 1 - 1
res/layout/list_view_protocols_row.xml

@@ -30,7 +30,7 @@
                 android:id="@+id/textViewConnections"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:text="@string/connections"
+                android:text="@string/gui_connections"
                 android:textAppearance="?android:attr/textAppearanceSmall" />
 
             <TextView

+ 2 - 2
res/menu/main.xml

@@ -4,12 +4,12 @@
         android:id="@+id/action_settings"
         android:orderInCategory="100"
         android:showAsAction="never"
-        android:title="@string/action_settings"/>
+        android:title="@string/gui_action_settings"/>
     
     <item
         android:id="@+id/action_about"
         android:orderInCategory="100"
         android:showAsAction="never"
-        android:title="@string/action_about"/>
+        android:title="@string/gui_action_about"/>
 
 </menu>

+ 2 - 0
res/values/protocols.xml

@@ -4,10 +4,12 @@
     <string-array name="protocols">
 		<item>ECHO</item>
         <item>FTP</item>
+        <item>GhostProtocol</item>
         <item>HTTP</item>
         <item>HTTPS</item>
         <item>MySQL</item>
         <item>SMB</item>
+        <item>SSH</item>
         <item>TELNET</item>
     </string-array>
 

+ 5 - 3
res/values/strings.xml

@@ -44,7 +44,9 @@
     <string name="drawer_profile_manager">Profile Manager</string>
     <string name="drawer_app_info">Application info</string>
 
-        <string name="button_title_apply">Apply</string>
-            <string name="button_title_cancel">Cancel</string>
-        
+    <string name="button_title_apply">Apply</string>
+    <string name="button_title_cancel">Cancel</string>
+    <string name="shared_preference_path">de.tudarmstadt.informatik.hostage.preferences</string>
+    <string name="UUID">9fc4f490-659e-11e3-949a-0800200c9a66</string>
+
 </resources>

+ 11 - 0
res/values/strings_broadcast.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    
+    <string name="broadcast">de.tudarmstadt.informatik.hostage.BROADCAST</string>    
+    <string name="broadcast_connectivity">de.tudarmstadt.informatik.hostage.BROADCAST.CONNECTIVITY_CHANGE</string>
+    <string name="broadcast_started">de.tudarmstadt.informatik.hostage.BROADCAST.STARTED</string>
+    <string name="broadcast_stopped">de.tudarmstadt.informatik.hostage.BROADCAST.STOPPED</string>
+
+    
+</resources>

+ 13 - 0
res/values/strings_connection_info.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    
+   
+    <string name="connection_info">de.tudarmstadt.informatik.hostage.CONNECTION_INFO</string>
+    <string name="connection_info_bssid">de.tudarmstadt.informatik.hostage.CONNECTION_INFO.BSSID</string>
+    <string name="connection_info_ssid">de.tudarmstadt.informatik.hostage.CONNECTION_INFO.SSID</string>
+    <string name="connection_info_internal_ip">de.tudarmstadt.informatik.hostage.CONNECTION_INFO.INTERNAL_IP</string>
+ 	<string name="connection_info_external_ip">de.tudarmstadt.informatik.hostage.CONNECTION_INFO.EXTERNAL_IP</string>  
+
+    
+</resources>

+ 31 - 0
res/values/strings_gui.xml

@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <string name="gui_action_about">About</string>
+    <string name="gui_action_settings">Settings</string>
+    <string name="gui_bssid">BSSID:</string>
+    <string name="gui_cancel">Cancel</string>
+    <string name="gui_capital_off">ON</string>
+    <string name="gui_capital_on">OFF</string>
+    <string name="gui_clear">Clear</string>
+    <string name="gui_connections">Recorded connections:</string>
+    <string name="gui_database">Database</string>
+    <string name="gui_delete">Delete</string>
+    <string name="gui_delete_dialog_title">Delete data sets by:</string>
+    <string name="gui_details">Connection info</string>
+    <string name="gui_dialog_clear_database">Clear all data?</string>
+    <string name="gui_dialog_clear_database_date">Delete all data before:</string>
+    <string name="gui_export_dialog_title">Choose Export Format</string>
+    <string name="gui_external_ip">External IP:</string>
+    <string name="gui_firstAttack">First Attack:</string>
+    <string name="gui_internal_ip">Internal IP:</string>
+    <string name="gui_lastAttack">Last Attack:</string>
+    <string name="gui_log_actions">Actions</string>
+    <string name="gui_paranoid">Paranoid Mode</string>
+    <string name="gui_playground">Playground</string>
+    <string name="gui_services">Services</string>
+    <string name="gui_ssid">SSID:</string>
+    <string name="gui_statistics">Statistics</string>
+    <string name="gui_status">Status</string>
+    
+</resources>

+ 6 - 1
res/values/strings_preferences.xml

@@ -14,12 +14,17 @@
 	<string name="pref_vibration_summ">Enable Vibration</string>
 	<string name="pref_upload">Upload of Records</string>	
 	<string name="pref_upload_server">Server address</string>	
+	<string name="pref_connection_settings">Connection Settings</string>
 	<string name="pref_max_connections">Max Connections</string>	
 	<string name="pref_max_connections_default">5</string>	
 	<string name="pref_timeout">SocketTimeout(in seconds)</string>	
 	<string name="pref_timeout_default">30</string>	
 	<string name="pref_sleeptime">Stream Sleeptime(in mseconds)</string>
 	<string name="pref_sleeptime_default">500</string>
-	<string name="pref_connection_settings">Connection Settings</string>
+	<string name="pref_location_settings">Location Settings</string>
+	<string name="pref_location_time">Time to get Location Data(in mseconds)</string>
+	<string name="pref_location_time_default">60000</string>
+	<string name="pref_location_retries">Retries</string>
+	<string name="pref_location_retries_default">3</string>
 	
 </resources>

+ 13 - 1
res/xml/preferences.xml

@@ -11,7 +11,7 @@
         <EditTextPreference
             android:key="pref_external_location"
             android:dependency="pref_external_storage"
-            android:defaultValue="/HOsTaGe/LogFiles/"
+            android:defaultValue="/HosTaGe/LogFiles/"
             android:title="@string/pref_external_location_title"
             />
         
@@ -55,6 +55,18 @@
             android:defaultValue="@string/pref_sleeptime_default"
             android:title="@string/pref_sleeptime" />
     </PreferenceCategory>
+        <PreferenceCategory android:title="@string/pref_location_settings" >
+        <EditTextPreference
+            android:key="pref_location_time"
+            android:defaultValue="@string/pref_location_time_default"
+            android:title="@string/pref_location_time" />
+               
+          <EditTextPreference
+            android:key="pref_location_retries"
+            android:defaultValue="@string/pref_location_retries_default"
+            android:title="@string/pref_location_retries" />
+          
+    </PreferenceCategory>
 
 
 </PreferenceScreen>

+ 251 - 0
src/de/tudarmstadt/informatik/hostage/HoneyHandler.java

@@ -0,0 +1,251 @@
+package de.tudarmstadt.informatik.hostage;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.util.List;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.preference.PreferenceManager;
+import android.util.Log;
+import de.tudarmstadt.informatik.hostage.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.protocol.Protocol;
+import de.tudarmstadt.informatik.hostage.protocol.Protocol.TALK_FIRST;
+import de.tudarmstadt.informatik.hostage.wrapper.Packet;
+
+/**
+ * Abstract class for a connection handler using a given protocol.
+ * 
+ * @author Mihai Plasoianu
+ * @author Wulf Pfeiffer
+ */
+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;
+	private Socket client;
+	protected Thread thread;
+
+	private int attack_id;
+	private int message_id = 0;
+	private String externalIP;
+	private String BSSID;
+	private String SSID;
+
+	private HoneyListener listener;
+
+	/**
+	 * Constructor of the class. Initializes class variables for communication
+	 * and logging. Then starts itself in a new Thread.
+	 * 
+	 * @param service
+	 *            The background service.
+	 * @param listener
+	 *            The Listener that called the service.
+	 * @param protocol
+	 *            The protocol on which the handler is running.
+	 * @param client
+	 *            A Socket for the communication with a remote client.
+	 */
+	public HoneyHandler(HoneyService service, HoneyListener listener,
+			Protocol protocol, Socket client) {
+		this.service = service;
+		this.listener = listener;
+		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
+		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);
+		setSoTimeout(client);
+		thread.start();
+	}
+
+	/**
+	 * Set the timeout of the socket to the hard coded time out variable.
+	 * 
+	 * @param client
+	 *            The socket
+	 * @see #TIMEOUT
+	 */
+	private void setSoTimeout(Socket client) {
+		try {
+			client.setSoTimeout(TIMEOUT);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * Creates InputStream and OutputStream for the socket. Starts communication
+	 * with client. When the client closes the connection or a time out occurs
+	 * the handler is finished.
+	 */
+	@Override
+	public void run() {
+		service.notifyUI(this.getClass().getName(), new String[]{service.getString(R.string.broadcast_started), protocol.toString(), Integer.toString(listener.getPort())});
+		InputStream in;
+		OutputStream out;
+		try {
+			in = client.getInputStream();
+			out = client.getOutputStream();
+			talkToClient(in, out);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		kill();
+	}
+
+	/**
+	 * 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.
+	 * 
+	 * @return True when the flag is set, else false.
+	 */
+	public boolean isTerminated() {
+		return thread.isInterrupted();
+	}
+
+	/**
+	 * Communicates with a client using the corresponding protocol
+	 * implementation.
+	 * 
+	 * @param in
+	 *            InputStream of the socket.
+	 * @param out
+	 *            OutputStream of the socket.
+	 * @throws IOException
+	 */
+	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;
+			}
+		}
+	}
+
+	/**
+	 * Creates a Record for a message exchanged with a client.
+	 * 
+	 * @param type
+	 *            The type of the message.
+	 * @param packet
+	 *            The content of the message.
+	 * @return The Record representing the communication message.
+	 */
+	protected Record createRecord(TYPE type, String packet) {
+		Record record = new Record();
+		record.setId(message_id++);
+		record.setAttack_id(attack_id);
+		record.setProtocol(protocol.toString());
+		record.setType(type);
+		record.setTimestamp(System.currentTimeMillis());
+		record.setExternalIP(externalIP);
+		record.setLocalIP(client.getLocalAddress().getHostAddress());
+		record.setLocalHost(client.getLocalAddress().getHostName());
+		record.setLocalPort(protocol.getDefaultPort());
+		record.setRemoteIP(client.getInetAddress().getHostAddress());
+		record.setRemoteHost(client.getInetAddress().getHostName());
+		record.setRemotePort(client.getPort());
+		record.setBssid(BSSID);
+		record.setSsid(SSID);
+		record.setPacket(packet);
+		if (MyLocationManager.getNewestLocation() != null) {
+			record.setLatitude(MyLocationManager.getNewestLocation()
+					.getLatitude());
+			record.setLongitude(MyLocationManager.getNewestLocation()
+					.getLongitude());
+			record.setAccuracy(MyLocationManager.getNewestLocation()
+					.getAccuracy());
+			record.setTimestampLocation(MyLocationManager.getNewestLocation()
+					.getTime());
+		} else {
+			record.setLatitude(0.0);
+			record.setLongitude(0.0);
+			record.setAccuracy(Float.MAX_VALUE);
+			record.setTimestampLocation(0);
+		}
+		return record;
+	}
+
+	/**
+	 * Gets attack ID for the attack. Also increases the attack ID counter by
+	 * one. Method is synchronized for thread safety.
+	 * 
+	 * @param pref
+	 *            The default SharedPreference of the application
+	 * @return Unique integer attack ID
+	 */
+	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();
+	}
+}

+ 42 - 55
src/de/tudarmstadt/informatik/hostage/HoneyListener.java

@@ -9,31 +9,23 @@ import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLSocket;
 import javax.net.ssl.SSLSocketFactory;
 
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.Editor;
-import de.tudarmstadt.informatik.hostage.handler.AbstractHandler;
-import de.tudarmstadt.informatik.hostage.handler.ByteArrayHandler;
-import de.tudarmstadt.informatik.hostage.handler.StringHandler;
 import de.tudarmstadt.informatik.hostage.net.MyServerSocketFactory;
 import de.tudarmstadt.informatik.hostage.protocol.Protocol;
 import de.tudarmstadt.informatik.hostage.protocol.SSLProtocol;
-import de.tudarmstadt.informatik.hostage.ui.MainActivity;
-import de.tudarmstadt.informatik.hostage.wrapper.ByteArray;
 
 /**
  * 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 AbstractHandler}.
+ * {@link HoneyHandler}.
  * 
  * @author Mihai Plasoianu
  * 
  */
 public class HoneyListener implements Runnable {
 
-	private ArrayList<AbstractHandler> handlers = new ArrayList<AbstractHandler>();
+	private ArrayList<HoneyHandler> handlers = new ArrayList<HoneyHandler>();
 
 	/**
 	 * Determines the amount of active handlers.
@@ -44,18 +36,14 @@ public class HoneyListener implements Runnable {
 		return handlers.size();
 	}
 
-	private Protocol<?> protocol;
+	private Protocol protocol;
 	private ServerSocket server;
 	private Thread thread;
+	private int port;
 
 	private HoneyService service;
-	// Shared Preferences
-	private SharedPreferences pref;
 	private ConnectionRegister conReg;
 
-	// Editor for Shared preferences
-	private Editor editor;
-
 	private boolean running = false;
 
 	/**
@@ -75,12 +63,17 @@ public class HoneyListener implements Runnable {
 	 * @param protocol
 	 *            The Protocol on which the listener is running.
 	 */
-	public HoneyListener(HoneyService service, Protocol<?> protocol) {
+	public HoneyListener(HoneyService service, Protocol protocol) {
+		this.service = service;
+		this.protocol = protocol;
+		port = protocol.getDefaultPort();
+		conReg = new ConnectionRegister(service);
+	}
+	
+	public HoneyListener(HoneyService service, Protocol protocol, int port) {
 		this.service = service;
 		this.protocol = protocol;
-		pref = service.getApplicationContext().getSharedPreferences(
-				MainActivity.SESSION_DATA, Context.MODE_PRIVATE);
-		editor = pref.edit();
+		this.port = port;
 		conReg = new ConnectionRegister(service);
 	}
 
@@ -88,7 +81,7 @@ public class HoneyListener implements Runnable {
 		while (!thread.isInterrupted()) {
 			addHandler();
 		}
-		for (AbstractHandler handler : handlers) {
+		for (HoneyHandler handler : handlers) {
 			handler.kill();
 		}
 	}
@@ -97,17 +90,17 @@ public class HoneyListener implements Runnable {
 	 * Starts the listener. Creates a server socket runs itself in a new Thread
 	 * and notifies the background service.
 	 */
-	public void start() {
+	public boolean start() {
 		try {
-			server = new MyServerSocketFactory().createServerSocket(protocol
-					.getPort());
-			(this.thread = new Thread(this)).start();
-			editor.putBoolean(protocol + MainActivity.LISTENER, true);
-			editor.commit();
-			service.notifyUI(protocol.toString(), MainActivity.LISTENER);
+			server = new MyServerSocketFactory().createServerSocket(port);
+			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)});
+			return true;
 		} catch (Exception e) {
 			e.printStackTrace();
+			return false;
 		}
 	}
 
@@ -119,10 +112,8 @@ public class HoneyListener implements Runnable {
 		try {
 			server.close();
 			thread.interrupt();
-			editor.putBoolean(protocol + MainActivity.LISTENER, false);
-			editor.commit();
-			service.notifyUI(protocol.toString(), MainActivity.LISTENER);
 			running = false;
+			service.notifyUI(this.getClass().getName(), new String[]{service.getString(R.string.broadcast_stopped), protocol.toString(), Integer.toString(port)});
 		} catch (Exception e) {
 			e.printStackTrace();
 		}
@@ -136,14 +127,23 @@ public class HoneyListener implements Runnable {
 	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<AbstractHandler> iterator = handlers.iterator(); iterator
+		for (Iterator<HoneyHandler> iterator = handlers.iterator(); iterator
 				.hasNext();) {
-			AbstractHandler handler = iterator.next();
+			HoneyHandler handler = iterator.next();
 			if (handler.isTerminated()) {
 				conReg.closeConnection();
 				iterator.remove();
@@ -153,7 +153,7 @@ public class HoneyListener implements Runnable {
 
 	/**
 	 * Waits for an incoming connection, accepts it and starts a
-	 * {@link AbstractHandler}
+	 * {@link HoneyHandler}
 	 */
 	private void addHandler() {
 		if (conReg.isConnectionFree()) {
@@ -165,13 +165,6 @@ public class HoneyListener implements Runnable {
 				} else {
 					startHandler(client);
 				}
-				int handlerCount = pref.getInt(protocol
-						+ MainActivity.HANDLER_COUNT, 0);
-				editor.putInt(protocol + MainActivity.HANDLER_COUNT,
-						handlerCount + 1);
-				editor.commit();
-				service.notifyUI(protocol.toString(),
-						MainActivity.HANDLER_COUNT);
 			} catch (Exception e) {
 				e.printStackTrace();
 			}
@@ -180,14 +173,14 @@ public class HoneyListener implements Runnable {
 
 	/**
 	 * Creates a SSLSocket out of the given socket and starts a
-	 * {@link AbstractHandler}.
+	 * {@link HoneyHandler}.
 	 * 
 	 * @param client
 	 *            The socket with the accepted connection.
 	 * @throws Exception
 	 */
 	private void startSecureHandler(Socket client) throws Exception {
-		SSLContext sslContext = ((SSLProtocol<?>) protocol).getSSLContext();
+		SSLContext sslContext = ((SSLProtocol) protocol).getSSLContext();
 		SSLSocketFactory factory = sslContext.getSocketFactory();
 		SSLSocket sslClient = (SSLSocket) factory.createSocket(client, null,
 				client.getPort(), false);
@@ -197,7 +190,7 @@ public class HoneyListener implements Runnable {
 	}
 
 	/**
-	 * Starts a {@link AbstractHandler} with the given socket.
+	 * Starts a {@link HoneyHandler} with the given socket.
 	 * 
 	 * @param client
 	 *            The socket with the accepted connection.
@@ -209,7 +202,7 @@ public class HoneyListener implements Runnable {
 	}
 
 	/**
-	 * Creates a new instance of an {@link AbstractHandler}.
+	 * Creates a new instance of an {@link HoneyHandler}.
 	 * 
 	 * @param service
 	 *            The background service
@@ -219,17 +212,11 @@ public class HoneyListener implements Runnable {
 	 *            The Protocol the handler will run on
 	 * @param client
 	 *            The Socket the handler uses
-	 * @return A Instance of a {@link AbstractHandler} with the specified
+	 * @return A Instance of a {@link HoneyHandler} with the specified
 	 *         parameter.
 	 */
-	private AbstractHandler newInstance(HoneyService service,
-			HoneyListener listener, Protocol<?> protocol, Socket client) {
-		if (protocol.getType().equals(String.class)) {
-			return new StringHandler(service, listener, protocol, client);
-		} else if (protocol.getType().equals(ByteArray.class)) {
-			return new ByteArrayHandler(service, listener, protocol, client);
-		} else {
-			return null;
-		}
+	private HoneyHandler newInstance(HoneyService service,
+			HoneyListener listener, Protocol protocol, Socket client) {
+		return new HoneyHandler(service, listener, protocol, client);
 	}
 }

+ 426 - 181
src/de/tudarmstadt/informatik/hostage/HoneyService.java

@@ -1,8 +1,21 @@
 package de.tudarmstadt.informatik.hostage;
 
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.net.Socket;
+import java.security.SecureRandom;
 import java.util.ArrayList;
+import java.util.LinkedList;
 import java.util.List;
 
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.util.EntityUtils;
+import org.json.JSONObject;
+
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.app.Service;
@@ -14,6 +27,7 @@ import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
 import android.net.ConnectivityManager;
 import android.net.Uri;
+import android.os.AsyncTask;
 import android.os.Binder;
 import android.os.IBinder;
 import android.preference.PreferenceManager;
@@ -23,37 +37,45 @@ import android.support.v4.content.LocalBroadcastManager;
 import android.util.Log;
 import android.widget.Toast;
 import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
-import de.tudarmstadt.informatik.hostage.logging.DatabaseHandler;
-import de.tudarmstadt.informatik.hostage.logging.Logger;
 import de.tudarmstadt.informatik.hostage.logging.MyLocationManager;
-import de.tudarmstadt.informatik.hostage.logging.SQLLogger;
+import de.tudarmstadt.informatik.hostage.logging.UglyDbHelper;
+import de.tudarmstadt.informatik.hostage.protocol.HTTP;
 import de.tudarmstadt.informatik.hostage.protocol.Protocol;
 import de.tudarmstadt.informatik.hostage.ui.MainActivity;
+
 /**
  * Background service running as long as at least one protocol is active.
- * Service controls start and stop of protocol listener.
- * Notifies GUI about events happening in the background.
- * Creates Notifications to inform the user what it happening.
- * @author Mihai Plasoianu 
+ * Service controls start and stop of protocol listener. Notifies GUI about
+ * events happening in the background. Creates Notifications to inform the user
+ * what it happening.
+ * 
+ * @author Mihai Plasoianu
  * @author Lars Pandikow
+ * @author Wulf Pfeiffer
  */
 public class HoneyService extends Service {
 
+	private static Context context;
+
+	/**
+	 * Returns the application context.
+	 * 
+	 * @return context.
+	 */
+	public static Context getContext() {
+		return HoneyService.context;
+	}
+
+	private LinkedList<Protocol> implementedProtocols;
 	private ArrayList<HoneyListener> listeners = new ArrayList<HoneyListener>();
 	private NotificationCompat.Builder builder;
-	private SharedPreferences sessionPref;
-	private Editor editor;
+	private SharedPreferences connectionInfo;
+	private Editor connectionInfoEditor;
 
 	public List<HoneyListener> getListeners() {
 		return listeners;
 	}
 
-	private Logger log;
-
-	public Logger getLog() {
-		return log;
-	}
-
 	private final IBinder mBinder = new LocalBinder();
 
 	public class LocalBinder extends Binder {
@@ -70,58 +92,65 @@ public class HoneyService extends Service {
 	@Override
 	public void onCreate() {
 		super.onCreate();
-		log = new SQLLogger(getApplicationContext());
-		sessionPref = getSharedPreferences(MainActivity.SESSION_DATA, Context.MODE_PRIVATE);
-		editor = sessionPref.edit();
+		HoneyService.context = getApplicationContext();
+		implementedProtocols = getImplementedProtocols();
+		connectionInfo = getSharedPreferences(getString(R.string.connection_info), Context.MODE_PRIVATE);
+		connectionInfoEditor = connectionInfo.edit();
 		createNotification();
-		for (Protocol<?> protocol : getProtocolArray()) {
-			listeners.add(new HoneyListener(this, protocol));
-		}
 		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[] {});
+		}
+	}
+
+	@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
-    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
 	public void onDestroy() {
 		cancelNotification();
-		super.onDestroy();
 		unregisterNetReceiver();
+		super.onDestroy();
 	}
-	
-	/** Starts an Instance of MyLocationManager to set the location within this class.
+
+	/**
+	 * Starts an Instance of MyLocationManager to set the location within this
+	 * class.
 	 */
-	private void getLocationData(){
+	private void getLocationData() {
 		MyLocationManager locationManager = new MyLocationManager(this);
-		locationManager.getUpdates(60 * 1000);
+		locationManager.getUpdates(60 * 1000, 3);
 	}
-	
+
 	/**
 	 * Deletes all session related data.
 	 */
-	private void deleteSessionData(){
-    	editor.clear();
-    	editor.commit();
+	private void deleteConnectionData() {
+		connectionInfoEditor.clear();
+		connectionInfoEditor.commit();
 	}
-	
+
 	/**
 	 * Register broadcast receiver for connectivity changes
 	 */
 	private void registerNetReceiver() {
-	    // register BroadcastReceiver on network state changes	    
+		// register BroadcastReceiver on network state changes
 		IntentFilter intent = new IntentFilter();
-	    intent.addAction(ConnectivityManager.CONNECTIVITY_ACTION); //"android.net.conn.CONNECTIVITY_CHANGE"
-	    registerReceiver(netReceiver, intent);
+		intent.addAction(ConnectivityManager.CONNECTIVITY_ACTION); // "android.net.conn.CONNECTIVITY_CHANGE"
+		registerReceiver(netReceiver, intent);
 	}
 
 	/**
-	 *  Unregister broadcast receiver for connectivity changes
+	 * Unregister broadcast receiver for connectivity changes
 	 */
 	private void unregisterNetReceiver() {
 		unregisterReceiver(netReceiver);
@@ -129,167 +158,178 @@ public class HoneyService extends Service {
 
 	/**
 	 * Receiver for connectivity change broadcast.
+	 * 
 	 * @see MainActivity#BROADCAST
 	 */
 	private BroadcastReceiver netReceiver = new BroadcastReceiver() {
 		@Override
 		public void onReceive(Context context, Intent intent) {
-				String bssid_old = sessionPref.getString(MainActivity.BSSID, "");
-				String bssid_new = HelperUtils.getBSSID(context);
-				//TODO INFORM UI
-				//TODO CHECK IF OTHER NETWORKS WORK TOO
-				if(bssid_new == null || !bssid_new.equals(bssid_old)){
-					getLocationData();
-					String[] protocols = getResources().getStringArray(R.array.protocols);
-					for (String protocol : protocols) {
-						editor.remove(protocol + MainActivity.HANDLER_COUNT);
-					}						
-					notifyUI("SERVICE", "CONNECTIVITY_CHANGE");
-				}
-		}
-	};	
-
-
-	/**
-	 * Creates a Notification in the notification bar.
-	 */
-	private void createNotification() {
-		DatabaseHandler dbh = new DatabaseHandler(this);
-		boolean activeHandlers = false;
-		boolean bssidSeen = false;
-		
-		for(String protocol : getResources().getStringArray(R.array.protocols)){
-			int handlerCount = sessionPref.getInt(protocol + MainActivity.HANDLER_COUNT, 0);
-			if(handlerCount > 0){
-				activeHandlers = true;
-			}
-			if(dbh.bssidSeen(protocol, HelperUtils.getBSSID(getApplicationContext()))){
-				bssidSeen = true;
+			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)});
 			}
 		}
-		builder = new NotificationCompat.Builder(this)
-										.setContentTitle(getString(R.string.app_name))
-										.setWhen(System.currentTimeMillis());	
-		if(activeHandlers){
-			builder.setSmallIcon(R.drawable.ic_service_red);
-			builder.setContentText("Network is infected!");
-		} else if(bssidSeen){
-			builder.setSmallIcon(R.drawable.ic_service_yellow);
-			builder.setContentText("Network has been infected in previous session!");
-		} 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));
-		PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
-				PendingIntent.FLAG_UPDATE_CURRENT);
-		builder.setContentIntent(resultPendingIntent);
-		NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
-		mNotificationManager.notify(1, builder.build());
-	}
+	};
 	
-	/**
-	 * Updates the notification when a attack is registered.
-	 */
-	private void updateNotification() {
-		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("Network is infected!")
-				.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(1, builder.build());
-	}
 
 	/**
-	 * Cancels the Notification
+	 * Notifies the GUI about a event.
+	 * 
+	 * @param sender
+	 *            Source where the event took place.
+	 * @param key
+	 *            Detailed information about the event.
 	 */
-	private void cancelNotification() {
-		NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
-		mNotificationManager.cancel(1);
+	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);
 	}
+	
 
 
 	/**
-	 * Creates a instance of each protocol defined in /res/values/protocols.xml and puts it in a List
-	 * @return ArrayList of {@link de.tudarmstadt.informatik.hostage.protocol.Protocol Protocol}
+	 * Returns an LinkedList<String> with the names of all implemented protocols.
+	 * 
+	 * @return ArrayList of
+	 *         {@link de.tudarmstadt.informatik.hostage.protocol.Protocol
+	 *         Protocol}
 	 */
-	private ArrayList<Protocol<?>> getProtocolArray() {
+	private LinkedList<Protocol> getImplementedProtocols() {
 		String[] protocols = getResources().getStringArray(R.array.protocols);
 		String packageName = Protocol.class.getPackage().getName();
-		ArrayList<Protocol<?>> protocolArray = new ArrayList<Protocol<?>>();
+		LinkedList<Protocol> implementedProtocols = new LinkedList<Protocol>();
 
 		for (String protocol : protocols) {
 			try {
-				protocolArray.add((Protocol<?>) Class.forName(
-						String.format("%s.%s", packageName, protocol))
-						.newInstance());
+				implementedProtocols.add((Protocol) Class.forName(String.format("%s.%s", packageName, protocol)).newInstance());
 			} catch (Exception e) {
 				e.printStackTrace();
 			}
 		}
-		return protocolArray;
+		return implementedProtocols;
 	}
 	
 	/**
-	 * Determines if there are running listeners.
+	 * 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.getDefaultPort();
+			}
+		}
+		return -1;
+	}
+
+	/**
+	 * Determines if there any listener is currently running.
+	 * 
 	 * @return True if there is a running listener, else false.
 	 */
-	public boolean hasRunningListeners(){
+	public boolean hasRunningListeners() {
 		for (HoneyListener listener : listeners) {
-				if (listener.isRunning())
-					return true;
+			if (listener.isRunning())
+				return true;
 		}
 		return false;
 	}
+	
+	/**
+	 * 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){
+		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
+	 * @return True if protocol is running, else false.
+	 */
+	public boolean isRunning(String protocolName, int port){
+		for (HoneyListener listener : listeners) {
+			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;
+	}
 
 	/**
-	 * Notifies the GUI about a event.
-	 * @param protocol The protocol where the event happened.
-	 * @param key The key for the event.
+	 * 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.
+	 * 
+	 * @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.
 	 */
-	public void notifyUI(String sender, String key) {
-		// Send Notification
-		if (key.equals(MainActivity.HANDLER_COUNT)){
-			updateNotification();
-		}else if(key.equals("CONNECTIVITY_CHANGE")){
-			createNotification();
+	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;
+			} 
 		}
-		Log.i("HoneyService", key);
-		// Inform UI of Preference Change
-		Intent intent = new Intent(MainActivity.BROADCAST);
-		intent.putExtra("SENDER", sender);
-		intent.putExtra("SENDER", key);
-		LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
-	}	
-	
+		return null;
+	}
+
 	/**
-	 * Starts all listeners which are not already running
+	 * Starts all listeners which are not already running.
 	 */
 	public void startListeners() {
 		for (HoneyListener listener : listeners) {
-			if(!listener.isRunning()){
+			if (!listener.isRunning()) {
 				listener.start();
 			}
 		}
-		Toast.makeText(getApplicationContext(), "SERVICES STARTED!", Toast.LENGTH_SHORT).show();
+		Toast.makeText(getApplicationContext(), "SERVICES STARTED!",
+				Toast.LENGTH_SHORT).show();
 	}
 
 	/**
@@ -297,36 +337,79 @@ public class HoneyService extends Service {
 	 */
 	public void stopListeners() {
 		for (HoneyListener listener : listeners) {
-			if(listener.isRunning()){
+			if (listener.isRunning()) {
 				listener.stop();
 			}
 		}
-		Toast.makeText(getApplicationContext(), "SERVICES STOPPED!", Toast.LENGTH_SHORT).show();
+		Toast.makeText(getApplicationContext(), "SERVICES STOPPED!",
+				Toast.LENGTH_SHORT).show();
 	}
 
 	/**
-	 * Starts the listener for the specified protocol.
-	 * @param protocolName Name of the protocol that should be started.
-	 */ 
-	public void startListener(String protocolName) {
+	 * 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.
+	 */
+	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.
+	 * 
+	 * @param protocolName
+	 *            Name of the protocol that should be started.
+	 * @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)) {
-				if(!listener.isRunning()){
-					listener.start();
+			if (listener.getProtocolName().equals(protocolName) && listener.getPort() == port) {
+				if (!listener.isRunning()) {
+					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();
+					return false;
 				}
+				
 			}
 		}
-		Toast.makeText(getApplicationContext(), protocolName + " SERVICE STARTED!", Toast.LENGTH_SHORT).show();
+		HoneyListener listener = createListener(protocolName, port);
+		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();
+		return false;
 	}
 
 	/**
 	 * Stops the listener for the specified protocol.
-	 * @param protocolName Name of the protocol that should be stopped.
-	 */ 
+	 * 
+	 * @param protocolName
+	 *            Name of the protocol that should be stopped.
+	 */
 	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.
+	 */
+	public void stopListener(String protocolName, int port) {
 		for (HoneyListener listener : listeners) {
-			if (listener.getProtocolName().equals(protocolName)) {
-				if(listener.isRunning()){
+			if (listener.getProtocolName().equals(protocolName) && listener.getPort() == port) {
+				if (listener.isRunning()) {
 					listener.stop();
 				}
 			}
@@ -335,19 +418,181 @@ public class HoneyService extends Service {
 	}
 
 	/**
-	 * Toggles a listener for specified protocol.
-	 * @param protocolName Name of the protocol that should be toggled.
+	 * Task for accuiring a qotd from one of four possible servers.
+	 * 
+	 * @author Wulf Pfeiffer
 	 */
-	public void toggleListener(String protocolName) {
-		for (HoneyListener listener : listeners) {
-			if (listener.getProtocolName().equals(protocolName)) {
-				if (listener.isRunning()) {
-					stopListener(protocolName);
-				} else {
-					startListener(protocolName);
+	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();
+		}
+
+		@Override
+		protected void onPostExecute(String result) {
+			if (result != null)
+				HTTP.setHtmlDocumentContent(result);
+		}
+	};
+	
+	/**
+	 * 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" });
+	}
+	
+	/**
+	 * 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;
+
+				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
+		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.
+	 */
+	private void createNotification() {
+		UglyDbHelper dbh = new UglyDbHelper(this);
+		boolean activeHandlers = false;
+		boolean bssidSeen = false;
+		boolean listening = false;
+
+		for (HoneyListener listener : listeners) {
+			if(listener.isRunning())
+				listening = true;
+			if (listener.getHandlerCount() > 0) {
+				activeHandlers = true;
+			}
+			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){
+			builder.setSmallIcon(R.drawable.ic_launcher);
+			builder.setContentText("HosTaGe is not active.");
+		} else if (activeHandlers) {
+			builder.setSmallIcon(R.drawable.ic_service_red);
+			builder.setContentText("Network is infected!");
+		} else if (bssidSeen) {
+			builder.setSmallIcon(R.drawable.ic_service_yellow);
+			builder.setContentText("Network has been infected in previous session!");
+		} 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));
+		PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
+				PendingIntent.FLAG_UPDATE_CURRENT);
+		builder.setContentIntent(resultPendingIntent);
+		builder.setOngoing(true);
+		NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+		mNotificationManager.notify(1, builder.build());
+	}
+
+	/**
+	 * 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());
+	}
+
+	/**
+	 * Cancels the Notification
+	 */
+	private void cancelNotification() {
+		NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+		mNotificationManager.cancel(1);
 	}
 
 }

+ 160 - 47
src/de/tudarmstadt/informatik/hostage/commons/HelperUtils.java

@@ -3,6 +3,7 @@ package de.tudarmstadt.informatik.hostage.commons;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.security.KeyStore;
+import java.security.SecureRandom;
 
 import org.apache.http.HttpVersion;
 import org.apache.http.client.HttpClient;
@@ -20,8 +21,6 @@ import org.apache.http.params.HttpParams;
 import org.apache.http.params.HttpProtocolParams;
 import org.apache.http.protocol.HTTP;
 
-import de.tudarmstadt.informatik.hostage.logging.Record;
-import de.tudarmstadt.informatik.hostage.net.MySSLSocketFactory;
 import android.content.Context;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
@@ -30,18 +29,24 @@ import android.net.wifi.WifiManager;
 import android.os.Environment;
 import android.preference.PreferenceManager;
 import android.text.TextUtils;
+import de.tudarmstadt.informatik.hostage.logging.Record;
+import de.tudarmstadt.informatik.hostage.logging.formatter.TraCINgFormatter;
+import de.tudarmstadt.informatik.hostage.net.MySSLSocketFactory;
 
 /**
  * Helper class with some static methods for general usage.
+ * 
  * @author Lars Pandikow
  * @author Wulf Pfeiffer
- *
+ * 
  */
 public final class HelperUtils {
 
 	/**
 	 * Gets SSID of the wireless network.
-	 * @param context Needs a context to get system recourses
+	 * 
+	 * @param context
+	 *            Needs a context to get system recourses
 	 * @return SSID of wireless network if connected, else null.
 	 */
 	public static String getSSID(Context context) {
@@ -64,7 +69,9 @@ public final class HelperUtils {
 
 	/**
 	 * Gets BSSID of the wireless network.
-	 * @param context Needs a context to get system recourses.
+	 * 
+	 * @param context
+	 *            Needs a context to get system recourses.
 	 * @return BSSID of wireless network if connected, else null.
 	 */
 	public static String getBSSID(Context context) {
@@ -87,8 +94,11 @@ public final class HelperUtils {
 
 	/**
 	 * Gets internal IP address of the device in a wireless network.
-	 * @param context Needs a context to get system recourses.
-	 * @return internal IP of the device in a wireless network if connected, else null.
+	 * 
+	 * @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 getInternalIP(Context context) {
 		String ipAddress = null;
@@ -117,11 +127,13 @@ public final class HelperUtils {
 		return new byte[] { (byte) ((bytes) & 0xff),
 				(byte) ((bytes >>> 8) & 0xff), (byte) ((bytes >>> 16) & 0xff),
 				(byte) ((bytes >>> 24) & 0xff) };
-	} 
+	}
 
 	/**
 	 * Checks if external storage is available for read and write.
-	 * @return True if external storage is available for read and write, else false.
+	 * 
+	 * @return True if external storage is available for read and write, else
+	 *         false.
 	 */
 	public static boolean isExternalStorageWritable() {
 		String state = Environment.getExternalStorageState();
@@ -133,6 +145,7 @@ public final class HelperUtils {
 
 	/**
 	 * Creates a HttpClient with an own SSL Socket.
+	 * 
 	 * @return HttpsClient who accepts accepts all certificates.
 	 * @see MySSLSocketFactory
 	 */
@@ -163,46 +176,56 @@ public final class HelperUtils {
 			return new DefaultHttpClient();
 		}
 	}
-	
+
 	/**
 	 * Uploads a single Record to a server, specified in the settings.
-	 * @param record The Record to upload.
+	 * 
+	 * @param record
+	 *            The Record to upload.
 	 * @return True if the upload was successful, else false.
 	 */
-	public static boolean uploadSingleRecord(Context context, Record record){
-	  	// Create a https client. Uses MySSLSocketFactory to accept all certificates
+	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"));
+			httppost = new HttpPost(PreferenceManager
+					.getDefaultSharedPreferences(context).getString(
+							"pref_upload", "https://ssi.cased.de"));
 			// Create JSON String of Record
-			StringEntity se = new StringEntity(record.toString(0x01));
+			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;
 	}
-	
+
 	/**
 	 * Concatenates several byte arrays.
-	 * @param bytes The byte arrays.
-	 * @return A single byte arrays containing all the bytes from the given arrays in the order they are given.
+	 * 
+	 * @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 byte[] concat(byte[]... bytes) {
 		int newSize = 0;
 		for (byte[] b : bytes)
-			if(b != null) newSize += b.length;
+			if (b != null)
+				newSize += b.length;
 		byte[] dst = new byte[newSize];
 
 		int currentPos = 0;
 		int newPos;
 		for (byte[] b : bytes) {
-			if(b != null) {
+			if (b != null) {
 				newPos = b.length;
 				System.arraycopy(b, 0, dst, currentPos, newPos);
 				currentPos += newPos;
@@ -210,10 +233,13 @@ public final class HelperUtils {
 		}
 		return dst;
 	}
-	
+
 	/**
-	 * Converts a byte[] to a String, but only characters in ASCII between 32 and 127
-	 * @param bytes that are converted
+	 * Converts a byte[] to a String, but only characters in ASCII between 32
+	 * and 127
+	 * 
+	 * @param bytes
+	 *            that are converted
 	 * @return converted String
 	 */
 	public static String byteToStr(byte[] bytes) {
@@ -229,44 +255,131 @@ public final class HelperUtils {
 
 	/**
 	 * Determines if a character is in ASCII between 32 and 126
-	 * @param character that is checked 
+	 * 
+	 * @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);
 	}
-	
+
 	/**
-	 * Converts a byte array into a hexadecimal String, e.g. {0x00, 0x01} to "00, 01". 
-	 * @param bytes that will be converted.
+	 * Converts a byte array into a hexadecimal String, e.g. {0x00, 0x01} to
+	 * "00, 01".
+	 * 
+	 * @param bytes
+	 *            that will be converted.
 	 * @return converted String.
 	 */
 	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 buffer.toString();
+		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 buffer.toString();
 	}
-	
+
 	/**
-	 * Converts a String into a byte array, e.g. "00, 01" to {0x00, 0x01}. 
-	 * @param string that will be converted.
+	 * Converts a String into a byte array, e.g. "00, 01" to {0x00, 0x01}.
+	 * 
+	 * @param string
+	 *            that will be converted.
 	 * @return converted byte array.
 	 */
 	public static byte[] hexStringToBytes(String string) {
-	    String[] hexStrings = string.split(", ");
-	    byte[] bytes = new byte[hexStrings.length];
-	    for(int j = 0; j < hexStrings.length; j++ ) {
-	    	bytes[j] = (byte) ((Character.digit(hexStrings[j].charAt(0), 16) << 4)
-                    + Character.digit(hexStrings[j].charAt(1), 16));
-	    }
-	    return bytes;
+		String[] hexStrings = string.split(", ");
+		byte[] bytes = new byte[hexStrings.length];
+		for (int j = 0; j < hexStrings.length; j++) {
+			bytes[j] = (byte) ((Character.digit(hexStrings[j].charAt(0), 16) << 4) + Character
+					.digit(hexStrings[j].charAt(1), 16));
+		}
+		return bytes;
+	}
+
+	/**
+	 * 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 length
+	 *            maximal / forced length of String.
+	 * @param forceLength
+	 *            forces the String to be exact the given length instead of
+	 *            maximum
+	 * @return random String.
+	 */
+	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);
+	}
+
+	/**
+	 * 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;
+	}
+
+	/**
+	 * Puts a 0x00 byte between each byte in a byte array.
+	 * 
+	 * @param bytes
+	 *            that need to be filled with 0x00.
+	 * @return filled byte array.
+	 */
+	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;
+	}
+
+	/**
+	 * Turns around the values of an byte[], e.g. {0x00, 0x01, 0x02} turns into
+	 * {0x02, 0x01, 0x00}.
+	 * 
+	 * @param bytes
+	 *            array that is turned.
+	 * @return turned array.
+	 */
+	public static byte[] turnByteArray(byte[] bytes) {
+		byte[] tmp = new byte[bytes.length];
+		for (int i = 0; i < bytes.length; i++) {
+			tmp[i] = bytes[bytes.length - 1 - i];
+		}
+		return tmp;
+	}
+	
+	/**
+	 * Generates a random byte[] of a specified size
+	 * @param size of the byte[]
+	 * @return random byte[]
+	 */
+	public static byte[] randomBytes(int size) {
+		byte[] bytes = new byte[size];
+		SecureRandom rdm = new SecureRandom();
+		rdm.nextBytes(bytes);
+		return bytes;		
 	}
 
 	public static boolean isWifiConnected(Context context){

+ 0 - 14
src/de/tudarmstadt/informatik/hostage/format/DefaultFormatter.java

@@ -1,14 +0,0 @@
-package de.tudarmstadt.informatik.hostage.format;
-
-/**
- * Default log view formatter.
- * 
- * @author Wulf Pfeiffer
- */
-public class DefaultFormatter implements ProtocolFormatter {
-
-	public String format(String packet) {
-		return packet;
-	}
-
-}

+ 0 - 46
src/de/tudarmstadt/informatik/hostage/format/LogViewFormatter.java

@@ -1,46 +0,0 @@
-package de.tudarmstadt.informatik.hostage.format;
-
-import de.tudarmstadt.informatik.hostage.R;
-import de.tudarmstadt.informatik.hostage.ui.MainActivity;
-
-/**
- * Log view formatter used to format packet contents for the log view.
- * @author Wulf Pfeiffer
- */
-public class LogViewFormatter {
-	
-	/**
-	 * Formats the content of a packet giving it a specific format specified by a ProtocolFormatter. 
-	 * @param protocol that is used for packet.
-	 * @param packet content.
-	 * @return formatted String of the packet content.
-	 */
-	public static String format(String protocol, String packet) {		
-		return getFormatter(protocol).format(packet);
-	}
-	
-	/**
-	 * Loads a ProtocolFormatter for a protocol.
-	 * If the protocol has its own formatter, with the name *protocol name*Formatter and it is located in .format package, it is loaded,
-	 * else a default formatter is loaded.
-	 * @param protocol that a formatter should be loaded for.
-	 * @return the loaded formatter.
-	 */
-	private static ProtocolFormatter getFormatter(String protocol) {
-		String[] protocols = MainActivity.getContext().getResources().getStringArray(R.array.protocols);
-		String packageName = ProtocolFormatter.class.getPackage().getName();
-		ProtocolFormatter formatter = new DefaultFormatter();
-
-		for (String prot : protocols) {
-			try {
-				if(protocol.equals(prot)) formatter = (ProtocolFormatter) Class.forName(
-						String.format("%s.%s", packageName, protocol+"Formatter"))
-						.newInstance();
-			} catch (Exception e) {
-				e.printStackTrace();
-			}
-		}
-		return formatter;
-	}
-
-}

+ 0 - 64
src/de/tudarmstadt/informatik/hostage/format/MySQLFormatter.java

@@ -1,64 +0,0 @@
-package de.tudarmstadt.informatik.hostage.format;
-
-import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
-
-/**
- * MySQL log view formatter.
- * @author Wulf Pfeiffer
- */
-public class MySQLFormatter implements ProtocolFormatter {
-
-	public String format(String packet) {
-		byte[] bytes = HelperUtils.hexStringToBytes(packet);
-		String command = "Command: " + getCommand(bytes) + "\n";
-		String content = "Content: " + HelperUtils.byteToStr(bytes) + "\n";
-		return command + content;
-	}
-	
-	/**
-	 * Checks a packet for its command code and returns the name of this command.
-	 * @param bytes to check.
-	 * @return name of the command.
-	 */
-	private String getCommand(byte[] bytes) {
-		//if packet number is 1 server started conversation so it must be login
-		if(bytes.length < 5) return "";
-		if(bytes[3] == 0x01) return "Login request"; 
-		//else check for command code
-		switch(bytes[4]) {
-		case 0x00: return "COM_SLEEP";
-		case 0x01: return "COM_QUIT";
-		case 0x02: return "COM_INIT_DB";
-		case 0x03: return "COM_QUERY";
-		case 0x04: return "COM_FIELD_LIST";
-		case 0x05: return "COM_CREATE_DB";
-		case 0x06: return "COM_DROP_DB";
-		case 0x07: return "COM_REFRESH";
-		case 0x08: return "COM_SHUTDOWN";
-		case 0x09: return "COM_STATISTICS";
-		case 0x0a: return "COM_PROCESS_INFO";
-		case 0x0b: return "COM_CONNECT";
-		case 0x0c: return "COM_PROCESS_KILL";
-		case 0x0d: return "COM_DEBUG";
-		case 0x0e: return "COM_PING";
-		case 0x0f: return "COM_TIME";
-		case 0x10: return "COM_DELAYED_INSERT";
-		case 0x11: return "COM_CHANGE_USER";
-		case 0x12: return "COM_BINLOG_DUMP";
-		case 0x13: return "COM_TABLE_DUMP";
-		case 0x14: return "COM_CONNECT_OUT";
-		case 0x15: return "COM_REGISTER_SLAVE";
-		case 0x16: return "COM_STMT_PREPARE";
-		case 0x17: return "COM_STMT_EXECUTE";
-		case 0x18: return "COM_STMT_SEND_LONG_DATA";
-		case 0x19: return "COM_STMT_CLOSE";
-		case 0x1a: return "COM_STMT_RESET";
-		case 0x1b: return "COM_SET_OPTION";
-		case 0x1c: return "COM_STMT_FETCH";
-		case 0x1d: return "COM_DAEMON";
-		case 0x1e: return "COM_BINLOG_DUMP_GTID";
-		default: return "unkown command";
-		}
-	}
-
-}

+ 0 - 17
src/de/tudarmstadt/informatik/hostage/format/ProtocolFormatter.java

@@ -1,17 +0,0 @@
-package de.tudarmstadt.informatik.hostage.format;
-
-/**
- * Interface for log view formatter.
- * This class provides functionality to format the presentation of specific protocols.
- * @author Wulf Pfeiffer
- */
-public interface ProtocolFormatter {
-
-	/**
-	 * Formats the content of packet. The packet content can be a normal String or a hexadecimal String,
-	 * depending of the type of the protocol. ByteArray protocols receive hexdecimal String, else normal Strings.
-	 * @param packet that should be formatted.
-	 * @return new format of the packet content.
-	 */
-	String format(String packet);
-}

+ 0 - 135
src/de/tudarmstadt/informatik/hostage/format/SMBFormatter.java

@@ -1,135 +0,0 @@
-package de.tudarmstadt.informatik.hostage.format;
-
-import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
-
-/**
- * SMB log view formatter.
- * @author Wulf Pfeiffer
- */
-public class SMBFormatter implements ProtocolFormatter {
-
-	public String format(String packet) {
-		byte[] bytes = HelperUtils.hexStringToBytes(packet);
-		byte cmd = bytes[8]; //command code located at 8
-		StringBuffer buffer = new StringBuffer();
-		buffer.append("Command: ");
-		buffer.append(getCommandString(cmd));
-		buffer.append("\n");
-		buffer.append("Content: ");
-		buffer.append(getContent(cmd, bytes));
-		
-		return buffer.toString();
-	}
-	
-	/**
-	 * Checks command code for its command code and returns the name of this command.
-	 * @param command as byte.
-	 * @return command name as String.
-	 */
-	private String getCommandString(byte command) {
-		switch(command) {
-		case 0x00: return "SMB_COM_CREATE_DIRECTORY";
-		case 0x01: return "SMB_COM_DELETE_DIRECTORY";
-		case 0x02: return "SMB_COM_OPEN";
-		case 0x03: return "SMB_COM_CREATE";
-		case 0x04: return "SMB_COM_CLOSE";
-		case 0x05: return "SMB_COM_FLUSH";
-		case 0x06: return "SMB_COM_DELETE";
-		case 0x07: return "SMB_COM_RENAME";
-		case 0x08: return "SMB_COM_QUERY_INFORMATION";
-		case 0x09: return "SMB_COM_SET_INFORMATION";
-		case 0x0A: return "SMB_COM_READ";
-		case 0x0B: return "SMB_COM_WRITE";
-		case 0x0C: return "SMB_COM_LOCK_BYTE_RANGE";
-		case 0x0D: return "SMB_COM_UNLOCK_BYTE_RANGE";
-		case 0x0E: return "SMB_COM_CREATE_TEMPORARY";
-		case 0x0F: return "SMB_COM_CREATE_NEW";
-		case 0x10: return "SMB_COM_CHECK_DIRECTORY";
-		case 0x11: return "SMB_COM_PROCESS_EXIT";
-		case 0x12: return "SMB_COM_SEEK";
-		case 0x13: return "SMB_COM_LOCK_AND_READ";
-		case 0x14: return "SMB_COM_WRITE_AND_UNLOCK";
-		case 0x1A: return "SMB_COM_READ_RAW";
-		case 0x1B: return "SMB_COM_READ_MPX";
-		case 0x1C: return "SMB_COM_READ_MPX_SECONDARY";
-		case 0x1D: return "SMB_COM_WRITE_RAW";
-		case 0x1E: return "SMB_COM_WRITE_MPX";
-		case 0x1F: return "SMB_COM_WRITE_MPX_SECONDARY";
-		case 0x20: return "SMB_COM_WRITE_COMPLETE";
-		case 0x21: return "SMB_COM_QUERY_SERVER";
-		case 0x22: return "SMB_COM_SET_INFORMATION2";
-		case 0x23: return "SMB_COM_QUERY_INFORMATION2";
-		case 0x24: return "SMB_COM_LOCKING_ANDX";
-		case 0x25: return "SMB_COM_TRANSACTION";
-		case 0x26: return "SMB_COM_TRANSACTION_SECONDARY";
-		case 0x27: return "SMB_COM_IOCTL";
-		case 0x28: return "SMB_COM_IOCTL_SECONDARY";
-		case 0x29: return "SMB_COM_COPY";
-		case 0x2A: return "SMB_COM_MOVE";
-		case 0x2B: return "SMB_COM_ECHO";
-		case 0x2C: return "SMB_COM_WRITE_AND_CLOSE";
-		case 0x2D: return "SMB_COM_OPEN_ANDX";
-		case 0x2E: return "SMB_COM_READ_ANDX";
-		case 0x2F: return "SMB_COM_WRITE_ANDX";
-		case 0x30: return "SMB_COM_NEW_FILE_SIZE";
-		case 0x31: return "SMB_COM_CLOSE_AND_TREE_DISC";
-		case 0x32: return "SMB_COM_TRANSACTION2";
-		case 0x33: return "SMB_COM_TRANSACTION2_SECONDARY";
-		case 0x34: return "SMB_COM_FIND_CLOSE2";
-		case 0x35: return "SMB_COM_FIND_NOTIFY_CLOSE";
-		case 0x70: return "SMB_COM_TREE_CONNECT";
-		case 0x71: return "SMB_COM_TREE_DISCONNECT";
-		case 0x72: return "SMB_COM_NEGOTIATE";
-		case 0x73: return "SMB_COM_SESSION_SETUP_ANDX";
-		case 0x74: return "SMB_COM_LOGOFF_ANDX";
-		case 0x75: return "SMB_COM_TREE_CONNECT_ANDX";
-		case (byte)0x80: return "SMB_COM_QUERY_INFORMATION_DISK";
-		case (byte)0x81: return "SMB_COM_SEARCH";
-		case (byte)0x82: return "SMB_COM_FIND";
-		case (byte)0x83: return "SMB_COM_FIND_UNIQUE";
-		case (byte)0x84: return "SMB_COM_FIND_CLOSE";
-		case (byte)0xA0: return "SMB_COM_NT_TRANSACT";
-		case (byte)0xA1: return "SMB_COM_NT_TRANSACT_SECONDARY";
-		case (byte)0xA2: return "SMB_COM_NT_CREATE_ANDX";
-		case (byte)0xA4: return "SMB_COM_NT_CANCEL";
-		case (byte)0xA5: return "SMB_COM_NT_RENAME";
-		case (byte)0xC0: return "SMB_COM_OPEN_PRINT_FILE";
-		case (byte)0xC1: return "SMB_COM_WRITE_PRINT_FILE";
-		case (byte)0xC2: return "SMB_COM_CLOSE_PRINT_FILE";
-		case (byte)0xC3: return "SMB_COM_GET_PRINT_QUEUE";
-		case (byte)0xD8: return "SMB_COM_READ_BULK";
-		case (byte)0xD9: return "SMB_COM_WRITE_BULK";
-		case (byte)0xDA: return "SMB_COM_WRITE_BULK_DATA";
-		case (byte)0xFF: return "SMB_COM_NONE";
-		default: return "Unknown Command";
-		}
-	}
-	
-	/**
-	 * Returns the content of a packet as a String value, depending on its command code
-	 * @param command of the packet.
-	 * @param packet content as byte array. 
-	 * @return content as a String.
-	 */
-	private String getContent(byte command, byte[] packet) {
-		switch(command) {
-		case 0x72: return get0x72content(packet);
-		case 0x73: return HelperUtils.byteToStr(packet);
-		case (byte) 0xa2: return HelperUtils.byteToStr(packet);
-		case 0x25: return HelperUtils.byteToStr(packet);
-		default: return "";
-		}
-	}
-	
-	/**
-	 * 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);
-	}
-
-}

+ 0 - 169
src/de/tudarmstadt/informatik/hostage/format/TELNETFormatter.java

@@ -1,169 +0,0 @@
-package de.tudarmstadt.informatik.hostage.format;
-
-import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
-
-/**
- * Telnet log view formatter.
- * 
- * @author Wulf Pfeiffer
- */
-public class TELNETFormatter implements ProtocolFormatter {
-
-	public String format(String packet) {
-		byte[] bytes = HelperUtils.hexStringToBytes(packet);
-		String options = "Options:\n" + checkForOptions(bytes) + "\n";
-		String content = "Content: " + HelperUtils.byteToStr(bytes);
-		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) {
-				switch (bytes[i + 1]) {
-				case (byte) 0xfb:
-					options.append(" WILL ");
-					break;
-				case (byte) 0xfc:
-					options.append(" WON'T ");
-					break;
-				case (byte) 0xfd:
-					options.append(" DO ");
-					break;
-				case (byte) 0xfe:
-					options.append(" DON'T ");
-					break;
-				default:
-					options.append(" unkown command ");
-					break;
-				}
-				// option name
-				switch (bytes[i + 2]) {
-				case 0x00:
-					options.append("Binary Transmission\n");
-					break;
-				case 0x01:
-					options.append("Echo\n");
-					break;
-				case 0x02:
-					options.append("Reconnection\n");
-					break;
-				case 0x03:
-					options.append("Suppress Go Ahead\n");
-					break;
-				case 0x04:
-					options.append("Approx Message Size Negotiation\n");
-					break;
-				case 0x05:
-					options.append("Status\n");
-					break;
-				case 0x06:
-					options.append("Timing Mark\n");
-					break;
-				case 0x07:
-					options.append("Remote Controlled Trans and Echo\n");
-					break;
-				case 0x08:
-					options.append("Output Line Width\n");
-					break;
-				case 0x09:
-					options.append("Output Page Size\n");
-					break;
-				case 0x0a:
-					options.append("Output Carriage-Return Disposition\n");
-					break;
-				case 0x0b:
-					options.append("Output Horizontal Tab Stops\n");
-					break;
-				case 0x0c:
-					options.append("Output Horizontal Tab Disposition\n");
-					break;
-				case 0x0d:
-					options.append("Output Formfeed Disposition\n");
-					break;
-				case 0x0e:
-					options.append("Output Vertical Tabstops\n");
-					break;
-				case 0x0f:
-					options.append("Output Vertical Tab Disposition\n");
-					break;
-				case 0x10:
-					options.append("Output Linefeed Disposition\n");
-					break;
-				case 0x11:
-					options.append("Extended ASCII\n");
-					break;
-				case 0x12:
-					options.append("Logout\n");
-					break;
-				case 0x13:
-					options.append("Byte Macro\n");
-					break;
-				case 0x14:
-					options.append("Data Entry Terminal\n");
-					break;
-				case 0x15:
-					options.append("SUPDUP\n");
-					break;
-				case 0x16:
-					options.append("SUPDUP Output\n");
-					break;
-				case 0x17:
-					options.append("Send Location\n");
-					break;
-				case 0x18:
-					options.append("Terminal Type\n");
-					break;
-				case 0x19:
-					options.append("End of Record\n");
-					break;
-				case 0x1a:
-					options.append("TACACS User Identification\n");
-					break;
-				case 0x1b:
-					options.append("Output Marking\n");
-					break;
-				case 0x1c:
-					options.append("Terminal Location Number\n");
-					break;
-				case 0x1d:
-					options.append("Telnet 3270 Regime\n");
-					break;
-				case 0x1e:
-					options.append("X.3 PAD\n");
-					break;
-				case 0x1f:
-					options.append("Negotiate About Window Size\n");
-					break;
-				case 0x20:
-					options.append("Terminal Speed\n");
-					break;
-				case 0x21:
-					options.append("Remote Flow Control\n");
-					break;
-				case 0x22:
-					options.append("Linemode\n");
-					break;
-				case 0x23:
-					options.append("X Display Location\n");
-					break;
-				case (byte) 0xff:
-					options.append("Extended-Options-List\n");
-					break;
-				default:
-					options.append("unknown option\n");
-					break;
-				}
-			}
-		}
-		return options.toString();
-	}
-
-}

+ 0 - 156
src/de/tudarmstadt/informatik/hostage/handler/AbstractHandler.java

@@ -1,156 +0,0 @@
-package de.tudarmstadt.informatik.hostage.handler;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.Socket;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.Editor;
-import android.preference.PreferenceManager;
-import de.tudarmstadt.informatik.hostage.HoneyListener;
-import de.tudarmstadt.informatik.hostage.HoneyService;
-import de.tudarmstadt.informatik.hostage.logging.Logger;
-import de.tudarmstadt.informatik.hostage.logging.Record;
-import de.tudarmstadt.informatik.hostage.logging.Record.TYPE;
-import de.tudarmstadt.informatik.hostage.protocol.Protocol;
-import de.tudarmstadt.informatik.hostage.ui.MainActivity;
-/**
- * Abstract class for a connection handler using a given protocol.
- * @author Mihai Plasoianu 
- */
-public abstract class AbstractHandler implements Runnable {
-
-	/**
-	 * Time until the socket throws a time out. The time is in milliseconds.
-	 */
-	private int TIMEOUT;
-
-	protected Protocol protocol;
-	private Socket client;
-	protected Thread thread;
-
-	private int attack_id;
-	private String externalIP;
-	private String BSSID;
-	private String SSID;
-
-	private HoneyListener listener;
-	protected Logger log;
-
-	/**
-	 * Constructor of the class.
-	 * Initializes class variables for communication and logging.
-	 * Then starts itself in a new Thread.
-	 * @param service The background service.
-	 * @param listener The Listener that called the service.
-	 * @param protocol The protocol on which the handler is running.
-	 * @param client A Socket for the communication with a remote client.
-	 */
-	public AbstractHandler(HoneyService service, HoneyListener listener,
-			Protocol protocol, Socket client) {
-		this.listener = listener;
-		this.log = service.getLog();
-		this.protocol = protocol;
-		this.client = client;
-		this.thread = new Thread(this);
-		SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(service);
-		Editor editor = pref.edit();
-		TIMEOUT = pref.getInt("timeout", 30) * 1000;
-		attack_id = pref.getInt("ATTACK_ID_COUNTER", 0);
-		editor.putInt("ATTACK_ID_COUNTER", attack_id + 1);
-		editor.commit();
-		SharedPreferences sessionPref = service.getSharedPreferences(MainActivity.SESSION_DATA, Context.MODE_PRIVATE);
-		BSSID = sessionPref.getString(MainActivity.BSSID, null);
-		SSID = sessionPref.getString(MainActivity.SSID, null);
-		externalIP = sessionPref.getString(MainActivity.EXTERNAL_IP, null);
-		setSoTimeout(client);
-		thread.start();
-	}
-
-	/**
-	 * Set the timeout of the socket to the hard coded time out variable.
-	 * @param client The socket
-	 * @see #TIMEOUT
-	 */
-	private void setSoTimeout(Socket client) {
-		try {
-			client.setSoTimeout(TIMEOUT);
-		} catch (Exception e) {
-			e.printStackTrace();
-		}
-	}
-
-	/**
-	 * Creates InputStream and OutputStream for the socket.
-	 * Starts communication with client.
-	 * When the client closes the connection or a time out occurs the handler is finished.
-	 */
-	public void run() {
-		InputStream in;
-		OutputStream out;
-		try {
-			in = client.getInputStream();
-			out = client.getOutputStream();
-			talkToClient(in, out);
-		} catch (Exception e) {
-			e.printStackTrace();
-		}
-		kill();
-	}
-
-	/**
-	 * Sets the interrupt flag of the thread and tries to close the socket.
-	 */
-	public void kill() {
-		thread.interrupt();
-		try {
-			client.close();
-		} catch (Exception e) {
-			e.printStackTrace();
-		}
-		listener.refreshHandlers();
-	}
-
-	/**
-	 * Determines if the interrupt flag of the thread is set.
-	 * @return True when the flag is set, else false.
-	 */
-	public boolean isTerminated() {
-		return thread.isInterrupted();
-	}
-
-	/**
-	 * Communicates with a client using the corresponding protocol implementation.
-	 * @param in InputStream of the socket.
-	 * @param out OutputStream of the socket.
-	 * @throws IOException
-	 */
-	abstract protected void talkToClient(InputStream in, OutputStream out)
-			throws IOException;
-
-	/**
-	 * Creates a Record for a message exchanged with a client.
-	 * @param type The type of the message.
-	 * @param packet The content of the message.
-	 * @return The Record representing the communication message.
-	 */
-	protected Record createRecord(TYPE type, String packet) {
-		Record record = new Record();
-		record.setAttack_id(attack_id);
-		record.setProtocol(protocol.toString());
-		record.setType(type);
-		record.setTimestamp(System.currentTimeMillis());
-		record.setExternalIP(externalIP);
-		record.setLocalIP(client.getLocalAddress());
-		record.setLocalPort(protocol.getPort());
-		record.setRemoteIP(client.getInetAddress());
-		record.setRemotePort(client.getPort());
-		record.setBSSID(BSSID);
-		record.setSSID(SSID);
-		record.setPacket(packet);
-		return record;
-	}
-
-}

+ 0 - 69
src/de/tudarmstadt/informatik/hostage/handler/ByteArrayHandler.java

@@ -1,69 +0,0 @@
-package de.tudarmstadt.informatik.hostage.handler;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.Socket;
-import java.util.List;
-
-import android.content.SharedPreferences;
-import android.preference.PreferenceManager;
-
-import de.tudarmstadt.informatik.hostage.HoneyListener;
-import de.tudarmstadt.informatik.hostage.HoneyService;
-import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
-import de.tudarmstadt.informatik.hostage.io.ByteArrayReaderWriter;
-import de.tudarmstadt.informatik.hostage.io.ReaderWriter;
-import de.tudarmstadt.informatik.hostage.logging.Record.TYPE;
-import de.tudarmstadt.informatik.hostage.protocol.Protocol;
-import de.tudarmstadt.informatik.hostage.protocol.Protocol.TALK_FIRST;
-import de.tudarmstadt.informatik.hostage.wrapper.ByteArray;
-
-/**
- * Handles the socket connections for byte arrays.
- * @author Mihai Plasoianu
- */
-public class ByteArrayHandler extends AbstractHandler {
-
-	/** Defined time until timeout */
-	private int SLEEPTIME;
-	
-	public ByteArrayHandler(HoneyService service, HoneyListener listener,
-			Protocol<?> protocol, Socket client) {
-		super(service, listener, protocol, client);
-		SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(service);
-		SLEEPTIME = pref.getInt("sleeptime", 500);
-	}
-
-	@Override
-	protected void talkToClient(InputStream in, OutputStream out)
-			throws IOException {
-		ReaderWriter<ByteArray> stream = new ByteArrayReaderWriter(in, out, SLEEPTIME);
-
-		ByteArray inputLine;
-		List<ByteArray> outputLine;
-
-		if (protocol.whoTalksFirst() == TALK_FIRST.SERVER) {
-			outputLine = protocol.processMessage(null);
-			stream.write(outputLine);
-			for (ByteArray s : outputLine) {
-				log.write(createRecord(TYPE.SEND, HelperUtils.bytesToHexString(s.get())));
-			}
-		}
-
-		while (!thread.isInterrupted() && (inputLine = stream.read()) != null) {
-			outputLine = protocol.processMessage(inputLine);
-			log.write(createRecord(TYPE.RECEIVE, HelperUtils.bytesToHexString(inputLine.get())));
-			if (outputLine != null) {
-				stream.write(outputLine);
-				for (ByteArray s : outputLine) {
-					log.write(createRecord(TYPE.SEND, HelperUtils.bytesToHexString(s.get())));
-				}
-			}
-			if (protocol.isClosed()) {
-				break;
-			}
-		}
-	}
-
-}

+ 0 - 59
src/de/tudarmstadt/informatik/hostage/handler/StringHandler.java

@@ -1,59 +0,0 @@
-package de.tudarmstadt.informatik.hostage.handler;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.Socket;
-import java.util.List;
-
-import de.tudarmstadt.informatik.hostage.HoneyListener;
-import de.tudarmstadt.informatik.hostage.HoneyService;
-import de.tudarmstadt.informatik.hostage.io.ReaderWriter;
-import de.tudarmstadt.informatik.hostage.io.StringReaderWriter;
-import de.tudarmstadt.informatik.hostage.logging.Record.TYPE;
-import de.tudarmstadt.informatik.hostage.protocol.Protocol;
-import de.tudarmstadt.informatik.hostage.protocol.Protocol.TALK_FIRST;
-
-/**
- * Handles the socket connections for byte Strings.
- * @author Mihai Plasoianu
- */
-public class StringHandler extends AbstractHandler {
-
-	public StringHandler(HoneyService service, HoneyListener listener,
-			Protocol<?> protocol, Socket client) {
-		super(service, listener, protocol, client);
-	}
-
-	@Override
-	protected void talkToClient(InputStream in, OutputStream out)
-			throws IOException {
-		ReaderWriter<String> stream = new StringReaderWriter(in, out);
-
-		String inputLine;
-		List<String> outputLine;
-
-		if (protocol.whoTalksFirst() == TALK_FIRST.SERVER) {
-			outputLine = protocol.processMessage(null);
-			stream.write(outputLine);
-			for (String s : outputLine) {
-				log.write(createRecord(TYPE.SEND, s));
-			}
-		}
-
-		while (!thread.isInterrupted() && (inputLine = stream.read()) != null) {
-			log.write(createRecord(TYPE.RECEIVE, inputLine));
-			outputLine = protocol.processMessage(inputLine);
-			if (outputLine != null) {
-				stream.write(outputLine);
-				for (String s : outputLine) {
-					log.write(createRecord(TYPE.SEND, s));
-				}
-			}
-			if (protocol.isClosed()) {
-				break;
-			}
-		}
-	}
-
-}

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

@@ -7,13 +7,14 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.List;
 
-import de.tudarmstadt.informatik.hostage.wrapper.ByteArray;
+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<ByteArray> {
+public class ByteArrayReaderWriter implements ReaderWriter {
 
 	private BufferedInputStream in;
 	private BufferedOutputStream out;
@@ -32,7 +33,7 @@ public class ByteArrayReaderWriter implements ReaderWriter<ByteArray> {
 	}
 
 	
-	public ByteArray read() throws IOException {
+	public Packet read() throws IOException {
 		int availableBytes;
 		while((availableBytes = in.available()) <= 0) {
 			try {
@@ -43,13 +44,13 @@ public class ByteArrayReaderWriter implements ReaderWriter<ByteArray> {
 		}
 		byte[] buffer = new byte[availableBytes];
 		in.read(buffer);
-		return new ByteArray(buffer);
+		return new Packet(buffer);
 	}
 
 	
-	public void write(List<ByteArray> message) throws IOException {
-		for (ByteArray m : message) {
-			out.write(m.get());
+	public void write(List<Packet> outputLine) throws IOException {
+		for (Packet o : outputLine) {
+			out.write(o.getMessage());
 			out.flush();
 		}
 	}

+ 6 - 5
src/de/tudarmstadt/informatik/hostage/io/ReaderWriter.java

@@ -2,26 +2,27 @@ 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 
- *
- * @param <T>
+ * @author Wulf Pfeiffer
  */
-public interface ReaderWriter<T> {
+public interface ReaderWriter {
 	/**
 	 * Method to read from a medium.
 	 * @return Returns the output.
 	 * @throws IOException
 	 */
-	T read() throws IOException;
+	Packet read() throws IOException;
 
 	/**
 	 * Method to write to a medium.
 	 * @param outputLine The input to write.
 	 * @throws IOException
 	 */
-	void write(List<T> outputLine) throws IOException;
+	void write(List<Packet> outputLine) throws IOException;
 
 }

+ 9 - 6
src/de/tudarmstadt/informatik/hostage/io/StringReaderWriter.java

@@ -9,11 +9,14 @@ 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<String> {
+public class StringReaderWriter implements ReaderWriter {
 
 	private BufferedReader in;
 	private BufferedWriter out;
@@ -30,14 +33,14 @@ public class StringReaderWriter implements ReaderWriter<String> {
 	}
 
 	
-	public String read() throws IOException {
-		return in.readLine();
+	public Packet read() throws IOException {
+		return new Packet(in.readLine());
 	}
 
 	
-	public void write(List<String> message) throws IOException {
-		for (String m : message) {
-			out.write(m + "\n");
+	public void write(List<Packet> outputLine) throws IOException {
+		for (Packet o : outputLine) {
+			out.write(o + "\n");
 			out.flush();
 		}
 	}

+ 0 - 645
src/de/tudarmstadt/informatik/hostage/logging/DatabaseHandler.java

@@ -1,645 +0,0 @@
-package de.tudarmstadt.informatik.hostage.logging;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.util.Log;
-import de.tudarmstadt.informatik.hostage.R;
-import de.tudarmstadt.informatik.hostage.logging.Record.TYPE;
-import de.tudarmstadt.informatik.hostage.protocol.Protocol;
-import de.tudarmstadt.informatik.hostage.ui.LogFilter;
-/**
- * This class creates SQL tables and handles all access to the database.<br>
- * It contains several methods with predefined queries to extract different kinds of information from the database.<br>
- * The database contains two tables: {@link #TABLE_RECORDS} and {@link #TABLE_BSSIDS}:<br>
- * {@link #TABLE_RECORDS} contains all logging information of a single message record except the SSID.<br>
- * {@link #TABLE_BSSIDS} contains the BSSID of all recorded Networks and the corresponding SSID.<br>
- * @author Lars Pandikow
- */
-public class DatabaseHandler extends SQLiteOpenHelper {
-
-	// All Static variables
-	// Database Version
-	private static final int DATABASE_VERSION = 1;
-
-	// Database Name
-	private static final String DATABASE_NAME = "recordManager";
-
-	// Contacts table names
-	private static final String TABLE_ATTACK_INFO = "attack_info";
-	private static final String TABLE_RECORDS = "records";
-	private static final String TABLE_BSSIDS = "bssids";
-	private static final String TABLE_PORTS = "ports";
-
-	// Contacts Table Columns names
-	private static final String KEY_ID = "_id";
-	private static final String KEY_ATTACK_ID = "_attack_id";
-	private static final String KEY_TYPE = "type";
-	private static final String KEY_TIME = "timestamp";
-	private static final String KEY_PACKET = "packet";
-	private static final String KEY_PROTOCOL = "protocol";
-	private static final String KEY_EXTERNAL_IP ="externalIP";
-	private static final String KEY_LOCAL_IP = "localIP";
-	private static final String KEY_LOCAL_HOSTNAME = "localHostName";
-	private static final String KEY_LOCAL_PORT = "localPort";
-	private static final String KEY_REMOTE_IP = "remoteIP";
-	private static final String KEY_REMOTE_HOSTNAME = "remoteHostName";
-	private static final String KEY_REMOTE_PORT = "remotePort";
-	private static final String KEY_BSSID = "_bssid";
-	private static final String KEY_SSID = "ssid";
-	private static final String KEY_LATITUDE = "latitude";
-	private static final String KEY_LONGITUDE = "longitude";
-	private 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_REMOTE_IP + " BLOB," + KEY_REMOTE_HOSTNAME + " TEXT," + KEY_REMOTE_PORT + " INTEGER," + KEY_BSSID + " TEXT," 
-			+ "FOREIGN KEY("+ KEY_BSSID +") REFERENCES " + TABLE_BSSIDS + "("+KEY_BSSID+")" 
-			+ "FOREIGN KEY("+ KEY_PROTOCOL +") REFERENCES " + TABLE_PORTS + "("+KEY_PROTOCOL+")" 
-			+ ")";
-	
-	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"
-			+ ")";
-	
-	private static final String CREATE_PORT_TABLE = "CREATE TABLE " + TABLE_PORTS + "(" 
-			+ KEY_PROTOCOL + " TEXT PRIMARY KEY," + KEY_LOCAL_PORT + " INTEGER"
-			+ ")";
-
-	private Context context;
-	
-	public DatabaseHandler(Context context) {
-		super(context, DATABASE_NAME, null, DATABASE_VERSION);
-		this.context = context;
-	}
-
-	// Creating Tables
-	@Override
-	public void onCreate(SQLiteDatabase db) {
-		db.execSQL(CREATE_PORT_TABLE);
-		db.execSQL(CREATE_BSSID_TABLE);
-		db.execSQL(CREATE_ATTACK_INFO_TABLE);
-		db.execSQL(CREATE_RECORD_TABLE);
-				
-		String[] protocols = context.getResources().getStringArray(R.array.protocols);
-		String packageName = Protocol.class.getPackage().getName();
-
-		//Initialize Port Table
-		for (String protocol : protocols) {
-			try {				
-				int port = ((Protocol<?>) Class.forName(String.format("%s.%s", packageName, protocol)).newInstance()).getPort();
-		        db.execSQL("INSERT INTO " + TABLE_PORTS + " VALUES ( '" + protocol + "'," + port + ")");
-			} catch (Exception e) {
-				e.printStackTrace();
-			}
-		}
-	}
-	
-	// 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);
-		db.execSQL("DROP TABLE IF EXISTS " + TABLE_PORTS);
-		
-		// Create tables again
-		onCreate(db);
-	}
-
-	/**
-	 * Adds a given {@link Record}  to the database.
-	 * @param record The added {@link Record} .
-	 */
-	public void addRecord(Record record) {
-		SQLiteDatabase db = this.getWritableDatabase();
-
-		ContentValues bssidValues = new ContentValues();
-		bssidValues.put(KEY_BSSID, record.getBSSID());
-		bssidValues.put(KEY_SSID, record.getSSID());
-		bssidValues.put(KEY_LATITUDE, record.getLatitude());
-		bssidValues.put(KEY_LONGITUDE, record.getLongitude());
-		bssidValues.put(KEY_ACCURACY, record.getAccuracy());
-		
-		ContentValues attackValues = new ContentValues();
-		attackValues.put(KEY_ATTACK_ID, record.getAttack_id()); // Log Attack ID
-		attackValues.put(KEY_PROTOCOL, record.getProtocol().toString());
-		attackValues.put(KEY_EXTERNAL_IP, record.getExternalIP());
-		attackValues.put(KEY_LOCAL_IP, record.getLocalIP().getAddress()); // Log Local IP
-		attackValues.put(KEY_LOCAL_HOSTNAME, record.getLocalIP().getHostName());
-		attackValues.put(KEY_REMOTE_IP, record.getRemoteIP().getAddress()); // Log Remote IP
-		attackValues.put(KEY_REMOTE_HOSTNAME, record.getRemoteIP().getHostName());
-		attackValues.put(KEY_REMOTE_PORT, record.getRemotePort()); // Log Remote Port
-		attackValues.put(KEY_BSSID, record.getBSSID());
-		
-		ContentValues recordValues = new ContentValues();
-		recordValues.put(KEY_ID, record.getId()); // Log Message Number
-		recordValues.put(KEY_ATTACK_ID, record.getAttack_id()); // Log Attack ID
-		recordValues.put(KEY_TYPE, record.getType().name()); // Log Type
-		recordValues.put(KEY_TIME, record.getTimestamp()); // Log Timestamp
-		recordValues.put(KEY_PACKET, record.getPacket()); // Log Packet
-		
-
-		// Inserting Rows
-		db.insertWithOnConflict(TABLE_BSSIDS, null, bssidValues, SQLiteDatabase.CONFLICT_REPLACE);
-		db.insertWithOnConflict(TABLE_ATTACK_INFO, null, attackValues, SQLiteDatabase.CONFLICT_REPLACE);
-		db.insert(TABLE_RECORDS, null, recordValues);
-		db.close(); // Closing database connection
-	}
-	
-	/**
-	 * 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();
-		try {
-		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(InetAddress.getByAddress(cursor.getString(8), cursor.getBlob(7)));
-		record.setRemoteIP(InetAddress.getByAddress(cursor.getString(10), cursor.getBlob(9)));
-		record.setRemotePort(Integer.parseInt(cursor.getString(11)));
-		record.setBSSID(cursor.getString(12));
-		record.setSSID(cursor.getString(13));
-		record.setLatitude(Double.parseDouble(cursor.getString(14)));
-		record.setLongitude(Double.parseDouble(cursor.getString(15)));
-		record.setAccuracy(Float.parseFloat(cursor.getString(16)));
-		record.setLocalPort(Integer.parseInt(cursor.getString(17)));
-		} catch (UnknownHostException e) {
-			e.printStackTrace();
-		}
-		return record;
-	}
-
-	/**
-	 * 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 Record getRecord(int id) {
-		String selectQuery = "SELECT  * FROM " + TABLE_RECORDS + " NATURAL JOIN " + TABLE_ATTACK_INFO + " NATURAL JOIN " + TABLE_BSSIDS + " NATURAL JOIN " + TABLE_PORTS + " WHERE " + KEY_ID + " = " + id;
-		SQLiteDatabase db = this.getReadableDatabase();
-
-		Cursor cursor = db.rawQuery(selectQuery, null);
-		Record record = null;
-		if (cursor.moveToFirst()){
-			record = createRecord(cursor);
-		} 
-		
-        cursor.close();
-		db.close();
-		// return contact
-		return record;
-	}
-
-	/**
-	 * Gets all {@link Record Records} saved in the database. 
-	 * @return A ArrayList of all the {@link Record Records} in the Database.
-	 */
-	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 + " NATURAL JOIN " + TABLE_PORTS;
-
-		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();
-		db.close();
-		// return record list
-		return recordList;
-	}
-    
-	/**
-	 * Gets a single {@link Record} with the given attack id from the database.
-	 * @param attack_id The attack id of the {@link Record};
-	 * @return The {@link Record}.
-	 */
-    public Record getRecordOfAttackId(long attack_id) {
-        String selectQuery = "SELECT  * FROM " + TABLE_RECORDS + " NATURAL JOIN " + TABLE_ATTACK_INFO + " NATURAL JOIN " + TABLE_BSSIDS + " NATURAL JOIN " + TABLE_PORTS + " WHERE " + KEY_ATTACK_ID + " = " + attack_id + " GROUP BY " + KEY_ATTACK_ID;
-        SQLiteDatabase db = this.getReadableDatabase();
-        Cursor cursor = db.rawQuery(selectQuery, null);
-        Record record = null;
-        
-		if (cursor.moveToFirst()) {
-				record = createRecord(cursor);
-		}
-        cursor.close();
- 
-        // return record list
-        db.close();
-        return record;
-    }
-    
-	/**
-	 * Gets all received {@link Record Records} for every attack identified by its attack id and ordered by date.
-	 * @return A ArrayList with all received {@link Record Records} for each attack id in the Database.
-	 */
-    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 + " NATURAL JOIN " + TABLE_PORTS + " WHERE " + KEY_TYPE + "='RECEIVE'" + " ORDER BY " + KEY_TIME;
-        SQLiteDatabase db = this.getReadableDatabase();
-        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 record list
-        db.close();
-        return recordList;
-    }
-    
-    
-    /*
-    // Contacts Table Columns names
-	private static final String KEY_ID = "_id";
-	private static final String KEY_ATTACK_ID = "_attack_id";
-	private static final String KEY_TYPE = "type";
-	private static final String KEY_TIME = "timestamp";
-	private static final String KEY_PACKET = "packet";
-	private static final String KEY_PROTOCOL = "protocol";
-	private static final String KEY_EXTERNAL_IP ="externalIP";
-	private static final String KEY_LOCAL_IP = "localIP";
-	private static final String KEY_LOCAL_HOSTNAME = "localHostName";
-	private static final String KEY_LOCAL_PORT = "localPort";
-	private static final String KEY_REMOTE_IP = "remoteIP";
-	private static final String KEY_REMOTE_HOSTNAME = "remoteHostName";
-	private static final String KEY_REMOTE_PORT = "remotePort";
-	private static final String KEY_BSSID = "_bssid";
-	private static final String KEY_SSID = "ssid";
-	private static final String KEY_LATITUDE = "latitude";
-	private static final String KEY_LONGITUDE = "longitude";
-	private static final String KEY_ACCURACY = "accuracy";
-	*/
-    
-	/**
-	 * Gets all received {@link Record Records} for the specified information in the LogFilter ordered by date.
-	 * @return A ArrayList with all received {@link Record Records} for the LogFilter.
-	 */
-    public ArrayList<Record> getRecordsForFilter(LogFilter filter) {
-    	ArrayList<Record> recordList = new ArrayList<Record>();
-        String selectQuery = "SELECT  * FROM " + TABLE_RECORDS + " NATURAL JOIN " + TABLE_ATTACK_INFO + " NATURAL JOIN " + TABLE_BSSIDS + " NATURAL JOIN " + TABLE_PORTS;
-
-        // TIMESTAMPS
-        selectQuery = selectQuery + " WHERE " + KEY_TIME;
-        selectQuery = selectQuery + " < " + filter.getBelowTimestamp();
-        selectQuery = selectQuery + " AND " + KEY_TIME;
-        selectQuery = selectQuery + " > " + filter.getAboveTimestamp();
-        
-        if (filter.getBSSIDs() != null && filter.getBSSIDs().size() > 0) {
-            selectQuery = selectQuery + " AND ";
-            selectQuery = selectQuery + filter.getBSSIDQueryStatement(KEY_BSSID);
-		}
-        if (filter.getESSIDs() != null && filter.getESSIDs().size() > 0) {
-            selectQuery = selectQuery + " AND ";
-            selectQuery = selectQuery + filter.getESSIDQueryStatement(KEY_SSID);
-		}
-        if (filter.getProtocols() != null && filter.getProtocols().size() > 0) {
-            selectQuery = selectQuery + " AND ";
-            selectQuery = selectQuery + filter.getProtocolsQueryStatement(KEY_PROTOCOL);
-		}
-
-        
-        // ORDERED BY TIME
-        selectQuery = selectQuery + " ORDER BY " + filter.getSorttype();
-        System.out.println(selectQuery);
-        SQLiteDatabase db = this.getReadableDatabase();
-        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 record list
-        db.close();
-        return recordList;
-    }
-    
-    
-	/**
-	 * Gets all non duplicate Records For the key BSSID.
-	 * @return A ArrayList with received Records.
-	 */
-    public ArrayList<String> getUniqueBSSIDRecords(){
-    	return this.getUniqueDataEntryForKeyType(KEY_BSSID, TABLE_BSSIDS);
-    }
-	/**
-	 * Gets all non duplicate Records For the key ESSID.
-	 * @return A ArrayList with received Records.
-	 */
-    public ArrayList<String> getUniqueESSIDRecords(){
-    	return this.getUniqueDataEntryForKeyType(KEY_SSID, TABLE_BSSIDS);
-    }
-	/**
-	 * Gets all non duplicate Records For the key protocol.
-	 * @return A ArrayList with received Records.
-	 */
-    public ArrayList<String> getUniqueProtocolRecords(){
-    	return this.getUniqueDataEntryForKeyType(KEY_PROTOCOL, TABLE_PORTS);
-    }
-	/**
-	 * Gets all non duplicate Data Entry For a specific KeyType ( e.g. BSSIDs).
-	 * @return A ArrayList with received Records.
-	 */
-    public ArrayList<String> getUniqueDataEntryForKeyType(String keyType, String table) {
-    	ArrayList<String> recordList = new ArrayList<String>();
-        //String selectQuery = "SELECT  * FROM " + TABLE_RECORDS + " NATURAL JOIN " + TABLE_ATTACK_INFO + " NATURAL JOIN " + TABLE_BSSIDS + " NATURAL JOIN " + TABLE_PORTS;
-        String selectQuery = "SELECT DISTINCT " + keyType + " FROM " + table + " ORDER BY " + keyType; // " NATURAL JOIN " + TABLE_ATTACK_INFO + " NATURAL JOIN " + TABLE_BSSIDS + " NATURAL JOIN " + TABLE_PORTS +
-
-        
-        // ORDERED BY TIME
-        System.out.println(selectQuery);
-        SQLiteDatabase db = this.getReadableDatabase();
-        Cursor cursor = db.rawQuery(selectQuery, null);
-		
-        // looping through all rows and adding to list
-		if (cursor.moveToFirst()) {
-			do {
-				String record = cursor.getString(0);
-				recordList.add(record);
-			} while (cursor.moveToNext());
-		}       
-        cursor.close();
- 
-        // return record list
-        db.close();
-        return recordList;
-    }
-    
-	/**
-	 * Gets a representative {@link Record} for every attack identified by its attack id.
-	 * @return A ArrayList with one {@link Record Records} for each attack id in the Database.
-	 */
-    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 + " NATURAL JOIN " + TABLE_PORTS + " GROUP BY " + KEY_ATTACK_ID;
-        SQLiteDatabase db = this.getReadableDatabase();
-        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 record list
-        db.close();
-        return recordList;
-    }
-    
-	/**
-	 * Gets a representative {@link Record} for every attack with a higher attack id than the specified.
-	 * @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 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 + " NATURAL JOIN " + TABLE_PORTS + " WHERE " + KEY_ATTACK_ID + " > " + attack_id + " GROUP BY " + KEY_ATTACK_ID;
-        SQLiteDatabase db = this.getReadableDatabase();
-        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;
-    }
-	
-	/**
-	 * 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.
-	 * @return The number of different attack_ids in the database.
-	 */
-    public int getAttackCount() {
-        String countQuery = "SELECT  * FROM " + TABLE_ATTACK_INFO;
-        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 for a specific protocol in the database.
-	 * @param protocol The String representation of the {@link de.tudarmstadt.informatik.hostage.protocol.Protocol Protocol}
-	 * @return The number of different attack_ids in the database.
-	 */
-    public int getAttackPerProtokolCount(String protocol) {
-        String countQuery = "SELECT  * FROM " + TABLE_ATTACK_INFO + " WHERE " + KEY_PROTOCOL + " = " + "'" + protocol + "'";
-        SQLiteDatabase db = this.getReadableDatabase();
-        Cursor cursor = db.rawQuery(countQuery, null);
-        int result = cursor.getCount();
-        cursor.close();
- 
-        // return count
-        db.close();
-        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.
-     * @return The highest attack id stored in the database.
-     */
-    public long getHighestAttackId(){
-    	String selectQuery = "SELECT MAX(" + 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 if an attack has been recorded on a specific protocol in a network with a given BSSID.
-     * @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 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(countQuery, null);
-        int result = cursor.getCount();
-        cursor.close();
-        db.close();
-        return result > 0;        
-    }
-    
-    /**
-     * Returns a String array with all BSSIDs stored in the database.
-     * @return String[] of all recorded BSSIDs.
-     */
-    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 {
-				bssidList[counter] = cursor.getString(0);
-				counter++;
-			} while (cursor.moveToNext());
-		}       
-        cursor.close();
-        db.close();
-        return bssidList;
-    }
-    
-    /**
-     * 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 String getSSID(String bssid){
-    	String selectQuery = "SELECT "+ KEY_SSID +" FROM " + TABLE_BSSIDS + " WHERE " + KEY_BSSID + " = " + "'" + bssid + "'";
-    	SQLiteDatabase db = this.getReadableDatabase();
-    	Cursor cursor = db.rawQuery(selectQuery, null);
-    	String ssid = null;
-    	if(cursor.moveToFirst()){
-    		ssid = cursor.getString(0);
-    	}
-        cursor.close();
-        db.close();
-        return ssid;
-    }
-    
-    /**
-     * Deletes all records from {@link #TABLE_RECORDS} with a specific BSSID.
-     * @param bssid The BSSID to match against.
-     */
-    public void deleteByBSSID(String bssid){
-    	SQLiteDatabase db = this.getReadableDatabase();
-    	db.delete(TABLE_RECORDS, KEY_BSSID + " = ?", new String[]{bssid});
-    	db.delete(TABLE_ATTACK_INFO, KEY_BSSID + " = ?", new String[]{bssid});
-    	db.close();
-    }
-
-    /**
-     * 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();
-    }
-    
-    /**
-     *  Deletes all records from {@link #TABLE_RECORDS}.
-     */
-    public void clearData(){
-    	SQLiteDatabase db = this.getReadableDatabase();
-        db.delete(TABLE_RECORDS, null, null);
-        db.delete(TABLE_ATTACK_INFO, null, null);
-        db.close();
-    }
-}

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

@@ -0,0 +1,30 @@
+package de.tudarmstadt.informatik.hostage.logging;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.ResultReceiver;
+
+public class LogResultReceiver extends ResultReceiver {
+
+	private Receiver mReceiver;
+
+	public void setReceiver(Receiver receiver) {
+		mReceiver = receiver;
+	}
+
+	public LogResultReceiver(Handler handler) {
+		super(handler);
+	}
+
+	public interface Receiver {
+		public void onReceiveResult(int resultCode, Bundle resultData);
+	}
+
+	@Override
+	protected void onReceiveResult(int resultCode, Bundle resultData) {
+		if (mReceiver != null) {
+			mReceiver.onReceiveResult(resultCode, resultData);
+		}
+	}
+
+}

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

@@ -1,90 +1,321 @@
 package de.tudarmstadt.informatik.hostage.logging;
 
 import java.util.ArrayList;
+
+import android.app.IntentService;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.ResultReceiver;
+
 /**
- * Interface to define which functionality is needed for a Logger in this application.
- * @author Mihai Plasoianu 
- * @author Lars Pandikow
- *
+ * An {@link IntentService} subclass for handling asynchronous task requests in
+ * a service on a separate handler thread.
+ * 
+ * @author Mihai Plasoianu
  */
-public interface Logger {
-	/**
-	 * Write a single Record to the log.
-	 * @param record The Record that has to be added.
-	 */
-	void write(Record record);
-	
-	/**
-	 * Returns all saved Records.
-	 * @return ArrayList which contains all Records from the log.
-	 */
-	ArrayList<Record> getAllRecords();
-	/**
-	 * Returns a single Record as representative for each attack with an attack id higher then the given.
-	 * @param lastUploadedAttackId The threshold value for attack id's
-	 * @return ArrayList which contains one Record for each attack.
-	 */
-	ArrayList<Record> getRecordOfEachAttack(int lastUploadedAttackId);
-	/**
-	 * 
-	 * @param attack_id Attack id of the record
-	 * @return A Record with a specific attack id, or null if there is no Record with such an attack id.
-	 */
-	Record getRecordOfAttackId(long attack_id);
-	
-	/**
-	 * Determines the number of recorded attacks.
-	 * @return he Number of Attacks.
-	 */
-	int getAttackCount();	
-	/**
-	 * Returns the number of recorded attack for a specific protocol.
-	 * @param protocol The considered protocol.
-	 * @return The Number of recorded attacks per protocol.
-	 */
-	int getAttackPerProtokolCount(String protocol);
-	/**
-	 * Finds the smallest saved attack id.
-	 * @return The smallest saved attack id.
-	 */
-	long getSmallestAttackId();
-	/**
-	 * Finds the highest saved attack id.
-	 * @return The highest saved attack id.
-	 */
-	long getHighestAttackId();
-	
-	/**
-	 * Determines if an attack on a given protocol has already been recorded in a network with a specific BSSID.
-	 * @param protocol The considered protocol.
-	 * @param bssid The considered BSSID.
-	 * @return True if there has been a attack on a protocol in a network with the given BSSID, else returns false.
-	 */
-	boolean bssidSeen(String protocol, String bssid);
-	/**
-	 * Returns all BSSIDs in which an attack has been recorded.
-	 * @return String arrays with all recorded BSSIDs
-	 */
-	String[] getAllBSSIDS();
-	/**
-	 * Returns the last known SSID of a network with a specific BSSID.
-	 * @param bssid The considered BSSID.
-	 * @return String representation of the searched SSID, or null if there is no entry with the given BSSID
-	 */
-	String getSSID(String bssid);
-	
-	/**
-	 * Deletes all Records with a smaller time stamp than the given.
-	 * @param time The time stamp to compare with.
-	 */
-	void deleteByDate(long time);
+public class Logger extends IntentService {
+
+	private static final String ACTION_LOG = "de.tudarmstadt.informatik.hostage.action.LOG";
+	private static final String ACTION_GET_RECORD_ALL = "de.tudarmstadt.informatik.hostage.action.GET_RECORD_ALL";
+	private static final String ACTION_GET_RECORD_EACH = "de.tudarmstadt.informatik.hostage.action.GET_RECORD_EACH";
+	private static final String ACTION_GET_RECORD_ID = "de.tudarmstadt.informatik.hostage.action.GET_RECORD_ID";
+	private static final String ACTION_GET_COUNT_ALL = "de.tudarmstadt.informatik.hostage.action.GET_COUNT_ALL";
+	private static final String ACTION_GET_COUNT_PROTOCOL = "de.tudarmstadt.informatik.hostage.action.GET_COUNT_PROTOCOL";
+	private static final String ACTION_GET_ATTACK_MIN = "de.tudarmstadt.informatik.hostage.action.GET_ATTACK_MIN";
+	private static final String ACTION_GET_ATTACK_MAX = "de.tudarmstadt.informatik.hostage.action.GET_ATTACK_MAX";
+	private static final String ACTION_IS_BSSID_SEEN = "de.tudarmstadt.informatik.hostage.action.IS_BSSID_SEEN";
+	private static final String ACTION_GET_BSSID_ALL = "de.tudarmstadt.informatik.hostage.action.GET_BSSID_ALL";
+	private static final String ACTION_GET_SSID_BSSID = "de.tudarmstadt.informatik.hostage.action.GET_SSID_BSSID";
+	private static final String ACTION_CLEAR_DATE = "de.tudarmstadt.informatik.hostage.action.CLEAR_DATE";
+	private static final String ACTION_CLEAR_BSSID = "de.tudarmstadt.informatik.hostage.action.CLEAR_BSSID";
+	private static final String ACTION_CLEAR_ALL = "de.tudarmstadt.informatik.hostage.action.CLEAR_ALL";
+
+	private static final String EXTRA_RECORD = "de.tudarmstadt.informatik.hostage.extra.RECORD";
+	private static final String EXTRA_PROTOCOL = "de.tudarmstadt.informatik.hostage.extra.PROTOCOL";
+	private static final String EXTRA_BSSID = "de.tudarmstadt.informatik.hostage.extra.BSSID";
+	private static final String EXTRA_PRIMITIVE = "de.tudarmstadt.informatik.hostage.extra.PRIMITIVE";
+
+	private static final String RESULT_RECEIVER = "de.tudarmstadt.informatik.hostage.RESULT_RECEIVER";
+
+	public static void log(Context context, Record record) {
+		Intent intent = new Intent(context, Logger.class);
+		intent.setAction(ACTION_LOG);
+		intent.putExtra(EXTRA_RECORD, record);
+		context.startService(intent);
+	}
+
+	public static void getAllRecords(Context context, ResultReceiver receiver) {
+		Intent intent = new Intent(context, Logger.class);
+		intent.setAction(ACTION_GET_RECORD_ALL);
+		intent.putExtra(RESULT_RECEIVER, receiver);
+		context.startService(intent);
+	}
+
+	public static void getRecordOfEachAttack(Context context,
+			int lastUploadedAttackId, ResultReceiver receiver) {
+		Intent intent = new Intent(context, Logger.class);
+		intent.setAction(ACTION_GET_RECORD_EACH);
+		intent.putExtra(EXTRA_PRIMITIVE, lastUploadedAttackId);
+		intent.putExtra(RESULT_RECEIVER, receiver);
+		context.startService(intent);
+	}
+
+	public static void getRecordOfAttackId(Context context, long attack_id,
+			ResultReceiver receiver) {
+		Intent intent = new Intent(context, Logger.class);
+		intent.setAction(ACTION_GET_RECORD_ID);
+		intent.putExtra(EXTRA_PRIMITIVE, attack_id);
+		intent.putExtra(RESULT_RECEIVER, receiver);
+		context.startService(intent);
+	}
+
+	public static void getAttackCount(Context context, ResultReceiver receiver) {
+		Intent intent = new Intent(context, Logger.class);
+		intent.setAction(ACTION_GET_COUNT_ALL);
+		intent.putExtra(RESULT_RECEIVER, receiver);
+		context.startService(intent);
+	}
+
+	public static void getAttackPerProtocolCount(Context context,
+			String protocol, ResultReceiver receiver) {
+		Intent intent = new Intent(context, Logger.class);
+		intent.setAction(ACTION_GET_COUNT_PROTOCOL);
+		intent.putExtra(EXTRA_PROTOCOL, protocol);
+		intent.putExtra(RESULT_RECEIVER, receiver);
+		context.startService(intent);
+	}
+
+	public static void getMinAttackId(Context context, ResultReceiver receiver) {
+		Intent intent = new Intent(context, Logger.class);
+		intent.setAction(ACTION_GET_ATTACK_MIN);
+		intent.putExtra(RESULT_RECEIVER, receiver);
+		context.startService(intent);
+	}
+
+	public static void getMaxAttackId(Context context, ResultReceiver receiver) {
+		Intent intent = new Intent(context, Logger.class);
+		intent.setAction(ACTION_GET_ATTACK_MAX);
+		intent.putExtra(RESULT_RECEIVER, receiver);
+		context.startService(intent);
+	}
+
+	public static void isBssidSeen(Context context, String protocol,
+			String bssid, 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.putExtra(RESULT_RECEIVER, receiver);
+		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 getSsid(Context context, String bssid,
+			ResultReceiver receiver) {
+		Intent intent = new Intent(context, Logger.class);
+		intent.setAction(ACTION_GET_SSID_BSSID);
+		intent.putExtra(EXTRA_BSSID, bssid);
+		intent.putExtra(RESULT_RECEIVER, receiver);
+		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) {
+		Intent intent = new Intent(context, Logger.class);
+		intent.setAction(ACTION_CLEAR_BSSID);
+		intent.putExtra(EXTRA_BSSID, bssid);
+		context.startService(intent);
+	}
+
+	public static void deleteAll(Context context) {
+		Intent intent = new Intent(context, Logger.class);
+		intent.setAction(ACTION_CLEAR_ALL);
+		context.startService(intent);
+	}
+
+	private UglyDbHelper mDbHelper;
+
+	public Logger() {
+		super("Logger");
+	}
+
+	@Override
+	public void onCreate() {
+		super.onCreate();
+		mDbHelper = new UglyDbHelper(getApplicationContext());
+	}
+
+	@Override
+	protected void onHandleIntent(Intent intent) {
+		if (intent != null) {
+			final String action = intent.getAction();
+			if (ACTION_LOG.equals(action)) {
+				final Record record = intent.getParcelableExtra(EXTRA_RECORD);
+				handleActionLog(record);
+			} else if (ACTION_GET_RECORD_ALL.equals(action)) {
+				ResultReceiver receiver = intent
+						.getParcelableExtra(RESULT_RECEIVER);
+				ArrayList<Record> r = handleActionGetAllRecords();
+				Bundle result = new Bundle();
+				result.putParcelableArrayList("result", r);
+				receiver.send(0, result);
+			} else if (ACTION_GET_RECORD_EACH.equals(action)) {
+				final int lastUploadedAttackId = intent.getIntExtra(
+						EXTRA_PRIMITIVE, -1);
+				ResultReceiver receiver = intent
+						.getParcelableExtra(RESULT_RECEIVER);
+				ArrayList<Record> r = handleActionGetRecordOfEachAttack(lastUploadedAttackId);
+				Bundle result = new Bundle();
+				result.putParcelableArrayList("result", r);
+				receiver.send(0, result);
+			} else if (ACTION_GET_RECORD_ID.equals(action)) {
+				final int attack_id = intent.getIntExtra(EXTRA_PRIMITIVE, -1);
+				ResultReceiver receiver = intent
+						.getParcelableExtra(RESULT_RECEIVER);
+				Record r = handleActionGetRecordOfAttackId(attack_id);
+				Bundle result = new Bundle();
+				result.putParcelable("result", r);
+				receiver.send(0, result);
+			} else if (ACTION_GET_COUNT_ALL.equals(action)) {
+				ResultReceiver receiver = intent
+						.getParcelableExtra(RESULT_RECEIVER);
+				int r = handleActionGetAttackCount();
+				Bundle result = new Bundle();
+				result.putInt("result", r);
+				receiver.send(0, result);
+			} else if (ACTION_GET_COUNT_PROTOCOL.equals(action)) {
+				final String protocol = intent.getStringExtra(EXTRA_PROTOCOL);
+				ResultReceiver receiver = intent
+						.getParcelableExtra(RESULT_RECEIVER);
+				int r = handleActionGetAttackPerProtocolCount(protocol);
+				Bundle result = new Bundle();
+				result.putInt("result", r);
+				receiver.send(0, result);
+			} else if (ACTION_GET_ATTACK_MIN.equals(action)) {
+				ResultReceiver receiver = intent
+						.getParcelableExtra(RESULT_RECEIVER);
+				long r = handleActionGetMinAttackId();
+				Bundle result = new Bundle();
+				result.putLong("result", r);
+				receiver.send(0, result);
+				handleActionGetMinAttackId();
+			} else if (ACTION_GET_ATTACK_MAX.equals(action)) {
+				ResultReceiver receiver = intent
+						.getParcelableExtra(RESULT_RECEIVER);
+				long r = handleActionGetMaxAttackId();
+				Bundle result = new Bundle();
+				result.putLong("result", r);
+				receiver.send(0, result);
+			} else if (ACTION_IS_BSSID_SEEN.equals(action)) {
+				final String protocol = intent.getStringExtra(EXTRA_PROTOCOL);
+				final String bssid = intent.getStringExtra(EXTRA_BSSID);
+				ResultReceiver receiver = intent
+						.getParcelableExtra(RESULT_RECEIVER);
+				boolean r = handleActionBssidSeen(protocol, bssid);
+				Bundle result = new Bundle();
+				result.putBoolean("result", r);
+				receiver.send(0, result);
+			} else if (ACTION_GET_BSSID_ALL.equals(action)) {
+				ResultReceiver receiver = intent
+						.getParcelableExtra(RESULT_RECEIVER);
+				String[] r = handleActionGetAllBssids();
+				Bundle result = new Bundle();
+				result.putStringArray("result", r);
+				receiver.send(0, result);
+			} else if (ACTION_GET_SSID_BSSID.equals(action)) {
+				final String bssid = intent.getStringExtra(EXTRA_BSSID);
+				ResultReceiver receiver = intent
+						.getParcelableExtra(RESULT_RECEIVER);
+				String r = handleActionGetSsid(bssid);
+				Bundle result = new Bundle();
+				result.putString("result", r);
+				receiver.send(0, result);
+			} else if (ACTION_CLEAR_DATE.equals(action)) {
+				final long time = intent.getLongExtra(EXTRA_PRIMITIVE, -1L);
+				handleActionDeleteByDate(time);
+			} else if (ACTION_CLEAR_BSSID.equals(action)) {
+				final String bssid = intent.getStringExtra(EXTRA_BSSID);
+				handleActionDeleteByBssid(bssid);
+			} else if (ACTION_CLEAR_ALL.equals(action)) {
+				handleActionDeleteAll();
+			}
+		}
+	}
+
 	/**
-	 * Deletes all Record which contain the given BSSID.
-	 * @param bssid The BSSID to compare with.
+	 * Log a record.
 	 */
-	void deleteByBSSID(String bssid);
+	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);
+	}
+
 	/**
-	 * Resets complete log file.
+	 * Delete all records.
 	 */
-	void clearData();
+	private void handleActionDeleteAll() {
+		mDbHelper.clearData();
+	}
+
 }

+ 38 - 10
src/de/tudarmstadt/informatik/hostage/logging/MyLocationManager.java

@@ -9,27 +9,27 @@ import android.location.LocationListener;
 import android.location.LocationManager;
 import android.os.Bundle;
 import android.util.Log;
-import android.widget.Toast;
 
 public class MyLocationManager {
 	
 	private LocationManager locationManager;
-	private static Location newestLocation;
-	private Context context;
-	
+	/**
+	 * Static variable that always holds the newest location update.
+	 */
+	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);
-		this.context = context;
 	}
 
 	// Define a listener that responds to location updates
 	LocationListener locationListener = new LocationListener() {
 	    public void onLocationChanged(Location location) {
-			Toast.makeText(context, location.getLatitude() +  " " + location.getLongitude() + " " + location.getAccuracy(), Toast.LENGTH_SHORT).show();
-
+	    	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)){
@@ -55,19 +55,38 @@ public class MyLocationManager {
 	          // 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;
@@ -90,10 +109,19 @@ public class MyLocationManager {
 	        	locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
 	  }
 	  
-	  public void getUpdates(long time){
+	  /**
+	   * 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 {

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

@@ -1,296 +1,290 @@
 package de.tudarmstadt.informatik.hostage.logging;
 
-import java.io.Serializable;
-import java.net.InetAddress;
-
-import de.tudarmstadt.informatik.hostage.format.LogViewFormatter;
+import android.os.Parcel;
+import android.os.Parcelable;
+import de.tudarmstadt.informatik.hostage.logging.formatter.Formatter;
 
 /**
  * This class defines the attributes of a record.<br>
- * A Record is a single message exchanged between the application and an attacker.<br>
- * The class has no own functionality except for getter and setter methods.
- * To change the logging mechanism you have to to change the logger in {@link de.tudarmstadt.informatik.hostage.HoneyService HoneyService} and 
+ * A Record is a single message exchanged between the application and an
+ * attacker.<br>
+ * The class has no own functionality except for getter and setter methods. To
+ * change the logging mechanism you have to to change the logger in
+ * {@link de.tudarmstadt.informatik.hostage.HoneyService HoneyService} and
  * {@link de.tudarmstadt.informatik.hostage.ui.ViewLog ViewLog}
- * @author Mihai Plasoianu 
+ * 
+ * @author Mihai Plasoianu
  * @author Lars Pandikow
  */
-public class Record implements Serializable {
-
-	private static final long serialVersionUID = 1L;
+public class Record implements Parcelable {
 
 	public static enum TYPE {
 		SEND, RECEIVE
 	};
 
+	// attack
 	private int id;
 	private long attack_id;
+	private long timestamp;
 	private String protocol;
 	private TYPE type;
-	private long timestamp;
-	private String externalIP;
-	private InetAddress localIP;
+	private String packet;
+
+	// network
+	private String localIP;
+	private String localHost;
 	private int localPort;
-	private InetAddress remoteIP;
+	private String remoteIP;
+	private String remoteHost;
 	private int remotePort;
-	private String BSSID;
-	private String SSID;
+	private String externalIP;
+	private String bssid;
+	private String ssid;
+
+	// location
+	private long timestampLocation;
 	private double latitude;
 	private double longitude;
 	private float accuracy;
-	private String packet;	
 
+	@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
+		public Record createFromParcel(Parcel source) {
+			return new Record(source);
+		}
+
+		@Override
+		public Record[] newArray(int size) {
+			return new Record[size];
+		}
+	};
+
+	public Record() {
+	}
+
+	public Record(Parcel source) {
+		// attack
+		this.id = source.readInt();
+		this.attack_id = source.readLong();
+		this.timestamp = source.readLong();
+		this.protocol = source.readString();
+		this.type = TYPE.valueOf(source.readString());
+		this.packet = source.readString();
+
+		// network
+		this.localIP = source.readString();
+		this.localHost = source.readString();
+		this.localPort = source.readInt();
+		this.remoteIP = source.readString();
+		this.remoteHost = source.readString();
+		this.remotePort = source.readInt();
+		this.externalIP = source.readString();
+		this.bssid = source.readString();
+		this.ssid = source.readString();
 
+		// location
+		this.timestampLocation = source.readLong();
+		this.latitude = source.readDouble();
+		this.longitude = source.readDouble();
+		this.accuracy = source.readFloat();
+	}
 
-	/**
-	 * @return the id
-	 */
 	public int getId() {
 		return id;
 	}
 
-	/**
-	 * @param id the id to set
-	 */
 	public void setId(int id) {
 		this.id = id;
 	}
 
-	/**
-	 * @return the attack_id
-	 */
 	public long getAttack_id() {
 		return attack_id;
 	}
 
-	/**
-	 * @param attack_id the attack_id to set
-	 */
 	public void setAttack_id(long attack_id) {
 		this.attack_id = attack_id;
 	}
 
-	/**
-	 * @return the protocol
-	 */
+	public long getTimestamp() {
+		return timestamp;
+	}
+
+	public void setTimestamp(long timestamp) {
+		this.timestamp = timestamp;
+	}
+
 	public String getProtocol() {
 		return protocol;
 	}
 
-	/**
-	 * @param protocol the protocol to set
-	 */
 	public void setProtocol(String protocol) {
 		this.protocol = protocol;
 	}
 
-	/**
-	 * @return the type
-	 */
 	public TYPE getType() {
 		return type;
 	}
 
-	/**
-	 * @param type the type to set
-	 */
 	public void setType(TYPE type) {
 		this.type = type;
 	}
 
-	/**
-	 * @return the timestamp
-	 */
-	public long getTimestamp() {
-		return timestamp;
+	public String getPacket() {
+		return packet;
 	}
 
-	/**
-	 * @param timestamp the timestamp to set
-	 */
-	public void setTimestamp(long timestamp) {
-		this.timestamp = timestamp;
+	public void setPacket(String packet) {
+		this.packet = packet;
 	}
 
-	/**
-	 * @return the externalIP
-	 */
-	public String getExternalIP() {
-		return externalIP;
+	public String getLocalIP() {
+		return localIP;
 	}
 
-	/**
-	 * @param externalIP the externalIP to set
-	 */
-	public void setExternalIP(String externalIP) {
-		this.externalIP = externalIP;
+	public void setLocalIP(String localIP) {
+		this.localIP = localIP;
 	}
 
-	/**
-	 * @return the localIP
-	 */
-	public InetAddress getLocalIP() {
-		return localIP;
+	public String getLocalHost() {
+		return localHost;
 	}
 
-	/**
-	 * @param localIP the localIP to set
-	 */
-	public void setLocalIP(InetAddress localIP) {
-		this.localIP = localIP;
+	public void setLocalHost(String localHost) {
+		this.localHost = localHost;
 	}
 
-	/**
-	 * @return the localPort
-	 */
 	public int getLocalPort() {
 		return localPort;
 	}
 
-	/**
-	 * @param localPort the localPort to set
-	 */
 	public void setLocalPort(int localPort) {
 		this.localPort = localPort;
 	}
 
-	/**
-	 * @return the remoteIP
-	 */
-	public InetAddress getRemoteIP() {
+	public String getRemoteIP() {
 		return remoteIP;
 	}
 
-	/**
-	 * @param remoteIP the remoteIP to set
-	 */
-	public void setRemoteIP(InetAddress remoteIP) {
+	public void setRemoteIP(String remoteIP) {
 		this.remoteIP = remoteIP;
 	}
 
-	/**
-	 * @return the remotePort
-	 */
+	public String getRemoteHost() {
+		return remoteHost;
+	}
+
+	public void setRemoteHost(String remoteHost) {
+		this.remoteHost = remoteHost;
+	}
+
 	public int getRemotePort() {
 		return remotePort;
 	}
 
-	/**
-	 * @param remotePort the remotePort to set
-	 */
 	public void setRemotePort(int remotePort) {
 		this.remotePort = remotePort;
 	}
 
-	/**
-	 * @return the bSSID
-	 */
-	public String getBSSID() {
-		return BSSID;
+	public String getExternalIP() {
+		return externalIP;
+	}
+
+	public void setExternalIP(String externalIP) {
+		this.externalIP = externalIP;
+	}
+
+	public String getBssid() {
+		return bssid;
+	}
+
+	public void setBssid(String bssid) {
+		this.bssid = bssid;
 	}
 
-	/**
-	 * @param bSSID the bSSID to set
-	 */
-	public void setBSSID(String bSSID) {
-		BSSID = bSSID;
+	public String getSsid() {
+		return ssid;
 	}
 
-	/**
-	 * @return the sSID
-	 */
-	public String getSSID() {
-		return SSID;
+	public void setSsid(String ssid) {
+		this.ssid = ssid;
 	}
 
-	/**
-	 * @param sSID the sSID to set
-	 */
-	public void setSSID(String sSID) {
-		SSID = sSID;
+	public long getTimestampLocation() {
+		return timestampLocation;
+	}
+
+	public void setTimestampLocation(long timestampLocation) {
+		this.timestampLocation = timestampLocation;
 	}
 
-	/**
-	 * @return the latitude
-	 */
 	public double getLatitude() {
 		return latitude;
 	}
 
-	/**
-	 * @param latitude the latitude to set
-	 */
 	public void setLatitude(double latitude) {
 		this.latitude = latitude;
 	}
 
-	/**
-	 * @return the longitude
-	 */
 	public double getLongitude() {
 		return longitude;
 	}
 
-	/**
-	 * @param longitude the longitude to set
-	 */
 	public void setLongitude(double longitude) {
 		this.longitude = longitude;
 	}
 
-	/**
-	 * @return the accuracy
-	 */
 	public float getAccuracy() {
 		return accuracy;
 	}
 
-	/**
-	 * @param accuracy the accuracy to set
-	 */
 	public void setAccuracy(float accuracy) {
 		this.accuracy = accuracy;
 	}
 
-	/**
-	 * @return the packet
-	 */
-	public String getPacket() {
-		return packet;
-	}
-
-	/**
-	 * @param packet the packet to set
-	 */
-	public void setPacket(String packet) {
-		this.packet = packet;
-	}
-
 	@Override
 	public String toString() {
-		return String.format("%d %s [%d,%s:%d,%s:%d,%s]", attack_id,
-				((type == TYPE.SEND) ? "SEND" : "RECEIVE"), timestamp,
-				localIP.getHostAddress(), localPort, remoteIP.getHostAddress(),
-				remotePort, LogViewFormatter.format(getProtocol(), getPacket()));
-	}
-	
-	/**
-	 * Returns a string representation after a chosen format. Formats should be defined in /res/values/arrays.xml to use with {@link de.tudarmstadt.informatik.hostage.ui.ViewLog#exportDatabase(android.view.View) exportDatabase(...)}
-	 * The Integer representation of the format is equal to its position in the format array.
-	 * @param format Integer representation of the format.
-	 * @return A string representation after chosen format.
-	 */
-	public String toString(int format){
-		// Choose String Format
-		switch (format){
-			// ViewLogTable format: contains all important information about an attack.
-			case 0: 
-				return String.format("%d: %s %s\nIn %s\n(%s)\nFrom [%s:%d]\nTo [%s:%d]\nLatitude: %f\nLongitude: %f\n%s\n\n", attack_id, protocol, ((type == TYPE.SEND) ? "SEND" : "RECEIVE"), SSID, BSSID, remoteIP.getHostAddress(), remotePort, localIP.getHostAddress(), localPort, getLatitude(), getLongitude(), LogViewFormatter.format(getProtocol(), getPacket()));	
-			// TraCINg Upload format, replaces internal ip's with external ip of network
-			case 1: 
-				return String.format("{ \"sensor\":{\"type\": \"Honeypot\", \"name\": \"HOsTaGe\"}, \"type\": \"%s\", \"src\":{\"ip\": \"%s\", \"port\": %d}, \"dst\":{\"ip\": \"%s\", \"port\": %d} }", protocol + " server access", externalIP, remotePort, externalIP, localPort);
-			default:
-				return toString();
+		return toString(null);
+	}
+
+	public String toString(Formatter formatter) {
+		if (null == formatter) {
+			return Formatter.getDefault().format(this);
 		}
+		return formatter.format(this);
 	}
-	
+
 }

+ 0 - 89
src/de/tudarmstadt/informatik/hostage/logging/SQLLogger.java

@@ -1,89 +0,0 @@
-package de.tudarmstadt.informatik.hostage.logging;
-
-import java.util.ArrayList;
-
-import android.content.Context;
-/**
- * Implementation of the Logger interface using the {@link DatabaseHandler} to create a SQL database.
- * @author Lars Pandikow
- *
- */
-public class SQLLogger implements Logger{
-	Context context;
-	DatabaseHandler dbh;
-	
-	public SQLLogger(Context context){
-		this.context = context;
-		dbh = new DatabaseHandler(context);	
-	}
-
-	
-	public synchronized void write(Record record) {
-		dbh.addRecord(record);
-	}
-
-	
-	public ArrayList<Record> getAllRecords() {
-		return dbh.getAllRecords();
-	}
-
-	
-	public ArrayList<Record> getRecordOfEachAttack(int lastUploadedAttackId) {
-		return dbh.getRecordOfEachAttack(lastUploadedAttackId);
-	}
-
-	
-	public Record getRecordOfAttackId(long attack_id) {
-		return dbh.getRecordOfAttackId(attack_id);
-	}
-
-	
-	public int getAttackCount() {
-		return dbh.getAttackCount();
-	}
-
-	
-	public int getAttackPerProtokolCount(String protocol) {
-		return dbh.getAttackPerProtokolCount(protocol);
-	}
-
-	
-	public long getSmallestAttackId() {
-		return dbh.getSmallestAttackId();
-	}
-
-	
-	public long getHighestAttackId() {
-		return dbh.getHighestAttackId();
-	}
-
-	
-	public boolean bssidSeen(String protocol, String bssid) {
-		return dbh.bssidSeen(protocol, bssid);
-	}
-
-	
-	public String[] getAllBSSIDS() {
-		return dbh.getAllBSSIDS();
-	}
-
-	
-	public String getSSID(String bssid) {
-		return dbh.getSSID(bssid);
-	}
-
-	
-	public void deleteByDate(long time) {
-		dbh.deleteByDate(time);		
-	}
-
-	
-	public void deleteByBSSID(String bssid) {
-		dbh.deleteByBSSID(bssid);
-	}
-
-	
-	public void clearData() {
-		dbh.clearData();
-	}
-}

+ 798 - 0
src/de/tudarmstadt/informatik/hostage/logging/UglyDbHelper.java

@@ -0,0 +1,798 @@
+package de.tudarmstadt.informatik.hostage.logging;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.util.Log;
+import de.tudarmstadt.informatik.hostage.logging.Record.TYPE;
+import de.tudarmstadt.informatik.hostage.ui.LogFilter;
+
+/**
+ * This class creates SQL tables and handles all access to the database.<br>
+ * It contains several methods with predefined queries to extract different
+ * kinds of information from the database.<br>
+ * The database contains two tables: {@link #TABLE_RECORDS} and
+ * {@link #TABLE_BSSIDS}:<br>
+ * {@link #TABLE_RECORDS} contains all logging information of a single message
+ * record except the SSID.<br>
+ * {@link #TABLE_BSSIDS} contains the BSSID of all recorded Networks and the
+ * corresponding SSID.<br>
+ * 
+ * @author Lars Pandikow
+ */
+public class UglyDbHelper extends SQLiteOpenHelper {
+
+	// All Static variables
+	// Database Version
+	private static final int DATABASE_VERSION = 1;
+
+	// Database Name
+	private static final String DATABASE_NAME = "recordManager";
+
+	// Contacts table names
+	private static final String TABLE_ATTACK_INFO = "attack_info";
+	private static final String TABLE_RECORDS = "records";
+	private static final String TABLE_BSSIDS = "bssids";
+
+	// Contacts Table Columns names
+	public static final String KEY_ID = "_id";
+	public static final String KEY_ATTACK_ID = "_attack_id";
+	public static final String KEY_TYPE = "type";
+	public static final String KEY_TIME = "timestamp";
+	public static final String KEY_PACKET = "packet";
+	public static final String KEY_PROTOCOL = "protocol";
+	public static final String KEY_EXTERNAL_IP = "externalIP";
+	public static final String KEY_LOCAL_IP = "localIP";
+	public static final String KEY_LOCAL_HOSTNAME = "localHostName";
+	public static final String KEY_LOCAL_PORT = "localPort";
+	public static final String KEY_REMOTE_IP = "remoteIP";
+	public static final String KEY_REMOTE_HOSTNAME = "remoteHostName";
+	public static final String KEY_REMOTE_PORT = "remotePort";
+	public static final String KEY_BSSID = "_bssid";
+	public static final String KEY_SSID = "ssid";
+	public static final String KEY_LATITUDE = "latitude";
+	public static final String KEY_LONGITUDE = "longitude";
+	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"
+	       + ")";
+
+	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);
+	}
+
+	  /*
+    // Contacts Table Columns names
+	private static final String KEY_ID = "_id";
+	private static final String KEY_ATTACK_ID = "_attack_id";
+	private static final String KEY_TYPE = "type";
+	private static final String KEY_TIME = "timestamp";
+	private static final String KEY_PACKET = "packet";
+	private static final String KEY_PROTOCOL = "protocol";
+	private static final String KEY_EXTERNAL_IP ="externalIP";
+	private static final String KEY_LOCAL_IP = "localIP";
+	private static final String KEY_LOCAL_HOSTNAME = "localHostName";
+	private static final String KEY_LOCAL_PORT = "localPort";
+	private static final String KEY_REMOTE_IP = "remoteIP";
+	private static final String KEY_REMOTE_HOSTNAME = "remoteHostName";
+	private static final String KEY_REMOTE_PORT = "remotePort";
+	private static final String KEY_BSSID = "_bssid";
+	private static final String KEY_SSID = "ssid";
+	private static final String KEY_LATITUDE = "latitude";
+	private static final String KEY_LONGITUDE = "longitude";
+	private static final String KEY_ACCURACY = "accuracy";
+	*/
+
+	/**
+	 * Gets all received {@link Record Records} for the specified information in the LogFilter ordered by date.
+	 * @return A ArrayList with all received {@link Record Records} for the LogFilter.
+	 */
+	public ArrayList<Record> getRecordsForFilter(LogFilter filter) {
+		ArrayList<Record> recordList = new ArrayList<Record>();
+		String selectQuery = "SELECT  * FROM " + TABLE_RECORDS + " NATURAL JOIN " + TABLE_ATTACK_INFO + " NATURAL JOIN " + TABLE_BSSIDS;
+
+		// TIMESTAMPS
+		selectQuery = selectQuery + " WHERE " + KEY_TIME;
+		selectQuery = selectQuery + " < " + filter.getBelowTimestamp();
+		selectQuery = selectQuery + " AND " + KEY_TIME;
+		selectQuery = selectQuery + " > " + filter.getAboveTimestamp();
+
+		if (filter.getBSSIDs() != null && filter.getBSSIDs().size() > 0) {
+			selectQuery = selectQuery + " AND ";
+			selectQuery = selectQuery + filter.getBSSIDQueryStatement(KEY_BSSID);
+		}
+		if (filter.getESSIDs() != null && filter.getESSIDs().size() > 0) {
+			selectQuery = selectQuery + " AND ";
+			selectQuery = selectQuery + filter.getESSIDQueryStatement(KEY_SSID);
+		}
+		if (filter.getProtocols() != null && filter.getProtocols().size() > 0) {
+			selectQuery = selectQuery + " AND ";
+			selectQuery = selectQuery + filter.getProtocolsQueryStatement(KEY_PROTOCOL);
+		}
+
+
+		// ORDERED BY TIME
+		selectQuery = selectQuery + " ORDER BY " + filter.getSorttype();
+		System.out.println(selectQuery);
+		SQLiteDatabase db = this.getReadableDatabase();
+		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 record list
+		db.close();
+		return recordList;
+	}
+
+	/**
+	 * Gets all non duplicate Records For the key BSSID.
+	 * @return A ArrayList with received Records.
+	 */
+	public ArrayList<String> getUniqueBSSIDRecords(){
+		return this.getUniqueDataEntryForKeyType(KEY_BSSID, TABLE_BSSIDS);
+	}
+	/**
+	 * Gets all non duplicate Records For the key ESSID.
+	 * @return A ArrayList with received Records.
+	 */
+	public ArrayList<String> getUniqueESSIDRecords(){
+		return this.getUniqueDataEntryForKeyType(KEY_SSID, TABLE_BSSIDS);
+	}
+
+	/**
+	 * Gets all non duplicate Data Entry For a specific KeyType ( e.g. BSSIDs).
+	 * @return A ArrayList with received Records.
+	 */
+	public ArrayList<String> getUniqueDataEntryForKeyType(String keyType, String table) {
+		ArrayList<String> recordList = new ArrayList<String>();
+		//String selectQuery = "SELECT  * FROM " + TABLE_RECORDS + " NATURAL JOIN " + TABLE_ATTACK_INFO + " NATURAL JOIN " + TABLE_BSSIDS + " NATURAL JOIN " + TABLE_PORTS;
+		String selectQuery = "SELECT DISTINCT " + keyType + " FROM " + table + " ORDER BY " + keyType; // " NATURAL JOIN " + TABLE_ATTACK_INFO + " NATURAL JOIN " + TABLE_BSSIDS + " NATURAL JOIN " + TABLE_PORTS +
+
+
+		// ORDERED BY TIME
+		System.out.println(selectQuery);
+		SQLiteDatabase db = this.getReadableDatabase();
+		Cursor cursor = db.rawQuery(selectQuery, null);
+
+		// looping through all rows and adding to list
+		if (cursor.moveToFirst()) {
+			do {
+				String record = cursor.getString(0);
+				recordList.add(record);
+			} while (cursor.moveToNext());
+		}
+		cursor.close();
+
+		// return record list
+		db.close();
+		return recordList;
+	}
+	/**
+	 * Adds a given {@link Record} to the database.
+	 * 
+	 * @param record
+	 *            The added {@link Record} .
+	 */
+	public void addRecord(Record record) {
+		SQLiteDatabase db = this.getWritableDatabase();
+
+		HashMap<String, Object> bssidValues = new HashMap<String, Object>();
+		bssidValues.put(KEY_BSSID, record.getBssid());
+		bssidValues.put(KEY_SSID, record.getSsid());
+		bssidValues.put(KEY_LATITUDE, record.getLatitude());
+		bssidValues.put(KEY_LONGITUDE, record.getLongitude());
+		bssidValues.put(KEY_ACCURACY, record.getAccuracy());
+		bssidValues.put(KEY_TIME, record.getTimestampLocation());
+
+		ContentValues attackValues = new ContentValues();
+		attackValues.put(KEY_ATTACK_ID, record.getAttack_id()); // Log Attack ID
+		attackValues.put(KEY_PROTOCOL, record.getProtocol().toString());
+		attackValues.put(KEY_EXTERNAL_IP, record.getExternalIP());
+		attackValues.put(KEY_LOCAL_IP, record.getLocalIP()); // Log Local IP
+		attackValues.put(KEY_LOCAL_HOSTNAME, record.getLocalHost());
+		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_BSSID, record.getBssid());
+
+		ContentValues recordValues = new ContentValues();
+		recordValues.put(KEY_ID, record.getId()); // Log Message Number
+		recordValues.put(KEY_ATTACK_ID, record.getAttack_id()); // Log Attack ID
+		recordValues.put(KEY_TYPE, record.getType().name()); // Log Type
+		recordValues.put(KEY_TIME, record.getTimestamp()); // Log Timestamp
+		recordValues.put(KEY_PACKET, record.getPacket()); // Log Packet
+
+		// Inserting Rows
+		db.insertWithOnConflict(TABLE_ATTACK_INFO, null, attackValues,
+				SQLiteDatabase.CONFLICT_REPLACE);
+		db.insert(TABLE_RECORDS, null, recordValues);
+		db.close(); // Closing database connection
+		// Update Network Information
+		updateNetworkInformation(bssidValues);
+	}
+
+	/**
+	 * 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;
+	}
+
+	/**
+	 * 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 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(selectQuery, null);
+		Record record = null;
+		if (cursor.moveToFirst()) {
+			record = createRecord(cursor);
+		}
+
+		cursor.close();
+		db.close();
+		// return contact
+		return record;
+	}
+
+	/**
+	 * Gets all {@link Record Records} saved in the database.
+	 * 
+	 * @return A ArrayList of all the {@link Record Records} in the Database.
+	 */
+	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();
+		db.close();
+		// return record list
+		return recordList;
+	}
+
+	/**
+	 * Gets a single {@link Record} with the given attack id from the database.
+	 * 
+	 * @param attack_id
+	 *            The attack id of the {@link Record};
+	 * @return The {@link Record}.
+	 */
+	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);
+		Record record = null;
+
+		if (cursor.moveToFirst()) {
+			record = createRecord(cursor);
+		}
+		cursor.close();
+
+		// return record list
+		db.close();
+		return record;
+	}
+
+	/**
+	 * Gets all received {@link Record Records} for every attack identified by
+	 * its attack id and ordered by date.
+	 * 
+	 * @return A ArrayList with all received {@link Record Records} for each
+	 *         attack id in the Database.
+	 */
+	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;
+		SQLiteDatabase db = this.getReadableDatabase();
+		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 record list
+		db.close();
+		return recordList;
+	}
+
+	/**
+	 * Gets a representative {@link Record} for every attack identified by its
+	 * attack id.
+	 * 
+	 * @return A ArrayList with one {@link Record Records} for each attack id in
+	 *         the Database.
+	 */
+	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);
+
+		// 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 record list
+		db.close();
+		return recordList;
+	}
+
+	/**
+	 * Gets a representative {@link Record} for every attack with a higher
+	 * attack id than the specified.
+	 * 
+	 * @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 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();
+		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;
+	}
+
+	/**
+	 * 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.
+	 * 
+	 * @return The number of different attack_ids in the database.
+	 */
+	public int getAttackCount() {
+		String countQuery = "SELECT  * FROM " + TABLE_ATTACK_INFO;
+		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 for a specific protocol in
+	 * the database.
+	 * 
+	 * @param protocol
+	 *            The String representation of the
+	 *            {@link de.tudarmstadt.informatik.hostage.protocol.Protocol
+	 *            Protocol}
+	 * @return The number of different attack_ids in the database.
+	 */
+	public int getAttackPerProtocolCount(String protocol) {
+		String countQuery = "SELECT  * FROM " + TABLE_ATTACK_INFO + " WHERE "
+				+ KEY_PROTOCOL + " = " + "'" + protocol + "'";
+		SQLiteDatabase db = this.getReadableDatabase();
+		Cursor cursor = db.rawQuery(countQuery, null);
+		int result = cursor.getCount();
+		cursor.close();
+
+		// return count
+		db.close();
+		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.
+	 * 
+	 * @return The highest attack id stored in the database.
+	 */
+	public long getHighestAttackId() {
+		String selectQuery = "SELECT MAX(" + 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 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 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;
+	}
+
+	/**
+	 * Determines if an attack has been recorded on a specific protocol in a
+	 * network with a given BSSID.
+	 * 
+	 * @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 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(countQuery, null);
+		int result = cursor.getCount();
+		cursor.close();
+		db.close();
+		return result > 0;
+	}
+
+	/**
+	 * Returns a String array with all BSSIDs stored in the database.
+	 * 
+	 * @return String[] of all recorded BSSIDs.
+	 */
+	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 {
+				bssidList[counter] = cursor.getString(0);
+				counter++;
+			} while (cursor.moveToNext());
+		}
+		cursor.close();
+		db.close();
+		return bssidList;
+	}
+
+	/**
+	 * 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 String getSSID(String bssid) {
+		String selectQuery = "SELECT " + KEY_SSID + " FROM " + TABLE_BSSIDS
+				+ " WHERE " + KEY_BSSID + " = " + "'" + bssid + "'";
+		SQLiteDatabase db = this.getReadableDatabase();
+		Cursor cursor = db.rawQuery(selectQuery, null);
+		String ssid = null;
+		if (cursor.moveToFirst()) {
+			ssid = cursor.getString(0);
+		}
+		cursor.close();
+		db.close();
+		return ssid;
+	}
+
+	/**
+	 * Deletes all records from {@link #TABLE_RECORDS} with a specific BSSID.
+	 * 
+	 * @param bssid
+	 *            The BSSID to match against.
+	 */
+	public void deleteByBSSID(String bssid) {
+		SQLiteDatabase db = this.getReadableDatabase();
+		db.delete(TABLE_RECORDS, KEY_BSSID + " = ?", new String[] { bssid });
+		db.delete(TABLE_ATTACK_INFO, KEY_BSSID + " = ?", new String[] { bssid });
+		db.close();
+	}
+
+	// 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();
+	}
+
+	/**
+	 * Deletes all records from {@link #TABLE_RECORDS}.
+	 */
+	public void clearData() {
+		SQLiteDatabase db = this.getReadableDatabase();
+		db.delete(TABLE_RECORDS, null, null);
+		db.delete(TABLE_ATTACK_INFO, null, null);
+		db.close();
+	}
+
+	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;
+	}
+
+	public void updateNetworkInformation(
+			HashMap<String, Object> networkInformation) {
+		SQLiteDatabase db = this.getReadableDatabase();
+		String bssid = (String) networkInformation.get(KEY_BSSID);
+		String bssidQuery = "SELECT  * FROM " + TABLE_BSSIDS + " WHERE "
+				+ KEY_BSSID + " = " + "'" + bssid + "'";
+		Cursor cursor = db.rawQuery(bssidQuery, null);
+		int result = cursor.getCount();
+		if (cursor != null
+				&& cursor.moveToFirst()
+				&& (result <= 0 || cursor.getLong(5) < (Long) networkInformation
+						.get(KEY_TIME)))
+			;
+		{
+			ContentValues bssidValues = new ContentValues();
+			bssidValues.put(KEY_BSSID, bssid);
+			bssidValues
+					.put(KEY_SSID, (String) networkInformation.get(KEY_SSID));
+			bssidValues.put(KEY_LATITUDE,
+					(double) (Double) networkInformation.get(KEY_LATITUDE));
+			bssidValues.put(KEY_LONGITUDE,
+					(double) (Double) networkInformation.get(KEY_LONGITUDE));
+			bssidValues.put(KEY_ACCURACY,
+					(float) (Float) networkInformation.get(KEY_ACCURACY));
+			bssidValues.put(KEY_TIME, (Long) networkInformation.get(KEY_TIME));
+			db.insertWithOnConflict(TABLE_BSSIDS, null, bssidValues,
+					SQLiteDatabase.CONFLICT_REPLACE);
+		}
+		cursor.close();
+		db.close();
+	}
+
+	public void updateNetworkInformation(
+			ArrayList<HashMap<String, Object>> networkInformation) {
+		Log.i("DatabaseHandler", "Starte updating");
+		for (HashMap<String, Object> values : networkInformation) {
+			updateNetworkInformation(values);
+		}
+	}
+}

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

@@ -0,0 +1,28 @@
+package de.tudarmstadt.informatik.hostage.logging.formatter;
+
+import de.tudarmstadt.informatik.hostage.logging.Record;
+import de.tudarmstadt.informatik.hostage.logging.formatter.protocol.ProtocolFormatter;
+
+public class DefaultFormatter extends Formatter {
+
+	private static DefaultFormatter INSTANCE = new DefaultFormatter();
+
+	private DefaultFormatter() {
+	}
+
+	public static DefaultFormatter getInstance() {
+		return INSTANCE;
+	}
+
+	@Override
+	public synchronized String format(Record record) {
+		ProtocolFormatter formatter = ProtocolFormatter.getFormatter(record
+				.getProtocol());
+		return String.format("%d %s [%d,%s:%d,%s:%d,%s]",
+				record.getAttack_id(), record.getType().name(),
+				record.getTimestamp(), record.getLocalIP(),
+				record.getLocalPort(), record.getRemoteIP(),
+				record.getRemotePort(), formatter.format(record.getPacket()));
+	}
+
+}

+ 23 - 0
src/de/tudarmstadt/informatik/hostage/logging/formatter/Formatter.java

@@ -0,0 +1,23 @@
+package de.tudarmstadt.informatik.hostage.logging.formatter;
+
+import de.tudarmstadt.informatik.hostage.logging.Record;
+
+public abstract class Formatter {
+
+	/**
+	 * @return Instance of DefaultFormatter.
+	 */
+	public static Formatter getDefault() {
+		return DefaultFormatter.getInstance();
+	}
+
+	/**
+	 * Formats a record.
+	 * 
+	 * @param record
+	 *            Record to format.
+	 * @return Formatted human-readable String.
+	 */
+	abstract public String format(Record record);
+
+}

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

@@ -0,0 +1,25 @@
+package de.tudarmstadt.informatik.hostage.logging.formatter;
+
+import de.tudarmstadt.informatik.hostage.logging.Record;
+
+public class TraCINgFormatter extends Formatter {
+
+	private static TraCINgFormatter INSTANCE = new TraCINgFormatter();
+
+	private TraCINgFormatter() {
+	}
+
+	public static TraCINgFormatter getInstance() {
+		return INSTANCE;
+	}
+
+	@Override
+	public synchronized String format(Record record) {
+		return String
+				.format("{ \"sensor\":{\"type\": \"Honeypot\", \"name\": \"HosTaGe\"}, \"type\": \"%s server access\", \"src\":{\"ip\": \"%s\", \"port\": %d}, \"dst\":{\"ip\": \"%s\", \"port\": %d} }",
+						record.getProtocol(), record.getRemoteIP(),
+						record.getRemotePort(), record.getExternalIP(),
+						record.getLocalPort());
+	}
+
+}

+ 103 - 0
src/de/tudarmstadt/informatik/hostage/logging/formatter/protocol/MySQL.java

@@ -0,0 +1,103 @@
+package de.tudarmstadt.informatik.hostage.logging.formatter.protocol;
+
+import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
+
+/**
+ * MySQL log view formatter.
+ * 
+ * @author Wulf Pfeiffer
+ */
+public class MySQL extends ProtocolFormatter {
+
+	@Override
+	public String format(String packet) {
+		byte[] bytes = HelperUtils.hexStringToBytes(packet);
+		String command = "Command: " + getCommand(bytes) + "\n";
+		String content = "Content: " + HelperUtils.byteToStr(bytes) + "\n";
+		return command + content;
+	}
+
+	/**
+	 * Checks a packet for its command code and returns the name of this
+	 * command.
+	 * 
+	 * @param bytes
+	 *            to check.
+	 * @return name of the command.
+	 */
+	private String getCommand(byte[] bytes) {
+		// if packet number is 1 server started conversation so it must be login
+		if (bytes.length < 5)
+			return "";
+		if (bytes[3] == 0x01)
+			return "Login request";
+		// else check for command code
+		switch (bytes[4]) {
+		case 0x00:
+			return "COM_SLEEP";
+		case 0x01:
+			return "COM_QUIT";
+		case 0x02:
+			return "COM_INIT_DB";
+		case 0x03:
+			return "COM_QUERY";
+		case 0x04:
+			return "COM_FIELD_LIST";
+		case 0x05:
+			return "COM_CREATE_DB";
+		case 0x06:
+			return "COM_DROP_DB";
+		case 0x07:
+			return "COM_REFRESH";
+		case 0x08:
+			return "COM_SHUTDOWN";
+		case 0x09:
+			return "COM_STATISTICS";
+		case 0x0a:
+			return "COM_PROCESS_INFO";
+		case 0x0b:
+			return "COM_CONNECT";
+		case 0x0c:
+			return "COM_PROCESS_KILL";
+		case 0x0d:
+			return "COM_DEBUG";
+		case 0x0e:
+			return "COM_PING";
+		case 0x0f:
+			return "COM_TIME";
+		case 0x10:
+			return "COM_DELAYED_INSERT";
+		case 0x11:
+			return "COM_CHANGE_USER";
+		case 0x12:
+			return "COM_BINLOG_DUMP";
+		case 0x13:
+			return "COM_TABLE_DUMP";
+		case 0x14:
+			return "COM_CONNECT_OUT";
+		case 0x15:
+			return "COM_REGISTER_SLAVE";
+		case 0x16:
+			return "COM_STMT_PREPARE";
+		case 0x17:
+			return "COM_STMT_EXECUTE";
+		case 0x18:
+			return "COM_STMT_SEND_LONG_DATA";
+		case 0x19:
+			return "COM_STMT_CLOSE";
+		case 0x1a:
+			return "COM_STMT_RESET";
+		case 0x1b:
+			return "COM_SET_OPTION";
+		case 0x1c:
+			return "COM_STMT_FETCH";
+		case 0x1d:
+			return "COM_DAEMON";
+		case 0x1e:
+			return "COM_BINLOG_DUMP_GTID";
+		default:
+			return "unkown command";
+		}
+	}
+
+}

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

@@ -0,0 +1,45 @@
+package de.tudarmstadt.informatik.hostage.logging.formatter.protocol;
+
+/**
+ * Protocol formatter. This class provides functionality to format the packet as
+ * a human-readable string of a specific protocol. Custom formatters should
+ * inherit from this class.
+ * 
+ * @author Wulf Pfeiffer
+ * @author Mihai Plasoianu
+ */
+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
+	 * otherwise.
+	 * 
+	 * @param protocolName
+	 *            String representation of a protocol.
+	 * @return The protocol formatter.
+	 */
+	public static ProtocolFormatter getFormatter(String protocolName) {
+		String packageName = ProtocolFormatter.class.getPackage().getName();
+		String className = String.format("%s.%s", packageName, protocolName);
+		// TODO Auf Singletons umstellen und newInstance() sparen.
+		try {
+			return (ProtocolFormatter) Class.forName(className).newInstance();
+		} catch (ReflectiveOperationException e) {
+			return new ProtocolFormatter();
+		}
+	}
+
+}

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

@@ -0,0 +1,225 @@
+package de.tudarmstadt.informatik.hostage.logging.formatter.protocol;
+
+import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
+
+/**
+ * SMB log view formatter.
+ * 
+ * @author Wulf Pfeiffer
+ */
+public class SMB extends ProtocolFormatter {
+
+	@Override
+	public String format(String packet) {
+		byte[] bytes = HelperUtils.hexStringToBytes(packet);
+		byte cmd = bytes[8]; // command code located at 8
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("Command: ");
+		buffer.append(getCommandString(cmd));
+		buffer.append("\n");
+		buffer.append("Content: ");
+		buffer.append(getContent(cmd, bytes));
+
+		return buffer.toString();
+	}
+
+	/**
+	 * Checks command code for its command code and returns the name of this
+	 * command.
+	 * 
+	 * @param command
+	 *            as byte.
+	 * @return command name as String.
+	 */
+	private String getCommandString(byte command) {
+		switch (command) {
+		case 0x00:
+			return "SMB_COM_CREATE_DIRECTORY";
+		case 0x01:
+			return "SMB_COM_DELETE_DIRECTORY";
+		case 0x02:
+			return "SMB_COM_OPEN";
+		case 0x03:
+			return "SMB_COM_CREATE";
+		case 0x04:
+			return "SMB_COM_CLOSE";
+		case 0x05:
+			return "SMB_COM_FLUSH";
+		case 0x06:
+			return "SMB_COM_DELETE";
+		case 0x07:
+			return "SMB_COM_RENAME";
+		case 0x08:
+			return "SMB_COM_QUERY_INFORMATION";
+		case 0x09:
+			return "SMB_COM_SET_INFORMATION";
+		case 0x0A:
+			return "SMB_COM_READ";
+		case 0x0B:
+			return "SMB_COM_WRITE";
+		case 0x0C:
+			return "SMB_COM_LOCK_BYTE_RANGE";
+		case 0x0D:
+			return "SMB_COM_UNLOCK_BYTE_RANGE";
+		case 0x0E:
+			return "SMB_COM_CREATE_TEMPORARY";
+		case 0x0F:
+			return "SMB_COM_CREATE_NEW";
+		case 0x10:
+			return "SMB_COM_CHECK_DIRECTORY";
+		case 0x11:
+			return "SMB_COM_PROCESS_EXIT";
+		case 0x12:
+			return "SMB_COM_SEEK";
+		case 0x13:
+			return "SMB_COM_LOCK_AND_READ";
+		case 0x14:
+			return "SMB_COM_WRITE_AND_UNLOCK";
+		case 0x1A:
+			return "SMB_COM_READ_RAW";
+		case 0x1B:
+			return "SMB_COM_READ_MPX";
+		case 0x1C:
+			return "SMB_COM_READ_MPX_SECONDARY";
+		case 0x1D:
+			return "SMB_COM_WRITE_RAW";
+		case 0x1E:
+			return "SMB_COM_WRITE_MPX";
+		case 0x1F:
+			return "SMB_COM_WRITE_MPX_SECONDARY";
+		case 0x20:
+			return "SMB_COM_WRITE_COMPLETE";
+		case 0x21:
+			return "SMB_COM_QUERY_SERVER";
+		case 0x22:
+			return "SMB_COM_SET_INFORMATION2";
+		case 0x23:
+			return "SMB_COM_QUERY_INFORMATION2";
+		case 0x24:
+			return "SMB_COM_LOCKING_ANDX";
+		case 0x25:
+			return "SMB_COM_TRANSACTION";
+		case 0x26:
+			return "SMB_COM_TRANSACTION_SECONDARY";
+		case 0x27:
+			return "SMB_COM_IOCTL";
+		case 0x28:
+			return "SMB_COM_IOCTL_SECONDARY";
+		case 0x29:
+			return "SMB_COM_COPY";
+		case 0x2A:
+			return "SMB_COM_MOVE";
+		case 0x2B:
+			return "SMB_COM_ECHO";
+		case 0x2C:
+			return "SMB_COM_WRITE_AND_CLOSE";
+		case 0x2D:
+			return "SMB_COM_OPEN_ANDX";
+		case 0x2E:
+			return "SMB_COM_READ_ANDX";
+		case 0x2F:
+			return "SMB_COM_WRITE_ANDX";
+		case 0x30:
+			return "SMB_COM_NEW_FILE_SIZE";
+		case 0x31:
+			return "SMB_COM_CLOSE_AND_TREE_DISC";
+		case 0x32:
+			return "SMB_COM_TRANSACTION2";
+		case 0x33:
+			return "SMB_COM_TRANSACTION2_SECONDARY";
+		case 0x34:
+			return "SMB_COM_FIND_CLOSE2";
+		case 0x35:
+			return "SMB_COM_FIND_NOTIFY_CLOSE";
+		case 0x70:
+			return "SMB_COM_TREE_CONNECT";
+		case 0x71:
+			return "SMB_COM_TREE_DISCONNECT";
+		case 0x72:
+			return "SMB_COM_NEGOTIATE";
+		case 0x73:
+			return "SMB_COM_SESSION_SETUP_ANDX";
+		case 0x74:
+			return "SMB_COM_LOGOFF_ANDX";
+		case 0x75:
+			return "SMB_COM_TREE_CONNECT_ANDX";
+		case (byte) 0x80:
+			return "SMB_COM_QUERY_INFORMATION_DISK";
+		case (byte) 0x81:
+			return "SMB_COM_SEARCH";
+		case (byte) 0x82:
+			return "SMB_COM_FIND";
+		case (byte) 0x83:
+			return "SMB_COM_FIND_UNIQUE";
+		case (byte) 0x84:
+			return "SMB_COM_FIND_CLOSE";
+		case (byte) 0xA0:
+			return "SMB_COM_NT_TRANSACT";
+		case (byte) 0xA1:
+			return "SMB_COM_NT_TRANSACT_SECONDARY";
+		case (byte) 0xA2:
+			return "SMB_COM_NT_CREATE_ANDX";
+		case (byte) 0xA4:
+			return "SMB_COM_NT_CANCEL";
+		case (byte) 0xA5:
+			return "SMB_COM_NT_RENAME";
+		case (byte) 0xC0:
+			return "SMB_COM_OPEN_PRINT_FILE";
+		case (byte) 0xC1:
+			return "SMB_COM_WRITE_PRINT_FILE";
+		case (byte) 0xC2:
+			return "SMB_COM_CLOSE_PRINT_FILE";
+		case (byte) 0xC3:
+			return "SMB_COM_GET_PRINT_QUEUE";
+		case (byte) 0xD8:
+			return "SMB_COM_READ_BULK";
+		case (byte) 0xD9:
+			return "SMB_COM_WRITE_BULK";
+		case (byte) 0xDA:
+			return "SMB_COM_WRITE_BULK_DATA";
+		case (byte) 0xFF:
+			return "SMB_COM_NONE";
+		default:
+			return "Unknown Command";
+		}
+	}
+
+	/**
+	 * Returns the content of a packet as a String value, depending on its
+	 * command code
+	 * 
+	 * @param command
+	 *            of the packet.
+	 * @param packet
+	 *            content as byte array.
+	 * @return content as a String.
+	 */
+	private String getContent(byte command, byte[] packet) {
+		switch (command) {
+		case 0x72:
+			return get0x72content(packet);
+		case 0x73:
+			return HelperUtils.byteToStr(packet);
+		case (byte) 0xa2:
+			return HelperUtils.byteToStr(packet);
+		case 0x25:
+			return HelperUtils.byteToStr(packet);
+		default:
+			return "";
+		}
+	}
+
+	/**
+	 * 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);
+	}
+
+}

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

@@ -0,0 +1,149 @@
+package de.tudarmstadt.informatik.hostage.logging.formatter.protocol;
+
+import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
+
+/**
+ * Telnet log view formatter.
+ * 
+ * @author Wulf Pfeiffer
+ */
+public class TELNET extends ProtocolFormatter {
+
+	@Override
+	public String format(String packet) {
+		byte[] bytes = HelperUtils.hexStringToBytes(packet);
+		String options = "Options:\n" + checkForOptions(bytes) + "\n";
+		String content = "Content: " + HelperUtils.byteToStr(bytes);
+		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.
+	 * 
+	 * @param b
+	 *            byte that is checked.
+	 * @return name of the command.
+	 */
+	private String checkCommand(byte b) {
+		switch (b) {
+		case 0x00:
+			return "Binary Transmission\n";
+		case 0x01:
+			return "Echo\n";
+		case 0x02:
+			return "Reconnection\n";
+		case 0x03:
+			return "Suppress Go Ahead\n";
+		case 0x04:
+			return "Approx Message Size Negotiation\n";
+		case 0x05:
+			return "Status\n";
+		case 0x06:
+			return "Timing Mark\n";
+		case 0x07:
+			return "Remote Controlled Trans and Echo\n";
+		case 0x08:
+			return "Output Line Width\n";
+		case 0x09:
+			return "Output Page Size\n";
+		case 0x0a:
+			return "Output Carriage-Return Disposition\n";
+		case 0x0b:
+			return "Output Horizontal Tab Stops\n";
+		case 0x0c:
+			return "Output Horizontal Tab Disposition\n";
+		case 0x0d:
+			return "Output Formfeed Disposition\n";
+		case 0x0e:
+			return "Output Vertical Tabstops\n";
+		case 0x0f:
+			return "Output Vertical Tab Disposition\n";
+		case 0x10:
+			return "Output Linefeed Disposition\n";
+		case 0x11:
+			return "Extended ASCII\n";
+		case 0x12:
+			return "Logout\n";
+		case 0x13:
+			return "Byte Macro\n";
+		case 0x14:
+			return "Data Entry Terminal\n";
+		case 0x15:
+			return "SUPDUP\n";
+		case 0x16:
+			return "SUPDUP Output\n";
+		case 0x17:
+			return "Send Location\n";
+		case 0x18:
+			return "Terminal Type\n";
+		case 0x19:
+			return "End of Record\n";
+		case 0x1a:
+			return "TACACS User Identification\n";
+		case 0x1b:
+			return "Output Marking\n";
+		case 0x1c:
+			return "Terminal Location Number\n";
+		case 0x1d:
+			return "Telnet 3270 Regime\n";
+		case 0x1e:
+			return "X.3 PAD\n";
+		case 0x1f:
+			return "Negotiate About Window Size\n";
+		case 0x20:
+			return "Terminal Speed\n";
+		case 0x21:
+			return "Remote Flow Control\n";
+		case 0x22:
+			return "Linemode\n";
+		case 0x23:
+			return "X Display Location\n";
+		case (byte) 0xff:
+			return "Extended-Options-List\n";
+		default:
+			return "unknown option\n";
+		}
+	}
+
+}

+ 21 - 11
src/de/tudarmstadt/informatik/hostage/net/MyServerSocketFactory.java

@@ -4,12 +4,14 @@ import java.io.FileDescriptor;
 import java.io.IOException;
 import java.lang.reflect.Field;
 import java.net.InetAddress;
+import java.net.InetSocketAddress;
 import java.net.ServerSocket;
 import java.net.SocketImpl;
 
 import javax.net.ServerSocketFactory;
 
 import de.tudarmstadt.informatik.hostage.system.PrivilegedPort;
+import de.tudarmstadt.informatik.hostage.ui.MainActivity;
 
 /**
  * Server Socket Factory using the porthack.
@@ -23,18 +25,26 @@ public class MyServerSocketFactory extends ServerSocketFactory {
 	 */
 	@Override
 	public ServerSocket createServerSocket(int port) throws IOException {
-		FileDescriptor fd = new PrivilegedPort(port).bindAndGetFD();
-
-		ServerSocket socket = new ServerSocket();
-		try {
-			SocketImpl impl = getImpl(socket);
-			injectFD(fd, impl);
-			injectImpl(impl, socket);
-			setBound(socket);
-		} catch (Exception e) {
-			e.printStackTrace();
+		ServerSocket socket = null;
+		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();			
+			socket = new ServerSocket();
+			
+			try {
+				SocketImpl impl = getImpl(socket);
+				injectFD(fd, impl);
+				injectImpl(impl, socket);
+				setBound(socket);
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
 		}
-
+		
 		return socket;
 	}
 

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

@@ -3,48 +3,48 @@ package de.tudarmstadt.informatik.hostage.protocol;
 import java.util.ArrayList;
 import java.util.List;
 
-import de.tudarmstadt.informatik.hostage.wrapper.ByteArray;
+import de.tudarmstadt.informatik.hostage.wrapper.Packet;
 
 /**
- * ECHO protocol
+ * ECHO protocol. Implementation of RFC document 862.
+ * 
  * @author Wulf Pfeiffer
  */
-public class ECHO implements Protocol<ByteArray>{
+public class ECHO implements Protocol {
 
-	
-	public int getPort() {
+	@Override
+	public int getDefaultPort() {
 		return 7;
 	}
 
-	
+	@Override
 	public TALK_FIRST whoTalksFirst() {
 		return TALK_FIRST.CLIENT;
 	}
-	
-	
-	public List<ByteArray> processMessage(ByteArray message) {
-		List<ByteArray> response = new ArrayList<ByteArray>();
-		//respond with the received message
-		response.add(message);
-		return response;
+
+	@Override
+	public List<Packet> processMessage(Packet requestPacket) {
+		List<Packet> responsePackets = new ArrayList<Packet>();
+		responsePackets.add(requestPacket);
+		return responsePackets;
 	}
 
-	
+	@Override
 	public boolean isClosed() {
 		return true;
 	}
 
-	
+	@Override
 	public boolean isSecure() {
 		return false;
 	}
 
-	
-	public Class<ByteArray> getType() {
-		return ByteArray.class;
+	@Override
+	public Class<byte[]> getType() {
+		return byte[].class;
 	}
-	
-	
+
+	@Override
 	public String toString() {
 		return "ECHO";
 	}

+ 48 - 39
src/de/tudarmstadt/informatik/hostage/protocol/FTP.java

@@ -3,11 +3,16 @@ package de.tudarmstadt.informatik.hostage.protocol;
 import java.util.ArrayList;
 import java.util.List;
 
+import de.tudarmstadt.informatik.hostage.wrapper.Packet;
+
 /**
- * FTP protocol
+ * FTP protocol.
+ * Implementation of RFC document 959.
+ * It can handle the following requests: USER, PASS, QUIT.
  * @author Wulf Pfeiffer
  */
-public final class FTP implements Protocol<String> {
+public class FTP implements Protocol {
+	
 	/**
 	 * Represents the states of the protocol
 	 */
@@ -20,95 +25,99 @@ public final class FTP implements Protocol<String> {
 	 */
 	private STATE state = STATE.NONE;
 	
-	
-	public int getPort() {
+	@Override
+	public int getDefaultPort() {
 		return 21;
 	}
 
-	
+	@Override
 	public TALK_FIRST whoTalksFirst() {
 		return TALK_FIRST.SERVER;
 	}
 
-	
-	public List<String> processMessage(String message) {
-		List<String> response = new ArrayList<String>();
+	@Override
+	public List<Packet> processMessage(Packet requestPacket) {
+		String request = null;
+		if (requestPacket != null) {
+			request = requestPacket.toString();
+		}
+		List<Packet> responsePackets = new ArrayList<Packet>();
 		switch (state) {
 		case NONE:
-			if (message == null) {
+			if (request == null) {
 				state = STATE.OPEN;
-				response.add(c220);
+				responsePackets.add(new Packet(REPLY_CODE_220));
 			} else {
 				state = STATE.CLOSED;
-				response.add(c421);
+				responsePackets.add(new Packet(REPLY_CODE_421));
 			}
 			break;
 		case OPEN:
-			if (message.contains("QUIT")) {
+			if (request.contains("QUIT")) {
 				state = STATE.CLOSED;
 				return null;
-			} else if (message.equals("USER \r\n")) {
-				response.add(c501);
-			} else if (message.contains("USER")) {
+			} else if (request.equals("USER \r\n")) {
+				responsePackets.add(new Packet(REPLY_CODE_501));
+			} else if (request.contains("USER")) {
 				state = STATE.USER;
-				response.add(c331);
+				responsePackets.add(new Packet(REPLY_CODE_331));
 			} else {
-				response.add(c332);
+				responsePackets.add(new Packet(REPLY_CODE_332));
 			}
 			break;
 		case USER:
-			if (message.equals("PASS \r\n")) {
+			if (request.equals("PASS \r\n")) {
 				state = STATE.OPEN;
-				response.add(c501);
-			} else if (message.contains("PASS")) {
+				responsePackets.add(new Packet(REPLY_CODE_501));
+			} else if (request.contains("PASS")) {
 				state = STATE.LOGGED_IN;
-				response.add(c230);
+				responsePackets.add(new Packet(REPLY_CODE_230));
 			} else {
 				state = STATE.CLOSED;
-				response.add(c221);
+				responsePackets.add(new Packet(REPLY_CODE_221));
 			}
 			break;
 		case LOGGED_IN:
-			if (message != null && !message.contains("QUIT")) {
-				response.add(c500);
+			if (request != null && !request.contains("QUIT")) {
+				responsePackets.add(new Packet(REPLY_CODE_500));
 			} else {
 				state = STATE.CLOSED;
-				response.add(c221);
+				responsePackets.add(new Packet(REPLY_CODE_221));
 			}
 			break;
 		default:
 			state = STATE.CLOSED;
-			response.add(c421);
+			responsePackets.add(new Packet(REPLY_CODE_421));
 		}
-		return response;
+		return responsePackets;
 	}
 	
 	//commands
-	private String c220 = "220 Service ready for new user.";
-	private String c221 = "221 Service closing control connection.";
-	private String c230 = "230 User logged in.";
-	private String c331 = "331 User name ok, need password.";
-	private String c332 = "332 Need account for login.";
-	private String c421 = "421 Service not available, closing control connection.";
-	private String c500 = "500 Syntax error, command unrecognized.";
-	private String c501 = "501 Syntax error in parameters or arguments";
+	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;
 	}
 
-	
+	@Override
 	public String toString() {
 		return "FTP";
 	}

+ 96 - 0
src/de/tudarmstadt/informatik/hostage/protocol/GhostProtocol.java

@@ -0,0 +1,96 @@
+package de.tudarmstadt.informatik.hostage.protocol;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.List;
+
+import de.tudarmstadt.informatik.hostage.wrapper.Packet;
+
+/**
+ * Ghost Protocol. This protocol mirrors an incoming connection back to the
+ * attacker on the same port, that it is running on. It will send all incoming
+ * requests back to the attacker on the mirrored connection and will relpy with
+ * the responses it get's from this mirrored connection.
+ * 
+ * @author Wulf Pfeiffer
+ */
+public class GhostProtocol implements Protocol {
+
+	private boolean isClosed = false;
+
+	@Override
+	public int getDefaultPort() {
+		return 5050; // TODO dynamic port / whats the default!? (1433)
+	}
+
+	@Override
+	public TALK_FIRST whoTalksFirst() {
+		return TALK_FIRST.CLIENT;
+	}
+
+	@Override
+	public List<Packet> processMessage(Packet requestPacket) {
+		List<Packet> responsePackets = new ArrayList<Packet>();
+		try {
+			if (mirroredConnection == null) {
+				mirroredConnection = new Socket("192.168.178.86", 5050); // TODO
+				mirrorInputStream = new BufferedInputStream(
+						mirroredConnection.getInputStream());
+				mirrorOutputStream = new BufferedOutputStream(
+						mirroredConnection.getOutputStream());
+			}
+			if (mirroredConnection.isInputShutdown()
+					|| mirroredConnection.isOutputShutdown()) {
+				mirrorInputStream.close();
+				mirrorOutputStream.close();
+				mirroredConnection.close();
+				isClosed = true;
+			}
+
+			mirrorOutputStream.write(requestPacket.getMessage());
+			mirrorOutputStream.flush();
+
+			int availableBytes;
+			while ((availableBytes = mirrorInputStream.available()) <= 0) {
+				try {
+					Thread.sleep(1);
+				} catch (InterruptedException e) {
+					e.printStackTrace();
+				}
+			}
+			byte[] mirrorResponse = new byte[availableBytes];
+			mirrorInputStream.read(mirrorResponse);
+			responsePackets.add(new Packet(mirrorResponse));
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		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;
+}

+ 115 - 64
src/de/tudarmstadt/informatik/hostage/protocol/HTTP.java

@@ -1,69 +1,85 @@
 package de.tudarmstadt.informatik.hostage.protocol;
 
+import java.security.SecureRandom;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Calendar;
 import java.util.List;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
+import de.tudarmstadt.informatik.hostage.wrapper.Packet;
+
 
 /**
- * HTTP protocol
+ * 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 final class HTTP implements Protocol<String> {
-	
+public class HTTP implements Protocol {
 	
-	public int getPort() {
+	@Override
+	public int getDefaultPort() {
 		return 80;
 	}
 
-	
+	@Override
 	public TALK_FIRST whoTalksFirst() {
 		return TALK_FIRST.CLIENT;
 	}
 	
-	
-	public List<String> processMessage(String message) {
-		List<String> response = new ArrayList<String>();
-		request = message + request;
+	@Override
+	public List<Packet> processMessage(Packet requestPacket) {
+		String request = null;
+		if (requestPacket != null) {
+			request = requestPacket.toString();
+		}
+		List<Packet> responsePackets = new ArrayList<Packet>();
+		this.request = request;
 
-		if(!message.contains(version)){
-			response.add(buildPacket(c505, ""));
-		} else if(message.contains(get)) {
-			response.add(buildPacket(c200, get));
-		} else if(message.contains(head)) {
-			response.add(buildPacket(c200, head));
-		} else if(message.contains(trace)){
-			response.add(buildPacket(c200, trace));
-		} else if(message.contains(options)){
-			response.add(buildPacket(c400, options));
-		} else if(message.contains(post)){
-			response.add(buildPacket(c400, post));
-		} else if(message.contains(put)){
-			response.add(buildPacket(c400, put));
-		} else if(message.contains(delete)){
-			response.add(buildPacket(c400, delete));
-		} else if(message.contains(connect)){
-			response.add(buildPacket(c400, connect));
+		if(!request.contains(httpVersion)){
+			responsePackets.add(buildPacket(STATUS_CODE_505, ""));
+		} else if(request.contains(GET)) {
+			responsePackets.add(buildPacket(STATUS_CODE_200, GET));
+		} else if(request.contains(HEAD)) {
+			responsePackets.add(buildPacket(STATUS_CODE_200, HEAD));
+		} else if(request.contains(TRACE)){
+			responsePackets.add(buildPacket(STATUS_CODE_200, TRACE));
+		} else if(request.contains(OPTIONS)){
+			responsePackets.add(buildPacket(STATUS_CODE_400, OPTIONS));
+		} else if(request.contains(POST)){
+			responsePackets.add(buildPacket(STATUS_CODE_200, POST));
+		} else if(request.contains(PUT)){
+			responsePackets.add(buildPacket(STATUS_CODE_400, PUT));
+		} else if(request.contains(DELETE)){
+			responsePackets.add(buildPacket(STATUS_CODE_200, DELETE));
+		} else if(request.contains(CONNECT)){
+			responsePackets.add(buildPacket(STATUS_CODE_400, CONNECT));
 		} else {
-			response.add(buildPacket(c400, ""));
+			responsePackets.add(buildPacket(STATUS_CODE_400, ""));
 		}
-		return response;
+		return responsePackets;
 	}
 
-	
+	@Override
 	public boolean isClosed() {
 		return true;
 	}
 
-	
+	@Override
 	public boolean isSecure() {
 		return false;
 	}
 
-	
+	@Override
 	public Class<String> getType() {
 		return String.class;
 	}
 
-	
+	@Override
 	public String toString() {
 		return "HTTP";
 	}
@@ -74,37 +90,68 @@ public final class HTTP implements Protocol<String> {
 	 * @param type request type that was sent by the client
 	 * @return the html response
 	 */
-	private String buildPacket(String code, String type) {
-		String doc = "";
-		if(type.equals(get)) doc = htmlDoc;
-		else if(type.equals(head)) doc = "";
-		else if(type.equals(trace)) doc = request;
-		else doc = errorHtmlPrefix + code + errorHtmlSuffix;
-		
-		return version + code + headerPrefix + doc.length() + headerSuffix + doc;
+	private Packet buildPacket(String code, String type) {
+		String document = "";
+		if (type.equals(GET)) {
+			document = htmlDocument;
+		} else if (type.equals(HEAD) || type.equals(DELETE)) {
+			document = "";
+		} else if (type.equals(TRACE)) {
+			document = request;
+		} else {
+			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	= "";
-	private String version	= "HTTP/1.1";
+	//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 String options 	= "OPTIONS";
-	private String get 		= "GET";
-	private String head 	= "HEAD";
-	private String post		= "POST";
-	private String put		= "PUT";
-	private String delete	= "DELETE";
-	private String trace	= "TRACE";
-	private String connect	= "CONNECT";
-	//response codes
-	private String c200 	= " 200 OK\r\n";
-	private String c400 	= " 400 Bad Request\r\n";
-	private String c505 	= " 505 HTTP Version not supported\r\n";
+	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: Mon, 01 Jul 2013 18:27:55 GMT\r\n" +
-			"Server: Apache/2.2.22 (Debian)\r\n" +
+			"Date: " + getServerTime() + "\r\n" +
+			"Server: " + serverVersion + " \r\n" +
 			"Vary: Accept-Encoding\r\n" +
 			"Content-Length: ";
 	private String headerSuffix =
@@ -114,17 +161,14 @@ public final class HTTP implements Protocol<String> {
 			"Content-Type: text/html\r\n" +
 			"\r\n";
 	//html website
-	private String htmlDoc = 
+	private String htmlDocument = 
 			"<!doctype html>\n" +
 			"<html lang=\"en\">\n" +
 			"<head>\n" +
 			"<meta charset=\"UTF-8\">\n" +
-			"<title>Test successful</title>\n" +
+			"<title>" + htmlDocumentContent + "</title>\n" +
+			"<body>" + htmlDocumentContent + "</body>\n" +
 			"</head>\n" +
-			"<body>\n" +
-			"<h1>Test successful</h1>\n" +
-			"<p>Congratulations.</p>\n" +
-			"</body>\n" +
 			"</html>";
 	//html error pre and suffix
 	private String errorHtmlPrefix =
@@ -136,7 +180,14 @@ public final class HTTP implements Protocol<String> {
 	private String errorHtmlSuffix =
 			"</title>\n" +
 			"</head>\n" +
-			"<body>\n" +
-			"</body>\n" +
 			"</html>";
+
+	/**
+	 * Sets the html document content for HTTP and HTTPS.
+	 * 
+	 * @param htmlDocumentContent
+	 */
+	public static void setHtmlDocumentContent(String htmlDocumentContent) {
+		HTTP.htmlDocumentContent = htmlDocumentContent;
+	}
 }

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

@@ -1,174 +1,59 @@
 package de.tudarmstadt.informatik.hostage.protocol;
 
 import java.security.KeyStore;
-import java.util.ArrayList;
-import java.util.List;
 
 import javax.net.ssl.KeyManagerFactory;
 import javax.net.ssl.SSLContext;
 
-import de.tudarmstadt.informatik.hostage.ui.MainActivity;
+import de.tudarmstadt.informatik.hostage.HoneyService;
 
 /**
- * HTTPS protocol
+ * HTTPS protocol. Extends HTTP.
+ * 
  * @author Wulf Pfeiffer
  */
-public class HTTPS implements SSLProtocol<String> {
+public class HTTPS extends HTTP implements SSLProtocol {
 
-	
-	public int getPort() {
+	@Override
+	public int getDefaultPort() {
 		return 443;
 	}
 
-	
-	public TALK_FIRST whoTalksFirst() {
-		return TALK_FIRST.CLIENT;
-	}
-	
-	
-	public List<String> processMessage(String message) {
-		List<String> response = new ArrayList<String>();
-		request = message + request;
-
-		if(!message.contains(version)){
-			response.add(buildPacket(c505, ""));
-		} else if(message.contains(get)) {
-			response.add(buildPacket(c200, get));
-		} else if(message.contains(head)) {
-			response.add(buildPacket(c200, head));
-		} else if(message.contains(trace)){
-			response.add(buildPacket(c200, trace));
-		} else if(message.contains(options)){
-			response.add(buildPacket(c400, options));
-		} else if(message.contains(post)){
-			response.add(buildPacket(c400, post));
-		} else if(message.contains(put)){
-			response.add(buildPacket(c400, put));
-		} else if(message.contains(delete)){
-			response.add(buildPacket(c400, delete));
-		} else if(message.contains(connect)){
-			response.add(buildPacket(c400, connect));
-		} else {
-			response.add(buildPacket(c400, ""));
-		}
-		return response;
-	}
-
-	
-	public boolean isClosed() {
-		return true;
-	}
-
-	
+	@Override
 	public boolean isSecure() {
 		return true;
 	}
 
-	
-	public Class<String> getType() {
-		return String.class;
-	}
-
-	
+	@Override
 	public String toString() {
 		return "HTTPS";
 	}
-	
-	
+
+	@Override
 	public SSLContext getSSLContext() {
-		String ksName = "https_cert.bks";
-		char ksPass[] = "password".toCharArray();
-		KeyStore ks;
-		KeyManagerFactory kmf = null;
+		String keyStoreName = "https_cert.bks";
+		char keyStorePassword[] = "password".toCharArray();
+		KeyStore keyStore;
+		KeyManagerFactory keyManagerFactory = null;
 		try {
-			ks = KeyStore.getInstance(KeyStore.getDefaultType());
-			ks.load(MainActivity.getContext().getAssets().open(ksName), ksPass);
-			kmf = KeyManagerFactory.getInstance(KeyManagerFactory
+			keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
+			keyStore.load(
+					HoneyService.getContext().getAssets().open(keyStoreName),
+					keyStorePassword);
+			keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory
 					.getDefaultAlgorithm());
-			kmf.init(ks, ksPass);
+			keyManagerFactory.init(keyStore, keyStorePassword);
 		} catch (Exception e) {
 			e.printStackTrace();
 		}
-
-		SSLContext sslcontext = null;
+		SSLContext sslContext = null;
 		try {
-			sslcontext = SSLContext.getInstance("SSLv3");
-			sslcontext.init(kmf.getKeyManagers(), null, null);
+			sslContext = SSLContext.getInstance("SSLv3");
+			sslContext.init(keyManagerFactory.getKeyManagers(), null, null);
 		} catch (Exception e) {
 			e.printStackTrace();
 		}
-		return sslcontext;
-	}
-
-	/**
-	 * 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
-	 * @return the html response
-	 */
-	private String buildPacket(String code, String type) {
-		String doc = "";
-		if(type.equals(get)) doc = htmlDoc;
-		else if(type.equals(head)) doc = "";
-		else if(type.equals(trace)) doc = request;
-		else doc = errorHtmlPrefix + code + errorHtmlSuffix;
-		
-		return version + code + headerPrefix + doc.length() + headerSuffix + doc;
+		return sslContext;
 	}
 
-	/** Whole request that was sent by the client */
-	private String request	= "";
-	private String version	= "HTTP/1.1";
-	//request codes
-	private String options 	= "OPTIONS";
-	private String get 		= "GET";
-	private String head 	= "HEAD";
-	private String post		= "POST";
-	private String put		= "PUT";
-	private String delete	= "DELETE";
-	private String trace	= "TRACE";
-	private String connect	= "CONNECT";
-	//response codes
-	private String c200 	= " 200 OK\r\n";
-	private String c400 	= " 400 Bad Request\r\n";
-	private String c505 	= " 505 HTTP Version not supported\r\n";
-	
-	//html header pre and suffix
-	private String headerPrefix =				
-			"Date: Mon, 01 Jul 2013 18:27:55 GMT\r\n" +
-			"Server: Apache/2.2.22 (Debian)\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 htmlDoc = 
-			"<!doctype html>\n" +
-			"<html lang=\"en\">\n" +
-			"<head>\n" +
-			"<meta charset=\"UTF-8\">\n" +
-			"<title>Test successful</title>\n" +
-			"</head>\n" +
-			"<body>\n" +
-			"<h1>Test successful</h1>\n" +
-			"<p>Congratulations.</p>\n" +
-			"</body>\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" +
-			"<body>\n" +
-			"</body>\n" +
-			"</html>";
 }

+ 111 - 75
src/de/tudarmstadt/informatik/hostage/protocol/MySQL.java

@@ -1,155 +1,191 @@
 package de.tudarmstadt.informatik.hostage.protocol;
 
 import java.nio.ByteBuffer;
+import java.security.SecureRandom;
 import java.util.ArrayList;
 import java.util.List;
 
 import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
-import de.tudarmstadt.informatik.hostage.wrapper.ByteArray;
+import de.tudarmstadt.informatik.hostage.wrapper.Packet;
 
 /**
- * MySQL protocol
+ * MySQL protocol.
+ * 
  * @author Wulf Pfeiffer
  */
-public class MySQL implements Protocol<ByteArray>{
+public class MySQL implements Protocol {
 	/**
 	 * Represents the states of the protocol
 	 */
 	private enum STATE {
 		NONE, CONNECTED, LOGIN_INFO, CLOSED
 	}
-	
+
 	/**
 	 * Denotes in which state the protocol is right now
 	 */
 	private STATE state = STATE.NONE;
-		
-	/** last request from client */ 
-	private byte[] lastMessage;
-	
-	
-	public List<ByteArray> processMessage(ByteArray request) {
-		List<ByteArray> response = new ArrayList<ByteArray>();
-		if(request != null)
-			lastMessage = request.get();
-				
-		switch(state) {
+
+	/** last request from client */
+	private byte[] lastReceivedMessage;
+
+	@Override
+	public List<Packet> processMessage(Packet requestPacket) {
+		byte[] request = null;
+		if (requestPacket != null) {
+			request = requestPacket.getMessage();
+		}
+		List<Packet> responsePackets = new ArrayList<Packet>();
+		if (request != null)
+			lastReceivedMessage = request;
+
+		switch (state) {
 		case NONE:
-			response.add(new ByteArray(greeting()));
+			responsePackets.add(greeting());
 			state = STATE.CONNECTED;
 			break;
 		case CONNECTED:
-			response.add(new ByteArray(responseOK()));
+			responsePackets.add(responseOK());
 			state = STATE.LOGIN_INFO;
 			break;
 		case LOGIN_INFO:
-			if(this.lastMessage[4] == 0x01) {
+			if (this.lastReceivedMessage[4] == 0x01) {
 				state = STATE.CLOSED;
 			} else {
-				response.add(new ByteArray(responseError()));
+				responsePackets.add(responseError());
 			}
 			break;
 		default:
 			state = STATE.CLOSED;
 			break;
 		}
-		
-		return response;
+
+		return responsePackets;
 	}
-	
-	
+
+	@Override
 	public TALK_FIRST whoTalksFirst() {
 		return TALK_FIRST.SERVER;
 	}
 
-	
-	public String toString(){
-		return "MySQL";		
+	@Override
+	public String toString() {
+		return "MySQL";
 	}
-	
-	
-	public int getPort() {
+
+	@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 packet that is wrapped
+	 * 
+	 * @param response
+	 *            that is wrapped
 	 * @return wrapped packet
 	 */
-	private byte[] wrapPacket(byte[] packet) {
-		byte[] buffer = ByteBuffer.allocate(4).putInt(packet.length).array();
-		byte[] packetLength = {buffer[3], buffer[2], buffer[1]};
+	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(lastMessage != null) packetNumber[0] = (byte) (lastMessage[3] + 1);
-		else packetNumber[0] = 0x00;
-		
-		byte[] response = HelperUtils.concat(packetLength, packetNumber, packet);
-		return response;
+		if (lastReceivedMessage != null)
+			packetNumber[0] = (byte) (lastReceivedMessage[3] + 1);
+		else
+			packetNumber[0] = 0x00;
+
+		byte[] wrappedResponse = HelperUtils.concat(packetLength, packetNumber,
+				response);
+		return new Packet(wrappedResponse);
 	}
-	
+
 	/**
 	 * Builds the greeting packet that the server sends as first packet
+	 * 
 	 * @return greeting packet
 	 */
-	private byte[] greeting() {
-		byte[] protocol = {0x0a};
-		String version = "5.5.31-0+wheezy1";
-		byte[] versionFin = {0x00};
-		byte[] thread = {0x2a, 0x00, 0x00, 0x00};
-		byte[] salt = {0x44, 0x64, 0x49, 0x7e, 0x60, 0x48, 0x25, 0x7e, 0x00};
-		byte[] capabilities = {(byte) 0xff, (byte) 0xf7};
-		byte[] language = {0x08};
-		byte[] status = {0x02, 0x00};
-		byte[] unused = {0x0f, (byte) 0x80, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-		byte[] salt2 = {0x6c, 0x26, 0x71, 0x2c, 0x25, 0x72, 0x31, 0x3d, 0x7d, 0x21, 0x26, 0x3b, 0x00};
+	private Packet greeting() {
+		byte[] protocol = { 0x0a };
+		byte[] version = serverVersion.getBytes();
+		byte[] versionFin = { 0x00 };
+		byte[] thread = { 0x2a, 0x00, 0x00, 0x00 };
+		byte[] salt = { 0x44, 0x64, 0x49, 0x7e, 0x60, 0x48, 0x25, 0x7e, 0x00 };
+		byte[] capabilities = { (byte) 0xff, (byte) 0xf7 };
+		byte[] language = { 0x08 };
+		byte[] status = { 0x02, 0x00 };
+		byte[] unused = { 0x0f, (byte) 0x80, 0x15, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+		byte[] salt2 = { 0x6c, 0x26, 0x71, 0x2c, 0x25, 0x72, 0x31, 0x3d, 0x7d,
+				0x21, 0x26, 0x3b, 0x00 };
 		String payload = "mysql_native_password";
-		byte[] fin = {0x00};
-		
-		byte[] response = HelperUtils.concat(protocol, version.getBytes(),versionFin, thread, salt, capabilities, language, status, unused, salt2, payload.getBytes(), fin);
+		byte[] fin = { 0x00 };
+
+		byte[] response = HelperUtils.concat(protocol, version, versionFin,
+				thread, salt, capabilities, language, status, unused, salt2,
+				payload.getBytes(), fin);
 		return wrapPacket(response);
 	}
-	
+
 	/**
 	 * Builds the ok-response packet
+	 * 
 	 * @return ok-response packet
 	 */
-	private byte[] responseOK() {
-		byte[] affectedRows = {0x00, 0x00, 0x00};
-		byte[] status = {0x02, 0x00};
-		byte[] warnings = {0x00, 0x00};
-		
+	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
+	 * 
 	 * @return error-response packet
 	 */
-	private byte[] responseError() {
-		byte[] fill1 = {(byte) 0xff};
-		byte[] code = {0x17, 0x04};
-		byte[] fill2 = {0x23};
+	private Packet responseError() {
+		byte[] fill1 = { (byte) 0xff };
+		byte[] code = { 0x17, 0x04 };
+		byte[] fill2 = { 0x23 };
 		String state = "08S01";
 		String msg = "Unknown command";
-		
-		byte[] response = HelperUtils.concat(fill1, code, fill2, state.getBytes(), msg.getBytes());		
+
+		byte[] response = HelperUtils.concat(fill1, code, fill2,
+				state.getBytes(), msg.getBytes());
 		return wrapPacket(response);
 	}
 
-	
-	public boolean isSecure() {
-		return false;
-	}
+	// 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"}}
+	};
 
-	
-	public Class<ByteArray> getType() {
-		return ByteArray.class;
+	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)];
 	}
+
+	private static String serverVersion = initMysqlVersion();
 }

+ 10 - 8
src/de/tudarmstadt/informatik/hostage/protocol/Protocol.java

@@ -2,12 +2,14 @@ package de.tudarmstadt.informatik.hostage.protocol;
 
 import java.util.List;
 
+import de.tudarmstadt.informatik.hostage.wrapper.Packet;
+
 /**
  * Interface for protocols that are used by the application.
- * @param <T> Denotes if the protocol is using Strings or ByteArrays.
  * @author Mihai Plasoianu
+ * @author Wulf Pfeiffer
  */
-public interface Protocol<T> {
+public interface Protocol {
 
 	/**
 	 * Represents who starts the communication once the connection is established.
@@ -17,10 +19,10 @@ public interface Protocol<T> {
 	};
 
 	/**
-	 * Returns the port on which the protocol is running.
-	 * @return the port used by the protocol (range: 0-65535)
+	 * Returns the default port on which the protocol is running.
+	 * @return the default port used by the protocol (range: 0-65535)
 	 */
-	int getPort();
+	int getDefaultPort();
 
 	/**
 	 * Returns who starts the communication (server or client)
@@ -30,10 +32,10 @@ public interface Protocol<T> {
 
 	/**
 	 * Determines the next message that is sent by the server.
-	 * @param message last message that was sent by the client.
+	 * @param packet last message that was sent by the client.
 	 * @return next message that will be sent.
 	 */
-	List<T> processMessage(T message);
+	List<Packet> processMessage(Packet packet);
 
 	/**
 	 * Returns whether the communication is ended and the connection should be closed or not.
@@ -51,7 +53,7 @@ public interface Protocol<T> {
 	 * Returns what type the protocol is using, Strings or ByteArrays.
 	 * @return the class that the protocol is using.
 	 */
-	Class<T> getType();
+	Class<? extends Object> getType();
 	
 	/**
 	 * Returns the name of the protocol.

+ 41 - 0
src/de/tudarmstadt/informatik/hostage/protocol/SIP.java

@@ -0,0 +1,41 @@
+package de.tudarmstadt.informatik.hostage.protocol;
+
+import java.util.List;
+
+import de.tudarmstadt.informatik.hostage.wrapper.Packet;
+
+public class SIP implements Protocol {
+
+	@Override
+	public int getDefaultPort() {
+		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
+		return true;
+	}
+
+	@Override
+	public boolean isSecure() {
+		return false;
+	}
+
+	@Override
+	public Class<byte[]> getType() {
+		return byte[].class;
+	}
+
+}

+ 599 - 483
src/de/tudarmstadt/informatik/hostage/protocol/SMB.java

@@ -1,20 +1,26 @@
 package de.tudarmstadt.informatik.hostage.protocol;
 
 import java.nio.ByteBuffer;
+import java.security.SecureRandom;
 import java.util.ArrayList;
 import java.util.Calendar;
+import java.util.GregorianCalendar;
 import java.util.List;
-import java.util.Random;
 import java.util.TimeZone;
 
+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.ByteArray;
+import de.tudarmstadt.informatik.hostage.wrapper.Packet;
 
 /**
- * SMB protocol
+ * 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 final class SMB implements Protocol<ByteArray> {
+public class SMB implements Protocol {
 	/**
 	 * Represents the states of the protocol
 	 */
@@ -29,108 +35,106 @@ public final class SMB implements Protocol<ByteArray> {
 
 	private byte[] lastMessage;
 	
-	
-	public int getPort() {
+	@Override
+	public int getDefaultPort() {
 		return 445;
 	}
 
-	
+	@Override
 	public TALK_FIRST whoTalksFirst() {
 		return TALK_FIRST.CLIENT;
 	}
 	
-	private SMBPacket packet = new SMBPacket();
-
-	
-	public List<ByteArray> processMessage(ByteArray message) {
-		if(message != null)
-			lastMessage = message.get();
-		packet.newMsg(lastMessage);
-		byte smbCommand = packet.getSmbCommand();
-		List<ByteArray> response = new ArrayList<ByteArray>();
+	@Override
+	public List<Packet> processMessage(Packet requestPacket) {
+		if(requestPacket != null)
+			lastMessage = requestPacket.getMessage();
+		parseMessageHeader(lastMessage);
+		byte smbCommand = getSmbCommand();
+		List<Packet> responsePackets = new ArrayList<Packet>();
 
 		switch (state) {
 		case NONE:
-			if (smbCommand == 0x72) {
+			if (smbCommand == SMB_COM_NEGOTIATE) {
 				state = STATE.CONNECTED;
-				response.add(new ByteArray(packet.getNego()));
+				responsePackets.add(getNego());
 			} else {
 				state = STATE.DISCONNECTED;
-				response.add(new ByteArray(packet.getTreeDisc()));
+				responsePackets.add(getTreeDisc());
 			}
 			break;
 		case CONNECTED:
-			if (smbCommand == 0x73) {
-				response.add(new ByteArray(packet.getSessSetup()));
-			} else if (smbCommand == 0x75) {
+			if (smbCommand == SMB_COM_SESSION_SETUP_ANDX) {
+				responsePackets.add(getSessSetup());
+			} else if (smbCommand == SMB_COM_TREE_CONNECT_ANDX) {
 				state = STATE.AUTHENTICATED;
-				response.add(new ByteArray(packet.getTreeCon()));
+				responsePackets.add(getTreeCon());
 			} else {
 				state = STATE.DISCONNECTED;
-				response.add(new ByteArray(packet.getTreeDisc()));
+				responsePackets.add(getTreeDisc());
 			}
 			break;
 		case AUTHENTICATED:
-			if (smbCommand == (byte) 0xa2) {
+			if (smbCommand == SMB_COM_NT_CREATE_ANDX) {
 				state = STATE.LISTING;
-				response.add(new ByteArray(packet.getNTCreate()));
-			} else if (smbCommand == 0x2b) {
-				response.add(new ByteArray(packet.getEcho()));
-			} else if (smbCommand == 0x32) {
-				response.add(new ByteArray(packet.getTrans2()));
-			} else if (smbCommand == 0x04) {
-				response.add(new ByteArray(packet.getClose()));
-			} else if (smbCommand == 0x71) {
+				responsePackets.add(getNTCreate());
+			} else if (smbCommand == SMB_COM_ECHO) {
+				responsePackets.add(getEcho());
+			} else if (smbCommand == SMB_COM_TRANSACTION2) {
+				responsePackets.add(getTrans2());
+			} else if (smbCommand == SMB_COM_CLOSE) {
+				responsePackets.add(getClose());
+			} else if (smbCommand == SMB_COM_TREE_DISCONNECT) {
 				state = STATE.CLOSED;
-				response.add(new ByteArray(packet.getTreeDisc()));
+				responsePackets.add(getTreeDisc());
 			} else {
 				state = STATE.DISCONNECTED;
-				response.add(new ByteArray(packet.getTreeDisc()));
+				responsePackets.add(getTreeDisc());
 			}
 			break;
 		case LISTING:
-			if (smbCommand == 0x25) {
-				response.add(new ByteArray(packet.getTrans()));
-			} else if (smbCommand == 0x04) {
-				response.add(new ByteArray(packet.getClose()));
-			} else if (smbCommand == 0x71) {
+			if (smbCommand == SMB_COM_TRANSACTION) {
+				responsePackets.add(getTrans());
+			} else if (smbCommand == SMB_COM_CLOSE) {
+				responsePackets.add(getClose());
+			} else if (smbCommand == SMB_COM_TREE_DISCONNECT) {
 				state = STATE.CLOSED;
-				response.add(new ByteArray(packet.getTreeDisc()));
-			} else if (smbCommand == 0x72) {
+				responsePackets.add(getTreeDisc());
+			} else if (smbCommand == SMB_COM_NEGOTIATE) {
 				state = STATE.CONNECTED;
-				response.add(new ByteArray(packet.getNego()));
+				responsePackets.add(getNego());
 			} else {
 				state = STATE.DISCONNECTED;
-				response.add(new ByteArray(packet.getTreeDisc()));
+				responsePackets.add(getTreeDisc());
 			}
 			break;
 		case DISCONNECTED:
 			state = STATE.CLOSED;
-			response.add(new ByteArray(packet.getTreeDisc()));
+			responsePackets.add(getTreeDisc());
 			break;
 		default:
 			state = STATE.CLOSED;
-			response.add(new ByteArray(packet.getTreeDisc()));
+			responsePackets.add(getTreeDisc());
 		}
-		return response;
+		return responsePackets;
 	}
 
-	
+	@Override
 	public boolean isClosed() {
 		return (state == STATE.CLOSED);
 	}
 
-	
+	@Override
 	public boolean isSecure() {
 		return false;
 	}
 
-	
-	public Class<ByteArray> getType() {
-		return ByteArray.class;
+	@Override
+	public Class<byte[]> getType() {
+		return byte[].class;
 	}
 
-	
+	@Override
 	public String toString() {
 		return "SMB";
 	}
@@ -139,7 +143,7 @@ public final class SMB implements Protocol<ByteArray> {
 	 * Converts the current system time into a byte[] with windows specific time
 	 * @return current system time in windows format as byte[]
 	 */
-	private byte[] getTimeInBytes() {
+	private static byte[] getTimeInBytes() {
 		long time = System.currentTimeMillis();
 		Calendar calend = Calendar.getInstance();
 		calend.setTimeZone(TimeZone.getTimeZone("UTC"));
@@ -147,472 +151,584 @@ public final class SMB implements Protocol<ByteArray> {
 		time -= calend.getTimeInMillis();
 		time *= 10000;
 
-		byte[] b = new byte[8];
-		byte[] b2 = ByteBuffer.allocate(8).putLong(time).array();
+		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--) {
-			b[i] = (byte) (b2[j] & 0xff);
+			timeInWindowsBytes[i] = (byte) (timeInBytes[j] & 0xff);
 		}
 
-		return b;
+		return timeInWindowsBytes;
 	}
 	
 	/**
-	 * Generates a random byte[] of a specified size
-	 * @param size of the byte[]
-	 * @return random byte[]
+	 * Converts the current timezone into a byte[] with windows specific format
+	 * @return current timezone in windows format as byte[]
 	 */
-	private byte[] randomBytes(int size) {
-		byte[] bytes = new byte[size];
-		Random rdm = new Random();
-		rdm.nextBytes(bytes);
-		return bytes;
+	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;
 	}
 
+	//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)];
+		}
+	}
+	
+	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
+	 */
+	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);
+	}
+	
 	/**
-	 * Denotes a SMB packet
+	 * Builds the negotiate packet
+	 * @return negotiate packet
 	 */
-	private class SMBPacket {
-		private byte[] message				= null; 
-		private final byte[] serverGUID		= 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];
-				
-		/** Constructor */
-		public SMBPacket() {}
+	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};
 		
-		/**
-		 * Breaks a message from the client down into its components
-		 * @param message that is analyzed
-		 */
-		public void newMsg(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]};
+		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
+	 */
+	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++;
+			}
 		}
-		
-		/**
-		 * 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);
+		return new byte[]{0x00, 0x00};
+	}
+	
+	/**
+	 * Builds the session setup packet
+	 * @ret	urn session setup packet
+	 */
+	private Packet getSessSetup() {
+		if(authenticateNext) {
+			return new Packet(getSetupAuth());
+		} else {
+			authenticateNext = true;
+			return new Packet(getSetupChal());
 		}
-		
-		/**
-		 * Wraps the header around a response
-		 * @param response that is wrapped
-		 * @return wrapped response
-		 */
-		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);
+	}
+	
+	/**
+	 * 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[] 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")) {
+			flags[3] = (byte) (flags[3] | 0x02);
 		}
-		
-		/**
-		 * Builds the negotiate packet
-		 * @return negotiate packet
-		 */
-		public byte[] 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		= {(byte) 0x88, (byte) 0xff};		//FIXME correct time zone
-			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 wrapNetbios(wrapHeader(response));
+		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};
 		}
+		// serverName
+		byte[] attributeNBDomain	= {0x02, 0x00, 0x10, 0x00};
+		// serverName	
+		byte[] attributeNBcomputer	= {0x01, 0x00, 0x10, 0x00};
+		// serverName	
+		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]};
 		
-		/**
-		 * 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};
-		}
+		ntStat 					= new byte[]{0x16, 0x00, 0x00, (byte) 0xc0};
+		userID					= new byte[]{0x00, 0x08};
 		
-		/**
-		 * Builds the session setup packet
-		 * @return session setup packet
-		 */
-		public byte[] getSessSetup() {
-			if(authenticateNext) return getSetupAuth();
-			else {
-				authenticateNext = true;
-				return getSetupChal();
-			}
-		}
+		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
+	 */
+	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());
 		
-		/**
-		 * 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[] secBlobLength	= {(byte) 0xc7, 0x00};
-			byte[] byteCount		= {0x35, 0x01};
-			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[] respToken		= {0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 
-										0x38, 0x00, 0x00, 0x00, 0x15, (byte) 0x82, (byte) 0x8a, 0x62};
-			byte[] challenge		= randomBytes(8);
-			byte[] respToken2		= {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x60, 0x00, 0x48, 0x00, 0x00, 0x00, 
-										0x06, 0x01, (byte) 0xb0, 0x1d, 0x00, 0x00, 0x00, 0x0f, 0x42, 0x00, 0x55, 0x00, 0x53, 0x00, 0x49, 0x00, 
-										0x4e, 0x00, 0x45, 0x00, 0x53, 0x00, 0x53, 0x00, 0x02, 0x00, 0x10, 0x00, 0x42, 0x00, 0x55, 0x00, 
-										0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x45, 0x00, 0x53, 0x00, 0x53, 0x00, 0x01, 0x00, 0x10, 0x00, 
-										0x42, 0x00, 0x55, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x45, 0x00, 0x53, 0x00, 0x53, 0x00, 
-										0x04, 0x00, 0x10, 0x00, 0x42, 0x00, 0x55, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x45, 0x00, 
-										0x53, 0x00, 0x53, 0x00, 0x03, 0x00, 0x10, 0x00, 0x42, 0x00, 0x55, 0x00, 0x53, 0x00, 0x49, 0x00, 
-										0x4e, 0x00, 0x45, 0x00, 0x53, 0x00, 0x53, 0x00, 0x07, 0x00, 0x08, 0x00};
-			byte[] timeStamp		= getTimeInBytes();
-			byte[] respToken3		= {0x00, 0x00, 0x00, 0x00};
-			byte[] nativOS			= {0x57, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x64, 0x00, 
-										0x6f, 0x00, 0x77, 0x00, 0x73, 0x00, 0x20, 0x00, 0x37, 0x00, 0x20, 0x00, 0x50, 0x00, 0x72, 0x00, 
-										0x6f, 0x00, 0x66, 0x00, 0x65, 0x00, 0x73, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 
-										0x61, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x37, 0x00, 0x36, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00};			//Windows 7 Professional 7600
-			byte[] nativLanMngr		= {0x57, 0x00, 0x69, 0x00, 0x6e, 0x00, 			
-										0x64, 0x00, 0x6f, 0x00, 0x77, 0x00, 0x73, 0x00, 0x20, 0x00, 0x37, 0x00, 0x20, 0x00, 0x50, 0x00, 
-										0x72, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x65, 0x00, 0x73, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 
-										0x6e, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x36, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x00, 0x00};			//Windows 7 Professional 6.1
-			
-			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, negToken, negResult, negToken2, supportedMech, negToken3, 
-												respToken, challenge, respToken2, timeStamp, respToken3, nativOS, nativLanMngr);
-			return wrapNetbios(wrapHeader(response));
-		}
+		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]};
 		
-		/**
-		 * 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	= {0x09, 0x00};
-			byte[] byteCount		= {(byte) 0x77, 0x00};
-			byte[] secBlob			= {(byte) 0xa1, 0x07, 0x30, 0x05, (byte) 0xa0, 0x03, 0x0a, 0x01, 0x00};
-			byte[] nativOS			= {0x57, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x64, 0x00, 
-										0x6f, 0x00, 0x77, 0x00, 0x73, 0x00, 0x20, 0x00, 0x37, 0x00, 0x20, 0x00, 0x50, 0x00, 0x72, 0x00, 
-										0x6f, 0x00, 0x66, 0x00, 0x65, 0x00, 0x73, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 
-										0x61, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x37, 0x00, 0x36, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00};			//Windows 7 Professional 7600
-			byte[] nativLanMngr		= {0x57, 0x00, 0x69, 0x00, 0x6e, 0x00, 			
-										0x64, 0x00, 0x6f, 0x00, 0x77, 0x00, 0x73, 0x00, 0x20, 0x00, 0x37, 0x00, 0x20, 0x00, 0x50, 0x00, 
-										0x72, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x65, 0x00, 0x73, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 
-										0x6e, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x36, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x00, 0x00};			//Windows 7 Professional 6.1
-
-			
-			byte[] response = HelperUtils.concat(wordCount, andXCommand, reserved, andXOffset, action, secBlobLength,
-					byteCount, secBlob, nativOS, nativLanMngr);
-			return wrapNetbios(wrapHeader(response));
-		}
+		byte[] response = HelperUtils.concat(wordCount, andXCommand, reserved, andXOffset, action, secBlobLength,
+				byteCount, secBlob, nativOS, nativLanMngr);
+		return wrapNetbios(wrapHeader(response));
+	}
+	
+	/**
+	 * Builds the tree connect packet
+	 * @return tree connect 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};
 		
-		/**
-		 * Builds the tree connect packet
-		 * @return tree connect packet
-		 */
-		public byte[] getTreeCon() {
-			String str 			= toString();
-			byte[] wordCount	= {0x00};
-			byte[] andXCommand	= {0x00, 0x00};
-			byte[] response 	= null;
-			
-			if(str.contains("IPC$") || str.contains("DOCS")) {
-				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("C$") || 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 wrapNetbios(wrapHeader(response));
+			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);
 		}
 		
-		/**
-		 * Builds the nt create packet
-		 * @return nt create packet
-		 */
-		public byte[] 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 wrapNetbios(wrapHeader(response));
-		}
+		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};
 		
-		/**
-		 * Builds the trans packet
-		 * @return trans packet
-		 */
-		public byte[] getTrans() {
-			byte[] transSub	= getTransSub();
-			byte[] response = null;
-			if(transSub[0] == 0x00 && transSub[1] == 0x0b) {
-				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			= {0x05, 0x00, 
-											0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, (byte) 0xb8, 0x10, 
-											(byte) 0xb8, 0x10, 0x4a, 0x41, 0x00, 0x00, 0x0d, 0x00, 0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c, 0x73, 0x72, 
-											0x76, 0x73, 0x76, 0x63, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 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(wordCount, totalParamCount, totalDataCount, reserved, paramCount, paramOffset,
-													paramDisplace, dataCount, dataOffset, dataDisplace, setupCount, reserved2, byteCount, padding, dcerpc);
-				
-			} else if(transSub[0] == 0x00 && transSub[1] == 0x00) {
-				byte[] wordCount		= {0x0a};
-				byte[] totalParamCount	= {0x00, 0x00};
-				byte[] totalDataCount	= {0x54, 0x01};
-				byte[] reserved			= {0x00, 0x00};
-				byte[] paramCount		= {0x00, 0x00};
-				byte[] paramOffset		= {0x38, 0x00};
-				byte[] paramDisplace	= {0x00, 0x00};
-				byte[] dataCount		= {0x54, 0x01};
-				byte[] dataOffset		= {0x38, 0x00};
-				byte[] dataDisplace		= {0x00, 0x00};
-				byte[] setupCount		= {0x00};
-				byte[] reserved2		= {0x00};
-				byte[] byteCount		= {0x55, 0x01};
-				byte[] padding			= {0x00};
-				
-				byte[] dcerpc			= {0x05, 0x00, 
-											0x02, 0x03, 0x10, 0x00, 0x00, 0x00, 0x54, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3c, 0x01, 
-											0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-				byte[] serverService	= {0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 
-											0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 
-											0x02, 0x00, 0x00, 0x00, 0x00, (byte) 0x80, 0x0c, 0x00, 0x02, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 
-											0x00, (byte) 0x80, 0x14, 0x00, 0x02, 0x00, 0x18, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 
-											0x02, 0x00, 0x20, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, (byte) 0x80, 0x24, 0x00, 0x02, 0x00, 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, 
-											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, 0x00, 0x00, 0x05, 0x00, 
-											0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x64, 0x00, 0x6f, 0x00, 0x63, 0x00, 
-											0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 
-											0x00, 0x00, 0x00, 0x00, 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, 0x04, 0x00, 0x00, 0x00};
-				byte[] referentID		= {0x28, 0x00, 0x02, 0x00};
-				byte[] resumeHandle		= {0x00, 0x00, 0x00, 0x00};
-				byte[] windowsError		= {0x00, 0x00, 0x00, 0x00};
-
-				response = HelperUtils.concat(wordCount, totalParamCount, totalDataCount, reserved, paramCount, paramOffset,
-													paramDisplace, dataCount, dataOffset, dataDisplace, setupCount, reserved2, byteCount, padding, dcerpc,
-													serverService, totalEntries, referentID, resumeHandle, windowsError);
-				
-				
-			}
+		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
+	 */
+	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};
 			
-			return wrapNetbios(wrapHeader(response));		
-		}
-		
-		/**
-		 * Builds the close packet
-		 * @return close packet
-		 */
-		public byte[] getClose() {
-			byte[] wordCount	= {0x00};
-			byte[] byteCount	= {0x00, 0x00};
+			byte[] dcerpc			= getDceRpc(transSub, 0); 
 			
-			smbCommand			= new byte[]{0x04};
+			response = HelperUtils.concat(wordCount, totalParamCount, totalDataCount, reserved, paramCount, paramOffset,
+												paramDisplace, dataCount, dataOffset, dataDisplace, setupCount, reserved2, byteCount, padding, dcerpc);
 			
-			byte[] response = HelperUtils.concat(wordCount, byteCount);
+		} 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};
 			
-			return wrapNetbios(wrapHeader(response));
+			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 tree disconnect packet
-		 * @return tree disconnect packet
-		 */
-		public byte[] getTreeDisc() {
-			byte[] wordCount	= {0x00};
-			byte[] byteCount	= {0x00, 0x00};
+	/**
+	 * Builds the DCERPC packet
+	 * @return DCERPC 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;
 			
-			smbCommand[0] = 0x71;
+		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};
 			
-			byte[] response = HelperUtils.concat(wordCount, byteCount);
+			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};
 			
-			return wrapNetbios(wrapHeader(response));
-		}
+			response = HelperUtils.concat(majorVersion, minorVersion, packetType, packetFlags, dataRepres,fragLength,
+					authLength, callID, allocHint, contextID, cancelCount);
+		}			
+		return response;
+	}
+	
+	/**
+	 * Builds the close packet
+	 * @return close packet
+	 */
+	private Packet getClose() {
+		byte[] wordCount	= {0x00};
+		byte[] byteCount	= {0x00, 0x00};
 		
-		/**
-		 * Builds the echo packet
-		 * @return echo packet
-		 */
-		public byte[] 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 wrapNetbios(wrapHeader(response));
-
-		}
+		smbCommand			= new byte[]{0x04};
 		
-		/**
-		 * Builds the trans2 packet
-		 * @return trans2 packet
-		 */
-		public byte[] 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 wrapNetbios(wrapHeader(response));
-		}
+		byte[] response = HelperUtils.concat(wordCount, byteCount);
 		
-		/**
-		 * 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;
-		}
-
+		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};
 		
-		public String toString() {
-			return HelperUtils.byteToStr(message);
-		}
+		smbCommand[0] = 0x71;
 		
-		/**
-		 * Returns the command number from the current message
-		 * @return command number
-		 */
-		public byte getSmbCommand() {
-			return smbCommand[0];
-		}
+		byte[] response = HelperUtils.concat(wordCount, byteCount);
+		
+		return new Packet(wrapNetbios(wrapHeader(response)));
 	}
-}
+	
+	/**
+	 * Builds the echo packet
+	 * @return echo packet
+	 */
+	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 trans2 packet
+	 * @return trans2 packet
+	 */
+	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;
+	}
+	/**
+	 * Returns the command number from the current message
+	 * @return command number
+	 */
+	private byte getSmbCommand() {
+		return smbCommand[0];
+	}
+	
+	//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;
+	
+}

+ 490 - 306
src/de/tudarmstadt/informatik/hostage/protocol/SSH.java

@@ -1,438 +1,622 @@
 package de.tudarmstadt.informatik.hostage.protocol;
 
+import java.io.IOException;
 import java.math.BigInteger;
 import java.nio.ByteBuffer;
-import java.security.KeyFactory;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.MessageDigest;
-import java.security.PublicKey;
-import java.security.Signature;
-import java.security.interfaces.DSAPublicKey;
+import java.security.SecureRandom;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Random;
 
-import javax.crypto.KeyAgreement;
-import javax.crypto.interfaces.DHPublicKey;
-import javax.crypto.spec.DHParameterSpec;
-import javax.crypto.spec.DHPublicKeySpec;
 import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
-import de.tudarmstadt.informatik.hostage.wrapper.ByteArray;
+import de.tudarmstadt.informatik.hostage.ssh.crypto.KeyMaterial;
+import de.tudarmstadt.informatik.hostage.ssh.crypto.PEMDecoder;
+import de.tudarmstadt.informatik.hostage.ssh.crypto.cipher.CBCMode;
+import de.tudarmstadt.informatik.hostage.ssh.crypto.cipher.DESede;
+import de.tudarmstadt.informatik.hostage.ssh.crypto.dh.DhExchange;
+import de.tudarmstadt.informatik.hostage.ssh.crypto.digest.MAC;
+import de.tudarmstadt.informatik.hostage.ssh.signature.DSAPrivateKey;
+import de.tudarmstadt.informatik.hostage.ssh.signature.DSASHA1Verify;
+import de.tudarmstadt.informatik.hostage.ssh.signature.DSASignature;
+import de.tudarmstadt.informatik.hostage.ssh.util.TypesReader;
+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.  
  * @author Wulf Pfeiffer
  */
-public final class SSH implements Protocol<ByteArray> {
+public class SSH implements Protocol {
 	/**
 	 * Represents the states of the protocol.
 	 */
 	private enum STATE {
-		NONE,
-		SERVER_VERSION,
-		CLIENT_VERSION,
-		KEX_INIT,
-		CLOSED
+		NONE, SERVER_VERSION, CLIENT_VERSION, KEX_INIT, NEW_KEYS, USERAUTH, CONNECTION, CHANNEL, TERMINAL_CMD, TERMINAL_ENTER, CLOSED
 	}
-	
+
 	/**
 	 * Denotes in which state the protocol is right now.
 	 */
-	private STATE connectionState = STATE.NONE;
-	
-	private String serverVersion = "SSH-2.0-";
-	private String serverType = "OpenSSH_6.0p1 Debian-4";
-		
-	//Diffie-Hellman-Group-1 p and g
-	private final byte[] p = {
-            (byte)0x00,
-            (byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
-            (byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34,
-            (byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1,
-            (byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74,
-            (byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22,
-            (byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD,
-            (byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B,
-            (byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37,
-            (byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45,
-            (byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6,
-            (byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B,
-            (byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED,
-            (byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5,
-            (byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6,
-            (byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE6,(byte)0x53,(byte)0x81,
-            (byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF
-      };
-	private final byte[] g = {0x02};
-	
-	//SSH Parameters for Kex etc.
-    private byte[] V_S = serverType.getBytes();
-    private byte[] V_C;
-    private byte[] I_S;
-    private byte[] I_C;
-    private byte[] e;
-    private byte[] f;
-    private byte[] k;
-    private byte[] h;
-    private byte[] K_S;
-    private byte[] sig;
-
-    //Keys for signature
-    private KeyPair dsa;
-			
-    //allowed algorithms for kexinit
-	private String kex_alg = "diffie-hellman-group1-sha1";
-	private String server_alg = "ssh-dss";
-	private String encrypt_alg_c = "aes128-ctr";
-	private String encrypt_alg_s = "aes128-ctr";
-	private String mac_alg_c = "hmac-sha1";
-	private String mac_alg_s = "hmac-sha1";
-	private String comp_alg_c = "none";
-	private String comp_alg_s = "none";
-	
-	private int cipherBlockSize = 16;
-	
-	/** Denotes in which state the protocol is right now */
 	private STATE state = STATE.NONE;
-	
-	
-	public int getPort() {
+	private boolean useEncryption = false;
+
+	@Override
+	public int getDefaultPort() {
 		return 22;
 	}
 
-	
+	@Override
 	public TALK_FIRST whoTalksFirst() {
 		return TALK_FIRST.SERVER;
 	}
 
-	
-	public List<ByteArray> processMessage(ByteArray message) {
-		List<ByteArray> response = new ArrayList<ByteArray>();
+	@Override
+	public List<Packet> processMessage(Packet requestPacket) {
+		List<Packet> responsePackets = new ArrayList<Packet>();
 		byte[] request = null;
-		if(message != null) request = message.get();
-		
-		switch(connectionState) {
-		case NONE:			
-			response.add(new ByteArray(serverVersion + serverType + "\r\n"));
-			connectionState = STATE.SERVER_VERSION;
+		if (requestPacket != null) {
+			request = requestPacket.getMessage();
+			if (useEncryption) {
+				request = decryptBytes(request);
+			}
+		}
+		switch (state) {
+		case NONE:
+			responsePackets.add(new Packet(serverVersion + serverType + "\r\n"));
+			state = STATE.SERVER_VERSION;
 			break;
 		case SERVER_VERSION:
 			extractType(request);
-			extractCookie(request);
-			response.add(new ByteArray(kexInit()));
-			connectionState = STATE.CLIENT_VERSION;
+			extractPayload(request);
+			responsePackets.add(kexInit());
+			state = STATE.CLIENT_VERSION;
 			break;
 		case CLIENT_VERSION:
 			extractPubKey(request);
-			response.add(new ByteArray(dhKexReply()));
-			//FIXME signature in dhKexReply seems to be wrong
-			response.add(new ByteArray(newKeys()));
-			connectionState = STATE.KEX_INIT;
+			responsePackets.add(dhKexReply());
+			state = STATE.KEX_INIT;
 			break;
 		case KEX_INIT:
-			connectionState = STATE.CLOSED;
+			responsePackets.add(newKeys());
+			useEncryption = true;
+			state = STATE.NEW_KEYS;
+			break;
+		case NEW_KEYS:
+			responsePackets.add(serviceReply(request));
+			state = STATE.USERAUTH;
+			break;
+		case USERAUTH:
+			responsePackets.add(connectionReply(request));
+			state = STATE.CONNECTION;
+			break;
+		case CONNECTION:
+			responsePackets.add(channelOpenReply(request));
+			state = STATE.CHANNEL;
+			break;
+		case CHANNEL:
+			responsePackets.add(channelSuccessReply(request));
+			responsePackets.add(terminalPrefix());
+			state = STATE.TERMINAL_CMD;
+			break;
+		case TERMINAL_CMD:
+			responsePackets.add(terminalReply(request));
 			break;
 		case CLOSED:
 			break;
 		default:
-			connectionState = STATE.CLOSED;
+			state = STATE.CLOSED;
 			break;
 		}
-		
-		return response;
+
+		return responsePackets;
 	}
 
-	
+	@Override
 	public boolean isClosed() {
 		return (state == STATE.CLOSED);
 	}
 
-	
+	@Override
 	public boolean isSecure() {
 		return false;
 	}
 
-	
-	public Class<ByteArray> getType() {
-		return ByteArray.class;
+	@Override
+	public Class<byte[]> getType() {
+		return byte[].class;
 	}
 
-	
+	@Override
 	public String toString() {
 		return "SSH";
 	}
 
 	/**
 	 * Wraps the packets with packet length and padding.
-	 * @param packet content that is wrapped.
+	 * 
+	 * @param response
+	 *            content that is wrapped.
 	 * @return wrapped packet.
 	 */
-	private byte[] wrapPacket(byte[] packet) {
-		int packetLength = 5 + packet.length; 	//4 byte packet length, 1 byte padding length, payload length
-		int paddingLengthCBS = cipherBlockSize - (packetLength % cipherBlockSize);
+	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
-		
+		int paddingLength = paddingLengthCBS > paddingLength8 ? paddingLengthCBS
+				: paddingLength8;
+		if (paddingLength < 4)
+			paddingLength += cipherBlockSize;
+		packetLength = packetLength + paddingLength - 4; // add padding string length to packet length
+
 		byte[] packetLen = ByteBuffer.allocate(4).putInt(packetLength).array();
-		byte[] paddingLen = {(byte) paddingLength};
-		byte[] paddingString = new byte[paddingLength];
-		for(int i = 0; i < paddingLength; i++) {
-			paddingString[i] = 0x00;
+		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);
+		}
+		packetNumber++;
+
+		return new Packet(wrappedResponse);
+	}
+
+	/**
+	 * Encrypts a request with triple DES.
+	 * 
+	 * @param request
+	 *            that is encrypted.
+	 * @return encrypted request.
+	 */
+	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);
+		}
+		return responseEncrypted;
+	}
+
+	/**
+	 * Decrypts a request with triple DES.
+	 * 
+	 * @param request
+	 *            that is decrypted.
+	 * @return decrypted request.
+	 */
+	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 HelperUtils.concat(packetLen, paddingLen, packet, paddingString);
+		return decryptedRequest;
 	}
-	
+
 	/**
-	 * Builds the Kex Init packet that contains all the allowed algorithms by the server.
+	 * Creates the SHA1 Mac with the given bytes.
+	 * 
+	 * @param bytes
+	 *            that are used for the Mac.
+	 * @return Mac.
+	 */
+	private byte[] createMac(byte[] bytes) {
+		byte[] mac = new byte[20];
+		macEncryption.initMac(packetNumber);
+		macEncryption.update(bytes, 0, bytes.length);
+		macEncryption.getMac(mac, 0);
+		return mac;
+	}
+
+	/**
+	 * Builds the Kex Init packet that contains all the allowed algorithms by
+	 * the server.
+	 * 
 	 * @return Kex Init packet.
 	 */
-	private byte[] kexInit() {
-		byte[] msgCode = {0x14};
-		I_S = randomBytes(16);
-		byte[] kexLength = ByteBuffer.allocate(4).putInt(kex_alg.getBytes().length).array();
-		byte[] serverLength = ByteBuffer.allocate(4).putInt(server_alg.getBytes().length).array();
-		byte[] encrypt_c_Length = ByteBuffer.allocate(4).putInt(encrypt_alg_c.getBytes().length).array();
-		byte[] encrypt_s_Length = ByteBuffer.allocate(4).putInt(encrypt_alg_s.getBytes().length).array();
-		byte[] mac_c_Length = ByteBuffer.allocate(4).putInt(mac_alg_c.getBytes().length).array();
-		byte[] mac_s_Length = ByteBuffer.allocate(4).putInt(mac_alg_s.getBytes().length).array();
-		byte[] comp_c_Length = ByteBuffer.allocate(4).putInt(comp_alg_c.getBytes().length).array();
-		byte[] comp_s_Length = ByteBuffer.allocate(4).putInt(comp_alg_s.getBytes().length).array();
-		byte[] language_c_s = {0x00, 0x00, 0x00, 0x00};
-		byte[] language_s_c = {0x00, 0x00, 0x00, 0x00};
-		byte[] kexFirsPckt = {0x00};
-		byte[] reserved = {0x00, 0x00, 0x00, 0x00};	
-		
-		byte[] response = HelperUtils.concat(msgCode, I_S, kexLength, kex_alg.getBytes(), serverLength, server_alg.getBytes(),
-							encrypt_c_Length, encrypt_alg_c.getBytes(), encrypt_s_Length, encrypt_alg_s.getBytes(), mac_c_Length, mac_alg_c.getBytes(),
-							mac_s_Length, mac_alg_s.getBytes(), comp_c_Length, comp_alg_c.getBytes(), comp_s_Length, comp_alg_s.getBytes(),
-							language_c_s, language_s_c, kexFirsPckt, reserved);
+	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);
 	}
-	
+
 	/**
-	 * Builds the Diffie-Hellman Kex Reply, containing the host key,f and the signature.
+	 * Builds the Diffie-Hellman Kex Reply, containing the host key,f and the
+	 * signature.
+	 * 
 	 * @return Diffie-Hellman Kex Reply packet.
 	 */
-	private byte[] dhKexReply() {
-		generateDHKeys();
-		generateHostKey();
-		generateSha1Hash();
-		generateSignature();
-		byte[] msgCode = {0x1f};
-		byte[] hostKeyLength = ByteBuffer.allocate(4).putInt(K_S.length).array();
-				byte[] fDHLength = ByteBuffer.allocate(4).putInt(f.length).array();
-		byte[] signatureLength = ByteBuffer.allocate(4).putInt(sig.length).array();
-		byte[] server_algLength = ByteBuffer.allocate(4).putInt(server_alg.getBytes().length).array();
-		byte[] payloadLength = ByteBuffer.allocate(4).putInt(server_algLength.length + signatureLength.length + sig.length + server_alg.getBytes().length).array();
-		byte[] response = HelperUtils.concat(msgCode, hostKeyLength,  K_S,
-									fDHLength, f, payloadLength, server_algLength, server_alg.getBytes(), signatureLength, sig);
+	private Packet dhKexReply() {
+		byte[] response = null;
+		try {
+			DhExchange dhx = new DhExchange();
+			dhx.serverInit(1, random);
+			dhx.setE(new BigInteger(e));
+			f = dhx.getF();
+			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();
+			DSASignature ds = DSASHA1Verify.generateSignature(h, dsa, random);
+			signature = DSASHA1Verify.encodeSSHDSASignature(ds);
+			TypesWriter tw = new TypesWriter();
+			tw.writeByte(31);
+			tw.writeString(K_S, 0, K_S.length);
+			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
+			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);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+
 		return wrapPacket(response);
 	}
-	
+
 	/**
 	 * New Keys response.
+	 * 
 	 * @return New Keys response.
 	 */
-	private byte[] newKeys() {
-		byte[] msgCode = {0x15};
+	private Packet newKeys() {
+		byte[] msgCode = { 0x15 };
 		return wrapPacket(msgCode);
 	}
-	
+
 	/**
-	 * Generates the required Diffie-Hellman keys with p and g from Oakley Group 1.
+	 * Service ssh-userauth reply.
+	 * 
+	 * @param request
+	 *            from the client.
+	 * @return Service reply.
 	 */
-	private void generateDHKeys() {	
-		try {
-			KeyPairGenerator myKpairGen = KeyPairGenerator.getInstance("DH");
-			KeyAgreement myKeyAgree = KeyAgreement.getInstance("DH");
-			BigInteger p = new BigInteger(this.p);
-			BigInteger g = new BigInteger(this.g);
-			BigInteger e = new BigInteger(this.e);
-			
-            DHParameterSpec dhParamSpec = new DHParameterSpec(p, g);
-            myKpairGen.initialize(dhParamSpec);
-            KeyPair myKpair = myKpairGen.generateKeyPair();
-            myKeyAgree.init(myKpair.getPrivate());
-            BigInteger f = ((DHPublicKey) (myKpair.getPublic())).getY();
-            this.f = f.toByteArray();
-            
-            KeyFactory myKeyFac = KeyFactory.getInstance("DH");
-            DHPublicKeySpec keySpec = new DHPublicKeySpec(e, p, g);
-            PublicKey yourPubKey = myKeyFac.generatePublic(keySpec);
-            myKeyAgree.doPhase(yourPubKey, true);
-            byte[] mySharedSecret = myKeyAgree.generateSecret();
-            k = mySharedSecret;
-		} catch (Exception e) {
-			e.printStackTrace();
+	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(0x06);
+		tw.writeString("ssh-userauth");
+		return wrapPacket(tw.getBytes());
 	}
-	
+
 	/**
-	 * Generates the Host Key based on the DSA algorithm
+	 * Userauth ssh-connection reply.
+	 * 
+	 * @param request
+	 *            from the client.
+	 * @return ssh-connection reply.
 	 */
-	private void generateHostKey() {
-        try {
-            KeyPairGenerator generator = KeyPairGenerator.getInstance("DSA");
-            dsa = generator.generateKeyPair();
-            
-            byte[] string = "ssh-dss".getBytes();
-            byte[] stringLength = ByteBuffer.allocate(4).putInt(string.length).array();
-            
-            byte[] p = ((DSAPublicKey) dsa.getPublic()).getParams().getP().toByteArray();
-            if(p[0] != 0x00) p = HelperUtils.concat(new byte[]{0x00}, p);
-            byte[] pLength = ByteBuffer.allocate(4).putInt(p.length).array();
-            
-            byte[] q = ((DSAPublicKey) dsa.getPublic()).getParams().getQ().toByteArray();
-            if(q[0] != 0x00) q = HelperUtils.concat(new byte[]{0x00}, q);
-            byte[] qLength = ByteBuffer.allocate(4).putInt(q.length).array();
-            
-            byte[] g = ((DSAPublicKey) dsa.getPublic()).getParams().getG().toByteArray();
-            if(g[0] != 0x00) g = HelperUtils.concat(new byte[]{0x00}, g);
-            byte[] gLength = ByteBuffer.allocate(4).putInt(g.length).array();
-            
-            byte[] y = ((DSAPublicKey) dsa.getPublic()).getY().toByteArray();
-            if(y[0] != 0x00) y = HelperUtils.concat(new byte[]{0x00}, y);
-            byte[] yLength = ByteBuffer.allocate(4).putInt(y.length).array();
-            
-            K_S = HelperUtils.concat(stringLength, string, pLength, p, qLength, q, gLength, g, yLength, y);       		
-        } catch (Exception e) {
-        	e.printStackTrace();
-        }
+	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
+		}
+		try {
+			TypesReader tr = new TypesReader(request, 6);
+			userName = tr.readString();
+			terminalPrefix = "[" + userName + "@" + serverName + "]$";
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		byte[] msgcode = { 0x34 };
+		return wrapPacket(msgcode);
 	}
-	
+
 	/**
-	 * Generates the SHA-1 Hash from several values
+	 * Channel Open Reply.
+	 * 
+	 * @param request
+	 *            from client.
+	 * @return Channel Open Reply.
 	 */
-	private void generateSha1Hash() {
+	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 {
-			MessageDigest sha = MessageDigest.getInstance("SHA-1");
-			sha.update(V_C);
-			sha.update(V_S);
-			sha.update(I_C);
-			sha.update(I_S);
-			sha.update(K_S);
-			sha.update(e);
-			sha.update(f);
-			sha.update(k);
-			h = sha.digest();
-		} catch (Exception e) {
+			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();
 		}
+
+		return wrapPacket(tw.getBytes());
 	}
-	
+
 	/**
-	 * Generates the signature of the hash using DSA algorithm with SHA-1
+	 * Channel Success Reply.
+	 * 
+	 * @param request
+	 *            from client.
+	 * @return Channel Success Reply.
 	 */
-	private void generateSignature() {	
-		//FIXME something is wrong with this signature.. maybe one of the used components is generated wrong?! 
+	private Packet channelSuccessReply(byte[] request) {
+		if (!(HelperUtils.byteToStr(request)).contains("pty-req")) {
+			return disconnectReply(2);
+		}
+		TypesWriter tw = new TypesWriter();
+		tw.writeByte(0x63); // msgcode
+		tw.writeUINT32(recipientChannel);
+
+		return wrapPacket(tw.getBytes());
+	}
+
+	/**
+	 * Returns the terminal prefix for the client.
+	 * 
+	 * @return terminal prefix.
+	 */
+	private Packet terminalPrefix() {
+		TypesWriter tw = new TypesWriter();
+		tw.writeByte(0x5e);
+		tw.writeUINT32(recipientChannel);
+		tw.writeString(terminalPrefix);
+		
+		return wrapPacket(tw.getBytes());
+	}
+
+	/**
+	 * Computes the reply for the client input.
+	 * 
+	 * @param request
+	 *            client input.
+	 * @return input reply.
+	 */
+	private Packet terminalReply(byte[] request) {
+		TypesReader tr = new TypesReader(request, 6);
+		String messsage = "";
+		System.out.println(HelperUtils.bytesToHexString(request));
 		try {
-			Signature sig = Signature.getInstance("SHA1withDSA");
-            sig.initVerify(dsa.getPublic());
-            sig.initSign(dsa.getPrivate());
-            sig.update(h);
-            this.sig = extractSignature(sig.sign());
-		} catch (Exception e) {
+			tr.readUINT32();
+			messsage = tr.readString();
+			System.out.println(messsage);
+			if (messsage.contains("\r")) {
+				System.out.println("hi");
+				if (command.toString().contains("exit")) {
+					state = STATE.CLOSED; // ugly style
+					return disconnectReply(2);
+				}
+				messsage = "\r\nbash: " + command + " :command not found\r\n"
+						+ terminalPrefix;
+				command = new StringBuffer();
+			} else if (messsage.contains(new String(new char[] { '\u007F' }))
+					&& command.length() > 0) {
+				command = command.delete(command.length() - 1, command.length());
+			} else {
+				command.append(messsage);
+			}
+		} catch (IOException e) {
 			e.printStackTrace();
 		}
+		TypesWriter tw = new TypesWriter();
+		tw.writeByte(0x5e); // msgcode
+		tw.writeUINT32(recipientChannel);
+		tw.writeString(messsage);
+		return wrapPacket(tw.getBytes());
+	}
+
+	/**
+	 * 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
+	 * 
+	 * @param request
+	 *            containing the clients type
 	 */
 	private void extractType(byte[] request) {
 		int length = 0;
-		for(int i = 8; i < request.length; i++, length++) { 	//start at 8 because "SSH-2.0-" is not part of type
-			if(request[i] == 0x0d) break;			//find the end of the type: '\r'
+		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, 8, V_C, 0, length);
+		System.arraycopy(request, 0, V_C, 0, length);
 	}
-	
+
 	/**
-	 * Extracts the cookie from the Kex Init client request 
-	 * @param request containing the clients cookie
+	 * Extracts the payload of a packet and writes it in I_C.
+	 * 
+	 * @param request
+	 *            packet of which the payload is extracted.
 	 */
-	private void extractCookie(byte[] request) {
-		int pos = 0;
-		if(request[5] != 0x14) {	//if type packet is in front of kex init
-			pos = 1;				//start behind the end of type message
-			for(int i = 0; i < request.length; i++, pos++) {
-				if(request[i] == 0x0a) break;		//find end of type message: '\n'
+	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;
 			}
 		}
-		I_C = new byte[16];
-		System.arraycopy(request, 6+pos, I_C, 0, 16); //srcLen: headersize+position after type packet
+		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
-	 * @param request containing the clients public key
+	 * 
+	 * @param request
+	 *            containing the clients public key
 	 */
 	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];
+		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];
 		}
 	}
-	
+
 	/**
 	 * Converts a byte[] to int
-	 * @param bytes that are converted
+	 * 
+	 * @param bytes
+	 *            that are converted
 	 * @return converted byte[] as int
 	 */
 	private static int byteToInt(byte[] bytes) {
-		  int ret = 0;
-		  for (int i=0; i < bytes.length; i++) {
-		    ret <<= 8;
-		    ret |= bytes[i] & 0xFF;
-		  }
-		  return ret;
+		int convertedInteger = 0;
+		for (int i = 0; i < bytes.length; i++) {
+			convertedInteger <<= 8;
+			convertedInteger |= bytes[i] & 0xFF;
+		}
+		return convertedInteger;
 	}
-	
-	/**
-	 * Generates a random byte[] of a specified size
-	 * @param size of the byte[]
-	 * @return random byte[]
-	 */
-	private byte[] randomBytes(int size) {
-		byte[] bytes = new byte[size];
-		Random rdm = new Random();
-		rdm.nextBytes(bytes);
-		return bytes;		
+
+	// 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" } } };
+
+	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)];
 	}
 
-	/**
-	 * Extracts r and s from a DSA-signature
-	 * @param signature 
-	 * @return r and s as byte[]
-	 */
-	private byte[] extractSignature(byte[] signature) {
-        int length = 0;
-        int index = 3;
-        length = signature[index++] & 0xff;
-        byte[] r = new byte[length];
-        System.arraycopy(signature, index, r, 0, r.length);
-        index = index + length + 1;
-        length = signature[index++] & 0xff;
-        byte[] s = new byte[length];
-        System.arraycopy(signature, index, s, 0, s.length);
-        byte[] result = new byte[40];
-        // result must be 40 bytes, but r and s may be longer than 20
-        System.arraycopy(r,
-                         (r.length > 20) ? 1 : 0,
-                         result,
-                         (r.length > 20) ? 0 : 20 - r.length,
-                         (r.length > 20) ? 20 : r.length);
-        System.arraycopy(s,
-                         (s.length > 20) ? 1 : 0,
-                         result,
-                         (s.length > 20) ? 20 : 40 - s.length,
-                         (s.length > 20) ? 20 : s.length);
-        return result;
-    }
+	// 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();
 }

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

@@ -4,9 +4,8 @@ import javax.net.ssl.SSLContext;
 /**
  * Interface for ssl protocols that are used by hostage
  * @author Wulf Pfeiffer
- * @param <T> Denotes if the protocol is using Strings or ByteArrays
  */
-public interface SSLProtocol<T> extends Protocol<T> {
+public interface SSLProtocol extends Protocol {
 
 	/**
 	 * Returns the initialized SSL Context with the KeyManager and TrustManager that will be used

+ 69 - 71
src/de/tudarmstadt/informatik/hostage/protocol/TELNET.java

@@ -4,13 +4,14 @@ import java.util.ArrayList;
 import java.util.List;
 
 import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
-import de.tudarmstadt.informatik.hostage.wrapper.ByteArray;
+import de.tudarmstadt.informatik.hostage.wrapper.Packet;
 
 /**
- * TELNET protocol
+ * TELNET protocol.
+ * Implementation of RFC document 854.
  * @author Wulf Pfeiffer
  */
-public final class TELNET implements Protocol<ByteArray> {
+public class TELNET implements Protocol {
 	/**
 	 * Represents the states of the protocol
 	 */
@@ -23,47 +24,33 @@ public final class TELNET implements Protocol<ByteArray> {
 	 */
 	private STATE state = STATE.NONE;
 	
-	private byte[] lastMessage;
-
-	/** user entered by the client */
-	private byte[] user;
-	/** last command sent by the client */
-	private byte[] command;
-	/** name of the server */
-	private String server = "raspberrypi";
-	/** command line prefix */
-	private byte[] sessionToken = null;
-
-	
-	public int getPort() {
+	@Override
+	public int getDefaultPort() {
 		return 23;
 	}
 
-	
+	@Override
 	public TALK_FIRST whoTalksFirst() {
 		return TALK_FIRST.SERVER;
 	}
 
-	
-	public List<ByteArray> processMessage(ByteArray message) {
+	@Override
+	public List<Packet> processMessage(Packet requestPacket) {
 		byte[] request = null;
-		if(message != null) {
-			lastMessage = message.get();
-			request = message.get();
-			System.out.println(HelperUtils.byteToStr(lastMessage));
+		if(requestPacket != null) {
+			request = requestPacket.getMessage();
 		}
-		List<ByteArray> response = new ArrayList<ByteArray>();
+		List<Packet> responsePackets = new ArrayList<Packet>();
 		
 		switch (state) {
 		case NONE:
-			response.add(new ByteArray(optionRequest));
+			responsePackets.add(new Packet(optionRequest));
 			state = STATE.OPEN;
 			break;
 		case OPEN:
 			if(request != null) {
-				response.add(new ByteArray(getOptionResponse(request)));
-				response.add(new ByteArray("Debian GNU/Linux 7.0\r\n"));
-				response.add(new ByteArray(server + " login: "));
+				responsePackets.add(new Packet(getOptionResponse(request)));
+				responsePackets.add(new Packet(serverName + " login: "));
 				state = STATE.LOGIN;
 			}
 			break;
@@ -74,35 +61,35 @@ public final class TELNET implements Protocol<ByteArray> {
 					byte[] buffer = new byte[request.length - 2]; 
 					System.arraycopy(request, 0, buffer, 0, request.length - 2); 
 					user = HelperUtils.concat(user, buffer);
-					response.add(new ByteArray(buffer));
+					responsePackets.add(new Packet(buffer));
 				}
-				response.add(new ByteArray("\r\n"));
-				response.add(new ByteArray("Password: "));
+				responsePackets.add(new Packet("\r\n"));
+				responsePackets.add(new Packet("Password: "));
 				state = STATE.AUTHENTICATE;
-				sessionToken = HelperUtils.concat(sessionPrefix, user, "@".getBytes(), server.getBytes(), sessionMiddle, user, "@".getBytes(), server.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) {
 				byte[] tmp = new byte[user.length - 1];
 				System.arraycopy(user, 0, tmp, 0, user.length - 1);
 				user = tmp;
-				response.add(new ByteArray("\b \b"));
+				responsePackets.add(new Packet("\b \b"));
 				break;
 			} else if (!checkForByte(request, (byte) 0xff)){
 				if(user == null)
 					user = request;
 				else
 					user = HelperUtils.concat(user, request);
-				response.add(message);
+				responsePackets.add(requestPacket);
 			}
 			break;
 		case AUTHENTICATE:
 			if(request == null) break;
 			else if(checkForByte(request, (byte) 0x0d)) {
-				response.add(new ByteArray("\r\nLinux" + server + " 3.6.11+\r\n"));
-				response.add(new ByteArray(sessionToken));
+				responsePackets.add(new Packet("\r\n"));
+				responsePackets.add(new Packet(sessionToken));
 				state = STATE.LOGGED_IN;
 			} else if (checkForByte(request, (byte) 0x7f)) {
-				response.add(new ByteArray("\b \b"));
+				responsePackets.add(new Packet("\b \b"));
 			}			
 			break;
 		case LOGGED_IN:
@@ -112,60 +99,61 @@ public final class TELNET implements Protocol<ByteArray> {
 					byte[] buffer = new byte[request.length - 2]; 
 					System.arraycopy(request, 0, buffer, 0, request.length - 2); 
 					command = HelperUtils.concat(command, buffer);
-					response.add(new ByteArray(buffer));
+					responsePackets.add(new Packet(buffer));
 				}
 				if(command == null) {
-					response.add(new ByteArray("\r\n"));
-					response.add(new ByteArray(sessionToken));
+					responsePackets.add(new Packet("\r\n"));
+					responsePackets.add(new Packet(sessionToken));
 				} else if (new String(command).contains("exit")) {
-					response.add(new ByteArray("\r\nlogout\r\n"));
+					responsePackets.add(new Packet("\r\nlogout\r\n"));
 					state = STATE.CLOSED;
 				} else {
 					String bash = "\r\n-bash: " + new String(command)+ ": command not found";
-					response.add(new ByteArray(bash));
-					response.add(new ByteArray("\r\n"));
-					response.add(new ByteArray(sessionToken));
+					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) {
 				byte[] tmp = new byte[command.length - 1];
 				System.arraycopy(command, 0, tmp, 0, command.length - 1);
 				command = tmp;
-				response.add(new ByteArray("\b \b"));
+				responsePackets.add(new Packet("\b \b"));
 				break;
 			} else if (!checkForByte(request, (byte) 0xff)){
 				if(command == null)
 					command = request;
 				else
 					command = HelperUtils.concat(command, request);
-				response.add(message);
+				responsePackets.add(requestPacket);
 			}
 			break;
 		default:
-			response.add(new ByteArray("\r\nlogout\r\n"));
+			responsePackets.add(new Packet("\r\nlogout\r\n"));
 			state = STATE.CLOSED;
 			break;
 		}
-		return response;
+		return responsePackets;
 	}
 
-	
+	@Override
 	public boolean isClosed() {
 		return (state == STATE.CLOSED);
 	}
 
-	
+	@Override
 	public boolean isSecure() {
 		return false;
 	}
 	
+	@Override
 	public String toString() {
 		return "TELNET";
 	}
 	
-	
-	public Class<ByteArray> getType() {
-		return ByteArray.class;
+	@Override
+	public Class<byte[]> getType() {
+		return byte[].class;
 	}
 	
 	/**
@@ -187,33 +175,43 @@ public final class TELNET implements Protocol<ByteArray> {
 	 * @return accepted and unaccepted options
 	 */
 	private byte[] getOptionResponse(byte[] request) {
-		List<byte[]> respList = new ArrayList<byte[]>();
-		byte[] cmdResp;
+		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) {
-				cmdResp = new byte[3];
-				cmdResp[0] = request[i];
-				cmdResp[1] = request[i + 1] == (byte) 0xfd ? (byte) 0xfc : (byte) 0xfe; 
-				cmdResp[2] = request[i+2];
-				respList.add(cmdResp);
+				requestInverse = new byte[3];
+				requestInverse[0] = request[i];
+				requestInverse[1] = request[i+1] == (byte) 0xfd ? (byte) 0xfc : (byte) 0xfe; 
+				requestInverse[2] = request[i+2];
+				responseList.add(requestInverse);
 			}			
 		}
-		byte[] response = new byte[0];
-		for(byte[] resp : respList) {
-			response = HelperUtils.concat(response, resp);
+		byte[] optionResponse = new byte[0];
+		for(byte[] response : responseList) {
+			optionResponse = HelperUtils.concat(optionResponse, response);
 		}
-		return 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 final byte[] optionRequest = {(byte) 0xff, (byte) 0xfb, 0x03,	//will suppress go ahead
-										(byte) 0xff, (byte) 0xfb, 0x01};	//will echo
+	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 final byte[] sessionPrefix = {0x1b, 0x5d, 0x30, 0x3b};
-	private final byte[] sessionMiddle = {0x40, 0x72, 0x61, 0x73, 
-			0x70, 0x62, 0x65, 0x72, 0x72, 0x79, 0x70, 0x69, 0x3a, 0x20, 0x7e, 0x07, 0x1b, 0x5b, 0x30, 0x31, 
+	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 final byte[] sessionSuffix = {0x1b, 0x5b, 0x30, 0x30, 0x6d, 0x20, 0x1b, 0x5b, 0x30, 0x31, 
+	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};
-
 }

+ 275 - 0
src/de/tudarmstadt/informatik/hostage/sync/BluetoothSync.java

@@ -0,0 +1,275 @@
+package de.tudarmstadt.informatik.hostage.sync;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.UUID;
+
+import android.app.AlertDialog;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothServerSocket;
+import android.bluetooth.BluetoothSocket;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.widget.ArrayAdapter;
+import de.tudarmstadt.informatik.hostage.R;
+import de.tudarmstadt.informatik.hostage.logging.UglyDbHelper;
+
+public class BluetoothSync{
+	
+	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 AlertDialog ad;
+	
+	public BluetoothSync(Context context){
+		this.context = context;		
+		serviceUUID = UUID.fromString(context.getResources().getString(R.string.UUID));
+		mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+	}
+
+	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;
+	}
+	
+	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(){		
+		if (mBluetoothAdapter == null) {
+		    // Device does not support Bluetooth
+			return false;
+		}
+		if (!mBluetoothAdapter.isEnabled()) {
+		    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
+		builder.setTitle("Choose Device");
+		builder.setAdapter(arrayAdapter, new DialogInterface.OnClickListener() {
+			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();
+			}
+		});
+//		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;
+	            }				
+			}
+		}
+		
+	    /** Will cancel the listening socket, and cause the thread to finish */
+	    public void cancel() {
+	        try {
+	            serverSocket.close();
+	        } catch (IOException e) { }
+	    }
+	}
+	
+	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) { }
+	    }
+	}
+	
+	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) { }
+	    }
+	}
+
+}

+ 182 - 0
src/de/tudarmstadt/informatik/hostage/sync/NFCSync.java

@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package de.tudarmstadt.informatik.hostage.sync;
+
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.content.Intent;
+import android.nfc.NdefMessage;
+import android.nfc.NdefRecord;
+import android.nfc.NfcAdapter;
+import android.nfc.NfcAdapter.CreateNdefMessageCallback;
+import android.nfc.NfcAdapter.OnNdefPushCompleteCallback;
+import android.nfc.NfcEvent;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+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();
+		Log.i("NFC", "Creating Message");
+        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")
+			);
+		} 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!");
+		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);
+		} 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();
+    }	
+
+}

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

@@ -25,18 +25,22 @@ public class ListViewAdapter extends BaseAdapter {
 		this.data = data;
 	}
 
+	@Override
 	public int getCount() {
 		return data.size();
 	}
 
+	@Override
 	public Object getItem(int position) {
 		return data.get(position);
 	}
 
+	@Override
 	public long getItemId(int position) {
 		return position;
 	}
 
+	@Override
 	public View getView(int position, View convertView, ViewGroup parent) {
 		View v = convertView;
 		if (v == null) {

+ 244 - 284
src/de/tudarmstadt/informatik/hostage/ui/MainActivity.java

@@ -1,16 +1,9 @@
 package de.tudarmstadt.informatik.hostage.ui;
 
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
 import java.util.ArrayList;
 import java.util.HashMap;
-
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.util.EntityUtils;
-import org.json.JSONObject;
-
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityManager.RunningServiceInfo;
@@ -21,12 +14,11 @@ import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
 import android.content.SharedPreferences;
-import android.content.SharedPreferences.Editor;
-import android.net.ConnectivityManager;
-import android.os.AsyncTask;
 import android.os.Bundle;
+import android.os.Handler;
 import android.os.IBinder;
 import android.support.v4.content.LocalBroadcastManager;
+import android.util.Log;
 import android.view.GestureDetector;
 import android.view.GestureDetector.SimpleOnGestureListener;
 import android.view.Menu;
@@ -42,43 +34,39 @@ import android.widget.CheckBox;
 import android.widget.ImageView;
 import android.widget.ListView;
 import android.widget.TextView;
-import android.widget.Toast;
 import android.widget.ToggleButton;
 import android.widget.ViewAnimator;
 import de.tudarmstadt.informatik.hostage.HoneyService;
 import de.tudarmstadt.informatik.hostage.HoneyService.LocalBinder;
 import de.tudarmstadt.informatik.hostage.R;
 import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
+import de.tudarmstadt.informatik.hostage.logging.LogResultReceiver;
+import de.tudarmstadt.informatik.hostage.logging.LogResultReceiver.Receiver;
 import de.tudarmstadt.informatik.hostage.logging.Logger;
-import de.tudarmstadt.informatik.hostage.logging.SQLLogger;
+import de.tudarmstadt.informatik.hostage.logging.UglyDbHelper;
+
 /**
  * MainActivity is the central activity for the GUI of the application.
- * MainActivity is launched when the application is first started.
- * It shows the user: <br>
+ * MainActivity is launched when the application is first started. It shows the
+ * user: <br>
  * - information about the network<br>
  * - light indicators for recorded attacks on each protocol<br>
  * - amount of attacks on each protocols<br>
  * The user can start and stop services.
+ * 
  * @author Mihai Plasoianu
  * @author Lars Pandikow
  * @author Wulf Pfeiffer
  */
-public class MainActivity extends Activity {
-	// String constants for whole application
+public class MainActivity extends Activity implements Receiver {
 	/**
-	 * Used for Broadcast between service and GUI. String: "de.tudarmstadt.informatik.hostage.BROADCAST"
+	 * Flag for root acces. True if phone has root acces, else false.
 	 */
-	public static final String BROADCAST = "de.tudarmstadt.informatik.hostage.BROADCAST";
+	public static boolean isRooted = false;
 	/**
-	 * Used to store session related data in a SharedPrefereces. String: "de.tudarmstadt.informatik.hostage.SESSION_DATA"
+	 * Flag for porthack. True if porthack is installed, else false.
 	 */
-	public static final String SESSION_DATA = "de.tudarmstadt.informatik.hostage.SESSION_DATA";
-	public static final String LISTENER = "_LISTENER";
-	public static final String HANDLER_COUNT = "_HANDLER_COUNT";
-	public static final String SSID = "SSID";
-	public static final String BSSID = "BSSID";
-	public static final String INTERNAL_IP = "INTERNAL_IP";
-	public static final String EXTERNAL_IP = "EXTERNAL_IP";
+	public static boolean porthackInstalled = false;
 
 	/**
 	 * Integer representing a grey light.
@@ -96,15 +84,12 @@ public class MainActivity extends Activity {
 	 * Integer representing a yellow light.
 	 */
 	public static final int LIGHT_YELLOW = 0x04;
-	
-    private static Context context;
 
+	public LogResultReceiver logResultReceiver;
+	private SharedPreferences connectionInfo;
 
 	private HoneyService mService;
 	private boolean serviceBound;
-	private SharedPreferences sessionPref;
-	private Editor sessionEditor;
-	private Logger logger;
 
 	// variables for the swipe animation
 	private ViewAnimator viewAnimator;
@@ -116,23 +101,22 @@ public class MainActivity extends Activity {
 
 	private ListView listView;
 	private ListViewAdapter adapter;
-	
-	private String protocolClicked;
-	
-	
+
+	private boolean isBssidSeen = false;
+
 	@Override
 	protected void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
-        MainActivity.context = getApplicationContext();	//set context
+		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
-		sessionPref = getSharedPreferences(MainActivity.SESSION_DATA, Context.MODE_PRIVATE);
-		logger = new SQLLogger(this);
-		sessionEditor = sessionPref.edit();
+		checkRootAndPorthack();
+		startAndBind();
 	}
 
 	@Override
@@ -140,160 +124,206 @@ public class MainActivity extends Activity {
 		getMenuInflater().inflate(R.menu.main, menu);
 		return true;
 	}
-	
+
 	@Override
 	public boolean onOptionsItemSelected(MenuItem item) {
-	    // Handle item selection
-	    switch (item.getItemId()) {
-	        case R.id.action_settings:
-	            startActivity(new Intent(this, SettingsActivity.class));
-	            break;
-	        case R.id.action_about:
-	            startActivity(new Intent(this, AboutActivity.class));
-	            break;
-	        default:
-	    }
-        return super.onOptionsItemSelected(item);
+		// Handle item selection
+		switch (item.getItemId()) {
+		case R.id.action_settings:
+			startActivity(new Intent(this, SettingsActivity.class));
+			break;
+		case R.id.action_about:
+			startActivity(new Intent(this, AboutActivity.class));
+			break;
+		default:
+		}
+		return super.onOptionsItemSelected(item);
 	}
 
 	@Override
 	protected void onStart() {
 		super.onStart();
-		//Register Broadcast Receiver
+		// Register Broadcast Receiver
 		registerReceiver();
-		registerNetReceiver();
-		// Bind service if running, else check for connection change and delete sessionData
+		logResultReceiver.setReceiver(this);
+		// Bind service if running, else check for connection change and delete
+		// sessionData
 		if (isServiceRunning()) {
 			bindService(getServiceIntent(), mConnection, BIND_AUTO_CREATE);
-		} else {
-			String bssid_old = sessionPref.getString(MainActivity.BSSID, "");
-			String bssid_new = HelperUtils.getBSSID(this);
-			if(bssid_new == null || !bssid_new.equals(bssid_old)){
-				deleteSessionData();
-			}
-		}
+		} 
 		// Update UI
-		updateUI();
 		updateConnectionInfText();
 	}
 
 	@Override
 	protected void onStop() {
-		//Unbind running service
-		if (isServiceRunning()) {
-			unbindService(mConnection);
-		}
 		// Unregister Broadcast Receiver
-		unregisterNetReceiver();
 		unregisterReceiver();
+		logResultReceiver.setReceiver(null);
 		super.onStop();
 	}
-	
+
 	@Override
-	protected void onDestroy(){
-		super.onDestroy();
-		// If service not running delete session data
-		if(!isServiceRunning()){
-			deleteSessionData();
+	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()) {
-				protocolClicked = "PANIC";
+				String[] protocols = getResources().getStringArray(R.array.protocols);
+				for(String protocol: protocols){
+					mService.startListener(protocol);	
+				}						
 			} else {
-				protocolClicked = "SMB";
-			}			
-			startAndBind();
+				if(mService.isRunning("SMB")){
+					mService.stopListener("SMB");
+				}else{
+					mService.startListener("SMB");
+				}	
+			}
 		} else {
 			mService.stopListeners();
 			stopAndUnbind();
 		}
 	}
-	
+
 	/**
 	 * Starts the ViewLog activity, when the Button is pressed.
+	 * 
 	 * @see ViewLog
-	 * @param view View elements which triggers the method call.
+	 * @param view
+	 *            View elements which triggers the method call.
 	 */
-	public void showLog(View view){
+	public void showLog(View view) {
 		startActivity(new Intent(this, ViewLog.class));
 	}
 
+	public void startPlayGround(View view) {
+		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.
+	 * 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();	
+		bindService();
 	}
-	
+
 	/**
 	 * Binds service to Activity
+	 * 
 	 * @see HoneyService
 	 */
-	private void bindService(){
+	private void bindService() {
 		bindService(getServiceIntent(), mConnection, BIND_AUTO_CREATE);
-		serviceBound = true;
 	}
 
 	/**
 	 * Stops service and unbinds it.
+	 * 
 	 * @see HoneyService
 	 */
 	private void stopAndUnbind() {
 		unbindService();
 		stopService(getServiceIntent());
 	}
-	
+
 	/**
 	 * Unbinds service.
+	 * 
 	 * @see HoneyService
 	 */
-	private void unbindService(){
+	private void unbindService() {
 		unbindService(mConnection);
-		serviceBound = false;
 	}
-	
+
 	/**
 	 * 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.
+		/**
+		 * 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();
-			if(protocolClicked != null && protocolClicked.equals("PANIC")){
-				mService.startListeners();
-			}else if (protocolClicked != null){
-				mService.toggleListener(protocolClicked);
-			}
-			protocolClicked = null;
+			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;			
+			mService = null;
+			serviceBound = false;
 		}
 
 	};
-	
+
+	/**
+	 * Checks if the phone ist rooted and if porthack is installed. Sets flags
+	 * {@link isRooted} and {@link porthackInstalled}
+	 */
+	private void checkRootAndPorthack() {
+		isRooted = false;
+		porthackInstalled = false;
+		Process p;
+		try {
+			String found = "Found";
+			String notFound = "Not found";
+			String command = "[ -f /data/local/p ] && echo " + found
+					+ " || echo " + notFound;
+			p = Runtime.getRuntime().exec(new String[] { "su", "-c", command });
+			BufferedReader in = new BufferedReader(new InputStreamReader(
+					p.getInputStream()));
+			/*
+			 * int av = byte[] b = new byte[av]; if (av != 0) { in.read(b); }
+			 */
+			String echoResponse = in.readLine();
+			Log.i("MainAc", echoResponse);
+			if (echoResponse.equals(found)) {
+				isRooted = true;
+				porthackInstalled = true;
+			} else if (echoResponse.equals(notFound)) {
+				isRooted = true;
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		Log.i("MainAc", "Rooted: " + isRooted + " Porthack: "
+				+ porthackInstalled);
+	}
+
 	/**
 	 * Returns an intent to start HoneyService.
+	 * 
 	 * @return An Intent to start HoneyService
 	 */
 	private Intent getServiceIntent() {
@@ -302,6 +332,7 @@ public class MainActivity extends Activity {
 
 	/**
 	 * Checks if user selected paranoid mode.
+	 * 
 	 * @return True when paranoid mode is selected, else returns false.
 	 */
 	private boolean isParanoid() {
@@ -309,7 +340,8 @@ public class MainActivity extends Activity {
 	}
 
 	/**
-	 * Initializes the ListView. Creating its contents dynamic from protocol res/values/protocols.xml
+	 * Initializes the ListView. Creating its contents dynamic from protocol
+	 * res/values/protocols.xml
 	 */
 	private void initListView() {
 		ArrayList<HashMap<String, String>> data = new ArrayList<HashMap<String, String>>();
@@ -338,27 +370,26 @@ public class MainActivity extends Activity {
 					int position, long id) {
 				String protocolName = (String) ((HashMap<?, ?>) adapter
 						.getItem(position)).get("protocol");
-				if (isServiceRunning()) {
-					mService.toggleListener(protocolName);	
-					if(!mService.hasRunningListeners()){
-						stopAndUnbind();
-					}
+				if(mService.isRunning(protocolName)){
+					mService.stopListener(protocolName);
 				}else{
-					protocolClicked = protocolName;
-					startAndBind();
-				}											
+					mService.startListener(protocolName);
+				}				
 			}
 		});
 	}
-
+	
 	/**
 	 * Checks if a {@link HoneyService} instance is running.
-	 * @return True if {@link HoneyService}  is running, else false.
+	 * 
+	 * @return True if {@link HoneyService} is running, else false.
 	 */
 	private boolean isServiceRunning() {
 		ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
-		for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
-			if (service.service.getClassName().equals(HoneyService.class.getName())) {
+		for (RunningServiceInfo service : manager
+				.getRunningServices(Integer.MAX_VALUE)) {
+			if (service.service.getClassName().equals(
+					HoneyService.class.getName())) {
 				return true;
 			}
 		}
@@ -366,32 +397,36 @@ public class MainActivity extends Activity {
 	}
 	
 	/**
-	 * Deletes all session related Data.
+	 * Checks if a {@link HoneyService} instance is running.
+	 * 
+	 * @return True if {@link HoneyService} is running, else false.
 	 */
-	private void deleteSessionData(){
-    	sessionEditor.clear();
-    	sessionEditor.commit();
+	private boolean isServiceBound() {
+		return serviceBound;
 	}
 
 	/**
 	 * Register broadcast receiver for custom broadcast.
+	 * 
 	 * @see #BROADCAST
 	 */
 	private void registerReceiver() {
 		LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver,
-				new IntentFilter(BROADCAST));
+				new IntentFilter(getString(R.string.broadcast)));
 	}
 
 	/**
 	 * Unregisters broadcast receiver for custom broadcast.
+	 * 
 	 * @see #BROADCAST
 	 */
 	private void unregisterReceiver() {
 		LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);
 	}
-	
+
 	/**
 	 * Receiver for custom broadcast.
+	 * 
 	 * @see #BROADCAST
 	 */
 	private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@@ -399,89 +434,65 @@ public class MainActivity extends Activity {
 		public void onReceive(Context context, Intent intent) {
 			// Update user interface.
 			updateUI();
-		}
-	};
-
-	/**
-	 * Register broadcast receiver for network state changes.
-	 * @see ConnectivityManager#CONNECTIVITY_ACTION
-	 */
-	private void registerNetReceiver() {   
-		IntentFilter intent = new IntentFilter();
-	    intent.addAction(ConnectivityManager.CONNECTIVITY_ACTION); //"android.net.conn.CONNECTIVITY_CHANGE"
-	    registerReceiver(netReceiver, intent);
-	}
-
-	/**
-	 * Unregister broadcast receiver for network state changes.
-	 */
-	private void unregisterNetReceiver() {
-		unregisterReceiver(netReceiver);
-	}
-
-	/**
-	 * Receiver for network state change events.
-	 */
-	private BroadcastReceiver netReceiver = new BroadcastReceiver() {
-		@Override
-		public void onReceive(Context context, Intent intent) {
-/*			String bssid_old = sessionPref.getString(BSSID, "");
-			String bssid_new = HelperUtils.getBSSID(context);
-
-			if ((bssid_new == null || !bssid_new.equals(bssid_old)) && serviceBound) {
-				Toast.makeText(getApplicationContext(),"Connection changed! Services stopped!", Toast.LENGTH_LONG).show();
-				unbindService();
-			}	
-*/			
 			updateConnectionInfText();
 		}
-	};	
+	};
 
 	/**
 	 * Updates Information shown by the GUI.
 	 */
-	private void updateUI() {		
+	private void updateUI() {
 		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)){
-			//Check if protocol is active
-			if(sessionPref.getBoolean(protocol + LISTENER, false)){
-				activeListeners = true;
-				int handlerCount = sessionPref.getInt(protocol + HANDLER_COUNT, 0);
-				//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 been recorded as infected.
-					if(logger.bssidSeen(protocol, HelperUtils.getBSSID(getApplicationContext()))){
-						updateProtocolLight(LIGHT_YELLOW, protocol);
-						yellowLight = true;
-					} else{
-						updateProtocolLight(LIGHT_GREEN, protocol);						
+		// 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()){
+				// Check if protocol is active
+				if (mService.isRunning(protocol)) {
+					activeListeners = true;
+					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
+						// 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))) {
+							updateProtocolLight(LIGHT_YELLOW, protocol);
+							yellowLight = true;
+						} else {
+							updateProtocolLight(LIGHT_GREEN, protocol);
+						}
+						updateProtocolConnections(0, protocol);
 					}
-					updateProtocolConnections(0, protocol);
+				} else {
+					updateProtocolLight(LIGHT_GREY, protocol);
 				}
 			}else{
 				updateProtocolLight(LIGHT_GREY, protocol);
-			}
+			}				
 		}
 
-		//Update the big attack indicator.
+		// Update the big attack indicator.
 		if (activeListeners) {
 			if (activeHandlers) {
 				updateStatusLight(LIGHT_RED);
 			} else {
-				if(yellowLight){
+				if (yellowLight) {
 					updateStatusLight(LIGHT_YELLOW);
 				} else {
 					updateStatusLight(LIGHT_GREEN);
-				}					
+				}
 			}
 			((ToggleButton) findViewById(R.id.toggleButtonOnOff))
 					.setChecked(true);
@@ -496,8 +507,10 @@ public class MainActivity extends Activity {
 
 	/**
 	 * Sets the big light indicator.
-	 * @param light Integer code to set the light color.
-	 * @see #LIGHT_GREY 
+	 * 
+	 * @param light
+	 *            Integer code to set the light color.
+	 * @see #LIGHT_GREY
 	 * @see #LIGHT_GREEN
 	 * @see #LIGHT_RED
 	 * @see #LIGHT_YELLOW
@@ -525,8 +538,11 @@ public class MainActivity extends Activity {
 
 	/**
 	 * 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.
+	 * 
+	 * @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) {
@@ -555,8 +571,11 @@ public class MainActivity extends Activity {
 
 	/**
 	 * 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.
+	 * 
+	 * @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) {
@@ -573,100 +592,48 @@ public class MainActivity extends Activity {
 	 * 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...");
-					
-					//Update the connection information
-					updateConnectionInfo();
-					SetExternalIPTask async = new SetExternalIPTask();
-					async.execute(new String[]{"http://ip2country.sourceforge.net/ip2c.php?format=JSON"});
-					
-					//Get connection information
-					String ssid = sessionPref.getString(SSID, null);
-					String bssid = sessionPref.getString(BSSID, null);
-					String internalIP = sessionPref.getString(INTERNAL_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("-");
+		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("-");
 	}
-	
-	/**
-	 * 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#SESSION_DATA
-	 */
-	private void updateConnectionInfo() {	
-		SharedPreferences pref = context.getSharedPreferences(MainActivity.SESSION_DATA, Context.MODE_PRIVATE);
-		Editor editor = pref.edit();
-		editor.putString(MainActivity.SSID, HelperUtils.getSSID(context));
-		editor.putString(MainActivity.BSSID, HelperUtils.getBSSID(context));
-		editor.putString(MainActivity.INTERNAL_IP, HelperUtils.getInternalIP(context));
-		editor.commit();
-	}	
-	
-	/**
-	 * 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;
-
-						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
-			protected void onPostExecute(String result){
-				sessionEditor.putString(MainActivity.EXTERNAL_IP, result);
-				sessionEditor.commit();
-				TextView externalIPView = (TextView) findViewById(R.id.textViewExternalIPValue);
-				if (result != null)
-					externalIPView.setText(result);
-				else
-					externalIPView.setText("-");	
-			}
-		};
 
+	/* ############# Help functions for animation ################## */
 
-	/*############# Help functions for animation ##################*/
-	
 	@Override
 	public boolean onTouchEvent(MotionEvent event) {
 		return gestureDetector.onTouchEvent(event);
 	}
-	
+
 	/**
 	 * Initializes variables for screen animation
 	 */
@@ -683,7 +650,7 @@ public class MainActivity extends Activity {
 		animFlipOutRL = AnimationUtils.loadAnimation(this,
 				R.anim.out_right_to_left);
 	}
-	
+
 	/**
 	 * Called when a swipe to the Left is registered.
 	 */
@@ -720,12 +687,5 @@ public class MainActivity extends Activity {
 			return true;
 		}
 	};
-
-	/**
-	 * Returns the context of the App.
-	 * @return context.
-	 */
-    public static Context getContext() {
-        return MainActivity.context;
-    }
+	
 }

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

@@ -0,0 +1,96 @@
+package de.tudarmstadt.informatik.hostage.ui;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Random;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.View;
+import android.widget.TextView;
+import de.tudarmstadt.informatik.hostage.R;
+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{
+	
+	BluetoothSync bs;
+
+	@Override
+	protected void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.activity_playground);
+		bs = new BluetoothSync(this);
+		setNetworkInfoText();
+	}
+
+	@Override
+	public boolean onCreateOptionsMenu(Menu menu) {
+		getMenuInflater().inflate(R.menu.main, menu);
+		return true;
+	}
+	
+	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){
+			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";			
+		}
+		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);
+		}
+
+		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);
+	}
+}

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

@@ -45,7 +45,19 @@ public class SettingsActivity extends PreferenceActivity implements OnSharedPref
         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());
     }    
 
     protected void onResume() {
@@ -118,6 +130,28 @@ public class SettingsActivity extends PreferenceActivity implements OnSharedPref
         	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);
+    	}
     	 
     }
 }

+ 199 - 162
src/de/tudarmstadt/informatik/hostage/ui/ViewLog.java

@@ -33,8 +33,6 @@ import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
 import android.widget.DatePicker;
-import android.widget.EditText;
-import android.widget.Filter;
 import android.widget.TableLayout;
 import android.widget.TableRow;
 import android.widget.TextView;
@@ -42,24 +40,24 @@ import android.widget.TimePicker;
 import android.widget.Toast;
 import de.tudarmstadt.informatik.hostage.R;
 import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
-import de.tudarmstadt.informatik.hostage.logging.Logger;
 import de.tudarmstadt.informatik.hostage.logging.Record;
-import de.tudarmstadt.informatik.hostage.logging.SQLLogger;
+import de.tudarmstadt.informatik.hostage.logging.formatter.TraCINgFormatter;
+
 /**
- * ViewLog shows Statistics about the recorded Attacks.
- * It also offers the user several options to perform actions with the database.
- * This includes:<br>
+ * ViewLog shows Statistics about the recorded Attacks. It also offers the user
+ * several options to perform actions with the database. This includes:<br>
  * - show records,<br>
  * - export records,<br>
  * - upload records,<br>
  * - and delete records.
+ * 
  * @author Lars Pandikow
  */
 public class ViewLog extends Activity {
-	
-	private final SimpleDateFormat sdf = new SimpleDateFormat("MMM dd,yyyy HH:mm", Locale.US);
 
-	private SQLLogger logger;
+	private final SimpleDateFormat sdf = new SimpleDateFormat(
+			"MMM dd,yyyy HH:mm", Locale.US);
+
 	private SharedPreferences pref;
 	private Editor editor;
 
@@ -67,7 +65,6 @@ public class ViewLog extends Activity {
 	protected void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
 		setContentView(R.layout.activity_viewlog);
-		logger = new SQLLogger(this);
 		pref = PreferenceManager.getDefaultSharedPreferences(this);
 		editor = pref.edit();
 		initStatistic();
@@ -81,27 +78,29 @@ public class ViewLog extends Activity {
 
 	@Override
 	public boolean onOptionsItemSelected(MenuItem item) {
-	    // Handle item selection
-	    switch (item.getItemId()) {
-	        case R.id.action_settings:
-	            startActivity(new Intent(this, SettingsActivity.class));
-	            break;
-	        case R.id.action_about:
-	            startActivity(new Intent(this, AboutActivity.class));
-	            break;
-	        default:
-	    }
-        return super.onOptionsItemSelected(item);
+		// Handle item selection
+		switch (item.getItemId()) {
+		case R.id.action_settings:
+			startActivity(new Intent(this, SettingsActivity.class));
+			break;
+		case R.id.action_about:
+			startActivity(new Intent(this, AboutActivity.class));
+			break;
+		default:
+		}
+		return super.onOptionsItemSelected(item);
 	}
 
 	/**
-	 * Creates a Dialog to choose export format.
-	 * Then calls {@link ViewLog#exportDatabase(int)}
-	 * @param view View elements which triggers the method call.
+	 * 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.export_dialog_title);
+		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);
@@ -110,77 +109,102 @@ public class ViewLog extends Activity {
 		builder.create();
 		builder.show();
 	}
-	
+
 	/**
-	 * Exports all records in a given format. Before exporting checks export location from preferences.
-	 * @param format Integer coded export format
+	 * 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){
+	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()){					
+			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();
+				} 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);
+			} else {
+				log = this.openFileOutput(
+						"hostage_" + format + "_" + System.currentTimeMillis()
+								+ ".log", Context.MODE_PRIVATE);
 			}
-			
-			ArrayList<Record> records = logger.getAllRecords();
-			for(Record record : records){
-					log.write((record.toString(format)).getBytes());
+
+			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();
+			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();
+			Toast.makeText(this, "Could not write to SD Card",
+					Toast.LENGTH_SHORT).show();
 			e.printStackTrace();
-		}	
+		}
 	}
-	
+
 	/**
-	 * Uploads a JSON Representation of each attack to a server, specified in the preferences.<br>
-	 * The method only uploads information about attacks that have net been uploaded yet.<br>
-	 * The local and remote IP of each record will be replaced with the external IP of then device at the time of the upload.
-	 * For the Upload it uses a HttpPost with a HttpsClient, which does not validate any certificates.<br>
+	 * Uploads a JSON Representation of each attack to a server, specified in
+	 * the preferences.<br>
+	 * The method only uploads information about attacks that have net been
+	 * uploaded yet.<br>
+	 * The local and remote IP of each record will be replaced with the external
+	 * IP of then device at the time of the upload. For the Upload it uses a
+	 * HttpPost with a HttpsClient, which does not validate any certificates.<br>
 	 * The Upload runs in its own Thread.<br>
-	 * While uploading the method also creates a notification to inform the user about the status of the upload.<br>
+	 * While uploading the method also creates a notification to inform the user
+	 * about the status of the upload.<br>
 	 * <b>Only uploads Records with a external IP that is not null!
-	 * @param  view View elements which triggers the method call.
+	 * 
+	 * @param view
+	 *            View elements which triggers the method call.
 	 * @see de.tudarmstadt.informatik.hostage.net.MySSLSocketFactory
 	 */
-	public void uploadDatabase(View view){
-		//Create a Notification
+	public void uploadDatabase(View view) {
+		// Create a Notification
 		final NotificationCompat.Builder builder;
 		final NotificationManager mNotifyManager;
-		final int lastUploadedAttackId = pref.getInt("LAST_UPLOADED_ATTACK_ID", -1);
+		final int lastUploadedAttackId = pref.getInt("LAST_UPLOADED_ATTACK_ID",
+				-1);
 		int currentAttackId = pref.getInt("ATTACK_ID_COUNTER", 0);
 		// Check if there are new records to upload
-		if(lastUploadedAttackId == currentAttackId -1){
+		if (lastUploadedAttackId == currentAttackId - 1) {
 			// Inform user that no upload is necessary
-			Toast.makeText(this, "All data have already been uploaded.", Toast.LENGTH_SHORT).show();
+			Toast.makeText(this, "All data have already been uploaded.",
+					Toast.LENGTH_SHORT).show();
 			return;
 		}
 		// Build and show Upload Notification in notification bar
 		builder = new NotificationCompat.Builder(this)
-							.setContentTitle(this.getString(R.string.app_name))
-							.setContentText("Upload in progress...")
-							.setTicker("Uploading Data...")
-							.setSmallIcon(R.drawable.ic_launcher)	
-							.setWhen(System.currentTimeMillis());	
+				.setContentTitle(this.getString(R.string.app_name))
+				.setContentText("Upload in progress...")
+				.setTicker("Uploading Data...")
+				.setSmallIcon(R.drawable.ic_launcher)
+				.setWhen(System.currentTimeMillis());
 		TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
 		stackBuilder.addParentStack(MainActivity.class);
 		stackBuilder.addNextIntent(new Intent());
@@ -194,78 +218,78 @@ public class ViewLog extends Activity {
 		final Context context = this;
 		// Create a new Thread for upload
 		new Thread(new Runnable() {
-			  public void run() {	
-					// get RecordList
-					ArrayList<Record> recordList = logger.getRecordOfEachAttack(lastUploadedAttackId);
-					final int progressMax = recordList.size();		
-					Log.i("SQLLogger", "Logs to upload: " + progressMax);	
-							
-							int progressBarStatus = 0;
-							int retry_counter = 0;
-							while(progressBarStatus < progressMax){
-								Record record = recordList.get(progressBarStatus);
-								// Only upload records with a saved external ip
-								if(record.getExternalIP() != null){
-									retry_counter = 0;
-									if(HelperUtils.uploadSingleRecord(context, record)){
-										// Update Notification progress bar
-										progressBarStatus++;								
-										builder.setProgress(progressMax, progressBarStatus, false);
-					                     // Update the progress bar
-										mNotifyManager.notify(2, builder.build());
-									}else{
-										retry_counter++;
-										if(retry_counter == 3){
-											retry_counter = 0;
-											progressBarStatus++;
-										}	
-									}						
-								}
-							}	
-							
-					if(progressBarStatus == progressMax){
-						// When the loop is finished, updates the notification
-			            builder.setContentText("Upload complete")
-			            	   .setTicker("Upload complete")
-			            // Removes the progress bar
-			                   .setProgress(0,0,false);
-			            mNotifyManager.notify(2, builder.build());
-			        }
-			}}).start();
-		editor.putInt("LAST_UPLOADED_ATTACK_ID",currentAttackId - 1);
-		editor.commit();				
-	}
-	
+			public void run() {
+				// get RecordList
+				ArrayList<Record> recordList = null;// logger.getRecordOfEachAttack(lastUploadedAttackId);
+				final int progressMax = recordList.size();
+				Log.i("SQLLogger", "Logs to upload: " + progressMax);
 
+				int progressBarStatus = 0;
+				int retry_counter = 0;
+				while (progressBarStatus < progressMax) {
+					Record record = recordList.get(progressBarStatus);
+					// Only upload records with a saved external ip
+					if (record.getExternalIP() != null) {
+						retry_counter = 0;
+						if (HelperUtils.uploadSingleRecord(context, record)) {
+							// Update Notification progress bar
+							progressBarStatus++;
+							builder.setProgress(progressMax, progressBarStatus,
+									false);
+							// Update the progress bar
+							mNotifyManager.notify(2, builder.build());
+						} else {
+							retry_counter++;
+							if (retry_counter == 3) {
+								retry_counter = 0;
+								progressBarStatus++;
+							}
+						}
+					}
+				}
+
+				if (progressBarStatus == progressMax) {
+					// When the loop is finished, updates the notification
+					builder.setContentText("Upload complete")
+							.setTicker("Upload complete")
+							// Removes the progress bar
+							.setProgress(0, 0, false);
+					mNotifyManager.notify(2, builder.build());
+				}
+			}
+		}).start();
+		editor.putInt("LAST_UPLOADED_ATTACK_ID", currentAttackId - 1);
+		editor.commit();
+	}
 
 	/**
 	 * Starts a ViewLogTable Activity.
-	 * @param view View elements which triggers the method call.
+	 * 
+	 * @param view
+	 *            View elements which triggers the method call.
 	 * @see ViewLogTable
 	 */
 	public void showLog(View view) {
-		LogFilter filter = new LogFilter();
-		
-		
-		Intent intent = new Intent(this, ViewLogTable.class);
-		intent.putExtra(LogFilter.LOG_FILTER_INTENT_KEY, filter);
-		startActivity(intent);
+		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.
-	 * @param view View elements which triggers the method call.
+	 * 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.delete_dialog_title);
+		builder.setTitle(R.string.gui_delete_dialog_title);
 		builder.setItems(R.array.delete_criteria,
 				new DialogInterface.OnClickListener() {
 					public void onClick(DialogInterface dialog, int position) {
@@ -284,25 +308,28 @@ public class ViewLog extends Activity {
 		builder.create();
 		builder.show();
 	}
-	
+
 	/**
-	 * Shows a List with all recorded BSSIDs.
-	 * If a BSSID is selected the method calls {@link Logger#deleteByBSSID(String)} to delete all records with the chosen BSSID
-	 * @see Logger#deleteByBSSID
+	 * Shows a List with all recorded BSSIDs. If a BSSID is selected the method
+	 * calls {@link ILogger#deleteByBSSID(String)} to delete all records with
+	 * the chosen BSSID
+	 * 
+	 * @see ILogger#deleteByBSSID
 	 */
 	private void deleteByBSSID() {
 		AlertDialog.Builder builder = new AlertDialog.Builder(this);
-		final String[] bssidArray = logger.getAllBSSIDS();
+		final String[] bssidArray = null;// logger.getAllBSSIDS();
 		final String[] strings = new String[bssidArray.length];
-		for(int i = 0; i < bssidArray.length; i++){
-			strings[i] = bssidArray[i] + " (" + logger.getSSID(bssidArray[i]) +")";
+		for (int i = 0; i < bssidArray.length; i++) {
+			strings[i] = bssidArray[i] + " (" // + logger.getSSID(bssidArray[i])
+					+ ")";
 		}
-		builder.setTitle(R.string.delete_dialog_title);
+		builder.setTitle(R.string.gui_delete_dialog_title);
 		builder.setItems(strings, new DialogInterface.OnClickListener() {
 			@SuppressLint("NewApi")
 			public void onClick(DialogInterface dialog, int position) {
-				
-				logger.deleteByBSSID(bssidArray[position]);
+
+				// logger.deleteByBSSID(bssidArray[position]);
 				Toast.makeText(
 						getApplicationContext(),
 						"All entries with bssid '" + bssidArray[position]
@@ -321,13 +348,13 @@ public class ViewLog extends Activity {
 	}
 
 	/**
-	 * Creates a DatePicking Dialog where the user can choose a date. Afterwards {@link ViewLog#deleteByDate(int, int, int)} is called.
+	 * Creates a DatePicking Dialog where the user can choose a date. Afterwards
+	 * {@link ViewLog#deleteByDate(int, int, int)} is called.
 	 */
 	private void deleteByDate() {
 		showDialog(0);
 	}
 
-
 	@Override
 	protected Dialog onCreateDialog(int id) {
 		switch (id) {
@@ -336,18 +363,24 @@ public class ViewLog extends Activity {
 			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 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 {@link Logger#deleteByDate(long)} is called with a long representation of the Date.
-	 * If the user cancels the Dialog nothing happens and the dialog disappears.
+	 * Shows a Dialog with the given date and ask him to confirm deleting
+	 * records that are older than the shown date. When the user confirms
+	 * {@link ILogger#deleteByDate(long)} is called with a long representation
+	 * of the Date. If the user cancels the Dialog nothing happens and the
+	 * dialog disappears.
+	 * 
 	 * @param year
 	 * @param monthOfYear
 	 * @param dayOfMonth
@@ -358,15 +391,15 @@ public class ViewLog extends Activity {
 		calendar.set(year, monthOfYear, dayOfMonth,
 				timePicker.getCurrentHour(), timePicker.getCurrentMinute(), 0);
 		AlertDialog.Builder builder = new AlertDialog.Builder(this);
-		builder.setTitle(R.string.dialog_clear_database_date)
+		builder.setTitle(R.string.gui_dialog_clear_database_date)
 				.setMessage(sdf.format(calendar.getTime()))
-				.setPositiveButton(R.string.delete,
+				.setPositiveButton(R.string.gui_delete,
 						new DialogInterface.OnClickListener() {
 							@SuppressLint("NewApi")
 							public void onClick(DialogInterface dialog, int id) {
 								long time = calendar.getTimeInMillis();
 								// Delete Data
-								logger.deleteByDate(time);
+								// logger.deleteByDate(time);
 								Toast.makeText(getApplicationContext(),
 										"Data sets deleted!",
 										Toast.LENGTH_SHORT).show();
@@ -380,7 +413,7 @@ public class ViewLog extends Activity {
 								}
 							}
 						})
-				.setNegativeButton(R.string.cancel,
+				.setNegativeButton(R.string.gui_cancel,
 						new DialogInterface.OnClickListener() {
 							public void onClick(DialogInterface dialog, int id) {
 								// User cancelled the dialog
@@ -392,19 +425,20 @@ public class ViewLog extends Activity {
 	}
 
 	/**
-	 * Shows a Dialog to confirm that the database should be cleared.
-	 * If confirmed {@link SQLLogger#clearData()} is called.
-	 * @see Logger#clearData()
+	 * Shows a Dialog to confirm that the database should be cleared. If
+	 * confirmed {@link SQLLogger#clearData()} is called.
+	 * 
+	 * @see ILogger#clearData()
 	 */
 	private void deleteAll() {
 		AlertDialog.Builder builder = new AlertDialog.Builder(this);
-		builder.setMessage(R.string.dialog_clear_database)
-				.setPositiveButton(R.string.clear,
+		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();
+								// logger.clearData();
 								editor.putInt("ATTACK_ID_COUNTER", 0);
 								editor.putInt("LAST_UPLOADED_ATTACK_ID", -1);
 								editor.commit();
@@ -421,7 +455,7 @@ public class ViewLog extends Activity {
 								}
 							}
 						})
-				.setNegativeButton(R.string.cancel,
+				.setNegativeButton(R.string.gui_cancel,
 						new DialogInterface.OnClickListener() {
 							public void onClick(DialogInterface dialog, int id) {
 								// User cancelled the dialog
@@ -433,11 +467,12 @@ public class ViewLog extends Activity {
 	}
 
 	/**
-	 * Initializes the Statistics. Creates a table row for every protocol and checks the dabase for the 
- count.
-	 * Calls {@link ViewLog#setFirstAndLastAttack()} to set the TextViews.
-	 * @see Logger#getAttackCount()
-	 * @see Logger#getAttackPerProtokolCount(String)
+	 * Initializes the Statistics. Creates a table row for every protocol and
+	 * checks the dabase for the attack count. Calls
+	 * {@link ViewLog#setFirstAndLastAttack()} to set the TextViews.
+	 * 
+	 * @see ILogger#getAttackCount()
+	 * @see ILogger#getAttackPerProtocolCount(String)
 	 */
 	private void initStatistic() {
 		TableLayout table = (TableLayout) findViewById(R.id.layoutContainer);
@@ -463,9 +498,10 @@ public class ViewLog extends Activity {
 			value.setPadding(3, 0, 3, 0);
 			row.addView(value);
 			if (protocol.equals("Total")) {
-				value.setText("" + logger.getAttackCount());
+				value.setText(""); // + logger.getAttackCount());
 			} else {
-				value.setText("" + logger.getAttackPerProtokolCount(protocol));
+				value.setText("");// +
+									// logger.getAttackPerProtocolCount(protocol));
 			}
 			table.addView(row);
 		}
@@ -474,13 +510,14 @@ public class ViewLog extends Activity {
 
 	/**
 	 * Sets the TextViews for first and last attack.
-	 * @see Logger#getSmallestAttackId()
-	 * @see Logger#getHighestAttackId()
-	 * @see Logger#getRecordOfAttackId(long)
+	 * 
+	 * @see ILogger#getSmallestAttackId()
+	 * @see ILogger#getHighestAttackId()
+	 * @see ILogger#getRecordOfAttackId(long)
 	 */
 	private void setFirstAndLastAttack() {
-		Record firstAttack = logger.getRecordOfAttackId(logger.getSmallestAttackId());
-		Record lastAttack = logger.getRecordOfAttackId(logger.getHighestAttackId());
+		Record firstAttack = null;// logger.getRecordOfAttackId(logger.getSmallestAttackId());
+		Record lastAttack = null;// logger.getRecordOfAttackId(logger.getHighestAttackId());
 		if (firstAttack != null) {
 			Date resultdate = new Date(firstAttack.getTimestamp());
 			TextView text = (TextView) findViewById(R.id.textFirstAttackValue);

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

@@ -1,34 +1,11 @@
 package de.tudarmstadt.informatik.hostage.ui;
 
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.HashMap;
-
-import android.annotation.SuppressLint;
 import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
 import android.os.Bundle;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.AdapterView;
-import android.widget.ListAdapter;
-import android.widget.ListView;
-import android.widget.SimpleAdapter;
-import android.widget.Toast;
-import de.tudarmstadt.informatik.hostage.R;
-import de.tudarmstadt.informatik.hostage.logging.DatabaseHandler;
+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.Record.TYPE;
 
 /**
  * Creates a simple log view. Shows the Information for every attack. The format
@@ -37,226 +14,24 @@ import de.tudarmstadt.informatik.hostage.logging.Record.TYPE;
  * @author Lars Pandikow
  * 
  */
-@SuppressLint("NewApi")
-public class ViewLogTable extends Activity{
-	DatabaseHandler dbh;
+public class ViewLogTable extends Activity {
 
-	private ArrayList<String> selectedProtocols;
-	
-	private LogFilter filter;
-	private boolean showFilterButton;
-	
 	@Override
 	protected void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
-		
-	    // Get the message from the intent
-	    Intent intent = getIntent();
-	    LogFilter filter = intent.getParcelableExtra(LogFilter.LOG_FILTER_INTENT_KEY);
-
-	    if(filter == null){
-	    	this.filter = new LogFilter();
-	    } else {
-	    	this.filter = filter;
-	    }
-
-	    this.showFilterButton = !filter.isNotEditable();
-	    
-	    
-		this.selectedProtocols = new ArrayList<String>();
-
-//		for (String protocol : this.getResources().getStringArray(
-//				R.array.protocols)) {
-//			this.selectedProtocols.add(protocol);
-//		}
-
-		dbh = new DatabaseHandler(getBaseContext());
-		setContentView(R.layout.activity_loglist);
-
-		this.addRecordToDB();
-
-		populateListViewFromDB();
-		registerListClickCallback();
-	}
-
-	public class RecordComparator implements Comparator<Record> {
-		public int compare(Record o1, Record o2) {
-			long time1 = o1.getTimestamp();
-			long time2 = o2.getTimestamp();
-			if (time1 < time2)
-				return -1;
-			if (time1 > time2)
-				return 1;
-			return 0;
-		}
-	}
-
-	private void addRecordToDB() {
-		Calendar cal = Calendar.getInstance();
-
-		int maxProtocolsIndex = this.getResources().getStringArray(
-				R.array.protocols).length;
-
-		int numberofRecords = (int) (Math.random() * (50 - 10));
-		for (int i = 0; i < numberofRecords; i++) {
-			Record record = new Record();
-			record.setBSSID("BSSID: " + i);
-			record.setSSID("SSID: w" + i);
-			record.setTimestamp(cal.getTimeInMillis()
-					+ ((i * 60 * 60 * 60 * 24) * 1000));
-
-			int index = i % maxProtocolsIndex;
-			String protocolName = this.getResources().getStringArray(
-					R.array.protocols)[index];
-
-			record.setProtocol(protocolName);
-			record.setId(i);
-			record.setAttack_id(i);
-			try {
-				InetAddress localIP = InetAddress.getByAddress("Digga",
-						new byte[] { 127, 0, 0, 1 }); // .getByName("192.168.2.1");
-				record.setLocalIP(localIP);
-				record.setRemoteIP(InetAddress.getByAddress("Digga",
-						new byte[] { 127, 1, 1, 1 }));
-				record.setType(TYPE.SEND);
-			} catch (UnknownHostException e) {
-				e.printStackTrace();
-			}
-
-			dbh.addRecord(record);
-		}
-	}
-
-	private void populateListViewFromDB() {
-		
-		ListView mylist = (ListView) findViewById(R.id.loglistview);
-	    
-		ArrayList<HashMap<String, String>> Items = new ArrayList<HashMap<String, String>>();
-
-		ArrayList<Record> data = dbh.getRecordsForFilter(this.filter);    
-		Collections.sort(data, new RecordComparator());
-		
-
-	        for (Record val : data) {
-		            HashMap<String, String> map = new HashMap<String, String>();
-		            map.put(this.getString(R.string.RecordBSSID), val.getBSSID() );
-		            map.put(this.getString(R.string.RecordSSID), val.getSSID());
-		            map.put(this.getString(R.string.RecordProtocol), val.getProtocol());
-		            map.put(this.getString(R.string.RecordTimestamp), this.getDateAsString(val.getTimestamp()));
-		            Items.add(map);  
-	        }
-	        
-	     // Adding Items to ListView
-	        String keys[] = new String[] { this.getString(R.string.RecordBSSID), this.getString(R.string.RecordSSID), this.getString(R.string.RecordProtocol), this.getString(R.string.RecordTimestamp)};
-	        int ids[] = new int[] {R.id.RecordTextFieldBSSID, R.id.RecordTextFieldSSID, R.id.RecordTextFieldProtocol, R.id.RecordTextFieldTimestamp };
-	        
-	        ListAdapter adapter = new SimpleAdapter(this, Items, R.layout.loglist_row, keys, ids);
-	        
-	        mylist.setAdapter(adapter);
-	}
-
-	@SuppressLint("SimpleDateFormat")
-	private String getDateAsString(long timeStamp) {
-
-		try {
-			DateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
-			Date netDate = (new Date(timeStamp));
-			return sdf.format(netDate);
-		} catch (Exception ex) {
-			return "xx";
-		}
-	}
-
-	private void registerListClickCallback() {
-		ListView mylist = (ListView) findViewById(R.id.loglistview);
-
-		mylist.setOnItemClickListener(new AdapterView.OnItemClickListener() {
-			public void onItemClick(AdapterView<?> parent, View viewClicked,
-					int position, long idInDB) {
-				DatabaseHandler dbh = new DatabaseHandler(getBaseContext());
-				Record rec = dbh.getRecord((int) idInDB);
-				String message = createInformationStringFromRecord(rec);
-				Toast.makeText(getApplicationContext(), message,
-						Toast.LENGTH_LONG).show();
-			}
-
-			private String createInformationStringFromRecord(Record rec) {
-				String message = "id: " + rec.getId() + "\n" + "attack_id: "
-						+ rec.getAttack_id() + "\n" + "protocol: "
-						+ rec.getProtocol() + "\n" + "type: " + rec.getType()
-						+ "\n" + "externalIP: " + rec.getExternalIP() + "\n"
-						+ "localIP: " + rec.getLocalIP() + "\n"
-						+ "local port: " + rec.getLocalPort() + "\n"
-						+ "remoteIP: " + rec.getRemoteIP() + "\n" + "BSSID: "
-						+ rec.getBSSID() + "\n" + "SSID: " + rec.getSSID()
-						+ "\n" + "latitude: " + rec.getLatitude() + "\n"
-						+ "longitude: " + rec.getLongitude() + "\n"
-						+ "accuracy: " + rec.getAccuracy() + "\n" + "packet: "
-						+ rec.getPacket() + "\n"
-						+ getDateAsString(rec.getTimestamp()) + "";
-				return message;
-			}
-
-			@SuppressLint("SimpleDateFormat")
-			private String getDateAsString(long timeStamp) {
-
-				try {
-					DateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
-					Date netDate = (new Date(timeStamp));
-					return sdf.format(netDate);
-				} catch (Exception ex) {
-					return "xx";
-				}
-			}
-
-		});
-	}
-
-	@Override
-	public boolean onCreateOptionsMenu(Menu menu) {
-		super.onCreateOptionsMenu(menu);
-		if(this.showFilterButton){
-			MenuItem item = menu.add("Filter");
-			
-
-			// MenuInflater inflater = getMenuInflater();
-			// inflater.inflate(R.menu.listview_detail_menu, menu);
-			return true;
-		} else {
-			return false;
+		UglyDbHelper dbh = new UglyDbHelper(getBaseContext());
+		StringBuffer log = new StringBuffer();
+		// Create a log entry for every attack in the Database
+		for (Record record : dbh.getAllRecords()) {
+			log.append(record.toString());
 		}
-	}
-
-	@Override
-	public boolean onOptionsItemSelected(MenuItem item) {
-		
-		this.openFilterMenu(item.getActionView());
-
-		this.populateListViewFromDB();
-		return super.onOptionsItemSelected(item);
-	}
-	
-
-	private void openFilterMenu(View anchorView){
-		
-	}
-
-	private void saveInSharedPreferences(String key, boolean value) {
-		// --SAVE Data
-		SharedPreferences preferences = this.getSharedPreferences();
-		SharedPreferences.Editor editor = preferences.edit();
-		editor.putBoolean(key, value);
-		editor.commit();
-	}
-
-	private boolean getBooleanInSharedPreferences(String key) {
-		SharedPreferences preferences = this.getSharedPreferences();
-		return preferences.getBoolean(key, true);
-	}
 
-	private SharedPreferences getSharedPreferences() {
-		return this.getSharedPreferences("HostagePreferences",
-				Context.MODE_PRIVATE);
+		ScrollView scroll = new ScrollView(this);
+		TextView text = new TextView(getApplicationContext());
+		text.setText(log);
+		text.setTextAppearance(this, android.R.style.TextAppearance_Medium);
+		scroll.addView(text);
+		setContentView(scroll);
 	}
 
 }

+ 12 - 19
src/de/tudarmstadt/informatik/hostage/ui2/fragment/RecordOverviewFragment.java

@@ -27,9 +27,9 @@ import android.widget.ListView;
 import android.widget.SimpleAdapter;
 import android.widget.Toast;
 import de.tudarmstadt.informatik.hostage.R;
-import de.tudarmstadt.informatik.hostage.logging.DatabaseHandler;
 import de.tudarmstadt.informatik.hostage.logging.Record;
 import de.tudarmstadt.informatik.hostage.logging.Record.TYPE;
+import de.tudarmstadt.informatik.hostage.logging.UglyDbHelper;
 import de.tudarmstadt.informatik.hostage.ui.LogFilter;
 import de.tudarmstadt.informatik.hostage.ui.LogFilter.SortType;
 import de.tudarmstadt.informatik.hostage.ui2.dialog.ChecklistDialog;
@@ -52,7 +52,7 @@ public class RecordOverviewFragment extends Fragment implements ChecklistDialog.
 	private LogFilter filter;
 	private ListView listView;
 	private boolean showFilterButton;
-	DatabaseHandler dbh;
+	UglyDbHelper dbh;
 	
 	
     public RecordOverviewFragment(){}
@@ -66,7 +66,7 @@ public class RecordOverviewFragment extends Fragment implements ChecklistDialog.
              Bundle savedInstanceState) {
 
 		
-		dbh = new DatabaseHandler(this.getActivity().getBaseContext());
+		dbh = new UglyDbHelper(this.getActivity().getBaseContext());
 	    // Get the message from the intent
 	    Intent intent = this.getActivity().getIntent();
 	    LogFilter filter = intent.getParcelableExtra(LogFilter.LOG_FILTER_INTENT_KEY);
@@ -107,8 +107,8 @@ public class RecordOverviewFragment extends Fragment implements ChecklistDialog.
 
 		for (Record val : data) {
 			HashMap<String, String> map = new HashMap<String, String>();
-			map.put(this.getString(R.string.RecordBSSID), val.getBSSID());
-			map.put(this.getString(R.string.RecordSSID), val.getSSID());
+			map.put(this.getString(R.string.RecordBSSID), val.getBssid());
+			map.put(this.getString(R.string.RecordSSID), val.getSsid());
 			map.put(this.getString(R.string.RecordProtocol), val.getProtocol());
 			map.put(this.getString(R.string.RecordTimestamp),
 					this.getDateAsString(val.getTimestamp()));
@@ -137,7 +137,7 @@ public class RecordOverviewFragment extends Fragment implements ChecklistDialog.
 		mylist.setOnItemClickListener(new AdapterView.OnItemClickListener() {
 			public void onItemClick(AdapterView<?> parent, View viewClicked,
 					int position, long idInDB) {
-				DatabaseHandler dbh = new DatabaseHandler(getBaseContext());
+				UglyDbHelper dbh = new UglyDbHelper(getBaseContext());
 				Record rec = dbh.getRecord((int) idInDB);
 				String message = createInformationStringFromRecord(rec);
 				Toast.makeText(getApplicationContext(), message,
@@ -152,7 +152,7 @@ public class RecordOverviewFragment extends Fragment implements ChecklistDialog.
 						+ "localIP: " + rec.getLocalIP() + "\n"
 						+ "local port: " + rec.getLocalPort() + "\n"
 						+ "remoteIP: " + rec.getRemoteIP() + "\n" + "BSSID: "
-						+ rec.getBSSID() + "\n" + "SSID: " + rec.getSSID()
+						+ rec.getBssid() + "\n" + "SSID: " + rec.getSsid()
 						+ "\n" + "latitude: " + rec.getLatitude() + "\n"
 						+ "longitude: " + rec.getLongitude() + "\n"
 						+ "accuracy: " + rec.getAccuracy() + "\n" + "packet: "
@@ -405,8 +405,8 @@ public class RecordOverviewFragment extends Fragment implements ChecklistDialog.
 		int numberofRecords = (int) (Math.random() * (50 - 10));
 		for (int i = 0; i < numberofRecords; i++) {
 			Record record = new Record();
-			record.setBSSID("BSSID: " + i);
-			record.setSSID("SSID: w" + i);
+			record.setBssid("BSSID: " + i);
+			record.setSsid("SSID: w" + i);
 			record.setTimestamp(cal.getTimeInMillis()
 					+ ((i * 60 * 60 * 60 * 24) * 1000));
 
@@ -417,16 +417,9 @@ public class RecordOverviewFragment extends Fragment implements ChecklistDialog.
 			record.setProtocol(protocolName);
 			record.setId(i);
 			record.setAttack_id(i);
-			try {
-				InetAddress localIP = InetAddress.getByAddress("Digga",
-						new byte[] { 127, 0, 0, 1 }); // .getByName("192.168.2.1");
-				record.setLocalIP(localIP);
-				record.setRemoteIP(InetAddress.getByAddress("Digga",
-						new byte[] { 127, 1, 1, 1 }));
-				record.setType(TYPE.SEND);
-			} catch (UnknownHostException e) {
-				e.printStackTrace();
-			}
+
+			record.setLocalIP("127.0.0.1");
+			record.setType(TYPE.SEND);
 
 			dbh.addRecord(record);
 		}

+ 0 - 55
src/de/tudarmstadt/informatik/hostage/wrapper/ByteArray.java

@@ -1,55 +0,0 @@
-package de.tudarmstadt.informatik.hostage.wrapper;
-/**
- * Wrapper class to use a byte array as an Object.
- * @author Mihai Plasoianu 
- *
- */
-public class ByteArray {
-
-	private final byte[] array;
-
-	/**
-	 * Constructor without parameters. Sets the internal array to null.
-	 */
-	public ByteArray() {
-		this.array = null;
-	}
-
-	/**
-	 * Constructor with a byte arrays as parameter. Sets the internal array to the given.
-	 * @param array The byte array that should be wrapped.
-	 */
-	public ByteArray(byte[] array) {
-		this.array = array;
-	}
-	
-	/**
-	 * Constructor with a String as parameter. Sets the internal array to a byte array representation of the string.
-	 * @param string
-	 */
-	public ByteArray(String string) {
-		this.array = string.getBytes();
-	}
-
-	/**
-	 * Returns the byte array.
-	 * @return The byte array
-	 */
-	public byte[] get() {
-		return array;
-	}
-
-	/**
-	 * Determines size of the array.
-	 * @return Size of the array
-	 */
-	public int size() {
-		return array.length;
-	}
-
-	@Override
-	public String toString() {
-		return new String(array);
-	}
-
-}

+ 91 - 0
src/de/tudarmstadt/informatik/hostage/wrapper/Packet.java

@@ -0,0 +1,91 @@
+package de.tudarmstadt.informatik.hostage.wrapper;
+
+import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
+
+/**
+ * Wrapper class for IO content.
+ * @author Wulf Pfeiffer
+ */
+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;
+	}
+
+	/**
+	 * Returns the message value as byte[].
+	 * @return message value
+	 */
+	public byte[] getMessage() {
+		return message;
+	}
+
+	/**
+	 * 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.
+	 */
+	public Class<? extends Object> getType() {
+		if (isStringMsg) {
+			return String.class;
+		} else if (isByteMsg){
+			return byte[].class;
+		} else {
+			return null;
+		}
+	}
+
+	/**
+	 * 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.
+	 */
+	public boolean isOfType(Class<? extends Object> type) {
+		return getType().equals(type);
+	}
+
+	/**
+	 * 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[].
+	 */
+	@Override
+	public String toString() {
+		if (isStringMsg) {
+			return new String((byte[]) message);
+		} else if (isByteMsg) {
+			return HelperUtils.bytesToHexString((byte[]) message);
+		} else {
+			return null;
+		}
+	}
+
+}