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/) diff --git a/app/app.iml b/app/app.iml index 846b0ee..79a4bf3 100644 --- a/app/app.iml +++ b/app/app.iml @@ -85,8 +85,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 a37c1f8..1ada524 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,17 +39,30 @@ 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.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 { - static String networkSSID = "KrautSpace"; + final static String networkSSID = "KrautSpace"; + private DerivBroadcastReceiver receiver = null; + @Override protected void onCreate(Bundle savedInstanceState) { @@ -62,9 +76,16 @@ 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); - registerReceiver(new DerivBroadcastReceiver(this, networkSSID),intentFilter); + receiver = new DerivBroadcastReceiver(this, networkSSID); + registerReceiver(receiver, intentFilter); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + unregisterReceiver(receiver); } @@ -103,8 +124,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); @@ -114,14 +135,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); @@ -130,10 +153,12 @@ 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); + WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); if (isChecked) { + WifiConfiguration wifiConfig = new WifiConfiguration(); wifiConfig.SSID = String.format("\"%s\"", networkSSID); @@ -142,34 +167,8 @@ public class MainActivity extends ActionBarActivity { wifiManager.enableNetwork(netId, true); wifiManager.reconnect(); - /*WifiConfiguration conf = new WifiConfiguration(); - conf.SSID = networkSSID; - 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)) { - wifiManager.enableNetwork(i.networkId, false); - } else { - wifiManager.disableNetwork(i.networkId); - } - } - wifiManager.disconnect(); - wifiManager.reconnect();*/ 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(networkSSID)) { - wifiManager.removeNetwork(i.networkId); - } else { - wifiManager.enableNetwork(i.networkId,false); - } - } - wifiManager.disconnect(); - wifiManager.reconnect();*/ Toast.makeText(buttonView.getContext(), getString(R.string.wlan_deactivated), Toast.LENGTH_SHORT).show(); } } @@ -191,12 +190,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()); } /** @@ -205,12 +199,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()); } /** @@ -219,20 +208,47 @@ 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) { + executeCommand("indoor_lock", v.getContext()); + } + + private void executeCommand(String cmd, Context context) { + // 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 { - new CommandExecuter(getDoorKey()).doInBackground("indoor_lock"); - Toast.makeText(v.getContext(), getString(R.string.door_open), Toast.LENGTH_SHORT).show(); + sc = SSLContext.getInstance("TLS"); + sc.init(null, trustAllCerts, new java.security.SecureRandom()); + sc.setDefault(sc); + } catch (Exception e) { - Toast.makeText(v.getContext(), "Konnte Befehl „Tür schließen“ nicht ausführen.", Toast.LENGTH_SHORT).show(); } + + /** 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(); } } diff --git a/tueroeffner.iml b/tueroeffner.iml new file mode 100644 index 0000000..2a02201 --- /dev/null +++ b/tueroeffner.iml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + +