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      */
GSSException(int majorCode)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      */
GSSException(int majorCode, String majorString)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      */
GSSException(int majorCode, int minorCode, String minorString)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      */
getMajor()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      */
getMinor()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      */
getMajorString()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      */
getMinorString()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      */
setMinor(int minorCode, String message)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      */
toString()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      */
getMessage()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      */
validateMajor(int major)396     private boolean validateMajor(int major) {
397 
398         if (major > 0 && major <= messages.length)
399             return (true);
400 
401         return (false);
402     }
403 }
404