/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @author Vera Y. Petrashkova */ package org.apache.harmony.auth.tests.javax.security.sasl; import java.io.IOException; import java.security.Provider; import java.security.Security; import java.util.Map; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.NameCallback; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.callback.TextOutputCallback; import javax.security.auth.callback.UnsupportedCallbackException; import javax.security.sasl.Sasl; import javax.security.sasl.SaslClient; import javax.security.sasl.SaslClientFactory; import javax.security.sasl.SaslException; import junit.framework.TestCase; import org.apache.harmony.auth.tests.support.SpiEngUtils; /** * Test for Sasl class */ public class Sasl3Test extends TestCase { private static final String CLNTSRV = "SaslClientFactory."; private static final String fClientClass = mySaslClientFactory.class.getName();; private Provider [] provs; private boolean initProvs; @Override protected void setUp() throws Exception { super.setUp(); if (!initProvs) { provs = Security.getProviders(); initProvs = true; } if (provs != null) { for (Provider element : provs) { Security.removeProvider(element.getName()); } } } protected Provider[] mProv; private void addProviders() { for (Provider element : mProv) { Security.insertProviderAt(element, 1); } } /* * @see TestCase#tearDown() */ @Override protected void tearDown() throws Exception { super.tearDown(); if (mProv != null) { for (Provider element : mProv) { Security.removeProvider(element.getName()); } } if (provs != null) { for (int i = 0; i < provs.length; i++) { Security.insertProviderAt(provs[i], (i+1)); } } } /** * Test for createSaslClient(String[] mechanisms, * String authanticationID, String protocol, String serverName, * Map prop, CallbackHandler cbh)) * method Assertions: throws NullPointerException when mechanisms is null; * throws SaslException when parameters (protocol, cbh, mechanisms) are * wrong. * * All providers are previously removed and 2 new providers were added. */ public void testCreateClient01() throws SaslException { mProv = new Provider[] { (new SpiEngUtils()).new MyProvider("MySaslClientProvider1", "Testing provider SaslClientFactory - 1", CLNTSRV .concat("NAME-1"), fClientClass), (new SpiEngUtils()).new MyProvider("MySaslClientProvider2", "Testing provider SaslClientFactory - 2", CLNTSRV .concat("NAME-2"), fClientClass) }; addProviders(); CallbackHandler cbH = new cbHand(); try { Sasl.createSaslClient(null, null, null, null, null, cbH); fail("NullPointerException should be thrown when mechanisms is null"); } catch (NullPointerException e) { } try { Sasl.createSaslClient(new String[] { "NAME-2" }, null, "protocol", null, null, cbH); fail("SaslException should be thrown when CallbackHandler is wrong"); } catch (SaslException e) { } cbH = new cbHandN(); try { Sasl.createSaslClient(new String[] { "NAME-1" }, null, "protocol", null, null, cbH); fail("SaslException should be thrown when mechanisms is wrong"); } catch (SaslException e) { } try { Sasl.createSaslClient(new String[] { "NAME-2" }, null, null, null, null, cbH); fail("SaslException should be thrown when protocol is null"); } catch (SaslException e) { } } /** * Test for createSaslClient(String[] mechanisms, * String authanticationID, String protocol, String serverName, * Map prop, CallbackHandler cbh)) * method Assertions: throws NullPointerException when mechanisms is null; * returns null SaslClient. * * All providers are previously removed. */ public void testCreateClient02() throws SaslException { try { Sasl.createSaslClient(null, null, null, null, null, null); fail("NullPointerException should be thrown when mechanisms is null"); } catch (NullPointerException e) { } assertNull("Not null result", Sasl.createSaslClient( new String[] { "NAME-999" }, null, null, null, null, null)); } /** * Test for createSaslClient(String[] mechanisms, * String authanticationID, String protocol, String serverName, * Map prop, CallbackHandler cbh)) * method * * Assertions: returns SaslClient; throws SaslClient for NAME-1 mechanism * * All providers are previously removed and 2 new providers were added. */ public void testCreateClient03() throws SaslException { mProv = new Provider[] { (new SpiEngUtils()).new MyProvider("MySaslClientProvider1", "Testing provider SaslClientFactory - 1", CLNTSRV .concat("NAME-1"), fClientClass), (new SpiEngUtils()).new MyProvider("MySaslClientProvider2", "Testing provider SaslClientFactory - 2", CLNTSRV .concat("NAME-2"), fClientClass) }; addProviders(); CallbackHandler cbH = new cbHandN(); SaslClient saslC = Sasl.createSaslClient(new String[] { "NAME-2" }, null, "protocol", null, null, cbH); assertNotNull("Null result", saslC); try { saslC.unwrap(null, 1, 1); fail("SaslException sould be thrown"); } catch (SaslException e) { } assertFalse("Incorrect isComplete() result", saslC.isComplete()); // try to create client for wrong mechanism try { saslC = Sasl.createSaslClient(new String[] { "NAME-1" }, null, "protocol", null, null, cbH); fail("SaslException sould be thrown"); } catch (SaslException e) { } } /** * Test for createSaslClient(String[] mechanisms, * String authanticationID, String protocol, String serverName, * Map prop, CallbackHandler cbh)) * method * * Assertions: returns SaslClient; throws SaslClient for NAME-1 mechanism * * All providers are previously removed and 1 new provider was added. */ public void testCreateClient04() throws SaslException { mProv = new Provider[] { (new SpiEngUtils()).new MyProvider( "MySaslClientProvider1", "Testing provider SaslClientFactory - 1", CLNTSRV .concat("NAME-1"), fClientClass) }; mProv[0].put(CLNTSRV.concat("NAME-2"), fClientClass); addProviders(); CallbackHandler cbH = new cbHandN(); SaslClient saslC = Sasl.createSaslClient(new String[] { "NAME-2" }, null, "protocol", null, null, cbH); assertNotNull("Null result for NAME-2", saslC); assertFalse("Incorrect isComplete() result", saslC.isComplete()); // try to create client for wrong mechanism try { saslC = Sasl.createSaslClient(new String[] { "NAME-1" }, null, "protocol", null, null, cbH); fail("SaslException sould be thrown"); } catch (SaslException e) { } } /** * Test for createSaslClient(String[] mechanisms, * String authanticationID, String protocol, String serverName, * Map prop, CallbackHandler cbh)) * method * * Assertions: return null client when there is no provider supported some * mechanism returns SaslClient when incorrect mechanism is used * * All providers are previously removed and 2 new providers were added. */ public void testCreateClient05() throws SaslException { mProv = new Provider[] { (new SpiEngUtils()).new MyProvider("MySaslClientProvider1", "Testing provider SaslClientFactory - 1", CLNTSRV .concat("NAME-2"), fClientClass.concat("Ext")), (new SpiEngUtils()).new MyProvider("MySaslClientProvider2", "Testing provider SaslClientFactory - 2", CLNTSRV .concat("NAME-1"), fClientClass), (new SpiEngUtils()).new MyProvider("MySaslClientProvider3", "Testing provider SaslClientFactory - 3", CLNTSRV .concat("NAME-6"), fClientClass) }; addProviders(); CallbackHandler cbH = new cbHandN(); SaslClient saslC; // try to create SaslClient for wrong mechanism // there is no provider supported NAME-77, NAME-66 mechanisms assertNull("Not null object was created for wrong mechanism", Sasl .createSaslClient(new String[] { "NAME-77", "NAME-66" }, null, "protocol", null, null, cbH)); saslC = Sasl.createSaslClient(new String[] { "NAME-2" }, null, "protocol", null, null, cbH); assertNotNull("Null result for NAME-2", saslC); try { saslC.unwrap(null, 1, 1); fail("SaslException sould be thrown"); } catch (SaslException e) { } assertFalse("Incorrect isComplete() result", saslC.isComplete()); // NAME-1 was defined in some provider but it is supported in // another provider try { Sasl.createSaslClient(new String[] { "NAME-1" }, null, "protocol", null, null, cbH); fail("SaslException sould be thrown"); } catch (SaslException e) { } // NAME-6 and NAME-5 were defined in one provider but they are // supported // in another provider saslC = Sasl.createSaslClient(new String[] { "NAME-6", "NAME-5" }, null, "protocol", null, null, cbH); assertNotNull("Null result for NAME-6 and NAME-5", saslC); } /* * Additional classes for creating SaslClient and SaslServer objects */ public static class mySaslClientFactory implements SaslClientFactory { public mySaslClientFactory() { super(); } public String[] getMechanismNames(Map prop) { return new String[] { "NAME-1", "NAME-2", "NAME-3", "NAME-4" }; } public SaslClient createSaslClient(String[] mech, String id, String protocol, String srvName, Map prop, CallbackHandler hnd) throws SaslException { if (mech == null) { throw new SaslException(); } if ("NAME-1".equals(mech[0])) { throw new SaslException("Incorrect mechanisms"); } if (protocol == null) { throw new SaslException("Protocol is null"); } TextOutputCallback[] cb = { new TextOutputCallback( TextOutputCallback.INFORMATION, "Information") }; try { hnd.handle(cb); } catch (UnsupportedCallbackException e) { throw new SaslException("Incorrect callback handlere", e); } catch (IOException e) { throw new SaslException("Incorrect callback handlere", e); } return new mySaslClient(); } public class mySaslClient implements SaslClient { public mySaslClient() { super(); } public Object getNegotiatedProperty(String s) { return ""; } public String getMechanismName() { return "Proba"; } public boolean isComplete() { return false; } public boolean hasInitialResponse() { return false; } public void dispose() throws SaslException { } public byte[] evaluateChallenge(byte[] challenge) throws SaslException { return new byte[0]; } public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException { throw new SaslException(); } public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException { return new byte[0]; } } } public static class mySaslClientFactoryExt extends mySaslClientFactory { @Override public String[] getMechanismNames(Map prop) { return new String[] { "NAME-5", "NAME-6" }; } @Override public SaslClient createSaslClient(String[] mech, String id, String protocol, String srvName, Map prop, CallbackHandler hnd) throws SaslException { if (mech == null) { throw new SaslException(); } return new mySaslClient(); } } public static class cbHand implements CallbackHandler { public cbHand() { } public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (Callback element : callbacks) { if (element instanceof NameCallback) { NameCallback nc = (NameCallback) element; nc.setName("Ok"); } else if (element instanceof PasswordCallback) { PasswordCallback pc = (PasswordCallback) element; System.err.print(pc.getPrompt()); System.err.flush(); pc.setPassword(new char[] { 'O', 'k' }); } else { throw new UnsupportedCallbackException(element, "Callback should be NamCallback or PasswordCallback"); } } } } public static class cbHandN implements CallbackHandler { public cbHandN() { } public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (Callback element : callbacks) { if (element instanceof TextOutputCallback) { TextOutputCallback toc = (TextOutputCallback) element; if (toc.getMessageType() != TextOutputCallback.INFORMATION) { throw new IOException("Unsupported message type: " + toc.getMessageType()); } } else { throw new UnsupportedCallbackException(element, "Callback should be TextOutputCallback"); } } } } }