Project Report: fawkez

Packagesummary org.jcoderz.commons.connector

org.jcoderz.commons.connector.SecurityUtil

LineHitsNoteSource
1  /*
2   * $Id: SecurityUtil.java 1011 2008-06-16 17:57:36Z amandel $
3   *
4   * Copyright 2006, The jCoderZ.org Project. All rights reserved.
5   *
6   * Redistribution and use in source and binary forms, with or without
7   * modification, are permitted provided that the following conditions are
8   * met:
9   *
10   *    * Redistributions of source code must retain the above copyright
11   *      notice, this list of conditions and the following disclaimer.
12   *    * Redistributions in binary form must reproduce the above
13   *      copyright notice, this list of conditions and the following
14   *      disclaimer in the documentation and/or other materials
15   *      provided with the distribution.
16   *    * Neither the name of the jCoderZ.org Project nor the names of
17   *      its contributors may be used to endorse or promote products
18   *      derived from this software without specific prior written
19   *      permission.
20   *
21   * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
22   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24   * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS
25   * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28   * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30   * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31   * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32   */
33  package org.jcoderz.commons.connector;
34   
35  import java.security.AccessController;
36  import java.security.PrivilegedAction;
37  import java.util.Iterator;
38  import java.util.Set;
39  import java.util.logging.Level;
40  import java.util.logging.Logger;
41   
42  import javax.resource.spi.ConnectionRequestInfo;
43  import javax.resource.spi.ManagedConnectionFactory;
44  import javax.resource.spi.SecurityException;
45  import javax.resource.spi.security.GenericCredential;
46  import javax.resource.spi.security.PasswordCredential;
47  import javax.security.auth.Subject;
48   
49  /**
50   * Utility provides method to extract user name and password from a set of
51   * security relevant objects such as
52   * {@link javax.resource.spi.security.PasswordCredential},
53   * {@link javax.resource.spi.ConnectionRequestInfo} and so on.
54   *
55   */
56 (1)public final class SecurityUtil
57  {
58     /** The full qualified name of this class. */
59     private static final String CLASSNAME = SecurityUtil.class.getName();
60   
61     /** The logger to use. */
62     private static final Logger logger = Logger.getLogger(CLASSNAME);
63   
64     private SecurityUtil ()
65     {
66   
67     }
68   
69     /**
70      * Extracts the user name and password from the given set of objects as
71      * specified in the JCA 1.0 Chapter 8.2.6.
72      *
73      * @param subject Current Security Subject passed by the application server.
74      * @param mcf The managed connection factory
75      * @param cri Connection reques info
76      *
77      * @return UserPassword instance. If no user name / password can be
78      * extracted, this method returns {@link UserPassword#EMPTY_USER_PASSWORD}.
79      *
80      * @throws SecurityException Thown if no applicable credentials found in
81      * the Subject.
82      */
83     public static UserPassword getUserPassword (Subject subject,
84        ManagedConnectionFactory mcf, ConnectionRequestInfo cri)
85           throws SecurityException
86     {
87        final String method = "getUserPassword";
88        final boolean finer = logger.isLoggable(Level.FINER);
89        if (finer)
90        {
91           logger.entering(CLASSNAME, method, new Object [] {subject, mcf, cri});
92        }
93   
94        UserPassword result = UserPassword.EMPTY_USER_PASSWORD;
95   
96        if (subject != null)
97        {
98           // JCA 1.0 8.2.6 Contract for RA (Option A)
99           final PasswordCredential pc = PrivilegedExecutor.getPasswordCredential(
100                 subject, mcf);
101           if (pc != null)
102           {
103              result = UserPassword.fromUserPassword(pc.getUserName(), new String(
104                    pc.getPassword()));
105           }
106           else
107           {
108              final SecurityException rse = new SecurityException(
109                    "No applicable credentials found in the Subject passed by the"
110                          + " application server.");
111   
112              logger.throwing(CLASSNAME, method, rse);
113 (2)            throw rse;
114   
115 (3)            // TODO Implements this path if required. (required ?)
116   
117              // JCA 1.0 8.2.6 Contract for RA (Option B)
118              /*
119              final GenericCredential gc
120                    = PrivilegedExecutor.getGenericCredential(subject, mcf);
121  
122              if (gc == null)
123              {
124                 throw new SecurityException("No applicable credentials found in"
125                       + " the Subject passed by the application server.");
126              }
127              */
128           }
129   
130        }
131        else if (cri != null)
132        {
133           // JCA 1.0 8.2.6 Contract for RA (Option C)
134           if (!(cri instanceof ConnectionRequestInfoBase))
135           {
136              final SecurityException rse = new SecurityException("No applicable "
137                    + "ConnectionRequestInfo passed by the application server.");
138              logger.throwing(CLASSNAME, method, rse);
139 (4)            throw rse;
140           }
141   
142           result = UserPassword.fromUserPassword(
143                 ((ConnectionRequestInfoBase) cri).getUserPassword());
144        }
145   
146        if (finer)
147        {
148           logger.exiting(CLASSNAME, method, result);
149        }
150   
151        return result;
152     }
153   
154     /**
155      * This class is intended to execute a privileged action.
156      * The security contract assumes that a resource adapter has the necessary
157      * security permissions to extract a private credential set from a Subject
158      * instance.
159      */
160     private static class PrivilegedExecutor
161           implements PrivilegedAction
162     {
163        private final Subject mSubject;
164        private final ManagedConnectionFactory mMcf;
165        private final boolean mPcAction;
166   
167        PrivilegedExecutor (Subject subject, ManagedConnectionFactory mcf,
168              boolean pcAction)
169        {
170           mSubject = subject;
171           mMcf = mcf;
172           mPcAction = pcAction;
173        }
174   
175        /** {@inheritDoc} */
176        public Object run ()
177        {
178           final Object result;
179           if (mPcAction)
180           {
181              result = getPwdCredential();
182           }
183           else
184           {
185              result = getGenCredential();
186           }
187           return result;
188        }
189   
190        private Object getPwdCredential ()
191        {
192           // This method implements the behavior of a Resource Adapter specified
193           // in the JCA 1.0 8.2.6 Contract for RA (Option A)
194   
195           // The resource adapter explicitly checks whether the passed Subject
196           // instance carries a PasswordCredential instance using the
197           // Subject.getPrivateCredentials method.
198           final Set creds = mSubject.getPrivateCredentials(
199                 PasswordCredential.class);
200           PasswordCredential pc = null;
201           // Since a Subject instance can carry multiple PasswordCredential
202           // instances, a Managed- ConnectionFactory should only use a
203           // PasswordCredential instance that has been specifically passed to
204           // it through the security contract.
205           final Iterator credentials = creds.iterator();
206           while (credentials.hasNext())
207           {
208              final PasswordCredential pcCurrent
209                    = (PasswordCredential) credentials.next();
210   
211              // The ManagedConnectionFactory implementation uses the equals
212              // method to compare itself with the passed instance.
213              if (pcCurrent.getManagedConnectionFactory().equals(mMcf))
214              {
215                 pc = pcCurrent;
216                 break;
217              }
218           }
219           return pc;
220        }
221   
222        private Object getGenCredential ()
223        {
224           // This method implements the behavior of a Resource Adapter specified
225           // in the JCA 1.0 8.2.6 Contract for RA (Option B)
226   
227           // The resource adapter explicitly checks whether passed Subject
228           // instance carries a GenericCredential instance using the methods
229           // getPrivateCredentials and getPublicCredentials defined on the
230           // Subject interface.
231           final Set creds = mSubject.getPrivateCredentials(
232                 GenericCredential.class);
233   
234           Object result = null;
235   
236           final Iterator credentials = creds.iterator();
237           while (credentials.hasNext())
238           {
239              final GenericCredential c = (GenericCredential) credentials.next();
240              result = c;
241              break;
242           }
243           return result;
244        }
245   
246        /**
247         * Tries to extract a PasswordCredential from the Subject
248         * <code>subject</code> applicable to the managed connection factory
249         * <code>mcf</code>.
250         * Executes a privileged action.
251         *
252         *
253         * @param subject Current Security Subject passed by the
254         *    application server.
255         * @param mcf The managed connection factory
256         *
257         * @return a PasswordCredential or null.
258         */
259        static PasswordCredential getPasswordCredential (Subject subject,
260              ManagedConnectionFactory mcf)
261        {
262           return (PasswordCredential) AccessController.doPrivileged(
263                 new PrivilegedExecutor(subject, mcf, true));
264        }
265   
266        /**
267         * Tries to extract a GenericCredential from the Subject
268         * <code>subject</code> applicable to the managed connection factory
269         * <code>mcf</code>.
270         * Executes a privileged action.
271         *
272         * @param subject Current Security Subject passed by the application
273         *    server.
274         *
275         * @param mcf The managed connection factory
276         *
277         * @return a GenericCredential or null.
278         */
279        static GenericCredential getGenericCredential (Subject subject,
280              ManagedConnectionFactory mcf)
281        {
282           return (GenericCredential) AccessController.doPrivileged(
283                 new PrivilegedExecutor(subject, mcf, false));
284        }
285     }
286  }
287   

Findings in this File

c (1) 56 : 0 Type Javadoc comment is missing an @author tag.
i (2) 113 : 0 method org.jcoderz.commons.connector.SecurityUtil.getUserPassword(Subject, ManagedConnectionFactory, ConnectionRequestInfo) throws exception with static message string
i (3) 115 : 0 Comment matches to-do format '(TODO|FIXME|CHECKME)'.
i (4) 139 : 0 method org.jcoderz.commons.connector.SecurityUtil.getUserPassword(Subject, ManagedConnectionFactory, ConnectionRequestInfo) throws exception with static message string