KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > iiop > security > SecurityServiceImpl


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 package com.sun.enterprise.iiop.security;
25
26 import java.net.Socket JavaDoc;
27 import java.security.Principal JavaDoc;
28 import java.security.ProtectionDomain JavaDoc;
29 import java.security.CodeSource JavaDoc;
30 import java.security.Policy JavaDoc;
31 import java.security.AccessController JavaDoc;
32 import java.security.PrivilegedAction JavaDoc;
33 import java.security.cert.X509Certificate JavaDoc;
34 import javax.security.auth.Subject JavaDoc;
35 import com.sun.enterprise.log.Log;
36 import com.sun.enterprise.util.ORBManager;
37 import com.sun.enterprise.InvocationManager;
38 import com.sun.enterprise.ComponentInvocation;
39 import com.sun.enterprise.InvocationException;
40 import com.sun.enterprise.Switch;
41 import com.sun.enterprise.security.LoginContext;
42 import com.sun.enterprise.security.CORBAObjectPermission;
43 import com.sun.enterprise.security.auth.login.PasswordCredential;
44 import com.sun.enterprise.security.auth.LoginContextDriver;
45 import com.sun.enterprise.iiop.POAProtocolMgr;
46 import com.sun.corba.ee.spi.ior.IOR;
47 import com.sun.corba.ee.spi.presentation.rmi.StubAdapter;
48
49 import java.util.Set JavaDoc;
50 import java.util.logging.*;
51 import com.sun.logging.*;
52
53 /**
54  * This class provides the implementation of the SPI between the
55  * CSIV2 layer and the RI.
56  * @author Vivek Nagar
57  * @author Harpreet Singh
58  */

59
60 public class SecurityServiceImpl implements SecurityService
61 {
62
63     private static java.util.logging.Logger JavaDoc _logger=null;
64     static{
65        _logger=LogDomains.getLogger(LogDomains.CORBA_LOGGER);
66         }
67     // ignoring exceptions thrown for _is_a calls from the ORB
68
private static String JavaDoc IS_A = "_is_a";
69
70     private Policy JavaDoc policy;
71
72
73     public SecurityServiceImpl() {
74
75     policy = Policy.getPolicy();
76     }
77
78
79     /**
80      * This is called by the CSIv2 interceptor on the client before
81      * sending the IIOP message.
82      * @param the effective_target field of the PortableInterceptor
83      * ClientRequestInfo object.
84      * @return a SecurityContext which is marshalled into the IIOP msg
85      * by the CSIv2 interceptor.
86      */

87     public SecurityContext getSecurityContext(
88                             org.omg.CORBA.Object JavaDoc effective_target)
89         throws InvalidMechanismException, InvalidIdentityTokenException
90         {
91         SecurityContext context = null;
92
93         IOR ior = ((com.sun.corba.ee.spi.orb.ORB)ORBManager.getORB()).getIOR(effective_target, false);
94     if (StubAdapter.isStub(effective_target)) {
95         if (StubAdapter.isLocal(effective_target)) {
96         return null;
97         }
98     }
99
100         try {
101             SecurityMechanismSelector sms = new SecurityMechanismSelector();
102             context = sms.selectSecurityContext(ior);
103         } catch (InvalidMechanismException ime){ // let this pass ahead
104
_logger.log(Level.SEVERE,"iiop.invalidmechanism_exception",ime);
105             throw new InvalidMechanismException (ime.getMessage());
106         } catch(InvalidIdentityTokenException iite){
107            _logger.log(Level.SEVERE,"iiop.invalididtoken_exception",iite);
108             throw new InvalidIdentityTokenException(iite.getMessage());
109             // let this pass ahead
110
} catch(SecurityMechanismException sme) {
111            _logger.log(Level.SEVERE,"iiop.secmechanism_exception",sme);
112             throw new RuntimeException JavaDoc(sme.getMessage());
113         }
114         return context;
115     }
116
117     /**
118      * This is called by the CSIv2 interceptor on the client after
119      * a reply is received.
120      * @param the reply status from the call. The reply status field
121      * could indicate an authentication retry.
122      * The following is the mapping of PI status to the reply_status field
123      * PortableInterceptor::SUCCESSFUL -> STATUS_PASSED
124      * PortableInterceptor::SYSTEM_EXCEPTION -> STATUS_FAILED
125      * PortableInterceptor::USER_EXCEPTION -> STATUS_PASSED
126      * PortableInterceptor::LOCATION_FORWARD -> STATUS_RETRY
127      * PortableInterceptor::TRANSPORT_RETRY -> STATUS_RETRY
128      * @param the effective_target field of the PI ClientRequestInfo object.
129      */

130     public void receivedReply(int reply_status,
131                                 org.omg.CORBA.Object JavaDoc effective_target)
132     {
133         if(reply_status == STATUS_FAILED) {
134             if(_logger.isLoggable(Level.FINE)){
135                 _logger.log(Level.FINE,"Failed status");
136             }
137             // what kind of exception should we throw?
138
throw new RuntimeException JavaDoc("Target did not accept security context");
139         } else if(reply_status == STATUS_RETRY) {
140             if(_logger.isLoggable(Level.FINE)){
141         _logger.log(Level.FINE,"Retry status");
142             }
143         } else {
144             if(_logger.isLoggable(Level.FINE)){
145         _logger.log(Level.FINE,"Passed status");
146             }
147         }
148     }
149
150     /**
151      * This is called by the CSIv2 interceptor on the server after
152      * receiving the IIOP message. If authentication fails a FAILED status
153      * is returned. If a FAILED status is returned the CSIV2 interceptor will
154      * marshall the MessageError service context and throw the NO_PERMISSION
155      * exception.
156      * @param the SecurityContext which arrived in the IIOP message.
157      * @return the status
158      */

159     public int setSecurityContext(SecurityContext context, byte[] object_id,
160                                   String JavaDoc method)
161     {
162         if(_logger.isLoggable(Level.FINE)){
163             _logger.log(Level.FINE,"ABOUT TO EVALUATE TRUST");
164         }
165
166         try {
167         // First check if the client sent the credentials
168
// as required by the object's CSIv2 policy.
169
// evaluateTrust will throw an exception if client did not
170
// conform to security policy.
171
SecurityMechanismSelector sms = new SecurityMechanismSelector();
172         SecurityContext ssc = sms.evaluateTrust(context, object_id);
173
174         Class JavaDoc cls = null;
175             Subject JavaDoc s = null;
176             if(ssc == null) {
177                 return STATUS_PASSED;
178             } else {
179                 if(ssc.authcls != null) {
180                     cls = ssc.authcls;
181                 } else {
182                     cls = ssc.identcls;
183                 }
184                 s = ssc.subject;
185             }
186
187         // Authenticate the client. An Exception is thrown if login fails.
188
// SecurityContext is set on current thread if login succeeds.
189
authenticate(s, cls);
190
191         // Authorize the client for non-EJB objects.
192
// Auth for EJB objects is done in BaseContainer.preInvoke().
193
if ( authorizeCORBA(object_id, method) )
194         return STATUS_PASSED;
195         else
196         return STATUS_FAILED;
197
198         } catch(Exception JavaDoc e) {
199             if (!method.equals(IS_A)){
200         if(_logger.isLoggable(Level.FINE)){
201                     _logger.log(Level.FINE,"iiop.authenticate_exception",e.toString());
202                 }
203             if(_logger.isLoggable(Level.FINE)){
204                     _logger.log(Level.FINE,"Authentication Exception",e);
205                 }
206             }
207             return STATUS_FAILED;
208         }
209     }
210
211
212     // return true if authorization succeeds, false otherwise.
213
private boolean authorizeCORBA(byte[] object_id, String JavaDoc method)
214         throws Exception JavaDoc {
215
216     // Check if target is an EJB
217
POAProtocolMgr protocolMgr = (POAProtocolMgr)
218                     Switch.getSwitch().getProtocolManager();
219         // Check to make sure protocolMgr is not null.
220
// This could happen during server initialization or if this call
221
// is on a callback object in the client VM.
222
if ( protocolMgr == null )
223             return true;
224
225     if ( protocolMgr.getEjbDescriptor(object_id) != null )
226         return true; // an EJB object
227

228     CORBAObjectPermission perm = new CORBAObjectPermission("*", method);
229
230     // Create a ProtectionDomain for principal on current thread.
231
com.sun.enterprise.security.SecurityContext sc =
232             com.sun.enterprise.security.SecurityContext.getCurrent();
233         Set JavaDoc principalSet = sc.getPrincipalSet();
234     Principal JavaDoc[] principals = (principalSet == null ? null :
235                          (Principal JavaDoc []) principalSet.toArray(new Principal JavaDoc[0]));
236     CodeSource JavaDoc cs = new CodeSource JavaDoc(new java.net.URL JavaDoc("file://"),
237                             (java.security.cert.Certificate JavaDoc[]) null);
238         ProtectionDomain JavaDoc prdm = new ProtectionDomain JavaDoc(cs, null, null, principals);
239
240     // Check if policy gives principal the permissions
241
boolean result = policy.implies(prdm, perm);
242
243     if ( _logger.isLoggable(Level.FINE) ) {
244         _logger.log(Level.FINE, "CORBA Object permission evaluation result="
245                     + result + " for method=" + method);
246     }
247     return result;
248     }
249
250
251     /**
252      * This is called by the CSIv2 interceptor on the server before
253      * sending the reply.
254      * @param the SecurityContext which arrived in the IIOP message.
255      */

256     public void sendingReply(SecurityContext context)
257     {
258         // NO OP
259
}
260     /**
261      * This is called on the server to unset the security context
262      * this is introduced to prevent the re-use of the thread
263      * security context on re-use of the thread.
264      */

265     public void unsetSecurityContext(){
266         // logout method from LoginContext not called
267
// as we dont want to unset the appcontainer context
268

269         // First check if this is a local call.
270
boolean isLocal = true;
271         ServerConnectionContext scc =
272                         SecurityMechanismSelector.getServerConnectionContext();
273         if ( scc != null && scc.getSocket() != null )
274             isLocal = false;
275
276         if ( !isLocal)
277             com.sun.enterprise.security.SecurityContext.setCurrent(null);
278     }
279
280     /**
281      * Authenticate the user with the specified subject and
282      * credential class.
283      */

284     private void authenticate(Subject JavaDoc s, Class JavaDoc cls)
285         throws SecurityMechanismException
286     {
287         // authenticate
288
try {
289             final Subject JavaDoc fs = s;
290             final Class JavaDoc cl = cls;
291             AccessController.doPrivileged(new PrivilegedAction JavaDoc() {
292                 public java.lang.Object JavaDoc run() {
293                     LoginContextDriver.login(fs, cl);
294                     return null;
295                 }
296             });
297         } catch(Exception JavaDoc e) {
298             if(_logger.isLoggable(Level.SEVERE)){
299         _logger.log(Level.SEVERE,"iiop.login_exception",e.toString());
300             }
301             if(_logger.isLoggable(Level.FINE)){
302         _logger.log(Level.FINE,"Login Exception",e);
303             }
304             throw new SecurityMechanismException("Cannot login user:" +
305                         e.getMessage());
306         }
307     }
308
309 }
310
311
312
Popular Tags