Sdiff g_dsp_status.c
  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 */