Sample: IBM® JGSS non-JAAS client program

For more information about using the sample client program, see Downloading and running the sample programs.

Note: By using the code examples, you agree to the terms of the Code license and disclaimer information.
// IBM JGSS 1.0 Sample Client Program

package com.ibm.security.jgss.test;
import org.ietf.jgss.*;
import com.ibm.security.jgss.Debug;
 
import java.io.*;
import java.net.*;
import java.util.*;
 
/**
 * A JGSS sample client; 
 * to be used in conjunction with the JGSS sample server.
 * The client first establishes a context with the server
 * and then sends wrapped message followed by a MIC to the server.
 * The MIC is calculated over the plain text that was wrapped.
 * The client requires to server to authenticate itself 
 * (mutual authentication) during context establishment.
 * It also delegates its credentials to the server.
 * 
 * It sets the JAVA variable 
 * javax.security.auth.useSubjectCredsOnly to false
 * so that JGSS will not acquire credentials through JAAS.
 * 
 * The client takes input parameters, and complements it 
 * with information from the jgss.ini file; any required input not
 * supplied on the command line is taking from the jgss.ini file.
 * 
 * Usage: Client [options]
 * 
 * The -? option produces a help message including supported options.
 * 
 * This sample client does not use JAAS.
 * The client can be run against the JAAS sample client and server.
 * See {@link JAASClient JAASClient} for a sample client that uses JAAS.
 */
 
class Client 
{
    private Util testUtil      = null;
    private String myName      = null;
    private GSSName gssName    = null;
    private String serverName = null;
    private int servicePort    = 0;
    private GSSManager mgr     = GSSManager.getInstance();
    private GSSName service    = null;
    private GSSContext context        = null;
    private String program     = "Client";
    private String debugPrefix = "Client: ";
    private TCPComms tcp       = null;
    private String data               = null;
    private byte[] dataBytes   = null;
    private String serviceHostname= null;
    private GSSCredential gssCred = null;
 
    private static Debug debug        = new Debug();
 
    private static final String usageString =
          "\t[-?] [-d | -n name] [-s serverName]"
        + "\n\t[-h serverHost [:port]] [-p port] [-m msg]" 
        + "\n"
        + "\n  -?\t\t\thelp; produces this message"
        + "\n  -n name\t\tthe client's principal name (without realm)"
        + "\n  -s serverName\t\tthe server's principal name (without realm)"
        + "\n  -h serverHost[:port]\tthe server's hostname"
        +         " (and optional port number)"
        + "\n  -p port\t\tthe port on which the server will be listening"
        + "\n  -m msg\t\tmessage to send to the server";
 
 
    // Caller must call initialize (may need to call processArgs first).
    public Client (String programName) throws Exception
    {
        testUtil = new Util();
        if (programName != null)
        {
            program = programName;
            debugPrefix = programName + ": ";
        }
    }
 
    // Caller must call initialize (may need to call processArgs first).
    Client (String programName, boolean useSubjectCredsOnly) throws Exception
    {
        this(programName);
        setUseSubjectCredsOnly(useSubjectCredsOnly);
    }
 
    public Client(GSSCredential myCred,
                  String serverNameWithoutRealm,
                  String serverHostname,
                  int serverPort,
                  String message)
        throws Exception
    {
        testUtil = new Util();
 
        if (myCred != null)
        {
            gssCred = myCred;
        }
        else
        {
            throw new GSSException(GSSException.NO_CRED, 0,
                                       "Null input credential");
        }
 
        init(serverNameWithoutRealm, serverHostname, serverPort, message);
    }
 
    void setUseSubjectCredsOnly(boolean useSubjectCredsOnly)
    {
        final String subjectOnly = useSubjectCredsOnly ? "true" : "false";
        final String property = "javax.security.auth.useSubjectCredsOnly";
 
        String temp = (String)java.security.AccessController.doPrivileged(
                        new sun.security.action.GetPropertyAction(property));
 
        if (temp == null)
        {
            debug.out(Debug.OPTS_CAT_APPLICATION, debugPrefix 
              + "setting useSubjectCredsOnly property to "
              + useSubjectCredsOnly);
 
            // Property not set. Set it to the specified value.
 
            java.security.AccessController.doPrivileged(
                 new java.security.PrivilegedAction() {
                   public Object run() {
                      System.setProperty(property, subjectOnly);
                      return null;
                   }
                 });
        }
        else
        {
            debug.out(Debug.OPTS_CAT_APPLICATION, debugPrefix 
              + "useSubjectCredsOnly property already set "
              + "in JVM  to " + temp);
        }
    }
 
    private void init(String myNameWithoutRealm,
                      String serverNameWithoutRealm,
                      String serverHostname,
                      int    serverPort,
                      String message) throws Exception
    {
        myName = myNameWithoutRealm;
        init(serverNameWithoutRealm, serverHostname, serverPort, message);
    }
 
    private void init(String serverNameWithoutRealm,
                      String serverHostname,
                      int    serverPort,
                      String message) throws Exception
    {
        // peer's name
        if (serverNameWithoutRealm != null)
        {
            this.serverName = serverNameWithoutRealm;
        }
        else
        {
            this.serverName = testUtil.getDefaultServicePrincipalWithoutRealm();
        }
 
        // peer's host
        if (serverHostname != null)
        {
            this.serviceHostname = serverHostname;
        }
        else
        {
            this.serviceHostname = testUtil.getDefaultServiceHostname();
        }
 
        // peer's port
        if (serverPort > 0)
        {
            this.servicePort = serverPort;
        }
        else
        {
            this.servicePort = testUtil.getDefaultServicePort();
        }
 
        // message for peer
        if (message != null)
        {
            this.data = message;
        }
        else
        {
            this.data = "The quick brown fox jumps over the lazy dog";
        }
 
        this.dataBytes = this.data.getBytes();
 
        tcp = new TCPComms(serviceHostname, servicePort);
    }
                   
 
    void initialize() throws Exception
    {
         Oid krb5MechanismOid = new Oid("1.2.840.113554.1.2.2");
 
        if (gssCred == null)
        {
            if (myName != null)
            {
                debug.out(Debug.OPTS_CAT_APPLICATION, debugPrefix 
                                   + "creating GSSName USER_NAME for " 
                                   + myName);
 
                gssName = mgr.createName(
                               myName,
                               GSSName.NT_USER_NAME,
                                krb5MechanismOid);
  
                debug.out(Debug.OPTS_CAT_APPLICATION, debugPrefix 
                                   + "Canonicalized GSSName=" + gssName);
            }
            else
                gssName = null; // for default credentials
 
  
            debug.out(Debug.OPTS_CAT_APPLICATION, debugPrefix + "creating"
               + ((gssName == null)? " default " : " ") 
               + "credential");
 
            gssCred = mgr.createCredential(
                                    gssName,
                                    GSSCredential.DEFAULT_LIFETIME,
                                    (Oid)null,
                                    GSSCredential.INITIATE_ONLY);
            if (gssName == null)
            {
                gssName = gssCred.getName();
 
                myName  = gssName.toString();
 
                debug.out(Debug.OPTS_CAT_APPLICATION, 
                    debugPrefix + "default credential principal=" + myName);
            }
        }
 
        debug.out(Debug.OPTS_CAT_APPLICATION, debugPrefix + gssCred);
   
        debug.out(Debug.OPTS_CAT_APPLICATION, debugPrefix
           + "creating canonicalized GSSName for serverName " + serverName);
 
        service = mgr.createName(serverName, 
                                 GSSName.NT_HOSTBASED_SERVICE,
                                  krb5MechanismOid);
 
        debug.out(Debug.OPTS_CAT_APPLICATION, debugPrefix 
           + "Canonicalized server name = " + service);
 
        debug.out(Debug.OPTS_CAT_APPLICATION, 
                            debugPrefix + "Raw data=" + data);
    }
 
 
    void establishContext(BitSet flags) throws Exception
    {
        try {
 
          debug.out(Debug.OPTS_CAT_APPLICATION, 
                            debugPrefix + "creating GSScontext");
 
          Oid defaultMech = null;
          context = mgr.createContext(service, defaultMech, gssCred, 
                                      GSSContext.INDEFINITE_LIFETIME);
 
          if (flags != null)
          {
              if (flags.get(Util.CONTEXT_OPTS_MUTUAL))
              {
                  debug.out(Debug.OPTS_CAT_APPLICATION, debugPrefix 
                       + "requesting mutualAuthn");
 
                  context.requestMutualAuth(true);
              }
 
              if (flags.get(Util.CONTEXT_OPTS_INTEG))
              {
                  debug.out(Debug.OPTS_CAT_APPLICATION, debugPrefix 
                       + "requesting integrity");
 
                  context.requestInteg(true);
              }
 
              if (flags.get(Util.CONTEXT_OPTS_CONF))
              {
                  context.requestConf(true);
                  debug.out(Debug.OPTS_CAT_APPLICATION, debugPrefix 
                          + "requesting confidentiality");
              }
 
              if (flags.get(Util.CONTEXT_OPTS_DELEG))
              {
                  context.requestCredDeleg(true);
                  debug.out(Debug.OPTS_CAT_APPLICATION, debugPrefix 
                           + "requesting delegation");
              }
 
              if (flags.get(Util.CONTEXT_OPTS_REPLAY))
              {
                  context.requestReplayDet(true);
                  debug.out(Debug.OPTS_CAT_APPLICATION, debugPrefix 
                      + "requesting replay detection");
              }
 
              if (flags.get(Util.CONTEXT_OPTS_SEQ))
              {
                  context.requestSequenceDet(true);
                  debug.out(Debug.OPTS_CAT_APPLICATION, debugPrefix 
                           + "requesting out-of-sequence detection");
              }
              // Add more later!
          }
 
          byte[] response = null;
          byte[] request = null;
          int len = 0;
          boolean done = false;
          do {
              debug.out(Debug.OPTS_CAT_APPLICATION, debugPrefix 
                  + "Calling initSecContext");
 
              request = context.initSecContext(response, 0, len);
 
              if (request != null)
              {
                  debug.out(Debug.OPTS_CAT_APPLICATION, debugPrefix 
                    + "Sending initial context token");
 
                  tcp.send(request);
              }
              done = context.isEstablished();
 
              if (!done)
              {
                  debug.out(Debug.OPTS_CAT_APPLICATION, 
                      debugPrefix + "Receiving response token");
 
                  byte[] temp = tcp.receive();
                  response = temp;
                  len = response.length;
              }
          } while(!done);
 
          debug.out(Debug.OPTS_CAT_APPLICATION, 
                debugPrefix + "context established with acceptor");
          
        } catch (Exception exc) {
            exc.printStackTrace();
            throw exc;
        }
    }
 
    void doMIC() throws Exception
    {
        debug.out(Debug.OPTS_CAT_APPLICATION, debugPrefix + "generating MIC");
        byte[] mic = context.getMIC(dataBytes, 0, dataBytes.length, null);
 
        if (mic != null)
        {
            debug.out(Debug.OPTS_CAT_APPLICATION, debugPrefix + "sending MIC");
            tcp.send(mic);
        }
        else
            debug.out(Debug.OPTS_CAT_APPLICATION, 
                             debugPrefix + "getMIC Failed");
    }
 
    void doWrap() throws Exception
    {
        MessageProp mp = new MessageProp(true);
        mp.setPrivacy(context.getConfState());
 
        debug.out(Debug.OPTS_CAT_APPLICATION, debugPrefix + "wrapping message");
 
        byte[] wrapped = context.wrap(dataBytes, 0, dataBytes.length, mp);
 
        if (wrapped != null)
        {
            debug.out(Debug.OPTS_CAT_APPLICATION,
                    debugPrefix + "sending wrapped message");
 
            tcp.send(wrapped);
        }
        else
            debug.out(Debug.OPTS_CAT_APPLICATION, debugPrefix + "wrap Failed");
    }
 
    void printUsage()
    {
        System.out.println(program + usageString);
    }
 
    void processArgs(String[] args) throws Exception
    {
        String port            = null;
        String myName          = null;
        int servicePort               = 0;
        String serviceHostname = null;
 
        String sHost = null;
        String msg = null;
 
        GetOptions options = new GetOptions(args, "?h:p:m:n:s:");
        int ch = -1;
        while ((ch = options.getopt()) != options.optEOF)
        {
            switch(ch)
            {
                case '?':
                    printUsage();
                    System.exit(1);
 
                case 'h':
                    if (sHost == null)
                    {
                        sHost = options.optArgGet();
                        int p = sHost.indexOf(':');
                        if (p != -1)
                        {
                            String temp1 = sHost.substring(0, p);
                            if (port == null)
                                port = sHost.substring(p+1, sHost.length()).trim();
                            sHost = temp1;
                        }
                    }
                    continue;
 
                case 'p':
                    if (port == null)
                        port = options.optArgGet();
                    continue;
 
                case 'm':
                    if (msg == null)
                        msg = options.optArgGet();
                    continue;
 
                case 'n':
                    if (myName == null)
                        myName = options.optArgGet();
                    continue;
 
                case 's':
                    if (serverName == null)
                        serverName = options.optArgGet();
                    continue;
            }
        }
 
        if ((port != null) && (port.length() > 0))
        {
            int p = -1;
            try {
                p = Integer.parseInt(port);
            } catch (Exception exc) {
                System.out.println("Bad port input: "+port);
            }
 
            if (p != -1)
                servicePort = p;
        }
       
        if ((sHost != null) && (sHost.length() > 0)) {
                serviceHostname = sHost;                
        }
 
        init(myName, serverName, serviceHostname, servicePort, msg);
    }
 
    void interactWithAcceptor(BitSet flags) throws Exception
    {
        establishContext(flags);
        doWrap();
        doMIC();
    }
 
    void interactWithAcceptor() throws Exception
    {
        BitSet flags = new BitSet();
        flags.set(Util.CONTEXT_OPTS_MUTUAL);
        flags.set(Util.CONTEXT_OPTS_CONF);
        flags.set(Util.CONTEXT_OPTS_INTEG);
        flags.set(Util.CONTEXT_OPTS_DELEG);
        interactWithAcceptor(flags);
    }
 
    void dispose() throws Exception
    {
        if (tcp != null)
        {
            tcp.close();
        }
    }
   
    public static void main(String args[]) throws Exception
    {
        System.out.println(debug.toString()); // XXXXXXX
        String programName = "Client";
        Client client = null;
        try {
            client = new Client(programName,
                                false); // don't use Subject creds.
            client.processArgs(args);
            client.initialize();
            client.interactWithAcceptor();
        } catch (Exception exc) {
            debug.out(Debug.OPTS_CAT_APPLICATION, 
                            programName + " Exception: " + exc.toString());
            exc.printStackTrace();
            throw exc;
        } finally {
            try {
                if (client != null)
                    client.dispose();
            } catch (Exception exc) {}
        }
 
        debug.out(Debug.OPTS_CAT_APPLICATION, programName + ": done");
    }
}
Related concepts
Example: IBM i5/OS PASE native method for Java
Related tasks
Example: Run the Java Performance Data Converter
Related reference
Example: Internationalization of dates using the java.util.DateFormat class
Example: Internationalization of numeric display using the java.util.NumberFormat class
Example: Internationalization of locale-specific data using the java.util.ResourceBundle class
Example: Access property
Example: BLOB
Example: CallableStatement interface for IBM Developer Kit for Java
Example: Remove values from a table through another statement's cursor
Example: CLOB
Example: Create a UDBDataSource and bind it with JNDI
Example: Create a UDBDataSource, and obtain a user ID and password
Example: Create a UDBDataSourceBind and set DataSource properties
Example: DatabaseMetaData interface for IBM Developer Kit for Java - Return a list of tables
Example: Datalink
Example: Distinct types
Example: Embed SQL Statements in your Java application
Example: End a transaction
Example: Invalid user ID and password
Example: JDBC
Example: Multiple connections that work on a transaction
Example: Obtain an initial context before binding UDBDataSource
Example: ParameterMetaData
Example: Change values with a statement through another statement's cursor
Example: ResultSet interface for IBM Developer Kit for Java
Example: ResultSet sensitivity
Example: Sensitive and insensitive ResultSets
Example: Set up connection pooling with UDBDataSource and UDBConnectionPoolDataSource
Example: SQLException
Example: Suspend and resume a transaction
Example: Suspended ResultSets
Example: Test the performance of connection pooling
Example: Test the performance of two DataSources
Example: Update BLOBs
Example: Update CLOBs
Example: Use a connection with multiple transactions
Example: Use BLOBs
Example: Use CLOBs
Example: Use JTA to handle a transaction
Example: Use metadata ResultSets that have more than one column
Example: Use native JDBC and IBM Toolbox for Java JDBC concurrently
Example: Use PreparedStatement to obtain a ResultSet
Create and populate a DB2CachedRowSet
Example: Use the Statement object's executeUpdate method
Examples: JAAS HelloWorld
Example: JAAS SampleThreadSubjectLogin
Sample: IBM JGSS non-JAAS server program
Sample: IBM JGSS JAAS-enabled client program
Sample: IBM JGSS JAAS-enabled server program
Examples: IBM Java Secure Sockets Extension
Example: Call a CL program with java.lang.Runtime.exec()
Example: Call a CL command with java.lang.Runtime.exec()
Example: Call another Java program with java.lang.Runtime.exec()
Example: Call Java from C
Example: Call Java from RPG
Example: Use input and output streams for interprocess communication
Example: Java Invocation API
Examples: Use the Java Native Interface for native methods
Example: Use sockets for interprocess communication
Examples: Change your Java code to use client socket factories
Examples: Change your Java code to use server socket factories
Examples: Change your Java client to use secure sockets layer
Examples: Change your Java server to use secure sockets layer