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