From ab75d799e3dc492fb55f18233f0dbfc2b46a8b96 Mon Sep 17 00:00:00 2001 From: Michael McMahon Date: Thu, 29 Nov 2012 09:41:20 +0000 Subject: [PATCH] 7200720: crash in net.dll during NTLM authentication Reviewed-by: chegar, dsamersoff --- jdk/make/java/net/Makefile | 1 + .../protocol/http/ntlm/NTLMAuthSequence.java | 25 +++++++++++--- .../http/ntlm/NTLMAuthentication.java | 4 +++ .../www/protocol/http/ntlm/NTLMAuthSequence.c | 33 ++++++++++++------- 4 files changed, 48 insertions(+), 15 deletions(-) diff --git a/jdk/make/java/net/Makefile b/jdk/make/java/net/Makefile index 60f83869f74..d45c92087f4 100644 --- a/jdk/make/java/net/Makefile +++ b/jdk/make/java/net/Makefile @@ -77,6 +77,7 @@ ifeq ($(PLATFORM), windows) FILES_export += java/net/DualStackPlainSocketImpl.java FILES_export += java/net/TwoStacksPlainDatagramSocketImpl.java FILES_export += java/net/DualStackPlainDatagramSocketImpl.java + FILES_export += sun/net/www/protocol/http/ntlm/NTLMAuthSequence.java else FILES_export += java/net/PlainDatagramSocketImpl.java endif diff --git a/jdk/src/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthSequence.java b/jdk/src/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthSequence.java index b48cdec9471..5e6cbb02f31 100644 --- a/jdk/src/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthSequence.java +++ b/jdk/src/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthSequence.java @@ -45,15 +45,25 @@ public class NTLMAuthSequence { private long ctxHandle; static { - initFirst(); + initFirst(Status.class); } + // Used by native code to indicate when a particular protocol sequence is completed + // and must not be re-used. + + class Status { + boolean sequenceComplete; + } + + Status status; + NTLMAuthSequence (String username, String password, String ntdomain) throws IOException { this.username = username; this.password = password; this.ntdomain = ntdomain; + this.status = new Status(); state = 0; crdHandle = getCredentialsHandle (username, ntdomain, password); if (crdHandle == 0) { @@ -63,19 +73,26 @@ public class NTLMAuthSequence { public String getAuthHeader (String token) throws IOException { byte[] input = null; + + assert !status.sequenceComplete; + if (token != null) input = (new BASE64Decoder()).decodeBuffer(token); - byte[] b = getNextToken (crdHandle, input); + byte[] b = getNextToken (crdHandle, input, status); if (b == null) throw new IOException ("Internal authentication error"); return (new B64Encoder()).encode (b); } - private native static void initFirst (); + public boolean isComplete() { + return status.sequenceComplete; + } + + private native static void initFirst (Class clazz); private native long getCredentialsHandle (String user, String domain, String password); - private native byte[] getNextToken (long crdHandle, byte[] lastToken); + private native byte[] getNextToken (long crdHandle, byte[] lastToken, Status returned); } class B64Encoder extends BASE64Encoder { diff --git a/jdk/src/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java b/jdk/src/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java index 8ca04d7fef7..8a8dc305087 100644 --- a/jdk/src/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java +++ b/jdk/src/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java @@ -193,8 +193,12 @@ public class NTLMAuthentication extends AuthenticationInfo { } String response = "NTLM " + seq.getAuthHeader (raw.length()>6?raw.substring(5):null); conn.setAuthenticationProperty(getHeaderName(), response); + if (seq.isComplete()) { + conn.authObj(null); + } return true; } catch (IOException e) { + conn.authObj(null); return false; } } diff --git a/jdk/src/windows/native/sun/net/www/protocol/http/ntlm/NTLMAuthSequence.c b/jdk/src/windows/native/sun/net/www/protocol/http/ntlm/NTLMAuthSequence.c index c648f7b764e..783f122a2b7 100644 --- a/jdk/src/windows/native/sun/net/www/protocol/http/ntlm/NTLMAuthSequence.c +++ b/jdk/src/windows/native/sun/net/www/protocol/http/ntlm/NTLMAuthSequence.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,18 +41,20 @@ #define SECURITY_WIN32 #include "sspi.h" -static void endSequence (PCredHandle credHand, PCtxtHandle ctxHandle); +static void endSequence (PCredHandle credHand, PCtxtHandle ctxHandle, JNIEnv *env, jobject status); static jfieldID ntlm_ctxHandleID; static jfieldID ntlm_crdHandleID; +static jfieldID status_seqCompleteID; static HINSTANCE lib = NULL; JNIEXPORT void JNICALL Java_sun_net_www_protocol_http_ntlm_NTLMAuthSequence_initFirst -(JNIEnv *env, jclass clazz) +(JNIEnv *env, jclass authseq_clazz, jclass status_clazz) { - ntlm_ctxHandleID = (*env)->GetFieldID(env, clazz, "ctxHandle", "J"); - ntlm_crdHandleID = (*env)->GetFieldID(env, clazz, "crdHandle", "J"); + ntlm_ctxHandleID = (*env)->GetFieldID(env, authseq_clazz, "ctxHandle", "J"); + ntlm_crdHandleID = (*env)->GetFieldID(env, authseq_clazz, "crdHandle", "J"); + status_seqCompleteID = (*env)->GetFieldID(env, status_clazz, "sequenceComplete", "Z"); } /* @@ -145,8 +147,14 @@ JNIEXPORT jlong JNICALL Java_sun_net_www_protocol_http_ntlm_NTLMAuthSequence_get } } + +/* + * Class: sun_net_www_protocol_http_ntlm_NTLMAuthSequence + * Method: getNextToken + * Signature: (J[BLsun/net/www/protocol/http/ntlm/NTLMAuthSequence/Status;)[B + */ JNIEXPORT jbyteArray JNICALL Java_sun_net_www_protocol_http_ntlm_NTLMAuthSequence_getNextToken -(JNIEnv *env, jobject this, jlong crdHandle, jbyteArray lastToken) +(JNIEnv *env, jobject this, jlong crdHandle, jbyteArray lastToken, jobject status) { VOID *pInput = 0; @@ -217,7 +225,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_net_www_protocol_http_ntlm_NTLMAuthSequenc } if (ss < 0) { - endSequence (pCred, pCtx); + endSequence (pCred, pCtx, env, status); return 0; } @@ -225,7 +233,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_net_www_protocol_http_ntlm_NTLMAuthSequenc ss = CompleteAuthToken( pCtx, &OutBuffDesc ); if (ss < 0) { - endSequence (pCred, pCtx); + endSequence (pCred, pCtx, env, status); return 0; } } @@ -235,18 +243,18 @@ JNIEXPORT jbyteArray JNICALL Java_sun_net_www_protocol_http_ntlm_NTLMAuthSequenc (*env)->SetByteArrayRegion(env, ret, 0, OutSecBuff.cbBuffer, OutSecBuff.pvBuffer); if (lastToken != 0) // 2nd stage - endSequence (pCred, pCtx); + endSequence (pCred, pCtx, env, status); result = ret; } if ((ss != SEC_I_CONTINUE_NEEDED) && (ss == SEC_I_COMPLETE_AND_CONTINUE)) { - endSequence (pCred, pCtx); + endSequence (pCred, pCtx, env, status); } return result; } -static void endSequence (PCredHandle credHand, PCtxtHandle ctxHandle) { +static void endSequence (PCredHandle credHand, PCtxtHandle ctxHandle, JNIEnv *env, jobject status) { if (credHand != 0) { FreeCredentialsHandle(credHand); free(credHand); @@ -256,4 +264,7 @@ static void endSequence (PCredHandle credHand, PCtxtHandle ctxHandle) { DeleteSecurityContext(ctxHandle); free(ctxHandle); } + + /* Sequence is complete so set flag */ + (*env)->SetBooleanField(env, status, status_seqCompleteID, JNI_TRUE); }