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(!) */ |