Browse Source

Merge branch 'master' of https://git.tk.informatik.tu-darmstadt.de/scm-ssi-student-hostagev2

Conflicts:
	src/de/tudarmstadt/informatik/hostage/ui/ViewLogTable.java
	src/de/tudarmstadt/informatik/hostage/ui2/fragment/RecordOverviewFragment.java
Julien Clauter 10 years ago
parent
commit
660f994587
100 changed files with 6279 additions and 4060 deletions
  1. 1 0
      .classpath
  2. 5 1
      .gitignore
  3. 0 33
      .project
  4. 12 5
      .settings/org.eclipse.jdt.core.prefs
  5. 0 4
      .settings/org.eclipse.m2e.core.prefs
  6. 32 2
      AndroidManifest.xml
  7. BIN
      assets/meshes/android.amh
  8. BIN
      assets/p
  9. 54 0
      build.gradle
  10. BIN
      libs/sshlib-v1.1.jar
  11. BIN
      libs/swipelistview-1.0.jar
  12. 4 0
      lint.xml
  13. 1 1
      native/Makefile
  14. BIN
      native/p
  15. 7 1
      native/p.c
  16. BIN
      native/p.o
  17. 40 1
      pom.xml
  18. 2 0
      project.properties
  19. BIN
      res/drawable-hdpi/ic_discard.png
  20. BIN
      res/drawable-hdpi/ic_edit.png
  21. BIN
      res/drawable-hdpi/ic_launcher.png
  22. BIN
      res/drawable-mdpi/ic_discard.png
  23. BIN
      res/drawable-mdpi/ic_edit.png
  24. BIN
      res/drawable-mdpi/ic_launcher.png
  25. BIN
      res/drawable-xhdpi/ic_discard.png
  26. BIN
      res/drawable-xhdpi/ic_edit.png
  27. BIN
      res/drawable-xhdpi/ic_launcher.png
  28. BIN
      res/drawable-xxhdpi/ic_launcher.png
  29. BIN
      res/drawable-xxxhdpi/ic_launcher.png
  30. 14 0
      res/drawable/panel_white_bg.xml
  31. 9 0
      res/layout/activity_edit_profile.xml
  32. 18 11
      res/layout/activity_main.xml
  33. 17 0
      res/layout/activity_nfc.xml
  34. 52 0
      res/layout/activity_playground.xml
  35. 5 5
      res/layout/activity_viewlog.xml
  36. 9 3
      res/layout/fragment_profile_manager.xml
  37. 117 0
      res/layout/fragment_services.xml
  38. 1 1
      res/layout/list_view_protocols_row.xml
  39. 148 59
      res/layout/profile_manager_list_item.xml
  40. 66 0
      res/layout/services_list_item.xml
  41. 2 2
      res/menu/main.xml
  42. 49 0
      res/values/attrs.xml
  43. 2 0
      res/values/protocols.xml
  44. 5 3
      res/values/strings.xml
  45. 11 0
      res/values/strings_broadcast.xml
  46. 13 0
      res/values/strings_connection_info.xml
  47. 31 0
      res/values/strings_gui.xml
  48. 6 1
      res/values/strings_preferences.xml
  49. 13 1
      res/xml/preferences.xml
  50. 251 0
      src/de/tudarmstadt/informatik/hostage/HoneyHandler.java
  51. 42 55
      src/de/tudarmstadt/informatik/hostage/HoneyListener.java
  52. 426 181
      src/de/tudarmstadt/informatik/hostage/HoneyService.java
  53. 160 47
      src/de/tudarmstadt/informatik/hostage/commons/HelperUtils.java
  54. 0 14
      src/de/tudarmstadt/informatik/hostage/format/DefaultFormatter.java
  55. 0 46
      src/de/tudarmstadt/informatik/hostage/format/LogViewFormatter.java
  56. 0 64
      src/de/tudarmstadt/informatik/hostage/format/MySQLFormatter.java
  57. 0 17
      src/de/tudarmstadt/informatik/hostage/format/ProtocolFormatter.java
  58. 0 135
      src/de/tudarmstadt/informatik/hostage/format/SMBFormatter.java
  59. 0 169
      src/de/tudarmstadt/informatik/hostage/format/TELNETFormatter.java
  60. 0 156
      src/de/tudarmstadt/informatik/hostage/handler/AbstractHandler.java
  61. 0 69
      src/de/tudarmstadt/informatik/hostage/handler/ByteArrayHandler.java
  62. 0 59
      src/de/tudarmstadt/informatik/hostage/handler/StringHandler.java
  63. 8 7
      src/de/tudarmstadt/informatik/hostage/io/ByteArrayReaderWriter.java
  64. 6 5
      src/de/tudarmstadt/informatik/hostage/io/ReaderWriter.java
  65. 9 6
      src/de/tudarmstadt/informatik/hostage/io/StringReaderWriter.java
  66. 0 645
      src/de/tudarmstadt/informatik/hostage/logging/DatabaseHandler.java
  67. 30 0
      src/de/tudarmstadt/informatik/hostage/logging/LogResultReceiver.java
  68. 311 80
      src/de/tudarmstadt/informatik/hostage/logging/Logger.java
  69. 38 10
      src/de/tudarmstadt/informatik/hostage/logging/MyLocationManager.java
  70. 162 168
      src/de/tudarmstadt/informatik/hostage/logging/Record.java
  71. 0 89
      src/de/tudarmstadt/informatik/hostage/logging/SQLLogger.java
  72. 798 0
      src/de/tudarmstadt/informatik/hostage/logging/UglyDbHelper.java
  73. 28 0
      src/de/tudarmstadt/informatik/hostage/logging/formatter/DefaultFormatter.java
  74. 23 0
      src/de/tudarmstadt/informatik/hostage/logging/formatter/Formatter.java
  75. 25 0
      src/de/tudarmstadt/informatik/hostage/logging/formatter/TraCINgFormatter.java
  76. 103 0
      src/de/tudarmstadt/informatik/hostage/logging/formatter/protocol/MySQL.java
  77. 45 0
      src/de/tudarmstadt/informatik/hostage/logging/formatter/protocol/ProtocolFormatter.java
  78. 225 0
      src/de/tudarmstadt/informatik/hostage/logging/formatter/protocol/SMB.java
  79. 149 0
      src/de/tudarmstadt/informatik/hostage/logging/formatter/protocol/TELNET.java
  80. 21 11
      src/de/tudarmstadt/informatik/hostage/net/MyServerSocketFactory.java
  81. 20 20
      src/de/tudarmstadt/informatik/hostage/protocol/ECHO.java
  82. 48 39
      src/de/tudarmstadt/informatik/hostage/protocol/FTP.java
  83. 96 0
      src/de/tudarmstadt/informatik/hostage/protocol/GhostProtocol.java
  84. 115 64
      src/de/tudarmstadt/informatik/hostage/protocol/HTTP.java
  85. 24 139
      src/de/tudarmstadt/informatik/hostage/protocol/HTTPS.java
  86. 111 75
      src/de/tudarmstadt/informatik/hostage/protocol/MySQL.java
  87. 10 8
      src/de/tudarmstadt/informatik/hostage/protocol/Protocol.java
  88. 41 0
      src/de/tudarmstadt/informatik/hostage/protocol/SIP.java
  89. 599 483
      src/de/tudarmstadt/informatik/hostage/protocol/SMB.java
  90. 490 306
      src/de/tudarmstadt/informatik/hostage/protocol/SSH.java
  91. 1 2
      src/de/tudarmstadt/informatik/hostage/protocol/SSLProtocol.java
  92. 69 71
      src/de/tudarmstadt/informatik/hostage/protocol/TELNET.java
  93. 275 0
      src/de/tudarmstadt/informatik/hostage/sync/BluetoothSync.java
  94. 182 0
      src/de/tudarmstadt/informatik/hostage/sync/NFCSync.java
  95. 4 0
      src/de/tudarmstadt/informatik/hostage/ui/ListViewAdapter.java
  96. 244 284
      src/de/tudarmstadt/informatik/hostage/ui/MainActivity.java
  97. 96 0
      src/de/tudarmstadt/informatik/hostage/ui/PlayGroundActivity.java
  98. 34 0
      src/de/tudarmstadt/informatik/hostage/ui/SettingsActivity.java
  99. 199 162
      src/de/tudarmstadt/informatik/hostage/ui/ViewLog.java
  100. 15 240
      src/de/tudarmstadt/informatik/hostage/ui/ViewLogTable.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>

+ 5 - 1
.gitignore

@@ -24,5 +24,9 @@ proguard/
 *.iws
 .idea/
 
-#Ignore target folder
+#Ignore some folders
 target/
+build/
+.gradle/
+gen-external-apklibs/
+

+ 0 - 33
.project

@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>hostage</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>com.android.ide.eclipse.adt.ApkBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>

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

@@ -1,5 +1,12 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
-org.eclipse.jdt.core.compiler.compliance=1.5
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.source=1.5
+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

+ 0 - 4
.settings/org.eclipse.m2e.core.prefs

@@ -1,4 +0,0 @@
-activeProfiles=
-eclipse.preferences.version=1
-resolveWorkspaceProjects=true
-version=1

+ 32 - 2
AndroidManifest.xml

@@ -18,13 +18,22 @@
     
     <!-- 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"
         android:icon="@drawable/ic_launcher"
         android:label="@string/app_name"
         android:theme="@style/AppTheme"
-        android:debuggable="true" >
+        android:debuggable="true"
+        android:installLocation="preferExternal">
         <activity
             android:name="de.tudarmstadt.informatik.hostage.ui2.activity.MainActivity"
             android:configChanges="keyboardHidden|orientation|screenSize"
@@ -36,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"
@@ -49,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/meshes/android.amh


BIN
assets/p


+ 54 - 0
build.gradle

@@ -0,0 +1,54 @@
+buildscript {
+    repositories {
+        mavenCentral()
+    }
+    dependencies {
+        classpath 'com.android.tools.build:gradle:0.8.+'
+    }
+}
+apply plugin: 'android'
+
+repositories {
+    mavenCentral()
+    maven {
+        url 'https://oss.sonatype.org/content/groups/public'
+    }
+}
+
+dependencies {
+    //compile fileTree(dir: 'libs', include: '*.jar')
+	compile 'com.google.android.gms:play-services:3.2.+'
+	compile 'org.roboguice:roboguice:2.0'
+    compile 'com.nineoldandroids:library:2.4.0+'
+    compile files('libs/swipelistview-1.0.jar')
+    compile files('libs/sshlib-v1.1.jar')
+}
+
+android {
+    compileSdkVersion 19
+    buildToolsVersion "19.0.0"
+
+    sourceSets {
+        main {
+            manifest.srcFile 'AndroidManifest.xml'
+            java.srcDirs = ['src']
+            resources.srcDirs = ['src']
+            aidl.srcDirs = ['src']
+            renderscript.srcDirs = ['src']
+            res.srcDirs = ['res']
+            assets.srcDirs = ['assets']
+        }
+
+        // Move the tests to tests/java, tests/res, etc...
+        instrumentTest.setRoot('tests')
+
+        // Move the build types to build-types/<type>
+        // For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ...
+        // This moves them out of them default location under src/<type>/... which would
+        // conflict with src/ being used by the main source set.
+        // Adding new build types or product flavors should be accompanied
+        // by a similar customization.
+        debug.setRoot('build-types/debug')
+        release.setRoot('build-types/release')
+    }
+}

BIN
libs/sshlib-v1.1.jar


BIN
libs/swipelistview-1.0.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


+ 40 - 1
pom.xml

@@ -54,7 +54,30 @@
 			<artifactId>roboguice</artifactId>
 			<version>2.0</version>
 		</dependency>
-	</dependencies>
+        <dependency>
+            <groupId>com.nineoldandroids</groupId>
+            <artifactId>library</artifactId>
+            <version>2.4.0</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fortysevendeg.android</groupId>
+            <artifactId>swipelistview</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <type>apklib</type>
+        </dependency>
+		<dependency>
+			<groupId>com.google.android.gms</groupId>
+			<artifactId>google-play-services</artifactId>
+			<version>14.0.0</version>
+			<type>apklib</type>
+		</dependency>
+		<dependency>
+			<groupId>com.google.android.gms</groupId>
+			<artifactId>google-play-services</artifactId>
+			<version>14.0.0</version>
+			<type>jar</type>
+		</dependency>
+    </dependencies>
 	<build>
 		<finalName>${project.artifactId}</finalName>
 		<sourceDirectory>src</sourceDirectory>
@@ -110,4 +133,20 @@
 			</plugin>
 		</plugins>
 	</build>
+    <repositories>
+        <repository>
+            <id>sonatype</id>
+            <url>https://oss.sonatype.org/content/groups/public/</url>
+            <releases>
+                <enabled>true</enabled>
+                <updatePolicy>daily</updatePolicy>
+                <checksumPolicy>fail</checksumPolicy>
+            </releases>
+            <snapshots>
+                <enabled>true</enabled>
+                <updatePolicy>always</updatePolicy>
+                <checksumPolicy>ignore</checksumPolicy>
+            </snapshots>
+        </repository>
+    </repositories>
 </project>

+ 2 - 0
project.properties

@@ -13,3 +13,5 @@
 # Project target.
 target=android-19
 android.library=false
+
+

BIN
res/drawable-hdpi/ic_discard.png


BIN
res/drawable-hdpi/ic_edit.png


BIN
res/drawable-hdpi/ic_launcher.png


BIN
res/drawable-mdpi/ic_discard.png


BIN
res/drawable-mdpi/ic_edit.png


BIN
res/drawable-mdpi/ic_launcher.png


BIN
res/drawable-xhdpi/ic_discard.png


BIN
res/drawable-xhdpi/ic_edit.png


BIN
res/drawable-xhdpi/ic_launcher.png


BIN
res/drawable-xxhdpi/ic_launcher.png


BIN
res/drawable-xxxhdpi/ic_launcher.png


+ 14 - 0
res/drawable/panel_white_bg.xml

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <!-- Bottom 3dp Shadow -->
+    <item>
+        <shape android:shape="rectangle">
+
+            <solid android:color="#FFFFFF" />
+            <corners android:radius="4dp" />
+
+        </shape>
+    </item>
+
+</layer-list>

+ 9 - 0
res/layout/activity_edit_profile.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:padding="10dip"
+              android:layout_width="fill_parent"
+              android:layout_height="wrap_content">
+</LinearLayout>

+ 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>

+ 9 - 3
res/layout/fragment_profile_manager.xml

@@ -7,10 +7,10 @@
     android:layout_height="fill_parent"
     android:id="@+id/profile_manager_root_view">
 
-    <ListView
+    <com.fortysevendeg.android.swipelistview.SwipeListView
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:swipe="http://schemas.android.com/apk/res-auto"
         android:id="@+id/profile_manager_listview"
         android:choiceMode="singleChoice"
         android:background="#F2F2F2"
@@ -20,6 +20,12 @@
         android:layout_alignParentLeft="true"
         android:layout_marginLeft="0dp"
         android:layout_alignParentTop="true"
-        android:layout_marginTop="0dp" />
+        android:layout_marginTop="0dp"
+        android:descendantFocusability="blocksDescendants"
+        swipeFrontView="@+id/swipelist_frontview"
+        swipeBackView="@+id/swipelist_backview"
+        swipe:swipeFrontView="@+id/swipelist_frontview"
+        swipe:swipeBackView="@+id/swipelist_backview"
+        swipe:swipeMode="both"/>
 
 </RelativeLayout>

+ 117 - 0
res/layout/fragment_services.xml

@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+        <TextView
+                android:id="@+id/textView"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentEnd="true"
+                android:layout_alignParentLeft="true"
+                android:layout_alignParentRight="false"
+                android:layout_marginLeft="15dp"
+                android:layout_marginTop="20dp"
+                android:layout_weight="1"
+                android:text="Current connection"
+                android:textSize="18dp"
+                android:textStyle="bold" />
+
+        <ImageView
+                android:id="@+id/imageView2"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentEnd="true"
+                android:layout_alignParentRight="true"
+                android:layout_alignParentTop="true"
+                android:layout_marginTop="5dp"
+                android:layout_marginRight="12dp"
+                android:src="@android:drawable/ic_menu_info_details" />
+    </RelativeLayout>
+
+    <View
+            android:layout_width="fill_parent"
+            android:layout_height="1dp"
+            android:layout_marginLeft="15dp"
+            android:layout_marginRight="15dp"
+            android:background="@android:color/darker_gray" />
+    <RelativeLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" >
+
+        <TextView
+                android:id="@+id/services_text_name"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentTop="true"
+                android:layout_centerHorizontal="true"
+                android:layout_gravity="center_horizontal"
+                android:layout_marginTop="21dp"
+                android:text="Eduroam"
+                android:textAppearance="?android:attr/textAppearanceLarge"
+                android:textSize="26sp" />
+
+    </RelativeLayout>
+
+    <RelativeLayout
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:baselineAligned="false"
+            android:orientation="horizontal"
+            android:weightSum="1" >
+
+        <TextView
+                android:id="@+id/textView"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentEnd="true"
+                android:layout_alignParentLeft="true"
+                android:layout_alignParentRight="false"
+                android:layout_marginLeft="15dp"
+                android:layout_marginTop="35dp"
+                android:layout_weight="1"
+                android:text="Monitor services"
+                android:textStyle="bold"
+                android:textSize="20dp"/>
+
+        <Switch
+                android:id="@+id/service_switch_connection"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentBottom="false"
+                android:layout_alignParentEnd="false"
+                android:layout_alignParentLeft="false"
+                android:layout_alignParentRight="true"
+                android:layout_alignParentTop="false"
+                android:layout_gravity="right"
+                android:layout_marginLeft="0dp"
+                android:layout_marginRight="15dp"
+                android:layout_marginTop="30dp"
+                android:layout_marginBottom="0dp"
+                android:layout_weight="1"
+                android:checked="false"
+                android:textSize="10dp" />
+
+    </RelativeLayout>
+
+    <View
+            android:layout_width="fill_parent"
+            android:layout_height="1dp"
+            android:layout_marginLeft="15dp"
+            android:layout_marginRight="15dp"
+            android:background="@android:color/darker_gray" />
+
+    <ListView android:layout_width="fill_parent"
+              android:layout_height="wrap_content"
+              android:id="@+id/services_list_view"
+            >
+
+
+    </ListView>
+
+</LinearLayout>

+ 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

+ 148 - 59
res/layout/profile_manager_list_item.xml

@@ -1,62 +1,151 @@
 <?xml version="1.0" encoding="utf-8"?>
 
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:padding="5dp"
-    android:baselineAligned="false"
-    android:background="@drawable/panel_bg">
-
-    <TextView
-        android:id="@+id/profile_manager_item_label"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:textAppearance="?android:attr/textAppearanceListItemSmall"
-        android:gravity="center_vertical"
-        android:paddingLeft="16dp"
-        android:paddingRight="16dp"
-        android:textColor="?android:attr/colorForeground"
-        android:minHeight="?android:attr/listPreferredItemHeightSmall"
-        android:text="Sample title"
-        android:layout_alignParentTop="true"
-        android:layout_toRightOf="@+id/profile_manager_item_image" />
-
-    <TextView
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="wrap_content"
+              android:layout_height="wrap_content">
+
+    <RelativeLayout
+        android:id="@+id/swipelist_backview"
+        android:orientation="horizontal"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:text="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet."
-        android:id="@+id/profile_manager_item_text"
-        android:paddingLeft="16dp"
-        android:paddingRight="16dp"
-        android:paddingBottom="16dp"
-        android:textColor="#808080"
-        android:visibility="visible"
-        android:singleLine="false"
-        android:phoneNumber="true"
-        android:layout_toLeftOf="@+id/profile_manager_item_activated"
-        android:layout_alignParentLeft="true"
-        android:layout_alignParentStart="true"
-        android:layout_below="@+id/profile_manager_item_label"
-        android:paddingTop="10dp" />
-
-    <ImageView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:id="@+id/profile_manager_item_activated"
-        android:src="@drawable/ic_action_accept"
-        android:layout_centerVertical="true"
-        android:layout_alignParentRight="true"
-        android:layout_alignParentEnd="true"
-        android:layout_marginRight="20dp"
-        android:visibility="visible" />
-
-    <ImageView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:id="@+id/profile_manager_item_image"
-        android:src="@drawable/ic_launcher"
-        android:layout_above="@+id/profile_manager_item_text"
-        android:layout_alignParentLeft="true"
-        android:layout_alignParentStart="true" />
-
-</RelativeLayout>
+        android:layout_height="match_parent"
+        android:background="@drawable/panel_white_bg"
+        android:focusable="false">
+
+        <LinearLayout
+            android:orientation="horizontal"
+            android:layout_width="fill_parent"
+            android:layout_height="fill_parent"
+            android:focusable="false"
+            android:layout_below="@+id/profile_manager_item_image_back">
+
+            <ImageButton
+                android:layout_width="0dp"
+                android:layout_height="match_parent"
+                android:text="Edit"
+                android:id="@+id/profile_manager_item_button_edit"
+                android:layout_weight="1"
+                style="@android:style/DeviceDefault.Light.ButtonBar"
+                android:focusable="false"
+                android:layout_alignParentTop="true"
+                android:layout_alignParentLeft="true"
+                android:layout_alignParentStart="true"
+                android:src="@drawable/ic_edit"/>
+            <View
+                android:layout_width="1dp"
+                android:layout_height="match_parent"
+                android:background="@color/light_grey"
+                android:layout_marginTop="10dp"
+                android:layout_marginBottom="10dp"/>
+
+            <ImageButton
+                android:layout_width="0dp"
+                android:layout_height="match_parent"
+                android:text="Delete"
+                android:id="@+id/profile_manager_item_button_delete"
+                android:layout_alignParentTop="true"
+                android:layout_alignParentRight="true"
+                android:layout_alignParentEnd="true"
+                android:layout_weight="1"
+                style="@android:style/DeviceDefault.Light.ButtonBar"
+                android:focusable="false"
+                android:layout_marginTop="0dp"
+                android:src="@drawable/ic_discard"/>
+        </LinearLayout>
+
+        <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:id="@+id/profile_manager_item_image_back"
+            android:src="@drawable/ic_launcher"
+            android:layout_toLeftOf="@+id/profile_manager_item_label_back"
+            android:layout_alignBottom="@+id/profile_manager_item_label_back"
+            android:layout_alignParentTop="true"
+            android:paddingLeft="15dp"
+            android:paddingTop="15dp"
+            android:paddingBottom="15dp"
+            android:paddingRight="-10dp"/>
+
+        <TextView
+            android:id="@+id/profile_manager_item_label_back"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="center_vertical"
+            android:paddingLeft="0dp"
+            android:paddingRight="0dp"
+            android:textColor="?android:attr/colorForeground"
+            android:minHeight="?android:attr/listPreferredItemHeightSmall"
+            android:text="Sample title"
+            android:background="@android:color/transparent"
+            android:singleLine="true"
+            android:layout_alignParentLeft="false"
+            android:textAlignment="center"
+            android:layout_centerHorizontal="true"
+            android:textSize="8sp"
+            android:layout_alignParentTop="true"/>
+
+    </RelativeLayout>
+
+    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                    android:id="@+id/swipelist_frontview"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:padding="5dp"
+                    android:baselineAligned="false"
+                    android:background="@drawable/panel_bg"
+                    android:focusable="false">
+
+        <TextView
+            android:id="@+id/profile_manager_item_label"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceListItemSmall"
+            android:gravity="center_vertical"
+            android:paddingLeft="16dp"
+            android:paddingRight="16dp"
+            android:textColor="?android:attr/colorForeground"
+            android:minHeight="?android:attr/listPreferredItemHeightSmall"
+            android:text="Sample title"
+            android:layout_alignParentTop="true"
+            android:layout_toRightOf="@+id/profile_manager_item_image" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet."
+            android:id="@+id/profile_manager_item_text"
+            android:paddingLeft="16dp"
+            android:paddingRight="16dp"
+            android:paddingBottom="16dp"
+            android:textColor="#808080"
+            android:visibility="visible"
+            android:singleLine="false"
+            android:layout_alignParentLeft="true"
+            android:layout_alignParentStart="true"
+            android:layout_below="@+id/profile_manager_item_label"
+            android:paddingTop="10dp"
+            android:layout_toLeftOf="@+id/profile_manager_item_activated"/>
+
+        <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:id="@+id/profile_manager_item_activated"
+            android:src="@drawable/ic_action_accept"
+            android:layout_centerVertical="true"
+            android:layout_alignParentRight="true"
+            android:layout_alignParentEnd="true"
+            android:layout_marginRight="20dp"
+            android:visibility="visible"
+            android:layout_marginLeft="20dp"/>
+
+        <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:id="@+id/profile_manager_item_image"
+            android:src="@drawable/ic_launcher"
+            android:layout_above="@+id/profile_manager_item_text"
+            android:layout_alignParentLeft="true"
+            android:layout_alignParentStart="true" />
+
+    </RelativeLayout>
+</FrameLayout>

+ 66 - 0
res/layout/services_list_item.xml

@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+    <RelativeLayout android:layout_width="fill_parent"
+                    android:layout_height="wrap_content"
+                    android:baselineAligned="false"
+                    android:orientation="horizontal"
+                    android:weightSum="1" >
+        <TextView
+                android:id="@+id/services_item_name"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentEnd="true"
+                android:layout_alignParentLeft="true"
+                android:layout_alignParentRight="false"
+                android:layout_marginLeft="50dp"
+                android:layout_marginTop="5dp"
+                android:layout_weight="1"
+                android:text="SSH"
+                android:textStyle="bold"
+                android:textSize="16dp"/>
+        <TextView
+                android:id="@+id/services_item_rec_attacks"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentEnd="true"
+                android:layout_alignParentLeft="true"
+                android:layout_alignParentRight="false"
+                android:layout_marginLeft="50dp"
+                android:layout_marginTop="25dp"
+                android:layout_weight="1"
+                android:text="recorded attacks: 20"
+                android:textStyle="bold"
+                android:textSize="12dp"/>
+        <Switch
+                android:id="@+id/services_item_switch"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentBottom="false"
+                android:layout_alignParentEnd="false"
+                android:layout_alignParentLeft="false"
+                android:layout_alignParentRight="true"
+                android:layout_alignParentTop="false"
+                android:layout_gravity="right"
+                android:layout_marginLeft="0dp"
+                android:layout_marginRight="15dp"
+                android:layout_marginTop="10dp"
+                android:layout_marginBottom="0dp"
+                android:layout_weight="1"
+                android:checked="false"
+                android:textSize="10dp" />
+    </RelativeLayout>
+
+    <View
+            android:layout_width="fill_parent"
+            android:layout_height="1dp"
+            android:layout_marginLeft="15dp"
+            android:layout_marginRight="15dp"
+            android:background="@android:color/darker_gray" />
+
+
+</LinearLayout>

+ 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>

+ 49 - 0
res/values/attrs.xml

@@ -0,0 +1,49 @@
+<!--
+  ~ Copyright (C) 2013 47 Degrees, LLC
+  ~ http://47deg.com
+  ~ hello@47deg.com
+  ~
+  ~ 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.
+  -->
+
+<resources>
+
+    <declare-styleable name="SwipeListView">
+        <attr name="swipeOpenOnLongPress" format="boolean"/>
+        <attr name="swipeAnimationTime" format="integer"/>
+        <attr name="swipeOffsetLeft" format="dimension"/>
+        <attr name="swipeOffsetRight" format="dimension"/>
+        <attr name="swipeCloseAllItemsWhenMoveList" format="boolean"/>
+        <attr name="swipeFrontView" format="reference"/>
+        <attr name="swipeBackView" format="reference"/>
+        <attr name="swipeMode" format="enum">
+            <enum name="none" value="0"/>
+            <enum name="both" value="1"/>
+            <enum name="right" value="2"/>
+            <enum name="left" value="3"/>
+        </attr>
+        <attr name="swipeActionLeft" format="enum">
+            <enum name="reveal" value="0"/>
+            <enum name="dismiss" value="1"/>
+            <enum name="choice" value="2"/>
+        </attr>
+        <attr name="swipeActionRight" format="enum">
+            <enum name="reveal" value="0"/>
+            <enum name="dismiss" value="1"/>
+            <enum name="choice" value="2"/>
+        </attr>
+        <attr name="swipeDrawableChecked" format="reference"/>
+        <attr name="swipeDrawableUnchecked" format="reference"/>
+    </declare-styleable>
+
+</resources>

+ 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 = 2;
+
+	// 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);
 	}
 
 }

Some files were not shown because too many files changed in this diff