Git init
[external/xmlsec1.git] / src / errors.c
1 /** 
2  * XML Security Library (http://www.aleksey.com/xmlsec).
3  *
4  * Error codes and error reporting functions.
5  *
6  * This is free software; see Copyright file in the source
7  * distribution for preciese wording.
8  * 
9  * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
10  */
11 #include "globals.h"
12
13 #include <stdlib.h>
14 #include <stdio.h>
15 #include <stdarg.h>
16 #include <time.h>
17
18 #include <libxml/tree.h>
19
20 #include <xmlsec/xmlsec.h>
21 #include <xmlsec/xmltree.h>
22 #include <xmlsec/private.h>
23 #include <xmlsec/errors.h>
24
25 #define XMLSEC_ERRORS_BUFFER_SIZE       1024
26
27 typedef struct _xmlSecErrorDescription                  xmlSecErrorDescription, *xmlSecErrorDescriptionPtr;
28 struct _xmlSecErrorDescription {
29     int                 errorCode;
30     const char*         errorMsg;
31 };
32
33 static xmlSecErrorDescription xmlSecErrorsTable[XMLSEC_ERRORS_MAX_NUMBER + 1] = {
34   { XMLSEC_ERRORS_R_XMLSEC_FAILED,              "xmlsec library function failed" }, 
35   { XMLSEC_ERRORS_R_MALLOC_FAILED,              "malloc function failed" }, 
36   { XMLSEC_ERRORS_R_STRDUP_FAILED,              "strdup function failed" }, 
37   { XMLSEC_ERRORS_R_CRYPTO_FAILED,              "crypto library function failed" }, 
38   { XMLSEC_ERRORS_R_XML_FAILED,                 "libxml2 library function failed" }, 
39   { XMLSEC_ERRORS_R_XSLT_FAILED,                "libxslt library function failed" }, 
40   { XMLSEC_ERRORS_R_IO_FAILED,                  "io function failed" }, 
41   { XMLSEC_ERRORS_R_DISABLED,                   "feature is disabled" }, 
42   { XMLSEC_ERRORS_R_NOT_IMPLEMENTED,            "feature is not implemented" }, 
43   { XMLSEC_ERRORS_R_INVALID_SIZE,               "invalid size" }, 
44   { XMLSEC_ERRORS_R_INVALID_DATA,               "invalid data" }, 
45   { XMLSEC_ERRORS_R_INVALID_RESULT,             "invalid result" }, 
46   { XMLSEC_ERRORS_R_INVALID_TYPE,               "invalid type" }, 
47   { XMLSEC_ERRORS_R_INVALID_OPERATION,          "invalid operation" }, 
48   { XMLSEC_ERRORS_R_INVALID_STATUS,             "invalid status" }, 
49   { XMLSEC_ERRORS_R_INVALID_FORMAT,             "invalid format" }, 
50   { XMLSEC_ERRORS_R_DATA_NOT_MATCH,             "data do not match" }, 
51   { XMLSEC_ERRORS_R_INVALID_NODE,               "invalid node" }, 
52   { XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,       "invalid node content" }, 
53   { XMLSEC_ERRORS_R_INVALID_NODE_ATTRIBUTE,     "invalid node attribute" }, 
54   { XMLSEC_ERRORS_R_MISSING_NODE_ATTRIBUTE,     "missing node attribute" }, 
55   { XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,       "node already present" }, 
56   { XMLSEC_ERRORS_R_UNEXPECTED_NODE,            "unexpected node" }, 
57   { XMLSEC_ERRORS_R_NODE_NOT_FOUND,             "node node found" }, 
58   { XMLSEC_ERRORS_R_INVALID_TRANSFORM,          "invalid transform" }, 
59   { XMLSEC_ERRORS_R_INVALID_TRANSFORM_KEY,      "invalid transform key" }, 
60   { XMLSEC_ERRORS_R_INVALID_URI_TYPE,           "invalid URI type" }, 
61   { XMLSEC_ERRORS_R_TRANSFORM_SAME_DOCUMENT_REQUIRED,   "same document is required for transform" }, 
62   { XMLSEC_ERRORS_R_TRANSFORM_DISABLED,         "transform is disabled" }, 
63   { XMLSEC_ERRORS_R_INVALID_KEY_DATA,           "invalid key data" }, 
64   { XMLSEC_ERRORS_R_KEY_DATA_NOT_FOUND,         "key data is not found" }, 
65   { XMLSEC_ERRORS_R_KEY_DATA_ALREADY_EXIST,     "key data already exist" }, 
66   { XMLSEC_ERRORS_R_INVALID_KEY_DATA_SIZE,      "invalid key data size" }, 
67   { XMLSEC_ERRORS_R_KEY_NOT_FOUND,              "key is not found" }, 
68   { XMLSEC_ERRORS_R_KEYDATA_DISABLED,           "key data is disabled" }, 
69   { XMLSEC_ERRORS_R_MAX_RETRIEVALS_LEVEL,       "maximum key retrieval level" }, 
70   { XMLSEC_ERRORS_R_MAX_RETRIEVAL_TYPE_MISMATCH,"key retrieval type mismatch" }, 
71   { XMLSEC_ERRORS_R_MAX_ENCKEY_LEVEL,           "maximum encrypted key level" }, 
72   { XMLSEC_ERRORS_R_CERT_VERIFY_FAILED,         "certificate verification failed" }, 
73   { XMLSEC_ERRORS_R_CERT_NOT_FOUND,             "certificate is not found" }, 
74   { XMLSEC_ERRORS_R_CERT_REVOKED,               "certificate is revoked" }, 
75   { XMLSEC_ERRORS_R_CERT_ISSUER_FAILED,         "certificate issuer check failed" }, 
76   { XMLSEC_ERRORS_R_CERT_NOT_YET_VALID,         "certificate is not yet valid" }, 
77   { XMLSEC_ERRORS_R_CERT_HAS_EXPIRED,           "certificate has expirred" }, 
78   { XMLSEC_ERRORS_R_DSIG_NO_REFERENCES,         "Reference nodes are not found" }, 
79   { XMLSEC_ERRORS_R_DSIG_INVALID_REFERENCE,     "Reference verification failed" }, 
80   { XMLSEC_ERRORS_R_ASSERTION,                  "assertion" }, 
81   { 0,                                          NULL}
82 };
83
84 static xmlSecErrorsCallback xmlSecErrorsClbk = xmlSecErrorsDefaultCallback;
85 static int  xmlSecPrintErrorMessages = 1;       /* whether the error messages will be printed immidiatelly */
86
87 /** 
88  * xmlSecErrorsInit:
89  *
90  * Initializes the errors reporting. It is called from #xmlSecInit function.
91  * and applications must not call this function directly.
92  */
93 void 
94 xmlSecErrorsInit(void) {
95 }
96
97 /** 
98  * xmlSecErrorsShutdown:
99  *
100  * Cleanups the errors reporting. It is called from #xmlSecShutdown function.
101  * and applications must not call this function directly.
102  */
103 void 
104 xmlSecErrorsShutdown(void) {
105 }
106
107 /**
108  * xmlSecErrorsSetCallback:
109  * @callback:           the new errors callback function.
110  *
111  * Sets the errors callback function to @callback that will be called 
112  * every time an error occurs.
113  */
114 void 
115 xmlSecErrorsSetCallback(xmlSecErrorsCallback callback) {
116     xmlSecErrorsClbk = callback;
117 }
118
119 /**
120  * xmlSecErrorsDefaultCallback:
121  * @file:               the error location file name (__FILE__ macro).
122  * @line:               the error location line number (__LINE__ macro).
123  * @func:               the error location function name (__FUNCTION__ macro).
124  * @errorObject:        the error specific error object 
125  * @errorSubject:       the error specific error subject.
126  * @reason:             the error code.
127  * @msg:                the additional error message.
128  *
129  * The default error reporting callback that utilizes LibXML
130  * error reporting #xmlGenericError function.
131  */
132 void 
133 xmlSecErrorsDefaultCallback(const char* file, int line, const char* func,
134                             const char* errorObject, const char* errorSubject,
135                             int reason, const char* msg) {
136     if(xmlSecPrintErrorMessages) {    
137         const char* error_msg = NULL;
138         xmlSecSize i;
139
140         for(i = 0; (i < XMLSEC_ERRORS_MAX_NUMBER) && (xmlSecErrorsGetMsg(i) != NULL); ++i) {
141             if(xmlSecErrorsGetCode(i) == reason) {
142                 error_msg = xmlSecErrorsGetMsg(i);
143                 break;
144             }
145         }
146         xmlGenericError(xmlGenericErrorContext,
147             "func=%s:file=%s:line=%d:obj=%s:subj=%s:error=%d:%s:%s\n",
148             (func != NULL) ? func : "unknown",
149             (file != NULL) ? file : "unknown",
150             line,
151             (errorObject != NULL) ? errorObject : "unknown",
152             (errorSubject != NULL) ? errorSubject : "unknown",
153             reason,
154             (error_msg != NULL) ? error_msg : "",
155             (msg != NULL) ? msg : "");
156     }
157 }
158
159 /**
160  * xmlSecErrorsDefaultCallbackEnableOutput:
161  * @enabled:            the flag.
162  * 
163  * Enables or disables calling LibXML2 callback from the default
164  * errors callback.
165  */
166 void 
167 xmlSecErrorsDefaultCallbackEnableOutput(int enabled) {
168     xmlSecPrintErrorMessages = enabled;
169 }
170
171 /**
172  * xmlSecErrorsGetCode:
173  * @pos:                the error position.
174  * 
175  * Gets the known error code at position @pos.
176  *
177  * Returns: the known error code or 0 if @pos is greater than 
178  * total number of known error codes.
179  */
180 int 
181 xmlSecErrorsGetCode(xmlSecSize pos) {
182     /* could not use asserts here! */
183     if(pos < sizeof(xmlSecErrorsTable) / sizeof(xmlSecErrorsTable[0])) {
184         return(xmlSecErrorsTable[pos].errorCode);
185     }
186     return(0);
187 }
188
189 /**
190  * xmlSecErrorsGetMsg:
191  * @pos:                the error position.
192  *
193  * Gets the known error message at position @pos.
194  *
195  * Returns: the known error message or NULL if @pos is greater than 
196  * total number of known error codes.
197  */
198 const char* 
199 xmlSecErrorsGetMsg(xmlSecSize pos) {
200     /* could not use asserts here! */
201     if(pos < sizeof(xmlSecErrorsTable) / sizeof(xmlSecErrorsTable[0])) {
202         return(xmlSecErrorsTable[pos].errorMsg);
203     }
204     return(NULL);
205 }
206
207 /**
208  * xmlSecError:
209  * @file:               the error location filename (__FILE__).
210  * @line:               the error location line number (__LINE__).
211  * @func:               the error location function (__FUNCTIION__).
212  * @errorObject:        the error specific error object 
213  * @errorSubject:       the error specific error subject. 
214  * @reason:             the error code.
215  * @msg:                the error message in printf format.
216  * @...:                the parameters for the @msg.
217  *
218  * Reports an error to the default (#xmlSecErrorsDefaultCallback) or 
219  * application specific callback installed using #xmlSecErrorsSetCallback 
220  * function.
221  */
222 void    
223 xmlSecError(const char* file, int line, const char* func, 
224             const char* errorObject, const char* errorSubject,
225             int reason, const char* msg, ...) {
226             
227     if(xmlSecErrorsClbk != NULL) {
228         xmlChar error_msg[XMLSEC_ERRORS_BUFFER_SIZE];
229         
230         if(msg != NULL) {
231             va_list va;
232
233             va_start(va, msg);
234             xmlSecStrVPrintf(error_msg, sizeof(error_msg), BAD_CAST msg, va);
235             error_msg[sizeof(error_msg) - 1] = '\0';
236             va_end(va); 
237         } else {
238             error_msg[0] = '\0';            
239         }
240         xmlSecErrorsClbk(file, line, func, errorObject, errorSubject, reason, (char*)error_msg);
241     }   
242 }