Source for org.ietf.jgss.GSSException

   1: /* GSSException.java -- a general exception in GSS.
   2:    Copyright (C) 2004, 2005 Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version.
  37: 
  38:    The documentation comments of this class are derived from the text
  39:    of RFC 2853:  Generic Security Service API Version 2: Java Bindings.
  40:    That document is covered under the following license notice:
  41: 
  42: Copyright (C) The Internet Society (2000).  All Rights Reserved.
  43: 
  44: This document and translations of it may be copied and furnished to
  45: others, and derivative works that comment on or otherwise explain it
  46: or assist in its implementation may be prepared, copied, published and
  47: distributed, in whole or in part, without restriction of any kind,
  48: provided that the above copyright notice and this paragraph are
  49: included on all such copies and derivative works.  However, this
  50: document itself may not be modified in any way, such as by removing
  51: the copyright notice or references to the Internet Society or other
  52: Internet organizations, except as needed for the purpose of developing
  53: Internet standards in which case the procedures for copyrights defined
  54: in the Internet Standards process must be followed, or as required to
  55: translate it into languages other than English.
  56: 
  57: The limited permissions granted above are perpetual and will not be
  58: revoked by the Internet Society or its successors or assigns.
  59: 
  60: This document and the information contained herein is provided on an
  61: "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
  62: TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT
  63: NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN
  64: WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
  65: MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. */
  66: 
  67: 
  68: package org.ietf.jgss;
  69: 
  70: import java.util.PropertyResourceBundle;
  71: import java.util.ResourceBundle;
  72: 
  73: /**
  74:  * This exception is thrown whenever a fatal GSS-API error occurs
  75:  * including mechanism specific errors.  It may contain both, the major
  76:  * and minor, GSS-API status codes.  The mechanism implementers are
  77:  * responsible for setting appropriate minor status codes when throwing
  78:  * this exception.  Aside from delivering the numeric error code(s) to
  79:  * the caller, this class performs the mapping from their numeric values
  80:  * to textual representations.  All Java GSS-API methods are declared
  81:  * throwing this exception.
  82:  *
  83:  * @specnote Some of the constant values defined in this class were
  84:  * chosen to be compatible with J2SE 1.4, and not with RFC 2853.
  85:  */
  86: public class GSSException extends Exception
  87: {
  88:   /**
  89:    * For compatability with Sun's JDK 1.4.2 rev. 5
  90:    */
  91:   private static final long serialVersionUID = -2706218945227726672L;
  92: 
  93:   // Constants and fields.
  94:   // -------------------------------------------------------------------------
  95: 
  96:   /**
  97:    * Channel bindings mismatch error.
  98:    * @specnote Should be 4 according to RFC 2853.
  99:    */
 100:   public static final int BAD_BINDINGS = 1;
 101: 
 102:   /**
 103:    * Unsupported mechanism requested error.
 104:    * @specnote Should be 1 according to RFC 2853.
 105:    */
 106:   public static final int BAD_MECH = 2;
 107: 
 108:   /**
 109:    * Invalid name provided error.
 110:    * @specnote Should be 2 according to RFC 2853.
 111:    */
 112:   public static final int BAD_NAME = 3;
 113: 
 114:   /**
 115:    * Name of unsupported type provided error.
 116:    * @specnote Should be 3 according to RFC 2853.
 117:    */
 118:   public static final int BAD_NAMETYPE = 4;
 119: 
 120:   /**
 121:    * Invalid status code error - this is the default status value.
 122:    */
 123:   public static final int BAD_STATUS = 5;
 124: 
 125:   /**
 126:    * Token had invalid integrity check error.
 127:    */
 128:   public static final int BAD_MIC = 6;
 129: 
 130:   /**
 131:    * Specified security context expired error.
 132:    * @specnote Should be 12 according to RFC 2853.
 133:    */
 134:   public static final int CONTEXT_EXPIRED = 7;
 135: 
 136:   /**
 137:    * Expired credentials detected error.
 138:    * @specnote Should be 11 according to RFC 2853.
 139:    */
 140:   public static final int CREDENTIALS_EXPIRED = 8;
 141: 
 142:   /**
 143:    * Defective credential error.
 144:    * @specnote Should be 10 according to RFC 2853.
 145:    */
 146:   public static final int DEFECTIVE_CREDENTIAL = 9;
 147: 
 148:   /**
 149:    * Defective token error.
 150:    * @specnote Should be 9 according to RFC 2853.
 151:    */
 152:   public static final int DEFECTIVE_TOKEN = 10;
 153: 
 154:   /**
 155:    * General failure, unspecified at GSS-API level.
 156:    * @specnote Should be 13 according to RFC 2853.
 157:    */
 158:   public static final int FAILURE = 11;
 159: 
 160:   /**
 161:    * Invalid security context error.
 162:    * @specnote Should be 8 according to RFC 2853.
 163:    */
 164:   public static final int NO_CONTEXT = 12;
 165: 
 166:   /**
 167:    * Invalid credentials error.
 168:    * @specnote Should be 7 according to RFC 2853.
 169:    */
 170:   public static final int NO_CRED = 13;
 171: 
 172:   /**
 173:    * Unsupported QOP value error.
 174:    */
 175:   public static final int BAD_QOP = 14;
 176: 
 177:   /**
 178:    * Operation unauthorized error.
 179:    */
 180:   public static final int UNAUTHORIZED = 15;
 181: 
 182:   /**
 183:    * Operation unavailable error.
 184:    */
 185:   public static final int UNAVAILABLE = 16;
 186: 
 187:   /**
 188:    * Duplicate credential element requested error.
 189:    */
 190:   public static final int DUPLICATE_ELEMENT = 17;
 191: 
 192:   /**
 193:    * Name contains multi-mechanism elements error.
 194:    */
 195:   public static final int NAME_NOT_MN = 18;
 196: 
 197:   /**
 198:    * The token was a duplicate of an earlier token.  This is a fatal error
 199:    * code that may occur during context establishment.  It is not used to
 200:    * indicate supplementary status values.  The MessageProp object is used
 201:    * for that purpose.
 202:    * @specnote Should be 20 according to RFC 2853.
 203:    */
 204:   public static final int DUPLICATE_TOKEN = 19;
 205: 
 206:   /**
 207:    * The token's validity period has expired.  This is a fatal error code
 208:    * that may occur during context establishment.  It is not used to
 209:    * indicate supplementary status values.  The MessageProp object is used
 210:    * for that purpose.
 211:    * @specnote Should be 19 according to RFC 2853.
 212:    */
 213:   public static final int OLD_TOKEN = 20;
 214: 
 215:   /**
 216:    * A later token has already been processed.  This is a fatal error code
 217:    * that may occur during context establishment.  It is not used to
 218:    * indicate supplementary status values.  The MessageProp object is used
 219:    * for that purpose.
 220:    */
 221:   public static final int UNSEQ_TOKEN = 21;
 222: 
 223:   /**
 224:    * An expected per-message token was not received.  This is a fatal
 225:    * error code that may occur during context establishment.  It is not
 226:    * used to indicate supplementary status values.  The MessageProp object
 227:    * is used for that purpose.
 228:    */
 229:   public static final int GAP_TOKEN = 22;
 230: 
 231:   private final int major;
 232:   private int minor;
 233:   private String minorString;
 234: 
 235:   private ResourceBundle messages;
 236: 
 237:   // Constructors.
 238:   // -------------------------------------------------------------------------
 239: 
 240:   /**
 241:    * Create a new GSS exception with the given major code.
 242:    *
 243:    * @param major The major GSS error code.
 244:    */
 245:   public GSSException(int major)
 246:   {
 247:     this(major, 0, null);
 248:   }
 249: 
 250:   /**
 251:    * Create a new GSS exception with the given major and minor codes, and a
 252:    * minor explanation string.
 253:    *
 254:    * @param major The major GSS error code.
 255:    * @param minor The minor application-specific error code.
 256:    * @param minorString An explanation of the minor error code.
 257:    */
 258:   public GSSException(int major, int minor, String minorString)
 259:   {
 260:     this.major = major;
 261:     this.minor = minor;
 262:     this.minorString = minorString;
 263:     try
 264:       {
 265:         messages = PropertyResourceBundle.getBundle("org/ietf/jgss/MessagesBundle");
 266:       }
 267:     catch (Exception e)
 268:       {
 269:         messages = null;
 270:       }
 271:   }
 272: 
 273:   // Instance methods.
 274:   // -------------------------------------------------------------------------
 275: 
 276:   /**
 277:    * Returns the major code representing the GSS error code that caused
 278:    * this exception to be thrown.
 279:    *
 280:    * @return The major error code.
 281:    */
 282:   public int getMajor()
 283:   {
 284:     return major;
 285:   }
 286: 
 287:   /**
 288:    * Returns the mechanism error code that caused this exception.  The
 289:    * minor code is set by the underlying mechanism.  Value of 0 indicates
 290:    * that mechanism error code is not set.
 291:    *
 292:    * @return The minor error code, or 0 if not set.
 293:    */
 294:   public int getMinor()
 295:   {
 296:     return minor;
 297:   }
 298: 
 299:   /**
 300:    * Returns a string explaining the GSS major error code causing this
 301:    * exception to be thrown.
 302:    *
 303:    * @return The major error string.
 304:    */
 305:   public String getMajorString()
 306:   {
 307:     switch (major)
 308:       {
 309:       case BAD_MECH:
 310:         return getMsg("GSSException.BAD_MECH",
 311:                       "An unsupported mechanism was requested.");
 312:       case BAD_NAME:
 313:         return getMsg("GSSException.BAD_NAME",
 314:                       "An invalid name was supplied.");
 315:       case BAD_NAMETYPE:
 316:         return getMsg("GSSException.BAD_NAMETYPE",
 317:                       "A supplied name was of an unsupported type.");
 318:       case BAD_BINDINGS:
 319:         return getMsg("GSSException.BAD_BINDINGS",
 320:                       "Incorrect channel bindings were supplied.");
 321:       case BAD_STATUS:
 322:         return getMsg("GSSException.BAD_STATUS",
 323:                       "An invalid status code was supplied.");
 324:       case BAD_MIC:
 325:         return getMsg("GSSException.BAD_MIC",
 326:                       "A token had an invalid MIC.");
 327:       case NO_CRED:
 328:         return getMsg("GSSException.NO_CRED",
 329:                       "No credentials were supplied, or the credentials were "+
 330:                       "unavailable or inaccessible.");
 331:       case NO_CONTEXT:
 332:         return getMsg("GSSException.NO_CONTEXT",
 333:                       "Invalid context has been supplied.");
 334:       case DEFECTIVE_TOKEN:
 335:         return getMsg("GSSException.DEFECTIVE_TOKEN",
 336:                       "A supplied token was invalid.");
 337:       case DEFECTIVE_CREDENTIAL:
 338:         return getMsg("GSSException.DEFECTIVE_CREDENTIAL",
 339:                       "A supplied credential was invalid.");
 340:       case CREDENTIALS_EXPIRED:
 341:         return getMsg("GSSException.CREDENTIALS_EXPIRED",
 342:                       "The referenced credentials have expired.");
 343:       case CONTEXT_EXPIRED:
 344:         return getMsg("GSSException.CONTEXT_EXPIRED",
 345:                       "The context has expired.");
 346:       case FAILURE:
 347:         return getMsg("GSSException.FAILURE",
 348:                       "Miscellaneous failure.");
 349:       case BAD_QOP:
 350:         return getMsg("GSSException.BAD_QOP",
 351:                       "The quality-of-protection requested could not be provided.");
 352:       case UNAUTHORIZED:
 353:         return getMsg("GSSException.UNAUTHORIZED",
 354:                       "The operation is forbidden by local security policy.");
 355:       case UNAVAILABLE:
 356:         return getMsg("GSSException.UNAVAILABLE",
 357:                       "The operation or option is unavailable.");
 358:       case DUPLICATE_ELEMENT:
 359:         return getMsg("GSSException.DUPLICATE_ELEMENT",
 360:                       "The requested credential element already exists.");
 361:       case NAME_NOT_MN:
 362:         return getMsg("GSSException.NAME_NOT_MN",
 363:                       "The provided name was not a mechanism name.");
 364:       case OLD_TOKEN:
 365:         return getMsg("GSSException.OLD_TOKEN",
 366:                       "The token's validity period has expired.");
 367:       case DUPLICATE_TOKEN:
 368:         return getMsg("GSSException.DUPLICATE_TOKEN",
 369:                       "The token was a duplicate of an earlier version.");
 370:       case UNSEQ_TOKEN:
 371:         return getMsg("GSSException.UNSEQ_TOKEN",
 372:                       "A later token has already been processed.");
 373:       case GAP_TOKEN:
 374:         return getMsg("GSSException.GAP_TOKEN",
 375:                       "An expected per-message token was not received.");
 376:       default: return "Unknown or invalid error code.";
 377:       }
 378:   }
 379: 
 380:   /**
 381:    * Returns a string explaining the mechanism specific error code.
 382:    * <code>null</code> will be returned when no mechanism error code has
 383:    * been set.
 384:    *
 385:    * @return The minor error string, or <code>null</code>.
 386:    */
 387:   public String getMinorString()
 388:   {
 389:     return minorString;
 390:   }
 391: 
 392:   /**
 393:    * Used internally by the GSS-API implementation and the underlying
 394:    * mechanisms to set the minor code and its textual representation.
 395:    *
 396:    * @param minorCode The mechanism specific error code.
 397:    * @param message   A textual explanation of the mechanism error code.
 398:    */
 399:   public void setMinor(int minorCode, String message)
 400:   {
 401:     this.minor = minorCode;
 402:     this.minorString = message;
 403:   }
 404: 
 405:   /**
 406:    * Returns a textual representation of both the major and minor status
 407:    * codes.
 408:    *
 409:    * @return The textual representation.
 410:    */
 411:   public String toString()
 412:   {
 413:     return GSSException.class.getName() + ": " + getMessage();
 414:   }
 415: 
 416:   /**
 417:    * Returns a detailed message of this exception.  Overrides {@link
 418:    * Throwable#getMessage()}. It is customary in Java to use this method to
 419:    * obtain exception information.
 420:    *
 421:    * @return The detail message.
 422:    */
 423:   public String getMessage()
 424:   {
 425:     if (minor == 0)
 426:       return getMajorString();
 427:     else
 428:       return getMajorString() + " (" + minorString + ")";
 429:   }
 430: 
 431:   // Own methods.
 432:   // -------------------------------------------------------------------------
 433: 
 434:   private String getMsg(String key, String defaultText)
 435:   {
 436:     if (messages != null)
 437:       {
 438:         try
 439:           {
 440:             return messages.getString(key);
 441:           }
 442:         catch (Exception e)
 443:           {
 444:           }
 445:       }
 446:     return defaultText;
 447:   }
 448: }