Update 0.2.5 - Invalid SSL support

This commit is contained in:
David 2013-05-27 13:31:08 +02:00
parent c18ab107d5
commit 59d0cc2ff5
28 changed files with 238 additions and 51 deletions

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="de.luhmer.owncloudnewsreader"
android:versionCode="6"
android:versionName="0.2.4" >
android:versionCode="7"
android:versionName="0.2.5" >
<uses-sdk
android:minSdkVersion="14"

Binary file not shown.

View file

@ -13,7 +13,8 @@
<string name="pref_default_username">admin</string>
<string name="pref_title_password">Passwort</string>
<string name="pref_title_AllowAllSSLCertificates">Allow all SSL Certificates</string>
<string name="pref_title_owncloudRootPath">ownCloud root address</string>
<string name="pref_default_owncloudRootPath">http://1.2.3.4/owncloud</string>

View file

@ -37,6 +37,10 @@
android:title="@string/pref_title_owncloudRootPath"
android:inputType="textUri" />
<CheckBoxPreference
android:key="cb_AllowAllSSLCertificates"
android:title="@string/pref_title_AllowAllSSLCertificates" />
<!--
NOTE: Hide buttons to simplify the UI. Users can touch outside the dialog to
dismiss it.

View file

@ -8,13 +8,7 @@ import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceCategory;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.preference.RingtonePreference;
import android.preference.*;
import android.text.TextUtils;
import java.util.List;
@ -41,7 +35,7 @@ public class SettingsActivity extends PreferenceActivity {
public static final String EDT_USERNAME_STRING = "edt_username";
public static final String EDT_PASSWORD_STRING = "edt_password";
public static final String EDT_OWNCLOUDROOTPATH_STRING = "edt_owncloudRootPath";
public static final String CB_ALLOWALLSSLCERTIFICATES_STRING = "cb_AllowAllSSLCertificates";
@Override
protected void onPostCreate(Bundle savedInstanceState) {
@ -88,7 +82,8 @@ public class SettingsActivity extends PreferenceActivity {
bindPreferenceSummaryToValue(findPreference(EDT_USERNAME_STRING));
bindPreferenceSummaryToValue(findPreference(EDT_PASSWORD_STRING));
bindPreferenceSummaryToValue(findPreference(EDT_OWNCLOUDROOTPATH_STRING));
bindPreferenceBooleanToValue(findPreference(CB_ALLOWALLSSLCERTIFICATES_STRING));
//bindPreferenceSummaryToValue(findPreference("example_list"));
//bindPreferenceSummaryToValue(findPreference("notifications_new_message_ringtone"));//TODO comment this out
@ -186,6 +181,15 @@ public class SettingsActivity extends PreferenceActivity {
}
};
private static Preference.OnPreferenceChangeListener sBindPreferenceBooleanToValueListener = new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
CheckBoxPreference cbPreference = ((CheckBoxPreference) preference);
cbPreference.setChecked((Boolean)newValue);
return true;
}
};
/**
* Binds a preference's summary to its value. More specifically, when the
* preference's value is changed, its summary (line of text below the
@ -208,6 +212,18 @@ public class SettingsActivity extends PreferenceActivity {
""));
}
private static void bindPreferenceBooleanToValue(Preference preference) {
// Set the listener to watch for value changes.
preference.setOnPreferenceChangeListener(sBindPreferenceBooleanToValueListener);
// Trigger the listener immediately with the preference's
// current value.
sBindPreferenceBooleanToValueListener.onPreferenceChange(
preference,
PreferenceManager.getDefaultSharedPreferences(
preference.getContext()).getBoolean(preference.getKey(), false));
}
/**
* This fragment shows general preferences only. It is used when the
* activity is showing a two-pane settings UI.
@ -227,6 +243,8 @@ public class SettingsActivity extends PreferenceActivity {
bindPreferenceSummaryToValue(findPreference(EDT_PASSWORD_STRING));
bindPreferenceSummaryToValue(findPreference(EDT_OWNCLOUDROOTPATH_STRING));
//bindPreferenceSummaryToValue(findPreference("example_list"));
bindPreferenceBooleanToValue(findPreference(CB_ALLOWALLSSLCERTIFICATES_STRING));
}
}

View file

@ -0,0 +1,106 @@
package de.luhmer.owncloudnewsreader.helper;
import android.content.Context;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.SingleClientConnManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
/**
* Created by David on 27.05.13.
*/
public class SSLHttpClient extends DefaultHttpClient {
final Context context;
TrustManager easyTrustManager = new X509TrustManager() {
@Override
public void checkClientTrusted(
X509Certificate[] chain,
String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(
X509Certificate[] chain,
String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
public SSLHttpClient(Context context) {
this.context = context;
}
@Override protected ClientConnectionManager createClientConnectionManager() {
SchemeRegistry registry = new SchemeRegistry();
registry.register(
new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
registry.register(new Scheme("https", newSslSocketFactory(), 443));
return new SingleClientConnManager(getParams(), registry);
}
private MySSLSocketFactory newSslSocketFactory() {
try {
KeyStore trusted = KeyStore.getInstance("BKS");
try {
trusted.load(null, null);
} finally {
}
MySSLSocketFactory sslfactory = new MySSLSocketFactory(trusted);
sslfactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
return sslfactory;
} catch (Exception e) {
throw new AssertionError(e);
}
}
public class MySSLSocketFactory extends SSLSocketFactory {
SSLContext sslContext = SSLContext.getInstance("TLS");
public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
super(truststore);
TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
sslContext.init(null, new TrustManager[] { tm }, null);
}
@Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
}
@Override
public Socket createSocket() throws IOException {
return sslContext.getSocketFactory().createSocket();
}
}
}

View file

@ -8,9 +8,16 @@ import java.net.HttpURLConnection;
import java.net.PasswordAuthentication;
import java.net.URL;
import java.net.URLConnection;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.List;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;
import de.luhmer.owncloudnewsreader.SettingsActivity;
import de.luhmer.owncloudnewsreader.helper.SSLHttpClient;
import de.luhmer.owncloudnewsreader.util.Base64;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
@ -24,26 +31,40 @@ import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONObject;
import javax.net.ssl.*;
public class HttpJsonRequest {
private static final String TAG = "HttpJsonRequest";
public static JSONObject PerformJsonRequest(String url, List<NameValuePair> nameValuePairs, String username, String password) throws Exception
public static JSONObject PerformJsonRequest(String urlString, List<NameValuePair> nameValuePairs, String username, String password, Context context) throws Exception
{
// http://androidarabia.net/quran4android/phpserver/connecttoserver.php
if(nameValuePairs != null)
{
urlString += "&" + URLEncodedUtils.format(nameValuePairs, "utf-8");
/*
JSONObject jObj = new JSONObject();
// Log.i(getClass().getSimpleName(), "send task - start");
//HttpParams httpParams = new BasicHttpParams();
//HttpConnectionParams.setConnectionTimeout(httpParams, TIMEOUT_MILLISEC);
//HttpConnectionParams.setSoTimeout(httpParams, TIMEOUT_MILLISEC);
//
//HttpParams p = new BasicHttpParams();
// p.setParameter("name", pvo.getName());
//p.setParameter("user", "1");
for (NameValuePair nameValuePair : nameValuePairs) {
jObj.put(nameValuePair.getName(), nameValuePair.getValue());
}*/
//request.setEntity(new ByteArrayEntity(jObj.toString().getBytes("UTF8")));
//httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
}
URL url = new URL(urlString);
// Instantiate an HttpClient
//HttpClient httpclient = new DefaultHttpClient(p);
DefaultHttpClient httpClient = new DefaultHttpClient();
DefaultHttpClient httpClient = null;
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
if(sp.getBoolean(SettingsActivity.CB_ALLOWALLSSLCERTIFICATES_STRING, false) && url.getProtocol().toLowerCase().equals("https"))
httpClient = new SSLHttpClient(context);
else
httpClient = new DefaultHttpClient();
if(username != null && password != null)
httpClient.getCredentialsProvider().setCredentials(new AuthScope(null, -1), new UsernamePasswordCredentials(username,password));
@ -60,22 +81,7 @@ public class HttpJsonRequest {
httpClient.setParams(params);*/
// Instantiate a GET HTTP method
if(nameValuePairs != null)
{
url += "&" + URLEncodedUtils.format(nameValuePairs, "utf-8");
/*
JSONObject jObj = new JSONObject();
for (NameValuePair nameValuePair : nameValuePairs) {
jObj.put(nameValuePair.getName(), nameValuePair.getValue());
}*/
//request.setEntity(new ByteArrayEntity(jObj.toString().getBytes("UTF8")));
//httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
}
HttpGet request = new HttpGet(url);
HttpGet request = new HttpGet(url.toString());
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String responseBody = httpClient.execute(request, responseHandler);
@ -134,7 +140,7 @@ public class HttpJsonRequest {
*/
public static int performTagChangeRequest(String url, String username, String password) throws Exception
public static int performTagChangeRequest(String url, String username, String password, Context context) throws Exception
{
//url = "http://192.168.10.126/owncloud/ocs/v1.php/apps/news/items/3787/read";
@ -142,12 +148,24 @@ public class HttpJsonRequest {
String authStringEnc = Base64.encode(authString.getBytes());
URL urlConn = new URL(url);
HttpURLConnection connection = (HttpURLConnection) urlConn.openConnection();
connection.setRequestProperty("Authorization", "Basic " + authStringEnc);
connection.setRequestMethod("PUT");
/*
InputStreamReader in = new InputStreamReader((InputStream) connection.getContent());
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
HttpURLConnection httpConnection = null;
if (urlConn.getProtocol().toLowerCase().equals("https") && sp.getBoolean(SettingsActivity.CB_ALLOWALLSSLCERTIFICATES_STRING, false)) {
trustAllHosts();
HttpsURLConnection https = (HttpsURLConnection) urlConn.openConnection();
https.setHostnameVerifier(DO_NOT_VERIFY);
httpConnection = https;
} else {
httpConnection = (HttpURLConnection) urlConn.openConnection();
}
httpConnection.setRequestProperty("Authorization", "Basic " + authStringEnc);
httpConnection.setRequestMethod("PUT");
InputStreamReader in = new InputStreamReader((InputStream) httpConnection.getContent());
BufferedReader buff = new BufferedReader(in);
String text = "";
String line;
@ -157,8 +175,48 @@ public class HttpJsonRequest {
text += line + "\n";
} while (line != null);
Log.d(TAG, text);
*/
return connection.getResponseCode();
return httpConnection.getResponseCode();
}
// always verify the host - dont check for certificate
final static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
/**
* Trust every server - dont check for any certificate
*/
private static void trustAllHosts() {
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[] {};
}
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
} };
// Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection
.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
e.printStackTrace();
}
}
}

View file

@ -51,7 +51,7 @@ public class OwnCloudReaderMethods {
String password = mPrefs.getString(SettingsActivity.EDT_PASSWORD_STRING, null);
String oc_root_path = mPrefs.getString(SettingsActivity.EDT_OWNCLOUDROOTPATH_STRING, "");
JSONObject jsonObj = HttpJsonRequest.PerformJsonRequest(oc_root_path + OwnCloudConstants.FEED_PATH + OwnCloudConstants.JSON_FORMAT, nVPairs, username, password);
JSONObject jsonObj = HttpJsonRequest.PerformJsonRequest(oc_root_path + OwnCloudConstants.FEED_PATH + OwnCloudConstants.JSON_FORMAT, nVPairs, username, password, act);
jsonObj = jsonObj.optJSONObject("ocs");
jsonObj = jsonObj.optJSONObject("data");
@ -94,7 +94,7 @@ public class OwnCloudReaderMethods {
String password = mPrefs.getString(SettingsActivity.EDT_PASSWORD_STRING, null);
String oc_root_path = mPrefs.getString(SettingsActivity.EDT_OWNCLOUDROOTPATH_STRING, "");
JSONObject jsonObj = HttpJsonRequest.PerformJsonRequest(oc_root_path + OwnCloudConstants.FOLDER_PATH + OwnCloudConstants.JSON_FORMAT, null, username, password);
JSONObject jsonObj = HttpJsonRequest.PerformJsonRequest(oc_root_path + OwnCloudConstants.FOLDER_PATH + OwnCloudConstants.JSON_FORMAT, null, username, password, act);
jsonObj = jsonObj.optJSONObject("ocs");
jsonObj = jsonObj.optJSONObject("data");
@ -118,7 +118,7 @@ public class OwnCloudReaderMethods {
String password = mPrefs.getString(SettingsActivity.EDT_PASSWORD_STRING, null);
String oc_root_path = mPrefs.getString(SettingsActivity.EDT_OWNCLOUDROOTPATH_STRING, "");
JSONObject jsonObj = HttpJsonRequest.PerformJsonRequest(oc_root_path + OwnCloudConstants.SUBSCRIPTION_PATH + OwnCloudConstants.JSON_FORMAT, null, username, password);
JSONObject jsonObj = HttpJsonRequest.PerformJsonRequest(oc_root_path + OwnCloudConstants.SUBSCRIPTION_PATH + OwnCloudConstants.JSON_FORMAT, null, username, password, act);
jsonObj = jsonObj.optJSONObject("ocs");
jsonObj = jsonObj.optJSONObject("data");
@ -171,7 +171,7 @@ public class OwnCloudReaderMethods {
}
try
{
int result = HttpJsonRequest.performTagChangeRequest(url, username, password);
int result = HttpJsonRequest.performTagChangeRequest(url, username, password, context);
if(result != -1 || result != 405)
return true;
else