xref: /freebsd/crypto/heimdal/lib/hx509/error.c (revision 6a068746777241722b2b32c5d0bc443a2a64d80b)
1c19800e8SDoug Rabson /*
2*ae771770SStanislav Sedov  * Copyright (c) 2006 - 2007 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 "hx_locl.h"
35c19800e8SDoug Rabson 
36c19800e8SDoug Rabson /**
37c19800e8SDoug Rabson  * @page page_error Hx509 error reporting functions
38c19800e8SDoug Rabson  *
39c19800e8SDoug Rabson  * See the library functions here: @ref hx509_error
40c19800e8SDoug Rabson  */
41c19800e8SDoug Rabson 
42c19800e8SDoug Rabson struct hx509_error_data {
43c19800e8SDoug Rabson     hx509_error next;
44c19800e8SDoug Rabson     int code;
45c19800e8SDoug Rabson     char *msg;
46c19800e8SDoug Rabson };
47c19800e8SDoug Rabson 
48c19800e8SDoug Rabson static void
free_error_string(hx509_error msg)49c19800e8SDoug Rabson free_error_string(hx509_error msg)
50c19800e8SDoug Rabson {
51c19800e8SDoug Rabson     while(msg) {
52c19800e8SDoug Rabson 	hx509_error m2 = msg->next;
53c19800e8SDoug Rabson 	free(msg->msg);
54c19800e8SDoug Rabson 	free(msg);
55c19800e8SDoug Rabson 	msg = m2;
56c19800e8SDoug Rabson     }
57c19800e8SDoug Rabson }
58c19800e8SDoug Rabson 
59c19800e8SDoug Rabson /**
60c19800e8SDoug Rabson  * Resets the error strings the hx509 context.
61c19800e8SDoug Rabson  *
62c19800e8SDoug Rabson  * @param context A hx509 context.
63c19800e8SDoug Rabson  *
64c19800e8SDoug Rabson  * @ingroup hx509_error
65c19800e8SDoug Rabson  */
66c19800e8SDoug Rabson 
67c19800e8SDoug Rabson void
hx509_clear_error_string(hx509_context context)68c19800e8SDoug Rabson hx509_clear_error_string(hx509_context context)
69c19800e8SDoug Rabson {
70*ae771770SStanislav Sedov     if (context) {
71c19800e8SDoug Rabson 	free_error_string(context->error);
72c19800e8SDoug Rabson 	context->error = NULL;
73c19800e8SDoug Rabson     }
74*ae771770SStanislav Sedov }
75c19800e8SDoug Rabson 
76c19800e8SDoug Rabson /**
77c19800e8SDoug Rabson  * Add an error message to the hx509 context.
78c19800e8SDoug Rabson  *
79c19800e8SDoug Rabson  * @param context A hx509 context.
80c19800e8SDoug Rabson  * @param flags
81c19800e8SDoug Rabson  * - HX509_ERROR_APPEND appends the error string to the old messages
82c19800e8SDoug Rabson      (code is updated).
83c19800e8SDoug Rabson  * @param code error code related to error message
84c19800e8SDoug Rabson  * @param fmt error message format
85c19800e8SDoug Rabson  * @param ap arguments to error message format
86c19800e8SDoug Rabson  *
87c19800e8SDoug Rabson  * @ingroup hx509_error
88c19800e8SDoug Rabson  */
89c19800e8SDoug Rabson 
90c19800e8SDoug Rabson void
hx509_set_error_stringv(hx509_context context,int flags,int code,const char * fmt,va_list ap)91c19800e8SDoug Rabson hx509_set_error_stringv(hx509_context context, int flags, int code,
92c19800e8SDoug Rabson 			const char *fmt, va_list ap)
93c19800e8SDoug Rabson {
94c19800e8SDoug Rabson     hx509_error msg;
95c19800e8SDoug Rabson 
96*ae771770SStanislav Sedov     if (context == NULL)
97*ae771770SStanislav Sedov 	return;
98*ae771770SStanislav Sedov 
99c19800e8SDoug Rabson     msg = calloc(1, sizeof(*msg));
100c19800e8SDoug Rabson     if (msg == NULL) {
101c19800e8SDoug Rabson 	hx509_clear_error_string(context);
102c19800e8SDoug Rabson 	return;
103c19800e8SDoug Rabson     }
104c19800e8SDoug Rabson 
105c19800e8SDoug Rabson     if (vasprintf(&msg->msg, fmt, ap) == -1) {
106c19800e8SDoug Rabson 	hx509_clear_error_string(context);
107c19800e8SDoug Rabson 	free(msg);
108c19800e8SDoug Rabson 	return;
109c19800e8SDoug Rabson     }
110c19800e8SDoug Rabson     msg->code = code;
111c19800e8SDoug Rabson 
112c19800e8SDoug Rabson     if (flags & HX509_ERROR_APPEND) {
113c19800e8SDoug Rabson 	msg->next = context->error;
114c19800e8SDoug Rabson 	context->error = msg;
115c19800e8SDoug Rabson     } else  {
116c19800e8SDoug Rabson 	free_error_string(context->error);
117c19800e8SDoug Rabson 	context->error = msg;
118c19800e8SDoug Rabson     }
119c19800e8SDoug Rabson }
120c19800e8SDoug Rabson 
121c19800e8SDoug Rabson /**
122c19800e8SDoug Rabson  * See hx509_set_error_stringv().
123c19800e8SDoug Rabson  *
124c19800e8SDoug Rabson  * @param context A hx509 context.
125c19800e8SDoug Rabson  * @param flags
126c19800e8SDoug Rabson  * - HX509_ERROR_APPEND appends the error string to the old messages
127c19800e8SDoug Rabson      (code is updated).
128c19800e8SDoug Rabson  * @param code error code related to error message
129c19800e8SDoug Rabson  * @param fmt error message format
130c19800e8SDoug Rabson  * @param ... arguments to error message format
131c19800e8SDoug Rabson  *
132c19800e8SDoug Rabson  * @ingroup hx509_error
133c19800e8SDoug Rabson  */
134c19800e8SDoug Rabson 
135c19800e8SDoug Rabson void
hx509_set_error_string(hx509_context context,int flags,int code,const char * fmt,...)136c19800e8SDoug Rabson hx509_set_error_string(hx509_context context, int flags, int code,
137c19800e8SDoug Rabson 		       const char *fmt, ...)
138c19800e8SDoug Rabson {
139c19800e8SDoug Rabson     va_list ap;
140c19800e8SDoug Rabson 
141c19800e8SDoug Rabson     va_start(ap, fmt);
142c19800e8SDoug Rabson     hx509_set_error_stringv(context, flags, code, fmt, ap);
143c19800e8SDoug Rabson     va_end(ap);
144c19800e8SDoug Rabson }
145c19800e8SDoug Rabson 
146c19800e8SDoug Rabson /**
147c19800e8SDoug Rabson  * Get an error string from context associated with error_code.
148c19800e8SDoug Rabson  *
149c19800e8SDoug Rabson  * @param context A hx509 context.
150c19800e8SDoug Rabson  * @param error_code Get error message for this error code.
151c19800e8SDoug Rabson  *
152c19800e8SDoug Rabson  * @return error string, free with hx509_free_error_string().
153c19800e8SDoug Rabson  *
154c19800e8SDoug Rabson  * @ingroup hx509_error
155c19800e8SDoug Rabson  */
156c19800e8SDoug Rabson 
157c19800e8SDoug Rabson char *
hx509_get_error_string(hx509_context context,int error_code)158c19800e8SDoug Rabson hx509_get_error_string(hx509_context context, int error_code)
159c19800e8SDoug Rabson {
160c19800e8SDoug Rabson     struct rk_strpool *p = NULL;
161c19800e8SDoug Rabson     hx509_error msg = context->error;
162c19800e8SDoug Rabson 
163c19800e8SDoug Rabson     if (msg == NULL || msg->code != error_code) {
164c19800e8SDoug Rabson 	const char *cstr;
165c19800e8SDoug Rabson 	char *str;
166c19800e8SDoug Rabson 
167c19800e8SDoug Rabson 	cstr = com_right(context->et_list, error_code);
168c19800e8SDoug Rabson 	if (cstr)
169c19800e8SDoug Rabson 	    return strdup(cstr);
170c19800e8SDoug Rabson 	cstr = strerror(error_code);
171c19800e8SDoug Rabson 	if (cstr)
172c19800e8SDoug Rabson 	    return strdup(cstr);
173c19800e8SDoug Rabson 	if (asprintf(&str, "<unknown error: %d>", error_code) == -1)
174c19800e8SDoug Rabson 	    return NULL;
175c19800e8SDoug Rabson 	return str;
176c19800e8SDoug Rabson     }
177c19800e8SDoug Rabson 
178c19800e8SDoug Rabson     for (msg = context->error; msg; msg = msg->next)
179c19800e8SDoug Rabson 	p = rk_strpoolprintf(p, "%s%s", msg->msg,
180c19800e8SDoug Rabson 			     msg->next != NULL ? "; " : "");
181c19800e8SDoug Rabson 
182c19800e8SDoug Rabson     return rk_strpoolcollect(p);
183c19800e8SDoug Rabson }
184c19800e8SDoug Rabson 
185c19800e8SDoug Rabson /**
186c19800e8SDoug Rabson  * Free error string returned by hx509_get_error_string().
187c19800e8SDoug Rabson  *
188c19800e8SDoug Rabson  * @param str error string to free.
189c19800e8SDoug Rabson  *
190c19800e8SDoug Rabson  * @ingroup hx509_error
191c19800e8SDoug Rabson  */
192c19800e8SDoug Rabson 
193c19800e8SDoug Rabson void
hx509_free_error_string(char * str)194c19800e8SDoug Rabson hx509_free_error_string(char *str)
195c19800e8SDoug Rabson {
196c19800e8SDoug Rabson     free(str);
197c19800e8SDoug Rabson }
198c19800e8SDoug Rabson 
199c19800e8SDoug Rabson /**
200c19800e8SDoug Rabson  * Print error message and fatally exit from error code
201c19800e8SDoug Rabson  *
202c19800e8SDoug Rabson  * @param context A hx509 context.
203c19800e8SDoug Rabson  * @param exit_code exit() code from process.
204c19800e8SDoug Rabson  * @param error_code Error code for the reason to exit.
205c19800e8SDoug Rabson  * @param fmt format string with the exit message.
206c19800e8SDoug Rabson  * @param ... argument to format string.
207c19800e8SDoug Rabson  *
208c19800e8SDoug Rabson  * @ingroup hx509_error
209c19800e8SDoug Rabson  */
210c19800e8SDoug Rabson 
211c19800e8SDoug Rabson void
hx509_err(hx509_context context,int exit_code,int error_code,const char * fmt,...)212c19800e8SDoug Rabson hx509_err(hx509_context context, int exit_code,
213c19800e8SDoug Rabson 	  int error_code, const char *fmt, ...)
214c19800e8SDoug Rabson {
215c19800e8SDoug Rabson     va_list ap;
216c19800e8SDoug Rabson     const char *msg;
217c19800e8SDoug Rabson     char *str;
218c19800e8SDoug Rabson 
219c19800e8SDoug Rabson     va_start(ap, fmt);
220c19800e8SDoug Rabson     vasprintf(&str, fmt, ap);
221c19800e8SDoug Rabson     va_end(ap);
222c19800e8SDoug Rabson     msg = hx509_get_error_string(context, error_code);
223c19800e8SDoug Rabson     if (msg == NULL)
224c19800e8SDoug Rabson 	msg = "no error";
225c19800e8SDoug Rabson 
226c19800e8SDoug Rabson     errx(exit_code, "%s: %s", str, msg);
227c19800e8SDoug Rabson }
228