Source Code Cross Referenced for DefaultPolicyParser.java in  » Apache-Harmony-Java-SE » org-package » org » apache » harmony » security » fortress » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Apache Harmony Java SE » org package » org.apache.harmony.security.fortress 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *  Licensed to the Apache Software Foundation (ASF) under one or more
003:         *  contributor license agreements.  See the NOTICE file distributed with
004:         *  this work for additional information regarding copyright ownership.
005:         *  The ASF licenses this file to You under the Apache License, Version 2.0
006:         *  (the "License"); you may not use this file except in compliance with
007:         *  the License.  You may obtain a copy of the License at
008:         *
009:         *     http://www.apache.org/licenses/LICENSE-2.0
010:         *
011:         *  Unless required by applicable law or agreed to in writing, software
012:         *  distributed under the License is distributed on an "AS IS" BASIS,
013:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         *  See the License for the specific language governing permissions and
015:         *  limitations under the License.
016:         */
017:
018:        /**
019:         * @author Alexey V. Varlamov
020:         * @version $Revision$
021:         */package org.apache.harmony.security.fortress;
022:
023:        import java.io.BufferedReader;
024:        import java.io.InputStream;
025:        import java.io.InputStreamReader;
026:        import java.io.Reader;
027:        import java.net.URL;
028:        import java.security.cert.Certificate;
029:        import java.security.cert.CertificateException;
030:        import java.security.cert.X509Certificate;
031:        import java.security.AccessController;
032:        import java.security.CodeSource;
033:        import java.security.KeyStore;
034:        import java.security.KeyStoreException;
035:        import java.security.Permission;
036:        import java.security.Principal;
037:        import java.security.UnresolvedPermission;
038:        import java.util.ArrayList;
039:        import java.util.Collection;
040:        import java.util.HashSet;
041:        import java.util.Iterator;
042:        import java.util.List;
043:        import java.util.Properties;
044:        import java.util.Set;
045:        import java.util.StringTokenizer;
046:
047:        import org.apache.harmony.security.DefaultPolicyScanner;
048:        import org.apache.harmony.security.PolicyEntry;
049:        import org.apache.harmony.security.UnresolvedPrincipal;
050:        import org.apache.harmony.security.DefaultPolicyScanner.GrantEntry;
051:        import org.apache.harmony.security.DefaultPolicyScanner.KeystoreEntry;
052:        import org.apache.harmony.security.DefaultPolicyScanner.PermissionEntry;
053:        import org.apache.harmony.security.DefaultPolicyScanner.PrincipalEntry;
054:        import org.apache.harmony.security.internal.nls.Messages;
055:
056:        /**
057:         * This is a basic loader of policy files. It delegates lexical analysis to 
058:         * a pluggable scanner and converts received tokens to a set of 
059:         * {@link org.apache.harmony.security.PolicyEntry PolicyEntries}. 
060:         * For details of policy format, see the 
061:         * {@link org.apache.harmony.security.DefaultPolicy default policy description}.
062:         * <br>
063:         * For ordinary uses, this class has just one public method <code>parse()</code>, 
064:         * which performs the main task.
065:         * Extensions of this parser may redefine specific operations separately, 
066:         * by overriding corresponding protected methods. 
067:         * <br>
068:         * This implementation is effectively thread-safe, as it has no field references 
069:         * to data being processed (that is, passes all the data as method parameters).
070:         * 
071:         * @see org.apache.harmony.security.DefaultPolicy
072:         * @see org.apache.harmony.security.DefaultPolicyScanner
073:         * @see org.apache.harmony.security.PolicyEntry
074:         */
075:        public class DefaultPolicyParser {
076:
077:            // Pluggable scanner for a specific file format
078:            private final DefaultPolicyScanner scanner;
079:
080:            /** 
081:             * Default constructor, 
082:             * {@link org.apache.harmony.security.DefaultPolicyScanner DefaultPolicyScanner} 
083:             * is used. 
084:             */
085:            public DefaultPolicyParser() {
086:                scanner = new DefaultPolicyScanner();
087:            }
088:
089:            /** 
090:             * Extension constructor for plugging-in custom scanner.
091:             */
092:            public DefaultPolicyParser(DefaultPolicyScanner s) {
093:                this .scanner = s;
094:            }
095:
096:            /**
097:             * This is the main business method. It manages loading process as follows:
098:             * the associated scanner is used to parse the stream to a set of 
099:             * {@link org.apache.harmony.security.DefaultPolicyScanner.GrantEntry composite tokens},
100:             * then this set is iterated and each token is translated to a PolicyEntry.
101:             * Semantically invalid tokens are ignored, the same as void PolicyEntries.
102:             * <br>
103:             * A policy file may refer to some KeyStore(s), and in this case the first
104:             * valid reference is initialized and used in processing tokens.   
105:             * 
106:             * @param location an URL of a policy file to be loaded
107:             * @param system system properties, used for property expansion
108:             * @return a collection of PolicyEntry objects, may be empty
109:             * @throws Exception IO error while reading location or file syntax error 
110:             */
111:            public Collection<PolicyEntry> parse(URL location, Properties system)
112:                    throws Exception {
113:
114:                boolean resolve = PolicyUtils.canExpandProperties();
115:                Reader r = new BufferedReader(new InputStreamReader(
116:                        AccessController
117:                                .doPrivileged(new PolicyUtils.URLLoader(
118:                                        location))));
119:
120:                Collection<GrantEntry> grantEntries = new HashSet<GrantEntry>();
121:                List<KeystoreEntry> keystores = new ArrayList<KeystoreEntry>();
122:
123:                try {
124:                    scanner.scanStream(r, grantEntries, keystores);
125:                } finally {
126:                    r.close();
127:                }
128:
129:                //XXX KeyStore could be loaded lazily...
130:                KeyStore ks = initKeyStore(keystores, location, system, resolve);
131:
132:                Collection<PolicyEntry> result = new HashSet<PolicyEntry>();
133:                for (Iterator<GrantEntry> iter = grantEntries.iterator(); iter
134:                        .hasNext();) {
135:                    DefaultPolicyScanner.GrantEntry ge = iter.next();
136:                    try {
137:                        PolicyEntry pe = resolveGrant(ge, ks, system, resolve);
138:                        if (!pe.isVoid()) {
139:                            result.add(pe);
140:                        }
141:                    } catch (Exception e) {
142:                        // TODO: log warning
143:                    }
144:                }
145:
146:                return result;
147:            }
148:
149:            /**
150:             * Translates GrantEntry token to PolicyEntry object. It goes step by step, 
151:             * trying to resolve each component of the GrantEntry:
152:             * <ul>
153:             * <li> If <code>codebase</code> is specified, expand it and construct an URL.
154:             * <li> If <code>signers</code> is specified, expand it and obtain 
155:             * corresponding Certificates.
156:             * <li> If <code>principals</code> collection is specified, iterate over it. 
157:             * For each PrincipalEntry, expand name and if no class specified, 
158:             * resolve actual X500Principal from a KeyStore certificate; otherwise keep it 
159:             * as UnresolvedPrincipal. 
160:             * <li> Iterate over <code>permissions</code> collection. For each PermissionEntry,
161:             * try to resolve (see method 
162:             * {@link #resolvePermission(DefaultPolicyScanner.PermissionEntry, DefaultPolicyScanner.GrantEntry, KeyStore, Properties, boolean) resolvePermission()}) 
163:             * a corresponding permission. If resolution failed, ignore the PermissionEntry. 
164:             * </ul>
165:             * In fact, property expansion in the steps above is conditional and is ruled by
166:             * the parameter <i>resolve</i>.  
167:             * <br>
168:             * Finally a new PolicyEntry is created, which associates the trinity 
169:             * of resolved URL, Certificates and Principals to a set of granted Permissions.
170:             * 
171:             * @param ge GrantEntry token to be resolved
172:             * @param ks KeyStore for resolving Certificates, may be <code>null</code> 
173:             * @param system system properties, used for property expansion 
174:             * @param resolve flag enabling/disabling property expansion
175:             * @return resolved PolicyEntry
176:             * @throws Exception if unable to resolve codebase, signers or principals 
177:             * of the GrantEntry
178:             * @see DefaultPolicyScanner.PrincipalEntry
179:             * @see DefaultPolicyScanner.PermissionEntry
180:             * @see org.apache.harmony.security.PolicyUtils
181:             */
182:            protected PolicyEntry resolveGrant(
183:                    DefaultPolicyScanner.GrantEntry ge, KeyStore ks,
184:                    Properties system, boolean resolve) throws Exception {
185:
186:                URL codebase = null;
187:                Certificate[] signers = null;
188:                Set<Principal> principals = new HashSet<Principal>();
189:                Set<Permission> permissions = new HashSet<Permission>();
190:                if (ge.codebase != null) {
191:                    codebase = new URL(resolve ? PolicyUtils.expandURL(
192:                            ge.codebase, system) : ge.codebase);
193:                }
194:                if (ge.signers != null) {
195:                    if (resolve) {
196:                        ge.signers = PolicyUtils.expand(ge.signers, system);
197:                    }
198:                    signers = resolveSigners(ks, ge.signers);
199:                }
200:                if (ge.principals != null) {
201:                    for (Iterator<PrincipalEntry> iter = ge.principals
202:                            .iterator(); iter.hasNext();) {
203:                        DefaultPolicyScanner.PrincipalEntry pe = iter.next();
204:                        if (resolve) {
205:                            pe.name = PolicyUtils.expand(pe.name, system);
206:                        }
207:                        if (pe.klass == null) {
208:                            principals.add(getPrincipalByAlias(ks, pe.name));
209:                        } else {
210:                            principals.add(new UnresolvedPrincipal(pe.klass,
211:                                    pe.name));
212:                        }
213:                    }
214:                }
215:                if (ge.permissions != null) {
216:                    for (Iterator<PermissionEntry> iter = ge.permissions
217:                            .iterator(); iter.hasNext();) {
218:                        DefaultPolicyScanner.PermissionEntry pe = iter.next();
219:                        try {
220:                            permissions.add(resolvePermission(pe, ge, ks,
221:                                    system, resolve));
222:                        } catch (Exception e) {
223:                            // TODO: log warning
224:                        }
225:                    }
226:                }
227:                return new PolicyEntry(new CodeSource(codebase, signers),
228:                        principals, permissions);
229:            }
230:
231:            /**
232:             * Translates PermissionEntry token to Permission object.
233:             * First, it performs general expansion for non-null <code>name</code> and
234:             * properties expansion for non-null <code>name</code>, <code>action</code> 
235:             * and <code>signers</code>.
236:             * Then, it obtains signing Certificates(if any), tries to find a class specified by 
237:             * <code>klass</code> name and instantiate a corresponding permission object.
238:             * If class is not found or it is signed improperly, returns UnresolvedPermission.
239:             *
240:             * @param pe PermissionEntry token to be resolved
241:             * @param ge parental GrantEntry of the PermissionEntry 
242:             * @param ks KeyStore for resolving Certificates, may be <code>null</code>
243:             * @param system system properties, used for property expansion
244:             * @param resolve flag enabling/disabling property expansion
245:             * @return resolved Permission object, either of concrete class or UnresolvedPermission
246:             * @throws Exception if failed to expand properties, 
247:             * or to get a Certificate, 
248:             * or to create an instance of a successfully found class 
249:             */
250:            protected Permission resolvePermission(
251:                    DefaultPolicyScanner.PermissionEntry pe,
252:                    DefaultPolicyScanner.GrantEntry ge, KeyStore ks,
253:                    Properties system, boolean resolve) throws Exception {
254:                if (pe.name != null) {
255:                    pe.name = PolicyUtils.expandGeneral(pe.name,
256:                            new PermissionExpander().configure(ge, ks));
257:                }
258:                if (resolve) {
259:                    if (pe.name != null) {
260:                        pe.name = PolicyUtils.expand(pe.name, system);
261:                    }
262:                    if (pe.actions != null) {
263:                        pe.actions = PolicyUtils.expand(pe.actions, system);
264:                    }
265:                    if (pe.signers != null) {
266:                        pe.signers = PolicyUtils.expand(pe.signers, system);
267:                    }
268:                }
269:                Certificate[] signers = (pe.signers == null) ? null
270:                        : resolveSigners(ks, pe.signers);
271:                try {
272:                    Class<?> klass = Class.forName(pe.klass);
273:                    if (PolicyUtils.matchSubset(signers, klass.getSigners())) {
274:                        return PolicyUtils.instantiatePermission(klass,
275:                                pe.name, pe.actions);
276:                    }
277:                } catch (ClassNotFoundException cnfe) {
278:                }
279:                //maybe properly signed class will be loaded later
280:                return new UnresolvedPermission(pe.klass, pe.name, pe.actions,
281:                        signers);
282:            }
283:
284:            /** 
285:             * Specific handler for expanding <i>self</i> and <i>alias</i> protocols. 
286:             */
287:            class PermissionExpander implements 
288:                    PolicyUtils.GeneralExpansionHandler {
289:
290:                // Store KeyStore
291:                private KeyStore ks;
292:
293:                // Store GrantEntry
294:                private DefaultPolicyScanner.GrantEntry ge;
295:
296:                /** 
297:                 * Combined setter of all required fields. 
298:                 */
299:                public PermissionExpander configure(
300:                        DefaultPolicyScanner.GrantEntry ge, KeyStore ks) {
301:                    this .ge = ge;
302:                    this .ks = ks;
303:                    return this ;
304:                }
305:
306:                /**
307:                 * Resolves the following protocols:
308:                 * <dl>
309:                 * <dt>self
310:                 * <dd>Denotes substitution to a principal information of the parental 
311:                 * GrantEntry. Returns a space-separated list of resolved Principals 
312:                 * (including wildcarded), formatting each as <b>class &quot;name&quot;</b>.
313:                 * If parental GrantEntry has no Principals, throws ExpansionFailedException.
314:                 * <dt>alias:<i>name</i>
315:                 * <dd>Denotes substitution of a KeyStore alias. Namely, if a KeyStore has 
316:                 * an X.509 certificate associated with the specified name, then returns 
317:                 * <b>javax.security.auth.x500.X500Principal &quot;<i>DN</i>&quot;</b> string, 
318:                 * where <i>DN</i> is a certificate's subject distinguished name.  
319:                 * </dl>
320:                 * @throws ExpansionFailedException - if protocol is other than 
321:                 * <i>self</i> or <i>alias</i>, or if data resolution failed 
322:                 */
323:                public String resolve(String protocol, String data)
324:                        throws PolicyUtils.ExpansionFailedException {
325:
326:                    if ("self".equals(protocol)) { //$NON-NLS-1$
327:                        //need expanding to list of principals in grant clause 
328:                        if (ge.principals != null && ge.principals.size() != 0) {
329:                            StringBuffer sb = new StringBuffer();
330:                            for (Iterator<PrincipalEntry> iter = ge.principals
331:                                    .iterator(); iter.hasNext();) {
332:                                DefaultPolicyScanner.PrincipalEntry pr = iter
333:                                        .next();
334:                                if (pr.klass == null) {
335:                                    // aliased X500Principal
336:                                    try {
337:                                        sb.append(pc2str(getPrincipalByAlias(
338:                                                ks, pr.name)));
339:                                    } catch (Exception e) {
340:                                        throw new PolicyUtils.ExpansionFailedException(
341:                                                Messages
342:                                                        .getString(
343:                                                                "security.143", pr.name), e); //$NON-NLS-1$
344:                                    }
345:                                } else {
346:                                    sb.append(pr.klass)
347:                                            .append(" \"").append(pr.name) //$NON-NLS-1$
348:                                            .append("\" "); //$NON-NLS-1$
349:                                }
350:                            }
351:                            return sb.toString();
352:                        } else {
353:                            throw new PolicyUtils.ExpansionFailedException(
354:                                    Messages.getString("security.144")); //$NON-NLS-1$
355:                        }
356:                    }
357:                    if ("alias".equals(protocol)) { //$NON-NLS-1$
358:                        try {
359:                            return pc2str(getPrincipalByAlias(ks, data));
360:                        } catch (Exception e) {
361:                            throw new PolicyUtils.ExpansionFailedException(
362:                                    Messages.getString("security.143", data), e); //$NON-NLS-1$
363:                        }
364:                    }
365:                    throw new PolicyUtils.ExpansionFailedException(Messages
366:                            .getString("security.145", protocol)); //$NON-NLS-1$
367:                }
368:
369:                // Formats a string describing the passed Principal. 
370:                private String pc2str(Principal pc) {
371:                    String klass = pc.getClass().getName();
372:                    String name = pc.getName();
373:                    StringBuffer sb = new StringBuffer(klass.length()
374:                            + name.length() + 5);
375:                    return sb.append(klass)
376:                            .append(" \"").append(name).append("\"") //$NON-NLS-1$ //$NON-NLS-2$
377:                            .toString();
378:                }
379:            }
380:
381:            /**
382:             * Takes a comma-separated list of aliases and obtains corresponding 
383:             * certificates.
384:             * @param ks KeyStore for resolving Certificates, may be <code>null</code> 
385:             * @param signers comma-separated list of certificate aliases, 
386:             * must be not <code>null</code>
387:             * @return an array of signing Certificates
388:             * @throws Exception if KeyStore is <code>null</code> 
389:             * or if it failed to provide a certificate  
390:             */
391:            protected Certificate[] resolveSigners(KeyStore ks, String signers)
392:                    throws Exception {
393:                if (ks == null) {
394:                    throw new KeyStoreException(Messages.getString(
395:                            "security.146", //$NON-NLS-1$
396:                            signers));
397:                }
398:
399:                Collection<Certificate> certs = new HashSet<Certificate>();
400:                StringTokenizer snt = new StringTokenizer(signers, ","); //$NON-NLS-1$
401:                while (snt.hasMoreTokens()) {
402:                    //XXX cache found certs ??
403:                    certs.add(ks.getCertificate(snt.nextToken().trim()));
404:                }
405:                return certs.toArray(new Certificate[certs.size()]);
406:            }
407:
408:            /**
409:             * Returns a subject's X500Principal of an X509Certificate, 
410:             * which is associated with the specified keystore alias. 
411:             * @param ks KeyStore for resolving Certificate, may be <code>null</code>
412:             * @param alias alias to a certificate
413:             * @return X500Principal with a subject distinguished name
414:             * @throws KeyStoreException if KeyStore is <code>null</code> 
415:             * or if it failed to provide a certificate
416:             * @throws CertificateException if found certificate is not 
417:             * an X509Certificate 
418:             */
419:            protected Principal getPrincipalByAlias(KeyStore ks, String alias)
420:                    throws KeyStoreException, CertificateException {
421:
422:                if (ks == null) {
423:                    throw new KeyStoreException(Messages.getString(
424:                            "security.147", alias)); //$NON-NLS-1$
425:                }
426:                //XXX cache found certs ??
427:                Certificate x509 = ks.getCertificate(alias);
428:                if (x509 instanceof  X509Certificate) {
429:                    return ((X509Certificate) x509).getSubjectX500Principal();
430:                } else {
431:                    throw new CertificateException(Messages.getString(
432:                            "security.148", //$NON-NLS-1$
433:                            alias, x509));
434:                }
435:            }
436:
437:            /**
438:             * Returns the first successfully loaded KeyStore, from the specified list of
439:             * possible locations. This method iterates over the list of KeystoreEntries;
440:             * for each entry expands <code>url</code> and <code>type</code>,
441:             * tries to construct instances of specified URL and KeyStore and to load 
442:             * the keystore. If it is loaded, returns the keystore, otherwise proceeds to 
443:             * the next KeystoreEntry. 
444:             * <br>
445:             * <b>Note:</b> an url may be relative to the policy file location or absolute.
446:             * @param keystores list of available KeystoreEntries
447:             * @param base the policy file location
448:             * @param system system properties, used for property expansion
449:             * @param resolve flag enabling/disabling property expansion
450:             * @return the first successfully loaded KeyStore or <code>null</code>
451:             */
452:            protected KeyStore initKeyStore(List<KeystoreEntry> keystores,
453:                    URL base, Properties system, boolean resolve) {
454:
455:                for (int i = 0; i < keystores.size(); i++) {
456:                    try {
457:                        DefaultPolicyScanner.KeystoreEntry ke = keystores
458:                                .get(i);
459:                        if (resolve) {
460:                            ke.url = PolicyUtils.expandURL(ke.url, system);
461:                            if (ke.type != null) {
462:                                ke.type = PolicyUtils.expand(ke.type, system);
463:                            }
464:                        }
465:                        if (ke.type == null || ke.type.length() == 0) {
466:                            ke.type = KeyStore.getDefaultType();
467:                        }
468:                        KeyStore ks = KeyStore.getInstance(ke.type);
469:                        URL location = new URL(base, ke.url);
470:                        InputStream is = AccessController
471:                                .doPrivileged(new PolicyUtils.URLLoader(
472:                                        location));
473:                        try {
474:                            ks.load(is, null);
475:                        } finally {
476:                            is.close();
477:                        }
478:                        return ks;
479:                    } catch (Exception e) {
480:                        // TODO: log warning
481:                    }
482:                }
483:                return null;
484:            }
485:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.