mturk 2005/05/31 23:38:09 Modified: jni/java/org/apache/tomcat/jni SSL.java SSLContext.java jni/native/include ssl_private.h tcn.h jni/native/src ssl.c Log: Add BIO callback to be able to use callback inside JVM for things like logging and password prompt by overiding BIOCallback. Revision Changes Path 1.5 +17 -1 jakarta-tomcat-connectors/jni/java/org/apache/tomcat/jni/SSL.java Index: SSL.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-connectors/jni/java/org/apache/tomcat/jni/SSL.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- SSL.java 30 May 2005 06:18:06 -0000 1.4 +++ SSL.java 1 Jun 2005 06:38:09 -0000 1.5 @@ -131,4 +131,20 @@ public static native boolean randMake(String filename, int length, boolean base64); + /** + * Initialize new BIO + * @param pool The pool to use. + * @param callback BIOCallback to use + * @return New BIO handle + */ + public static native long newBIO(long pool, BIOCallback callback) + throws Exception; + + /** + * Close BIO and derefrence callback object + * @param bio BIO to close and destroy. + * @return APR Status code + */ + public static native int closeBIO(long bio); + } 1.3 +13 -3 jakarta-tomcat-connectors/jni/java/org/apache/tomcat/jni/SSLContext.java Index: SSLContext.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-connectors/jni/java/org/apache/tomcat/jni/SSLContext.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- SSLContext.java 31 May 2005 11:28:03 -0000 1.2 +++ SSLContext.java 1 Jun 2005 06:38:09 -0000 1.3 @@ -37,7 +37,8 @@ * SSL_PROTOCOL_ALL * </PRE> */ - public static native long initS(long pool, int protocol); + public static native long initS(long pool, int protocol) + throws Exception; /** * Initialize new Client context @@ -51,6 +52,15 @@ * SSL_PROTOCOL_ALL * </PRE> */ - public static native long initC(long pool, int protocol); + public static native long initC(long pool, int protocol) + throws Exception; + + /** + * Free the resources used by the Context + * @param ctx Server or Client context to free. + * @return APR Status code. + */ + public static native int free(long ctx); + } 1.5 +9 -1 jakarta-tomcat-connectors/jni/native/include/ssl_private.h Index: ssl_private.h =================================================================== RCS file: /home/cvs/jakarta-tomcat-connectors/jni/native/include/ssl_private.h,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- ssl_private.h 30 May 2005 06:17:54 -0000 1.4 +++ ssl_private.h 1 Jun 2005 06:38:09 -0000 1.5 @@ -138,4 +138,12 @@ typedef struct tcn_ssl_ctxt tcn_ssl_ctxt_t; +/* + * Additional Functions + */ +void SSL_init_app_data2_idx(void); +void *SSL_get_app_data2(SSL *); +void SSL_set_app_data2(SSL *, void *); + + #endif /* SSL_PRIVATE_H */ 1.10 +8 -7 jakarta-tomcat-connectors/jni/native/include/tcn.h Index: tcn.h =================================================================== RCS file: /home/cvs/jakarta-tomcat-connectors/jni/native/include/tcn.h,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- tcn.h 30 May 2005 06:17:54 -0000 1.9 +++ tcn.h 1 Jun 2005 06:38:09 -0000 1.10 @@ -59,7 +59,7 @@ void tcn_Throw(JNIEnv *env, const char *cname, const char *msg); void tcn_ThrowException(JNIEnv *env, const char *msg); void tcn_ThrowAPRException(JNIEnv *env, apr_status_t err); -jstring tcn_new_string(JNIEnv *env, const char *str); +jstring tcn_new_string(JNIEnv *env, const char *str, int l); char *tcn_get_string(JNIEnv *env, jstring jstr); char *tcn_strdup(JNIEnv *env, jstring jstr); char *tcn_pstrdup(JNIEnv *env, jstring jstr, apr_pool_t *p); @@ -72,8 +72,8 @@ #define J2T(T) (apr_time_t)((T)) #if 1 -#define TCN_BEGIN_MACRO { -#define TCN_END_MACRO } (void *)(0) +#define TCN_BEGIN_MACRO if (1) { +#define TCN_END_MACRO } else (void *)(0) #else #define TCN_BEGIN_MACRO do { #define TCN_END_MACRO } while (0) @@ -134,17 +134,18 @@ } \ TCN_END_MACRO +#define TCN_MAX_METHODS 8 struct tcn_callback { JNIEnv *env; jobject obj; - jmethodID mid; + jmethodID mid[TCN_MAX_METHODS]; void *opaque; }; typedef struct tcn_callback tcn_callback_t; -#ifdef TCN_DO_STATISTICS +#define TCN_MIN(a, b) ((a) < (b) ? (a) : (b)) #define TCN_MAX(a, b) ((a) > (b) ? (a) : (b)) -#endif + #endif /* TCN_H */ 1.14 +195 -2 jakarta-tomcat-connectors/jni/native/src/ssl.c Index: ssl.c =================================================================== RCS file: /home/cvs/jakarta-tomcat-connectors/jni/native/src/ssl.c,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- ssl.c 30 May 2005 06:17:54 -0000 1.13 +++ ssl.c 1 Jun 2005 06:38:09 -0000 1.14 @@ -351,6 +351,9 @@ #endif /* Initialize PRNG */ ssl_rand_seed(NULL); + /* For SSL_get_app_data2() at request time */ + SSL_init_app_data2_idx(); + /* * Let us cleanup the ssl library when the library is unloaded */ @@ -384,7 +387,7 @@ } TCN_IMPLEMENT_CALL(jboolean, SSL, randMake)(TCN_STDARGS, jstring file, - jint length, jboolean base64) + jint length, jboolean base64) { TCN_ALLOC_CSTRING(file); int r; @@ -394,6 +397,196 @@ return r ? JNI_TRUE : JNI_FALSE; } +/* OpenSSL Java Stream BIO */ + +typedef struct { + apr_pool_t *pool; + tcn_callback_t cb; +} BIO_JAVA; + +static apr_status_t generic_bio_cleanup(void *data) +{ + BIO *b = (BIO *)data; + + if (b) { + BIO_free(b); + } + return APR_SUCCESS; +} + +static int jbs_new(BIO *bi) +{ + BIO_JAVA *j; + + if ((j = OPENSSL_malloc(sizeof(BIO_JAVA))) == NULL) + return 0; + bi->shutdown = 1; + bi->init = 0; + bi->num = -1; + bi->ptr = (char *)j; + + return 1; +} + +static int jbs_free(BIO *bi) +{ + if (bi == NULL) + return 0; + if (bi->ptr != NULL) { + BIO_JAVA *j = (BIO_JAVA *)bi->ptr; + if (bi->init) { + TCN_UNLOAD_CLASS(j->cb.env, j->cb.obj); + } + bi->init = 0; + } + OPENSSL_free(bi->ptr); + bi->ptr = NULL; + return 1; +} + +static int jbs_write(BIO *b, const char *in, int inl) +{ + int ret = 0; + if (b->init && in != NULL) { + BIO_JAVA *j = (BIO_JAVA *)b->ptr; + JNIEnv *e = j->cb.env; + if ((*e)->CallIntMethod(e, j->cb.obj, + j->cb.mid[0], + tcn_new_string(e, in, inl))) + ret = inl; + } + return ret; +} + +static int jbs_read(BIO *b, char *out, int outl) +{ + int ret = 0; + if (b->init && out != NULL) { + BIO_JAVA *j = (BIO_JAVA *)b->ptr; + JNIEnv *e = j->cb.env; + jobject o; + if ((o = (*e)->CallObjectMethod(e, j->cb.obj, + j->cb.mid[1], (jint)(outl - 1)))) { + TCN_ALLOC_CSTRING(o); + if (J2S(o)) { + int l = (int)strlen(J2S(o)); + ret = TCN_MIN(outl, l); + memcpy(out, J2S(o), ret); + } + TCN_FREE_CSTRING(o); + } + } + return ret; +} + +static int jbs_puts(BIO *b, const char *in) +{ + int ret = 0; + if (b->init && in != NULL) { + BIO_JAVA *j = (BIO_JAVA *)b->ptr; + JNIEnv *e = j->cb.env; + ret = (*e)->CallIntMethod(e, j->cb.obj, + j->cb.mid[2], + tcn_new_string(e, in, -1)); + } + return ret; +} + +static int jbs_gets(BIO *b, char *out, int outl) +{ + int ret = 0; + if (b->init && out != NULL) { + BIO_JAVA *j = (BIO_JAVA *)b->ptr; + JNIEnv *e = j->cb.env; + jobject o; + if ((o = (*e)->CallObjectMethod(e, j->cb.obj, + j->cb.mid[3], (jint)(outl - 1)))) { + TCN_ALLOC_CSTRING(o); + if (J2S(o)) { + int l = (int)strlen(J2S(o)); + if (l < outl) { + strcpy(out, J2S(o)); + ret = outl; + } + } + TCN_FREE_CSTRING(o); + } + } + return ret; +} + +static long jbs_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + return 0; +} + +static BIO_METHOD jbs_methods = { + BIO_TYPE_FILE, + "JavaString Stream", + jbs_write, + jbs_read, + jbs_puts, + jbs_gets, + jbs_ctrl, + jbs_new, + jbs_free, + NULL +}; + +static BIO_METHOD *BIO_jbs() +{ + return(&jbs_methods); +} + +TCN_IMPLEMENT_CALL(jlong, SSL, newBIO)(TCN_STDARGS, jlong pool, + jobject callback) +{ + BIO *bio = NULL; + BIO_JAVA *j; + jclass cls; + + UNREFERENCED(o); + + if ((bio = BIO_new(BIO_jbs())) == NULL) { + tcn_ThrowException(e, "Create BIO failed"); + goto init_failed; + } + j = (BIO_JAVA *)bio->ptr; + j->pool = J2P(pool, apr_pool_t *); + if (j->pool) { + apr_pool_cleanup_register(j->pool, (const void *)bio, + generic_bio_cleanup, + apr_pool_cleanup_null); + } + + cls = (*e)->GetObjectClass(e, callback); + j->cb.env = e; + j->cb.mid[0] = (*e)->GetMethodID(e, cls, "write", "(Ljava/lang/String;)I"); + j->cb.mid[1] = (*e)->GetMethodID(e, cls, "read", "(I)Ljava/lang/String;"); + j->cb.mid[2] = (*e)->GetMethodID(e, cls, "puts", "(Ljava/lang/String;)I"); + j->cb.mid[3] = (*e)->GetMethodID(e, cls, "gets", "(I)Ljava/lang/String;"); + /* TODO: Check if method id's are valid */ + j->cb.obj = (*e)->NewGlobalRef(e, callback); + + bio->init = 1; + return P2J(bio); +init_failed: + return 0; +} + +TCN_IMPLEMENT_CALL(jint, SSL, closeBIO)(TCN_STDARGS, jlong bio) +{ + BIO *b = J2P(bio, BIO *); + BIO_JAVA *j; + + UNREFERENCED_STDARGS; + j = (BIO_JAVA *)b->ptr; + if (j->pool) { + apr_pool_cleanup_run(j->pool, b, generic_bio_cleanup); + } + return APR_SUCCESS; +} + #else /* OpenSSL is not supported * If someday we make OpenSSL optional
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]