You've already forked mariadb-connector-c
mirror of
https://github.com/mariadb-corporation/mariadb-connector-c.git
synced 2025-08-10 01:02:57 +03:00
CONC-446 For Schannel errors, provide better errors
Print error symbol (e.g S"EC_E_ILLEGAL_MESSAGE") in the error message for some schannel errors, in addition to error message Print error code for all errors coming from schannel. Fix some whitespace.
This commit is contained in:
@@ -26,69 +26,73 @@
|
|||||||
#define MAX_SSL_ERR_LEN 100
|
#define MAX_SSL_ERR_LEN 100
|
||||||
|
|
||||||
#define SCHANNEL_PAYLOAD(A) (A).cbMaximumMessage + (A).cbHeader + (A).cbTrailer
|
#define SCHANNEL_PAYLOAD(A) (A).cbMaximumMessage + (A).cbHeader + (A).cbTrailer
|
||||||
void ma_schannel_set_win_error(MARIADB_PVIO *pvio, DWORD ErrorNo __attribute__((unused)));
|
void ma_schannel_set_win_error(MARIADB_PVIO *pvio, DWORD ErrorNo);
|
||||||
|
|
||||||
|
static void get_schannel_error_info(DWORD err, const char** sym, const char** text)
|
||||||
|
{
|
||||||
|
#define ERR_ENTRY(a,b) {a,#a, b}
|
||||||
|
static struct {
|
||||||
|
DWORD code; /* Error code , e.g SEC_E_ILLEGAL_MESSAGE */
|
||||||
|
const char* symbol; /* Error code as string, e.g "SEC_E_ILLEGAL_MESSAGE"*/
|
||||||
|
const char* msg; /* English text message */
|
||||||
|
} errinfo[] =
|
||||||
|
{
|
||||||
|
ERR_ENTRY(SEC_E_ILLEGAL_MESSAGE, "The message received was unexpected or badly formatted"),
|
||||||
|
ERR_ENTRY(SEC_E_UNTRUSTED_ROOT, "Untrusted root certificate"),
|
||||||
|
ERR_ENTRY(SEC_E_BUFFER_TOO_SMALL, "Buffer too small"),
|
||||||
|
ERR_ENTRY(SEC_E_CRYPTO_SYSTEM_INVALID, "Cipher is not supported"),
|
||||||
|
ERR_ENTRY(SEC_E_INSUFFICIENT_MEMORY, "Out of memory"),
|
||||||
|
ERR_ENTRY(SEC_E_OUT_OF_SEQUENCE, "Invalid message sequence"),
|
||||||
|
ERR_ENTRY(SEC_E_DECRYPT_FAILURE, "The specified data could not be decrypted"),
|
||||||
|
ERR_ENTRY(SEC_I_INCOMPLETE_CREDENTIALS, "Incomplete credentials"),
|
||||||
|
ERR_ENTRY(SEC_E_ENCRYPT_FAILURE, "The specified data could not be encrypted"),
|
||||||
|
ERR_ENTRY(SEC_I_CONTEXT_EXPIRED, "The context has expired and can no longer be used"),
|
||||||
|
ERR_ENTRY(SEC_E_ALGORITHM_MISMATCH, "no cipher match"),
|
||||||
|
ERR_ENTRY(SEC_E_NO_CREDENTIALS, "no credentials"),
|
||||||
|
ERR_ENTRY(SEC_E_INVALID_TOKEN, "The token supplied to function is invalid")
|
||||||
|
};
|
||||||
|
for (int i = 0; i < sizeof(errinfo) / sizeof(errinfo[0]); i++)
|
||||||
|
{
|
||||||
|
if (errinfo[i].code == err)
|
||||||
|
{
|
||||||
|
*sym = errinfo[i].symbol;
|
||||||
|
*text = errinfo[i].msg;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*sym = NULL;
|
||||||
|
*text = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* {{{ void ma_schannel_set_sec_error */
|
/* {{{ void ma_schannel_set_sec_error */
|
||||||
void ma_schannel_set_sec_error(MARIADB_PVIO* pvio, DWORD ErrorNo)
|
void ma_schannel_set_sec_error(MARIADB_PVIO* pvio, DWORD ErrorNo)
|
||||||
{
|
{
|
||||||
MYSQL* mysql = pvio->mysql;
|
MYSQL* mysql = pvio->mysql;
|
||||||
|
const char* sym;
|
||||||
|
const char* text;
|
||||||
if (ErrorNo != SEC_E_OK)
|
if (ErrorNo != SEC_E_OK)
|
||||||
mysql->net.extension->extended_errno = ErrorNo;
|
mysql->net.extension->extended_errno = ErrorNo;
|
||||||
|
if (ErrorNo == SEC_E_INTERNAL_ERROR && GetLastError())
|
||||||
switch(ErrorNo) {
|
{
|
||||||
case SEC_E_ILLEGAL_MESSAGE:
|
ma_schannel_set_win_error(pvio, GetLastError());
|
||||||
pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "SSL connection error: The message received was unexpected or badly formatted");
|
return;
|
||||||
break;
|
}
|
||||||
case SEC_E_UNTRUSTED_ROOT:
|
get_schannel_error_info(ErrorNo, &sym, &text);
|
||||||
pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "SSL connection error: Untrusted root certificate");
|
if (sym)
|
||||||
break;
|
{
|
||||||
case SEC_E_BUFFER_TOO_SMALL:
|
pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
|
||||||
pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "SSL connection error: Buffer too small");
|
"SSL connection error: %s (%s , 0x%08x)", text, sym, ErrorNo);
|
||||||
break;
|
}
|
||||||
case SEC_E_CRYPTO_SYSTEM_INVALID:
|
|
||||||
pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "SSL connection error: Cipher is not supported");
|
|
||||||
break;
|
|
||||||
case SEC_E_INSUFFICIENT_MEMORY:
|
|
||||||
pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "SSL connection error: Out of memory");
|
|
||||||
break;
|
|
||||||
case SEC_E_OUT_OF_SEQUENCE:
|
|
||||||
pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "SSL connection error: Invalid message sequence");
|
|
||||||
break;
|
|
||||||
case SEC_E_DECRYPT_FAILURE:
|
|
||||||
pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "SSL connection error: An error occurred during decrypting data");
|
|
||||||
break;
|
|
||||||
case SEC_I_INCOMPLETE_CREDENTIALS:
|
|
||||||
pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "SSL connection error: Incomplete credentials");
|
|
||||||
break;
|
|
||||||
case SEC_E_ENCRYPT_FAILURE:
|
|
||||||
pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "SSL connection error: An error occurred during encrypting data");
|
|
||||||
break;
|
|
||||||
case SEC_I_CONTEXT_EXPIRED:
|
|
||||||
pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "SSL connection error: Context expired ");
|
|
||||||
break;
|
|
||||||
case SEC_E_ALGORITHM_MISMATCH:
|
|
||||||
pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "SSL connection error: no cipher match");
|
|
||||||
break;
|
|
||||||
case SEC_E_NO_CREDENTIALS:
|
|
||||||
pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "SSL connection error: no credentials");
|
|
||||||
break;
|
|
||||||
case SEC_E_OK:
|
|
||||||
break;
|
|
||||||
case SEC_E_INTERNAL_ERROR:
|
|
||||||
if (GetLastError())
|
|
||||||
ma_schannel_set_win_error(pvio, 0);
|
|
||||||
else
|
else
|
||||||
pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "The Local Security Authority cannot be contacted");
|
{
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ma_schannel_set_win_error(pvio, ErrorNo);
|
ma_schannel_set_win_error(pvio, ErrorNo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ void ma_schnnel_set_win_error */
|
/* {{{ void ma_schnnel_set_win_error */
|
||||||
void ma_schannel_set_win_error(MARIADB_PVIO *pvio, DWORD ErrorNo __attribute__((unused)))
|
void ma_schannel_set_win_error(MARIADB_PVIO *pvio, DWORD ErrorNo)
|
||||||
{
|
{
|
||||||
ulong ssl_errno= ErrorNo ? ErrorNo : GetLastError();
|
ulong ssl_errno= ErrorNo ? ErrorNo : GetLastError();
|
||||||
char *ssl_error_reason= NULL;
|
char *ssl_error_reason= NULL;
|
||||||
@@ -99,14 +103,15 @@ void ma_schannel_set_win_error(MARIADB_PVIO *pvio, DWORD ErrorNo __attribute__((
|
|||||||
pvio->set_error(pvio->mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "Unknown SSL error");
|
pvio->set_error(pvio->mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "Unknown SSL error");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* todo: obtain error message */
|
|
||||||
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
NULL, ssl_errno, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
NULL, ssl_errno, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
(LPTSTR) &ssl_error_reason, 0, NULL );
|
(LPTSTR) &ssl_error_reason, 0, NULL );
|
||||||
for (p = ssl_error_reason; *p; p++)
|
for (p = ssl_error_reason; *p; p++)
|
||||||
if (*p == '\n' || *p == '\r')
|
if (*p == '\n' || *p == '\r')
|
||||||
*p = 0;
|
*p = 0;
|
||||||
snprintf(buffer, sizeof(buffer), "SSL connection error: %s",ssl_error_reason);
|
snprintf(buffer, sizeof(buffer), "SSL connection error: %s. Windows error %lu / 0x%08lx",ssl_error_reason,
|
||||||
|
ErrorNo, ErrorNo);
|
||||||
pvio->set_error(pvio->mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, buffer);
|
pvio->set_error(pvio->mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, buffer);
|
||||||
if (ssl_error_reason)
|
if (ssl_error_reason)
|
||||||
LocalFree(ssl_error_reason);
|
LocalFree(ssl_error_reason);
|
||||||
@@ -873,7 +878,9 @@ SECURITY_STATUS ma_schannel_client_handshake(MARIADB_TLS *ctls)
|
|||||||
end:
|
end:
|
||||||
LocalFree(sctx->IoBuffer);
|
LocalFree(sctx->IoBuffer);
|
||||||
sctx->IoBufferSize= 0;
|
sctx->IoBufferSize= 0;
|
||||||
|
if (BuffersOut.pvBuffer)
|
||||||
FreeContextBuffer(BuffersOut.pvBuffer);
|
FreeContextBuffer(BuffersOut.pvBuffer);
|
||||||
|
|
||||||
DeleteSecurityContext(&sctx->ctxt);
|
DeleteSecurityContext(&sctx->ctxt);
|
||||||
return sRet;
|
return sRet;
|
||||||
}
|
}
|
||||||
|
@@ -158,8 +158,7 @@ cipher_map[] =
|
|||||||
|
|
||||||
#define MAX_ALG_ID 50
|
#define MAX_ALG_ID 50
|
||||||
|
|
||||||
void ma_schannel_set_sec_error(MARIADB_PVIO *pvio, DWORD ErrorNo);
|
extern void ma_schannel_set_sec_error(MARIADB_PVIO *pvio, DWORD ErrorNo);
|
||||||
void ma_schannel_set_win_error(MYSQL *mysql);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Initializes SSL and allocate global
|
Initializes SSL and allocate global
|
||||||
|
Reference in New Issue
Block a user