<?xml version='1.0'?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
               "http://docbook.org/xml/4.2/docbookx.dtd"
               [
               <!ENTITY copyright SYSTEM "copyright.xml">
               ]>

<chapter label="Advanced Security" id ="22">
  <title>
    Advanced Security
  </title>

  <tocchap>
    <tocentry>
      
    </tocentry>
    <toclevel1>
      <tocentry linkend="Introduction">
	<ulink url="#Introduction">Introduction</ulink>
      </tocentry>
    </toclevel1>

    <toclevel1>
      <tocentry>
	<ulink url="#Invocation constraints">Invocation constraints</ulink>
      </tocentry>
    </toclevel1>

    <toclevel1>
      <tocentry>
	<ulink url="#Method constraints">Method constraints</ulink>
      </tocentry>
    </toclevel1>

    <toclevel1>
      <tocentry>
	<ulink url="#Logging">Logging</ulink>
      </tocentry>
    </toclevel1>

    <toclevel1>
      <tocentry>
	<ulink url="#Protocols">Protocols</ulink>
      </tocentry>
      <toclevel2>
	<tocentry>
	  <ulink url="#Protocols.TCP">TCP</ulink>
	</tocentry>
      </toclevel2>
      <toclevel2>
	<tocentry>
	  <ulink url="#Protocols.SSL">SSL</ulink>
	</tocentry>
      </toclevel2>
    </toclevel1>

    <toclevel1>
      <tocentry>
	<ulink url="#Proxy preparer">Proxy preparer</ulink>
      </tocentry>
    </toclevel1>
    <toclevel1>
	<tocentry>
	  <ulink url="#File classifier server">File classifier server</ulink>
	</tocentry>
    </toclevel1>
    <toclevel1>
      <tocentry>
	<ulink url="#Integrity">Integrity</ulink>
      </tocentry>
      <toclevel2>
	<tocentry>
	  <ulink url="#Integrity.Client">Client</ulink>
	</tocentry>
      </toclevel2>
       <toclevel2>
	<tocentry>
	  <ulink url="#Integrity.TCP server">TCP server</ulink>
	</tocentry>
      </toclevel2>
       <toclevel2>
	<tocentry>
	  <ulink url="#Integrity.SSL server">SSL server</ulink>
	</tocentry>
      </toclevel2>
    </toclevel1>

    <toclevel1>
      <tocentry>
	<ulink
	  url="#Proxy verification">Proxy verification</ulink>
      </tocentry>
      <toclevel2>
	<tocentry>
	  <ulink url="#Proxy verification.HTTPMD">HTTPMD</ulink>
	</tocentry>
      </toclevel2>
      <toclevel2>
	<tocentry>
	  <ulink url="#Proxy verification.Calculating HTTPMD URLs">
	    Calculating HTTPMD URLs</ulink>
	</tocentry>
      </toclevel2>
      <toclevel2>
	<tocentry>
	  <ulink url="#Proxy verification.Reggie">Reggie</ulink>
	</tocentry>
      </toclevel2>
      <toclevel2>
	<tocentry>
	  <ulink url="#Proxy verification.Proxy verifier">Proxy verifier</ulink>
	</tocentry>
      </toclevel2>
      <toclevel2>
	<tocentry>
	  <ulink url="#Proxy verification.Client with proxy verification">
	    Client with proxy verification</ulink>
	</tocentry>
      </toclevel2>
      <toclevel2>
	<tocentry>
	  <ulink url="#Proxy verification.SSL trusted server">
	    SSL trusted server</ulink>
	</tocentry>
      </toclevel2>
      <toclevel2>
	<tocentry>
	  <ulink url="#Proxy verification.Errors">Errors</ulink>
	</tocentry>
      </toclevel2>
    </toclevel1>

    <toclevel1>
      <tocentry>
	<ulink url="#Confidentiality">Confidentiality</ulink>
      </tocentry>
      <toclevel2>
	<tocentry>
	  <ulink url="#Confidentiality.Client">Client</ulink>
	</tocentry>
      </toclevel2>
      <toclevel2>
	<tocentry>
	  <ulink url="#Confidentiality.SSL confidential server">SSL confidential server</ulink>
	</tocentry>
      </toclevel2>
    </toclevel1>

    <toclevel1>
      <tocentry>
	<ulink url="#Mix 'n Match">Mix 'n Match</ulink>
      </tocentry>
    </toclevel1>

     <toclevel1>
      <tocentry>
	<ulink url="#Identity Management">Identity Management</ulink>
      </tocentry>
      <toclevel2>
	<tocentry>
	  <ulink url="#Identity Management.JAAS">JAAS</ulink>
	</tocentry>
      </toclevel2>
      <toclevel2>
	<tocentry>
	  <ulink url="#Identity Management.Keystores">Keystores</ulink>
	</tocentry>
      </toclevel2>
      <toclevel2>
	<tocentry>
	  <ulink url="#Identity Management.Authenticating Server">Authenticating Server</ulink>
	</tocentry>
      </toclevel2>
      <toclevel2>
	<tocentry>
	  <ulink url="#Identity Management.Client requiring authentication">
	  Client requiring authentication</ulink>
	</tocentry>
      </toclevel2>
      <toclevel2>
	<tocentry>
	  <ulink url="#Identity Management.Alternative constraints">
	    Alternative constraints</ulink>
	</tocentry>
      </toclevel2>
      <toclevel2>
	<tocentry>
	  <ulink url="#Identity Management.Authenticating Client">
	    Authenticating Client</ulink>
	</tocentry>
      </toclevel2>
      <toclevel2>
	<tocentry>
	  <ulink url="#Identity Management.Server requiring authentication">
	    Server Requiring Authentication</ulink>
	</tocentry>
      </toclevel2>
    </toclevel1>

    <toclevel1>
      <tocentry>
	<ulink url="#Authorisation">Authorisation</ulink>
      </tocentry>
    </toclevel1>

    <toclevel1>
      <tocentry>
	<ulink url="#Conclusion">Conclusion</ulink>
      </tocentry>
    </toclevel1>

  </tocchap>
 
  
  <abstract>
    <para>
      Jini from the beginning has used the Java security model to
      control the actions of proxies when they are run from clients.
      However, this does not control security of the transport aspects
      of remote method calls. Jini 2.0 introduced a wide-ranging set
      of mechanisms largely aimed at such issues as encryption,
      authorisation, etc
    </para>
  </abstract>
  
  <sect1>
    <title id="Introduction">
      Introduction
    </title>
    <para>
      Prior to version 2.0, Jini just used the standard Java security mechanism.
      This was designed to deal with code downloaded from a remote location,
      and was put in place to limit what foreign code could be in a local
      virtual machine. This is a capability-based model, in which
      the client grants to foreign code the capability of performing certain
      activities. So for example, foreign code cannot write to the local
      file system unless this permission has been granted.
      This was covered in detail on the chapter on Basic Security.
    </para>

    <para>
      What this has ignored is a range of issues concerning the network
      transport. For example
      <orderedlist>
	<listitem>
	  <para>
	    <emphasis>Integrity:</emphasis> have the classes and instance
	    data reached the client in the form they started, or has someone
	    along the way corrupted them?
	  </para>
	</listitem>
	<listitem>
	  <para>
	    <emphasis>Authentication:</emphasis> did the data come from
	    whom you expected, or did it come from someone else?
	    The client may need to authenticate itself to the server,
	    or vice-versa
	  </para>
	</listitem>
	<listitem>
	  <para>
	    <emphasis>Authorisation:</emphasis> once you know who it came
	    from, what rights will you grant it? This was covered in the
	    Basic Security chapter
	  </para>
	</listitem>
	<listitem>
	  <para>
	    <emphasis>Confidentiality:</emphasis> has the data been encrypted
	    so that others cannot read it?
	  </para>
	</listitem>
      </orderedlist>
    </para>

    <para>
      These are standard network security concerns. However, Jini gives them
      some special wrinkles. For example, instance data for a proxy may be
      sent from a server to a client either directly or via a lookup
      server. In addition to the instance data, class files often have to be
      loaded, and these may come from a third party HTTP server. There are
      even subtleties in where a service may be running: an activatable
      service doesn't run in the server that started it, but in a third party
      activation service.
    </para>
  </sect1>
  
  <sect1>
    <title id="Invocation constraints">
      Invocation constraints
    </title>
    
    <para>
      The security considerations act as <emphasis>constraints</emphasis> on
      normal execution: something that might have been allowed will be
      restricted. For example, a client may put the constraint that 
      communications be encrypted. It might not want to know many details
      of how this has been done (that sort of detail can be left to the
      middleware itself). But if it hasn't been done, then it will just
      not accept the communication.
    </para>

    <para>
      Jini 2.0 defines a set of objects that specify constraints on 
      behaviour. They don't specify <emphasis>how</emphasis> a constraint
      is implemented, just <emphasis>what</emphasis> the constraint is. 
      Some of these are
      <orderedlist>
	<listitem>
	  <para>
	    <classname>Integrity.YES</classname>: 
	    Detect when message contents (both requests and replies) have 
	    been altered by third parties, and if detected, refuse to 
	    process the message and throw an exception
	  </para>
	</listitem>
	<listitem>
	  <para>
	    <classname>Integrity.NO</classname>:
	    Do not detect when message contents have been altered by 
	    third parties
	  </para>
	</listitem>
	<listitem>
	  <para>
	    In between YES and NO is DON'T CARE. There is no specific object
	    to express this constraint (or lack of it). 
	    If you don't care whether it is checked or not,
	    then you don't specify either a YES or NO
	    constraint - you just don't mention the constraint at all
	  </para>
	</listitem>
	<listitem>
	  <para>
	    <classname>Confidentiality.YES</classname>:
	    Transmit message contents so that they cannot easily be 
	    interpreted by third parties (typically by using encryption)
	  </para>
	</listitem>
	<listitem>
	  <para>
	    <classname>Confidentiality.NO</classname>:
	    Transmit message contents in the clear (no use of encryption)
	  </para>
	</listitem>
	<listitem>
	  <para>
	    Similarly, in between YES and NO is DON'T CARE. 
	    There is no specific object
	    to express this constraint (or lack of it). You just don't use
	    either the YES or NO object to mean that you don't care if
	    it is confidential or not - this is common to all constraints
	  </para>
	</listitem>
	<listitem>
	  <para>
	    <classname>ClientAuthentication.YES</classname>:
	    The client must authenticate to the server
	  </para>
	</listitem>
	<listitem>
	  <para>
	    <classname>ClientAuthentication.NO</classname>:
	    Do not authenticate the client to the server.
	    This has a special meaning in that the client will
	    refuse to say who it is:
	    the client remains anonymous. This may be important
	    for applications where participants wish to preserve
	    their privacy
	  </para>
	</listitem>
	<listitem>
	  <para>
	    <classname>ServerAuthentication.YES </classname>:
	    Authenticate the server to the client
	  </para>
	</listitem>
	<listitem>
	  <para>
	    <classname>ServerAuthentication.NO </classname>:
	    Do not authenticate the server to the client, 
	    so that the server remains anonymous
	  </para>
	</listitem>
      </orderedlist>
      The JavaDoc for <classname>InvocationConstraint</classname> lists
      all its subclasses, and within each of these will be constant
      objects such as the above.
    </para>

    <para>
      Each <classname>InvocationConstraint</classname> can potentially
      limit client or server activity. We can make up two sets of
      constraints: <emphasis>mandatory</emphasis> constraints that 
      <emphasis>must</emphasis> be satisified and
      <emphasis>preferences</emphasis> that 
      <emphasis>should</emphasis> be satisfied if they
      do not conflict with a mandatory one. For eaxmple, if both 
       <classname>Integrity.YES</classname> and  
      <classname>Integrity.No</classname> are specified as mandatory
      then any call must fail. If however one is specified as mandatory
      and the other as preferred, then the mandatory one must be
      satisfied.
    </para>

    <para>
      An <classname>InvocationConstraints</classname> (note the plural)
      takes a set of mandatory and a set of preferred constraints.
      These can be specified as collections or arrays to a constructor.
      <programlisting>
class InvocationConstraints {
    InvocationConstraints(Collection reqs, Collection prefs);
    InvocationConstraints(InvocationConstraint[] reqs, 
                          InvocationConstraint[] prefs);
    InvocationConstraints(InvocationConstraint req, 
                          InvocationConstraint pref);

    ...
} 
      </programlisting>
    </para>
  </sect1>

  <sect1>
    <title id="Method constraints">
      Method constraints
    </title>
    <para>
      Whenever a method call is made, constraint checks should be made.
      For example, a bank method <classname>withdraw()</classname>
      should always authenticate the caller. It should be done on each
      call, not just once - a certificate that is valid for one call
      may not be valid the next time a call is made.
    </para>

    <para>
      The <classname>MethodConstraints</classname> interface allows each method
      to have its own set of constraints: for example a method that sends
      credit card details might require encryption whereas a "browse"
      request would not. A <classname>BasicMethodConstraints</classname> class
      is usually used as implementation of this interface. In this
      all methods can be set to use the same set of constraints
      or it can be set up on  a per-method basis. 
      <programlisting>
class BasicMethodConstraints {
     BasicMethodConstraints(InvocationConstraints constraints);
     BasicMethodConstraints(BasicMethodConstraints.MethodDesc[] descs); 

     ...
}
      </programlisting>
    </para>
    
  </sect1>

  <sect1>
    <title id="Logging">Logging</title>

    <para>
      It is difficult to get security right, and hard to debug. The 
      <classname>Logger</classname> is your friend here (see the chapter
      on Logging). Security is handled by the 
      <classname>net.jini.security.Security</classname> and this writes
      to three loggers
      <orderedlist>
	<listitem>
	  <para>
	    <classname>net.jini.security.integrity</classname>
	  </para>
	</listitem>
	<listitem>
	  <para>
	    <classname>net.jini.security.trust</classname>
	  </para>
	</listitem>
	<listitem>
	  <para>
	    <classname>net.jini.security.policy</classname>
	  </para>
	</listitem>
      </orderedlist>
    </para>

    <para>
      Sample code to get logging information from the client is
      <programlisting>
    static final String TRUST_LOG = "net.jini.security.trust";
    static final String INTEGRITY_LOG = "net.jini.security.integrity";
    static final String POLICY_LOG = "net.jini.security.policy";

    static final Logger trustLogger = Logger.getLogger(TRUST_LOG);
    static final Logger integrityLogger = Logger.getLogger(INTEGRITY_LOG);
    static final Logger policyLogger = Logger.getLogger(POLICY_LOG);

    private static FileHandler trustFh;
    private static FileHandler integrityFh;
    private static FileHandler policyFh;

    private static void installLoggers() {
	try {
	    // this handler will save ALL log messages in the file
	    trustFh = new FileHandler("log.client.trust.txt");
	    integrityFh = new FileHandler("log.client.integrity.txt");
	    policyFh = new FileHandler("log.client.policy.txt");

	    // the format is simple rather than XML
	    trustFh.setFormatter(new SimpleFormatter());
	    integrityFh.setFormatter(new SimpleFormatter());
	    policyFh.setFormatter(new SimpleFormatter());

	    trustLogger.addHandler(trustFh);
	    integrityLogger.addHandler(integrityFh);
	    policyLogger.addHandler(policyFh);

	    trustLogger.setLevel(java.util.logging.Level.ALL);
	    integrityLogger.setLevel(java.util.logging.Level.ALL);
	    policyLogger.setLevel(java.util.logging.Level.ALL);
	} catch(Exception e) {
	    e.printStackTrace();
	}
    }
      </programlisting>
    </para>
  </sect1>

  <sect1>
    <title id="Protocols">Protocols</title>

    <para>
      There is a range of different protocols that can be used to shift
      data around the network. These include TCP and HTTP (which of course
      is layered above TCP), and those designed with security in mind
      such as HTTPS, SSL (now officially TLS) and others.
    </para>

    <sect2>
      <title id="Protocols.TCP">TCP</title>

      <para>
	A service uses TCP by using a <classname>BasiJeriExporter</classname>
	with TCP server. Typically the exporter will be defined in a 
	configuration file such as
      <programlisting>
	<?program "config/security/jeri-tcp.config"?>
      </programlisting>
      </para>

      <para>
	TCP does not support <emphasis>any</emphasis> of the security
	mechanisms of this chapter. So we use it as a "bad example"
	once and then no longer consider it.
      </para>
    </sect2>
    

    <sect2>
      <title id="Protocols.SSL">SSL</title>
      <para>
	The server can use
	Jeri over SSL, by a  configuration such as
	<filename>config/security/jeri-ssl-minimal.config</filename>
	<programlisting>
	  <?program "config/security/jeri-ssl-minimal.config"?>
	</programlisting>
	SSL is designed to support encryption using a secret key mechanism
	following open negotiation. It can also support authentication
	of both client and server using public key certificates.
      </para>

    </sect2>
    <para></para>
  </sect1>

  <sect1>
    <title id="Proxy preparer">Proxy preparer</title>
    <para>
      When a client gets a proxy from a server, the server may already have
      placed some constraints on it. But any of these constraints are those that
      the server requires, not those that the client may require. So the
      client has to set its own constraints on the service proxy. It does
      this by creating a new proxy from the original by adding in its own
      constraints. The is described by both an interface and sample
      implementations. The interface is <classname>ProxyPreparer</classname>
      <programlisting>
interface ProxyPreparer {
   Object prepareProxy(Object proxy)
                    throws RemoteException;
}
      </programlisting>
      and an implementation is <classname>BasicProsyPreparer</classname>
      <programlisting>
class BasicProxyPreparer {
    BasicProxyPreparer();
    BasicProxyPreparer(boolean verify, 
                       MethodConstraints methodConstraints, 
                       Permission[] permissions);
    BasicProxyPreparer(boolean verify, 
                       Permission[] permissions);
} 
      </programlisting>
      The second constructor is the one most likely to be used by a client: 
      get a proxy from a service, create a
      basic proxy preparer with constraints and permissions (and whether
      or not to  verify the proxy - see later) and use this to
      prepare a new proxy with the constraints
      and permissions. The new proxy is then used for all calls on the 
      service.
    </para>
 
    <para>
      A client that finds a file classifier and prepares a new service
      proxy, taking the proxy preparer from a configuration file is
      <programlisting>
	<?program "src/client/TestFileClassifierProxyPreparer.java"?>
      </programlisting>
      A minimal configuration file for this client is 
      <filename>config/security/preparer-minimal.config</filename>
      <programlisting>
	<?program "config/security/preparer-minimal.config"?>
      </programlisting>
      This can be run directly by
      <programlisting>
	java ... client.TestFileClassifierProxyPreparer \
                 config/security/preparer-minimal.config
      </programlisting>
      or from the Ant build files by
      <programlisting>
	ant run -DrunFile=client.TestFileClassifierProxyPreparer \ 
                -Dconfig=config/security/preparer-minimal.config
      </programlisting>
    </para>

    <para>
      This client will run successfully with any service that does not
      impose any constraints on the client. So, for example, it will run
      with any service of earlier chapters which do not impose any
      contraints at all. However, using this configuration
      it will not run with some of the
      examples later in this chapter which <emphasis>do</emphasis>
      impose client-side constraints.
    </para>
 </sect1>

  <sect1>
    <title id="File classifier server">File classifier server</title>

    <para>
      A file classifier server using configuration has already been given
      in the chapter Configuration. The version here is almost the
      same, with the addition of placing the service name in the 
      configuration (since we might need to run different versions
      of the service for different security requirements).
      <programlisting>
	<?program "src/config/FileClassifierServerConfig.java"?>
      </programlisting>
    </para>

    <para>
      This server can be run using a configuration file such as a standard
      Jeri over TCP configuration 
      <filename>config/security/jeri-tcp.config</filename>
      <programlisting>
	<?program "config/security/jeri-tcp.config"?>
      </programlisting>   
     This can be run from gthe command line by
      <programlisting>
	java ... security.FileClassifierServer \
                 config/security/jeri-tcp.config
      </programlisting>
      or from the Ant build files by
      <programlisting>
	ant run -DrunFile=security.FileClassifierServer \ 
                -Dconfig=config/security/jeri-tcp.config
      </programlisting> 
   </para>

    <para>
      The server with the <classname>rmi.FileClassifierImpl</classname>
      and <filename>config/security/jeri-tcp.config</filename> configuration
      has no security features, and will be discarded by a client that
      imposes any constraints. However, by changing the service class
      or configuration file it can meet various client requirements.
    </para>

    <para>
      To build the server and run it with various configuration files
      I use the Ant file 
      <filename>security.FileClassifierServer.xml</filename>.
      This configuration file is a bit trickier than earlier ones
      in that it needs to set different parameters for different
      situations. For example, in the following section on Integrity
      ordinary HTTP URLs can be used but in the later section on
      Proxy Trust a different type of URL, HTTPMD ones must be used.
      This is controlled by various command line "defines" which
      can run specialised targets such as <command>httpmd</command>
      if the Ant file is run with a command-line define of
      <command>-Ddo.trust=yes</command>. This sets the property
      <command>codebase.httpd</command> to an HTTPMD URL. 
      Otherwise, the target
      is not run and a default value of this property as an
      HTTP URL is used.
    </para>

    <para>
      The Ant file is
      <programlisting>
	<?antFile "antBuildFiles/security.FileClassifierServer.xml"?>
      </programlisting>
    </para>
  </sect1>
  
  <sect1>
    <title id="Integrity">
      Integrity
    </title>

    <para>
      Integrity ensures that each method call sent from the client
      to server gets there in original form - that is, it is not 
      altered in any way, and similarly that replies are not altered.
      It does not guarantee privacy - anyone can look at messages
      (that is the role of confidentiality).
      It also does not guarantee that the entity you are sending
      messages to is the one you think it is (that is the role of
      authentication).
    </para>
    
    <sect2 id ="Integrity.Client">
      <title>Client</title>
 
      <para>
	A client can enforce integrity by requiring that the proxy support
	the constraint <classname>Integrity.YES</classname>. With the
	example client above, this can be done by using the
	<filename>config/security/preparer-integrity.config</filename> 
	configuration file
	<programlisting>
	  <?program "config/security/preparer-integrity.config"?>
	</programlisting>
      </para>
      
      <para>
	To run the client using this configuration, run
	<programlisting>
	java ... client.TestFileClassifierProxyPreparer \
                 config/security/preparer-integrity.config
	</programlisting>
	or
	<programlisting>
	ant run -DrunFile=client.TestFileClassifierProxyPreparer \ 
                -Dconfig=config/security/preparer-integrity.config
	</programlisting>
	instead of
	<programlisting>
	java ... client.TestFileClassifierProxyPreparer \
                 config/security/preparer-minimal.config
	</programlisting>
	or 
	<programlisting>
	ant run -DrunFile=client.TestFileClassifierProxyPreparer \ 
                -Dconfig=config/security/preparer-minimal.config
	</programlisting>
	Note that only the configuration file has changed.
      </para>
    </sect2>
    
    <sect2>
      <title id="Integrity.TCP server">TCP server</title>
      <para>
	TCP does not support integrity checking. 
	Using TCP, we can expect integrity to fail.
	The server can use
	Jeri over TCP, by a  configuration such as
	<filename>config/security/jeri-tcp.config</filename>
      <programlisting>
	<?program "config/security/jeri-tcp.config"?>
      </programlisting>
	It can be run by
	<programlisting>
	  java ... security.FileClassifierServer config/security/jeri-tcp.config
	</programlisting>
	or from the Ant file by
	<programlisting>
	  ant run -DrunFile=security.FileClassifierServer \
                  -Dconfig=config/security/jeri-tcp.config
	</programlisting>
      </para>

      <para>
	The client can find the service, and create a new proxy for it.
	But when it tries to call a method through this proxy, integrity
	checking will fail. This shows by the client throwing an
	exception
      <programlisting>
java.rmi.ConnectIOException: I/O exception connecting to 
BasicObjectEndpoint[e42fc746-e7c7-444b-bbc9-b124217439c4,
TcpEndpoint[127.0.0.1:43084]]; nested exception is:
     net.jini.io.UnsupportedConstraintException: 
         cannot satisfy constraint: Integrity.YES
      </programlisting>
	This exception is thrown when the client attempts to call any
	method on the proxy. In the example above, it occurs in the
	first method call to the proxy
	<programlisting>
type = classifier.getMIMEType(fileName)
	</programlisting>
      </para>

      <para>
	TCP not only fails to support integrity checking, it also fails
	to support any of the other security mechanisms of this chapter. 
	We will not consider it any further in this chapter.
      </para>
    </sect2>

    <sect2>
      <title id="Integrity.SSL server">SSL server</title>

      <para>
	SSL (or TLS) does support integrity checking.  The server can use
	Jeri over SSL, by a  configuration such as
	<filename>config/security/jeri-ssl-minimal.config</filename>
      <programlisting>
	<?program "config/security/jeri-ssl-minimal.config"?>
      </programlisting>
	It can be run by
	<programlisting>
	  java ... security.FileClassifierServer config/security/jeri-ssl-minimal.config
	</programlisting>
	or from the Ant file by
	<programlisting>
	  ant run -DrunFile=security.FileClassifierServer \
                  -Dconfig=config/security/jeri-ssl-minimal.config
	</programlisting>
      </para>

      <para>
	The service used here is still the RMI service 
	discussed in earlier chapters
	<classname>rmi.FileClassifierImpl</classname>
	<programlisting>
	  <?program "src/rmi/FileClassifierImpl.java"?>
	</programlisting>
	The service needs no changes to satisfy integrity - integrity
	is supplied by the SSL protocol.
      </para>

      <para>
	This service/server/configuration combination
	works with no exceptions thrown.
      </para>

      <para>
	This section was the "teaser": <emphasis>Look how easy it
	is to implement advanced security! Just add a constraint to the
	client and use an appropriate protocol for the service!</emphasis> 
	The following
	sections look at other aspects of security, and it does get
	a little more complex :-)
      </para>
    </sect2>
  </sect1>

  <sect1>
    <title id="Proxy verification">
      Proxy verification
    </title>
    <para>
      When a client finds a service, it goes through several stages: it
      prepares a service description and asks lookup services if they
      have any services matching that description. If they do, then the
      lookup service downloads a <classname>MarshalledObject</classname>
      for the service. This basically contains two things: the instance
      data for the service and a URL for the class files of the service.
    </para>

    <para>
      The service places class or jar files on the HTTP server. The client
      gets these files from the HTTP server. In Jini 1.2 both the service
      and client trust the HTTP server. For a secure system this trust should
      be demonstrable. The client needs to able to verify that the class
      files it got from the server are the class files that the service
      put there. This can be done in many ways, but the Jini team has come
      up with a neat way, called HTTPMD.
    </para>

    <sect2>
      <title id="Proxy verification.HTTPMD">HTTPMD</title>

      <para>
	There is no integrity or other security aspects in getting files
	from an HTTP server. The standard way of ensuring security means using a
	protocol such as HTTPS, but this is quite heavyweight, and not
	really suited to the purpose of proxy verification: while we can
	get a verified document from an HTTPS server, we still don't know
	whether or not to trust that server! 
      </para>

      <para>
	What we want to get from an HTTP server is a jar file for the
	classes that are provided by the service. It is only the service
	that knows if they are correct or not. 
	That is, it doesn't really matter whether or not the HTTP server
	can be trusted, but whether we can get information from the
	service to verify the jar file.
	A common way of checking
	that two files are identical is to use a <emphasis>hash</emphasis>
	of each file. A hash is a number (often 128 bits) that is calculated
	from the file contents. Hash algorithms are designed with two
	properties
	<orderedlist>
	  <listitem>
	    <para>
	      If two files have the same hash, then it is
	      "almost certain" that they are the same file 
	      (that is, have the same contents)
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      Given a hash value, it is "nearly impossible" to 
	      create a file with that hash value
	    </para>
	  </listitem>
	</orderedlist>
	So a service can put a jar file on an HTTP server and a client
	can download it. If the hash calculated by the client
	is the same as the service thinks it should be, then the client
	can be "almost certain" that it has the correct file.
      </para>

      <para>
	There are many hash algorithms. Popular ones are
	<orderedlist>
	  <listitem>
	    <para>
	      <emphasis>MD5</emphasis>
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      <emphasis>SHA</emphasis>
	    </para>
	  </listitem>
	</orderedlist>
      </para>

      <para>
	When you get a marshalled object from a lookup service, it contains
	the URL for the class files. This URL was inserted by the service.
	If the URL contained the hash for the class files, then it would be
	possible for a client to verify that it had obtained the correct files.
	(Of course, this assumes that the lookup service and HTTP server are
	not in collusion to deliver false hash values - see later for trusting
	the  lookup service.)
      </para>

      <para>
	Jini defines an HTTPMD (HTTP + Message Digest) URL that adds the hash
	value as component of the URL. The scheme is changed from "http"
	to "httpmd" and the hash is added as an extra component, along
	with a statement of the hash algorithm. For example, a URL of
	<programlisting>
http:jan.newmarch.name/classes/FileClassifierServer-dl.jar
	</programlisting>
	would change to 
	<programlisting>
httpmd:jan.newmarch.name/classes/FileClassifierServer-dl.jar;\
md5=7ef2019216d0e9069308cec29b779bc0
	</programlisting>
	using the MD5 hash algorithm.
      </para>
      
      <para>
	The service can specify such a URL in its
	<classname>java.rmi.server.codebase</classname> property.
	There is a small hiccup: this is a non-standard protocol
	that is not recognised by the standard Java virtual machine.
	There is however a standard mechanism for adding new handlers
	to a JVM. The process for doing this is described by Brian Maso
	in the article 
	<ulink url="http://java.sun.com/developer/onlineTraining/protocolhandlers/">
	A New Era for Java Protocol Handlers</ulink> at
	<filename>http://java.sun.com/developer/onlineTraining/protocolhandlers</filename>. 
	The HTTPMD handler is 
	part of the Jini package. It only needs to be installed into the JVM.
	This is done by defining an appropriate property
	<programlisting>
java -Djava.protocol.handler.pkgs=net.jini.url ...
	</programlisting>
	which looks for the class <classname>net.jini.url.httpmd.Handler</classname>
	whenever it needs to handle an HTTPMD document.
      </para>

      <para>
http://java.sun.com/developer/onlineTraining/protocolhandlers/
      </para>
    </sect2>

    <sect2>
      <title id="Proxy verification.Calculating HTTPMD URLs">
	Calculating HTTPMD URLs</title>

      <para>
	There are often tools available in any Operating System for calculation
	of message digests. For example, most Linux distributions include
	the <command>md5sum</command> command for MD5 digests and
	<command>shasum</command> for SHA digests. Use of such tools is
	O/S specific, and must be run by hand or automatically from some
	sort of script.
      </para>

      <para>
	There is an message digest class in <classname>java.security</classname>
	package. This can be used in a platform-independent way. However, it
	won't directly handle an HTTPMD URL. Jini 2.0 includes the
	<classname>HttpmdUtil</classname> class which will calculate 
	digests from a URL. It has two methods
	<programlisting>
class HttpmdUtil {
    static String computeDigest(URL url, 
                                String algorithm);
    static String computeDigestCodebase(String sourceDirectory, 
                                        String codebase);
}
	</programlisting>
      </para>

      <para>
	The first method useful if you already have a jar file installed in
	an HTTP server and wish to calculate its digest. So for example
	you could call
	<programlisting>
HttpmdUtil.computeDigest("http://localhost/classes/ClassFiles.jar", "MD5");
	</programlisting>
	The resulting digest could be appended to a new URL of type HTTPMD.
	Note that for this mechanism to be valid, the program using this 
	must trust the HTTP server!
      </para>

      <para>
	A simple program to calculate and print the hash value of a URL
	using this is
	<classname>PrintDigest</classname>
	<programlisting>
	  <?program "PrintDigest.java"?>
	</programlisting>
	We use this program in our Ant files which assume
	a local trusted HTTP server.
      </para>

      <para>
	The second method is useful before deployment of the jar file to an HTTP
	server. It returns a new URL for a given URL with a new digest value.
	For example, the call
	<programlisting>
HttpmdUtil.computeDigestCodebase("dist", 
               "httpmd://localhost/classes/ClassFiles.jar;md5=0");
	</programlisting>
	This strips the scheme, host and digest value from the URL and appends
	the directories and jar filename to the given directory. In this case
	it calculates the digest for the local file
	<filename>dist/classes/ClassFiles.jar</filename>. 
	It then rebuilds the URL as e.g.
	<filename>httpmd://localhost/classes/ClassFiles.jar;md5=...</filename>.
	This only involves local trust. However, it does rely on a consistent
	directory convention between local files and HTTP URLs - and I 
	didn't obey that convention :-(
      </para>

      <para>
	A third technique is given in the Jini "hello" example
	<filename>source/vob/jive/src/com/sun/jini/example/hello</filename>.
	This is a sophisticated method and not for the faint-hearted.
	It installs a new <classname>RMIClassLoaderSpi</classname>
	called <classname>MdClassAnnotationProvider</classname>.
	The <classname>getClassAnnotation()</classname> method of this
	class uses the second method of the <classname>HttpmdUtil</classname>
	to generate an HTTPMD URL on demand from an HTTP URL.
      </para>


    </sect2>

    <sect2>
      <title id="Proxy verification.Reggie">Reggie</title>

      <para>
	The standard setup for <command>reggie</command> does not
	recognise the HTTPMD protocol. I'm not sure why it is looking
	inside the marshalled objects for this, but it will cause an
	exception to be thrown in services if it does not understand it.
	This is an easy fix: add the property
	<command>-Djava.protocol.handler.pkgs=net.jini.url</command>
	to the command that starts <command>reggie</command>.
      </para>
    </sect2>

    <sect2>
      <title id="Proxy verification.Proxy verifier">Proxy verifier</title>

      <para>
	When the client gets a proxy for a service, 
	it gets a marshalled object with
	instance data and a URL for the class files. Assuming that the
	URL has not been tampered with, it can download the class files
	from an HTTP server. If it is an HTTPMD URL then it can verify
	that the class files are correct - as long as it trusts the
	proxy. This is a tricky problem: how to verify that the proxy
	is correct when you have a - possibly - false and misleading
	proxy? Moreover, this possibly antagonistic proxy is the only
	way you have of talking to the service.
      </para>

      <para>
	The only entity that can really verify that the proxy is correct
	is the original service. So can we send the proxy to the service
	and get it to tell us? Well, no: if we ask the untrusted proxy 
	to send itself for verification to the service, then it might
	just lie and claim that, yes, it has done so. What we have to
	do is to get an object from the service that can perform verification
	locally - under the client's eyes, as it were. 
      </para>

      <para>
	The mechanism adopted by Jini to solve this is to use several levels
	of proxy: the (untrusted) service proxy is asked to deliver a
	"bootstrap" proxy that can deliver a verifier. This verifier
	is the object that will deliver the verdict on whether the proxy
	can be trusted, so it must be trustworthy itself. Jini ensures
	this by insisting that the class files for this verifier are local
	to the client and so are trusted just like any other local code.
      </para>

      <para>
	The client needs to have a list of local verifiers that it trusts
	just because they are local. A standard set is given in the Jini
	library <filename>jsk-platform.jar</filename> file. This jar file
	contains the following verifiers:
	<orderedlist>
	  <listitem>
	    <para>
	      <classname>ConstraintTrustVerifier</classname>
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      <classname>BasicJeriTrustVerifier</classname>
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      <classname>SslTrustVerifier</classname>
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      <classname>KerberosTrustVerifier</classname>
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      <classname>ProxyTrustVerifier</classname>
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      <classname>ConstrainableLookupLocatorTrustVerifier</classname>
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      <classname>DiscoveryConstraintTrustVerifier</classname>
	    </para>
	  </listitem>
	</orderedlist>
      </para>

    </sect2>

    <sect2>
      <title id="Proxy verification.Client with proxy verification">
	Client with proxy verification</title>

      <para>
	To require trust from a service, the client must do three things
	<orderedlist>
	  <listitem>
	    <para>
	      Include <filename>jsk-platform.jar</filename> in its classpath
	      to get a set of proxy verifiers
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      Install an HTTPMD handler by the runtime property
	      <command>java.protocol.handler.pkgs=net.jini.url</command>
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      Specify trust checking by setting the first argument of 
	      <classname>BasicProxyPreparer</classname> to 
	      <classname>true</classname>. A configuration file to require
	      trust checking (and nothing else)
	      is <filename>config/security/preparer-trust.config</filename>
	      <programlisting>
		<?program "config/security/preparer-trust.config"?>
	      </programlisting>
	    </para>

	    <para>
	      A command line to run this client is
	      <programlisting>
java ... client.TestFileClassifierProxyPreparer \
         config/security/preparer-trust.config
	      </programlisting>
	      or using Ant
	      <programlisting>
ant run -DrunFile=client.TestFileClassifierProxyPreparer \
        -Dconfig=config/security/preparer-trust.config
	      </programlisting>
	    </para>
	  </listitem>
	</orderedlist>
      </para>
    </sect2>

    <sect2>
      <title id="Proxy verification.SSL trusted server">SSL trusted server</title>

      <para>
	SSL will allow trust checking to be performed. 
	<orderedlist>
	  <listitem>
	    <para>
	      The service does not
	      need to be adapted, and can still be the 
	      <classname>rmi.FileClassifierImpl</classname> given above
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      The server needs to install an HTTPMD handler 
	      by the runtime property
	      <command>java.protocol.handler.pkgs=net.jini.url</command>
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      The <filename>security.FileClassiferServer-dl.jar</filename>
	      jar file needs to be created with contents 
	      <code>common/MIMEType.class,
                     common/FileClassifier.class,
		     rmi/RemoteFileClassifier.class,
		     rmi/FileClassifierImpl.class</code>
	      and copied to an HTTP server
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      A hash needs to be performed on this 
	      <filename>security.FileClassiferServer-dl.jar</filename>
	      jar file.
	      In this tutorial we use the <classname>HttpmdUtil</classname>
	      to caculate this as explained earlier (we trust the local 
	      HTTP server)
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      The codebase should be an <filename>HTTPMD</filename> URL,
	      including the hash value from the last step
	    </para>
	  </listitem>
	</orderedlist>
      </para>

      <para>
	The service does not need to specify anything other than that it
	uses SSL for transport (the server supplies the HTTPMD codebase).
	The server can use the 
	<filename>config/security/jeri-ssl-minimal.config</filename>
	configuration
	<programlisting>
	  <?program "config/security/jeri-ssl-minimal.config"?>
	</programlisting>
      </para>
      
      <para>
	A command line to run this server is
	<programlisting>
java ... -Djava.rmi.server.codebase=httpmd://... \
         security.FileClassiferServer \
         config/security/jeri-ssl-minimal.config
	</programlisting>
	or from Ant
	      <programlisting>
ant run -DrunFile=security.FileClassiferServer \
        -Dconfig=config/security/jeri-ssl-minimal.config \
        -Ddo.trust=yes
	      </programlisting>
      </para>
      
      <para>
	This server/configuration 
	will handle a client that requires trust verification.
	If the trust logger file for the client is examined it will contain
	lines such as
	<programlisting>
FINE: trust verifiers [net.jini.constraint.ConstraintTrustVerifier...]
Aug 16, 2004 9:59:35 PM net.jini.security.Security$Context isTrustedObject
FINE: net.jini.jeri.ssl.SslTrustVerifier@df1832 trusts 
      SslEndpoint[127.0.0.1:39693]
Aug 16, 2004 9:59:35 PM net.jini.security.Security$Context isTrustedObject
FINE: net.jini.jeri.BasicJeriTrustVerifier@1a116c9 trusts 
      BasicObjectEndpoint[...,SslEndpoint[...]]
Aug 16, 2004 9:59:35 PM net.jini.security.Security$Context isTrustedObject
FINE: net.jini.constraint.ConstraintTrustVerifier@1d1e730 trusts 
      InvocationConstraints[reqs: {}, prefs: {}]
Aug 16, 2004 9:59:35 PM net.jini.security.Security$Context isTrustedObject
FINE: net.jini.constraint.ConstraintTrustVerifier@1d1e730 trusts 
      BasicMethodConstraints{default => null}
Aug 16, 2004 9:59:35 PM net.jini.security.Security$Context isTrustedObject
FINE: net.jini.jeri.BasicJeriTrustVerifier@1a116c9 trusts 
      Proxy[RemoteFileClassifier,
            BasicInvocationHandler[BasicObjectEndpoint[...]]
	</programlisting>
	This shows that the <classname>SslTrustVerifier</classname>
	trusts the <classname>SslEndpoint</classname>, and that because
	of that the <classname>BasicJeriTrustVerifier</classname>
	trusts the <classname>BasicObjectEndpoint</classname> which 
	contains the <classname>SslEndpoint</classname>. Trust is also
	applied to the constraints after which the proxy is declared
	to be trusted.
      </para>

      <para>
	It is important to note the limits of what has been achieved in this
	section: we have downloaded a proxy that we can trust - but whose
	proxy is it? We have been assured that the code we have got has
	not been tampered with by anyone else, but we could still be
	getting code from "Antagonistic Alice". All that we know at this
	point is that we have the code that Alice intended to send to us
	and that Mallory in the middle hasn't tampered with it!
      </para>
    </sect2>

    <sect2>
      <title id="Proxy verification.Errors">Errors</title>
      <para>
	<orderedlist>
	  <listitem>
	    <para>
	      If you forget to include <filename>jsk-platform.jar</filename>
	      in the client's classpath, then it won't be able to find the
	      standard verifiers and won't be able to verify any proxies.
	      The client will throw a <classname>SecurityException</classname>
	      <programlisting>
java.lang.SecurityException: object is not trusted: 
     Proxy[RemoteFileClassifier,BasicInvocationHandler[
           BasicObjectEndpoint[1c4c3ec0-f91e-46a6-827b-626575702a07,
                               SslEndpoint[127.0.0.1:56641]]]]
     at net.jini.security.Security.verifyObjectTrust(Security.java:268)
     at net.jini.security.BasicProxyPreparer.verify(BasicProxyPreparer.java:309)
	      </programlisting>
	      The trust logger will also show
	      <programlisting>
FINE: trust verifiers []
Aug 16, 2004 5:54:27 PM net.jini.security.Security$Context isTrustedObject
FAILED: no verifier trusts Proxy[RemoteFileClassifier,BasicInvocationHandler[Bas
icObjectEndpoint[1c4c3ec0-f91e-46a6-827b-626575702a07,SslEndpoint[127.0.0.1:5664
1]]]]
	      </programlisting>
	      with the failure caused by an empty verifiers list
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      If the server uses HTTP URLs instead of HTTPMD URLs, then the
	      client is unable to perform an integrity check. This will
	      result in the client throwing a 
	      <classname>SecurityException</classname>
	      <programlisting>
java.lang.SecurityException: URL does not provide integrity: 
     http://192.168.1.13/classes/security.FileClassifierServer-dl.jar
     at net.jini.security.Security.verifyCodebaseIntegrity(Security.java:343)
	      </programlisting>
	      The integrity logger will also show
	      <programlisting>
FINE: integrity verifiers [net.jini.url.httpmd.HttpmdIntegrityVerifier@1b5998f,
      net.jini.url.https.HttpsIntegrityVerifier@17494c8, 
      net.jini.url.file.FileIntegrityVerifier@d3db51]
Aug 16, 2004 6:01:27 PM net.jini.security.Security verifyCodebaseIntegrity
FAILED: no verifier verifies 
       http://192.168.1.13/classes/security.FileClassifierServer-dl.jar
	      </programlisting>
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      It is necessary to install the HTTPMD handler in the server,
	      the client and in <command>reggie</command>. If you omit
	      to include it in the server, then the discovery logger reports
	      <programlisting>
INFO: exception occurred during unicast discovery
 java.net.MalformedURLException: unknown protocol: httpmd
     at java.net.URL.&gt;init&lt;(URL.java:544)
	      </programlisting>
	      If you leave this handler out of the client it throws an
	      exception during service discovery
	      <programlisting>
java.rmi.UnmarshalException: error unmarshalling return; nested exception is:
     java.net.MalformedURLException: unknown protocol: httpmd
     at com.sun.jini.reggie.RegistrarProxy.lookup(RegistrarProxy.java:130)
	      </programlisting>
	      If you omit to install the HTTPMD handler in 
	      <command>reggie</command>, then when the 
	      <emphasis>server</emphasis> runs, it gets an error thrown
	      from <command>reggie</command> which shows in a message from
	      the <classname>JoinManager</classname> logger:
	      <programlisting>
INFO: JoinManager - failure
java.rmi.ServerException: RemoteException in server thread; nested exception is:
     java.rmi.UnmarshalException: unmarshalling method/arguments; 
          nested exception is:
     java.net.MalformedURLException: unknown protocol: httpmd
     at net.jini.jeri.BasicInvocationDispatcher.dispatch(...)
	      </programlisting>
	    </para>
	  </listitem>
	</orderedlist>
      </para>
    </sect2>
    
  </sect1>
  
  <sect1>
    <title id="Confidentiality">
      Confidentiality
    </title>
    <para>
      A conversation is confidential if no-one can overhear it, or even if
      they can hear it then they cannot understand it. Typically applications
      use encryption to ensure that messages cannot be read by others.
    </para>

    <sect2>
      <title id="Confidentiality.Client">Client</title>

      <para>
	Either a client or a server can specify confidentiality.
	A client specifies this by making adding a
	<classname>Confidentiality.YES</classname> constraint to the
	proxy preparer. For example, the 
	<filename>config/security/preparer-conf.config</filename> configuration
	file can contain
	<programlisting>
	  <?program "config/security/preparer-conf.config"?>
	</programlisting>
      </para>

      <para>
	To run the client using this configuration, run
	<programlisting>
	java ... client.TestFileClassifierProxyPreparer \
                 config/security/preparer-conf.config
	</programlisting>
	or
	<programlisting>
	ant run -DrunFile=client.TestFileClassifierProxyPreparer \ 
                -Dconfig=config/security/preparer-conf.config
	</programlisting>
	Note that only the configuration file has changed.
      </para>
    </sect2>

    <sect2>
      <title id="Confidentiality.SSL confidential server">
	SSL confidential server</title>

      <para>
	SSL supports confidentiality. Indeed, that is the major purpose
	behind its design. So all that is needed is for a server to
	specify that it is using SSL, which can be done using the earlier
	<filename>config/security/jeri-ssl-minimal.config</filename>
	configuration file
	<programlisting>
	  <?program "config/security/jeri-ssl-minimal.config"?>
	</programlisting>
      </para>

      <para>
	A command line to run this server is
	<programlisting>
java ... security.FileClassiferServer \
         config/security/jeri-ssl-minimal.config
	</programlisting>
	or from Ant
	<programlisting>
ant run -DrunFile=security.FileClassiferServer \
        -Dconfig=config/security/jeri-ssl-minimal.config
	      </programlisting>
      </para>  
    </sect2>

  </sect1>
  
  <sect1>
    <title id="Mix 'n Match">
      Mix 'n Match
    </title>
    <para>
      So far we have tried the following combinations
      <orderedlist>
	<listitem>
	  <para> 
	    <filename>preparer-minimal.config</filename>
	    and <filename>jeri-tcp.config"</filename> -
	    no security on either side, and this works the same
	    way as examples in earlier chapters without security
	  </para>
	</listitem>
	<listitem>
	  <para>
	    <filename>preparer-integrity.config</filename> 
	    and <filename>>jeri-tcp.config</filename> -
	    this failed due to lack of support by TCP for integrity
	    checking
	  </para>
	</listitem>
	<listitem>
	  <para>
	    <filename>preparer-integrity.config</filename> 
	    and <filename>jeri-ssl-minimal.config</filename> -
	    this succeeds since SSL supports integrity checking
	  </para>
	</listitem>
	<listitem>
	  <para>
	    <filename>preparer-trust.config</filename> 
	    and <filename>>jeri-ssl-minimal.config</filename>
	    with HTTPMD URLs - this works because SSL supports trust of
	    messages and the HTTPMD URLs allow the client to trust the
	    HTTP server
	  </para>
	</listitem>
	<listitem>
	  <para>
	    <filename>preparer-conf.config</filename> 
	    and <filename>jeri-ssl-minimal.config</filename> -
	    this works because SSL supports confidentiality
	    through encryption
	  </para>
	</listitem>
      </orderedlist>
    </para>

    <para>
      We can try variations on these: for example, a client that requires
      trust and integrity with a server that requires encryption. 
      This is just an additive process: add in the extra constraints
      to the appropriate configuration and ensure that the client or
      server has the correct runtime to handle the constraints.
      The client
      configuration in this case is 
      <filename>config/security/preparer-trust-integrity.config</filename> 
      <programlisting>
	<?program "config/security/preparer-trust-integrity.config"?>
      </programlisting>
      and the server configuration is 
      <filename>config/security/jeri-ssl-conf.config</filename>
      configuration file
      <programlisting>
	<?program "config/security/jeri-ssl-conf.config"?>
      </programlisting>
    </para>

    <para>
      These can be run by
      <programlisting>
java ... client.TestFileClassifierProxyPreparer \
                 config/security/preparer-trust-integrity.config

java ... -Djava.rmi.server.codebase=httpmd://... \
         security.FileClassiferServer \
         config/security/jeri-ssl-conf.config
      </programlisting>
      or from Ant
      <programlisting>
ant run -DrunFile=client.TestFileClassifierProxyPreparer \ 
         -Dconfig=config/security/preparer-trust-integrity.config

ant run -DrunFile=security.FileClassiferServer \
        -Dconfig=config/security/jeri-ssl-.config \
        -Ddo.trust=yes
      </programlisting>
    </para>  
 
    <para>
      This combination works satisfactorily. The client logs are indicative
      of what has happened. The trust logger shows (with much text elided)
      <programlisting>
FINE: HttpmdIntegrityVerifier verifies httpmd://...
FINE: trust verifiers [...]
FINE: SslTrustVerifier trusts SslEndpoint[...]
FINE: BasicJeriTrustVerifier trusts BasicObjectEndpoint[...]
FINE: ConstraintTrustVerifier trusts Confidentiality.YES
FINE: ConstraintTrustVerifier trusts 
           InvocationConstraints[reqs: {Confidentiality.YES}, prefs: {}]
FINE: ConstraintTrustVerifier trusts 
           BasicMethodConstraints{default => 
               InvocationConstraints[reqs: {Confidentiality.YES}, prefs: {}]}
FINE: BasicJeriTrustVerifier trusts Proxy[...]
      </programlisting>
      This shows that the <classname>HttpmdIntegrityVerifier</classname>
      trusts the HTTPMD URL; The <classname>SslTrustVerifier</classname>
      trusts the <classname>SslEndpoint</classname>; the 
      <classname>ConstraintTrustVerifier</classname> trusts
      <classname>Confidentiality</classname>; and hence the
      <classname>ConstraintTrustVerifier</classname> trusts the
      <classname>BasicMethodConstraints</classname>; and so finally,
      the <classname>BasicJeriTrustVerifier</classname> trusts the proxy.
    </para>

    <para>
      Similarly, the integrity log shows
      <programlisting>
FINE: integrity verifiers [...]
FINE: HttpmdIntegrityVerifier verifies httpmd://...
      </programlisting>
      showing that the <classname>HttpmdIntegrityVerifier</classname>
      verifies the HTTPMD URL.
    </para>

    <para>
      By way of contrast, if the client is run with one constraint and the
      server is run with its opposite, then the constraints cannot be
      satisfied. For example, if the client has set
      <classname>Confidentiality.NO</classname> and the server has
      set <classname>Confidentiality.YES</classname>, then the client
      will throw an exception
      <programlisting>
java.rmi.ConnectIOException: I/O exception connecting to 
     BasicObjectEndpoint[...,SslEndpoint[...]]; nested exception is:
     net.jini.io.UnsupportedConstraintException: Constraints not supported: 
         InvocationConstraints[reqs: {Confidentiality.NO, 
                                      Confidentiality.YES}, prefs: {}]
      </programlisting>
    </para>
  </sect1>

  <sect1>
    <title id="Identity Management">Identity Management</title>
 
    <para>
      If you want to give different individuals different access rights,
      then you need to be able to verify their identity. This means that
      they must have some way of expressing what their identity is in a
      form that you will recognise. People (and things) may have a number
      of identities: the father of a particular person, the staff id number,
      the driving license number, their name, and so on. Essentially, different
      labels for the one entity. The terminology adopted is that the entity
      is called a <emphasis>subject</emphasis>, and in Java
      this is represented by the <classname>Subject</classname> class in
      the <classname>javax.security.auth</classname> package. The different
      identities for a subject are called <emphasis>principals</emphasis>, and
      they too have a Java class, the <classname>Principal</classname> class.
    </para>

    <para>
      A subject authenticates itself to a service using a principal and
      information to verify itself as that principal. For example, you 
      log into a computer using your username as principal and password
      for verification. Other mechanisms could be used. For example, you
      verify yourself to the police officer who has just pulled you over
      by the photo on your drivers license.
    </para>

    <para>
      A credential (such as a driver's license) is used to authenticate
      a subject to later services. In the computer world, these include 
      be X.509 certificates and Kerberos tickets.
    </para>

    <sect2>
      <title id="Identity Management.JAAS">JAAS</title>

      <para>
	A white paper describing JAAS is at 
	<ulink url="http://java.sun.com/security/jaas/doc/acsac.html">
	  USER AUTHENTICATION AND AUTHORIZATION IN THE JAVA(TM) PLATFORM
	</ulink>
	(http://java.sun.com/security/jaas/doc/acsac.html), with other 
	information such as "JavaTM Authentication and Authorization 
	Service (JAAS) Reference Guide" which should be in the Java
	distribution directory
	<filename>docs/guide/security/jaas/JAASRefGuide.html</filename>
	and "JAAS Authentication" at
	http://java.sun.com/j2se/1.4.2/docs/guide/security/jgss/tutorials/AcnOnly.html
      </para>
      
      <para>
	JAAS (Java Authentication and Authorization Service) is a framework
	for verifying common identities. These include
	<orderedlist>
	  <listitem>
	    <para>
	      JNDI
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      KeyStore
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      Kerberos
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      Windows NT
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      Unix
	    </para>
	  </listitem>
	</orderedlist>
	Information on these can be found at
	<ulink url="http://java.sun.com/j2se/1.4.2/docs/guide/security/jgss/tutorials/LoginConfigFile.html">http://java.sun.com/j2se/1.4.2/docs/guide/security/jgss/tutorials/LoginConfigFile.html</ulink>.
      </para>

      <para>
	JAAS augments the standard Java security model by adding support
	for principals. So security access is not just granted on the
	properties of the code itself (signed, etc) but also on the
	principals running the code.
      </para>

      <para>
	In order to use JAAS, you firstly need to create a 
	<classname>LoginContext</classname>. This picks up information
	from a configuration file to decide which principal it is
	authenticating as, and how to do it. The configuration file is
	similar in concept to the Jini  configuration files, but the
	syntax is different and the contents depend upon the mechanism
	used.
      </para>

      <para>
	Once you have a context, you attempt to <command>login()</command>.
	If successful, you are then a recognised entity, and are a
	subject with identity. As a subject, you may be able to do more
	things than if you have no identity. For example, in an SSL
	interaction you will be able to present certificates for this
	identity if required. Similarly with Kerberos: if challenged,
	you have an identity and a ticket credential to prove it.
      </para>

      <para>
	You then add the JAAS security checks to code by running it
	as the privileged subject. The code for this looks like
	<programlisting>
    LoginContext loginContext = 
	new LoginContext("...");
    if (loginContext == null) {
	// do some action without JAAS security
    } else {
	loginContext.login();
	Subject.doAsPrivileged(
	            loginContext.getSubject(),
		    new PrivilegedExceptionAction() {
		           public Object run() throws Exception {
				       // do the same action, but now
                                       // as a particular subject
				       return null;
			   }
	            },
	            null);
    }
	</programlisting>
      </para>

    </sect2>
      
    <sect2>
      <title id="Identity Management.Keystores">Keystores</title>

      <para>
	A keystore is a place to store certain types of credentials, such as
	X.509 certificates which are used by SSL. A keystore is manipulated
	by the <command>keytool</command> command. Conventionally,
	your own private (and associated public keys) are stored in a 
	<filename>keystore...</filename> file while public keys from others
	are stored in a <filename>truststore...</filename> file.
      </para>

      <para>
	We can create private keys for the client by
	<programlisting>
	  keytool -keystore keystore.client -genkey
	</programlisting>
	This will prompt for X.509 information, which assumes that you are
	an individual working for an organisation
	<programlisting>
Enter keystore password:  client
What is your first and last name?
  [Unknown]:  Client
What is the name of your organizational unit?
  [Unknown]:  IT
What is the name of your organization?
  [Unknown]:  Monash
What is the name of your City or Locality?
  [Unknown]:  Melbourne
What is the name of your State or Province?
  [Unknown]:  Vic
What is the two-letter country code for this unit?
  [Unknown]:  AU
Is CN=Client, OU=IT, O=Monash, L=Melbourne, ST=Vic, C=AU correct?
  [no]:  yes

Enter key password for &lt;mykey&gt;
        (RETURN if same as keystore password):
	</programlisting>
      </para>

      <para>
	Similarly, we can set up a keystore for the server
	<programlisting>
keytool -keystore keystore.server -genkey
Enter keystore password:  server
What is your first and last name?
  [Unknown]:  Server
What is the name of your organizational unit?
  [Unknown]:  IT
What is the name of your organization?
  [Unknown]:  Monash
What is the name of your City or Locality?
  [Unknown]:  Melbourne
What is the name of your State or Province?
  [Unknown]:  Vic
What is the two-letter country code for this unit?
  [Unknown]:  AU
Is CN=Server, OU=IT, O=Monash, L=Melbourne, ST=Vic, C=AU correct?
  [no]:  yes

Enter key password for &lt;mykey&gt;
        (RETURN if same as keystore password):
	</programlisting>
      </para>

      <para>
	We can export the server's public key from the its keystore
	and import it into the
	client's truststore under the alias "Server" by
	<programlisting>
<emphasis>keytool -keystore keystore.server -export -file server.cert</emphasis>
Enter keystore password:  server
Certificate stored in file &lt;server.cert&gt;

keytool -keystore truststore.client -import -file server.cert -alias Server
Enter keystore password:  client
Owner: CN=Server, OU=IT, O=Monash, L=Melbourne, ST=Vic, C=AU
Issuer: CN=Server, OU=IT, O=Monash, L=Melbourne, ST=Vic, C=AU
Serial number: 4123f906
Valid from: Thu Aug 19 10:49:10 EST 2004 until: Wed Nov 17 11:49:10 EST 2004
Certificate fingerprints:
         MD5:  6E:24:70:EB:E2:2C:A0:72:C5:B9:9B:95:72:39:87:B1
         SHA1: 2B:AB:0D:80:4F:DF:B8:66:3B:E7:49:66:3D:53:EC:C5:B8:3A:91:5E
Trust this certificate? [no]:  yes
Certificate was added to keystore
	</programlisting>
	and similarly we can export the client's public key and import it
	into the server's truststore under the alias "Client"
	<programlisting>
keytool -keystore keystore.client -export -file client.cert
Enter keystore password:  client
Certificate stored in file &lt;client.cert&gt;

keytool -keystore truststore.server -import -file client.cert -alias Client
Enter keystore password:  server
Owner: CN=Client, OU=IT, O=Monash, L=Melbourne, ST=Vic, C=AU
Issuer: CN=Client, OU=IT, O=Monash, L=Melbourne, ST=Vic, C=AU
Serial number: 4123f88d
Valid from: Thu Aug 19 10:47:09 EST 2004 until: Wed Nov 17 11:47:09 EST 2004
Certificate fingerprints:
         MD5:  EA:4A:67:E3:A6:58:2D:F4:52:00:FE:CF:2C:AC:7A:6A
         SHA1: 8C:68:E3:9C:E8:08:4A:33:F5:12:E4:9D:73:D6:EF:A4:A5:82:B2:79
Trust this certificate? [no]:  yes
Certificate was added to keystore
	</programlisting>
      </para>
    </sect2>

    <sect2>
      <title id="Identity Management.Authenticating Server">Authenticating Server</title>

      <para>
	A server that is prepared to authenticate itself must be able to
	offer suitable credentials when challenged. For SSL, this would
	be an X.509 certificate, for Kerberos it would be a Kerberos
	ticket, etc. If JAAS is used to provide these credentials then
	it must be able to "login" to gets it authentication information.
      </para>

      <para>
	The server code needs to be modified slightly to get a login
	context and then login using a principal to get a subject. 
	If this succeeds then it can run the rest of the code as 
	that subject. The changes to the file classifier server are given
	as static code to execute before creating the server. The 
	<filename>security/FileClassifierServerAuth</filename> is
	<programlisting>
	  <?program "src/security/FileClassifierServerAuth.java"?>
	</programlisting>
	This login context uses a hard-coded string to specify the name
	"security.FileClassifierServerAuth" used by JAAS to find 
	information from the JAAS configuration file; this string
	could better be given in a Jini configuration file in a 
	production environment.
      </para>

      <para>
	A few other pieces need to be put in place in order that this
	server can authenticate itself
	<orderedlist>
	  <listitem>
	    <para>
	      The server needs to be run with an additional runtime property.
	      The property 
	      <command>java.security.auth.login.config</command>
	      needs to be set to the login configuration file, as in
	      <programlisting>
	java ... -Djava.security.auth.login.config=ssl-server.login ...
	      </programlisting>
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      The JAAS login file specifies how JAAS is to get its credentials.
	      For example, for SSL it will need a certificate which it can 
	      get from a keystore. So for an SSL authenticating server the 
	      <filename>ssl-server.login</filename> could contain
	      <programlisting>
		<?program "resources/security/ssl-server.login"?>
	      </programlisting>
	      The configuration name "security.FileClassifierServerAuth"
	      is the same as the parameter to the
	      <classname>LoginContext</classname> constructor.
	      The file also specifies the alias to be used in looking up entries
	      (the default is "mykey" if not specified during creation of
	      the keystore), the keystore and a file that contains the
	      password to access this keystore
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      The password file <filename>password.server</filename> 
	      just contains the password we set earlier: "server".
	    </para>
	  </listitem>
	</orderedlist>
      </para>

      <para>
	This server can be run from the command line
	<programlisting>
java ... security.FileClassiferServerAuth \
         config/security/jeri-ssl-minimal.config
	</programlisting>
	or from Ant
	<programlisting>
ant run -DrunFile=security.FileClassiferServerAuth \
        -Dconfig=config/security/jeri-ssl-minimal.config
	</programlisting>
	The server does not need to set any constraints (since it just
	authenticates itself), so the minimal server configuration file
	can be used.
      </para>
    </sect2>

    <sect2>
      <title id="Identity Management.Client requiring authentication">
	Client requiring authentication</title>

      <para>
	The client can require that the server have a proof of identity,
	or that it identifies itself as a particular subject. This is just
	like asking "Do you have a card that proves you are over eighteen?"
	versus "Do you have a card that proves you are Joe Bloggs?".
      </para>

      <para>
	The first case ("do you have a credential?") can be specified in the
	client configuration file by just adding the 
	<classname>ServerAuthentication.YES</classname> constraint
	<programlisting>
	  <?program "config/security/preparer-auth.config"?>
	</programlisting>
	The client is the previous 
	<filename>TestFileClassiferProxyPreparer</filename>
	used throughout this chapter. However, although it doesn't look
	up any certicates it does seem to need a trust store to be
	specified - a bug? 
	This can be done by adding the property to the runtime
	<programlisting>
	  -Djavax.net.ssl.trustStore=truststore.client
	</programlisting>
      </para>

      <para>
	The second case requires specifying which principal(s) 
	the server is required to authenticate as. The most common
	case is when the client requires a single principal as identity.
	The <classname>ServerMinPrincipal</classname> is used for this,
	with constructors for a single principal or for a set of principals.
	In order to get an SSL principal, we need to do something like
	pull it out of a keystore. This involves the steps of:
	get the users from a keystore and get a single user from this list.
	The <classname>KeyStores</classname> class in Jini 
	allows these steps to be done
	from within a configuration file.
       </para>

      <para>
	The client is still unaltered from 
	<filename>TestFileClassifierProxyPreparer</filename>. The configuration
	file is now <filename>preparer-auth-server.config</filename>
	<programlisting>
	  <?program "config/security/preparer-auth-server.config"?>
	</programlisting>
      </para>
    </sect2>

    <sect2>
      <title id="Identity Management.Alternative constraints">Alternative constraints</title>

      <para>
	Classes such as <classname>ServerMinPrincipal</classname>
	can take a set of principals and AND them together:
	"are you Jan Newmarch AND are you over eighteen AND are you
	the father of Katy Newmarch?" A client may want to express a
	set of alternatives such as "do you have a driver's license
	OR do you have a social security card?" The 
	<classname>ConstraintAlternatives</classname> class can be
	used to handle these cases.
      </para>
    </sect2>

    <sect2 id="Identity Management.Authenticating Client">
      <title>Authenticating Client</title>

      <para>
	The same mechanism used for a server to authenticate itself is used
	by the client. That is, it sets up a login context, logs in and then
	runs code as a particular subject. The modified code is
	<filename>client.TestFileClassifierAuth</filename>
	<programlisting>
	  <?program "src/client/TestFileClassifierAuth.java"?>
	</programlisting>
      </para>

      <para>
	Like the server, other pieces need to be in place
	order that this client can authenticate itself
	<orderedlist>
	  <listitem>
	    <para>
	      The client needs to be run with an additional runtime property.
	      The property 
	      <command>java.security.auth.login.config</command>
	      needs to be set to the login configuration file, as in
	      <programlisting>
	java ... -Djava.security.auth.login.config=ssl-client.login ...
	      </programlisting>
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      The JAAS login file specifies how JAAS is to get its credentials.
	      For example, for SSL it will need a certificate which it can 
	      get from a keystore. So for an SSL authenticating server the 
	      <filename>ssl-client.login</filename> could contain
	      <programlisting>
		<?program "resources/security/ssl-client.login"?>
	      </programlisting>
	      The configuration name "security.TestFileClassifierAuth"
	      is the same as the parameter to the
	      <classname>LoginContext</classname> constructor.
	      The file also specifies the alias to be used in looking up entries
	      (the default is "mykey" if not specified during creation of
	      the keystore), the keystore and a file that contains the
	      password to access this keystore
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      The password file <filename>password.client</filename> 
	      just contains the password we set earlier: "client".
	    </para>
	  </listitem>
	</orderedlist>
      </para>
    </sect2>

    <sect2 id="Identity Management.Server requiring authentication">
      <title>Server Requiring Authentication</title>

      <para>
	If the server requires the client to authenticate as a particular
	user then it can be the 
	<classname>config.FileClassifierServer</classname>.
	It does not need to have the authentication code itself. It can 
	specify client authentication by the 
	<filename>jeri-ssl-auth-client.config</filename>
	configuration file
	<programlisting>
	  <?program "config/security/jeri-ssl-auth-client.config"?>
	</programlisting>
      </para>

      <para>
	In addition to this, the server needs to be run with a define
	<programlisting>
	  -Djavax.net.ssl.trustStore=resources/security/truststore.server
	</programlisting>
	to locate the truststore file it will use to verify certificates
	from the client.
      </para>
    </sect2>

 </sect1>

  <sect1 id="Authorisation">
    <title>Authorisation</title>

    <para>
      Standard Java uses policy files to determine what foreign code
      is allowed to do. This policy is installed when the application
      starts, so is a <emphasis>static</emphasis> policy mechanism.
      In Jini 2.0, when a service is discovered, it may wish to ask 
      for a policy to be applied at that time, ie 
      <emphasis>dynamically</emphasis>. Extensions to the basic security
      model in JDK 1.4 allow this to occur, by permitting
      dynamic policy setting on class loaders.
    </para>

    <para>
      In order to allow dynamic policy granting, the Java runtime must
      have the appropriate classes installed and trusted. This is the
      purpose of the <filename>jsk-policy.jar</filename> file from 
      the Jini library. As part of the installation process for Jini,
      you are recommended to install this into the 
      <filename>jre/lib/ext</filename> directory of your Java
      distribution. This allows the Java runtime to pick these up
      as trusted classes when it starts.
    </para>

    <para>
      The runtime needs to be told about these classes. This can be done
      by using the runtime define
      <programlisting>
	-Djava.security.properties=security.properties
      </programlisting>
      where <filename>security.properties</filename> is a file
      containing the single line saying which Jini class to use for
      dynamic policies
      <programlisting>
	<?program "resources/security/security.properties"?>
      </programlisting>
    </para>

    <para>
      For the client, an array of permissions specifies the permissions it will 
      grant to a proxy. This array is set in the 
      <classname>BasicProxyPreparer</classname>.
    </para>

    <para>
      The server can set a permission in the 
      <classname>BasicILFactory</classname>. This permission is
      used to perform server-side access control on incoming remote calls.
    </para>
  </sect1>

  <sect1 id="Conclusion">
    <title>Conclusion</title>

    <para>
      Ensuring security on the network is a complex task anyway, and the
      Jini possibilities of mobile code increases the security risks.
      This chapter has presented an "end-programmers" view of the new
      Jini 2.0 security. The architecture behind this is highly
      configurable, and what has been presented is one set of "plugins"
      to make it (relatively) easy for the programmer. However, if you
      want more control over any part of this process, then you can dig
      further into this architecture and "roll your own" for almost
      all parts of it.
    </para>
  </sect1>
  &copyright;
</chapter>
