7200720: crash in net.dll during NTLM authentication
Reviewed-by: chegar, dsamersoff
--- a/jdk/make/java/net/Makefile Fri Nov 23 13:07:54 2012 +0400
+++ b/jdk/make/java/net/Makefile Thu Nov 29 09:41:20 2012 +0000
@@ -77,6 +77,7 @@
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
--- a/jdk/src/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthSequence.java Fri Nov 23 13:07:54 2012 +0400
+++ b/jdk/src/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthSequence.java Thu Nov 29 09:41:20 2012 +0000
@@ -45,15 +45,25 @@
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 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<NTLMAuthSequence.Status> 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 {
--- a/jdk/src/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java Fri Nov 23 13:07:54 2012 +0400
+++ b/jdk/src/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java Thu Nov 29 09:41:20 2012 +0000
@@ -193,8 +193,12 @@
}
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;
}
}
--- a/jdk/src/windows/native/sun/net/www/protocol/http/ntlm/NTLMAuthSequence.c Fri Nov 23 13:07:54 2012 +0400
+++ b/jdk/src/windows/native/sun/net/www/protocol/http/ntlm/NTLMAuthSequence.c Thu Nov 29 09:41:20 2012 +0000
@@ -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 @@
}
}
+
+/*
+ * 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 @@
}
if (ss < 0) {
- endSequence (pCred, pCtx);
+ endSequence (pCred, pCtx, env, status);
return 0;
}
@@ -225,7 +233,7 @@
ss = CompleteAuthToken( pCtx, &OutBuffDesc );
if (ss < 0) {
- endSequence (pCred, pCtx);
+ endSequence (pCred, pCtx, env, status);
return 0;
}
}
@@ -235,18 +243,18 @@
(*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 @@
DeleteSecurityContext(ctxHandle);
free(ctxHandle);
}
+
+ /* Sequence is complete so set flag */
+ (*env)->SetBooleanField(env, status, status_seqCompleteID, JNI_TRUE);
}