From ef3cc55525877ffaa6a6b329b6c91c97191c3985 Mon Sep 17 00:00:00 2001 From: "nicolson%netscape.com" Date: Sat, 10 Feb 2001 02:49:33 +0000 Subject: [PATCH] fill out SSLSocket with more methods. --- security/jss/org/mozilla/jss/ssl/SSLSocket.c | 262 ++++++++++++++++-- .../jss/org/mozilla/jss/ssl/SSLSocket.java | 143 +++++----- 2 files changed, 308 insertions(+), 97 deletions(-) diff --git a/security/jss/org/mozilla/jss/ssl/SSLSocket.c b/security/jss/org/mozilla/jss/ssl/SSLSocket.c index 1ad1cc9fa302..829c1a9f007d 100644 --- a/security/jss/org/mozilla/jss/ssl/SSLSocket.c +++ b/security/jss/org/mozilla/jss/ssl/SSLSocket.c @@ -102,10 +102,16 @@ DestroyJSSL_SocketData(JNIEnv *env, JSSL_SocketData *sd) } +/* + * These must match up with the constants defined in SSLSocket.java. + */ static PRInt32 enums[] = { SSL_ENABLE_SSL2, /* 0 */ SSL_ENABLE_SSL3, /* 1 */ - SO_LINGER, /* 2 */ + PR_SockOpt_NoDelay, /* 2 */ + PR_SockOpt_Keepalive, /* 3 */ + PR_SHUTDOWN_RCV, /* 4 */ + PR_SHUTDOWN_SEND, /* 5 */ 0 }; @@ -157,9 +163,7 @@ Java_org_mozilla_jss_ssl_SSLSocket_forceHandshake(JNIEnv *env, jobject self) int rv; /* get my fd */ - if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS ) { - goto finish; - } + if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS ) goto finish; /* do the work */ rv = SSL_ForceHandshake(sock->fd); @@ -172,31 +176,6 @@ Java_org_mozilla_jss_ssl_SSLSocket_forceHandshake(JNIEnv *env, jobject self) finish: } -JNIEXPORT void JNICALL -Java_org_mozilla_jss_ssl_SSLSocket_setTcpNoDelay(JNIEnv *env, jobject self, - jboolean on) -{ - PRSocketOptionData sockOptions; - PRStatus status; - JSSL_SocketData *sock; - - if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS ) { - goto finish; - } - - sockOptions.option = PR_SockOpt_NoDelay; - sockOptions.value.no_delay = on; - - status = PR_SetSocketOption(sock->fd, &sockOptions); - - if( status != PR_SUCCESS ) { - JSS_throwMsg(env, SOCKET_EXCEPTION, "PR_SetSocketOption failed"); - goto finish; - } - -finish: -} - /* * linger * The linger time, in hundredths of a second. @@ -253,6 +232,176 @@ finish: return sockOptions.value.no_delay; } +JNIEXPORT void JNICALL +Java_org_mozilla_jss_ssl_SSLSocket_setTcpNoDelay(JNIEnv *env, jobject self, + jboolean on) +{ + PRSocketOptionData sockOptions; + PRStatus status; + JSSL_SocketData *sock; + + if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS ) { + goto finish; + } + + sockOptions.option = PR_SockOpt_NoDelay; + sockOptions.value.no_delay = on; + + status = PR_SetSocketOption(sock->fd, &sockOptions); + + if( status != PR_SUCCESS ) { + JSS_throwMsg(env, SOCKET_EXCEPTION, "PR_SetSocketOption failed"); + goto finish; + } + +finish: +} + +JNIEXPORT jint JNICALL +Java_org_mozilla_jss_ssl_SSLSocket_getSendBufferSize(JNIEnv *env, jobject self) +{ + PRSocketOptionData sockOptions; + JSSL_SocketData *sock; + PRStatus status; + + if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS ) { + goto finish; + } + + sockOptions.option = PR_SockOpt_SendBufferSize; + + status = PR_GetSocketOption(sock->fd, &sockOptions); + if( status != PR_SUCCESS ) { + JSS_throwMsg(env, SOCKET_EXCEPTION, "PR_GetSocketOption failed"); + goto finish; + } + +finish: + return sockOptions.value.send_buffer_size; +} + +JNIEXPORT void JNICALL +Java_org_mozilla_jss_ssl_SSLSocket_setSendBufferSize(JNIEnv *env, jobject self, + jint size) +{ + PRSocketOptionData sockOptions; + PRStatus status; + JSSL_SocketData *sock; + + if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS ) { + goto finish; + } + + sockOptions.option = PR_SockOpt_SendBufferSize; + sockOptions.value.send_buffer_size = size; + + status = PR_SetSocketOption(sock->fd, &sockOptions); + + if( status != PR_SUCCESS ) { + JSS_throwMsg(env, SOCKET_EXCEPTION, "PR_SetSocketOption failed"); + goto finish; + } + +finish: +} + +JNIEXPORT jboolean JNICALL +Java_org_mozilla_jss_ssl_SSLSocket_getKeepAlive(JNIEnv *env, jobject self) +{ + PRSocketOptionData sockOptions; + JSSL_SocketData *sock; + PRStatus status; + + if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS ) { + goto finish; + } + + sockOptions.option = PR_SockOpt_Keepalive; + + status = PR_GetSocketOption(sock->fd, &sockOptions); + if( status != PR_SUCCESS ) { + JSS_throwMsg(env, SOCKET_EXCEPTION, "PR_GetSocketOption failed"); + goto finish; + } + +finish: + return sockOptions.value.keep_alive; +} + +JNIEXPORT jint JNICALL +Java_org_mozilla_jss_ssl_SSLSocket_getReceiveBufferSize( + JNIEnv *env, jobject self) +{ + PRSocketOptionData sockOptions; + JSSL_SocketData *sock; + PRStatus status; + + if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS ) { + goto finish; + } + + sockOptions.option = PR_SockOpt_RecvBufferSize; + + status = PR_GetSocketOption(sock->fd, &sockOptions); + if( status != PR_SUCCESS ) { + JSS_throwMsg(env, SOCKET_EXCEPTION, "PR_GetSocketOption failed"); + goto finish; + } + +finish: + return sockOptions.value.recv_buffer_size; +} + +JNIEXPORT void JNICALL +Java_org_mozilla_jss_ssl_SSLSocket_setReceiveBufferSize( + JNIEnv *env, jobject self, jint size) +{ + PRSocketOptionData sockOptions; + PRStatus status; + JSSL_SocketData *sock; + + if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS ) { + goto finish; + } + + sockOptions.option = PR_SockOpt_RecvBufferSize; + sockOptions.value.recv_buffer_size = size; + + status = PR_SetSocketOption(sock->fd, &sockOptions); + + if( status != PR_SUCCESS ) { + JSS_throwMsg(env, SOCKET_EXCEPTION, "PR_SetSocketOption failed"); + goto finish; + } + +finish: +} + +JNIEXPORT void JNICALL +Java_org_mozilla_jss_ssl_SSLSocket_setKeepAlive(JNIEnv *env, jobject self, + jboolean on) +{ + PRSocketOptionData sockOptions; + PRStatus status; + JSSL_SocketData *sock; + + if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS ) { + goto finish; + } + + sockOptions.option = PR_SockOpt_Keepalive; + sockOptions.value.keep_alive = on; + + status = PR_SetSocketOption(sock->fd, &sockOptions); + + if( status != PR_SUCCESS ) { + JSS_throwMsg(env, SOCKET_EXCEPTION, "PR_SetSocketOption failed"); + goto finish; + } + +finish: +} + JNIEXPORT jint JNICALL Java_org_mozilla_jss_ssl_SSLSocket_getSoLinger(JNIEnv *env, jobject self) { @@ -319,7 +468,7 @@ Java_org_mozilla_jss_ssl_SSLSocket_getLocalAddressNative(JNIEnv *env, } JNIEXPORT jint JNICALL -Java_org_mozilla_jss_ssl_SSLSocket_getLocalPort(JNIEnv *env, +Java_org_mozilla_jss_ssl_SSLSocket_getLocalPortNative(JNIEnv *env, jobject self) { PRNetAddr addr; @@ -907,3 +1056,56 @@ finish: (*env)->ReleaseByteArrayElements(env, bufBA, buf, JNI_ABORT); } } + +JNIEXPORT void JNICALL +Java_org_mozilla_jss_ssl_SSLSocket_shutdownNative( + JNIEnv *env, jobject self, jint how) +{ + JSSL_SocketData *sock; + PRStatus status; + + if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish; + + status = PR_Shutdown(sock->fd, enums[how]); + if( status != PR_SUCCESS) { + JSS_throwMsg(env, SOCKET_EXCEPTION, "Failed to shutdown socket"); + goto finish; + } + +finish: +} + +JNIEXPORT void JNICALL +Java_org_mozilla_jss_ssl_SSLSocket_invalidateSession(JNIEnv *env, jobject self) +{ + JSSL_SocketData *sock; + SECStatus status; + + if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish; + + status = SSL_InvalidateSession(sock->fd); + if(status != SECSuccess) { + JSS_throwMsg(env, SOCKET_EXCEPTION, "Failed to invalidate session"); + goto finish; + } + +finish: +} + +JNIEXPORT void JNICALL +Java_org_mozilla_jss_ssl_SSLSocket_redoHandshake( + JNIEnv *env, jobject self, jboolean flushCache) +{ + JSSL_SocketData *sock; + SECStatus status; + + if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish; + + status = SSL_ReHandshake(sock->fd, flushCache); + if(status != SECSuccess) { + JSS_throwMsg(env, SOCKET_EXCEPTION, "Failed to redo handshake"); + goto finish; + } + +finish: +} diff --git a/security/jss/org/mozilla/jss/ssl/SSLSocket.java b/security/jss/org/mozilla/jss/ssl/SSLSocket.java index 1f4433e23156..b177a5a97ac6 100644 --- a/security/jss/org/mozilla/jss/ssl/SSLSocket.java +++ b/security/jss/org/mozilla/jss/ssl/SSLSocket.java @@ -38,7 +38,7 @@ import java.io.*; import java.util.LinkedList; import java.util.ListIterator; -public class SSLSocket { +public class SSLSocket extends java.net.Socket { /** * For sockets that get created by accept(). @@ -127,44 +127,62 @@ public class SSLSocket { } - public InetAddress getInetAddress() throws SocketException { - int intAddr = getPeerAddressNative(); - InetAddress in; - byte[] addr = new byte[4]; - addr[0] = (byte)((intAddr >>> 24) & 0xff); - addr[1] = (byte)((intAddr >>> 16) & 0xff); - addr[2] = (byte)((intAddr >>> 8) & 0xff); - addr[3] = (byte)((intAddr ) & 0xff); + public InetAddress getInetAddress() { try { - in = InetAddress.getByName( - addr[0] + "." + addr[1] + "." + addr[2] + "." + addr[3] ); - } catch (java.net.UnknownHostException e) { - in = null; + int intAddr = getPeerAddressNative(); + InetAddress in; + byte[] addr = new byte[4]; + addr[0] = (byte)((intAddr >>> 24) & 0xff); + addr[1] = (byte)((intAddr >>> 16) & 0xff); + addr[2] = (byte)((intAddr >>> 8) & 0xff); + addr[3] = (byte)((intAddr ) & 0xff); + try { + in = InetAddress.getByName( + addr[0] + "." + addr[1] + "." + addr[2] + "." + addr[3] ); + } catch (java.net.UnknownHostException e) { + in = null; + } + return in; + } catch(SocketException e) { + e.printStackTrace(); + return null; } - return in; } private native int getPeerAddressNative() throws SocketException; - public InetAddress getLocalAddress() throws SocketException { - int intAddr = getLocalAddressNative(); - InetAddress in; - byte[] addr = new byte[4]; - addr[0] = (byte)((intAddr >>> 24) & 0xff); - addr[1] = (byte)((intAddr >>> 16) & 0xff); - addr[2] = (byte)((intAddr >>> 8) & 0xff); - addr[3] = (byte)((intAddr ) & 0xff); + public InetAddress getLocalAddress() { try { - in = InetAddress.getByName( - addr[0] + "." + addr[1] + "." + addr[2] + "." + addr[3] ); - } catch (java.net.UnknownHostException e) { - in = null; + int intAddr = getLocalAddressNative(); + InetAddress in; + byte[] addr = new byte[4]; + addr[0] = (byte)((intAddr >>> 24) & 0xff); + addr[1] = (byte)((intAddr >>> 16) & 0xff); + addr[2] = (byte)((intAddr >>> 8) & 0xff); + addr[3] = (byte)((intAddr ) & 0xff); + try { + in = InetAddress.getByName( + addr[0] + "." + addr[1] + "." + addr[2] + "." + addr[3] ); + } catch (java.net.UnknownHostException e) { + in = null; + } + return in; + } catch(SocketException e) { + e.printStackTrace(); + return null; } - return in; } private native int getLocalAddressNative() throws SocketException; - private native int getLocalPort() throws SocketException; + public int getLocalPort() { + try { + return getLocalPortNative(); + } catch(SocketException e) { + e.printStackTrace(); + return 0; + } + } + private native int getLocalPortNative() throws SocketException; public native int getPort(); @@ -181,6 +199,20 @@ public class SSLSocket { public native boolean getTcpNoDelay() throws SocketException; + public native void setKeepAlive(boolean on) throws SocketException; + + public native boolean getKeepAlive(boolean on) throws SocketException; + + public void shutdownInput() throws IOException { + shutdownNative(PR_SHUTDOWN_RCV); + } + + public void shutdownOutput() throws IOException { + shutdownNative(PR_SHUTDOWN_SEND); + } + + private native void shutdownNative(int how) throws IOException; + /** * param linger The time (in hundredths of a second) to linger for. */ @@ -200,18 +232,10 @@ public class SSLSocket { // // XXX These aren't implemented by native code. Perhaps they could be. // - public void setSendBufferSize(int size) throws SocketException { - throw new SocketException("not implemented"); - } - public int getSendBufferSize() throws SocketException { - throw new SocketException("not implemented"); - } - public void setReceiveBufferSize(int size) throws SocketException { - throw new SocketException("not implemented"); - } - public int getReceiveBufferSize(int size) throws SocketException { - throw new SocketException("not implemented"); - } + public native void setSendBufferSize(int size) throws SocketException; + public native int getSendBufferSize() throws SocketException; + public native void setReceiveBufferSize(int size) throws SocketException; + public native int getReceiveBufferSize(int size) throws SocketException; public void close() throws IOException { if( sockProxy != null ) { @@ -284,7 +308,10 @@ public class SSLSocket { */ private static final int SSL_ENABLE_SSL2 = 0; private static final int SSL_ENABLE_SSL3 = 1; - private static final int SO_LINGER = 2; + private static final int TCP_NODELAY = 2; + private static final int SO_KEEPALIVE = 3; + private static final int PR_SHUTDOWN_RCV = 4; + private static final int PR_SHUTDOWN_SEND = 5; /** * SO_TIMEOUT timeout in millis. I don't know why we have to keep it here @@ -329,32 +356,14 @@ public class SSLSocket { private native void socketWrite(byte[] b, int off, int len, int timeout) throws IOException; -/* - protected static native void setPermittedByPolicy(int cipher, - int permitted); - public static native void configServerSessionIDCache(int maxSidEntries, - public static native void clearSessionCache(); - protected native int invalidateSession(); - native SSLSecurityStatus getStatus(); // throws ???? - native void resetHandshake(); // throws ???? - native void forceHandshake(); // throws ???? - native void redoHandshake(); // throws ???? - private native void socketConnect(InetAddress address, int port) - throws IOException; - private native void socketBind(InetAddress address, int port) - throws IOException; - private native void socketListen(int count) - throws IOException; - private native void socketAccept(SocketImpl s) - throws IOException; - private native void socketSetNeedClientAuth(boolean b); - private native void socketSetNeedClientAuthNoExpiryCheck(boolean b); - private native void socketSetOptionIntVal(int cmd, boolean on, int value) - throws SocketException; - private native int socketGetOption(int opt) throws SocketException; - private native void setClientNickname(String nickname); - private native void setServerNickname(String nickname); -*/ + + public native void invalidateSession() throws SocketException; + + public void redoHandshake() throws SocketException { + redoHandshake(false); + } + + public native void redoHandshake(boolean flushCache) throws SocketException; protected void finalize() throws Throwable { close();