You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by he...@apache.org on 2004/07/07 11:02:00 UTC
cvs commit: ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/context/security/impl SecurityContext4J2EEImpl.java
hemapani 2004/07/07 02:02:00
Modified: contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/toWs/wrapperWs
SimpleRemoteInterfaceBasedWrapperClassWriter.java
contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/context/security
SecurityContext4J2EE.java
contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/toWs
GenerationConstants.java
contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/utils
AntExecuter.java
contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/context/security/impl
SecurityContext4J2EEImpl.java
Added: contrib/ews/src/org/apache/ws/axis/security
PWDCallbackHandler4J2EE.java WSS4J2EEConstants.java
BasicAuth4J2EESender.java SimpleWSS4J2EESender.java
AllSecurity4J2EEReceiver.java
BasicAuth4J2EEReceiver.java
SimpleWSS4J2EEReceiver.java
CheckPoint4J2EEHandler.java
contrib/ews/src/org/apache/ws/security WSS4J2EEEngine.java
Removed: contrib/ews/src/org/apache/ws/axis/security
WSS4J2EEReceiver.java
contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/context/security
SimpleWSS4J2EEReceiver.java WSS4J2EEEngine.java
WSS4J2EEConstants.java CheckPoint4J2EEHandler.java
SimpleWSS4J2EESender.java
Log:
add priyanga's new Handlers to support secuity
had to keep the Handlers in the axis.security/ws.secuirty packages as
they have default constructers
Revision Changes Path
1.1 ws-axis/contrib/ews/src/org/apache/ws/axis/security/PWDCallbackHandler4J2EE.java
Index: PWDCallbackHandler4J2EE.java
===================================================================
/*
* Created on Jun 27, 2004
*
*
*/
package org.apache.ws.axis.security;
import java.io.IOException;
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;
/**
* This is a simple PasswordCallback Handler that can be used by
* Wrapper web service, before invoking the EJB, to authenticate
* the client using JAAS.
*
* @author Rajith Priyanga (rpriyanga@yahoo.com)
* @date Jun 27, 2004
*
*/
public class PWDCallbackHandler4J2EE implements CallbackHandler{
String username = null;
char[] password = null;
/**
* @see javax.security.auth.callback.CallbackHandler#handle(javax.security.auth.callback.Callback[])
*/
public PWDCallbackHandler4J2EE(String username, char[] password){
this.username = username;
this.password = password;
}
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
boolean recognized = false;
//Callback handler which implements both the following interfaces
//can also be handled.
for (int i = 0; i < callbacks.length; i++){
if (callbacks[i] instanceof NameCallback){
NameCallback ncb = (NameCallback) callbacks[i];
ncb.setName(username);
recognized = true;
}
if (callbacks[i] instanceof PasswordCallback){
PasswordCallback pcb = (PasswordCallback) callbacks[i];
pcb.setPassword(password);
recognized = true;
}
if(!recognized){
throw new UnsupportedCallbackException(callbacks[i], "Callback Type is not supported.");
}
}
}
}
1.1 ws-axis/contrib/ews/src/org/apache/ws/axis/security/WSS4J2EEConstants.java
Index: WSS4J2EEConstants.java
===================================================================
/*
* Created on May 28, 2004
*
*
*/
package org.apache.ws.axis.security;
import org.apache.ws.axis.security.WSDoAllConstants;
/**
* Defines the Constants used or WS-J2EE security Mapping implementation.
*
* @author Rajith Priyanga (rpriyanga@yahoo.com)
* @date May 28, 2004
*
*/
public class WSS4J2EEConstants extends WSDoAllConstants {
/**
* This property contains the security information required to authenticate
* the user to the J2EE server, plus some more information. Represents
* a SecurityContext4J2EE object.
*
*/
public static final String SEC_CONTEXT_4J2EE = "SEC_CONTEXT_4J2EE";
public static final String AUTH_AT_AXIS = "AuthenticationAtAxis";
}
1.1 ws-axis/contrib/ews/src/org/apache/ws/axis/security/BasicAuth4J2EESender.java
Index: BasicAuth4J2EESender.java
===================================================================
/*
* Created on Jun 20, 2004
*
*
*/
package org.apache.ws.axis.security;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.Callback;
import org.apache.axis.AxisFault;
import org.apache.axis.MessageContext;
import org.apache.axis.handlers.BasicHandler;
import org.apache.ws.axis.security.WSDoAllConstants;
import org.apache.ws.security.WSPasswordCallback;
/**
* This class can be used as a client side Axis handler which can insert
* BasicHTTPAuthentication data to the request. This class uses the
* PasswordCallbackHandler specified by the client in the DD or Call object,
* to obtain the credentials of the client to add to the HTTP header.
* (i.e. <code>passwordCallbackClass</code> property.)
*
* @author Rajith Priyanga (rpriyanga@yahoo.com)
* @date Jun 20, 2004
*
*/
public class BasicAuth4J2EESender extends BasicHandler {
/**
* @see org.apache.axis.Handler#invoke(org.apache.axis.MessageContext)
*/
public void invoke(MessageContext cntxt) throws AxisFault {
String username = cntxt.getUsername();
try{
cntxt.setPassword(fetchPWD(username, cntxt));
}
catch(Exception e){
throw AxisFault.makeFault(e);
}
}
/**
* Fetches the password to be sent, using the given Password Callback
* class.
* @param username
* @param cntxt
* @return
* @throws Exception
*/
private String fetchPWD(String username, MessageContext cntxt) throws Exception{
if(username==null){
throw new Exception("No username provided!");
}
WSPasswordCallback pwcb = new WSPasswordCallback(username, WSPasswordCallback.USERNAME_TOKEN);
Callback[] cb = new Callback[1];
cb[0] = pwcb;
CallbackHandler cbh = (CallbackHandler)cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_REF);
if(cbh == null){
String cbhClass = (String)cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_CLASS);
cbh = (CallbackHandler)Class.forName(cbhClass).newInstance();
}
if(cbh == null){
throw new Exception("No PasswordCallbackHandler class found.");
}
else{
cbh.handle(cb);
}
String pwd = ((WSPasswordCallback)(cb[0])).getPassword();
if(pwd==null)
throw new Exception("No password provided!");
return pwd;
}
}
1.1 ws-axis/contrib/ews/src/org/apache/ws/axis/security/SimpleWSS4J2EESender.java
Index: SimpleWSS4J2EESender.java
===================================================================
/*
* Created on May 29, 2004
*
*
*/
package org.apache.ws.axis.security;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Random;
import java.util.TimeZone;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.xml.soap.Name;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPFactory;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPHeaderElement;
import org.apache.axis.AxisFault;
import org.apache.axis.Message;
import org.apache.axis.MessageContext;
import org.apache.axis.handlers.BasicHandler;
import org.apache.ws.axis.security.WSDoAllConstants;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.WSPasswordCallback;
import org.apache.ws.security.message.token.UsernameToken;
/**
*
* This is a server side Axis handler that can be used to retrieve the
* credentials available in the UsernameToken element. This will
* retrieve the credentials and populate the SecurityContext4J2EE
* property with them.
*
* This is a very simple handler that can handle only UsernameToken
* elements. So that this can be used for testing peroposes and
* other simple works.
*
* @author Rajith Priyanga (rpriyanga@yahoo.com)
* @date May 29, 2004
*
*/
public class SimpleWSS4J2EESender extends BasicHandler {
MessageContext cntxt = null;
/**
* Adds the username-password information to the SOAP header
* within the UsernameToken, as requested by the user.
* @see org.apache.axis.Handler#invoke(org.apache.axis.MessageContext)
*/
public void invoke(MessageContext msgCntxt) throws AxisFault {
this.cntxt = msgCntxt;
String action = (String)cntxt.getProperty(WSDoAllConstants.ACTION);
if(action==null)
return;
String[] actions = action.split(" ");
boolean utAction = false;
//Check whether UsernameToken action is requested. Otherwise no more processing.
for(int i=0; i<actions.length; i++){
utAction = actions[i].equalsIgnoreCase(WSDoAllConstants.USERNAME_TOKEN);
if(utAction)
break;
}
if(!utAction)
return;
//Get the username from the msg context.
String username = this.cntxt.getUsername();
//If the username property is not in the message context,
if(username==null)
username = (String)cntxt.getProperty(WSDoAllConstants.USER);
if(username==null)
throw AxisFault.makeFault(new Exception("No username specified!"));
//Get the password type. If it is not defined, the deault is PasswardText.
String pwdType = (String)cntxt.getProperty(WSDoAllConstants.PASSWORD_TYPE);
if(pwdType==null)
pwdType = WSConstants.PASSWORD_TEXT;
addUsernameToken(username, pwdType);
}
/**
* Creates and adds the Security-UsernameToken to the SOAP message.
* @param username
* @param passwordType
* @throws AxisFault
*/
private void addUsernameToken(String username, String passwordType) throws AxisFault{
Message m = cntxt.getCurrentMessage();
try{
SOAPHeader h = m.getSOAPPart().getEnvelope().getHeader();
SOAPFactory sf = SOAPFactory.newInstance();
m.getSOAPEnvelope().addNamespaceDeclaration(WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS);
Name secN = sf.createName(WSConstants.WSSE_LN, WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS);
SOAPHeaderElement secElem = h.addHeaderElement(secN);
//Add the Username Token.
SOAPElement utElem = sf.createElement(WSConstants.WSSE_PREFIX+ ":" + WSConstants.USERNAME_TOKEN_LN);
secElem.addChildElement(utElem);
//Add the Username element.
SOAPElement unElem = sf.createElement(WSConstants.WSSE_PREFIX+ ":" + WSConstants.USERNAME_LN);
unElem.addTextNode(username);
utElem.addChildElement(unElem);
//Create the Password element.
SOAPElement pwdElem = sf.createElement(WSConstants.WSSE_PREFIX+ ":" + WSConstants.PASSWORD_LN);
Name pwdType = sf.createName(WSConstants.PASSWORD_TYPE_ATTR, WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS);
//Add password element.
if(passwordType.equalsIgnoreCase(WSConstants.PASSWORD_TEXT)){
pwdElem.addAttribute(pwdType,WSConstants.PASSWORD_TEXT);
pwdElem.addTextNode(fetchPWD(username));
utElem.addChildElement(pwdElem);
}
else if(passwordType.equalsIgnoreCase(WSConstants.PASSWORD_DIGEST)){
m.getSOAPEnvelope().addNamespaceDeclaration(WSConstants.WSU_PREFIX, WSConstants.WSU_NS);
pwdElem.addAttribute(pwdType,WSConstants.PASSWORD_DIGEST);
String nonce = getNonce();
String created = getCreated();
String digest = UsernameToken.doPasswordDigest(nonce, created, fetchPWD(username));
SOAPElement nonceElem = sf.createElement(WSConstants.WSSE_PREFIX+":"+WSConstants.NONCE_LN);
SOAPElement createdElem = sf.createElement(WSConstants.WSU_PREFIX+":"+WSConstants.CREATED_LN);
nonceElem.addTextNode(nonce);
createdElem.addTextNode(created);
pwdElem.addTextNode(digest);
utElem.addChildElement(pwdElem);
utElem.addChildElement(nonceElem);
utElem.addChildElement(createdElem);
}
else{
throw AxisFault.makeFault(new Exception("Unsupported PasswordType"));
}
}
catch(Exception ex){
throw AxisFault.makeFault(ex);
}
}
/*
* Generates nonce.
*/
private String getNonce(){
Random rand = new Random();
byte[] nonce = new byte[16];
rand.nextBytes(nonce);
String nonceStr = org.apache.xml.security.utils.Base64.encode(nonce);
return nonceStr;
}
/**
* Generates created as per specification.
* @return
*/
private String getCreated(){
SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
sd.setTimeZone(TimeZone.getTimeZone("GMT"));
Calendar now = Calendar.getInstance();
return sd.format(now.getTime());
}
/**
* Fetch the password of the user from the specified PasswordCallbak class.
* @param username
* @return
* @throws Exception
*/
private String fetchPWD(String username) throws Exception{
WSPasswordCallback pwcb = new WSPasswordCallback(username, WSPasswordCallback.USERNAME_TOKEN);
Callback[] cb = new Callback[1];
cb[0] = pwcb;
CallbackHandler cbh = (CallbackHandler)this.cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_REF);
if(cbh == null){
String cbhClass = (String)this.cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_CLASS);
cbh = (CallbackHandler)Class.forName(cbhClass).newInstance();
}
if(cbh == null){
throw new Exception("No PasswordCallbackHandler class found.");
}
else{
cbh.handle(cb);
}
String pwd = ((WSPasswordCallback)(cb[0])).getPassword();
if(pwd==null)
throw new Exception("Password is not provided! Can't create UsernameToken.");
return pwd;
}
}
1.1 ws-axis/contrib/ews/src/org/apache/ws/axis/security/AllSecurity4J2EEReceiver.java
Index: AllSecurity4J2EEReceiver.java
===================================================================
/*
* Created on Jun 20, 2004
*
*
*/
package org.apache.ws.axis.security;
import java.io.ByteArrayOutputStream;
import java.math.BigInteger;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.TimeZone;
import java.util.Vector;
import javax.security.auth.callback.CallbackHandler;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPHeaderElement;
import org.apache.axis.AxisFault;
import org.apache.axis.Message;
import org.apache.axis.MessageContext;
import org.apache.axis.SOAPPart;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ws.axis.security.WSDoAllConstants;
import org.apache.ws.axis.security.WSDoAllReceiver;
import org.apache.ws.axis.security.WSDoAllReceiverResult;
import org.apache.ws.axis.security.util.AxisUtil;
import org.apache.ws.security.SOAPConstants;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.WSS4J2EEEngine;
import org.apache.ws.security.WSSecurityEngineResult;
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.components.crypto.Crypto;
import org.apache.ws.security.components.crypto.CryptoFactory;
import org.apache.ws.security.message.token.Timestamp;
import org.apache.ws.security.util.WSSecurityUtil;
import org.apache.xml.security.utils.XMLUtils;
import org.w3c.dom.Document;
/**
* This class can be used to process any kind of WSSecurity token,
* to retrieve the credentials required to Authenticate the user to
* J2EE server and to populate the SecurityContext4J2EE property
* with them.
*
* This class is written by modifying the some parts of
* the WSDoAllReceiver class availble in WSS4J project. Modification
* done to it should also be appeared here. This is a temporary solution
* until that class come to a stable state.
*
* This uses WSS4J2EEEngine instead of WSSecurityEngine. Therefore the
* authentication is only taken place at J2EE server, not at Axis.
*
* @author Rajith Priyanga (rpriyanga@yahoo.com)
* @author Werner Dittmann (Werner.Dittmann@siemens.com)
* @date Jun 20, 2004
*
*/
public class AllSecurity4J2EEReceiver extends WSDoAllReceiver{
static final WSS4J2EEEngine sec4j2eeEngine = new WSS4J2EEEngine();
static Log log = LogFactory.getLog(WSDoAllReceiver.class.getName());
private boolean doDebug = true;
private static Hashtable cryptos = new Hashtable(5);
private MessageContext msgContext = null;
Crypto sigCrypto = null;
String sigPropFile = null;
Crypto decCrypto = null;
String decPropFile = null;
protected int timeToLive = 300; // Timestamp: time in seconds the receiver accepts between creation and reception
/**
* Axis calls invoke to handle a message.
* <p/>
*
* @param mc message context.
* @throws AxisFault
*/
public void invoke(MessageContext mc) throws AxisFault {
/////////////////////////////////////////
try{
sec4j2eeEngine.setMessageContext(mc);
}
catch(Exception ex){
throw AxisFault.makeFault(ex);
}
////////////////////////////////////////
if (doDebug) {
log.debug("WSDoAllReceiver: enter invoke() with msg type: "
+ mc.getCurrentMessage().getMessageType());
}
msgContext = mc;
Vector actions = new Vector();
String action = null;
if ((action = (String) getOption(WSDoAllConstants.ACTION)) == null) {
action = (String) msgContext.getProperty(WSDoAllConstants.ACTION);
}
if (action == null) {
throw new AxisFault("WSDoAllReceiver: No action defined");
}
int doAction = AxisUtil.decodeAction(action, actions);
String actor = (String) getOption(WSDoAllConstants.ACTOR);
Message sm = msgContext.getCurrentMessage();
Document doc = null;
try {
doc = sm.getSOAPEnvelope().getAsDocument();
if (doDebug) {
log.debug("Received SOAP request: ");
log.debug(org.apache.axis.utils.XMLUtils.PrettyDocumentToString(doc));
}
} catch (Exception ex) {
throw new AxisFault(
"WSDoAllReceiver: cannot convert into document",
ex);
}
/*
* Check if it's a response and if its a fault. Don't
* process faults.
*/
String msgType = sm.getMessageType();
if (msgType != null && msgType.equals(Message.RESPONSE)) {
SOAPConstants soapConstants =
WSSecurityUtil.getSOAPConstants(doc.getDocumentElement());
if (WSSecurityUtil
.findElement(
doc.getDocumentElement(),
"Fault",
soapConstants.getEnvelopeURI())
!= null) {
return;
}
}
/*
* To check a UsernameToken or to decrypt an encrypted message we need
* a password.
*/
CallbackHandler cbHandler = null;
if ((doAction & (WSConstants.ENCR | WSConstants.UT)) != 0) {
cbHandler = getPasswordCB();
}
/*
* Get and check the Signature specific parameters first because they
* may be used for encryption too.
*/
if ((doAction & WSConstants.SIGN) == WSConstants.SIGN) {
decodeSignatureParameter();
}
if ((doAction & WSConstants.ENCR) == WSConstants.ENCR) {
decodeDecryptionParameter();
}
Vector wsResult = null;
try {
wsResult =
sec4j2eeEngine.processSecurityHeader(
doc,
actor,
cbHandler,
sigCrypto,
decCrypto);
} catch (WSSecurityException ex) {
ex.printStackTrace();
throw new AxisFault(
"WSDoAllReceiver: security processing failed",
ex);
}
if (wsResult == null) { // no security header found
if (doAction == WSConstants.NO_SECURITY) {
return;
} else {
throw new AxisFault("WSDoAllReceiver: Request does not contain required Security header");
}
}
/*
* If we had some security processing, get the original
* SOAP part of Axis' message and replace it with new SOAP
* part. This new part may contain decrypted elements.
*/
SOAPPart sPart = (org.apache.axis.SOAPPart) sm.getSOAPPart();
ByteArrayOutputStream os = new ByteArrayOutputStream();
XMLUtils.outputDOM(doc, os, true);
sPart.setCurrentMessage(os.toByteArray(), SOAPPart.FORM_BYTES);
if (doDebug) {
log.debug("Processed received SOAP request");
log.debug(org.apache.axis.utils.XMLUtils.PrettyDocumentToString(doc));
}
/*
* After setting the new current message, probably modified because
* of decryption, we need to locate the security header. That is,
* we force Axis (with getSOAPEnvelope()) to parse the string, build
* the new header. Then we examine, look up the security header
* and set the header as processed.
*
* Please note: find all header elements that contain the same
* actor that was given to processSecurityHeader(). Then
* check if there is a security header with this actor.
*/
SOAPHeader sHeader = null;
try {
sHeader = sm.getSOAPEnvelope().getHeader();
} catch (Exception ex) {
throw new AxisFault("WSDoAllReceiver: cannot get SOAP header after security processing", ex);
}
Iterator headers = sHeader.examineHeaderElements(actor);
SOAPHeaderElement headerElement = null;
while (headers.hasNext()) {
SOAPHeaderElement hE = (SOAPHeaderElement) headers.next();
if (hE.getLocalName().equals(WSConstants.WSSE_LN)
&& hE.getNamespaceURI().equals(WSConstants.WSSE_NS)) {
headerElement = hE;
break;
}
}
((org.apache.axis.message.SOAPHeaderElement) headerElement).setProcessed(true);
/*
* Now we can check the certificate used to sign the message.
* In the following implementation the certificate is only trusted
* if either it itself or the certificate of the issuer is installed
* in the keystore.
*
* Note: the method verifyTrust(X509Certificate) allows custom
* implementations with other validation algorithms for subclasses.
*/
// Extract the signature action result from the action vector
WSSecurityEngineResult actionResult = WSSecurityUtil.fetchActionResult(wsResult, WSConstants.SIGN);
if (actionResult != null) {
X509Certificate returnCert = actionResult.getCertificate();
if (returnCert != null) {
if (!verifyTrust(returnCert)) {
throw new AxisFault("WSDoAllReceiver: The certificate used for the signature is not trusted");
}
}
}
/*
* Perform further checks on the timestamp that was transmitted in the header.
* In the following implementation the timestamp is valid if it was
* created after (now-ttl), where ttl is set on server side, not by the client.
*
* Note: the method verifyTimestamp(Timestamp) allows custom
* implementations with other validation algorithms for subclasses.
*/
// Extract the timestamp action result from the action vector
actionResult = WSSecurityUtil.fetchActionResult(wsResult, WSConstants.TS);
if (actionResult != null) {
Timestamp timestamp = actionResult.getTimestamp();
if (timestamp != null) {
String ttl = null;
if ((ttl =
(String) getOption(WSDoAllConstants.TTL_TIMESTAMP))
== null) {
ttl =
(String) msgContext.getProperty(
WSDoAllConstants.TTL_TIMESTAMP);
}
int ttl_i = 0;
if (ttl != null) {
try {
ttl_i = Integer.parseInt(ttl);
} catch (NumberFormatException e) {
ttl_i = timeToLive;
}
}
if (ttl_i <= 0) {
ttl_i = timeToLive;
}
if (!verifyTimestamp(timestamp, timeToLive)) {
throw new AxisFault("WSDoAllReceiver: The timestamp could not be validated");
}
}
}
/*
* now check the security actions: do they match, in right order?
*/
int resultActions = wsResult.size();
int size = actions.size();
if (size != resultActions) {
throw new AxisFault("WSDoAllReceiver: security processing failed (actions number mismatch)");
}
for (int i = 0; i < size; i++) {
if (((Integer) actions.get(i)).intValue()
!= ((WSSecurityEngineResult)wsResult.get(i)).getAction()) {
throw new AxisFault("WSDoAllReceiver: security processing failed (actions mismatch)");
}
}
/*
* All ok up to this point. Now construct and setup the
* security result structure. The service may fetch this
* and check it.
*/
Vector results = null;
if ((results = (Vector) mc.getProperty(WSDoAllConstants.RECV_RESULTS))
== null) {
results = new Vector();
mc.setProperty(WSDoAllConstants.RECV_RESULTS, results);
}
WSDoAllReceiverResult rResult =
new WSDoAllReceiverResult(
actor,
wsResult);
results.add(0, rResult);
if (doDebug) {
log.debug("WSDoAllReceiver: exit invoke()");
}
}
/**
* Hook to allow subclasses to load their Signature Crypto however they see fit.
*/
protected Crypto loadSignatureCrypto() throws AxisFault {
Crypto crypto = null;
if ((sigPropFile = (String) getOption(WSDoAllConstants.SIG_PROP_FILE))
== null) {
sigPropFile =
(String) msgContext.getProperty(WSDoAllConstants.SIG_PROP_FILE);
}
if (sigPropFile != null) {
if ((crypto = (Crypto) cryptos.get(sigPropFile)) == null) {
crypto = CryptoFactory.getInstance(sigPropFile);
cryptos.put(sigPropFile, crypto);
}
} else {
throw new AxisFault("WSDoAllReceiver: Signature: no crypto property file");
}
return crypto;
}
/**
* Hook to allow subclasses to load their Decryption Crypto however they see fit.
*/
protected Crypto loadDecryptionCrypto() throws AxisFault {
Crypto crypto = null;
if ((decPropFile = (String) getOption(WSDoAllConstants.DEC_PROP_FILE))
== null) {
decPropFile =
(String) msgContext.getProperty(WSDoAllConstants.DEC_PROP_FILE);
}
if (decPropFile != null) {
if ((crypto = (Crypto) cryptos.get(decPropFile)) == null) {
crypto = CryptoFactory.getInstance(decPropFile);
cryptos.put(decPropFile, crypto);
}
} else if ((crypto = sigCrypto) == null) {
throw new AxisFault("WSDoAllReceiver: Encryption: no crypto property file");
}
return crypto;
}
private void decodeSignatureParameter() throws AxisFault {
sigCrypto = loadSignatureCrypto();
/* There are currently no other signature parameters that need to be handled
* here, but we call the load crypto hook rather than just changing the visibility
* of this method to maintain parity with WSDoAllSender.
*/
}
/*
* Set and check the decryption specific parameters, if necessary
* take over signatur crypto instance.
*/
private void decodeDecryptionParameter() throws AxisFault {
decCrypto = loadDecryptionCrypto();
/* There are currently no other decryption parameters that need to be handled
* here, but we call the load crypto hook rather than just changing the visibility
* of this method to maintain parity with WSDoAllSender.
*/
}
/**
* Get the password callback class and get an instance
* <p/>
*/
private CallbackHandler getPasswordCB() throws AxisFault {
String callback = null;
CallbackHandler cbHandler = null;
if ((callback = (String) getOption(WSDoAllConstants.PW_CALLBACK_CLASS))
== null) {
callback =
(String) msgContext.getProperty(
WSDoAllConstants.PW_CALLBACK_CLASS);
}
if (callback != null) {
Class cbClass = null;
try {
cbClass = java.lang.Class.forName(callback);
} catch (ClassNotFoundException e) {
throw new AxisFault(
"WSDoAllReceiver: cannot load password callback class: "
+ callback,
e);
}
try {
cbHandler = (CallbackHandler) cbClass.newInstance();
} catch (java.lang.Exception e) {
throw new AxisFault(
"WSDoAllReceiver: cannot create instance of password callback: "
+ callback,
e);
}
} else {
cbHandler =
(CallbackHandler) msgContext.getProperty(
WSDoAllConstants.PW_CALLBACK_REF);
if (cbHandler == null) {
throw new AxisFault("WSDoAllReceiver: no reference in callback property");
}
}
return cbHandler;
}
/**
* Evaluate whether a given certificate should be trusted.
* Hook to allow subclasses to implement custom validation methods however they see fit.
* <p/>
* Policy used in this implementation:
* 1. Search the keystore for the transmitted certificate
* 2. Search the keystore for a connection to the transmitted certificate
* (that is, search for certificate(s) of the issuer of the transmitted certificate
* 3. Verify the trust path for those certificates found because the search for the issuer might be fooled by a phony DN (String!)
*
* @param cert the certificate that should be validated against the keystore
* @return true if the certificate is trusted, false if not (AxisFault is thrown for exceptions during CertPathValidation)
* @throws AxisFault
*/
private boolean verifyTrust(X509Certificate cert) throws AxisFault {
// If no certificate was transmitted, do not trust the signature
if (cert == null) {
return false;
}
String[] aliases = null;
String alias = null;
X509Certificate[] certs;
String subjectString = cert.getSubjectDN().getName();
String issuerString = cert.getIssuerDN().getName();
BigInteger issuerSerial = cert.getSerialNumber();
if (doDebug) {
log.debug("WSDoAllReceiver: Transmitted certificate has subject " + subjectString);
log.debug("WSDoAllReceiver: Transmitted certificate has issuer " + issuerString + " (serial " + issuerSerial + ")");
}
// FIRST step
// Search the keystore for the transmitted certificate
// Search the keystore for the alias of the transmitted certificate
try {
alias = sigCrypto.getAliasForX509Cert(issuerString, issuerSerial);
} catch (WSSecurityException ex) {
throw new AxisFault("WSDoAllReceiver: Could not get alias for certificate with " + subjectString, ex);
}
if (alias != null) {
// Retrieve the certificate for the alias from the keystore
try {
certs = sigCrypto.getCertificates(alias);
} catch (WSSecurityException ex) {
throw new AxisFault("WSDoAllReceiver: Could not get certificates for alias " + alias, ex);
}
// If certificates have been found, the certificates must be compared
// to ensure againgst phony DNs (compare encoded form including signature)
if (certs != null && certs.length > 0 && cert.equals(certs[0])) {
if (doDebug) {
log.debug("Direct trust for certificate with " + subjectString);
}
return true;
}
} else {
if (doDebug) {
log.debug("No alias found for subject from issuer with " + issuerString + " (serial " + issuerSerial + ")");
}
}
// SECOND step
// Search for the issuer of the transmitted certificate in the keystore
// Search the keystore for the alias of the transmitted certificates issuer
try {
aliases = sigCrypto.getAliasesForDN(issuerString);
} catch (WSSecurityException ex) {
throw new AxisFault("WSDoAllReceiver: Could not get alias for certificate with " + issuerString, ex);
}
// If the alias has not been found, the issuer is not in the keystore
// As a direct result, do not trust the transmitted certificate
if (aliases == null || aliases.length < 1) {
if (doDebug) {
log.debug("No aliases found in keystore for issuer " + issuerString + " of certificate for " + subjectString);
}
return false;
}
// THIRD step
// Check the certificate trust path for every alias of the issuer found in the keystore
for (int i = 0; i < aliases.length; i++) {
alias = aliases[i];
if (doDebug) {
log.debug("Preparing to validate certificate path with alias " + alias + " for issuer " + issuerString);
}
// Retrieve the certificate(s) for the alias from the keystore
try {
certs = sigCrypto.getCertificates(alias);
} catch (WSSecurityException ex) {
throw new AxisFault("WSDoAllReceiver: Could not get certificates for alias " + alias, ex);
}
// If no certificates have been found, there has to be an error:
// The keystore can find an alias but no certificate(s)
if (certs == null | certs.length < 1) {
throw new AxisFault("WSDoAllReceiver: Could not get certificates for alias " + alias);
}
// Form a certificate chain from the transmitted certificate
// and the certificate(s) of the issuer from the keystore
// First, create new array
X509Certificate[] x509certs = new X509Certificate[certs.length + 1];
/* The following conversion into provider specific format seems not to be necessary
// Create new certificate, possibly provider-specific
try {
cert = sigCrypto.loadCertificate(new ByteArrayInputStream(cert.getEncoded()));
} catch (CertificateEncodingException ex) {
throw new AxisFault("WSDoAllReceiver: Combination of subject and issuers certificates failed", ex);
} catch (WSSecurityException ex) {
throw new AxisFault("WSDoAllReceiver: Combination of subject and issuers certificates failed", ex);
}
*/
// Then add the first certificate ...
x509certs[0] = cert;
// ... and the other certificates
for (int j=0; j < certs.length; j++) {
cert = certs[i];
/* The following conversion into provider specific format seems not to be necessary
// Create new certificate, possibly provider-specific
try {
cert = sigCrypto.loadCertificate(new ByteArrayInputStream(cert.getEncoded()));
} catch (CertificateEncodingException ex) {
throw new AxisFault("WSDoAllReceiver: Combination of subject and issuers certificates failed", ex);
} catch (WSSecurityException ex) {
throw new AxisFault("WSDoAllReceiver: Combination of subject and issuers certificates failed", ex);
}
*/
x509certs[certs.length + j] = cert;
}
certs = x509certs;
// Use the validation method from the crypto to check whether the subjects certificate was really signed by the issuer stated in the certificate
try {
if (sigCrypto.validateCertPath(certs)) {
if (doDebug) {
log.debug("WSDoAllReceiver: Certificate path has been verified for certificate with subject " + subjectString);
}
return true;
}
} catch (WSSecurityException ex) {
throw new AxisFault("WSDoAllReceiver: Certificate path verification failed for certificate with subject " + subjectString, ex);
}
}
log.debug("WSDoAllReceiver: Certificate path could not be verified for certificate with subject " + subjectString);
return false;
}
/**
* Evaluate whether a timestamp is considered valid on receiverside.
* Hook to allow subclasses to implement custom validation methods however they see fit.
* <p/>
* Policy used in this implementation:
* 1. The receiver can set its own time to live (besides from that set on sender side)
* 2. If the message was created before (now-ttl) the message is rejected
*
* @param timestamp the timestamp that is validated
* @param timeToLive the limit on receiverside, the timestamp is validated against
* @return true if the timestamp is before (now-timeToLive), false otherwise
* @throws AxisFault
*/
protected boolean verifyTimestamp(Timestamp timestamp, int timeToLive) throws AxisFault {
// Calculate the time that is allowed for the message to travel
Calendar validCreation = Calendar.getInstance();
long currentTime = validCreation.getTimeInMillis();
currentTime -= timeToLive * 1000;
validCreation.setTimeInMillis(currentTime);
if (doDebug) {
log.debug("Preparing to verify the timestamp");
SimpleDateFormat zulu = new SimpleDateFormat(
"yyyy-MM-dd'T'HH:mm:ss'Z'");
zulu.setTimeZone(TimeZone.getTimeZone("GMT"));
log.debug("Validation of Timestamp: Current time is "
+ zulu.format(Calendar.getInstance().getTime()));
log.debug("Validation of Timestamp: Valid creation is "
+ zulu.format(validCreation.getTime()));
log.debug("Validation of Timestamp: Timestamp created is "
+ zulu.format(timestamp.getCreated().getTime()));
}
// Validate the time it took the message to travel
// if (timestamp.getCreated().before(validCreation) ||
// !timestamp.getCreated().equals(validCreation)) {
if (!timestamp.getCreated().after(validCreation)) {
if (doDebug) {
log.debug("Validation of Timestamp: The message was created too long ago");
}
return false;
}
log.debug("Validation of Timestamp: Everything is ok");
return true;
}
}
1.1 ws-axis/contrib/ews/src/org/apache/ws/axis/security/BasicAuth4J2EEReceiver.java
Index: BasicAuth4J2EEReceiver.java
===================================================================
/*
* Created on Jun 20, 2004
*
*
*/
package org.apache.ws.axis.security;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import org.apache.axis.AxisFault;
import org.apache.axis.MessageContext;
import org.apache.axis.handlers.BasicHandler;
import org.apache.geronimo.ews.ws4j2ee.context.security.impl.SecurityContext4J2EEImpl;
import org.apache.ws.axis.security.WSDoAllConstants;
import org.apache.ws.security.WSPasswordCallback;
/**
* If the client is using BasicHTTP Authentication, this class can be used
* as a server side Axis handler, which retreives the credentials available in
* the HTTP header and populate the SecurityContext4J2EE property.
*
* Only if the <code>WSS4J2EEConstants.AUTH_AT_AXIS</code> property is set to true,
* this does the authentication at the Axis. For that at the DD the <code>passwordCallbackClass</code>
* should be available.
*
* @author Rajith Priyanga
* @date Jun 20, 2004
*
*/
public class BasicAuth4J2EEReceiver extends BasicHandler {
private boolean doAuthentication = false;
/**
* @see org.apache.axis.Handler#invoke(org.apache.axis.MessageContext)
*/
public void invoke(MessageContext cntxt) throws AxisFault {
doAuthentication = false;
String username = cntxt.getUsername();
String password = cntxt.getPassword();
if(username==null|| password==null){
throw AxisFault.makeFault(new Exception("null values for username or/and password."));
}
//Decides whether to do authentication at Axis or not.
if(cntxt.containsProperty(WSS4J2EEConstants.AUTH_AT_AXIS)){
String check = (String)cntxt.getProperty(WSS4J2EEConstants.AUTH_AT_AXIS);
if(check!=null && check.equalsIgnoreCase("true"))
this.doAuthentication = true;
}
if(this.doAuthentication){
try{
this.veryfyPWD(username, password, cntxt);
}
catch(Exception e){
throw AxisFault.makeFault(e);
}
}
populateSecurityContext4J2EE(username, password, cntxt);
}
/**
* Populates the SecurityContext4J2EE property with the given credentials.
* Also this adds a PWDCallbackHandler4J2EE to the SecurityContext4J2EE.
* @param username
* @param password
* @param cntxt
*/
private void populateSecurityContext4J2EE(String username, String password, MessageContext cntxt){
SecurityContext4J2EEImpl sc4j2ee =
(SecurityContext4J2EEImpl)cntxt.getProperty(WSS4J2EEConstants.SEC_CONTEXT_4J2EE);
if(sc4j2ee==null){
sc4j2ee = new SecurityContext4J2EEImpl();
cntxt.setProperty(WSS4J2EEConstants.SEC_CONTEXT_4J2EE, sc4j2ee);
}
//Populate the SecurityContext4J2EE with the auth data.
sc4j2ee.setUsername(username);
sc4j2ee.setPassword(password.toCharArray());
sc4j2ee.setPasswordDigested(false);
PWDCallbackHandler4J2EE pwdcbh = new PWDCallbackHandler4J2EE(username, password.toCharArray());
sc4j2ee.setPWDCallbackHandler4J2EE(pwdcbh);
}
private boolean veryfyPWD(String username, String password, MessageContext cntxt) throws Exception{
if(password.equals(this.fetchActualPWD(username, cntxt))){
return true;
}
else{
return false;
}
}
private String fetchActualPWD(String username, MessageContext cntxt) throws Exception{
WSPasswordCallback pwcb = new WSPasswordCallback(username, WSPasswordCallback.USERNAME_TOKEN);
Callback[] cb = new Callback[1];
cb[0] = pwcb;
CallbackHandler cbh = (CallbackHandler)cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_REF);
if(cbh == null){
String cbhClass = (String)cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_CLASS);
cbh = (CallbackHandler)Class.forName(cbhClass).newInstance();
}
if(cbh==null){
throw new Exception("PasswordCallbackHandler not found!");
}
cbh.handle(cb);
String pwd = ((WSPasswordCallback)(cb[0])).getPassword();
if(pwd==null)
throw new Exception("Password is not provided.");
return pwd;
}
}
1.1 ws-axis/contrib/ews/src/org/apache/ws/axis/security/SimpleWSS4J2EEReceiver.java
Index: SimpleWSS4J2EEReceiver.java
===================================================================
/*
* Created on May 29, 2004
*
*
*/
package org.apache.ws.axis.security;
import java.util.Iterator;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.xml.soap.Name;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPFactory;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPHeaderElement;
import org.apache.axis.AxisFault;
import org.apache.axis.Message;
import org.apache.axis.MessageContext;
import org.apache.axis.handlers.BasicHandler;
import org.apache.geronimo.ews.ws4j2ee.context.security.impl.SecurityContext4J2EEImpl;
import org.apache.ws.axis.security.WSDoAllConstants;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.WSPasswordCallback;
import org.apache.ws.security.message.token.UsernameToken;
/**
* This is an Axis handler that can be used to retrieve the credentials
* available in the <code>UsernameToken</code> element.
* This is a simple security handler that can provide only that service.
* Therefore this handler can be used for testing perposes and
* other simple works.
*
* This can be configured to do the authentication at Axis or at J2EE Server.
* For that you have to set the <code>WSS4J2EEConstants.AUTH_AT_AXIS</code>
* to true.
*
*
* @author Rajith Priyanga (rpriyanga@yahoo.com)
* @date May 29, 2004
*
*/
public class SimpleWSS4J2EEReceiver extends BasicHandler {
MessageContext cntxt = null;
boolean doAuthentication = false;
/**
* Retrieve the username-password information and perform a verification.
* @see org.apache.axis.Handler#invoke(org.apache.axis.MessageContext)
*/
public void invoke(MessageContext msgCntxt) throws AxisFault {
this.cntxt = msgCntxt;
doAuthentication = false;
try{
//Get the SOAP header.
Message m = msgCntxt.getCurrentMessage();
SOAPHeader sh = m.getSOAPPart().getEnvelope().getHeader();
//Retrieve the action property.
String action = null;
if((action = (String) getOption(WSDoAllConstants.ACTION))==null)
action = (String)cntxt.getProperty(WSDoAllConstants.ACTION);
if(action==null){
return;
}
String[] actions = action.split(" ");
if(actions==null)
return;
boolean utAction = false;
//Check whether UsernameToken action property is available. Otherwise no more processing.
for(int i=0; i<actions.length; i++){
utAction = actions[i].equalsIgnoreCase(WSDoAllConstants.USERNAME_TOKEN);
if(utAction)
break;
}
if(!utAction)
return;
//Get all the headers.
Iterator headers = sh.getChildElements();
SOAPHeaderElement headerElem = null;
if(headers==null){
throw AxisFault.makeFault(new Exception("No Security Headers found"));
}
//Find the security header.
while (headers.hasNext()) {
headerElem = (SOAPHeaderElement) headers.next();
if (headerElem.getLocalName().equals(WSConstants.WSSE_LN)
&& headerElem.getNamespaceURI().equals(WSConstants.WSSE_NS)) {
//headerElem.setMustUnderstand(false);
break;
}
}
//Decides whether to do authentication at Axis or not.
if(cntxt.containsProperty(WSS4J2EEConstants.AUTH_AT_AXIS)){
String check = (String)cntxt.getProperty(WSS4J2EEConstants.AUTH_AT_AXIS);
if(check!=null && check.equalsIgnoreCase("true"))
this.doAuthentication = true;
}
//Hand over the security header to process it's UsernameToken.
processUsernameToken(headerElem);
headerElem.detachNode();
}
catch(Exception ex){
throw AxisFault.makeFault(ex);
}
}
/**
* Processes the UsernameToken element of the security header.
* It populates the SecurityContext4J2EE property of the MessageContext too.
* @param secHeader SOAP Security Header.
* @throws Exception
*/
private void processUsernameToken(SOAPHeaderElement secHeader) throws Exception{
SOAPFactory sf = SOAPFactory.newInstance();
Name utName = sf.createName(WSConstants.USERNAME_TOKEN_LN, WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS);
Iterator toks = secHeader.getChildElements(utName);
if(toks==null){
throw new Exception("No Security tokens found!");
}
//Get the UsernameToken element
SOAPElement utElem = null;
if(toks.hasNext()){
utElem = (SOAPElement)toks.next();
}
else{
throw new Exception("No UsernameToken found!");
}
Name unName = sf.createName(WSConstants.USERNAME_LN, WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS);
Name pwdName = sf.createName(WSConstants.PASSWORD_LN, WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS);
//Get the user name
String username = ((SOAPElement)(utElem.getChildElements(unName).next())).getValue();
//Get the password element
SOAPElement pwdElem = (SOAPElement)utElem.getChildElements(pwdName).next();
//Get the password type
String pwdType = pwdElem.getAttributeValue(sf.createName(WSConstants.PASSWORD_TYPE_ATTR, WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS));//, WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS));
//Get the password
String pwd = pwdElem.getValue();
//If the password type is not speciied take it as PASSWORD_TEXT type.
if(pwdType==null)
pwdType = WSConstants.PASSWORD_TEXT;
if(pwdType.equalsIgnoreCase(WSConstants.PASSWORD_TEXT)){
///////////// This part can be removed. . /////////////////
if(doAuthentication){
if(!veryfyPWD(username, pwd)){
throw new Exception("Password Verification failed!");
}
}
///////////////////////////////////////////////////////////
this.populateSecurityContext4J2EE(username, pwd, pwdType, null, null);
//this.Authenticate4J2EE();
}
else if(pwdType.equalsIgnoreCase(WSConstants.PASSWORD_DIGEST)){
Name nonceName = sf.createName(WSConstants.NONCE_LN, WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS);
Name createdName = sf.createName(WSConstants.CREATED_LN, WSConstants.WSU_PREFIX, WSConstants.WSU_NS);
Iterator elems = utElem.getChildElements(nonceName);
String nonce = this.extractNonce(elems);
elems = utElem.getChildElements(createdName);
String created = this.extractCreated(elems);
///////////// This part can be removed. . /////////////////
if(doAuthentication){
if(!veryfyPWD(username, pwd, nonce, created)){
throw new Exception("Password Verification failed!");
}
}
///////////////////////////////////////////////////////////
this.populateSecurityContext4J2EE(username, pwd, pwdType, nonce, created);
}
else{
throw new Exception("Unsupported Password Type!");
}
}
/**
* Extracts the nonce value from the given set of elements.
* (It is given as a iteratorf o elements)
* @param elements
* @return
* @throws Exception
*/
private String extractNonce(Iterator elements) throws Exception{
boolean noNonce = false;
String nonce = null;
if(elements==null){
noNonce = true;
}
if(!noNonce && elements.hasNext()){
nonce = ((SOAPElement)(elements.next())).getValue();
}
else{
noNonce = true;
}
if(nonce == null){
noNonce = true;
}
if(noNonce)
throw new Exception("Nonce is not specified!");
return nonce;
}
/**
* Extracts the created value from the given set of elements.
* (It is given as a iteratorf o elements)
* @param elements
* @return
* @throws Exception
*/
private String extractCreated(Iterator elements) throws Exception{
boolean noCreated = false;
String created = null;
if(elements==null)
noCreated = true;
if(!noCreated && elements.hasNext())
created = ((SOAPElement)(elements.next())).getValue();
else
noCreated = true;
if(created == null)
noCreated = true;
if(noCreated)
throw new Exception("Created is not specified!");
return created;
}
/**
* Verifies the PASSWORD_TEXT type passwords.
*/
private boolean veryfyPWD(String username, String password) throws Exception{
if(password.equals(this.fetchActualPWD(username))){
return true;
}
else{
return false;
}
}
/**
* Verifies the PASSWORD_DIGEST type passwords.
*/
private boolean veryfyPWD(String username,
String password,
String nonce,
String created) throws Exception{
//TODO
//Check whether (created > currentTime - 5 minutes).
//Cache the nonce for the user and check it before verification.
if(nonce == null || created == null){
throw new Exception("Nonce or Created not supplied!");
}
String digest = UsernameToken.doPasswordDigest(nonce, created, this.fetchActualPWD(username));
if(password.equals(digest)){
return true;
}
else{
return false;
}
}
/**}
* Fetches the actual password using the CallbackHandler specified
* in the deployment descripter.
* @param username username
* @return the actual password of the user.
* @throws Exception
*/
private String fetchActualPWD(String username) throws Exception{
WSPasswordCallback pwcb = new WSPasswordCallback(username, WSPasswordCallback.USERNAME_TOKEN);
Callback[] cb = new Callback[1];
cb[0] = pwcb;
CallbackHandler cbh = (CallbackHandler)this.cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_REF);
if(cbh == null){
String cbhClass = (String)this.cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_CLASS);
cbh = (CallbackHandler)Class.forName(cbhClass).newInstance();
}
if(cbh==null){
throw new Exception("PasswordCallbackHandler not found!");
}
cbh.handle(cb);
String pwd = ((WSPasswordCallback)(cb[0])).getPassword();
if(pwd==null)
throw new Exception("Password is not provided.");
return pwd;
}
/**
* Associates a Authenticated principal with this thread this thread.
* @throws Exception
*/
/*private void Authenticate4J2EE() throws Exception{
CallbackHandler cbh = (CallbackHandler)this.cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_REF);
if(cbh == null){
String cbhClass = (String)this.cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_CLASS);
cbh = (CallbackHandler)Class.forName(cbhClass).newInstance();
}
if(cbh != null){
javax.security.auth.login.LoginContext lc
= new javax.security.auth.login.LoginContext("LC4" + this.cntxt.getTargetService(), cbh);
lc.login();
}
else
throw new Exception("CallbackHandler is null.");
}*/
/**
* Populates the SecurityContext4J2EE property with the given
* security information.
* @param username
* @param password
* @param passwordType
* @param nonce
* @param created
*/
private void populateSecurityContext4J2EE(String username, String password, String passwordType, String nonce, String created){
SecurityContext4J2EEImpl sc4j2ee =
(SecurityContext4J2EEImpl)this.cntxt.getProperty(WSS4J2EEConstants.SEC_CONTEXT_4J2EE);
if(sc4j2ee==null){
sc4j2ee = new SecurityContext4J2EEImpl();
this.cntxt.setProperty(WSS4J2EEConstants.SEC_CONTEXT_4J2EE, sc4j2ee);
}
//Populate the SecurityContext4J2EE with the user name token data.
sc4j2ee.setUsername(username);
sc4j2ee.setPassword(password.toCharArray());
if(passwordType.equalsIgnoreCase(WSConstants.PASSWORD_DIGEST)){
sc4j2ee.setPasswordDigested(true);
sc4j2ee.setNonce(nonce);
sc4j2ee.setCreated(created);
}
else
sc4j2ee.setPasswordDigested(false);
PWDCallbackHandler4J2EE cbh = new PWDCallbackHandler4J2EE(username, password.toCharArray());
sc4j2ee.setPWDCallbackHandler4J2EE(cbh);
}
}
1.1 ws-axis/contrib/ews/src/org/apache/ws/axis/security/CheckPoint4J2EEHandler.java
Index: CheckPoint4J2EEHandler.java
===================================================================
/*
* Created on Apr 6, 2004
*
*
*/
package org.apache.ws.axis.security;
import org.apache.axis.AxisFault;
import org.apache.axis.MessageContext;
import org.apache.axis.handlers.BasicHandler;
import org.apache.geronimo.ews.ws4j2ee.context.security.SecurityContext4J2EE;
/**
*
* Still this is not in use. But may be in future...
*
* @author Rajith Priyanga (rpriyanga@yahoo.com)
* @date Apr 6, 2004
*
*/
public abstract class CheckPoint4J2EEHandler extends BasicHandler {
/**
* @see org.apache.axis.Handler#invoke(org.apache.axis.MessageContext)
*/
public void invoke(MessageContext cntxt) throws AxisFault{
SecurityContext4J2EE sc4j2ee;
//TODO
//Populate the SecurityContext4J2EE object with available info.
//Other info will be dynamically calculated rom MessageCOntext.
}
/**
* Decides whether the message integrity is sufficiently varifiable.
* @param cntxt Message context.
* @return true if the test is passed.
*/
public abstract boolean integrityTest(MessageContext cntxt);
/**
* Decides whether the message privacy is sufficiently protected.
* @param cntxt Message context
* @return true if the test is passed.
*/
public abstract boolean privacyTest(MessageContext cntxt);
/**
* Returns the password of the given user. This should be retrieved
* from a password store.
* @param username
* @return The actual password.
*/
public abstract char[] getPassword(String username);
}
1.5 +4 -3 ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/toWs/wrapperWs/SimpleRemoteInterfaceBasedWrapperClassWriter.java
Index: SimpleRemoteInterfaceBasedWrapperClassWriter.java
===================================================================
RCS file: /home/cvs/ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/toWs/wrapperWs/SimpleRemoteInterfaceBasedWrapperClassWriter.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- SimpleRemoteInterfaceBasedWrapperClassWriter.java 10 Jun 2004 11:35:19 -0000 1.4
+++ SimpleRemoteInterfaceBasedWrapperClassWriter.java 7 Jul 2004 09:02:00 -0000 1.5
@@ -136,10 +136,11 @@
out.write("\t\tif(msgcontext == null){\n");
out.write("\t\t msgcontext = org.apache.axis.MessageContext.getCurrentContext();\n");
out.write("\t\t}\n");
-
+ out.write("\t\torg.apache.geronimo.ews.ws4j2ee.context.security.SecurityContext4J2EE seccontext =\n");
+ out.write("\t\t (org.apache.geronimo.ews.ws4j2ee.context.security.SecurityContext4J2EE)msgcontext\n");
+ out.write("\t\t.getProperty(org.apache.ws.axis.security.WSS4J2EEConstants.SEC_CONTEXT_4J2EE);\n");
out.write("\t\t javax.security.auth.callback.CallbackHandler handler\n");
- out.write("\t\t = org.apache.geronimo.ews.ws4j2ee.wsutils.security.jaasmodules.\n");
- out.write("\t\t AutenticationCallbackHandlerFactory.createCallbackHandler(msgcontext);\n");
+ out.write("\t\t = seccontext.getPWDCallbackHandler4J2EE();\n");
out.write("\t\t if(handler != null){\n");
out.write("\t\t javax.security.auth.login.LoginContext lc\n");
out.write("\t\t = new javax.security.auth.login.LoginContext(\"TestClient\", handler);\n");
1.2 +11 -5 ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/context/security/SecurityContext4J2EE.java
Index: SecurityContext4J2EE.java
===================================================================
RCS file: /home/cvs/ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/context/security/SecurityContext4J2EE.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- SecurityContext4J2EE.java 14 Jun 2004 08:24:39 -0000 1.1
+++ SecurityContext4J2EE.java 7 Jul 2004 09:02:00 -0000 1.2
@@ -1,10 +1,8 @@
-/*
- * Created on Apr 5, 2004
- *
- *
- */
package org.apache.geronimo.ews.ws4j2ee.context.security;
+
+
+import javax.security.auth.callback.CallbackHandler;
import javax.security.cert.X509Certificate;
/**
@@ -83,4 +81,12 @@
* @return the X509 Certificate.
*/
public byte[] getKerberoseTicket();
+
+ /**
+ * Returns a PasswordCallbackHandler which can be used in
+ * authentication done using JAAS module at the wrapper web service.
+ * @return CallbackHandler.
+ */
+ public CallbackHandler getPWDCallbackHandler4J2EE();
+
}
1.13 +0 -3 ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/toWs/GenerationConstants.java
Index: GenerationConstants.java
===================================================================
RCS file: /home/cvs/ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/toWs/GenerationConstants.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- GenerationConstants.java 27 Jun 2004 15:20:23 -0000 1.12
+++ GenerationConstants.java 7 Jul 2004 09:02:00 -0000 1.13
@@ -55,9 +55,6 @@
package org.apache.geronimo.ews.ws4j2ee.toWs;
-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.util.Properties;
/**
* <p>This interface has constants that are specific to the generators.</p>
1.6 +1 -1 ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/utils/AntExecuter.java
Index: AntExecuter.java
===================================================================
RCS file: /home/cvs/ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/utils/AntExecuter.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- AntExecuter.java 27 Jun 2004 15:20:24 -0000 1.5
+++ AntExecuter.java 7 Jul 2004 09:02:00 -0000 1.6
@@ -45,7 +45,7 @@
ant.setAntfile(file.getAbsolutePath());
ant.setDir(file.getParentFile());
ant.execute();
- }catch(ClassCastException e){
+ }catch(ClassNotFoundException e){
System.out.println("Ant file will not be run programatcally as the " +
"$JAVA_HOME/lib/tool.jar is not in the class path. To run the ant " +
"prgramatically add that jar to classpath");
}catch(BuildException e){
System.out.println(e.getMessage() +
1.1 ws-axis/contrib/ews/src/org/apache/ws/security/WSS4J2EEEngine.java
Index: WSS4J2EEEngine.java
===================================================================
/*
* Created on May 28, 2004
*
*
*/
package org.apache.ws.security;
import javax.security.auth.callback.CallbackHandler;
import org.apache.axis.MessageContext;
import org.apache.geronimo.ews.ws4j2ee.context.security.impl.SecurityContext4J2EEImpl;
import org.apache.ws.axis.security.PWDCallbackHandler4J2EE;
import org.apache.ws.axis.security.WSS4J2EEConstants;
import org.apache.ws.security.message.token.UsernameToken;
import org.w3c.dom.Element;
/**
* This class is used in <code>AllSecurityReceiver</code<> to process the secuirty
* headers in the SOAP message. This works slightly different from the
* WSSecurityEngine of wss4j project.
* i.e
* This processes the UsernameToken element in a different way.
* The credentials available in the token are retrieved and the
* SecurityContext4J2EE is populated using them.
* No authentication is done at Axis. Therefore no principal
* is created, instead this replace it with null.
*
* Before using the above service, the MessageContext should be set.
*
* @author Davanum Srinivas (dims@yahoo.com).
* @author Werner Dittmann (Werner.Dittmann@siemens.com).
* @author Rajith Priyanga (rpriyanga@yahoo.com)
* @date May 28, 2004
*
*/
public class WSS4J2EEEngine extends WSSecurityEngine{
private MessageContext msgCntxt = null;
public void setMessageContext(MessageContext msgContext) throws Exception{
if(msgContext==null){
throw new Exception("Mssage Context is null!");
}
else{
this.msgCntxt = msgContext;
}
}
/**
* Processes the UsernameToken element and populate the SecurityContext4J2EE prperty
* with the credentials available in it.
* No authentication is done here.
* Always returns null
*/
public WSUsernameTokenPrincipal handleUsernameToken(Element token, CallbackHandler cb) throws WSSecurityException {
UsernameToken ut = new UsernameToken(token);
try{
this.populateSecurityContext4J2EE(ut.getName(),
ut.getPassword().toCharArray(),
ut.isHashed(),
ut.getNonce(),
ut.getCreated());
}
catch(Exception e){
throw new WSSecurityException(WSSecurityException.FAILURE, "Invalid Username Token found!");
}
return null;
}
/**
* Register a SecurityContext4J2EE object with the MessageContext as
* WSS4J2EEConstants.SEC_CONTEXT_4J2EE property.
* Populates the SEC_CONTEXT_4J2EE property with the security information
* avatilable in the UsernameToken.
* @param ut
*/
private void populateSecurityContext4J2EE(String user, char[] pwd, boolean isDigested, String nonce, String created){
SecurityContext4J2EEImpl sc4j2ee =
(SecurityContext4J2EEImpl)this.msgCntxt.getProperty(WSS4J2EEConstants.SEC_CONTEXT_4J2EE);
if(sc4j2ee==null){
sc4j2ee = new SecurityContext4J2EEImpl();
this.msgCntxt.setProperty(WSS4J2EEConstants.SEC_CONTEXT_4J2EE, sc4j2ee);
}
//Populate the SecurityContext4J2EE with the user name token data.
sc4j2ee.setUsername(user);
if(isDigested){
sc4j2ee.setPasswordDigested(true);
sc4j2ee.setNonce(nonce);
sc4j2ee.setCreated(created);
}
else
sc4j2ee.setPasswordDigested(false);
sc4j2ee.setPassword(pwd);
PWDCallbackHandler4J2EE cbh = new PWDCallbackHandler4J2EE(user, pwd);
sc4j2ee.setPWDCallbackHandler4J2EE(cbh);
}
}
1.2 +15 -14 ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/context/security/impl/SecurityContext4J2EEImpl.java
Index: SecurityContext4J2EEImpl.java
===================================================================
RCS file: /home/cvs/ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/context/security/impl/SecurityContext4J2EEImpl.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- SecurityContext4J2EEImpl.java 14 Jun 2004 08:24:39 -0000 1.1
+++ SecurityContext4J2EEImpl.java 7 Jul 2004 09:02:00 -0000 1.2
@@ -1,14 +1,9 @@
-/*
- * Created on Apr 6, 2004
- *
- *
- */
package org.apache.geronimo.ews.ws4j2ee.context.security.impl;
+import javax.security.auth.callback.CallbackHandler;
import javax.security.cert.X509Certificate;
import org.apache.geronimo.ews.ws4j2ee.context.security.SecurityContext4J2EE;
-
/**
* @author Rajith Priyanga (rpriyanga@yahoo.com)
* @date Apr 6, 2004
@@ -27,15 +22,8 @@
private boolean privacy = false;
private boolean integrity = false;
private boolean isPwdDigested= false;
- //private MessageContext cntxt;
+ private CallbackHandler cbh;
- /**
- * This has a circular reference to the MessageContext.
- * @param cntxt
- */
- /*public SecurityContext4J2EEImpl(MessageContext cntxt){
- this.cntxt = cntxt;
- }*/
public SecurityContext4J2EEImpl(){
@@ -192,6 +180,19 @@
*/
public void setPassword(char[] password) {
this.pwd = password;
+ }
+
+
+ /**
+ * @see org.apache.geranimo.ews.ws4j2ee.context.security.SecurityContext4J2EE#getPWDCallbackHandler4J2EE()
+ */
+ public CallbackHandler getPWDCallbackHandler4J2EE() {
+ return this.cbh;
+ }
+
+
+ public void setPWDCallbackHandler4J2EE(CallbackHandler callbackHandler){
+ this.cbh = callbackHandler;
}
}
Re: cvs commit:
ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/context/securi
ty/impl SecurityContext4J2EEImpl.java
Posted by Srinath Perera <he...@opensource.lk>.
Thanks Dims :) , The problem is priyanga extending from the some classes
in the ws-security that has default constructer's and the only way to
extend from them is to have them in the packages
org/apache/ws/axis/security, org/apache/ws/axis/security which is not
beautiful for the package structure.
(I think they are default constructers for the secutiry reasons and the
wss4j can not change them. )
First I have commit them as keeping the classes that have the problem
under ws.xx packages and other inside ews packages. But Priyanga felt and
I am accept the fact that all the code should be in one place. So I put
them inside ws.xx packages.
I try to think way to get away but still I found nothing :(
Thanks
Srinath
> Srinath,
>
> We can fix whatever is needed to be fixed in WSS4J....Just let me know.
>
> thanks,
> dims
>
>
> On 7 Jul 2004 09:02:00 -0000, hemapani@apache.org <he...@apache.org>
> wrote:
>> hemapani 2004/07/07 02:02:00
>>
>> Modified:
>> contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/toWs/wrapperWs
>> SimpleRemoteInterfaceBasedWrapperClassWriter.java
>> contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/context/security
>> SecurityContext4J2EE.java
>> contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/toWs
>> GenerationConstants.java
>> contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/utils
>> AntExecuter.java
>> contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/context/security/impl
>> SecurityContext4J2EEImpl.java
>> Added: contrib/ews/src/org/apache/ws/axis/security
>> PWDCallbackHandler4J2EE.java
>> WSS4J2EEConstants.java
>> BasicAuth4J2EESender.java
>> SimpleWSS4J2EESender.java
>> AllSecurity4J2EEReceiver.java
>> BasicAuth4J2EEReceiver.java
>> SimpleWSS4J2EEReceiver.java
>> CheckPoint4J2EEHandler.java
>> contrib/ews/src/org/apache/ws/security
>> WSS4J2EEEngine.java
>> Removed: contrib/ews/src/org/apache/ws/axis/security
>> WSS4J2EEReceiver.java
>> contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/context/security
>> SimpleWSS4J2EEReceiver.java WSS4J2EEEngine.java
>> WSS4J2EEConstants.java
>> CheckPoint4J2EEHandler.java
>> SimpleWSS4J2EESender.java
>> Log:
>> add priyanga's new Handlers to support secuity
>> had to keep the Handlers in the axis.security/ws.secuirty packages as
>> they have default constructers
>>
>> Revision Changes Path
>> 1.1
>> ws-axis/contrib/ews/src/org/apache/ws/axis/security/PWDCallbackHandler4J2EE.java
>>
>> Index: PWDCallbackHandler4J2EE.java
>> ===================================================================
>> /*
>> * Created on Jun 27, 2004
>> *
>> *
>> */
>> package org.apache.ws.axis.security;
>>
>> import java.io.IOException;
>>
>> 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;
>> /**
>> * This is a simple PasswordCallback Handler that can be used by
>> * Wrapper web service, before invoking the EJB, to authenticate
>> * the client using JAAS.
>> *
>> * @author Rajith Priyanga (rpriyanga@yahoo.com)
>> * @date Jun 27, 2004
>> *
>> */
>> public class PWDCallbackHandler4J2EE implements CallbackHandler{
>>
>> String username = null;
>> char[] password = null;
>>
>> /**
>> * @see
>> javax.security.auth.callback.CallbackHandler#handle(javax.security.auth.callback.Callback[])
>> */
>> public PWDCallbackHandler4J2EE(String username, char[]
>> password){
>> this.username = username;
>> this.password = password;
>> }
>>
>> public void handle(Callback[] callbacks) throws IOException,
>> UnsupportedCallbackException {
>> boolean recognized = false;
>> //Callback handler which implements both the following
>> interfaces
>> //can also be handled.
>> for (int i = 0; i < callbacks.length; i++){
>> if (callbacks[i] instanceof NameCallback){
>> NameCallback ncb = (NameCallback)
>> callbacks[i];
>> ncb.setName(username);
>> recognized = true;
>> }
>> if (callbacks[i] instanceof PasswordCallback){
>> PasswordCallback pcb =
>> (PasswordCallback) callbacks[i];
>> pcb.setPassword(password);
>> recognized = true;
>> }
>> if(!recognized){
>> throw new
>> UnsupportedCallbackException(callbacks[i],
>> "Callback Type is not supported.");
>> }
>> }
>> }
>>
>> }
>>
>> 1.1
>> ws-axis/contrib/ews/src/org/apache/ws/axis/security/WSS4J2EEConstants.java
>>
>> Index: WSS4J2EEConstants.java
>> ===================================================================
>> /*
>> * Created on May 28, 2004
>> *
>> *
>> */
>> package org.apache.ws.axis.security;
>>
>> import org.apache.ws.axis.security.WSDoAllConstants;
>>
>> /**
>> * Defines the Constants used or WS-J2EE security Mapping
>> implementation.
>> *
>> * @author Rajith Priyanga (rpriyanga@yahoo.com)
>> * @date May 28, 2004
>> *
>> */
>> public class WSS4J2EEConstants extends WSDoAllConstants {
>>
>> /**
>> * This property contains the security information required to
>> authenticate
>> * the user to the J2EE server, plus some more information.
>> Represents
>> * a SecurityContext4J2EE object.
>> *
>> */
>> public static final String SEC_CONTEXT_4J2EE =
>> "SEC_CONTEXT_4J2EE";
>>
>> public static final String AUTH_AT_AXIS =
>> "AuthenticationAtAxis";
>> }
>>
>> 1.1
>> ws-axis/contrib/ews/src/org/apache/ws/axis/security/BasicAuth4J2EESender.java
>>
>> Index: BasicAuth4J2EESender.java
>> ===================================================================
>> /*
>> * Created on Jun 20, 2004
>> *
>> *
>> */
>> package org.apache.ws.axis.security;
>>
>> import javax.security.auth.callback.CallbackHandler;
>> import javax.security.auth.callback.Callback;
>>
>> import org.apache.axis.AxisFault;
>> import org.apache.axis.MessageContext;
>> import org.apache.axis.handlers.BasicHandler;
>>
>> import org.apache.ws.axis.security.WSDoAllConstants;
>> import org.apache.ws.security.WSPasswordCallback;
>>
>> /**
>> * This class can be used as a client side Axis handler which can
>> insert
>> * BasicHTTPAuthentication data to the request. This class uses the
>> * PasswordCallbackHandler specified by the client in the DD or Call
>> object,
>> * to obtain the credentials of the client to add to the HTTP header.
>> * (i.e. <code>passwordCallbackClass</code> property.)
>> *
>> * @author Rajith Priyanga (rpriyanga@yahoo.com)
>> * @date Jun 20, 2004
>> *
>> */
>> public class BasicAuth4J2EESender extends BasicHandler {
>>
>> /**
>> * @see
>> org.apache.axis.Handler#invoke(org.apache.axis.MessageContext)
>> */
>> public void invoke(MessageContext cntxt) throws AxisFault {
>> String username = cntxt.getUsername();
>> try{
>> cntxt.setPassword(fetchPWD(username, cntxt));
>> }
>> catch(Exception e){
>> throw AxisFault.makeFault(e);
>> }
>> }
>>
>> /**
>> * Fetches the password to be sent, using the given Password
>> Callback
>> * class.
>> * @param username
>> * @param cntxt
>> * @return
>> * @throws Exception
>> */
>> private String fetchPWD(String username, MessageContext cntxt)
>> throws Exception{
>> if(username==null){
>> throw new Exception("No username provided!");
>> }
>>
>> WSPasswordCallback pwcb = new
>> WSPasswordCallback(username,
>> WSPasswordCallback.USERNAME_TOKEN);
>> Callback[] cb = new Callback[1];
>> cb[0] = pwcb;
>>
>> CallbackHandler cbh =
>> (CallbackHandler)cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_REF);
>> if(cbh == null){
>> String cbhClass =
>> (String)cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_CLASS);
>> cbh =
>> (CallbackHandler)Class.forName(cbhClass).newInstance();
>> }
>> if(cbh == null){
>> throw new Exception("No PasswordCallbackHandler
>> class found.");
>> }
>> else{
>> cbh.handle(cb);
>> }
>> String pwd =
>> ((WSPasswordCallback)(cb[0])).getPassword();
>> if(pwd==null)
>> throw new Exception("No password provided!");
>> return pwd;
>> }
>>
>> }
>>
>> 1.1
>> ws-axis/contrib/ews/src/org/apache/ws/axis/security/SimpleWSS4J2EESender.java
>>
>> Index: SimpleWSS4J2EESender.java
>> ===================================================================
>> /*
>> * Created on May 29, 2004
>> *
>> *
>> */
>> package org.apache.ws.axis.security;
>>
>> import java.text.SimpleDateFormat;
>> import java.util.Calendar;
>> import java.util.Random;
>> import java.util.TimeZone;
>>
>> import javax.security.auth.callback.Callback;
>> import javax.security.auth.callback.CallbackHandler;
>> import javax.xml.soap.Name;
>> import javax.xml.soap.SOAPElement;
>> import javax.xml.soap.SOAPFactory;
>> import javax.xml.soap.SOAPHeader;
>> import javax.xml.soap.SOAPHeaderElement;
>>
>> import org.apache.axis.AxisFault;
>> import org.apache.axis.Message;
>> import org.apache.axis.MessageContext;
>> import org.apache.axis.handlers.BasicHandler;
>> import org.apache.ws.axis.security.WSDoAllConstants;
>> import org.apache.ws.security.WSConstants;
>> import org.apache.ws.security.WSPasswordCallback;
>> import org.apache.ws.security.message.token.UsernameToken;
>>
>> /**
>> *
>> * This is a server side Axis handler that can be used to retrieve the
>> * credentials available in the UsernameToken element. This will
>> * retrieve the credentials and populate the SecurityContext4J2EE
>> * property with them.
>> *
>> * This is a very simple handler that can handle only UsernameToken
>> * elements. So that this can be used for testing peroposes and
>> * other simple works.
>> *
>> * @author Rajith Priyanga (rpriyanga@yahoo.com)
>> * @date May 29, 2004
>> *
>> */
>> public class SimpleWSS4J2EESender extends BasicHandler {
>>
>> MessageContext cntxt = null;
>>
>> /**
>> * Adds the username-password information to the SOAP header
>> * within the UsernameToken, as requested by the user.
>> * @see
>> org.apache.axis.Handler#invoke(org.apache.axis.MessageContext)
>> */
>> public void invoke(MessageContext msgCntxt) throws AxisFault {
>> this.cntxt = msgCntxt;
>> String action =
>> (String)cntxt.getProperty(WSDoAllConstants.ACTION);
>> if(action==null)
>> return;
>>
>> String[] actions = action.split(" ");
>>
>> boolean utAction = false;
>> //Check whether UsernameToken action is requested.
>> Otherwise no more processing.
>> for(int i=0; i<actions.length; i++){
>> utAction =
>> actions[i].equalsIgnoreCase(WSDoAllConstants.USERNAME_TOKEN);
>> if(utAction)
>> break;
>> }
>> if(!utAction)
>> return;
>> //Get the username from the msg context.
>> String username = this.cntxt.getUsername();
>>
>> //If the username property is not in the message
>> context,
>> if(username==null)
>> username =
>> (String)cntxt.getProperty(WSDoAllConstants.USER);
>> if(username==null)
>> throw AxisFault.makeFault(new Exception("No
>> username specified!"));
>>
>> //Get the password type. If it is not defined, the
>> deault is PasswardText.
>> String pwdType =
>> (String)cntxt.getProperty(WSDoAllConstants.PASSWORD_TYPE);
>> if(pwdType==null)
>> pwdType = WSConstants.PASSWORD_TEXT;
>> addUsernameToken(username, pwdType);
>> }
>>
>> /**
>> * Creates and adds the Security-UsernameToken to the SOAP
>> message.
>> * @param username
>> * @param passwordType
>> * @throws AxisFault
>> */
>> private void addUsernameToken(String username, String
>> passwordType) throws AxisFault{
>> Message m = cntxt.getCurrentMessage();
>> try{
>> SOAPHeader h =
>> m.getSOAPPart().getEnvelope().getHeader();
>>
>> SOAPFactory sf = SOAPFactory.newInstance();
>>
>> m.getSOAPEnvelope().addNamespaceDeclaration(WSConstants.WSSE_PREFIX,
>> WSConstants.WSSE_NS);
>>
>> Name secN = sf.createName(WSConstants.WSSE_LN,
>> WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS);
>> SOAPHeaderElement secElem =
>> h.addHeaderElement(secN);
>>
>> //Add the Username Token.
>> SOAPElement utElem =
>> sf.createElement(WSConstants.WSSE_PREFIX+ ":" +
>> WSConstants.USERNAME_TOKEN_LN);
>> secElem.addChildElement(utElem);
>>
>> //Add the Username element.
>> SOAPElement unElem =
>> sf.createElement(WSConstants.WSSE_PREFIX+ ":" +
>> WSConstants.USERNAME_LN);
>> unElem.addTextNode(username);
>> utElem.addChildElement(unElem);
>>
>> //Create the Password element.
>> SOAPElement pwdElem =
>> sf.createElement(WSConstants.WSSE_PREFIX+ ":" +
>> WSConstants.PASSWORD_LN);
>>
>> Name pwdType =
>> sf.createName(WSConstants.PASSWORD_TYPE_ATTR,
>> WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS);
>> //Add password element.
>> if(passwordType.equalsIgnoreCase(WSConstants.PASSWORD_TEXT)){
>> pwdElem.addAttribute(pwdType,WSConstants.PASSWORD_TEXT);
>> pwdElem.addTextNode(fetchPWD(username));
>> utElem.addChildElement(pwdElem);
>> }
>> else
>> if(passwordType.equalsIgnoreCase(WSConstants.PASSWORD_DIGEST)){
>> m.getSOAPEnvelope().addNamespaceDeclaration(WSConstants.WSU_PREFIX,
>> WSConstants.WSU_NS);
>> pwdElem.addAttribute(pwdType,WSConstants.PASSWORD_DIGEST);
>>
>> String nonce = getNonce();
>> String created = getCreated();
>> String digest =
>> UsernameToken.doPasswordDigest(nonce,
>> created, fetchPWD(username));
>>
>> SOAPElement nonceElem =
>> sf.createElement(WSConstants.WSSE_PREFIX+":"+WSConstants.NONCE_LN);
>> SOAPElement createdElem =
>> sf.createElement(WSConstants.WSU_PREFIX+":"+WSConstants.CREATED_LN);
>>
>> nonceElem.addTextNode(nonce);
>> createdElem.addTextNode(created);
>> pwdElem.addTextNode(digest);
>>
>> utElem.addChildElement(pwdElem);
>> utElem.addChildElement(nonceElem);
>> utElem.addChildElement(createdElem);
>> }
>> else{
>> throw AxisFault.makeFault(new
>> Exception("Unsupported PasswordType"));
>> }
>> }
>> catch(Exception ex){
>> throw AxisFault.makeFault(ex);
>> }
>> }
>>
>> /*
>> * Generates nonce.
>> */
>> private String getNonce(){
>> Random rand = new Random();
>> byte[] nonce = new byte[16];
>> rand.nextBytes(nonce);
>> String nonceStr =
>> org.apache.xml.security.utils.Base64.encode(nonce);
>> return nonceStr;
>> }
>>
>> /**
>> * Generates created as per specification.
>> * @return
>> */
>> private String getCreated(){
>> SimpleDateFormat sd = new
>> SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
>> sd.setTimeZone(TimeZone.getTimeZone("GMT"));
>> Calendar now = Calendar.getInstance();
>> return sd.format(now.getTime());
>> }
>>
>> /**
>> * Fetch the password of the user from the specified
>> PasswordCallbak class.
>> * @param username
>> * @return
>> * @throws Exception
>> */
>> private String fetchPWD(String username) throws Exception{
>> WSPasswordCallback pwcb = new
>> WSPasswordCallback(username,
>> WSPasswordCallback.USERNAME_TOKEN);
>> Callback[] cb = new Callback[1];
>> cb[0] = pwcb;
>>
>> CallbackHandler cbh =
>> (CallbackHandler)this.cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_REF);
>> if(cbh == null){
>> String cbhClass =
>> (String)this.cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_CLASS);
>> cbh =
>> (CallbackHandler)Class.forName(cbhClass).newInstance();
>> }
>> if(cbh == null){
>> throw new Exception("No PasswordCallbackHandler
>> class found.");
>> }
>> else{
>> cbh.handle(cb);
>> }
>> String pwd =
>> ((WSPasswordCallback)(cb[0])).getPassword();
>> if(pwd==null)
>> throw new Exception("Password is not provided!
>> Can't create UsernameToken.");
>> return pwd;
>> }
>>
>> }
>>
>> 1.1
>> ws-axis/contrib/ews/src/org/apache/ws/axis/security/AllSecurity4J2EEReceiver.java
>>
>> Index: AllSecurity4J2EEReceiver.java
>> ===================================================================
>> /*
>> * Created on Jun 20, 2004
>> *
>> *
>> */
>> package org.apache.ws.axis.security;
>>
>> import java.io.ByteArrayOutputStream;
>> import java.math.BigInteger;
>> import java.security.cert.X509Certificate;
>> import java.text.SimpleDateFormat;
>> import java.util.Calendar;
>> import java.util.Hashtable;
>> import java.util.Iterator;
>> import java.util.TimeZone;
>> import java.util.Vector;
>>
>> import javax.security.auth.callback.CallbackHandler;
>> import javax.xml.soap.SOAPHeader;
>> import javax.xml.soap.SOAPHeaderElement;
>>
>> import org.apache.axis.AxisFault;
>> import org.apache.axis.Message;
>> import org.apache.axis.MessageContext;
>> import org.apache.axis.SOAPPart;
>> import org.apache.commons.logging.Log;
>> import org.apache.commons.logging.LogFactory;
>> import org.apache.ws.axis.security.WSDoAllConstants;
>> import org.apache.ws.axis.security.WSDoAllReceiver;
>> import org.apache.ws.axis.security.WSDoAllReceiverResult;
>> import org.apache.ws.axis.security.util.AxisUtil;
>> import org.apache.ws.security.SOAPConstants;
>> import org.apache.ws.security.WSConstants;
>> import org.apache.ws.security.WSS4J2EEEngine;
>> import org.apache.ws.security.WSSecurityEngineResult;
>> import org.apache.ws.security.WSSecurityException;
>> import org.apache.ws.security.components.crypto.Crypto;
>> import org.apache.ws.security.components.crypto.CryptoFactory;
>> import org.apache.ws.security.message.token.Timestamp;
>> import org.apache.ws.security.util.WSSecurityUtil;
>> import org.apache.xml.security.utils.XMLUtils;
>> import org.w3c.dom.Document;
>>
>> /**
>> * This class can be used to process any kind of WSSecurity token,
>> * to retrieve the credentials required to Authenticate the user to
>> * J2EE server and to populate the SecurityContext4J2EE property
>> * with them.
>> *
>> * This class is written by modifying the some parts of
>> * the WSDoAllReceiver class availble in WSS4J project. Modification
>> * done to it should also be appeared here. This is a temporary
>> solution
>> * until that class come to a stable state.
>> *
>> * This uses WSS4J2EEEngine instead of WSSecurityEngine. Therefore the
>> * authentication is only taken place at J2EE server, not at Axis.
>> *
>> * @author Rajith Priyanga (rpriyanga@yahoo.com)
>> * @author Werner Dittmann (Werner.Dittmann@siemens.com)
>> * @date Jun 20, 2004
>> *
>> */
>> public class AllSecurity4J2EEReceiver extends WSDoAllReceiver{
>>
>> static final WSS4J2EEEngine sec4j2eeEngine = new
>> WSS4J2EEEngine();
>>
>> static Log log =
>> LogFactory.getLog(WSDoAllReceiver.class.getName());
>>
>> private boolean doDebug = true;
>>
>> private static Hashtable cryptos = new Hashtable(5);
>>
>> private MessageContext msgContext = null;
>>
>> Crypto sigCrypto = null;
>> String sigPropFile = null;
>>
>> Crypto decCrypto = null;
>> String decPropFile = null;
>>
>> protected int timeToLive = 300; // Timestamp: time in seconds
>> the receiver accepts between creation and reception
>>
>> /**
>> * Axis calls invoke to handle a message.
>> * <p/>
>> *
>> * @param mc message context.
>> * @throws AxisFault
>> */
>> public void invoke(MessageContext mc) throws AxisFault {
>>
>> /////////////////////////////////////////
>> try{
>> sec4j2eeEngine.setMessageContext(mc);
>> }
>> catch(Exception ex){
>> throw AxisFault.makeFault(ex);
>> }
>> ////////////////////////////////////////
>>
>> if (doDebug) {
>> log.debug("WSDoAllReceiver: enter invoke() with
>> msg type: "
>> +
>> mc.getCurrentMessage().getMessageType());
>> }
>> msgContext = mc;
>>
>> Vector actions = new Vector();
>> String action = null;
>> if ((action = (String)
>> getOption(WSDoAllConstants.ACTION)) == null) {
>> action = (String)
>> msgContext.getProperty(WSDoAllConstants.ACTION);
>> }
>> if (action == null) {
>> throw new AxisFault("WSDoAllReceiver: No action
>> defined");
>> }
>> int doAction = AxisUtil.decodeAction(action, actions);
>>
>> String actor = (String)
>> getOption(WSDoAllConstants.ACTOR);
>>
>> Message sm = msgContext.getCurrentMessage();
>> Document doc = null;
>> try {
>> doc = sm.getSOAPEnvelope().getAsDocument();
>> if (doDebug) {
>> log.debug("Received SOAP request: ");
>> log.debug(org.apache.axis.utils.XMLUtils.PrettyDocumentToString(doc));
>> }
>> } catch (Exception ex) {
>> throw new AxisFault(
>> "WSDoAllReceiver: cannot convert into
>> document",
>> ex);
>> }
>> /*
>> * Check if it's a response and if its a fault. Don't
>> * process faults.
>> */
>> String msgType = sm.getMessageType();
>> if (msgType != null && msgType.equals(Message.RESPONSE))
>> {
>> SOAPConstants soapConstants =
>> WSSecurityUtil.getSOAPConstants(doc.getDocumentElement());
>> if (WSSecurityUtil
>> .findElement(
>> doc.getDocumentElement(),
>> "Fault",
>> soapConstants.getEnvelopeURI())
>> != null) {
>> return;
>> }
>> }
>>
>> /*
>> * To check a UsernameToken or to decrypt an encrypted
>> message we need
>> * a password.
>> */
>> CallbackHandler cbHandler = null;
>> if ((doAction & (WSConstants.ENCR | WSConstants.UT)) !=
>> 0) {
>> cbHandler = getPasswordCB();
>> }
>>
>> /*
>> * Get and check the Signature specific parameters first
>> because they
>> * may be used for encryption too.
>> */
>>
>> if ((doAction & WSConstants.SIGN) == WSConstants.SIGN) {
>> decodeSignatureParameter();
>> }
>>
>> if ((doAction & WSConstants.ENCR) == WSConstants.ENCR) {
>> decodeDecryptionParameter();
>> }
>>
>> Vector wsResult = null;
>> try {
>> wsResult =
>> sec4j2eeEngine.processSecurityHeader(
>> doc,
>> actor,
>> cbHandler,
>> sigCrypto,
>> decCrypto);
>> } catch (WSSecurityException ex) {
>> ex.printStackTrace();
>> throw new AxisFault(
>> "WSDoAllReceiver: security processing
>> failed",
>> ex);
>> }
>> if (wsResult == null) { // no security
>> header found
>> if (doAction == WSConstants.NO_SECURITY) {
>> return;
>> } else {
>> throw new AxisFault("WSDoAllReceiver:
>> Request does not contain required
>> Security header");
>> }
>> }
>>
>> /*
>> * If we had some security processing, get the original
>> * SOAP part of Axis' message and replace it with new
>> SOAP
>> * part. This new part may contain decrypted elements.
>> */
>> SOAPPart sPart = (org.apache.axis.SOAPPart)
>> sm.getSOAPPart();
>>
>> ByteArrayOutputStream os = new ByteArrayOutputStream();
>> XMLUtils.outputDOM(doc, os, true);
>> sPart.setCurrentMessage(os.toByteArray(),
>> SOAPPart.FORM_BYTES);
>> if (doDebug) {
>> log.debug("Processed received SOAP request");
>> log.debug(org.apache.axis.utils.XMLUtils.PrettyDocumentToString(doc));
>> }
>>
>> /*
>> * After setting the new current message, probably
>> modified because
>> * of decryption, we need to locate the security header.
>> That is,
>> * we force Axis (with getSOAPEnvelope()) to parse the
>> string, build
>> * the new header. Then we examine, look up the security
>> header
>> * and set the header as processed.
>> *
>> * Please note: find all header elements that contain
>> the same
>> * actor that was given to processSecurityHeader(). Then
>> * check if there is a security header with this actor.
>> */
>>
>> SOAPHeader sHeader = null;
>> try {
>> sHeader = sm.getSOAPEnvelope().getHeader();
>> } catch (Exception ex) {
>> throw new AxisFault("WSDoAllReceiver: cannot get
>> SOAP header after security processing", ex);
>> }
>>
>> Iterator headers = sHeader.examineHeaderElements(actor);
>>
>> SOAPHeaderElement headerElement = null;
>> while (headers.hasNext()) {
>> SOAPHeaderElement hE = (SOAPHeaderElement)
>> headers.next();
>> if
>> (hE.getLocalName().equals(WSConstants.WSSE_LN)
>> &&
>> hE.getNamespaceURI().equals(WSConstants.WSSE_NS))
>> {
>> headerElement = hE;
>> break;
>> }
>> }
>> ((org.apache.axis.message.SOAPHeaderElement)
>> headerElement).setProcessed(true);
>>
>> /*
>> * Now we can check the certificate used to sign the
>> message.
>> * In the following implementation the certificate is
>> only trusted
>> * if either it itself or the certificate of the issuer
>> is installed
>> * in the keystore.
>> *
>> * Note: the method verifyTrust(X509Certificate) allows
>> custom
>> * implementations with other validation algorithms for
>> subclasses.
>> */
>>
>> // Extract the signature action result from the action
>> vector
>> WSSecurityEngineResult actionResult =
>> WSSecurityUtil.fetchActionResult(wsResult,
>> WSConstants.SIGN);
>>
>> if (actionResult != null) {
>> X509Certificate returnCert =
>> actionResult.getCertificate();
>>
>> if (returnCert != null) {
>> if (!verifyTrust(returnCert)) {
>> throw new
>> AxisFault("WSDoAllReceiver: The
>> certificate used for the
>> signature is not trusted");
>> }
>> }
>> }
>>
>> /*
>> * Perform further checks on the timestamp that was
>> transmitted in the header.
>> * In the following implementation the timestamp is
>> valid if it was
>> * created after (now-ttl), where ttl is set on server
>> side, not by the client.
>> *
>> * Note: the method verifyTimestamp(Timestamp) allows
>> custom
>> * implementations with other validation algorithms for
>> subclasses.
>> */
>>
>> // Extract the timestamp action result from the action
>> vector
>> actionResult =
>> WSSecurityUtil.fetchActionResult(wsResult,
>> WSConstants.TS);
>>
>> if (actionResult != null) {
>> Timestamp timestamp =
>> actionResult.getTimestamp();
>>
>> if (timestamp != null) {
>> String ttl = null;
>> if ((ttl =
>> (String)
>> getOption(WSDoAllConstants.TTL_TIMESTAMP))
>> == null) {
>> ttl =
>> (String)
>> msgContext.getProperty(
>> WSDoAllConstants.TTL_TIMESTAMP);
>> }
>> int ttl_i = 0;
>> if (ttl != null) {
>> try {
>> ttl_i =
>> Integer.parseInt(ttl);
>> } catch (NumberFormatException
>> e) {
>> ttl_i = timeToLive;
>> }
>> }
>> if (ttl_i <= 0) {
>> ttl_i = timeToLive;
>> }
>>
>> if (!verifyTimestamp(timestamp,
>> timeToLive)) {
>> throw new
>> AxisFault("WSDoAllReceiver: The
>> timestamp could not be
>> validated");
>> }
>> }
>> }
>>
>> /*
>> * now check the security actions: do they match, in
>> right order?
>> */
>> int resultActions = wsResult.size();
>> int size = actions.size();
>> if (size != resultActions) {
>> throw new AxisFault("WSDoAllReceiver: security
>> processing failed (actions number mismatch)");
>> }
>> for (int i = 0; i < size; i++) {
>> if (((Integer) actions.get(i)).intValue()
>> !=
>> ((WSSecurityEngineResult)wsResult.get(i)).getAction())
>> {
>> throw new AxisFault("WSDoAllReceiver:
>> security processing failed (actions
>> mismatch)");
>> }
>> }
>>
>> /*
>> * All ok up to this point. Now construct and setup the
>> * security result structure. The service may fetch this
>> * and check it.
>> */
>> Vector results = null;
>> if ((results = (Vector)
>> mc.getProperty(WSDoAllConstants.RECV_RESULTS))
>> == null) {
>> results = new Vector();
>> mc.setProperty(WSDoAllConstants.RECV_RESULTS,
>> results);
>> }
>> WSDoAllReceiverResult rResult =
>> new WSDoAllReceiverResult(
>> actor,
>> wsResult);
>> results.add(0, rResult);
>> if (doDebug) {
>> log.debug("WSDoAllReceiver: exit invoke()");
>> }
>> }
>>
>> /**
>> * Hook to allow subclasses to load their Signature Crypto
>> however they see fit.
>> */
>> protected Crypto loadSignatureCrypto() throws AxisFault {
>> Crypto crypto = null;
>> if ((sigPropFile = (String)
>> getOption(WSDoAllConstants.SIG_PROP_FILE))
>> == null) {
>> sigPropFile =
>> (String)
>> msgContext.getProperty(WSDoAllConstants.SIG_PROP_FILE);
>> }
>> if (sigPropFile != null) {
>> if ((crypto = (Crypto) cryptos.get(sigPropFile))
>> == null) {
>> crypto =
>> CryptoFactory.getInstance(sigPropFile);
>> cryptos.put(sigPropFile, crypto);
>> }
>> } else {
>> throw new AxisFault("WSDoAllReceiver: Signature:
>> no crypto property file");
>> }
>> return crypto;
>> }
>>
>> /**
>> * Hook to allow subclasses to load their Decryption Crypto
>> however they see fit.
>> */
>> protected Crypto loadDecryptionCrypto() throws AxisFault {
>> Crypto crypto = null;
>> if ((decPropFile = (String)
>> getOption(WSDoAllConstants.DEC_PROP_FILE))
>> == null) {
>> decPropFile =
>> (String)
>> msgContext.getProperty(WSDoAllConstants.DEC_PROP_FILE);
>> }
>> if (decPropFile != null) {
>> if ((crypto = (Crypto) cryptos.get(decPropFile))
>> == null) {
>> crypto =
>> CryptoFactory.getInstance(decPropFile);
>> cryptos.put(decPropFile, crypto);
>> }
>> } else if ((crypto = sigCrypto) == null) {
>> throw new AxisFault("WSDoAllReceiver:
>> Encryption: no crypto property file");
>> }
>> return crypto;
>> }
>>
>> private void decodeSignatureParameter() throws AxisFault {
>> sigCrypto = loadSignatureCrypto();
>> /* There are currently no other signature parameters
>> that need to be handled
>> * here, but we call the load crypto hook rather than
>> just changing the visibility
>> * of this method to maintain parity with WSDoAllSender.
>> */
>> }
>>
>> /*
>> * Set and check the decryption specific parameters, if
>> necessary
>> * take over signatur crypto instance.
>> */
>>
>> private void decodeDecryptionParameter() throws AxisFault {
>> decCrypto = loadDecryptionCrypto();
>> /* There are currently no other decryption parameters
>> that need to be handled
>> * here, but we call the load crypto hook rather than
>> just changing the visibility
>> * of this method to maintain parity with WSDoAllSender.
>> */
>> }
>>
>> /**
>> * Get the password callback class and get an instance
>> * <p/>
>> */
>> private CallbackHandler getPasswordCB() throws AxisFault {
>>
>> String callback = null;
>> CallbackHandler cbHandler = null;
>> if ((callback = (String)
>> getOption(WSDoAllConstants.PW_CALLBACK_CLASS))
>> == null) {
>> callback =
>> (String) msgContext.getProperty(
>> WSDoAllConstants.PW_CALLBACK_CLASS);
>> }
>> if (callback != null) {
>> Class cbClass = null;
>> try {
>> cbClass =
>> java.lang.Class.forName(callback);
>> } catch (ClassNotFoundException e) {
>> throw new AxisFault(
>> "WSDoAllReceiver: cannot load
>> password callback class: "
>> + callback,
>> e);
>> }
>> try {
>> cbHandler = (CallbackHandler)
>> cbClass.newInstance();
>> } catch (java.lang.Exception e) {
>> throw new AxisFault(
>> "WSDoAllReceiver: cannot create
>> instance of password callback: "
>> + callback,
>> e);
>> }
>> } else {
>> cbHandler =
>> (CallbackHandler)
>> msgContext.getProperty(
>> WSDoAllConstants.PW_CALLBACK_REF);
>> if (cbHandler == null) {
>> throw new AxisFault("WSDoAllReceiver: no
>> reference in callback property");
>> }
>> }
>> return cbHandler;
>> }
>>
>> /**
>> * Evaluate whether a given certificate should be trusted.
>> * Hook to allow subclasses to implement custom validation
>> methods however they see fit.
>> * <p/>
>> * Policy used in this implementation:
>> * 1. Search the keystore for the transmitted certificate
>> * 2. Search the keystore for a connection to the transmitted
>> certificate
>> * (that is, search for certificate(s) of the issuer of the
>> transmitted certificate
>> * 3. Verify the trust path for those certificates found because
>> the search for the issuer might be fooled by a phony DN
>> (String!)
>> *
>> * @param cert the certificate that should be validated
>> against the keystore
>> * @return true if the certificate is
>> trusted, false if not (AxisFault is thrown for exceptions
>> during CertPathValidation)
>> * @throws AxisFault
>> */
>> private boolean verifyTrust(X509Certificate cert) throws
>> AxisFault {
>>
>> // If no certificate was transmitted, do not trust the
>> signature
>> if (cert == null) {
>> return false;
>> }
>>
>> String[] aliases = null;
>> String alias = null;
>> X509Certificate[] certs;
>>
>> String subjectString = cert.getSubjectDN().getName();
>> String issuerString = cert.getIssuerDN().getName();
>> BigInteger issuerSerial = cert.getSerialNumber();
>>
>> if (doDebug) {
>> log.debug("WSDoAllReceiver: Transmitted
>> certificate has subject " + subjectString);
>> log.debug("WSDoAllReceiver: Transmitted
>> certificate has issuer " + issuerString + "
>> (serial " + issuerSerial + ")");
>> }
>>
>> // FIRST step
>> // Search the keystore for the transmitted certificate
>>
>> // Search the keystore for the alias of the transmitted
>> certificate
>> try {
>> alias =
>> sigCrypto.getAliasForX509Cert(issuerString,
>> issuerSerial);
>> } catch (WSSecurityException ex) {
>> throw new AxisFault("WSDoAllReceiver: Could not
>> get alias for certificate with " +
>> subjectString, ex);
>> }
>>
>> if (alias != null) {
>> // Retrieve the certificate for the alias from
>> the keystore
>> try {
>> certs =
>> sigCrypto.getCertificates(alias);
>> } catch (WSSecurityException ex) {
>> throw new AxisFault("WSDoAllReceiver:
>> Could not get certificates for alias " +
>> alias, ex);
>> }
>>
>> // If certificates have been found, the
>> certificates must be compared
>> // to ensure againgst phony DNs (compare encoded
>> form including signature)
>> if (certs != null && certs.length > 0 &&
>> cert.equals(certs[0])) {
>> if (doDebug) {
>> log.debug("Direct trust for
>> certificate with " +
>> subjectString);
>> }
>> return true;
>> }
>> } else {
>> if (doDebug) {
>> log.debug("No alias found for subject
>> from issuer with " + issuerString + "
>> (serial " + issuerSerial + ")");
>> }
>> }
>>
>> // SECOND step
>> // Search for the issuer of the transmitted certificate
>> in the keystore
>>
>> // Search the keystore for the alias of the transmitted
>> certificates issuer
>> try {
>> aliases =
>> sigCrypto.getAliasesForDN(issuerString);
>> } catch (WSSecurityException ex) {
>> throw new AxisFault("WSDoAllReceiver: Could not
>> get alias for certificate with " + issuerString,
>> ex);
>> }
>>
>> // If the alias has not been found, the issuer is not in
>> the keystore
>> // As a direct result, do not trust the transmitted
>> certificate
>> if (aliases == null || aliases.length < 1) {
>> if (doDebug) {
>> log.debug("No aliases found in keystore
>> for issuer " + issuerString + " of
>> certificate for " + subjectString);
>> }
>> return false;
>> }
>>
>> // THIRD step
>> // Check the certificate trust path for every alias of
>> the issuer found in the keystore
>> for (int i = 0; i < aliases.length; i++) {
>> alias = aliases[i];
>>
>> if (doDebug) {
>> log.debug("Preparing to validate
>> certificate path with alias " + alias +
>> " for issuer " + issuerString);
>> }
>>
>> // Retrieve the certificate(s) for the alias
>> from the keystore
>> try {
>> certs =
>> sigCrypto.getCertificates(alias);
>> } catch (WSSecurityException ex) {
>> throw new AxisFault("WSDoAllReceiver:
>> Could not get certificates for alias " +
>> alias, ex);
>> }
>>
>> // If no certificates have been found, there has
>> to be an error:
>> // The keystore can find an alias but no
>> certificate(s)
>> if (certs == null | certs.length < 1) {
>> throw new AxisFault("WSDoAllReceiver:
>> Could not get certificates for alias " +
>> alias);
>> }
>>
>> // Form a certificate chain from the transmitted
>> certificate
>> // and the certificate(s) of the issuer from the
>> keystore
>>
>> // First, create new array
>> X509Certificate[] x509certs = new
>> X509Certificate[certs.length + 1];
>>
>> /* The following conversion into provider
>> specific format seems not to be necessary
>> // Create new certificate, possibly
>> provider-specific
>> try {
>> cert =
>> sigCrypto.loadCertificate(new
>> ByteArrayInputStream(cert.getEncoded()));
>> } catch (CertificateEncodingException
>> ex) {
>> throw new
>> AxisFault("WSDoAllReceiver:
>> Combination of subject and
>> issuers certificates failed",
>> ex);
>> } catch (WSSecurityException ex) {
>> throw new
>> AxisFault("WSDoAllReceiver:
>> Combination of subject and
>> issuers certificates failed",
>> ex);
>> }
>> */
>>
>> // Then add the first certificate ...
>> x509certs[0] = cert;
>>
>> // ... and the other certificates
>> for (int j=0; j < certs.length; j++) {
>> cert = certs[i];
>>
>> /* The following conversion into
>> provider specific format seems not to be
>> necessary
>> // Create new certificate,
>> possibly provider-specific
>> try {
>> cert =
>> sigCrypto.loadCertificate(new
>> ByteArrayInputStream(cert.getEncoded()));
>> } catch
>> (CertificateEncodingException
>> ex) {
>> throw new
>> AxisFault("WSDoAllReceiver:
>> Combination of subject
>> and issuers certificates
>> failed", ex);
>> } catch (WSSecurityException ex)
>> {
>> throw new
>> AxisFault("WSDoAllReceiver:
>> Combination of subject
>> and issuers certificates
>> failed", ex);
>> }
>> */
>>
>> x509certs[certs.length + j] = cert;
>> }
>> certs = x509certs;
>>
>> // Use the validation method from the crypto to
>> check whether the subjects certificate was
>> really signed by the issuer stated in the
>> certificate
>> try {
>> if (sigCrypto.validateCertPath(certs)) {
>> if (doDebug) {
>> log.debug("WSDoAllReceiver:
>> Certificate path has
>> been verified for
>> certificate with subject
>> " + subjectString);
>> }
>> return true;
>> }
>> } catch (WSSecurityException ex) {
>> throw new AxisFault("WSDoAllReceiver:
>> Certificate path verification failed for
>> certificate with subject " +
>> subjectString, ex);
>> }
>> }
>>
>> log.debug("WSDoAllReceiver: Certificate path could not
>> be verified for certificate with subject " +
>> subjectString);
>> return false;
>> }
>>
>> /**
>> * Evaluate whether a timestamp is considered valid on
>> receiverside.
>> * Hook to allow subclasses to implement custom validation
>> methods however they see fit.
>> * <p/>
>> * Policy used in this implementation:
>> * 1. The receiver can set its own time to live (besides from
>> that set on sender side)
>> * 2. If the message was created before (now-ttl) the message is
>> rejected
>> *
>> * @param timestamp the timestamp that is validated
>> * @param timeToLive the limit on receiverside, the timestamp is
>> validated against
>> * @return true if the timestamp is before
>> (now-timeToLive), false otherwise
>> * @throws AxisFault
>> */
>> protected boolean verifyTimestamp(Timestamp timestamp, int
>> timeToLive) throws AxisFault {
>>
>> // Calculate the time that is allowed for the message to
>> travel
>> Calendar validCreation = Calendar.getInstance();
>> long currentTime = validCreation.getTimeInMillis();
>> currentTime -= timeToLive * 1000;
>> validCreation.setTimeInMillis(currentTime);
>>
>> if (doDebug) {
>> log.debug("Preparing to verify the timestamp");
>> SimpleDateFormat zulu = new SimpleDateFormat(
>> "yyyy-MM-dd'T'HH:mm:ss'Z'");
>> zulu.setTimeZone(TimeZone.getTimeZone("GMT"));
>> log.debug("Validation of Timestamp: Current time
>> is "
>> +
>> zulu.format(Calendar.getInstance().getTime()));
>> log.debug("Validation of Timestamp: Valid
>> creation is "
>> +
>> zulu.format(validCreation.getTime()));
>> log.debug("Validation of Timestamp: Timestamp
>> created is "
>> +
>> zulu.format(timestamp.getCreated().getTime()));
>> }
>> // Validate the time it took the message to travel
>> // if
>> (timestamp.getCreated().before(validCreation) ||
>> // !timestamp.getCreated().equals(validCreation)) {
>> if (!timestamp.getCreated().after(validCreation)) {
>> if (doDebug) {
>> log.debug("Validation of Timestamp: The
>> message was created too long ago");
>> }
>> return false;
>> }
>>
>> log.debug("Validation of Timestamp: Everything is ok");
>> return true;
>> }
>>
>> }
>>
>> 1.1
>> ws-axis/contrib/ews/src/org/apache/ws/axis/security/BasicAuth4J2EEReceiver.java
>>
>> Index: BasicAuth4J2EEReceiver.java
>> ===================================================================
>> /*
>> * Created on Jun 20, 2004
>> *
>> *
>> */
>> package org.apache.ws.axis.security;
>>
>> import javax.security.auth.callback.Callback;
>> import javax.security.auth.callback.CallbackHandler;
>>
>> import org.apache.axis.AxisFault;
>> import org.apache.axis.MessageContext;
>> import org.apache.axis.handlers.BasicHandler;
>> import
>> org.apache.geronimo.ews.ws4j2ee.context.security.impl.SecurityContext4J2EEImpl;
>> import org.apache.ws.axis.security.WSDoAllConstants;
>> import org.apache.ws.security.WSPasswordCallback;
>>
>> /**
>> * If the client is using BasicHTTP Authentication, this class can be
>> used
>> * as a server side Axis handler, which retreives the credentials
>> available in
>> * the HTTP header and populate the SecurityContext4J2EE property.
>> *
>> * Only if the <code>WSS4J2EEConstants.AUTH_AT_AXIS</code> property is
>> set to true,
>> * this does the authentication at the Axis. For that at the DD the
>> <code>passwordCallbackClass</code>
>> * should be available.
>> *
>> * @author Rajith Priyanga
>> * @date Jun 20, 2004
>> *
>> */
>> public class BasicAuth4J2EEReceiver extends BasicHandler {
>>
>> private boolean doAuthentication = false;
>> /**
>> * @see
>> org.apache.axis.Handler#invoke(org.apache.axis.MessageContext)
>> */
>> public void invoke(MessageContext cntxt) throws AxisFault {
>> doAuthentication = false;
>> String username = cntxt.getUsername();
>> String password = cntxt.getPassword();
>> if(username==null|| password==null){
>> throw AxisFault.makeFault(new Exception("null
>> values for username or/and password."));
>> }
>>
>> //Decides whether to do authentication at Axis or not.
>> if(cntxt.containsProperty(WSS4J2EEConstants.AUTH_AT_AXIS)){
>> String check =
>> (String)cntxt.getProperty(WSS4J2EEConstants.AUTH_AT_AXIS);
>> if(check!=null &&
>> check.equalsIgnoreCase("true"))
>> this.doAuthentication = true;
>> }
>>
>> if(this.doAuthentication){
>> try{
>> this.veryfyPWD(username, password,
>> cntxt);
>> }
>> catch(Exception e){
>> throw AxisFault.makeFault(e);
>> }
>> }
>>
>> populateSecurityContext4J2EE(username, password, cntxt);
>> }
>>
>> /**
>> * Populates the SecurityContext4J2EE property with the given
>> credentials.
>> * Also this adds a PWDCallbackHandler4J2EE to the
>> SecurityContext4J2EE.
>> * @param username
>> * @param password
>> * @param cntxt
>> */
>> private void populateSecurityContext4J2EE(String username,
>> String password, MessageContext cntxt){
>> SecurityContext4J2EEImpl sc4j2ee =
>> (SecurityContext4J2EEImpl)cntxt.getProperty(WSS4J2EEConstants.SEC_CONTEXT_4J2EE);
>>
>> if(sc4j2ee==null){
>> sc4j2ee = new SecurityContext4J2EEImpl();
>> cntxt.setProperty(WSS4J2EEConstants.SEC_CONTEXT_4J2EE,
>> sc4j2ee);
>> }
>>
>> //Populate the SecurityContext4J2EE with the auth data.
>> sc4j2ee.setUsername(username);
>> sc4j2ee.setPassword(password.toCharArray());
>> sc4j2ee.setPasswordDigested(false);
>>
>> PWDCallbackHandler4J2EE pwdcbh = new
>> PWDCallbackHandler4J2EE(username,
>> password.toCharArray());
>> sc4j2ee.setPWDCallbackHandler4J2EE(pwdcbh);
>> }
>>
>> private boolean veryfyPWD(String username, String password,
>> MessageContext cntxt) throws Exception{
>> if(password.equals(this.fetchActualPWD(username,
>> cntxt))){
>> return true;
>> }
>> else{
>> return false;
>> }
>> }
>>
>> private String fetchActualPWD(String username, MessageContext
>> cntxt) throws Exception{
>> WSPasswordCallback pwcb = new
>> WSPasswordCallback(username,
>> WSPasswordCallback.USERNAME_TOKEN);
>> Callback[] cb = new Callback[1];
>>
>> cb[0] = pwcb;
>>
>> CallbackHandler cbh =
>> (CallbackHandler)cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_REF);
>>
>> if(cbh == null){
>> String cbhClass =
>> (String)cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_CLASS);
>> cbh =
>> (CallbackHandler)Class.forName(cbhClass).newInstance();
>> }
>>
>> if(cbh==null){
>> throw new Exception("PasswordCallbackHandler not
>> found!");
>> }
>>
>> cbh.handle(cb);
>> String pwd =
>> ((WSPasswordCallback)(cb[0])).getPassword();
>>
>> if(pwd==null)
>> throw new Exception("Password is not
>> provided.");
>>
>> return pwd;
>>
>> }
>>
>> }
>>
>> 1.1
>> ws-axis/contrib/ews/src/org/apache/ws/axis/security/SimpleWSS4J2EEReceiver.java
>>
>> Index: SimpleWSS4J2EEReceiver.java
>> ===================================================================
>> /*
>> * Created on May 29, 2004
>> *
>> *
>> */
>> package org.apache.ws.axis.security;
>>
>> import java.util.Iterator;
>>
>> import javax.security.auth.callback.Callback;
>> import javax.security.auth.callback.CallbackHandler;
>> import javax.xml.soap.Name;
>> import javax.xml.soap.SOAPElement;
>> import javax.xml.soap.SOAPFactory;
>> import javax.xml.soap.SOAPHeader;
>> import javax.xml.soap.SOAPHeaderElement;
>>
>> import org.apache.axis.AxisFault;
>> import org.apache.axis.Message;
>> import org.apache.axis.MessageContext;
>> import org.apache.axis.handlers.BasicHandler;
>> import
>> org.apache.geronimo.ews.ws4j2ee.context.security.impl.SecurityContext4J2EEImpl;
>> import org.apache.ws.axis.security.WSDoAllConstants;
>> import org.apache.ws.security.WSConstants;
>> import org.apache.ws.security.WSPasswordCallback;
>> import org.apache.ws.security.message.token.UsernameToken;
>>
>> /**
>> * This is an Axis handler that can be used to retrieve the
>> credentials
>> * available in the <code>UsernameToken</code> element.
>> * This is a simple security handler that can provide only that
>> service.
>> * Therefore this handler can be used for testing perposes and
>> * other simple works.
>> *
>> * This can be configured to do the authentication at Axis or at J2EE
>> Server.
>> * For that you have to set the
>> <code>WSS4J2EEConstants.AUTH_AT_AXIS</code>
>> * to true.
>> *
>> *
>> * @author Rajith Priyanga (rpriyanga@yahoo.com)
>> * @date May 29, 2004
>> *
>> */
>> public class SimpleWSS4J2EEReceiver extends BasicHandler {
>>
>> MessageContext cntxt = null;
>>
>> boolean doAuthentication = false;
>>
>> /**
>> * Retrieve the username-password information and perform a
>> verification.
>> * @see
>> org.apache.axis.Handler#invoke(org.apache.axis.MessageContext)
>> */
>> public void invoke(MessageContext msgCntxt) throws AxisFault {
>> this.cntxt = msgCntxt;
>> doAuthentication = false;
>>
>> try{
>> //Get the SOAP header.
>> Message m = msgCntxt.getCurrentMessage();
>> SOAPHeader sh =
>> m.getSOAPPart().getEnvelope().getHeader();
>>
>> //Retrieve the action property.
>> String action = null;
>> if((action = (String)
>> getOption(WSDoAllConstants.ACTION))==null)
>> action =
>> (String)cntxt.getProperty(WSDoAllConstants.ACTION);
>>
>> if(action==null){
>> return;
>> }
>>
>> String[] actions = action.split(" ");
>> if(actions==null)
>> return;
>>
>> boolean utAction = false;
>>
>> //Check whether UsernameToken action property is
>> available. Otherwise no more processing.
>> for(int i=0; i<actions.length; i++){
>> utAction =
>> actions[i].equalsIgnoreCase(WSDoAllConstants.USERNAME_TOKEN);
>> if(utAction)
>> break;
>> }
>> if(!utAction)
>> return;
>>
>> //Get all the headers.
>> Iterator headers = sh.getChildElements();
>> SOAPHeaderElement headerElem = null;
>>
>> if(headers==null){
>> throw AxisFault.makeFault(new
>> Exception("No Security Headers found"));
>> }
>> //Find the security header.
>> while (headers.hasNext()) {
>> headerElem = (SOAPHeaderElement)
>> headers.next();
>> if
>> (headerElem.getLocalName().equals(WSConstants.WSSE_LN)
>> &&
>> headerElem.getNamespaceURI().equals(WSConstants.WSSE_NS))
>> {
>> //headerElem.setMustUnderstand(false);
>> break;
>> }
>> }
>>
>> //Decides whether to do authentication at Axis
>> or not.
>> if(cntxt.containsProperty(WSS4J2EEConstants.AUTH_AT_AXIS)){
>> String check =
>> (String)cntxt.getProperty(WSS4J2EEConstants.AUTH_AT_AXIS);
>> if(check!=null &&
>> check.equalsIgnoreCase("true"))
>> this.doAuthentication = true;
>> }
>>
>> //Hand over the security header to process it's
>> UsernameToken.
>> processUsernameToken(headerElem);
>> headerElem.detachNode();
>> }
>> catch(Exception ex){
>> throw AxisFault.makeFault(ex);
>> }
>> }
>>
>> /**
>> * Processes the UsernameToken element of the security header.
>> * It populates the SecurityContext4J2EE property of the
>> MessageContext too.
>> * @param secHeader SOAP Security Header.
>> * @throws Exception
>> */
>> private void processUsernameToken(SOAPHeaderElement secHeader)
>> throws Exception{
>> SOAPFactory sf = SOAPFactory.newInstance();
>> Name utName =
>> sf.createName(WSConstants.USERNAME_TOKEN_LN,
>> WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS);
>> Iterator toks = secHeader.getChildElements(utName);
>>
>> if(toks==null){
>> throw new Exception("No Security tokens
>> found!");
>> }
>>
>> //Get the UsernameToken element
>> SOAPElement utElem = null;
>> if(toks.hasNext()){
>> utElem = (SOAPElement)toks.next();
>> }
>> else{
>> throw new Exception("No UsernameToken found!");
>> }
>> Name unName = sf.createName(WSConstants.USERNAME_LN,
>> WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS);
>> Name pwdName = sf.createName(WSConstants.PASSWORD_LN,
>> WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS);
>>
>> //Get the user name
>> String username =
>> ((SOAPElement)(utElem.getChildElements(unName).next())).getValue();
>>
>> //Get the password element
>> SOAPElement pwdElem =
>> (SOAPElement)utElem.getChildElements(pwdName).next();
>>
>> //Get the password type
>> String pwdType =
>> pwdElem.getAttributeValue(sf.createName(WSConstants.PASSWORD_TYPE_ATTR,
>> WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS));//,
>> WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS));
>>
>> //Get the password
>> String pwd = pwdElem.getValue();
>>
>> //If the password type is not speciied take it as
>> PASSWORD_TEXT type.
>> if(pwdType==null)
>> pwdType = WSConstants.PASSWORD_TEXT;
>>
>> if(pwdType.equalsIgnoreCase(WSConstants.PASSWORD_TEXT)){
>> ///////////// This part can be removed. .
>> /////////////////
>> if(doAuthentication){
>> if(!veryfyPWD(username, pwd)){
>> throw new Exception("Password
>> Verification failed!");
>> }
>> }
>> ///////////////////////////////////////////////////////////
>> this.populateSecurityContext4J2EE(username, pwd,
>> pwdType, null, null);
>> //this.Authenticate4J2EE();
>> }
>> else
>> if(pwdType.equalsIgnoreCase(WSConstants.PASSWORD_DIGEST)){
>> Name nonceName =
>> sf.createName(WSConstants.NONCE_LN,
>> WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS);
>> Name createdName =
>> sf.createName(WSConstants.CREATED_LN,
>> WSConstants.WSU_PREFIX, WSConstants.WSU_NS);
>>
>> Iterator elems =
>> utElem.getChildElements(nonceName);
>> String nonce = this.extractNonce(elems);
>>
>> elems = utElem.getChildElements(createdName);
>> String created = this.extractCreated(elems);
>> ///////////// This part can be removed. .
>> /////////////////
>> if(doAuthentication){
>> if(!veryfyPWD(username, pwd, nonce,
>> created)){
>> throw new Exception("Password
>> Verification failed!");
>> }
>> }
>> ///////////////////////////////////////////////////////////
>> this.populateSecurityContext4J2EE(username, pwd,
>> pwdType, nonce, created);
>> }
>> else{
>> throw new Exception("Unsupported Password
>> Type!");
>> }
>> }
>>
>> /**
>> * Extracts the nonce value from the given set of elements.
>> * (It is given as a iteratorf o elements)
>> * @param elements
>> * @return
>> * @throws Exception
>> */
>> private String extractNonce(Iterator elements) throws Exception{
>> boolean noNonce = false;
>> String nonce = null;
>>
>> if(elements==null){
>> noNonce = true;
>> }
>> if(!noNonce && elements.hasNext()){
>> nonce =
>> ((SOAPElement)(elements.next())).getValue();
>> }
>> else{
>> noNonce = true;
>> }
>> if(nonce == null){
>> noNonce = true;
>> }
>> if(noNonce)
>> throw new Exception("Nonce is not specified!");
>>
>> return nonce;
>> }
>>
>> /**
>> * Extracts the created value from the given set of elements.
>> * (It is given as a iteratorf o elements)
>> * @param elements
>> * @return
>> * @throws Exception
>> */
>> private String extractCreated(Iterator elements) throws
>> Exception{
>> boolean noCreated = false;
>> String created = null;
>>
>> if(elements==null)
>> noCreated = true;
>>
>> if(!noCreated && elements.hasNext())
>> created =
>> ((SOAPElement)(elements.next())).getValue();
>> else
>> noCreated = true;
>>
>> if(created == null)
>> noCreated = true;
>>
>> if(noCreated)
>> throw new Exception("Created is not
>> specified!");
>>
>> return created;
>> }
>>
>> /**
>> * Verifies the PASSWORD_TEXT type passwords.
>> */
>> private boolean veryfyPWD(String username, String password)
>> throws Exception{
>> if(password.equals(this.fetchActualPWD(username))){
>> return true;
>> }
>> else{
>> return false;
>> }
>> }
>>
>> /**
>> * Verifies the PASSWORD_DIGEST type passwords.
>> */
>> private boolean veryfyPWD(String username,
>> String
>> password,
>> String nonce,
>> String
>> created)
>> throws
>> Exception{
>>
>> //TODO
>> //Check whether (created > currentTime - 5 minutes).
>> //Cache the nonce for the user and check it before
>> verification.
>>
>> if(nonce == null || created == null){
>> throw new Exception("Nonce or Created not
>> supplied!");
>> }
>>
>> String digest = UsernameToken.doPasswordDigest(nonce,
>> created, this.fetchActualPWD(username));
>>
>> if(password.equals(digest)){
>> return true;
>> }
>> else{
>> return false;
>> }
>> }
>>
>> /**}
>> * Fetches the actual password using the CallbackHandler
>> specified
>> * in the deployment descripter.
>> * @param username username
>> * @return the actual password of the user.
>> * @throws Exception
>> */
>>
>> private String fetchActualPWD(String username) throws Exception{
>> WSPasswordCallback pwcb = new
>> WSPasswordCallback(username,
>> WSPasswordCallback.USERNAME_TOKEN);
>> Callback[] cb = new Callback[1];
>>
>> cb[0] = pwcb;
>>
>> CallbackHandler cbh =
>> (CallbackHandler)this.cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_REF);
>>
>> if(cbh == null){
>> String cbhClass =
>> (String)this.cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_CLASS);
>> cbh =
>> (CallbackHandler)Class.forName(cbhClass).newInstance();
>> }
>>
>> if(cbh==null){
>> throw new Exception("PasswordCallbackHandler not
>> found!");
>> }
>>
>> cbh.handle(cb);
>> String pwd =
>> ((WSPasswordCallback)(cb[0])).getPassword();
>>
>> if(pwd==null)
>> throw new Exception("Password is not
>> provided.");
>>
>> return pwd;
>>
>> }
>>
>> /**
>> * Associates a Authenticated principal with this thread this
>> thread.
>> * @throws Exception
>> */
>> /*private void Authenticate4J2EE() throws Exception{
>> CallbackHandler cbh =
>> (CallbackHandler)this.cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_REF);
>> if(cbh == null){
>> String cbhClass =
>> (String)this.cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_CLASS);
>> cbh =
>> (CallbackHandler)Class.forName(cbhClass).newInstance();
>> }
>>
>> if(cbh != null){
>> javax.security.auth.login.LoginContext lc
>> = new
>> javax.security.auth.login.LoginContext("LC4"
>> + this.cntxt.getTargetService(), cbh);
>> lc.login();
>> }
>> else
>> throw new Exception("CallbackHandler is null.");
>> }*/
>>
>> /**
>> * Populates the SecurityContext4J2EE property with the given
>> * security information.
>> * @param username
>> * @param password
>> * @param passwordType
>> * @param nonce
>> * @param created
>> */
>> private void populateSecurityContext4J2EE(String username,
>> String password, String passwordType, String nonce, String
>> created){
>> SecurityContext4J2EEImpl sc4j2ee =
>> (SecurityContext4J2EEImpl)this.cntxt.getProperty(WSS4J2EEConstants.SEC_CONTEXT_4J2EE);
>>
>> if(sc4j2ee==null){
>> sc4j2ee = new SecurityContext4J2EEImpl();
>> this.cntxt.setProperty(WSS4J2EEConstants.SEC_CONTEXT_4J2EE,
>> sc4j2ee);
>> }
>>
>> //Populate the SecurityContext4J2EE with the user name
>> token data.
>> sc4j2ee.setUsername(username);
>> sc4j2ee.setPassword(password.toCharArray());
>>
>> if(passwordType.equalsIgnoreCase(WSConstants.PASSWORD_DIGEST)){
>> sc4j2ee.setPasswordDigested(true);
>> sc4j2ee.setNonce(nonce);
>> sc4j2ee.setCreated(created);
>> }
>> else
>> sc4j2ee.setPasswordDigested(false);
>>
>> PWDCallbackHandler4J2EE cbh = new
>> PWDCallbackHandler4J2EE(username,
>> password.toCharArray());
>> sc4j2ee.setPWDCallbackHandler4J2EE(cbh);
>> }
>>
>> }
>>
>> 1.1
>> ws-axis/contrib/ews/src/org/apache/ws/axis/security/CheckPoint4J2EEHandler.java
>>
>> Index: CheckPoint4J2EEHandler.java
>> ===================================================================
>> /*
>> * Created on Apr 6, 2004
>> *
>> *
>> */
>> package org.apache.ws.axis.security;
>>
>> import org.apache.axis.AxisFault;
>> import org.apache.axis.MessageContext;
>> import org.apache.axis.handlers.BasicHandler;
>> import
>> org.apache.geronimo.ews.ws4j2ee.context.security.SecurityContext4J2EE;
>>
>> /**
>> *
>> * Still this is not in use. But may be in future...
>> *
>> * @author Rajith Priyanga (rpriyanga@yahoo.com)
>> * @date Apr 6, 2004
>> *
>> */
>> public abstract class CheckPoint4J2EEHandler extends BasicHandler {
>>
>> /**
>> * @see
>> org.apache.axis.Handler#invoke(org.apache.axis.MessageContext)
>> */
>> public void invoke(MessageContext cntxt) throws AxisFault{
>> SecurityContext4J2EE sc4j2ee;
>> //TODO
>> //Populate the SecurityContext4J2EE object with
>> available info.
>> //Other info will be dynamically calculated rom
>> MessageCOntext.
>> }
>>
>> /**
>> * Decides whether the message integrity is sufficiently
>> varifiable.
>> * @param cntxt Message context.
>> * @return true if the test is passed.
>> */
>> public abstract boolean integrityTest(MessageContext cntxt);
>>
>> /**
>> * Decides whether the message privacy is sufficiently
>> protected.
>> * @param cntxt Message context
>> * @return true if the test is passed.
>> */
>> public abstract boolean privacyTest(MessageContext cntxt);
>>
>> /**
>> * Returns the password of the given user. This should be
>> retrieved
>> * from a password store.
>> * @param username
>> * @return The actual password.
>> */
>> public abstract char[] getPassword(String username);
>>
>> }
>>
>> 1.5 +4 -3
>> ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/toWs/wrapperWs/SimpleRemoteInterfaceBasedWrapperClassWriter.java
>>
>> Index: SimpleRemoteInterfaceBasedWrapperClassWriter.java
>> ===================================================================
>> RCS file:
>> /home/cvs/ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/toWs/wrapperWs/SimpleRemoteInterfaceBasedWrapperClassWriter.java,v
>> retrieving revision 1.4
>> retrieving revision 1.5
>> diff -u -r1.4 -r1.5
>> --- SimpleRemoteInterfaceBasedWrapperClassWriter.java 10 Jun 2004
>> 11:35:19 -0000 1.4
>> +++ SimpleRemoteInterfaceBasedWrapperClassWriter.java 7 Jul 2004
>> 09:02:00 -0000 1.5
>> @@ -136,10 +136,11 @@
>> out.write("\t\tif(msgcontext == null){\n");
>> out.write("\t\t msgcontext =
>> org.apache.axis.MessageContext.getCurrentContext();\n");
>> out.write("\t\t}\n");
>> -
>> +
>> out.write("\t\torg.apache.geronimo.ews.ws4j2ee.context.security.SecurityContext4J2EE
>> seccontext =\n");
>> + out.write("\t\t
>> (org.apache.geronimo.ews.ws4j2ee.context.security.SecurityContext4J2EE)msgcontext\n");
>> +
>> out.write("\t\t.getProperty(org.apache.ws.axis.security.WSS4J2EEConstants.SEC_CONTEXT_4J2EE);\n");
>> out.write("\t\t
>> javax.security.auth.callback.CallbackHandler handler\n");
>> - out.write("\t\t =
>> org.apache.geronimo.ews.ws4j2ee.wsutils.security.jaasmodules.\n");
>> - out.write("\t\t
>> AutenticationCallbackHandlerFactory.createCallbackHandler(msgcontext);\n");
>> + out.write("\t\t =
>> seccontext.getPWDCallbackHandler4J2EE();\n");
>> out.write("\t\t if(handler != null){\n");
>> out.write("\t\t javax.security.auth.login.LoginContext
>> lc\n");
>> out.write("\t\t = new
>> javax.security.auth.login.LoginContext(\"TestClient\",
>> handler);\n");
>>
>> 1.2 +11 -5
>> ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/context/security/SecurityContext4J2EE.java
>>
>> Index: SecurityContext4J2EE.java
>> ===================================================================
>> RCS file:
>> /home/cvs/ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/context/security/SecurityContext4J2EE.java,v
>> retrieving revision 1.1
>> retrieving revision 1.2
>> diff -u -r1.1 -r1.2
>> --- SecurityContext4J2EE.java 14 Jun 2004 08:24:39 -0000 1.1
>> +++ SecurityContext4J2EE.java 7 Jul 2004 09:02:00 -0000 1.2
>> @@ -1,10 +1,8 @@
>> -/*
>> - * Created on Apr 5, 2004
>> - *
>> - *
>> - */
>> package org.apache.geronimo.ews.ws4j2ee.context.security;
>>
>> +
>> +
>> +import javax.security.auth.callback.CallbackHandler;
>> import javax.security.cert.X509Certificate;
>>
>> /**
>> @@ -83,4 +81,12 @@
>> * @return the X509 Certificate.
>> */
>> public byte[] getKerberoseTicket();
>> +
>> + /**
>> + * Returns a PasswordCallbackHandler which can be used in
>> + * authentication done using JAAS module at the wrapper web
>> service.
>> + * @return CallbackHandler.
>> + */
>> + public CallbackHandler getPWDCallbackHandler4J2EE();
>> +
>> }
>>
>> 1.13 +0 -3
>> ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/toWs/GenerationConstants.java
>>
>> Index: GenerationConstants.java
>> ===================================================================
>> RCS file:
>> /home/cvs/ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/toWs/GenerationConstants.java,v
>> retrieving revision 1.12
>> retrieving revision 1.13
>> diff -u -r1.12 -r1.13
>> --- GenerationConstants.java 27 Jun 2004 15:20:23 -0000 1.12
>> +++ GenerationConstants.java 7 Jul 2004 09:02:00 -0000 1.13
>> @@ -55,9 +55,6 @@
>>
>> package org.apache.geronimo.ews.ws4j2ee.toWs;
>>
>> -import java.io.FileInputStream;
>> -import java.io.InputStream;
>> -import java.util.Properties;
>>
>> /**
>> * <p>This interface has constants that are specific to the
>> generators.</p>
>>
>> 1.6 +1 -1
>> ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/utils/AntExecuter.java
>>
>> Index: AntExecuter.java
>> ===================================================================
>> RCS file:
>> /home/cvs/ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/utils/AntExecuter.java,v
>> retrieving revision 1.5
>> retrieving revision 1.6
>> diff -u -r1.5 -r1.6
>> --- AntExecuter.java 27 Jun 2004 15:20:24 -0000 1.5
>> +++ AntExecuter.java 7 Jul 2004 09:02:00 -0000 1.6
>> @@ -45,7 +45,7 @@
>> ant.setAntfile(file.getAbsolutePath());
>> ant.setDir(file.getParentFile());
>> ant.execute();
>> - }catch(ClassCastException e){
>> + }catch(ClassNotFoundException e){
>> System.out.println("Ant file will not be run
>> programatcally as the " +
>> "$JAVA_HOME/lib/tool.jar is not in the class
>> path. To run the ant " +
>> "prgramatically add that jar to classpath");
>> }catch(BuildException e){
>> System.out.println(e.getMessage() +
>>
>> 1.1
>> ws-axis/contrib/ews/src/org/apache/ws/security/WSS4J2EEEngine.java
>>
>> Index: WSS4J2EEEngine.java
>> ===================================================================
>> /*
>> * Created on May 28, 2004
>> *
>> *
>> */
>> package org.apache.ws.security;
>>
>> import javax.security.auth.callback.CallbackHandler;
>>
>> import org.apache.axis.MessageContext;
>>
>> import
>> org.apache.geronimo.ews.ws4j2ee.context.security.impl.SecurityContext4J2EEImpl;
>> import org.apache.ws.axis.security.PWDCallbackHandler4J2EE;
>> import org.apache.ws.axis.security.WSS4J2EEConstants;
>> import org.apache.ws.security.message.token.UsernameToken;
>> import org.w3c.dom.Element;
>> /**
>> * This class is used in <code>AllSecurityReceiver</code<> to process
>> the secuirty
>> * headers in the SOAP message. This works slightly different from the
>> * WSSecurityEngine of wss4j project.
>> * i.e
>> * This processes the UsernameToken element in a different way.
>> * The credentials available in the token are retrieved and the
>> * SecurityContext4J2EE is populated using them.
>> * No authentication is done at Axis. Therefore no principal
>> * is created, instead this replace it with null.
>> *
>> * Before using the above service, the MessageContext should be set.
>> *
>> * @author Davanum Srinivas (dims@yahoo.com).
>> * @author Werner Dittmann (Werner.Dittmann@siemens.com).
>> * @author Rajith Priyanga (rpriyanga@yahoo.com)
>> * @date May 28, 2004
>> *
>> */
>> public class WSS4J2EEEngine extends WSSecurityEngine{
>>
>> private MessageContext msgCntxt = null;
>>
>> public void setMessageContext(MessageContext msgContext) throws
>> Exception{
>> if(msgContext==null){
>> throw new Exception("Mssage Context is null!");
>> }
>> else{
>> this.msgCntxt = msgContext;
>> }
>> }
>>
>> /**
>> * Processes the UsernameToken element and populate the
>> SecurityContext4J2EE prperty
>> * with the credentials available in it.
>> * No authentication is done here.
>> * Always returns null
>> */
>> public WSUsernameTokenPrincipal handleUsernameToken(Element
>> token, CallbackHandler cb) throws WSSecurityException {
>>
>> UsernameToken ut = new UsernameToken(token);
>> try{
>> this.populateSecurityContext4J2EE(ut.getName(),
>> ut.getPassword().toCharArray(),
>> ut.isHashed(),
>> ut.getNonce(),
>> ut.getCreated());
>> }
>> catch(Exception e){
>> throw new
>> WSSecurityException(WSSecurityException.FAILURE,
>> "Invalid Username Token found!");
>> }
>>
>> return null;
>> }
>>
>> /**
>> * Register a SecurityContext4J2EE object with the
>> MessageContext as
>> * WSS4J2EEConstants.SEC_CONTEXT_4J2EE property.
>> * Populates the SEC_CONTEXT_4J2EE property with the security
>> information
>> * avatilable in the UsernameToken.
>> * @param ut
>> */
>> private void populateSecurityContext4J2EE(String user, char[]
>> pwd, boolean isDigested, String nonce, String created){
>> SecurityContext4J2EEImpl sc4j2ee =
>> (SecurityContext4J2EEImpl)this.msgCntxt.getProperty(WSS4J2EEConstants.SEC_CONTEXT_4J2EE);
>>
>> if(sc4j2ee==null){
>> sc4j2ee = new SecurityContext4J2EEImpl();
>> this.msgCntxt.setProperty(WSS4J2EEConstants.SEC_CONTEXT_4J2EE,
>> sc4j2ee);
>> }
>>
>> //Populate the SecurityContext4J2EE with the user name
>> token data.
>> sc4j2ee.setUsername(user);
>> if(isDigested){
>> sc4j2ee.setPasswordDigested(true);
>> sc4j2ee.setNonce(nonce);
>> sc4j2ee.setCreated(created);
>> }
>> else
>> sc4j2ee.setPasswordDigested(false);
>>
>> sc4j2ee.setPassword(pwd);
>> PWDCallbackHandler4J2EE cbh = new
>> PWDCallbackHandler4J2EE(user, pwd);
>> sc4j2ee.setPWDCallbackHandler4J2EE(cbh);
>> }
>>
>> }
>>
>> 1.2 +15 -14
>> ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/context/security/impl/SecurityContext4J2EEImpl.java
>>
>> Index: SecurityContext4J2EEImpl.java
>> ===================================================================
>> RCS file:
>> /home/cvs/ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/context/security/impl/SecurityContext4J2EEImpl.java,v
>> retrieving revision 1.1
>> retrieving revision 1.2
>> diff -u -r1.1 -r1.2
>> --- SecurityContext4J2EEImpl.java 14 Jun 2004 08:24:39 -0000
>> 1.1
>> +++ SecurityContext4J2EEImpl.java 7 Jul 2004 09:02:00 -0000
>> 1.2
>> @@ -1,14 +1,9 @@
>> -/*
>> - * Created on Apr 6, 2004
>> - *
>> - *
>> - */
>> package org.apache.geronimo.ews.ws4j2ee.context.security.impl;
>>
>> +import javax.security.auth.callback.CallbackHandler;
>> import javax.security.cert.X509Certificate;
>>
>> import
>> org.apache.geronimo.ews.ws4j2ee.context.security.SecurityContext4J2EE;
>> -
>> /**
>> * @author Rajith Priyanga (rpriyanga@yahoo.com)
>> * @date Apr 6, 2004
>> @@ -27,15 +22,8 @@
>> private boolean privacy = false;
>> private boolean integrity = false;
>> private boolean isPwdDigested= false;
>> - //private MessageContext cntxt;
>> + private CallbackHandler cbh;
>>
>> - /**
>> - * This has a circular reference to the MessageContext.
>> - * @param cntxt
>> - */
>> - /*public SecurityContext4J2EEImpl(MessageContext cntxt){
>> - this.cntxt = cntxt;
>> - }*/
>>
>> public SecurityContext4J2EEImpl(){
>> @@ -192,6 +180,19 @@
>> */
>> public void setPassword(char[] password) {
>> this.pwd = password;
>> + }
>> +
>> +
>> + /**
>> + * @see
>> org.apache.geranimo.ews.ws4j2ee.context.security.SecurityContext4J2EE#getPWDCallbackHandler4J2EE()
>> + */
>> + public CallbackHandler getPWDCallbackHandler4J2EE() {
>> + return this.cbh;
>> + }
>> +
>> +
>> + public void setPWDCallbackHandler4J2EE(CallbackHandler
>> callbackHandler){
>> + this.cbh = callbackHandler;
>> }
>>
>> }
>>
>>
>
>
> --
> Davanum Srinivas - http://webservices.apache.org/~dims/
>
>
------------------------------------
Lanka Sofware Foundation
------------------------------------
Re: cvs commit: ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/context/security/impl SecurityContext4J2EEImpl.java
Posted by Davanum Srinivas <da...@gmail.com>.
Srinath,
We can fix whatever is needed to be fixed in WSS4J....Just let me know.
thanks,
dims
On 7 Jul 2004 09:02:00 -0000, hemapani@apache.org <he...@apache.org> wrote:
> hemapani 2004/07/07 02:02:00
>
> Modified: contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/toWs/wrapperWs
> SimpleRemoteInterfaceBasedWrapperClassWriter.java
> contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/context/security
> SecurityContext4J2EE.java
> contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/toWs
> GenerationConstants.java
> contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/utils
> AntExecuter.java
> contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/context/security/impl
> SecurityContext4J2EEImpl.java
> Added: contrib/ews/src/org/apache/ws/axis/security
> PWDCallbackHandler4J2EE.java WSS4J2EEConstants.java
> BasicAuth4J2EESender.java SimpleWSS4J2EESender.java
> AllSecurity4J2EEReceiver.java
> BasicAuth4J2EEReceiver.java
> SimpleWSS4J2EEReceiver.java
> CheckPoint4J2EEHandler.java
> contrib/ews/src/org/apache/ws/security WSS4J2EEEngine.java
> Removed: contrib/ews/src/org/apache/ws/axis/security
> WSS4J2EEReceiver.java
> contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/context/security
> SimpleWSS4J2EEReceiver.java WSS4J2EEEngine.java
> WSS4J2EEConstants.java CheckPoint4J2EEHandler.java
> SimpleWSS4J2EESender.java
> Log:
> add priyanga's new Handlers to support secuity
> had to keep the Handlers in the axis.security/ws.secuirty packages as
> they have default constructers
>
> Revision Changes Path
> 1.1 ws-axis/contrib/ews/src/org/apache/ws/axis/security/PWDCallbackHandler4J2EE.java
>
> Index: PWDCallbackHandler4J2EE.java
> ===================================================================
> /*
> * Created on Jun 27, 2004
> *
> *
> */
> package org.apache.ws.axis.security;
>
> import java.io.IOException;
>
> 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;
> /**
> * This is a simple PasswordCallback Handler that can be used by
> * Wrapper web service, before invoking the EJB, to authenticate
> * the client using JAAS.
> *
> * @author Rajith Priyanga (rpriyanga@yahoo.com)
> * @date Jun 27, 2004
> *
> */
> public class PWDCallbackHandler4J2EE implements CallbackHandler{
>
> String username = null;
> char[] password = null;
>
> /**
> * @see javax.security.auth.callback.CallbackHandler#handle(javax.security.auth.callback.Callback[])
> */
> public PWDCallbackHandler4J2EE(String username, char[] password){
> this.username = username;
> this.password = password;
> }
>
> public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
> boolean recognized = false;
> //Callback handler which implements both the following interfaces
> //can also be handled.
> for (int i = 0; i < callbacks.length; i++){
> if (callbacks[i] instanceof NameCallback){
> NameCallback ncb = (NameCallback) callbacks[i];
> ncb.setName(username);
> recognized = true;
> }
> if (callbacks[i] instanceof PasswordCallback){
> PasswordCallback pcb = (PasswordCallback) callbacks[i];
> pcb.setPassword(password);
> recognized = true;
> }
> if(!recognized){
> throw new UnsupportedCallbackException(callbacks[i], "Callback Type is not supported.");
> }
> }
> }
>
> }
>
> 1.1 ws-axis/contrib/ews/src/org/apache/ws/axis/security/WSS4J2EEConstants.java
>
> Index: WSS4J2EEConstants.java
> ===================================================================
> /*
> * Created on May 28, 2004
> *
> *
> */
> package org.apache.ws.axis.security;
>
> import org.apache.ws.axis.security.WSDoAllConstants;
>
> /**
> * Defines the Constants used or WS-J2EE security Mapping implementation.
> *
> * @author Rajith Priyanga (rpriyanga@yahoo.com)
> * @date May 28, 2004
> *
> */
> public class WSS4J2EEConstants extends WSDoAllConstants {
>
> /**
> * This property contains the security information required to authenticate
> * the user to the J2EE server, plus some more information. Represents
> * a SecurityContext4J2EE object.
> *
> */
> public static final String SEC_CONTEXT_4J2EE = "SEC_CONTEXT_4J2EE";
>
> public static final String AUTH_AT_AXIS = "AuthenticationAtAxis";
> }
>
> 1.1 ws-axis/contrib/ews/src/org/apache/ws/axis/security/BasicAuth4J2EESender.java
>
> Index: BasicAuth4J2EESender.java
> ===================================================================
> /*
> * Created on Jun 20, 2004
> *
> *
> */
> package org.apache.ws.axis.security;
>
> import javax.security.auth.callback.CallbackHandler;
> import javax.security.auth.callback.Callback;
>
> import org.apache.axis.AxisFault;
> import org.apache.axis.MessageContext;
> import org.apache.axis.handlers.BasicHandler;
>
> import org.apache.ws.axis.security.WSDoAllConstants;
> import org.apache.ws.security.WSPasswordCallback;
>
> /**
> * This class can be used as a client side Axis handler which can insert
> * BasicHTTPAuthentication data to the request. This class uses the
> * PasswordCallbackHandler specified by the client in the DD or Call object,
> * to obtain the credentials of the client to add to the HTTP header.
> * (i.e. <code>passwordCallbackClass</code> property.)
> *
> * @author Rajith Priyanga (rpriyanga@yahoo.com)
> * @date Jun 20, 2004
> *
> */
> public class BasicAuth4J2EESender extends BasicHandler {
>
> /**
> * @see org.apache.axis.Handler#invoke(org.apache.axis.MessageContext)
> */
> public void invoke(MessageContext cntxt) throws AxisFault {
> String username = cntxt.getUsername();
> try{
> cntxt.setPassword(fetchPWD(username, cntxt));
> }
> catch(Exception e){
> throw AxisFault.makeFault(e);
> }
> }
>
> /**
> * Fetches the password to be sent, using the given Password Callback
> * class.
> * @param username
> * @param cntxt
> * @return
> * @throws Exception
> */
> private String fetchPWD(String username, MessageContext cntxt) throws Exception{
> if(username==null){
> throw new Exception("No username provided!");
> }
>
> WSPasswordCallback pwcb = new WSPasswordCallback(username, WSPasswordCallback.USERNAME_TOKEN);
> Callback[] cb = new Callback[1];
> cb[0] = pwcb;
>
> CallbackHandler cbh = (CallbackHandler)cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_REF);
> if(cbh == null){
> String cbhClass = (String)cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_CLASS);
> cbh = (CallbackHandler)Class.forName(cbhClass).newInstance();
> }
> if(cbh == null){
> throw new Exception("No PasswordCallbackHandler class found.");
> }
> else{
> cbh.handle(cb);
> }
> String pwd = ((WSPasswordCallback)(cb[0])).getPassword();
> if(pwd==null)
> throw new Exception("No password provided!");
> return pwd;
> }
>
> }
>
> 1.1 ws-axis/contrib/ews/src/org/apache/ws/axis/security/SimpleWSS4J2EESender.java
>
> Index: SimpleWSS4J2EESender.java
> ===================================================================
> /*
> * Created on May 29, 2004
> *
> *
> */
> package org.apache.ws.axis.security;
>
> import java.text.SimpleDateFormat;
> import java.util.Calendar;
> import java.util.Random;
> import java.util.TimeZone;
>
> import javax.security.auth.callback.Callback;
> import javax.security.auth.callback.CallbackHandler;
> import javax.xml.soap.Name;
> import javax.xml.soap.SOAPElement;
> import javax.xml.soap.SOAPFactory;
> import javax.xml.soap.SOAPHeader;
> import javax.xml.soap.SOAPHeaderElement;
>
> import org.apache.axis.AxisFault;
> import org.apache.axis.Message;
> import org.apache.axis.MessageContext;
> import org.apache.axis.handlers.BasicHandler;
> import org.apache.ws.axis.security.WSDoAllConstants;
> import org.apache.ws.security.WSConstants;
> import org.apache.ws.security.WSPasswordCallback;
> import org.apache.ws.security.message.token.UsernameToken;
>
> /**
> *
> * This is a server side Axis handler that can be used to retrieve the
> * credentials available in the UsernameToken element. This will
> * retrieve the credentials and populate the SecurityContext4J2EE
> * property with them.
> *
> * This is a very simple handler that can handle only UsernameToken
> * elements. So that this can be used for testing peroposes and
> * other simple works.
> *
> * @author Rajith Priyanga (rpriyanga@yahoo.com)
> * @date May 29, 2004
> *
> */
> public class SimpleWSS4J2EESender extends BasicHandler {
>
> MessageContext cntxt = null;
>
> /**
> * Adds the username-password information to the SOAP header
> * within the UsernameToken, as requested by the user.
> * @see org.apache.axis.Handler#invoke(org.apache.axis.MessageContext)
> */
> public void invoke(MessageContext msgCntxt) throws AxisFault {
> this.cntxt = msgCntxt;
> String action = (String)cntxt.getProperty(WSDoAllConstants.ACTION);
> if(action==null)
> return;
>
> String[] actions = action.split(" ");
>
> boolean utAction = false;
> //Check whether UsernameToken action is requested. Otherwise no more processing.
> for(int i=0; i<actions.length; i++){
> utAction = actions[i].equalsIgnoreCase(WSDoAllConstants.USERNAME_TOKEN);
> if(utAction)
> break;
> }
> if(!utAction)
> return;
> //Get the username from the msg context.
> String username = this.cntxt.getUsername();
>
> //If the username property is not in the message context,
> if(username==null)
> username = (String)cntxt.getProperty(WSDoAllConstants.USER);
> if(username==null)
> throw AxisFault.makeFault(new Exception("No username specified!"));
>
> //Get the password type. If it is not defined, the deault is PasswardText.
> String pwdType = (String)cntxt.getProperty(WSDoAllConstants.PASSWORD_TYPE);
> if(pwdType==null)
> pwdType = WSConstants.PASSWORD_TEXT;
> addUsernameToken(username, pwdType);
> }
>
> /**
> * Creates and adds the Security-UsernameToken to the SOAP message.
> * @param username
> * @param passwordType
> * @throws AxisFault
> */
> private void addUsernameToken(String username, String passwordType) throws AxisFault{
> Message m = cntxt.getCurrentMessage();
> try{
> SOAPHeader h = m.getSOAPPart().getEnvelope().getHeader();
>
> SOAPFactory sf = SOAPFactory.newInstance();
>
> m.getSOAPEnvelope().addNamespaceDeclaration(WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS);
>
> Name secN = sf.createName(WSConstants.WSSE_LN, WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS);
> SOAPHeaderElement secElem = h.addHeaderElement(secN);
>
> //Add the Username Token.
> SOAPElement utElem = sf.createElement(WSConstants.WSSE_PREFIX+ ":" + WSConstants.USERNAME_TOKEN_LN);
> secElem.addChildElement(utElem);
>
> //Add the Username element.
> SOAPElement unElem = sf.createElement(WSConstants.WSSE_PREFIX+ ":" + WSConstants.USERNAME_LN);
> unElem.addTextNode(username);
> utElem.addChildElement(unElem);
>
> //Create the Password element.
> SOAPElement pwdElem = sf.createElement(WSConstants.WSSE_PREFIX+ ":" + WSConstants.PASSWORD_LN);
>
> Name pwdType = sf.createName(WSConstants.PASSWORD_TYPE_ATTR, WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS);
> //Add password element.
> if(passwordType.equalsIgnoreCase(WSConstants.PASSWORD_TEXT)){
> pwdElem.addAttribute(pwdType,WSConstants.PASSWORD_TEXT);
> pwdElem.addTextNode(fetchPWD(username));
> utElem.addChildElement(pwdElem);
> }
> else if(passwordType.equalsIgnoreCase(WSConstants.PASSWORD_DIGEST)){
> m.getSOAPEnvelope().addNamespaceDeclaration(WSConstants.WSU_PREFIX, WSConstants.WSU_NS);
> pwdElem.addAttribute(pwdType,WSConstants.PASSWORD_DIGEST);
>
> String nonce = getNonce();
> String created = getCreated();
> String digest = UsernameToken.doPasswordDigest(nonce, created, fetchPWD(username));
>
> SOAPElement nonceElem = sf.createElement(WSConstants.WSSE_PREFIX+":"+WSConstants.NONCE_LN);
> SOAPElement createdElem = sf.createElement(WSConstants.WSU_PREFIX+":"+WSConstants.CREATED_LN);
>
> nonceElem.addTextNode(nonce);
> createdElem.addTextNode(created);
> pwdElem.addTextNode(digest);
>
> utElem.addChildElement(pwdElem);
> utElem.addChildElement(nonceElem);
> utElem.addChildElement(createdElem);
> }
> else{
> throw AxisFault.makeFault(new Exception("Unsupported PasswordType"));
> }
> }
> catch(Exception ex){
> throw AxisFault.makeFault(ex);
> }
> }
>
> /*
> * Generates nonce.
> */
> private String getNonce(){
> Random rand = new Random();
> byte[] nonce = new byte[16];
> rand.nextBytes(nonce);
> String nonceStr = org.apache.xml.security.utils.Base64.encode(nonce);
> return nonceStr;
> }
>
> /**
> * Generates created as per specification.
> * @return
> */
> private String getCreated(){
> SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
> sd.setTimeZone(TimeZone.getTimeZone("GMT"));
> Calendar now = Calendar.getInstance();
> return sd.format(now.getTime());
> }
>
> /**
> * Fetch the password of the user from the specified PasswordCallbak class.
> * @param username
> * @return
> * @throws Exception
> */
> private String fetchPWD(String username) throws Exception{
> WSPasswordCallback pwcb = new WSPasswordCallback(username, WSPasswordCallback.USERNAME_TOKEN);
> Callback[] cb = new Callback[1];
> cb[0] = pwcb;
>
> CallbackHandler cbh = (CallbackHandler)this.cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_REF);
> if(cbh == null){
> String cbhClass = (String)this.cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_CLASS);
> cbh = (CallbackHandler)Class.forName(cbhClass).newInstance();
> }
> if(cbh == null){
> throw new Exception("No PasswordCallbackHandler class found.");
> }
> else{
> cbh.handle(cb);
> }
> String pwd = ((WSPasswordCallback)(cb[0])).getPassword();
> if(pwd==null)
> throw new Exception("Password is not provided! Can't create UsernameToken.");
> return pwd;
> }
>
> }
>
> 1.1 ws-axis/contrib/ews/src/org/apache/ws/axis/security/AllSecurity4J2EEReceiver.java
>
> Index: AllSecurity4J2EEReceiver.java
> ===================================================================
> /*
> * Created on Jun 20, 2004
> *
> *
> */
> package org.apache.ws.axis.security;
>
> import java.io.ByteArrayOutputStream;
> import java.math.BigInteger;
> import java.security.cert.X509Certificate;
> import java.text.SimpleDateFormat;
> import java.util.Calendar;
> import java.util.Hashtable;
> import java.util.Iterator;
> import java.util.TimeZone;
> import java.util.Vector;
>
> import javax.security.auth.callback.CallbackHandler;
> import javax.xml.soap.SOAPHeader;
> import javax.xml.soap.SOAPHeaderElement;
>
> import org.apache.axis.AxisFault;
> import org.apache.axis.Message;
> import org.apache.axis.MessageContext;
> import org.apache.axis.SOAPPart;
> import org.apache.commons.logging.Log;
> import org.apache.commons.logging.LogFactory;
> import org.apache.ws.axis.security.WSDoAllConstants;
> import org.apache.ws.axis.security.WSDoAllReceiver;
> import org.apache.ws.axis.security.WSDoAllReceiverResult;
> import org.apache.ws.axis.security.util.AxisUtil;
> import org.apache.ws.security.SOAPConstants;
> import org.apache.ws.security.WSConstants;
> import org.apache.ws.security.WSS4J2EEEngine;
> import org.apache.ws.security.WSSecurityEngineResult;
> import org.apache.ws.security.WSSecurityException;
> import org.apache.ws.security.components.crypto.Crypto;
> import org.apache.ws.security.components.crypto.CryptoFactory;
> import org.apache.ws.security.message.token.Timestamp;
> import org.apache.ws.security.util.WSSecurityUtil;
> import org.apache.xml.security.utils.XMLUtils;
> import org.w3c.dom.Document;
>
> /**
> * This class can be used to process any kind of WSSecurity token,
> * to retrieve the credentials required to Authenticate the user to
> * J2EE server and to populate the SecurityContext4J2EE property
> * with them.
> *
> * This class is written by modifying the some parts of
> * the WSDoAllReceiver class availble in WSS4J project. Modification
> * done to it should also be appeared here. This is a temporary solution
> * until that class come to a stable state.
> *
> * This uses WSS4J2EEEngine instead of WSSecurityEngine. Therefore the
> * authentication is only taken place at J2EE server, not at Axis.
> *
> * @author Rajith Priyanga (rpriyanga@yahoo.com)
> * @author Werner Dittmann (Werner.Dittmann@siemens.com)
> * @date Jun 20, 2004
> *
> */
> public class AllSecurity4J2EEReceiver extends WSDoAllReceiver{
>
> static final WSS4J2EEEngine sec4j2eeEngine = new WSS4J2EEEngine();
>
> static Log log = LogFactory.getLog(WSDoAllReceiver.class.getName());
>
> private boolean doDebug = true;
>
> private static Hashtable cryptos = new Hashtable(5);
>
> private MessageContext msgContext = null;
>
> Crypto sigCrypto = null;
> String sigPropFile = null;
>
> Crypto decCrypto = null;
> String decPropFile = null;
>
> protected int timeToLive = 300; // Timestamp: time in seconds the receiver accepts between creation and reception
>
> /**
> * Axis calls invoke to handle a message.
> * <p/>
> *
> * @param mc message context.
> * @throws AxisFault
> */
> public void invoke(MessageContext mc) throws AxisFault {
>
> /////////////////////////////////////////
> try{
> sec4j2eeEngine.setMessageContext(mc);
> }
> catch(Exception ex){
> throw AxisFault.makeFault(ex);
> }
> ////////////////////////////////////////
>
> if (doDebug) {
> log.debug("WSDoAllReceiver: enter invoke() with msg type: "
> + mc.getCurrentMessage().getMessageType());
> }
> msgContext = mc;
>
> Vector actions = new Vector();
> String action = null;
> if ((action = (String) getOption(WSDoAllConstants.ACTION)) == null) {
> action = (String) msgContext.getProperty(WSDoAllConstants.ACTION);
> }
> if (action == null) {
> throw new AxisFault("WSDoAllReceiver: No action defined");
> }
> int doAction = AxisUtil.decodeAction(action, actions);
>
> String actor = (String) getOption(WSDoAllConstants.ACTOR);
>
> Message sm = msgContext.getCurrentMessage();
> Document doc = null;
> try {
> doc = sm.getSOAPEnvelope().getAsDocument();
> if (doDebug) {
> log.debug("Received SOAP request: ");
> log.debug(org.apache.axis.utils.XMLUtils.PrettyDocumentToString(doc));
> }
> } catch (Exception ex) {
> throw new AxisFault(
> "WSDoAllReceiver: cannot convert into document",
> ex);
> }
> /*
> * Check if it's a response and if its a fault. Don't
> * process faults.
> */
> String msgType = sm.getMessageType();
> if (msgType != null && msgType.equals(Message.RESPONSE)) {
> SOAPConstants soapConstants =
> WSSecurityUtil.getSOAPConstants(doc.getDocumentElement());
> if (WSSecurityUtil
> .findElement(
> doc.getDocumentElement(),
> "Fault",
> soapConstants.getEnvelopeURI())
> != null) {
> return;
> }
> }
>
> /*
> * To check a UsernameToken or to decrypt an encrypted message we need
> * a password.
> */
> CallbackHandler cbHandler = null;
> if ((doAction & (WSConstants.ENCR | WSConstants.UT)) != 0) {
> cbHandler = getPasswordCB();
> }
>
> /*
> * Get and check the Signature specific parameters first because they
> * may be used for encryption too.
> */
>
> if ((doAction & WSConstants.SIGN) == WSConstants.SIGN) {
> decodeSignatureParameter();
> }
>
> if ((doAction & WSConstants.ENCR) == WSConstants.ENCR) {
> decodeDecryptionParameter();
> }
>
> Vector wsResult = null;
> try {
> wsResult =
> sec4j2eeEngine.processSecurityHeader(
> doc,
> actor,
> cbHandler,
> sigCrypto,
> decCrypto);
> } catch (WSSecurityException ex) {
> ex.printStackTrace();
> throw new AxisFault(
> "WSDoAllReceiver: security processing failed",
> ex);
> }
> if (wsResult == null) { // no security header found
> if (doAction == WSConstants.NO_SECURITY) {
> return;
> } else {
> throw new AxisFault("WSDoAllReceiver: Request does not contain required Security header");
> }
> }
>
> /*
> * If we had some security processing, get the original
> * SOAP part of Axis' message and replace it with new SOAP
> * part. This new part may contain decrypted elements.
> */
> SOAPPart sPart = (org.apache.axis.SOAPPart) sm.getSOAPPart();
>
> ByteArrayOutputStream os = new ByteArrayOutputStream();
> XMLUtils.outputDOM(doc, os, true);
> sPart.setCurrentMessage(os.toByteArray(), SOAPPart.FORM_BYTES);
> if (doDebug) {
> log.debug("Processed received SOAP request");
> log.debug(org.apache.axis.utils.XMLUtils.PrettyDocumentToString(doc));
> }
>
> /*
> * After setting the new current message, probably modified because
> * of decryption, we need to locate the security header. That is,
> * we force Axis (with getSOAPEnvelope()) to parse the string, build
> * the new header. Then we examine, look up the security header
> * and set the header as processed.
> *
> * Please note: find all header elements that contain the same
> * actor that was given to processSecurityHeader(). Then
> * check if there is a security header with this actor.
> */
>
> SOAPHeader sHeader = null;
> try {
> sHeader = sm.getSOAPEnvelope().getHeader();
> } catch (Exception ex) {
> throw new AxisFault("WSDoAllReceiver: cannot get SOAP header after security processing", ex);
> }
>
> Iterator headers = sHeader.examineHeaderElements(actor);
>
> SOAPHeaderElement headerElement = null;
> while (headers.hasNext()) {
> SOAPHeaderElement hE = (SOAPHeaderElement) headers.next();
> if (hE.getLocalName().equals(WSConstants.WSSE_LN)
> && hE.getNamespaceURI().equals(WSConstants.WSSE_NS)) {
> headerElement = hE;
> break;
> }
> }
> ((org.apache.axis.message.SOAPHeaderElement) headerElement).setProcessed(true);
>
> /*
> * Now we can check the certificate used to sign the message.
> * In the following implementation the certificate is only trusted
> * if either it itself or the certificate of the issuer is installed
> * in the keystore.
> *
> * Note: the method verifyTrust(X509Certificate) allows custom
> * implementations with other validation algorithms for subclasses.
> */
>
> // Extract the signature action result from the action vector
> WSSecurityEngineResult actionResult = WSSecurityUtil.fetchActionResult(wsResult, WSConstants.SIGN);
>
> if (actionResult != null) {
> X509Certificate returnCert = actionResult.getCertificate();
>
> if (returnCert != null) {
> if (!verifyTrust(returnCert)) {
> throw new AxisFault("WSDoAllReceiver: The certificate used for the signature is not trusted");
> }
> }
> }
>
> /*
> * Perform further checks on the timestamp that was transmitted in the header.
> * In the following implementation the timestamp is valid if it was
> * created after (now-ttl), where ttl is set on server side, not by the client.
> *
> * Note: the method verifyTimestamp(Timestamp) allows custom
> * implementations with other validation algorithms for subclasses.
> */
>
> // Extract the timestamp action result from the action vector
> actionResult = WSSecurityUtil.fetchActionResult(wsResult, WSConstants.TS);
>
> if (actionResult != null) {
> Timestamp timestamp = actionResult.getTimestamp();
>
> if (timestamp != null) {
> String ttl = null;
> if ((ttl =
> (String) getOption(WSDoAllConstants.TTL_TIMESTAMP))
> == null) {
> ttl =
> (String) msgContext.getProperty(
> WSDoAllConstants.TTL_TIMESTAMP);
> }
> int ttl_i = 0;
> if (ttl != null) {
> try {
> ttl_i = Integer.parseInt(ttl);
> } catch (NumberFormatException e) {
> ttl_i = timeToLive;
> }
> }
> if (ttl_i <= 0) {
> ttl_i = timeToLive;
> }
>
> if (!verifyTimestamp(timestamp, timeToLive)) {
> throw new AxisFault("WSDoAllReceiver: The timestamp could not be validated");
> }
> }
> }
>
> /*
> * now check the security actions: do they match, in right order?
> */
> int resultActions = wsResult.size();
> int size = actions.size();
> if (size != resultActions) {
> throw new AxisFault("WSDoAllReceiver: security processing failed (actions number mismatch)");
> }
> for (int i = 0; i < size; i++) {
> if (((Integer) actions.get(i)).intValue()
> != ((WSSecurityEngineResult)wsResult.get(i)).getAction()) {
> throw new AxisFault("WSDoAllReceiver: security processing failed (actions mismatch)");
> }
> }
>
> /*
> * All ok up to this point. Now construct and setup the
> * security result structure. The service may fetch this
> * and check it.
> */
> Vector results = null;
> if ((results = (Vector) mc.getProperty(WSDoAllConstants.RECV_RESULTS))
> == null) {
> results = new Vector();
> mc.setProperty(WSDoAllConstants.RECV_RESULTS, results);
> }
> WSDoAllReceiverResult rResult =
> new WSDoAllReceiverResult(
> actor,
> wsResult);
> results.add(0, rResult);
> if (doDebug) {
> log.debug("WSDoAllReceiver: exit invoke()");
> }
> }
>
> /**
> * Hook to allow subclasses to load their Signature Crypto however they see fit.
> */
> protected Crypto loadSignatureCrypto() throws AxisFault {
> Crypto crypto = null;
> if ((sigPropFile = (String) getOption(WSDoAllConstants.SIG_PROP_FILE))
> == null) {
> sigPropFile =
> (String) msgContext.getProperty(WSDoAllConstants.SIG_PROP_FILE);
> }
> if (sigPropFile != null) {
> if ((crypto = (Crypto) cryptos.get(sigPropFile)) == null) {
> crypto = CryptoFactory.getInstance(sigPropFile);
> cryptos.put(sigPropFile, crypto);
> }
> } else {
> throw new AxisFault("WSDoAllReceiver: Signature: no crypto property file");
> }
> return crypto;
> }
>
> /**
> * Hook to allow subclasses to load their Decryption Crypto however they see fit.
> */
> protected Crypto loadDecryptionCrypto() throws AxisFault {
> Crypto crypto = null;
> if ((decPropFile = (String) getOption(WSDoAllConstants.DEC_PROP_FILE))
> == null) {
> decPropFile =
> (String) msgContext.getProperty(WSDoAllConstants.DEC_PROP_FILE);
> }
> if (decPropFile != null) {
> if ((crypto = (Crypto) cryptos.get(decPropFile)) == null) {
> crypto = CryptoFactory.getInstance(decPropFile);
> cryptos.put(decPropFile, crypto);
> }
> } else if ((crypto = sigCrypto) == null) {
> throw new AxisFault("WSDoAllReceiver: Encryption: no crypto property file");
> }
> return crypto;
> }
>
> private void decodeSignatureParameter() throws AxisFault {
> sigCrypto = loadSignatureCrypto();
> /* There are currently no other signature parameters that need to be handled
> * here, but we call the load crypto hook rather than just changing the visibility
> * of this method to maintain parity with WSDoAllSender.
> */
> }
>
> /*
> * Set and check the decryption specific parameters, if necessary
> * take over signatur crypto instance.
> */
>
> private void decodeDecryptionParameter() throws AxisFault {
> decCrypto = loadDecryptionCrypto();
> /* There are currently no other decryption parameters that need to be handled
> * here, but we call the load crypto hook rather than just changing the visibility
> * of this method to maintain parity with WSDoAllSender.
> */
> }
>
> /**
> * Get the password callback class and get an instance
> * <p/>
> */
> private CallbackHandler getPasswordCB() throws AxisFault {
>
> String callback = null;
> CallbackHandler cbHandler = null;
> if ((callback = (String) getOption(WSDoAllConstants.PW_CALLBACK_CLASS))
> == null) {
> callback =
> (String) msgContext.getProperty(
> WSDoAllConstants.PW_CALLBACK_CLASS);
> }
> if (callback != null) {
> Class cbClass = null;
> try {
> cbClass = java.lang.Class.forName(callback);
> } catch (ClassNotFoundException e) {
> throw new AxisFault(
> "WSDoAllReceiver: cannot load password callback class: "
> + callback,
> e);
> }
> try {
> cbHandler = (CallbackHandler) cbClass.newInstance();
> } catch (java.lang.Exception e) {
> throw new AxisFault(
> "WSDoAllReceiver: cannot create instance of password callback: "
> + callback,
> e);
> }
> } else {
> cbHandler =
> (CallbackHandler) msgContext.getProperty(
> WSDoAllConstants.PW_CALLBACK_REF);
> if (cbHandler == null) {
> throw new AxisFault("WSDoAllReceiver: no reference in callback property");
> }
> }
> return cbHandler;
> }
>
> /**
> * Evaluate whether a given certificate should be trusted.
> * Hook to allow subclasses to implement custom validation methods however they see fit.
> * <p/>
> * Policy used in this implementation:
> * 1. Search the keystore for the transmitted certificate
> * 2. Search the keystore for a connection to the transmitted certificate
> * (that is, search for certificate(s) of the issuer of the transmitted certificate
> * 3. Verify the trust path for those certificates found because the search for the issuer might be fooled by a phony DN (String!)
> *
> * @param cert the certificate that should be validated against the keystore
> * @return true if the certificate is trusted, false if not (AxisFault is thrown for exceptions during CertPathValidation)
> * @throws AxisFault
> */
> private boolean verifyTrust(X509Certificate cert) throws AxisFault {
>
> // If no certificate was transmitted, do not trust the signature
> if (cert == null) {
> return false;
> }
>
> String[] aliases = null;
> String alias = null;
> X509Certificate[] certs;
>
> String subjectString = cert.getSubjectDN().getName();
> String issuerString = cert.getIssuerDN().getName();
> BigInteger issuerSerial = cert.getSerialNumber();
>
> if (doDebug) {
> log.debug("WSDoAllReceiver: Transmitted certificate has subject " + subjectString);
> log.debug("WSDoAllReceiver: Transmitted certificate has issuer " + issuerString + " (serial " + issuerSerial + ")");
> }
>
> // FIRST step
> // Search the keystore for the transmitted certificate
>
> // Search the keystore for the alias of the transmitted certificate
> try {
> alias = sigCrypto.getAliasForX509Cert(issuerString, issuerSerial);
> } catch (WSSecurityException ex) {
> throw new AxisFault("WSDoAllReceiver: Could not get alias for certificate with " + subjectString, ex);
> }
>
> if (alias != null) {
> // Retrieve the certificate for the alias from the keystore
> try {
> certs = sigCrypto.getCertificates(alias);
> } catch (WSSecurityException ex) {
> throw new AxisFault("WSDoAllReceiver: Could not get certificates for alias " + alias, ex);
> }
>
> // If certificates have been found, the certificates must be compared
> // to ensure againgst phony DNs (compare encoded form including signature)
> if (certs != null && certs.length > 0 && cert.equals(certs[0])) {
> if (doDebug) {
> log.debug("Direct trust for certificate with " + subjectString);
> }
> return true;
> }
> } else {
> if (doDebug) {
> log.debug("No alias found for subject from issuer with " + issuerString + " (serial " + issuerSerial + ")");
> }
> }
>
> // SECOND step
> // Search for the issuer of the transmitted certificate in the keystore
>
> // Search the keystore for the alias of the transmitted certificates issuer
> try {
> aliases = sigCrypto.getAliasesForDN(issuerString);
> } catch (WSSecurityException ex) {
> throw new AxisFault("WSDoAllReceiver: Could not get alias for certificate with " + issuerString, ex);
> }
>
> // If the alias has not been found, the issuer is not in the keystore
> // As a direct result, do not trust the transmitted certificate
> if (aliases == null || aliases.length < 1) {
> if (doDebug) {
> log.debug("No aliases found in keystore for issuer " + issuerString + " of certificate for " + subjectString);
> }
> return false;
> }
>
> // THIRD step
> // Check the certificate trust path for every alias of the issuer found in the keystore
> for (int i = 0; i < aliases.length; i++) {
> alias = aliases[i];
>
> if (doDebug) {
> log.debug("Preparing to validate certificate path with alias " + alias + " for issuer " + issuerString);
> }
>
> // Retrieve the certificate(s) for the alias from the keystore
> try {
> certs = sigCrypto.getCertificates(alias);
> } catch (WSSecurityException ex) {
> throw new AxisFault("WSDoAllReceiver: Could not get certificates for alias " + alias, ex);
> }
>
> // If no certificates have been found, there has to be an error:
> // The keystore can find an alias but no certificate(s)
> if (certs == null | certs.length < 1) {
> throw new AxisFault("WSDoAllReceiver: Could not get certificates for alias " + alias);
> }
>
> // Form a certificate chain from the transmitted certificate
> // and the certificate(s) of the issuer from the keystore
>
> // First, create new array
> X509Certificate[] x509certs = new X509Certificate[certs.length + 1];
>
> /* The following conversion into provider specific format seems not to be necessary
> // Create new certificate, possibly provider-specific
> try {
> cert = sigCrypto.loadCertificate(new ByteArrayInputStream(cert.getEncoded()));
> } catch (CertificateEncodingException ex) {
> throw new AxisFault("WSDoAllReceiver: Combination of subject and issuers certificates failed", ex);
> } catch (WSSecurityException ex) {
> throw new AxisFault("WSDoAllReceiver: Combination of subject and issuers certificates failed", ex);
> }
> */
>
> // Then add the first certificate ...
> x509certs[0] = cert;
>
> // ... and the other certificates
> for (int j=0; j < certs.length; j++) {
> cert = certs[i];
>
> /* The following conversion into provider specific format seems not to be necessary
> // Create new certificate, possibly provider-specific
> try {
> cert = sigCrypto.loadCertificate(new ByteArrayInputStream(cert.getEncoded()));
> } catch (CertificateEncodingException ex) {
> throw new AxisFault("WSDoAllReceiver: Combination of subject and issuers certificates failed", ex);
> } catch (WSSecurityException ex) {
> throw new AxisFault("WSDoAllReceiver: Combination of subject and issuers certificates failed", ex);
> }
> */
>
> x509certs[certs.length + j] = cert;
> }
> certs = x509certs;
>
> // Use the validation method from the crypto to check whether the subjects certificate was really signed by the issuer stated in the certificate
> try {
> if (sigCrypto.validateCertPath(certs)) {
> if (doDebug) {
> log.debug("WSDoAllReceiver: Certificate path has been verified for certificate with subject " + subjectString);
> }
> return true;
> }
> } catch (WSSecurityException ex) {
> throw new AxisFault("WSDoAllReceiver: Certificate path verification failed for certificate with subject " + subjectString, ex);
> }
> }
>
> log.debug("WSDoAllReceiver: Certificate path could not be verified for certificate with subject " + subjectString);
> return false;
> }
>
> /**
> * Evaluate whether a timestamp is considered valid on receiverside.
> * Hook to allow subclasses to implement custom validation methods however they see fit.
> * <p/>
> * Policy used in this implementation:
> * 1. The receiver can set its own time to live (besides from that set on sender side)
> * 2. If the message was created before (now-ttl) the message is rejected
> *
> * @param timestamp the timestamp that is validated
> * @param timeToLive the limit on receiverside, the timestamp is validated against
> * @return true if the timestamp is before (now-timeToLive), false otherwise
> * @throws AxisFault
> */
> protected boolean verifyTimestamp(Timestamp timestamp, int timeToLive) throws AxisFault {
>
> // Calculate the time that is allowed for the message to travel
> Calendar validCreation = Calendar.getInstance();
> long currentTime = validCreation.getTimeInMillis();
> currentTime -= timeToLive * 1000;
> validCreation.setTimeInMillis(currentTime);
>
> if (doDebug) {
> log.debug("Preparing to verify the timestamp");
> SimpleDateFormat zulu = new SimpleDateFormat(
> "yyyy-MM-dd'T'HH:mm:ss'Z'");
> zulu.setTimeZone(TimeZone.getTimeZone("GMT"));
> log.debug("Validation of Timestamp: Current time is "
> + zulu.format(Calendar.getInstance().getTime()));
> log.debug("Validation of Timestamp: Valid creation is "
> + zulu.format(validCreation.getTime()));
> log.debug("Validation of Timestamp: Timestamp created is "
> + zulu.format(timestamp.getCreated().getTime()));
> }
> // Validate the time it took the message to travel
> // if (timestamp.getCreated().before(validCreation) ||
> // !timestamp.getCreated().equals(validCreation)) {
> if (!timestamp.getCreated().after(validCreation)) {
> if (doDebug) {
> log.debug("Validation of Timestamp: The message was created too long ago");
> }
> return false;
> }
>
> log.debug("Validation of Timestamp: Everything is ok");
> return true;
> }
>
> }
>
> 1.1 ws-axis/contrib/ews/src/org/apache/ws/axis/security/BasicAuth4J2EEReceiver.java
>
> Index: BasicAuth4J2EEReceiver.java
> ===================================================================
> /*
> * Created on Jun 20, 2004
> *
> *
> */
> package org.apache.ws.axis.security;
>
> import javax.security.auth.callback.Callback;
> import javax.security.auth.callback.CallbackHandler;
>
> import org.apache.axis.AxisFault;
> import org.apache.axis.MessageContext;
> import org.apache.axis.handlers.BasicHandler;
> import org.apache.geronimo.ews.ws4j2ee.context.security.impl.SecurityContext4J2EEImpl;
> import org.apache.ws.axis.security.WSDoAllConstants;
> import org.apache.ws.security.WSPasswordCallback;
>
> /**
> * If the client is using BasicHTTP Authentication, this class can be used
> * as a server side Axis handler, which retreives the credentials available in
> * the HTTP header and populate the SecurityContext4J2EE property.
> *
> * Only if the <code>WSS4J2EEConstants.AUTH_AT_AXIS</code> property is set to true,
> * this does the authentication at the Axis. For that at the DD the <code>passwordCallbackClass</code>
> * should be available.
> *
> * @author Rajith Priyanga
> * @date Jun 20, 2004
> *
> */
> public class BasicAuth4J2EEReceiver extends BasicHandler {
>
> private boolean doAuthentication = false;
> /**
> * @see org.apache.axis.Handler#invoke(org.apache.axis.MessageContext)
> */
> public void invoke(MessageContext cntxt) throws AxisFault {
> doAuthentication = false;
> String username = cntxt.getUsername();
> String password = cntxt.getPassword();
> if(username==null|| password==null){
> throw AxisFault.makeFault(new Exception("null values for username or/and password."));
> }
>
> //Decides whether to do authentication at Axis or not.
> if(cntxt.containsProperty(WSS4J2EEConstants.AUTH_AT_AXIS)){
> String check = (String)cntxt.getProperty(WSS4J2EEConstants.AUTH_AT_AXIS);
> if(check!=null && check.equalsIgnoreCase("true"))
> this.doAuthentication = true;
> }
>
> if(this.doAuthentication){
> try{
> this.veryfyPWD(username, password, cntxt);
> }
> catch(Exception e){
> throw AxisFault.makeFault(e);
> }
> }
>
> populateSecurityContext4J2EE(username, password, cntxt);
> }
>
> /**
> * Populates the SecurityContext4J2EE property with the given credentials.
> * Also this adds a PWDCallbackHandler4J2EE to the SecurityContext4J2EE.
> * @param username
> * @param password
> * @param cntxt
> */
> private void populateSecurityContext4J2EE(String username, String password, MessageContext cntxt){
> SecurityContext4J2EEImpl sc4j2ee =
> (SecurityContext4J2EEImpl)cntxt.getProperty(WSS4J2EEConstants.SEC_CONTEXT_4J2EE);
>
> if(sc4j2ee==null){
> sc4j2ee = new SecurityContext4J2EEImpl();
> cntxt.setProperty(WSS4J2EEConstants.SEC_CONTEXT_4J2EE, sc4j2ee);
> }
>
> //Populate the SecurityContext4J2EE with the auth data.
> sc4j2ee.setUsername(username);
> sc4j2ee.setPassword(password.toCharArray());
> sc4j2ee.setPasswordDigested(false);
>
> PWDCallbackHandler4J2EE pwdcbh = new PWDCallbackHandler4J2EE(username, password.toCharArray());
> sc4j2ee.setPWDCallbackHandler4J2EE(pwdcbh);
> }
>
> private boolean veryfyPWD(String username, String password, MessageContext cntxt) throws Exception{
> if(password.equals(this.fetchActualPWD(username, cntxt))){
> return true;
> }
> else{
> return false;
> }
> }
>
> private String fetchActualPWD(String username, MessageContext cntxt) throws Exception{
> WSPasswordCallback pwcb = new WSPasswordCallback(username, WSPasswordCallback.USERNAME_TOKEN);
> Callback[] cb = new Callback[1];
>
> cb[0] = pwcb;
>
> CallbackHandler cbh = (CallbackHandler)cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_REF);
>
> if(cbh == null){
> String cbhClass = (String)cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_CLASS);
> cbh = (CallbackHandler)Class.forName(cbhClass).newInstance();
> }
>
> if(cbh==null){
> throw new Exception("PasswordCallbackHandler not found!");
> }
>
> cbh.handle(cb);
> String pwd = ((WSPasswordCallback)(cb[0])).getPassword();
>
> if(pwd==null)
> throw new Exception("Password is not provided.");
>
> return pwd;
>
> }
>
> }
>
> 1.1 ws-axis/contrib/ews/src/org/apache/ws/axis/security/SimpleWSS4J2EEReceiver.java
>
> Index: SimpleWSS4J2EEReceiver.java
> ===================================================================
> /*
> * Created on May 29, 2004
> *
> *
> */
> package org.apache.ws.axis.security;
>
> import java.util.Iterator;
>
> import javax.security.auth.callback.Callback;
> import javax.security.auth.callback.CallbackHandler;
> import javax.xml.soap.Name;
> import javax.xml.soap.SOAPElement;
> import javax.xml.soap.SOAPFactory;
> import javax.xml.soap.SOAPHeader;
> import javax.xml.soap.SOAPHeaderElement;
>
> import org.apache.axis.AxisFault;
> import org.apache.axis.Message;
> import org.apache.axis.MessageContext;
> import org.apache.axis.handlers.BasicHandler;
> import org.apache.geronimo.ews.ws4j2ee.context.security.impl.SecurityContext4J2EEImpl;
> import org.apache.ws.axis.security.WSDoAllConstants;
> import org.apache.ws.security.WSConstants;
> import org.apache.ws.security.WSPasswordCallback;
> import org.apache.ws.security.message.token.UsernameToken;
>
> /**
> * This is an Axis handler that can be used to retrieve the credentials
> * available in the <code>UsernameToken</code> element.
> * This is a simple security handler that can provide only that service.
> * Therefore this handler can be used for testing perposes and
> * other simple works.
> *
> * This can be configured to do the authentication at Axis or at J2EE Server.
> * For that you have to set the <code>WSS4J2EEConstants.AUTH_AT_AXIS</code>
> * to true.
> *
> *
> * @author Rajith Priyanga (rpriyanga@yahoo.com)
> * @date May 29, 2004
> *
> */
> public class SimpleWSS4J2EEReceiver extends BasicHandler {
>
> MessageContext cntxt = null;
>
> boolean doAuthentication = false;
>
> /**
> * Retrieve the username-password information and perform a verification.
> * @see org.apache.axis.Handler#invoke(org.apache.axis.MessageContext)
> */
> public void invoke(MessageContext msgCntxt) throws AxisFault {
> this.cntxt = msgCntxt;
> doAuthentication = false;
>
> try{
> //Get the SOAP header.
> Message m = msgCntxt.getCurrentMessage();
> SOAPHeader sh = m.getSOAPPart().getEnvelope().getHeader();
>
> //Retrieve the action property.
> String action = null;
> if((action = (String) getOption(WSDoAllConstants.ACTION))==null)
> action = (String)cntxt.getProperty(WSDoAllConstants.ACTION);
>
> if(action==null){
> return;
> }
>
> String[] actions = action.split(" ");
> if(actions==null)
> return;
>
> boolean utAction = false;
>
> //Check whether UsernameToken action property is available. Otherwise no more processing.
> for(int i=0; i<actions.length; i++){
> utAction = actions[i].equalsIgnoreCase(WSDoAllConstants.USERNAME_TOKEN);
> if(utAction)
> break;
> }
> if(!utAction)
> return;
>
> //Get all the headers.
> Iterator headers = sh.getChildElements();
> SOAPHeaderElement headerElem = null;
>
> if(headers==null){
> throw AxisFault.makeFault(new Exception("No Security Headers found"));
> }
> //Find the security header.
> while (headers.hasNext()) {
> headerElem = (SOAPHeaderElement) headers.next();
> if (headerElem.getLocalName().equals(WSConstants.WSSE_LN)
> && headerElem.getNamespaceURI().equals(WSConstants.WSSE_NS)) {
> //headerElem.setMustUnderstand(false);
> break;
> }
> }
>
> //Decides whether to do authentication at Axis or not.
> if(cntxt.containsProperty(WSS4J2EEConstants.AUTH_AT_AXIS)){
> String check = (String)cntxt.getProperty(WSS4J2EEConstants.AUTH_AT_AXIS);
> if(check!=null && check.equalsIgnoreCase("true"))
> this.doAuthentication = true;
> }
>
> //Hand over the security header to process it's UsernameToken.
> processUsernameToken(headerElem);
> headerElem.detachNode();
> }
> catch(Exception ex){
> throw AxisFault.makeFault(ex);
> }
> }
>
> /**
> * Processes the UsernameToken element of the security header.
> * It populates the SecurityContext4J2EE property of the MessageContext too.
> * @param secHeader SOAP Security Header.
> * @throws Exception
> */
> private void processUsernameToken(SOAPHeaderElement secHeader) throws Exception{
> SOAPFactory sf = SOAPFactory.newInstance();
> Name utName = sf.createName(WSConstants.USERNAME_TOKEN_LN, WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS);
> Iterator toks = secHeader.getChildElements(utName);
>
> if(toks==null){
> throw new Exception("No Security tokens found!");
> }
>
> //Get the UsernameToken element
> SOAPElement utElem = null;
> if(toks.hasNext()){
> utElem = (SOAPElement)toks.next();
> }
> else{
> throw new Exception("No UsernameToken found!");
> }
> Name unName = sf.createName(WSConstants.USERNAME_LN, WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS);
> Name pwdName = sf.createName(WSConstants.PASSWORD_LN, WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS);
>
> //Get the user name
> String username = ((SOAPElement)(utElem.getChildElements(unName).next())).getValue();
>
> //Get the password element
> SOAPElement pwdElem = (SOAPElement)utElem.getChildElements(pwdName).next();
>
> //Get the password type
> String pwdType = pwdElem.getAttributeValue(sf.createName(WSConstants.PASSWORD_TYPE_ATTR, WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS));//, WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS));
>
> //Get the password
> String pwd = pwdElem.getValue();
>
> //If the password type is not speciied take it as PASSWORD_TEXT type.
> if(pwdType==null)
> pwdType = WSConstants.PASSWORD_TEXT;
>
> if(pwdType.equalsIgnoreCase(WSConstants.PASSWORD_TEXT)){
> ///////////// This part can be removed. . /////////////////
> if(doAuthentication){
> if(!veryfyPWD(username, pwd)){
> throw new Exception("Password Verification failed!");
> }
> }
> ///////////////////////////////////////////////////////////
> this.populateSecurityContext4J2EE(username, pwd, pwdType, null, null);
> //this.Authenticate4J2EE();
> }
> else if(pwdType.equalsIgnoreCase(WSConstants.PASSWORD_DIGEST)){
> Name nonceName = sf.createName(WSConstants.NONCE_LN, WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS);
> Name createdName = sf.createName(WSConstants.CREATED_LN, WSConstants.WSU_PREFIX, WSConstants.WSU_NS);
>
> Iterator elems = utElem.getChildElements(nonceName);
> String nonce = this.extractNonce(elems);
>
> elems = utElem.getChildElements(createdName);
> String created = this.extractCreated(elems);
> ///////////// This part can be removed. . /////////////////
> if(doAuthentication){
> if(!veryfyPWD(username, pwd, nonce, created)){
> throw new Exception("Password Verification failed!");
> }
> }
> ///////////////////////////////////////////////////////////
> this.populateSecurityContext4J2EE(username, pwd, pwdType, nonce, created);
> }
> else{
> throw new Exception("Unsupported Password Type!");
> }
> }
>
> /**
> * Extracts the nonce value from the given set of elements.
> * (It is given as a iteratorf o elements)
> * @param elements
> * @return
> * @throws Exception
> */
> private String extractNonce(Iterator elements) throws Exception{
> boolean noNonce = false;
> String nonce = null;
>
> if(elements==null){
> noNonce = true;
> }
> if(!noNonce && elements.hasNext()){
> nonce = ((SOAPElement)(elements.next())).getValue();
> }
> else{
> noNonce = true;
> }
> if(nonce == null){
> noNonce = true;
> }
> if(noNonce)
> throw new Exception("Nonce is not specified!");
>
> return nonce;
> }
>
> /**
> * Extracts the created value from the given set of elements.
> * (It is given as a iteratorf o elements)
> * @param elements
> * @return
> * @throws Exception
> */
> private String extractCreated(Iterator elements) throws Exception{
> boolean noCreated = false;
> String created = null;
>
> if(elements==null)
> noCreated = true;
>
> if(!noCreated && elements.hasNext())
> created = ((SOAPElement)(elements.next())).getValue();
> else
> noCreated = true;
>
> if(created == null)
> noCreated = true;
>
> if(noCreated)
> throw new Exception("Created is not specified!");
>
> return created;
> }
>
> /**
> * Verifies the PASSWORD_TEXT type passwords.
> */
> private boolean veryfyPWD(String username, String password) throws Exception{
> if(password.equals(this.fetchActualPWD(username))){
> return true;
> }
> else{
> return false;
> }
> }
>
> /**
> * Verifies the PASSWORD_DIGEST type passwords.
> */
> private boolean veryfyPWD(String username,
> String password,
> String nonce,
> String created) throws Exception{
>
> //TODO
> //Check whether (created > currentTime - 5 minutes).
> //Cache the nonce for the user and check it before verification.
>
> if(nonce == null || created == null){
> throw new Exception("Nonce or Created not supplied!");
> }
>
> String digest = UsernameToken.doPasswordDigest(nonce, created, this.fetchActualPWD(username));
>
> if(password.equals(digest)){
> return true;
> }
> else{
> return false;
> }
> }
>
> /**}
> * Fetches the actual password using the CallbackHandler specified
> * in the deployment descripter.
> * @param username username
> * @return the actual password of the user.
> * @throws Exception
> */
>
> private String fetchActualPWD(String username) throws Exception{
> WSPasswordCallback pwcb = new WSPasswordCallback(username, WSPasswordCallback.USERNAME_TOKEN);
> Callback[] cb = new Callback[1];
>
> cb[0] = pwcb;
>
> CallbackHandler cbh = (CallbackHandler)this.cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_REF);
>
> if(cbh == null){
> String cbhClass = (String)this.cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_CLASS);
> cbh = (CallbackHandler)Class.forName(cbhClass).newInstance();
> }
>
> if(cbh==null){
> throw new Exception("PasswordCallbackHandler not found!");
> }
>
> cbh.handle(cb);
> String pwd = ((WSPasswordCallback)(cb[0])).getPassword();
>
> if(pwd==null)
> throw new Exception("Password is not provided.");
>
> return pwd;
>
> }
>
> /**
> * Associates a Authenticated principal with this thread this thread.
> * @throws Exception
> */
> /*private void Authenticate4J2EE() throws Exception{
> CallbackHandler cbh = (CallbackHandler)this.cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_REF);
> if(cbh == null){
> String cbhClass = (String)this.cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_CLASS);
> cbh = (CallbackHandler)Class.forName(cbhClass).newInstance();
> }
>
> if(cbh != null){
> javax.security.auth.login.LoginContext lc
> = new javax.security.auth.login.LoginContext("LC4" + this.cntxt.getTargetService(), cbh);
> lc.login();
> }
> else
> throw new Exception("CallbackHandler is null.");
> }*/
>
> /**
> * Populates the SecurityContext4J2EE property with the given
> * security information.
> * @param username
> * @param password
> * @param passwordType
> * @param nonce
> * @param created
> */
> private void populateSecurityContext4J2EE(String username, String password, String passwordType, String nonce, String created){
> SecurityContext4J2EEImpl sc4j2ee =
> (SecurityContext4J2EEImpl)this.cntxt.getProperty(WSS4J2EEConstants.SEC_CONTEXT_4J2EE);
>
> if(sc4j2ee==null){
> sc4j2ee = new SecurityContext4J2EEImpl();
> this.cntxt.setProperty(WSS4J2EEConstants.SEC_CONTEXT_4J2EE, sc4j2ee);
> }
>
> //Populate the SecurityContext4J2EE with the user name token data.
> sc4j2ee.setUsername(username);
> sc4j2ee.setPassword(password.toCharArray());
>
> if(passwordType.equalsIgnoreCase(WSConstants.PASSWORD_DIGEST)){
> sc4j2ee.setPasswordDigested(true);
> sc4j2ee.setNonce(nonce);
> sc4j2ee.setCreated(created);
> }
> else
> sc4j2ee.setPasswordDigested(false);
>
> PWDCallbackHandler4J2EE cbh = new PWDCallbackHandler4J2EE(username, password.toCharArray());
> sc4j2ee.setPWDCallbackHandler4J2EE(cbh);
> }
>
> }
>
> 1.1 ws-axis/contrib/ews/src/org/apache/ws/axis/security/CheckPoint4J2EEHandler.java
>
> Index: CheckPoint4J2EEHandler.java
> ===================================================================
> /*
> * Created on Apr 6, 2004
> *
> *
> */
> package org.apache.ws.axis.security;
>
> import org.apache.axis.AxisFault;
> import org.apache.axis.MessageContext;
> import org.apache.axis.handlers.BasicHandler;
> import org.apache.geronimo.ews.ws4j2ee.context.security.SecurityContext4J2EE;
>
> /**
> *
> * Still this is not in use. But may be in future...
> *
> * @author Rajith Priyanga (rpriyanga@yahoo.com)
> * @date Apr 6, 2004
> *
> */
> public abstract class CheckPoint4J2EEHandler extends BasicHandler {
>
> /**
> * @see org.apache.axis.Handler#invoke(org.apache.axis.MessageContext)
> */
> public void invoke(MessageContext cntxt) throws AxisFault{
> SecurityContext4J2EE sc4j2ee;
> //TODO
> //Populate the SecurityContext4J2EE object with available info.
> //Other info will be dynamically calculated rom MessageCOntext.
> }
>
> /**
> * Decides whether the message integrity is sufficiently varifiable.
> * @param cntxt Message context.
> * @return true if the test is passed.
> */
> public abstract boolean integrityTest(MessageContext cntxt);
>
> /**
> * Decides whether the message privacy is sufficiently protected.
> * @param cntxt Message context
> * @return true if the test is passed.
> */
> public abstract boolean privacyTest(MessageContext cntxt);
>
> /**
> * Returns the password of the given user. This should be retrieved
> * from a password store.
> * @param username
> * @return The actual password.
> */
> public abstract char[] getPassword(String username);
>
> }
>
> 1.5 +4 -3 ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/toWs/wrapperWs/SimpleRemoteInterfaceBasedWrapperClassWriter.java
>
> Index: SimpleRemoteInterfaceBasedWrapperClassWriter.java
> ===================================================================
> RCS file: /home/cvs/ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/toWs/wrapperWs/SimpleRemoteInterfaceBasedWrapperClassWriter.java,v
> retrieving revision 1.4
> retrieving revision 1.5
> diff -u -r1.4 -r1.5
> --- SimpleRemoteInterfaceBasedWrapperClassWriter.java 10 Jun 2004 11:35:19 -0000 1.4
> +++ SimpleRemoteInterfaceBasedWrapperClassWriter.java 7 Jul 2004 09:02:00 -0000 1.5
> @@ -136,10 +136,11 @@
> out.write("\t\tif(msgcontext == null){\n");
> out.write("\t\t msgcontext = org.apache.axis.MessageContext.getCurrentContext();\n");
> out.write("\t\t}\n");
> -
> + out.write("\t\torg.apache.geronimo.ews.ws4j2ee.context.security.SecurityContext4J2EE seccontext =\n");
> + out.write("\t\t (org.apache.geronimo.ews.ws4j2ee.context.security.SecurityContext4J2EE)msgcontext\n");
> + out.write("\t\t.getProperty(org.apache.ws.axis.security.WSS4J2EEConstants.SEC_CONTEXT_4J2EE);\n");
> out.write("\t\t javax.security.auth.callback.CallbackHandler handler\n");
> - out.write("\t\t = org.apache.geronimo.ews.ws4j2ee.wsutils.security.jaasmodules.\n");
> - out.write("\t\t AutenticationCallbackHandlerFactory.createCallbackHandler(msgcontext);\n");
> + out.write("\t\t = seccontext.getPWDCallbackHandler4J2EE();\n");
> out.write("\t\t if(handler != null){\n");
> out.write("\t\t javax.security.auth.login.LoginContext lc\n");
> out.write("\t\t = new javax.security.auth.login.LoginContext(\"TestClient\", handler);\n");
>
> 1.2 +11 -5 ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/context/security/SecurityContext4J2EE.java
>
> Index: SecurityContext4J2EE.java
> ===================================================================
> RCS file: /home/cvs/ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/context/security/SecurityContext4J2EE.java,v
> retrieving revision 1.1
> retrieving revision 1.2
> diff -u -r1.1 -r1.2
> --- SecurityContext4J2EE.java 14 Jun 2004 08:24:39 -0000 1.1
> +++ SecurityContext4J2EE.java 7 Jul 2004 09:02:00 -0000 1.2
> @@ -1,10 +1,8 @@
> -/*
> - * Created on Apr 5, 2004
> - *
> - *
> - */
> package org.apache.geronimo.ews.ws4j2ee.context.security;
>
> +
> +
> +import javax.security.auth.callback.CallbackHandler;
> import javax.security.cert.X509Certificate;
>
> /**
> @@ -83,4 +81,12 @@
> * @return the X509 Certificate.
> */
> public byte[] getKerberoseTicket();
> +
> + /**
> + * Returns a PasswordCallbackHandler which can be used in
> + * authentication done using JAAS module at the wrapper web service.
> + * @return CallbackHandler.
> + */
> + public CallbackHandler getPWDCallbackHandler4J2EE();
> +
> }
>
> 1.13 +0 -3 ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/toWs/GenerationConstants.java
>
> Index: GenerationConstants.java
> ===================================================================
> RCS file: /home/cvs/ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/toWs/GenerationConstants.java,v
> retrieving revision 1.12
> retrieving revision 1.13
> diff -u -r1.12 -r1.13
> --- GenerationConstants.java 27 Jun 2004 15:20:23 -0000 1.12
> +++ GenerationConstants.java 7 Jul 2004 09:02:00 -0000 1.13
> @@ -55,9 +55,6 @@
>
> package org.apache.geronimo.ews.ws4j2ee.toWs;
>
> -import java.io.FileInputStream;
> -import java.io.InputStream;
> -import java.util.Properties;
>
> /**
> * <p>This interface has constants that are specific to the generators.</p>
>
> 1.6 +1 -1 ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/utils/AntExecuter.java
>
> Index: AntExecuter.java
> ===================================================================
> RCS file: /home/cvs/ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/utils/AntExecuter.java,v
> retrieving revision 1.5
> retrieving revision 1.6
> diff -u -r1.5 -r1.6
> --- AntExecuter.java 27 Jun 2004 15:20:24 -0000 1.5
> +++ AntExecuter.java 7 Jul 2004 09:02:00 -0000 1.6
> @@ -45,7 +45,7 @@
> ant.setAntfile(file.getAbsolutePath());
> ant.setDir(file.getParentFile());
> ant.execute();
> - }catch(ClassCastException e){
> + }catch(ClassNotFoundException e){
> System.out.println("Ant file will not be run programatcally as the " + "$JAVA_HOME/lib/tool.jar is not in the class path. To run the ant " + "prgramatically add that jar to classpath");
> }catch(BuildException e){
> System.out.println(e.getMessage() +
>
> 1.1 ws-axis/contrib/ews/src/org/apache/ws/security/WSS4J2EEEngine.java
>
> Index: WSS4J2EEEngine.java
> ===================================================================
> /*
> * Created on May 28, 2004
> *
> *
> */
> package org.apache.ws.security;
>
> import javax.security.auth.callback.CallbackHandler;
>
> import org.apache.axis.MessageContext;
>
> import org.apache.geronimo.ews.ws4j2ee.context.security.impl.SecurityContext4J2EEImpl;
> import org.apache.ws.axis.security.PWDCallbackHandler4J2EE;
> import org.apache.ws.axis.security.WSS4J2EEConstants;
> import org.apache.ws.security.message.token.UsernameToken;
> import org.w3c.dom.Element;
> /**
> * This class is used in <code>AllSecurityReceiver</code<> to process the secuirty
> * headers in the SOAP message. This works slightly different from the
> * WSSecurityEngine of wss4j project.
> * i.e
> * This processes the UsernameToken element in a different way.
> * The credentials available in the token are retrieved and the
> * SecurityContext4J2EE is populated using them.
> * No authentication is done at Axis. Therefore no principal
> * is created, instead this replace it with null.
> *
> * Before using the above service, the MessageContext should be set.
> *
> * @author Davanum Srinivas (dims@yahoo.com).
> * @author Werner Dittmann (Werner.Dittmann@siemens.com).
> * @author Rajith Priyanga (rpriyanga@yahoo.com)
> * @date May 28, 2004
> *
> */
> public class WSS4J2EEEngine extends WSSecurityEngine{
>
> private MessageContext msgCntxt = null;
>
> public void setMessageContext(MessageContext msgContext) throws Exception{
> if(msgContext==null){
> throw new Exception("Mssage Context is null!");
> }
> else{
> this.msgCntxt = msgContext;
> }
> }
>
> /**
> * Processes the UsernameToken element and populate the SecurityContext4J2EE prperty
> * with the credentials available in it.
> * No authentication is done here.
> * Always returns null
> */
> public WSUsernameTokenPrincipal handleUsernameToken(Element token, CallbackHandler cb) throws WSSecurityException {
>
> UsernameToken ut = new UsernameToken(token);
> try{
> this.populateSecurityContext4J2EE(ut.getName(),
> ut.getPassword().toCharArray(),
> ut.isHashed(),
> ut.getNonce(),
> ut.getCreated());
> }
> catch(Exception e){
> throw new WSSecurityException(WSSecurityException.FAILURE, "Invalid Username Token found!");
> }
>
> return null;
> }
>
> /**
> * Register a SecurityContext4J2EE object with the MessageContext as
> * WSS4J2EEConstants.SEC_CONTEXT_4J2EE property.
> * Populates the SEC_CONTEXT_4J2EE property with the security information
> * avatilable in the UsernameToken.
> * @param ut
> */
> private void populateSecurityContext4J2EE(String user, char[] pwd, boolean isDigested, String nonce, String created){
> SecurityContext4J2EEImpl sc4j2ee =
> (SecurityContext4J2EEImpl)this.msgCntxt.getProperty(WSS4J2EEConstants.SEC_CONTEXT_4J2EE);
>
> if(sc4j2ee==null){
> sc4j2ee = new SecurityContext4J2EEImpl();
> this.msgCntxt.setProperty(WSS4J2EEConstants.SEC_CONTEXT_4J2EE, sc4j2ee);
> }
>
> //Populate the SecurityContext4J2EE with the user name token data.
> sc4j2ee.setUsername(user);
> if(isDigested){
> sc4j2ee.setPasswordDigested(true);
> sc4j2ee.setNonce(nonce);
> sc4j2ee.setCreated(created);
> }
> else
> sc4j2ee.setPasswordDigested(false);
>
> sc4j2ee.setPassword(pwd);
> PWDCallbackHandler4J2EE cbh = new PWDCallbackHandler4J2EE(user, pwd);
> sc4j2ee.setPWDCallbackHandler4J2EE(cbh);
> }
>
> }
>
> 1.2 +15 -14 ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/context/security/impl/SecurityContext4J2EEImpl.java
>
> Index: SecurityContext4J2EEImpl.java
> ===================================================================
> RCS file: /home/cvs/ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/context/security/impl/SecurityContext4J2EEImpl.java,v
> retrieving revision 1.1
> retrieving revision 1.2
> diff -u -r1.1 -r1.2
> --- SecurityContext4J2EEImpl.java 14 Jun 2004 08:24:39 -0000 1.1
> +++ SecurityContext4J2EEImpl.java 7 Jul 2004 09:02:00 -0000 1.2
> @@ -1,14 +1,9 @@
> -/*
> - * Created on Apr 6, 2004
> - *
> - *
> - */
> package org.apache.geronimo.ews.ws4j2ee.context.security.impl;
>
> +import javax.security.auth.callback.CallbackHandler;
> import javax.security.cert.X509Certificate;
>
> import org.apache.geronimo.ews.ws4j2ee.context.security.SecurityContext4J2EE;
> -
> /**
> * @author Rajith Priyanga (rpriyanga@yahoo.com)
> * @date Apr 6, 2004
> @@ -27,15 +22,8 @@
> private boolean privacy = false;
> private boolean integrity = false;
> private boolean isPwdDigested= false;
> - //private MessageContext cntxt;
> + private CallbackHandler cbh;
>
> - /**
> - * This has a circular reference to the MessageContext.
> - * @param cntxt
> - */
> - /*public SecurityContext4J2EEImpl(MessageContext cntxt){
> - this.cntxt = cntxt;
> - }*/
>
> public SecurityContext4J2EEImpl(){
> @@ -192,6 +180,19 @@
> */
> public void setPassword(char[] password) {
> this.pwd = password;
> + }
> +
> +
> + /**
> + * @see org.apache.geranimo.ews.ws4j2ee.context.security.SecurityContext4J2EE#getPWDCallbackHandler4J2EE()
> + */
> + public CallbackHandler getPWDCallbackHandler4J2EE() {
> + return this.cbh;
> + }
> +
> +
> + public void setPWDCallbackHandler4J2EE(CallbackHandler callbackHandler){
> + this.cbh = callbackHandler;
> }
>
> }
>
>
--
Davanum Srinivas - http://webservices.apache.org/~dims/
Re: cvs commit: ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/context/security/impl SecurityContext4J2EEImpl.java
Posted by Davanum Srinivas <da...@gmail.com>.
Srinath,
We can fix whatever is needed to be fixed in WSS4J....Just let me know.
thanks,
dims
On 7 Jul 2004 09:02:00 -0000, hemapani@apache.org <he...@apache.org> wrote:
> hemapani 2004/07/07 02:02:00
>
> Modified: contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/toWs/wrapperWs
> SimpleRemoteInterfaceBasedWrapperClassWriter.java
> contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/context/security
> SecurityContext4J2EE.java
> contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/toWs
> GenerationConstants.java
> contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/utils
> AntExecuter.java
> contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/context/security/impl
> SecurityContext4J2EEImpl.java
> Added: contrib/ews/src/org/apache/ws/axis/security
> PWDCallbackHandler4J2EE.java WSS4J2EEConstants.java
> BasicAuth4J2EESender.java SimpleWSS4J2EESender.java
> AllSecurity4J2EEReceiver.java
> BasicAuth4J2EEReceiver.java
> SimpleWSS4J2EEReceiver.java
> CheckPoint4J2EEHandler.java
> contrib/ews/src/org/apache/ws/security WSS4J2EEEngine.java
> Removed: contrib/ews/src/org/apache/ws/axis/security
> WSS4J2EEReceiver.java
> contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/context/security
> SimpleWSS4J2EEReceiver.java WSS4J2EEEngine.java
> WSS4J2EEConstants.java CheckPoint4J2EEHandler.java
> SimpleWSS4J2EESender.java
> Log:
> add priyanga's new Handlers to support secuity
> had to keep the Handlers in the axis.security/ws.secuirty packages as
> they have default constructers
>
> Revision Changes Path
> 1.1 ws-axis/contrib/ews/src/org/apache/ws/axis/security/PWDCallbackHandler4J2EE.java
>
> Index: PWDCallbackHandler4J2EE.java
> ===================================================================
> /*
> * Created on Jun 27, 2004
> *
> *
> */
> package org.apache.ws.axis.security;
>
> import java.io.IOException;
>
> 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;
> /**
> * This is a simple PasswordCallback Handler that can be used by
> * Wrapper web service, before invoking the EJB, to authenticate
> * the client using JAAS.
> *
> * @author Rajith Priyanga (rpriyanga@yahoo.com)
> * @date Jun 27, 2004
> *
> */
> public class PWDCallbackHandler4J2EE implements CallbackHandler{
>
> String username = null;
> char[] password = null;
>
> /**
> * @see javax.security.auth.callback.CallbackHandler#handle(javax.security.auth.callback.Callback[])
> */
> public PWDCallbackHandler4J2EE(String username, char[] password){
> this.username = username;
> this.password = password;
> }
>
> public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
> boolean recognized = false;
> //Callback handler which implements both the following interfaces
> //can also be handled.
> for (int i = 0; i < callbacks.length; i++){
> if (callbacks[i] instanceof NameCallback){
> NameCallback ncb = (NameCallback) callbacks[i];
> ncb.setName(username);
> recognized = true;
> }
> if (callbacks[i] instanceof PasswordCallback){
> PasswordCallback pcb = (PasswordCallback) callbacks[i];
> pcb.setPassword(password);
> recognized = true;
> }
> if(!recognized){
> throw new UnsupportedCallbackException(callbacks[i], "Callback Type is not supported.");
> }
> }
> }
>
> }
>
> 1.1 ws-axis/contrib/ews/src/org/apache/ws/axis/security/WSS4J2EEConstants.java
>
> Index: WSS4J2EEConstants.java
> ===================================================================
> /*
> * Created on May 28, 2004
> *
> *
> */
> package org.apache.ws.axis.security;
>
> import org.apache.ws.axis.security.WSDoAllConstants;
>
> /**
> * Defines the Constants used or WS-J2EE security Mapping implementation.
> *
> * @author Rajith Priyanga (rpriyanga@yahoo.com)
> * @date May 28, 2004
> *
> */
> public class WSS4J2EEConstants extends WSDoAllConstants {
>
> /**
> * This property contains the security information required to authenticate
> * the user to the J2EE server, plus some more information. Represents
> * a SecurityContext4J2EE object.
> *
> */
> public static final String SEC_CONTEXT_4J2EE = "SEC_CONTEXT_4J2EE";
>
> public static final String AUTH_AT_AXIS = "AuthenticationAtAxis";
> }
>
> 1.1 ws-axis/contrib/ews/src/org/apache/ws/axis/security/BasicAuth4J2EESender.java
>
> Index: BasicAuth4J2EESender.java
> ===================================================================
> /*
> * Created on Jun 20, 2004
> *
> *
> */
> package org.apache.ws.axis.security;
>
> import javax.security.auth.callback.CallbackHandler;
> import javax.security.auth.callback.Callback;
>
> import org.apache.axis.AxisFault;
> import org.apache.axis.MessageContext;
> import org.apache.axis.handlers.BasicHandler;
>
> import org.apache.ws.axis.security.WSDoAllConstants;
> import org.apache.ws.security.WSPasswordCallback;
>
> /**
> * This class can be used as a client side Axis handler which can insert
> * BasicHTTPAuthentication data to the request. This class uses the
> * PasswordCallbackHandler specified by the client in the DD or Call object,
> * to obtain the credentials of the client to add to the HTTP header.
> * (i.e. <code>passwordCallbackClass</code> property.)
> *
> * @author Rajith Priyanga (rpriyanga@yahoo.com)
> * @date Jun 20, 2004
> *
> */
> public class BasicAuth4J2EESender extends BasicHandler {
>
> /**
> * @see org.apache.axis.Handler#invoke(org.apache.axis.MessageContext)
> */
> public void invoke(MessageContext cntxt) throws AxisFault {
> String username = cntxt.getUsername();
> try{
> cntxt.setPassword(fetchPWD(username, cntxt));
> }
> catch(Exception e){
> throw AxisFault.makeFault(e);
> }
> }
>
> /**
> * Fetches the password to be sent, using the given Password Callback
> * class.
> * @param username
> * @param cntxt
> * @return
> * @throws Exception
> */
> private String fetchPWD(String username, MessageContext cntxt) throws Exception{
> if(username==null){
> throw new Exception("No username provided!");
> }
>
> WSPasswordCallback pwcb = new WSPasswordCallback(username, WSPasswordCallback.USERNAME_TOKEN);
> Callback[] cb = new Callback[1];
> cb[0] = pwcb;
>
> CallbackHandler cbh = (CallbackHandler)cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_REF);
> if(cbh == null){
> String cbhClass = (String)cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_CLASS);
> cbh = (CallbackHandler)Class.forName(cbhClass).newInstance();
> }
> if(cbh == null){
> throw new Exception("No PasswordCallbackHandler class found.");
> }
> else{
> cbh.handle(cb);
> }
> String pwd = ((WSPasswordCallback)(cb[0])).getPassword();
> if(pwd==null)
> throw new Exception("No password provided!");
> return pwd;
> }
>
> }
>
> 1.1 ws-axis/contrib/ews/src/org/apache/ws/axis/security/SimpleWSS4J2EESender.java
>
> Index: SimpleWSS4J2EESender.java
> ===================================================================
> /*
> * Created on May 29, 2004
> *
> *
> */
> package org.apache.ws.axis.security;
>
> import java.text.SimpleDateFormat;
> import java.util.Calendar;
> import java.util.Random;
> import java.util.TimeZone;
>
> import javax.security.auth.callback.Callback;
> import javax.security.auth.callback.CallbackHandler;
> import javax.xml.soap.Name;
> import javax.xml.soap.SOAPElement;
> import javax.xml.soap.SOAPFactory;
> import javax.xml.soap.SOAPHeader;
> import javax.xml.soap.SOAPHeaderElement;
>
> import org.apache.axis.AxisFault;
> import org.apache.axis.Message;
> import org.apache.axis.MessageContext;
> import org.apache.axis.handlers.BasicHandler;
> import org.apache.ws.axis.security.WSDoAllConstants;
> import org.apache.ws.security.WSConstants;
> import org.apache.ws.security.WSPasswordCallback;
> import org.apache.ws.security.message.token.UsernameToken;
>
> /**
> *
> * This is a server side Axis handler that can be used to retrieve the
> * credentials available in the UsernameToken element. This will
> * retrieve the credentials and populate the SecurityContext4J2EE
> * property with them.
> *
> * This is a very simple handler that can handle only UsernameToken
> * elements. So that this can be used for testing peroposes and
> * other simple works.
> *
> * @author Rajith Priyanga (rpriyanga@yahoo.com)
> * @date May 29, 2004
> *
> */
> public class SimpleWSS4J2EESender extends BasicHandler {
>
> MessageContext cntxt = null;
>
> /**
> * Adds the username-password information to the SOAP header
> * within the UsernameToken, as requested by the user.
> * @see org.apache.axis.Handler#invoke(org.apache.axis.MessageContext)
> */
> public void invoke(MessageContext msgCntxt) throws AxisFault {
> this.cntxt = msgCntxt;
> String action = (String)cntxt.getProperty(WSDoAllConstants.ACTION);
> if(action==null)
> return;
>
> String[] actions = action.split(" ");
>
> boolean utAction = false;
> //Check whether UsernameToken action is requested. Otherwise no more processing.
> for(int i=0; i<actions.length; i++){
> utAction = actions[i].equalsIgnoreCase(WSDoAllConstants.USERNAME_TOKEN);
> if(utAction)
> break;
> }
> if(!utAction)
> return;
> //Get the username from the msg context.
> String username = this.cntxt.getUsername();
>
> //If the username property is not in the message context,
> if(username==null)
> username = (String)cntxt.getProperty(WSDoAllConstants.USER);
> if(username==null)
> throw AxisFault.makeFault(new Exception("No username specified!"));
>
> //Get the password type. If it is not defined, the deault is PasswardText.
> String pwdType = (String)cntxt.getProperty(WSDoAllConstants.PASSWORD_TYPE);
> if(pwdType==null)
> pwdType = WSConstants.PASSWORD_TEXT;
> addUsernameToken(username, pwdType);
> }
>
> /**
> * Creates and adds the Security-UsernameToken to the SOAP message.
> * @param username
> * @param passwordType
> * @throws AxisFault
> */
> private void addUsernameToken(String username, String passwordType) throws AxisFault{
> Message m = cntxt.getCurrentMessage();
> try{
> SOAPHeader h = m.getSOAPPart().getEnvelope().getHeader();
>
> SOAPFactory sf = SOAPFactory.newInstance();
>
> m.getSOAPEnvelope().addNamespaceDeclaration(WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS);
>
> Name secN = sf.createName(WSConstants.WSSE_LN, WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS);
> SOAPHeaderElement secElem = h.addHeaderElement(secN);
>
> //Add the Username Token.
> SOAPElement utElem = sf.createElement(WSConstants.WSSE_PREFIX+ ":" + WSConstants.USERNAME_TOKEN_LN);
> secElem.addChildElement(utElem);
>
> //Add the Username element.
> SOAPElement unElem = sf.createElement(WSConstants.WSSE_PREFIX+ ":" + WSConstants.USERNAME_LN);
> unElem.addTextNode(username);
> utElem.addChildElement(unElem);
>
> //Create the Password element.
> SOAPElement pwdElem = sf.createElement(WSConstants.WSSE_PREFIX+ ":" + WSConstants.PASSWORD_LN);
>
> Name pwdType = sf.createName(WSConstants.PASSWORD_TYPE_ATTR, WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS);
> //Add password element.
> if(passwordType.equalsIgnoreCase(WSConstants.PASSWORD_TEXT)){
> pwdElem.addAttribute(pwdType,WSConstants.PASSWORD_TEXT);
> pwdElem.addTextNode(fetchPWD(username));
> utElem.addChildElement(pwdElem);
> }
> else if(passwordType.equalsIgnoreCase(WSConstants.PASSWORD_DIGEST)){
> m.getSOAPEnvelope().addNamespaceDeclaration(WSConstants.WSU_PREFIX, WSConstants.WSU_NS);
> pwdElem.addAttribute(pwdType,WSConstants.PASSWORD_DIGEST);
>
> String nonce = getNonce();
> String created = getCreated();
> String digest = UsernameToken.doPasswordDigest(nonce, created, fetchPWD(username));
>
> SOAPElement nonceElem = sf.createElement(WSConstants.WSSE_PREFIX+":"+WSConstants.NONCE_LN);
> SOAPElement createdElem = sf.createElement(WSConstants.WSU_PREFIX+":"+WSConstants.CREATED_LN);
>
> nonceElem.addTextNode(nonce);
> createdElem.addTextNode(created);
> pwdElem.addTextNode(digest);
>
> utElem.addChildElement(pwdElem);
> utElem.addChildElement(nonceElem);
> utElem.addChildElement(createdElem);
> }
> else{
> throw AxisFault.makeFault(new Exception("Unsupported PasswordType"));
> }
> }
> catch(Exception ex){
> throw AxisFault.makeFault(ex);
> }
> }
>
> /*
> * Generates nonce.
> */
> private String getNonce(){
> Random rand = new Random();
> byte[] nonce = new byte[16];
> rand.nextBytes(nonce);
> String nonceStr = org.apache.xml.security.utils.Base64.encode(nonce);
> return nonceStr;
> }
>
> /**
> * Generates created as per specification.
> * @return
> */
> private String getCreated(){
> SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
> sd.setTimeZone(TimeZone.getTimeZone("GMT"));
> Calendar now = Calendar.getInstance();
> return sd.format(now.getTime());
> }
>
> /**
> * Fetch the password of the user from the specified PasswordCallbak class.
> * @param username
> * @return
> * @throws Exception
> */
> private String fetchPWD(String username) throws Exception{
> WSPasswordCallback pwcb = new WSPasswordCallback(username, WSPasswordCallback.USERNAME_TOKEN);
> Callback[] cb = new Callback[1];
> cb[0] = pwcb;
>
> CallbackHandler cbh = (CallbackHandler)this.cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_REF);
> if(cbh == null){
> String cbhClass = (String)this.cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_CLASS);
> cbh = (CallbackHandler)Class.forName(cbhClass).newInstance();
> }
> if(cbh == null){
> throw new Exception("No PasswordCallbackHandler class found.");
> }
> else{
> cbh.handle(cb);
> }
> String pwd = ((WSPasswordCallback)(cb[0])).getPassword();
> if(pwd==null)
> throw new Exception("Password is not provided! Can't create UsernameToken.");
> return pwd;
> }
>
> }
>
> 1.1 ws-axis/contrib/ews/src/org/apache/ws/axis/security/AllSecurity4J2EEReceiver.java
>
> Index: AllSecurity4J2EEReceiver.java
> ===================================================================
> /*
> * Created on Jun 20, 2004
> *
> *
> */
> package org.apache.ws.axis.security;
>
> import java.io.ByteArrayOutputStream;
> import java.math.BigInteger;
> import java.security.cert.X509Certificate;
> import java.text.SimpleDateFormat;
> import java.util.Calendar;
> import java.util.Hashtable;
> import java.util.Iterator;
> import java.util.TimeZone;
> import java.util.Vector;
>
> import javax.security.auth.callback.CallbackHandler;
> import javax.xml.soap.SOAPHeader;
> import javax.xml.soap.SOAPHeaderElement;
>
> import org.apache.axis.AxisFault;
> import org.apache.axis.Message;
> import org.apache.axis.MessageContext;
> import org.apache.axis.SOAPPart;
> import org.apache.commons.logging.Log;
> import org.apache.commons.logging.LogFactory;
> import org.apache.ws.axis.security.WSDoAllConstants;
> import org.apache.ws.axis.security.WSDoAllReceiver;
> import org.apache.ws.axis.security.WSDoAllReceiverResult;
> import org.apache.ws.axis.security.util.AxisUtil;
> import org.apache.ws.security.SOAPConstants;
> import org.apache.ws.security.WSConstants;
> import org.apache.ws.security.WSS4J2EEEngine;
> import org.apache.ws.security.WSSecurityEngineResult;
> import org.apache.ws.security.WSSecurityException;
> import org.apache.ws.security.components.crypto.Crypto;
> import org.apache.ws.security.components.crypto.CryptoFactory;
> import org.apache.ws.security.message.token.Timestamp;
> import org.apache.ws.security.util.WSSecurityUtil;
> import org.apache.xml.security.utils.XMLUtils;
> import org.w3c.dom.Document;
>
> /**
> * This class can be used to process any kind of WSSecurity token,
> * to retrieve the credentials required to Authenticate the user to
> * J2EE server and to populate the SecurityContext4J2EE property
> * with them.
> *
> * This class is written by modifying the some parts of
> * the WSDoAllReceiver class availble in WSS4J project. Modification
> * done to it should also be appeared here. This is a temporary solution
> * until that class come to a stable state.
> *
> * This uses WSS4J2EEEngine instead of WSSecurityEngine. Therefore the
> * authentication is only taken place at J2EE server, not at Axis.
> *
> * @author Rajith Priyanga (rpriyanga@yahoo.com)
> * @author Werner Dittmann (Werner.Dittmann@siemens.com)
> * @date Jun 20, 2004
> *
> */
> public class AllSecurity4J2EEReceiver extends WSDoAllReceiver{
>
> static final WSS4J2EEEngine sec4j2eeEngine = new WSS4J2EEEngine();
>
> static Log log = LogFactory.getLog(WSDoAllReceiver.class.getName());
>
> private boolean doDebug = true;
>
> private static Hashtable cryptos = new Hashtable(5);
>
> private MessageContext msgContext = null;
>
> Crypto sigCrypto = null;
> String sigPropFile = null;
>
> Crypto decCrypto = null;
> String decPropFile = null;
>
> protected int timeToLive = 300; // Timestamp: time in seconds the receiver accepts between creation and reception
>
> /**
> * Axis calls invoke to handle a message.
> * <p/>
> *
> * @param mc message context.
> * @throws AxisFault
> */
> public void invoke(MessageContext mc) throws AxisFault {
>
> /////////////////////////////////////////
> try{
> sec4j2eeEngine.setMessageContext(mc);
> }
> catch(Exception ex){
> throw AxisFault.makeFault(ex);
> }
> ////////////////////////////////////////
>
> if (doDebug) {
> log.debug("WSDoAllReceiver: enter invoke() with msg type: "
> + mc.getCurrentMessage().getMessageType());
> }
> msgContext = mc;
>
> Vector actions = new Vector();
> String action = null;
> if ((action = (String) getOption(WSDoAllConstants.ACTION)) == null) {
> action = (String) msgContext.getProperty(WSDoAllConstants.ACTION);
> }
> if (action == null) {
> throw new AxisFault("WSDoAllReceiver: No action defined");
> }
> int doAction = AxisUtil.decodeAction(action, actions);
>
> String actor = (String) getOption(WSDoAllConstants.ACTOR);
>
> Message sm = msgContext.getCurrentMessage();
> Document doc = null;
> try {
> doc = sm.getSOAPEnvelope().getAsDocument();
> if (doDebug) {
> log.debug("Received SOAP request: ");
> log.debug(org.apache.axis.utils.XMLUtils.PrettyDocumentToString(doc));
> }
> } catch (Exception ex) {
> throw new AxisFault(
> "WSDoAllReceiver: cannot convert into document",
> ex);
> }
> /*
> * Check if it's a response and if its a fault. Don't
> * process faults.
> */
> String msgType = sm.getMessageType();
> if (msgType != null && msgType.equals(Message.RESPONSE)) {
> SOAPConstants soapConstants =
> WSSecurityUtil.getSOAPConstants(doc.getDocumentElement());
> if (WSSecurityUtil
> .findElement(
> doc.getDocumentElement(),
> "Fault",
> soapConstants.getEnvelopeURI())
> != null) {
> return;
> }
> }
>
> /*
> * To check a UsernameToken or to decrypt an encrypted message we need
> * a password.
> */
> CallbackHandler cbHandler = null;
> if ((doAction & (WSConstants.ENCR | WSConstants.UT)) != 0) {
> cbHandler = getPasswordCB();
> }
>
> /*
> * Get and check the Signature specific parameters first because they
> * may be used for encryption too.
> */
>
> if ((doAction & WSConstants.SIGN) == WSConstants.SIGN) {
> decodeSignatureParameter();
> }
>
> if ((doAction & WSConstants.ENCR) == WSConstants.ENCR) {
> decodeDecryptionParameter();
> }
>
> Vector wsResult = null;
> try {
> wsResult =
> sec4j2eeEngine.processSecurityHeader(
> doc,
> actor,
> cbHandler,
> sigCrypto,
> decCrypto);
> } catch (WSSecurityException ex) {
> ex.printStackTrace();
> throw new AxisFault(
> "WSDoAllReceiver: security processing failed",
> ex);
> }
> if (wsResult == null) { // no security header found
> if (doAction == WSConstants.NO_SECURITY) {
> return;
> } else {
> throw new AxisFault("WSDoAllReceiver: Request does not contain required Security header");
> }
> }
>
> /*
> * If we had some security processing, get the original
> * SOAP part of Axis' message and replace it with new SOAP
> * part. This new part may contain decrypted elements.
> */
> SOAPPart sPart = (org.apache.axis.SOAPPart) sm.getSOAPPart();
>
> ByteArrayOutputStream os = new ByteArrayOutputStream();
> XMLUtils.outputDOM(doc, os, true);
> sPart.setCurrentMessage(os.toByteArray(), SOAPPart.FORM_BYTES);
> if (doDebug) {
> log.debug("Processed received SOAP request");
> log.debug(org.apache.axis.utils.XMLUtils.PrettyDocumentToString(doc));
> }
>
> /*
> * After setting the new current message, probably modified because
> * of decryption, we need to locate the security header. That is,
> * we force Axis (with getSOAPEnvelope()) to parse the string, build
> * the new header. Then we examine, look up the security header
> * and set the header as processed.
> *
> * Please note: find all header elements that contain the same
> * actor that was given to processSecurityHeader(). Then
> * check if there is a security header with this actor.
> */
>
> SOAPHeader sHeader = null;
> try {
> sHeader = sm.getSOAPEnvelope().getHeader();
> } catch (Exception ex) {
> throw new AxisFault("WSDoAllReceiver: cannot get SOAP header after security processing", ex);
> }
>
> Iterator headers = sHeader.examineHeaderElements(actor);
>
> SOAPHeaderElement headerElement = null;
> while (headers.hasNext()) {
> SOAPHeaderElement hE = (SOAPHeaderElement) headers.next();
> if (hE.getLocalName().equals(WSConstants.WSSE_LN)
> && hE.getNamespaceURI().equals(WSConstants.WSSE_NS)) {
> headerElement = hE;
> break;
> }
> }
> ((org.apache.axis.message.SOAPHeaderElement) headerElement).setProcessed(true);
>
> /*
> * Now we can check the certificate used to sign the message.
> * In the following implementation the certificate is only trusted
> * if either it itself or the certificate of the issuer is installed
> * in the keystore.
> *
> * Note: the method verifyTrust(X509Certificate) allows custom
> * implementations with other validation algorithms for subclasses.
> */
>
> // Extract the signature action result from the action vector
> WSSecurityEngineResult actionResult = WSSecurityUtil.fetchActionResult(wsResult, WSConstants.SIGN);
>
> if (actionResult != null) {
> X509Certificate returnCert = actionResult.getCertificate();
>
> if (returnCert != null) {
> if (!verifyTrust(returnCert)) {
> throw new AxisFault("WSDoAllReceiver: The certificate used for the signature is not trusted");
> }
> }
> }
>
> /*
> * Perform further checks on the timestamp that was transmitted in the header.
> * In the following implementation the timestamp is valid if it was
> * created after (now-ttl), where ttl is set on server side, not by the client.
> *
> * Note: the method verifyTimestamp(Timestamp) allows custom
> * implementations with other validation algorithms for subclasses.
> */
>
> // Extract the timestamp action result from the action vector
> actionResult = WSSecurityUtil.fetchActionResult(wsResult, WSConstants.TS);
>
> if (actionResult != null) {
> Timestamp timestamp = actionResult.getTimestamp();
>
> if (timestamp != null) {
> String ttl = null;
> if ((ttl =
> (String) getOption(WSDoAllConstants.TTL_TIMESTAMP))
> == null) {
> ttl =
> (String) msgContext.getProperty(
> WSDoAllConstants.TTL_TIMESTAMP);
> }
> int ttl_i = 0;
> if (ttl != null) {
> try {
> ttl_i = Integer.parseInt(ttl);
> } catch (NumberFormatException e) {
> ttl_i = timeToLive;
> }
> }
> if (ttl_i <= 0) {
> ttl_i = timeToLive;
> }
>
> if (!verifyTimestamp(timestamp, timeToLive)) {
> throw new AxisFault("WSDoAllReceiver: The timestamp could not be validated");
> }
> }
> }
>
> /*
> * now check the security actions: do they match, in right order?
> */
> int resultActions = wsResult.size();
> int size = actions.size();
> if (size != resultActions) {
> throw new AxisFault("WSDoAllReceiver: security processing failed (actions number mismatch)");
> }
> for (int i = 0; i < size; i++) {
> if (((Integer) actions.get(i)).intValue()
> != ((WSSecurityEngineResult)wsResult.get(i)).getAction()) {
> throw new AxisFault("WSDoAllReceiver: security processing failed (actions mismatch)");
> }
> }
>
> /*
> * All ok up to this point. Now construct and setup the
> * security result structure. The service may fetch this
> * and check it.
> */
> Vector results = null;
> if ((results = (Vector) mc.getProperty(WSDoAllConstants.RECV_RESULTS))
> == null) {
> results = new Vector();
> mc.setProperty(WSDoAllConstants.RECV_RESULTS, results);
> }
> WSDoAllReceiverResult rResult =
> new WSDoAllReceiverResult(
> actor,
> wsResult);
> results.add(0, rResult);
> if (doDebug) {
> log.debug("WSDoAllReceiver: exit invoke()");
> }
> }
>
> /**
> * Hook to allow subclasses to load their Signature Crypto however they see fit.
> */
> protected Crypto loadSignatureCrypto() throws AxisFault {
> Crypto crypto = null;
> if ((sigPropFile = (String) getOption(WSDoAllConstants.SIG_PROP_FILE))
> == null) {
> sigPropFile =
> (String) msgContext.getProperty(WSDoAllConstants.SIG_PROP_FILE);
> }
> if (sigPropFile != null) {
> if ((crypto = (Crypto) cryptos.get(sigPropFile)) == null) {
> crypto = CryptoFactory.getInstance(sigPropFile);
> cryptos.put(sigPropFile, crypto);
> }
> } else {
> throw new AxisFault("WSDoAllReceiver: Signature: no crypto property file");
> }
> return crypto;
> }
>
> /**
> * Hook to allow subclasses to load their Decryption Crypto however they see fit.
> */
> protected Crypto loadDecryptionCrypto() throws AxisFault {
> Crypto crypto = null;
> if ((decPropFile = (String) getOption(WSDoAllConstants.DEC_PROP_FILE))
> == null) {
> decPropFile =
> (String) msgContext.getProperty(WSDoAllConstants.DEC_PROP_FILE);
> }
> if (decPropFile != null) {
> if ((crypto = (Crypto) cryptos.get(decPropFile)) == null) {
> crypto = CryptoFactory.getInstance(decPropFile);
> cryptos.put(decPropFile, crypto);
> }
> } else if ((crypto = sigCrypto) == null) {
> throw new AxisFault("WSDoAllReceiver: Encryption: no crypto property file");
> }
> return crypto;
> }
>
> private void decodeSignatureParameter() throws AxisFault {
> sigCrypto = loadSignatureCrypto();
> /* There are currently no other signature parameters that need to be handled
> * here, but we call the load crypto hook rather than just changing the visibility
> * of this method to maintain parity with WSDoAllSender.
> */
> }
>
> /*
> * Set and check the decryption specific parameters, if necessary
> * take over signatur crypto instance.
> */
>
> private void decodeDecryptionParameter() throws AxisFault {
> decCrypto = loadDecryptionCrypto();
> /* There are currently no other decryption parameters that need to be handled
> * here, but we call the load crypto hook rather than just changing the visibility
> * of this method to maintain parity with WSDoAllSender.
> */
> }
>
> /**
> * Get the password callback class and get an instance
> * <p/>
> */
> private CallbackHandler getPasswordCB() throws AxisFault {
>
> String callback = null;
> CallbackHandler cbHandler = null;
> if ((callback = (String) getOption(WSDoAllConstants.PW_CALLBACK_CLASS))
> == null) {
> callback =
> (String) msgContext.getProperty(
> WSDoAllConstants.PW_CALLBACK_CLASS);
> }
> if (callback != null) {
> Class cbClass = null;
> try {
> cbClass = java.lang.Class.forName(callback);
> } catch (ClassNotFoundException e) {
> throw new AxisFault(
> "WSDoAllReceiver: cannot load password callback class: "
> + callback,
> e);
> }
> try {
> cbHandler = (CallbackHandler) cbClass.newInstance();
> } catch (java.lang.Exception e) {
> throw new AxisFault(
> "WSDoAllReceiver: cannot create instance of password callback: "
> + callback,
> e);
> }
> } else {
> cbHandler =
> (CallbackHandler) msgContext.getProperty(
> WSDoAllConstants.PW_CALLBACK_REF);
> if (cbHandler == null) {
> throw new AxisFault("WSDoAllReceiver: no reference in callback property");
> }
> }
> return cbHandler;
> }
>
> /**
> * Evaluate whether a given certificate should be trusted.
> * Hook to allow subclasses to implement custom validation methods however they see fit.
> * <p/>
> * Policy used in this implementation:
> * 1. Search the keystore for the transmitted certificate
> * 2. Search the keystore for a connection to the transmitted certificate
> * (that is, search for certificate(s) of the issuer of the transmitted certificate
> * 3. Verify the trust path for those certificates found because the search for the issuer might be fooled by a phony DN (String!)
> *
> * @param cert the certificate that should be validated against the keystore
> * @return true if the certificate is trusted, false if not (AxisFault is thrown for exceptions during CertPathValidation)
> * @throws AxisFault
> */
> private boolean verifyTrust(X509Certificate cert) throws AxisFault {
>
> // If no certificate was transmitted, do not trust the signature
> if (cert == null) {
> return false;
> }
>
> String[] aliases = null;
> String alias = null;
> X509Certificate[] certs;
>
> String subjectString = cert.getSubjectDN().getName();
> String issuerString = cert.getIssuerDN().getName();
> BigInteger issuerSerial = cert.getSerialNumber();
>
> if (doDebug) {
> log.debug("WSDoAllReceiver: Transmitted certificate has subject " + subjectString);
> log.debug("WSDoAllReceiver: Transmitted certificate has issuer " + issuerString + " (serial " + issuerSerial + ")");
> }
>
> // FIRST step
> // Search the keystore for the transmitted certificate
>
> // Search the keystore for the alias of the transmitted certificate
> try {
> alias = sigCrypto.getAliasForX509Cert(issuerString, issuerSerial);
> } catch (WSSecurityException ex) {
> throw new AxisFault("WSDoAllReceiver: Could not get alias for certificate with " + subjectString, ex);
> }
>
> if (alias != null) {
> // Retrieve the certificate for the alias from the keystore
> try {
> certs = sigCrypto.getCertificates(alias);
> } catch (WSSecurityException ex) {
> throw new AxisFault("WSDoAllReceiver: Could not get certificates for alias " + alias, ex);
> }
>
> // If certificates have been found, the certificates must be compared
> // to ensure againgst phony DNs (compare encoded form including signature)
> if (certs != null && certs.length > 0 && cert.equals(certs[0])) {
> if (doDebug) {
> log.debug("Direct trust for certificate with " + subjectString);
> }
> return true;
> }
> } else {
> if (doDebug) {
> log.debug("No alias found for subject from issuer with " + issuerString + " (serial " + issuerSerial + ")");
> }
> }
>
> // SECOND step
> // Search for the issuer of the transmitted certificate in the keystore
>
> // Search the keystore for the alias of the transmitted certificates issuer
> try {
> aliases = sigCrypto.getAliasesForDN(issuerString);
> } catch (WSSecurityException ex) {
> throw new AxisFault("WSDoAllReceiver: Could not get alias for certificate with " + issuerString, ex);
> }
>
> // If the alias has not been found, the issuer is not in the keystore
> // As a direct result, do not trust the transmitted certificate
> if (aliases == null || aliases.length < 1) {
> if (doDebug) {
> log.debug("No aliases found in keystore for issuer " + issuerString + " of certificate for " + subjectString);
> }
> return false;
> }
>
> // THIRD step
> // Check the certificate trust path for every alias of the issuer found in the keystore
> for (int i = 0; i < aliases.length; i++) {
> alias = aliases[i];
>
> if (doDebug) {
> log.debug("Preparing to validate certificate path with alias " + alias + " for issuer " + issuerString);
> }
>
> // Retrieve the certificate(s) for the alias from the keystore
> try {
> certs = sigCrypto.getCertificates(alias);
> } catch (WSSecurityException ex) {
> throw new AxisFault("WSDoAllReceiver: Could not get certificates for alias " + alias, ex);
> }
>
> // If no certificates have been found, there has to be an error:
> // The keystore can find an alias but no certificate(s)
> if (certs == null | certs.length < 1) {
> throw new AxisFault("WSDoAllReceiver: Could not get certificates for alias " + alias);
> }
>
> // Form a certificate chain from the transmitted certificate
> // and the certificate(s) of the issuer from the keystore
>
> // First, create new array
> X509Certificate[] x509certs = new X509Certificate[certs.length + 1];
>
> /* The following conversion into provider specific format seems not to be necessary
> // Create new certificate, possibly provider-specific
> try {
> cert = sigCrypto.loadCertificate(new ByteArrayInputStream(cert.getEncoded()));
> } catch (CertificateEncodingException ex) {
> throw new AxisFault("WSDoAllReceiver: Combination of subject and issuers certificates failed", ex);
> } catch (WSSecurityException ex) {
> throw new AxisFault("WSDoAllReceiver: Combination of subject and issuers certificates failed", ex);
> }
> */
>
> // Then add the first certificate ...
> x509certs[0] = cert;
>
> // ... and the other certificates
> for (int j=0; j < certs.length; j++) {
> cert = certs[i];
>
> /* The following conversion into provider specific format seems not to be necessary
> // Create new certificate, possibly provider-specific
> try {
> cert = sigCrypto.loadCertificate(new ByteArrayInputStream(cert.getEncoded()));
> } catch (CertificateEncodingException ex) {
> throw new AxisFault("WSDoAllReceiver: Combination of subject and issuers certificates failed", ex);
> } catch (WSSecurityException ex) {
> throw new AxisFault("WSDoAllReceiver: Combination of subject and issuers certificates failed", ex);
> }
> */
>
> x509certs[certs.length + j] = cert;
> }
> certs = x509certs;
>
> // Use the validation method from the crypto to check whether the subjects certificate was really signed by the issuer stated in the certificate
> try {
> if (sigCrypto.validateCertPath(certs)) {
> if (doDebug) {
> log.debug("WSDoAllReceiver: Certificate path has been verified for certificate with subject " + subjectString);
> }
> return true;
> }
> } catch (WSSecurityException ex) {
> throw new AxisFault("WSDoAllReceiver: Certificate path verification failed for certificate with subject " + subjectString, ex);
> }
> }
>
> log.debug("WSDoAllReceiver: Certificate path could not be verified for certificate with subject " + subjectString);
> return false;
> }
>
> /**
> * Evaluate whether a timestamp is considered valid on receiverside.
> * Hook to allow subclasses to implement custom validation methods however they see fit.
> * <p/>
> * Policy used in this implementation:
> * 1. The receiver can set its own time to live (besides from that set on sender side)
> * 2. If the message was created before (now-ttl) the message is rejected
> *
> * @param timestamp the timestamp that is validated
> * @param timeToLive the limit on receiverside, the timestamp is validated against
> * @return true if the timestamp is before (now-timeToLive), false otherwise
> * @throws AxisFault
> */
> protected boolean verifyTimestamp(Timestamp timestamp, int timeToLive) throws AxisFault {
>
> // Calculate the time that is allowed for the message to travel
> Calendar validCreation = Calendar.getInstance();
> long currentTime = validCreation.getTimeInMillis();
> currentTime -= timeToLive * 1000;
> validCreation.setTimeInMillis(currentTime);
>
> if (doDebug) {
> log.debug("Preparing to verify the timestamp");
> SimpleDateFormat zulu = new SimpleDateFormat(
> "yyyy-MM-dd'T'HH:mm:ss'Z'");
> zulu.setTimeZone(TimeZone.getTimeZone("GMT"));
> log.debug("Validation of Timestamp: Current time is "
> + zulu.format(Calendar.getInstance().getTime()));
> log.debug("Validation of Timestamp: Valid creation is "
> + zulu.format(validCreation.getTime()));
> log.debug("Validation of Timestamp: Timestamp created is "
> + zulu.format(timestamp.getCreated().getTime()));
> }
> // Validate the time it took the message to travel
> // if (timestamp.getCreated().before(validCreation) ||
> // !timestamp.getCreated().equals(validCreation)) {
> if (!timestamp.getCreated().after(validCreation)) {
> if (doDebug) {
> log.debug("Validation of Timestamp: The message was created too long ago");
> }
> return false;
> }
>
> log.debug("Validation of Timestamp: Everything is ok");
> return true;
> }
>
> }
>
> 1.1 ws-axis/contrib/ews/src/org/apache/ws/axis/security/BasicAuth4J2EEReceiver.java
>
> Index: BasicAuth4J2EEReceiver.java
> ===================================================================
> /*
> * Created on Jun 20, 2004
> *
> *
> */
> package org.apache.ws.axis.security;
>
> import javax.security.auth.callback.Callback;
> import javax.security.auth.callback.CallbackHandler;
>
> import org.apache.axis.AxisFault;
> import org.apache.axis.MessageContext;
> import org.apache.axis.handlers.BasicHandler;
> import org.apache.geronimo.ews.ws4j2ee.context.security.impl.SecurityContext4J2EEImpl;
> import org.apache.ws.axis.security.WSDoAllConstants;
> import org.apache.ws.security.WSPasswordCallback;
>
> /**
> * If the client is using BasicHTTP Authentication, this class can be used
> * as a server side Axis handler, which retreives the credentials available in
> * the HTTP header and populate the SecurityContext4J2EE property.
> *
> * Only if the <code>WSS4J2EEConstants.AUTH_AT_AXIS</code> property is set to true,
> * this does the authentication at the Axis. For that at the DD the <code>passwordCallbackClass</code>
> * should be available.
> *
> * @author Rajith Priyanga
> * @date Jun 20, 2004
> *
> */
> public class BasicAuth4J2EEReceiver extends BasicHandler {
>
> private boolean doAuthentication = false;
> /**
> * @see org.apache.axis.Handler#invoke(org.apache.axis.MessageContext)
> */
> public void invoke(MessageContext cntxt) throws AxisFault {
> doAuthentication = false;
> String username = cntxt.getUsername();
> String password = cntxt.getPassword();
> if(username==null|| password==null){
> throw AxisFault.makeFault(new Exception("null values for username or/and password."));
> }
>
> //Decides whether to do authentication at Axis or not.
> if(cntxt.containsProperty(WSS4J2EEConstants.AUTH_AT_AXIS)){
> String check = (String)cntxt.getProperty(WSS4J2EEConstants.AUTH_AT_AXIS);
> if(check!=null && check.equalsIgnoreCase("true"))
> this.doAuthentication = true;
> }
>
> if(this.doAuthentication){
> try{
> this.veryfyPWD(username, password, cntxt);
> }
> catch(Exception e){
> throw AxisFault.makeFault(e);
> }
> }
>
> populateSecurityContext4J2EE(username, password, cntxt);
> }
>
> /**
> * Populates the SecurityContext4J2EE property with the given credentials.
> * Also this adds a PWDCallbackHandler4J2EE to the SecurityContext4J2EE.
> * @param username
> * @param password
> * @param cntxt
> */
> private void populateSecurityContext4J2EE(String username, String password, MessageContext cntxt){
> SecurityContext4J2EEImpl sc4j2ee =
> (SecurityContext4J2EEImpl)cntxt.getProperty(WSS4J2EEConstants.SEC_CONTEXT_4J2EE);
>
> if(sc4j2ee==null){
> sc4j2ee = new SecurityContext4J2EEImpl();
> cntxt.setProperty(WSS4J2EEConstants.SEC_CONTEXT_4J2EE, sc4j2ee);
> }
>
> //Populate the SecurityContext4J2EE with the auth data.
> sc4j2ee.setUsername(username);
> sc4j2ee.setPassword(password.toCharArray());
> sc4j2ee.setPasswordDigested(false);
>
> PWDCallbackHandler4J2EE pwdcbh = new PWDCallbackHandler4J2EE(username, password.toCharArray());
> sc4j2ee.setPWDCallbackHandler4J2EE(pwdcbh);
> }
>
> private boolean veryfyPWD(String username, String password, MessageContext cntxt) throws Exception{
> if(password.equals(this.fetchActualPWD(username, cntxt))){
> return true;
> }
> else{
> return false;
> }
> }
>
> private String fetchActualPWD(String username, MessageContext cntxt) throws Exception{
> WSPasswordCallback pwcb = new WSPasswordCallback(username, WSPasswordCallback.USERNAME_TOKEN);
> Callback[] cb = new Callback[1];
>
> cb[0] = pwcb;
>
> CallbackHandler cbh = (CallbackHandler)cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_REF);
>
> if(cbh == null){
> String cbhClass = (String)cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_CLASS);
> cbh = (CallbackHandler)Class.forName(cbhClass).newInstance();
> }
>
> if(cbh==null){
> throw new Exception("PasswordCallbackHandler not found!");
> }
>
> cbh.handle(cb);
> String pwd = ((WSPasswordCallback)(cb[0])).getPassword();
>
> if(pwd==null)
> throw new Exception("Password is not provided.");
>
> return pwd;
>
> }
>
> }
>
> 1.1 ws-axis/contrib/ews/src/org/apache/ws/axis/security/SimpleWSS4J2EEReceiver.java
>
> Index: SimpleWSS4J2EEReceiver.java
> ===================================================================
> /*
> * Created on May 29, 2004
> *
> *
> */
> package org.apache.ws.axis.security;
>
> import java.util.Iterator;
>
> import javax.security.auth.callback.Callback;
> import javax.security.auth.callback.CallbackHandler;
> import javax.xml.soap.Name;
> import javax.xml.soap.SOAPElement;
> import javax.xml.soap.SOAPFactory;
> import javax.xml.soap.SOAPHeader;
> import javax.xml.soap.SOAPHeaderElement;
>
> import org.apache.axis.AxisFault;
> import org.apache.axis.Message;
> import org.apache.axis.MessageContext;
> import org.apache.axis.handlers.BasicHandler;
> import org.apache.geronimo.ews.ws4j2ee.context.security.impl.SecurityContext4J2EEImpl;
> import org.apache.ws.axis.security.WSDoAllConstants;
> import org.apache.ws.security.WSConstants;
> import org.apache.ws.security.WSPasswordCallback;
> import org.apache.ws.security.message.token.UsernameToken;
>
> /**
> * This is an Axis handler that can be used to retrieve the credentials
> * available in the <code>UsernameToken</code> element.
> * This is a simple security handler that can provide only that service.
> * Therefore this handler can be used for testing perposes and
> * other simple works.
> *
> * This can be configured to do the authentication at Axis or at J2EE Server.
> * For that you have to set the <code>WSS4J2EEConstants.AUTH_AT_AXIS</code>
> * to true.
> *
> *
> * @author Rajith Priyanga (rpriyanga@yahoo.com)
> * @date May 29, 2004
> *
> */
> public class SimpleWSS4J2EEReceiver extends BasicHandler {
>
> MessageContext cntxt = null;
>
> boolean doAuthentication = false;
>
> /**
> * Retrieve the username-password information and perform a verification.
> * @see org.apache.axis.Handler#invoke(org.apache.axis.MessageContext)
> */
> public void invoke(MessageContext msgCntxt) throws AxisFault {
> this.cntxt = msgCntxt;
> doAuthentication = false;
>
> try{
> //Get the SOAP header.
> Message m = msgCntxt.getCurrentMessage();
> SOAPHeader sh = m.getSOAPPart().getEnvelope().getHeader();
>
> //Retrieve the action property.
> String action = null;
> if((action = (String) getOption(WSDoAllConstants.ACTION))==null)
> action = (String)cntxt.getProperty(WSDoAllConstants.ACTION);
>
> if(action==null){
> return;
> }
>
> String[] actions = action.split(" ");
> if(actions==null)
> return;
>
> boolean utAction = false;
>
> //Check whether UsernameToken action property is available. Otherwise no more processing.
> for(int i=0; i<actions.length; i++){
> utAction = actions[i].equalsIgnoreCase(WSDoAllConstants.USERNAME_TOKEN);
> if(utAction)
> break;
> }
> if(!utAction)
> return;
>
> //Get all the headers.
> Iterator headers = sh.getChildElements();
> SOAPHeaderElement headerElem = null;
>
> if(headers==null){
> throw AxisFault.makeFault(new Exception("No Security Headers found"));
> }
> //Find the security header.
> while (headers.hasNext()) {
> headerElem = (SOAPHeaderElement) headers.next();
> if (headerElem.getLocalName().equals(WSConstants.WSSE_LN)
> && headerElem.getNamespaceURI().equals(WSConstants.WSSE_NS)) {
> //headerElem.setMustUnderstand(false);
> break;
> }
> }
>
> //Decides whether to do authentication at Axis or not.
> if(cntxt.containsProperty(WSS4J2EEConstants.AUTH_AT_AXIS)){
> String check = (String)cntxt.getProperty(WSS4J2EEConstants.AUTH_AT_AXIS);
> if(check!=null && check.equalsIgnoreCase("true"))
> this.doAuthentication = true;
> }
>
> //Hand over the security header to process it's UsernameToken.
> processUsernameToken(headerElem);
> headerElem.detachNode();
> }
> catch(Exception ex){
> throw AxisFault.makeFault(ex);
> }
> }
>
> /**
> * Processes the UsernameToken element of the security header.
> * It populates the SecurityContext4J2EE property of the MessageContext too.
> * @param secHeader SOAP Security Header.
> * @throws Exception
> */
> private void processUsernameToken(SOAPHeaderElement secHeader) throws Exception{
> SOAPFactory sf = SOAPFactory.newInstance();
> Name utName = sf.createName(WSConstants.USERNAME_TOKEN_LN, WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS);
> Iterator toks = secHeader.getChildElements(utName);
>
> if(toks==null){
> throw new Exception("No Security tokens found!");
> }
>
> //Get the UsernameToken element
> SOAPElement utElem = null;
> if(toks.hasNext()){
> utElem = (SOAPElement)toks.next();
> }
> else{
> throw new Exception("No UsernameToken found!");
> }
> Name unName = sf.createName(WSConstants.USERNAME_LN, WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS);
> Name pwdName = sf.createName(WSConstants.PASSWORD_LN, WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS);
>
> //Get the user name
> String username = ((SOAPElement)(utElem.getChildElements(unName).next())).getValue();
>
> //Get the password element
> SOAPElement pwdElem = (SOAPElement)utElem.getChildElements(pwdName).next();
>
> //Get the password type
> String pwdType = pwdElem.getAttributeValue(sf.createName(WSConstants.PASSWORD_TYPE_ATTR, WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS));//, WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS));
>
> //Get the password
> String pwd = pwdElem.getValue();
>
> //If the password type is not speciied take it as PASSWORD_TEXT type.
> if(pwdType==null)
> pwdType = WSConstants.PASSWORD_TEXT;
>
> if(pwdType.equalsIgnoreCase(WSConstants.PASSWORD_TEXT)){
> ///////////// This part can be removed. . /////////////////
> if(doAuthentication){
> if(!veryfyPWD(username, pwd)){
> throw new Exception("Password Verification failed!");
> }
> }
> ///////////////////////////////////////////////////////////
> this.populateSecurityContext4J2EE(username, pwd, pwdType, null, null);
> //this.Authenticate4J2EE();
> }
> else if(pwdType.equalsIgnoreCase(WSConstants.PASSWORD_DIGEST)){
> Name nonceName = sf.createName(WSConstants.NONCE_LN, WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS);
> Name createdName = sf.createName(WSConstants.CREATED_LN, WSConstants.WSU_PREFIX, WSConstants.WSU_NS);
>
> Iterator elems = utElem.getChildElements(nonceName);
> String nonce = this.extractNonce(elems);
>
> elems = utElem.getChildElements(createdName);
> String created = this.extractCreated(elems);
> ///////////// This part can be removed. . /////////////////
> if(doAuthentication){
> if(!veryfyPWD(username, pwd, nonce, created)){
> throw new Exception("Password Verification failed!");
> }
> }
> ///////////////////////////////////////////////////////////
> this.populateSecurityContext4J2EE(username, pwd, pwdType, nonce, created);
> }
> else{
> throw new Exception("Unsupported Password Type!");
> }
> }
>
> /**
> * Extracts the nonce value from the given set of elements.
> * (It is given as a iteratorf o elements)
> * @param elements
> * @return
> * @throws Exception
> */
> private String extractNonce(Iterator elements) throws Exception{
> boolean noNonce = false;
> String nonce = null;
>
> if(elements==null){
> noNonce = true;
> }
> if(!noNonce && elements.hasNext()){
> nonce = ((SOAPElement)(elements.next())).getValue();
> }
> else{
> noNonce = true;
> }
> if(nonce == null){
> noNonce = true;
> }
> if(noNonce)
> throw new Exception("Nonce is not specified!");
>
> return nonce;
> }
>
> /**
> * Extracts the created value from the given set of elements.
> * (It is given as a iteratorf o elements)
> * @param elements
> * @return
> * @throws Exception
> */
> private String extractCreated(Iterator elements) throws Exception{
> boolean noCreated = false;
> String created = null;
>
> if(elements==null)
> noCreated = true;
>
> if(!noCreated && elements.hasNext())
> created = ((SOAPElement)(elements.next())).getValue();
> else
> noCreated = true;
>
> if(created == null)
> noCreated = true;
>
> if(noCreated)
> throw new Exception("Created is not specified!");
>
> return created;
> }
>
> /**
> * Verifies the PASSWORD_TEXT type passwords.
> */
> private boolean veryfyPWD(String username, String password) throws Exception{
> if(password.equals(this.fetchActualPWD(username))){
> return true;
> }
> else{
> return false;
> }
> }
>
> /**
> * Verifies the PASSWORD_DIGEST type passwords.
> */
> private boolean veryfyPWD(String username,
> String password,
> String nonce,
> String created) throws Exception{
>
> //TODO
> //Check whether (created > currentTime - 5 minutes).
> //Cache the nonce for the user and check it before verification.
>
> if(nonce == null || created == null){
> throw new Exception("Nonce or Created not supplied!");
> }
>
> String digest = UsernameToken.doPasswordDigest(nonce, created, this.fetchActualPWD(username));
>
> if(password.equals(digest)){
> return true;
> }
> else{
> return false;
> }
> }
>
> /**}
> * Fetches the actual password using the CallbackHandler specified
> * in the deployment descripter.
> * @param username username
> * @return the actual password of the user.
> * @throws Exception
> */
>
> private String fetchActualPWD(String username) throws Exception{
> WSPasswordCallback pwcb = new WSPasswordCallback(username, WSPasswordCallback.USERNAME_TOKEN);
> Callback[] cb = new Callback[1];
>
> cb[0] = pwcb;
>
> CallbackHandler cbh = (CallbackHandler)this.cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_REF);
>
> if(cbh == null){
> String cbhClass = (String)this.cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_CLASS);
> cbh = (CallbackHandler)Class.forName(cbhClass).newInstance();
> }
>
> if(cbh==null){
> throw new Exception("PasswordCallbackHandler not found!");
> }
>
> cbh.handle(cb);
> String pwd = ((WSPasswordCallback)(cb[0])).getPassword();
>
> if(pwd==null)
> throw new Exception("Password is not provided.");
>
> return pwd;
>
> }
>
> /**
> * Associates a Authenticated principal with this thread this thread.
> * @throws Exception
> */
> /*private void Authenticate4J2EE() throws Exception{
> CallbackHandler cbh = (CallbackHandler)this.cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_REF);
> if(cbh == null){
> String cbhClass = (String)this.cntxt.getProperty(WSDoAllConstants.PW_CALLBACK_CLASS);
> cbh = (CallbackHandler)Class.forName(cbhClass).newInstance();
> }
>
> if(cbh != null){
> javax.security.auth.login.LoginContext lc
> = new javax.security.auth.login.LoginContext("LC4" + this.cntxt.getTargetService(), cbh);
> lc.login();
> }
> else
> throw new Exception("CallbackHandler is null.");
> }*/
>
> /**
> * Populates the SecurityContext4J2EE property with the given
> * security information.
> * @param username
> * @param password
> * @param passwordType
> * @param nonce
> * @param created
> */
> private void populateSecurityContext4J2EE(String username, String password, String passwordType, String nonce, String created){
> SecurityContext4J2EEImpl sc4j2ee =
> (SecurityContext4J2EEImpl)this.cntxt.getProperty(WSS4J2EEConstants.SEC_CONTEXT_4J2EE);
>
> if(sc4j2ee==null){
> sc4j2ee = new SecurityContext4J2EEImpl();
> this.cntxt.setProperty(WSS4J2EEConstants.SEC_CONTEXT_4J2EE, sc4j2ee);
> }
>
> //Populate the SecurityContext4J2EE with the user name token data.
> sc4j2ee.setUsername(username);
> sc4j2ee.setPassword(password.toCharArray());
>
> if(passwordType.equalsIgnoreCase(WSConstants.PASSWORD_DIGEST)){
> sc4j2ee.setPasswordDigested(true);
> sc4j2ee.setNonce(nonce);
> sc4j2ee.setCreated(created);
> }
> else
> sc4j2ee.setPasswordDigested(false);
>
> PWDCallbackHandler4J2EE cbh = new PWDCallbackHandler4J2EE(username, password.toCharArray());
> sc4j2ee.setPWDCallbackHandler4J2EE(cbh);
> }
>
> }
>
> 1.1 ws-axis/contrib/ews/src/org/apache/ws/axis/security/CheckPoint4J2EEHandler.java
>
> Index: CheckPoint4J2EEHandler.java
> ===================================================================
> /*
> * Created on Apr 6, 2004
> *
> *
> */
> package org.apache.ws.axis.security;
>
> import org.apache.axis.AxisFault;
> import org.apache.axis.MessageContext;
> import org.apache.axis.handlers.BasicHandler;
> import org.apache.geronimo.ews.ws4j2ee.context.security.SecurityContext4J2EE;
>
> /**
> *
> * Still this is not in use. But may be in future...
> *
> * @author Rajith Priyanga (rpriyanga@yahoo.com)
> * @date Apr 6, 2004
> *
> */
> public abstract class CheckPoint4J2EEHandler extends BasicHandler {
>
> /**
> * @see org.apache.axis.Handler#invoke(org.apache.axis.MessageContext)
> */
> public void invoke(MessageContext cntxt) throws AxisFault{
> SecurityContext4J2EE sc4j2ee;
> //TODO
> //Populate the SecurityContext4J2EE object with available info.
> //Other info will be dynamically calculated rom MessageCOntext.
> }
>
> /**
> * Decides whether the message integrity is sufficiently varifiable.
> * @param cntxt Message context.
> * @return true if the test is passed.
> */
> public abstract boolean integrityTest(MessageContext cntxt);
>
> /**
> * Decides whether the message privacy is sufficiently protected.
> * @param cntxt Message context
> * @return true if the test is passed.
> */
> public abstract boolean privacyTest(MessageContext cntxt);
>
> /**
> * Returns the password of the given user. This should be retrieved
> * from a password store.
> * @param username
> * @return The actual password.
> */
> public abstract char[] getPassword(String username);
>
> }
>
> 1.5 +4 -3 ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/toWs/wrapperWs/SimpleRemoteInterfaceBasedWrapperClassWriter.java
>
> Index: SimpleRemoteInterfaceBasedWrapperClassWriter.java
> ===================================================================
> RCS file: /home/cvs/ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/toWs/wrapperWs/SimpleRemoteInterfaceBasedWrapperClassWriter.java,v
> retrieving revision 1.4
> retrieving revision 1.5
> diff -u -r1.4 -r1.5
> --- SimpleRemoteInterfaceBasedWrapperClassWriter.java 10 Jun 2004 11:35:19 -0000 1.4
> +++ SimpleRemoteInterfaceBasedWrapperClassWriter.java 7 Jul 2004 09:02:00 -0000 1.5
> @@ -136,10 +136,11 @@
> out.write("\t\tif(msgcontext == null){\n");
> out.write("\t\t msgcontext = org.apache.axis.MessageContext.getCurrentContext();\n");
> out.write("\t\t}\n");
> -
> + out.write("\t\torg.apache.geronimo.ews.ws4j2ee.context.security.SecurityContext4J2EE seccontext =\n");
> + out.write("\t\t (org.apache.geronimo.ews.ws4j2ee.context.security.SecurityContext4J2EE)msgcontext\n");
> + out.write("\t\t.getProperty(org.apache.ws.axis.security.WSS4J2EEConstants.SEC_CONTEXT_4J2EE);\n");
> out.write("\t\t javax.security.auth.callback.CallbackHandler handler\n");
> - out.write("\t\t = org.apache.geronimo.ews.ws4j2ee.wsutils.security.jaasmodules.\n");
> - out.write("\t\t AutenticationCallbackHandlerFactory.createCallbackHandler(msgcontext);\n");
> + out.write("\t\t = seccontext.getPWDCallbackHandler4J2EE();\n");
> out.write("\t\t if(handler != null){\n");
> out.write("\t\t javax.security.auth.login.LoginContext lc\n");
> out.write("\t\t = new javax.security.auth.login.LoginContext(\"TestClient\", handler);\n");
>
> 1.2 +11 -5 ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/context/security/SecurityContext4J2EE.java
>
> Index: SecurityContext4J2EE.java
> ===================================================================
> RCS file: /home/cvs/ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/context/security/SecurityContext4J2EE.java,v
> retrieving revision 1.1
> retrieving revision 1.2
> diff -u -r1.1 -r1.2
> --- SecurityContext4J2EE.java 14 Jun 2004 08:24:39 -0000 1.1
> +++ SecurityContext4J2EE.java 7 Jul 2004 09:02:00 -0000 1.2
> @@ -1,10 +1,8 @@
> -/*
> - * Created on Apr 5, 2004
> - *
> - *
> - */
> package org.apache.geronimo.ews.ws4j2ee.context.security;
>
> +
> +
> +import javax.security.auth.callback.CallbackHandler;
> import javax.security.cert.X509Certificate;
>
> /**
> @@ -83,4 +81,12 @@
> * @return the X509 Certificate.
> */
> public byte[] getKerberoseTicket();
> +
> + /**
> + * Returns a PasswordCallbackHandler which can be used in
> + * authentication done using JAAS module at the wrapper web service.
> + * @return CallbackHandler.
> + */
> + public CallbackHandler getPWDCallbackHandler4J2EE();
> +
> }
>
> 1.13 +0 -3 ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/toWs/GenerationConstants.java
>
> Index: GenerationConstants.java
> ===================================================================
> RCS file: /home/cvs/ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/toWs/GenerationConstants.java,v
> retrieving revision 1.12
> retrieving revision 1.13
> diff -u -r1.12 -r1.13
> --- GenerationConstants.java 27 Jun 2004 15:20:23 -0000 1.12
> +++ GenerationConstants.java 7 Jul 2004 09:02:00 -0000 1.13
> @@ -55,9 +55,6 @@
>
> package org.apache.geronimo.ews.ws4j2ee.toWs;
>
> -import java.io.FileInputStream;
> -import java.io.InputStream;
> -import java.util.Properties;
>
> /**
> * <p>This interface has constants that are specific to the generators.</p>
>
> 1.6 +1 -1 ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/utils/AntExecuter.java
>
> Index: AntExecuter.java
> ===================================================================
> RCS file: /home/cvs/ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/utils/AntExecuter.java,v
> retrieving revision 1.5
> retrieving revision 1.6
> diff -u -r1.5 -r1.6
> --- AntExecuter.java 27 Jun 2004 15:20:24 -0000 1.5
> +++ AntExecuter.java 7 Jul 2004 09:02:00 -0000 1.6
> @@ -45,7 +45,7 @@
> ant.setAntfile(file.getAbsolutePath());
> ant.setDir(file.getParentFile());
> ant.execute();
> - }catch(ClassCastException e){
> + }catch(ClassNotFoundException e){
> System.out.println("Ant file will not be run programatcally as the " + "$JAVA_HOME/lib/tool.jar is not in the class path. To run the ant " + "prgramatically add that jar to classpath");
> }catch(BuildException e){
> System.out.println(e.getMessage() +
>
> 1.1 ws-axis/contrib/ews/src/org/apache/ws/security/WSS4J2EEEngine.java
>
> Index: WSS4J2EEEngine.java
> ===================================================================
> /*
> * Created on May 28, 2004
> *
> *
> */
> package org.apache.ws.security;
>
> import javax.security.auth.callback.CallbackHandler;
>
> import org.apache.axis.MessageContext;
>
> import org.apache.geronimo.ews.ws4j2ee.context.security.impl.SecurityContext4J2EEImpl;
> import org.apache.ws.axis.security.PWDCallbackHandler4J2EE;
> import org.apache.ws.axis.security.WSS4J2EEConstants;
> import org.apache.ws.security.message.token.UsernameToken;
> import org.w3c.dom.Element;
> /**
> * This class is used in <code>AllSecurityReceiver</code<> to process the secuirty
> * headers in the SOAP message. This works slightly different from the
> * WSSecurityEngine of wss4j project.
> * i.e
> * This processes the UsernameToken element in a different way.
> * The credentials available in the token are retrieved and the
> * SecurityContext4J2EE is populated using them.
> * No authentication is done at Axis. Therefore no principal
> * is created, instead this replace it with null.
> *
> * Before using the above service, the MessageContext should be set.
> *
> * @author Davanum Srinivas (dims@yahoo.com).
> * @author Werner Dittmann (Werner.Dittmann@siemens.com).
> * @author Rajith Priyanga (rpriyanga@yahoo.com)
> * @date May 28, 2004
> *
> */
> public class WSS4J2EEEngine extends WSSecurityEngine{
>
> private MessageContext msgCntxt = null;
>
> public void setMessageContext(MessageContext msgContext) throws Exception{
> if(msgContext==null){
> throw new Exception("Mssage Context is null!");
> }
> else{
> this.msgCntxt = msgContext;
> }
> }
>
> /**
> * Processes the UsernameToken element and populate the SecurityContext4J2EE prperty
> * with the credentials available in it.
> * No authentication is done here.
> * Always returns null
> */
> public WSUsernameTokenPrincipal handleUsernameToken(Element token, CallbackHandler cb) throws WSSecurityException {
>
> UsernameToken ut = new UsernameToken(token);
> try{
> this.populateSecurityContext4J2EE(ut.getName(),
> ut.getPassword().toCharArray(),
> ut.isHashed(),
> ut.getNonce(),
> ut.getCreated());
> }
> catch(Exception e){
> throw new WSSecurityException(WSSecurityException.FAILURE, "Invalid Username Token found!");
> }
>
> return null;
> }
>
> /**
> * Register a SecurityContext4J2EE object with the MessageContext as
> * WSS4J2EEConstants.SEC_CONTEXT_4J2EE property.
> * Populates the SEC_CONTEXT_4J2EE property with the security information
> * avatilable in the UsernameToken.
> * @param ut
> */
> private void populateSecurityContext4J2EE(String user, char[] pwd, boolean isDigested, String nonce, String created){
> SecurityContext4J2EEImpl sc4j2ee =
> (SecurityContext4J2EEImpl)this.msgCntxt.getProperty(WSS4J2EEConstants.SEC_CONTEXT_4J2EE);
>
> if(sc4j2ee==null){
> sc4j2ee = new SecurityContext4J2EEImpl();
> this.msgCntxt.setProperty(WSS4J2EEConstants.SEC_CONTEXT_4J2EE, sc4j2ee);
> }
>
> //Populate the SecurityContext4J2EE with the user name token data.
> sc4j2ee.setUsername(user);
> if(isDigested){
> sc4j2ee.setPasswordDigested(true);
> sc4j2ee.setNonce(nonce);
> sc4j2ee.setCreated(created);
> }
> else
> sc4j2ee.setPasswordDigested(false);
>
> sc4j2ee.setPassword(pwd);
> PWDCallbackHandler4J2EE cbh = new PWDCallbackHandler4J2EE(user, pwd);
> sc4j2ee.setPWDCallbackHandler4J2EE(cbh);
> }
>
> }
>
> 1.2 +15 -14 ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/context/security/impl/SecurityContext4J2EEImpl.java
>
> Index: SecurityContext4J2EEImpl.java
> ===================================================================
> RCS file: /home/cvs/ws-axis/contrib/ews/src/org/apache/geronimo/ews/ws4j2ee/context/security/impl/SecurityContext4J2EEImpl.java,v
> retrieving revision 1.1
> retrieving revision 1.2
> diff -u -r1.1 -r1.2
> --- SecurityContext4J2EEImpl.java 14 Jun 2004 08:24:39 -0000 1.1
> +++ SecurityContext4J2EEImpl.java 7 Jul 2004 09:02:00 -0000 1.2
> @@ -1,14 +1,9 @@
> -/*
> - * Created on Apr 6, 2004
> - *
> - *
> - */
> package org.apache.geronimo.ews.ws4j2ee.context.security.impl;
>
> +import javax.security.auth.callback.CallbackHandler;
> import javax.security.cert.X509Certificate;
>
> import org.apache.geronimo.ews.ws4j2ee.context.security.SecurityContext4J2EE;
> -
> /**
> * @author Rajith Priyanga (rpriyanga@yahoo.com)
> * @date Apr 6, 2004
> @@ -27,15 +22,8 @@
> private boolean privacy = false;
> private boolean integrity = false;
> private boolean isPwdDigested= false;
> - //private MessageContext cntxt;
> + private CallbackHandler cbh;
>
> - /**
> - * This has a circular reference to the MessageContext.
> - * @param cntxt
> - */
> - /*public SecurityContext4J2EEImpl(MessageContext cntxt){
> - this.cntxt = cntxt;
> - }*/
>
> public SecurityContext4J2EEImpl(){
> @@ -192,6 +180,19 @@
> */
> public void setPassword(char[] password) {
> this.pwd = password;
> + }
> +
> +
> + /**
> + * @see org.apache.geranimo.ews.ws4j2ee.context.security.SecurityContext4J2EE#getPWDCallbackHandler4J2EE()
> + */
> + public CallbackHandler getPWDCallbackHandler4J2EE() {
> + return this.cbh;
> + }
> +
> +
> + public void setPWDCallbackHandler4J2EE(CallbackHandler callbackHandler){
> + this.cbh = callbackHandler;
> }
>
> }
>
>
--
Davanum Srinivas - http://webservices.apache.org/~dims/