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