Branch data Line data Source code
1 : : /* error.c --- Error handling functions.
2 : : * Copyright (C) 2002, 2003, 2004, 2006, 2007, 2008, 2010 Simon Josefsson
3 : : *
4 : : * This file is part of Shishi.
5 : : *
6 : : * Shishi is free software; you can redistribute it and/or modify it
7 : : * under the terms of the GNU General Public License as published by
8 : : * the Free Software Foundation; either version 3 of the License, or
9 : : * (at your option) any later version.
10 : : *
11 : : * Shishi is distributed in the hope that it will be useful, but
12 : : * WITHOUT ANY WARRANTY; without even the implied warranty of
13 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : : * GNU General Public License for more details.
15 : : *
16 : : * You should have received a copy of the GNU General Public License
17 : : * along with Shishi; if not, see http://www.gnu.org/licenses or write
18 : : * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
19 : : * Floor, Boston, MA 02110-1301, USA
20 : : *
21 : : */
22 : :
23 : : #include "internal.h"
24 : :
25 : : struct shishi_error_msgs
26 : : {
27 : : int errorcode;
28 : : const char *message;
29 : : };
30 : :
31 : : static const struct shishi_error_msgs _shishi_error_messages[] = {
32 : : {SHISHI_OK,
33 : : N_("Shishi success")},
34 : : {SHISHI_ASN1_ERROR,
35 : : N_("Error in ASN.1 function (corrupt data?)")},
36 : : {SHISHI_FOPEN_ERROR,
37 : : N_("Could not open file")},
38 : : {SHISHI_IO_ERROR,
39 : : N_("File input/output error")},
40 : : {SHISHI_MALLOC_ERROR,
41 : : N_("Memory allocation error in shishi library.")},
42 : : {SHISHI_BASE64_ERROR,
43 : : N_("Base64 encoding or decoding failed. Data corrupt?")},
44 : : {SHISHI_REALM_MISMATCH,
45 : : N_("Client realm value differ between request and reply.")},
46 : : {SHISHI_CNAME_MISMATCH,
47 : : N_("Client name value differ between request and reply.")},
48 : : {SHISHI_NONCE_MISMATCH,
49 : : N_("Replay protection value (nonce) differ between request and reply.")},
50 : : {SHISHI_TICKET_BAD_KEYTYPE,
51 : : N_("Keytype used to encrypt ticket doesn't match provided key. "
52 : : "This usually indicates an internal application error.")},
53 : : {SHISHI_CRYPTO_INTERNAL_ERROR,
54 : : N_("Internal error in low-level crypto routines.")},
55 : : {SHISHI_CRYPTO_ERROR,
56 : : N_("Low-level cryptographic primitive failed. This usually indicates "
57 : : "bad password or data corruption.")},
58 : : {SHISHI_RECVFROM_ERROR,
59 : : N_("Error receiving data from server")},
60 : : {SHISHI_KDC_TIMEOUT,
61 : : N_("Timedout talking to KDC. This usually indicates a network "
62 : : "or KDC address problem.")},
63 : : {SHISHI_KDC_NOT_KNOWN_FOR_REALM,
64 : : N_("No KDC for realm known.")},
65 : : {SHISHI_SOCKET_ERROR,
66 : : N_("The system call socket() failed. This usually indicates that "
67 : : "your system does not support the socket type.")},
68 : : {SHISHI_BIND_ERROR,
69 : : N_("The system call bind() failed. This usually indicates "
70 : : "insufficient permissions.")},
71 : : {SHISHI_SENDTO_ERROR,
72 : : N_("The system call sendto() failed.")},
73 : : {SHISHI_CLOSE_ERROR,
74 : : N_("The system call close() failed.")},
75 : : {SHISHI_GOT_KRBERROR,
76 : : N_("Server replied with an error message to request.")},
77 : : {SHISHI_INVALID_TKTS,
78 : : N_("Ticketset not initialized. This usually indicates an internal "
79 : : "application error.")},
80 : : {SHISHI_APREQ_DECRYPT_FAILED,
81 : : N_("Could not decrypt AP-REQ using provided key. "
82 : : "This usually indicates an internal application error.")},
83 : : {SHISHI_TICKET_DECRYPT_FAILED,
84 : : N_("Could not decrypt Ticket using provided key. "
85 : : "This usually indicates an internal application error.")},
86 : : {SHISHI_KEYTAB_ERROR,
87 : : N_("Failed to parse keytab file")},
88 : : {SHISHI_CCACHE_ERROR,
89 : : N_("Failed to parse credential cache file")},
90 : : {-1, NULL}
91 : : };
92 : :
93 : : /**
94 : : * shishi_strerror:
95 : : * @err: shishi error code.
96 : : *
97 : : * Convert return code to human readable string.
98 : : *
99 : : * Return value: Returns a pointer to a statically allocated string
100 : : * containing a description of the error with the error value @err.
101 : : * This string can be used to output a diagnostic message to the user.
102 : : **/
103 : : const char *
104 : 0 : shishi_strerror (int err)
105 : : {
106 : 0 : const char *p = _("Unknown error");
107 : : size_t i;
108 : :
109 [ # # ]: 0 : for (i = 0; _shishi_error_messages[i].errorcode != -1; i++)
110 [ # # ]: 0 : if (_shishi_error_messages[i].errorcode == err)
111 : : {
112 : 0 : p = _(_shishi_error_messages[i].message);
113 : 0 : break;
114 : : }
115 : :
116 : 0 : return p;
117 : :
118 : : }
119 : :
120 : : /**
121 : : * shishi_error:
122 : : * @handle: shishi handle as allocated by shishi_init().
123 : : *
124 : : * Extract detailed error information string. Note that the memory is
125 : : * managed by the Shishi library, so you must not deallocate the
126 : : * string.
127 : : *
128 : : * Return value: Returns pointer to error information string, that must
129 : : * not be deallocate by caller.
130 : : **/
131 : : const char *
132 : 1 : shishi_error (Shishi * handle)
133 : : {
134 : : if (handle->error)
135 : 1 : return handle->error;
136 : :
137 : : return _("No error");
138 : : }
139 : :
140 : : /**
141 : : * shishi_error_clear:
142 : : * @handle: shishi handle as allocated by shishi_init().
143 : : *
144 : : * Clear the detailed error information string. See shishi_error()
145 : : * for how to access the error string, and shishi_error_set() and
146 : : * shishi_error_printf() for how to set the error string. This
147 : : * function is mostly for Shishi internal use, but if you develop an
148 : : * extension of Shishi, it may be useful to use the same error
149 : : * handling infrastructure.
150 : : **/
151 : : void
152 : 0 : shishi_error_clear (Shishi * handle)
153 : : {
154 : 0 : handle->error[0] = '\0';
155 : 0 : }
156 : :
157 : : /**
158 : : * shishi_error_set:
159 : : * @handle: shishi handle as allocated by shishi_init().
160 : : * @errstr: Zero terminated character array containing error description,
161 : : * or NULL to clear the error description string.
162 : : *
163 : : * Set the detailed error information string to specified string. The
164 : : * string is copied into the Shishi internal structure, so you can
165 : : * deallocate the string passed to this function after the call. This
166 : : * function is mostly for Shishi internal use, but if you develop an
167 : : * extension of Shishi, it may be useful to use the same error
168 : : * handling infrastructure.
169 : : **/
170 : : void
171 : 5 : shishi_error_set (Shishi * handle, const char *errstr)
172 : : {
173 [ + - ]: 5 : if (errstr)
174 : : {
175 : 5 : strncpy (handle->error, errstr, sizeof (handle->error));
176 : :
177 [ - + ]: 5 : if (VERBOSENOISE (handle))
178 : 5 : puts (handle->error);
179 : : }
180 : : else
181 : 0 : shishi_error_clear (handle);
182 : 5 : }
183 : :
184 : : /**
185 : : * shishi_error_printf:
186 : : * @handle: shishi handle as allocated by shishi_init().
187 : : * @format: printf style format string.
188 : : * @...: print style arguments.
189 : : *
190 : : * Set the detailed error information string to a printf formatted
191 : : * string. This function is mostly for Shishi internal use, but if
192 : : * you develop an extension of Shishi, it may be useful to use the
193 : : * same error handling infrastructure.
194 : : **/
195 : : void
196 : 3 : shishi_error_printf (Shishi * handle, const char *format, ...)
197 : : {
198 : : va_list ap;
199 : : char *s;
200 : :
201 : 3 : va_start (ap, format);
202 : :
203 : 3 : vasprintf (&s, format, ap);
204 : 3 : strncpy (handle->error, s, sizeof (handle->error));
205 : 3 : handle->error[sizeof (handle->error) - 1] = '\0';
206 : 3 : free (s);
207 : :
208 [ - + ]: 3 : if (VERBOSE (handle))
209 : 0 : puts (handle->error);
210 : :
211 : 3 : va_end (ap);
212 : 3 : }
213 : :
214 : : /**
215 : : * shishi_error_outputtype:
216 : : * @handle: shishi handle as allocated by shishi_init().
217 : : *
218 : : * Get the current output type for logging messages.
219 : : *
220 : : * Return value: Return output type (NULL, stderr or syslog) for
221 : : * informational and warning messages.
222 : : **/
223 : : int
224 : 0 : shishi_error_outputtype (Shishi * handle)
225 : : {
226 : 0 : return handle->outputtype;
227 : : }
228 : :
229 : : /**
230 : : * shishi_error_set_outputtype:
231 : : * @handle: shishi handle as allocated by shishi_init().
232 : : * @type: output type.
233 : : *
234 : : * Set output type (NULL, stderr or syslog) for informational
235 : : * and warning messages.
236 : : **/
237 : : void
238 : 14 : shishi_error_set_outputtype (Shishi * handle, int type)
239 : : {
240 : 14 : handle->outputtype = type;
241 : 14 : }
242 : :
243 : : /**
244 : : * shishi_info:
245 : : * @handle: shishi handle as allocated by shishi_init().
246 : : * @format: printf style format string.
247 : : * @...: print style arguments.
248 : : *
249 : : * Print informational message to output as defined in handle.
250 : : **/
251 : : void
252 : 0 : shishi_info (Shishi * handle, const char *format, ...)
253 : : {
254 : : va_list ap;
255 : : char *out;
256 : : int type;
257 : :
258 : 0 : va_start (ap, format);
259 : 0 : vasprintf (&out, format, ap);
260 : :
261 : 0 : type = shishi_error_outputtype (handle);
262 [ # # ]: 0 : switch (type)
263 : : {
264 : : case SHISHI_OUTPUTTYPE_SYSLOG:
265 : : /* If we don't have syslog, log to stderr... */
266 : : #ifdef HAVE_SYSLOG
267 : : syslog (LOG_ERR, _("libshishi: info: %s"), out);
268 : : break;
269 : : #endif
270 : : case SHISHI_OUTPUTTYPE_STDERR:
271 : 0 : fprintf (stderr, _("libshishi: info: %s\n"), out);
272 : : break;
273 : : default:
274 : : break;
275 : : }
276 : :
277 : 0 : free (out);
278 : 0 : va_end (ap);
279 : 0 : }
280 : :
281 : : /**
282 : : * shishi_warn:
283 : : * @handle: shishi handle as allocated by shishi_init().
284 : : * @format: printf style format string.
285 : : * @...: print style arguments.
286 : : *
287 : : * Print a warning to output as defined in handle.
288 : : **/
289 : : void
290 : 0 : shishi_warn (Shishi * handle, const char *format, ...)
291 : : {
292 : : va_list ap;
293 : : char *out;
294 : : int type;
295 : :
296 : 0 : va_start (ap, format);
297 : 0 : vasprintf (&out, format, ap);
298 : :
299 : 0 : type = shishi_error_outputtype (handle);
300 [ # # ]: 0 : switch (type)
301 : : {
302 : : case SHISHI_OUTPUTTYPE_SYSLOG:
303 : : /* If we don't have syslog, log to stderr... */
304 : : #ifdef HAVE_SYSLOG
305 : : syslog (LOG_ERR, _("libshishi: warning: %s"), out);
306 : : break;
307 : : #endif
308 : : case SHISHI_OUTPUTTYPE_STDERR:
309 : 0 : fprintf (stderr, _("libshishi: warning: %s\n"), out);
310 : : break;
311 : : default:
312 : : break;
313 : : }
314 : :
315 : 0 : free (out);
316 : 0 : va_end (ap);
317 : 0 : }
318 : :
319 : : /**
320 : : * shishi_verbose:
321 : : * @handle: shishi handle as allocated by shishi_init().
322 : : * @format: printf style format string.
323 : : * @...: print style arguments.
324 : : *
325 : : * Print a diagnostic message to output as defined in handle.
326 : : **/
327 : : void
328 : 0 : shishi_verbose (Shishi * handle, const char *format, ...)
329 : : {
330 : : va_list ap;
331 : : char *out;
332 : : int type;
333 : :
334 [ # # ]: 0 : if (!VERBOSE (handle))
335 : 0 : return;
336 : :
337 : 0 : va_start (ap, format);
338 : 0 : vasprintf (&out, format, ap);
339 : :
340 : 0 : type = shishi_error_outputtype (handle);
341 [ # # ]: 0 : switch (type)
342 : : {
343 : : case SHISHI_OUTPUTTYPE_SYSLOG:
344 : : /* If we don't have syslog, log to stderr... */
345 : : #ifdef HAVE_SYSLOG
346 : : syslog (LOG_DEBUG, "%s", out);
347 : : break;
348 : : #endif
349 : : case SHISHI_OUTPUTTYPE_STDERR:
350 : 0 : fprintf (stderr, "%s\n", out);
351 : : break;
352 : : default:
353 : : break;
354 : : }
355 : :
356 : 0 : free (out);
357 : 0 : va_end (ap);
358 : : }
|