1 /*
   2  * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package org.ietf.jgss;
  27 
  28 /**
  29  * This exception is thrown whenever a GSS-API error occurs, including
  30  * any mechanism specific error.  It may contain both the major and the
  31  * minor GSS-API status codes.  Major error codes are those defined at the
  32  * GSS-API level in this class. Minor error codes are mechanism specific
  33  * error codes that can provide additional information. The underlying
  34  * mechanism implementation is responsible for setting appropriate minor
  35  * status codes when throwing this exception.  Aside from delivering the
  36  * numeric error codes to the caller, this class performs the mapping from
  37  * their numeric values to textual representations.
  38  *
  39  * @author Mayank Upadhyay
  40  * @since 1.4
  41  */
  42 public class GSSException extends Exception {
  43 
  44     private static final long serialVersionUID = -2706218945227726672L;
  45 
  46     /**
  47      * Channel bindings mismatch.
  48      */
  49     public static final int BAD_BINDINGS = 1; //start with 1
  50 
  51     /**
  52      * Unsupported mechanism requested.
  53      */
  54     public static final int BAD_MECH = 2;
  55 
  56     /**
  57      * Invalid name provided.
  58      */
  59     public static final int BAD_NAME = 3;
  60 
  61     /**
  62      * Name of unsupported type provided.
  63      */
  64     public static final int BAD_NAMETYPE = 4;
  65 
  66     /**
  67      * Invalid status code.
  68      */
  69     /*
  70      * This is meant to be thrown by display_status which displays
  71      * major/minor status when an incorrect status type is passed in to it!
  72      */
  73     public static final int BAD_STATUS = 5;
  74 
  75     /**
  76      * Token had invalid integrity check.
  77      */
  78     public static final int BAD_MIC = 6;
  79 
  80     /**
  81      * Security context expired.
  82      */
  83     public static final int CONTEXT_EXPIRED = 7;
  84 
  85     /**
  86      * Expired credentials.
  87      */
  88     public static final int CREDENTIALS_EXPIRED  = 8;
  89 
  90     /**
  91      * Defective credentials.
  92      *
  93      */
  94     public static final int DEFECTIVE_CREDENTIAL = 9;
  95 
  96     /**
  97      * Defective token.
  98      *
  99      */
 100     public static final int DEFECTIVE_TOKEN = 10;
 101 
 102     /**
 103      * General failure, unspecified at GSS-API level.
 104      */
 105     public static final int FAILURE = 11;
 106 
 107     /**
 108      * Invalid security context.
 109      */
 110     public static final int NO_CONTEXT = 12;
 111 
 112     /**
 113      * Invalid credentials.
 114      */
 115     public static final int NO_CRED = 13;
 116 
 117     /**
 118      * Unsupported QOP value.
 119      */
 120     public static final int BAD_QOP = 14;
 121 
 122     /**
 123      * Operation unauthorized.
 124      */
 125     public static final int UNAUTHORIZED = 15;
 126 
 127     /**
 128      * Operation unavailable.
 129      */
 130     public static final int UNAVAILABLE = 16;
 131 
 132     /**
 133      * Duplicate credential element requested.
 134      */
 135     public static final int DUPLICATE_ELEMENT = 17;
 136 
 137     /**
 138      * Name contains multi-mechanism elements.
 139      */
 140     public static final int NAME_NOT_MN = 18;
 141 
 142     /**
 143      * The token was a duplicate of an earlier token.
 144      * This is a fatal error code that may occur during
 145      * context establishment.  It is not used to indicate
 146      * supplementary status values. The MessageProp object is
 147      * used for that purpose.
 148      */
 149     public static final int DUPLICATE_TOKEN = 19;
 150 
 151     /**
 152      * The token's validity period has expired.  This is a
 153      * fatal error code that may occur during context establishment.
 154      * It is not used to indicate supplementary status values.
 155      * The MessageProp object is used for that purpose.
 156      */
 157     public static final int OLD_TOKEN = 20;
 158 
 159 
 160     /**
 161      * A later token has already been processed.  This is a
 162      * fatal error code that may occur during context establishment.
 163      * It is not used to indicate supplementary status values.
 164      * The MessageProp object is used for that purpose.
 165      */
 166     public static final int UNSEQ_TOKEN = 21;
 167 
 168 
 169     /**
 170      * An expected per-message token was not received.  This is a
 171      * fatal error code that may occur during context establishment.
 172      * It is not used to indicate supplementary status values.
 173      * The MessageProp object is used for that purpose.
 174      */
 175     public static final int GAP_TOKEN = 22;
 176 
 177 
 178     private static String[] messages = {
 179         "Channel binding mismatch", // BAD_BINDINGS
 180         "Unsupported mechanism requested", // BAD_MECH
 181         "Invalid name provided", // BAD_NAME
 182         "Name of unsupported type provided", //BAD_NAMETYPE
 183         "Invalid input status selector", // BAD_STATUS
 184         "Token had invalid integrity check", // BAD_SIG
 185         "Specified security context expired", // CONTEXT_EXPIRED
 186         "Expired credentials detected", // CREDENTIALS_EXPIRED
 187         "Defective credential detected", // DEFECTIVE_CREDENTIAL
 188         "Defective token detected", // DEFECTIVE_TOKEN
 189         "Failure unspecified at GSS-API level", // FAILURE
 190         "Security context init/accept not yet called or context deleted",
 191                                                 // NO_CONTEXT
 192         "No valid credentials provided", // NO_CRED
 193         "Unsupported QOP value", // BAD_QOP
 194         "Operation unauthorized", // UNAUTHORIZED
 195         "Operation unavailable", // UNAVAILABLE
 196         "Duplicate credential element requested", //DUPLICATE_ELEMENT
 197         "Name contains multi-mechanism elements", // NAME_NOT_MN
 198         "The token was a duplicate of an earlier token", //DUPLICATE_TOKEN
 199         "The token's validity period has expired", //OLD_TOKEN
 200         "A later token has already been processed", //UNSEQ_TOKEN
 201         "An expected per-message token was not received", //GAP_TOKEN
 202     };
 203 
 204    /**
 205     * The major code for this exception
 206     *
 207     * @serial
 208     */
 209     private int major;
 210 
 211    /**
 212     * The minor code for this exception
 213     *
 214     * @serial
 215     */
 216     private int minor = 0;
 217 
 218    /**
 219     * The text string for minor code
 220     *
 221     * @serial
 222     */
 223     private String minorMessage = null;
 224 
 225    /**
 226     * Alternate text string for major code
 227     *
 228     * @serial
 229     */
 230 
 231     private String majorString = null;
 232 
 233     /**
 234      *  Creates a GSSException object with a specified major code.
 235      *
 236      * @param majorCode the The GSS error code for the problem causing this
 237      * exception to be thrown.
 238      */
 239     public GSSException (int majorCode) {
 240 
 241         if (validateMajor(majorCode))
 242             major = majorCode;
 243         else
 244             major = FAILURE;
 245     }
 246 
 247     /**
 248      * Construct a GSSException object with a specified major code and a
 249      * specific major string for it.
 250      *
 251      * @param majorCode the fatal error code causing this exception.
 252      * @param majorString an expicit message to be included in this exception
 253      */
 254     GSSException (int majorCode, String majorString) {
 255 
 256         if (validateMajor(majorCode))
 257             major = majorCode;
 258         else
 259             major = FAILURE;
 260         this.majorString = majorString;
 261     }
 262 
 263 
 264     /**
 265      * Creates a GSSException object with the specified major code, minor
 266      * code, and minor code textual explanation.  This constructor is to be
 267      * used when the exception is originating from the underlying mechanism
 268      * level. It allows the setting of both the GSS code and the mechanism
 269      * code.
 270      *
 271      * @param majorCode the GSS error code for the problem causing this
 272      * exception to be thrown.
 273      * @param minorCode the mechanism level error code for the problem
 274      * causing this exception to be thrown.
 275      * @param minorString the textual explanation of the mechanism error
 276      * code.
 277      */
 278     public GSSException (int majorCode, int minorCode, String minorString) {
 279 
 280         if (validateMajor(majorCode))
 281             major = majorCode;
 282         else
 283             major = FAILURE;
 284 
 285         minor = minorCode;
 286         minorMessage = minorString;
 287     }
 288 
 289     /**
 290      * Returns the GSS-API level major error code for the problem causing
 291      * this exception to be thrown. Major error codes are
 292      * defined at the mechanism independent GSS-API level in this
 293      * class. Mechanism specific error codes that might provide more
 294      * information are set as the minor error code.
 295      *
 296      * @return int the GSS-API level major error code causing this exception
 297      * @see #getMajorString
 298      * @see #getMinor
 299      * @see #getMinorString
 300      */
 301     public int getMajor() {
 302         return major;
 303     }
 304 
 305     /**
 306      * Returns the mechanism level error code for the problem causing this
 307      * exception to be thrown. The minor code is set by the underlying
 308      * mechanism.
 309      *
 310      * @return int the mechanism error code; 0 indicates that it has not
 311      * been set.
 312      * @see #getMinorString
 313      * @see #setMinor
 314      */
 315     public int  getMinor(){
 316         return minor;
 317     }
 318 
 319     /**
 320      * Returns a string explaining the GSS-API level major error code in
 321      * this exception.
 322      *
 323      * @return String explanation string for the major error code
 324      * @see #getMajor
 325      * @see #toString
 326      */
 327     public String getMajorString() {
 328 
 329         if (majorString != null)
 330             return majorString;
 331         else
 332             return messages[major - 1];
 333     }
 334 
 335 
 336     /**
 337      * Returns a string explaining the mechanism specific error code.
 338      * If the minor status code is 0, then no mechanism level error details
 339      * will be available.
 340      *
 341      * @return String a textual explanation of mechanism error code
 342      * @see #getMinor
 343      * @see #getMajorString
 344      * @see #toString
 345      */
 346     public String getMinorString() {
 347 
 348         return minorMessage;
 349     }
 350 
 351 
 352     /**
 353      * Used by the exception thrower to set the mechanism
 354      * level minor error code and its string explanation.  This is used by
 355      * mechanism providers to indicate error details.
 356      *
 357      * @param minorCode the mechanism specific error code
 358      * @param message textual explanation of the mechanism error code
 359      * @see #getMinor
 360      */
 361     public void setMinor(int minorCode, String message) {
 362 
 363         minor = minorCode;
 364         minorMessage = message;
 365     }
 366 
 367 
 368     /**
 369      * Returns a textual representation of both the major and the minor
 370      * status codes.
 371      *
 372      * @return a String with the error descriptions
 373      */
 374     public String toString() {
 375         return ("GSSException: " + getMessage());
 376     }
 377 
 378     /**
 379      * Returns a textual representation of both the major and the minor
 380      * status codes.
 381      *
 382      * @return a String with the error descriptions
 383      */
 384     public String getMessage() {
 385         if (minor == 0)
 386             return (getMajorString());
 387 
 388         return (getMajorString()
 389                 + " (Mechanism level: " + getMinorString() + ")");
 390     }
 391 
 392 
 393     /*
 394      * Validates the major code in the proper range.
 395      */
 396     private boolean validateMajor(int major) {
 397 
 398         if (major > 0 && major <= messages.length)
 399             return (true);
 400 
 401         return (false);
 402     }
 403 }