PageRenderTime 54ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/test/sun/net/www/protocol/http/DigestTest.java

https://github.com/ikeji/openjdk7-jdk
Java | 242 lines | 172 code | 36 blank | 34 comment | 9 complexity | 1d2697befb901b67dfb83e3a8f81dfb7 MD5 | raw file
  1. /*
  2. * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
  3. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4. *
  5. * This code is free software; you can redistribute it and/or modify it
  6. * under the terms of the GNU General Public License version 2 only, as
  7. * published by the Free Software Foundation.
  8. *
  9. * This code is distributed in the hope that it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  12. * version 2 for more details (a copy is included in the LICENSE file that
  13. * accompanied this code).
  14. *
  15. * You should have received a copy of the GNU General Public License version
  16. * 2 along with this work; if not, write to the Free Software Foundation,
  17. * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18. *
  19. * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20. * or visit www.oracle.com if you need additional information or have any
  21. * questions.
  22. */
  23. /**
  24. * @test
  25. * @bug 4432213
  26. * @run main/othervm -Dhttp.auth.digest.validateServer=true DigestTest
  27. * @summary Need to support Digest Authentication for Proxies
  28. */
  29. import java.io.*;
  30. import java.util.*;
  31. import java.net.*;
  32. import java.security.*;
  33. import sun.net.www.*;
  34. /* This is one simple test of the RFC2617 digest authentication behavior
  35. * It specifically tests that the client correctly checks the returned
  36. * Authentication-Info header field from the server and throws an exception
  37. * if the password is wrong
  38. */
  39. class DigestServer extends Thread {
  40. ServerSocket s;
  41. Socket s1;
  42. InputStream is;
  43. OutputStream os;
  44. int port;
  45. String reply1 = "HTTP/1.1 401 Unauthorized\r\n"+
  46. "WWW-Authenticate: Digest realm=\""+realm+"\" domain=/ "+
  47. "nonce=\""+nonce+"\" qop=\"auth\"\r\n\r\n";
  48. String reply2 = "HTTP/1.1 200 OK\r\n" +
  49. "Date: Mon, 15 Jan 2001 12:18:21 GMT\r\n" +
  50. "Server: Apache/1.3.14 (Unix)\r\n" +
  51. "Content-Type: text/html; charset=iso-8859-1\r\n" +
  52. "Transfer-encoding: chunked\r\n\r\n"+
  53. "B\r\nHelloWorld1\r\n"+
  54. "B\r\nHelloWorld2\r\n"+
  55. "B\r\nHelloWorld3\r\n"+
  56. "B\r\nHelloWorld4\r\n"+
  57. "B\r\nHelloWorld5\r\n"+
  58. "0\r\n"+
  59. "Authentication-Info: ";
  60. DigestServer (ServerSocket y) {
  61. s = y;
  62. port = s.getLocalPort();
  63. }
  64. public void run () {
  65. try {
  66. s1 = s.accept ();
  67. is = s1.getInputStream ();
  68. os = s1.getOutputStream ();
  69. is.read ();
  70. os.write (reply1.getBytes());
  71. Thread.sleep (2000);
  72. s1.close ();
  73. s1 = s.accept ();
  74. is = s1.getInputStream ();
  75. os = s1.getOutputStream ();
  76. is.read ();
  77. // need to get the cnonce out of the response
  78. MessageHeader header = new MessageHeader (is);
  79. String raw = header.findValue ("Authorization");
  80. HeaderParser parser = new HeaderParser (raw);
  81. String cnonce = parser.findValue ("cnonce");
  82. String cnstring = parser.findValue ("nc");
  83. String reply = reply2 + getAuthorization (uri, "GET", cnonce, cnstring) +"\r\n";
  84. os.write (reply.getBytes());
  85. Thread.sleep (2000);
  86. s1.close ();
  87. } catch (Exception e) {
  88. System.out.println (e);
  89. e.printStackTrace();
  90. } finally {
  91. try { s.close(); } catch (IOException unused) {}
  92. }
  93. }
  94. static char[] passwd = "password".toCharArray();
  95. static String username = "user";
  96. static String nonce = "abcdefghijklmnopqrstuvwxyz";
  97. static String realm = "wallyworld";
  98. static String uri = "/foo.html";
  99. private String getAuthorization (String uri, String method, String cnonce, String cnstring) {
  100. String response;
  101. try {
  102. response = computeDigest(false, username,passwd,realm,
  103. method, uri, nonce, cnonce, cnstring);
  104. } catch (NoSuchAlgorithmException ex) {
  105. return null;
  106. }
  107. String value = "Digest"
  108. + " qop=auth\""
  109. + "\", cnonce=\"" + cnonce
  110. + "\", rspauth=\"" + response
  111. + "\", nc=\"" + cnstring + "\"";
  112. return (value+ "\r\n");
  113. }
  114. private String computeDigest(
  115. boolean isRequest, String userName, char[] password,
  116. String realm, String connMethod,
  117. String requestURI, String nonceString,
  118. String cnonce, String ncValue
  119. ) throws NoSuchAlgorithmException
  120. {
  121. String A1, HashA1;
  122. MessageDigest md = MessageDigest.getInstance("MD5");
  123. {
  124. A1 = userName + ":" + realm + ":";
  125. HashA1 = encode(A1, password, md);
  126. }
  127. String A2;
  128. if (isRequest) {
  129. A2 = connMethod + ":" + requestURI;
  130. } else {
  131. A2 = ":" + requestURI;
  132. }
  133. String HashA2 = encode(A2, null, md);
  134. String combo, finalHash;
  135. { /* RRC2617 when qop=auth */
  136. combo = HashA1+ ":" + nonceString + ":" + ncValue + ":" +
  137. cnonce + ":auth:" +HashA2;
  138. }
  139. finalHash = encode(combo, null, md);
  140. return finalHash;
  141. }
  142. private final static char charArray[] = {
  143. '0', '1', '2', '3', '4', '5', '6', '7',
  144. '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
  145. };
  146. private String encode(String src, char[] passwd, MessageDigest md) {
  147. md.update(src.getBytes());
  148. if (passwd != null) {
  149. byte[] passwdBytes = new byte[passwd.length];
  150. for (int i=0; i<passwd.length; i++)
  151. passwdBytes[i] = (byte)passwd[i];
  152. md.update(passwdBytes);
  153. Arrays.fill(passwdBytes, (byte)0x00);
  154. }
  155. byte[] digest = md.digest();
  156. StringBuffer res = new StringBuffer(digest.length * 2);
  157. for (int i = 0; i < digest.length; i++) {
  158. int hashchar = ((digest[i] >>> 4) & 0xf);
  159. res.append(charArray[hashchar]);
  160. hashchar = (digest[i] & 0xf);
  161. res.append(charArray[hashchar]);
  162. }
  163. return res.toString();
  164. }
  165. }
  166. public class DigestTest {
  167. static class MyAuthenticator extends Authenticator {
  168. public MyAuthenticator () {
  169. super ();
  170. }
  171. public PasswordAuthentication getPasswordAuthentication ()
  172. {
  173. return (new PasswordAuthentication ("user", "Wrongpassword".toCharArray()));
  174. }
  175. }
  176. public static void main(String[] args) throws Exception {
  177. int port;
  178. DigestServer server;
  179. ServerSocket sock;
  180. try {
  181. sock = new ServerSocket (0);
  182. port = sock.getLocalPort ();
  183. }
  184. catch (Exception e) {
  185. System.out.println ("Exception: " + e);
  186. return;
  187. }
  188. server = new DigestServer(sock);
  189. server.start ();
  190. boolean passed = false;
  191. try {
  192. Authenticator.setDefault (new MyAuthenticator ());
  193. String s = "http://localhost:" + port + DigestServer.uri;
  194. URL url = new URL(s);
  195. java.net.URLConnection conURL = url.openConnection();
  196. InputStream in = conURL.getInputStream();
  197. while (in.read () != -1) {}
  198. in.close ();
  199. } catch(ProtocolException e) {
  200. passed = true;
  201. }
  202. if (!passed) {
  203. throw new RuntimeException ("Expected a ProtocolException from wrong password");
  204. }
  205. }
  206. }