19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.net.http;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * HttpAuthHeader: a class to store HTTP authentication-header parameters.
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For more information, see: RFC 2617: HTTP Authentication.
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide}
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class HttpAuthHeader {
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Possible HTTP-authentication header tokens to search for:
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final static String BASIC_TOKEN = "Basic";
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final static String DIGEST_TOKEN = "Digest";
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final static String REALM_TOKEN = "realm";
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final static String NONCE_TOKEN = "nonce";
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final static String STALE_TOKEN = "stale";
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final static String OPAQUE_TOKEN = "opaque";
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final static String QOP_TOKEN = "qop";
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final static String ALGORITHM_TOKEN = "algorithm";
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * An authentication scheme. We currently support two different schemes:
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * HttpAuthHeader.BASIC  - basic, and
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * HttpAuthHeader.DIGEST - digest (algorithm=MD5, QOP="auth").
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mScheme;
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int UNKNOWN = 0;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int BASIC = 1;
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int DIGEST = 2;
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * A flag, indicating that the previous request from the client was
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * rejected because the nonce value was stale. If stale is TRUE
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * (case-insensitive), the client may wish to simply retry the request
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * with a new encrypted response, without reprompting the user for a
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * new username and password.
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mStale;
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * A string to be displayed to users so they know which username and
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * password to use.
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private String mRealm;
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * A server-specified data string which should be uniquely generated
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * each time a 401 response is made.
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private String mNonce;
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * A string of data, specified by the server, which should be returned
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  by the client unchanged in the Authorization header of subsequent
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * requests with URIs in the same protection space.
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private String mOpaque;
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This directive is optional, but is made so only for backward
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * compatibility with RFC 2069 [6]; it SHOULD be used by all
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * implementations compliant with this version of the Digest scheme.
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * If present, it is a quoted string of one or more tokens indicating
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the "quality of protection" values supported by the server.  The
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * value "auth" indicates authentication; the value "auth-int"
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * indicates authentication with integrity protection.
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private String mQop;
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * A string indicating a pair of algorithms used to produce the digest
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and a checksum. If this is not present it is assumed to be "MD5".
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private String mAlgorithm;
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Is this authentication request a proxy authentication request?
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mIsProxy;
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Username string we get from the user.
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private String mUsername;
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Password string we get from the user.
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private String mPassword;
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Creates a new HTTP-authentication header object from the
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * input header string.
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The header string is assumed to contain parameters of at
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * most one authentication-scheme (ensured by the caller).
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public HttpAuthHeader(String header) {
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (header != null) {
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            parseHeader(header);
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return True iff this is a proxy authentication header.
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isProxy() {
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mIsProxy;
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Marks this header as a proxy authentication header.
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setProxy() {
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIsProxy = true;
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The username string.
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public String getUsername() {
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mUsername;
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the username string.
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setUsername(String username) {
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mUsername = username;
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The password string.
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public String getPassword() {
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mPassword;
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the password string.
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setPassword(String password) {
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPassword = password;
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return True iff this is the  BASIC-authentication request.
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isBasic () {
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mScheme == BASIC;
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return True iff this is the DIGEST-authentication request.
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isDigest() {
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mScheme == DIGEST;
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The authentication scheme requested. We currently
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * support two schemes:
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * HttpAuthHeader.BASIC  - basic, and
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * HttpAuthHeader.DIGEST - digest (algorithm=MD5, QOP="auth").
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getScheme() {
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mScheme;
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return True if indicating that the previous request from
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the client was rejected because the nonce value was stale.
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean getStale() {
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mStale;
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The realm value or null if there is none.
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public String getRealm() {
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mRealm;
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The nonce value or null if there is none.
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public String getNonce() {
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mNonce;
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The opaque value or null if there is none.
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public String getOpaque() {
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mOpaque;
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The QOP ("quality-of_protection") value or null if
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * there is none. The QOP value is always lower-case.
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public String getQop() {
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mQop;
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The name of the algorithm used or null if there is
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * none. By default, MD5 is used.
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public String getAlgorithm() {
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mAlgorithm;
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return True iff the authentication scheme requested by the
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * server is supported; currently supported schemes:
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * BASIC,
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * DIGEST (only algorithm="md5", no qop or qop="auth).
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isSupportedScheme() {
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // it is a good idea to enforce non-null realms!
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mRealm != null) {
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mScheme == BASIC) {
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mScheme == DIGEST) {
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        mAlgorithm.equals("md5") &&
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        (mQop == null || mQop.equals("auth"));
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Parses the header scheme name and then scheme parameters if
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the scheme is supported.
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void parseHeader(String header) {
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (HttpLog.LOGV) {
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            HttpLog.v("HttpAuthHeader.parseHeader(): header: " + header);
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (header != null) {
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String parameters = parseScheme(header);
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (parameters != null) {
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // if we have a supported scheme
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mScheme != UNKNOWN) {
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    parseParameters(parameters);
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Parses the authentication scheme name. If we have a Digest
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * scheme, sets the algorithm value to the default of MD5.
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The authentication scheme parameters string to be
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * parsed later (if the scheme is supported) or null if failed
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to parse the scheme (the header value is null?).
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private String parseScheme(String header) {
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (header != null) {
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int i = header.indexOf(' ');
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (i >= 0) {
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String scheme = header.substring(0, i).trim();
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (scheme.equalsIgnoreCase(DIGEST_TOKEN)) {
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mScheme = DIGEST;
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // md5 is the default algorithm!!!
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mAlgorithm = "md5";
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (scheme.equalsIgnoreCase(BASIC_TOKEN)) {
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        mScheme = BASIC;
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return header.substring(i + 1);
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Parses a comma-separated list of authentification scheme
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * parameters.
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void parseParameters(String parameters) {
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (HttpLog.LOGV) {
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            HttpLog.v("HttpAuthHeader.parseParameters():" +
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      " parameters: " + parameters);
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (parameters != null) {
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int i;
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            do {
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                i = parameters.indexOf(',');
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (i < 0) {
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // have only one parameter
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    parseParameter(parameters);
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    parseParameter(parameters.substring(0, i));
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    parameters = parameters.substring(i + 1);
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } while (i >= 0);
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Parses a single authentication scheme parameter. The parameter
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * string is expected to follow the format: PARAMETER=VALUE.
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void parseParameter(String parameter) {
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (parameter != null) {
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // here, we are looking for the 1st occurence of '=' only!!!
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int i = parameter.indexOf('=');
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (i >= 0) {
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String token = parameter.substring(0, i).trim();
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String value =
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    trimDoubleQuotesIfAny(parameter.substring(i + 1).trim());
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (HttpLog.LOGV) {
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    HttpLog.v("HttpAuthHeader.parseParameter():" +
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                              " token: " + token +
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                              " value: " + value);
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (token.equalsIgnoreCase(REALM_TOKEN)) {
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mRealm = value;
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (mScheme == DIGEST) {
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        parseParameter(token, value);
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * If the token is a known parameter name, parses and initializes
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the token value.
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void parseParameter(String token, String value) {
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (token != null && value != null) {
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (token.equalsIgnoreCase(NONCE_TOKEN)) {
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mNonce = value;
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (token.equalsIgnoreCase(STALE_TOKEN)) {
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                parseStale(value);
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (token.equalsIgnoreCase(OPAQUE_TOKEN)) {
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mOpaque = value;
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (token.equalsIgnoreCase(QOP_TOKEN)) {
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mQop = value.toLowerCase();
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (token.equalsIgnoreCase(ALGORITHM_TOKEN)) {
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mAlgorithm = value.toLowerCase();
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Parses and initializes the 'stale' paramer value. Any value
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * different from case-insensitive "true" is considered "false".
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void parseStale(String value) {
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (value != null) {
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (value.equalsIgnoreCase("true")) {
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mStale = true;
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Trims double-quotes around a parameter value if there are any.
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The string value without the outermost pair of double-
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * quotes or null if the original value is null.
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static private String trimDoubleQuotesIfAny(String value) {
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (value != null) {
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int len = value.length();
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (len > 2 &&
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                value.charAt(0) == '\"' && value.charAt(len - 1) == '\"') {
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return value.substring(1, len - 1);
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return value;
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
423