cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cohei...@apache.org
Subject svn commit: r1545617 - in /cxf/trunk: parent/ rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/ rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/common/ rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/sam...
Date Tue, 26 Nov 2013 11:15:54 GMT
Author: coheigea
Date: Tue Nov 26 11:15:53 2013
New Revision: 1545617

URL: http://svn.apache.org/r1545617
Log:
Switching to WSS4J 2.0-SNAPSHOT again. Added support for SOAP with Attachments

Added:
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AttachmentInCallbackHandler.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AttachmentOutCallbackHandler.java
Modified:
    cxf/trunk/parent/pom.xml
    cxf/trunk/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SamlPostBindingFilter.java
    cxf/trunk/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SamlRedirectBindingFilter.java
    cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/common/SecurityUtils.java
    cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SAMLUtils.java
    cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigOutInterceptor.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractTokenInterceptor.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AlgorithmSuiteTranslater.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/CryptoCoverageUtil.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JStaxInInterceptor.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/SamlTokenInterceptor.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenInterceptor.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JOutInterceptor.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JStaxInInterceptor.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JStaxOutInterceptor.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AbstractBindingBuilder.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AbstractStaxBindingHandler.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AsymmetricBindingHandler.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/StaxAsymmetricBindingHandler.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/StaxSymmetricBindingHandler.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/SymmetricBindingHandler.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/TransportBindingHandler.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/AlgorithmSuitePolicyValidator.java
    cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SAMLTokenProvider.java
    cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/renewer/SAMLTokenRenewer.java
    cxf/trunk/services/sts/systests/advanced/src/test/java/org/apache/cxf/systest/sts/secure_conv/SCTSAMLTokenProvider.java
    cxf/trunk/services/xkms/xkms-client/src/main/java/org/apache/cxf/xkms/crypto/impl/CryptoProviderUtils.java
    cxf/trunk/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/action/SecretKeyPasswordCallback.java
    cxf/trunk/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/common/KeystorePasswordCallback.java

Modified: cxf/trunk/parent/pom.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/parent/pom.xml?rev=1545617&r1=1545616&r2=1545617&view=diff
==============================================================================
--- cxf/trunk/parent/pom.xml (original)
+++ cxf/trunk/parent/pom.xml Tue Nov 26 11:15:53 2013
@@ -148,7 +148,7 @@
         <cxf.woodstox.core.version>4.2.0</cxf.woodstox.core.version>
         <cxf.woodstox.stax2-api.version>3.1.1</cxf.woodstox.stax2-api.version>
         <cxf.wsdl4j.version>1.6.3</cxf.wsdl4j.version>
-        <cxf.wss4j.version>2.0-beta</cxf.wss4j.version>
+        <cxf.wss4j.version>2.0-SNAPSHOT</cxf.wss4j.version>
         <cxf.xerces.version>2.11.0</cxf.xerces.version>
         <cxf.xmlbeans.version>2.6.0</cxf.xmlbeans.version>
         <cxf.xmlschema.version>2.0.3</cxf.xmlschema.version>

Modified: cxf/trunk/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SamlPostBindingFilter.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SamlPostBindingFilter.java?rev=1545617&r1=1545616&r2=1545617&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SamlPostBindingFilter.java (original)
+++ cxf/trunk/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SamlPostBindingFilter.java Tue Nov 26 11:15:53 2013
@@ -139,7 +139,7 @@ public class SamlPostBindingFilter exten
         LOG.fine("Using Signature algorithm " + sigAlgo);
         
         // Get the password
-        WSPasswordCallback[] cb = {new WSPasswordCallback(signatureUser, WSPasswordCallback.Usage.SIGNATURE)};
+        WSPasswordCallback[] cb = {new WSPasswordCallback(signatureUser, WSPasswordCallback.SIGNATURE)};
         callbackHandler.handle(cb);
         String password = cb[0].getPassword();
         

Modified: cxf/trunk/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SamlRedirectBindingFilter.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SamlRedirectBindingFilter.java?rev=1545617&r1=1545616&r2=1545617&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SamlRedirectBindingFilter.java (original)
+++ cxf/trunk/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SamlRedirectBindingFilter.java Tue Nov 26 11:15:53 2013
@@ -139,7 +139,7 @@ public class SamlRedirectBindingFilter e
         ub.queryParam(SSOConstants.SIG_ALG, URLEncoder.encode(sigAlgo, "UTF-8"));
         
         // Get the password
-        WSPasswordCallback[] cb = {new WSPasswordCallback(signatureUser, WSPasswordCallback.Usage.SIGNATURE)};
+        WSPasswordCallback[] cb = {new WSPasswordCallback(signatureUser, WSPasswordCallback.SIGNATURE)};
         callbackHandler.handle(cb);
         String password = cb[0].getPassword();
         

Modified: cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/common/SecurityUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/common/SecurityUtils.java?rev=1545617&r1=1545616&r2=1545617&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/common/SecurityUtils.java (original)
+++ cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/common/SecurityUtils.java Tue Nov 26 11:15:53 2013
@@ -117,7 +117,7 @@ public final class SecurityUtils {
     }
     
     public static String getPassword(Message message, String userName, 
-                                     WSPasswordCallback.Usage type, Class<?> callingClass) {
+                                     int type, Class<?> callingClass) {
         CallbackHandler handler = getCallbackHandler(message, callingClass);
         if (handler == null) {
             return null;

Modified: cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SAMLUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SAMLUtils.java?rev=1545617&r1=1545616&r2=1545617&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SAMLUtils.java (original)
+++ cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SAMLUtils.java Tue Nov 26 11:15:53 2013
@@ -118,7 +118,7 @@ public final class SAMLUtils {
                 }
         
                 String password = 
-                    SecurityUtils.getPassword(message, user, WSPasswordCallback.Usage.SIGNATURE, 
+                    SecurityUtils.getPassword(message, user, WSPasswordCallback.SIGNATURE, 
                             SAMLUtils.class);
                 
                 assertion.signAssertion(user, password, crypto, false);

Modified: cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigOutInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigOutInterceptor.java?rev=1545617&r1=1545616&r2=1545617&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigOutInterceptor.java (original)
+++ cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigOutInterceptor.java Tue Nov 26 11:15:53 2013
@@ -113,7 +113,7 @@ public class XmlSigOutInterceptor extend
         }
 
         String password = 
-            SecurityUtils.getPassword(message, user, WSPasswordCallback.Usage.SIGNATURE, this.getClass());
+            SecurityUtils.getPassword(message, user, WSPasswordCallback.SIGNATURE, this.getClass());
     
         X509Certificate[] issuerCerts = SecurityUtils.getCertificates(crypto, user);
         

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractTokenInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractTokenInterceptor.java?rev=1545617&r1=1545616&r2=1545617&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractTokenInterceptor.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractTokenInterceptor.java Tue Nov 26 11:15:53 2013
@@ -239,7 +239,7 @@ public abstract class AbstractTokenInter
     }
     
     protected String getPassword(String userName, AbstractToken info, 
-                                 WSPasswordCallback.Usage usage, SoapMessage message) {
+                                 int usage, SoapMessage message) {
         //Then try to get the password from the given callback handler
     
         CallbackHandler handler = getCallback(message);

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AlgorithmSuiteTranslater.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AlgorithmSuiteTranslater.java?rev=1545617&r1=1545616&r2=1545617&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AlgorithmSuiteTranslater.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AlgorithmSuiteTranslater.java Tue Nov 26 11:15:53 2013
@@ -137,6 +137,8 @@ public final class AlgorithmSuiteTransla
             algorithmSuite.addTransformAlgorithm(cxfAlgorithmSuite.getC14n().getValue());
             algorithmSuite.addTransformAlgorithm(SPConstants.STRT10);
             algorithmSuite.addTransformAlgorithm(WSConstants.NS_XMLDSIG_ENVELOPED_SIGNATURE);
+            algorithmSuite.addTransformAlgorithm(WSConstants.SWA_ATTACHMENT_CONTENT_SIG_TRANS);
+            algorithmSuite.addTransformAlgorithm(WSConstants.SWA_ATTACHMENT_COMPLETE_SIG_TRANS);
     
             algorithmSuite.addDerivedKeyAlgorithm(SPConstants.P_SHA1);
             algorithmSuite.addDerivedKeyAlgorithm(SPConstants.P_SHA1_L128);

Added: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AttachmentInCallbackHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AttachmentInCallbackHandler.java?rev=1545617&view=auto
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AttachmentInCallbackHandler.java (added)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AttachmentInCallbackHandler.java Tue Nov 26 11:15:53 2013
@@ -0,0 +1,119 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.ws.security.wss4j;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.activation.DataHandler;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+import org.apache.cxf.attachment.AttachmentDataSource;
+import org.apache.cxf.binding.soap.SoapMessage;
+import org.apache.wss4j.common.ext.AttachmentRequestCallback;
+import org.apache.wss4j.common.ext.AttachmentResultCallback;
+
+/**
+ * A outbound CallbackHandler to be used to sign/encrypt SOAP Attachments.
+ */
+public class AttachmentInCallbackHandler implements CallbackHandler {
+    
+    private final SoapMessage soapMessage;
+    
+    public AttachmentInCallbackHandler(SoapMessage soapMessage) {
+        this.soapMessage = soapMessage;
+    }
+
+    @Override
+    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
+        for (int i = 0; i < callbacks.length; i++) {
+            Callback callback = callbacks[i];
+            if (callback instanceof AttachmentRequestCallback) {
+                AttachmentRequestCallback attachmentRequestCallback = (AttachmentRequestCallback) callback;
+
+                List<org.apache.wss4j.common.ext.Attachment> attachmentList =
+                    new ArrayList<org.apache.wss4j.common.ext.Attachment>();
+                attachmentRequestCallback.setAttachments(attachmentList);
+
+                org.apache.cxf.message.Attachment attachment = null;
+
+                final Collection<org.apache.cxf.message.Attachment> attachments = 
+                    soapMessage.getAttachments();
+                // Calling LazyAttachmentCollection.size() here to force it to load the attachments
+                if (attachments.size() > 0) {
+                    for (Iterator<org.apache.cxf.message.Attachment> iterator = attachments.iterator(); 
+                        iterator.hasNext();) {
+                        attachment = iterator.next();
+    
+                        if (!attachmentRequestCallback.getAttachmentId().equals(attachment.getId())) {
+                            continue;
+                        }
+    
+                        org.apache.wss4j.common.ext.Attachment att =
+                            new org.apache.wss4j.common.ext.Attachment();
+                        att.setMimeType(attachment.getDataHandler().getContentType());
+                        att.setId(attachment.getId());
+                        att.setSourceStream(attachment.getDataHandler().getInputStream());
+                        Iterator<String> headerIterator = attachment.getHeaderNames();
+                        while (headerIterator.hasNext()) {
+                            String next = headerIterator.next();
+                            att.addHeader(next, attachment.getHeader(next));
+                        }
+                        attachmentList.add(att);
+    
+                        iterator.remove();
+                    }
+                }
+            } else if (callback instanceof AttachmentResultCallback) {
+                AttachmentResultCallback attachmentResultCallback = (AttachmentResultCallback) callback;
+
+                final Collection<org.apache.cxf.message.Attachment> attachments = soapMessage.getAttachments();
+
+                org.apache.cxf.attachment.AttachmentImpl securedAttachment =
+                    new org.apache.cxf.attachment.AttachmentImpl(
+                        attachmentResultCallback.getAttachmentId(),
+                        new DataHandler(
+                            new AttachmentDataSource(
+                                attachmentResultCallback.getAttachment().getMimeType(),
+                                attachmentResultCallback.getAttachment().getSourceStream())
+                        )
+                    );
+                Map<String, String> headers = attachmentResultCallback.getAttachment().getHeaders();
+                Iterator<Map.Entry<String, String>> iterator = headers.entrySet().iterator();
+                while (iterator.hasNext()) {
+                    Map.Entry<String, String> next = iterator.next();
+                    securedAttachment.setHeader(next.getKey(), next.getValue());
+                }
+                attachments.add(securedAttachment);
+
+            } else {
+                throw new UnsupportedCallbackException(callback, "Unsupported callback");
+            }
+        }
+    }
+
+
+}

Added: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AttachmentOutCallbackHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AttachmentOutCallbackHandler.java?rev=1545617&view=auto
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AttachmentOutCallbackHandler.java (added)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AttachmentOutCallbackHandler.java Tue Nov 26 11:15:53 2013
@@ -0,0 +1,116 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.ws.security.wss4j;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.activation.DataHandler;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+import org.apache.cxf.attachment.AttachmentDataSource;
+import org.apache.cxf.binding.soap.SoapMessage;
+import org.apache.wss4j.common.ext.AttachmentRequestCallback;
+import org.apache.wss4j.common.ext.AttachmentResultCallback;
+
+/**
+ * A outbound CallbackHandler to be used to sign/encrypt SOAP Attachments.
+ */
+public class AttachmentOutCallbackHandler implements CallbackHandler {
+    
+    private final SoapMessage soapMessage;
+    
+    public AttachmentOutCallbackHandler(SoapMessage soapMessage) {
+        this.soapMessage = soapMessage;
+    }
+
+    @Override
+    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
+        for (int i = 0; i < callbacks.length; i++) {
+            Callback callback = callbacks[i];
+            if (callback instanceof AttachmentRequestCallback) {
+                AttachmentRequestCallback attachmentRequestCallback = (AttachmentRequestCallback) callback;
+
+                List<org.apache.wss4j.common.ext.Attachment> attachmentList =
+                    new ArrayList<org.apache.wss4j.common.ext.Attachment>();
+                attachmentRequestCallback.setAttachments(attachmentList);
+
+                final Collection<org.apache.cxf.message.Attachment> attachments = 
+                    soapMessage.getAttachments();
+                if (attachments == null) {
+                    return;
+                }
+                for (Iterator<org.apache.cxf.message.Attachment> iterator = attachments.iterator(); 
+                    iterator.hasNext();) {
+                    org.apache.cxf.message.Attachment attachment = iterator.next();
+
+                    org.apache.wss4j.common.ext.Attachment att =
+                        new org.apache.wss4j.common.ext.Attachment();
+                    att.setMimeType(attachment.getDataHandler().getContentType());
+                    att.setId(attachment.getId());
+                    att.setSourceStream(attachment.getDataHandler().getInputStream());
+
+                    Iterator<String> headerIterator = attachment.getHeaderNames();
+                    while (headerIterator.hasNext()) {
+                        String next = headerIterator.next();
+                        att.addHeader(next, attachment.getHeader(next));
+                    }
+                    attachmentList.add(att);
+
+                    iterator.remove();
+                }
+
+            } else if (callback instanceof AttachmentResultCallback) {
+                AttachmentResultCallback attachmentResultCallback = (AttachmentResultCallback) callback;
+
+                final Collection<org.apache.cxf.message.Attachment> attachments = 
+                    soapMessage.getAttachments();
+
+                org.apache.cxf.attachment.AttachmentImpl securedAttachment =
+                    new org.apache.cxf.attachment.AttachmentImpl(
+                        attachmentResultCallback.getAttachmentId(),
+                        new DataHandler(
+                            new AttachmentDataSource(
+                                attachmentResultCallback.getAttachment().getMimeType(),
+                                attachmentResultCallback.getAttachment().getSourceStream())
+                        )
+                    );
+                Map<String, String> headers = attachmentResultCallback.getAttachment().getHeaders();
+                Iterator<Map.Entry<String, String>> iterator = headers.entrySet().iterator();
+                while (iterator.hasNext()) {
+                    Map.Entry<String, String> next = iterator.next();
+                    securedAttachment.setHeader(next.getKey(), next.getValue());
+                }
+                attachments.add(securedAttachment);
+
+            } else {
+                throw new UnsupportedCallbackException(callback, "Unsupported callback");
+            }
+        }
+    }
+
+
+}

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/CryptoCoverageUtil.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/CryptoCoverageUtil.java?rev=1545617&r1=1545616&r2=1545617&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/CryptoCoverageUtil.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/CryptoCoverageUtil.java Tue Nov 26 11:15:53 2013
@@ -34,7 +34,6 @@ import javax.xml.xpath.XPathFactory;
 
 import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
-
 import org.apache.cxf.helpers.DOMUtils;
 import org.apache.cxf.helpers.MapNamespaceContext;
 import org.apache.wss4j.common.ext.WSSecurityException;
@@ -131,6 +130,47 @@ public final class CryptoCoverageUtil {
         }
     }
 
+    public static void checkAttachmentsCoverage(
+        Collection<org.apache.cxf.message.Attachment> attachments,
+        final Collection<WSDataRef> refs,
+        CoverageType type,
+        CoverageScope scope
+    ) throws WSSecurityException {
+        String requiredTransform = null;
+        if (type == CoverageType.SIGNED && scope == CoverageScope.CONTENT) {
+            requiredTransform = WSConstants.SWA_ATTACHMENT_CONTENT_SIG_TRANS;
+        } else if (type == CoverageType.SIGNED) {
+            requiredTransform = WSConstants.SWA_ATTACHMENT_COMPLETE_SIG_TRANS;
+        }
+        
+        if (attachments != null) {
+            // For each matching attachment, check for a ref that covers it.
+            for (org.apache.cxf.message.Attachment attachment : attachments) {
+                boolean matched = false;
+                
+                for (WSDataRef r : refs) {
+                    String id = r.getWsuId();
+                    if (id != null && id.startsWith("cid:")) {
+                        id = id.substring(4);
+                    }
+                    
+                    if (r.isAttachment() && attachment.getId() != null && attachment.getId().equals(id) 
+                        && (CoverageType.ENCRYPTED == type || r.getTransformAlgorithms() != null
+                        && r.getTransformAlgorithms().contains(requiredTransform))) {
+                        matched = true;
+                        break;
+                    }
+                }
+                
+                // We looked through all of the refs, but the element was not signed/encrypted
+                if (!matched) {
+                    throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE,
+                            new Exception("The " + getCoverageTypeString(type)
+                            + " does not cover the required elements"));
+                }
+            }
+        }
+    }
     
     /**
      * Checks that the references provided refer to the required

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java?rev=1545617&r1=1545616&r2=1545617&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java Tue Nov 26 11:15:53 2013
@@ -98,6 +98,7 @@ import org.apache.wss4j.policy.SP12Const
 import org.apache.wss4j.policy.SP13Constants;
 import org.apache.wss4j.policy.SPConstants;
 import org.apache.wss4j.policy.model.AlgorithmSuite;
+import org.apache.wss4j.policy.model.Attachments;
 import org.apache.wss4j.policy.model.Header;
 import org.apache.wss4j.policy.model.RequiredElements;
 import org.apache.wss4j.policy.model.RequiredParts;
@@ -614,6 +615,20 @@ public class PolicyBasedWSS4JInIntercept
                         ai.setNotAsserted(h.getNamespace() + ":" + h.getName() + " not + " + type);
                     }
                 }
+                
+                Attachments attachments = p.getAttachments();
+                if (attachments != null) {
+                    try {
+                        CoverageScope scope = CoverageScope.ELEMENT;
+                        if (attachments.isContentSignatureTransform()) {
+                            scope = CoverageScope.CONTENT;
+                        }
+                        CryptoCoverageUtil.checkAttachmentsCoverage(msg.getAttachments(), signed, 
+                                                                type, scope);
+                    } catch (WSSecurityException e) {
+                        ai.setNotAsserted("An attachment was not signed/encrypted");
+                    }
+                }
             }
         }
         return true;

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JStaxInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JStaxInInterceptor.java?rev=1545617&r1=1545616&r2=1545617&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JStaxInInterceptor.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JStaxInInterceptor.java Tue Nov 26 11:15:53 2013
@@ -536,7 +536,13 @@ public class PolicyBasedWSS4JStaxInInter
         }
         
         String actor = (String)msg.getContextualProperty(SecurityConstants.ACTOR);
-        return new PolicyEnforcer(operationPolicies, soapAction, isRequestor(msg), actor);
+        final Collection<org.apache.cxf.message.Attachment> attachments = 
+            msg.getAttachments();
+        int attachmentCount = 0;
+        if (attachments != null && !attachments.isEmpty()) {
+            attachmentCount = attachments.size();
+        }
+        return new PolicyEnforcer(operationPolicies, soapAction, isRequestor(msg), actor, attachmentCount);
     }
     
 }

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/SamlTokenInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/SamlTokenInterceptor.java?rev=1545617&r1=1545616&r2=1545617&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/SamlTokenInterceptor.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/SamlTokenInterceptor.java Tue Nov 26 11:15:53 2013
@@ -292,7 +292,7 @@ public class SamlTokenInterceptor extend
                 password = (String)message.getContextualProperty(SecurityConstants.PASSWORD);
                 if (StringUtils.isEmpty(password)) {
                     password = 
-                        getPassword(issuerName, token, WSPasswordCallback.Usage.SIGNATURE, message);
+                        getPassword(issuerName, token, WSPasswordCallback.SIGNATURE, message);
                 }
             }
             Crypto crypto = samlCallback.getIssuerCrypto();

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenInterceptor.java?rev=1545617&r1=1545616&r2=1545617&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenInterceptor.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenInterceptor.java Tue Nov 26 11:15:53 2013
@@ -355,7 +355,7 @@ public class UsernameTokenInterceptor ex
             
             String password = (String)message.getContextualProperty(SecurityConstants.PASSWORD);
             if (StringUtils.isEmpty(password)) {
-                password = getPassword(userName, token, WSPasswordCallback.Usage.USERNAME_TOKEN, message);
+                password = getPassword(userName, token, WSPasswordCallback.USERNAME_TOKEN, message);
             }
             
             if (!StringUtils.isEmpty(password)) {

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java?rev=1545617&r1=1545616&r2=1545617&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java Tue Nov 26 11:15:53 2013
@@ -218,6 +218,8 @@ public class WSS4JInInterceptor extends 
          */
         try {
             reqData.setMsgContext(msg);
+            reqData.setAttachmentCallbackHandler(new AttachmentInCallbackHandler(msg));
+            
             setAlgorithmSuites(msg, reqData);
             
             reqData.setCallbackHandler(getCallback(reqData, utWithCallbacks));

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JOutInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JOutInterceptor.java?rev=1545617&r1=1545616&r2=1545617&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JOutInterceptor.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JOutInterceptor.java Tue Nov 26 11:15:53 2013
@@ -29,6 +29,7 @@ import java.util.logging.Logger;
 import javax.xml.soap.SOAPMessage;
 
 import org.w3c.dom.Document;
+
 import org.apache.cxf.binding.soap.SoapFault;
 import org.apache.cxf.binding.soap.SoapMessage;
 import org.apache.cxf.binding.soap.SoapVersion;
@@ -171,6 +172,7 @@ public class WSS4JOutInterceptor extends
             translateProperties(mc);
     
             reqData.setMsgContext(mc);
+            reqData.setAttachmentCallbackHandler(new AttachmentOutCallbackHandler(mc));
             
             /*
              * The overall try, just to have a finally at the end to perform some

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JStaxInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JStaxInInterceptor.java?rev=1545617&r1=1545616&r2=1545617&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JStaxInInterceptor.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JStaxInInterceptor.java Tue Nov 26 11:15:53 2013
@@ -132,6 +132,10 @@ public class WSS4JStaxInInterceptor exte
                 secProps = ConfigurationConverter.convert(getProperties());
             }
             
+            if (secProps.getAttachmentCallbackHandler() == null) {
+                secProps.setAttachmentCallbackHandler(new AttachmentInCallbackHandler(soapMessage));
+            }
+            
             TokenStoreCallbackHandler callbackHandler = 
                 new TokenStoreCallbackHandler(
                     secProps.getCallbackHandler(), WSS4JUtils.getTokenStore(soapMessage)

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JStaxOutInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JStaxOutInterceptor.java?rev=1545617&r1=1545616&r2=1545617&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JStaxOutInterceptor.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JStaxOutInterceptor.java Tue Nov 26 11:15:53 2013
@@ -143,6 +143,10 @@ public class WSS4JStaxOutInterceptor ext
                 return;
             }
             
+            if (secProps.getAttachmentCallbackHandler() == null) {
+                secProps.setAttachmentCallbackHandler(new AttachmentOutCallbackHandler(mc));
+            }
+            
             SecurityEventListener securityEventListener = 
                 configureSecurityEventListener(mc, secProps);
             
@@ -284,7 +288,7 @@ public class WSS4JStaxOutInterceptor ext
     final class WSS4JStaxOutInterceptorInternal extends AbstractPhaseInterceptor<Message> {
         public WSS4JStaxOutInterceptorInternal() {
             super(Phase.PRE_STREAM_ENDING);
-            getAfter().add(AttachmentOutInterceptor.AttachmentOutEndingInterceptor.class.getName());
+            getBefore().add(AttachmentOutInterceptor.AttachmentOutEndingInterceptor.class.getName());
         }
         
         public void handleMessage(Message mc) throws Fault {

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AbstractBindingBuilder.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AbstractBindingBuilder.java?rev=1545617&r1=1545616&r2=1545617&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AbstractBindingBuilder.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AbstractBindingBuilder.java Tue Nov 26 11:15:53 2013
@@ -72,6 +72,7 @@ import org.apache.cxf.ws.policy.PolicyCo
 import org.apache.cxf.ws.security.SecurityConstants;
 import org.apache.cxf.ws.security.tokenstore.SecurityToken;
 import org.apache.cxf.ws.security.tokenstore.TokenStore;
+import org.apache.cxf.ws.security.wss4j.AttachmentOutCallbackHandler;
 import org.apache.cxf.ws.security.wss4j.WSS4JUtils;
 import org.apache.cxf.wsdl.WSDLConstants;
 import org.apache.neethi.Assertion;
@@ -121,6 +122,7 @@ import org.apache.wss4j.policy.model.Abs
 import org.apache.wss4j.policy.model.AbstractTokenWrapper;
 import org.apache.wss4j.policy.model.AlgorithmSuite.AlgorithmSuiteType;
 import org.apache.wss4j.policy.model.AsymmetricBinding;
+import org.apache.wss4j.policy.model.Attachments;
 import org.apache.wss4j.policy.model.ContentEncryptedElements;
 import org.apache.wss4j.policy.model.EncryptedElements;
 import org.apache.wss4j.policy.model.EncryptedParts;
@@ -452,7 +454,7 @@ public abstract class AbstractBindingBui
                         throw new Fault(e1);
                     }
 
-                    String password = getPassword(uname, token, WSPasswordCallback.Usage.SIGNATURE);
+                    String password = getPassword(uname, token, WSPasswordCallback.SIGNATURE);
                     sig.setUserInfo(uname, password);
                     try {
                         sig.prepare(saaj.getSOAPPart(), secToken.getCrypto(), secHeader);
@@ -695,7 +697,7 @@ public abstract class AbstractBindingBui
             } else {
                 String password = (String)message.getContextualProperty(SecurityConstants.PASSWORD);
                 if (StringUtils.isEmpty(password)) {
-                    password = getPassword(userName, token, WSPasswordCallback.Usage.USERNAME_TOKEN);
+                    password = getPassword(userName, token, WSPasswordCallback.USERNAME_TOKEN);
                 }
             
                 if (!StringUtils.isEmpty(password)) {
@@ -747,7 +749,7 @@ public abstract class AbstractBindingBui
             
             String password = (String)message.getContextualProperty(SecurityConstants.PASSWORD);
             if (StringUtils.isEmpty(password)) {
-                password = getPassword(userName, token, WSPasswordCallback.Usage.USERNAME_TOKEN);
+                password = getPassword(userName, token, WSPasswordCallback.USERNAME_TOKEN);
             }
 
             if (!StringUtils.isEmpty(password)) {
@@ -837,7 +839,7 @@ public abstract class AbstractBindingBui
             }
             String password = samlCallback.getIssuerKeyPassword();
             if (password == null) {
-                password = getPassword(issuerName, token, WSPasswordCallback.Usage.SIGNATURE);
+                password = getPassword(issuerName, token, WSPasswordCallback.SIGNATURE);
             }
             Crypto crypto = samlCallback.getIssuerCrypto();
             if (crypto == null) {
@@ -894,7 +896,7 @@ public abstract class AbstractBindingBui
         return id;
     }
     
-    public String getPassword(String userName, Assertion info, WSPasswordCallback.Usage usage) {
+    public String getPassword(String userName, Assertion info, int usage) {
         //Then try to get the password from the given callback handler
         CallbackHandler handler = getCallbackHandler();
         if (handler == null) {
@@ -1034,6 +1036,12 @@ public abstract class AbstractBindingBui
                                                             "Element");
                 signedParts.add(wep);
             }
+            
+            Attachments attachments = parts.getAttachments();
+            if (attachments != null) {
+                WSEncryptionPart wep = new WSEncryptionPart("cid:Attachments", "Element");
+                signedParts.add(wep);
+            }
         }
     
         // REVISIT consider catching exceptions and unassert failed assertions or
@@ -1080,6 +1088,15 @@ public abstract class AbstractBindingBui
                                                             "Element");
                 signedParts.add(wep);
             }
+            Attachments attachments = parts.getAttachments();
+            if (attachments != null) {
+                String modifier = "Element";
+                if (attachments.isContentSignatureTransform()) {
+                    modifier = "Content";
+                }
+                WSEncryptionPart wep = new WSEncryptionPart("cid:Attachments", modifier);
+                signedParts.add(wep);
+            }
         }
         
         // REVISIT consider catching exceptions and unassert failed assertions or
@@ -1199,6 +1216,11 @@ public abstract class AbstractBindingBui
         
         // Handle sign/enc parts
         for (WSEncryptionPart part : parts) {
+            if (part.getId() != null && part.getId().startsWith("cid:")) {
+                // Attachments are handled inside WSS4J via a CallbackHandler
+                result.add(part);
+                continue;
+            }
             final List<Element> elements;
             
             if (StringUtils.isEmpty(part.getName())) {
@@ -1612,6 +1634,7 @@ public abstract class AbstractBindingBui
         AbstractTokenWrapper wrapper, AbstractToken token, boolean attached, boolean endorse
     ) throws WSSecurityException {
         WSSecSignature sig = new WSSecSignature(wssConfig);
+        sig.setAttachmentCallbackHandler(new AttachmentOutCallbackHandler(message));
         checkForX509PkiPath(sig, token);
         boolean alsoIncludeToken = false;
         if (token instanceof IssuedToken || token instanceof SamlToken) {
@@ -1716,7 +1739,7 @@ public abstract class AbstractBindingBui
             }
         }
 
-        String password = getPassword(user, token, WSPasswordCallback.Usage.SIGNATURE);
+        String password = getPassword(user, token, WSPasswordCallback.SIGNATURE);
         sig.setUserInfo(user, password);
         sig.setSignatureAlgorithm(binding.getAlgorithmSuite().getAsymmetricSignature());
         AlgorithmSuiteType algType = binding.getAlgorithmSuite().getAlgorithmSuiteType();

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AbstractStaxBindingHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AbstractStaxBindingHandler.java?rev=1545617&r1=1545616&r2=1545617&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AbstractStaxBindingHandler.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AbstractStaxBindingHandler.java Tue Nov 26 11:15:53 2013
@@ -38,7 +38,6 @@ import javax.xml.namespace.QName;
 import javax.xml.soap.SOAPException;
 
 import org.w3c.dom.Element;
-
 import org.apache.cxf.binding.soap.SoapMessage;
 import org.apache.cxf.common.classloader.ClassLoaderUtils;
 import org.apache.cxf.message.MessageUtils;
@@ -64,6 +63,7 @@ import org.apache.wss4j.policy.model.Abs
 import org.apache.wss4j.policy.model.AbstractToken;
 import org.apache.wss4j.policy.model.AbstractTokenWrapper;
 import org.apache.wss4j.policy.model.AlgorithmSuite.AlgorithmSuiteType;
+import org.apache.wss4j.policy.model.Attachments;
 import org.apache.wss4j.policy.model.ContentEncryptedElements;
 import org.apache.wss4j.policy.model.EncryptedElements;
 import org.apache.wss4j.policy.model.EncryptedParts;
@@ -872,6 +872,16 @@ public abstract class AbstractStaxBindin
                 securePart.setRequired(false);
                 signedParts.add(securePart);
             }
+            Attachments attachments = parts.getAttachments();
+            if (attachments != null) {
+                Modifier modifier = Modifier.Element;
+                if (attachments.isContentSignatureTransform()) {
+                    modifier = Modifier.Content;
+                }
+                SecurePart securePart = new SecurePart("cid:Attachments", modifier);
+                securePart.setRequired(false);
+                signedParts.add(securePart);
+            }
         }
         
         if (elements != null && elements.getXPaths() != null) {
@@ -938,6 +948,13 @@ public abstract class AbstractStaxBindin
                 securePart.setRequired(false);
                 encryptedParts.add(securePart);
             }
+            
+            Attachments attachments = parts.getAttachments();
+            if (attachments != null) {
+                SecurePart securePart = new SecurePart("cid:Attachments", Modifier.Element);
+                securePart.setRequired(false);
+                encryptedParts.add(securePart);
+            }
         }
         
         if (elements != null && elements.getXPaths() != null) {

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AsymmetricBindingHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AsymmetricBindingHandler.java?rev=1545617&r1=1545616&r2=1545617&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AsymmetricBindingHandler.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AsymmetricBindingHandler.java Tue Nov 26 11:15:53 2013
@@ -41,6 +41,7 @@ import org.apache.cxf.ws.policy.Assertio
 import org.apache.cxf.ws.policy.AssertionInfoMap;
 import org.apache.cxf.ws.security.SecurityConstants;
 import org.apache.cxf.ws.security.tokenstore.SecurityToken;
+import org.apache.cxf.ws.security.wss4j.AttachmentOutCallbackHandler;
 import org.apache.wss4j.common.WSEncryptionPart;
 import org.apache.wss4j.common.crypto.Crypto;
 import org.apache.wss4j.common.ext.WSSecurityException;
@@ -468,6 +469,7 @@ public class AsymmetricBindingHandler ex
             } else {
                 try {
                     WSSecEncrypt encr = new WSSecEncrypt(wssConfig);
+                    encr.setAttachmentCallbackHandler(new AttachmentOutCallbackHandler(message));
                     
                     encr.setDocument(saaj.getSOAPPart());
                     Crypto crypto = getEncryptionCrypto(recToken);
@@ -517,18 +519,29 @@ public class AsymmetricBindingHandler ex
                     }
                     
                     Element encryptedKeyElement = encr.getEncryptedKeyElement();
-                                       
+                    List<Element> attachments = encr.getAttachmentEncryptedDataElements();
                     //Encrypt, get hold of the ref list and add it
                     if (externalRef) {
                         Element refList = encr.encryptForRef(null, encrParts);
                         insertBeforeBottomUp(refList);
+                        if (attachments != null) {
+                            for (Element attachment : attachments) {
+                                this.insertBeforeBottomUp(attachment);
+                            }
+                        }
+                        this.addEncryptedKeyElement(encryptedKeyElement);
                     } else {
                         Element refList = encr.encryptForRef(null, encrParts);
-                    
+                        this.addEncryptedKeyElement(encryptedKeyElement);
+                        
                         // Add internal refs
                         encryptedKeyElement.appendChild(refList);
+                        if (attachments != null) {
+                            for (Element attachment : attachments) {
+                                this.addEncryptedKeyElement(attachment);
+                            }
+                        }
                     }
-                    this.addEncryptedKeyElement(encryptedKeyElement);
                     return encr;
                 } catch (WSSecurityException e) {
                     LOG.log(Level.FINE, e.getMessage(), e);

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/StaxAsymmetricBindingHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/StaxAsymmetricBindingHandler.java?rev=1545617&r1=1545616&r2=1545617&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/StaxAsymmetricBindingHandler.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/StaxAsymmetricBindingHandler.java Tue Nov 26 11:15:53 2013
@@ -370,13 +370,41 @@ public class StaxAsymmetricBindingHandle
                 }
             }
             
-            for (SecurePart part : encrParts) {
-                QName name = part.getName();
-                parts += "{" + part.getModifier() + "}{"
-                    +  name.getNamespaceURI() + "}" + name.getLocalPart() + ";";
+            String optionalParts = "";
+            if (config.containsKey(ConfigurationConstants.OPTIONAL_ENCRYPTION_PARTS)) {
+                optionalParts = (String)config.get(ConfigurationConstants.OPTIONAL_ENCRYPTION_PARTS);
+                if (!optionalParts.endsWith(";")) {
+                    optionalParts += ";";
+                }
             }
-            
+
+            if (encrParts != null) {
+                for (SecurePart part : encrParts) {
+                    QName name = part.getName();
+                    String modifier = part.getModifier().getModifier();
+                    if (modifier == null || Modifier.Element.getModifier().equals(modifier)) {
+                        modifier = "Element";
+                    } else {
+                        modifier = "Content";
+                    }
+                    
+                    String parsedPart = "";
+                    if (name != null) {
+                        parsedPart = "{" + modifier + "}{" + name.getNamespaceURI() + "}" + name.getLocalPart() + ";";
+                    } else {
+                        parsedPart = "{" + modifier + "}" + part.getExternalReference() + ";";
+                    }
+                    
+                    if (part.isRequired()) {
+                        parts += parsedPart;
+                    } else {
+                        optionalParts += parsedPart;
+                    }
+                }
+            }
+
             config.put(ConfigurationConstants.ENCRYPTION_PARTS, parts);
+            config.put(ConfigurationConstants.OPTIONAL_ENCRYPTION_PARTS, optionalParts);
     
             config.put(ConfigurationConstants.ENC_KEY_ID, 
                        getKeyIdentifierType(recToken, encrToken));
@@ -436,10 +464,24 @@ public class StaxAsymmetricBindingHandle
         
         for (SecurePart part : sigParts) {
             QName name = part.getName();
+            String modifier = part.getModifier().getModifier();
+            if (modifier == null || Modifier.Element.getModifier().equals(modifier)) {
+                modifier = "Element";
+            } else {
+                modifier = "Content";
+            }
+            
+            String parsedPart = "";
+            if (name != null) {
+                parsedPart = "{" + modifier + "}{" + name.getNamespaceURI() + "}" + name.getLocalPart() + ";";
+            } else {
+                parsedPart = "{" + modifier + "}" + part.getExternalReference() + ";";
+            }
+            
             if (part.isRequired()) {
-                parts += "{Element}{" +  name.getNamespaceURI() + "}" + name.getLocalPart() + ";";
+                parts += parsedPart;
             } else {
-                optionalParts += "{Element}{" +  name.getNamespaceURI() + "}" + name.getLocalPart() + ";";
+                optionalParts += parsedPart;
             }
         }
         

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/StaxSymmetricBindingHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/StaxSymmetricBindingHandler.java?rev=1545617&r1=1545616&r2=1545617&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/StaxSymmetricBindingHandler.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/StaxSymmetricBindingHandler.java Tue Nov 26 11:15:53 2013
@@ -439,16 +439,42 @@ public class StaxSymmetricBindingHandler
                     parts += ";";
                 }
             }
+            
+            String optionalParts = "";
+            if (config.containsKey(ConfigurationConstants.OPTIONAL_ENCRYPTION_PARTS)) {
+                optionalParts = (String)config.get(ConfigurationConstants.OPTIONAL_ENCRYPTION_PARTS);
+                if (!optionalParts.endsWith(";")) {
+                    optionalParts += ";";
+                }
+            }
 
             if (encrParts != null) {
                 for (SecurePart part : encrParts) {
                     QName name = part.getName();
-                    parts += "{" + part.getModifier() + "}{"
-                        +  name.getNamespaceURI() + "}" + name.getLocalPart() + ";";
+                    String modifier = part.getModifier().getModifier();
+                    if (modifier == null || Modifier.Element.getModifier().equals(modifier)) {
+                        modifier = "Element";
+                    } else {
+                        modifier = "Content";
+                    }
+                    
+                    String parsedPart = "";
+                    if (name != null) {
+                        parsedPart = "{" + modifier + "}{" + name.getNamespaceURI() + "}" + name.getLocalPart() + ";";
+                    } else {
+                        parsedPart = "{" + modifier + "}" + part.getExternalReference() + ";";
+                    }
+                    
+                    if (part.isRequired()) {
+                        parts += parsedPart;
+                    } else {
+                        optionalParts += parsedPart;
+                    }
                 }
             }
 
             config.put(ConfigurationConstants.ENCRYPTION_PARTS, parts);
+            config.put(ConfigurationConstants.OPTIONAL_ENCRYPTION_PARTS, optionalParts);
 
             if (isRequestor()) {
                 config.put(ConfigurationConstants.ENC_KEY_ID, 
@@ -543,10 +569,24 @@ public class StaxSymmetricBindingHandler
         
         for (SecurePart part : sigParts) {
             QName name = part.getName();
+            String modifier = part.getModifier().getModifier();
+            if (modifier == null || Modifier.Element.getModifier().equals(modifier)) {
+                modifier = "Element";
+            } else {
+                modifier = "Content";
+            }
+            
+            String parsedPart = "";
+            if (name != null) {
+                parsedPart = "{" + modifier + "}{" + name.getNamespaceURI() + "}" + name.getLocalPart() + ";";
+            } else {
+                parsedPart = "{" + modifier + "}" + part.getExternalReference() + ";";
+            }
+            
             if (part.isRequired()) {
-                parts += "{Element}{" +  name.getNamespaceURI() + "}" + name.getLocalPart() + ";";
+                parts += parsedPart;
             } else {
-                optionalParts += "{Element}{" +  name.getNamespaceURI() + "}" + name.getLocalPart() + ";";
+                optionalParts += parsedPart;
             }
         }
         

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/SymmetricBindingHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/SymmetricBindingHandler.java?rev=1545617&r1=1545616&r2=1545617&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/SymmetricBindingHandler.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/SymmetricBindingHandler.java Tue Nov 26 11:15:53 2013
@@ -40,6 +40,7 @@ import org.apache.cxf.ws.policy.Assertio
 import org.apache.cxf.ws.security.SecurityConstants;
 import org.apache.cxf.ws.security.tokenstore.SecurityToken;
 import org.apache.cxf.ws.security.tokenstore.TokenStore;
+import org.apache.cxf.ws.security.wss4j.AttachmentOutCallbackHandler;
 import org.apache.wss4j.common.WSEncryptionPart;
 import org.apache.wss4j.common.crypto.Crypto;
 import org.apache.wss4j.common.derivedKey.ConversationConstants;
@@ -513,6 +514,7 @@ public class SymmetricBindingHandler ext
             } else {
                 try {
                     WSSecEncrypt encr = new WSSecEncrypt(wssConfig);
+                    encr.setAttachmentCallbackHandler(new AttachmentOutCallbackHandler(message));
                     String encrTokId = encrTok.getId();
                     if (attached) {
                         encrTokId = encrTok.getWsuId();
@@ -588,13 +590,24 @@ public class SymmetricBindingHandler ext
                         encr.prependBSTElementToHeader(secHeader);
                     }
                    
-                   
                     Element refList = encr.encryptForRef(null, encrParts);
+                    List<Element> attachments = encr.getAttachmentEncryptedDataElements();
                     if (atEnd) {
                         this.insertBeforeBottomUp(refList);
+                        if (attachments != null) {
+                            for (Element attachment : attachments) {
+                                this.insertBeforeBottomUp(attachment);
+                            }
+                        }
                     } else {
-                        this.addDerivedKeyElement(refList);                        
+                        this.addDerivedKeyElement(refList);
+                        if (attachments != null) {
+                            for (Element attachment : attachments) {
+                                this.addDerivedKeyElement(attachment);
+                            }
+                        }
                     }
+                    
                     return encr;
                 } catch (WSSecurityException e) {
                     LOG.log(Level.FINE, e.getMessage(), e);
@@ -742,6 +755,7 @@ public class SymmetricBindingHandler ext
             return doSignatureDK(sigs, policyAbstractTokenWrapper, policyToken, tok, included);
         } else {
             WSSecSignature sig = new WSSecSignature(wssConfig);
+            sig.setAttachmentCallbackHandler(new AttachmentOutCallbackHandler(message));
             // If a EncryptedKeyToken is used, set the correct value type to
             // be used in the wsse:Reference in ds:KeyInfo
             int type = included ? WSConstants.CUSTOM_SYMM_SIGNING 

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/TransportBindingHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/TransportBindingHandler.java?rev=1545617&r1=1545616&r2=1545617&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/TransportBindingHandler.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/TransportBindingHandler.java Tue Nov 26 11:15:53 2013
@@ -545,7 +545,7 @@ public class TransportBindingHandler ext
                 String userNameKey = SecurityConstants.SIGNATURE_USERNAME;
                 uname = (String)message.getContextualProperty(userNameKey);
             }
-            String password = getPassword(uname, token, WSPasswordCallback.Usage.SIGNATURE);
+            String password = getPassword(uname, token, WSPasswordCallback.SIGNATURE);
             if (password == null) {
                 password = "";
             }

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/AlgorithmSuitePolicyValidator.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/AlgorithmSuitePolicyValidator.java?rev=1545617&r1=1545616&r2=1545617&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/AlgorithmSuitePolicyValidator.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/AlgorithmSuitePolicyValidator.java Tue Nov 26 11:15:53 2013
@@ -132,7 +132,9 @@ public class AlgorithmSuitePolicyValidat
             }
             for (String transformAlgorithm : transformAlgorithms) {
                 if (!(algorithmPolicy.getC14n().getValue().equals(transformAlgorithm)
-                    || STRTransform.TRANSFORM_URI.equals(transformAlgorithm))) {
+                    || STRTransform.TRANSFORM_URI.equals(transformAlgorithm)
+                    || WSConstants.SWA_ATTACHMENT_CONTENT_SIG_TRANS.equals(transformAlgorithm)
+                    || WSConstants.SWA_ATTACHMENT_COMPLETE_SIG_TRANS.equals(transformAlgorithm))) {
                     ai.setNotAsserted("The transform algorithms do not match the requirement");
                     return false;
                 }

Modified: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SAMLTokenProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SAMLTokenProvider.java?rev=1545617&r1=1545616&r2=1545617&view=diff
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SAMLTokenProvider.java (original)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SAMLTokenProvider.java Tue Nov 26 11:15:53 2013
@@ -389,7 +389,7 @@ public class SAMLTokenProvider implement
                 LOG.fine("Signature alias is null so using default alias: " + alias);
             }
             // Get the password
-            WSPasswordCallback[] cb = {new WSPasswordCallback(alias, WSPasswordCallback.Usage.SIGNATURE)};
+            WSPasswordCallback[] cb = {new WSPasswordCallback(alias, WSPasswordCallback.SIGNATURE)};
             LOG.fine("Creating SAML Token");
             callbackHandler.handle(cb);
             String password = cb[0].getPassword();

Modified: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/renewer/SAMLTokenRenewer.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/renewer/SAMLTokenRenewer.java?rev=1545617&r1=1545616&r2=1545617&view=diff
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/renewer/SAMLTokenRenewer.java (original)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/renewer/SAMLTokenRenewer.java Tue Nov 26 11:15:53 2013
@@ -489,7 +489,7 @@ public class SAMLTokenRenewer implements
                 LOG.fine("Signature alias is null so using default alias: " + alias);
             }
             // Get the password
-            WSPasswordCallback[] cb = {new WSPasswordCallback(alias, WSPasswordCallback.Usage.SIGNATURE)};
+            WSPasswordCallback[] cb = {new WSPasswordCallback(alias, WSPasswordCallback.SIGNATURE)};
             LOG.fine("Creating SAML Token");
             callbackHandler.handle(cb);
             String password = cb[0].getPassword();

Modified: cxf/trunk/services/sts/systests/advanced/src/test/java/org/apache/cxf/systest/sts/secure_conv/SCTSAMLTokenProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/systests/advanced/src/test/java/org/apache/cxf/systest/sts/secure_conv/SCTSAMLTokenProvider.java?rev=1545617&r1=1545616&r2=1545617&view=diff
==============================================================================
--- cxf/trunk/services/sts/systests/advanced/src/test/java/org/apache/cxf/systest/sts/secure_conv/SCTSAMLTokenProvider.java (original)
+++ cxf/trunk/services/sts/systests/advanced/src/test/java/org/apache/cxf/systest/sts/secure_conv/SCTSAMLTokenProvider.java Tue Nov 26 11:15:53 2013
@@ -197,7 +197,7 @@ public class SCTSAMLTokenProvider implem
 
             // Get the password
             String alias = stsProperties.getSignatureUsername();
-            WSPasswordCallback[] cb = {new WSPasswordCallback(alias, WSPasswordCallback.Usage.SIGNATURE)};
+            WSPasswordCallback[] cb = {new WSPasswordCallback(alias, WSPasswordCallback.SIGNATURE)};
             LOG.fine("Creating SAML Token");
             stsProperties.getCallbackHandler().handle(cb);
             String password = cb[0].getPassword();

Modified: cxf/trunk/services/xkms/xkms-client/src/main/java/org/apache/cxf/xkms/crypto/impl/CryptoProviderUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/xkms/xkms-client/src/main/java/org/apache/cxf/xkms/crypto/impl/CryptoProviderUtils.java?rev=1545617&r1=1545616&r2=1545617&view=diff
==============================================================================
--- cxf/trunk/services/xkms/xkms-client/src/main/java/org/apache/cxf/xkms/crypto/impl/CryptoProviderUtils.java (original)
+++ cxf/trunk/services/xkms/xkms-client/src/main/java/org/apache/cxf/xkms/crypto/impl/CryptoProviderUtils.java Tue Nov 26 11:15:53 2013
@@ -34,7 +34,6 @@ import org.apache.cxf.ws.security.Securi
 import org.apache.cxf.xkms.crypto.CryptoProviderException;
 import org.apache.wss4j.common.crypto.Merlin;
 import org.apache.wss4j.common.ext.WSPasswordCallback;
-import org.apache.wss4j.common.ext.WSPasswordCallback.Usage;
 
 final class CryptoProviderUtils {
 
@@ -129,7 +128,7 @@ final class CryptoProviderUtils {
         return handler;
     }
 
-    public static String getCallbackPwdFromMessage(Message message, String userName, Usage usage) {
+    public static String getCallbackPwdFromMessage(Message message, String userName, int usage) {
         // Then try to get the password from the given callback handler
         CallbackHandler handler = getCallbackHandler(message);
         if (handler == null) {
@@ -139,7 +138,7 @@ final class CryptoProviderUtils {
         return getCallbackPwd(userName, usage, handler);
     }
 
-    public static String getCallbackPwd(String userName, Usage usage, CallbackHandler handler) {
+    public static String getCallbackPwd(String userName, int usage, CallbackHandler handler) {
         if (handler == null) {
             return null;
         }

Modified: cxf/trunk/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/action/SecretKeyPasswordCallback.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/action/SecretKeyPasswordCallback.java?rev=1545617&r1=1545616&r2=1545617&view=diff
==============================================================================
--- cxf/trunk/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/action/SecretKeyPasswordCallback.java (original)
+++ cxf/trunk/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/action/SecretKeyPasswordCallback.java Tue Nov 26 11:15:53 2013
@@ -46,7 +46,7 @@ public class SecretKeyPasswordCallback i
     public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
         for (int i = 0; i < callbacks.length; i++) {
             WSPasswordCallback pc = (WSPasswordCallback)callbacks[i];
-            if (pc.getUsage() == WSPasswordCallback.Usage.SECRET_KEY) {
+            if (pc.getUsage() == WSPasswordCallback.SECRET_KEY) {
                 pc.setKey(KEY);
             }
         }

Modified: cxf/trunk/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/common/KeystorePasswordCallback.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/common/KeystorePasswordCallback.java?rev=1545617&r1=1545616&r2=1545617&view=diff
==============================================================================
--- cxf/trunk/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/common/KeystorePasswordCallback.java (original)
+++ cxf/trunk/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/common/KeystorePasswordCallback.java Tue Nov 26 11:15:53 2013
@@ -54,7 +54,7 @@ public class KeystorePasswordCallback im
     public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
         for (int i = 0; i < callbacks.length; i++) {
             WSPasswordCallback pc = (WSPasswordCallback)callbacks[i];
-            if (pc.getUsage() == WSPasswordCallback.Usage.PASSWORD_ENCRYPTOR_PASSWORD) {
+            if (pc.getUsage() == WSPasswordCallback.PASSWORD_ENCRYPTOR_PASSWORD) {
                 pc.setPassword("this-is-a-secret");
             } else {
                 String pass = passwords.get(pc.getIdentifier());



Mime
View raw message