1 /* 2 * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #include "sun_security_jgss_wrapper_GSSLibStub.h" 27 #include "NativeUtil.h" 28 #include "NativeFunc.h" 29 #include "jlong.h" 30 #include <jni.h> 31 32 /* Constants for indicating what type of info is needed for inquiries */ 33 const int TYPE_CRED_NAME = 10; 34 const int TYPE_CRED_TIME = 11; 35 const int TYPE_CRED_USAGE = 12; 36 37 /* 38 * Class: sun_security_jgss_wrapper_GSSLibStub 39 * Method: init 40 * Signature: (Ljava/lang/String;Z)Z 41 */ 42 JNIEXPORT jboolean JNICALL 43 Java_sun_security_jgss_wrapper_GSSLibStub_init(JNIEnv *env, 44 jclass jcls, 45 jstring jlibName, 46 jboolean jDebug) { 47 const char *libName; 48 char *error = NULL; 49 50 if (!jDebug) { 51 JGSS_DEBUG = 0; 52 } else { 53 JGSS_DEBUG = 1; 54 } 55 56 if (jlibName == NULL) { 57 TRACE0("[GSSLibStub_init] GSS lib name is NULL"); 58 return JNI_FALSE; 59 } 60 61 libName = (*env)->GetStringUTFChars(env, jlibName, NULL); 62 if (libName == NULL) { 63 return JNI_FALSE; 64 } 65 TRACE1("[GSSLibStub_init] libName=%s", libName); 66 67 /* initialize global function table */ 68 error = loadNative(libName); 69 (*env)->ReleaseStringUTFChars(env, jlibName, libName); 70 71 if (error == NULL) { 72 return JNI_TRUE; 73 } else { 74 TRACE0(error); 75 return JNI_FALSE; 76 } 77 } 78 79 /* 80 * Class: sun_security_jgss_wrapper_GSSLibStub 81 * Method: getMechPtr 82 * Signature: ([B)J 83 */ 84 JNIEXPORT jlong JNICALL 85 Java_sun_security_jgss_wrapper_GSSLibStub_getMechPtr(JNIEnv *env, 86 jclass jcls, 87 jbyteArray jbytes) { 88 gss_OID cOid; 89 unsigned int i, len; 90 jbyte* bytes; 91 jthrowable gssEx; 92 int found; 93 94 if (jbytes != NULL) { 95 found = 0; 96 len = (unsigned int)((*env)->GetArrayLength(env, jbytes) - 2); 97 bytes = (*env)->GetByteArrayElements(env, jbytes, NULL); 98 if (bytes == NULL) { 99 return ptr_to_jlong(NULL); 100 } 101 for (i = 0; i < ftab->mechs->count; i++) { 102 cOid = &(ftab->mechs->elements[i]); 103 if (len == cOid->length && 104 (memcmp(cOid->elements, (bytes + 2), len) == 0)) { 105 // Found a match 106 found = 1; 107 break; 108 } 109 } 110 (*env)->ReleaseByteArrayElements(env, jbytes, bytes, 0); 111 112 if (found != 1) { 113 checkStatus(env, NULL, GSS_S_BAD_MECH, 0, "[GSSLibStub_getMechPtr]"); 114 return ptr_to_jlong(NULL); 115 } else { 116 return ptr_to_jlong(cOid); 117 } 118 } else { 119 return ptr_to_jlong(GSS_C_NO_OID); 120 } 121 } 122 123 /* 124 * Utility routine which releases the specified gss_channel_bindings_t 125 * structure. 126 */ 127 void deleteGSSCB(gss_channel_bindings_t cb) { 128 jobject jinetAddr; 129 jbyteArray value; 130 131 if (cb == GSS_C_NO_CHANNEL_BINDINGS) return; 132 133 /* release initiator address */ 134 if (cb->initiator_addrtype != GSS_C_AF_NULLADDR) { 135 resetGSSBuffer(&(cb->initiator_address)); 136 } 137 /* release acceptor address */ 138 if (cb->acceptor_addrtype != GSS_C_AF_NULLADDR) { 139 resetGSSBuffer(&(cb->acceptor_address)); 140 } 141 /* release application data */ 142 if (cb->application_data.length != 0) { 143 resetGSSBuffer(&(cb->application_data)); 144 } 145 free(cb); 146 } 147 148 /* 149 * Utility routine which creates a gss_channel_bindings_t structure 150 * using the specified org.ietf.jgss.ChannelBinding object. 151 * NOTE: must call deleteGSSCB() to free up the resources. 152 */ 153 gss_channel_bindings_t newGSSCB(JNIEnv *env, jobject jcb) { 154 gss_channel_bindings_t cb; 155 jobject jinetAddr; 156 jbyteArray value; 157 int i; 158 159 if (jcb == NULL) { 160 return GSS_C_NO_CHANNEL_BINDINGS; 161 } 162 163 cb = malloc(sizeof(struct gss_channel_bindings_struct)); 164 if (cb == NULL) { 165 throwOutOfMemoryError(env,NULL); 166 return NULL; 167 } 168 169 // initialize addrtype in CB first 170 cb->initiator_addrtype = GSS_C_AF_NULLADDR; 171 cb->acceptor_addrtype = GSS_C_AF_NULLADDR; 172 173 /* set up initiator address */ 174 jinetAddr = (*env)->CallObjectMethod(env, jcb, 175 MID_ChannelBinding_getInitiatorAddr); 176 if ((*env)->ExceptionCheck(env)) { 177 goto cleanup; 178 } 179 if (jinetAddr != NULL) { 180 value = (*env)->CallObjectMethod(env, jinetAddr, 181 MID_InetAddress_getAddr); 182 if ((*env)->ExceptionCheck(env)) { 183 goto cleanup; 184 } 185 cb->initiator_addrtype = GSS_C_AF_INET; 186 initGSSBuffer(env, value, &(cb->initiator_address)); 187 if ((*env)->ExceptionCheck(env)) { 188 goto cleanup; 189 } 190 } 191 /* set up acceptor address */ 192 jinetAddr = (*env)->CallObjectMethod(env, jcb, 193 MID_ChannelBinding_getAcceptorAddr); 194 if ((*env)->ExceptionCheck(env)) { 195 goto cleanup; 196 } 197 if (jinetAddr != NULL) { 198 value = (*env)->CallObjectMethod(env, jinetAddr, 199 MID_InetAddress_getAddr); 200 if ((*env)->ExceptionCheck(env)) { 201 goto cleanup; 202 } 203 cb->acceptor_addrtype = GSS_C_AF_INET; 204 initGSSBuffer(env, value, &(cb->acceptor_address)); 205 if ((*env)->ExceptionCheck(env)) { 206 goto cleanup; 207 } 208 } 209 /* set up application data */ 210 value = (*env)->CallObjectMethod(env, jcb, 211 MID_ChannelBinding_getAppData); 212 if ((*env)->ExceptionCheck(env)) { 213 goto cleanup; 214 } 215 initGSSBuffer(env, value, &(cb->application_data)); 216 if ((*env)->ExceptionCheck(env)) { 217 goto cleanup; 218 } 219 return cb; 220 cleanup: 221 deleteGSSCB(cb); 222 return NULL; 223 } 224 225 /* 226 * Utility routine for storing the supplementary information 227 * into the specified org.ietf.jgss.MessageProp object. 228 */ 229 void setSupplementaryInfo(JNIEnv *env, jobject jstub, jobject jprop, 230 int suppInfo, int minor) { 231 jboolean isDuplicate, isOld, isUnseq, hasGap; 232 jstring minorMsg; 233 234 if (suppInfo != GSS_S_COMPLETE) { 235 isDuplicate = ((suppInfo & GSS_S_DUPLICATE_TOKEN) != 0); 236 isOld = ((suppInfo & GSS_S_OLD_TOKEN) != 0); 237 isUnseq = ((suppInfo & GSS_S_UNSEQ_TOKEN) != 0); 238 hasGap = ((suppInfo & GSS_S_GAP_TOKEN) != 0); 239 minorMsg = getMinorMessage(env, jstub, minor); 240 if ((*env)->ExceptionCheck(env)) { 241 return; 242 } 243 (*env)->CallVoidMethod(env, jprop, MID_MessageProp_setSupplementaryStates, 244 isDuplicate, isOld, isUnseq, hasGap, minor, 245 minorMsg); 246 } 247 } 248 249 /* 250 * Class: sun_security_jgss_wrapper_GSSLibStub 251 * Method: indicateMechs 252 * Signature: ()[Lorg/ietf/jgss/Oid; 253 */ 254 JNIEXPORT jobjectArray JNICALL 255 Java_sun_security_jgss_wrapper_GSSLibStub_indicateMechs(JNIEnv *env, 256 jclass jcls) 257 { 258 if (ftab->mechs != NULL && ftab->mechs != GSS_C_NO_OID_SET) { 259 return getJavaOIDArray(env, ftab->mechs); 260 } else return NULL; 261 } 262 263 /* 264 * Class: sun_security_jgss_wrapper_GSSLibStub 265 * Method: inquireNamesForMech 266 * Signature: ()[Lorg/ietf/jgss/Oid; 267 */ 268 JNIEXPORT jobjectArray JNICALL 269 Java_sun_security_jgss_wrapper_GSSLibStub_inquireNamesForMech(JNIEnv *env, 270 jobject jobj) 271 { 272 OM_uint32 minor, major; 273 gss_OID mech; 274 gss_OID_set nameTypes; 275 jobjectArray result; 276 277 if (ftab->inquireNamesForMech != NULL) { 278 mech = (gss_OID)jlong_to_ptr((*env)->GetLongField(env, jobj, FID_GSSLibStub_pMech)); 279 nameTypes = GSS_C_NO_OID_SET; 280 281 /* gss_inquire_names_for_mech(...) => N/A */ 282 major = (*ftab->inquireNamesForMech)(&minor, mech, &nameTypes); 283 284 /* release intermediate buffers before checking status */ 285 result = getJavaOIDArray(env, nameTypes); 286 deleteGSSOIDSet(nameTypes); 287 if ((*env)->ExceptionCheck(env)) { 288 return NULL; 289 } 290 291 checkStatus(env, jobj, major, minor, "[GSSLibStub_inquireNamesForMech]"); 292 if ((*env)->ExceptionCheck(env)) { 293 return NULL; 294 } 295 return result; 296 } 297 return NULL; 298 } 299 300 /* 301 * Class: sun_security_jgss_wrapper_GSSLibStub 302 * Method: releaseName 303 * Signature: (J)V 304 */ 305 JNIEXPORT void JNICALL 306 Java_sun_security_jgss_wrapper_GSSLibStub_releaseName(JNIEnv *env, 307 jobject jobj, 308 jlong pName) 309 { 310 OM_uint32 minor, major; 311 gss_name_t nameHdl; 312 313 nameHdl = (gss_name_t) jlong_to_ptr(pName); 314 315 TRACE1("[GSSLibStub_releaseName] %ld", (long) pName); 316 317 if (nameHdl != GSS_C_NO_NAME) { 318 /* gss_release_name(...) => GSS_S_BAD_NAME */ 319 major = (*ftab->releaseName)(&minor, &nameHdl); 320 checkStatus(env, jobj, major, minor, "[GSSLibStub_releaseName]"); 321 } 322 } 323 324 /* 325 * Class: sun_security_jgss_wrapper_GSSLibStub 326 * Method: importName 327 * Signature: ([BLorg/ietf/jgss/Oid;)J 328 */ 329 JNIEXPORT jlong JNICALL 330 Java_sun_security_jgss_wrapper_GSSLibStub_importName(JNIEnv *env, 331 jobject jobj, 332 jbyteArray jnameVal, 333 jobject jnameType) 334 { 335 OM_uint32 minor, major; 336 gss_buffer_desc nameVal; 337 gss_OID nameType; 338 gss_name_t nameHdl; 339 nameHdl = GSS_C_NO_NAME; 340 341 TRACE0("[GSSLibStub_importName]"); 342 343 initGSSBuffer(env, jnameVal, &nameVal); 344 if ((*env)->ExceptionCheck(env)) { 345 return jlong_zero; 346 } 347 348 nameType = newGSSOID(env, jnameType); 349 if ((*env)->ExceptionCheck(env)) { 350 resetGSSBuffer(&nameVal); 351 return jlong_zero; 352 } 353 354 /* gss_import_name(...) => GSS_S_BAD_NAMETYPE, GSS_S_BAD_NAME, 355 GSS_S_BAD_MECH */ 356 major = (*ftab->importName)(&minor, &nameVal, nameType, &nameHdl); 357 358 TRACE1("[GSSLibStub_importName] %ld", (long) nameHdl); 359 360 /* release intermediate buffers */ 361 deleteGSSOID(nameType); 362 resetGSSBuffer(&nameVal); 363 364 checkStatus(env, jobj, major, minor, "[GSSLibStub_importName]"); 365 if ((*env)->ExceptionCheck(env)) { 366 return jlong_zero; 367 } 368 return ptr_to_jlong(nameHdl); 369 } 370 371 372 /* 373 * Class: sun_security_jgss_wrapper_GSSLibStub 374 * Method: compareName 375 * Signature: (JJ)Z 376 */ 377 JNIEXPORT jboolean JNICALL 378 Java_sun_security_jgss_wrapper_GSSLibStub_compareName(JNIEnv *env, 379 jobject jobj, 380 jlong pName1, 381 jlong pName2) 382 { 383 OM_uint32 minor, major; 384 gss_name_t nameHdl1, nameHdl2; 385 int isEqual; 386 387 isEqual = 0; 388 nameHdl1 = (gss_name_t) jlong_to_ptr(pName1); 389 nameHdl2 = (gss_name_t) jlong_to_ptr(pName2); 390 391 TRACE2("[GSSLibStub_compareName] %ld %ld", (long)pName1, (long)pName2); 392 393 if ((nameHdl1 != GSS_C_NO_NAME) && (nameHdl2 != GSS_C_NO_NAME)) { 394 395 /* gss_compare_name(...) => GSS_S_BAD_NAMETYPE, GSS_S_BAD_NAME(!) */ 396 major = (*ftab->compareName)(&minor, nameHdl1, nameHdl2, &isEqual); 397 398 checkStatus(env, jobj, major, minor, "[GSSLibStub_compareName]"); 399 } 400 return (isEqual != 0); 401 } 402 403 /* 404 * Class: sun_security_jgss_wrapper_GSSLibStub 405 * Method: canonicalizeName 406 * Signature: (J)J 407 */ 408 JNIEXPORT jlong JNICALL 409 Java_sun_security_jgss_wrapper_GSSLibStub_canonicalizeName(JNIEnv *env, 410 jobject jobj, 411 jlong pName) 412 { 413 OM_uint32 minor, major; 414 gss_name_t nameHdl, mnNameHdl; 415 gss_OID mech; 416 417 nameHdl = (gss_name_t) jlong_to_ptr(pName); 418 419 TRACE1("[GSSLibStub_canonicalizeName] %ld", (long) pName); 420 421 if (nameHdl != GSS_C_NO_NAME) { 422 mech = (gss_OID) jlong_to_ptr((*env)->GetLongField(env, jobj, FID_GSSLibStub_pMech)); 423 mnNameHdl = GSS_C_NO_NAME; 424 425 /* gss_canonicalize_name(...) may return GSS_S_BAD_NAMETYPE, 426 GSS_S_BAD_NAME, GSS_S_BAD_MECH */ 427 major = (*ftab->canonicalizeName)(&minor, nameHdl, mech, &mnNameHdl); 428 429 TRACE1("[GSSLibStub_canonicalizeName] MN=%ld", (long)mnNameHdl); 430 431 checkStatus(env, jobj, major, minor, "[GSSLibStub_canonicalizeName]"); 432 if ((*env)->ExceptionCheck(env)) { 433 return (jlong) GSS_C_NO_NAME; 434 } 435 return ptr_to_jlong(mnNameHdl); 436 } 437 return (jlong) GSS_C_NO_NAME; 438 } 439 440 /* 441 * Class: sun_security_jgss_wrapper_GSSLibStub 442 * Method: exportName 443 * Signature: (J)[B 444 */ 445 JNIEXPORT jbyteArray JNICALL 446 Java_sun_security_jgss_wrapper_GSSLibStub_exportName(JNIEnv *env, 447 jobject jobj, 448 jlong pName) { 449 OM_uint32 minor, major; 450 gss_name_t nameHdl, mNameHdl; 451 gss_buffer_desc outBuf; 452 jbyteArray jresult; 453 454 nameHdl = (gss_name_t) jlong_to_ptr(pName); 455 456 TRACE1("[GSSLibStub_exportName] %ld", (long) pName); 457 458 /* gss_export_name(...) => GSS_S_NAME_NOT_MN, GSS_S_BAD_NAMETYPE, 459 GSS_S_BAD_NAME */ 460 major = (*ftab->exportName)(&minor, nameHdl, &outBuf); 461 462 /* canonicalize the internal name to MN and retry */ 463 if (major == GSS_S_NAME_NOT_MN) { 464 /* release intermediate buffers before retrying */ 465 (*ftab->releaseBuffer)(&minor, &outBuf); 466 467 TRACE0("[GSSLibStub_exportName] canonicalize and re-try"); 468 469 mNameHdl = (gss_name_t)jlong_to_ptr( 470 Java_sun_security_jgss_wrapper_GSSLibStub_canonicalizeName 471 (env, jobj, pName)); 472 if ((*env)->ExceptionCheck(env)) { 473 return NULL; 474 } 475 476 major = (*ftab->exportName)(&minor, mNameHdl, &outBuf); 477 Java_sun_security_jgss_wrapper_GSSLibStub_releaseName 478 (env, jobj, ptr_to_jlong(mNameHdl)); 479 if ((*env)->ExceptionCheck(env)) { 480 /* release intermediate buffers */ 481 (*ftab->releaseBuffer)(&minor, &outBuf); 482 return NULL; 483 } 484 } 485 486 /* release intermediate buffers before checking status */ 487 jresult = getJavaBuffer(env, &outBuf); 488 if ((*env)->ExceptionCheck(env)) { 489 return NULL; 490 } 491 492 checkStatus(env, jobj, major, minor, "[GSSLibStub_exportName]"); 493 if ((*env)->ExceptionCheck(env)) { 494 return NULL; 495 } 496 return jresult; 497 } 498 499 /* 500 * Class: sun_security_jgss_wrapper_GSSLibStub 501 * Method: displayName 502 * Signature: (J)[Ljava/lang/Object; 503 */ 504 JNIEXPORT jobjectArray JNICALL 505 Java_sun_security_jgss_wrapper_GSSLibStub_displayName(JNIEnv *env, 506 jobject jobj, 507 jlong pName) { 508 OM_uint32 minor, major; 509 gss_name_t nameHdl; 510 gss_buffer_desc outNameBuf; 511 gss_OID outNameType; 512 jstring jname; 513 jobject jtype; 514 jobjectArray jresult; 515 516 nameHdl = (gss_name_t) jlong_to_ptr(pName); 517 518 TRACE1("[GSSLibStub_displayName] %ld", (long) pName); 519 520 if (nameHdl == GSS_C_NO_NAME) { 521 checkStatus(env, jobj, GSS_S_BAD_NAME, 0, "[GSSLibStub_displayName]"); 522 return NULL; 523 } 524 525 /* gss_display_name(...) => GSS_S_BAD_NAME */ 526 major = (*ftab->displayName)(&minor, nameHdl, &outNameBuf, &outNameType); 527 528 /* release intermediate buffers before checking status */ 529 jname = getJavaString(env, &outNameBuf); 530 if ((*env)->ExceptionCheck(env)) { 531 return NULL; 532 } 533 534 checkStatus(env, jobj, major, minor, "[GSSLibStub_displayName]"); 535 if ((*env)->ExceptionCheck(env)) { 536 return NULL; 537 } 538 539 jtype = getJavaOID(env, outNameType); 540 if ((*env)->ExceptionCheck(env)) { 541 return NULL; 542 } 543 544 jresult = (*env)->NewObjectArray(env, 2, CLS_Object, NULL); 545 /* return immediately if an exception has occurred */ 546 if ((*env)->ExceptionCheck(env)) { 547 return NULL; 548 } 549 550 (*env)->SetObjectArrayElement(env, jresult, 0, jname); 551 if ((*env)->ExceptionCheck(env)) { 552 return NULL; 553 } 554 (*env)->SetObjectArrayElement(env, jresult, 1, jtype); 555 if ((*env)->ExceptionCheck(env)) { 556 return NULL; 557 } 558 559 return jresult; 560 } 561 562 /* 563 * Class: sun_security_jgss_wrapper_GSSLibStub 564 * Method: acquireCred 565 * Signature: (JII)J 566 */ 567 JNIEXPORT jlong JNICALL 568 Java_sun_security_jgss_wrapper_GSSLibStub_acquireCred(JNIEnv *env, 569 jobject jobj, 570 jlong pName, 571 jint reqTime, 572 jint usage) 573 { 574 OM_uint32 minor, major; 575 gss_OID mech; 576 gss_OID_set mechs; 577 gss_cred_usage_t credUsage; 578 gss_name_t nameHdl; 579 gss_cred_id_t credHdl; 580 credHdl = GSS_C_NO_CREDENTIAL; 581 582 TRACE0("[GSSLibStub_acquireCred]"); 583 584 mech = (gss_OID) jlong_to_ptr((*env)->GetLongField(env, jobj, FID_GSSLibStub_pMech)); 585 mechs = newGSSOIDSet(mech); 586 credUsage = (gss_cred_usage_t) usage; 587 nameHdl = (gss_name_t) jlong_to_ptr(pName); 588 589 TRACE2("[GSSLibStub_acquireCred] pName=%ld, usage=%d", (long)pName, usage); 590 591 /* gss_acquire_cred(...) => GSS_S_BAD_MECH, GSS_S_BAD_NAMETYPE, 592 GSS_S_BAD_NAME, GSS_S_CREDENTIALS_EXPIRED, GSS_S_NO_CRED */ 593 major = 594 (*ftab->acquireCred)(&minor, nameHdl, reqTime, mechs, 595 credUsage, &credHdl, NULL, NULL); 596 /* release intermediate buffers */ 597 deleteGSSOIDSet(mechs); 598 599 TRACE1("[GSSLibStub_acquireCred] pCred=%ld", (long) credHdl); 600 601 checkStatus(env, jobj, major, minor, "[GSSLibStub_acquireCred]"); 602 if ((*env)->ExceptionCheck(env)) { 603 return jlong_zero; 604 } 605 return ptr_to_jlong(credHdl); 606 } 607 608 /* 609 * Class: sun_security_jgss_wrapper_GSSLibStub 610 * Method: releaseCred 611 * Signature: (J)J 612 */ 613 JNIEXPORT jlong JNICALL 614 Java_sun_security_jgss_wrapper_GSSLibStub_releaseCred(JNIEnv *env, 615 jobject jobj, 616 jlong pCred) 617 { 618 OM_uint32 minor, major; 619 gss_cred_id_t credHdl; 620 621 credHdl = (gss_cred_id_t) jlong_to_ptr(pCred); 622 623 TRACE1("[GSSLibStub_releaseCred] %ld", (long int)pCred); 624 625 if (credHdl != GSS_C_NO_CREDENTIAL) { 626 /* gss_release_cred(...) => GSS_S_NO_CRED(!) */ 627 major = (*ftab->releaseCred)(&minor, &credHdl); 628 629 checkStatus(env, jobj, major, minor, "[GSSLibStub_releaseCred]"); 630 if ((*env)->ExceptionCheck(env)) { 631 return jlong_zero; 632 } 633 } 634 return ptr_to_jlong(credHdl); 635 } 636 637 /* 638 * Utility routine for obtaining info about a credential. 639 */ 640 void inquireCred(JNIEnv *env, jobject jobj, gss_cred_id_t pCred, 641 jint type, void *result) { 642 OM_uint32 minor=0, major=0; 643 OM_uint32 routineErr; 644 gss_cred_id_t credHdl; 645 646 credHdl = pCred; 647 648 TRACE1("[gss_inquire_cred] %ld", (long) pCred); 649 650 /* gss_inquire_cred(...) => GSS_S_DEFECTIVE_CREDENTIAL(!), 651 GSS_S_CREDENTIALS_EXPIRED(!), GSS_S_NO_CRED(!) */ 652 if (type == TYPE_CRED_NAME) { 653 major = (*ftab->inquireCred)(&minor, credHdl, result, NULL, NULL, NULL); 654 } else if (type == TYPE_CRED_TIME) { 655 major = (*ftab->inquireCred)(&minor, credHdl, NULL, result, NULL, NULL); 656 } else if (type == TYPE_CRED_USAGE) { 657 major = (*ftab->inquireCred)(&minor, credHdl, NULL, NULL, result, NULL); 658 } 659 660 routineErr = GSS_ROUTINE_ERROR(major); 661 if (routineErr == GSS_S_CREDENTIALS_EXPIRED) { 662 /* ignore GSS_S_CREDENTIALS_EXPIRED for query */ 663 major = GSS_CALLING_ERROR(major) | 664 GSS_SUPPLEMENTARY_INFO(major); 665 } else if (routineErr == GSS_S_NO_CRED) { 666 /* twik since Java API throws BAD_MECH instead of NO_CRED */ 667 major = GSS_CALLING_ERROR(major) | 668 GSS_S_BAD_MECH | GSS_SUPPLEMENTARY_INFO(major); 669 } 670 checkStatus(env, jobj, major, minor, "[gss_inquire_cred]"); 671 } 672 673 /* 674 * Class: sun_security_jgss_wrapper_GSSLibStub 675 * Method: getCredName 676 * Signature: (J)J 677 */ 678 JNIEXPORT jlong JNICALL 679 Java_sun_security_jgss_wrapper_GSSLibStub_getCredName(JNIEnv *env, 680 jobject jobj, 681 jlong pCred) 682 { 683 gss_name_t nameHdl; 684 gss_cred_id_t credHdl; 685 686 credHdl = (gss_cred_id_t) jlong_to_ptr(pCred); 687 688 TRACE1("[GSSLibStub_getCredName] %ld", (long int)pCred); 689 690 nameHdl = GSS_C_NO_NAME; 691 inquireCred(env, jobj, credHdl, TYPE_CRED_NAME, &nameHdl); 692 /* return immediately if an exception has occurred */ 693 if ((*env)->ExceptionCheck(env)) { 694 return jlong_zero; 695 } 696 697 TRACE1("[GSSLibStub_getCredName] pName=%ld", (long) nameHdl); 698 return ptr_to_jlong(nameHdl); 699 } 700 701 /* 702 * Class: sun_security_jgss_wrapper_GSSLibStub 703 * Method: getCredTime 704 * Signature: (J)I 705 */ 706 JNIEXPORT jint JNICALL 707 Java_sun_security_jgss_wrapper_GSSLibStub_getCredTime(JNIEnv *env, 708 jobject jobj, 709 jlong pCred) 710 { 711 gss_cred_id_t credHdl; 712 OM_uint32 lifetime; 713 714 credHdl = (gss_cred_id_t) jlong_to_ptr(pCred); 715 716 TRACE1("[GSSLibStub_getCredTime] %ld", (long int)pCred); 717 718 lifetime = 0; 719 inquireCred(env, jobj, credHdl, TYPE_CRED_TIME, &lifetime); 720 /* return immediately if an exception has occurred */ 721 if ((*env)->ExceptionCheck(env)) { 722 return 0; 723 } 724 return getJavaTime(lifetime); 725 } 726 727 /* 728 * Class: sun_security_jgss_wrapper_GSSLibStub 729 * Method: getCredUsage 730 * Signature: (J)I 731 */ 732 JNIEXPORT jint JNICALL 733 Java_sun_security_jgss_wrapper_GSSLibStub_getCredUsage(JNIEnv *env, 734 jobject jobj, 735 jlong pCred) 736 { 737 gss_cred_usage_t usage; 738 gss_cred_id_t credHdl; 739 740 credHdl = (gss_cred_id_t) jlong_to_ptr(pCred); 741 742 TRACE1("[GSSLibStub_getCredUsage] %ld", (long int)pCred); 743 744 inquireCred(env, jobj, credHdl, TYPE_CRED_USAGE, &usage); 745 /* return immediately if an exception has occurred */ 746 if ((*env)->ExceptionCheck(env)) { 747 return -1; 748 } 749 return (jint) usage; 750 } 751 /* 752 * Class: sun_security_jgss_wrapper_GSSLibStub 753 * Method: importContext 754 * Signature: ([B)Lsun/security/jgss/wrapper/NativeGSSContext; 755 */ 756 JNIEXPORT jobject JNICALL 757 Java_sun_security_jgss_wrapper_GSSLibStub_importContext(JNIEnv *env, 758 jobject jobj, 759 jbyteArray jctxtToken) 760 { 761 OM_uint32 minor, major; 762 gss_buffer_desc ctxtToken; 763 gss_ctx_id_t contextHdl; 764 gss_OID mech, mech2; 765 766 TRACE0("[GSSLibStub_importContext]"); 767 768 contextHdl = GSS_C_NO_CONTEXT; 769 initGSSBuffer(env, jctxtToken, &ctxtToken); 770 if ((*env)->ExceptionCheck(env)) { 771 return NULL; 772 } 773 774 /* gss_import_sec_context(...) => GSS_S_NO_CONTEXT, GSS_S_DEFECTIVE_TOKEN, 775 GSS_S_UNAVAILABLE, GSS_S_UNAUTHORIZED */ 776 major = (*ftab->importSecContext)(&minor, &ctxtToken, &contextHdl); 777 778 TRACE1("[GSSLibStub_importContext] pContext=%ld", (long) contextHdl); 779 780 /* release intermediate buffers */ 781 resetGSSBuffer(&ctxtToken); 782 783 checkStatus(env, jobj, major, minor, "[GSSLibStub_importContext]"); 784 /* return immediately if an exception has occurred */ 785 if ((*env)->ExceptionCheck(env)) { 786 return NULL; 787 } 788 789 /* now that the context has been imported, proceed to find out 790 its mech */ 791 major = (*ftab->inquireContext)(&minor, contextHdl, NULL, NULL, 792 NULL, &mech, NULL, NULL, NULL); 793 794 checkStatus(env, jobj, major, minor, "[GSSLibStub_importContext] getMech"); 795 /* return immediately if an exception has occurred */ 796 if ((*env)->ExceptionCheck(env)) { 797 return NULL; 798 } 799 800 mech2 = (gss_OID) jlong_to_ptr((*env)->GetLongField(env, jobj, 801 FID_GSSLibStub_pMech)); 802 803 if (sameMech(mech, mech2) == JNI_TRUE) { 804 /* mech match - return the context object */ 805 return (*env)->NewObject(env, CLS_NativeGSSContext, 806 MID_NativeGSSContext_ctor, 807 ptr_to_jlong(contextHdl), jobj); 808 } else { 809 /* mech mismatch - clean up then return null */ 810 major = (*ftab->deleteSecContext)(&minor, &contextHdl, GSS_C_NO_BUFFER); 811 checkStatus(env, jobj, major, minor, 812 "[GSSLibStub_importContext] cleanup"); 813 return NULL; 814 } 815 } 816 817 /* 818 * Class: sun_security_jgss_wrapper_GSSLibStub 819 * Method: initContext 820 * Signature: (JJLorg/ietf/jgss/ChannelBinding;[BLsun/security/jgss/wrapper/NativeGSSContext;)[B 821 */ 822 JNIEXPORT jbyteArray JNICALL 823 Java_sun_security_jgss_wrapper_GSSLibStub_initContext(JNIEnv *env, 824 jobject jobj, 825 jlong pCred, 826 jlong pName, 827 jobject jcb, 828 jbyteArray jinToken, 829 jobject jcontextSpi) 830 { 831 OM_uint32 minor, major; 832 gss_cred_id_t credHdl ; 833 gss_ctx_id_t contextHdl, contextHdlSave; 834 gss_name_t targetName; 835 gss_OID mech; 836 OM_uint32 flags, aFlags; 837 OM_uint32 time, aTime; 838 gss_channel_bindings_t cb; 839 gss_buffer_desc inToken; 840 gss_buffer_desc outToken; 841 jbyteArray jresult; 842 /* UNCOMMENT after SEAM bug#6287358 is backported to S10 843 gss_OID aMech; 844 jobject jMech; 845 */ 846 847 TRACE0("[GSSLibStub_initContext]"); 848 849 credHdl = (gss_cred_id_t) jlong_to_ptr(pCred); 850 contextHdl = contextHdlSave = (gss_ctx_id_t) jlong_to_ptr( 851 (*env)->GetLongField(env, jcontextSpi, FID_NativeGSSContext_pContext)); 852 targetName = (gss_name_t) jlong_to_ptr(pName); 853 mech = (gss_OID) jlong_to_ptr((*env)->GetLongField(env, jobj, FID_GSSLibStub_pMech)); 854 flags = (OM_uint32) (*env)->GetIntField(env, jcontextSpi, 855 FID_NativeGSSContext_flags); 856 time = getGSSTime((*env)->GetIntField(env, jcontextSpi, 857 FID_NativeGSSContext_lifetime)); 858 cb = newGSSCB(env, jcb); 859 if ((*env)->ExceptionCheck(env)) { 860 return NULL; 861 } 862 863 initGSSBuffer(env, jinToken, &inToken); 864 if ((*env)->ExceptionCheck(env)) { 865 deleteGSSCB(cb); 866 return NULL; 867 } 868 869 TRACE2( "[GSSLibStub_initContext] before: pCred=%ld, pContext=%ld", 870 (long)credHdl, (long)contextHdl); 871 872 /* gss_init_sec_context(...) => GSS_S_CONTINUE_NEEDED(!), 873 GSS_S_DEFECTIVE_TOKEN, GSS_S_NO_CRED, GSS_S_DEFECTIVE_CREDENTIAL(!), 874 GSS_S_CREDENTIALS_EXPIRED, GSS_S_BAD_BINDINGS, GSS_S_BAD_MIC, 875 GSS_S_OLD_TOKEN, GSS_S_DUPLICATE_TOKEN, GSS_S_NO_CONTEXT(!), 876 GSS_S_BAD_NAMETYPE, GSS_S_BAD_NAME(!), GSS_S_BAD_MECH */ 877 major = (*ftab->initSecContext)(&minor, credHdl, 878 &contextHdl, targetName, mech, 879 flags, time, cb, &inToken, NULL /*aMech*/, 880 &outToken, &aFlags, &aTime); 881 882 TRACE2("[GSSLibStub_initContext] after: pContext=%ld, outToken len=%ld", 883 (long)contextHdl, (long)outToken.length); 884 885 // update context handle with the latest value if changed 886 // this is to work with both MIT and Solaris. Former deletes half-built 887 // context if error occurs 888 if (contextHdl != contextHdlSave) { 889 (*env)->SetLongField(env, jcontextSpi, FID_NativeGSSContext_pContext, 890 ptr_to_jlong(contextHdl)); 891 TRACE1("[GSSLibStub_initContext] set pContext=%ld", (long)contextHdl); 892 } 893 894 if (GSS_ERROR(major) == GSS_S_COMPLETE) { 895 /* update member values if needed */ 896 (*env)->SetIntField(env, jcontextSpi, FID_NativeGSSContext_flags, aFlags); 897 TRACE1("[GSSLibStub_initContext] set flags=0x%x", aFlags); 898 899 if (major == GSS_S_COMPLETE) { 900 (*env)->SetIntField(env, jcontextSpi, FID_NativeGSSContext_lifetime, 901 getJavaTime(aTime)); 902 TRACE0("[GSSLibStub_initContext] context established"); 903 904 (*env)->SetBooleanField(env, jcontextSpi, 905 FID_NativeGSSContext_isEstablished, 906 JNI_TRUE); 907 908 /* UNCOMMENT after SEAM bug#6287358 is backported to S10 909 jMech = getJavaOID(env, aMech); 910 (*env)->SetObjectField(env, jcontextSpi, 911 FID_NativeGSSContext_actualMech, jMech); 912 */ 913 } else if (major & GSS_S_CONTINUE_NEEDED) { 914 TRACE0("[GSSLibStub_initContext] context not established"); 915 major -= GSS_S_CONTINUE_NEEDED; 916 } 917 } 918 919 /* release intermediate buffers before checking status */ 920 deleteGSSCB(cb); 921 resetGSSBuffer(&inToken); 922 jresult = getJavaBuffer(env, &outToken); 923 if ((*env)->ExceptionCheck(env)) { 924 return NULL; 925 } 926 927 checkStatus(env, jobj, major, minor, "[GSSLibStub_initContext]"); 928 if ((*env)->ExceptionCheck(env)) { 929 return NULL; 930 } 931 return jresult; 932 } 933 934 /* 935 * Class: sun_security_jgss_wrapper_GSSLibStub 936 * Method: acceptContext 937 * Signature: (JLorg/ietf/jgss/ChannelBinding;[BLsun/security/jgss/wrapper/NativeGSSContext;)[B 938 */ 939 JNIEXPORT jbyteArray JNICALL 940 Java_sun_security_jgss_wrapper_GSSLibStub_acceptContext(JNIEnv *env, 941 jobject jobj, 942 jlong pCred, 943 jobject jcb, 944 jbyteArray jinToken, 945 jobject jcontextSpi) 946 { 947 OM_uint32 minor, major; 948 OM_uint32 minor2, major2; 949 gss_ctx_id_t contextHdl, contextHdlSave; 950 gss_cred_id_t credHdl; 951 gss_buffer_desc inToken; 952 gss_channel_bindings_t cb; 953 gss_name_t srcName; 954 gss_buffer_desc outToken; 955 gss_OID aMech; 956 OM_uint32 aFlags; 957 OM_uint32 aTime; 958 gss_cred_id_t delCred; 959 jobject jsrcName=GSS_C_NO_NAME; 960 jobject jdelCred; 961 jobject jMech; 962 jbyteArray jresult; 963 jboolean setTarget; 964 gss_name_t targetName; 965 jobject jtargetName; 966 967 TRACE0("[GSSLibStub_acceptContext]"); 968 969 contextHdl = contextHdlSave = (gss_ctx_id_t)jlong_to_ptr( 970 (*env)->GetLongField(env, jcontextSpi, FID_NativeGSSContext_pContext)); 971 credHdl = (gss_cred_id_t) jlong_to_ptr(pCred); 972 initGSSBuffer(env, jinToken, &inToken); 973 if ((*env)->ExceptionCheck(env)) { 974 return NULL; 975 } 976 cb = newGSSCB(env, jcb); 977 if ((*env)->ExceptionCheck(env)) { 978 resetGSSBuffer(&inToken); 979 return NULL; 980 } 981 srcName = targetName = GSS_C_NO_NAME; 982 delCred = GSS_C_NO_CREDENTIAL; 983 setTarget = (credHdl == GSS_C_NO_CREDENTIAL); 984 aFlags = 0; 985 986 TRACE2( "[GSSLibStub_acceptContext] before: pCred=%ld, pContext=%ld", 987 (long) credHdl, (long) contextHdl); 988 989 /* gss_accept_sec_context(...) => GSS_S_CONTINUE_NEEDED(!), 990 GSS_S_DEFECTIVE_TOKEN, GSS_S_DEFECTIVE_CREDENTIAL(!), 991 GSS_S_NO_CRED, GSS_S_CREDENTIALS_EXPIRED, GSS_S_BAD_BINDINGS, 992 GSS_S_NO_CONTEXT(!), GSS_S_BAD_MIC, GSS_S_OLD_TOKEN, 993 GSS_S_DUPLICATE_TOKEN, GSS_S_BAD_MECH */ 994 major = 995 (*ftab->acceptSecContext)(&minor, &contextHdl, credHdl, 996 &inToken, cb, &srcName, &aMech, &outToken, 997 &aFlags, &aTime, &delCred); 998 /* release intermediate buffers before checking status */ 999 1000 deleteGSSCB(cb); 1001 resetGSSBuffer(&inToken); 1002 1003 TRACE3("[GSSLibStub_acceptContext] after: pCred=%ld, pContext=%ld, pDelegCred=%ld", 1004 (long)credHdl, (long)contextHdl, (long) delCred); 1005 1006 // update context handle with the latest value if changed 1007 // this is to work with both MIT and Solaris. Former deletes half-built 1008 // context if error occurs 1009 if (contextHdl != contextHdlSave) { 1010 (*env)->SetLongField(env, jcontextSpi, FID_NativeGSSContext_pContext, 1011 ptr_to_jlong(contextHdl)); 1012 TRACE1("[GSSLibStub_acceptContext] set pContext=%ld", (long)contextHdl); 1013 } 1014 1015 if (GSS_ERROR(major) == GSS_S_COMPLETE) { 1016 /* update member values if needed */ 1017 // WORKAROUND for a Heimdal bug 1018 if (delCred == GSS_C_NO_CREDENTIAL) { 1019 aFlags &= 0xfffffffe; 1020 } 1021 (*env)->SetIntField(env, jcontextSpi, FID_NativeGSSContext_flags, aFlags); 1022 TRACE1("[GSSLibStub_acceptContext] set flags=0x%x", aFlags); 1023 1024 if (setTarget) { 1025 major2 = (*ftab->inquireContext)(&minor2, contextHdl, NULL, 1026 &targetName, NULL, NULL, NULL, 1027 NULL, NULL); 1028 checkStatus(env, jobj, major2, minor2, 1029 "[GSSLibStub_acceptContext] inquire"); 1030 if ((*env)->ExceptionCheck(env)) { 1031 goto error; 1032 } 1033 1034 jtargetName = (*env)->NewObject(env, CLS_GSSNameElement, 1035 MID_GSSNameElement_ctor, 1036 ptr_to_jlong(targetName), jobj); 1037 if ((*env)->ExceptionCheck(env)) { 1038 goto error; 1039 } 1040 1041 TRACE1("[GSSLibStub_acceptContext] set targetName=%ld", 1042 (long)targetName); 1043 1044 (*env)->SetObjectField(env, jcontextSpi, FID_NativeGSSContext_targetName, 1045 jtargetName); 1046 if ((*env)->ExceptionCheck(env)) { 1047 goto error; 1048 } 1049 } 1050 if (srcName != GSS_C_NO_NAME) { 1051 jsrcName = (*env)->NewObject(env, CLS_GSSNameElement, 1052 MID_GSSNameElement_ctor, 1053 ptr_to_jlong(srcName), jobj); 1054 if ((*env)->ExceptionCheck(env)) { 1055 goto error; 1056 } 1057 1058 TRACE1("[GSSLibStub_acceptContext] set srcName=%ld", (long)srcName); 1059 1060 (*env)->SetObjectField(env, jcontextSpi, FID_NativeGSSContext_srcName, 1061 jsrcName); 1062 if ((*env)->ExceptionCheck(env)) { 1063 goto error; 1064 } 1065 } 1066 if (major == GSS_S_COMPLETE) { 1067 TRACE0("[GSSLibStub_acceptContext] context established"); 1068 1069 (*env)->SetIntField(env, jcontextSpi, FID_NativeGSSContext_lifetime, 1070 getJavaTime(aTime)); 1071 (*env)->SetBooleanField(env, jcontextSpi, 1072 FID_NativeGSSContext_isEstablished, 1073 JNI_TRUE); 1074 jMech = getJavaOID(env, aMech); 1075 if ((*env)->ExceptionCheck(env)) { 1076 goto error; 1077 } 1078 (*env)->SetObjectField(env, jcontextSpi, 1079 FID_NativeGSSContext_actualMech, jMech); 1080 if ((*env)->ExceptionCheck(env)) { 1081 goto error; 1082 } 1083 if (delCred != GSS_C_NO_CREDENTIAL) { 1084 jdelCred = (*env)->NewObject(env, CLS_GSSCredElement, 1085 MID_GSSCredElement_ctor, 1086 ptr_to_jlong(delCred), jsrcName, jMech); 1087 if ((*env)->ExceptionCheck(env)) { 1088 goto error; 1089 } 1090 (*env)->SetObjectField(env, jcontextSpi, 1091 FID_NativeGSSContext_delegatedCred, 1092 jdelCred); 1093 TRACE1("[GSSLibStub_acceptContext] set delegatedCred=%ld", 1094 (long) delCred); 1095 1096 if ((*env)->ExceptionCheck(env)) { 1097 goto error; 1098 } 1099 } 1100 } else if (major & GSS_S_CONTINUE_NEEDED) { 1101 TRACE0("[GSSLibStub_acceptContext] context not established"); 1102 1103 if (aFlags & GSS_C_PROT_READY_FLAG) { 1104 (*env)->SetIntField(env, jcontextSpi, FID_NativeGSSContext_lifetime, 1105 getJavaTime(aTime)); 1106 } 1107 major -= GSS_S_CONTINUE_NEEDED; 1108 } 1109 } 1110 return getJavaBuffer(env, &outToken); 1111 1112 error: 1113 (*ftab->releaseBuffer)(&minor, &outToken); 1114 if (srcName != GSS_C_NO_NAME) { 1115 (*ftab->releaseName)(&minor, &srcName); 1116 } 1117 if (targetName != GSS_C_NO_NAME) { 1118 (*ftab->releaseName)(&minor, &targetName); 1119 } 1120 if (delCred != GSS_C_NO_CREDENTIAL) { 1121 (*ftab->releaseCred) (&minor, &delCred); 1122 } 1123 return NULL; 1124 } 1125 1126 /* 1127 * Class: sun_security_jgss_wrapper_GSSLibStub 1128 * Method: inquireContext 1129 * Signature: (J)[J 1130 */ 1131 JNIEXPORT jlongArray JNICALL 1132 Java_sun_security_jgss_wrapper_GSSLibStub_inquireContext(JNIEnv *env, 1133 jobject jobj, 1134 jlong pContext) 1135 { 1136 OM_uint32 minor, major; 1137 gss_ctx_id_t contextHdl; 1138 gss_name_t srcName, targetName; 1139 OM_uint32 time; 1140 OM_uint32 flags; 1141 int isInitiator, isEstablished; 1142 jlong result[6]; 1143 jlongArray jresult; 1144 1145 contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext); 1146 1147 TRACE1("[GSSLibStub_inquireContext] %ld", (long)contextHdl); 1148 1149 srcName = targetName = GSS_C_NO_NAME; 1150 time = 0; 1151 flags = isInitiator = isEstablished = 0; 1152 1153 /* gss_inquire_context(...) => GSS_S_NO_CONTEXT(!) */ 1154 major = (*ftab->inquireContext)(&minor, contextHdl, &srcName, 1155 &targetName, &time, NULL, &flags, 1156 &isInitiator, &isEstablished); 1157 /* update member values if needed */ 1158 TRACE2("[GSSLibStub_inquireContext] srcName %ld, targetName %ld", 1159 (long)srcName, (long)targetName); 1160 1161 checkStatus(env, jobj, major, minor, "[GSSLibStub_inquireContext]"); 1162 if ((*env)->ExceptionCheck(env)) { 1163 return NULL; 1164 } 1165 result[0] = ptr_to_jlong(srcName); 1166 result[1] = ptr_to_jlong(targetName); 1167 result[2] = (jlong) isInitiator; 1168 result[3] = (jlong) isEstablished; 1169 result[4] = (jlong) flags; 1170 result[5] = (jlong) getJavaTime(time); 1171 1172 jresult = (*env)->NewLongArray(env, 6); 1173 if (jresult == NULL) { 1174 return NULL; 1175 } 1176 (*env)->SetLongArrayRegion(env, jresult, 0, 6, result); 1177 if ((*env)->ExceptionCheck(env)) { 1178 return NULL; 1179 } 1180 return jresult; 1181 } 1182 1183 /* 1184 * Class: sun_security_jgss_wrapper_GSSLibStub 1185 * Method: getContextMech 1186 * Signature: (J)Lorg/ietf/jgss/Oid; 1187 */ 1188 JNIEXPORT jobject JNICALL 1189 Java_sun_security_jgss_wrapper_GSSLibStub_getContextMech(JNIEnv *env, 1190 jobject jobj, 1191 jlong pContext) 1192 { 1193 OM_uint32 minor, major; 1194 gss_OID mech; 1195 gss_ctx_id_t contextHdl; 1196 1197 contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext); 1198 1199 TRACE1("[GSSLibStub_getContextMech] %ld", (long int)pContext); 1200 1201 major = (*ftab->inquireContext)(&minor, contextHdl, NULL, NULL, 1202 NULL, &mech, NULL, NULL, NULL); 1203 1204 checkStatus(env, jobj, major, minor, "[GSSLibStub_getContextMech]"); 1205 /* return immediately if an exception has occurred */ 1206 if ((*env)->ExceptionCheck(env)) { 1207 return NULL; 1208 } 1209 1210 return getJavaOID(env, mech); 1211 } 1212 1213 /* 1214 * Class: sun_security_jgss_wrapper_GSSLibStub 1215 * Method: getContextName 1216 * Signature: (JZ)J 1217 */ 1218 JNIEXPORT jlong JNICALL 1219 Java_sun_security_jgss_wrapper_GSSLibStub_getContextName(JNIEnv *env, 1220 jobject jobj, jlong pContext, jboolean isSrc) 1221 { 1222 OM_uint32 minor, major; 1223 gss_name_t nameHdl; 1224 gss_ctx_id_t contextHdl; 1225 1226 contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext); 1227 1228 TRACE2("[GSSLibStub_getContextName] %ld, isSrc=%d", 1229 (long)contextHdl, isSrc); 1230 1231 nameHdl = GSS_C_NO_NAME; 1232 if (isSrc == JNI_TRUE) { 1233 major = (*ftab->inquireContext)(&minor, contextHdl, &nameHdl, NULL, 1234 NULL, NULL, NULL, NULL, NULL); 1235 } else { 1236 major = (*ftab->inquireContext)(&minor, contextHdl, NULL, &nameHdl, 1237 NULL, NULL, NULL, NULL, NULL); 1238 } 1239 1240 checkStatus(env, jobj, major, minor, "[GSSLibStub_inquireContextAll]"); 1241 /* return immediately if an exception has occurred */ 1242 if ((*env)->ExceptionCheck(env)) { 1243 return jlong_zero; 1244 } 1245 1246 TRACE1("[GSSLibStub_getContextName] pName=%ld", (long) nameHdl); 1247 1248 return ptr_to_jlong(nameHdl); 1249 } 1250 1251 /* 1252 * Class: sun_security_jgss_wrapper_GSSLibStub 1253 * Method: getContextTime 1254 * Signature: (J)I 1255 */ 1256 JNIEXPORT jint JNICALL 1257 Java_sun_security_jgss_wrapper_GSSLibStub_getContextTime(JNIEnv *env, 1258 jobject jobj, 1259 jlong pContext) { 1260 OM_uint32 minor, major; 1261 gss_ctx_id_t contextHdl; 1262 OM_uint32 time; 1263 1264 contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext); 1265 1266 TRACE1("[GSSLibStub_getContextTime] %ld", (long)contextHdl); 1267 1268 if (contextHdl == GSS_C_NO_CONTEXT) return 0; 1269 1270 /* gss_context_time(...) => GSS_S_CONTEXT_EXPIRED(!), 1271 GSS_S_NO_CONTEXT(!) */ 1272 major = (*ftab->contextTime)(&minor, contextHdl, &time); 1273 if (GSS_ROUTINE_ERROR(major) == GSS_S_CONTEXT_EXPIRED) { 1274 major = GSS_CALLING_ERROR(major) | GSS_SUPPLEMENTARY_INFO(major); 1275 } 1276 checkStatus(env, jobj, major, minor, "[GSSLibStub_getContextTime]"); 1277 if ((*env)->ExceptionCheck(env)) { 1278 return 0; 1279 } 1280 return getJavaTime(time); 1281 } 1282 1283 /* 1284 * Class: sun_security_jgss_wrapper_GSSLibStub 1285 * Method: deleteContext 1286 * Signature: (J)J 1287 */ 1288 JNIEXPORT jlong JNICALL 1289 Java_sun_security_jgss_wrapper_GSSLibStub_deleteContext(JNIEnv *env, 1290 jobject jobj, 1291 jlong pContext) 1292 { 1293 OM_uint32 minor, major; 1294 gss_ctx_id_t contextHdl; 1295 1296 contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext); 1297 1298 TRACE1("[GSSLibStub_deleteContext] %ld", (long)contextHdl); 1299 1300 if (contextHdl == GSS_C_NO_CONTEXT) return ptr_to_jlong(GSS_C_NO_CONTEXT); 1301 1302 /* gss_delete_sec_context(...) => GSS_S_NO_CONTEXT(!) */ 1303 major = (*ftab->deleteSecContext)(&minor, &contextHdl, GSS_C_NO_BUFFER); 1304 1305 checkStatus(env, jobj, major, minor, "[GSSLibStub_deleteContext]"); 1306 if ((*env)->ExceptionCheck(env)) { 1307 return jlong_zero; 1308 } 1309 return (jlong) ptr_to_jlong(contextHdl); 1310 } 1311 1312 /* 1313 * Class: sun_security_jgss_wrapper_GSSLibStub 1314 * Method: wrapSizeLimit 1315 * Signature: (JIII)I 1316 */ 1317 JNIEXPORT jint JNICALL 1318 Java_sun_security_jgss_wrapper_GSSLibStub_wrapSizeLimit(JNIEnv *env, 1319 jobject jobj, 1320 jlong pContext, 1321 jint reqFlag, 1322 jint jqop, 1323 jint joutSize) 1324 { 1325 OM_uint32 minor, major; 1326 gss_ctx_id_t contextHdl; 1327 OM_uint32 outSize, maxInSize; 1328 gss_qop_t qop; 1329 1330 contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext); 1331 1332 TRACE1("[GSSLibStub_wrapSizeLimit] %ld", (long)contextHdl); 1333 1334 if (contextHdl == GSS_C_NO_CONTEXT) { 1335 // Twik per javadoc 1336 checkStatus(env, jobj, GSS_S_NO_CONTEXT, 0, 1337 "[GSSLibStub_wrapSizeLimit]"); 1338 return 0; 1339 } 1340 1341 qop = (gss_qop_t) jqop; 1342 outSize = (OM_uint32) joutSize; 1343 /* gss_wrap_size_limit(...) => GSS_S_NO_CONTEXT(!), GSS_S_CONTEXT_EXPIRED, 1344 GSS_S_BAD_QOP */ 1345 major = (*ftab->wrapSizeLimit)(&minor, contextHdl, reqFlag, 1346 qop, outSize, &maxInSize); 1347 1348 checkStatus(env, jobj, major, minor, "[GSSLibStub_wrapSizeLimit]"); 1349 if ((*env)->ExceptionCheck(env)) { 1350 return 0; 1351 } 1352 return (jint) maxInSize; 1353 } 1354 1355 /* 1356 * Class: sun_security_jgss_wrapper_GSSLibStub 1357 * Method: exportContext 1358 * Signature: (J)[B 1359 */ 1360 JNIEXPORT jbyteArray JNICALL 1361 Java_sun_security_jgss_wrapper_GSSLibStub_exportContext(JNIEnv *env, 1362 jobject jobj, 1363 jlong pContext) 1364 { 1365 OM_uint32 minor, major; 1366 gss_ctx_id_t contextHdl; 1367 gss_buffer_desc interProcToken; 1368 jbyteArray jresult; 1369 1370 contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext); 1371 1372 TRACE1("[GSSLibStub_exportContext] %ld", (long)contextHdl); 1373 1374 if (contextHdl == GSS_C_NO_CONTEXT) { 1375 // Twik per javadoc 1376 checkStatus(env, jobj, GSS_S_NO_CONTEXT, 0, "[GSSLibStub_exportContext]"); 1377 return NULL; 1378 } 1379 /* gss_export_sec_context(...) => GSS_S_CONTEXT_EXPIRED, 1380 GSS_S_NO_CONTEXT, GSS_S_UNAVAILABLE */ 1381 major = 1382 (*ftab->exportSecContext)(&minor, &contextHdl, &interProcToken); 1383 1384 /* release intermediate buffers */ 1385 jresult = getJavaBuffer(env, &interProcToken); 1386 if ((*env)->ExceptionCheck(env)) { 1387 return NULL; 1388 } 1389 checkStatus(env, jobj, major, minor, "[GSSLibStub_exportContext]"); 1390 if ((*env)->ExceptionCheck(env)) { 1391 return NULL; 1392 } 1393 1394 return jresult; 1395 } 1396 1397 /* 1398 * Class: sun_security_jgss_wrapper_GSSLibStub 1399 * Method: getMic 1400 * Signature: (JI[B)[B 1401 */ 1402 JNIEXPORT jbyteArray JNICALL 1403 Java_sun_security_jgss_wrapper_GSSLibStub_getMic(JNIEnv *env, jobject jobj, 1404 jlong pContext, jint jqop, 1405 jbyteArray jmsg) 1406 { 1407 OM_uint32 minor, major; 1408 gss_ctx_id_t contextHdl; 1409 gss_qop_t qop; 1410 gss_buffer_desc msg; 1411 gss_buffer_desc msgToken; 1412 jbyteArray jresult; 1413 1414 contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext); 1415 1416 TRACE1("[GSSLibStub_getMic] %ld", (long)contextHdl); 1417 1418 if (contextHdl == GSS_C_NO_CONTEXT) { 1419 // Twik per javadoc 1420 checkStatus(env, jobj, GSS_S_CONTEXT_EXPIRED, 0, "[GSSLibStub_getMic]"); 1421 return NULL; 1422 } 1423 contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext); 1424 qop = (gss_qop_t) jqop; 1425 initGSSBuffer(env, jmsg, &msg); 1426 if ((*env)->ExceptionCheck(env)) { 1427 return NULL; 1428 } 1429 1430 /* gss_get_mic(...) => GSS_S_CONTEXT_EXPIRED, GSS_S_NO_CONTEXT(!), 1431 GSS_S_BAD_QOP */ 1432 major = 1433 (*ftab->getMic)(&minor, contextHdl, qop, &msg, &msgToken); 1434 1435 /* release intermediate buffers */ 1436 resetGSSBuffer(&msg); 1437 jresult = getJavaBuffer(env, &msgToken); 1438 if ((*env)->ExceptionCheck(env)) { 1439 return NULL; 1440 } 1441 checkStatus(env, jobj, major, minor, "[GSSLibStub_getMic]"); 1442 if ((*env)->ExceptionCheck(env)) { 1443 return NULL; 1444 } 1445 1446 return jresult; 1447 } 1448 1449 /* 1450 * Class: sun_security_jgss_wrapper_GSSLibStub 1451 * Method: verifyMic 1452 * Signature: (J[B[BLorg/ietf/jgss/MessageProp;)V 1453 */ 1454 JNIEXPORT void JNICALL 1455 Java_sun_security_jgss_wrapper_GSSLibStub_verifyMic(JNIEnv *env, 1456 jobject jobj, 1457 jlong pContext, 1458 jbyteArray jmsgToken, 1459 jbyteArray jmsg, 1460 jobject jprop) 1461 { 1462 OM_uint32 minor, major; 1463 gss_ctx_id_t contextHdl; 1464 gss_buffer_desc msg; 1465 gss_buffer_desc msgToken; 1466 gss_qop_t qop; 1467 1468 contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext); 1469 1470 TRACE1("[GSSLibStub_verifyMic] %ld", (long)contextHdl); 1471 1472 if (contextHdl == GSS_C_NO_CONTEXT) { 1473 // Twik per javadoc 1474 checkStatus(env, jobj, GSS_S_CONTEXT_EXPIRED, 0, 1475 "[GSSLibStub_verifyMic]"); 1476 return; 1477 } 1478 1479 qop = (gss_qop_t) (*env)->CallIntMethod(env, jprop, MID_MessageProp_getQOP); 1480 if ((*env)->ExceptionCheck(env)) { return; } 1481 1482 initGSSBuffer(env, jmsg, &msg); 1483 if ((*env)->ExceptionCheck(env)) { return; } 1484 1485 initGSSBuffer(env, jmsgToken, &msgToken); 1486 if ((*env)->ExceptionCheck(env)) { 1487 resetGSSBuffer(&msg); 1488 return; 1489 } 1490 1491 /* gss_verify_mic(...) => GSS_S_DEFECTIVE_TOKEN, GSS_S_BAD_MIC, 1492 GSS_S_CONTEXT_EXPIRED, GSS_S_DUPLICATE_TOKEN(!), GSS_S_OLD_TOKEN(!), 1493 GSS_S_UNSEQ_TOKEN(!), GSS_S_GAP_TOKEN(!), GSS_S_NO_CONTEXT(!) */ 1494 major = 1495 (*ftab->verifyMic)(&minor, contextHdl, &msg, &msgToken, &qop); 1496 1497 /* release intermediate buffers */ 1498 resetGSSBuffer(&msg); 1499 resetGSSBuffer(&msgToken); 1500 1501 checkStatus(env, jobj, GSS_ERROR(major), minor, "[GSSLibStub_verifyMic]"); 1502 if ((*env)->ExceptionCheck(env)) { 1503 return; 1504 } 1505 1506 (*env)->CallVoidMethod(env, jprop, MID_MessageProp_setQOP, qop); 1507 if ((*env)->ExceptionCheck(env)) { 1508 return; 1509 } 1510 1511 setSupplementaryInfo(env, jobj, jprop, GSS_SUPPLEMENTARY_INFO(major), 1512 minor); 1513 if ((*env)->ExceptionCheck(env)) { 1514 return; 1515 } 1516 } 1517 1518 /* 1519 * Class: sun_security_jgss_wrapper_GSSLibStub 1520 * Method: wrap 1521 * Signature: (J[BLorg/ietf/jgss/MessageProp;)[B 1522 */ 1523 JNIEXPORT jbyteArray JNICALL 1524 Java_sun_security_jgss_wrapper_GSSLibStub_wrap(JNIEnv *env, 1525 jobject jobj, 1526 jlong pContext, 1527 jbyteArray jmsg, 1528 jobject jprop) 1529 { 1530 OM_uint32 minor, major; 1531 jboolean confFlag; 1532 gss_qop_t qop; 1533 gss_buffer_desc msg; 1534 gss_buffer_desc msgToken; 1535 int confState; 1536 gss_ctx_id_t contextHdl; 1537 jbyteArray jresult; 1538 1539 contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext); 1540 1541 TRACE1("[GSSLibStub_wrap] %ld", (long)contextHdl); 1542 1543 if (contextHdl == GSS_C_NO_CONTEXT) { 1544 // Twik per javadoc 1545 checkStatus(env, jobj, GSS_S_CONTEXT_EXPIRED, 0, "[GSSLibStub_wrap]"); 1546 return NULL; 1547 } 1548 1549 confFlag = 1550 (*env)->CallBooleanMethod(env, jprop, MID_MessageProp_getPrivacy); 1551 if ((*env)->ExceptionCheck(env)) { 1552 return NULL; 1553 } 1554 1555 qop = (gss_qop_t) 1556 (*env)->CallIntMethod(env, jprop, MID_MessageProp_getQOP); 1557 if ((*env)->ExceptionCheck(env)) { 1558 return NULL; 1559 } 1560 1561 initGSSBuffer(env, jmsg, &msg); 1562 if ((*env)->ExceptionCheck(env)) { 1563 return NULL; 1564 } 1565 1566 /* gss_wrap(...) => GSS_S_CONTEXT_EXPIRED, GSS_S_NO_CONTEXT(!), 1567 GSS_S_BAD_QOP */ 1568 major = (*ftab->wrap)(&minor, contextHdl, confFlag, qop, &msg, &confState, 1569 &msgToken); 1570 1571 /* release intermediate buffers */ 1572 resetGSSBuffer(&msg); 1573 jresult = getJavaBuffer(env, &msgToken); 1574 if ((*env)->ExceptionCheck(env)) { 1575 return NULL; 1576 } 1577 1578 checkStatus(env, jobj, major, minor, "[GSSLibStub_wrap]"); 1579 if ((*env)->ExceptionCheck(env)) { 1580 return NULL; 1581 } 1582 1583 (*env)->CallVoidMethod(env, jprop, MID_MessageProp_setPrivacy, 1584 (confState? JNI_TRUE:JNI_FALSE)); 1585 if ((*env)->ExceptionCheck(env)) { 1586 return NULL; 1587 } 1588 return jresult; 1589 } 1590 1591 /* 1592 * Class: sun_security_jgss_wrapper_GSSLibStub 1593 * Method: unwrap 1594 * Signature: (J[BLorg/ietf/jgss/MessageProp;)[B 1595 */ 1596 JNIEXPORT jbyteArray JNICALL 1597 Java_sun_security_jgss_wrapper_GSSLibStub_unwrap(JNIEnv *env, 1598 jobject jobj, 1599 jlong pContext, 1600 jbyteArray jmsgToken, 1601 jobject jprop) 1602 { 1603 OM_uint32 minor, major; 1604 gss_ctx_id_t contextHdl; 1605 gss_buffer_desc msgToken; 1606 gss_buffer_desc msg; 1607 int confState; 1608 gss_qop_t qop; 1609 jbyteArray jresult; 1610 1611 contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext); 1612 1613 TRACE1("[GSSLibStub_unwrap] %ld", (long)contextHdl); 1614 1615 if (contextHdl == GSS_C_NO_CONTEXT) { 1616 // Twik per javadoc 1617 checkStatus(env, jobj, GSS_S_CONTEXT_EXPIRED, 0, "[GSSLibStub_unwrap]"); 1618 return NULL; 1619 } 1620 1621 initGSSBuffer(env, jmsgToken, &msgToken); 1622 if ((*env)->ExceptionCheck(env)) { 1623 return NULL; 1624 } 1625 1626 confState = 0; 1627 qop = GSS_C_QOP_DEFAULT; 1628 /* gss_unwrap(...) => GSS_S_DEFECTIVE_TOKEN, GSS_S_BAD_MIC, 1629 GSS_S_CONTEXT_EXPIRED, GSS_S_DUPLICATE_TOKEN(!), GSS_S_OLD_TOKEN(!), 1630 GSS_S_UNSEQ_TOKEN(!), GSS_S_GAP_TOKEN(!), GSS_S_NO_CONTEXT(!) */ 1631 major = 1632 (*ftab->unwrap)(&minor, contextHdl, &msgToken, &msg, &confState, &qop); 1633 1634 /* release intermediate buffers */ 1635 resetGSSBuffer(&msgToken); 1636 jresult = getJavaBuffer(env, &msg); 1637 if ((*env)->ExceptionCheck(env)) { 1638 return NULL; 1639 } 1640 1641 checkStatus(env, jobj, GSS_ERROR(major), minor, "[GSSLibStub_unwrap]"); 1642 if ((*env)->ExceptionCheck(env)) { 1643 return NULL; 1644 } 1645 1646 /* update the message prop with relevant info */ 1647 (*env)->CallVoidMethod(env, jprop, MID_MessageProp_setPrivacy, 1648 (confState != 0)); 1649 if ((*env)->ExceptionCheck(env)) { 1650 return NULL; 1651 } 1652 (*env)->CallVoidMethod(env, jprop, MID_MessageProp_setQOP, qop); 1653 if ((*env)->ExceptionCheck(env)) { 1654 return NULL; 1655 } 1656 setSupplementaryInfo(env, jobj, jprop, GSS_SUPPLEMENTARY_INFO(major), 1657 minor); 1658 if ((*env)->ExceptionCheck(env)) { 1659 return NULL; 1660 } 1661 1662 return jresult; 1663 }