summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AndroidManifest.xml2
-rw-r--r--README.cert13
-rw-r--r--res/layout/main.xml3
-rw-r--r--res/raw/deki_eu.bksbin0 -> 5056 bytes
-rw-r--r--src/eu/deki/paste/DekiEuPaste.java81
-rw-r--r--src/eu/deki/paste/MainActivity.java20
-rw-r--r--src/eu/deki/paste/PasteTask.java62
7 files changed, 177 insertions, 4 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index d9f6273..967c2dc 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -12,4 +12,6 @@
</intent-filter>
</activity>
</application>
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>
diff --git a/README.cert b/README.cert
new file mode 100644
index 0000000..99329fe
--- /dev/null
+++ b/README.cert
@@ -0,0 +1,13 @@
+Requires BouncyCastle provider
+Note: version 1.46 is required (as Android also uses this version)
+
+For non-selfsigned certificates, the root certificate of the CA has to be included (CACert: class 1 and 3 certs)
+
+
+CERTSTORE=res/raw/deki_eu.bks
+keytool -import -v -trustcacerts -alias 0 -file <(openssl x509 -in cacert-root1.crt) -keystore $CERTSTORE -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath /tmp/bcprov-jdk15on-147.jar -storepass abcdefg
+keytool -import -v -trustcacerts -alias 1 -file <(openssl x509 -in cacert-root3.crt) -keystore $CERTSTORE -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath /tmp/bcprov-jdk15on-147.jar -storepass abcdefg
+keytool -import -v -trustcacerts -alias 2 -file <(openssl x509 -in deki.eu.crt) -keystore $CERTSTORE -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath /tmp/bcprov-jdk15on-147.jar -storepass abcdefg
+
+(see also: http://blog.crazybob.org/2010/02/android-trusting-ssl-certificates.html )
+
diff --git a/res/layout/main.xml b/res/layout/main.xml
index 8155076..f811f65 100644
--- a/res/layout/main.xml
+++ b/res/layout/main.xml
@@ -21,6 +21,7 @@
<Button android:id="@+id/paste_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:text="@string/paste_button" />
+ android:text="@string/paste_button"
+ android:onClick="onPasteButtonClick" />
</LinearLayout>
diff --git a/res/raw/deki_eu.bks b/res/raw/deki_eu.bks
new file mode 100644
index 0000000..25c7abd
--- /dev/null
+++ b/res/raw/deki_eu.bks
Binary files differ
diff --git a/src/eu/deki/paste/DekiEuPaste.java b/src/eu/deki/paste/DekiEuPaste.java
new file mode 100644
index 0000000..a0d0ba9
--- /dev/null
+++ b/src/eu/deki/paste/DekiEuPaste.java
@@ -0,0 +1,81 @@
+package eu.deki.paste;
+
+import java.net.URL;
+import java.net.URLEncoder;
+import java.net.MalformedURLException;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.SSLContext;
+import java.io.OutputStream;
+import java.io.InputStream;
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.security.KeyStore;
+import android.content.Context;
+import android.util.Log;
+import eu.deki.paste.PasteTask;
+
+public class DekiEuPaste extends PasteTask
+{
+ private static final String pasteUrl = "https://deki.eu/paste/new";
+
+ public DekiEuPaste(Context parent)
+ {
+ super(parent);
+ }
+
+ @Override
+ protected String paste(String title, String content, String delay) throws IOException
+ {
+ System.setProperty("http.keepAlive", "false");
+
+ String request = "title=" + URLEncoder.encode(title) + "&content=" + URLEncoder.encode(content) + "&expiration=" + URLEncoder.encode(delay);
+
+ URL url;
+ try {
+ url = new URL(pasteUrl);
+ } catch(MalformedURLException ex) {
+ // will never happen because of hardcoded URL
+ return null;
+ }
+
+ InputStream in = parentActivity.getResources().openRawResource(R.raw.deki_eu);
+ SSLContext context = null;
+ try
+ {
+ KeyStore trustedStore = KeyStore.getInstance("BKS");
+ trustedStore.load(in, "abcdefg".toCharArray());
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
+ //TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+ tmf.init(trustedStore);
+ context = SSLContext.getInstance("TLS");
+ context.init(null, tmf.getTrustManagers(), null);
+ }
+ catch(Exception ex)
+ {
+ Log.i("PasteIt", "Could not initialize certificate verification", ex);
+ return null;
+ }
+ finally
+ {
+ in.close();
+ }
+
+ HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
+ conn.setSSLSocketFactory(context.getSocketFactory());
+ conn.setDoOutput(true);
+ conn.setFixedLengthStreamingMode(request.getBytes().length);
+
+ OutputStream out = new BufferedOutputStream(conn.getOutputStream());
+ out.write(request.getBytes());
+ out.close();
+
+ conn.getHeaderFields();
+ String redirectUrl = conn.getURL().toString();
+
+ conn.disconnect();
+
+ return redirectUrl;
+ }
+}
+
diff --git a/src/eu/deki/paste/MainActivity.java b/src/eu/deki/paste/MainActivity.java
index 032fede..4f721b7 100644
--- a/src/eu/deki/paste/MainActivity.java
+++ b/src/eu/deki/paste/MainActivity.java
@@ -3,21 +3,35 @@ package eu.deki.paste;
import android.app.Activity;
import android.os.Bundle;
import android.widget.Spinner;
+import android.widget.EditText;
import android.widget.ArrayAdapter;
+import android.view.View;
+import eu.deki.paste.PasteTask;
+import eu.deki.paste.DekiEuPaste;
public class MainActivity extends Activity
{
- private Spinner expiration;
-
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
- expiration = (Spinner) findViewById(R.id.expiration);
+ Spinner expiration = (Spinner) findViewById(R.id.expiration);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.expiration_array, android.R.layout.simple_spinner_item);
//adapter.setDropDownViewResource(android.R.layout.simple_spinner_item);
expiration.setAdapter(adapter);
}
+
+ public void onPasteButtonClick(View view)
+ {
+ EditText titleText = (EditText) findViewById(R.id.paste_title);
+ EditText contentText = (EditText) findViewById(R.id.paste_content);
+ Spinner expiration = (Spinner) findViewById(R.id.expiration);
+
+ // TODO: check network status
+
+ new DekiEuPaste(this).execute(titleText.getText().toString(), contentText.getText().toString(), "1hour");
+ }
}
+
diff --git a/src/eu/deki/paste/PasteTask.java b/src/eu/deki/paste/PasteTask.java
new file mode 100644
index 0000000..29b5c32
--- /dev/null
+++ b/src/eu/deki/paste/PasteTask.java
@@ -0,0 +1,62 @@
+package eu.deki.paste;
+
+import java.io.IOException;
+import android.os.AsyncTask;
+import android.widget.Toast;
+import android.content.Context;
+import android.util.Log;
+
+public abstract class PasteTask extends AsyncTask<String, Void, String>
+{
+ private String errorMessage = null;
+ protected Context parentActivity = null;
+
+ public PasteTask(Context parent)
+ {
+ super();
+ parentActivity = parent;
+ }
+
+ @Override
+ protected String doInBackground(String... params)
+ {
+ String title, content, expiration, result;
+
+ if(params.length != 3)
+ return null;
+
+ title = params[0];
+ content = params[1];
+ expiration = params[2];
+
+ try
+ {
+ result = paste(title, content, expiration);
+ }
+ catch(IOException ex)
+ {
+ cancel(false);
+ errorMessage = ex.getLocalizedMessage();
+ result = errorMessage;
+ Log.e("PasteIt", "doInBackground", ex);
+ }
+
+ return result;
+ }
+
+ @Override
+ protected void onPostExecute(String result)
+ {
+
+ }
+
+ @Override
+ protected void onCancelled()
+ {
+ //Toast toast = Toast.makeText(parentActivity.getApplicationContext(), errorMessage, Toast.LENGTH_SHORT);
+ //toast.show();
+ }
+
+ protected abstract String paste(String title, String content, String delay) throws IOException;
+}
+