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