KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > tanukisoftware > wrapper > security > WrapperEventPermission


1 package org.tanukisoftware.wrapper.security;
2
3 /*
4  * Copyright (c) 1999, 2006 Tanuki Software Inc.
5  *
6  * Permission is hereby granted, free of charge, to any person
7  * obtaining a copy of the Java Service Wrapper and associated
8  * documentation files (the "Software"), to deal in the Software
9  * without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sub-license,
11  * and/or sell copies of the Software, and to permit persons to
12  * whom the Software is furnished to do so, subject to the
13  * following conditions:
14  *
15  * The above copyright notice and this permission notice shall be
16  * included in all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21  * NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23  * WHETHER IN AN EVENT_TYPE OF CONTRACT, TORT OR OTHERWISE, ARISING
24  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25  * OTHER DEALINGS IN THE SOFTWARE.
26  */

27
28 import java.security.Permission JavaDoc;
29 import java.security.PermissionCollection JavaDoc;
30 import java.util.Enumeration JavaDoc;
31 import java.util.Vector JavaDoc;
32 import java.util.StringTokenizer JavaDoc;
33
34 /**
35  * WrapperEventPermissions are used to grant the right to register to start
36  * receiving events from the Wrapper.
37  * <p>
38  * Some of these permissions can result in performance degredations if used
39  * impropperly.
40  * <p>
41  * The following are examples of how to specify the permission within a policy
42  * file.
43  * <pre>
44  * grant codeBase "file:../lib/-" {
45  * // Grant various permissions to a specific service.
46  * permission org.tanukisoftware.wrapper.security.WrapperEventPermission "service";
47  * permission org.tanukisoftware.wrapper.security.WrapperEventPermission "service, core";
48  * permission org.tanukisoftware.wrapper.security.WrapperEventPermission "*";
49  * };
50  * </pre>
51  * <p>
52  * Possible eventTypes include the following:
53  * <table border='1' cellpadding='2' cellspacing='0'>
54  * <tr>
55  * <th>Permission Event Type Name</th>
56  * <th>What the Permission Allows</th>
57  * <th>Risks of Allowing this Permission</th>
58  * </tr>
59  *
60  * <tr>
61  * <td>service</td>
62  * <td>Register to obtain events whenever the Wrapper service receives any service events.</td>
63  * <td>Malicious code could receive this event and never return and thus cause performance
64  * and timeout problems with the Wrapper. Normal use of these events are quite safe
65  * however.</td>
66  * </tr>
67  *
68  * <tr>
69  * <td>control</td>
70  * <td>Register to obtain events whenever the Wrapper receives any system control signals.</td>
71  * <td>Malicious code could trap and consome control events, thus preventing an application
72  * from being shut down cleanly.</td>
73  * </tr>
74  *
75  * <tr>
76  * <td>core</td>
77  * <td>Register to obtain events on the core workings of the Wrapper.</td>
78  * <td>Malicious code or even well meaning code can greatly affect the performance of
79  * the Wrapper simply by handling these methods slowly. Some of these events are
80  * fired from within the core timing code of the Wrapper. They are useful for
81  * testing and performance checks, but in general they should not be used by
82  * most applications.
83  * </td>
84  * </tr>
85  * </table>
86  *
87  * @author Leif Mortenson <leif@tanukisoftware.com>
88  */

89 public class WrapperEventPermission
90     extends Permission JavaDoc
91 {
92     public static String JavaDoc EVENT_TYPE_SERVICE = "service";
93     public static String JavaDoc EVENT_TYPE_CONTROL = "control";
94     public static String JavaDoc EVENT_TYPE_CORE = "core";
95     
96     private static int MASK_SERVICE = 1;
97     private static int MASK_CONTROL = 2;
98     private static int MASK_CORE = 65536;
99     private static int MASK_ALL = MASK_SERVICE | MASK_CONTROL | MASK_CORE;
100     
101     private int m_eventTypeMask;
102     
103     /*---------------------------------------------------------------
104      * Constructors
105      *-------------------------------------------------------------*/

106     /**
107      * Creates a new WrapperEventPermission for the specified service.
108      *
109      * @param eventTypes The event type or event types to be registered.
110      */

111     public WrapperEventPermission( String JavaDoc eventTypes )
112     {
113         super( "*" );
114         m_eventTypeMask = buildEventTypeMask( eventTypes );
115     }
116     
117     /*---------------------------------------------------------------
118      * Permission Methods
119      *-------------------------------------------------------------*/

120     /**
121      * Checks two Permission objects for equality.
122      * <p>
123      * Do not use the equals method for making access control decisions; use
124      * the implies method.
125      *
126      * @param obj The object we are testing for equality with this object.
127      *
128      * @return True if both Permission objects are equivalent.
129      */

130     public boolean equals( Object JavaDoc obj )
131     {
132         if ( obj == this )
133         {
134             return true;
135         }
136         
137         if ( !( obj instanceof WrapperEventPermission ) )
138         {
139             return false;
140         }
141         
142         WrapperEventPermission wsp = (WrapperEventPermission)obj;
143         
144         return ( m_eventTypeMask == wsp.m_eventTypeMask ) &&
145             getName().equals( wsp.getName() );
146     }
147     
148     /**
149      * Return the canonical string representation of the eventTypes.
150      * Always returns present eventTypes in the following order:
151      * start, stop, pause, continue, interrogate. userCode.
152      *
153      * @return the canonical string representation of the eventTypes.
154      */

155     public String JavaDoc getActions()
156     {
157         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
158         boolean first = true;
159         
160         if ( ( m_eventTypeMask & MASK_SERVICE ) != 0 )
161         {
162             if ( first )
163             {
164                 sb.append( ',' );
165             }
166             else
167             {
168                 first = false;
169             }
170             sb.append( EVENT_TYPE_SERVICE );
171         }
172         if ( ( m_eventTypeMask & MASK_CONTROL ) != 0 )
173         {
174             if ( first )
175             {
176                 sb.append( ',' );
177             }
178             else
179             {
180                 first = false;
181             }
182             sb.append( EVENT_TYPE_CONTROL );
183         }
184         if ( ( m_eventTypeMask & MASK_CORE ) != 0 )
185         {
186             if ( first )
187             {
188                 sb.append( ',' );
189             }
190             else
191             {
192                 first = false;
193             }
194             sb.append( EVENT_TYPE_CORE );
195         }
196         
197         return sb.toString();
198     }
199
200     /**
201      * Checks if this WrapperEventPermission object "implies" the
202      * specified permission.
203      * <P>
204      * More specifically, this method returns true if:<p>
205      * <ul>
206      * <li><i>p2</i> is an instanceof FilePermission,<p>
207      * <li><i>p2</i>'s eventTypes are a proper subset of this object's eventTypes,
208      * and<p>
209      * <li><i>p2</i>'s service name is implied by this object's service name.
210      * For example, "MyApp*" implies "MyApp".
211      * </ul>
212      *
213      * @param p2 the permission to check against.
214      *
215      * @return true if the specified permission is implied by this object,
216      */

217     public boolean implies( Permission JavaDoc p2 )
218     {
219         if ( !( p2 instanceof WrapperEventPermission ) )
220         {
221             return false;
222         }
223         
224         WrapperEventPermission wsp = (WrapperEventPermission)p2;
225         
226         // we get the effective mask. i.e., the "and" of this and that.
227
// They must be equal to that.mask for implies to return true.
228

229         return ( ( m_eventTypeMask & wsp.m_eventTypeMask ) == wsp.m_eventTypeMask ) &&
230             impliesIgnoreEventTypeMask( wsp );
231     }
232     
233     /**
234      * Returns an custom WECollection implementation of a PermissionCollection.
235      */

236     public PermissionCollection JavaDoc newPermissionCollection()
237     {
238         return new WECollection();
239     }
240
241     /**
242      * Returns the hash code value for this object.
243      *
244      * @return A hash code value for this object.
245      */

246     public int hashCode()
247     {
248         return getName().hashCode();
249     }
250     
251     /*---------------------------------------------------------------
252      * Methods
253      *-------------------------------------------------------------*/

254     /**
255      * Returns the eventType mask of the Permission.
256      */

257     int getActionMask()
258     {
259         return m_eventTypeMask;
260     }
261     
262     /**
263      * Tests whether this permissions implies another without taking the
264      * eventType mask into account.
265      */

266     boolean impliesIgnoreEventTypeMask( WrapperEventPermission p2 )
267     {
268         if ( getName().equals( p2.getName() ) )
269         {
270             return true;
271         }
272         
273         if ( p2.getName().endsWith( "*" ) )
274         {
275             if ( getName().startsWith( p2.getName().substring( 0, p2.getName().length() - 1 ) ) )
276             {
277                 return true;
278             }
279         }
280         return false;
281     }
282     
283     /**
284      * Builds an eventType mask given a comma separated list of eventTypes.
285      */

286     private int buildEventTypeMask( String JavaDoc eventTypes )
287     {
288         // Check for the constants first as they are used internally.
289
if ( eventTypes == EVENT_TYPE_SERVICE )
290         {
291             return MASK_SERVICE;
292         }
293         else if ( eventTypes == EVENT_TYPE_CONTROL )
294         {
295             return MASK_CONTROL;
296         }
297         else if ( eventTypes == EVENT_TYPE_CORE )
298         {
299             return MASK_CORE;
300         }
301         else if ( eventTypes.equals( "*" ) )
302         {
303             return MASK_ALL;
304         }
305         
306         int mask = 0;
307         StringTokenizer JavaDoc st = new StringTokenizer JavaDoc( eventTypes, "," );
308         while ( st.hasMoreTokens() )
309         {
310             String JavaDoc eventType = st.nextToken();
311             if ( eventType.equals( EVENT_TYPE_SERVICE ) )
312             {
313                 mask |= MASK_SERVICE;
314             }
315             else if ( eventType.equals( EVENT_TYPE_CONTROL ) )
316             {
317                 mask |= MASK_CONTROL;
318             }
319             else if ( eventType.equals( EVENT_TYPE_CORE ) )
320             {
321                 mask |= MASK_CORE;
322             }
323             else
324             {
325                 throw new IllegalArgumentException JavaDoc(
326                     "Invalid permission eventType: \"" + eventType + "\"" );
327             }
328         }
329         
330         return mask;
331     }
332 }
333         
334 final class WECollection
335     extends PermissionCollection JavaDoc
336 {
337     private Vector JavaDoc m_permissions = new Vector JavaDoc();
338     
339     /*---------------------------------------------------------------
340      * Constructors
341      *-------------------------------------------------------------*/

342     /**
343      * Creates an empty WECollection.
344      */

345     public WECollection()
346     {
347     }
348     
349     /*---------------------------------------------------------------
350      * Methods
351      *-------------------------------------------------------------*/

352     /**
353      * Adds a permission to the FilePermissions. The key for the hash is
354      * permission.path.
355      *
356      * @param permission the Permission object to add.
357      *
358      * @exception IllegalArgumentException - if the permission is not a
359      * FilePermission
360      *
361      * @exception SecurityException - if this FilePermissionCollection object
362      * has been marked readonly
363      */

364     public void add( Permission JavaDoc permission )
365     {
366         if ( !( permission instanceof WrapperEventPermission ) )
367         {
368             throw new IllegalArgumentException JavaDoc( "invalid permission: " + permission );
369         }
370         
371         if ( isReadOnly() )
372         {
373             throw new SecurityException JavaDoc( "Collection is read-only.");
374         }
375         
376         m_permissions.add( permission );
377     }
378     
379     /**
380      * Check and see if this set of permissions implies the permissions
381      * expressed in "permission".
382      *
383      * @param permission the Permission object to compare
384      *
385      * @return true if "permission" is a proper subset of a permission in
386      * the set, false if not.
387      */

388     public boolean implies( Permission JavaDoc permission )
389     {
390         if ( !( permission instanceof WrapperEventPermission ) )
391         {
392             return false;
393         }
394
395         WrapperEventPermission wsp = (WrapperEventPermission)permission;
396         
397         int desiredMask = wsp.getActionMask();
398         int pendingMask = desiredMask;
399         int foundMask = 0;
400         
401         for ( Enumeration JavaDoc en = m_permissions.elements(); en.hasMoreElements(); )
402         {
403             WrapperEventPermission p2 =
404                 (WrapperEventPermission)en.nextElement();
405             if ( ( pendingMask & p2.getActionMask() ) != 0 )
406             {
407                 // This permission has one or more eventTypes that we need.
408
if ( wsp.impliesIgnoreEventTypeMask( p2 ) )
409                 {
410                     foundMask |= desiredMask & p2.getActionMask();
411                     if ( foundMask == desiredMask )
412                     {
413                         return true;
414                     }
415                     pendingMask = desiredMask ^ foundMask;
416                 }
417             }
418         }
419         
420         return false;
421     }
422
423     /**
424      * Returns an enumeration of all the WrapperEventPermission
425      * objects in the container.
426      *
427      * @return An enumeration of all the WrapperEventPermission
428      * objects.
429      */

430     public Enumeration JavaDoc elements()
431     {
432         return m_permissions.elements();
433     }
434 }
435
Popular Tags