/* */ package org.jboss.security.auth.spi;
/* */
/* */ import java.io.IOException;
/* */ import java.math.BigInteger;
/* */ import java.security.KeyStore;
/* */ import java.security.KeyStoreException;
/* */ import java.security.Principal;
/* */ import java.security.acl.Group;
/* */ import java.security.cert.X509Certificate;
/* */ import java.util.ArrayList;
/* */ import java.util.Enumeration;
/* */ import java.util.Map;
/* */ import java.util.Set;
/* */ import javax.naming.InitialContext;
/* */ import javax.naming.NamingException;
/* */ import javax.security.auth.Subject;
/* */ import javax.security.auth.callback.Callback;
/* */ import javax.security.auth.callback.CallbackHandler;
/* */ import javax.security.auth.callback.NameCallback;
/* */ import javax.security.auth.callback.UnsupportedCallbackException;
/* */ import javax.security.auth.login.FailedLoginException;
/* */ import javax.security.auth.login.LoginException;
/* */ import org.jboss.logging.Logger;
/* */ import org.jboss.security.SecurityDomain;
/* */ import org.jboss.security.auth.callback.ObjectCallback;
/* */ import org.jboss.security.auth.certs.X509CertificateVerifier;
/* */
/* */ public class BaseCertLoginModule extends AbstractServerLoginModule
/* */ {
/* */ private Principal identity;
/* */ private X509Certificate credential;
/* 70 */ private SecurityDomain domain = null;
/* */ private X509CertificateVerifier verifier;
/* */ private boolean trace;
/* */
/* */ public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options)
/* */ {
/* 96 */ super.initialize(subject, callbackHandler, sharedState, options);
/* 97 */ this.trace = this.log.isTraceEnabled();
/* */
/* 100 */ String sd = (String)options.get("securityDomain");
/* 101 */ if (sd == null) {
/* 102 */ sd = "java:/jaas/other";
/* */ }
/* 104 */ if (this.trace) {
/* 105 */ this.log.trace("securityDomain=" + sd);
/* */ }
/* */ try
/* */ {
/* 109 */ Object tempDomain = new InitialContext().lookup(sd);
/* 110 */ if ((tempDomain instanceof SecurityDomain))
/* */ {
/* 112 */ this.domain = ((SecurityDomain)tempDomain);
/* 113 */ if (this.trace)
/* */ {
/* 115 */ if (this.domain != null)
/* 116 */ this.log.trace("found domain: " + this.domain.getClass().getName());
/* */ else
/* 118 */ this.log.trace("the domain " + sd + " is null!");
/* */ }
/* */ }
/* */ else
/* */ {
/* 123 */ this.log.error("The domain " + sd + " is not a SecurityDomain. All authentication using this module will fail!");
/* */ }
/* */ }
/* */ catch (NamingException e)
/* */ {
/* 128 */ this.log.error("Unable to find the securityDomain named: " + sd, e);
/* */ }
/* */
/* 131 */ String option = (String)options.get("verifier");
/* 132 */ if (option != null)
/* */ {
/* */ try
/* */ {
/* 136 */ ClassLoader loader = Thread.currentThread().getContextClassLoader();
/* 137 */ Class verifierClass = loader.loadClass(option);
/* 138 */ this.verifier = ((X509CertificateVerifier)verifierClass.newInstance());
/* */ }
/* */ catch (Throwable e)
/* */ {
/* 142 */ if (this.trace)
/* 143 */ this.log.trace("Failed to create X509CertificateVerifier", e);
/* 144 */ IllegalArgumentException ex = new IllegalArgumentException("Invalid verifier: " + option);
/* 145 */ ex.initCause(e);
/* */ }
/* */ }
/* */
/* 149 */ if (this.trace)
/* 150 */ this.log.trace("exit: initialize(Subject, CallbackHandler, Map, Map)");
/* */ }
/* */
/* */ public boolean login()
/* */ throws LoginException
/* */ {
/* 158 */ if (this.trace) {
/* 159 */ this.log.trace("enter: login()");
/* */ }
/* 161 */ if (super.login() == true)
/* */ {
/* 164 */ Object username = this.sharedState.get("javax.security.auth.login.name");
/* 165 */ if ((username instanceof Principal)) {
/* 166 */ this.identity = ((Principal)username);
/* */ }
/* */ else {
/* 169 */ String name = username.toString();
/* */ try
/* */ {
/* 172 */ this.identity = createIdentity(name);
/* */ }
/* */ catch (Exception e)
/* */ {
/* 176 */ this.log.debug("Failed to create principal", e);
/* 177 */ throw new LoginException("Failed to create principal: " + e.getMessage());
/* */ }
/* */ }
/* */
/* 181 */ Object password = this.sharedState.get("javax.security.auth.login.password");
/* 182 */ if ((password instanceof X509Certificate)) {
/* 183 */ this.credential = ((X509Certificate)password);
/* 184 */ } else if (password != null)
/* */ {
/* 186 */ this.log.debug("javax.security.auth.login.password is not X509Certificate");
/* 187 */ this.loginOk = false;
/* 188 */ return false;
/* */ }
/* 190 */ return true;
/* */ }
/* */
/* 193 */ this.loginOk = false;
/* 194 */ Object[] info = getAliasAndCert();
/* 195 */ String alias = (String)info[0];
/* 196 */ this.credential = ((X509Certificate)info[1]);
/* */
/* 198 */ if ((alias == null) && (this.credential == null))
/* */ {
/* 200 */ this.identity = this.unauthenticatedIdentity;
/* 201 */ this.log.trace("Authenticating as unauthenticatedIdentity=" + this.identity);
/* */ }
/* */
/* 204 */ if (this.identity == null)
/* */ {
/* */ try
/* */ {
/* 208 */ this.identity = createIdentity(alias);
/* */ }
/* */ catch (Exception e)
/* */ {
/* 212 */ this.log.debug("Failed to create identity for alias:" + alias, e);
/* */ }
/* */
/* 215 */ if (!validateCredential(alias, this.credential))
/* */ {
/* 217 */ this.log.debug("Bad credential for alias=" + alias);
/* 218 */ throw new FailedLoginException("Supplied Credential did not match existing credential for " + alias);
/* */ }
/* */ }
/* */
/* 222 */ if (getUseFirstPass() == true)
/* */ {
/* 225 */ this.sharedState.put("javax.security.auth.login.name", alias);
/* 226 */ this.sharedState.put("javax.security.auth.login.password", this.credential);
/* */ }
/* 228 */ this.loginOk = true;
/* 229 */ if (this.trace)
/* */ {
/* 231 */ this.log.trace("User '" + this.identity + "' authenticated, loginOk=" + this.loginOk);
/* 232 */ this.log.debug("exit: login()");
/* */ }
/* 234 */ return true;
/* */ }
/* */
/* */ public boolean commit()
/* */ throws LoginException
/* */ {
/* 243 */ boolean ok = super.commit();
/* 244 */ if (ok == true)
/* */ {
/* 247 */ if (this.credential != null)
/* */ {
/* 249 */ this.subject.getPublicCredentials().add(this.credential);
/* */ }
/* */ }
/* 252 */ return ok;
/* */ }
/* */
/* */ protected Group[] getRoleSets()
/* */ throws LoginException
/* */ {
/* 261 */ return new Group[0];
/* */ }
/* */
/* */ protected Principal getIdentity()
/* */ {
/* 266 */ return this.identity;
/* */ }
/* */
/* */ protected Object getCredentials() {
/* 270 */ return this.credential;
/* */ }
/* */
/* */ protected String getUsername() {
/* 274 */ String username = null;
/* 275 */ if (getIdentity() != null)
/* 276 */ username = getIdentity().getName();
/* 277 */ return username;
/* */ }
/* */
/* */ protected Object[] getAliasAndCert() throws LoginException
/* */ {
/* 282 */ if (this.trace)
/* 283 */ this.log.trace("enter: getAliasAndCert()");
/* 284 */ Object[] info = { null, null };
/* */
/* 286 */ if (this.callbackHandler == null)
/* */ {
/* 288 */ throw new LoginException("Error: no CallbackHandler available to collect authentication information");
/* */ }
/* 290 */ NameCallback nc = new NameCallback("Alias: ");
/* 291 */ ObjectCallback oc = new ObjectCallback("Certificate: ");
/* 292 */ Callback[] callbacks = { nc, oc };
/* 293 */ String alias = null;
/* 294 */ X509Certificate cert = null;
/* */ try
/* */ {
/* 298 */ this.callbackHandler.handle(callbacks);
/* 299 */ alias = nc.getName();
/* 300 */ Object tmpCert = oc.getCredential();
/* 301 */ if (tmpCert != null)
/* */ {
/* 303 */ if ((tmpCert instanceof X509Certificate))
/* */ {
/* 305 */ cert = (X509Certificate)tmpCert;
/* 306 */ if (this.trace)
/* 307 */ this.log.trace("found cert " + cert.getSerialNumber().toString(16) + ":" + cert.getSubjectDN().getName());
/* */ }
/* 309 */ else if ((tmpCert instanceof X509Certificate[]))
/* */ {
/* 311 */ X509Certificate[] certChain = (X509Certificate[])(X509Certificate[])tmpCert;
/* 312 */ if (certChain.length > 0)
/* 313 */ cert = certChain[0];
/* */ }
/* */ else
/* */ {
/* 317 */ String msg = "Don't know how to obtain X509Certificate from: " + tmpCert.getClass();
/* */
/* 319 */ this.log.warn(msg);
/* 320 */ throw new LoginException(msg);
/* */ }
/* */ }
/* */ else
/* */ {
/* 325 */ this.log.warn("CallbackHandler did not provide a certificate");
/* */ }
/* */ }
/* */ catch (IOException e)
/* */ {
/* 330 */ this.log.debug("Failed to invoke callback", e);
/* 331 */ throw new LoginException("Failed to invoke callback: " + e.toString());
/* */ }
/* */ catch (UnsupportedCallbackException uce)
/* */ {
/* 335 */ throw new LoginException("CallbackHandler does not support: " + uce.getCallback());
/* */ }
/* */
/* 339 */ info[0] = alias;
/* 340 */ info[1] = cert;
/* 341 */ if (this.trace)
/* 342 */ this.log.trace("exit: getAliasAndCert()");
/* 343 */ return info;
/* */ }
/* */
/* */ protected boolean validateCredential(String alias, X509Certificate cert)
/* */ {
/* 348 */ if (this.trace)
/* 349 */ this.log.trace("enter: validateCredentail(String, X509Certificate)");
/* 350 */ boolean isValid = false;
/* */
/* 353 */ KeyStore keyStore = null;
/* 354 */ KeyStore trustStore = null;
/* 355 */ if (this.domain != null)
/* */ {
/* 357 */ keyStore = this.domain.getKeyStore();
/* 358 */ trustStore = this.domain.getTrustStore();
/* */ }
/* 360 */ if (trustStore == null) {
/* 361 */ trustStore = keyStore;
/* */ }
/* 363 */ if (this.verifier != null)
/* */ {
/* 366 */ if (this.trace)
/* 367 */ this.log.trace("Validating cert using: " + this.verifier);
/* 368 */ isValid = this.verifier.verify(cert, alias, keyStore, trustStore);
/* */ }
/* 370 */ else if ((keyStore != null) && (cert != null))
/* */ {
/* 373 */ X509Certificate storeCert = null;
/* */ try
/* */ {
/* 376 */ storeCert = (X509Certificate)keyStore.getCertificate(alias);
/* 377 */ if (this.trace)
/* */ {
/* 379 */ StringBuffer buf = new StringBuffer("\n\tSupplied Credential: ");
/* 380 */ buf.append(cert.getSerialNumber().toString(16));
/* 381 */ buf.append("\n\t\t");
/* 382 */ buf.append(cert.getSubjectDN().getName());
/* 383 */ buf.append("\n\n\tExisting Credential: ");
/* 384 */ if (storeCert != null)
/* */ {
/* 386 */ buf.append(storeCert.getSerialNumber().toString(16));
/* 387 */ buf.append("\n\t\t");
/* 388 */ buf.append(storeCert.getSubjectDN().getName());
/* 389 */ buf.append("\n");
/* */ }
/* */ else
/* */ {
/* 393 */ ArrayList aliases = new ArrayList();
/* 394 */ Enumeration en = keyStore.aliases();
/* 395 */ while (en.hasMoreElements())
/* */ {
/* 397 */ aliases.add(en.nextElement());
/* */ }
/* 399 */ buf.append("No match for alias: " + alias + ", we have aliases " + aliases);
/* */ }
/* 401 */ this.log.trace(buf.toString());
/* */ }
/* */ }
/* */ catch (KeyStoreException e)
/* */ {
/* 406 */ this.log.warn("failed to find the certificate for " + alias, e);
/* */ }
/* */
/* 409 */ if (cert.equals(storeCert))
/* 410 */ isValid = true;
/* */ }
/* */ else
/* */ {
/* 414 */ this.log.warn("Domain, KeyStore, or cert is null. Unable to validate the certificate.");
/* */ }
/* */
/* 417 */ if (this.trace)
/* */ {
/* 419 */ this.log.trace("The supplied certificate " + (isValid ? "matched" : "DID NOT match") + " the certificate in the keystore.");
/* */
/* 423 */ this.log.trace("exit: validateCredentail(String, X509Certificate)");
/* */ }
/* 425 */ return isValid;
/* */ }
/* */ }
/* Location: /home/mnovotny/projects/EMBEDDED_JBOSS_BETA3_COMMUNITY/embedded/output/lib/embedded-jboss/lib/jboss-embedded-all.jar
* Qualified Name: org.jboss.security.auth.spi.BaseCertLoginModule
* JD-Core Version: 0.6.0
*/