/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.geronimo.javamail.authentication;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.ArrayList;

import javax.mail.AuthenticationFailedException;
import javax.mail.MessagingException;

import org.apache.geronimo.mail.util.Base64;
import org.apache.geronimo.mail.util.Hex;

/**
 * Process a DIGEST-MD5 authentication, using the challenge/response mechanisms.
 */
public class DigestMD5Authenticator implements ClientAuthenticator {

    protected static final int AUTHENTICATE_CLIENT = 0;

    protected static final int AUTHENTICATE_SERVER = 1;

    protected static final int AUTHENTICATION_COMPLETE = 2;

    // the host server name
    protected String host;

    // the user we're authenticating
    protected String username;

    // the user's password (the "shared secret")
    protected String password;

    // the target login realm
    protected String realm;

    // our message digest for processing the challenges.
    MessageDigest digest;

    // the string we send to the server on the first challenge.
    protected String clientResponse;

    // the response back from an authentication challenge.
    protected String authenticationResponse = null;

    // our list of realms received from the server (normally just one).
    protected ArrayList realms;

    // the nonce value sent from the server
    protected String nonce;

    // indicates whether we've gone through the entire challenge process.
    protected int stage = AUTHENTICATE_CLIENT;

    /**
     * Main constructor.
     *
     * @param host
     *            The server host name.
     * @param username
     *            The login user name.
     * @param password
     *            The login password.
     * @param realm
     *            The target login realm (can be null).
     */
    public DigestMD5Authenticator(String host, String username, String password, String realm) {
        this.host = host;
        this.username = username;
        this.password = password;
        this.realm = realm;
    }

    /**
     * Respond to the hasInitialResponse query. This mechanism does not have an
     * initial response.
     *
     * @return Always returns false.
     */
    public boolean hasInitialResponse() {
        return false;
    }

    /**
     * Indicate whether the challenge/response process is complete.
     *
     * @return True if the last challenge has been processed, false otherwise.
     */
    public boolean isComplete() {
        return stage == AUTHENTICATION_COMPLETE;
    }

    /**
     * Retrieve the authenticator mechanism name.
     *
     * @return Always returns the string "DIGEST-MD5"
     */
    public String getMechanismName() {
        return "DIGEST-MD5";
    }

    /**
     * Evaluate a DIGEST-MD5 login challenge, returning the a result string that
     * should satisfy the clallenge.
     *
     * @param challenge
     *            The decoded challenge data, as a string.
     *
     * @return A formatted challege response, as an array of bytes.
     * @exception MessagingException
     */
    public byte[] evaluateChallenge(byte[] challenge) throws MessagingException {

        // DIGEST-MD5 authentication goes in two stages. First state involves us
        // validating with the
        // server, the second stage is the server validating with us, using the
        // shared secret.
        switch (stage) {
        // stage one of the process.
        case AUTHENTICATE_CLIENT: {
            // get the response and advance the processing stage.
            byte[] response = authenticateClient(challenge);
            stage = AUTHENTICATE_SERVER;
            return response;
        }

        // stage two of the process.
        case AUTHENTICATE_SERVER: {
            // get the response and advance the processing stage to completed.
            byte[] response = authenticateServer(challenge);
            stage = AUTHENTICATION_COMPLETE;
            return response;
        }

        // should never happen.
        default:
            throw new MessagingException("Invalid LOGIN challenge");
        }
    }

    /**
     * Evaluate a DIGEST-MD5 login server authentication challenge, returning
     * the a result string that should satisfy the clallenge.
     *
     * @param challenge
     *            The decoded challenge data, as a string.
     *
     * @return A formatted challege response, as an array of bytes.
     * @exception MessagingException
     */
    public byte[] authenticateServer(byte[] challenge) throws MessagingException {
        // parse the challenge string and validate.
        if (!parseChallenge(challenge)) {
            return null;
        }

        try {
            // like all of the client validation steps, the following is order
            // critical.
            // first add in the URI information.
            digest.update((":smtp/" + host).getBytes("US-ASCII"));
            // now mix in the response we sent originally
            String responseString = clientResponse + new String(Hex.encode(digest.digest()), "US-ASCII");
            digest.update(responseString.getBytes("US-ASCII"));

            // now convert that into a hex encoded string.
            String validationText = new String(Hex.encode(digest.digest()), "US-ASCII");

            // if everything went well, this calculated value should match what
            // we got back from the server.
            // our response back is just a null string....
            if (validationText.equals(authenticationResponse)) {
                return new byte[0];
            }
            throw new AuthenticationFailedException("Invalid DIGEST-MD5 response from server");
        } catch (UnsupportedEncodingException e) {
            throw new MessagingException("Invalid character encodings");
        }

    }

    /**
     * Evaluate a DIGEST-MD5 login client authentication challenge, returning
     * the a result string that should satisfy the clallenge.
     *
     * @param challenge
     *            The decoded challenge data, as a string.
     *
     * @return A formatted challege response, as an array of bytes.
     * @exception MessagingException
     */
    public byte[] authenticateClient(byte[] challenge) throws MessagingException {
        // parse the challenge string and validate.
        if (!parseChallenge(challenge)) {
            return null;
        }

        SecureRandom randomGenerator;
        // before doing anything, make sure we can get the required crypto
        // support.
        try {
            randomGenerator = new SecureRandom();
            digest = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            throw new MessagingException("Unable to access cryptography libraries");
        }

        // if not configured for a realm, take the first realm from the list, if
        // any
        if (realm == null) {
            // if not handed any realms, just use the host name.
            if (realms.isEmpty()) {
                realm = host;
            } else {
                // pretty arbitrary at this point, so just use the first one.
                realm = (String) realms.get(0);
            }
        }

        // use secure random to generate a collection of bytes. that is our
        // cnonce value.
        byte[] cnonceBytes = new byte[32];

        randomGenerator.nextBytes(cnonceBytes);

        try {
            // and get this as a base64 encoded string.
            String cnonce = new String(Base64.encode(cnonceBytes), "US-ASCII");

            // Now the digest computation part. This gets a bit tricky, and must be
            // done in strict order.
            // this identifies where we're logging into.
            String idString = username + ":" + realm + ":" + password;
            // we get a digest for this string, then use the digest for the
            // first stage
            // of the next digest operation.
            digest.update(digest.digest(idString.getBytes("US-ASCII")));

            // now we add the nonce strings to the digest.
            String nonceString = ":" + nonce + ":" + cnonce;
            digest.update(nonceString.getBytes("US-ASCII"));

            // hex encode this digest, and add on the string values
            // NB, we only support "auth" for the quality of protection value
            // (qop). We save this in an
            // instance variable because we'll need this to validate the
            // response back from the server.
            clientResponse = new String(Hex.encode(digest.digest()), "US-ASCII") + ":" + nonce + ":00000001:" + cnonce + ":auth:";

            // now we add in identification values to the hash.
            String authString = "AUTHENTICATE:smtp/" + host;
            digest.update(authString.getBytes("US-ASCII"));

            // this gets added on to the client response
            String responseString = clientResponse + new String(Hex.encode(digest.digest()), "US-ASCII");
            // and this gets fed back into the digest
            digest.update(responseString.getBytes("US-ASCII"));

            // and FINALLY, the challege digest is hex encoded for sending back
            // to the server (whew).
            String challengeResponse = new String(Hex.encode(digest.digest()), "US-ASCII");

            // now finally build the keyword/value part of the challenge
            // response. These can be
            // in any order.
            StringBuffer response = new StringBuffer();

            response.append("username=\"");
            response.append(username);
            response.append("\"");

            response.append(",realm=\"");
            response.append(realm);
            response.append("\"");

            // we only support auth qop values, and the nonce-count (nc) is
            // always 1.
            response.append(",qop=auth");
            response.append(",nc=00000001");

            response.append(",nonce=\"");
            response.append(nonce);
            response.append("\"");

            response.append(",cnonce=\"");
            response.append(cnonce);
            response.append("\"");

            response.append(",digest-uri=\"smtp/");
            response.append(host);
            response.append("\"");

            response.append(",response=");
            response.append(challengeResponse);

            return response.toString().getBytes("US-ASCII");

        } catch (UnsupportedEncodingException e) {
            throw new MessagingException("Invalid character encodings");
        }
    }

    /**
     * Parse the challege string, pulling out information required for our
     * challenge response.
     *
     * @param challenge
     *            The challenge data.
     *
     * @return true if there were no errors parsing the string, false otherwise.
     * @exception MessagingException
     */
    protected boolean parseChallenge(byte[] challenge) throws MessagingException {
        realms = new ArrayList();

        DigestParser parser = null;
        try {
            parser = new DigestParser(new String(challenge, "US-ASCII"));
        } catch (UnsupportedEncodingException ex) {
        }

        // parse the entire string...but we ignore everything but the options we
        // support.
        while (parser.hasMore()) {
            NameValuePair pair = parser.parseNameValuePair();

            String name = pair.name;

            // realm to add to our list?
            if (name.equalsIgnoreCase("realm")) {
                realms.add(pair.value);
            }
            // we need the nonce to evaluate the client challenge.
            else if (name.equalsIgnoreCase("nonce")) {
                nonce = pair.value;
            }
            // rspauth is the challenge replay back, which allows us to validate
            // that server is also legit.
            else if (name.equalsIgnoreCase("rspauth")) {
                authenticationResponse = pair.value;
            }
        }

        return true;
    }

    /**
     * Inner class for parsing a DIGEST-MD5 challenge string, which is composed
     * of "name=value" pairs, separated by "," characters.
     */
    class DigestParser {
        // the challenge we're parsing
        String challenge;

        // length of the challenge
        int length;

        // current parsing position
        int position;

        /**
         * Normal constructor.
         *
         * @param challenge
         *            The challenge string to be parsed.
         */
        public DigestParser(String challenge) {
            this.challenge = challenge;
            this.length = challenge.length();
            position = 0;
        }

        /**
         * Test if there are more values to parse.
         *
         * @return true if we've not reached the end of the challenge string,
         *         false if the challenge has been completely consumed.
         */
        private boolean hasMore() {
            return position < length;
        }

        /**
         * Return the character at the current parsing position.
         *
         * @return The string character for the current parse position.
         */
        private char currentChar() {
            return challenge.charAt(position);
        }

        /**
         * step forward to the next character position.
         */
        private void nextChar() {
            position++;
        }

        /**
         * Skip over any white space characters in the challenge string.
         */
        private void skipSpaces() {
            while (position < length && Character.isWhitespace(currentChar())) {
                position++;
            }
        }

        /**
         * Parse a quoted string used with a name/value pair, accounting for
         * escape characters embedded within the string.
         *
         * @return The string value of the character string.
         */
        private String parseQuotedValue() {
            // we're here because we found the starting double quote. Step over
            // it and parse to the closing
            // one.
            nextChar();

            StringBuffer value = new StringBuffer();

            while (hasMore()) {
                char ch = currentChar();

                // is this an escape char?
                if (ch == '\\') {
                    // step past this, and grab the following character
                    nextChar();
                    // we have an invalid quoted string....
                    if (!hasMore()) {
                        return null;
                    }
                    value.append(currentChar());
                }
                // end of the string?
                else if (ch == '"') {
                    // step over this so the caller doesn't process it.
                    nextChar();
                    // return the constructed string.
                    return value.toString();
                } else {
                    // step over the character and contine with the next
                    // characteer1
                    value.append(ch);
                }
                nextChar();
            }
            /* fell off the end without finding a closing quote! */
            return null;
        }

        /**
         * Parse a token value used with a name/value pair.
         *
         * @return The string value of the token. Returns null if nothing is
         *         found up to the separater.
         */
        private String parseTokenValue() {

            StringBuffer value = new StringBuffer();

            while (hasMore()) {
                char ch = currentChar();
                switch (ch) {
                // process the token separators.
                case ' ':
                case '\t':
                case '(':
                case ')':
                case '<':
                case '>':
                case '@':
                case ',':
                case ';':
                case ':':
                case '\\':
                case '"':
                case '/':
                case '[':
                case ']':
                case '?':
                case '=':
                case '{':
                case '}':
                    // no token characters found? this is bad.
                    if (value.length() == 0) {
                        return null;
                    }
                    // return the accumulated characters.
                    return value.toString();

                default:
                    // is this a control character? That's a delimiter (likely
                    // invalid for the next step,
                    // but it is a token terminator.
                    if (ch < 32 || ch > 127) {
                        // no token characters found? this is bad.
                        if (value.length() == 0) {
                            return null;
                        }
                        // return the accumulated characters.
                        return value.toString();
                    }
                    value.append(ch);
                    break;
                }
                // step to the next character.
                nextChar();
            }
            // no token characters found? this is bad.
            if (value.length() == 0) {
                return null;
            }
            // return the accumulated characters.
            return value.toString();
        }

        /**
         * Parse out a name token of a name/value pair.
         *
         * @return The string value of the name.
         */
        private String parseName() {
            // skip to the value start
            skipSpaces();

            // the name is a token.
            return parseTokenValue();
        }

        /**
         * Parse out a a value of a name/value pair.
         *
         * @return The string value associated with the name.
         */
        private String parseValue() {
            // skip to the value start
            skipSpaces();

            // start of a quoted string?
            if (currentChar() == '"') {
                // parse it out as a string.
                return parseQuotedValue();
            }
            // the value must be a token.
            return parseTokenValue();
        }

        /**
         * Parse a name/value pair in an DIGEST-MD5 string.
         *
         * @return A NameValuePair object containing the two parts of the value.
         * @exception MessagingException
         */
        public NameValuePair parseNameValuePair() throws MessagingException {
            // get the name token
            String name = parseName();
            if (name == null) {
                throw new MessagingException("Name syntax error");
            }

            // the name should be followed by an "=" sign
            if (!hasMore() || currentChar() != '=') {
                throw new MessagingException("Name/value pair syntax error");
            }

            // step over the equals
            nextChar();

            // now get the value part
            String value = parseValue();
            if (value == null) {
                throw new MessagingException("Name/value pair syntax error");
            }

            // skip forward to the terminator, which should either be the end of
            // the line or a ","
            skipSpaces();
            // all that work, only to have a syntax error at the end (sigh)
            if (hasMore()) {
                if (currentChar() != ',') {
                    throw new MessagingException("Name/value pair syntax error");
                }
                // step over, and make sure we position ourselves at either the
                // end or the first
                // real character for parsing the next name/value pair.
                nextChar();
                skipSpaces();
            }
            return new NameValuePair(name, value);
        }
    }

    /**
     * Simple inner class to represent a name/value pair.
     */
    public class NameValuePair {
        public String name;

        public String value;

        NameValuePair(String name, String value) {
            this.name = name;
            this.value = value;
        }

    }
}
