Browse Source

-Automated Portbinder installation
--Auto selection of architecture and download of Portbinder
--Decompressing of the compressed file + chmod'ding
--Update the variable checking after a successful installation

Shankar Karuppayah 10 years ago
parent
commit
4666aaa5eb

+ 3 - 3
res/values/strings.xml

@@ -28,11 +28,11 @@
     <string name="help">How?</string>
     <string name="portbinder">Portbinder</string>
     <string name="portbinder_tutorial">Video Tutorial</string>
-    <string name="portbinder_website">Visit Official Website</string>
-    <string name="helpPortbinder">You can compile the \'Portbinder\' yourself from source, i.e., located in the folder \'native\', or download some precompiled binaries (with your own risk) based on the architecture of your device, e.g., ARM, from our website. \n\nPlease also check the video tutorial on how to install \'Portbinder\' in your device.</string>
+    <string name="portbinder_website">Visit Website</string>
+    <string name="helpPortbinder">You can compile the \'Portbinder\' yourself from source, i.e., located in the folder \'native\', or download some precompiled binaries (with your own risk) based on the architecture of your device, e.g., ARM, x86, or MIPS, from our website. (Please also check the video tutorial on how to install \'Portbinder\' in your device.)\n\nAlternatively, you can use the automated installer by pressing the \'Just Help Me!\' button.</string>
+    <string name="help_me">Just Help Me!</string>
 
 	<string name="profile_needs_name">An profile needs a name. Please type in a name and press save again.</string>
-
     <string name="monitor_current_connection">Monitor current connection</string>
     <string name="active_profile">Active profile: </string>
 

+ 0 - 5
res/values/strings_preferences.xml

@@ -32,11 +32,6 @@
 	<string name="pref_location_retries_default">3</string>
 	<string name="pref_auto_synchronize_title">Auto Synchronization</string>
 	<string name="pref_auto_synchronize_summ">Enable auto synchronization of log data</string>
-    <string name="pref_portbinder_settings">Portbinder Settings</string>
-    <string name="pref_portbinder_location">Location of Portbinder</string>
-    <string name="pref_portbinder_location_summary">Location of Portbinder binary</string>
-    <string name="pref_portbinder_location_default">/data/local/bind</string>
-
 
 </resources>
 

+ 2 - 4
res/xml/preferences.xml

@@ -61,18 +61,16 @@
             android:defaultValue="@string/pref_sleeptime_default"
             android:title="@string/pref_sleeptime" />
     </PreferenceCategory>
-        <PreferenceCategory android:title="@string/pref_location_settings" >
+    <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
+        <EditTextPreference
             android:key="pref_location_retries"
             android:defaultValue="@string/pref_location_retries_default"
             android:title="@string/pref_location_retries" />
 
     </PreferenceCategory>
-
-
 </PreferenceScreen>

+ 0 - 9
res/xml/settings_preferences.xml

@@ -73,15 +73,6 @@
                     android:defaultValue="@string/pref_location_retries_default"
                     android:title="@string/pref_location_retries" />
 
-            </PreferenceCategory>
-            <PreferenceCategory android:title="@string/pref_portbinder_settings" >
-                <EditTextPreference
-                    android:key="pref_portbinder_location"
-                    android:defaultValue="@string/pref_portbinder_location_default"
-                    android:summary="@string/pref_portbinder_location_summary"
-                    android:title="@string/pref_portbinder_location" />
-
-
             </PreferenceCategory>
 		</PreferenceScreen>
 	</PreferenceCategory>

+ 58 - 0
src/de/tudarmstadt/informatik/hostage/system/Decompress.java

@@ -0,0 +1,58 @@
+package de.tudarmstadt.informatik.hostage.system;
+
+import android.util.Log;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+/**
+ * Created by shankar on 16.05.14.
+ */
+public class Decompress {
+    private String _zipFile;
+    private String _location;
+
+    public Decompress(String zipFile, String location) {
+        _zipFile = zipFile;
+        _location = location;
+
+        _dirChecker("");
+    }
+
+    public void unzip() {
+        try  {
+            FileInputStream fin = new FileInputStream(_zipFile);
+            ZipInputStream zin = new ZipInputStream(fin);
+            ZipEntry ze = null;
+            while ((ze = zin.getNextEntry()) != null) {
+                Log.v("Decompress", "Unzipping " + ze.getName());
+
+                if(ze.isDirectory()) {
+                    _dirChecker(ze.getName());
+                } else {
+                    FileOutputStream fout = new FileOutputStream(_location + ze.getName());
+                    for (int c = zin.read(); c != -1; c = zin.read()) {
+                        fout.write(c);
+                    }
+
+                    zin.closeEntry();
+                    fout.close();
+                }
+
+            }
+            zin.close();
+        } catch(Exception e) {
+            Log.e("Decompress", "unzip", e);
+        }
+
+    }
+
+    private void _dirChecker(String dir) {
+        File f = new File(_location + dir);
+
+        if(!f.isDirectory()) {
+            f.mkdirs();
+        }
+    }
+}

+ 46 - 4
src/de/tudarmstadt/informatik/hostage/system/Device.java

@@ -2,8 +2,16 @@ package de.tudarmstadt.informatik.hostage.system;
 
 import java.io.IOException;
 
+import android.app.Activity;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
 import android.util.Log;
 
+import de.tudarmstadt.informatik.hostage.Hostage;
+import de.tudarmstadt.informatik.hostage.R;
+
+
 public class Device {
 
 	@SuppressWarnings("unused")
@@ -14,14 +22,15 @@ public class Device {
 	private static boolean root = false;
 	private static boolean pp = false;
 
-	private Device() {
-		new Thread(new Runnable() {
+    private Device() {
+
+        new Thread(new Runnable() {
 			@Override
 			public void run() {
 				try {
-					String test = "[ -e /data/local/bind ]";
+                    String portBinder = "[ -e /data/local/bind ]";
 
-					Process su = new ProcessBuilder("su", "-c", test).start();
+					Process su = new ProcessBuilder("su", "-c", portBinder).start();
 					switch (su.waitFor()) {
 					case 0:
 						root = true;
@@ -59,4 +68,37 @@ public class Device {
 		return pp;
 	}
 
+    /**
+     * Called after auto-loading porthack. To update the local variables.
+     */
+
+    public static boolean updatePorthack (){
+        try {
+            String portBinder = "[ -e /data/local/bind ]";
+
+            Process su = new ProcessBuilder("su", "-c", portBinder).start();
+            switch (su.waitFor()) {
+                case 0:
+                    root = true;
+                    pp = true;
+                    break;
+                case 1:
+                    root = true;
+                    pp = false;
+                    break;
+                case 127:
+                    root = false;
+                    pp = false;
+                    break;
+            }
+        } catch (InterruptedException e) {
+        } catch (IOException e) {
+        } finally {
+            initialized = true;
+            Log.d("hostage", "Root: " + Boolean.toString(root));
+            Log.d("hostage", "PP: " + Boolean.toString(pp));
+        }
+        return (pp && root);
+    }
+
 }

+ 5 - 2
src/de/tudarmstadt/informatik/hostage/system/PrivilegedPort.java

@@ -6,10 +6,14 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 
+import android.content.SharedPreferences;
 import android.net.LocalServerSocket;
 import android.net.LocalSocket;
+import android.preference.PreferenceManager;
 import android.util.Log;
 
+import de.tudarmstadt.informatik.hostage.Hostage;
+
 public class PrivilegedPort implements Runnable {
 
 	public static enum TYPE {
@@ -52,9 +56,8 @@ public class PrivilegedPort implements Runnable {
 
 	@Override
 	public void run() {
-        /*@Shankar TODO: Update the location of PortBinder to GUI-Input*/
-		String command = String.format("/data/local/bind %s %d", type.toString(), port);
 
+        String command = String.format("/data/local/bind %s %d", type.toString(), port);
 
 		try {
 			Process p = new ProcessBuilder("su", "-c", command).start();

+ 123 - 7
src/de/tudarmstadt/informatik/hostage/ui2/fragment/SettingsFragment.java

@@ -2,11 +2,16 @@ package de.tudarmstadt.informatik.hostage.ui2.fragment;
 
 import android.app.AlertDialog;
 import android.app.DownloadManager;
+import android.app.DownloadManager.Query;
+import android.app.DownloadManager.Request;
 import android.app.Fragment;
 import android.app.FragmentManager;
+import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
+import android.content.IntentFilter;
+import android.database.Cursor;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Environment;
@@ -14,10 +19,22 @@ import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.ImageView;
 import android.widget.TextView;
 
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.channels.FileChannel;
+import java.util.zip.ZipInputStream;
+
 import de.tudarmstadt.informatik.hostage.Hostage;
 import de.tudarmstadt.informatik.hostage.R;
+import de.tudarmstadt.informatik.hostage.system.Decompress;
 import de.tudarmstadt.informatik.hostage.system.Device;
 import de.tudarmstadt.informatik.hostage.ui2.activity.MainActivity;
 
@@ -32,14 +49,18 @@ public class SettingsFragment extends UpNavigatibleFragment {
 	/**
 	 * {@inheritDoc}
 	 */
-	@Override
-	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+
+    private long enqueue;
+    private DownloadManager dm;
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
 		super.onCreateView(inflater, container, savedInstanceState);
 		getActivity().setTitle(getResources().getString(R.string.drawer_settings));
 		View v = inflater.inflate(R.layout.fragment_settings, container, false);
 
-		TextView rootedText = (TextView) v.findViewById(R.id.settings_device_rooted);
-		TextView porthackText = (TextView) v.findViewById(R.id.settings_porthack_installed);
+		final TextView rootedText = (TextView) v.findViewById(R.id.settings_device_rooted);
+		final TextView porthackText = (TextView) v.findViewById(R.id.settings_porthack_installed);
 
 		if (Device.isRooted()) {
 			rootedText.setText(R.string.yes);
@@ -57,6 +78,72 @@ public class SettingsFragment extends UpNavigatibleFragment {
 			porthackText.setTextColor(getResources().getColor(R.color.holo_red));
 		}
 
+        //Handle if a download 'may' be needed
+        BroadcastReceiver receiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                String action = intent.getAction();
+                if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
+                    long downloadId = intent.getLongExtra(
+                            DownloadManager.EXTRA_DOWNLOAD_ID, 0);
+                    Query query = new Query();
+                    query.setFilterById(enqueue);
+                    Cursor c = dm.query(query);
+                    if (c.moveToFirst()) {
+                        int columnIndex = c
+                                .getColumnIndex(DownloadManager.COLUMN_STATUS);
+                        if (DownloadManager.STATUS_SUCCESSFUL == c
+                                .getInt(columnIndex)) {
+
+                            String downloadFile = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME));
+                            String makeWritable[]= {"su","-c","chmod","777","/data/local"}; //change permission to allow rw access from x only
+                            String allowExec[]= {"su","-c","chmod","711","/data/local/bind"}; //change permission to allow x access
+                            String revert[]= {"su","-c","chmod","751","/data/local"}; //change permission back to x only
+
+                            try {
+                                //Chmod the local directory for write access
+                                Process process = Runtime.getRuntime().exec(makeWritable);
+                                process.waitFor();
+
+                                Log.d("portbinder:","Changing permission on /data/local to allow write access");
+
+                                //Decompressing downloaded zip to local directory
+                                Decompress dwnld = new Decompress(downloadFile,"/data/local/" );
+                                dwnld.unzip();
+                                Log.v("portbinder:","Decompressing downloaded file");
+
+                                //Chmod the Portbinder to allow it to be executable
+                                process = Runtime.getRuntime().exec(allowExec);
+                                process.waitFor();
+                                Log.v("portbinder:","Changing permission on /data/local/bind to allow the binary to be executed");
+
+                                //Chmod the local directory to back to non-read/write access
+                                process = Runtime.getRuntime().exec(revert);
+                                process.waitFor();
+                                Log.v("portbinder:","Changing permission on /data/local back to no-write access");
+
+
+                            } catch (IOException e) {
+                                e.printStackTrace();
+                            } catch (InterruptedException e) {
+                                e.printStackTrace();
+                            }
+
+                            if(Device.updatePorthack()) //if successful
+                            {
+                                porthackText.setText(R.string.yes);
+                                porthackText.setTextColor(getResources().getColor(R.color.holo_dark_green));
+                            }
+
+                        }
+                    }
+                }
+            }
+        };
+
+        getActivity().registerReceiver(receiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
+
+
         //Allow no porthack text box clickable
         if (Device.isRooted() && !Device.isPorthackInstalled())
         {
@@ -86,7 +173,7 @@ public class SettingsFragment extends UpNavigatibleFragment {
 
                                                 }
                                             })
-                                            .setNeutralButton(R.string.portbinder_tutorial, new DialogInterface.OnClickListener() {
+                                            /*.setNeutralButton(R.string.portbinder_tutorial, new DialogInterface.OnClickListener() {
                                                 public void onClick(DialogInterface dialog, int which) {
 
                                                     Uri uri = Uri.parse("https://www.youtube.com/watch?v=gi6fSiIJASk");
@@ -94,7 +181,7 @@ public class SettingsFragment extends UpNavigatibleFragment {
                                                     startActivity(intent);
 
                                                 }
-                                            })
+                                            })*/
                                             .setNegativeButton(R.string.portbinder_website, new DialogInterface.OnClickListener() {
                                                 public void onClick(DialogInterface dialog, int which) {
 
@@ -103,6 +190,36 @@ public class SettingsFragment extends UpNavigatibleFragment {
                                                     startActivity(intent);
 
                                                 }
+                                            })
+                                                    //Testing automated installation of portbinder
+                                            .setNeutralButton(R.string.help_me, new DialogInterface.OnClickListener() {
+                                                public void onClick(DialogInterface dialog, int which) {
+                                                    //Download Portbinder
+                                                    dm = (DownloadManager) getActivity().getSystemService(Context.DOWNLOAD_SERVICE);
+
+                                                    //Identify architecture
+                                                    String arch = System.getProperty("os.arch"); //get the device architecture
+
+                                                    //selecting necessary PortBinder
+                                                    Uri uri = Uri.EMPTY; //initialize variable
+
+                                                    if (arch.matches("arm.*"))      //arm
+                                                        uri = Uri.parse("https://www.tk.informatik.tu-darmstadt.de/fileadmin/user_upload/Group_TK/bind-arm.zip");
+                                                    else if (arch.matches("x86"))   //x86
+                                                        uri = Uri.parse("https://www.tk.informatik.tu-darmstadt.de/fileadmin/user_upload/Group_TK/bind-x86.zip");
+                                                    else if (arch.matches("mips"))  //mips
+                                                        uri = Uri.parse("https://www.tk.informatik.tu-darmstadt.de/fileadmin/user_upload/Group_TK/bind-mips.zip");
+
+                                                    if (uri != Uri.EMPTY) {
+                                                        Request request = new Request(uri)
+                                                                .setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "bind.zip");
+                                                        enqueue = dm.enqueue(request);
+//                                                    dm.enqueue(request);
+                                                    }
+                                                    else {
+                                                        //report to user of an unknown architecture
+                                                    }
+                                                }
                                             })
                                             .setIcon(android.R.drawable.ic_dialog_info).show();
 
@@ -122,7 +239,6 @@ public class SettingsFragment extends UpNavigatibleFragment {
 	public void onViewCreated(View view, Bundle savedInstanceState) {
 		super.onViewCreated(view, savedInstanceState);
 
-
 		FragmentManager manager = this.getFragmentManager();
 		manager.beginTransaction().replace(R.id.settings_fragment_container, new PreferenceHostageFrament()).commit();
 	}