package org.jacorb.test.orb.iiop; /* * JacORB - a free Java ORB * * Copyright (C) 2000-2014 Gerald Brose / The JacORB Team. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.util.Properties; import org.jacorb.config.ConfigurationException; import org.jacorb.config.JacORBConfiguration; import org.jacorb.orb.CDROutputStream; import org.jacorb.orb.ORB; import org.jacorb.orb.iiop.ClientIIOPConnection; import org.jacorb.orb.iiop.IIOPAddress; import org.jacorb.orb.iiop.IIOPProfile; import org.jacorb.test.harness.ORBTestCase; import org.jacorb.test.harness.TestUtils; import org.junit.Before; import org.junit.Test; import org.omg.CORBA.NO_PERMISSION; import org.omg.CSIIOP.AS_ContextSec; import org.omg.CSIIOP.CompoundSecMech; import org.omg.CSIIOP.CompoundSecMechList; import org.omg.CSIIOP.CompoundSecMechListHelper; import org.omg.CSIIOP.SAS_ContextSec; import org.omg.CSIIOP.ServiceConfiguration; import org.omg.CSIIOP.TAG_TLS_SEC_TRANS; import org.omg.CSIIOP.TLS_SEC_TRANS; import org.omg.CSIIOP.TLS_SEC_TRANSHelper; import org.omg.CSIIOP.TransportAddress; import org.omg.IOP.TAG_CSI_SEC_MECH_LIST; import org.omg.IOP.TAG_NULL_TAG; import org.omg.IOP.TaggedComponent; import org.omg.SSLIOP.SSL; import org.omg.SSLIOP.SSLHelper; import org.omg.SSLIOP.TAG_SSL_SEC_TRANS; /** * @author <a href="mailto:russell.gold@oracle.com">Russell Gold</a> */ public class ClientIIOPConnectionTest extends ORBTestCase { private TestConnection testConnection = new TestConnection(); private IIOPProfile iiopProfile; private static final short SSL_FEATURE = (short) 16; private static final short NOT_REQUIRED = (short) 0; private static final short NOT_SUPPORTED = (short) 0; @Before public void setUp() throws Exception { iiopProfile = new IIOPProfile( new IIOPAddress( "localhost", 4000 ), null, getORB().getGIOPMinorVersion()); } class TestConnection extends ClientIIOPConnection { void setProfile( ORB orb, IIOPProfile profile ) throws ConfigurationException { this.profile = profile; profile.configure( orb.getConfiguration() ); checkSSL(); } } private void configureConnection( boolean enableSsl, int clientSupports, int clientRequires ) throws Exception { configureObjectUnderTest( new String[][] { { "jacorb.log.default.verbosity", TestUtils.verbose ? "4" : "0" }, { "jacorb.security.support_ssl", enableSsl ? "on" : "off" }, { "jacorb.security.ssl.client.supported_options", Integer.toString( clientSupports ) }, { "jacorb.security.ssl.client.required_options", Integer.toString( clientRequires ) }, } ); } private void configureObjectUnderTest( String[][] settings ) throws ConfigurationException { Properties properties = new Properties(); for (int i = 0; i < settings.length; i++) { properties.setProperty( settings[i][0], settings[i][1] ); } testConnection.configure( JacORBConfiguration.getConfiguration( properties, orb, false )); } /** * Verifies that if no profiles are available, the connection does not use ssl. */ @Test public void testNoProfiles() throws Exception { assertFalse( "Should not report ssl enabled", testConnection.isSSL() ); assertEquals( "ssl port", -1, testConnection.getSsl_port() ); } /** * Verifies that if a TAG_SSL_SEC_TRANS profile (now obsolete) is present, * the connection will use it as a specification of SSL. */ @Test public void testSslSecTransProfile() throws Exception { int port = 5000; configureConnection( true, SSL_FEATURE, SSL_FEATURE ); addSslSecTransComponent( SSL_FEATURE, SSL_FEATURE, port ); testConnection.setProfile( getORB(), iiopProfile ); assertTrue( "Should report ssl enabled", testConnection.isSSL() ); assertEquals( "ssl port", port, testConnection.getSsl_port() ); } /** * Verifies that if a TAG_SSL_SEC_TRANS profile is present, * but the client is not supporting ssl, the connection does not use it. */ @Test public void testSslSecTransWithSslNotSupported() throws Exception { configureConnection( false, NOT_SUPPORTED, NOT_REQUIRED ); addSslSecTransComponent( SSL_FEATURE, SSL_FEATURE, (short) 80 ); testConnection.setProfile( getORB(), iiopProfile ); assertFalse( "Should not report ssl enabled", testConnection.isSSL() ); assertEquals( "ssl port", -1, testConnection.getSsl_port() ); } /** * Verifies that if a TAG_SSL_SEC_TRANS profile does not enable ssl if neither client nor server requires it. */ @Test public void testSslSecTransProfileNotRequired() throws Exception { configureConnection( true, SSL_FEATURE, NOT_REQUIRED ); addSslSecTransComponent( SSL_FEATURE, NOT_REQUIRED, 50 ); testConnection.setProfile( getORB(), iiopProfile ); assertFalse( "Should not report ssl enabled", testConnection.isSSL() ); assertEquals( "ssl port", -1, testConnection.getSsl_port() ); } /** * Verifies that if a TAG_COMPOUND_SEC_MECH profile with a TLS transport mechanism is present, * the connection will use it as a specification of SSL. */ @Test public void testTlsTransProfile() throws Exception { int port = 5000; configureConnection( true, SSL_FEATURE, SSL_FEATURE ); addCompoundSecMechComponentWithTls( SSL_FEATURE, SSL_FEATURE, port ); testConnection.setProfile( getORB(), iiopProfile ); assertTrue( "Should report ssl enabled", testConnection.isSSL() ); assertEquals( "ssl port", port, testConnection.getSsl_port() ); } /** * Verifies that port numbers > 32767 are supported. */ @Test public void testTlsHighPortNum() throws Exception { int port = 40000; configureConnection( true, SSL_FEATURE, SSL_FEATURE ); addCompoundSecMechComponentWithTls( SSL_FEATURE, SSL_FEATURE, port ); testConnection.setProfile( getORB(), iiopProfile ); assertTrue( "Should report ssl enabled", testConnection.isSSL() ); assertEquals( "ssl port", port, testConnection.getSsl_port() ); } /** * Verifies that if a TAG_COMPOUND_SEC_MECH is present with no transport mechanism, * and the client requires SSL, an exception will be thrown. */ @Test public void testCompoundSecMechNoTls() throws Exception { try { configureConnection( true, SSL_FEATURE, SSL_FEATURE ); addCompoundSecMechComponentWithoutTls( SSL_FEATURE, SSL_FEATURE ); testConnection.setProfile( getORB(), iiopProfile ); fail( "Should have thrown a NO_PERMISSION exception" ); } catch (NO_PERMISSION e) { } assertFalse( "Should not report ssl enabled", testConnection.isSSL() ); assertEquals( "ssl port", -1, testConnection.getSsl_port() ); } /** * Verifies that if a TAG_COMPOUND_SEC_MECH profile with a TLS transport mechanism is present, * but the client is not supporting ssl, the connection does not use it. */ @Test public void testTlsTransProfileWithSslNotSupported() throws Exception { configureConnection( false, SSL_FEATURE, SSL_FEATURE ); addCompoundSecMechComponentWithTls( SSL_FEATURE, SSL_FEATURE, 60 ); testConnection.setProfile( getORB(), iiopProfile ); assertFalse( "Should not report ssl enabled", testConnection.isSSL() ); assertEquals( "ssl port", -1, testConnection.getSsl_port() ); } /** * Verifies that if a TAG_COMPOUND_SEC_MECH profile with a TLS transport mechanism is present, * ssl is not enabled if neither client nor server requires it. */ @Test public void testTlsTransProfileNotRequired() throws Exception { int port = 5000; configureConnection( true, SSL_FEATURE, NOT_REQUIRED ); addCompoundSecMechComponentWithTls( SSL_FEATURE, NOT_REQUIRED, port ); testConnection.setProfile( getORB(), iiopProfile ); assertFalse( "Should not report ssl enabled", testConnection.isSSL() ); assertEquals( "ssl port", -1, testConnection.getSsl_port() ); } /** * Verifies that if both a TAG_SSL_SEC_TRANS and a TAG_COMPOUND_SEC_MECH profile without a TLS transport mechanism are present, * the SSL_SEC_TRANS will be used. */ @Test public void testSslTransProfileFavoredOverNonTlsSecMech() throws Exception { int port = 5000; configureConnection( true, SSL_FEATURE, SSL_FEATURE ); addSslSecTransComponent( SSL_FEATURE, SSL_FEATURE, port ); addCompoundSecMechComponentWithoutTls( SSL_FEATURE, SSL_FEATURE ); testConnection.setProfile( getORB(), iiopProfile ); assertTrue( "Should report ssl enabled", testConnection.isSSL() ); assertEquals( "ssl port", port, testConnection.getSsl_port() ); } private void addSslSecTransComponent( short target_supports, short target_requires, int port ) { iiopProfile.addComponent( TAG_SSL_SEC_TRANS.value, new SSL( target_supports, target_requires, (short) (port & 0x0ffff)), SSLHelper.class); } private void addCompoundSecMechComponentWithTls( short target_supports, short target_requires, int port ) { iiopProfile.addComponent( TAG_CSI_SEC_MECH_LIST.value, createCompoundSecMechListWithTls( target_supports, target_requires, port), CompoundSecMechListHelper.class); } private CompoundSecMechList createCompoundSecMechListWithTls( short targetSupports, short targetRequires, int port ) { SAS_ContextSec sasContextSec = new SAS_ContextSec( NOT_REQUIRED, NOT_REQUIRED, new ServiceConfiguration[0], new byte[0][0], 0 ); TaggedComponent transportMech = createTlsTransportMech( targetSupports, targetRequires, port ); AS_ContextSec asContextSec = new AS_ContextSec( targetSupports, targetRequires, new byte[0], new byte[0] ); CompoundSecMech[] compoundSecMech = new CompoundSecMech[] { new CompoundSecMech( targetRequires, transportMech, asContextSec, sasContextSec) }; return new CompoundSecMechList(false, compoundSecMech); } private void addCompoundSecMechComponentWithoutTls( short target_supports, short target_requires ) { iiopProfile.addComponent( TAG_CSI_SEC_MECH_LIST.value, createCompoundSecMechListWithoutTls( target_supports, target_requires ), CompoundSecMechListHelper.class); } private CompoundSecMechList createCompoundSecMechListWithoutTls( short targetSupports, short targetRequires ) { SAS_ContextSec sasContextSec = new SAS_ContextSec( NOT_REQUIRED, NOT_REQUIRED, new ServiceConfiguration[0], new byte[0][0], 0 ); TaggedComponent transportMech = new TaggedComponent( TAG_NULL_TAG.value, new byte[0] ); AS_ContextSec asContextSec = new AS_ContextSec( targetSupports, targetRequires, new byte[0], new byte[0] ); CompoundSecMech[] compoundSecMech = new CompoundSecMech[] { new CompoundSecMech( targetRequires, transportMech, asContextSec, sasContextSec) }; return new CompoundSecMechList(false, compoundSecMech); } private static TaggedComponent createTlsTransportMech( short targetSupports, short targetRequires, int port ) { CDROutputStream out = new CDROutputStream(); try { out.beginEncapsulatedArray(); TLS_SEC_TRANS tls = new TLS_SEC_TRANS( targetSupports, targetRequires, new TransportAddress[] { new TransportAddress( "local", (short) (port & 0x0ffff) )} ); TLS_SEC_TRANSHelper.write( out, tls ); return new TaggedComponent( TAG_TLS_SEC_TRANS.value, out.getBufferCopy() ); } finally { out.close(); } } }