提交 b83823d6 编写于 作者: W weijun

7150092: NTLM authentication fail if user specified a different realm

Reviewed-by: michaelm
上级 fffb4919
...@@ -46,7 +46,7 @@ public final class Client extends NTLM { ...@@ -46,7 +46,7 @@ public final class Client extends NTLM {
final private String hostname; final private String hostname;
final private String username; final private String username;
private String domain; // might be updated by Type 2 msg private String domain;
private byte[] pw1, pw2; private byte[] pw1, pw2;
/** /**
...@@ -82,7 +82,7 @@ public final class Client extends NTLM { ...@@ -82,7 +82,7 @@ public final class Client extends NTLM {
} }
this.hostname = hostname; this.hostname = hostname;
this.username = username; this.username = username;
this.domain = domain; this.domain = domain == null ? "" : domain;
this.pw1 = getP1(password); this.pw1 = getP1(password);
this.pw2 = getP2(password); this.pw2 = getP2(password);
debug("NTLM Client: (h,u,t,version(v)) = (%s,%s,%s,%s(%s))\n", debug("NTLM Client: (h,u,t,version(v)) = (%s,%s,%s,%s(%s))\n",
...@@ -95,19 +95,13 @@ public final class Client extends NTLM { ...@@ -95,19 +95,13 @@ public final class Client extends NTLM {
*/ */
public byte[] type1() { public byte[] type1() {
Writer p = new Writer(1, 32); Writer p = new Writer(1, 32);
int flags = 0x8203; // Negotiate always sign, Negotiate NTLM,
if (hostname != null) { // Request Target, Negotiate OEM, Negotiate unicode
flags |= 0x2000; int flags = 0x8207;
}
if (domain != null) {
flags |= 0x1000;
}
if (v != Version.NTLM) { if (v != Version.NTLM) {
flags |= 0x80000; flags |= 0x80000;
} }
p.writeInt(12, flags); p.writeInt(12, flags);
p.writeSecurityBuffer(24, hostname, false);
p.writeSecurityBuffer(16, domain, false);
debug("NTLM Client: Type 1 created\n"); debug("NTLM Client: Type 1 created\n");
debug(p.getBytes()); debug(p.getBytes());
return p.getBytes(); return p.getBytes();
...@@ -133,13 +127,10 @@ public final class Client extends NTLM { ...@@ -133,13 +127,10 @@ public final class Client extends NTLM {
byte[] challenge = r.readBytes(24, 8); byte[] challenge = r.readBytes(24, 8);
int inputFlags = r.readInt(20); int inputFlags = r.readInt(20);
boolean unicode = (inputFlags & 1) == 1; boolean unicode = (inputFlags & 1) == 1;
String domainFromServer = r.readSecurityBuffer(12, unicode);
if (domainFromServer != null) { // IE uses domainFromServer to generate an alist if server has not
domain = domainFromServer; // provided one. Firefox/WebKit do not. Neither do we.
} //String domainFromServer = r.readSecurityBuffer(12, unicode);
if (domain == null) {
domain = "";
}
int flags = 0x88200 | (inputFlags & 3); int flags = 0x88200 | (inputFlags & 3);
Writer p = new Writer(3, 64); Writer p = new Writer(3, 64);
...@@ -163,7 +154,9 @@ public final class Client extends NTLM { ...@@ -163,7 +154,9 @@ public final class Client extends NTLM {
if (writeLM) lm = calcV2(nthash, if (writeLM) lm = calcV2(nthash,
username.toUpperCase(Locale.US)+domain, nonce, challenge); username.toUpperCase(Locale.US)+domain, nonce, challenge);
if (writeNTLM) { if (writeNTLM) {
byte[] alist = type2.length > 48 ? // Some client create a alist even if server does not send
// one: (i16)2 (i16)len target_in_unicode (i16)0 (i16) 0
byte[] alist = ((inputFlags & 0x800000) != 0) ?
r.readSecurityBuffer(40) : new byte[0]; r.readSecurityBuffer(40) : new byte[0];
byte[] blob = new byte[32+alist.length]; byte[] blob = new byte[32+alist.length];
System.arraycopy(new byte[]{1,1,0,0,0,0,0,0}, 0, blob, 0, 8); System.arraycopy(new byte[]{1,1,0,0,0,0,0,0}, 0, blob, 0, 8);
......
/* /*
* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
...@@ -92,7 +93,9 @@ public abstract class Server extends NTLM { ...@@ -92,7 +93,9 @@ public abstract class Server extends NTLM {
debug("NTLM Server: Type 1 received\n"); debug("NTLM Server: Type 1 received\n");
if (type1 != null) debug(type1); if (type1 != null) debug(type1);
Writer p = new Writer(2, 32); Writer p = new Writer(2, 32);
int flags = 0x80205; // Negotiate NTLM2 Key, Target Type Domain,
// Negotiate NTLM, Request Target, Negotiate unicode
int flags = 0x90205;
p.writeSecurityBuffer(12, domain, true); p.writeSecurityBuffer(12, domain, true);
p.writeInt(20, flags); p.writeInt(20, flags);
p.writeBytes(24, nonce); p.writeBytes(24, nonce);
...@@ -127,8 +130,9 @@ public abstract class Server extends NTLM { ...@@ -127,8 +130,9 @@ public abstract class Server extends NTLM {
"Wrong domain: " + incomingDomain + "Wrong domain: " + incomingDomain +
" vs " + domain); // Needed? " vs " + domain); // Needed?
}*/ }*/
boolean verified = false; boolean verified = false;
char[] password = getPassword(domain, username); char[] password = getPassword(incomingDomain, username);
if (password == null) { if (password == null) {
throw new NTLMException(NTLMException.USER_UNKNOWN, throw new NTLMException(NTLMException.USER_UNKNOWN,
"Unknown user"); "Unknown user");
...@@ -179,6 +183,8 @@ public abstract class Server extends NTLM { ...@@ -179,6 +183,8 @@ public abstract class Server extends NTLM {
} }
} }
if (incomingNTLM.length > 0) { if (incomingNTLM.length > 0) {
// We didn't sent alist in type2(), so there
// is nothing to check here.
byte[] clientBlob = Arrays.copyOfRange( byte[] clientBlob = Arrays.copyOfRange(
incomingNTLM, 16, incomingNTLM.length); incomingNTLM, 16, incomingNTLM.length);
byte[] ntlmresponse = calcV2(nthash, byte[] ntlmresponse = calcV2(nthash,
......
...@@ -160,9 +160,17 @@ final class NTLMClient implements SaslClient { ...@@ -160,9 +160,17 @@ final class NTLMClient implements SaslClient {
} }
} }
try { try {
String name = ncb.getName();
if (name == null) {
name = authzid;
}
String domain = dcb.getText();
if (domain == null) {
domain = serverName;
}
client = new Client(version, hostname, client = new Client(version, hostname,
ncb.getName(), name,
dcb.getText(), domain,
pcb.getPassword()); pcb.getPassword());
} catch (NTLMException ne) { } catch (NTLMException ne) {
throw new SaslException( throw new SaslException(
......
...@@ -141,8 +141,10 @@ final class NTLMServer implements SaslServer { ...@@ -141,8 +141,10 @@ final class NTLMServer implements SaslServer {
server = new Server(version, domain) { server = new Server(version, domain) {
public char[] getPassword(String ntdomain, String username) { public char[] getPassword(String ntdomain, String username) {
try { try {
RealmCallback rcb = new RealmCallback( RealmCallback rcb =
"Domain: ", ntdomain); (ntdomain == null || ntdomain.isEmpty())
? new RealmCallback("Domain: ")
: new RealmCallback("Domain: ", ntdomain);
NameCallback ncb = new NameCallback( NameCallback ncb = new NameCallback(
"Name: ", username); "Name: ", username);
PasswordCallback pcb = new PasswordCallback( PasswordCallback pcb = new PasswordCallback(
......
...@@ -77,8 +77,7 @@ public class NTLMAuthentication extends AuthenticationInfo { ...@@ -77,8 +77,7 @@ public class NTLMAuthentication extends AuthenticationInfo {
static { static {
defaultDomain = java.security.AccessController.doPrivileged( defaultDomain = java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction("http.auth.ntlm.domain", new sun.security.action.GetPropertyAction("http.auth.ntlm.domain", ""));
"domain"));
}; };
public static boolean supportsTransparentAuth () { public static boolean supportsTransparentAuth () {
...@@ -100,17 +99,13 @@ public class NTLMAuthentication extends AuthenticationInfo { ...@@ -100,17 +99,13 @@ public class NTLMAuthentication extends AuthenticationInfo {
public String run() { public String run() {
String localhost; String localhost;
try { try {
localhost = InetAddress.getLocalHost().getHostName().toUpperCase(); localhost = InetAddress.getLocalHost().getHostName();
} catch (UnknownHostException e) { } catch (UnknownHostException e) {
localhost = "localhost"; localhost = "localhost";
} }
return localhost; return localhost;
} }
}); });
int x = hostname.indexOf ('.');
if (x != -1) {
hostname = hostname.substring (0, x);
}
}; };
PasswordAuthentication pw; PasswordAuthentication pw;
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
/* /*
* @test * @test
* @bug 6911951 * @bug 6911951 7150092
* @summary NTLM should be a supported Java SASL mechanism * @summary NTLM should be a supported Java SASL mechanism
*/ */
import java.io.IOException; import java.io.IOException;
...@@ -59,7 +59,6 @@ public class NTLMTest { ...@@ -59,7 +59,6 @@ public class NTLMTest {
checkAuthOnly(); checkAuthOnly();
checkClientNameOverride(); checkClientNameOverride();
checkServerDomainOverride();
checkClientDomainOverride(); checkClientDomainOverride();
checkVersions(); checkVersions();
checkClientHostname(); checkClientHostname();
...@@ -116,15 +115,12 @@ public class NTLMTest { ...@@ -116,15 +115,12 @@ public class NTLMTest {
Map<String,Object> ps = new HashMap<>(); Map<String,Object> ps = new HashMap<>();
ps.put("com.sun.security.sasl.ntlm.version", vs); ps.put("com.sun.security.sasl.ntlm.version", vs);
SaslClient clnt = Sasl.createSaslClient( SaslClient clnt = Sasl.createSaslClient(
new String[]{MECH}, USER1, PROTOCOL, null, pc, new String[]{MECH}, USER1, PROTOCOL, REALM, pc,
new CallbackHandler() { new CallbackHandler() {
public void handle(Callback[] callbacks) public void handle(Callback[] callbacks)
throws IOException, UnsupportedCallbackException { throws IOException, UnsupportedCallbackException {
for (Callback cb: callbacks) { for (Callback cb: callbacks) {
if (cb instanceof NameCallback) { if (cb instanceof PasswordCallback) {
NameCallback ncb = (NameCallback)cb;
ncb.setName(ncb.getDefaultName());
} else if (cb instanceof PasswordCallback) {
((PasswordCallback)cb).setPassword(PASS1); ((PasswordCallback)cb).setPassword(PASS1);
} }
} }
...@@ -159,15 +155,12 @@ public class NTLMTest { ...@@ -159,15 +155,12 @@ public class NTLMTest {
Map<String,Object> pc = new HashMap<>(); Map<String,Object> pc = new HashMap<>();
pc.put("com.sun.security.sasl.ntlm.hostname", "this.is.com"); pc.put("com.sun.security.sasl.ntlm.hostname", "this.is.com");
SaslClient clnt = Sasl.createSaslClient( SaslClient clnt = Sasl.createSaslClient(
new String[]{MECH}, USER1, PROTOCOL, null, pc, new String[]{MECH}, USER1, PROTOCOL, REALM, pc,
new CallbackHandler() { new CallbackHandler() {
public void handle(Callback[] callbacks) public void handle(Callback[] callbacks)
throws IOException, UnsupportedCallbackException { throws IOException, UnsupportedCallbackException {
for (Callback cb: callbacks) { for (Callback cb: callbacks) {
if (cb instanceof NameCallback) { if (cb instanceof PasswordCallback) {
NameCallback ncb = (NameCallback)cb;
ncb.setName(ncb.getDefaultName());
} else if (cb instanceof PasswordCallback) {
((PasswordCallback)cb).setPassword(PASS1); ((PasswordCallback)cb).setPassword(PASS1);
} }
} }
...@@ -212,12 +205,8 @@ public class NTLMTest { ...@@ -212,12 +205,8 @@ public class NTLMTest {
public void handle(Callback[] callbacks) public void handle(Callback[] callbacks)
throws IOException, UnsupportedCallbackException { throws IOException, UnsupportedCallbackException {
for (Callback cb: callbacks) { for (Callback cb: callbacks) {
if (cb instanceof NameCallback) { if (cb instanceof RealmCallback) {
NameCallback ncb = (NameCallback)cb; ((RealmCallback)cb).setText(REALM);
ncb.setName(ncb.getDefaultName());
} else if(cb instanceof RealmCallback) {
RealmCallback dcb = (RealmCallback)cb;
dcb.setText("THIRDDOMAIN");
} else if (cb instanceof PasswordCallback) { } else if (cb instanceof PasswordCallback) {
((PasswordCallback)cb).setPassword(PASS1); ((PasswordCallback)cb).setPassword(PASS1);
} }
...@@ -255,13 +244,13 @@ public class NTLMTest { ...@@ -255,13 +244,13 @@ public class NTLMTest {
*/ */
private static void checkClientNameOverride() throws Exception { private static void checkClientNameOverride() throws Exception {
SaslClient clnt = Sasl.createSaslClient( SaslClient clnt = Sasl.createSaslClient(
new String[]{MECH}, null, PROTOCOL, null, null, new String[]{MECH}, "someone", PROTOCOL, REALM, null,
new CallbackHandler() { new CallbackHandler() {
public void handle(Callback[] callbacks) public void handle(Callback[] callbacks)
throws IOException, UnsupportedCallbackException { throws IOException, UnsupportedCallbackException {
for (Callback cb: callbacks) { for (Callback cb: callbacks) {
if (cb instanceof NameCallback) { if (cb instanceof NameCallback) {
NameCallback ncb = (NameCallback)cb; NameCallback ncb = (NameCallback) cb;
ncb.setName(USER1); ncb.setName(USER1);
} else if (cb instanceof PasswordCallback) { } else if (cb instanceof PasswordCallback) {
((PasswordCallback)cb).setPassword(PASS1); ((PasswordCallback)cb).setPassword(PASS1);
...@@ -270,54 +259,7 @@ public class NTLMTest { ...@@ -270,54 +259,7 @@ public class NTLMTest {
} }
}); });
SaslServer srv = Sasl.createSaslServer(MECH, PROTOCOL, REALM, null, SaslServer srv = Sasl.createSaslServer(MECH, PROTOCOL, "FAKE", null,
new CallbackHandler() {
public void handle(Callback[] callbacks)
throws IOException, UnsupportedCallbackException {
String domain = null, name = null;
PasswordCallback pcb = null;
for (Callback cb: callbacks) {
if (cb instanceof NameCallback) {
name = ((NameCallback)cb).getDefaultName();
} else if (cb instanceof RealmCallback) {
domain = ((RealmCallback)cb).getDefaultText();
} else if (cb instanceof PasswordCallback) {
pcb = (PasswordCallback)cb;
}
}
if (pcb != null) {
pcb.setPassword(getPass(domain, name));
}
}
});
handshake(clnt, srv);
}
/**
* server side domain provided in props.
* @throws Exception
*/
private static void checkServerDomainOverride() throws Exception {
SaslClient clnt = Sasl.createSaslClient(
new String[]{MECH}, USER1, PROTOCOL, null, null,
new CallbackHandler() {
public void handle(Callback[] callbacks)
throws IOException, UnsupportedCallbackException {
for (Callback cb: callbacks) {
if (cb instanceof NameCallback) {
NameCallback ncb = (NameCallback)cb;
ncb.setName(ncb.getDefaultName());
} else if (cb instanceof PasswordCallback) {
((PasswordCallback)cb).setPassword(PASS1);
}
}
}
});
Map<String,Object> ps = new HashMap<>();
ps.put("com.sun.security.sasl.ntlm.domain", REALM);
SaslServer srv = Sasl.createSaslServer(MECH, PROTOCOL, null, ps,
new CallbackHandler() { new CallbackHandler() {
public void handle(Callback[] callbacks) public void handle(Callback[] callbacks)
throws IOException, UnsupportedCallbackException { throws IOException, UnsupportedCallbackException {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册