Using the Control API with JavaThe manual describes how to access the ZXTM Control API using Java. This example will show in more detail what can be done with the API and the Java language by replicating the UI Wizard "SSL Decrypt a service". Before we start writing the code we need to consider the operations we need to do to correctly set an existing SSL service to do SSL decryption.
Note: When setting a virtual server to decrypt it is important to remember that an SSL certificate must already be associated with it. If you do not perform these actions in that order an exception will be raised when you try to set the service to do decryption. There are a number of things that are required in order to be able to compile and run Java applications using SOAP. Next we need to convert the WSDL files provided with ZXTM into java classes which define the types and functions we need to interface with ZXTM. To do this we need to use the WSDL2Java tool provided by the Apache Axis package which is available at http://ws.apache.org/axis/. We do this by running the following command: java org.apache.axis.wsdl.WSDL2Java <WSDL> Repeat this for each of the WSDL files. The output will be a set of java classes in the directory com/zeus/soap/zxtm/_1_1/. You will need to correctly locate these files along with their directory structure in your CLASSPATH before you can use them. There are two packages that Axis depends on, the Java Activation Framework package and the JavaMail package. These must be installed or available in your CLASSPATH for the WSDL2Java tool to run correctly. Now that we are at the point where our environment is setup correctly we can continue to look at the example in more detail. The ZXTM SOAP API is only accessable using HTTPS by default for security. However this is a problem when using Java as it refuses to connect to sites which identify themselves with self-signed SSL certificates. ZXTM uses a self-signed certificate to identify itself by default. There are two solutions to this; one, to install a signed certificate or two, to override the default security policy to allow self-signed certificates. In this example I will be using the second option. The following code needs to be added before any connections are made to the SOAP server; // Install the all-trusting trust manager Security.addProvider( new MyProvider() ); Security.setProperty( "ssl.TrustManagerFactory.algorithm", "TrustAllCertificates"); Where the implementation for MyProvider() is as follows;
import java.security.Security;
import java.security.KeyStore;
import java.security.Provider;
import java.security.cert.X509Certificate;
import javax.net.ssl.ManagerFactoryParameters;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactorySpi;
import javax.net.ssl.X509TrustManager;
/* The following code disables certificate checking.
* Use the Security.addProvider and Security.setProperty
* calls to enable it */
public static class MyProvider extends Provider {
public MyProvider() {
super( "MyProvider", 1.0, "Trust certificates" );
put( "TrustManagerFactory.TrustAllCertificates",
MyTrustManagerFactory.class.getName() );
}
protected static class MyTrustManagerFactory
extends TrustManagerFactorySpi {
public MyTrustManagerFactory() {}
protected void engineInit( KeyStore keystore ) {}
protected void engineInit(
ManagerFactoryParameters mgrparams ) {}
protected TrustManager[] engineGetTrustManagers() {
return new TrustManager[] {
new MyX509TrustManager()
};
}
}
protected static class MyX509TrustManager
implements X509TrustManager {
public void checkClientTrusted(
X509Certificate[] chain, String authType) {}
public void checkServerTrusted(
X509Certificate[] chain, String authType) {}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
}
Once you have copied this heavy bit of code you can connect to the SOAP server without modifying it. Now we need to provide the implementation for each of the steps of our task. Firstly we need to change the protocol of the virtual server from HTTPS to HTTP. The following code performs this task;
/* URL to access the SOAP server
* Replace username, password and somemachine to the correct values in your case.
* Port 9090 is the default port on which the SOAP server operates it may be different
* as it can be configured using the user interface */
String admin_url = "https://username:password@somemachine:9090/apps/zxtm/soap.fcgi";
VirtualServerLocator vsl = new VirtualServerLocator();
vsl.setVirtualServerPortEndpointAddress( admin_url );
VirtualServerPort vsp = vsl.getVirtualServerPort();
// We now have a VirtualServerPort object which we can use to obtain virtual server information
// Change the protocol
String[] vname = new String[1];
vname[0] = "Test_VS"; // Replace with appropriate virtual server name
VirtualServerProtocol[] protoname = new VirtualServerProtocol[1];
protoname[0] = VirtualServerProtocol.fromValue("http");
vsp.setProtocol( vname, protoname );
This will set the protocol of virtual server "Test_VS" to HTTP. Note that all operations are done using lists as arguments. Although this may seem cumbersome for examples like this, it is invaluable when doing bulk updates to multiple objects. The next step is to create a self-signed certificate or select an installed certificate to use for SSL decrypting our traffic. I will show how to create a certificate rather than selecting one as it highlights how to create and install objects using the API. The following code creates an SSL certificate, installs it on the ZXTM and then associates it with the virtual server we modified above.
// Create a self-signed cert
X509Name subject = new X509Name( "www.somecompany.com",
"GB",
"London",
"",
"Some Company",
"",
"" );
CatalogSSLCertificatesCertificateDetails cert_details =
new CatalogSSLCertificatesCertificateDetails( subject, 60, 2048 );
CatalogSSLCertificatesLocator sslcl = new CatalogSSLCertificatesLocator();
sslcl.setCatalogSSLCertificatesPortEndpointAddress( admin_url );
CatalogSSLCertificatesPort sslp = sslcl.getCatalogSSLCertificatesPort();
// We have a CatalogSSLCertificatesPort so we can access and modify SSL certificates
String[] certlist = new String[1];
certlist[0] = "self-signedTest_VS";
CatalogSSLCertificatesCertificateDetails[] detlist = new CatalogSSLCertificatesCertificateDetails[1];
detlist[0] = cert_details;
//Install "self-signedTest_VS"
sslp.createSelfSignedCertificate( certlist, detlist );
// Set SSLCertificate
// Note: we must set the cert before we set the virtual server
// to decrypt mode.
vsp.setSSLCertificate( vname, certlist );
As you can see there is a pattern to how things are accessed through "Ports". For each type of object that can be manipulated through the SOAP API you need to create a "Port" for it. Once we have associated our new SSL certificate with the virtual server we can enable SSL decryption of traffic. This is very simple to do as the code below shows; // Set SSL Decrypt boolean[] boolname = new boolean[1]; boolname[0] = true; vsp.setSSLDecrypt( vname, boolname ); The final step is to enable re-encryption for the virtual server's default traffic pool. // Fix Default Pool to re-encrypt String[] defaultpool = vsp.getDefaultPool( vname ); PoolLocator pl = new PoolLocator(); pl.setPoolPortEndpointAddress( admin_url ); PoolPort pp = pl.getPoolPort(); pp.setSSLEncrypt( defaultpool, boolname ); So now we have all of the components required to build a program to do all of them. The following full example is a commandline tool which takes five arguments. These arguments in order are, server_name, server_port, username, password and the name of the virtual server to alter. It also handles the exceptions that may be thrown during execution.
import com.zeus.soap.zxtm._1_0.*;
import java.security.Security;
import java.security.KeyStore;
import java.security.Provider;
import java.security.cert.X509Certificate;
import javax.net.ssl.ManagerFactoryParameters;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactorySpi;
import javax.net.ssl.X509TrustManager;
public class SSLDecryptWizard {
public static void main( String[] args ) {
try {
// Install the all-trusting trust manager
Security.addProvider( new MyProvider() );
Security.setProperty(
"ssl.TrustManagerFactory.algorithm",
"TrustAllCertificates");
String admin_url = "https://"+args[2]+":"+args[3]+"@"+args[0]+":"+args[1]+"/apps/zxtm/soap.fcgi";
String virtual_server = args[4];
System.out.println( "Service to SSL decrypt: "+virtual_server );
VirtualServerLocator vsl = new VirtualServerLocator();
vsl.setVirtualServerPortEndpointAddress( admin_url );
VirtualServerPort vsp = vsl.getVirtualServerPort();
String[] vsnames = vsp.getVirtualServerNames();
VirtualServerProtocol[] vsproto = vsp.getProtocol( vsnames );
boolean flag = false;
for( int i = 0; i < vsnames.length; i++ ){
if( vsnames[i].compareTo( virtual_server ) == 0 ){
if( vsproto[i].toString().compareTo( "https" ) == 0 ){
System.out.println( "VS: "+vsnames[i]+" Proto: "+vsproto[i].toString() );
// Create a self-signed cert
X509Name subject = new X509Name( "www.zeus.com",
"GB",
"Cambridge",
"",
"Zeus Technology",
"",
"" );
CatalogSSLCertificatesCertificateDetails cert_details =
new CatalogSSLCertificatesCertificateDetails( subject, 60, 2048 );
CatalogSSLCertificatesLocator sslcl = new CatalogSSLCertificatesLocator();
sslcl.setCatalogSSLCertificatesPortEndpointAddress( admin_url );
CatalogSSLCertificatesPort sslp = sslcl.getCatalogSSLCertificatesPort();
String[] certlist = new String[1];
certlist[0] = "self-signed"+virtual_server;
CatalogSSLCertificatesCertificateDetails[] detlist = new CatalogSSLCertificatesCertificateDetails[1];
detlist[0] = cert_details;
sslp.createSelfSignedCertificate( certlist, detlist );
// Change the protocol
String[] vname = new String[1];
vname[0] = virtual_server;
VirtualServerProtocol[] protoname = new VirtualServerProtocol[1];
protoname[0] = VirtualServerProtocol.fromValue("http");
vsp.setProtocol( vname, protoname );
System.out.println( "Protocol Set" );
// Set SSLCertificate
// Note: we must set the cert before we set the virtual server
// to decrypt mode.
vsp.setSSLCertificate( vname, certlist );
System.out.println( "SSL Cert Set" );
// Set SSL Decrypt
boolean[] boolname = new boolean[1];
boolname[0] = true;
vsp.setSSLDecrypt( vname, boolname );
System.out.println( "SSL Decrypt Set" );
// Fix Default Pool to re-encrypt
String[] defaultpool = vsp.getDefaultPool( vname );
System.out.println( "Default Pool: "+defaultpool[0] );
PoolLocator pl = new PoolLocator();
pl.setPoolPortEndpointAddress( admin_url );
PoolPort pp = pl.getPoolPort();
pp.setSSLEncrypt( defaultpool, boolname );
System.out.println( "SSL Encrypt Set" );
} else {
System.out.println( "Virtual server \""+virtual_server+"\" is not operating under the HTTPS protocol." );
}
flag = true;
break;
}
}
if( flag ){
System.out.println( "Virtual server \""+virtual_server+"\" configured to decrypt SSL." );
} else {
System.out.println( "Virtual server \""+virtual_server+"\" does not exist." );
}
} catch (Exception e) {
System.out.println( e.toString() );
}
}
/* The following code disables certificate checking.
* Use the Security.addProvider and Security.setProperty
* calls to enable it */
public static class MyProvider extends Provider {
public MyProvider() {
super( "MyProvider", 1.0, "Trust certificates" );
put( "TrustManagerFactory.TrustAllCertificates",
MyTrustManagerFactory.class.getName() );
}
protected static class MyTrustManagerFactory
extends TrustManagerFactorySpi {
public MyTrustManagerFactory() {}
protected void engineInit( KeyStore keystore ) {}
protected void engineInit(
ManagerFactoryParameters mgrparams ) {}
protected TrustManager[] engineGetTrustManagers() {
return new TrustManager[] {
new MyX509TrustManager()
};
}
}
protected static class MyX509TrustManager
implements X509TrustManager {
public void checkClientTrusted(
X509Certificate[] chain, String authType) {}
public void checkServerTrusted(
X509Certificate[] chain, String authType) {}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
}
}
Dec
[Zeus Dev Team] 03 January 2006
|
Recent Articles
Other Resources
|


