/** * XML Security Library (http://www.aleksey.com/xmlsec). * * Error codes and error reporting functions. * * This is free software; see Copyright file in the source * distribution for preciese wording. * * Copyright (C) 2002-2016 Aleksey Sanin . All Rights Reserved. */ #include "globals.h" #include #include #include #include #include #include #include #include #include #define XMLSEC_ERRORS_BUFFER_SIZE 1024 typedef struct _xmlSecErrorDescription xmlSecErrorDescription, *xmlSecErrorDescriptionPtr; struct _xmlSecErrorDescription { int errorCode; const char* errorMsg; }; static xmlSecErrorDescription xmlSecErrorsTable[XMLSEC_ERRORS_MAX_NUMBER + 1] = { { XMLSEC_ERRORS_R_XMLSEC_FAILED, "xmlsec library function failed" }, { XMLSEC_ERRORS_R_MALLOC_FAILED, "malloc function failed" }, { XMLSEC_ERRORS_R_STRDUP_FAILED, "strdup function failed" }, { XMLSEC_ERRORS_R_CRYPTO_FAILED, "crypto library function failed" }, { XMLSEC_ERRORS_R_XML_FAILED, "libxml2 library function failed" }, { XMLSEC_ERRORS_R_XSLT_FAILED, "libxslt library function failed" }, { XMLSEC_ERRORS_R_IO_FAILED, "io function failed" }, { XMLSEC_ERRORS_R_DISABLED, "feature is disabled" }, { XMLSEC_ERRORS_R_NOT_IMPLEMENTED, "feature is not implemented" }, { XMLSEC_ERRORS_R_INVALID_SIZE, "invalid size" }, { XMLSEC_ERRORS_R_INVALID_DATA, "invalid data" }, { XMLSEC_ERRORS_R_INVALID_RESULT, "invalid result" }, { XMLSEC_ERRORS_R_INVALID_TYPE, "invalid type" }, { XMLSEC_ERRORS_R_INVALID_OPERATION, "invalid operation" }, { XMLSEC_ERRORS_R_INVALID_STATUS, "invalid status" }, { XMLSEC_ERRORS_R_INVALID_FORMAT, "invalid format" }, { XMLSEC_ERRORS_R_DATA_NOT_MATCH, "data do not match" }, { XMLSEC_ERRORS_R_INVALID_NODE, "invalid node" }, { XMLSEC_ERRORS_R_INVALID_NODE_CONTENT, "invalid node content" }, { XMLSEC_ERRORS_R_INVALID_NODE_ATTRIBUTE, "invalid node attribute" }, { XMLSEC_ERRORS_R_MISSING_NODE_ATTRIBUTE, "missing node attribute" }, { XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT, "node already present" }, { XMLSEC_ERRORS_R_UNEXPECTED_NODE, "unexpected node" }, { XMLSEC_ERRORS_R_NODE_NOT_FOUND, "node node found" }, { XMLSEC_ERRORS_R_INVALID_TRANSFORM, "invalid transform" }, { XMLSEC_ERRORS_R_INVALID_TRANSFORM_KEY, "invalid transform key" }, { XMLSEC_ERRORS_R_INVALID_URI_TYPE, "invalid URI type" }, { XMLSEC_ERRORS_R_TRANSFORM_SAME_DOCUMENT_REQUIRED, "same document is required for transform" }, { XMLSEC_ERRORS_R_TRANSFORM_DISABLED, "transform is disabled" }, { XMLSEC_ERRORS_R_INVALID_KEY_DATA, "invalid key data" }, { XMLSEC_ERRORS_R_KEY_DATA_NOT_FOUND, "key data is not found" }, { XMLSEC_ERRORS_R_KEY_DATA_ALREADY_EXIST, "key data already exist" }, { XMLSEC_ERRORS_R_INVALID_KEY_DATA_SIZE, "invalid key data size" }, { XMLSEC_ERRORS_R_KEY_NOT_FOUND, "key is not found" }, { XMLSEC_ERRORS_R_KEYDATA_DISABLED, "key data is disabled" }, { XMLSEC_ERRORS_R_MAX_RETRIEVALS_LEVEL, "maximum key retrieval level" }, { XMLSEC_ERRORS_R_MAX_RETRIEVAL_TYPE_MISMATCH,"key retrieval type mismatch" }, { XMLSEC_ERRORS_R_MAX_ENCKEY_LEVEL, "maximum encrypted key level" }, { XMLSEC_ERRORS_R_CERT_VERIFY_FAILED, "certificate verification failed" }, { XMLSEC_ERRORS_R_CERT_NOT_FOUND, "certificate is not found" }, { XMLSEC_ERRORS_R_CERT_REVOKED, "certificate is revoked" }, { XMLSEC_ERRORS_R_CERT_ISSUER_FAILED, "certificate issuer check failed" }, { XMLSEC_ERRORS_R_CERT_NOT_YET_VALID, "certificate is not yet valid" }, { XMLSEC_ERRORS_R_CERT_HAS_EXPIRED, "certificate has expirred" }, { XMLSEC_ERRORS_R_DSIG_NO_REFERENCES, "Reference nodes are not found" }, { XMLSEC_ERRORS_R_DSIG_INVALID_REFERENCE, "Reference verification failed" }, { XMLSEC_ERRORS_R_ASSERTION, "assertion" }, { 0, NULL} }; static xmlSecErrorsCallback xmlSecErrorsClbk = xmlSecErrorsDefaultCallback; static int xmlSecPrintErrorMessages = 1; /* whether the error messages will be printed immidiatelly */ /** * xmlSecErrorsInit: * * Initializes the errors reporting. It is called from #xmlSecInit function. * and applications must not call this function directly. */ void xmlSecErrorsInit(void) { } /** * xmlSecErrorsShutdown: * * Cleanups the errors reporting. It is called from #xmlSecShutdown function. * and applications must not call this function directly. */ void xmlSecErrorsShutdown(void) { } /** * xmlSecErrorsSetCallback: * @callback: the new errors callback function. * * Sets the errors callback function to @callback that will be called * every time an error occurs. */ void xmlSecErrorsSetCallback(xmlSecErrorsCallback callback) { xmlSecErrorsClbk = callback; } /** * xmlSecErrorsDefaultCallback: * @file: the error location file name (__FILE__ macro). * @line: the error location line number (__LINE__ macro). * @func: the error location function name (__FUNCTION__ macro). * @errorObject: the error specific error object * @errorSubject: the error specific error subject. * @reason: the error code. * @msg: the additional error message. * * The default error reporting callback that utilizes LibXML * error reporting #xmlGenericError function. */ void xmlSecErrorsDefaultCallback(const char* file, int line, const char* func, const char* errorObject, const char* errorSubject, int reason, const char* msg) { if(xmlSecPrintErrorMessages) { const char* error_msg = NULL; xmlSecSize i; for(i = 0; (i < XMLSEC_ERRORS_MAX_NUMBER) && (xmlSecErrorsGetMsg(i) != NULL); ++i) { if(xmlSecErrorsGetCode(i) == reason) { error_msg = xmlSecErrorsGetMsg(i); break; } } xmlGenericError(xmlGenericErrorContext, "func=%s:file=%s:line=%d:obj=%s:subj=%s:error=%d:%s:%s\n", (func != NULL) ? func : "unknown", (file != NULL) ? file : "unknown", line, (errorObject != NULL) ? errorObject : "unknown", (errorSubject != NULL) ? errorSubject : "unknown", reason, (error_msg != NULL) ? error_msg : "", (msg != NULL) ? msg : ""); } } /** * xmlSecErrorsDefaultCallbackEnableOutput: * @enabled: the flag. * * Enables or disables calling LibXML2 callback from the default * errors callback. */ void xmlSecErrorsDefaultCallbackEnableOutput(int enabled) { xmlSecPrintErrorMessages = enabled; } /** * xmlSecErrorsGetCode: * @pos: the error position. * * Gets the known error code at position @pos. * * Returns: the known error code or 0 if @pos is greater than * total number of known error codes. */ int xmlSecErrorsGetCode(xmlSecSize pos) { /* could not use asserts here! */ if(pos < sizeof(xmlSecErrorsTable) / sizeof(xmlSecErrorsTable[0])) { return(xmlSecErrorsTable[pos].errorCode); } return(0); } /** * xmlSecErrorsGetMsg: * @pos: the error position. * * Gets the known error message at position @pos. * * Returns: the known error message or NULL if @pos is greater than * total number of known error codes. */ const char* xmlSecErrorsGetMsg(xmlSecSize pos) { /* could not use asserts here! */ if(pos < sizeof(xmlSecErrorsTable) / sizeof(xmlSecErrorsTable[0])) { return(xmlSecErrorsTable[pos].errorMsg); } return(NULL); } /** * xmlSecError: * @file: the error location filename (__FILE__). * @line: the error location line number (__LINE__). * @func: the error location function (__FUNCTIION__). * @errorObject: the error specific error object * @errorSubject: the error specific error subject. * @reason: the error code. * @msg: the error message in printf format. * @...: the parameters for the @msg. * * Reports an error to the default (#xmlSecErrorsDefaultCallback) or * application specific callback installed using #xmlSecErrorsSetCallback * function. */ void xmlSecError(const char* file, int line, const char* func, const char* errorObject, const char* errorSubject, int reason, const char* msg, ...) { if(xmlSecErrorsClbk != NULL) { xmlChar error_msg[XMLSEC_ERRORS_BUFFER_SIZE]; if(msg != NULL) { va_list va; va_start(va, msg); xmlSecStrVPrintf(error_msg, sizeof(error_msg), msg, va); error_msg[sizeof(error_msg) - 1] = '\0'; va_end(va); } else { error_msg[0] = '\0'; } xmlSecErrorsClbk(file, line, func, errorObject, errorSubject, reason, (char*)error_msg); } }