Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: cryptix/sasl/rmi/SaslClientSocketFactory.java


1   package cryptix.sasl.rmi;
2   
3   // $Id: SaslClientSocketFactory.java,v 1.3 2001/10/17 09:59:20 raif Exp $
4   //
5   // Copyright (c) 2000-2001 The Cryptix Foundation. All rights reserved.
6   //
7   // Use, modification, copying and distribution of this software is subject to
8   // the terms and conditions of the Cryptix General Licence. You should have
9   // received a copy of the Cryptix General License along with this library; if
10  // not, you can download a copy from <http://www.cryptix.org/>.
11  
12  import cryptix.sasl.SaslInputStream;
13  import cryptix.sasl.SaslOutputStream;
14  
15  import java.io.InputStream;
16  import java.io.IOException;
17  import java.io.OutputStream;
18  import java.io.Serializable;
19  import java.net.Socket;
20  import java.net.SocketException;
21  import java.rmi.server.RMIClientSocketFactory;
22  
23  import javax.security.sasl.SaslClient;
24  
25  import org.apache.log4j.Category;
26  
27  /**
28   * A <tt>SaslClientSocketFactory</tt> instance is used by the RMI runtime in
29   * order to obtain client sockets for RMI calls. A remote object can be
30   * associated with a <tt>SaslClientSocketFactory</tt> when it is created/exported
31   * via the constructors or <tt>exportObject()</tt> methods of
32   * {@link java.rmi.server.UnicastRemoteObject} and {@link java.rmi.activation.Activatable}.<p>
33   *
34   * A <tt>RMIClientSocketFactory</tt> instance associated with a remote object
35   * will be downloaded to clients when the remote object's reference is
36   * transmitted in an RMI call. This <tt>SaslClientSocketFactory</tt> will be
37   * used to create connections to the remote object for remote method calls.<p>
38   *
39   * A <tt>SaslClientSocketFactory</tt> instance can also be associated with a
40   * remote object registry so that clients can use custom socket communication
41   * with a remote object registry.
42   *
43   * @version 1.1
44   */
45  public class SaslClientSocketFactory
46  implements RMIClientSocketFactory, Serializable
47  {
48     // Constants and variables
49     // --------------------------------------------------------------------------
50  
51     private static Category cat = Category.getInstance(SaslClientSocketFactory.class);
52  
53     /**
54      * A dummy 0-byte message to use with SASL-ified RMI socket for mechanisms
55      * whose client side does not have an initial response. This dummy message
56      * is then supposed to be discarded by their server-side implementations.
57      */
58     private static final byte[] NULL_MESSAGE = new byte[0];
59  
60     // Constructor(s)
61     // --------------------------------------------------------------------------
62  
63     // Class methods
64     // -------------------------------------------------------------------------
65  
66     // Instance methods
67     // -------------------------------------------------------------------------
68  
69     /**
70      * Creates a client socket connected to the specified host and port.
71      *
72      * @param host the host name.
73      * @param port the port number.
74      * @return a socket connected to the specified host and port.
75      * @exception IOException if an I/O error occurs during socket creation.
76     */
77     public Socket createSocket(String host, int port) throws IOException {
78        cat.debug("==> createSocket("+String.valueOf(host)+", "+String.valueOf(port)+")");
79  
80        SaslSocket result = new SaslSocket(host, port);
81  
82        SaslClient client = MechanismSelector.instance().newClient(host);
83        if (client == null) {
84           cat.info("Using default RMI...");
85        } else { // SASL authentication
86           try {
87              cat.info("Doing (client) SASL authentication...");
88  
89              String mechanism = client.getMechanismName();
90              cat.info("Chosen mechanism: "+mechanism);
91  
92              InputStream in = result.getInputStream();
93              OutputStream out = result.getOutputStream();
94              byte[] challenge, response;
95              if (client.hasInitialResponse()) {
96                 response = client.evaluateChallenge(null);
97                 // implies that server has last word; ie. client sends nothing
98                 // after server sends last challenge
99                 do {
100                   RMIUtil.writeLV(out, response);
101                   if (!client.isComplete()) {
102                      challenge = RMIUtil.readLV(in);
103                      response = client.evaluateChallenge(challenge);
104                   }
105                } while (!client.isComplete());
106             } else
107                // implies that client has last word; ie. server sends nothing
108                // after client sends last response
109                do {
110                   RMIUtil.writeLV(out, NULL_MESSAGE);
111                   challenge = RMIUtil.readLV(in);
112                   response = client.evaluateChallenge(challenge);
113                   RMIUtil.writeLV(out, response);
114                } while (!client.isComplete());
115 
116             cat.info("Done (client) SASL authentication...");
117 
118             InputStream secureIn = new SaslInputStream(client, in);
119             OutputStream secureOut = new SaslOutputStream(client, out);
120 
121             result.setSecureInputStream(secureIn);
122             result.setSecureOutputStream(secureOut);
123 
124          } catch (IOException x) {
125             cat.error("In createSocket(): "+String.valueOf(x));
126             if (!(x instanceof SocketException)) {
127                cat.debug("createSocket()", x);
128             }
129             throw x;
130          }
131       }
132 
133       cat.debug("<== createSocket()");
134       return result;
135    }
136 }