src/java.base/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
author dfuchs
Fri, 30 Aug 2019 15:42:27 +0100
branchJDK-8229867-branch
changeset 57968 8595871a5446
parent 57956 e0b8b019d2f5
permissions -rw-r--r--
JDK-8229867: first prototype
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
57956
e0b8b019d2f5 8229997: Apply java.io.Serial annotations in java.base
darcy
parents: 53018
diff changeset
     2
 * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4158
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4158
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4158
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4158
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4158
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package sun.net.www.protocol.http;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.io.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.net.URL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.net.ProtocolException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.net.PasswordAuthentication;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.util.Arrays;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import java.util.Random;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import sun.net.www.HeaderParser;
24372
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
    36
import sun.net.NetProperties;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
import java.security.MessageDigest;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
import java.security.NoSuchAlgorithmException;
24372
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
    39
import java.security.PrivilegedAction;
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
    40
import java.security.AccessController;
42351
85ed90be0ae1 8169495: Add a method to set an Authenticator on a HttpURLConnection.
dfuchs
parents: 35306
diff changeset
    41
import java.util.Objects;
479
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
    42
import static sun.net.www.protocol.http.HttpURLConnection.HTTP_CONNECT;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 * DigestAuthentication: Encapsulate an http server authentication using
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 * the "Digest" scheme, as described in RFC2069 and updated in RFC2617
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 * @author Bill Foote
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
class DigestAuthentication extends AuthenticationInfo {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
57956
e0b8b019d2f5 8229997: Apply java.io.Serial annotations in java.base
darcy
parents: 53018
diff changeset
    53
    @java.io.Serial
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
    private static final long serialVersionUID = 100L;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
    private String authMethod;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
32649
2ee9017c7597 8136583: Core libraries should use blessed modifier order
martin
parents: 29986
diff changeset
    58
    private static final String compatPropName = "http.auth.digest." +
24372
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
    59
        "quoteParameters";
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
    60
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
    61
    // true if http.auth.digest.quoteParameters Net property is true
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
    62
    private static final boolean delimCompatFlag;
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
    63
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
    64
    static {
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
    65
        Boolean b = AccessController.doPrivileged(
29986
97167d851fc4 8078467: Update core libraries to use diamond with anonymous classes
darcy
parents: 25859
diff changeset
    66
            new PrivilegedAction<>() {
24372
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
    67
                public Boolean run() {
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
    68
                    return NetProperties.getBoolean(compatPropName);
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
    69
                }
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
    70
            }
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
    71
        );
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
    72
        delimCompatFlag = (b == null) ? false : b.booleanValue();
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
    73
    }
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
    74
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
    // Authentication parameters defined in RFC2617.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
    // One instance of these may be shared among several DigestAuthentication
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
    // instances as a result of a single authorization (for multiple domains)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
57968
8595871a5446 JDK-8229867: first prototype
dfuchs
parents: 57956
diff changeset
    79
    // synchronized should be safe here
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
    static class Parameters implements java.io.Serializable {
1334
21b652819b97 6746836: java.net exception classes don't specify serialVersionUID
chegar
parents: 715
diff changeset
    81
        private static final long serialVersionUID = -3584543755194526252L;
21b652819b97 6746836: java.net exception classes don't specify serialVersionUID
chegar
parents: 715
diff changeset
    82
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
        private boolean serverQop; // server proposed qop=auth
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
        private String opaque;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
        private String cnonce;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
        private String nonce;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
        private String algorithm;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
        private int NCcount=0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
        // The H(A1) string used for MD5-sess
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
        private String  cachedHA1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
        // Force the HA1 value to be recalculated because the nonce has changed
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
        private boolean redoCachedHA1 = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
        private static final int cnonceRepeat = 5;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
        private static final int cnoncelen = 40; /* number of characters in cnonce */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
        private static Random   random;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
        static {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
            random = new Random();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
        Parameters () {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
            serverQop = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
            opaque = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
            algorithm = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
            cachedHA1 = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
            nonce = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
            setNewCnonce();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
        boolean authQop () {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
            return serverQop;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
        synchronized void incrementNC() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
            NCcount ++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
        synchronized int getNCCount () {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
            return NCcount;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
        int cnonce_count = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
        /* each call increments the counter */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
        synchronized String getCnonce () {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
            if (cnonce_count >= cnonceRepeat) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
                setNewCnonce();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
            cnonce_count++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
            return cnonce;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
        synchronized void setNewCnonce () {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
            byte bb[] = new byte [cnoncelen/2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
            char cc[] = new char [cnoncelen];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
            random.nextBytes (bb);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
            for (int  i=0; i<(cnoncelen/2); i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
                int x = bb[i] + 128;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
                cc[i*2]= (char) ('A'+ x/16);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
                cc[i*2+1]= (char) ('A'+ x%16);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
            cnonce = new String (cc, 0, cnoncelen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
            cnonce_count = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
            redoCachedHA1 = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
        synchronized void setQop (String qop) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
            if (qop != null) {
35306
74feccca64cc 8138990: Implementation of HTTP Digest authentication may be more flexible
asmotrak
parents: 32649
diff changeset
   151
                String items[] = qop.split(",");
74feccca64cc 8138990: Implementation of HTTP Digest authentication may be more flexible
asmotrak
parents: 32649
diff changeset
   152
                for (String item : items) {
74feccca64cc 8138990: Implementation of HTTP Digest authentication may be more flexible
asmotrak
parents: 32649
diff changeset
   153
                    if ("auth".equalsIgnoreCase(item.trim())) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
                        serverQop = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
                        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
            serverQop = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
        synchronized String getOpaque () { return opaque;}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
        synchronized void setOpaque (String s) { opaque=s;}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
        synchronized String getNonce () { return nonce;}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
        synchronized void setNonce (String s) {
35306
74feccca64cc 8138990: Implementation of HTTP Digest authentication may be more flexible
asmotrak
parents: 32649
diff changeset
   168
            if (nonce == null || !s.equals(nonce)) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
                nonce=s;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
                NCcount = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
                redoCachedHA1 = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
        synchronized String getCachedHA1 () {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
            if (redoCachedHA1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
                return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
                return cachedHA1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
        synchronized void setCachedHA1 (String s) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
            cachedHA1=s;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
            redoCachedHA1=false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
        synchronized String getAlgorithm () { return algorithm;}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
        synchronized void setAlgorithm (String s) { algorithm=s;}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
    Parameters params;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
     * Create a DigestAuthentication
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
    public DigestAuthentication(boolean isProxy, URL url, String realm,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
                                String authMethod, PasswordAuthentication pw,
42351
85ed90be0ae1 8169495: Add a method to set an Authenticator on a HttpURLConnection.
dfuchs
parents: 35306
diff changeset
   199
                                Parameters params, String authenticatorKey) {
3859
8b82336dedb3 6882594: Remove static dependancy on NTLM authentication
chegar
parents: 1334
diff changeset
   200
        super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
8b82336dedb3 6882594: Remove static dependancy on NTLM authentication
chegar
parents: 1334
diff changeset
   201
              AuthScheme.DIGEST,
8b82336dedb3 6882594: Remove static dependancy on NTLM authentication
chegar
parents: 1334
diff changeset
   202
              url,
42351
85ed90be0ae1 8169495: Add a method to set an Authenticator on a HttpURLConnection.
dfuchs
parents: 35306
diff changeset
   203
              realm,
85ed90be0ae1 8169495: Add a method to set an Authenticator on a HttpURLConnection.
dfuchs
parents: 35306
diff changeset
   204
              Objects.requireNonNull(authenticatorKey));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
        this.authMethod = authMethod;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
        this.pw = pw;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
        this.params = params;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
    public DigestAuthentication(boolean isProxy, String host, int port, String realm,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
                                String authMethod, PasswordAuthentication pw,
42351
85ed90be0ae1 8169495: Add a method to set an Authenticator on a HttpURLConnection.
dfuchs
parents: 35306
diff changeset
   212
                                Parameters params, String authenticatorKey) {
3859
8b82336dedb3 6882594: Remove static dependancy on NTLM authentication
chegar
parents: 1334
diff changeset
   213
        super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
8b82336dedb3 6882594: Remove static dependancy on NTLM authentication
chegar
parents: 1334
diff changeset
   214
              AuthScheme.DIGEST,
8b82336dedb3 6882594: Remove static dependancy on NTLM authentication
chegar
parents: 1334
diff changeset
   215
              host,
8b82336dedb3 6882594: Remove static dependancy on NTLM authentication
chegar
parents: 1334
diff changeset
   216
              port,
42351
85ed90be0ae1 8169495: Add a method to set an Authenticator on a HttpURLConnection.
dfuchs
parents: 35306
diff changeset
   217
              realm,
85ed90be0ae1 8169495: Add a method to set an Authenticator on a HttpURLConnection.
dfuchs
parents: 35306
diff changeset
   218
              Objects.requireNonNull(authenticatorKey));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
        this.authMethod = authMethod;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
        this.pw = pw;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
        this.params = params;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
     * @return true if this authentication supports preemptive authorization
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
     */
4157
558590fb3b49 6893238: Move NTLM and SPNEGO implementations into separate packages
chegar
parents: 3952
diff changeset
   227
    @Override
558590fb3b49 6893238: Move NTLM and SPNEGO implementations into separate packages
chegar
parents: 3952
diff changeset
   228
    public boolean supportsPreemptiveAuthorization() {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
        return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
    /**
24372
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
   233
     * Recalculates the request-digest and returns it.
479
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   234
     *
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   235
     * <P> Used in the common case where the requestURI is simply the
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   236
     * abs_path.
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   237
     *
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   238
     * @param  url
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   239
     *         the URL
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   240
     *
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   241
     * @param  method
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   242
     *         the HTTP method
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   243
     *
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
     * @return the value of the HTTP header this authentication wants set
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
     */
4157
558590fb3b49 6893238: Move NTLM and SPNEGO implementations into separate packages
chegar
parents: 3952
diff changeset
   246
    @Override
558590fb3b49 6893238: Move NTLM and SPNEGO implementations into separate packages
chegar
parents: 3952
diff changeset
   247
    public String getHeaderValue(URL url, String method) {
479
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   248
        return getHeaderValueImpl(url.getFile(), method);
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   249
    }
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   250
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   251
    /**
24372
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
   252
     * Recalculates the request-digest and returns it.
479
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   253
     *
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   254
     * <P> Used when the requestURI is not the abs_path. The exact
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   255
     * requestURI can be passed as a String.
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   256
     *
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   257
     * @param  requestURI
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   258
     *         the Request-URI from the HTTP request line
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   259
     *
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   260
     * @param  method
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   261
     *         the HTTP method
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   262
     *
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   263
     * @return the value of the HTTP header this authentication wants set
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   264
     */
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   265
    String getHeaderValue(String requestURI, String method) {
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   266
        return getHeaderValueImpl(requestURI, method);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
     * Check if the header indicates that the current auth. parameters are stale.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
     * If so, then replace the relevant field with the new value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
     * and return true. Otherwise return false.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
     * returning true means the request can be retried with the same userid/password
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
     * returning false means we have to go back to the user to ask for a new
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
     * username password.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
     */
4157
558590fb3b49 6893238: Move NTLM and SPNEGO implementations into separate packages
chegar
parents: 3952
diff changeset
   277
    @Override
558590fb3b49 6893238: Move NTLM and SPNEGO implementations into separate packages
chegar
parents: 3952
diff changeset
   278
    public boolean isAuthorizationStale (String header) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
        HeaderParser p = new HeaderParser (header);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
        String s = p.findValue ("stale");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
        if (s == null || !s.equals("true"))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
        String newNonce = p.findValue ("nonce");
53018
8bf9268df0e2 8215281: Use String.isEmpty() when applicable in java.base
redestad
parents: 47216
diff changeset
   284
        if (newNonce == null || newNonce.isEmpty()) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
        params.setNonce (newNonce);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
        return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
     * Set header(s) on the given connection.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
     * @param conn The connection to apply the header(s) to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
     * @param p A source of header values for this connection, if needed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
     * @param raw Raw header values for this connection, if needed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
     * @return true if all goes well, false if no headers were set.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
     */
4157
558590fb3b49 6893238: Move NTLM and SPNEGO implementations into separate packages
chegar
parents: 3952
diff changeset
   298
    @Override
558590fb3b49 6893238: Move NTLM and SPNEGO implementations into separate packages
chegar
parents: 3952
diff changeset
   299
    public boolean setHeaders(HttpURLConnection conn, HeaderParser p, String raw) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
        params.setNonce (p.findValue("nonce"));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
        params.setOpaque (p.findValue("opaque"));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
        params.setQop (p.findValue("qop"));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
4150
74dfe4a968c6 6890349: Fix #6870935 in jdk7/pit/b74 caused HttpClinet's check for "proxy capture" attack by-passed.
michaelm
parents: 3952
diff changeset
   304
        String uri="";
479
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   305
        String method;
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   306
        if (type == PROXY_AUTHENTICATION &&
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   307
                conn.tunnelState() == HttpURLConnection.TunnelState.SETUP) {
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   308
            uri = HttpURLConnection.connectRequestURI(conn.getURL());
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   309
            method = HTTP_CONNECT;
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   310
        } else {
4150
74dfe4a968c6 6890349: Fix #6870935 in jdk7/pit/b74 caused HttpClinet's check for "proxy capture" attack by-passed.
michaelm
parents: 3952
diff changeset
   311
            try {
74dfe4a968c6 6890349: Fix #6870935 in jdk7/pit/b74 caused HttpClinet's check for "proxy capture" attack by-passed.
michaelm
parents: 3952
diff changeset
   312
                uri = conn.getRequestURI();
74dfe4a968c6 6890349: Fix #6870935 in jdk7/pit/b74 caused HttpClinet's check for "proxy capture" attack by-passed.
michaelm
parents: 3952
diff changeset
   313
            } catch (IOException e) {}
479
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   314
            method = conn.getMethod();
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   315
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
        if (params.nonce == null || authMethod == null || pw == null || realm == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
        if (authMethod.length() >= 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
            // Method seems to get converted to all lower case elsewhere.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
            // It really does need to start with an upper case letter
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
            // here.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
            authMethod = Character.toUpperCase(authMethod.charAt(0))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
                        + authMethod.substring(1).toLowerCase();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
        String algorithm = p.findValue("algorithm");
53018
8bf9268df0e2 8215281: Use String.isEmpty() when applicable in java.base
redestad
parents: 47216
diff changeset
   328
        if (algorithm == null || algorithm.isEmpty()) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
            algorithm = "MD5";  // The default, accoriding to rfc2069
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
        params.setAlgorithm (algorithm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
        // If authQop is true, then the server is doing RFC2617 and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
        // has offered qop=auth. We do not support any other modes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
        // and if auth is not offered we fallback to the RFC2069 behavior
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
        if (params.authQop()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
            params.setNewCnonce();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
479
c6ddcfc7ff4d 6687282: URLConnection for HTTPS connection through Proxy w/ Digest Authentication gives 400 Bad Request
chegar
parents: 2
diff changeset
   341
        String value = getHeaderValueImpl (uri, method);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
        if (value != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
            conn.setAuthenticationProperty(getHeaderName(), value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
    /* Calculate the Authorization header field given the request URI
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
     * and based on the authorization information in params
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
    private String getHeaderValueImpl (String uri, String method) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
        String response;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
        char[] passwd = pw.getPassword();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
        boolean qop = params.authQop();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
        String opaque = params.getOpaque();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
        String cnonce = params.getCnonce ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
        String nonce = params.getNonce ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
        String algorithm = params.getAlgorithm ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
        params.incrementNC ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
        int  nccount = params.getNCCount ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
        String ncstring=null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
        if (nccount != -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
            ncstring = Integer.toHexString (nccount).toLowerCase();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
            int len = ncstring.length();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
            if (len < 8)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
                ncstring = zeroPad [len] + ncstring;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
            response = computeDigest(true, pw.getUserName(),passwd,realm,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
                                        method, uri, nonce, cnonce, ncstring);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
        } catch (NoSuchAlgorithmException ex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
        String ncfield = "\"";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
        if (qop) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
            ncfield = "\", nc=" + ncstring;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
24372
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
   384
        String algoS, qopS;
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
   385
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
   386
        if (delimCompatFlag) {
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
   387
            // Put quotes around these String value parameters
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
   388
            algoS = ", algorithm=\"" + algorithm + "\"";
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
   389
            qopS = ", qop=\"auth\"";
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
   390
        } else {
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
   391
            // Don't put quotes around them, per the RFC
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
   392
            algoS = ", algorithm=" + algorithm;
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
   393
            qopS = ", qop=auth";
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
   394
        }
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
   395
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
        String value = authMethod
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
                        + " username=\"" + pw.getUserName()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
                        + "\", realm=\"" + realm
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
                        + "\", nonce=\"" + nonce
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
                        + ncfield
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
                        + ", uri=\"" + uri
24372
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
   402
                        + "\", response=\"" + response + "\""
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
   403
                        + algoS;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
        if (opaque != null) {
24372
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
   405
            value += ", opaque=\"" + opaque + "\"";
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
        if (cnonce != null) {
24372
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
   408
            value += ", cnonce=\"" + cnonce + "\"";
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
        if (qop) {
24372
2ff88b15e82e 8034170: src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java
michaelm
parents: 23010
diff changeset
   411
            value += qopS;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
        return value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
    public void checkResponse (String header, String method, URL url)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
                                                        throws IOException {
3952
dc329398de30 6870935: DIGEST proxy authentication fails to connect to URLs with no trailing slash
michaelm
parents: 3859
diff changeset
   418
        checkResponse (header, method, url.getFile());
dc329398de30 6870935: DIGEST proxy authentication fails to connect to URLs with no trailing slash
michaelm
parents: 3859
diff changeset
   419
    }
dc329398de30 6870935: DIGEST proxy authentication fails to connect to URLs with no trailing slash
michaelm
parents: 3859
diff changeset
   420
dc329398de30 6870935: DIGEST proxy authentication fails to connect to URLs with no trailing slash
michaelm
parents: 3859
diff changeset
   421
    public void checkResponse (String header, String method, String uri)
dc329398de30 6870935: DIGEST proxy authentication fails to connect to URLs with no trailing slash
michaelm
parents: 3859
diff changeset
   422
                                                        throws IOException {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
        char[] passwd = pw.getPassword();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
        String username = pw.getUserName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
        boolean qop = params.authQop();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
        String opaque = params.getOpaque();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
        String cnonce = params.cnonce;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
        String nonce = params.getNonce ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
        String algorithm = params.getAlgorithm ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
        int  nccount = params.getNCCount ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
        String ncstring=null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
        if (header == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
            throw new ProtocolException ("No authentication information in response");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
        if (nccount != -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
            ncstring = Integer.toHexString (nccount).toUpperCase();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
            int len = ncstring.length();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
            if (len < 8)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
                ncstring = zeroPad [len] + ncstring;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
            String expected = computeDigest(false, username,passwd,realm,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
                                        method, uri, nonce, cnonce, ncstring);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
            HeaderParser p = new HeaderParser (header);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
            String rspauth = p.findValue ("rspauth");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
            if (rspauth == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
                throw new ProtocolException ("No digest in response");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
            if (!rspauth.equals (expected)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
                throw new ProtocolException ("Response digest invalid");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
            /* Check if there is a nextnonce field */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
            String nextnonce = p.findValue ("nextnonce");
53018
8bf9268df0e2 8215281: Use String.isEmpty() when applicable in java.base
redestad
parents: 47216
diff changeset
   456
            if (nextnonce != null && !nextnonce.isEmpty()) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
                params.setNonce (nextnonce);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
        } catch (NoSuchAlgorithmException ex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
            throw new ProtocolException ("Unsupported algorithm in response");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
    private String computeDigest(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
                        boolean isRequest, String userName, char[] password,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
                        String realm, String connMethod,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
                        String requestURI, String nonceString,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
                        String cnonce, String ncValue
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
                    ) throws NoSuchAlgorithmException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
        String A1, HashA1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
        String algorithm = params.getAlgorithm ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
        boolean md5sess = algorithm.equalsIgnoreCase ("MD5-sess");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
        MessageDigest md = MessageDigest.getInstance(md5sess?"MD5":algorithm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
        if (md5sess) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
            if ((HashA1 = params.getCachedHA1 ()) == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
                String s = userName + ":" + realm + ":";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
                String s1 = encode (s, password, md);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
                A1 = s1 + ":" + nonceString + ":" + cnonce;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
                HashA1 = encode(A1, null, md);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
                params.setCachedHA1 (HashA1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
            A1 = userName + ":" + realm + ":";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
            HashA1 = encode(A1, password, md);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
        String A2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
        if (isRequest) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
            A2 = connMethod + ":" + requestURI;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
            A2 = ":" + requestURI;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
        String HashA2 = encode(A2, null, md);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
        String combo, finalHash;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
        if (params.authQop()) { /* RRC2617 when qop=auth */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
            combo = HashA1+ ":" + nonceString + ":" + ncValue + ":" +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
                        cnonce + ":auth:" +HashA2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
        } else { /* for compatibility with RFC2069 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
            combo = HashA1 + ":" +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
                       nonceString + ":" +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
                       HashA2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
        finalHash = encode(combo, null, md);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
        return finalHash;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
32649
2ee9017c7597 8136583: Core libraries should use blessed modifier order
martin
parents: 29986
diff changeset
   514
    private static final char charArray[] = {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
        '0', '1', '2', '3', '4', '5', '6', '7',
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
        '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
    };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
32649
2ee9017c7597 8136583: Core libraries should use blessed modifier order
martin
parents: 29986
diff changeset
   519
    private static final String zeroPad[] = {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
        // 0         1          2         3        4       5      6     7
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
        "00000000", "0000000", "000000", "00000", "0000", "000", "00", "0"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
    };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
    private String encode(String src, char[] passwd, MessageDigest md) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
            md.update(src.getBytes("ISO-8859-1"));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
        } catch (java.io.UnsupportedEncodingException uee) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
            assert false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
        if (passwd != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
            byte[] passwdBytes = new byte[passwd.length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
            for (int i=0; i<passwd.length; i++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
                passwdBytes[i] = (byte)passwd[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
            md.update(passwdBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
            Arrays.fill(passwdBytes, (byte)0x00);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
        byte[] digest = md.digest();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
24969
afa6934dd8e8 8041679: Replace uses of StringBuffer with StringBuilder within core library classes
psandoz
parents: 24372
diff changeset
   539
        StringBuilder res = new StringBuilder(digest.length * 2);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
        for (int i = 0; i < digest.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
            int hashchar = ((digest[i] >>> 4) & 0xf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
            res.append(charArray[hashchar]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
            hashchar = (digest[i] & 0xf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
            res.append(charArray[hashchar]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
        return res.toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
}