1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements. See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership. The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License. You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied. See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.ws.security.message;
21  
22  import org.apache.ws.security.WSSecurityException;
23  import org.apache.ws.security.WSSecurityEngine;
24  import org.apache.ws.security.WSConstants;
25  import org.apache.ws.security.WSSConfig;
26  import org.apache.ws.security.common.CustomHandler;
27  import org.apache.ws.security.common.SOAPUtil;
28  import org.apache.ws.security.common.UsernamePasswordCallbackHandler;
29  import org.apache.ws.security.handler.RequestData;
30  import org.apache.ws.security.handler.WSHandlerConstants;
31  import org.w3c.dom.Document;
32  
33  import javax.security.auth.callback.CallbackHandler;
34  
35  /**
36   * This is a test for processing a Username Token to enforce either a plaintext or digest
37   * password type. See WSS-255.
38   */
39  public class PasswordTypeTest extends org.junit.Assert {
40      private static final org.apache.commons.logging.Log LOG = 
41          org.apache.commons.logging.LogFactory.getLog(PasswordTypeTest.class);
42      private CallbackHandler callbackHandler = new UsernamePasswordCallbackHandler();
43  
44      /**
45       * Test that adds a UserNameToken with password Digest to a WS-Security envelope
46       */
47      @org.junit.Test
48      public void testPasswordDigest() throws Exception {
49          WSSecUsernameToken builder = new WSSecUsernameToken();
50          builder.setUserInfo("wernerd", "verySecret");
51          Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
52          WSSecHeader secHeader = new WSSecHeader();
53          secHeader.insertSecurityHeader(doc);
54          Document signedDoc = builder.build(doc, secHeader);
55  
56          if (LOG.isDebugEnabled()) {
57              LOG.debug("Message with UserNameToken PW Digest:");
58              String outputString = 
59                  org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
60              LOG.debug(outputString);
61          }
62          WSSecurityEngine secEngine = new WSSecurityEngine();
63          WSSConfig wssConfig = WSSConfig.getNewInstance();
64          
65          //
66          // It should pass with PASSWORD_DIGEST
67          //
68          wssConfig.setRequiredPasswordType(WSConstants.PASSWORD_DIGEST);
69          secEngine.setWssConfig(wssConfig);
70          secEngine.processSecurityHeader(doc, null, callbackHandler, null);
71          
72          //
73          // It should pass with null
74          //
75          wssConfig.setRequiredPasswordType(null);
76          secEngine.setWssConfig(wssConfig);
77          secEngine.processSecurityHeader(doc, null, callbackHandler, null);
78          
79          //
80          // It should fail with PASSWORD_TEXT
81          //
82          try {
83              wssConfig.setRequiredPasswordType(WSConstants.PASSWORD_TEXT);
84              secEngine.setWssConfig(wssConfig);
85              secEngine.processSecurityHeader(doc, null, callbackHandler, null);
86              fail("Expected failure on the wrong password type");
87          } catch (WSSecurityException ex) {
88              assertTrue(ex.getErrorCode() == WSSecurityException.FAILED_AUTHENTICATION);
89              // expected
90          }
91      }
92      
93      /**
94       * Test that adds a UserNameToken with password text to a WS-Security envelope
95       */
96      @org.junit.Test
97      public void testUsernameTokenText() throws Exception {
98          WSSecUsernameToken builder = new WSSecUsernameToken();
99          builder.setPasswordType(WSConstants.PASSWORD_TEXT);
100         builder.setUserInfo("wernerd", "verySecret");
101         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
102         WSSecHeader secHeader = new WSSecHeader();
103         secHeader.insertSecurityHeader(doc);
104         Document signedDoc = builder.build(doc, secHeader);
105         
106         if (LOG.isDebugEnabled()) {
107             LOG.debug("Message with UserNameToken PW Text:");
108             String outputString = 
109                 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
110             LOG.debug(outputString);
111         }
112         WSSecurityEngine secEngine = new WSSecurityEngine();
113         WSSConfig wssConfig = WSSConfig.getNewInstance();
114         
115         //
116         // It should pass with PASSWORD_TEXT
117         //
118         wssConfig.setRequiredPasswordType(WSConstants.PASSWORD_TEXT);
119         secEngine.setWssConfig(wssConfig);
120         secEngine.processSecurityHeader(doc, null, callbackHandler, null);
121         
122         //
123         // It should pass with null
124         //
125         wssConfig.setRequiredPasswordType(null);
126         secEngine.setWssConfig(wssConfig);
127         secEngine.processSecurityHeader(doc, null, callbackHandler, null);
128         
129         //
130         // It should fail with PASSWORD_DIGEST
131         //
132         try {
133             wssConfig.setRequiredPasswordType(WSConstants.PASSWORD_DIGEST);
134             secEngine.setWssConfig(wssConfig);
135             secEngine.processSecurityHeader(doc, null, callbackHandler, null);
136             fail("Expected failure on the wrong password type");
137         } catch (WSSecurityException ex) {
138             assertTrue(ex.getErrorCode() == WSSecurityException.FAILED_AUTHENTICATION);
139             // expected
140         }
141         
142     }
143     
144     /**
145      * Test that adds a UserNameToken via WSHandler
146      */
147     @org.junit.Test
148     public void testUsernameTokenWSHandler() throws Exception {
149         CustomHandler handler = new CustomHandler();
150         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
151         
152         RequestData reqData = new RequestData();
153         java.util.Map<String, Object> config = new java.util.TreeMap<String, Object>();
154         config.put("password", "verySecret");
155         config.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
156         reqData.setUsername("wernerd");
157         reqData.setMsgContext(config);
158         
159         java.util.List<Integer> actions = new java.util.ArrayList<Integer>();
160         actions.add(Integer.valueOf(WSConstants.UT));
161         
162         handler.send(WSConstants.UT, doc, reqData, actions, true);
163         
164         if (LOG.isDebugEnabled()) {
165             LOG.debug("Username Token via WSHandler");
166             String outputString = 
167                 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
168             LOG.debug(outputString);
169         }
170         
171         //
172         // It should pass even on a different password type, as we haven't set the
173         // processing to be strict
174         //
175         config.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_DIGEST);
176         reqData.setMsgContext(config);
177         handler.receive(WSConstants.UT, reqData);
178         WSSecurityEngine secEngine = new WSSecurityEngine();
179         secEngine.setWssConfig(reqData.getWssConfig());
180         secEngine.processSecurityHeader(doc, null, callbackHandler, null);
181         
182         //
183         // It should fail on strict password type processing
184         //
185         config.put(WSHandlerConstants.PASSWORD_TYPE_STRICT, "true");
186         reqData.setMsgContext(config);
187         handler.receive(WSConstants.UT, reqData);
188         try {
189             secEngine.processSecurityHeader(doc, null, callbackHandler, null);
190             fail("Expected failure on the wrong password type");
191         } catch (WSSecurityException ex) {
192             // expected
193         }
194     }
195 
196 }