summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/strerror.c569
-rw-r--r--lib/strerror.h3
-rw-r--r--lib/vtls/schannel_verify.c23
3 files changed, 245 insertions, 350 deletions
diff --git a/lib/strerror.c b/lib/strerror.c
index baf5451ae..7bdd42dd2 100644
--- a/lib/strerror.c
+++ b/lib/strerror.c
@@ -442,19 +442,23 @@ curl_share_strerror(CURLSHcode error)
}
#ifdef USE_WINSOCK
-
-/* This function handles most / all (?) Winsock errors curl is able to produce.
+/* This is a helper function for Curl_strerror that converts Winsock error
+ * codes (WSAGetLastError) to error messages.
+ * Returns NULL if no error message was found for error code.
*/
static const char *
get_winsock_error (int err, char *buf, size_t len)
{
-#ifdef PRESERVE_WINDOWS_ERROR_CODE
- DWORD old_win_err = GetLastError();
-#endif
- int old_errno = errno;
const char *p;
-#ifndef CURL_DISABLE_VERBOSE_STRINGS
+ if(!len)
+ return NULL;
+
+ *buf = '\0';
+
+#ifdef CURL_DISABLE_VERBOSE_STRINGS
+ return NULL;
+#else
switch(err) {
case WSAEINTR:
p = "Call interrupted";
@@ -623,26 +627,63 @@ get_winsock_error (int err, char *buf, size_t len)
default:
return NULL;
}
-#else
- if(!err)
- return NULL;
- else
- p = "error";
-#endif
strncpy(buf, p, len);
buf [len-1] = '\0';
+ return buf;
+#endif
+}
+#endif /* USE_WINSOCK */
- if(errno != old_errno)
- errno = old_errno;
+#if defined(WIN32) || defined(_WIN32_WCE)
+/* This is a helper function for Curl_strerror that converts Windows API error
+ * codes (GetLastError) to error messages.
+ * Returns NULL if no error message was found for error code.
+ */
+static const char *
+get_winapi_error(int err, char *buf, size_t buflen)
+{
+ char *p;
-#ifdef PRESERVE_WINDOWS_ERROR_CODE
- if(old_win_err != GetLastError())
- SetLastError(old_win_err);
+ if(!buflen)
+ return NULL;
+
+ *buf = '\0';
+
+#ifdef _WIN32_WCE
+ {
+ wchar_t wbuf[256];
+ wbuf[0] = L'\0';
+
+ if(FormatMessage((FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS), NULL, err,
+ LANG_NEUTRAL, wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL)) {
+ size_t written = wcstombs(buf, wbuf, buflen - 1);
+ if(written != (size_t)-1)
+ buf[written] = '\0';
+ else
+ *buf = '\0';
+ }
+ }
+#else
+ if(!FormatMessageA((FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS), NULL, err,
+ LANG_NEUTRAL, buf, (DWORD)buflen, NULL)) {
+ *buf = '\0';
+ }
#endif
- return buf;
+ /* Truncate multiple lines */
+ p = strchr(buf, '\n');
+ if(p) {
+ if(p > buf && *(p-1) == '\r')
+ *(p-1) = '\0';
+ else
+ *p = '\0';
+ }
+
+ return (*buf ? buf : NULL);
}
-#endif /* USE_WINSOCK */
+#endif /* WIN32 || _WIN32_WCE */
/*
* Our thread-safe and smart strerror() replacement.
@@ -654,6 +695,14 @@ get_winsock_error (int err, char *buf, size_t len)
*
* We don't do range checking (on systems other than Windows) since there is
* no good reliable and portable way to do it.
+ *
+ * On Windows different types of error codes overlap. This function has an
+ * order of preference when trying to match error codes:
+ * CRT (errno), Winsock (WSAGetLastError), Windows API (GetLastError).
+ *
+ * It may be more correct to call one of the variant functions instead:
+ * Call Curl_sspi_strerror if the error code is definitely Windows SSPI.
+ * Call Curl_winapi_strerror if the error code is definitely Windows API.
*/
const char *Curl_strerror(int err, char *buf, size_t buflen)
{
@@ -664,37 +713,30 @@ const char *Curl_strerror(int err, char *buf, size_t buflen)
char *p;
size_t max;
+ if(!buflen)
+ return NULL;
+
DEBUGASSERT(err >= 0);
max = buflen - 1;
*buf = '\0';
-#ifdef USE_WINSOCK
-
-#ifdef _WIN32_WCE
- {
- wchar_t wbuf[256];
- wbuf[0] = L'\0';
-
- FormatMessage((FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS), NULL, err,
- LANG_NEUTRAL, wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL);
- wcstombs(buf, wbuf, max);
- }
-#else
+#if defined(WIN32) || defined(_WIN32_WCE)
+#if defined(WIN32)
/* 'sys_nerr' is the maximum errno number, it is not widely portable */
if(err >= 0 && err < sys_nerr)
strncpy(buf, strerror(err), max);
- else {
- if(!get_winsock_error(err, buf, max) &&
- !FormatMessageA((FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS), NULL, err,
- LANG_NEUTRAL, buf, (DWORD)max, NULL))
+ else
+#endif
+ {
+ if(
+#ifdef USE_WINSOCK
+ !get_winsock_error(err, buf, max) &&
+#endif
+ !get_winapi_error((DWORD)err, buf, max))
msnprintf(buf, max, "Unknown error %d (%#x)", err, err);
}
-#endif
-
-#else /* not USE_WINSOCK coming up */
+#else /* not Windows coming up */
#if defined(HAVE_STRERROR_R) && defined(HAVE_POSIX_STRERROR_R)
/*
@@ -742,7 +784,7 @@ const char *Curl_strerror(int err, char *buf, size_t buflen)
}
#endif
-#endif /* end of ! USE_WINSOCK */
+#endif /* end of not Windows */
buf[max] = '\0'; /* make sure the string is zero terminated */
@@ -765,7 +807,52 @@ const char *Curl_strerror(int err, char *buf, size_t buflen)
return buf;
}
+/*
+ * Curl_winapi_strerror:
+ * Variant of Curl_strerror if the error code is definitely Windows API.
+ */
+#if defined(WIN32) || defined(_WIN32_WCE)
+const char *Curl_winapi_strerror(DWORD err, char *buf, size_t buflen)
+{
+#ifdef PRESERVE_WINDOWS_ERROR_CODE
+ DWORD old_win_err = GetLastError();
+#endif
+ int old_errno = errno;
+
+ if(!buflen)
+ return NULL;
+
+ *buf = '\0';
+
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+ if(!get_winapi_error(err, buf, buflen)) {
+ msnprintf(buf, buflen, "Unknown error %u (0x%08X)", err, err);
+ }
+#else
+ {
+ const char *txt = (err == ERROR_SUCCESS) ? "No error" : "Error";
+ strncpy(buf, txt, buflen);
+ buf[buflen - 1] = '\0';
+ }
+#endif
+
+ if(errno != old_errno)
+ errno = old_errno;
+
+#ifdef PRESERVE_WINDOWS_ERROR_CODE
+ if(old_win_err != GetLastError())
+ SetLastError(old_win_err);
+#endif
+
+ return buf;
+}
+#endif /* WIN32 || _WIN32_WCE */
+
#ifdef USE_WINDOWS_SSPI
+/*
+ * Curl_sspi_strerror:
+ * Variant of Curl_strerror if the error code is definitely Windows SSPI.
+ */
const char *Curl_sspi_strerror(int err, char *buf, size_t buflen)
{
#ifdef PRESERVE_WINDOWS_ERROR_CODE
@@ -773,18 +860,11 @@ const char *Curl_sspi_strerror(int err, char *buf, size_t buflen)
#endif
int old_errno = errno;
const char *txt;
- char *outbuf;
- size_t outmax;
-#ifndef CURL_DISABLE_VERBOSE_STRINGS
- char txtbuf[80];
- char msgbuf[256];
- char *p, *str, *msg = NULL;
- bool msg_formatted = FALSE;
-#endif
- outbuf = buf;
- outmax = buflen - 1;
- *outbuf = '\0';
+ if(!buflen)
+ return NULL;
+
+ *buf = '\0';
#ifndef CURL_DISABLE_VERBOSE_STRINGS
@@ -792,314 +872,121 @@ const char *Curl_sspi_strerror(int err, char *buf, size_t buflen)
case SEC_E_OK:
txt = "No error";
break;
- case CRYPT_E_REVOKED:
- txt = "CRYPT_E_REVOKED";
- break;
- case SEC_E_ALGORITHM_MISMATCH:
- txt = "SEC_E_ALGORITHM_MISMATCH";
- break;
- case SEC_E_BAD_BINDINGS:
- txt = "SEC_E_BAD_BINDINGS";
- break;
- case SEC_E_BAD_PKGID:
- txt = "SEC_E_BAD_PKGID";
- break;
- case SEC_E_BUFFER_TOO_SMALL:
- txt = "SEC_E_BUFFER_TOO_SMALL";
- break;
- case SEC_E_CANNOT_INSTALL:
- txt = "SEC_E_CANNOT_INSTALL";
- break;
- case SEC_E_CANNOT_PACK:
- txt = "SEC_E_CANNOT_PACK";
- break;
- case SEC_E_CERT_EXPIRED:
- txt = "SEC_E_CERT_EXPIRED";
- break;
- case SEC_E_CERT_UNKNOWN:
- txt = "SEC_E_CERT_UNKNOWN";
- break;
- case SEC_E_CERT_WRONG_USAGE:
- txt = "SEC_E_CERT_WRONG_USAGE";
- break;
- case SEC_E_CONTEXT_EXPIRED:
- txt = "SEC_E_CONTEXT_EXPIRED";
- break;
- case SEC_E_CROSSREALM_DELEGATION_FAILURE:
- txt = "SEC_E_CROSSREALM_DELEGATION_FAILURE";
- break;
- case SEC_E_CRYPTO_SYSTEM_INVALID:
- txt = "SEC_E_CRYPTO_SYSTEM_INVALID";
- break;
- case SEC_E_DECRYPT_FAILURE:
- txt = "SEC_E_DECRYPT_FAILURE";
- break;
- case SEC_E_DELEGATION_POLICY:
- txt = "SEC_E_DELEGATION_POLICY";
- break;
- case SEC_E_DELEGATION_REQUIRED:
- txt = "SEC_E_DELEGATION_REQUIRED";
- break;
- case SEC_E_DOWNGRADE_DETECTED:
- txt = "SEC_E_DOWNGRADE_DETECTED";
- break;
- case SEC_E_ENCRYPT_FAILURE:
- txt = "SEC_E_ENCRYPT_FAILURE";
- break;
- case SEC_E_ILLEGAL_MESSAGE:
- txt = "SEC_E_ILLEGAL_MESSAGE";
- break;
- case SEC_E_INCOMPLETE_CREDENTIALS:
- txt = "SEC_E_INCOMPLETE_CREDENTIALS";
- break;
- case SEC_E_INCOMPLETE_MESSAGE:
- txt = "SEC_E_INCOMPLETE_MESSAGE";
- break;
- case SEC_E_INSUFFICIENT_MEMORY:
- txt = "SEC_E_INSUFFICIENT_MEMORY";
- break;
- case SEC_E_INTERNAL_ERROR:
- txt = "SEC_E_INTERNAL_ERROR";
- break;
- case SEC_E_INVALID_HANDLE:
- txt = "SEC_E_INVALID_HANDLE";
- break;
- case SEC_E_INVALID_PARAMETER:
- txt = "SEC_E_INVALID_PARAMETER";
- break;
- case SEC_E_INVALID_TOKEN:
- txt = "SEC_E_INVALID_TOKEN";
- break;
- case SEC_E_ISSUING_CA_UNTRUSTED:
- txt = "SEC_E_ISSUING_CA_UNTRUSTED";
- break;
- case SEC_E_ISSUING_CA_UNTRUSTED_KDC:
- txt = "SEC_E_ISSUING_CA_UNTRUSTED_KDC";
- break;
- case SEC_E_KDC_CERT_EXPIRED:
- txt = "SEC_E_KDC_CERT_EXPIRED";
- break;
- case SEC_E_KDC_CERT_REVOKED:
- txt = "SEC_E_KDC_CERT_REVOKED";
- break;
- case SEC_E_KDC_INVALID_REQUEST:
- txt = "SEC_E_KDC_INVALID_REQUEST";
- break;
- case SEC_E_KDC_UNABLE_TO_REFER:
- txt = "SEC_E_KDC_UNABLE_TO_REFER";
- break;
- case SEC_E_KDC_UNKNOWN_ETYPE:
- txt = "SEC_E_KDC_UNKNOWN_ETYPE";
- break;
- case SEC_E_LOGON_DENIED:
- txt = "SEC_E_LOGON_DENIED";
- break;
- case SEC_E_MAX_REFERRALS_EXCEEDED:
- txt = "SEC_E_MAX_REFERRALS_EXCEEDED";
- break;
- case SEC_E_MESSAGE_ALTERED:
- txt = "SEC_E_MESSAGE_ALTERED";
- break;
- case SEC_E_MULTIPLE_ACCOUNTS:
- txt = "SEC_E_MULTIPLE_ACCOUNTS";
- break;
- case SEC_E_MUST_BE_KDC:
- txt = "SEC_E_MUST_BE_KDC";
- break;
- case SEC_E_NOT_OWNER:
- txt = "SEC_E_NOT_OWNER";
- break;
- case SEC_E_NO_AUTHENTICATING_AUTHORITY:
- txt = "SEC_E_NO_AUTHENTICATING_AUTHORITY";
- break;
- case SEC_E_NO_CREDENTIALS:
- txt = "SEC_E_NO_CREDENTIALS";
- break;
- case SEC_E_NO_IMPERSONATION:
- txt = "SEC_E_NO_IMPERSONATION";
- break;
- case SEC_E_NO_IP_ADDRESSES:
- txt = "SEC_E_NO_IP_ADDRESSES";
- break;
- case SEC_E_NO_KERB_KEY:
- txt = "SEC_E_NO_KERB_KEY";
- break;
- case SEC_E_NO_PA_DATA:
- txt = "SEC_E_NO_PA_DATA";
- break;
- case SEC_E_NO_S4U_PROT_SUPPORT:
- txt = "SEC_E_NO_S4U_PROT_SUPPORT";
- break;
- case SEC_E_NO_TGT_REPLY:
- txt = "SEC_E_NO_TGT_REPLY";
- break;
- case SEC_E_OUT_OF_SEQUENCE:
- txt = "SEC_E_OUT_OF_SEQUENCE";
- break;
- case SEC_E_PKINIT_CLIENT_FAILURE:
- txt = "SEC_E_PKINIT_CLIENT_FAILURE";
- break;
- case SEC_E_PKINIT_NAME_MISMATCH:
- txt = "SEC_E_PKINIT_NAME_MISMATCH";
- break;
- case SEC_E_POLICY_NLTM_ONLY:
- txt = "SEC_E_POLICY_NLTM_ONLY";
- break;
- case SEC_E_QOP_NOT_SUPPORTED:
- txt = "SEC_E_QOP_NOT_SUPPORTED";
- break;
- case SEC_E_REVOCATION_OFFLINE_C:
- txt = "SEC_E_REVOCATION_OFFLINE_C";
- break;
- case SEC_E_REVOCATION_OFFLINE_KDC:
- txt = "SEC_E_REVOCATION_OFFLINE_KDC";
- break;
- case SEC_E_SECPKG_NOT_FOUND:
- txt = "SEC_E_SECPKG_NOT_FOUND";
- break;
- case SEC_E_SECURITY_QOS_FAILED:
- txt = "SEC_E_SECURITY_QOS_FAILED";
- break;
- case SEC_E_SHUTDOWN_IN_PROGRESS:
- txt = "SEC_E_SHUTDOWN_IN_PROGRESS";
- break;
- case SEC_E_SMARTCARD_CERT_EXPIRED:
- txt = "SEC_E_SMARTCARD_CERT_EXPIRED";
- break;
- case SEC_E_SMARTCARD_CERT_REVOKED:
- txt = "SEC_E_SMARTCARD_CERT_REVOKED";
- break;
- case SEC_E_SMARTCARD_LOGON_REQUIRED:
- txt = "SEC_E_SMARTCARD_LOGON_REQUIRED";
- break;
- case SEC_E_STRONG_CRYPTO_NOT_SUPPORTED:
- txt = "SEC_E_STRONG_CRYPTO_NOT_SUPPORTED";
- break;
- case SEC_E_TARGET_UNKNOWN:
- txt = "SEC_E_TARGET_UNKNOWN";
- break;
- case SEC_E_TIME_SKEW:
- txt = "SEC_E_TIME_SKEW";
- break;
- case SEC_E_TOO_MANY_PRINCIPALS:
- txt = "SEC_E_TOO_MANY_PRINCIPALS";
- break;
- case SEC_E_UNFINISHED_CONTEXT_DELETED:
- txt = "SEC_E_UNFINISHED_CONTEXT_DELETED";
- break;
- case SEC_E_UNKNOWN_CREDENTIALS:
- txt = "SEC_E_UNKNOWN_CREDENTIALS";
- break;
- case SEC_E_UNSUPPORTED_FUNCTION:
- txt = "SEC_E_UNSUPPORTED_FUNCTION";
- break;
- case SEC_E_UNSUPPORTED_PREAUTH:
- txt = "SEC_E_UNSUPPORTED_PREAUTH";
- break;
- case SEC_E_UNTRUSTED_ROOT:
- txt = "SEC_E_UNTRUSTED_ROOT";
- break;
- case SEC_E_WRONG_CREDENTIAL_HANDLE:
- txt = "SEC_E_WRONG_CREDENTIAL_HANDLE";
- break;
- case SEC_E_WRONG_PRINCIPAL:
- txt = "SEC_E_WRONG_PRINCIPAL";
- break;
- case SEC_I_COMPLETE_AND_CONTINUE:
- txt = "SEC_I_COMPLETE_AND_CONTINUE";
- break;
- case SEC_I_COMPLETE_NEEDED:
- txt = "SEC_I_COMPLETE_NEEDED";
- break;
- case SEC_I_CONTEXT_EXPIRED:
- txt = "SEC_I_CONTEXT_EXPIRED";
- break;
- case SEC_I_CONTINUE_NEEDED:
- txt = "SEC_I_CONTINUE_NEEDED";
- break;
- case SEC_I_INCOMPLETE_CREDENTIALS:
- txt = "SEC_I_INCOMPLETE_CREDENTIALS";
- break;
- case SEC_I_LOCAL_LOGON:
- txt = "SEC_I_LOCAL_LOGON";
- break;
- case SEC_I_NO_LSA_CONTEXT:
- txt = "SEC_I_NO_LSA_CONTEXT";
- break;
- case SEC_I_RENEGOTIATE:
- txt = "SEC_I_RENEGOTIATE";
- break;
- case SEC_I_SIGNATURE_NEEDED:
- txt = "SEC_I_SIGNATURE_NEEDED";
- break;
+#define SEC2TXT(sec) case sec: txt = #sec; break;
+ SEC2TXT(CRYPT_E_REVOKED);
+ SEC2TXT(SEC_E_ALGORITHM_MISMATCH);
+ SEC2TXT(SEC_E_BAD_BINDINGS);
+ SEC2TXT(SEC_E_BAD_PKGID);
+ SEC2TXT(SEC_E_BUFFER_TOO_SMALL);
+ SEC2TXT(SEC_E_CANNOT_INSTALL);
+ SEC2TXT(SEC_E_CANNOT_PACK);
+ SEC2TXT(SEC_E_CERT_EXPIRED);
+ SEC2TXT(SEC_E_CERT_UNKNOWN);
+ SEC2TXT(SEC_E_CERT_WRONG_USAGE);
+ SEC2TXT(SEC_E_CONTEXT_EXPIRED);
+ SEC2TXT(SEC_E_CROSSREALM_DELEGATION_FAILURE);
+ SEC2TXT(SEC_E_CRYPTO_SYSTEM_INVALID);
+ SEC2TXT(SEC_E_DECRYPT_FAILURE);
+ SEC2TXT(SEC_E_DELEGATION_POLICY);
+ SEC2TXT(SEC_E_DELEGATION_REQUIRED);
+ SEC2TXT(SEC_E_DOWNGRADE_DETECTED);
+ SEC2TXT(SEC_E_ENCRYPT_FAILURE);
+ SEC2TXT(SEC_E_ILLEGAL_MESSAGE);
+ SEC2TXT(SEC_E_INCOMPLETE_CREDENTIALS);
+ SEC2TXT(SEC_E_INCOMPLETE_MESSAGE);
+ SEC2TXT(SEC_E_INSUFFICIENT_MEMORY);
+ SEC2TXT(SEC_E_INTERNAL_ERROR);
+ SEC2TXT(SEC_E_INVALID_HANDLE);
+ SEC2TXT(SEC_E_INVALID_PARAMETER);
+ SEC2TXT(SEC_E_INVALID_TOKEN);
+ SEC2TXT(SEC_E_ISSUING_CA_UNTRUSTED);
+ SEC2TXT(SEC_E_ISSUING_CA_UNTRUSTED_KDC);
+ SEC2TXT(SEC_E_KDC_CERT_EXPIRED);
+ SEC2TXT(SEC_E_KDC_CERT_REVOKED);
+ SEC2TXT(SEC_E_KDC_INVALID_REQUEST);
+ SEC2TXT(SEC_E_KDC_UNABLE_TO_REFER);
+ SEC2TXT(SEC_E_KDC_UNKNOWN_ETYPE);
+ SEC2TXT(SEC_E_LOGON_DENIED);
+ SEC2TXT(SEC_E_MAX_REFERRALS_EXCEEDED);
+ SEC2TXT(SEC_E_MESSAGE_ALTERED);
+ SEC2TXT(SEC_E_MULTIPLE_ACCOUNTS);
+ SEC2TXT(SEC_E_MUST_BE_KDC);
+ SEC2TXT(SEC_E_NOT_OWNER);
+ SEC2TXT(SEC_E_NO_AUTHENTICATING_AUTHORITY);
+ SEC2TXT(SEC_E_NO_CREDENTIALS);
+ SEC2TXT(SEC_E_NO_IMPERSONATION);
+ SEC2TXT(SEC_E_NO_IP_ADDRESSES);
+ SEC2TXT(SEC_E_NO_KERB_KEY);
+ SEC2TXT(SEC_E_NO_PA_DATA);
+ SEC2TXT(SEC_E_NO_S4U_PROT_SUPPORT);
+ SEC2TXT(SEC_E_NO_TGT_REPLY);
+ SEC2TXT(SEC_E_OUT_OF_SEQUENCE);
+ SEC2TXT(SEC_E_PKINIT_CLIENT_FAILURE);
+ SEC2TXT(SEC_E_PKINIT_NAME_MISMATCH);
+ SEC2TXT(SEC_E_POLICY_NLTM_ONLY);
+ SEC2TXT(SEC_E_QOP_NOT_SUPPORTED);
+ SEC2TXT(SEC_E_REVOCATION_OFFLINE_C);
+ SEC2TXT(SEC_E_REVOCATION_OFFLINE_KDC);
+ SEC2TXT(SEC_E_SECPKG_NOT_FOUND);
+ SEC2TXT(SEC_E_SECURITY_QOS_FAILED);
+ SEC2TXT(SEC_E_SHUTDOWN_IN_PROGRESS);
+ SEC2TXT(SEC_E_SMARTCARD_CERT_EXPIRED);
+ SEC2TXT(SEC_E_SMARTCARD_CERT_REVOKED);
+ SEC2TXT(SEC_E_SMARTCARD_LOGON_REQUIRED);
+ SEC2TXT(SEC_E_STRONG_CRYPTO_NOT_SUPPORTED);
+ SEC2TXT(SEC_E_TARGET_UNKNOWN);
+ SEC2TXT(SEC_E_TIME_SKEW);
+ SEC2TXT(SEC_E_TOO_MANY_PRINCIPALS);
+ SEC2TXT(SEC_E_UNFINISHED_CONTEXT_DELETED);
+ SEC2TXT(SEC_E_UNKNOWN_CREDENTIALS);
+ SEC2TXT(SEC_E_UNSUPPORTED_FUNCTION);
+ SEC2TXT(SEC_E_UNSUPPORTED_PREAUTH);
+ SEC2TXT(SEC_E_UNTRUSTED_ROOT);
+ SEC2TXT(SEC_E_WRONG_CREDENTIAL_HANDLE);
+ SEC2TXT(SEC_E_WRONG_PRINCIPAL);
+ SEC2TXT(SEC_I_COMPLETE_AND_CONTINUE);
+ SEC2TXT(SEC_I_COMPLETE_NEEDED);
+ SEC2TXT(SEC_I_CONTEXT_EXPIRED);
+ SEC2TXT(SEC_I_CONTINUE_NEEDED);
+ SEC2TXT(SEC_I_INCOMPLETE_CREDENTIALS);
+ SEC2TXT(SEC_I_LOCAL_LOGON);
+ SEC2TXT(SEC_I_NO_LSA_CONTEXT);
+ SEC2TXT(SEC_I_RENEGOTIATE);
+ SEC2TXT(SEC_I_SIGNATURE_NEEDED);
default:
txt = "Unknown error";
}
- if(err == SEC_E_OK)
- strncpy(outbuf, txt, outmax);
- else if(err == SEC_E_ILLEGAL_MESSAGE)
- msnprintf(outbuf, outmax,
+ if(err == SEC_E_ILLEGAL_MESSAGE) {
+ msnprintf(buf, buflen,
"SEC_E_ILLEGAL_MESSAGE (0x%08X) - This error usually occurs "
"when a fatal SSL/TLS alert is received (e.g. handshake failed)."
" More detail may be available in the Windows System event log.",
err);
+ }
else {
- str = txtbuf;
+ char txtbuf[80];
+ char msgbuf[256];
+
msnprintf(txtbuf, sizeof(txtbuf), "%s (0x%08X)", txt, err);
- txtbuf[sizeof(txtbuf)-1] = '\0';
-#ifdef _WIN32_WCE
- {
- wchar_t wbuf[256];
- wbuf[0] = L'\0';
-
- if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, err, LANG_NEUTRAL,
- wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL)) {
- wcstombs(msgbuf, wbuf, sizeof(msgbuf)-1);
- msg_formatted = TRUE;
- }
- }
-#else
- if(FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, err, LANG_NEUTRAL,
- msgbuf, sizeof(msgbuf)-1, NULL)) {
- msg_formatted = TRUE;
+ if(get_winapi_error(err, msgbuf, sizeof(msgbuf)))
+ msnprintf(buf, buflen, "%s - %s", txtbuf, msgbuf);
+ else {
+ strncpy(buf, txtbuf, buflen);
+ buf[buflen - 1] = '\0';
}
-#endif
- if(msg_formatted) {
- msgbuf[sizeof(msgbuf)-1] = '\0';
- /* strip trailing '\r\n' or '\n' */
- p = strrchr(msgbuf, '\n');
- if(p && (p - msgbuf) >= 2)
- *p = '\0';
- p = strrchr(msgbuf, '\r');
- if(p && (p - msgbuf) >= 1)
- *p = '\0';
- msg = msgbuf;
- }
- if(msg)
- msnprintf(outbuf, outmax, "%s - %s", str, msg);
- else
- strncpy(outbuf, str, outmax);
}
#else
-
if(err == SEC_E_OK)
txt = "No error";
else
txt = "Error";
-
- strncpy(outbuf, txt, outmax);
-
+ strncpy(buf, txt, buflen);
+ buf[buflen - 1] = '\0';
#endif
- outbuf[outmax] = '\0';
-
if(errno != old_errno)
errno = old_errno;
@@ -1108,6 +995,6 @@ const char *Curl_sspi_strerror(int err, char *buf, size_t buflen)
SetLastError(old_win_err);
#endif
- return outbuf;
+ return buf;
}
#endif /* USE_WINDOWS_SSPI */
diff --git a/lib/strerror.h b/lib/strerror.h
index 683b5b4a3..278c1082f 100644
--- a/lib/strerror.h
+++ b/lib/strerror.h
@@ -27,6 +27,9 @@
#define STRERROR_LEN 128 /* a suitable length */
const char *Curl_strerror(int err, char *buf, size_t buflen);
+#if defined(WIN32) || defined(_WIN32_WCE)
+const char *Curl_winapi_strerror(DWORD err, char *buf, size_t buflen);
+#endif
#ifdef USE_WINDOWS_SSPI
const char *Curl_sspi_strerror(int err, char *buf, size_t buflen);
#endif
diff --git a/lib/vtls/schannel_verify.c b/lib/vtls/schannel_verify.c
index 1bdf50a55..3a668adc7 100644
--- a/lib/vtls/schannel_verify.c
+++ b/lib/vtls/schannel_verify.c
@@ -99,7 +99,8 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store,
char buffer[STRERROR_LEN];
failf(data,
"schannel: invalid path name for CA file '%s': %s",
- ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
+ ca_file,
+ Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer)));
result = CURLE_SSL_CACERT_BADFILE;
goto cleanup;
}
@@ -120,7 +121,8 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store,
char buffer[STRERROR_LEN];
failf(data,
"schannel: failed to open CA file '%s': %s",
- ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
+ ca_file,
+ Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer)));
result = CURLE_SSL_CACERT_BADFILE;
goto cleanup;
}
@@ -129,7 +131,8 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store,
char buffer[STRERROR_LEN];
failf(data,
"schannel: failed to determine size of CA file '%s': %s",
- ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
+ ca_file,
+ Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer)));
result = CURLE_SSL_CACERT_BADFILE;
goto cleanup;
}
@@ -159,7 +162,8 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store,
char buffer[STRERROR_LEN];
failf(data,
"schannel: failed to read from CA file '%s': %s",
- ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
+ ca_file,
+ Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer)));
result = CURLE_SSL_CACERT_BADFILE;
goto cleanup;
}
@@ -223,7 +227,7 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store,
"schannel: failed to extract certificate from CA file "
"'%s': %s",
ca_file,
- Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
+ Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer)));
result = CURLE_SSL_CACERT_BADFILE;
more_certs = 0;
}
@@ -252,7 +256,8 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store,
"schannel: failed to add certificate from CA file '%s' "
"to certificate store: %s",
ca_file,
- Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
+ Curl_winapi_strerror(GetLastError(), buffer,
+ sizeof(buffer)));
result = CURLE_SSL_CACERT_BADFILE;
more_certs = 0;
}
@@ -460,7 +465,7 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex)
if(!trust_store) {
char buffer[STRERROR_LEN];
failf(data, "schannel: failed to create certificate store: %s",
- Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
+ Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer)));
result = CURLE_SSL_CACERT_BADFILE;
}
else {
@@ -489,7 +494,7 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex)
char buffer[STRERROR_LEN];
failf(data,
"schannel: failed to create certificate chain engine: %s",
- Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
+ Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer)));
result = CURLE_SSL_CACERT_BADFILE;
}
}
@@ -512,7 +517,7 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex)
&pChainContext)) {
char buffer[STRERROR_LEN];
failf(data, "schannel: CertGetCertificateChain failed: %s",
- Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
+ Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer)));
pChainContext = NULL;
result = CURLE_PEER_FAILED_VERIFICATION;
}