KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jonas > security > auth > spi > CRLLoginModule


1 /**
2  * JOnAS: Java(TM) Open Application Server
3  * Copyright (C) 1999-2004 Bull S.A.
4  * Contact: jonas-team@objectweb.org
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or 1any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19  * USA
20  *
21  * Initial developer: Alexandre Thaveau & Marc-Antoine Bourgeot
22  * --------------------------------------------------------------------------
23  * $Id: CRLLoginModule.java,v 1.2 2004/05/25 15:13:28 benoitf Exp $
24  * --------------------------------------------------------------------------
25  */

26
27 package org.objectweb.jonas.security.auth.spi;
28
29 import java.io.File JavaDoc;
30 import java.io.FileInputStream JavaDoc;
31 import java.security.cert.CertStore JavaDoc;
32 import java.security.cert.CertStoreParameters JavaDoc;
33 import java.security.cert.CertificateFactory JavaDoc;
34 import java.security.cert.CollectionCertStoreParameters JavaDoc;
35 import java.security.cert.LDAPCertStoreParameters JavaDoc;
36 import java.security.cert.X509CRL JavaDoc;
37 import java.security.cert.X509CRLSelector JavaDoc;
38 import java.security.cert.X509Certificate JavaDoc;
39 import java.util.ArrayList JavaDoc;
40 import java.util.Iterator JavaDoc;
41 import java.util.Map JavaDoc;
42
43 import javax.security.auth.Subject JavaDoc;
44 import javax.security.auth.callback.Callback JavaDoc;
45 import javax.security.auth.callback.CallbackHandler JavaDoc;
46 import javax.security.auth.callback.NameCallback JavaDoc;
47 import javax.security.auth.login.LoginException JavaDoc;
48 import javax.security.auth.spi.LoginModule JavaDoc;
49
50 import org.objectweb.jonas.security.auth.JPrincipal;
51 import org.objectweb.jonas.security.auth.callback.CertificateCallback;
52
53 /**
54  * Defines a login module for the authentication by using certificates
55  * @author Alexandre Thaveau (initial developer)
56  * @author Marc-Antoine Bourgeot (initial developer)
57  */

58 public class CRLLoginModule implements LoginModule JavaDoc {
59
60     /**
61      * Subject used
62      */

63     private Subject JavaDoc subject = null;
64
65     /**
66      * The callbackhandler user for identification
67      */

68     private CallbackHandler JavaDoc callbackHandler = null;
69
70     /**
71      * Shared state with all login modules
72      */

73     private Map JavaDoc sharedState = null;
74
75     /**
76      * Options for this login module
77      */

78     private Map JavaDoc options = null;
79
80     /**
81      * Name of the principal
82      */

83     private String JavaDoc principalName = null;
84
85     /**
86      * Password f the principal
87      */

88     private String JavaDoc password = null;
89
90     /**
91      * Roles of the principal
92      */

93     private ArrayList JavaDoc principalRoles = null;
94
95     /**
96      * Certificate of the user
97      */

98     private X509Certificate JavaDoc cert = null;
99
100     /**
101      * Initialize this LoginModule. This method is called by the LoginContext
102      * after this LoginModule has been instantiated. The purpose of this method
103      * is to initialize this LoginModule with the relevant information. If this
104      * LoginModule does not understand any of the data stored in sharedState or
105      * options parameters, they can be ignored.
106      * @param subject the Subject to be authenticated.
107      * @param callbackHandler a CallbackHandler for communicating with the end
108      * user (prompting for usernames and passwords, for example).
109      * @param sharedState state shared with other configured LoginModules.
110      * @param options options specified in the login Configuration for this
111      * particular LoginModule.
112      */

113     public void initialize(Subject JavaDoc subject, CallbackHandler JavaDoc callbackHandler, Map JavaDoc sharedState, Map JavaDoc options) {
114         this.subject = subject;
115         this.callbackHandler = callbackHandler;
116         this.sharedState = sharedState;
117         this.options = options;
118     }
119
120     /**
121      * Method to authenticate a Subject (phase 1). The implementation of this
122      * method authenticates a Subject. For example, it may prompt for Subject
123      * information such as a username and password and then attempt to verify
124      * the password. This method saves the result of the authentication attempt
125      * as private state within the LoginModule.
126      * @return true if the authentication succeeded, or false if this
127      * LoginModule should be ignored.
128      * @throws LoginException if the authentication fails
129      */

130     public boolean login() throws LoginException JavaDoc {
131
132         // No handler
133
if (callbackHandler == null) {
134             throw new LoginException JavaDoc("No handler has been defined.");
135         }
136         String JavaDoc crlsResourceName = (String JavaDoc) options.get("CRLsResourceName");
137         String JavaDoc certStoreAccessName = null;
138         NameCallback JavaDoc nameCallback = null;
139         CertificateCallback certificateCallback = null;
140         try {
141             // Handle callbacks, here just the certificate and name, name and
142
// password are already checked
143
nameCallback = new NameCallback JavaDoc("User :");
144             certificateCallback = new CertificateCallback();
145             Callback JavaDoc[] callbacks = new Callback JavaDoc[] {nameCallback, certificateCallback};
146             callbackHandler.handle(callbacks);
147         } catch (Exception JavaDoc e) {
148             throw new LoginException JavaDoc("Problem while getting informations in the callbackhandler: " + e.getMessage());
149         }
150
151         try {
152             this.cert = (X509Certificate JavaDoc) certificateCallback.getUserCertificate();
153             if (nameCallback.getName().startsWith("##DN##")) {
154                 if ((this.cert == null)) {
155                     throw new LoginException JavaDoc("Client certificate not present, it can be verified with CRL");
156                 }
157             } else {
158                 //if client to be authenticated doesn't require a certificate
159
// based access -> ok
160
return true;
161             }
162
163             //store the parameters of the CertStore
164
CertStoreParameters JavaDoc certStoreParameters = null;
165             //two choices : directory, LDAP
166
//initialization of an Directory certstore
167
if (crlsResourceName.equalsIgnoreCase("Directory")) {
168                 certStoreAccessName = "Collection";
169                 // Directory where are stocked the CRLs
170
String JavaDoc crlsDirectoryName = (String JavaDoc) options.get("CRLsDirectoryName");
171                 // No resource is specified -> fail
172
if (crlsDirectoryName == null) {
173                     throw new LoginException JavaDoc(
174                             "You have to give an argument to this login module. The \"CRLsDirectoryName\" parameter is required.");
175                 }
176                 File JavaDoc crlsDirectory = new File JavaDoc(crlsDirectoryName);
177                 if (!crlsDirectory.isDirectory()) {
178                     throw new LoginException JavaDoc(crlsDirectoryName + " is not a directory");
179                 }
180                 //list files located in the directory
181
CertificateFactory JavaDoc cf = CertificateFactory.getInstance("X.509");
182                 FileInputStream JavaDoc fis = null;
183                 //file name array for all CRLs
184
String JavaDoc[] crlFileName = crlsDirectory.list();
185                 //collection to stock X509CRL objects
186
ArrayList JavaDoc crls = new ArrayList JavaDoc(crlFileName.length);
187                 X509CRL JavaDoc crl = null;
188
189                 for (int i = 0; i < crlFileName.length; i++) {
190                     //extension of the file must be .crl
191
if (crlFileName[i].matches(".+\\.crl")) {
192                         fis = new FileInputStream JavaDoc(crlsDirectory.getAbsolutePath() + File.separatorChar + crlFileName[i]);
193                         crl = (X509CRL JavaDoc) cf.generateCRL(fis);
194                         crls.add(crl);
195                         fis.close();
196                         fis = null;
197                         crl = null;
198                     }
199                 }
200                 //initialize the certstore
201
certStoreParameters = new CollectionCertStoreParameters JavaDoc(crls);
202             } else if (crlsResourceName.equalsIgnoreCase("LDAP")) {
203                 //initialization of an LDAP certstore
204
certStoreAccessName = "LDAP";
205                 //get the address and the port of the server
206
String JavaDoc address = (String JavaDoc) options.get("address");
207                 int port = Integer.parseInt((String JavaDoc) options.get("port"));
208                 if (address == null) {
209                     throw new LoginException JavaDoc(
210                             "You have to give an argument to this login module. The \"address\" and \"port\" parameter are required.");
211                 }
212                 //initialize the certstore
213
certStoreParameters = new LDAPCertStoreParameters JavaDoc(address, port);
214             } else {
215                 throw new LoginException JavaDoc(
216                         "You have to give an argument to this login module. The \"CRLsResourceName\" is not valid. Must be set to \"Directory\" or \"LDAP\"");
217             }
218
219             //check if the client certificate has not been revoked
220
CertStore JavaDoc crlsStore = CertStore.getInstance(certStoreAccessName, certStoreParameters);
221             X509CRLSelector JavaDoc x509CRLSelector = new X509CRLSelector JavaDoc();
222             //add a selection criterion to check the right CRLs, here issuer
223
// name
224
//of CRL and certificate must be the same
225
x509CRLSelector.addIssuerName(this.cert.getIssuerX500Principal().getEncoded());
226             Iterator JavaDoc crlIterator = crlsStore.getCRLs(x509CRLSelector).iterator();
227             while (crlIterator.hasNext()) {
228                 if (((X509CRL JavaDoc) crlIterator.next()).isRevoked(this.cert)) {
229                     throw new LoginException JavaDoc("Client certificate has been revoked");
230                 }
231             }
232         } catch (Exception JavaDoc e) {
233             throw new LoginException JavaDoc("Error during the login phase : " + e.getMessage());
234         }
235
236         return true;
237     }
238
239     /**
240      * Method to commit the authentication process (phase 2). This method is
241      * called if the LoginContext's overall authentication succeeded (the
242      * relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules
243      * succeeded). If this LoginModule's own authentication attempt succeeded
244      * (checked by retrieving the private state saved by the login method), then
245      * this method associates relevant Principals and Credentials with the
246      * Subject located in the LoginModule. If this LoginModule's own
247      * authentication attempted failed, then this method removes/destroys any
248      * state that was originally saved.
249      * @return true if this method succeeded, or false if this LoginModule
250      * should be ignored.
251      * @throws LoginException if the commit fails
252      */

253     public boolean commit() throws LoginException JavaDoc {
254         return true;
255     }
256
257     /**
258      * Method to abort the authentication process (phase 2). This method is
259      * called if the LoginContext's overall authentication failed. (the relevant
260      * REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules did not
261      * succeed). If this LoginModule's own authentication attempt succeeded
262      * (checked by retrieving the private state saved by the login method), then
263      * this method cleans up any state that was originally saved.
264      * @return true if this method succeeded, or false if this LoginModule
265      * should be ignored.
266      * @throws LoginException if the abort fails
267      */

268     public boolean abort() throws LoginException JavaDoc {
269
270         // Reset temp values
271
principalName = null;
272         principalRoles = null;
273
274         return true;
275     }
276
277     /**
278      * Method which logs out a Subject. An implementation of this method might
279      * remove/destroy a Subject's Principals and Credentials.
280      * @return true if this method succeeded, or false if this LoginModule
281      * should be ignored.
282      * @throws LoginException if the logout fails
283      */

284     public boolean logout() throws LoginException JavaDoc {
285
286         // Remove principal name
287
subject.getPrincipals().remove(new JPrincipal(principalName));
288
289         return true;
290     }
291
292 }
Popular Tags