001    /**
002     *
003     * Copyright 2003-2004 The Apache Software Foundation
004     *
005     *  Licensed under the Apache License, Version 2.0 (the "License");
006     *  you may not use this file except in compliance with the License.
007     *  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    package org.apache.geronimo.security.util;
019    
020    import java.lang.reflect.Constructor;
021    import java.security.AccessController;
022    import java.security.PrivilegedActionException;
023    import java.security.PrivilegedExceptionAction;
024    import java.util.Set;
025    import javax.security.auth.Subject;
026    import javax.security.auth.x500.X500Principal;
027    import javax.security.jacc.PolicyContext;
028    import javax.security.jacc.PolicyContextException;
029    import javax.security.jacc.PolicyContextHandler;
030    
031    import org.apache.geronimo.common.DeploymentException;
032    import org.apache.geronimo.common.GeronimoSecurityException;
033    import org.apache.geronimo.security.DomainPrincipal;
034    import org.apache.geronimo.security.PrimaryDomainPrincipal;
035    import org.apache.geronimo.security.PrimaryPrincipal;
036    import org.apache.geronimo.security.PrimaryRealmPrincipal;
037    import org.apache.geronimo.security.RealmPrincipal;
038    import org.apache.geronimo.security.deploy.DefaultDomainPrincipal;
039    import org.apache.geronimo.security.deploy.DefaultPrincipal;
040    import org.apache.geronimo.security.deploy.DefaultRealmPrincipal;
041    import org.apache.geronimo.security.deploy.PrincipalInfo;
042    
043    
044    /**
045     * A collection of utility functions that assist with the configuration of
046     * <code>PolicyConfiguration</code>s.
047     *
048     * @version $Rev: 355877 $ $Date: 2005-12-10 18:48:27 -0800 (Sat, 10 Dec 2005) $
049     * @see javax.security.jacc.PolicyConfiguration
050     * @see "JSR 115" Java Authorization Contract for Containers
051     */
052    public class ConfigurationUtil {
053    
054        /**
055         * Create an X500Principal from a deployment description.
056         *
057         * @param name the distinguished name of the principal
058         * @return an X500Principal from a deployment description
059         */
060        public static X500Principal generateX500Principal(String name) {
061            return new X500Principal(name);
062        }
063    
064        /**
065         * Create a Principal from a deployment description.
066         *
067         * @param principalInfo the deployment description of the principal to be created.
068         * @param classLoader
069         * @return a RealmPrincipal from a deployment description
070         */
071        public static java.security.Principal generatePrincipal(final PrincipalInfo principalInfo, ClassLoader classLoader) {
072            return generatePrincipal(principalInfo.getClassName(), principalInfo.getPrincipalName(), classLoader);
073        }
074    
075        public static java.security.Principal generatePrincipal(final String className, final String principalName, final ClassLoader classLoader) {
076            try {
077                return (java.security.Principal) AccessController.doPrivileged(new PrivilegedExceptionAction() {
078                    public Object run() throws Exception {
079                        Class clazz = classLoader.loadClass(className);
080                        Constructor constructor = clazz.getDeclaredConstructor(new Class[]{String.class});
081                        return (java.security.Principal) constructor.newInstance(new Object[]{principalName});
082                    }
083                });
084            } catch (PrivilegedActionException e) {
085                e.printStackTrace();
086                if (e.getException() != null) {
087                    e.getException().printStackTrace();
088                }
089                return null;
090            }
091        }
092    
093        /**
094         * Create a RealmPrincipal from a deployment description.
095         *
096         * @param principalInfo the deployment description of the principal to be created.
097         * @param classLoader
098         * @return a RealmPrincipal from a deployment description
099         */
100        public static RealmPrincipal generateRealmPrincipal(final String realm, final String loginDomain, final PrincipalInfo principalInfo, ClassLoader classLoader) {
101            return generateRealmPrincipal(realm, loginDomain, principalInfo.getClassName(), principalInfo.getPrincipalName(), classLoader);
102        }
103    
104        public static RealmPrincipal generateRealmPrincipal(final String realm, final String loginDomain, final String className, final String principalName,
105                                                            ClassLoader classLoader)
106        {
107            return new RealmPrincipal(realm, loginDomain, generatePrincipal(className, principalName, classLoader));
108        }
109    
110        /**
111         * Create a DomainPrincipal from a deployment description.
112         *
113         * @param principalInfo the deployment description of the principal to be created.
114         * @param classLoader
115         * @return a RealmPrincipal from a deployment description
116         */
117        public static DomainPrincipal generateDomainPrincipal(final String loginDomain, final PrincipalInfo principalInfo, ClassLoader classLoader) {
118            return generateDomainPrincipal(loginDomain, principalInfo.getClassName(), principalInfo.getPrincipalName(), classLoader);
119        }
120    
121        public static DomainPrincipal generateDomainPrincipal(final String loginDomain, final String className, final String principalName, ClassLoader classLoader) {
122            return new DomainPrincipal(loginDomain, generatePrincipal(className, principalName, classLoader));
123        }
124    
125        /**
126         * Create a RealmPrincipal from a deployment description.
127         *
128         * @param principalInfo the deployment description of the principal to be created.
129         * @param classLoader
130         * @return a PrimaryRealmPrincipal from a deployment description
131         */
132        public static PrimaryRealmPrincipal generatePrimaryRealmPrincipal(final String realm, final String domain, final PrincipalInfo principalInfo, ClassLoader classLoader) throws DeploymentException {
133            return generatePrimaryRealmPrincipal(realm, domain, principalInfo.getClassName(), principalInfo.getPrincipalName(), classLoader);
134        }
135    
136        public static PrimaryRealmPrincipal generatePrimaryRealmPrincipal(final String realm, final String domain, final String className, final String principalName,
137                                                                          final ClassLoader classLoader) throws DeploymentException
138        {
139            try {
140                return (PrimaryRealmPrincipal) AccessController.doPrivileged(new PrivilegedExceptionAction() {
141                    public Object run() throws Exception {
142                        java.security.Principal p = null;
143                        Class clazz = classLoader.loadClass(className);
144                        Constructor constructor = clazz.getDeclaredConstructor(new Class[]{String.class});
145                        p = (java.security.Principal) constructor.newInstance(new Object[]{principalName});
146    
147                        return new PrimaryRealmPrincipal(realm, domain, p);
148                    }
149                });
150            } catch (PrivilegedActionException pae) {
151                throw new DeploymentException("Unable to create realm principal", pae.getException());
152            }
153        }
154    
155        /**
156         * Create a DomainPrincipal from a deployment description.
157         *
158         * @param principalInfo the deployment description of the principal to be created.
159         * @param classLoader
160         * @return a PrimaryDomainPrincipal from a deployment description
161         */
162        public static PrimaryDomainPrincipal generatePrimaryDomainPrincipal(final String domain, final PrincipalInfo principalInfo, ClassLoader classLoader) throws DeploymentException {
163            return generatePrimaryDomainPrincipal(domain, principalInfo.getClassName(), principalInfo.getPrincipalName(), classLoader);
164        }
165    
166        public static PrimaryDomainPrincipal generatePrimaryDomainPrincipal(final String domain, final String className, final String principalName,
167                                                                            final ClassLoader classLoader) throws DeploymentException
168        {
169            try {
170                return (PrimaryDomainPrincipal) AccessController.doPrivileged(new PrivilegedExceptionAction() {
171                    public Object run() throws Exception {
172                        java.security.Principal p = null;
173                        Class clazz = classLoader.loadClass(className);
174                        Constructor constructor = clazz.getDeclaredConstructor(new Class[]{String.class});
175                        p = (java.security.Principal) constructor.newInstance(new Object[]{principalName});
176    
177                        return new PrimaryDomainPrincipal(domain, p);
178                    }
179                });
180            } catch (PrivilegedActionException pae) {
181                throw new DeploymentException("Unable to create domain principal", pae.getException());
182            }
183        }
184    
185        /**
186         * Create a Principal from a deployment description.
187         *
188         * @param principalInfo the deployment description of the principal to be created.
189         * @param classLoader
190         * @return a Principal from a deployment description
191         */
192        public static PrimaryPrincipal generatePrimaryPrincipal(final PrincipalInfo principalInfo, ClassLoader classLoader) throws DeploymentException {
193            return generatePrimaryPrincipal(principalInfo.getClassName(), principalInfo.getPrincipalName(), classLoader);
194        }
195    
196        public static PrimaryPrincipal generatePrimaryPrincipal(final String className, final String principalName, final ClassLoader classLoader) throws DeploymentException {
197            try {
198                return (PrimaryPrincipal) AccessController.doPrivileged(new PrivilegedExceptionAction() {
199                    public Object run() throws Exception {
200                        java.security.Principal p = null;
201                        Class clazz = classLoader.loadClass(className);
202                        Constructor constructor = clazz.getDeclaredConstructor(new Class[]{String.class});
203                        p = (java.security.Principal) constructor.newInstance(new Object[]{principalName});
204    
205                        return new PrimaryPrincipal(p);
206                    }
207                });
208            } catch (PrivilegedActionException pae) {
209                throw new DeploymentException("Unable to create principal", pae.getException());
210            }
211        }
212    
213        /**
214         * Generate the default principal from the security config.
215         *
216         * @param defaultPrincipal
217         * @param classLoader
218         * @return the default principal
219         */
220        public static Subject generateDefaultSubject(DefaultPrincipal defaultPrincipal, ClassLoader classLoader) throws DeploymentException {
221            if (defaultPrincipal == null) {
222                throw new GeronimoSecurityException("No DefaultPrincipal configuration supplied");
223            }
224            Subject defaultSubject = new Subject();
225            java.security.Principal principal;
226            java.security.Principal primaryPrincipal;
227    
228            if (defaultPrincipal instanceof DefaultRealmPrincipal) {
229                DefaultRealmPrincipal defaultRealmPrincipal = (DefaultRealmPrincipal) defaultPrincipal;
230                principal = generateRealmPrincipal(defaultRealmPrincipal.getRealm(), defaultRealmPrincipal.getDomain(), defaultRealmPrincipal.getPrincipal(), classLoader);
231                primaryPrincipal = generatePrimaryRealmPrincipal(defaultRealmPrincipal.getRealm(), defaultRealmPrincipal.getDomain(), defaultRealmPrincipal.getPrincipal(), classLoader);
232            } else if (defaultPrincipal instanceof DefaultDomainPrincipal) {
233                DefaultDomainPrincipal defaultDomainPrincipal = (DefaultDomainPrincipal) defaultPrincipal;
234                principal = generateDomainPrincipal(defaultDomainPrincipal.getDomain(), defaultDomainPrincipal.getPrincipal(), classLoader);
235                primaryPrincipal = generatePrimaryDomainPrincipal(defaultDomainPrincipal.getDomain(), defaultDomainPrincipal.getPrincipal(), classLoader);
236            } else {
237                principal = generatePrincipal(defaultPrincipal.getPrincipal(), classLoader);
238                primaryPrincipal = generatePrimaryPrincipal(defaultPrincipal.getPrincipal(), classLoader);
239    
240            }
241            defaultSubject.getPrincipals().add(principal);
242            defaultSubject.getPrincipals().add(primaryPrincipal);
243    
244            Set namedUserPasswordCredentials = defaultPrincipal.getNamedUserPasswordCredentials();
245            if (namedUserPasswordCredentials != null) {
246                defaultSubject.getPrivateCredentials().addAll(namedUserPasswordCredentials);
247            }
248    
249            return defaultSubject;
250        }
251    
252    
253        /**
254         * A simple helper method to register PolicyContextHandlers
255         *
256         * @param handler an object that implements the <code>PolicyContextHandler</code>
257         *                interface. The value of this parameter must not be null.
258         * @param replace this boolean value defines the behavior of this method
259         *                if, when it is called, a <code>PolicyContextHandler</code> has already
260         *                been registered to handle the same key. In that case, and if the value
261         *                of this argument is true, the existing handler is replaced with the
262         *                argument handler. If the value of this parameter is false the existing
263         *                registration is preserved and an exception is thrown.
264         */
265        public static void registerPolicyContextHandler(PolicyContextHandler handler, boolean replace) throws PolicyContextException {
266            String[] keys = handler.getKeys();
267    
268            for (int i = 0; i < keys.length; i++) {
269                PolicyContext.registerHandler(keys[i], handler, replace);
270            }
271        }
272    
273    
274    }