Home | History | Annotate | Line # | Download | only in krb5
      1  1.1     elric /*	$NetBSD: display_status.c,v 1.3 2023/06/19 21:41:43 christos Exp $	*/
      2  1.1     elric 
      3  1.1     elric /*
      4  1.1     elric  * Copyright (c) 1998 - 2006 Kungliga Tekniska Hgskolan
      5  1.1     elric  * (Royal Institute of Technology, Stockholm, Sweden).
      6  1.1     elric  * All rights reserved.
      7  1.1     elric  *
      8  1.1     elric  * Redistribution and use in source and binary forms, with or without
      9  1.1     elric  * modification, are permitted provided that the following conditions
     10  1.1     elric  * are met:
     11  1.1     elric  *
     12  1.1     elric  * 1. Redistributions of source code must retain the above copyright
     13  1.1     elric  *    notice, this list of conditions and the following disclaimer.
     14  1.1     elric  *
     15  1.1     elric  * 2. Redistributions in binary form must reproduce the above copyright
     16  1.1     elric  *    notice, this list of conditions and the following disclaimer in the
     17  1.1     elric  *    documentation and/or other materials provided with the distribution.
     18  1.1     elric  *
     19  1.1     elric  * 3. Neither the name of the Institute nor the names of its contributors
     20  1.1     elric  *    may be used to endorse or promote products derived from this software
     21  1.1     elric  *    without specific prior written permission.
     22  1.1     elric  *
     23  1.1     elric  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
     24  1.1     elric  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     25  1.1     elric  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26  1.1     elric  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
     27  1.1     elric  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     28  1.1     elric  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     29  1.1     elric  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     30  1.1     elric  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     31  1.1     elric  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     32  1.1     elric  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     33  1.1     elric  * SUCH DAMAGE.
     34  1.1     elric  */
     35  1.1     elric 
     36  1.1     elric #include "gsskrb5_locl.h"
     37  1.1     elric 
     38  1.1     elric static const char *
     39  1.1     elric calling_error(OM_uint32 v)
     40  1.1     elric {
     41  1.1     elric     static const char *msgs[] = {
     42  1.1     elric 	NULL,			/* 0 */
     43  1.1     elric 	"A required input parameter could not be read.", /*  */
     44  1.1     elric 	"A required output parameter could not be written.", /*  */
     45  1.1     elric 	"A parameter was malformed"
     46  1.1     elric     };
     47  1.1     elric 
     48  1.1     elric     v >>= GSS_C_CALLING_ERROR_OFFSET;
     49  1.1     elric 
     50  1.1     elric     if (v == 0)
     51  1.1     elric 	return "";
     52  1.1     elric     else if (v >= sizeof(msgs)/sizeof(*msgs))
     53  1.1     elric 	return "unknown calling error";
     54  1.1     elric     else
     55  1.1     elric 	return msgs[v];
     56  1.1     elric }
     57  1.1     elric 
     58  1.1     elric static const char *
     59  1.1     elric routine_error(OM_uint32 v)
     60  1.1     elric {
     61  1.1     elric     static const char *msgs[] = {
     62  1.1     elric 	NULL,			/* 0 */
     63  1.1     elric 	"An unsupported mechanism was requested",
     64  1.1     elric 	"An invalid name was supplied",
     65  1.1     elric 	"A supplied name was of an unsupported type",
     66  1.1     elric 	"Incorrect channel bindings were supplied",
     67  1.1     elric 	"An invalid status code was supplied",
     68  1.1     elric 	"A token had an invalid MIC",
     69  1.3  christos 	"No credentials were supplied, or the credentials were unavailable or inaccessible.",
     70  1.1     elric 	"No context has been established",
     71  1.1     elric 	"A token was invalid",
     72  1.1     elric 	"A credential was invalid",
     73  1.1     elric 	"The referenced credentials have expired",
     74  1.1     elric 	"The context has expired",
     75  1.1     elric 	"Miscellaneous failure (see text)",
     76  1.1     elric 	"The quality-of-protection requested could not be provide",
     77  1.1     elric 	"The operation is forbidden by local security policy",
     78  1.1     elric 	"The operation or option is not available",
     79  1.1     elric 	"The requested credential element already exists",
     80  1.1     elric 	"The provided name was not a mechanism name.",
     81  1.1     elric     };
     82  1.1     elric 
     83  1.1     elric     v >>= GSS_C_ROUTINE_ERROR_OFFSET;
     84  1.1     elric 
     85  1.1     elric     if (v == 0)
     86  1.1     elric 	return "";
     87  1.1     elric     else if (v >= sizeof(msgs)/sizeof(*msgs))
     88  1.1     elric 	return "unknown routine error";
     89  1.1     elric     else
     90  1.1     elric 	return msgs[v];
     91  1.1     elric }
     92  1.1     elric 
     93  1.1     elric static const char *
     94  1.1     elric supplementary_error(OM_uint32 v)
     95  1.1     elric {
     96  1.1     elric     static const char *msgs[] = {
     97  1.1     elric 	"normal completion",
     98  1.1     elric 	"continuation call to routine required",
     99  1.1     elric 	"duplicate per-message token detected",
    100  1.1     elric 	"timed-out per-message token detected",
    101  1.1     elric 	"reordered (early) per-message token detected",
    102  1.1     elric 	"skipped predecessor token(s) detected"
    103  1.1     elric     };
    104  1.1     elric 
    105  1.1     elric     v >>= GSS_C_SUPPLEMENTARY_OFFSET;
    106  1.1     elric 
    107  1.1     elric     if (v >= sizeof(msgs)/sizeof(*msgs))
    108  1.1     elric 	return "unknown routine error";
    109  1.1     elric     else
    110  1.1     elric 	return msgs[v];
    111  1.1     elric }
    112  1.1     elric 
    113  1.1     elric void
    114  1.1     elric _gsskrb5_clear_status (void)
    115  1.1     elric {
    116  1.1     elric     krb5_context context;
    117  1.1     elric 
    118  1.1     elric     if (_gsskrb5_init (&context) != 0)
    119  1.1     elric 	return;
    120  1.1     elric     krb5_clear_error_message(context);
    121  1.1     elric }
    122  1.1     elric 
    123  1.1     elric void
    124  1.1     elric _gsskrb5_set_status (int ret, const char *fmt, ...)
    125  1.1     elric {
    126  1.1     elric     krb5_context context;
    127  1.1     elric     va_list args;
    128  1.1     elric     char *str;
    129  1.1     elric     int e;
    130  1.1     elric 
    131  1.1     elric     if (_gsskrb5_init (&context) != 0)
    132  1.1     elric 	return;
    133  1.1     elric 
    134  1.1     elric     va_start(args, fmt);
    135  1.1     elric     e = vasprintf(&str, fmt, args);
    136  1.1     elric     va_end(args);
    137  1.1     elric     if (e >= 0 && str) {
    138  1.1     elric 	krb5_set_error_message(context, ret, "%s", str);
    139  1.1     elric 	free(str);
    140  1.1     elric     }
    141  1.1     elric }
    142  1.1     elric 
    143  1.1     elric OM_uint32 GSSAPI_CALLCONV _gsskrb5_display_status
    144  1.1     elric (OM_uint32		*minor_status,
    145  1.1     elric  OM_uint32		 status_value,
    146  1.1     elric  int			 status_type,
    147  1.1     elric  const gss_OID	 mech_type,
    148  1.1     elric  OM_uint32		*message_context,
    149  1.1     elric  gss_buffer_t	 status_string)
    150  1.1     elric {
    151  1.1     elric     krb5_context context;
    152  1.1     elric     char *buf = NULL;
    153  1.1     elric     int e = 0;
    154  1.1     elric 
    155  1.1     elric     GSSAPI_KRB5_INIT (&context);
    156  1.1     elric 
    157  1.1     elric     status_string->length = 0;
    158  1.1     elric     status_string->value = NULL;
    159  1.1     elric 
    160  1.1     elric     if (gss_oid_equal(mech_type, GSS_C_NO_OID) == 0 &&
    161  1.1     elric 	gss_oid_equal(mech_type, GSS_KRB5_MECHANISM) == 0) {
    162  1.1     elric 	*minor_status = 0;
    163  1.1     elric 	return GSS_C_GSS_CODE;
    164  1.1     elric     }
    165  1.1     elric 
    166  1.1     elric     if (status_type == GSS_C_GSS_CODE) {
    167  1.1     elric 	if (GSS_SUPPLEMENTARY_INFO(status_value))
    168  1.1     elric 	    e = asprintf(&buf, "%s",
    169  1.1     elric 			 supplementary_error(GSS_SUPPLEMENTARY_INFO(status_value)));
    170  1.1     elric 	else
    171  1.1     elric 	    e = asprintf (&buf, "%s %s",
    172  1.1     elric 			  calling_error(GSS_CALLING_ERROR(status_value)),
    173  1.1     elric 			  routine_error(GSS_ROUTINE_ERROR(status_value)));
    174  1.1     elric     } else if (status_type == GSS_C_MECH_CODE) {
    175  1.1     elric 	const char *buf2 = krb5_get_error_message(context, status_value);
    176  1.1     elric 	if (buf2) {
    177  1.1     elric 	    buf = strdup(buf2);
    178  1.1     elric 	    krb5_free_error_message(context, buf2);
    179  1.1     elric 	} else {
    180  1.1     elric 	    e = asprintf(&buf, "unknown mech error-code %u",
    181  1.1     elric 			 (unsigned)status_value);
    182  1.1     elric 	}
    183  1.1     elric     } else {
    184  1.1     elric 	*minor_status = EINVAL;
    185  1.1     elric 	return GSS_S_BAD_STATUS;
    186  1.1     elric     }
    187  1.1     elric 
    188  1.1     elric     if (e < 0 || buf == NULL) {
    189  1.1     elric 	*minor_status = ENOMEM;
    190  1.1     elric 	return GSS_S_FAILURE;
    191  1.1     elric     }
    192  1.1     elric 
    193  1.1     elric     *message_context = 0;
    194  1.1     elric     *minor_status = 0;
    195  1.1     elric 
    196  1.1     elric     status_string->length = strlen(buf);
    197  1.1     elric     status_string->value  = buf;
    198  1.1     elric 
    199  1.1     elric     return GSS_S_COMPLETE;
    200  1.1     elric }
    201