/*
 * Copyright 2000-2003 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code 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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code 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 in the LICENSE file that
 * accompanied this code).
 *
 * 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 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package com.sun.security.sasl.util;

import javax.security.sasl.*;
import java.io.*;
import java.util.Map;
import java.util.StringTokenizer;
import java.security.AccessController;
import java.security.PrivilegedAction;

import java.util.logging.Logger;
import java.util.logging.Level;

import sun.misc.HexDumpEncoder;

/**
 * The base class used by client and server implementations of SASL
 * mechanisms to process properties passed in the props argument
 * and strings with the same format (e.g., used in digest-md5).
 *
 * Also contains utilities for doing int to network-byte-order
 * transformations.
 *
 * @author Rosanna Lee
 */
public abstract class AbstractSaslImpl {
    /**
     * Logger for debug messages
     */
    protected static Logger logger;  // set in initLogger(); lazily loads logger

    protected boolean completed = false;
    protected boolean privacy = false;
    protected boolean integrity = false;
    protected byte[] qop;           // ordered list of qops
    protected byte allQop;          // a mask indicating which QOPs are requested
    protected byte[] strength;      // ordered list of cipher strengths

    // These are relevant only when privacy or integray have been negotiated
    protected int sendMaxBufSize = 0;     // specified by peer but can override
    protected int recvMaxBufSize = 65536; // optionally specified by self
    protected int rawSendSize;            // derived from sendMaxBufSize

    protected String myClassName;

    protected AbstractSaslImpl(Map props, String className) throws SaslException {
        initLogger();
        myClassName = className;

        // Parse properties  to set desired context options
        if (props != null) {
            String prop;

            // "auth", "auth-int", "auth-conf"
            qop = parseQop(prop=(String)props.get(Sasl.QOP));
            logger.logp(Level.FINE, myClassName, "constructor",
                "SASLIMPL01:Preferred qop property: {0}", prop);
            allQop = combineMasks(qop);

            if (logger.isLoggable(Level.FINE)) {
                logger.logp(Level.FINE, myClassName, "constructor",
                    "SASLIMPL02:Preferred qop mask: {0}", new Byte(allQop));

                if (qop.length > 0) {
                    StringBuffer qopbuf = new StringBuffer();
                    for (int i = 0; i < qop.length; i++) {
                        qopbuf.append(Byte.toString(qop[i]));
                        qopbuf.append(' ');
                    }
                    logger.logp(Level.FINE, myClassName, "constructor",
                        "SASLIMPL03:Preferred qops : {0}", qopbuf.toString());
                }
            }

            // "low", "medium", "high"
            strength = parseStrength(prop=(String)props.get(Sasl.STRENGTH));
            logger.logp(Level.FINE, myClassName, "constructor",
                "SASLIMPL04:Preferred strength property: {0}", prop);
            if (logger.isLoggable(Level.FINE) && strength.length > 0) {
                StringBuffer strbuf = new StringBuffer();
                for (int i = 0; i < strength.length; i++) {
                    strbuf.append(Byte.toString(strength[i]));
                    strbuf.append(' ');
                }
                logger.logp(Level.FINE, myClassName, "constructor",
                    "SASLIMPL05:Cipher strengths: {0}", strbuf.toString());
            }

            // Max receive buffer size
            prop = (String)props.get(Sasl.MAX_BUFFER);
            if (prop != null) {
                try {
                    logger.logp(Level.FINE, myClassName, "constructor",
                        "SASLIMPL06:Max receive buffer size: {0}", prop);
                    recvMaxBufSize = Integer.parseInt(prop);
                } catch (NumberFormatException e) {
                    throw new SaslException(
                "Property must be string representation of integer: " +
                        Sasl.MAX_BUFFER);
                }
            }

            // Max send buffer size
            prop = (String)props.get(MAX_SEND_BUF);
            if (prop != null) {
                try {
                    logger.logp(Level.FINE, myClassName, "constructor",
                        "SASLIMPL07:Max send buffer size: {0}", prop);
                    sendMaxBufSize = Integer.parseInt(prop);
                } catch (NumberFormatException e) {
                    throw new SaslException(
                "Property must be string representation of integer: " +
                        MAX_SEND_BUF);
                }
            }
        } else {
            qop = DEFAULT_QOP;
            allQop = NO_PROTECTION;
            strength = STRENGTH_MASKS;
        }
    }

    /**
     * Determines whether this mechanism has completed.
     *
     * @return true if has completed; false otherwise;
     */
    public boolean isComplete() {
        return completed;
    }

    /**
     * Retrieves the negotiated property.
     * @exception SaslException if this authentication exchange has not completed
     */
    public Object getNegotiatedProperty(String propName) {
        if (!completed) {
            throw new IllegalStateException("SASL authentication not completed");
        }

        if (propName.equals(Sasl.QOP)) {
            if (privacy) {
                return "auth-conf";
            } else if (integrity) {
                return "auth-int";
            } else {
                return "auth";
            }
        } else if (propName.equals(Sasl.MAX_BUFFER)) {
            return Integer.toString(recvMaxBufSize);
        } else if (propName.equals(Sasl.RAW_SEND_SIZE)) {
            return Integer.toString(rawSendSize);
        } else if (propName.equals(MAX_SEND_BUF)) {
            return Integer.toString(sendMaxBufSize);
        } else {
            return null;
        }
    }

    protected static final byte combineMasks(byte[] in) {
        byte answer = 0;
        for (int i = 0; i < in.length; i++) {
            answer |= in[i];
        }
        return answer;
    }

    protected static final byte findPreferredMask(byte pref, byte[] in) {
        for (int i = 0; i < in.length; i++) {
            if ((in[i]&pref) != 0) {
                return in[i];
            }
        }
        return (byte)0;
    }

    private static final byte[] parseQop(String qop) throws SaslException {
        return parseQop(qop, null, false);
    }

    protected static final byte[] parseQop(String qop, String[] saveTokens,
        boolean ignore) throws SaslException {
        if (qop == null) {
            return DEFAULT_QOP;   // default
        }

        return parseProp(Sasl.QOP, qop, QOP_TOKENS, QOP_MASKS, saveTokens, ignore);
    }

    private static final byte[] parseStrength(String strength)
        throws SaslException {
        if (strength == null) {
            return DEFAULT_STRENGTH;   // default
        }

        return parseProp(Sasl.STRENGTH, strength, STRENGTH_TOKENS,
            STRENGTH_MASKS, null, false);
    }

    private static final byte[] parseProp(String propName, String propVal,
        String[] vals, byte[] masks, String[] tokens, boolean ignore)
        throws SaslException {

        StringTokenizer parser = new StringTokenizer(propVal, ", \t\n");
        String token;
        byte[] answer = new byte[vals.length];
        int i = 0;
        boolean found;

        while (parser.hasMoreTokens() && i < answer.length) {
            token = parser.nextToken();
            found = false;
            for (int j = 0; !found && j < vals.length; j++) {
                if (token.equalsIgnoreCase(vals[j])) {
                    found = true;
                    answer[i++] = masks[j];
                    if (tokens != null) {
                        tokens[j] = token;    // save what was parsed
                    }
                }
            }
            if (!found && !ignore) {
                throw new SaslException(
                    "Invalid token in " + propName + ": " + propVal);
            }
        }
        // Initialize rest of array with 0
        for (int j = i; j < answer.length; j++) {
            answer[j] = 0;
        }
        return answer;
    }


    /**
     * Outputs a byte array and converts
     */
    protected static final void traceOutput(String srcClass, String srcMethod,
        String traceTag, byte[] output) {
        traceOutput(srcClass, srcMethod, traceTag, output, 0, output.length);
    }

    protected static final void traceOutput(String srcClass, String srcMethod,
        String traceTag, byte[] output, int offset, int len) {
        try {
            int origlen = len;
            Level lev;

            if (!logger.isLoggable(Level.FINEST)) {
                len = Math.min(16, len);
                lev = Level.FINER;
            } else {
                lev = Level.FINEST;
            }

            ByteArrayOutputStream out = new ByteArrayOutputStream(len);
            new HexDumpEncoder().encodeBuffer(
                new ByteArrayInputStream(output, offset, len), out);

            // Message id supplied by caller as part of traceTag
            logger.logp(lev, srcClass, srcMethod, "{0} ( {1} ): {2}",
                new Object[] {traceTag, new Integer(origlen), out.toString()});
        } catch (Exception e) {
            logger.logp(Level.WARNING, srcClass, srcMethod,
                "SASLIMPL09:Error generating trace output: {0}", e);
        }
    }


    /**
     * Returns the integer represented by  4 bytes in network byte order.
     */
    protected static final int networkByteOrderToInt(byte[] buf, int start,
        int count) {
        if (count > 4) {
            throw new IllegalArgumentException("Cannot handle more than 4 bytes");
        }

        int answer = 0;

        for (int i = 0; i < count; i++) {
            answer <<= 8;
            answer |= ((int)buf[start+i] & 0xff);
        }
        return answer;
    }

    /**
     * Encodes an integer into 4 bytes in network byte order in the buffer
     * supplied.
     */
    protected static final void intToNetworkByteOrder(int num, byte[] buf,
        int start, int count) {
        if (count > 4) {
            throw new IllegalArgumentException("Cannot handle more than 4 bytes");
        }

        for (int i = count-1; i >= 0; i--) {
            buf[start+i] = (byte)(num & 0xff);
            num >>>= 8;
        }
    }

    /**
     * Sets logger field.
     */
    private static synchronized void initLogger() {
        if (logger == null) {
            logger = Logger.getLogger(SASL_LOGGER_NAME);
        }
    }

    // ---------------- Constants  -----------------
    private static final String SASL_LOGGER_NAME = "javax.security.sasl";
    protected static final String MAX_SEND_BUF = "javax.security.sasl.sendmaxbuffer";

    // default 0 (no protection); 1 (integrity only)
    protected static final byte NO_PROTECTION = (byte)1;
    protected static final byte INTEGRITY_ONLY_PROTECTION = (byte)2;
    protected static final byte PRIVACY_PROTECTION = (byte)4;

    protected static final byte LOW_STRENGTH = (byte)1;
    protected static final byte MEDIUM_STRENGTH = (byte)2;
    protected static final byte HIGH_STRENGTH = (byte)4;

    private static final byte[] DEFAULT_QOP = new byte[]{NO_PROTECTION};
    private static final String[] QOP_TOKENS = {"auth-conf",
                                       "auth-int",
                                       "auth"};
    private static final byte[] QOP_MASKS = {PRIVACY_PROTECTION,
                                     INTEGRITY_ONLY_PROTECTION,
                                     NO_PROTECTION};

    private static final byte[] DEFAULT_STRENGTH = new byte[]{
        HIGH_STRENGTH, MEDIUM_STRENGTH, LOW_STRENGTH};
    private static final String[] STRENGTH_TOKENS = {"low",
                                                     "medium",
                                                     "high"};
    private static final byte[] STRENGTH_MASKS = {LOW_STRENGTH,
                                                  MEDIUM_STRENGTH,
                                                  HIGH_STRENGTH};
}
