/**
* Copyright (c) 1996-2007 Cafesoft, LLC. All Rights Reserved.
*
* This software is the confidential and proprietary information of
* Cafesoft, LLC. ("Confidential Information"). You shall not disclose
* such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into
* with Cafesoft.
*
* CAFESOFT MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY
* OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE, OR NON-INFRINGEMENT. CAFESOFT SHALL NOT BE LIABLE FOR ANY DAMAGES
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
* THIS SOFTWARE OR ITS DERIVATIVES.
*/
package com.cafesoft.cams.auth.callback;
import com.cafesoft.core.util.X509CertificateUtils;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.io.IOException;
/**
* CallbackHandler interface for JAAS LoginModules that must prompt for input.
* Provides the specified username and password when prompted by the Callback.
*
* @author Norbert K. Kuhnert
* @version $Revision: 1.4 $ $Date: 2007/01/10 19:20:51 $ $Author: gary $
* @since 11/8/01
*/
public class NamePasswordCallbackHandler implements CallbackHandler
{
/**
* The username to be provided when prompted.
*/
private String username;
/**
* The password to be provided when prompted.
*/
private String password;
/**
* The PEM-encoded X509Certificate.
*/
private String x509CertPEM;
/**
* The X509Certificate.
*/
private X509Certificate[] x509CertArray;
/**
* The Cams cookie domain value sent by web agents with all login
* and SSO requests (facilitates web SSO)
*/
private String cookieDomain;
/**
* Create a new NamePasswordCallbackHandler (required Cams default
* constructor that is dynamically called by the authentication
* server).
*/
public NamePasswordCallbackHandler()
{
this.username = null;
this.password = null;
this.cookieDomain = null;
this.x509CertPEM = null;
this.x509CertArray = null;
}
/**
* Create a new NamePasswordCallbackHandler (optional constructor
* used to facilitate testing).
*
* @param username the username to provide when prompted.
* @param password the password to provide when prompted.
*/
public NamePasswordCallbackHandler(String username, String password)
{
this.username = username;
this.password = password;
}
/**
* Set the username.
*
* @param username the username to be provided to a NameCallback.
*/
public void setUsername(String username)
{
if (username == null)
{
this.username = "";
return;
}
this.username = username;
}
/**
* Set the password.
*
* @param password the password to be provided to a PasswordCallback.
*/
public void setPassword(String password)
{
if (password == null)
{
this.password = "";
return;
}
this.password = password;
}
/**
* Set the Cams cookie domain.
*
* NOTE: this method was added to silenced a "No such method" warning
* reported in the security domain trace log when this common callback
* value is added to HTTP authentication requests to facilitate efficient
* cross DNS domain SSO.
*
* @param cookieDomain the Cams cookie domain.
*/
public void setCams_cookie_domain(String cookieDomain)
{
if (cookieDomain == null)
{
this.cookieDomain = "";
return;
}
this.cookieDomain = cookieDomain;
}
/**
* Set an X509Certificate chain.
* NOTE: the certificate may include one or more PEM-formatted
* X509 certificates including:
* "-----BEGIN CERTIFICATE-----"\n
*
* "-----END CERTIFICATE-----"
*
* @param x509CertPEM the PEM-encoded client certificate
*/
public void setX509_client_cert(String x509CertPEM)
{
if (x509CertPEM == null)
{
this.x509CertPEM = null;
return;
}
this.x509CertPEM = x509CertPEM;
}
/**
* Set the Cams session identifier.
*
* @param sessionId an existing Cams session identifier in String form.
*/
public void setSession_id(String sessionId)
{
// Do nothing! This method enables a possible existing Cams session
// identifier to be passed from Cams web agents to the Cams policy
// server for "reauthentication" or "additional authentication". If
// a Cams session identifier is sent from an Cams web agent, it is
// available to CPS auth-pipeline components via the AuthRequest.
}
/**
* Retrieve or display the information requested in the provided Callbacks.
* The handle method implementation checks the instance(s) of the Callback
* object(s) passed in to retrieve or display the requested information.
*
* @param callbacks an array of Callback objects provided by an underlying
* security service which contains the information requested to be retrieved
* or displayed.
*
* @exception IOException if an input or output error ocurrs
* @exception UnsupportedCallbackException if the implementation of this
* method does not support one or more of the Callbacks specified in the
* callbacks parameter
*/
public void handle(Callback[] callbacks)
throws IOException, UnsupportedCallbackException
{
// Loop over all Callbacks
for (int i = 0; i < callbacks.length; i++)
{
Callback cb = callbacks[i];
if (cb instanceof NameCallback)
{
((NameCallback)cb).setName(username);
}
else if (cb instanceof PasswordCallback)
{
// JAAS specifies that the password is a char[]
if(password != null)
((PasswordCallback)cb).setPassword(password.toCharArray());
else
((PasswordCallback)cb).setPassword(new char[0]);
}
else if (cb instanceof X509CertificateCallback)
{
if ((x509CertArray == null) && (x509CertPEM != null))
{
// Decode the PEM-formatted certificate chain
try
{
this.x509CertArray =
X509CertificateUtils.decodeChainFromPEM(x509CertPEM);
}
catch (CertificateException e)
{
throw new IOException(
"Unable to decode PEM-encoded X509Certficate chain");
}
}
if(x509CertArray != null)
((X509CertificateCallback)cb).setX509Certificates(x509CertArray);
else
((X509CertificateCallback)cb).setX509Certificates(null);
}
else
{
throw new UnsupportedCallbackException(
cb, "Unrecognized Callback");
}
}
}
} // End of class: NamePasswordCallbackHandler