Source for org.ietf.jgss.GSSException

   1: /* GSSException.java -- a general exception in GSS.
   2:    Copyright (C) 2004 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: public class GSSException extends Exception
  84: {
  85:   /**
  86:    * For compatability with Sun's JDK 1.4.2 rev. 5
  87:    */
  88:   private static final long serialVersionUID = -2706218945227726672L;
  89: 
  90:   // Constants and fields.
  91:   // -------------------------------------------------------------------------
  92: 
  93:   // These values do not jive with the "Constant Field Values" in the J2SE
  94:   // 1.4.1, but do follow RFC 2853. I trust the IETF, but not Sun.
  95: 
  96:   /**
  97:    * Channel bindings mismatch error.
  98:    */
  99:   public static final int BAD_BINDINGS = 4;
 100: 
 101:   /**
 102:    * Unsupported mechanism requested error.
 103:    */
 104:   public static final int BAD_MECH = 1;
 105: 
 106:   /**
 107:    * Invalid name provided error.
 108:    */
 109:   public static final int BAD_NAME = 2;
 110: 
 111:   /**
 112:    * Name of unsupported type provided error.
 113:    */
 114:   public static final int BAD_NAMETYPE = 3;
 115: 
 116:   /**
 117:    * Invalid status code error - this is the default status value.
 118:    */
 119:   public static final int BAD_STATUS = 5;
 120: 
 121:   /**
 122:    * Token had invalid integrity check error.
 123:    */
 124:   public static final int BAD_MIC = 6;
 125: 
 126:   /**
 127:    * Specified security context expired error.
 128:    */
 129:   public static final int CONTEXT_EXPIRED = 12;
 130: 
 131:   /**
 132:    * Expired credentials detected error.
 133:    */
 134:   public static final int CREDENTIALS_EXPIRED = 11;
 135: 
 136:   /**
 137:    * Defective credential error.
 138:    */
 139:   public static final int DEFECTIVE_CREDENTIAL = 10;
 140: 
 141:   /**
 142:    * Defective token error.
 143:    */
 144:   public static final int DEFECTIVE_TOKEN = 9;
 145: 
 146:   /**
 147:    * General failure, unspecified at GSS-API level.
 148:    */
 149:   public static final int FAILURE = 13;
 150: 
 151:   /**
 152:    * Invalid security context error.
 153:    */
 154:   public static final int NO_CONTEXT = 8;
 155: 
 156:   /**
 157:    * Invalid credentials error.
 158:    */
 159:   public static final int NO_CRED = 7;
 160: 
 161:   /**
 162:    * Unsupported QOP value error.
 163:    */
 164:   public static final int BAD_QOP = 14;
 165: 
 166:   /**
 167:    * Operation unauthorized error.
 168:    */
 169:   public static final int UNAUTHORIZED = 15;
 170: 
 171:   /**
 172:    * Operation unavailable error.
 173:    */
 174:   public static final int UNAVAILABLE = 16;
 175: 
 176:   /**
 177:    * Duplicate credential element requested error.
 178:    */
 179:   public static final int DUPLICATE_ELEMENT = 17;
 180: 
 181:   /**
 182:    * Name contains multi-mechanism elements error.
 183:    */
 184:   public static final int NAME_NOT_MN = 18;
 185: 
 186:   /**
 187:    * The token was a duplicate of an earlier token.  This is a fatal error
 188:    * code that may occur during context establishment.  It is not used to
 189:    * indicate supplementary status values.  The MessageProp object is used
 190:    * for that purpose.
 191:    */
 192:   public static final int DUPLICATE_TOKEN = 20;
 193: 
 194:   /**
 195:    * The token's validity period has expired.  This is a fatal error code
 196:    * that may occur during context establishment.  It is not used to
 197:    * indicate supplementary status values.  The MessageProp object is used
 198:    * for that purpose.
 199:    */
 200:   public static final int OLD_TOKEN = 19;
 201: 
 202:   /**
 203:    * A later token has already been processed.  This is a fatal error code
 204:    * that may occur during context establishment.  It is not used to
 205:    * indicate supplementary status values.  The MessageProp object is used
 206:    * for that purpose.
 207:    */
 208:   public static final int UNSEQ_TOKEN = 21;
 209: 
 210:   /**
 211:    * An expected per-message token was not received.  This is a fatal
 212:    * error code that may occur during context establishment.  It is not
 213:    * used to indicate supplementary status values.  The MessageProp object
 214:    * is used for that purpose.
 215:    */
 216:   public static final int GAP_TOKEN = 22;
 217: 
 218:   private final int major;
 219:   private int minor;
 220:   private String minorString;
 221: 
 222:   private ResourceBundle messages;
 223: 
 224:   // Constructors.
 225:   // -------------------------------------------------------------------------
 226: 
 227:   /**
 228:    * Create a new GSS exception with the given major code.
 229:    *
 230:    * @param major The major GSS error code.
 231:    */
 232:   public GSSException(int major)
 233:   {
 234:     this(major, 0, null);
 235:   }
 236: 
 237:   /**
 238:    * Create a new GSS exception with the given major and minor codes, and a
 239:    * minor explanation string.
 240:    *
 241:    * @param major The major GSS error code.
 242:    * @param minor The minor application-specific error code.
 243:    * @param minorString An explanation of the minor error code.
 244:    */
 245:   public GSSException(int major, int minor, String minorString)
 246:   {
 247:     this.major = major;
 248:     this.minor = minor;
 249:     this.minorString = minorString;
 250:     try
 251:       {
 252:         messages = PropertyResourceBundle.getBundle("org/ietf/jgss/MessagesBundle");
 253:       }
 254:     catch (Exception e)
 255:       {
 256:         messages = null;
 257:       }
 258:   }
 259: 
 260:   // Instance methods.
 261:   // -------------------------------------------------------------------------
 262: 
 263:   /**
 264:    * Returns the major code representing the GSS error code that caused
 265:    * this exception to be thrown.
 266:    *
 267:    * @return The major error code.
 268:    */
 269:   public int getMajor()
 270:   {
 271:     return major;
 272:   }
 273: 
 274:   /**
 275:    * Returns the mechanism error code that caused this exception.  The
 276:    * minor code is set by the underlying mechanism.  Value of 0 indicates
 277:    * that mechanism error code is not set.
 278:    *
 279:    * @return The minor error code, or 0 if not set.
 280:    */
 281:   public int getMinor()
 282:   {
 283:     return minor;
 284:   }
 285: 
 286:   /**
 287:    * Returns a string explaining the GSS major error code causing this
 288:    * exception to be thrown.
 289:    *
 290:    * @return The major error string.
 291:    */
 292:   public String getMajorString()
 293:   {
 294:     switch (major)
 295:       {
 296:       case BAD_MECH:
 297:         return getMsg("GSSException.BAD_MECH",
 298:                       "An unsupported mechanism was requested.");
 299:       case BAD_NAME:
 300:         return getMsg("GSSException.BAD_NAME",
 301:                       "An invalid name was supplied.");
 302:       case BAD_NAMETYPE:
 303:         return getMsg("GSSException.BAD_NAMETYPE",
 304:                       "A supplied name was of an unsupported type.");
 305:       case BAD_BINDINGS:
 306:         return getMsg("GSSException.BAD_BINDINGS",
 307:                       "Incorrect channel bindings were supplied.");
 308:       case BAD_STATUS:
 309:         return getMsg("GSSException.BAD_STATUS",
 310:                       "An invalid status code was supplied.");
 311:       case BAD_MIC:
 312:         return getMsg("GSSException.BAD_MIC",
 313:                       "A token had an invalid MIC.");
 314:       case NO_CRED:
 315:         return getMsg("GSSException.NO_CRED",
 316:                       "No credentials were supplied, or the credentials were "+
 317:                       "unavailable or inaccessible.");
 318:       case NO_CONTEXT:
 319:         return getMsg("GSSException.NO_CONTEXT",
 320:                       "Invalid context has been supplied.");
 321:       case DEFECTIVE_TOKEN:
 322:         return getMsg("GSSException.DEFECTIVE_TOKEN",
 323:                       "A supplied token was invalid.");
 324:       case DEFECTIVE_CREDENTIAL:
 325:         return getMsg("GSSException.DEFECTIVE_CREDENTIAL",
 326:                       "A supplied credential was invalid.");
 327:       case CREDENTIALS_EXPIRED:
 328:         return getMsg("GSSException.CREDENTIALS_EXPIRED",
 329:                       "The referenced credentials have expired.");
 330:       case CONTEXT_EXPIRED:
 331:         return getMsg("GSSException.CONTEXT_EXPIRED",
 332:                       "The context has expired.");
 333:       case FAILURE:
 334:         return getMsg("GSSException.FAILURE",
 335:                       "Miscellaneous failure.");
 336:       case BAD_QOP:
 337:         return getMsg("GSSException.BAD_QOP",
 338:                       "The quality-of-protection requested could not be provided.");
 339:       case UNAUTHORIZED:
 340:         return getMsg("GSSException.UNAUTHORIZED",
 341:                       "The operation is forbidden by local security policy.");
 342:       case UNAVAILABLE:
 343:         return getMsg("GSSException.UNAVAILABLE",
 344:                       "The operation or option is unavailable.");
 345:       case DUPLICATE_ELEMENT:
 346:         return getMsg("GSSException.DUPLICATE_ELEMENT",
 347:                       "The requested credential element already exists.");
 348:       case NAME_NOT_MN:
 349:         return getMsg("GSSException.NAME_NOT_MN",
 350:                       "The provided name was not a mechanism name.");
 351:       case OLD_TOKEN:
 352:         return getMsg("GSSException.OLD_TOKEN",
 353:                       "The token's validity period has expired.");
 354:       case DUPLICATE_TOKEN:
 355:         return getMsg("GSSException.DUPLICATE_TOKEN",
 356:                       "The token was a duplicate of an earlier version.");
 357:       case UNSEQ_TOKEN:
 358:         return getMsg("GSSException.UNSEQ_TOKEN",
 359:                       "A later token has already been processed.");
 360:       case GAP_TOKEN:
 361:         return getMsg("GSSException.GAP_TOKEN",
 362:                       "An expected per-message token was not received.");
 363:       default: return "Unknown or invalid error code.";
 364:       }
 365:   }
 366: 
 367:   /**
 368:    * Returns a string explaining the mechanism specific error code.
 369:    * <code>null</code> will be returned when no mechanism error code has
 370:    * been set.
 371:    *
 372:    * @return The minor error string, or <code>null</code>.
 373:    */
 374:   public String getMinorString()
 375:   {
 376:     return minorString;
 377:   }
 378: 
 379:   /**
 380:    * Used internally by the GSS-API implementation and the underlying
 381:    * mechanisms to set the minor code and its textual representation.
 382:    *
 383:    * @param minorCode The mechanism specific error code.
 384:    * @param message   A textual explanation of the mechanism error code.
 385:    */
 386:   public void setMinor(int minorCode, String message)
 387:   {
 388:     this.minor = minorCode;
 389:     this.minorString = message;
 390:   }
 391: 
 392:   /**
 393:    * Returns a textual representation of both the major and minor status
 394:    * codes.
 395:    *
 396:    * @return The textual representation.
 397:    */
 398:   public String toString()
 399:   {
 400:     return GSSException.class.getName() + ": " + getMessage();
 401:   }
 402: 
 403:   /**
 404:    * Returns a detailed message of this exception.  Overrides {@link
 405:    * Throwable#getMessage()}. It is customary in Java to use this method to
 406:    * obtain exception information.
 407:    *
 408:    * @return The detail message.
 409:    */
 410:   public String getMessage()
 411:   {
 412:     if (minor == 0)
 413:       return getMajorString();
 414:     else
 415:       return getMajorString() + " (" + minorString + ")";
 416:   }
 417: 
 418:   // Own methods.
 419:   // -------------------------------------------------------------------------
 420: 
 421:   private String getMsg(String key, String defaultText)
 422:   {
 423:     if (messages != null)
 424:       {
 425:         try
 426:           {
 427:             return messages.getString(key);
 428:           }
 429:         catch (Exception e)
 430:           {
 431:           }
 432:       }
 433:     return defaultText;
 434:   }
 435: }