1 /*
2 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
6 #pragma ident "@(#)g_dsp_status.c 1.18 04/09/08 SMI"
7
8 /*
9 * glue routine gss_display_status
10 *
11 */
12
13 #include <mechglueP.h>
14 #include <stdio.h>
15 #ifdef HAVE_STDLIB_H
16 #include <stdlib.h>
17 #endif
18 #include <string.h>
19 #include <libintl.h>
20 #include <errno.h>
21
22 #ifndef TEXT_DOMAIN
23 #error TEXT_DOMAIN not defined
24 #endif
25
26 /* local function */
27 static OM_uint32 displayMajor(OM_uint32, OM_uint32 *, gss_buffer_t);
28
29
30 OM_uint32
31 gss_display_status(minor_status,
32 status_value,
33 status_type,
34 req_mech_type,
35 message_context,
36 status_string)
37
38 OM_uint32 *minor_status;
39 OM_uint32 status_value;
40 int status_type;
41 const gss_OID req_mech_type;
42 OM_uint32 *message_context;
43 gss_buffer_t status_string;
44 {
45 OM_uint32 status;
46 gss_OID mech_type = (gss_OID) req_mech_type;
47 gss_mechanism mech;
48
49 gss_initialize();
50
51 /*
52 * select the approprate underlying mechanism routine and
53 * call it.
54 */
55 mech = __gss_get_mechanism(mech_type);
56
57 if (mech_type == GSS_C_NULL_OID)
58 mech_type = &mech->mech_type;
59
60 if (mech->gss_display_status)
61 status = mech->gss_display_status(mech->context, minor_status,
62 status_value, status_type, mech_type,
63 message_context, status_string));
64 else
65 status = GSS_S_BAD_BINDINGS;
66
67 return (status);
68 } /* gss_display_status */
69
|
1 /*
2 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
6 #pragma ident "@(#)g_dsp_status.c 1.17 04/02/23 SMI"
7
8 /*
9 * glue routine gss_display_status
10 *
11 */
12
13 #include <mechglueP.h>
14 #include <stdio.h>
15 #ifdef HAVE_STDLIB_H
16 #include <stdlib.h>
17 #endif
18 #include <string.h>
19 #include <libintl.h>
20 #include <errno.h>
21
22 #ifndef TEXT_DOMAIN
23 #error TEXT_DOMAIN not defined
24 #endif
25
26 /* local function */
27 static OM_uint32 displayMajor(OM_uint32, OM_uint32 *, gss_buffer_t);
28
29
30 OM_uint32
31 gss_display_status(minor_status,
32 status_value,
33 status_type,
34 req_mech_type,
35 message_context,
36 status_string)
37
38 OM_uint32 *minor_status;
39 OM_uint32 status_value;
40 int status_type;
41 const gss_OID req_mech_type;
42 OM_uint32 *message_context;
43 gss_buffer_t status_string;
44 {
45 gss_OID mech_type = (gss_OID) req_mech_type;
46 gss_mechanism mech;
47
48 /* check the input parameters */
49 if (!minor_status)
50 return (GSS_S_CALL_INACCESSIBLE_WRITE);
51
52 *minor_status = 0;
53
54 if (!message_context || status_string == NULL)
55 return (GSS_S_CALL_INACCESSIBLE_WRITE);
56
57 status_string->length = 0;
58 status_string->value = NULL;
59
60 /* we handle major status codes, and the mechs do the minor */
61 if (status_type == GSS_C_GSS_CODE)
62 return (displayMajor(status_value, message_context,
63 status_string));
64
65 /*
66 * must be the minor status - let mechs do the work
67 * select the appropriate underlying mechanism routine and
68 * call it.
69 */
70 mech = __gss_get_mechanism(mech_type);
71
72 if (mech && mech->gss_display_status) {
73 if (mech_type == GSS_C_NULL_OID)
74 mech_type = &mech->mech_type;
75
76 return (mech->gss_display_status(mech->context, minor_status,
77 status_value, status_type, mech_type,
78 message_context, status_string));
79 }
80
81 if (!mech)
82 return (GSS_S_BAD_MECH);
83
84 return (GSS_S_UNAVAILABLE);
85 } /* gss_display_status */
86
87
88 /*
89 * function to map the major error codes
90 * it uses case statements so that the strings could be wrapped by gettext
91 * msgCtxt is interpreted as:
92 * 0 - first call
93 * 1 - routine error
94 * >= 2 - the supplementary error code bit shifted by 1
95 */
96 static OM_uint32
97 displayMajor(status, msgCtxt, outStr)
98 OM_uint32 status;
99 OM_uint32 *msgCtxt;
100 gss_buffer_t outStr;
101 {
102 OM_uint32 oneVal, mask = 0x1, currErr;
103 char *errStr = NULL;
104 int i, haveErr = 0;
105
106 /* take care of the success value first */
107 if (status == GSS_S_COMPLETE)
108 errStr = dgettext(TEXT_DOMAIN,
109 "The routine completed successfully");
110 else if (*msgCtxt == 0 && (oneVal = GSS_CALLING_ERROR(status))) {
111 switch (oneVal) {
112 case GSS_S_CALL_INACCESSIBLE_READ:
113 errStr = dgettext(TEXT_DOMAIN,
114 "A required input parameter"
115 " could not be read");
116 break;
117
118 case GSS_S_CALL_INACCESSIBLE_WRITE:
119 errStr = dgettext(TEXT_DOMAIN,
120 "A required output parameter"
121 " could not be written");
122 break;
123
124 case GSS_S_CALL_BAD_STRUCTURE:
125 errStr = dgettext(TEXT_DOMAIN,
126 "A parameter was malformed");
127 break;
128
129 default:
130 errStr = dgettext(TEXT_DOMAIN,
131 "An invalid status code was supplied");
132 break;
133 }
134
135 /* we now need to determine new value of msgCtxt */
136 if (GSS_ROUTINE_ERROR(status))
137 *msgCtxt = 1;
138 else if ((oneVal = GSS_SUPPLEMENTARY_INFO(status)) != 0)
139 *msgCtxt = (OM_uint32)(oneVal << 1);
140 else
141 *msgCtxt = 0;
142
143 } else if ((*msgCtxt == 0 || *msgCtxt == 1) &&
144 (oneVal = GSS_ROUTINE_ERROR(status))) {
145 switch (oneVal) {
146 case GSS_S_BAD_MECH:
147 errStr = dgettext(TEXT_DOMAIN,
148 "An unsupported mechanism"
149 " was requested");
150 break;
151
152 case GSS_S_BAD_NAME:
153 errStr = dgettext(TEXT_DOMAIN,
154 "An invalid name was supplied");
155 break;
156
157 case GSS_S_BAD_NAMETYPE:
158 errStr = dgettext(TEXT_DOMAIN,
159 "A supplied name was of an"
160 " unsupported type");
161 break;
162
163 case GSS_S_BAD_BINDINGS:
164 errStr = dgettext(TEXT_DOMAIN,
165 "Incorrect channel bindings"
166 " were supplied");
167 break;
168
169 case GSS_S_BAD_SIG: /* same as GSS_S_BAD_MIC: */
170 errStr = dgettext(TEXT_DOMAIN,
171 "A token had an invalid Message"
172 " Integrity Check (MIC)");
173 break;
174
175 case GSS_S_NO_CRED:
176 errStr = dgettext(TEXT_DOMAIN,
177 "No credentials were supplied, or the"
178 " credentials were unavailable or"
179 " inaccessible");
180 break;
181
182 case GSS_S_NO_CONTEXT:
183 errStr = dgettext(TEXT_DOMAIN,
184 "No context has been established");
185 break;
186
187 case GSS_S_DEFECTIVE_TOKEN:
188 errStr = dgettext(TEXT_DOMAIN,
189 "Invalid token was supplied");
190 break;
191
192 case GSS_S_DEFECTIVE_CREDENTIAL:
193 errStr = dgettext(TEXT_DOMAIN,
194 "Invalid credential was supplied");
195 break;
196
197 case GSS_S_CREDENTIALS_EXPIRED:
198 errStr = dgettext(TEXT_DOMAIN,
199 "The referenced credential has"
200 " expired");
201 break;
202
203 case GSS_S_CONTEXT_EXPIRED:
204 errStr = dgettext(TEXT_DOMAIN,
205 "The referenced context has expired");
206 break;
207
208 case GSS_S_FAILURE:
209 errStr = dgettext(TEXT_DOMAIN,
210 "Unspecified GSS failure. Minor code"
211 " may provide more information");
212 break;
213
214 case GSS_S_BAD_QOP:
215 errStr = dgettext(TEXT_DOMAIN,
216 "The quality-of-protection (QOP) "
217 "requested could not be provided");
218 break;
219
220 case GSS_S_UNAUTHORIZED:
221 errStr = dgettext(TEXT_DOMAIN,
222 "The operation is forbidden by local"
223 " security policy");
224 break;
225
226 case GSS_S_UNAVAILABLE:
227 errStr = dgettext(TEXT_DOMAIN,
228 "The operation or option is not"
229 " available or unsupported");
230 break;
231
232 case GSS_S_DUPLICATE_ELEMENT:
233 errStr = dgettext(TEXT_DOMAIN,
234 "The requested credential element"
235 " already exists");
236 break;
237
238 case GSS_S_NAME_NOT_MN:
239 errStr = dgettext(TEXT_DOMAIN,
240 "The provided name was not mechanism"
241 " specific (MN)");
242 break;
243
244 case GSS_S_BAD_STATUS:
245 default:
246 errStr = dgettext(TEXT_DOMAIN,
247 "An invalid status code was supplied");
248 }
249
250 /* we must determine if the caller should call us again */
251 if ((oneVal = GSS_SUPPLEMENTARY_INFO(status)) != 0)
252 *msgCtxt = (OM_uint32)(oneVal << 1);
253 else
254 *msgCtxt = 0;
255
256 } else if ((*msgCtxt == 0 || *msgCtxt >= 2) &&
257 (oneVal = GSS_SUPPLEMENTARY_INFO(status))) {
258 /*
259 * if msgCtxt is not 0, then it should encode
260 * the supplementary error code we should be printing
261 */
262 if (*msgCtxt >= 2)
263 oneVal = (OM_uint32) (*msgCtxt) >> 1;
264 else
265 oneVal = GSS_SUPPLEMENTARY_INFO(status);
266
267 /* we display the errors LSB first */
268 for (i = 0; i < 16; i++) {
269 if (oneVal & mask) {
270 haveErr = 1;
271 break;
272 }
273 mask <<= 1;
274 }
275
276 /* isolate the bit or if not found set to illegal value */
277 if (haveErr)
278 currErr = oneVal & mask;
279 else
280 currErr = 1 << 17; /* illegal value */
281
282 switch (currErr) {
283 case GSS_S_CONTINUE_NEEDED:
284 errStr = dgettext(TEXT_DOMAIN,
285 "The routine must be called again to"
286 " complete its function");
287 break;
288
289 case GSS_S_DUPLICATE_TOKEN:
290 errStr = dgettext(TEXT_DOMAIN,
291 "The token was a duplicate of an"
292 " earlier token");
293 break;
294
295 case GSS_S_OLD_TOKEN:
296 errStr = dgettext(TEXT_DOMAIN,
297 "The token's validity period"
298 " has expired");
299 break;
300
301 case GSS_S_UNSEQ_TOKEN:
302 errStr = dgettext(TEXT_DOMAIN,
303 "A later token has already been"
304 " processed");
305 break;
306
307 case GSS_S_GAP_TOKEN:
308 errStr = dgettext(TEXT_DOMAIN,
309 "An expected per-message token was"
310 " not received");
311 break;
312
313 default:
314 errStr = dgettext(TEXT_DOMAIN,
315 "An invalid status code was supplied");
316 }
317
318 /*
319 * we must check if there is any other supplementary errors
320 * if found, then turn off current bit, and store next value
321 * in msgCtxt shifted by 1 bit
322 */
323 if (!haveErr)
324 *msgCtxt = 0;
325 else if (GSS_SUPPLEMENTARY_INFO(oneVal) ^ mask)
326 *msgCtxt = (OM_uint32)
327 ((GSS_SUPPLEMENTARY_INFO(oneVal) ^ mask) << 1);
328 else
329 *msgCtxt = 0;
330 }
331
332 if (errStr == NULL)
333 errStr = dgettext(TEXT_DOMAIN,
334 "An invalid status code was supplied");
335
336 /* now copy the status code and return to caller */
337 outStr->length = strlen(errStr);
338 outStr->value = malloc((size_t)outStr->length+1);
339 if (outStr->value == NULL) {
340 outStr->length = 0;
341 return (GSS_S_FAILURE);
342 }
343
344 (void) strcpy((char *)outStr->value, errStr);
345 return (GSS_S_COMPLETE);
346 } /* displayMajor */
|