CRLLoginModule.java

00001 
00027 package org.objectweb.jonas.security.auth.spi;
00028 
00029 import java.io.File;
00030 import java.io.FileInputStream;
00031 import java.security.cert.CertStore;
00032 import java.security.cert.CertStoreParameters;
00033 import java.security.cert.CertificateFactory;
00034 import java.security.cert.CollectionCertStoreParameters;
00035 import java.security.cert.LDAPCertStoreParameters;
00036 import java.security.cert.X509CRL;
00037 import java.security.cert.X509CRLSelector;
00038 import java.security.cert.X509Certificate;
00039 import java.util.ArrayList;
00040 import java.util.Iterator;
00041 import java.util.Map;
00042 
00043 import javax.security.auth.Subject;
00044 import javax.security.auth.callback.Callback;
00045 import javax.security.auth.callback.CallbackHandler;
00046 import javax.security.auth.callback.NameCallback;
00047 import javax.security.auth.login.LoginException;
00048 import javax.security.auth.spi.LoginModule;
00049 
00050 import org.objectweb.jonas.security.auth.JPrincipal;
00051 import org.objectweb.jonas.security.auth.callback.CertificateCallback;
00052 
00058 public class CRLLoginModule implements LoginModule {
00059 
00063     private Subject subject = null;
00064 
00068     private CallbackHandler callbackHandler = null;
00069 
00073     private Map sharedState = null;
00074 
00078     private Map options = null;
00079 
00083     private String principalName = null;
00084 
00088     private String password = null;
00089 
00093     private ArrayList principalRoles = null;
00094 
00098     private X509Certificate cert = null;
00099 
00113     public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {
00114         this.subject = subject;
00115         this.callbackHandler = callbackHandler;
00116         this.sharedState = sharedState;
00117         this.options = options;
00118     }
00119 
00130     public boolean login() throws LoginException {
00131 
00132         // No handler
00133         if (callbackHandler == null) {
00134             throw new LoginException("No handler has been defined.");
00135         }
00136         String crlsResourceName = (String) options.get("CRLsResourceName");
00137         String certStoreAccessName = null;
00138         NameCallback nameCallback = null;
00139         CertificateCallback certificateCallback = null;
00140         try {
00141             // Handle callbacks, here just the certificate and name, name and
00142             // password are already checked
00143             nameCallback = new NameCallback("User :");
00144             certificateCallback = new CertificateCallback();
00145             Callback[] callbacks = new Callback[] {nameCallback, certificateCallback};
00146             callbackHandler.handle(callbacks);
00147         } catch (Exception e) {
00148             throw new LoginException("Problem while getting informations in the callbackhandler: " + e.getMessage());
00149         }
00150 
00151         try {
00152             this.cert = (X509Certificate) certificateCallback.getUserCertificate();
00153             if (nameCallback.getName().startsWith("##DN##")) {
00154                 if ((this.cert == null)) {
00155                     throw new LoginException("Client certificate not present, it can be verified with CRL");
00156                 }
00157             } else {
00158                 //if client to be authenticated doesn't require a certificate
00159                 // based access -> ok
00160                 return true;
00161             }
00162 
00163             //store the parameters of the CertStore
00164             CertStoreParameters certStoreParameters = null;
00165             //two choices : directory, LDAP
00166             //initialization of an Directory certstore
00167             if (crlsResourceName.equalsIgnoreCase("Directory")) {
00168                 certStoreAccessName = "Collection";
00169                 // Directory where are stocked the CRLs
00170                 String crlsDirectoryName = (String) options.get("CRLsDirectoryName");
00171                 // No resource is specified -> fail
00172                 if (crlsDirectoryName == null) {
00173                     throw new LoginException(
00174                             "You have to give an argument to this login module. The \"CRLsDirectoryName\" parameter is required.");
00175                 }
00176                 File crlsDirectory = new File(crlsDirectoryName);
00177                 if (!crlsDirectory.isDirectory()) {
00178                     throw new LoginException(crlsDirectoryName + " is not a directory");
00179                 }
00180                 //list files located in the directory
00181                 CertificateFactory cf = CertificateFactory.getInstance("X.509");
00182                 FileInputStream fis = null;
00183                 //file name array for all CRLs
00184                 String[] crlFileName = crlsDirectory.list();
00185                 //collection to stock X509CRL objects
00186                 ArrayList crls = new ArrayList(crlFileName.length);
00187                 X509CRL crl = null;
00188 
00189                 for (int i = 0; i < crlFileName.length; i++) {
00190                     //extension of the file must be .crl
00191                     if (crlFileName[i].matches(".+\\.crl")) {
00192                         fis = new FileInputStream(crlsDirectory.getAbsolutePath() + File.separatorChar + crlFileName[i]);
00193                         crl = (X509CRL) cf.generateCRL(fis);
00194                         crls.add(crl);
00195                         fis.close();
00196                         fis = null;
00197                         crl = null;
00198                     }
00199                 }
00200                 //initialize the certstore
00201                 certStoreParameters = new CollectionCertStoreParameters(crls);
00202             } else if (crlsResourceName.equalsIgnoreCase("LDAP")) {
00203                 //initialization of an LDAP certstore
00204                 certStoreAccessName = "LDAP";
00205                 //get the address and the port of the server
00206                 String address = (String) options.get("address");
00207                 int port = Integer.parseInt((String) options.get("port"));
00208                 if (address == null) {
00209                     throw new LoginException(
00210                             "You have to give an argument to this login module. The \"address\" and \"port\" parameter are required.");
00211                 }
00212                 //initialize the certstore
00213                 certStoreParameters = new LDAPCertStoreParameters(address, port);
00214             } else {
00215                 throw new LoginException(
00216                         "You have to give an argument to this login module. The \"CRLsResourceName\" is not valid. Must be set to \"Directory\" or \"LDAP\"");
00217             }
00218 
00219             //check if the client certificate has not been revoked
00220             CertStore crlsStore = CertStore.getInstance(certStoreAccessName, certStoreParameters);
00221             X509CRLSelector x509CRLSelector = new X509CRLSelector();
00222             //add a selection criterion to check the right CRLs, here issuer
00223             // name
00224             //of CRL and certificate must be the same
00225             x509CRLSelector.addIssuerName(this.cert.getIssuerX500Principal().getEncoded());
00226             Iterator crlIterator = crlsStore.getCRLs(x509CRLSelector).iterator();
00227             while (crlIterator.hasNext()) {
00228                 if (((X509CRL) crlIterator.next()).isRevoked(this.cert)) {
00229                     throw new LoginException("Client certificate has been revoked");
00230                 }
00231             }
00232         } catch (Exception e) {
00233             throw new LoginException("Error during the login phase : " + e.getMessage());
00234         }
00235 
00236         return true;
00237     }
00238 
00253     public boolean commit() throws LoginException {
00254         return true;
00255     }
00256 
00268     public boolean abort() throws LoginException {
00269 
00270         // Reset temp values
00271         principalName = null;
00272         principalRoles = null;
00273 
00274         return true;
00275     }
00276 
00284     public boolean logout() throws LoginException {
00285 
00286         // Remove principal name
00287         subject.getPrincipals().remove(new JPrincipal(principalName));
00288 
00289         return true;
00290     }
00291 
00292 }

Generated on Tue Feb 15 15:05:21 2005 for JOnAS by  doxygen 1.3.9.1