From 80d7d639f7405db7e5ea3f54d15e302f7772c351 Mon Sep 17 00:00:00 2001
From: Armin Novak <armin.novak@gmail.com>
Date: Fri, 5 Feb 2016 02:32:47 +0100
Subject: [PATCH] Updated android API.

---
 .../presentation/SessionActivity.java         | 39 ++++++++--
 .../freerdpcore/services/LibFreeRDP.java      | 31 ++++++--
 client/Android/android_freerdp.c              | 75 +++++++++++++------
 client/Android/android_jni_callback.c         |  2 +-
 4 files changed, 112 insertions(+), 35 deletions(-)

diff --git a/client/Android/Studio/freeRDPCore/src/main/java/com/freerdp/freerdpcore/presentation/SessionActivity.java b/client/Android/Studio/freeRDPCore/src/main/java/com/freerdp/freerdpcore/presentation/SessionActivity.java
index 08bc61395..453a0ba07 100644
--- a/client/Android/Studio/freeRDPCore/src/main/java/com/freerdp/freerdpcore/presentation/SessionActivity.java
+++ b/client/Android/Studio/freeRDPCore/src/main/java/com/freerdp/freerdpcore/presentation/SessionActivity.java
@@ -1066,12 +1066,10 @@ public class SessionActivity extends ActionBarActivity implements
 	}
 
 	@Override
-	public boolean OnVerifiyCertificate(String subject, String issuer,
-										String fingerprint) {
-
+	public int OnVerifiyCertificate(String commonName, String subject, String issuer, String fingerprint, boolean mismatch) {
 		// see if global settings says accept all
 		if (GlobalSettings.getAcceptAllCertificates())
-			return true;
+			return 0;
 
 		// this is where the return code of our dialog will be stored
 		callbackDialogResult = false;
@@ -1095,7 +1093,38 @@ public class SessionActivity extends ActionBarActivity implements
 		} catch (InterruptedException e) {
 		}
 
-		return callbackDialogResult;
+		return callbackDialogResult ? 1 : 0;
+	}
+
+	@Override
+	public int OnVerifiyChangedCertificate(String commonName, String subject, String issuer, String fingerprint, String oldSubject, String oldIssuer, String oldFingerprint) {
+		// see if global settings says accept all
+		if (GlobalSettings.getAcceptAllCertificates())
+			return 0;
+
+		// this is where the return code of our dialog will be stored
+		callbackDialogResult = false;
+
+		// set message
+		String msg = getResources().getString(
+				R.string.dlg_msg_verify_certificate);
+		msg = msg + "\n\nSubject: " + subject + "\nIssuer: " + issuer
+				+ "\nFingerprint: " + fingerprint;
+		dlgVerifyCertificate.setMessage(msg);
+
+		// start dialog in UI thread
+		uiHandler.sendMessage(Message.obtain(null, UIHandler.SHOW_DIALOG,
+				dlgVerifyCertificate));
+
+		// wait for result
+		try {
+			synchronized (dlgVerifyCertificate) {
+				dlgVerifyCertificate.wait();
+			}
+		} catch (InterruptedException e) {
+		}
+
+		return callbackDialogResult ? 1 : 0;
 	}
 
 	@Override
diff --git a/client/Android/Studio/freeRDPCore/src/main/java/com/freerdp/freerdpcore/services/LibFreeRDP.java b/client/Android/Studio/freeRDPCore/src/main/java/com/freerdp/freerdpcore/services/LibFreeRDP.java
index c07a5d26e..0d77c12ff 100644
--- a/client/Android/Studio/freeRDPCore/src/main/java/com/freerdp/freerdpcore/services/LibFreeRDP.java
+++ b/client/Android/Studio/freeRDPCore/src/main/java/com/freerdp/freerdpcore/services/LibFreeRDP.java
@@ -89,7 +89,12 @@ public class LibFreeRDP {
 
         boolean OnAuthenticate(StringBuilder username, StringBuilder domain, StringBuilder password);
 
-        boolean OnVerifiyCertificate(String subject, String issuer, String fingerprint);
+        int OnVerifiyCertificate(String commonName, String subject,
+                String issuer, String fingerprint, boolean mismatch);
+
+        int OnVerifiyChangedCertificate(String commonName, String subject,
+                String issuer, String fingerprint, String oldSubject,
+                String oldIssuer, String oldFingerprint);
 
         void OnGraphicsUpdate(int x, int y, int width, int height);
 
@@ -330,14 +335,30 @@ public class LibFreeRDP {
         return false;
     }
 
-    private static boolean OnVerifyCertificate(int inst, String subject, String issuer, String fingerprint) {
+    private static int OnVerifyCertificate(int inst, String commonName, String subject,
+                                           String issuer, String fingerprint, boolean
+                                                   hostMismatch) {
         SessionState s = GlobalApp.getSession(inst);
         if (s == null)
-            return false;
+            return 0;
         UIEventListener uiEventListener = s.getUIEventListener();
         if (uiEventListener != null)
-            return uiEventListener.OnVerifiyCertificate(subject, issuer, fingerprint);
-        return false;
+            return uiEventListener.OnVerifiyCertificate(commonName, subject, issuer, fingerprint,
+                    hostMismatch);
+        return 0;
+    }
+
+    private static int OnVerifyCertificate(int inst, String commonName, String subject,
+                                           String issuer, String fingerprint, String oldSubject,
+                                           String oldIssuer, String oldFingerprint) {
+        SessionState s = GlobalApp.getSession(inst);
+        if (s == null)
+            return 0;
+        UIEventListener uiEventListener = s.getUIEventListener();
+        if (uiEventListener != null)
+            return uiEventListener.OnVerifiyChangedCertificate(commonName, subject, issuer,
+                    fingerprint, oldSubject, oldIssuer, oldFingerprint);
+        return 0;
     }
 
     private static void OnGraphicsUpdate(int inst, int x, int y, int width, int height) {
diff --git a/client/Android/android_freerdp.c b/client/Android/android_freerdp.c
index 2baf0f4a2..8253f30d7 100644
--- a/client/Android/android_freerdp.c
+++ b/client/Android/android_freerdp.c
@@ -417,37 +417,64 @@ static BOOL android_authenticate(freerdp* instance, char** username,
 	return ((res == JNI_TRUE) ? TRUE : FALSE);
 }
 
-static BOOL android_verify_certificate(freerdp* instance, char* subject,
-					   char* issuer, char* fingerprint)
+static DWORD android_verify_certificate(
+        freerdp* instance, const char* common_name,
+        const char* subject, const char* issuer,
+        const char* fingerprint, BOOL host_mismatch)
 {
-	JNIEnv* env;
-	jboolean attached = jni_attach_thread(&env);
-	jstring jstr1 = (*env)->NewStringUTF(env, subject);
-	jstring jstr2 = (*env)->NewStringUTF(env, issuer);
-	jstring jstr3 = (*env)->NewStringUTF(env, fingerprint);
-	jboolean res;
+    WLog_DBG(TAG, "Certificate details:");
+    WLog_DBG(TAG, "\tSubject: %s", subject);
+    WLog_DBG(TAG, "\tIssuer: %s", issuer);
+    WLog_DBG(TAG, "\tThumbprint: %s", fingerprint);
+    WLog_DBG(TAG, "The above X.509 certificate could not be verified, possibly because you do not have "
+            "the CA certificate in your certificate store, or the certificate has expired."
+            "Please look at the documentation on how to create local certificate store for a private CA.\n");
 
-	res = freerdp_callback_bool_result(
-			  "OnVerifyCertificate",
-			  "(ILjava/lang/String;"
-			  "Ljava/lang/String;"
-			  "Ljava/lang/String;)Z",
-			  instance, jstr1, jstr2, jstr3);
+    JNIEnv* env;
+    jboolean attached = jni_attach_thread(&env);
+    jstring jstr0 = (*env)->NewStringUTF(env, common_name);
+    jstring jstr1 = (*env)->NewStringUTF(env, subject);
+    jstring jstr2 = (*env)->NewStringUTF(env, issuer);
+    jstring jstr3 = (*env)->NewStringUTF(env, fingerprint);
 
-	if (attached == JNI_TRUE)
-		jni_detach_thread();
+    jint res = freerdp_callback_int_result("OnVerifyCertificate",
+            "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)I",
+            instance, jstr0, jstr1, jstr2, jstr3, host_mismatch);
 
-	return ((res == JNI_TRUE) ? TRUE : FALSE);
+    if (attached == JNI_TRUE)
+        jni_detach_thread();
+    
+    return res;
 }
 
-static BOOL android_verify_changed_certificate(
-		freerdp* instance, char* subject, char* issuer,
-		char* new_fingerprint, char* old_subject,
-		char* old_issuer, char* old_fingerprint)
+static DWORD android_verify_changed_certificate(freerdp* instance,
+					const char* common_name,
+					const char* subject,
+					const char* issuer,
+					const char* new_fingerprint,
+					const char* old_subject,
+					const char* old_issuer,
+					const char* old_fingerprint)
 {
-	return android_verify_certificate(
-				instance, subject, issuer,
-				new_fingerprint);
+    JNIEnv* env;
+    jboolean attached = jni_attach_thread(&env);
+    jstring jstr0 = (*env)->NewStringUTF(env, common_name);
+    jstring jstr1 = (*env)->NewStringUTF(env, subject);
+    jstring jstr2 = (*env)->NewStringUTF(env, issuer);
+    jstring jstr3 = (*env)->NewStringUTF(env, new_fingerprint);
+    jstring jstr4 = (*env)->NewStringUTF(env, old_subject);
+    jstring jstr5 = (*env)->NewStringUTF(env, old_issuer);
+    jstring jstr6 = (*env)->NewStringUTF(env, old_fingerprint);
+
+    jint res = freerdp_callback_int_result("OnVerifyChangedCertificate",
+            "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;"
+            "Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I",
+            instance, jstr0, jstr1, jstr2, jstr3, jstr4, jstr5, jstr6);
+
+    if (attached == JNI_TRUE)
+        jni_detach_thread();
+    
+    return res;
 }
 
 static void* jni_input_thread(void* arg)
diff --git a/client/Android/android_jni_callback.c b/client/Android/android_jni_callback.c
index d103b80e2..64985d600 100644
--- a/client/Android/android_jni_callback.c
+++ b/client/Android/android_jni_callback.c
@@ -181,7 +181,7 @@ jint java_callback_int(jobject obj, const char * callback, const char* signature
 	jint res = -1;
 	JNIEnv *env;
 
-	DEBUG_ANDROID("java_callback: %s (%s)", callback, signature);
+	WLog_DBG(TAG, "java_callback: %s (%s)", callback, signature);
 
 	attached = jni_attach_thread(&env);