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