001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.ejb;
023:
024: import java.lang.reflect.InvocationHandler;
025: import java.lang.reflect.Method;
026: import java.lang.reflect.Proxy;
027: import java.lang.reflect.UndeclaredThrowableException;
028: import java.security.AccessController;
029: import java.security.Principal;
030: import java.security.PrivilegedAction;
031: import java.security.PrivilegedActionException;
032: import java.security.PrivilegedExceptionAction;
033:
034: import javax.management.MBeanServer;
035: import javax.management.ObjectName;
036: import javax.security.auth.Subject;
037: import javax.security.jacc.PolicyContext;
038: import javax.security.jacc.PolicyContextException;
039:
040: import org.jboss.mx.util.MBeanProxy;
041: import org.jboss.security.RunAsIdentity;
042: import org.jboss.security.SecurityAssociation;
043:
044: //$Id: SecurityActions.java 57209 2006-09-26 12:21:57Z dimitris@jboss.org $
045:
046: /** A collection of privileged actions for this package
047: *
048: * @author Scott.Stark@jboss.org
049: * @author Anil.Saldhana@jboss.org
050: * @version $Revison:$
051: */
052: class SecurityActions {
053: private static class SetContextID implements PrivilegedAction {
054: String contextID;
055:
056: SetContextID(String contextID) {
057: this .contextID = contextID;
058: }
059:
060: public Object run() {
061: String previousID = PolicyContext.getContextID();
062: PolicyContext.setContextID(contextID);
063: return previousID;
064: }
065: }
066:
067: private static class PeekRunAsRoleAction implements
068: PrivilegedAction {
069: int depth;
070:
071: PeekRunAsRoleAction(int depth) {
072: this .depth = depth;
073: }
074:
075: public Object run() {
076: RunAsIdentity principal = SecurityAssociation
077: .peekRunAsIdentity(depth);
078: return principal;
079: }
080: }
081:
082: /**
083: * Wrap the MBeanProxy proxy in a priviledged action so that method
084: * dispatch is done from a PrivilegedExceptionAction
085: */
086: private static class MBeanProxyAction implements
087: PrivilegedExceptionAction {
088: Class iface;
089: ObjectName name;
090: MBeanServer server;
091:
092: MBeanProxyAction(Class iface, ObjectName name,
093: MBeanServer server) {
094: this .iface = iface;
095: this .name = name;
096: this .server = server;
097: }
098:
099: public Object run() throws Exception {
100: Object proxy = MBeanProxy.get(iface, name, server);
101: Class[] ifaces = { iface };
102: InvocationHandler secureHandler = new InvocationHandlerAction(
103: proxy);
104: Object secureProxy = Proxy.newProxyInstance(iface
105: .getClassLoader(), ifaces, secureHandler);
106: return secureProxy;
107: }
108: }
109:
110: private static class InvocationHandlerAction implements
111: InvocationHandler, PrivilegedExceptionAction {
112: private Method method;
113: private Object[] args;
114: private Object mbean;
115:
116: private InvocationHandlerAction(Object mbean) {
117: this .mbean = mbean;
118: }
119:
120: public Object invoke(Object proxy, Method method, Object[] args)
121: throws Throwable {
122: this .method = method;
123: this .args = args;
124: Object value;
125: try {
126: value = AccessController.doPrivileged(this );
127: } catch (PrivilegedActionException e) {
128: throw e.getException();
129: }
130: return value;
131: }
132:
133: public Object run() throws Exception {
134: Object value = method.invoke(mbean, args);
135: return value;
136: }
137: }
138:
139: static Object getMBeanProxy(Class iface, ObjectName name,
140: MBeanServer server) throws Exception {
141: Object proxy;
142: if (System.getSecurityManager() == null) {
143: proxy = MBeanProxy.get(iface, name, server);
144: } else {
145: MBeanProxyAction action = new MBeanProxyAction(iface, name,
146: server);
147: proxy = AccessController.doPrivileged(action);
148: }
149: return proxy;
150: }
151:
152: static ClassLoader getContextClassLoader() {
153: return TCLAction.UTIL.getContextClassLoader();
154: }
155:
156: static ClassLoader getContextClassLoader(Thread thread) {
157: return TCLAction.UTIL.getContextClassLoader(thread);
158: }
159:
160: static void setContextClassLoader(ClassLoader loader) {
161: TCLAction.UTIL.setContextClassLoader(loader);
162: }
163:
164: static void setContextClassLoader(Thread thread, ClassLoader loader) {
165: TCLAction.UTIL.setContextClassLoader(thread, loader);
166: }
167:
168: static String setContextID(String contextID) {
169: PrivilegedAction action = new SetContextID(contextID);
170: String previousID = (String) AccessController
171: .doPrivileged(action);
172: return previousID;
173: }
174:
175: static RunAsIdentity peekRunAsIdentity(int depth) {
176: PrivilegedAction action = new PeekRunAsRoleAction(depth);
177: RunAsIdentity principal = (RunAsIdentity) AccessController
178: .doPrivileged(action);
179: return principal;
180: }
181:
182: static Principal getCallerPrincipal() {
183: return IdentityAction.UTIL.getIdentityAction()
184: .getCallerPrincipal();
185: }
186:
187: interface IdentityAction {
188: class UTIL {
189: static IdentityAction getIdentityAction() {
190: return System.getSecurityManager() == null ? NON_PRIVILEGED
191: : PRIVILEGED;
192: }
193: }
194:
195: IdentityAction NON_PRIVILEGED = new IdentityAction() {
196: public Principal getCallerPrincipal() {
197: return SecurityAssociation.getCallerPrincipal();
198: }
199: };
200: IdentityAction PRIVILEGED = new IdentityAction() {
201: private final PrivilegedAction getCallerPrincipalAction = new PrivilegedAction() {
202: public Object run() {
203: return SecurityAssociation.getCallerPrincipal();
204: }
205: };
206:
207: public Principal getCallerPrincipal() {
208: return (Principal) AccessController
209: .doPrivileged(getCallerPrincipalAction);
210: }
211: };
212:
213: Principal getCallerPrincipal();
214: }
215:
216: interface TCLAction {
217: class UTIL {
218: static TCLAction getTCLAction() {
219: return System.getSecurityManager() == null ? NON_PRIVILEGED
220: : PRIVILEGED;
221: }
222:
223: static ClassLoader getContextClassLoader() {
224: return getTCLAction().getContextClassLoader();
225: }
226:
227: static ClassLoader getContextClassLoader(Thread thread) {
228: return getTCLAction().getContextClassLoader(thread);
229: }
230:
231: static void setContextClassLoader(ClassLoader cl) {
232: getTCLAction().setContextClassLoader(cl);
233: }
234:
235: static void setContextClassLoader(Thread thread,
236: ClassLoader cl) {
237: getTCLAction().setContextClassLoader(thread, cl);
238: }
239: }
240:
241: TCLAction NON_PRIVILEGED = new TCLAction() {
242: public ClassLoader getContextClassLoader() {
243: return Thread.currentThread().getContextClassLoader();
244: }
245:
246: public ClassLoader getContextClassLoader(Thread thread) {
247: return thread.getContextClassLoader();
248: }
249:
250: public void setContextClassLoader(ClassLoader cl) {
251: Thread.currentThread().setContextClassLoader(cl);
252: }
253:
254: public void setContextClassLoader(Thread thread,
255: ClassLoader cl) {
256: thread.setContextClassLoader(cl);
257: }
258: };
259:
260: TCLAction PRIVILEGED = new TCLAction() {
261: private final PrivilegedAction getTCLPrivilegedAction = new PrivilegedAction() {
262: public Object run() {
263: return Thread.currentThread()
264: .getContextClassLoader();
265: }
266: };
267:
268: public ClassLoader getContextClassLoader() {
269: return (ClassLoader) AccessController
270: .doPrivileged(getTCLPrivilegedAction);
271: }
272:
273: public ClassLoader getContextClassLoader(final Thread thread) {
274: return (ClassLoader) AccessController
275: .doPrivileged(new PrivilegedAction() {
276: public Object run() {
277: return thread.getContextClassLoader();
278: }
279: });
280: }
281:
282: public void setContextClassLoader(final ClassLoader cl) {
283: AccessController.doPrivileged(new PrivilegedAction() {
284: public Object run() {
285: Thread.currentThread()
286: .setContextClassLoader(cl);
287: return null;
288: }
289: });
290: }
291:
292: public void setContextClassLoader(final Thread thread,
293: final ClassLoader cl) {
294: AccessController.doPrivileged(new PrivilegedAction() {
295: public Object run() {
296: thread.setContextClassLoader(cl);
297: return null;
298: }
299: });
300: }
301: };
302:
303: ClassLoader getContextClassLoader();
304:
305: ClassLoader getContextClassLoader(Thread thread);
306:
307: void setContextClassLoader(ClassLoader cl);
308:
309: void setContextClassLoader(Thread thread, ClassLoader cl);
310: }
311:
312: interface PolicyContextActions {
313: /** The JACC PolicyContext key for the current Subject */
314: static final String SUBJECT_CONTEXT_KEY = "javax.security.auth.Subject.container";
315: PolicyContextActions PRIVILEGED = new PolicyContextActions() {
316: private final PrivilegedExceptionAction exAction = new PrivilegedExceptionAction() {
317: public Object run() throws Exception {
318: return (Subject) PolicyContext
319: .getContext(SUBJECT_CONTEXT_KEY);
320: }
321: };
322:
323: public Subject getContextSubject()
324: throws PolicyContextException {
325: try {
326: return (Subject) AccessController
327: .doPrivileged(exAction);
328: } catch (PrivilegedActionException e) {
329: Exception ex = e.getException();
330: if (ex instanceof PolicyContextException)
331: throw (PolicyContextException) ex;
332: else
333: throw new UndeclaredThrowableException(ex);
334: }
335: }
336: };
337:
338: PolicyContextActions NON_PRIVILEGED = new PolicyContextActions() {
339: public Subject getContextSubject()
340: throws PolicyContextException {
341: return (Subject) PolicyContext
342: .getContext(SUBJECT_CONTEXT_KEY);
343: }
344: };
345:
346: Subject getContextSubject() throws PolicyContextException;
347: }
348:
349: static Subject getContextSubject() throws PolicyContextException {
350: if (System.getSecurityManager() == null) {
351: return PolicyContextActions.NON_PRIVILEGED
352: .getContextSubject();
353: } else {
354: return PolicyContextActions.PRIVILEGED.getContextSubject();
355: }
356: }
357: }
|