Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/com/sun/security/sasl/ntlm/NTLMTest.java
38867 views
/*1* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 6911951 715009226* @summary NTLM should be a supported Java SASL mechanism27*/28import java.io.IOException;29import javax.security.sasl.*;30import javax.security.auth.callback.*;31import java.util.*;3233public class NTLMTest {3435private static final String MECH = "NTLM";36private static final String REALM = "REALM";37private static final String PROTOCOL = "jmx";38private static final byte[] EMPTY = new byte[0];3940private static final String USER1 = "dummy";41private static final char[] PASS1 = "bogus".toCharArray();42private static final String USER2 = "foo";43private static final char[] PASS2 = "bar".toCharArray();4445private static final Map<String,char[]> maps =46new HashMap<String,char[]>();47static {48maps.put(USER1, PASS1);49maps.put(USER2, PASS2);50}5152static char[] getPass(String d, String u) {53if (!d.equals(REALM)) return null;54return maps.get(u);55}5657public static void main(String[] args) throws Exception {5859checkAuthOnly();60checkClientNameOverride();61checkClientDomainOverride();62checkVersions();63checkClientHostname();64}6566static void checkVersions() throws Exception {67// Server accepts all version68checkVersion(null, null);69checkVersion("LM/NTLM", null);70checkVersion("LM", null);71checkVersion("NTLM", null);72checkVersion("NTLM2", null);73checkVersion("LMv2/NTLMv2", null);74checkVersion("LMv2", null);75checkVersion("NTLMv2", null);7677// Client's default version is LMv278checkVersion(null, "LMv2");7980// Also works if they specified identical versions81checkVersion("LM/NTLM", "LM");82checkVersion("LM", "LM");83checkVersion("NTLM", "LM");84checkVersion("NTLM2", "NTLM2");85checkVersion("LMv2/NTLMv2", "LMv2");86checkVersion("LMv2", "LMv2");87checkVersion("NTLMv2", "LMv2");8889// But should not work if different90try {91checkVersion("LM/NTLM", "LMv2");92throw new Exception("Should not succeed");93} catch (SaslException se) {94// OK95}96try {97checkVersion("LMv2/NTLMv2", "LM");98throw new Exception("Should not succeed");99} catch (SaslException se) {100// OK101}102103}104105/**106* A test on version matching107* @param vc ntlm version specified for client108* @param vs ntlm version specified for server109* @throws Exception110*/111private static void checkVersion(String vc, String vs) throws Exception {112Map<String,Object> pc = new HashMap<>();113pc.put("com.sun.security.sasl.ntlm.version", vc);114Map<String,Object> ps = new HashMap<>();115ps.put("com.sun.security.sasl.ntlm.version", vs);116SaslClient clnt = Sasl.createSaslClient(117new String[]{MECH}, USER1, PROTOCOL, REALM, pc,118new CallbackHandler() {119public void handle(Callback[] callbacks)120throws IOException, UnsupportedCallbackException {121for (Callback cb: callbacks) {122if (cb instanceof PasswordCallback) {123((PasswordCallback)cb).setPassword(PASS1);124}125}126}127});128129SaslServer srv = Sasl.createSaslServer(MECH, PROTOCOL, REALM, ps,130new CallbackHandler() {131public void handle(Callback[] callbacks)132throws IOException, UnsupportedCallbackException {133String domain = null, name = null;134PasswordCallback pcb = null;135for (Callback cb: callbacks) {136if (cb instanceof NameCallback) {137name = ((NameCallback)cb).getDefaultName();138} else if (cb instanceof RealmCallback) {139domain = ((RealmCallback)cb).getDefaultText();140} else if (cb instanceof PasswordCallback) {141pcb = (PasswordCallback)cb;142}143}144if (pcb != null) {145pcb.setPassword(getPass(domain, name));146}147}148});149150handshake(clnt, srv);151}152153private static void checkClientHostname() throws Exception {154Map<String,Object> pc = new HashMap<>();155pc.put("com.sun.security.sasl.ntlm.hostname", "this.is.com");156SaslClient clnt = Sasl.createSaslClient(157new String[]{MECH}, USER1, PROTOCOL, REALM, pc,158new CallbackHandler() {159public void handle(Callback[] callbacks)160throws IOException, UnsupportedCallbackException {161for (Callback cb: callbacks) {162if (cb instanceof PasswordCallback) {163((PasswordCallback)cb).setPassword(PASS1);164}165}166}167});168169SaslServer srv = Sasl.createSaslServer(MECH, PROTOCOL, REALM, null,170new CallbackHandler() {171public void handle(Callback[] callbacks)172throws IOException, UnsupportedCallbackException {173String domain = null, name = null;174PasswordCallback pcb = null;175for (Callback cb: callbacks) {176if (cb instanceof NameCallback) {177name = ((NameCallback)cb).getDefaultName();178} else if (cb instanceof RealmCallback) {179domain = ((RealmCallback)cb).getDefaultText();180} else if (cb instanceof PasswordCallback) {181pcb = (PasswordCallback)cb;182}183}184if (pcb != null) {185pcb.setPassword(getPass(domain, name));186}187}188});189190handshake(clnt, srv);191if (!"this.is.com".equals(192srv.getNegotiatedProperty("com.sun.security.sasl.ntlm.hostname"))) {193throw new Exception("Hostname not trasmitted to server");194}195}196197/**198* Client realm override, but finally overridden by server response199*/200private static void checkClientDomainOverride() throws Exception {201SaslClient clnt = Sasl.createSaslClient(202new String[]{MECH}, USER1, PROTOCOL, "ANOTHERREALM", null,203new CallbackHandler() {204public void handle(Callback[] callbacks)205throws IOException, UnsupportedCallbackException {206for (Callback cb: callbacks) {207if (cb instanceof RealmCallback) {208((RealmCallback)cb).setText(REALM);209} else if (cb instanceof PasswordCallback) {210((PasswordCallback)cb).setPassword(PASS1);211}212}213}214});215216SaslServer srv = Sasl.createSaslServer(MECH, PROTOCOL, REALM, null,217new CallbackHandler() {218public void handle(Callback[] callbacks)219throws IOException, UnsupportedCallbackException {220String domain = null, name = null;221PasswordCallback pcb = null;222for (Callback cb: callbacks) {223if (cb instanceof NameCallback) {224name = ((NameCallback)cb).getDefaultName();225} else if (cb instanceof RealmCallback) {226domain = ((RealmCallback)cb).getDefaultText();227} else if (cb instanceof PasswordCallback) {228pcb = (PasswordCallback)cb;229}230}231if (pcb != null) {232pcb.setPassword(getPass(domain, name));233}234}235});236237handshake(clnt, srv);238}239240/**241* Client side user name provided in callback.242* @throws Exception243*/244private static void checkClientNameOverride() throws Exception {245SaslClient clnt = Sasl.createSaslClient(246new String[]{MECH}, "someone", PROTOCOL, REALM, null,247new CallbackHandler() {248public void handle(Callback[] callbacks)249throws IOException, UnsupportedCallbackException {250for (Callback cb: callbacks) {251if (cb instanceof NameCallback) {252NameCallback ncb = (NameCallback) cb;253ncb.setName(USER1);254} else if (cb instanceof PasswordCallback) {255((PasswordCallback)cb).setPassword(PASS1);256}257}258}259});260261SaslServer srv = Sasl.createSaslServer(MECH, PROTOCOL, "FAKE", null,262new CallbackHandler() {263public void handle(Callback[] callbacks)264throws IOException, UnsupportedCallbackException {265String domain = null, name = null;266PasswordCallback pcb = null;267for (Callback cb: callbacks) {268if (cb instanceof NameCallback) {269name = ((NameCallback)cb).getDefaultName();270} else if (cb instanceof RealmCallback) {271domain = ((RealmCallback)cb).getDefaultText();272} else if (cb instanceof PasswordCallback) {273pcb = (PasswordCallback)cb;274}275}276if (pcb != null) {277pcb.setPassword(getPass(domain, name));278}279}280});281282handshake(clnt, srv);283}284285private static void checkAuthOnly() throws Exception {286Map<String,Object> props = new HashMap<>();287props.put(Sasl.QOP, "auth-conf");288try {289Sasl.createSaslClient(290new String[]{MECH}, USER2, PROTOCOL, REALM, props, null);291throw new Exception("NTLM should not support auth-conf");292} catch (SaslException se) {293// Normal294}295}296297private static void handshake(SaslClient clnt, SaslServer srv)298throws Exception {299if (clnt == null) {300throw new IllegalStateException(301"Unable to find client impl for " + MECH);302}303if (srv == null) {304throw new IllegalStateException(305"Unable to find server impl for " + MECH);306}307308byte[] response = (clnt.hasInitialResponse()309? clnt.evaluateChallenge(EMPTY) : EMPTY);310System.out.println("Initial:");311new sun.misc.HexDumpEncoder().encodeBuffer(response, System.out);312byte[] challenge;313314while (!clnt.isComplete() || !srv.isComplete()) {315challenge = srv.evaluateResponse(response);316response = null;317if (challenge != null) {318System.out.println("Challenge:");319new sun.misc.HexDumpEncoder().encodeBuffer(challenge, System.out);320response = clnt.evaluateChallenge(challenge);321}322if (response != null) {323System.out.println("Response:");324new sun.misc.HexDumpEncoder().encodeBuffer(response, System.out);325}326}327328if (clnt.isComplete() && srv.isComplete()) {329System.out.println("SUCCESS");330if (!srv.getAuthorizationID().equals(USER1)) {331throw new Exception("Not correct user");332}333} else {334throw new IllegalStateException(335"FAILURE: mismatched state:"336+ " client complete? " + clnt.isComplete()337+ " server complete? " + srv.isComplete());338}339340if (!clnt.getNegotiatedProperty(Sasl.QOP).equals("auth") ||341!srv.getNegotiatedProperty(Sasl.QOP).equals("auth") ||342!clnt.getNegotiatedProperty(343"com.sun.security.sasl.ntlm.domain").equals(REALM)) {344throw new Exception("Negotiated property error");345}346clnt.dispose();347srv.dispose();348}349}350351352