jdk/src/share/native/sun/security/jgss/wrapper/GSSLibStub.c
changeset 22940 56b3ab8ec81c
parent 18175 4ed91d93ab81
child 22942 3e0d28137ea8
equal deleted inserted replaced
22939:fc08f20ea32f 22940:56b3ab8ec81c
    26 #include "sun_security_jgss_wrapper_GSSLibStub.h"
    26 #include "sun_security_jgss_wrapper_GSSLibStub.h"
    27 #include "NativeUtil.h"
    27 #include "NativeUtil.h"
    28 #include "NativeFunc.h"
    28 #include "NativeFunc.h"
    29 #include "jlong.h"
    29 #include "jlong.h"
    30 #include <jni.h>
    30 #include <jni.h>
       
    31 #include "jni_util.h"
    31 
    32 
    32 /* Throws a Java Exception by name */
    33 /* Throws a Java Exception by name */
    33 
    34 
    34 void throwByName(JNIEnv *env, const char *name, const char *msg) {
    35 void throwByName(JNIEnv *env, const char *name, const char *msg) {
    35     jclass cls = (*env)->FindClass(env, name);
    36     jclass cls = (*env)->FindClass(env, name);
    36 
    37 
    37     if (cls != 0) /* Otherwise an exception has already been thrown */
    38     if (cls != 0) /* Otherwise an exception has already been thrown */
    38         (*env)->ThrowNew(env, cls, msg);
    39         (*env)->ThrowNew(env, cls, msg);
       
    40     JNU_Equals(env, NULL, NULL);
    39 }
    41 }
    40 
    42 
    41 void throwOutOfMemoryError(JNIEnv *env, const char *message) {
    43 void throwOutOfMemoryError(JNIEnv *env, const char *message) {
    42     throwByName(env, "java/lang/OutOfMemoryError", message);
    44     throwByName(env, "java/lang/OutOfMemoryError", message);
    43 }
    45 }
    63         debug(env, "[GSSLibStub_init] GSS lib name is NULL");
    65         debug(env, "[GSSLibStub_init] GSS lib name is NULL");
    64         return JNI_FALSE;
    66         return JNI_FALSE;
    65     }
    67     }
    66 
    68 
    67     libName = (*env)->GetStringUTFChars(env, jlibName, NULL);
    69     libName = (*env)->GetStringUTFChars(env, jlibName, NULL);
       
    70     if (libName == NULL) {
       
    71         if (!(*env)->ExceptionCheck(env)) {
       
    72             throwOutOfMemoryError(env, NULL);
       
    73         }
       
    74         return JNI_FALSE;
       
    75     }
    68     sprintf(debugBuf, "[GSSLibStub_init] libName=%s", libName);
    76     sprintf(debugBuf, "[GSSLibStub_init] libName=%s", libName);
    69     debug(env, debugBuf);
    77     debug(env, debugBuf);
    70 
    78 
    71     /* initialize global function table */
    79     /* initialize global function table */
    72     error = loadNative(libName);
    80     error = loadNative(libName);
   108           found = JNI_TRUE;
   116           found = JNI_TRUE;
   109           break;
   117           break;
   110         }
   118         }
   111       }
   119       }
   112       (*env)->ReleaseByteArrayElements(env, jbytes, bytes, 0);
   120       (*env)->ReleaseByteArrayElements(env, jbytes, bytes, 0);
       
   121     } else {
       
   122       JNU_CHECK_EXCEPTION_RETURN(env, jlong_zero);
   113     }
   123     }
   114     if (found != JNI_TRUE) {
   124     if (found != JNI_TRUE) {
   115       checkStatus(env, NULL, GSS_S_BAD_MECH, 0, "[GSSLibStub_getMechPtr]");
   125       checkStatus(env, NULL, GSS_S_BAD_MECH, 0, "[GSSLibStub_getMechPtr]");
   116       return ptr_to_jlong(NULL);
   126       return ptr_to_jlong(NULL);
   117     } else return ptr_to_jlong(cOid);
   127     } else return ptr_to_jlong(cOid);
   145                              MID_ChannelBinding_getInitiatorAddr);
   155                              MID_ChannelBinding_getInitiatorAddr);
   146   if (jinetAddr != NULL) {
   156   if (jinetAddr != NULL) {
   147     cb->initiator_addrtype = GSS_C_AF_INET;
   157     cb->initiator_addrtype = GSS_C_AF_INET;
   148     value = (*env)->CallObjectMethod(env, jinetAddr,
   158     value = (*env)->CallObjectMethod(env, jinetAddr,
   149                                      MID_InetAddress_getAddr);
   159                                      MID_InetAddress_getAddr);
   150     initGSSBuffer(env, value, &(cb->initiator_address));
   160     if (!initGSSBuffer(env, value, &(cb->initiator_address))) {
       
   161         return NULL;
       
   162     }
   151   } else {
   163   } else {
   152     cb->initiator_addrtype = GSS_C_AF_NULLADDR;
   164     cb->initiator_addrtype = GSS_C_AF_NULLADDR;
   153     cb->initiator_address.length = 0;
   165     cb->initiator_address.length = 0;
   154     cb->initiator_address.value = NULL;
   166     cb->initiator_address.value = NULL;
   155   }
   167   }
   159                              MID_ChannelBinding_getAcceptorAddr);
   171                              MID_ChannelBinding_getAcceptorAddr);
   160   if (jinetAddr != NULL) {
   172   if (jinetAddr != NULL) {
   161     cb->acceptor_addrtype = GSS_C_AF_INET;
   173     cb->acceptor_addrtype = GSS_C_AF_INET;
   162     value = (*env)->CallObjectMethod(env, jinetAddr,
   174     value = (*env)->CallObjectMethod(env, jinetAddr,
   163                                      MID_InetAddress_getAddr);
   175                                      MID_InetAddress_getAddr);
   164     initGSSBuffer(env, value, &(cb->acceptor_address));
   176     if (!initGSSBuffer(env, value, &(cb->acceptor_address))) {
       
   177         return NULL;
       
   178     }
   165   } else {
   179   } else {
   166     cb->acceptor_addrtype = GSS_C_AF_NULLADDR;
   180     cb->acceptor_addrtype = GSS_C_AF_NULLADDR;
   167     cb->acceptor_address.length = 0;
   181     cb->acceptor_address.length = 0;
   168     cb->acceptor_address.value = NULL;
   182     cb->acceptor_address.value = NULL;
   169   }
   183   }
   170   /* set up application data */
   184   /* set up application data */
   171   value = (*env)->CallObjectMethod(env, jcb,
   185   value = (*env)->CallObjectMethod(env, jcb,
   172                                    MID_ChannelBinding_getAppData);
   186                                    MID_ChannelBinding_getAppData);
   173   if (value != NULL) {
   187   if (value != NULL) {
   174     initGSSBuffer(env, value, &(cb->application_data));
   188     if (!initGSSBuffer(env, value, &(cb->application_data))) {
       
   189         return NULL;
       
   190     }
   175   } else {
   191   } else {
   176     cb->application_data.length = 0;
   192     cb->application_data.length = 0;
   177     cb->application_data.value = NULL;
   193     cb->application_data.value = NULL;
   178   }
   194   }
   179   return cb;
   195   return cb;
   228     isDuplicate = ((suppInfo & GSS_S_DUPLICATE_TOKEN) != 0);
   244     isDuplicate = ((suppInfo & GSS_S_DUPLICATE_TOKEN) != 0);
   229     isOld = ((suppInfo & GSS_S_OLD_TOKEN) != 0);
   245     isOld = ((suppInfo & GSS_S_OLD_TOKEN) != 0);
   230     isUnseq = ((suppInfo & GSS_S_UNSEQ_TOKEN) != 0);
   246     isUnseq = ((suppInfo & GSS_S_UNSEQ_TOKEN) != 0);
   231     hasGap = ((suppInfo & GSS_S_GAP_TOKEN) != 0);
   247     hasGap = ((suppInfo & GSS_S_GAP_TOKEN) != 0);
   232     minorMsg = getMinorMessage(env, jstub, minor);
   248     minorMsg = getMinorMessage(env, jstub, minor);
       
   249     CHECK_NULL(minorMsg);
   233     (*env)->CallVoidMethod(env, jprop, MID_MessageProp_setSupplementaryStates,
   250     (*env)->CallVoidMethod(env, jprop, MID_MessageProp_setSupplementaryStates,
   234                            isDuplicate, isOld, isUnseq, hasGap, minor,
   251                            isDuplicate, isOld, isUnseq, hasGap, minor,
   235                            minorMsg);
   252                            minorMsg);
   236   }
   253   }
   237 }
   254 }
   275   result = getJavaOIDArray(env, nameTypes);
   292   result = getJavaOIDArray(env, nameTypes);
   276 
   293 
   277   /* release intermediate buffers */
   294   /* release intermediate buffers */
   278   deleteGSSOIDSet(nameTypes);
   295   deleteGSSOIDSet(nameTypes);
   279 
   296 
       
   297   CHECK_NULL_RETURN(result, NULL);
   280   checkStatus(env, jobj, major, minor, "[GSSLibStub_inquireNamesForMech]");
   298   checkStatus(env, jobj, major, minor, "[GSSLibStub_inquireNamesForMech]");
   281   return result;
   299   return result;
   282   } else return NULL;
   300   } else return NULL;
   283 }
   301 }
   284 
   302 
   324   gss_name_t nameHdl;
   342   gss_name_t nameHdl;
   325   nameHdl = GSS_C_NO_NAME;
   343   nameHdl = GSS_C_NO_NAME;
   326 
   344 
   327   debug(env, "[GSSLibStub_importName]");
   345   debug(env, "[GSSLibStub_importName]");
   328 
   346 
   329   initGSSBuffer(env, jnameVal, &nameVal);
   347   if (!initGSSBuffer(env, jnameVal, &nameVal)) {
       
   348     return jlong_zero;
       
   349   }
   330   nameType = newGSSOID(env, jnameType);
   350   nameType = newGSSOID(env, jnameType);
   331   if ((*env)->ExceptionCheck(env)) {
   351   if ((*env)->ExceptionCheck(env)) {
   332     deleteGSSOID(nameType);
   352     deleteGSSOID(nameType);
   333     resetGSSBuffer(env, jnameVal, &nameVal);
   353     resetGSSBuffer(env, jnameVal, &nameVal);
   334     return jlong_zero;
   354     return jlong_zero;
   499   /* gss_display_name(...) => GSS_S_BAD_NAME */
   519   /* gss_display_name(...) => GSS_S_BAD_NAME */
   500   major = (*ftab->displayName)(&minor, nameHdl, &outNameBuf, &outNameType);
   520   major = (*ftab->displayName)(&minor, nameHdl, &outNameBuf, &outNameType);
   501 
   521 
   502   /* release intermediate buffers */
   522   /* release intermediate buffers */
   503   jname = getJavaString(env, &outNameBuf);
   523   jname = getJavaString(env, &outNameBuf);
       
   524   if (jname == NULL && !(*env)->ExceptionCheck(env)) {
       
   525     throwOutOfMemoryError(env, NULL);
       
   526     return NULL;
       
   527   }
   504 
   528 
   505   jtype = getJavaOID(env, outNameType);
   529   jtype = getJavaOID(env, outNameType);
   506   jresult = (*env)->NewObjectArray(env, 2, CLS_Object, NULL);
   530   jresult = (*env)->NewObjectArray(env, 2, CLS_Object, NULL);
       
   531   CHECK_NULL_RETURN(jresult, NULL);
   507 
   532 
   508   /* return immediately if an exception has occurred */
   533   /* return immediately if an exception has occurred */
   509   if ((*env)->ExceptionCheck(env)) {
   534   if ((*env)->ExceptionCheck(env)) {
   510     return NULL;
   535     return NULL;
   511   }
   536   }
   736   gss_OID mech, mech2;
   761   gss_OID mech, mech2;
   737 
   762 
   738   debug(env, "[GSSLibStub_importContext]");
   763   debug(env, "[GSSLibStub_importContext]");
   739 
   764 
   740   contextHdl = GSS_C_NO_CONTEXT;
   765   contextHdl = GSS_C_NO_CONTEXT;
   741   initGSSBuffer(env, jctxtToken, &ctxtToken);
   766   if (!initGSSBuffer(env, jctxtToken, &ctxtToken)) {
       
   767     return NULL;
       
   768   }
   742 
   769 
   743   /* gss_import_sec_context(...) => GSS_S_NO_CONTEXT, GSS_S_DEFECTIVE_TOKEN,
   770   /* gss_import_sec_context(...) => GSS_S_NO_CONTEXT, GSS_S_DEFECTIVE_TOKEN,
   744      GSS_S_UNAVAILABLE, GSS_S_UNAUTHORIZED */
   771      GSS_S_UNAVAILABLE, GSS_S_UNAUTHORIZED */
   745   major = (*ftab->importSecContext)(&minor, &ctxtToken, &contextHdl);
   772   major = (*ftab->importSecContext)(&minor, &ctxtToken, &contextHdl);
   746 
   773 
   827   if ((*env)->ExceptionCheck(env)) {
   854   if ((*env)->ExceptionCheck(env)) {
   828     free(cb);
   855     free(cb);
   829     return NULL;
   856     return NULL;
   830   }
   857   }
   831 
   858 
   832   initGSSBuffer(env, jinToken, &inToken);
   859   if (!initGSSBuffer(env, jinToken, &inToken)) {
       
   860     return NULL;
       
   861   }
   833 
   862 
   834   sprintf(debugBuf,
   863   sprintf(debugBuf,
   835           "[GSSLibStub_initContext] before: pCred=%ld, pContext=%ld",
   864           "[GSSLibStub_initContext] before: pCred=%ld, pContext=%ld",
   836           (long)credHdl, (long)contextHdl);
   865           (long)credHdl, (long)contextHdl);
   837   debug(env, debugBuf);
   866   debug(env, debugBuf);
   925   debug(env, "[GSSLibStub_acceptContext]");
   954   debug(env, "[GSSLibStub_acceptContext]");
   926 
   955 
   927   contextHdl = (gss_ctx_id_t)jlong_to_ptr(
   956   contextHdl = (gss_ctx_id_t)jlong_to_ptr(
   928     (*env)->GetLongField(env, jcontextSpi, FID_NativeGSSContext_pContext));
   957     (*env)->GetLongField(env, jcontextSpi, FID_NativeGSSContext_pContext));
   929   credHdl = (gss_cred_id_t) jlong_to_ptr(pCred);
   958   credHdl = (gss_cred_id_t) jlong_to_ptr(pCred);
   930   initGSSBuffer(env, jinToken, &inToken);
   959   if (!initGSSBuffer(env, jinToken, &inToken)) {
       
   960     return NULL;
       
   961   }
   931   cb = getGSSCB(env, jcb);
   962   cb = getGSSCB(env, jcb);
   932   if ((*env)->ExceptionCheck(env)) {
   963   if ((*env)->ExceptionCheck(env)) {
   933     free(cb);
   964     free(cb);
   934     resetGSSBuffer(env, jinToken, &inToken);
   965     resetGSSBuffer(env, jinToken, &inToken);
   935     return NULL;
   966     return NULL;
  1100   result[3] = (jlong) isEstablished;
  1131   result[3] = (jlong) isEstablished;
  1101   result[4] = (jlong) flags;
  1132   result[4] = (jlong) flags;
  1102   result[5] = (jlong) getJavaTime(time);
  1133   result[5] = (jlong) getJavaTime(time);
  1103 
  1134 
  1104   jresult = (*env)->NewLongArray(env, 6);
  1135   jresult = (*env)->NewLongArray(env, 6);
       
  1136   CHECK_NULL_RETURN(jresult, NULL);
  1105   (*env)->SetLongArrayRegion(env, jresult, 0, 6, result);
  1137   (*env)->SetLongArrayRegion(env, jresult, 0, 6, result);
  1106 
  1138 
  1107   /* release intermediate buffers */
  1139   /* release intermediate buffers */
  1108 
  1140 
  1109   checkStatus(env, jobj, major, minor, "[GSSLibStub_inquireContext]");
  1141   checkStatus(env, jobj, major, minor, "[GSSLibStub_inquireContext]");
  1333     checkStatus(env, jobj, GSS_S_CONTEXT_EXPIRED, 0, "[GSSLibStub_getMic]");
  1365     checkStatus(env, jobj, GSS_S_CONTEXT_EXPIRED, 0, "[GSSLibStub_getMic]");
  1334     return NULL;
  1366     return NULL;
  1335   }
  1367   }
  1336   contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
  1368   contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
  1337   qop = (gss_qop_t) jqop;
  1369   qop = (gss_qop_t) jqop;
  1338   initGSSBuffer(env, jmsg, &msg);
  1370   if (!initGSSBuffer(env, jmsg, &msg)) {
       
  1371     return NULL;
       
  1372   }
  1339 
  1373 
  1340   /* gss_get_mic(...) => GSS_S_CONTEXT_EXPIRED, GSS_S_NO_CONTEXT(!),
  1374   /* gss_get_mic(...) => GSS_S_CONTEXT_EXPIRED, GSS_S_NO_CONTEXT(!),
  1341      GSS_S_BAD_QOP */
  1375      GSS_S_BAD_QOP */
  1342   major =
  1376   major =
  1343     (*ftab->getMic)(&minor, contextHdl, qop, &msg, &msgToken);
  1377     (*ftab->getMic)(&minor, contextHdl, qop, &msg, &msgToken);
  1377     // Twik per javadoc
  1411     // Twik per javadoc
  1378     checkStatus(env, jobj, GSS_S_CONTEXT_EXPIRED, 0,
  1412     checkStatus(env, jobj, GSS_S_CONTEXT_EXPIRED, 0,
  1379         "[GSSLibStub_verifyMic]");
  1413         "[GSSLibStub_verifyMic]");
  1380     return;
  1414     return;
  1381   }
  1415   }
  1382   initGSSBuffer(env, jmsg, &msg);
  1416 
  1383   initGSSBuffer(env, jmsgToken, &msgToken);
  1417   if (!initGSSBuffer(env, jmsg, &msg) ||
       
  1418       !initGSSBuffer(env, jmsgToken, &msgToken)) {
       
  1419     return;
       
  1420   }
       
  1421 
  1384   qop = (gss_qop_t) (*env)->CallIntMethod(env, jprop, MID_MessageProp_getQOP);
  1422   qop = (gss_qop_t) (*env)->CallIntMethod(env, jprop, MID_MessageProp_getQOP);
  1385   /* gss_verify_mic(...) => GSS_S_DEFECTIVE_TOKEN, GSS_S_BAD_MIC,
  1423   /* gss_verify_mic(...) => GSS_S_DEFECTIVE_TOKEN, GSS_S_BAD_MIC,
  1386      GSS_S_CONTEXT_EXPIRED, GSS_S_DUPLICATE_TOKEN(!), GSS_S_OLD_TOKEN(!),
  1424      GSS_S_CONTEXT_EXPIRED, GSS_S_DUPLICATE_TOKEN(!), GSS_S_OLD_TOKEN(!),
  1387      GSS_S_UNSEQ_TOKEN(!), GSS_S_GAP_TOKEN(!), GSS_S_NO_CONTEXT(!) */
  1425      GSS_S_UNSEQ_TOKEN(!), GSS_S_GAP_TOKEN(!), GSS_S_NO_CONTEXT(!) */
  1388   major =
  1426   major =
  1431 
  1469 
  1432   confFlag =
  1470   confFlag =
  1433     (*env)->CallBooleanMethod(env, jprop, MID_MessageProp_getPrivacy);
  1471     (*env)->CallBooleanMethod(env, jprop, MID_MessageProp_getPrivacy);
  1434   qop = (gss_qop_t)
  1472   qop = (gss_qop_t)
  1435     (*env)->CallIntMethod(env, jprop, MID_MessageProp_getQOP);
  1473     (*env)->CallIntMethod(env, jprop, MID_MessageProp_getQOP);
  1436   initGSSBuffer(env, jmsg, &msg);
  1474   if (!initGSSBuffer(env, jmsg, &msg)) {
       
  1475     return NULL;
       
  1476   }
  1437   /* gss_wrap(...) => GSS_S_CONTEXT_EXPIRED, GSS_S_NO_CONTEXT(!),
  1477   /* gss_wrap(...) => GSS_S_CONTEXT_EXPIRED, GSS_S_NO_CONTEXT(!),
  1438      GSS_S_BAD_QOP */
  1478      GSS_S_BAD_QOP */
  1439   major = (*ftab->wrap)(&minor, contextHdl, confFlag, qop, &msg, &confState,
  1479   major = (*ftab->wrap)(&minor, contextHdl, confFlag, qop, &msg, &confState,
  1440                    &msgToken);
  1480                    &msgToken);
  1441 
  1481 
  1477   if (contextHdl == GSS_C_NO_CONTEXT) {
  1517   if (contextHdl == GSS_C_NO_CONTEXT) {
  1478     // Twik per javadoc
  1518     // Twik per javadoc
  1479     checkStatus(env, jobj, GSS_S_CONTEXT_EXPIRED, 0, "[GSSLibStub_unwrap]");
  1519     checkStatus(env, jobj, GSS_S_CONTEXT_EXPIRED, 0, "[GSSLibStub_unwrap]");
  1480     return NULL;
  1520     return NULL;
  1481   }
  1521   }
  1482   initGSSBuffer(env, jmsgToken, &msgToken);
  1522   if (!initGSSBuffer(env, jmsgToken, &msgToken)) {
       
  1523     return NULL;
       
  1524   }
  1483   confState = 0;
  1525   confState = 0;
  1484   qop = GSS_C_QOP_DEFAULT;
  1526   qop = GSS_C_QOP_DEFAULT;
  1485   /* gss_unwrap(...) => GSS_S_DEFECTIVE_TOKEN, GSS_S_BAD_MIC,
  1527   /* gss_unwrap(...) => GSS_S_DEFECTIVE_TOKEN, GSS_S_BAD_MIC,
  1486      GSS_S_CONTEXT_EXPIRED, GSS_S_DUPLICATE_TOKEN(!), GSS_S_OLD_TOKEN(!),
  1528      GSS_S_CONTEXT_EXPIRED, GSS_S_DUPLICATE_TOKEN(!), GSS_S_OLD_TOKEN(!),
  1487      GSS_S_UNSEQ_TOKEN(!), GSS_S_GAP_TOKEN(!), GSS_S_NO_CONTEXT(!) */
  1529      GSS_S_UNSEQ_TOKEN(!), GSS_S_GAP_TOKEN(!), GSS_S_NO_CONTEXT(!) */