Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/sun/net/www/protocol/http/DigestTest.java
38867 views
/*1* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/**24* @test25* @bug 443221326* @run main/othervm -Dhttp.auth.digest.validateServer=true DigestTest27* @summary Need to support Digest Authentication for Proxies28*/2930import java.io.*;31import java.util.*;32import java.net.*;33import java.security.*;34import sun.net.www.*;3536/* This is one simple test of the RFC2617 digest authentication behavior37* It specifically tests that the client correctly checks the returned38* Authentication-Info header field from the server and throws an exception39* if the password is wrong40*/4142class DigestServer extends Thread {4344ServerSocket s;45Socket s1;46InputStream is;47OutputStream os;48int port;4950String reply1 = "HTTP/1.1 401 Unauthorized\r\n"+51"WWW-Authenticate: Digest realm=\""+realm+"\" domain=/ "+52"nonce=\""+nonce+"\" qop=\"auth\"\r\n\r\n";5354String reply2 = "HTTP/1.1 200 OK\r\n" +55"Date: Mon, 15 Jan 2001 12:18:21 GMT\r\n" +56"Server: Apache/1.3.14 (Unix)\r\n" +57"Content-Type: text/html; charset=iso-8859-1\r\n" +58"Transfer-encoding: chunked\r\n\r\n"+59"B\r\nHelloWorld1\r\n"+60"B\r\nHelloWorld2\r\n"+61"B\r\nHelloWorld3\r\n"+62"B\r\nHelloWorld4\r\n"+63"B\r\nHelloWorld5\r\n"+64"0\r\n"+65"Authentication-Info: ";6667DigestServer (ServerSocket y) {68s = y;69port = s.getLocalPort();70}7172public void run () {73try {74s1 = s.accept ();75is = s1.getInputStream ();76os = s1.getOutputStream ();77is.read ();78os.write (reply1.getBytes());79Thread.sleep (2000);80s1.close ();8182s1 = s.accept ();83is = s1.getInputStream ();84os = s1.getOutputStream ();85is.read ();86// need to get the cnonce out of the response87MessageHeader header = new MessageHeader (is);88String raw = header.findValue ("Authorization");89HeaderParser parser = new HeaderParser (raw);90String cnonce = parser.findValue ("cnonce");91String cnstring = parser.findValue ("nc");9293String reply = reply2 + getAuthorization (uri, "GET", cnonce, cnstring) +"\r\n";94os.write (reply.getBytes());95Thread.sleep (2000);96s1.close ();97} catch (Exception e) {98System.out.println (e);99e.printStackTrace();100} finally {101try { s.close(); } catch (IOException unused) {}102}103}104105static char[] passwd = "password".toCharArray();106static String username = "user";107static String nonce = "abcdefghijklmnopqrstuvwxyz";108static String realm = "wallyworld";109static String uri = "/foo.html";110111private String getAuthorization (String uri, String method, String cnonce, String cnstring) {112String response;113114try {115response = computeDigest(false, username,passwd,realm,116method, uri, nonce, cnonce, cnstring);117} catch (NoSuchAlgorithmException ex) {118return null;119}120121String value = "Digest"122+ " qop=auth\""123+ "\", cnonce=\"" + cnonce124+ "\", rspauth=\"" + response125+ "\", nc=\"" + cnstring + "\"";126return (value+ "\r\n");127}128129private String computeDigest(130boolean isRequest, String userName, char[] password,131String realm, String connMethod,132String requestURI, String nonceString,133String cnonce, String ncValue134) throws NoSuchAlgorithmException135{136137String A1, HashA1;138139MessageDigest md = MessageDigest.getInstance("MD5");140141{142A1 = userName + ":" + realm + ":";143HashA1 = encode(A1, password, md);144}145146String A2;147if (isRequest) {148A2 = connMethod + ":" + requestURI;149} else {150A2 = ":" + requestURI;151}152String HashA2 = encode(A2, null, md);153String combo, finalHash;154155{ /* RRC2617 when qop=auth */156combo = HashA1+ ":" + nonceString + ":" + ncValue + ":" +157cnonce + ":auth:" +HashA2;158159}160finalHash = encode(combo, null, md);161return finalHash;162}163164private final static char charArray[] = {165'0', '1', '2', '3', '4', '5', '6', '7',166'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'167};168169private String encode(String src, char[] passwd, MessageDigest md) {170md.update(src.getBytes());171if (passwd != null) {172byte[] passwdBytes = new byte[passwd.length];173for (int i=0; i<passwd.length; i++)174passwdBytes[i] = (byte)passwd[i];175md.update(passwdBytes);176Arrays.fill(passwdBytes, (byte)0x00);177}178byte[] digest = md.digest();179180StringBuffer res = new StringBuffer(digest.length * 2);181for (int i = 0; i < digest.length; i++) {182int hashchar = ((digest[i] >>> 4) & 0xf);183res.append(charArray[hashchar]);184hashchar = (digest[i] & 0xf);185res.append(charArray[hashchar]);186}187return res.toString();188}189190}191192public class DigestTest {193194static class MyAuthenticator extends Authenticator {195public MyAuthenticator () {196super ();197}198199public PasswordAuthentication getPasswordAuthentication ()200{201return (new PasswordAuthentication ("user", "Wrongpassword".toCharArray()));202}203}204205206public static void main(String[] args) throws Exception {207int port;208DigestServer server;209ServerSocket sock;210211try {212sock = new ServerSocket (0);213port = sock.getLocalPort ();214}215catch (Exception e) {216System.out.println ("Exception: " + e);217return;218}219220server = new DigestServer(sock);221server.start ();222boolean passed = false;223224try {225Authenticator.setDefault (new MyAuthenticator ());226String s = "http://localhost:" + port + DigestServer.uri;227URL url = new URL(s);228java.net.URLConnection conURL = url.openConnection();229230InputStream in = conURL.getInputStream();231while (in.read () != -1) {}232in.close ();233} catch(ProtocolException e) {234passed = true;235}236237if (!passed) {238throw new RuntimeException ("Expected a ProtocolException from wrong password");239}240}241}242243244