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