solace

/**
 * SolJMSSecureSession.java
 
 * This is a simple sample of a Secure JMS Producer.
 *
 * This sample publishes 10 JMS Text Messages to a specified Topic or Queue
 *
 * Notice that the specified username, ConnectionFactory, Topic and Queue 
 * should exist in your configuration (configured with SolAdmin)
 *
 * A server certificate needs to be installed on the appliance and SSL must be
 * enabled on the appliance for this sample to work.
 * Also, in order to connect to the appliance with Certificate Validation enabled
 * (which is enabled by default), the appliance's certificate chain must be signed
 * by one of the root CAs in the trust store used by the sample.
 *
 * For this sample to use CLIENT CERTIFICATE authentication, a trust store has to
 * be set up on the appliance and it must contain the root CA that signed the client
 * certificate. The VPN must also have client-certificate authentication enabled.
 *
 * Usage: 
 * run SolJMSSecureSession [-username USERNAME] [-password PASSWORD] [-vpn VPN]
 * -url JNDI_PROVIDER_URL 
 * [-x AUTH_METHOD] 
 * [-cf CONNECTION_FACTORY_JNDI_NAME] 
 * [-prot PROTOCOL] 
 * [-ciphers CIPHERS] 
 * [-ts TRUST_STORE] 
 * [-tspwd TRUST_STORE_PASSWORD] 
 * [-tsfmt TRUST_STORE_FORMAT] 
 * [-ks KEY_STORE] 
 * [-kspwd KEY_STORE_PASSWORD] 
 * [-ksfmt KEY_STORE_FORMAT] 
 * [-ksnfmt KEY_STORE_NORMALIZED_FORMAT] 
 * [-pk PRIVATE_KEY_ALIAS] 
 * [-pkpwd PRIVATE_KEY_PASSWORD] 
 * [-no_validate_certificates] 
 * [-no_validate_dates] 
 * [-cn TRUSTED_COMMON_NAMES] 
 * 
 * Where:
 * - USERNAME is the username to use to authenticate.  Mandatory when BASIC authentication is used.  Optional when CLIENT_CERTIFICATE authentication is used.
 * - PASSWORD  is defaulted to empty string
 * - AUTH_METHOD authentication scheme (One of : BASIC, CLIENT_CERTIFICATE). (Default: BASIC).  Specifying USERNAME is mandatory when BASIC is used.
 * - VPN defaults to the default vpn 
 * - JNDI_PROVIDER_URL is the URL to access the JNDI store (e.g. smfs://10.10.10.10:55555 for a secure connection) 
 * - CONNECTION_FACTORY_JNDI_NAME  is defaulted to cf/default 
 * - PROTOCOL is defaulted to SSLv3,TLSv1,TLSv1.1,TLSv1.2
 * - CIPHERS is defaulted to all supported ciphers
 * - TRUST_STORE is the path to a trust store file that contains trusted root CAs.  This parameter is mandatory unless -no_validate_certificates is specified.  Used to validate the appliance's server certificate.
 * - TRUST_STORE_FORMAT is the format of the specified trust store.  Possible values : [JKS, PKCS12].  The default value is JKS.
 * - TRUST_STORE_PASSWORD is the password for the specified trust store.  This is used to check the trust store's integrity.
 * - TRUSTED_COMMON_NAMES is the list of acceptable common names for matching in server certificates (default: no CN validation performed)
 * - KEY_STORE is the key store file to use for client certificate authentication.  Mandatory when CLIENT_CERTIFICATE authentication is used.
 * - KEY_STORE_FORMAT is the format of the specified key store. The default value is JKS.
 * - KEY_STORE_NORMALIZED_FORMAT is the format of the internal normalized key store.  If not specified the format is the same as the key store format.
 * - KEY_STORE_PASSWORD is the password for the specified key store.  This is used to check the key store's integrity.  This parameter is mandatory when PRIVATE_KEY_PASSWORD is not specified.  It is also used to decipher the private key when the PRIVATE_KEY_PASSWORD option is omitted.
 * - PRIVATE_KEY_ALIAS is the alias of the private key to use for client certificate authentication.
 * - PRIVATE_KEY_PASSWORD is the password to decipher the private key from the key store (default: the value passed for KEY_STORE_PASSWORD).
 * 
 * Copyright 2004-2020 Solace Corporation. All rights reserved.
 */

package com.solace.samples.secure;

import java.util.Hashtable;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.ConnectionMetaData;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import com.solacesystems.jms.SupportedProperty;

/**
 * Creates a JMS secure session that sends 10 JMS text messages.
 * 
 */
public class SolJMSSecureSession {
    
    private enum AuthenticationScheme {
        BASIC,
        CLIENT_CERTIFICATE,
        KERBEROS
    };
    
    private static final String SOLJMS_INITIAL_CONTEXT_FACTORY = 
        "com.solacesystems.jndi.SolJNDIInitialContextFactory"; 
    
    // URL to the JNDI data store.
    private String jndiProviderURL; 
    
    // The publisher/subscriber name, as configured with SolAdmin.
    private String username;
    
    // The publisher/subscriber password, as configured with an authentication server; default is empty.
    private String password = "";
    
    // The Message VPN on the appliance to connect to.
    private String vpn = null;

    // The default JNDI name of the connection factory.
    private String cfJNDIName = "cf/default";

    private String excludeProtocols = null;
    
    private String ciphers = null;
    
    private String trustStore = null;
    
    private String trustStorePwd = null;
    
    private String trustStoreFmt = "JKS";

    private String keyStore = null;
    
    private String keyStorePwd = null;
    
    private String keyStoreFmt = "JKS";
    
    private String keyStoreNormalizedFmt = null;
    
    private String privateKeyAlias = null;

    private String privateKeyPwd = null;
    
    private boolean validateCertificates = true;
    
    private boolean validateCertificateDate = true;
    
    private String trustedCommonNames = null;
    
    private String sslConnectionDowngradeTo = null;
    
    private boolean compression = false;
    
    // The number of messages to send.
    private int numMsgsToSend = 10;
    
    // Kerberos authentication
    private AuthenticationScheme authScheme = AuthenticationScheme.BASIC;

    private  void printUsage() {
        System.out.println("\nUsage: \nrun SolJMSSecureSession [-username USERNAME] [-password PASSWORD] [-vpn VPN]\n" +
                            "-url JNDI_PROVIDER_URL \n" +
                            "[-x AUTH_METHOD] \n" +
                            "[-cf CONNECTION_FACTORY_JNDI_NAME] \n" +
                            "[-compression] \n" +
                            "[-exclprots EXCLUDE_PROTOCOLS] \n" +
                            "[-ciphers CIPHERS] \n" +
                            "[-ts TRUST_STORE] \n" +
                            "[-tspwd TRUST_STORE_PASSWORD] \n" +
                            "[-tsfmt TRUST_STORE_FORMAT] \n" +
                            "[-ks KEY_STORE] \n" +
                            "[-kspwd KEY_STORE_PASSWORD] \n" +
                            "[-ksfmt KEY_STORE_FORMAT] \n" +
                            "[-ksnfmt KEY_STORE_NORMALIZED_FORMAT] \n" +
                            "[-pk PRIVATE_KEY_ALIAS] \n" +
                            "[-pkpwd PRIVATE_KEY_PASSWORD] \n" +
                            "[-no_validate_certificates] \n" +
                            "[-no_validate_dates] \n" +
                            "[-cn TRUSTED_COMMON_NAMES] \n" +
                            "[-d PLAIN_TEXT]\nWhere:\n" + 
                            "- USERNAME is the username to use to authenticate.  Mandatory when BASIC authentication is used.  Optional when CLIENT_CERTIFICATE authentication is used.\n" +
                            "- PASSWORD is defaulted to empty string \n" +
                            "- AUTH_METHOD authentication scheme (One of : BASIC, CLIENT_CERTIFICATE). (Default: BASIC).  Specifying USERNAME is mandatory when BASIC is used.\n" +
                            "- VPN defaults to the default vpn \n" +
                            "- JNDI_PROVIDER_URL is the URL to access the JNDI store (e.g. smfs://10.10.10.10:55555 for a secure connection) \n" + 
                            "- CONNECTION_FACTORY_JNDI_NAME  is defaulted to " + cfJNDIName + " \n" +
                            "- EXCLUDE_PROTOCOLS is defaulted to an empty string\n" +
                            "- CIPHERS is defaulted to all supported ciphers\n" +
                            "- TRUST_STORE is the path to a trust store file that contains trusted root CAs.  This parameter is mandatory unless -no_validate_certificates is specified.  Used to validate the appliance's server certificate.\n" +
                            "- TRUST_STORE_FORMAT is the format of the specified trust store.  Possible values : [JKS, PKCS12].  The default value is JKS.\n" + 
                            "- TRUST_STORE_PASSWORD is the password for the specified trust store.  This is used to check the trust store's integrity.\n" +
                            "- TRUSTED_COMMON_NAMES is the list of acceptable common names for matching in server certificates (default: no CN validation performed)\n" +
                            "- KEY_STORE is the key store file to use for client certificate authentication.  Mandatory when CLIENT_CERTIFICATE authentication is used.\n" + 
                            "- KEY_STORE_FORMAT is the format of the specified key store. The default value is JKS.\n" +
                            "- KEY_STORE_NORMALIZED_FORMAT is the format of the internal normalized key store.  If not specified the format is the same as the key store format.\n" +
                            "- KEY_STORE_PASSWORD is the password for the specified key store.  This is used to check the key store's integrity.  This parameter is mandatory when the PRIVATE_KEY_PASSWORD option is not specified.  It is also used to decipher the private key when the PRIVATE_KEY_PASSWORD option is omitted.\n" + 
                            "- PRIVATE_KEY_ALIAS is the alias of the private key to use for client certificate authentication.\n" +
                            "- PRIVATE_KEY_PASSWORD is the password to decipher the private key from the key store (default: the value passed for KEY_STORE_PASSWORD)." +
                            "- PLAIN_TEXT SSL connection downgrade protocol");
    }
    
    private void run() {
        
        // The client needs to specify both of the following properties:
        Hashtable<String, Object> env = new Hashtable<String, Object>();
        env.put(InitialContext.INITIAL_CONTEXT_FACTORY, SOLJMS_INITIAL_CONTEXT_FACTORY);
        env.put(InitialContext.PROVIDER_URL, jndiProviderURL);
        if (username != null) {
            env.put(Context.SECURITY_PRINCIPAL, username);
        }
        env.put(Context.SECURITY_CREDENTIALS, password);
        
        if (compression) {
            env.put(SupportedProperty.SOLACE_JMS_COMPRESSION_LEVEL, 9);     // non-zero compression level
        }
        
        // SSL
        if (excludeProtocols != null) {
            env.put(SupportedProperty.SOLACE_JMS_SSL_EXCLUDED_PROTOCOLS, excludeProtocols);
        }
        if (ciphers != null) {
            env.put(SupportedProperty.SOLACE_JMS_SSL_CIPHER_SUITES, ciphers);
        }
        if (trustStore != null) {
            env.put(SupportedProperty.SOLACE_JMS_SSL_TRUST_STORE, trustStore);
        }
        env.put(SupportedProperty.SOLACE_JMS_SSL_TRUST_STORE_FORMAT, trustStoreFmt);
        if (trustStorePwd != null) {
            env.put(SupportedProperty.SOLACE_JMS_SSL_TRUST_STORE_PASSWORD, trustStorePwd);
        }
        if (trustedCommonNames != null) {
            env.put(SupportedProperty.SOLACE_JMS_SSL_TRUSTED_COMMON_NAME_LIST, trustedCommonNames);
        }
        env.put(SupportedProperty.SOLACE_JMS_SSL_VALIDATE_CERTIFICATE, validateCertificates);
        env.put(SupportedProperty.SOLACE_JMS_SSL_VALIDATE_CERTIFICATE_DATE, validateCertificateDate);
        
        if (keyStore != null) {
            env.put(SupportedProperty.SOLACE_JMS_SSL_KEY_STORE, keyStore);
        }
        if (keyStorePwd != null) {
            env.put(SupportedProperty.SOLACE_JMS_SSL_KEY_STORE_PASSWORD, keyStorePwd);
        }
        if (keyStoreFmt != null) {
            env.put(SupportedProperty.SOLACE_JMS_SSL_KEY_STORE_FORMAT, keyStoreFmt);
        }
        if (keyStoreNormalizedFmt != null) {
            env.put(SupportedProperty.SOLACE_JMS_SSL_KEY_STORE_NORMALIZED_FORMAT, keyStoreNormalizedFmt);
        }
        if (privateKeyAlias != null) {
            env.put(SupportedProperty.SOLACE_JMS_SSL_PRIVATE_KEY_ALIAS, privateKeyAlias);
        }
        if (privateKeyPwd != null) {
            env.put(SupportedProperty.SOLACE_JMS_SSL_PRIVATE_KEY_PASSWORD, privateKeyPwd);
        }
        if (vpn != null) {
            env.put(SupportedProperty.SOLACE_JMS_VPN, vpn);
        }
        if (sslConnectionDowngradeTo !=  null) {
            env.put(SupportedProperty.SOLACE_JMS_SSL_CONNECTION_DOWNGRADE_TO, sslConnectionDowngradeTo);
        }
        if (authScheme.equals(AuthenticationScheme.BASIC)) {
            env.put(SupportedProperty.SOLACE_JMS_AUTHENTICATION_SCHEME, SupportedProperty.AUTHENTICATION_SCHEME_BASIC);
        } else if (authScheme.equals(AuthenticationScheme.CLIENT_CERTIFICATE)) {
            env.put(SupportedProperty.SOLACE_JMS_AUTHENTICATION_SCHEME, SupportedProperty.AUTHENTICATION_SCHEME_CLIENT_CERTIFICATE);
        } else {
            env.put(SupportedProperty.SOLACE_JMS_AUTHENTICATION_SCHEME, SupportedProperty.AUTHENTICATION_SCHEME_GSS_KRB);
        }

        // InitialContext is used to lookup the JMS administered objects.
    	InitialContext initialContext = null;
    	
    	// JMS Connection
    	Connection connection = null;
    	
        try {
            // Create InitialContext.
            initialContext = new InitialContext(env);
        	
            // Lookup ConnectionFactory.
        	ConnectionFactory cf = (ConnectionFactory)initialContext.lookup(cfJNDIName);
        	
        	// Create connection.
            connection = cf.createConnection();
            
            // Print version information.
            ConnectionMetaData metadata = connection.getMetaData();
            System.out.println(metadata.getJMSProviderName() + " " + metadata.getProviderVersion());

            // Create a non-transacted, Auto Ack session.
            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

            Destination destination = session.createTopic("secure/session");

            // From the session, create a producer for the destination.
            // Use the default delivery mode as set in the connection factory
            MessageProducer producer = session.createProducer(destination);

            // Create a text message.
            TextMessage testMessage = session.createTextMessage("Hello from SolJMSSecureSession");

            
            System.out.println("About to send " + numMsgsToSend + " JMS Text Message(s)");
            // Send text message.
            for (int i = 0; i < numMsgsToSend; i++) {
                producer.send(testMessage);
                System.out.println("SENT: " + testMessage.getText());
                try {
                    Thread.sleep(1000);
                } catch (Exception ex) {}
            }
            System.out.println("DONE");            
        } catch (NamingException e) {
        	e.printStackTrace();
        } catch (JMSException e) {
        	e.printStackTrace();
        } finally {
        	if (connection != null) {
        		try {
        			connection.close();
        		} catch (Exception e) {}
        	}
        	if (initialContext != null) {
        		try {
        			initialContext.close();
        		} catch (Exception e) {}
        	}
        }
    }
    
    public static void main(String[] args) {
        try {
            SolJMSSecureSession instance = new SolJMSSecureSession();

            for (int i = 0; i < args.length; i++) {
                if (args[i].equals("-url")) {
                    i++;
                    if (i >= args.length) instance.printUsage();
                    instance.jndiProviderURL = args[i];
                } else if (args[i].equals("-username")) {
                    i++;
                    if (i >= args.length) instance.printUsage();
                    instance.username = args[i];
                } else if (args[i].equals("-password")) {
                    i++;
                    if (i >= args.length) instance.printUsage();
                    instance.password = args[i];
                } else if (args[i].equals("-vpn")) {
                    i++;
                    if (i >= args.length) instance.printUsage();
                    instance.vpn = args[i];              
                } else if (args[i].equals("-cf")) {
                    i++;
                    if (i >= args.length) instance.printUsage();
                    instance.cfJNDIName = args[i];
                } else if (args[i].equals("-exclprots")) {
                    i++;
                    if (i >= args.length) instance.printUsage();
                    instance.excludeProtocols = args[i];
                } else if (args[i].equals("-ciphers")) {
                    i++;
                    if (i >= args.length) instance.printUsage();
                    instance.ciphers = args[i];      
                } else if (args[i].equals("-ts")) {
                	i++;
                	if (i >= args.length) instance.printUsage();
                	instance.trustStore = args[i];
                } else if (args[i].equals("-tsfmt")) {
                    i++;
                    if (i >= args.length) instance.printUsage();
                    instance.trustStoreFmt = args[i];      
                } else if (args[i].equals("-tspwd")) {
                    i++;
                    if (i >= args.length) instance.printUsage();
                    instance.trustStorePwd = args[i];      
                } else if (args[i].equals("-ks")) {
                    i++;
                    if (i >= args.length) instance.printUsage();
                    instance.keyStore = args[i];
                } else if (args[i].equals("-ksfmt")) {
                    i++;
                    if (i >= args.length) instance.printUsage();
                    instance.keyStoreFmt = args[i];      
                } else if (args[i].equals("-ksnfmt")) {
                    i++;
                    if (i >= args.length) instance.printUsage();
                    instance.keyStoreNormalizedFmt = args[i];      
                } else if (args[i].equals("-kspwd")) {
                    i++;
                    if (i >= args.length) instance.printUsage();
                    instance.keyStorePwd = args[i];      
                } else if (args[i].equals("-pk")) {
                    i++;
                    if (i >= args.length) instance.printUsage();
                    instance.privateKeyAlias = args[i];      
                } else if (args[i].equals("-pkpwd")) {
                    i++;
                    if (i >= args.length) instance.printUsage();
                    instance.privateKeyPwd = args[i];      
                } else if (args[i].equals("-no_validate_certificates")) {
                    instance.validateCertificates = false;      
                } else if (args[i].equals("-no_validate_dates")) {
                    instance.validateCertificateDate = false;      
                } else if (args[i].equals("-cn")) {
                    i++;
                    if (i >= args.length) instance.printUsage();
                    instance.trustedCommonNames = args[i];      
                } else if (args[i].equals("-x")) {
                    i++;
                    if (i >= args.length) instance.printUsage();
                    if (args[i].toLowerCase().equals("basic")) {
                        instance.authScheme = AuthenticationScheme.BASIC;
                    } else if (args[i].toLowerCase().equals("client_certificate")) {
                        instance.authScheme = AuthenticationScheme.CLIENT_CERTIFICATE;     
                    } else if (args[i].toLowerCase().equals("kerberos")) {
                        instance.authScheme = AuthenticationScheme.KERBEROS;     
                    } else {
                        instance.printUsage();
                        System.out.println("Illegal authentication type specified - \"" + args[i] + "\", expected one of basic, kerberos");
                    }  
                }
                else if (args[i].equals("-d")) {
                    i++;
                    if (i >= args.length) instance.printUsage();
                    instance.sslConnectionDowngradeTo = args[i];      
                }
                else if (args[i].equals("-compression")) {
                	instance.compression = true;
                }
                else {
                    instance.printUsage();
                    System.out.println("Illegal argument specified - " + args[i]);
                    return;
                }
            }
            
            if (instance.jndiProviderURL == null) {
                instance.printUsage();
                System.out.println("Please specify \"-url\" parameter");
                return;
            } else {
                if (!instance.jndiProviderURL.toLowerCase().startsWith("smfs://")) {
                    System.err.println("Please use smfs:// in \"-url\" parameter for a secure session");
                    return;
                }
            }
            if (instance.username == null && instance.authScheme == AuthenticationScheme.BASIC) {
                instance.printUsage();
                System.out.println("Please specify \"-username\" parameter, or -x CLIENT_CERTIFICATE with -ks and -kspwd or -pkpwd parameters to specify a client certificate.");
                return;
            }

            if (instance.authScheme == AuthenticationScheme.CLIENT_CERTIFICATE && (instance.keyStore == null || (instance.keyStorePwd == null && instance.privateKeyPwd == null))) {
                instance.printUsage();
                System.out.println("Please specify KEY_STORE (-ks) and KEY_STORE_PASSWORD (-kspwd) or PRIVATE_KEY_PASSWORD (-pkpwd) when using CLIENT_CERTIFICATE authentication scheme.");
                return;
            }

            instance.run();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
        System.exit(0);
    }    
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值