View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership. The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License. You may obtain a copy of the License at
9    * 
10   *      http://www.apache.org/licenses/LICENSE-2.0
11   * 
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.river.reggie.proxy;
19  
20  import java.io.IOException;
21  import java.io.InvalidObjectException;
22  import java.io.ObjectInputStream;
23  import java.io.ObjectOutputStream;
24  import java.io.Serializable;
25  import java.rmi.RemoteException;
26  import net.jini.core.constraint.RemoteMethodControl;
27  import net.jini.core.lookup.ServiceID;
28  import net.jini.security.TrustVerifier;
29  import net.jini.security.proxytrust.TrustEquivalence;
30  
31  /**
32   * Trust verifier for smart proxies used by Reggie.
33   *
34   * @author Sun Microsystems, Inc.
35   *
36   */
37  public final class ProxyVerifier implements TrustVerifier, Serializable {
38  
39      private static final long serialVersionUID = 2L;
40  
41      /**
42       * Canonical service reference, used for comparison with inner server
43       * references extracted from smart proxies to verify.
44       *
45       * @serial
46       */
47      private final RemoteMethodControl server;
48      /**
49       * The registrar's service ID, used for comparison with registrar service
50       * IDs extracted from smart proxies to verify.
51       */
52      private transient ServiceID registrarID;
53  
54      /**
55       * Constructs proxy verifier which compares server references extracted
56       * from smart proxies with the given canonical server reference, which must
57       * implement both RemoteMethodControl and TrustEquivalence.  For proxies
58       * which contain a copy of the registrar's service ID, that copy is
59       * compared against the given service ID to ensure consistency.
60       */
61      public ProxyVerifier(Registrar server, ServiceID registrarID) {
62  	if (!(server instanceof RemoteMethodControl)) {
63  	    throw new UnsupportedOperationException(
64  		"server does not implement RemoteMethodControl");
65  	} else if (!(server instanceof TrustEquivalence)) {
66  	    throw new UnsupportedOperationException(
67  		"server does not implement TrustEquivalence");
68  	}
69  	this.server = (RemoteMethodControl) server;
70  	this.registrarID = registrarID;
71      }
72  
73      /**
74       * Returns true if the given object is a trusted proxy, or false otherwise.
75       * The given object is trusted if it is trust equivalent to the canonical
76       * server reference carried by this trust verifier, or if it is an instance
77       * of one of Reggie's constrainable smart proxy classes, and all component
78       * proxies it contains are trusted, and its inner server reference is trust
79       * equivalent to the canonical server reference, and its inner copy of the
80       * registrar's service ID (if it has one) is equal to the service ID
81       * carried by this verifier.
82       */
83      public boolean isTrustedObject(Object obj, TrustVerifier.Context ctx)
84  	throws RemoteException
85      {
86  	if (obj == null || ctx == null) {
87  	    throw new NullPointerException();
88  	}
89  	RemoteMethodControl inputServer;
90  	ServiceID inputRegistrarID;
91  	if (obj instanceof ConstrainableRegistrarProxy) {
92  	    RegistrarProxy proxy = (RegistrarProxy) obj;
93  	    inputServer = (RemoteMethodControl) proxy.server;
94  	    inputRegistrarID = proxy.registrarID;
95  	} else if (obj instanceof ConstrainableAdminProxy) {
96  	    AdminProxy proxy = (AdminProxy) obj;
97  	    inputServer = (RemoteMethodControl) proxy.server;
98  	    inputRegistrarID = proxy.registrarID;
99  	} else if (obj instanceof ConstrainableRegistration) {
100 	    Registration reg = (Registration) obj;
101 	    if (!isTrustedObject(reg.lease, ctx)) {
102 		return false;
103 	    }
104 	    inputServer = (RemoteMethodControl) reg.server;
105 	    inputRegistrarID = registrarID;
106 	} else if (obj instanceof ConstrainableEventLease ||
107 		   obj instanceof ConstrainableServiceLease)
108 	{
109 	    RegistrarLease lease = (RegistrarLease) obj;
110 	    inputServer = (RemoteMethodControl) lease.server;
111 	    inputRegistrarID = lease.registrarID;
112 	} else if (obj instanceof RemoteMethodControl) {
113 	    inputServer = (RemoteMethodControl) obj;
114 	    inputRegistrarID = registrarID;
115 	} else {
116 	    return false;
117 	}
118 
119 	TrustEquivalence trustEquiv = (TrustEquivalence)
120 	    server.setConstraints(inputServer.getConstraints());
121 	return trustEquiv.checkTrustEquivalence(inputServer) &&
122 	       registrarID.equals(inputRegistrarID);
123     }
124 
125     /**
126      * Writes the default serializable field value for this instance, followed
127      * by the registrar's service ID encoded as specified by the
128      * ServiceID.writeBytes method.
129      */
130     private void writeObject(ObjectOutputStream out) throws IOException {
131 	out.defaultWriteObject();
132 	registrarID.writeBytes(out);
133     }
134 
135     /**
136      * Reads the default serializable field value for this instance, followed
137      * by the registrar's service ID encoded as specified by the
138      * ServiceID.writeBytes method.  Verifies that the deserialized registrar
139      * reference implements both RemoteMethodControl and TrustEquivalence.
140      */
141     private void readObject(ObjectInputStream in)
142 	throws IOException, ClassNotFoundException
143     {
144 	in.defaultReadObject();
145 	registrarID = new ServiceID(in);
146 	if (!(server instanceof RemoteMethodControl)) {
147 	    throw new InvalidObjectException(
148 		"server does not implement RemoteMethodControl");
149 	} else if (!(server instanceof TrustEquivalence)) {
150 	    throw new InvalidObjectException(
151 		"server does not implement TrustEquivalence");
152 	}
153     }
154 }