/*
 * 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 org.ietf.jgss;

/**
 * This exception is thrown whenever a GSS-API error occurs, including
 * any mechanism specific error.  It may contain both the major and the
 * minor GSS-API status codes.  Major error codes are those defined at the
 * GSS-API level in this class. Minor error codes are mechanism specific
 * error codes that can provide additional information. The underlying
 * mechanism implementation is responsible for setting appropriate minor
 * status codes when throwing this exception.  Aside from delivering the
 * numeric error codes to the caller, this class performs the mapping from
 * their numeric values to textual representations. <p>
 *
 * @author Mayank Upadhyay
 * @since 1.4
 */
public class GSSException extends Exception {

    private static final long serialVersionUID = -2706218945227726672L;

    /**
     * Channel bindings mismatch.
     */
    public static final int BAD_BINDINGS = 1; //start with 1

    /**
     * Unsupported mechanism requested.
     */
    public static final int BAD_MECH = 2;

    /**
     * Invalid name provided.
     */
    public static final int BAD_NAME = 3;

    /**
     * Name of unsupported type provided.
     */
    public static final int BAD_NAMETYPE = 4;

    /**
     * Invalid status code.
     */
    /*
     * This is meant to be thrown by display_status which displays
     * major/minor status when an incorrect status type is passed in to it!
     */
    public static final int BAD_STATUS = 5;

    /**
     * Token had invalid integrity check.
     */
    public static final int BAD_MIC = 6;

    /**
     * Security context expired.
     */
    public static final int CONTEXT_EXPIRED = 7;

    /**
     * Expired credentials.
     */
    public static final int CREDENTIALS_EXPIRED  = 8;

    /**
     * Defective credentials.
     *
     */
    public static final int DEFECTIVE_CREDENTIAL = 9;

    /**
     * Defective token.
     *
     */
    public static final int DEFECTIVE_TOKEN = 10;

    /**
     * General failure, unspecified at GSS-API level.
     */
    public static final int FAILURE = 11;

    /**
     * Invalid security context.
     */
    public static final int NO_CONTEXT = 12;

    /**
     * Invalid credentials.
     */
    public static final int NO_CRED = 13;

    /**
     * Unsupported QOP value.
     */
    public static final int BAD_QOP = 14;

    /**
     * Operation unauthorized.
     */
    public static final int UNAUTHORIZED = 15;

    /**
     * Operation unavailable.
     */
    public static final int UNAVAILABLE = 16;

    /**
     * Duplicate credential element requested.
     */
    public static final int DUPLICATE_ELEMENT = 17;

    /**
     * Name contains multi-mechanism elements.
     */
    public static final int NAME_NOT_MN = 18;

    /**
     * The token was a duplicate of an earlier token.
     * This is a fatal error code that may occur during
     * context establishment.  It is not used to indicate
     * supplementary status values. The MessageProp object is
     * used for that purpose.
     */
    public static final int DUPLICATE_TOKEN = 19;

    /**
     * The token's validity period has expired.  This is a
     * fatal error code that may occur during context establishment.
     * It is not used to indicate supplementary status values.
     * The MessageProp object is used for that purpose.
     */
    public static final int OLD_TOKEN = 20;


    /**
     * A later token has already been processed.  This is a
     * fatal error code that may occur during context establishment.
     * It is not used to indicate supplementary status values.
     * The MessageProp object is used for that purpose.
     */
    public static final int UNSEQ_TOKEN = 21;


    /**
     * An expected per-message token was not received.  This is a
     * fatal error code that may occur during context establishment.
     * It is not used to indicate supplementary status values.
     * The MessageProp object is used for that purpose.
     */
    public static final int GAP_TOKEN = 22;


    private static String[] messages = {
        "Channel binding mismatch", // BAD_BINDINGS
        "Unsupported mechanism requested", // BAD_MECH
        "Invalid name provided", // BAD_NAME
        "Name of unsupported type provided", //BAD_NAMETYPE
        "Invalid input status selector", // BAD_STATUS
        "Token had invalid integrity check", // BAD_SIG
        "Specified security context expired", // CONTEXT_EXPIRED
        "Expired credentials detected", // CREDENTIALS_EXPIRED
        "Defective credential detected", // DEFECTIVE_CREDENTIAL
        "Defective token detected", // DEFECTIVE_TOKEN
        "Failure unspecified at GSS-API level", // FAILURE
        "Security context init/accept not yet called or context deleted",
                                                // NO_CONTEXT
        "No valid credentials provided", // NO_CRED
        "Unsupported QOP value", // BAD_QOP
        "Operation unauthorized", // UNAUTHORIZED
        "Operation unavailable", // UNAVAILABLE
        "Duplicate credential element requested", //DUPLICATE_ELEMENT
        "Name contains multi-mechanism elements", // NAME_NOT_MN
        "The token was a duplicate of an earlier token", //DUPLICATE_TOKEN
        "The token's validity period has expired", //OLD_TOKEN
        "A later token has already been processed", //UNSEQ_TOKEN
        "An expected per-message token was not received", //GAP_TOKEN
    };

   /**
    * The major code for this exception
    *
    * @serial
    */
    private int major;

   /**
    * The minor code for this exception
    *
    * @serial
    */
    private int minor = 0;

   /**
    * The text string for minor code
    *
    * @serial
    */
    private String minorMessage = null;

   /**
    * Alternate text string for major code
    *
    * @serial
    */

    private String majorString = null;

    /**
     *  Creates a GSSException object with a specified major code.
     *
     * @param majorCode the The GSS error code for the problem causing this
     * exception to be thrown.
     */
    public GSSException (int majorCode) {

        if (validateMajor(majorCode))
            major = majorCode;
        else
            major = FAILURE;
    }

    /**
     * Construct a GSSException object with a specified major code and a
     * specific major string for it.
     *
     * @param majorCode the fatal error code causing this exception.
     * @param majorString an expicit message to be included in this exception
     */
    GSSException (int majorCode, String majorString) {

        if (validateMajor(majorCode))
            major = majorCode;
        else
            major = FAILURE;
        this.majorString = majorString;
    }


    /**
     * Creates a GSSException object with the specified major code, minor
     * code, and minor code textual explanation.  This constructor is to be
     * used when the exception is originating from the underlying mechanism
     * level. It allows the setting of both the GSS code and the mechanism
     * code.
     *
     * @param majorCode the GSS error code for the problem causing this
     * exception to be thrown.
     * @param minorCode the mechanism level error code for the problem
     * causing this exception to be thrown.
     * @param minorString the textual explanation of the mechanism error
     * code.
     */
    public GSSException (int majorCode, int minorCode, String minorString) {

        if (validateMajor(majorCode))
            major = majorCode;
        else
            major = FAILURE;

        minor = minorCode;
        minorMessage = minorString;
    }

    /**
     * Returns the GSS-API level major error code for the problem causing
     * this exception to be thrown. Major error codes are
     * defined at the mechanism independent GSS-API level in this
     * class. Mechanism specific error codes that might provide more
     * information aer set as the minor error code.
     *
     * @return int the GSS-API level major error code causing this exception
     * @see #getMajorString
     * @see #getMinor
     * @see #getMinorString
     */
    public int getMajor() {
        return major;
    }

    /**
     * Returns the mechanism level error code for the problem causing this
     * exception to be thrown. The minor code is set by the underlying
     * mechanism.
     *
     * @return int the mechanism error code; 0 indicates that it has not
     * been set.
     * @see #getMinorString
     * @see #setMinor
     */
    public int  getMinor(){
        return minor;
    }

    /**
     * Returns a string explaining the GSS-API level major error code in
     * this exception.
     *
     * @return String explanation string for the major error code
     * @see #getMajor
     * @see #toString
     */
    public String getMajorString() {

        if (majorString != null)
            return majorString;
        else
            return messages[major - 1];
    }


    /**
     * Returns a string explaining the mechanism specific error code.
     * If the minor status code is 0, then no mechanism level error details
     * will be available.
     *
     * @return String a textual explanation of mechanism error code
     * @see #getMinor
     * @see #getMajorString
     * @see #toString
     */
    public String getMinorString() {

        return minorMessage;
    }


    /**
     * Used by the exception thrower to set the mechanism
     * level minor error code and its string explanation.  This is used by
     * mechanism providers to indicate error details.
     *
     * @param minorCode the mechanism specific error code
     * @param message textual explanation of the mechanism error code
     * @see #getMinor
     */
    public void setMinor(int minorCode, String message) {

        minor = minorCode;
        minorMessage = message;
    }


    /**
     * Returns a textual representation of both the major and the minor
     * status codes.
     *
     * @return a String with the error descriptions
     */
    public String toString() {
        return ("GSSException: " + getMessage());
    }

    /**
     * Returns a textual representation of both the major and the minor
     * status codes.
     *
     * @return a String with the error descriptions
     */
    public String getMessage() {
        if (minor == 0)
            return (getMajorString());

        return (getMajorString()
                + " (Mechanism level: " + getMinorString() + ")");
    }


    /*
     * Validates the major code in the proper range.
     */
    private boolean validateMajor(int major) {

        if (major > 0 && major <= messages.length)
            return (true);

        return (false);
    }
}
