| /* |
| * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| #include "sun_security_jgss_wrapper_GSSLibStub.h" |
| #include "NativeUtil.h" |
| #include "NativeFunc.h" |
| |
| /* Constants for indicating what type of info is needed for inqueries */ |
| const int TYPE_CRED_NAME = 10; |
| const int TYPE_CRED_TIME = 11; |
| const int TYPE_CRED_USAGE = 12; |
| |
| /* |
| * Class: sun_security_jgss_wrapper_GSSLibStub |
| * Method: init |
| * Signature: (Ljava/lang/String;)Z |
| */ |
| JNIEXPORT jboolean JNICALL |
| Java_sun_security_jgss_wrapper_GSSLibStub_init(JNIEnv *env, |
| jclass jcls, |
| jstring jlibName) { |
| const char *libName; |
| char *error = NULL; |
| |
| if (jlibName == NULL) { |
| debug(env, "[GSSLibStub_init] GSS lib name is NULL"); |
| return JNI_FALSE; |
| } |
| |
| libName = (*env)->GetStringUTFChars(env, jlibName, NULL); |
| sprintf(debugBuf, "[GSSLibStub_init] libName=%s", libName); |
| debug(env, debugBuf); |
| |
| /* initialize global function table */ |
| error = loadNative(libName); |
| (*env)->ReleaseStringUTFChars(env, jlibName, libName); |
| |
| if (error == NULL) { |
| return JNI_TRUE; |
| } else { |
| debug(env, error); |
| return JNI_FALSE; |
| } |
| } |
| |
| /* |
| * Class: sun_security_jgss_wrapper_GSSLibStub |
| * Method: getMechPtr |
| * Signature: ([B)J |
| */ |
| JNIEXPORT jlong JNICALL |
| Java_sun_security_jgss_wrapper_GSSLibStub_getMechPtr(JNIEnv *env, |
| jclass jcls, |
| jbyteArray jbytes) { |
| gss_OID cOid; |
| int i, len; |
| jbyte* bytes; |
| jthrowable gssEx; |
| jboolean found; |
| |
| if (jbytes != NULL) { |
| found = JNI_FALSE; |
| len = (*env)->GetArrayLength(env, jbytes) - 2; |
| bytes = (*env)->GetByteArrayElements(env, jbytes, NULL); |
| if (bytes != NULL) { |
| for (i = 0; i < ftab->mechs->count; i++) { |
| cOid = &(ftab->mechs->elements[i]); |
| if (len == cOid->length && |
| (memcmp(cOid->elements, (bytes + 2), len) == 0)) { |
| // Found a match |
| found = JNI_TRUE; |
| break; |
| } |
| } |
| (*env)->ReleaseByteArrayElements(env, jbytes, bytes, 0); |
| } |
| if (found != JNI_TRUE) { |
| checkStatus(env, NULL, GSS_S_BAD_MECH, 0, "[GSSLibStub_getMechPtr]"); |
| return NULL; |
| } else return cOid; |
| } else return GSS_C_NO_OID; |
| } |
| |
| |
| /* |
| * Utility routine which creates a gss_channel_bindings_t structure |
| * using the specified org.ietf.jgss.ChannelBinding object. |
| */ |
| gss_channel_bindings_t getGSSCB(JNIEnv *env, jobject jcb) { |
| gss_channel_bindings_t cb; |
| jobject jinetAddr; |
| jbyteArray value; |
| |
| if (jcb == NULL) { |
| return GSS_C_NO_CHANNEL_BINDINGS; |
| } |
| cb = malloc(sizeof(struct gss_channel_bindings_struct)); |
| /* set up initiator address */ |
| jinetAddr = |
| (*env)->CallObjectMethod(env, jcb, |
| MID_ChannelBinding_getInitiatorAddr); |
| if (jinetAddr != NULL) { |
| cb->initiator_addrtype = GSS_C_AF_INET; |
| value = (*env)->CallObjectMethod(env, jinetAddr, |
| MID_InetAddress_getAddr); |
| initGSSBuffer(env, value, &(cb->initiator_address)); |
| } else { |
| cb->initiator_addrtype = GSS_C_AF_NULLADDR; |
| cb->initiator_address.length = 0; |
| cb->initiator_address.value = NULL; |
| } |
| /* set up acceptor address */ |
| jinetAddr = |
| (*env)->CallObjectMethod(env, jcb, |
| MID_ChannelBinding_getAcceptorAddr); |
| if (jinetAddr != NULL) { |
| cb->acceptor_addrtype = GSS_C_AF_INET; |
| value = (*env)->CallObjectMethod(env, jinetAddr, |
| MID_InetAddress_getAddr); |
| initGSSBuffer(env, value, &(cb->acceptor_address)); |
| } else { |
| cb->acceptor_addrtype = GSS_C_AF_NULLADDR; |
| cb->acceptor_address.length = 0; |
| cb->acceptor_address.value = NULL; |
| } |
| /* set up application data */ |
| value = (*env)->CallObjectMethod(env, jcb, |
| MID_ChannelBinding_getAppData); |
| if (value != NULL) { |
| initGSSBuffer(env, value, &(cb->application_data)); |
| } else { |
| cb->application_data.length = 0; |
| cb->application_data.value = NULL; |
| } |
| return cb; |
| } |
| |
| /* |
| * Utility routine which releases the specified gss_channel_bindings_t |
| * structure. |
| */ |
| void releaseGSSCB(JNIEnv *env, jobject jcb, gss_channel_bindings_t cb) { |
| jobject jinetAddr; |
| jbyteArray value; |
| |
| if (cb == GSS_C_NO_CHANNEL_BINDINGS) return; |
| /* release initiator address */ |
| if (cb->initiator_addrtype != GSS_C_AF_NULLADDR) { |
| jinetAddr = |
| (*env)->CallObjectMethod(env, jcb, |
| MID_ChannelBinding_getInitiatorAddr); |
| value = (*env)->CallObjectMethod(env, jinetAddr, |
| MID_InetAddress_getAddr); |
| resetGSSBuffer(env, value, &(cb->initiator_address)); |
| } |
| /* release acceptor address */ |
| if (cb->acceptor_addrtype != GSS_C_AF_NULLADDR) { |
| jinetAddr = |
| (*env)->CallObjectMethod(env, jcb, |
| MID_ChannelBinding_getAcceptorAddr); |
| value = (*env)->CallObjectMethod(env, jinetAddr, |
| MID_InetAddress_getAddr); |
| resetGSSBuffer(env, value, &(cb->acceptor_address)); |
| } |
| /* release application data */ |
| if (cb->application_data.length != 0) { |
| value = (*env)->CallObjectMethod(env, jcb, |
| MID_ChannelBinding_getAppData); |
| resetGSSBuffer(env, value, &(cb->application_data)); |
| } |
| free(cb); |
| } |
| |
| /* |
| * Utility routine for storing the supplementary information |
| * into the specified org.ietf.jgss.MessageProp object. |
| */ |
| void setSupplementaryInfo(JNIEnv *env, jobject jstub, jobject jprop, |
| int suppInfo, int minor) { |
| jboolean isDuplicate, isOld, isUnseq, hasGap; |
| jstring minorMsg; |
| |
| if (suppInfo != GSS_S_COMPLETE) { |
| isDuplicate = ((suppInfo & GSS_S_DUPLICATE_TOKEN) != 0); |
| isOld = ((suppInfo & GSS_S_OLD_TOKEN) != 0); |
| isUnseq = ((suppInfo & GSS_S_UNSEQ_TOKEN) != 0); |
| hasGap = ((suppInfo & GSS_S_GAP_TOKEN) != 0); |
| minorMsg = getMinorMessage(env, jstub, minor); |
| (*env)->CallVoidMethod(env, jprop, MID_MessageProp_setSupplementaryStates, |
| isDuplicate, isOld, isUnseq, hasGap, minor, |
| minorMsg); |
| } |
| } |
| |
| /* |
| * Class: sun_security_jgss_wrapper_GSSLibStub |
| * Method: indicateMechs |
| * Signature: ()[Lorg/ietf/jgss/Oid; |
| */ |
| JNIEXPORT jobjectArray JNICALL |
| Java_sun_security_jgss_wrapper_GSSLibStub_indicateMechs(JNIEnv *env, |
| jclass jcls) |
| { |
| if (ftab->mechs != NULL && ftab->mechs != GSS_C_NO_OID_SET) { |
| return getJavaOIDArray(env, ftab->mechs); |
| } else return NULL; |
| } |
| |
| /* |
| * Class: sun_security_jgss_wrapper_GSSLibStub |
| * Method: inquireNamesForMech |
| * Signature: ()[Lorg/ietf/jgss/Oid; |
| */ |
| JNIEXPORT jobjectArray JNICALL |
| Java_sun_security_jgss_wrapper_GSSLibStub_inquireNamesForMech(JNIEnv *env, |
| jobject jobj) |
| { |
| OM_uint32 minor, major; |
| gss_OID mech; |
| gss_OID_set nameTypes; |
| jobjectArray result; |
| |
| if (ftab->inquireNamesForMech != NULL) { |
| |
| mech = (gss_OID) (*env)->GetLongField(env, jobj, FID_GSSLibStub_pMech); |
| nameTypes = GSS_C_NO_OID_SET; |
| |
| /* gss_inquire_names_for_mech(...) => N/A */ |
| major = (*ftab->inquireNamesForMech)(&minor, mech, &nameTypes); |
| |
| result = getJavaOIDArray(env, nameTypes); |
| |
| /* release intermediate buffers */ |
| deleteGSSOIDSet(nameTypes); |
| |
| checkStatus(env, jobj, major, minor, "[GSSLibStub_inquireNamesForMech]"); |
| return result; |
| } else return NULL; |
| } |
| |
| /* |
| * Class: sun_security_jgss_wrapper_GSSLibStub |
| * Method: releaseName |
| * Signature: (J)V |
| */ |
| JNIEXPORT void JNICALL |
| Java_sun_security_jgss_wrapper_GSSLibStub_releaseName(JNIEnv *env, |
| jobject jobj, |
| jlong pName) |
| { |
| OM_uint32 minor, major; |
| gss_name_t nameHdl; |
| |
| nameHdl = (gss_name_t) pName; |
| |
| sprintf(debugBuf, "[GSSLibStub_releaseName] %ld", (long) pName); |
| debug(env, debugBuf); |
| |
| if (nameHdl != GSS_C_NO_NAME) { |
| /* gss_release_name(...) => GSS_S_BAD_NAME */ |
| major = (*ftab->releaseName)(&minor, &nameHdl); |
| checkStatus(env, jobj, major, minor, "[GSSLibStub_releaseName]"); |
| } |
| } |
| |
| /* |
| * Class: sun_security_jgss_wrapper_GSSLibStub |
| * Method: importName |
| * Signature: ([BLorg/ietf/jgss/Oid;)J |
| */ |
| JNIEXPORT jlong JNICALL |
| Java_sun_security_jgss_wrapper_GSSLibStub_importName(JNIEnv *env, |
| jobject jobj, |
| jbyteArray jnameVal, |
| jobject jnameType) |
| { |
| OM_uint32 minor, major; |
| gss_buffer_desc nameVal; |
| gss_OID nameType; |
| gss_name_t nameHdl; |
| |
| debug(env, "[GSSLibStub_importName]"); |
| |
| initGSSBuffer(env, jnameVal, &nameVal); |
| nameType = newGSSOID(env, jnameType); |
| nameHdl = GSS_C_NO_NAME; |
| |
| /* gss_import_name(...) => GSS_S_BAD_NAMETYPE, GSS_S_BAD_NAME, |
| GSS_S_BAD_MECH */ |
| major = (*ftab->importName)(&minor, &nameVal, nameType, &nameHdl); |
| |
| sprintf(debugBuf, "[GSSLibStub_importName] %ld", (long) nameHdl); |
| debug(env, debugBuf); |
| |
| /* release intermediate buffers */ |
| deleteGSSOID(nameType); |
| resetGSSBuffer(env, jnameVal, &nameVal); |
| |
| checkStatus(env, jobj, major, minor, "[GSSLibStub_importName]"); |
| return (jlong) nameHdl; |
| } |
| |
| |
| /* |
| * Class: sun_security_jgss_wrapper_GSSLibStub |
| * Method: compareName |
| * Signature: (JJ)Z |
| */ |
| JNIEXPORT jboolean JNICALL |
| Java_sun_security_jgss_wrapper_GSSLibStub_compareName(JNIEnv *env, |
| jobject jobj, |
| jlong pName1, |
| jlong pName2) |
| { |
| OM_uint32 minor, major; |
| gss_name_t nameHdl1, nameHdl2; |
| int isEqual; |
| |
| isEqual = 0; |
| nameHdl1 = (gss_name_t) pName1; |
| nameHdl2 = (gss_name_t) pName2; |
| |
| sprintf(debugBuf, "[GSSLibStub_compareName] %ld %ld", (long) pName1, |
| (long) pName2); |
| debug(env, debugBuf); |
| |
| if ((nameHdl1 != GSS_C_NO_NAME) && (nameHdl2 != GSS_C_NO_NAME)) { |
| |
| /* gss_compare_name(...) => GSS_S_BAD_NAMETYPE, GSS_S_BAD_NAME(!) */ |
| major = (*ftab->compareName)(&minor, nameHdl1, nameHdl2, &isEqual); |
| |
| checkStatus(env, jobj, major, minor, "[GSSLibStub_compareName]"); |
| } |
| return (isEqual != 0); |
| } |
| |
| /* |
| * Class: sun_security_jgss_wrapper_GSSLibStub |
| * Method: canonicalizeName |
| * Signature: (J)J |
| */ |
| JNIEXPORT jlong JNICALL |
| Java_sun_security_jgss_wrapper_GSSLibStub_canonicalizeName(JNIEnv *env, |
| jobject jobj, |
| jlong pName) |
| { |
| OM_uint32 minor, major; |
| gss_name_t nameHdl, mnNameHdl; |
| gss_OID mech; |
| |
| nameHdl = (gss_name_t) pName; |
| sprintf(debugBuf, "[GSSLibStub_canonicalizeName] %ld", (long) pName); |
| debug(env, debugBuf); |
| |
| if (nameHdl != GSS_C_NO_NAME) { |
| mech = (gss_OID) (*env)->GetLongField(env, jobj, FID_GSSLibStub_pMech); |
| mnNameHdl = GSS_C_NO_NAME; |
| |
| /* gss_canonicalize_name(...) may return GSS_S_BAD_NAMETYPE, |
| GSS_S_BAD_NAME, GSS_S_BAD_MECH */ |
| major = (*ftab->canonicalizeName)(&minor, nameHdl, mech, &mnNameHdl); |
| |
| sprintf(debugBuf, "[GSSLibStub_canonicalizeName] MN=%ld", |
| (long)mnNameHdl); |
| debug(env, debugBuf); |
| |
| /* release intermediate buffers */ |
| |
| checkStatus(env, jobj, major, minor, "[GSSLibStub_canonicalizeName]"); |
| } else mnNameHdl = GSS_C_NO_NAME; |
| |
| return (jlong) mnNameHdl; |
| } |
| |
| /* |
| * Class: sun_security_jgss_wrapper_GSSLibStub |
| * Method: exportName |
| * Signature: (J)[B |
| */ |
| JNIEXPORT jbyteArray JNICALL |
| Java_sun_security_jgss_wrapper_GSSLibStub_exportName(JNIEnv *env, |
| jobject jobj, |
| jlong pName) { |
| OM_uint32 minor, major; |
| gss_name_t nameHdl, mNameHdl; |
| gss_buffer_desc outBuf; |
| jbyteArray jresult; |
| |
| nameHdl = (gss_name_t) pName; |
| sprintf(debugBuf, "[GSSLibStub_exportName] %ld", (long) pName); |
| debug(env, debugBuf); |
| |
| /* gss_export_name(...) => GSS_S_NAME_NOT_MN, GSS_S_BAD_NAMETYPE, |
| GSS_S_BAD_NAME */ |
| major = (*ftab->exportName)(&minor, nameHdl, &outBuf); |
| |
| /* canonicalize the internal name to MN and retry */ |
| if (major == GSS_S_NAME_NOT_MN) { |
| debug(env, "[GSSLibStub_exportName] canonicalize and re-try"); |
| |
| mNameHdl = (gss_name_t) |
| Java_sun_security_jgss_wrapper_GSSLibStub_canonicalizeName |
| (env, jobj, pName); |
| /* return immediately if an exception has occurred */ |
| if ((*env)->ExceptionCheck(env)) { |
| return NULL; |
| } |
| major = (*ftab->exportName)(&minor, mNameHdl, &outBuf); |
| Java_sun_security_jgss_wrapper_GSSLibStub_releaseName |
| (env, jobj, (jlong) mNameHdl); |
| /* return immediately if an exception has occurred */ |
| if ((*env)->ExceptionCheck(env)) { |
| return NULL; |
| } |
| } |
| |
| /* release intermediate buffers */ |
| jresult = getJavaBuffer(env, &outBuf); |
| |
| checkStatus(env, jobj, major, minor, "[GSSLibStub_exportName]"); |
| return jresult; |
| } |
| |
| /* |
| * Class: sun_security_jgss_wrapper_GSSLibStub |
| * Method: displayName |
| * Signature: (J)[Ljava/lang/Object; |
| */ |
| JNIEXPORT jobjectArray JNICALL |
| Java_sun_security_jgss_wrapper_GSSLibStub_displayName(JNIEnv *env, |
| jobject jobj, |
| jlong pName) { |
| OM_uint32 minor, major; |
| gss_name_t nameHdl; |
| gss_buffer_desc outNameBuf; |
| gss_OID outNameType; |
| jstring jname; |
| jobject jtype; |
| jobjectArray jresult; |
| |
| nameHdl = (gss_name_t) pName; |
| sprintf(debugBuf, "[GSSLibStub_displayName] %ld", (long) pName); |
| debug(env, debugBuf); |
| |
| if (nameHdl == GSS_C_NO_NAME) { |
| checkStatus(env, jobj, GSS_S_BAD_NAME, 0, "[GSSLibStub_displayName]"); |
| return NULL; |
| } |
| |
| /* gss_display_name(...) => GSS_S_BAD_NAME */ |
| major = (*ftab->displayName)(&minor, nameHdl, &outNameBuf, &outNameType); |
| |
| /* release intermediate buffers */ |
| jname = getJavaString(env, &outNameBuf); |
| |
| jtype = getJavaOID(env, outNameType); |
| jresult = (*env)->NewObjectArray(env, 2, CLS_Object, NULL); |
| |
| /* return immediately if an exception has occurred */ |
| if ((*env)->ExceptionCheck(env)) { |
| return NULL; |
| } |
| |
| (*env)->SetObjectArrayElement(env, jresult, 0, jname); |
| (*env)->SetObjectArrayElement(env, jresult, 1, jtype); |
| |
| checkStatus(env, jobj, major, minor, "[GSSLibStub_displayName]"); |
| return jresult; |
| } |
| |
| /* |
| * Class: sun_security_jgss_wrapper_GSSLibStub |
| * Method: acquireCred |
| * Signature: (JII)J |
| */ |
| JNIEXPORT jlong JNICALL |
| Java_sun_security_jgss_wrapper_GSSLibStub_acquireCred(JNIEnv *env, |
| jobject jobj, |
| jlong pName, |
| jint reqTime, |
| jint usage) |
| { |
| OM_uint32 minor, major; |
| gss_OID mech; |
| gss_OID_set mechs; |
| gss_cred_usage_t credUsage; |
| gss_name_t nameHdl; |
| gss_cred_id_t credHdl; |
| |
| debug(env, "[GSSLibStub_acquireCred]"); |
| |
| |
| mech = (gss_OID) (*env)->GetLongField(env, jobj, FID_GSSLibStub_pMech); |
| mechs = newGSSOIDSet(env, mech); |
| credUsage = (gss_cred_usage_t) usage; |
| nameHdl = (gss_name_t) pName; |
| credHdl = GSS_C_NO_CREDENTIAL; |
| |
| sprintf(debugBuf, "[GSSLibStub_acquireCred] pName=%ld, usage=%d", |
| (long) pName, usage); |
| debug(env, debugBuf); |
| |
| /* gss_acquire_cred(...) => GSS_S_BAD_MECH, GSS_S_BAD_NAMETYPE, |
| GSS_S_BAD_NAME, GSS_S_CREDENTIALS_EXPIRED, GSS_S_NO_CRED */ |
| major = |
| (*ftab->acquireCred)(&minor, nameHdl, reqTime, mechs, |
| credUsage, &credHdl, NULL, NULL); |
| /* release intermediate buffers */ |
| deleteGSSOIDSet(mechs); |
| |
| sprintf(debugBuf, "[GSSLibStub_acquireCred] pCred=%ld", (long) credHdl); |
| debug(env, debugBuf); |
| |
| checkStatus(env, jobj, major, minor, "[GSSLibStub_acquireCred]"); |
| return (jlong) credHdl; |
| } |
| |
| /* |
| * Class: sun_security_jgss_wrapper_GSSLibStub |
| * Method: releaseCred |
| * Signature: (J)J |
| */ |
| JNIEXPORT jlong JNICALL |
| Java_sun_security_jgss_wrapper_GSSLibStub_releaseCred(JNIEnv *env, |
| jobject jobj, |
| jlong pCred) |
| { |
| OM_uint32 minor, major; |
| gss_cred_id_t credHdl; |
| |
| credHdl = (gss_cred_id_t) pCred; |
| |
| sprintf(debugBuf, "[GSSLibStub_releaseCred] %ld", pCred); |
| debug(env, debugBuf); |
| |
| if (credHdl != GSS_C_NO_CREDENTIAL) { |
| |
| /* gss_release_cred(...) => GSS_S_NO_CRED(!) */ |
| major = (*ftab->releaseCred)(&minor, &credHdl); |
| |
| checkStatus(env, jobj, major, minor, "[GSSLibStub_releaseCred]"); |
| } |
| return (jlong) credHdl; |
| } |
| |
| /* |
| * Utility routine for obtaining info about a credential. |
| */ |
| void inquireCred(JNIEnv *env, jobject jobj, gss_cred_id_t pCred, |
| jint type, void *result) { |
| OM_uint32 minor, major; |
| OM_uint32 routineErr; |
| gss_cred_id_t credHdl; |
| |
| credHdl = pCred; |
| |
| sprintf(debugBuf, "[gss_inquire_cred] %ld", (long) pCred); |
| debug(env, debugBuf); |
| |
| /* gss_inquire_cred(...) => GSS_S_DEFECTIVE_CREDENTIAL(!), |
| GSS_S_CREDENTIALS_EXPIRED(!), GSS_S_NO_CRED(!) */ |
| if (type == TYPE_CRED_NAME) { |
| major = (*ftab->inquireCred)(&minor, credHdl, result, NULL, NULL, NULL); |
| } else if (type == TYPE_CRED_TIME) { |
| major = (*ftab->inquireCred)(&minor, credHdl, NULL, result, NULL, NULL); |
| } else if (type == TYPE_CRED_USAGE) { |
| major = (*ftab->inquireCred)(&minor, credHdl, NULL, NULL, result, NULL); |
| } |
| |
| /* release intermediate buffers */ |
| |
| routineErr = GSS_ROUTINE_ERROR(major); |
| if (routineErr == GSS_S_CREDENTIALS_EXPIRED) { |
| /* ignore GSS_S_CREDENTIALS_EXPIRED for query */ |
| major = GSS_CALLING_ERROR(major) | |
| GSS_SUPPLEMENTARY_INFO(major); |
| } else if (routineErr == GSS_S_NO_CRED) { |
| /* twik since Java API throws BAD_MECH instead of NO_CRED */ |
| major = GSS_CALLING_ERROR(major) | |
| GSS_S_BAD_MECH | GSS_SUPPLEMENTARY_INFO(major); |
| } |
| checkStatus(env, jobj, major, minor, "[gss_inquire_cred]"); |
| } |
| |
| /* |
| * Class: sun_security_jgss_wrapper_GSSLibStub |
| * Method: getCredName |
| * Signature: (J)J |
| */ |
| JNIEXPORT jlong JNICALL |
| Java_sun_security_jgss_wrapper_GSSLibStub_getCredName(JNIEnv *env, |
| jobject jobj, |
| jlong pCred) |
| { |
| gss_name_t nameHdl; |
| gss_cred_id_t credHdl; |
| |
| credHdl = (gss_cred_id_t) pCred; |
| |
| sprintf(debugBuf, "[GSSLibStub_getCredName] %ld", pCred); |
| debug(env, debugBuf); |
| |
| nameHdl = GSS_C_NO_NAME; |
| inquireCred(env, jobj, credHdl, TYPE_CRED_NAME, &nameHdl); |
| |
| /* return immediately if an exception has occurred */ |
| if ((*env)->ExceptionCheck(env)) { |
| return 0; |
| } |
| |
| sprintf(debugBuf, "[GSSLibStub_getCredName] pName=%ld", (long) nameHdl); |
| debug(env, debugBuf); |
| |
| return (jlong) nameHdl; |
| } |
| |
| /* |
| * Class: sun_security_jgss_wrapper_GSSLibStub |
| * Method: getCredTime |
| * Signature: (J)I |
| */ |
| JNIEXPORT jint JNICALL |
| Java_sun_security_jgss_wrapper_GSSLibStub_getCredTime(JNIEnv *env, |
| jobject jobj, |
| jlong pCred) |
| { |
| gss_cred_id_t credHdl; |
| OM_uint32 lifetime; |
| |
| credHdl = (gss_cred_id_t) pCred; |
| |
| sprintf(debugBuf, "[GSSLibStub_getCredTime] %ld", pCred); |
| debug(env, debugBuf); |
| |
| lifetime = 0; |
| inquireCred(env, jobj, credHdl, TYPE_CRED_TIME, &lifetime); |
| |
| /* return immediately if an exception has occurred */ |
| if ((*env)->ExceptionCheck(env)) { |
| return 0; |
| } |
| return getJavaTime(lifetime); |
| } |
| |
| /* |
| * Class: sun_security_jgss_wrapper_GSSLibStub |
| * Method: getCredUsage |
| * Signature: (J)I |
| */ |
| JNIEXPORT jint JNICALL |
| Java_sun_security_jgss_wrapper_GSSLibStub_getCredUsage(JNIEnv *env, |
| jobject jobj, |
| jlong pCred) |
| { |
| gss_cred_usage_t usage; |
| gss_cred_id_t credHdl; |
| |
| credHdl = (gss_cred_id_t) pCred; |
| |
| sprintf(debugBuf, "[GSSLibStub_getCredUsage] %ld", pCred); |
| debug(env, debugBuf); |
| |
| inquireCred(env, jobj, credHdl, TYPE_CRED_USAGE, &usage); |
| |
| /* return immediately if an exception has occurred */ |
| if ((*env)->ExceptionCheck(env)) { |
| return -1; |
| } |
| return (jint) usage; |
| } |
| /* |
| * Class: sun_security_jgss_wrapper_GSSLibStub |
| * Method: importContext |
| * Signature: ([B)Lsun/security/jgss/wrapper/NativeGSSContext; |
| */ |
| JNIEXPORT jobject JNICALL |
| Java_sun_security_jgss_wrapper_GSSLibStub_importContext(JNIEnv *env, |
| jobject jobj, |
| jbyteArray jctxtToken) |
| { |
| OM_uint32 minor, major; |
| gss_buffer_desc ctxtToken; |
| gss_ctx_id_t contextHdl; |
| gss_OID mech, mech2; |
| |
| debug(env, "[GSSLibStub_importContext]"); |
| |
| contextHdl = GSS_C_NO_CONTEXT; |
| initGSSBuffer(env, jctxtToken, &ctxtToken); |
| |
| /* gss_import_sec_context(...) => GSS_S_NO_CONTEXT, GSS_S_DEFECTIVE_TOKEN, |
| GSS_S_UNAVAILABLE, GSS_S_UNAUTHORIZED */ |
| major = (*ftab->importSecContext)(&minor, &ctxtToken, &contextHdl); |
| |
| sprintf(debugBuf, "[GSSLibStub_importContext] pContext=%ld", |
| (long) contextHdl); |
| debug(env, debugBuf); |
| |
| /* release intermediate buffers */ |
| resetGSSBuffer(env, jctxtToken, &ctxtToken); |
| |
| checkStatus(env, jobj, major, minor, "[GSSLibStub_importContext]"); |
| /* return immediately if an exception has occurred */ |
| if ((*env)->ExceptionCheck(env)) { |
| return NULL; |
| } |
| |
| /* now that the context has been imported, proceed to find out |
| its mech */ |
| major = (*ftab->inquireContext)(&minor, contextHdl, NULL, NULL, |
| NULL, &mech, NULL, NULL, NULL); |
| |
| checkStatus(env, jobj, major, minor, "[GSSLibStub_importContext] getMech"); |
| /* return immediately if an exception has occurred */ |
| if ((*env)->ExceptionCheck(env)) { |
| return NULL; |
| } |
| |
| mech2 = (gss_OID) (*env)->GetLongField(env, jobj, FID_GSSLibStub_pMech); |
| |
| if (sameMech(env, mech, mech2) == JNI_TRUE) { |
| /* mech match - return the context object */ |
| return (*env)->NewObject(env, CLS_NativeGSSContext, |
| MID_NativeGSSContext_ctor, |
| (jlong) contextHdl, jobj); |
| } else { |
| /* mech mismatch - clean up then return null */ |
| major = (*ftab->deleteSecContext)(&minor, &contextHdl, GSS_C_NO_BUFFER); |
| checkStatus(env, jobj, major, minor, |
| "[GSSLibStub_importContext] cleanup"); |
| return NULL; |
| } |
| } |
| /* |
| * Class: sun_security_jgss_wrapper_GSSLibStub |
| * Method: initContext |
| * Signature: (JJLorg/ietf/jgss/ChannelBinding;[BLsun/security/jgss/wrapper/NativeGSSContext;)[B |
| */ |
| JNIEXPORT jbyteArray JNICALL |
| Java_sun_security_jgss_wrapper_GSSLibStub_initContext(JNIEnv *env, |
| jobject jobj, |
| jlong pCred, |
| jlong pName, |
| jobject jcb, |
| jbyteArray jinToken, |
| jobject jcontextSpi) |
| { |
| OM_uint32 minor, major; |
| gss_cred_id_t credHdl ; |
| gss_ctx_id_t contextHdl; |
| gss_name_t targetName; |
| gss_OID mech; |
| OM_uint32 flags, aFlags; |
| OM_uint32 time, aTime; |
| gss_channel_bindings_t cb; |
| gss_buffer_desc inToken; |
| gss_buffer_desc outToken; |
| jbyteArray jresult; |
| /* UNCOMMENT after SEAM bug#6287358 is backported to S10 |
| gss_OID aMech; |
| jobject jMech; |
| */ |
| debug(env, "[GSSLibStub_initContext]"); |
| |
| credHdl = (gss_cred_id_t) pCred; |
| contextHdl = (gss_ctx_id_t) |
| (*env)->GetLongField(env, jcontextSpi, FID_NativeGSSContext_pContext); |
| targetName = (gss_name_t) pName; |
| mech = (gss_OID) (*env)->GetLongField(env, jobj, FID_GSSLibStub_pMech); |
| flags = (OM_uint32) (*env)->GetIntField(env, jcontextSpi, |
| FID_NativeGSSContext_flags); |
| time = getGSSTime((*env)->GetIntField(env, jcontextSpi, |
| FID_NativeGSSContext_lifetime)); |
| cb = getGSSCB(env, jcb); |
| initGSSBuffer(env, jinToken, &inToken); |
| |
| sprintf(debugBuf, |
| "[GSSLibStub_initContext] before: pCred=%ld, pContext=%ld", |
| (long)credHdl, (long)contextHdl); |
| debug(env, debugBuf); |
| |
| /* gss_init_sec_context(...) => GSS_S_CONTINUE_NEEDED(!), |
| GSS_S_DEFECTIVE_TOKEN, GSS_S_NO_CRED, GSS_S_DEFECTIVE_CREDENTIAL(!), |
| GSS_S_CREDENTIALS_EXPIRED, GSS_S_BAD_BINDINGS, GSS_S_BAD_MIC, |
| GSS_S_OLD_TOKEN, GSS_S_DUPLICATE_TOKEN, GSS_S_NO_CONTEXT(!), |
| GSS_S_BAD_NAMETYPE, GSS_S_BAD_NAME(!), GSS_S_BAD_MECH */ |
| major = (*ftab->initSecContext)(&minor, credHdl, |
| &contextHdl, targetName, mech, |
| flags, time, cb, &inToken, NULL /*aMech*/, |
| &outToken, &aFlags, &aTime); |
| |
| sprintf(debugBuf, "[GSSLibStub_initContext] after: pContext=%ld", |
| (long)contextHdl); |
| debug(env, debugBuf); |
| sprintf(debugBuf, "[GSSLibStub_initContext] outToken len=%ld", |
| (long)outToken.length); |
| debug(env, debugBuf); |
| |
| if (GSS_ERROR(major) == GSS_S_COMPLETE) { |
| /* update member values if needed */ |
| (*env)->SetLongField(env, jcontextSpi, FID_NativeGSSContext_pContext, |
| (jlong) contextHdl); |
| (*env)->SetIntField(env, jcontextSpi, FID_NativeGSSContext_flags, aFlags); |
| sprintf(debugBuf, "[GSSLibStub_initContext] set flags=0x%x", aFlags); |
| debug(env, debugBuf); |
| |
| if (major == GSS_S_COMPLETE) { |
| (*env)->SetIntField(env, jcontextSpi, FID_NativeGSSContext_lifetime, |
| getJavaTime(aTime)); |
| debug(env, "[GSSLibStub_initContext] context established"); |
| |
| (*env)->SetBooleanField(env, jcontextSpi, |
| FID_NativeGSSContext_isEstablished, |
| JNI_TRUE); |
| |
| /* UNCOMMENT after SEAM bug#6287358 is backported to S10 |
| jMech = getJavaOID(env, aMech); |
| (*env)->SetObjectField(env, jcontextSpi, |
| FID_NativeGSSContext_actualMech, jMech); |
| */ |
| } else if (major & GSS_S_CONTINUE_NEEDED) { |
| debug(env, "[GSSLibStub_initContext] context not established"); |
| major -= GSS_S_CONTINUE_NEEDED; |
| } |
| } |
| /* release intermediate buffers */ |
| releaseGSSCB(env, jcb, cb); |
| resetGSSBuffer(env, jinToken, &inToken); |
| jresult = getJavaBuffer(env, &outToken); |
| |
| checkStatus(env, jobj, major, minor, "[GSSLibStub_initContext]"); |
| return jresult; |
| } |
| |
| /* |
| * Class: sun_security_jgss_wrapper_GSSLibStub |
| * Method: acceptContext |
| * Signature: (JLorg/ietf/jgss/ChannelBinding;[BLsun/security/jgss/wrapper/NativeGSSContext;)[B |
| */ |
| JNIEXPORT jbyteArray JNICALL |
| Java_sun_security_jgss_wrapper_GSSLibStub_acceptContext(JNIEnv *env, |
| jobject jobj, |
| jlong pCred, |
| jobject jcb, |
| jbyteArray jinToken, |
| jobject jcontextSpi) |
| { |
| OM_uint32 minor, major; |
| OM_uint32 minor2, major2; |
| gss_ctx_id_t contextHdl; |
| gss_cred_id_t credHdl; |
| gss_buffer_desc inToken; |
| gss_channel_bindings_t cb; |
| gss_name_t srcName; |
| gss_buffer_desc outToken; |
| gss_OID aMech; |
| OM_uint32 aFlags; |
| OM_uint32 aTime; |
| gss_cred_id_t delCred; |
| jobject jsrcName; |
| jobject jdelCred; |
| jobject jMech; |
| jbyteArray jresult; |
| jboolean setTarget; |
| gss_name_t targetName; |
| jobject jtargetName; |
| |
| debug(env, "[GSSLibStub_acceptContext]"); |
| |
| contextHdl = (gss_ctx_id_t) |
| (*env)->GetLongField(env, jcontextSpi, FID_NativeGSSContext_pContext); |
| credHdl = (gss_cred_id_t) pCred; |
| initGSSBuffer(env, jinToken, &inToken); |
| cb = getGSSCB(env, jcb); |
| srcName = GSS_C_NO_NAME; |
| delCred = GSS_C_NO_CREDENTIAL; |
| setTarget = (credHdl == GSS_C_NO_CREDENTIAL); |
| aFlags = 0; |
| |
| sprintf(debugBuf, |
| "[GSSLibStub_acceptContext] before: pCred=%ld, pContext=%ld", |
| (long) credHdl, (long) contextHdl); |
| debug(env, debugBuf); |
| |
| /* gss_accept_sec_context(...) => GSS_S_CONTINUE_NEEDED(!), |
| GSS_S_DEFECTIVE_TOKEN, GSS_S_DEFECTIVE_CREDENTIAL(!), |
| GSS_S_NO_CRED, GSS_S_CREDENTIALS_EXPIRED, GSS_S_BAD_BINDINGS, |
| GSS_S_NO_CONTEXT(!), GSS_S_BAD_MIC, GSS_S_OLD_TOKEN, |
| GSS_S_DUPLICATE_TOKEN, GSS_S_BAD_MECH */ |
| major = |
| (*ftab->acceptSecContext)(&minor, &contextHdl, credHdl, |
| &inToken, cb, &srcName, &aMech, &outToken, |
| &aFlags, &aTime, &delCred); |
| |
| sprintf(debugBuf, |
| "[GSSLibStub_acceptContext] after: pCred=%ld, pContext=%ld, pDelegCred=%ld", |
| (long)credHdl, (long)contextHdl, (long) delCred); |
| debug(env, debugBuf); |
| |
| if (GSS_ERROR(major) == GSS_S_COMPLETE) { |
| /* update member values if needed */ |
| (*env)->SetLongField(env, jcontextSpi, FID_NativeGSSContext_pContext, |
| (jlong) contextHdl); |
| sprintf(debugBuf, "[GSSLibStub_acceptContext] set pContext=%ld", |
| (long)contextHdl); |
| debug(env, debugBuf); |
| // WORKAROUND for a Heimdal bug |
| if (delCred == GSS_C_NO_CREDENTIAL) { |
| aFlags &= 0xfffffffe; |
| } |
| (*env)->SetIntField(env, jcontextSpi, FID_NativeGSSContext_flags, aFlags); |
| sprintf(debugBuf, "[GSSLibStub_acceptContext] set flags=0x%x", |
| aFlags); |
| debug(env, debugBuf); |
| if (setTarget) { |
| major2 = (*ftab->inquireContext)(&minor2, contextHdl, NULL, |
| &targetName, NULL, NULL, NULL, |
| NULL, NULL); |
| jtargetName = (*env)->NewObject(env, CLS_GSSNameElement, |
| MID_GSSNameElement_ctor, |
| (jlong) targetName, jobj); |
| |
| /* return immediately if an exception has occurred */ |
| if ((*env)->ExceptionCheck(env)) { |
| return NULL; |
| } |
| sprintf(debugBuf, "[GSSLibStub_acceptContext] set targetName=%ld", |
| (long)targetName); |
| debug(env, debugBuf); |
| (*env)->SetObjectField(env, jcontextSpi, FID_NativeGSSContext_targetName, |
| jtargetName); |
| } |
| if (srcName != GSS_C_NO_NAME) { |
| jsrcName = (*env)->NewObject(env, CLS_GSSNameElement, |
| MID_GSSNameElement_ctor, |
| (jlong) srcName, jobj); |
| /* return immediately if an exception has occurred */ |
| if ((*env)->ExceptionCheck(env)) { |
| return NULL; |
| } |
| sprintf(debugBuf, "[GSSLibStub_acceptContext] set srcName=%ld", |
| (long)srcName); |
| debug(env, debugBuf); |
| (*env)->SetObjectField(env, jcontextSpi, FID_NativeGSSContext_srcName, |
| jsrcName); |
| } |
| if (major == GSS_S_COMPLETE) { |
| debug(env, "[GSSLibStub_acceptContext] context established"); |
| |
| (*env)->SetIntField(env, jcontextSpi, FID_NativeGSSContext_lifetime, |
| getJavaTime(aTime)); |
| |
| (*env)->SetBooleanField(env, jcontextSpi, |
| FID_NativeGSSContext_isEstablished, |
| JNI_TRUE); |
| jMech = getJavaOID(env, aMech); |
| (*env)->SetObjectField(env, jcontextSpi, |
| FID_NativeGSSContext_actualMech, jMech); |
| if (delCred != GSS_C_NO_CREDENTIAL) { |
| jdelCred = (*env)->NewObject(env, CLS_GSSCredElement, |
| MID_GSSCredElement_ctor, |
| (jlong) delCred, jsrcName, jMech); |
| /* return immediately if an exception has occurred */ |
| if ((*env)->ExceptionCheck(env)) { |
| return NULL; |
| } |
| (*env)->SetObjectField(env, jcontextSpi, |
| FID_NativeGSSContext_delegatedCred, |
| jdelCred); |
| sprintf(debugBuf, "[GSSLibStub_acceptContext] set delegatedCred=%ld", |
| (long) delCred); |
| debug(env, debugBuf); |
| } |
| } else if (major & GSS_S_CONTINUE_NEEDED) { |
| debug(env, "[GSSLibStub_acceptContext] context not established"); |
| |
| if (aFlags & GSS_C_PROT_READY_FLAG) { |
| (*env)->SetIntField(env, jcontextSpi, FID_NativeGSSContext_lifetime, |
| getJavaTime(aTime)); |
| } |
| major -= GSS_S_CONTINUE_NEEDED; |
| } |
| } |
| /* release intermediate buffers */ |
| releaseGSSCB(env, jcb, cb); |
| resetGSSBuffer(env, jinToken, &inToken); |
| jresult = getJavaBuffer(env, &outToken); |
| |
| checkStatus(env, jobj, major, minor, "[GSSLibStub_acceptContext]"); |
| return jresult; |
| } |
| |
| /* |
| * Class: sun_security_jgss_wrapper_GSSLibStub |
| * Method: inquireContext |
| * Signature: (J)[J |
| */ |
| JNIEXPORT jlongArray JNICALL |
| Java_sun_security_jgss_wrapper_GSSLibStub_inquireContext(JNIEnv *env, |
| jobject jobj, |
| jlong pContext) |
| { |
| OM_uint32 minor, major; |
| gss_ctx_id_t contextHdl; |
| gss_name_t srcName, targetName; |
| OM_uint32 time; |
| OM_uint32 flags; |
| int isInitiator, isEstablished; |
| jlong result[6]; |
| jlongArray jresult; |
| |
| contextHdl = (gss_ctx_id_t) pContext; |
| |
| sprintf(debugBuf, "[GSSLibStub_inquireContext] %ld", (long)contextHdl); |
| debug(env, debugBuf); |
| |
| srcName = targetName = GSS_C_NO_NAME; |
| time = 0; |
| flags = isInitiator = isEstablished = 0; |
| |
| /* gss_inquire_context(...) => GSS_S_NO_CONTEXT(!) */ |
| major = (*ftab->inquireContext)(&minor, contextHdl, &srcName, |
| &targetName, &time, NULL, &flags, |
| &isInitiator, &isEstablished); |
| /* update member values if needed */ |
| sprintf(debugBuf, "[GSSLibStub_inquireContext] srcName %ld", (long)srcName); |
| debug(env, debugBuf); |
| sprintf(debugBuf, "[GSSLibStub_inquireContext] targetName %ld", |
| (long)targetName); |
| debug(env, debugBuf); |
| |
| result[0] = (jlong) srcName; |
| result[1] = (jlong) targetName; |
| result[2] = (jlong) isInitiator; |
| result[3] = (jlong) isEstablished; |
| result[4] = (jlong) flags; |
| result[5] = (jlong) getJavaTime(time); |
| |
| jresult = (*env)->NewLongArray(env, 6); |
| (*env)->SetLongArrayRegion(env, jresult, 0, 6, result); |
| |
| /* release intermediate buffers */ |
| |
| checkStatus(env, jobj, major, minor, "[GSSLibStub_inquireContext]"); |
| return jresult; |
| } |
| |
| /* |
| * Class: sun_security_jgss_wrapper_GSSLibStub |
| * Method: getContextMech |
| * Signature: (J)Lorg/ietf/jgss/Oid; |
| */ |
| JNIEXPORT jobject JNICALL |
| Java_sun_security_jgss_wrapper_GSSLibStub_getContextMech(JNIEnv *env, |
| jobject jobj, |
| jlong pContext) |
| { |
| OM_uint32 minor, major; |
| gss_OID mech; |
| gss_ctx_id_t contextHdl; |
| |
| contextHdl = (gss_ctx_id_t) pContext; |
| |
| sprintf(debugBuf, "[GSSLibStub_getContextMech] %ld", pContext); |
| debug(env, debugBuf); |
| |
| major = (*ftab->inquireContext)(&minor, contextHdl, NULL, NULL, |
| NULL, &mech, NULL, NULL, NULL); |
| |
| checkStatus(env, jobj, major, minor, "[GSSLibStub_getContextMech]"); |
| /* return immediately if an exception has occurred */ |
| if ((*env)->ExceptionCheck(env)) { |
| return NULL; |
| } |
| |
| return getJavaOID(env, mech); |
| } |
| |
| /* |
| * Class: sun_security_jgss_wrapper_GSSLibStub |
| * Method: getContextName |
| * Signature: (JZ)J |
| */ |
| JNIEXPORT jlong JNICALL |
| Java_sun_security_jgss_wrapper_GSSLibStub_getContextName(JNIEnv *env, |
| jobject jobj, jlong pContext, jboolean isSrc) |
| { |
| OM_uint32 minor, major; |
| gss_name_t nameHdl; |
| gss_ctx_id_t contextHdl; |
| |
| contextHdl = (gss_ctx_id_t) pContext; |
| |
| sprintf(debugBuf, "[GSSLibStub_getContextName] %ld, isSrc=%d", |
| (long)contextHdl, isSrc); |
| debug(env, debugBuf); |
| |
| nameHdl = GSS_C_NO_NAME; |
| if (isSrc == JNI_TRUE) { |
| major = (*ftab->inquireContext)(&minor, contextHdl, &nameHdl, NULL, |
| NULL, NULL, NULL, NULL, NULL); |
| } else { |
| major = (*ftab->inquireContext)(&minor, contextHdl, NULL, &nameHdl, |
| NULL, NULL, NULL, NULL, NULL); |
| } |
| |
| checkStatus(env, jobj, major, minor, "[GSSLibStub_inquireContextAll]"); |
| /* return immediately if an exception has occurred */ |
| if ((*env)->ExceptionCheck(env)) { |
| return (long)NULL; |
| } |
| |
| sprintf(debugBuf, "[GSSLibStub_getContextName] pName=%ld", (long) nameHdl); |
| debug(env, debugBuf); |
| |
| return (jlong) nameHdl; |
| } |
| |
| /* |
| * Class: sun_security_jgss_wrapper_GSSLibStub |
| * Method: getContextTime |
| * Signature: (J)I |
| */ |
| JNIEXPORT jint JNICALL |
| Java_sun_security_jgss_wrapper_GSSLibStub_getContextTime(JNIEnv *env, |
| jobject jobj, |
| jlong pContext) { |
| OM_uint32 minor, major; |
| gss_ctx_id_t contextHdl; |
| OM_uint32 time; |
| |
| contextHdl = (gss_ctx_id_t) pContext; |
| sprintf(debugBuf, "[GSSLibStub_getContextTime] %ld", (long)contextHdl); |
| debug(env, debugBuf); |
| |
| if (contextHdl == GSS_C_NO_CONTEXT) return 0; |
| |
| /* gss_context_time(...) => GSS_S_CONTEXT_EXPIRED(!), |
| GSS_S_NO_CONTEXT(!) */ |
| major = (*ftab->contextTime)(&minor, contextHdl, &time); |
| if (GSS_ROUTINE_ERROR(major) == GSS_S_CONTEXT_EXPIRED) { |
| major = GSS_CALLING_ERROR(major) | GSS_SUPPLEMENTARY_INFO(major); |
| } |
| checkStatus(env, jobj, major, minor, "[GSSLibStub_getContextTime]"); |
| return getJavaTime(time); |
| } |
| |
| /* |
| * Class: sun_security_jgss_wrapper_GSSLibStub |
| * Method: deleteContext |
| * Signature: (J)J |
| */ |
| JNIEXPORT jlong JNICALL |
| Java_sun_security_jgss_wrapper_GSSLibStub_deleteContext(JNIEnv *env, |
| jobject jobj, |
| jlong pContext) |
| { |
| OM_uint32 minor, major; |
| gss_ctx_id_t contextHdl; |
| |
| contextHdl = (gss_ctx_id_t) pContext; |
| sprintf(debugBuf, "[GSSLibStub_deleteContext] %ld", (long)contextHdl); |
| debug(env, debugBuf); |
| |
| if (contextHdl == GSS_C_NO_CONTEXT) return GSS_C_NO_CONTEXT; |
| |
| /* gss_delete_sec_context(...) => GSS_S_NO_CONTEXT(!) */ |
| major = (*ftab->deleteSecContext)(&minor, &contextHdl, GSS_C_NO_BUFFER); |
| |
| checkStatus(env, jobj, major, minor, "[GSSLibStub_deleteContext]"); |
| return (jlong) contextHdl; |
| } |
| |
| /* |
| * Class: sun_security_jgss_wrapper_GSSLibStub |
| * Method: wrapSizeLimit |
| * Signature: (JIII)I |
| */ |
| JNIEXPORT jint JNICALL |
| Java_sun_security_jgss_wrapper_GSSLibStub_wrapSizeLimit(JNIEnv *env, |
| jobject jobj, |
| jlong pContext, |
| jint reqFlag, |
| jint jqop, |
| jint joutSize) |
| { |
| OM_uint32 minor, major; |
| gss_ctx_id_t contextHdl; |
| OM_uint32 outSize, maxInSize; |
| gss_qop_t qop; |
| |
| contextHdl = (gss_ctx_id_t) pContext; |
| sprintf(debugBuf, "[GSSLibStub_wrapSizeLimit] %ld", (long)contextHdl); |
| debug(env, debugBuf); |
| |
| // Check context handle?? |
| |
| qop = (gss_qop_t) jqop; |
| outSize = (OM_uint32) joutSize; |
| maxInSize = 0; |
| /* gss_wrap_size_limit(...) => GSS_S_NO_CONTEXT(!), GSS_S_CONTEXT_EXPIRED, |
| GSS_S_BAD_QOP */ |
| major = (*ftab->wrapSizeLimit)(&minor, contextHdl, reqFlag, |
| qop, outSize, &maxInSize); |
| |
| checkStatus(env, jobj, major, minor, "[GSSLibStub_wrapSizeLimit]"); |
| return (jint) maxInSize; |
| } |
| |
| /* |
| * Class: sun_security_jgss_wrapper_GSSLibStub |
| * Method: exportContext |
| * Signature: (J)[B |
| */ |
| JNIEXPORT jbyteArray JNICALL |
| Java_sun_security_jgss_wrapper_GSSLibStub_exportContext(JNIEnv *env, |
| jobject jobj, |
| jlong pContext) |
| { |
| OM_uint32 minor, major; |
| gss_ctx_id_t contextHdl; |
| gss_buffer_desc interProcToken; |
| jbyteArray jresult; |
| |
| contextHdl = (gss_ctx_id_t) pContext; |
| sprintf(debugBuf, "[GSSLibStub_exportContext] %ld", (long)contextHdl); |
| debug(env, debugBuf); |
| |
| if (contextHdl == GSS_C_NO_CONTEXT) { |
| // Twik per javadoc |
| checkStatus(env, jobj, GSS_S_NO_CONTEXT, 0, "[GSSLibStub_exportContext]"); |
| return NULL; |
| } |
| /* gss_export_sec_context(...) => GSS_S_CONTEXT_EXPIRED, |
| GSS_S_NO_CONTEXT, GSS_S_UNAVAILABLE */ |
| major = |
| (*ftab->exportSecContext)(&minor, &contextHdl, &interProcToken); |
| |
| /* release intermediate buffers */ |
| jresult = getJavaBuffer(env, &interProcToken); |
| checkStatus(env, jobj, major, minor, "[GSSLibStub_exportContext]"); |
| return jresult; |
| } |
| |
| /* |
| * Class: sun_security_jgss_wrapper_GSSLibStub |
| * Method: getMic |
| * Signature: (JI[B)[B |
| */ |
| JNIEXPORT jbyteArray JNICALL |
| Java_sun_security_jgss_wrapper_GSSLibStub_getMic(JNIEnv *env, jobject jobj, |
| jlong pContext, jint jqop, |
| jbyteArray jmsg) |
| { |
| OM_uint32 minor, major; |
| gss_ctx_id_t contextHdl; |
| gss_qop_t qop; |
| gss_buffer_desc msg; |
| gss_buffer_desc msgToken; |
| jbyteArray jresult; |
| |
| contextHdl = (gss_ctx_id_t) pContext; |
| sprintf(debugBuf, "[GSSLibStub_getMic] %ld", (long)contextHdl); |
| debug(env, debugBuf); |
| |
| if (contextHdl == GSS_C_NO_CONTEXT) { |
| // Twik per javadoc |
| checkStatus(env, jobj, GSS_S_CONTEXT_EXPIRED, 0, "[GSSLibStub_getMic]"); |
| return NULL; |
| } |
| contextHdl = (gss_ctx_id_t) pContext; |
| qop = (gss_qop_t) jqop; |
| initGSSBuffer(env, jmsg, &msg); |
| |
| /* gss_get_mic(...) => GSS_S_CONTEXT_EXPIRED, GSS_S_NO_CONTEXT(!), |
| GSS_S_BAD_QOP */ |
| major = |
| (*ftab->getMic)(&minor, contextHdl, qop, &msg, &msgToken); |
| |
| /* release intermediate buffers */ |
| resetGSSBuffer(env, jmsg, &msg); |
| jresult = getJavaBuffer(env, &msgToken); |
| |
| checkStatus(env, jobj, major, minor, "[GSSLibStub_getMic]"); |
| return jresult; |
| } |
| |
| /* |
| * Class: sun_security_jgss_wrapper_GSSLibStub |
| * Method: verifyMic |
| * Signature: (J[B[BLorg/ietf/jgss/MessageProp;)V |
| */ |
| JNIEXPORT void JNICALL |
| Java_sun_security_jgss_wrapper_GSSLibStub_verifyMic(JNIEnv *env, |
| jobject jobj, |
| jlong pContext, |
| jbyteArray jmsgToken, |
| jbyteArray jmsg, |
| jobject jprop) |
| { |
| OM_uint32 minor, major; |
| gss_ctx_id_t contextHdl; |
| gss_buffer_desc msg; |
| gss_buffer_desc msgToken; |
| gss_qop_t qop; |
| |
| contextHdl = (gss_ctx_id_t) pContext; |
| sprintf(debugBuf, "[GSSLibStub_verifyMic] %ld", (long)contextHdl); |
| debug(env, debugBuf); |
| |
| if (contextHdl == GSS_C_NO_CONTEXT) { |
| // Twik per javadoc |
| checkStatus(env, jobj, GSS_S_CONTEXT_EXPIRED, 0, |
| "[GSSLibStub_verifyMic]"); |
| return; |
| } |
| initGSSBuffer(env, jmsg, &msg); |
| initGSSBuffer(env, jmsgToken, &msgToken); |
| qop = (gss_qop_t) (*env)->CallIntMethod(env, jprop, MID_MessageProp_getQOP); |
| /* gss_verify_mic(...) => GSS_S_DEFECTIVE_TOKEN, GSS_S_BAD_MIC, |
| GSS_S_CONTEXT_EXPIRED, GSS_S_DUPLICATE_TOKEN(!), GSS_S_OLD_TOKEN(!), |
| GSS_S_UNSEQ_TOKEN(!), GSS_S_GAP_TOKEN(!), GSS_S_NO_CONTEXT(!) */ |
| major = |
| (*ftab->verifyMic)(&minor, contextHdl, &msg, &msgToken, &qop); |
| |
| /* release intermediate buffers */ |
| resetGSSBuffer(env, jmsg, &msg); |
| resetGSSBuffer(env, jmsgToken, &msgToken); |
| |
| (*env)->CallVoidMethod(env, jprop, MID_MessageProp_setQOP, qop); |
| setSupplementaryInfo(env, jobj, jprop, GSS_SUPPLEMENTARY_INFO(major), |
| minor); |
| checkStatus(env, jobj, GSS_ERROR(major), minor, "[GSSLibStub_verifyMic]"); |
| } |
| |
| /* |
| * Class: sun_security_jgss_wrapper_GSSLibStub |
| * Method: wrap |
| * Signature: (J[BLorg/ietf/jgss/MessageProp;)[B |
| */ |
| JNIEXPORT jbyteArray JNICALL |
| Java_sun_security_jgss_wrapper_GSSLibStub_wrap(JNIEnv *env, |
| jobject jobj, |
| jlong pContext, |
| jbyteArray jmsg, |
| jobject jprop) |
| { |
| OM_uint32 minor, major; |
| jboolean confFlag; |
| gss_qop_t qop; |
| gss_buffer_desc msg; |
| gss_buffer_desc msgToken; |
| int confState; |
| gss_ctx_id_t contextHdl; |
| jbyteArray jresult; |
| |
| contextHdl = (gss_ctx_id_t) pContext; |
| sprintf(debugBuf, "[GSSLibStub_wrap] %ld", (long)contextHdl); |
| debug(env, debugBuf); |
| |
| if (contextHdl == GSS_C_NO_CONTEXT) { |
| // Twik per javadoc |
| checkStatus(env, jobj, GSS_S_CONTEXT_EXPIRED, 0, "[GSSLibStub_wrap]"); |
| return NULL; |
| } |
| |
| confFlag = |
| (*env)->CallBooleanMethod(env, jprop, MID_MessageProp_getPrivacy); |
| qop = (gss_qop_t) |
| (*env)->CallIntMethod(env, jprop, MID_MessageProp_getQOP); |
| initGSSBuffer(env, jmsg, &msg); |
| /* gss_wrap(...) => GSS_S_CONTEXT_EXPIRED, GSS_S_NO_CONTEXT(!), |
| GSS_S_BAD_QOP */ |
| major = (*ftab->wrap)(&minor, contextHdl, confFlag, qop, &msg, &confState, |
| &msgToken); |
| |
| (*env)->CallVoidMethod(env, jprop, MID_MessageProp_setPrivacy, |
| (confState? JNI_TRUE:JNI_FALSE)); |
| |
| /* release intermediate buffers */ |
| resetGSSBuffer(env, jmsg, &msg); |
| jresult = getJavaBuffer(env, &msgToken); |
| |
| checkStatus(env, jobj, major, minor, "[GSSLibStub_wrap]"); |
| return jresult; |
| } |
| |
| /* |
| * Class: sun_security_jgss_wrapper_GSSLibStub |
| * Method: unwrap |
| * Signature: (J[BLorg/ietf/jgss/MessageProp;)[B |
| */ |
| JNIEXPORT jbyteArray JNICALL |
| Java_sun_security_jgss_wrapper_GSSLibStub_unwrap(JNIEnv *env, |
| jobject jobj, |
| jlong pContext, |
| jbyteArray jmsgToken, |
| jobject jprop) |
| { |
| OM_uint32 minor, major; |
| gss_ctx_id_t contextHdl; |
| gss_buffer_desc msgToken; |
| gss_buffer_desc msg; |
| int confState; |
| gss_qop_t qop; |
| jbyteArray jresult; |
| |
| contextHdl = (gss_ctx_id_t) pContext; |
| sprintf(debugBuf, "[GSSLibStub_unwrap] %ld", (long)contextHdl); |
| debug(env, debugBuf); |
| |
| if (contextHdl == GSS_C_NO_CONTEXT) { |
| // Twik per javadoc |
| checkStatus(env, jobj, GSS_S_CONTEXT_EXPIRED, 0, "[GSSLibStub_unwrap]"); |
| return NULL; |
| } |
| initGSSBuffer(env, jmsgToken, &msgToken); |
| confState = 0; |
| qop = GSS_C_QOP_DEFAULT; |
| /* gss_unwrap(...) => GSS_S_DEFECTIVE_TOKEN, GSS_S_BAD_MIC, |
| GSS_S_CONTEXT_EXPIRED, GSS_S_DUPLICATE_TOKEN(!), GSS_S_OLD_TOKEN(!), |
| GSS_S_UNSEQ_TOKEN(!), GSS_S_GAP_TOKEN(!), GSS_S_NO_CONTEXT(!) */ |
| major = |
| (*ftab->unwrap)(&minor, contextHdl, &msgToken, &msg, &confState, &qop); |
| /* update the message prop with relevant info */ |
| (*env)->CallVoidMethod(env, jprop, MID_MessageProp_setPrivacy, |
| (confState != 0)); |
| (*env)->CallVoidMethod(env, jprop, MID_MessageProp_setQOP, qop); |
| setSupplementaryInfo(env, jobj, jprop, GSS_SUPPLEMENTARY_INFO(major), |
| minor); |
| |
| /* release intermediate buffers */ |
| resetGSSBuffer(env, jmsgToken, &msgToken); |
| jresult = getJavaBuffer(env, &msg); |
| |
| checkStatus(env, jobj, GSS_ERROR(major), minor, "[GSSLibStub_unwrap]"); |
| return jresult; |
| } |