KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > security > jauth > ConfigFile


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 package com.sun.enterprise.security.jauth;
25
26 import java.io.*;
27 import java.util.*;
28 import java.net.URL JavaDoc;
29
30 import java.lang.reflect.Constructor JavaDoc;
31 import java.lang.reflect.Method JavaDoc;
32 import java.lang.reflect.InvocationTargetException JavaDoc;
33
34 import javax.security.auth.Subject JavaDoc;
35 import javax.security.auth.callback.Callback JavaDoc;
36 import javax.security.auth.callback.CallbackHandler JavaDoc;
37 import javax.security.auth.callback.UnsupportedCallbackException JavaDoc;
38 import javax.security.auth.login.AppConfigurationEntry JavaDoc;
39
40 import sun.security.util.PropertyExpander;
41 import sun.security.util.Debug;
42
43 /**
44  * This is a default file-based AuthConfig implementation.
45  *
46  * @version %I%, %G%
47  */

48 class ConfigFile extends AuthConfig {
49
50     // indicates the age of the configuration approximately in
51
// terms of the number of times refresh has been called
52
private int epoch;
53
54     // parser class name
55
private String JavaDoc parserClassName;
56
57     // parser
58
private ConfigParser parser;
59
60     // package private for ConfigFileParser
61
static final String JavaDoc CLIENT = "client";
62     static final String JavaDoc SERVER = "server";
63
64     private static final String JavaDoc DEFAULT_HANDLER =
65             "auth.login.defaultCallbackHandler";
66
67     private static final String JavaDoc DEFAULT_PARSER_CLASS =
68     "com.sun.enterprise.security.jauth.ConfigXMLParser";
69
70     private static final Debug debug =
71             Debug.getInstance("configfile", "[ConfigFile]");
72
73     ConfigFile() throws IOException {
74     String JavaDoc propertyValue = System.getProperty("configfile.parser");
75     if (propertyValue == null) {
76         parserClassName = DEFAULT_PARSER_CLASS;
77     } else {
78         parserClassName = propertyValue;
79     }
80     this.epoch = 1;
81     parser = ConfigFile.loadParser(parserClassName);
82     }
83
84     /**
85      * Get a default ClientAuthContext.
86      *
87      * @return an instance of ConfigClient.
88      */

89     public ClientAuthContext getClientAuthContext(String JavaDoc intercept,
90                         String JavaDoc id,
91                         AuthPolicy requestPolicy,
92                         AuthPolicy responsePolicy,
93                         CallbackHandler JavaDoc handler)
94         throws AuthException {
95
96     ConfigFile.Entry[] entries = getEntries(intercept,
97                         id,
98                         requestPolicy,
99                         responsePolicy,
100                         CLIENT);
101     if (entries == null || entries.length == 0) {
102         return null;
103     }
104
105     // instantiate and initialize modules up front as well
106

107     if (handler == null) {
108         handler = ConfigFile.loadDefaultCallbackHandler();
109     } else if (handler instanceof DependentCallbackHandler) {
110         handler = new DelegatingHandler(handler);
111         }
112
113     for (int i = 0; i < entries.length; i++) {
114         entries[i].module = ConfigFile.createModule(entries[i], handler);
115     }
116
117     return new ConfigClient(entries);
118     }
119
120     /**
121      * Get a default ServerAuthContext.
122      *
123      * @return an instance of ConfigServer.
124      */

125     public ServerAuthContext getServerAuthContext(String JavaDoc intercept,
126                         String JavaDoc id,
127                         AuthPolicy requestPolicy,
128                         AuthPolicy responsePolicy,
129                         CallbackHandler JavaDoc handler)
130         throws AuthException {
131
132     ConfigFile.Entry[] entries = getEntries(intercept,
133                         id,
134                         requestPolicy,
135                         responsePolicy,
136                         SERVER);
137     if (entries == null || entries.length == 0) {
138         return null;
139     }
140
141     // instantiate and initialize modules up front as well
142

143     if (handler == null) {
144         handler = ConfigFile.loadDefaultCallbackHandler();
145     } else if (handler instanceof DependentCallbackHandler) {
146         handler = new DelegatingHandler(handler);
147         }
148
149     for (int i = 0; i < entries.length; i++) {
150         entries[i].module = ConfigFile.createModule(entries[i], handler);
151     }
152
153     return new ConfigServer(entries);
154     }
155
156     public void refresh() throws AuthException {
157     synchronized (parser) {
158         ConfigParser nextParser;
159         int next = this.epoch + 1;
160         try {
161         nextParser = ConfigFile.loadParser(parserClassName);
162         } catch (IOException ioe) {
163         throw new AuthException(ioe.toString());
164         }
165         this.epoch = (next == 0 ? 1 : next);
166         parser = nextParser;
167     }
168     }
169
170     private ConfigFile.Entry[] getEntries(String JavaDoc intercept,
171                 String JavaDoc id,
172                 AuthPolicy requestPolicy,
173                 AuthPolicy responsePolicy,
174                 String JavaDoc type) {
175
176     // get the parsed module config and DD information
177

178     HashMap configMap;
179
180     synchronized (parser) {
181         configMap = parser.getConfigMap();
182     }
183
184     if (configMap == null) {
185         return null;
186     }
187     
188     // get the module config info for this intercept
189

190     InterceptEntry intEntry = (InterceptEntry)configMap.get(intercept);
191     if (intEntry == null || intEntry.idMap == null) {
192         if (debug != null) {
193         debug.println("module config has no IDs configured for [" +
194                 intercept +
195                 "]");
196         }
197         return null;
198     }
199
200     // look up the DD's provider ID in the module config
201

202     IDEntry idEntry = null;
203     if (id == null || (idEntry = (IDEntry)intEntry.idMap.get(id)) == null) {
204
205         // either the DD did not specify a provider ID,
206
// or the DD-specified provider ID was not found
207
// in the module config.
208
//
209
// in either case, look for a default ID in the module config
210

211         if (debug != null) {
212         debug.println("DD did not specify ID, " +
213                 "or DD-specified ID for [" +
214                 intercept +
215                 "] not found in config -- " +
216                 "attempting to look for default ID");
217         }
218
219         String JavaDoc defaultID;
220         if (CLIENT.equals(type)) {
221         defaultID = intEntry.defaultClientID;
222         } else {
223         defaultID = intEntry.defaultServerID;
224         }
225
226         idEntry = (IDEntry)intEntry.idMap.get(defaultID);
227         if (idEntry == null) {
228
229         // did not find a default provider ID
230

231         if (debug != null) {
232             debug.println("no default config ID for [" +
233                     intercept +
234                     "]");
235         }
236         return null;
237         }
238     }
239
240     // we found the DD provider ID in the module config
241
// or we found a default module config
242

243     // check provider-type
244
if (idEntry.type.indexOf(type) < 0) {
245         if (debug != null) {
246         debug.println("request type [" +
247                 type +
248                 "] does not match config type [" +
249                 idEntry.type +
250                 "]");
251         }
252         return null;
253     }
254
255     // check whether a policy is set
256
AuthPolicy reqP = (requestPolicy != null || responsePolicy != null) ?
257         requestPolicy :
258         idEntry.requestPolicy; //default;
259

260     AuthPolicy respP = (requestPolicy != null || responsePolicy != null) ?
261         responsePolicy :
262         idEntry.responsePolicy; //default;
263

264     // optimization: if policy was not set, return null
265
if (reqP == null && respP == null) {
266         if (debug != null) {
267         debug.println("no policy applies");
268         }
269         return null;
270     }
271
272     // return the configured modules with the correct policies
273

274     ConfigFile.Entry[] entries = new Entry JavaDoc[idEntry.modules.size()];
275     for (int i = 0; i < entries.length; i++) {
276         AppConfigurationEntry JavaDoc aEntry =
277                 (AppConfigurationEntry JavaDoc)idEntry.modules.get(i);
278         entries[i] = new ConfigFile.Entry(reqP,
279                     respP,
280                     aEntry.getLoginModuleName(),
281                     aEntry.getControlFlag(),
282                     aEntry.getOptions());
283     }
284         
285     if (debug != null) {
286         debug.println("getEntries found " +
287             entries.length +
288             " entries for: " +
289             intercept +
290             " -- "
291             + id);
292
293         for (int i = 0; i < entries.length; i++) {
294         debug.println("Entry " + (i+1) + ":" +
295             "\n module class: " + entries[i].getLoginModuleName() +
296             "\n flag: " + entries[i].getControlFlag() +
297             "\n options: " + entries[i].getOptions() +
298             "\n request policy: " + entries[i].requestPolicy +
299             "\n response policy: " + entries[i].responsePolicy);
300         }
301     }
302
303     return entries;
304     }
305
306     /**
307      * get a custom config file parser
308      *
309      * XXX custom file that can be used in place of [domain|sun-acc].xml
310      */

311     private static ConfigParser loadParser(String JavaDoc className)
312         throws IOException {
313     try {
314
315         final String JavaDoc finalClassName = className;
316         final ClassLoader JavaDoc finalLoader = AuthConfig.getClassLoader();
317
318         return (ConfigParser)java.security.AccessController.doPrivileged
319         (new java.security.PrivilegedExceptionAction JavaDoc() {
320         public Object JavaDoc run() throws Exception JavaDoc {
321             Class JavaDoc c = Class.forName(finalClassName,true,finalLoader);
322             return c.newInstance();
323         }
324         });
325     } catch (java.security.PrivilegedActionException JavaDoc pae) {
326             IOException iex = new IOException(pae.getException().toString());
327             iex.initCause(pae.getException());
328             throw iex;
329     }
330     }
331
332     /**
333      * get the default callback handler
334      */

335     private static CallbackHandler JavaDoc loadDefaultCallbackHandler()
336         throws AuthException {
337
338         // get the default handler class
339
try {
340
341             final ClassLoader JavaDoc finalLoader = AuthConfig.getClassLoader();
342
343             return (CallbackHandler JavaDoc)
344                 java.security.AccessController.doPrivileged
345                 (new java.security.PrivilegedExceptionAction JavaDoc() {
346                 public Object JavaDoc run() throws Exception JavaDoc {
347  
348             String JavaDoc className =
349             System.getProperty("configfile.handler");
350  
351             if (className == null || className.length() == 0) {
352             className =
353                java.security.Security.getProperty(DEFAULT_HANDLER);
354             
355             if (className == null || className.length() == 0) {
356                             return null;
357                         }
358             }
359  
360             Class JavaDoc c = Class.forName(className,
361                         true,
362                         finalLoader);
363                     return c.newInstance();
364                 }
365             });
366         } catch (java.security.PrivilegedActionException JavaDoc pae) {
367             AuthException aex = new AuthException(pae.getException().toString());
368             aex.initCause(pae.getException());
369             throw aex;
370         }
371     }
372
373     /**
374      * Instantiate+initialize module class
375      */

376     private static Object JavaDoc createModule(ConfigFile.Entry entry,
377                     CallbackHandler JavaDoc handler)
378         throws AuthException {
379     try {
380
381         // instantiate module using no-arg constructor
382

383         Object JavaDoc newModule = entry.newInstance();
384
385         // initialize module
386

387         Object JavaDoc[] initArgs = { entry.getRequestPolicy(),
388                 entry.getResponsePolicy(),
389                 handler,
390                 entry.getOptions() };
391
392         boolean foundOne = false;
393         Method JavaDoc[] mArray = newModule.getClass().getMethods();
394         for (int i = 0; i < mArray.length; i++) {
395         if (mArray[i].getName().equals(AuthContext.INIT)) {
396             mArray[i].invoke(newModule, initArgs);
397             foundOne = true;
398             break;
399         }
400         }
401
402         if (foundOne) {
403         // return the new module
404
return newModule;
405         }
406
407         throw new SecurityException JavaDoc("could not find " +
408                 AuthContext.INIT +
409                 " method in module");
410
411     } catch (Exception JavaDoc e) {
412         if (e instanceof AuthException) {
413         throw (AuthException)e;
414         }
415         AuthException ae = new AuthException();
416         ae.initCause(e);
417         throw ae;
418     }
419     }
420
421     /**
422      * Class representing a single AuthModule entry configured
423      * for an ID, interception point, and stack.
424      *
425      * <p> An instance of this class contains the same
426      * information as its superclass, AppConfigurationEntry.
427      * It additionally stores the request and response policy assigned
428      * to this module.
429      *
430      * <p> This class also provides a way for a caller to obtain
431      * an instance of the module listed in the entry by invoking
432      * the <code>newInstance</code> method.
433      */

434     static class Entry extends javax.security.auth.login.AppConfigurationEntry JavaDoc {
435
436     // for loading modules
437
private static final Class JavaDoc[] PARAMS = { };
438     private static final Object JavaDoc[] ARGS = { };
439
440     private AuthPolicy requestPolicy;
441     private AuthPolicy responsePolicy;
442     Object JavaDoc module; // convenience location to store instance -
443
// package private for AuthContext
444

445     /**
446      * Construct a ConfigFile entry.
447      *
448      * <p> An entry encapsulates a single module and its related
449      * information.
450      *
451      * @param requestPolicy the request policy assigned to the module
452      * listed in this entry, which may be null.
453      *
454      * @param responsePolicy the response policy assigned to the module
455      * listed in this entry, which may be null.
456      *
457      * @param moduleClass the fully qualified class name of the module.
458      *
459      * @param flag the module control flag. This value must either
460      * be REQUIRED, REQUISITE, SUFFICIENT, or OPTIONAL.
461      *
462      * @param options the options configured for this module.
463      */

464     Entry(AuthPolicy requestPolicy,
465             AuthPolicy responsePolicy,
466             String JavaDoc moduleClass,
467             AppConfigurationEntry.LoginModuleControlFlag JavaDoc flag,
468             Map options) {
469         super(moduleClass, flag, options);
470         this.requestPolicy = requestPolicy;
471         this.responsePolicy = responsePolicy;
472     }
473
474     /**
475      * Return the request policy assigned to this module.
476      *
477      * @return the policy, which may be null.
478      */

479     AuthPolicy getRequestPolicy() {
480         return requestPolicy;
481     }
482
483     /**
484      * Return the response policy assigned to this module.
485      *
486      * @return the policy, which may be null.
487      */

488     AuthPolicy getResponsePolicy() {
489         return responsePolicy;
490     }
491
492     /**
493      * Return a new instance of the module contained in this entry.
494      *
495      * <p> The default implementation of this method attempts
496      * to invoke the default no-args constructor of the module class.
497      * This method may be overridden if a different constructor
498      * should be invoked.
499      *
500      * @return a new instance of the module contained in this entry.
501      *
502      * @exception AuthException if the instantiation failed.
503      */

504     Object JavaDoc newInstance() throws AuthException {
505         try {
506         final ClassLoader JavaDoc finalLoader= AuthConfig.getClassLoader();
507         String JavaDoc clazz = getLoginModuleName();
508         Class JavaDoc c = Class.forName(clazz,
509                     true,
510                     finalLoader);
511         java.lang.reflect.Constructor JavaDoc constructor =
512                     c.getConstructor(PARAMS);
513         return constructor.newInstance(ARGS);
514         } catch (Exception JavaDoc e) {
515         AuthException ae = new AuthException();
516         ae.initCause(e);
517         throw ae;
518         }
519     }
520     }
521
522     /**
523      * parsed Intercept entry
524      */

525     static class InterceptEntry {
526
527     String JavaDoc defaultClientID;
528     String JavaDoc defaultServerID;
529     HashMap idMap;
530
531     InterceptEntry(String JavaDoc defaultClientID,
532         String JavaDoc defaultServerID,
533         HashMap idMap) {
534         this.defaultClientID = defaultClientID;
535         this.defaultServerID = defaultServerID;
536         this.idMap = idMap;
537     }
538     }
539
540     /**
541      * parsed ID entry
542      */

543     static class IDEntry {
544
545     private String JavaDoc type; // provider type (client, server, client-server)
546
private AuthPolicy requestPolicy;
547     private AuthPolicy responsePolicy;
548     private ArrayList modules;
549
550     IDEntry(String JavaDoc type,
551         AuthPolicy requestPolicy,
552         AuthPolicy responsePolicy,
553         ArrayList modules) {
554
555         this.type = type;
556         this.modules = modules;
557         this.requestPolicy = requestPolicy;
558         this.responsePolicy = responsePolicy;
559     }
560
561     // XXX delete this later
562
IDEntry(String JavaDoc type,
563         String JavaDoc requestPolicy,
564         String JavaDoc responsePolicy,
565         ArrayList modules) {
566
567         this.type = type;
568
569         if (requestPolicy != null) {
570         this.requestPolicy =
571             new AuthPolicy(AuthPolicy.SOURCE_AUTH_SENDER,
572                     true, // recipient-auth
573
true); // beforeContent
574
}
575         if (responsePolicy != null) {
576         this.responsePolicy =
577             new AuthPolicy(AuthPolicy.SOURCE_AUTH_CONTENT,
578                     true, // recipient-auth
579
false); // beforeContent
580
}
581
582         this.modules = modules;
583     }
584     }
585
586     /**
587      * Default implementation of ClientAuthContext.
588      */

589     private static class ConfigClient implements ClientAuthContext {
590
591     // class that does all the work
592
private AuthContext context;
593
594     private static final sun.security.util.Debug debug =
595         sun.security.util.Debug.getInstance("configclient",
596                         "[ConfigClient]");
597
598     ConfigClient(Entry JavaDoc[] entries) throws AuthException {
599         context = new AuthContext(entries, debug);
600     }
601
602     public void secureRequest(AuthParam param,
603                 Subject JavaDoc subject,
604                 Map sharedState)
605         throws AuthException {
606
607         // invoke modules
608
Object JavaDoc[] args = { param, subject, sharedState };
609         context.invoke(AuthContext.SECURE_REQUEST, args);
610     }
611
612     public void validateResponse(AuthParam param,
613                 Subject JavaDoc subject,
614                 Map sharedState)
615         throws AuthException {
616         // invoke modules
617
Object JavaDoc[] args = { param, subject, sharedState };
618         context.invoke(AuthContext.VALIDATE_RESPONSE, args);
619     }
620
621     public void disposeSubject(Subject JavaDoc subject,
622                 Map sharedState)
623         throws AuthException {
624         // invoke modules
625
Object JavaDoc[] args = { subject, sharedState };
626         context.invoke(AuthContext.DISPOSE_SUBJECT, args);
627     }
628     }
629
630     /**
631      * Default implementation of ServerAuthContext.
632      */

633     private static class ConfigServer implements ServerAuthContext {
634
635     // class that does all the work
636
private AuthContext context;
637
638     private static final sun.security.util.Debug debug =
639         sun.security.util.Debug.getInstance("configserver",
640                         "[ConfigServer]");
641
642     ConfigServer(Entry JavaDoc[] entries) throws AuthException {
643
644         context = new AuthContext(entries, debug);
645     }
646
647     public void validateRequest(AuthParam param,
648                 Subject JavaDoc subject,
649                 Map sharedState)
650         throws AuthException {
651         // invoke modules
652
Object JavaDoc[] args = { param, subject, sharedState };
653         context.invoke(AuthContext.VALIDATE_REQUEST, args);
654     }
655
656     public void secureResponse(AuthParam param,
657                 Subject JavaDoc subject,
658                 Map sharedState)
659         throws AuthException {
660         // invoke modules
661
Object JavaDoc[] args = { param, subject, sharedState };
662         context.invoke(AuthContext.SECURE_RESPONSE, args);
663     }
664
665     public void disposeSubject(Subject JavaDoc subject,
666                 Map sharedState)
667         throws AuthException {
668         // invoke modules
669
Object JavaDoc[] args = { subject, sharedState };
670         context.invoke(AuthContext.DISPOSE_SUBJECT, args);
671     }
672
673     public boolean managesSessions(Map sharedState)
674         throws AuthException {
675             
676         // invoke modules
677
Object JavaDoc[] args = { sharedState };
678         Object JavaDoc[] rValues = null;
679
680         try {
681         rValues = context.invoke(AuthContext.MANAGES_SESSIONS, args);
682         } catch (AuthException ae) {
683         // this new method may not be implemeneted
684
// by old modules
685
if (!(ae.getCause() instanceof NoSuchMethodException JavaDoc)) {
686             throw ae;
687         }
688         }
689
690         boolean rvalue = false;
691
692         for (int i=0; rValues != null && i<rValues.length; i++) {
693         if (rValues[i] != null) {
694             boolean thisValue = ((Boolean JavaDoc) rValues[i]).booleanValue();
695             rvalue = rvalue | thisValue;
696         }
697         }
698
699         return rvalue;
700     }
701     }
702
703     private class DelegatingHandler implements CallbackHandler JavaDoc {
704
705     CallbackHandler JavaDoc handler;
706
707     CallbackHandler JavaDoc defaultHandler;
708
709     private DelegatingHandler(CallbackHandler JavaDoc cbh) {
710         handler = cbh;
711         try {
712         defaultHandler = ConfigFile.loadDefaultCallbackHandler();
713         } catch (Exception JavaDoc e) {
714         defaultHandler = null;
715         }
716     }
717
718     public void handle (Callback JavaDoc[] callbacks)
719     throws IOException, UnsupportedCallbackException JavaDoc {
720         if (defaultHandler == null) {
721         handler.handle(callbacks);
722         }
723         else {
724         Callback JavaDoc[] oneCallback = new Callback JavaDoc[1];
725         for (int i=0; i<callbacks.length; i++) {
726             
727             boolean tryDefault = false;
728             
729             oneCallback[0] = callbacks[i];
730             try {
731             handler.handle(oneCallback);
732             } catch (UnsupportedCallbackException JavaDoc uce) {
733             tryDefault = true;
734             }
735             if (tryDefault) {
736             defaultHandler.handle(oneCallback);
737             }
738         }
739         }
740     }
741     }
742
743 }
744
Popular Tags