KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > batik > util > ApplicationSecurityEnforcer


1 /*
2
3    Copyright 2002-2003 The Apache Software Foundation
4
5    Licensed under the Apache License, Version 2.0 (the "License");
6    you may not use this file except in compliance with the License.
7    You may obtain a copy of the License at
8
9        http://www.apache.org/licenses/LICENSE-2.0
10
11    Unless required by applicable law or agreed to in writing, software
12    distributed under the License is distributed on an "AS IS" BASIS,
13    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14    See the License for the specific language governing permissions and
15    limitations under the License.
16
17  */

18 package org.apache.batik.util;
19
20 import java.net.URL JavaDoc;
21 import java.security.Policy JavaDoc;
22
23 /**
24  * This is a helper class which helps applications enforce secure
25  * script execution.
26  * <br />
27  * It is used by the Squiggle browser as well as the rasterizer.
28  * <br />
29  * This class can install a <tt>SecurityManager</tt> for an application
30  * and resolves whether the application runs in a development
31  * environment or from a jar file (in other words, it resolves code-base
32  * issues for the application).
33  * <br />
34  *
35  * @author <a mailto="vincent.hardy@sun.com">Vincent Hardy</a>
36  * @version $Id: ApplicationSecurityEnforcer.java,v 1.13 2005/03/27 08:58:36 cam Exp $
37  */

38 public class ApplicationSecurityEnforcer {
39     /**
40      * Message for the SecurityException thrown when there is already
41      * a SecurityManager installed at the time Squiggle tries
42      * to install its own security settings.
43      */

44     public static final String JavaDoc EXCEPTION_ALIEN_SECURITY_MANAGER
45         = "ApplicationSecurityEnforcer.message.security.exception.alien.security.manager";
46
47     /**
48      * Message for the NullPointerException thrown when no policy
49      * file can be found.
50      */

51     public static final String JavaDoc EXCEPTION_NO_POLICY_FILE
52         = "ApplicationSecurityEnforcer.message.null.pointer.exception.no.policy.file";
53
54     /**
55      * System property for specifying an additional policy file.
56      */

57     public static final String JavaDoc PROPERTY_JAVA_SECURITY_POLICY
58         = "java.security.policy";
59
60     /**
61      * Files in a jar file have a URL with the jar protocol
62      */

63     public static final String JavaDoc JAR_PROTOCOL
64         = "jar:";
65
66     /**
67      * Used in jar file urls to separate the jar file name
68      * from the referenced file
69      */

70     public static final String JavaDoc JAR_URL_FILE_SEPARATOR
71         = "!/";
72
73     /**
74      * System property for App's development base directory
75      */

76     public static final String JavaDoc PROPERTY_APP_DEV_BASE
77         = "app.dev.base";
78
79     /**
80      * System property for App's jars base directory
81      */

82     public static final String JavaDoc PROPERTY_APP_JAR_BASE
83         = "app.jar.base";
84
85     /**
86      * Directory where classes are expanded in the development
87      * version
88      */

89     public static final String JavaDoc APP_MAIN_CLASS_DIR
90         = "classes/";
91
92     /**
93      * The application's main entry point
94      */

95     protected Class JavaDoc appMainClass;
96
97     /**
98      * The application's security policy
99      */

100     protected String JavaDoc securityPolicy;
101
102     /**
103      * The resource name for the application's main class
104      */

105     protected String JavaDoc appMainClassRelativeURL;
106
107     /**
108      * Keeps track of the last SecurityManager installed
109      */

110     protected BatikSecurityManager lastSecurityManagerInstalled;
111
112     /**
113      * Creates a new ApplicationSecurityEnforcer.
114      * @param appMainClass class of the applications's main entry point
115      * @param securityPolicy resource for the security policy which
116      * should be enforced for the application.
117      * @param appJarFile the Jar file into which the application is
118      * packaged.
119      * @deprecated This constructor is now deprecated. Use the two
120      * argument constructor instead as this version will
121      * be removed after the 1.5beta4 release.
122      */

123     public ApplicationSecurityEnforcer(Class JavaDoc appMainClass,
124                                        String JavaDoc securityPolicy,
125                                        String JavaDoc appJarFile){
126         this(appMainClass, securityPolicy);
127     }
128
129
130     /**
131      * Creates a new ApplicationSecurityEnforcer.
132      * @param appMainClass class of the applications's main entry point
133      * @param securityPolicy resource for the security policy which
134      * should be enforced for the application.
135      */

136     public ApplicationSecurityEnforcer(Class JavaDoc appMainClass,
137                                        String JavaDoc securityPolicy){
138         this.appMainClass = appMainClass;
139         this.securityPolicy = securityPolicy;
140         this.appMainClassRelativeURL =
141             appMainClass.getName().replace('.', '/')
142             +
143             ".class";
144             
145     }
146
147     /**
148      * Enforces security by installing a <tt>SecurityManager</tt>.
149      * This will throw a <tt>SecurityException</tt> if installing
150      * a <tt>SecurityManager</tt> requires overriding an existing
151      * <tt>SecurityManager</tt>. In other words, this method will
152      * not install a new <tt>SecurityManager</tt> if there is
153      * already one it did not install in place.
154      */

155     public void enforceSecurity(boolean enforce){
156         SecurityManager JavaDoc sm = System.getSecurityManager();
157
158         if (sm != null && sm != lastSecurityManagerInstalled) {
159             // Throw a Security exception: we do not want to override
160
// an 'alien' SecurityManager with either null or
161
// a new SecurityManager.
162
throw new SecurityException JavaDoc
163                 (Messages.getString(EXCEPTION_ALIEN_SECURITY_MANAGER));
164         }
165         
166         if (enforce) {
167             // We first set the security manager to null to
168
// force reloading of the policy file in case there
169
// has been a change since it was last enforced (this
170
// may happen with dynamically generated policy files).
171
System.setSecurityManager(null);
172             installSecurityManager();
173         } else {
174             if (sm != null) {
175                 System.setSecurityManager(null);
176                 lastSecurityManagerInstalled = null;
177             }
178         }
179     }
180
181     /**
182      * Returns the url for the default policy. This never
183      * returns null, but it may throw a NullPointerException
184      */

185     public URL JavaDoc getPolicyURL() {
186         ClassLoader JavaDoc cl = appMainClass.getClassLoader();
187         URL JavaDoc policyURL = cl.getResource(securityPolicy);
188         
189         if (policyURL == null) {
190             throw new NullPointerException JavaDoc
191                 (Messages.formatMessage(EXCEPTION_NO_POLICY_FILE,
192                                         new Object JavaDoc[]{securityPolicy}));
193         }
194
195         return policyURL;
196     }
197
198     /**
199      * Installs a SecurityManager on behalf of the application
200      */

201     public void installSecurityManager(){
202         Policy JavaDoc policy = Policy.getPolicy();
203         BatikSecurityManager securityManager = new BatikSecurityManager();
204
205         //
206
// If there is a java.security.policy property defined,
207
// it takes precedence over the one passed to this object.
208
// Otherwise, we default to the one passed to the constructor
209
//
210
ClassLoader JavaDoc cl = appMainClass.getClassLoader();
211         String JavaDoc securityPolicyProperty
212             = System.getProperty(PROPERTY_JAVA_SECURITY_POLICY);
213
214         if (securityPolicyProperty == null || securityPolicyProperty.equals("")) {
215             // Specify app's security policy in the
216
// system property.
217
URL JavaDoc policyURL = getPolicyURL();
218             
219             System.setProperty(PROPERTY_JAVA_SECURITY_POLICY,
220                                policyURL.toString());
221         }
222         
223         //
224
// The following detects whether the application is running in the
225
// development environment, in which case it will set the
226
// app.dev.base property or if it is running in the binary
227
// distribution, in which case it will set the app.jar.base
228
// property. These properties are expanded in the security
229
// policy files.
230
// Property expansion is used to provide portability of the
231
// policy files between various code bases (e.g., file base,
232
// server base, etc..).
233
//
234
URL JavaDoc mainClassURL = cl.getResource(appMainClassRelativeURL);
235         if (mainClassURL == null){
236             // Something is really wrong: we would be running a class
237
// which can't be found....
238
throw new Error JavaDoc(appMainClassRelativeURL);
239         }
240         
241         String JavaDoc expandedMainClassName = mainClassURL.toString();
242         if (expandedMainClassName.startsWith(JAR_PROTOCOL) ) {
243             setJarBase(expandedMainClassName);
244         } else {
245             setDevBase(expandedMainClassName);
246         }
247         
248         // Install new security manager
249
System.setSecurityManager(securityManager);
250         lastSecurityManagerInstalled = securityManager;
251         
252         // Forces re-loading of the security policy
253
policy.refresh();
254
255         if (securityPolicyProperty == null || securityPolicyProperty.equals("")) {
256             System.setProperty(PROPERTY_JAVA_SECURITY_POLICY, "");
257         }
258     }
259
260     private void setJarBase(String JavaDoc expandedMainClassName){
261         //
262
// Only set the app.jar.base if it is not already defined
263
//
264
String JavaDoc curAppJarBase = System.getProperty(PROPERTY_APP_JAR_BASE);
265         if (curAppJarBase == null) {
266             expandedMainClassName = expandedMainClassName.substring(JAR_PROTOCOL.length());
267             
268             int codeBaseEnd =
269                 expandedMainClassName.indexOf(JAR_URL_FILE_SEPARATOR +
270                                               appMainClassRelativeURL);
271             
272             if (codeBaseEnd == -1){
273                 // Something is seriously wrong. This should *never* happen
274
// as the APP_SECURITY_POLICY_URL is such that it will be
275
// a substring of its corresponding URL value
276
throw new Error JavaDoc();
277             }
278             
279             String JavaDoc appCodeBase = expandedMainClassName.substring(0, codeBaseEnd);
280
281             // At this point appCodeBase contains the JAR file name
282
// Now, we extract it.
283
codeBaseEnd = appCodeBase.lastIndexOf('/');
284             if (codeBaseEnd == -1) {
285                 appCodeBase = "";
286             } else {
287                 appCodeBase = appCodeBase.substring(0, codeBaseEnd);
288             }
289
290             System.setProperty(PROPERTY_APP_JAR_BASE, appCodeBase);
291         }
292     }
293
294     /**
295      * Position the app.dev.base property for expansion in
296      * the policy file used when App is running in its
297      * development version
298      */

299     private void setDevBase(String JavaDoc expandedMainClassName){
300         //
301
// Only set the app.code.base property if it is not already
302
// defined.
303
//
304
String JavaDoc curAppCodeBase = System.getProperty(PROPERTY_APP_DEV_BASE);
305         if (curAppCodeBase == null) {
306             int codeBaseEnd =
307                 expandedMainClassName.indexOf(APP_MAIN_CLASS_DIR
308                                               + appMainClassRelativeURL);
309             
310             if (codeBaseEnd == -1){
311                 // Something is seriously wrong. This should *never* happen
312
// as the APP_SECURITY_POLICY_URL is such that it will be
313
// a substring of its corresponding URL value
314
throw new Error JavaDoc();
315             }
316             
317             String JavaDoc appCodeBase = expandedMainClassName.substring(0, codeBaseEnd);
318             System.setProperty(PROPERTY_APP_DEV_BASE, appCodeBase);
319         }
320     }
321
322
323 }
324
325
Popular Tags