FileDocCategorySizeDatePackage
AuthenticationHeader.javaAPI DocphoneME MR2 API (J2ME)17246Wed May 02 18:00:42 BST 2007gov.nist.siplite.header

AuthenticationHeader.java

/*
 * Portions Copyright  2000-2007 Sun Microsystems, Inc. All Rights
 * Reserved.  Use is subject to license terms.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version
 * 2 only, as published by the Free Software Foundation.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License version 2 for more details (a copy is
 * included at /legal/license.txt).
 * 
 * You should have received a copy of the GNU General Public License
 * version 2 along with this work; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 * 
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
 * Clara, CA 95054 or visit www.sun.com if you need additional
 * information or have any questions.
 */
/*
 */
package gov.nist.siplite.header;

import gov.nist.core.*;
import gov.nist.siplite.address.*;

/**
 * The generic AuthenticationHeader
 *
 *
 * <a href="{@docRoot}/uncopyright.html">This code is in the public domain.</a>
 *
 */
public abstract class AuthenticationHeader extends ParametersHeader {
    /** Domain header label. */
    public static String DOMAIN = "domain";
    /** Realm header label. */
    public static String REALM = "realm";
    /** Opaque header. */
    public static String OPAQUE = "opaque";
    /** Algorithm header label. */
    public static String ALGORITHM = "algorithm";
    /** Qop header (RFC?). */
    public static String QOP = "qop";
    /** Stale header (RFC?). */
    public static String STALE = "stale";
    /** Signature header. */
    public static String SIGNATURE = "signature";
    /** Response header. */
    public static String RESPONSE = "response";
    /** Signed byte header. */
    public static String SIGNED_BY = "signed-by";
    /** NC header (RFC?). */
    public static String NC = "nc";
    /** URI header. */
    public static String URI = "uri";
    /** User name header. */
    public static String USERNAME = "username";
    /** C-nonce header. */
    public static String CNONCE = "cnonce";
    /** Nonce header. */
    public static String NONCE = "nonce";
    /** Digest header. */
    public static String DIGEST = "Digest";
    /** Next nonce header. */
    public static String NEXT_NONCE = "next-nonce";

    /** Current protocol scheme. */
    protected String scheme;

    /**
     * Constructor with header name.
     * @param name header to process
     */
    public AuthenticationHeader(String name) {
        super(name);
        parameters.setSeparator(Separators.COMMA); // oddball
        this.scheme = DIGEST;
    }

    /** Default constructor. */
    public AuthenticationHeader() {
        super();
        parameters.setSeparator(Separators.COMMA);
    }

    /**
     * Sets the specified parameter.
     * @param nv parameter's name/value pair
     */
    public void setParameter(NameValue nv) {
        Object val = nv.getValue();
        setParameter(nv.getName(), (val == null) ? null : val.toString());
    }

    /**
     * Sets the specified parameter.
     * @param name name of the parameter
     * @param value value of the parameter.
     */
    public void setParameter(String name, String value)
            throws IllegalArgumentException {
        NameValue nv =
                super.parameters.getNameValue(name.toLowerCase());

        boolean quotedParam = false;
        
        if (isQuoted(name)) {
            
            if (value == null) {
                throw new NullPointerException("null value");
            }
            
            quotedParam = true;
            boolean quoteStart = value.startsWith(Separators.DOUBLE_QUOTE);
            boolean quoteEnd = value.endsWith(Separators.DOUBLE_QUOTE);
            
            if ((quoteStart && !quoteEnd) || (!quoteStart && quoteEnd)) {
                throw new IllegalArgumentException
                    (value + " : Unexpected DOUBLE_QUOTE");
            }
            
            if (quoteStart) { // quoteEnd is true in this case
                value = value.substring(1, value.length() - 1);
            }
        }
        
        if (nv == null) {
            nv = new NameValue(name.toLowerCase(), value);

            if (quotedParam) {
                nv.setQuotedValue();
            }

            super.setParameter(nv);
        } else {
            nv.setValue(value);
        }

    }
    
    /**
     * Returns the value of the named parameter, or null if it is not set. A
     * zero-length String indicates flag parameter.
     *
     * @param name name of parameter to retrieve
     * @return the value of specified parameter
     */
    public String getParameter(String name) {
        String returnValue = super.getParameter(name);
        if ((returnValue != null) && isQuoted(name)) { // remove quotes
            returnValue = returnValue.substring(1, returnValue.length() - 1);
        }
        return returnValue;
        
    }
    
    /**
     * Returns true if parameter must be quoted, else - false.
     * zero-length String indicates flag parameter.
     *
     * @param name name of parameter to retrieve
     * @return flag of parameter (quoted or not)
     */
    private boolean isQuoted(String name) {
        if (equalsIgnoreCase(name, QOP) ||
                equalsIgnoreCase(name, REALM) ||
                equalsIgnoreCase(name, URI) ||
                equalsIgnoreCase(name, CNONCE) ||
                equalsIgnoreCase(name, NONCE) ||
                equalsIgnoreCase(name, USERNAME) ||
                equalsIgnoreCase(name, DOMAIN) ||
                equalsIgnoreCase(name, OPAQUE) ||
                equalsIgnoreCase(name, NEXT_NONCE) ||
                equalsIgnoreCase(name, RESPONSE)) {
            return true;
        }
        return false;
    }

    /**
     * Encodes in canonical form.
     * @return canonical string.
     */
    public String encodeBody() {
        return this.scheme + Separators.SP + parameters.encode();
    }

    /**
     * Sets the scheme of the challenge information for this
     * AuthenticationHeaderHeader. For example, Digest.
     *
     * @param scheme - the new string value that identifies the challenge
     * information scheme.
     * @since v1.1
     */
    public void setScheme(String scheme) {
        this.scheme = scheme;
    }

    /**
     * Returns the scheme of the challenge information for this
     * AuthenticationHeaderHeader.
     *
     * @return the string value of the challenge information.
     * @since v1.1
     */
    public String getScheme() {
        return scheme;
    }

    /**
     * Sets the Realm of the WWWAuthenicateHeader to the <var>realm</var>
     * parameter value. Realm strings MUST be globally unique. It is
     * RECOMMENDED that a realm string contain a hostname or domain name.
     * Realm strings SHOULD present a human-readable identifier that can be
     * rendered to a user.
     *
     * @param realm the new Realm String of this WWWAuthenicateHeader.
     * @throws ParseException which signals that an error has been reached
     * unexpectedly while parsing the realm.
     * @since v1.1
     */
    public void setRealm(String realm) {
        if (realm == null)
            throw new NullPointerException("null realm");
        setParameter(REALM, realm);
    }

    /**
     * Returns the Realm value of this WWWAuthenicateHeader. This convenience
     * method returns only the realm of the complete Challenge.
     *
     * @return the String representing the Realm information, null if value is
     * not set.
     * @since v1.1
     */
    public String getRealm() {
        return getParameter(REALM);
    }

    /**
     * Sets the Nonce of the WWWAuthenicateHeader to the <var>nonce</var>
     * parameter value.
     *
     * @param nonce - the new nonce String of this WWWAuthenicateHeader.
     * @throws ParseException which signals that an error has been reached
     * unexpectedly while parsing the nonce value.
     * @since v1.1
     */
    public void setNonce(String nonce) {
        if (nonce == null)
            throw new NullPointerException("null nonce");
        setParameter(NONCE, nonce);
    }

    /**
     * Returns the Nonce value of this WWWAuthenicateHeader.
     *
     * @return the String representing the nonce information, null if value is
     * not set.
     * @since v1.1
     */
    public String getNonce() {
        return getParameter(NONCE);
    }

    /**
     * Sets the URI of the WWWAuthenicateHeader to the <var>uri</var>
     * parameter value.
     *
     * @param uri - the new URI of this WWWAuthenicateHeader.
     * @since v1.1
     */
    public void setURI(URI uri) {
        if (uri != null) {
            NameValue nv = new NameValue(URI, uri);
            nv.setQuotedValue();
            super.parameters.set(nv);
        } else {
            throw new NullPointerException("Null URI");
        }
    }

    /**
     * Returns the URI value of this WWWAuthenicateHeader,
     * for example DigestURI.
     *
     * @return the URI representing the URI information, null if value is
     * not set.
     * @since v1.1
     */
    public URI getURI() {
        return getParameterAsURI(URI);
    }

    /**
     * Sets the Algorithm of the WWWAuthenicateHeader to the new
     * <var>algorithm</var> parameter value.
     *
     * @param algorithm - the new algorithm String of this WWWAuthenicateHeader.
     * @throws ParseException which signals that an error has been reached
     * unexpectedly while parsing the algorithm value.
     * @since v1.1
     */
    public void setAlgorithm(String algorithm) throws ParseException {
        if (algorithm == null)
            throw new NullPointerException("null arg");
        setParameter(ALGORITHM, algorithm);
    }

    /**
     * Returns the Algorithm value of this WWWAuthenicateHeader.
     *
     * @return the String representing the Algorithm information, null if the
     * value is not set.
     * @since v1.1
     */
    public String getAlgorithm() {
        return getParameter(ALGORITHM);
    }

    /**
     * Sets the Qop value of the WWWAuthenicateHeader to the new
     * <var>qop</var> parameter value.
     *
     * @param qop - the new Qop string of this WWWAuthenicateHeader.
     * @throws ParseException which signals that an error has been reached
     * unexpectedly while parsing the Qop value.
     * @since v1.1
     */
    public void setQop(String qop) throws ParseException {
        if (qop == null)
            throw new NullPointerException("null arg");
        setParameter(QOP, qop);
    }

    /**
     * Returns the Qop value of this WWWAuthenicateHeader.
     *
     * @return the string representing the Qop information, null if the
     * value is not set.
     * @since v1.1
     */
    public String getQop() {
        return getParameter(QOP);
    }

    /**
     * Sets the Opaque value of the WWWAuthenicateHeader to the new
     * <var>opaque</var> parameter value.
     *
     * @param opaque - the new Opaque string of this WWWAuthenicateHeader.
     * @throws ParseException which signals that an error has been reached
     * unexpectedly while parsing the opaque value.
     * @since v1.1
     */
    public void setOpaque(String opaque) throws ParseException {
        if (opaque == null)
            throw new NullPointerException("null arg");
        setParameter(OPAQUE, opaque);
    }

    /**
     * Returns the Opaque value of this WWWAuthenicateHeader.
     *
     * @return the String representing the Opaque information, null if the
     * value is not set.
     * @since v1.1
     */
    public String getOpaque() {
        return getParameter(OPAQUE);
    }

    /**
     * Sets the Domain of the WWWAuthenicateHeader to the <var>domain</var>
     * parameter value.
     *
     * @param domain - the new Domain string of this WWWAuthenicateHeader.
     * @throws ParseException which signals that an error has been reached
     * unexpectedly while parsing the domain.
     * @since v1.1
     */
    public void setDomain(String domain) throws ParseException {
        if (domain == null)
            throw new NullPointerException("null arg");
        setParameter(DOMAIN, domain);
    }


    /**
     * Returns the Domain value of this WWWAuthenicateHeader.
     *
     * @return the String representing the Domain information, null if value is
     * not set.
     * @since v1.1
     */
    public String getDomain() {
        return getParameter(DOMAIN);
    }

    /**
     * Sets the value of the stale parameter of the WWWAuthenicateHeader to the
     * <var>stale</var> parameter value.
     *
     * @param stale - the new boolean value of the stale parameter.
     * @since v1.1
     */
    public void setStale(boolean stale) {
        setParameter(new NameValue(STALE, new Boolean(stale)));
    }

    /**
     * Returns the boolean value of the state paramater of this
     * WWWAuthenicateHeader.
     *
     * @return the boolean representing if the challenge is stale.
     * @since v1.1
     */
    public boolean isStale() {
        return this.getParameterAsBoolean(STALE);
    }

    /**
     * Set the CNonce.
     *
     * @param cnonce -- a nonce string.
     */
    public void setCNonce(String cnonce) throws ParseException {
        this.setParameter(CNONCE, cnonce);
    }

    /**
     * Get the CNonce.
     *
     * @return the cnonce value.
     */
    public String getCNonce() {
        return getParameter(CNONCE);
    }

    /**
     * Counts the nonce.
     * @return the count of nonces
     */
    public int getNonceCount() {
        return this.getParameterAsHexInt(NC);

    }

    /**
     * Set the nonce count parameter.
     *
     * @param nonceCount -- nonce count to set.
     */

    public void setNonceCount(int nonceCount)
    throws ParseException, IllegalArgumentException {
        if (nonceCount < 0)
            throw new IllegalArgumentException("bad value");

        String nc = Integer.toHexString(nonceCount);

        String base = "00000000";
        nc = base.substring(0, 8 - nc.length()) + nc;
        this.setParameter(NC, nc);

    }

    /**
     * Gets the RESPONSE value (or null if it does not exist).
     *
     * @return String response parameter value.
     */
    public String getResponse() {
        return (String) getParameterValue(RESPONSE);
    }


    /**
     * Sets the Response.
     *
     * @param response to set.
     */
    public void setResponse(String response) throws ParseException {
        if (response == null)
            throw new NullPointerException("Null parameter");
        this.setParameter(RESPONSE, response);
    }


    /**
     * Returns the Username value of this AuthorizationHeader.
     * This convenience method returns only the username of the
     * complete Response.
     *
     * @return the String representing the Username information,
     * null if value is not set.
     *
     * @since JAIN SIP v1.1
     *
     */
    public String getUsername() {
        return (String) getParameter
                (USERNAME);
    }

    /**
     * Sets the Username of the AuthorizationHeader to
     * the <var>username</var> parameter value.
     *
     * @param username the new Username String of this AuthorizationHeader.
     *
     * @throws ParseException which signals that an error has been reached
     *
     * unexpectedly while parsing the username.
     *
     * @since JAIN SIP v1.1
     *
     */
    public void setUsername(String username) {
        this.setParameter(USERNAME, username);
    }

    /**
     * Clone - do a deep copy.
     * @return Object Authorization
     */
    public Object clone() {
        Exception ex = null;
        try {
            AuthenticationHeader retval = (AuthenticationHeader)
            this.getClass().newInstance();
            if (this.scheme != null) retval.scheme = new String(this.scheme);
            if (this.parameters != null)
                retval.parameters = (NameValueList)parameters.clone();
            return retval;
        } catch (InstantiationException ie) {
            ex = ie;
        } catch (IllegalAccessException iae) {
            ex = iae;
        }
        if (ex != null) {
            InternalErrorHandler.handleException(ex);
        }
        return null;
    }

    /**
     * Compares for equivalence.
     * @param that object to compare
     * @return true if object matches
     */
    public boolean equals(Object that) {
        if (! that.getClass().equals(this.getClass())) {
            return false;
        } else {
            AuthenticationHeader other = (AuthenticationHeader) that;
            return (equalsIgnoreCase(this.scheme, other.scheme) &&
                    this.parameters.equals(other.parameters));
        }
    }

    /**
     * Gets the value of the header (just returns the scheme).
     * @return the scheme object.
     */
    public Object getValue() {
        return getScheme();

    }

}