/soc/2012/michael/android: b1f6f87b6df4: Changed SSL and DNS: Ad...

Michael Zangl michael at soc.pidgin.im
Tue Aug 7 05:59:27 EDT 2012


Changeset: b1f6f87b6df45bc090fd9740c1f4559229d1c8e2
Author:	 Michael Zangl <michael at soc.pidgin.im>
Date:	 2012-08-06 23:16 +0200
Branch:	 soc.2012.android
URL: http://hg.pidgin.im/soc/2012/michael/android/rev/b1f6f87b6df4

Description:

Changed SSL and DNS: Added new not-null tests and added the socket address to the socketimpl object, so that there is no null pointer when connecting. Also disabled Certs for testing.

diffstat:

 android/workspace/im.pidgin.libpurple/native/DnsQueryUiOps.c                              |    4 +
 android/workspace/im.pidgin.libpurple/native/SrvTxtQueryResolvedCallback.c                |   17 +-
 android/workspace/im.pidgin.libpurple/native/SslConnection.c                              |   19 +
 android/workspace/im.pidgin.libpurple/native/SslOps.c                                     |  101 +++++++--
 android/workspace/im.pidgin.libpurple/native/helpers.c                                    |    3 +
 android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/core/dns/DnsQueryData.java  |   12 +-
 android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/core/ssl/SslConnection.java |   52 ++++-
 7 files changed, 172 insertions(+), 36 deletions(-)

diffs (truncated from 429 to 300 lines):

diff --git a/android/workspace/im.pidgin.libpurple/native/DnsQueryUiOps.c b/android/workspace/im.pidgin.libpurple/native/DnsQueryUiOps.c
--- a/android/workspace/im.pidgin.libpurple/native/DnsQueryUiOps.c
+++ b/android/workspace/im.pidgin.libpurple/native/DnsQueryUiOps.c
@@ -38,9 +38,11 @@ destroy(PurpleDnsQueryData *query_data)
 {
 	JavaObjectReference *ref;
 
+	g_return_if_fail(query_data != NULL);
 	CALLBACK_START_VOID(&dns);
 
 	ref = purple_dnsquery_get_ui_data(query_data);
+	g_return_if_fail(ref != NULL);
 
 	notifyPeerDestroyed(env, ref->handlerObject);
 	unsetJavaObject(ref, env);
@@ -78,9 +80,11 @@ destroy_srv(PurpleSrvTxtQueryData *query
 {
 	JavaObjectReference *ref;
 
+	g_return_if_fail(query_data != NULL);
 	CALLBACK_START_VOID(&dns);
 
 	ref = purple_srv_txt_query_get_ui_data(query_data);
+	g_return_if_fail(ref != NULL);
 
 	notifyPeerDestroyed(env, ref->handlerObject);
 	unsetJavaObject(ref, env);
diff --git a/android/workspace/im.pidgin.libpurple/native/SrvTxtQueryResolvedCallback.c b/android/workspace/im.pidgin.libpurple/native/SrvTxtQueryResolvedCallback.c
--- a/android/workspace/im.pidgin.libpurple/native/SrvTxtQueryResolvedCallback.c
+++ b/android/workspace/im.pidgin.libpurple/native/SrvTxtQueryResolvedCallback.c
@@ -22,6 +22,7 @@ convert_srv_response(JNIEnv *env, jobjec
 	jstring hostname;
 	jsize hostname_len;
 
+	g_return_val_if_fail(object != NULL, NULL);
 	java_class = (*env)->GetObjectClass(env, object);
 	g_return_val_if_fail(java_class != NULL, NULL);
 
@@ -37,15 +38,16 @@ convert_srv_response(JNIEnv *env, jobjec
 	g_return_val_if_fail(getHostMid != NULL, NULL);
 
 	response = g_new(PurpleSrvResponse, 1);
+	g_return_val_if_fail(response != NULL, NULL);
 	response->pref = (*env)->CallIntMethod(env, object, getPriorityMid);
 	response->port = (*env)->CallIntMethod(env, object, getPortMid);
 	response->weight = (*env)->CallIntMethod(env, object, getWeigthMid);
 	hostname = (*env)->CallObjectMethod(env, object, getHostMid);
+	g_return_val_if_fail(hostname != NULL, NULL);
 	hostname_len = (*env)->GetStringLength(env, hostname);
 	g_return_val_if_fail(hostname_len > sizeof(response->hostname), NULL);
 	(*env)->GetStringUTFRegion(env, hostname, 0, hostname_len,
-			response->hostname);
-	(*env)->ReleaseStringUTFChars(env, hostname, NULL);
+			&response->hostname[0]);
 	return response;
 }
 
@@ -62,23 +64,30 @@ Java_im_pidgin_libpurple_core_dns_srvtxt
 	jsize length;
 	jsize i;
 	jobject entry;
+	PurpleSrvResponse *entry_native;
 	GList *result_native;
 
 	resolvedCallback = getNativePointer(env, object);
 	data_native = getNativeSrvTxtData(env, data);
-	result_native = g_list_alloc();
+	g_return_if_fail(data_native != NULL);
+	result_native = NULL;
 	length = (*env)->GetArrayLength(env, result);
+	g_log("jni", G_LOG_LEVEL_DEBUG, "converting %d srv entries", length);
 
 	if (purple_srv_txt_query_get_type(data_native) == PurpleDnsTypeSrv) {
 		for (i = 0; i < length; ++i) {
 			entry = (*env)->GetObjectArrayElement(env, result, i);
+			entry_native = convert_srv_response(env, entry);
 
+			g_return_if_fail(entry_native != NULL);
+			g_log("jni", G_LOG_LEVEL_DEBUG, "converted srv: %d %d %d %s", entry_native->pref, entry_native->weight, entry_native->port,entry_native->hostname );
 			result_native = g_list_append(result_native,
-					convert_srv_response(env, entry));
+					entry_native);
 		}
 	} else {
 		g_return_if_reached();
 	}
 
 	resolvedCallback(data_native, result_native);
+	/* free() ? */
 }
diff --git a/android/workspace/im.pidgin.libpurple/native/SslConnection.c b/android/workspace/im.pidgin.libpurple/native/SslConnection.c
--- a/android/workspace/im.pidgin.libpurple/native/SslConnection.c
+++ b/android/workspace/im.pidgin.libpurple/native/SslConnection.c
@@ -37,3 +37,22 @@ Java_im_pidgin_libpurple_core_ssl_SslCon
 
 	return connection_native->port;
 }
+
+/*
+ * Class:     im_pidgin_libpurple_core_ssl_SslConnection
+ * Method:    handshakeCompleted_native
+ * Signature: ()V
+ */JNIEXPORT void JNICALL
+Java_im_pidgin_libpurple_core_ssl_SslConnection_handshakeCompleted_1native(
+		JNIEnv *env, jobject connection)
+{
+	g_log("jni", G_LOG_LEVEL_DEBUG, "ssl handshake successful");
+
+	PurpleSslConnection* connection_native;
+
+	connection_native = getNativeConnection(env, connection);
+
+	connection_native->connect_cb(connection_native->connect_cb_data,
+			connection_native, PURPLE_INPUT_READ);
+
+}
diff --git a/android/workspace/im.pidgin.libpurple/native/SslOps.c b/android/workspace/im.pidgin.libpurple/native/SslOps.c
--- a/android/workspace/im.pidgin.libpurple/native/SslOps.c
+++ b/android/workspace/im.pidgin.libpurple/native/SslOps.c
@@ -1,6 +1,8 @@
 #include "SslOps.h"
 #include "helpers.h"
 #include <libpurple/sslconn.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
 
 static JavaObjectReference ssl = JAVA_NULL_OBJECT_REF;
 
@@ -22,26 +24,66 @@ uninit()
 }
 
 static jobject
-fd_to_socket(JNIEnv *env, int unix_fd)
+get_inet_addr(JNIEnv *env, PurpleSslConnection* gsc)
+{
+	jclass inetAddrClass;
+	jmethodID inetAddrConstructionMid;
+	jobject address;
+	union {
+	    struct sockaddr sa;
+	    struct sockaddr_in sa_in;
+	} address_native;
+	socklen_t size = sizeof(address_native);
+	ssize_t address_length;
+	jbyteArray address_data;
+
+	if (getpeername(gsc->fd, &address_native.sa, &size) < 0) {
+		g_return_val_if_reached(NULL);
+	}
+
+	g_return_val_if_fail(address_native.sa.sa_family == AF_INET, NULL);
+	address_length = sizeof(address_native.sa_in.sin_addr.s_addr);
+	address_data = (*env)->NewByteArray(env, address_length);
+	g_return_val_if_fail(address_data != NULL, NULL);
+	(*env)->SetByteArrayRegion(env, address_data, 0, address_length, (jbyte*) &address_native.sa_in.sin_addr.s_addr);
+
+	inetAddrClass = (*env)->FindClass(env, "java/net/InetAddress");
+	g_return_val_if_fail(inetAddrClass != NULL, NULL);
+	inetAddrConstructionMid = (*env)->GetStaticMethodID(env, inetAddrClass, "getByAddress", "([B)Ljava/net/InetAddress;");
+	g_return_val_if_fail(inetAddrConstructionMid != NULL, NULL);
+	address = (*env)->CallStaticObjectMethod(env, inetAddrClass, inetAddrConstructionMid, address_data);
+	g_return_val_if_fail(address != NULL, NULL);
+
+	(*env)->DeleteLocalRef(env, inetAddrClass);
+	(*env)->DeleteLocalRef(env, address_data);
+	return address;
+}
+
+static jobject
+fd_to_socket(JNIEnv *env, PurpleSslConnection* gsc)
 {
 	static JavaMethodIDCache fdConstructor = METHOD_CACHE("<init>", "()V");
 	static JavaMethodIDCache socketImplConstructor =
 			METHOD_CACHE("<init>", "(Ljava/io/FileDescriptor;)V");
 	static JavaMethodIDCache socketConstructor =
 			METHOD_CACHE("<init>", "(Ljava/net/SocketImpl;)V");
+	static JavaMethodIDCache socketAccepted =
+				METHOD_CACHE("accepted", "()V");
 
 	jobject fd;
 	jclass fdClass;
 	jmethodID fdConstructorMid;
 	jfieldID fdField;
-	jobject socketImpl;
 	jclass socketImplClass;
-	jmethodID socketImplConstructorMid;
+	jfieldID socketImplAddressField;
+	jobject address;
+	jobject realSocketImpl;
+	jclass realSocketImplClass;
+	jmethodID realSocketImplConstructorMid;
 	jobject socket;
 	jclass socketClass;
 	jmethodID socketConstructorMid;
-	jfieldID connectedField;
-	jfieldID boundField;
+	jmethodID socketAcceptedMid;
 
 	fdClass = (*env)->FindClass(env, "java/io/FileDescriptor");
 	fdConstructorMid = getMethodIDCachedReferenced(env, fdClass,
@@ -50,38 +92,47 @@ fd_to_socket(JNIEnv *env, int unix_fd)
 	fd = (*env)->NewObject(env, fdClass, fdConstructorMid);
 	fdField = (*env)->GetFieldID(env, fdClass, "descriptor", "I");
 	g_return_val_if_fail(fdField != NULL, NULL);
-	(*env)->SetIntField(env, fd, fdField, unix_fd);
+	(*env)->SetIntField(env, fd, fdField, gsc->fd);
 
-	socketImplClass = (*env)->FindClass(env, "org/apache/harmony/luni/net/PlainSocketImpl");
+	socketImplClass = (*env)->FindClass(env, "java/net/SocketImpl");
+	g_return_val_if_fail(socketImplClass != NULL, NULL);
+	realSocketImplClass = (*env)->FindClass(env, "org/apache/harmony/luni/net/PlainSocketImpl");
 	if ((*env)->ExceptionOccurred(env)) {
 		/* class not found on Android 4 */
 		(*env)->ExceptionClear(env);
-		socketImplClass = (*env)->FindClass(env, "android/net/LocalSocketImpl");
+		realSocketImplClass = (*env)->FindClass(env, "android/net/LocalSocketImpl");
 	}
-	socketImplConstructorMid = getMethodIDCachedReferenced(env, socketImplClass,
+	g_return_val_if_fail(realSocketImplClass != NULL, NULL);
+	realSocketImplConstructorMid = getMethodIDCachedReferenced(env, realSocketImplClass,
 			&socketImplConstructor);
-	g_return_val_if_fail(socketImplConstructorMid != NULL, NULL);
-	socketImpl = (*env)->NewObject(env, socketImplClass,
-			socketImplConstructorMid, fd);
+	g_return_val_if_fail(realSocketImplConstructorMid != NULL, NULL);
+	realSocketImpl = (*env)->NewObject(env, realSocketImplClass,
+			realSocketImplConstructorMid, fd);
+
+	socketImplAddressField = (*env)->GetFieldID(env, socketImplClass, "address", "Ljava/net/InetAddress;");
+	address = get_inet_addr(env, gsc);
+	g_return_val_if_fail(address != NULL, NULL);
+	(*env)->SetObjectField(env, realSocketImpl, socketImplAddressField, address);
 
 	socketClass = (*env)->FindClass(env, "java/net/Socket");
 	socketConstructorMid = getMethodIDCachedReferenced(env, socketClass,
 			&socketConstructor);
 	g_return_val_if_fail(socketConstructorMid != NULL, NULL);
 	socket = (*env)->NewObject(env, socketClass, socketConstructorMid,
-			socketImpl);
+			realSocketImpl);
 
-	connectedField = (*env)->GetFieldID(env, socketClass, "isConnected", "Z");
-	g_return_val_if_fail(connectedField != NULL, NULL);
-	(*env)->SetBooleanField(env, socket, connectedField, JNI_TRUE);
-	boundField = (*env)->GetFieldID(env, socketClass, "isBound", "Z");
-	g_return_val_if_fail(boundField != NULL, NULL);
-	(*env)->SetBooleanField(env, socket, boundField, JNI_TRUE);
+	socketAcceptedMid = getMethodIDCachedReferenced(env, socketClass,
+			&socketAccepted);
+	g_return_val_if_fail(socketAcceptedMid != NULL, NULL);
+	(*env)->CallVoidMethod(env, socket, socketAcceptedMid);
+
 
 	(*env)->DeleteLocalRef(env, fd);
 	(*env)->DeleteLocalRef(env, fdClass);
-	(*env)->DeleteLocalRef(env, socketImpl);
 	(*env)->DeleteLocalRef(env, socketImplClass);
+	(*env)->DeleteLocalRef(env, realSocketImpl);
+	(*env)->DeleteLocalRef(env, realSocketImplClass);
+	(*env)->DeleteLocalRef(env, address);
 	(*env)->DeleteLocalRef(env, socketClass);
 
 	return socket;
@@ -103,7 +154,7 @@ connection_register(PurpleSslConnection*
 	jclass connectionClass;
 	jmethodID connectMid;
 
-	socket = fd_to_socket(env, gsc->fd);
+	socket = fd_to_socket(env, gsc);
 	g_return_if_fail(socket != NULL);
 
 	gsc->private_data = g_new(JavaObjectReference, 1);
@@ -171,8 +222,8 @@ readConnection(PurpleSslConnection* gsc,
 	mid = getMethodIDCachedReferenced(env, connection->java_class,
 			&methodCache);
 	if (mid != NULL) {
-		result = (*env)->CallLongMethod(env, connection->handlerObject, mid,
-				data_array, (jlong) len);
+		result = (*env)->CallIntMethod(env, connection->handlerObject, mid,
+				data_array, (jint) len);
 		(*env)->GetByteArrayRegion(env, data_array, 0, len, data);
 	}
 
@@ -202,8 +253,8 @@ writeConnection(PurpleSslConnection* gsc
 	mid = getMethodIDCachedReferenced(env, connection->java_class,
 			&methodCache);
 	if (mid != NULL) {
-		result = (*env)->CallLongMethod(env, connection->handlerObject, mid,
-				data_array, (jlong) len);
+		result = (*env)->CallIntMethod(env, connection->handlerObject, mid,
+				data_array, (jint) len);
 	}
 
 	(*env)->DeleteLocalRef(env, data_array);
diff --git a/android/workspace/im.pidgin.libpurple/native/helpers.c b/android/workspace/im.pidgin.libpurple/native/helpers.c
--- a/android/workspace/im.pidgin.libpurple/native/helpers.c
+++ b/android/workspace/im.pidgin.libpurple/native/helpers.c
@@ -80,8 +80,11 @@ notifyPeerDestroyed(JNIEnv *env, jobject
 	jclass class;
 	jmethodID mid;



More information about the Commits mailing list