From 37c057006700339ad82a488d402593773b6c5c1f Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Wed, 11 Feb 2015 17:54:41 +0100 Subject: [PATCH 1/5] Use [Ion](https://github.com/koush/ion) for http requests. --- app/app.iml | 6 +- app/build.gradle | 2 + .../tueroeffner/CommandExecuter.java | 63 ------------------- .../datenknoten/tueroeffner/MainActivity.java | 44 ++++++------- tueroeffner.iml | 21 +++++++ 5 files changed, 48 insertions(+), 88 deletions(-) delete mode 100644 app/src/main/java/me/datenknoten/tueroeffner/CommandExecuter.java create mode 100644 tueroeffner.iml diff --git a/app/app.iml b/app/app.iml index 4bffb70..8783ab7 100644 --- a/app/app.iml +++ b/app/app.iml @@ -83,8 +83,12 @@ - + + + + + diff --git a/app/build.gradle b/app/build.gradle index 7a38372..ef82f9d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -30,4 +30,6 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:21.0.2' + compile 'org.thoughtcrime.ssl.pinning:AndroidPinning:1.0.0' + compile 'com.koushikdutta.ion:ion:2.+' } diff --git a/app/src/main/java/me/datenknoten/tueroeffner/CommandExecuter.java b/app/src/main/java/me/datenknoten/tueroeffner/CommandExecuter.java deleted file mode 100644 index 1a85d7f..0000000 --- a/app/src/main/java/me/datenknoten/tueroeffner/CommandExecuter.java +++ /dev/null @@ -1,63 +0,0 @@ -/******************************************************************************* - * "THE VODKA-WARE LICENSE" (Revision 42): - * Tim wrote this file. As long as you retain this notice you - * can do whatever you want with this stuff. If we meet some day, and you think - * this stuff is worth it, you can buy me a vodka in return — Tim Schumacher - ******************************************************************************/ - -package me.datenknoten.tueroeffner; - -import android.os.AsyncTask; -import android.widget.EditText; - -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 java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; - -/** - * Created by tim on 27.01.2015. - */ -public class CommandExecuter extends AsyncTask { - private String key = ""; - - public CommandExecuter(String Key) { - this.key = Key; - } - - @Override - protected Boolean doInBackground(String... params) { - int count = params.length; - - try { - for (String param : params) { - executeCommand(param); - // Escape early if cancel() is called - if (isCancelled()) break; - } - return true; - } catch (Exception e) { - return false; - - } - - } - - /** - * Sends a command to the door server. - * - * @param cmd - */ - private Boolean executeCommand(String cmd) throws IOException, URISyntaxException { - HttpClient client = new DefaultHttpClient(); - HttpGet request = new HttpGet(); - URI uri = new URI("https://tuer.hackspace-jena.de/cgi-bin/kraut.space?secret="+key+"&cmd="+cmd); - request.setURI(uri); - HttpResponse response = client.execute(request); - return true; - } -} diff --git a/app/src/main/java/me/datenknoten/tueroeffner/MainActivity.java b/app/src/main/java/me/datenknoten/tueroeffner/MainActivity.java index b931bc5..d843ea5 100644 --- a/app/src/main/java/me/datenknoten/tueroeffner/MainActivity.java +++ b/app/src/main/java/me/datenknoten/tueroeffner/MainActivity.java @@ -21,6 +21,7 @@ import android.support.v4.app.Fragment; import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; +import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; @@ -38,12 +39,18 @@ import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; +import org.thoughtcrime.ssl.pinning.PinningTrustManager; +import org.thoughtcrime.ssl.pinning.SystemKeyStore; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.util.List; +import com.koushikdutta.async.future.FutureCallback; +import com.koushikdutta.ion.Ion; + +import javax.net.ssl.TrustManager; public class MainActivity extends ActionBarActivity { @@ -181,12 +188,7 @@ public class MainActivity extends ActionBarActivity { * @param v */ public void buttonOpenOuterDoor(View v) { - try { - new CommandExecuter(getDoorKey()).doInBackground("outdoor_buzz"); - Toast.makeText(v.getContext(), getString(R.string.buzzer_success), Toast.LENGTH_SHORT).show(); - } catch (Exception e) { - Toast.makeText(v.getContext(), "Konnte Befehl „Buzzer“ nicht ausführen.", Toast.LENGTH_SHORT).show(); - } + executeCommand("outdoor_buzz",v.getContext()); } /** @@ -195,12 +197,7 @@ public class MainActivity extends ActionBarActivity { * @param v */ public void buttonOpenInnerDoor(View v) { - try { - new CommandExecuter(getDoorKey()).doInBackground("indoor_unlock"); - Toast.makeText(v.getContext(), getString(R.string.door_unlock), Toast.LENGTH_SHORT).show(); - } catch (Exception e) { - Toast.makeText(v.getContext(), "Konnte Befehl „Tür aufschließen“ nicht ausführen.", Toast.LENGTH_SHORT).show(); - } + executeCommand("indoor_unlock",v.getContext()); } /** @@ -209,20 +206,19 @@ public class MainActivity extends ActionBarActivity { * @param v */ public void buttonUnlockInnerDoor(View v) { - try { - new CommandExecuter(getDoorKey()).doInBackground("indoor_open"); - Toast.makeText(v.getContext(), getString(R.string.door_open), Toast.LENGTH_SHORT).show(); - } catch (Exception e) { - Toast.makeText(v.getContext(), "Konnte Befehl „Tür öffnen“ nicht ausführen.", Toast.LENGTH_SHORT).show(); - } + executeCommand("indoor_open",v.getContext()); } public void buttonLockInnerDoor(View v) { - try { - new CommandExecuter(getDoorKey()).doInBackground("indoor_lock"); - Toast.makeText(v.getContext(), getString(R.string.door_open), Toast.LENGTH_SHORT).show(); - } catch (Exception e) { - Toast.makeText(v.getContext(), "Konnte Befehl „Tür schließen“ nicht ausführen.", Toast.LENGTH_SHORT).show(); - } + executeCommand("indoor_lock",v.getContext()); + } + + private void executeCommand(String cmd, Context context) { + TrustManager[] trustManagers = new TrustManager[] { new PinningTrustManager(SystemKeyStore.getInstance(context), + new String[] { "F1E2BB0724ACF34E60557DE95BD3DD30BCD08817" }, 0) }; + //Ion.getDefault(this).configure().setLogging("iontest", Log.VERBOSE); + Ion ion = Ion.getInstance(context, "tuer"); + ion.getHttpClient().getSSLSocketMiddleware().setTrustManagers(trustManagers); + ion.with(this).load("https://tuer.krautspace.de/cgi-bin/kraut.space?secret=" + this.getDoorKey() + "&cmd=" + cmd).asString(); } } diff --git a/tueroeffner.iml b/tueroeffner.iml new file mode 100644 index 0000000..2a02201 --- /dev/null +++ b/tueroeffner.iml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + From 9e29092b8722d810e4f4ba91b50cbcce8865ebda Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Wed, 11 Feb 2015 18:03:40 +0100 Subject: [PATCH 2/5] Free the reciever when it not used any more. --- .../datenknoten/tueroeffner/MainActivity.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/me/datenknoten/tueroeffner/MainActivity.java b/app/src/main/java/me/datenknoten/tueroeffner/MainActivity.java index f11d8d2..5c56cd8 100644 --- a/app/src/main/java/me/datenknoten/tueroeffner/MainActivity.java +++ b/app/src/main/java/me/datenknoten/tueroeffner/MainActivity.java @@ -56,6 +56,7 @@ import javax.net.ssl.TrustManager; public class MainActivity extends ActionBarActivity { final static String networkSSID = "KrautSpace"; + private DerivBroadcastReceiver receiver = null; @Override protected void onCreate(Bundle savedInstanceState) { @@ -70,7 +71,14 @@ public class MainActivity extends ActionBarActivity { IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION) ; intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); - registerReceiver(new DerivBroadcastReceiver(this, networkSSID),intentFilter); + receiver = new DerivBroadcastReceiver(this, networkSSID); + registerReceiver(receiver,intentFilter); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + unregisterReceiver(receiver); } @@ -136,18 +144,19 @@ public class MainActivity extends ActionBarActivity { s.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + String escaped_ssid = "\""+networkSSID+"\""; Context context = rootView.getContext(); WifiManager wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE); if (isChecked) { WifiConfiguration conf = new WifiConfiguration(); - conf.SSID = networkSSID; + conf.SSID = escaped_ssid; conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); int retval = wifiManager.addNetwork(conf); List list = wifiManager.getConfiguredNetworks(); for( WifiConfiguration i : list ) { - if(i.SSID != null && i.SSID.equals(networkSSID)) { + if(i.SSID != null && i.SSID.equals(escaped_ssid)) { wifiManager.enableNetwork(i.networkId, false); } else { wifiManager.disableNetwork(i.networkId); @@ -159,7 +168,7 @@ public class MainActivity extends ActionBarActivity { } else { List list = wifiManager.getConfiguredNetworks(); for( WifiConfiguration i : list ) { - if(i.SSID != null && i.SSID.equals(networkSSID)) { + if(i.SSID != null && i.SSID.equals(escaped_ssid)) { wifiManager.removeNetwork(i.networkId); } else { wifiManager.enableNetwork(i.networkId,false); From 2840fa6af4d992a89c81996681871a8b7f50ce49 Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Wed, 11 Feb 2015 18:14:58 +0100 Subject: [PATCH 3/5] Added a buildstatus badge. --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 3d72d36..34f6aa4 100644 --- a/Readme.md +++ b/Readme.md @@ -2,5 +2,5 @@ Eine kleine Android Anwendung zum einfachen öffnen der [Tür](https://www.krautspace.de/hswiki:fernschliessanlage). -Aktuelle Builds gibts unter https://login.datenknoten.me/~tim/tueroeffner/. +[![Build Status](http://buildserver.datenknoten.me/buildStatus/icon?job=tueroeffner)](http://buildserver.datenknoten.me/job/tueroeffner/) From c16a50cdf4724888270742a30fda99bc89167f30 Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Tue, 24 Feb 2015 20:58:29 +0100 Subject: [PATCH 4/5] Use the all trusting truststore. --- .../datenknoten/tueroeffner/MainActivity.java | 40 ++++++++++++++++--- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/me/datenknoten/tueroeffner/MainActivity.java b/app/src/main/java/me/datenknoten/tueroeffner/MainActivity.java index 5c56cd8..586f19e 100644 --- a/app/src/main/java/me/datenknoten/tueroeffner/MainActivity.java +++ b/app/src/main/java/me/datenknoten/tueroeffner/MainActivity.java @@ -223,11 +223,39 @@ public class MainActivity extends ActionBarActivity { } private void executeCommand(String cmd, Context context) { - TrustManager[] trustManagers = new TrustManager[] { new PinningTrustManager(SystemKeyStore.getInstance(context), - new String[] { "F1E2BB0724ACF34E60557DE95BD3DD30BCD08817" }, 0) }; - //Ion.getDefault(this).configure().setLogging("iontest", Log.VERBOSE); - Ion ion = Ion.getInstance(context, "tuer"); - ion.getHttpClient().getSSLSocketMiddleware().setTrustManagers(trustManagers); - ion.with(this).load("https://tuer.krautspace.de/cgi-bin/kraut.space?secret=" + this.getDoorKey() + "&cmd=" + cmd).asString(); + // Trust Manager + TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() { + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return null; + } + + public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) { + } + + public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) { + } + }}; + //Install the all-trusting trust manager + SSLContext sc = null; + try { + sc = SSLContext.getInstance("TLS"); + sc.init(null, trustAllCerts, new java.security.SecureRandom()); + sc.setDefault(sc); + + } catch (Exception e) { + } + + /** TODO it would be better to get the PinningTrustManager to get running, because its more safe. */ + /*TrustManager[] trustManagers = new TrustManager[]{new PinningTrustManager(SystemKeyStore.getInstance(context), + new String[]{"F1E2BB0724ACF34E60557DE95BD3DD30BCD08817"}, 0)};*/ + + Ion.getDefault(context).getHttpClient().getSSLSocketMiddleware().setTrustManagers(trustAllCerts); + Ion.getDefault(context).getHttpClient().getSSLSocketMiddleware().setSSLContext(sc); + + Ion.getDefault(context).getHttpClient().getSSLSocketMiddleware().setHostnameVerifier(org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); + + Ion.getDefault(this).configure().setLogging("iontest", Log.VERBOSE); + + Ion.with(this).load("https://tuer.hackspace-jena.de/cgi-bin/kraut.space?secret=" + this.getDoorKey() + "&cmd=" + cmd).asString(); } } From 08b2becce042429d323f0f2818f9bc23e9851dad Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Tue, 24 Feb 2015 20:59:58 +0100 Subject: [PATCH 5/5] Format the code. --- .../datenknoten/tueroeffner/MainActivity.java | 43 +++++++++++-------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/me/datenknoten/tueroeffner/MainActivity.java b/app/src/main/java/me/datenknoten/tueroeffner/MainActivity.java index 586f19e..99b3aa0 100644 --- a/app/src/main/java/me/datenknoten/tueroeffner/MainActivity.java +++ b/app/src/main/java/me/datenknoten/tueroeffner/MainActivity.java @@ -45,12 +45,17 @@ import org.thoughtcrime.ssl.pinning.SystemKeyStore; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; +import java.security.NoSuchAlgorithmException; import java.util.List; +import java.util.StringTokenizer; import com.koushikdutta.async.future.FutureCallback; import com.koushikdutta.ion.Ion; +import com.koushikdutta.ion.future.ResponseFuture; +import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; public class MainActivity extends ActionBarActivity { @@ -69,10 +74,10 @@ public class MainActivity extends ActionBarActivity { } IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION) ; + intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); receiver = new DerivBroadcastReceiver(this, networkSSID); - registerReceiver(receiver,intentFilter); + registerReceiver(receiver, intentFilter); } @Override @@ -117,8 +122,8 @@ public class MainActivity extends ActionBarActivity { Bundle savedInstanceState) { final View rootView = inflater.inflate(R.layout.fragment_main, container, false); - final SharedPreferences door_pref = getActivity().getSharedPreferences("tueroeffner",Context.MODE_PRIVATE); - String door_key = door_pref.getString(getString(R.string.door_key),""); + final SharedPreferences door_pref = getActivity().getSharedPreferences("tueroeffner", Context.MODE_PRIVATE); + String door_key = door_pref.getString(getString(R.string.door_key), ""); final EditText key_editor = (EditText) rootView.findViewById(R.id.txtPass); key_editor.setText(door_key); @@ -128,14 +133,16 @@ public class MainActivity extends ActionBarActivity { // you can call or do what you want with your EditText here SharedPreferences.Editor editor = door_pref.edit(); - editor.putString(getString(R.string.door_key),key_editor.getText().toString()); + editor.putString(getString(R.string.door_key), key_editor.getText().toString()); editor.apply(); } - public void beforeTextChanged(CharSequence s, int start, int count, int after) {} + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } - public void onTextChanged(CharSequence s, int start, int before, int count) {} + public void onTextChanged(CharSequence s, int start, int before, int count) { + } }); Switch s = (Switch) rootView.findViewById(R.id.switchWLAN); @@ -144,9 +151,9 @@ public class MainActivity extends ActionBarActivity { s.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - String escaped_ssid = "\""+networkSSID+"\""; + String escaped_ssid = "\"" + networkSSID + "\""; Context context = rootView.getContext(); - WifiManager wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE); + WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); if (isChecked) { WifiConfiguration conf = new WifiConfiguration(); conf.SSID = escaped_ssid; @@ -155,8 +162,8 @@ public class MainActivity extends ActionBarActivity { List list = wifiManager.getConfiguredNetworks(); - for( WifiConfiguration i : list ) { - if(i.SSID != null && i.SSID.equals(escaped_ssid)) { + for (WifiConfiguration i : list) { + if (i.SSID != null && i.SSID.equals(escaped_ssid)) { wifiManager.enableNetwork(i.networkId, false); } else { wifiManager.disableNetwork(i.networkId); @@ -167,11 +174,11 @@ public class MainActivity extends ActionBarActivity { Toast.makeText(buttonView.getContext(), getString(R.string.wlan_activated), Toast.LENGTH_SHORT).show(); } else { List list = wifiManager.getConfiguredNetworks(); - for( WifiConfiguration i : list ) { - if(i.SSID != null && i.SSID.equals(escaped_ssid)) { + for (WifiConfiguration i : list) { + if (i.SSID != null && i.SSID.equals(escaped_ssid)) { wifiManager.removeNetwork(i.networkId); } else { - wifiManager.enableNetwork(i.networkId,false); + wifiManager.enableNetwork(i.networkId, false); } } wifiManager.disconnect(); @@ -197,7 +204,7 @@ public class MainActivity extends ActionBarActivity { * @param v */ public void buttonOpenOuterDoor(View v) { - executeCommand("outdoor_buzz",v.getContext()); + executeCommand("outdoor_buzz", v.getContext()); } /** @@ -206,7 +213,7 @@ public class MainActivity extends ActionBarActivity { * @param v */ public void buttonOpenInnerDoor(View v) { - executeCommand("indoor_unlock",v.getContext()); + executeCommand("indoor_unlock", v.getContext()); } /** @@ -215,11 +222,11 @@ public class MainActivity extends ActionBarActivity { * @param v */ public void buttonUnlockInnerDoor(View v) { - executeCommand("indoor_open",v.getContext()); + executeCommand("indoor_open", v.getContext()); } public void buttonLockInnerDoor(View v) { - executeCommand("indoor_lock",v.getContext()); + executeCommand("indoor_lock", v.getContext()); } private void executeCommand(String cmd, Context context) {