diff options
-rw-r--r-- | lib/curl_schannel.c | 28 | ||||
-rw-r--r-- | lib/curl_sspi.c | 146 | ||||
-rw-r--r-- | lib/curl_sspi.h | 14 | ||||
-rw-r--r-- | lib/socks_sspi.c | 10 | ||||
-rw-r--r-- | lib/strerror.c | 314 | ||||
-rw-r--r-- | lib/strerror.h | 10 |
6 files changed, 347 insertions, 175 deletions
diff --git a/lib/curl_schannel.c b/lib/curl_schannel.c index e84c86fe4..3cac4e149 100644 --- a/lib/curl_schannel.c +++ b/lib/curl_schannel.c @@ -6,6 +6,7 @@ * \___|\___/|_| \_\_____| * * Copyright (C) 2012, Marc Hoersken, <info@marc-hoersken.de>, et al. + * Copyright (C) 2012, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -61,6 +62,7 @@ #include "sslgen.h" #include "sendf.h" #include "connect.h" /* for the connect timeout */ +#include "strerror.h" #include "select.h" /* for the socket readyness */ #include "inet_pton.h" /* for IP addr SNI check */ @@ -89,7 +91,6 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) SCHANNEL_CRED schannel_cred; SECURITY_STATUS sspi_status = SEC_E_OK; struct curl_schannel_cred *old_cred = NULL; - char *sspi_msg = NULL; struct in_addr addr; #ifdef ENABLE_IPV6 struct in6_addr addr6; @@ -158,14 +159,12 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) &connssl->cred->cred_handle, &connssl->cred->time_stamp); if(sspi_status != SEC_E_OK) { - sspi_msg = Curl_sspi_status_msg(sspi_status); if(sspi_status == SEC_E_WRONG_PRINCIPAL) failf(data, "schannel: SNI or certificate check failed: %s\n", - sspi_msg); + Curl_sspi_strerror(conn, sspi_status)); else failf(data, "schannel: AcquireCredentialsHandleA failed: %s\n", - sspi_msg); - free(sspi_msg); + Curl_sspi_strerror(conn, sspi_status)); free(connssl->cred); connssl->cred = NULL; return CURLE_SSL_CONNECT_ERROR; @@ -201,14 +200,12 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) &outbuf_desc, &connssl->ret_flags, &connssl->ctxt->time_stamp); if(sspi_status != SEC_I_CONTINUE_NEEDED) { - sspi_msg = Curl_sspi_status_msg(sspi_status); if(sspi_status == SEC_E_WRONG_PRINCIPAL) failf(data, "schannel: SNI or certificate check failed: %s\n", - sspi_msg); + Curl_sspi_strerror(conn, sspi_status)); else failf(data, "schannel: initial InitializeSecurityContextA failed: %s\n", - sspi_msg); - free(sspi_msg); + Curl_sspi_strerror(conn, sspi_status)); free(connssl->ctxt); connssl->ctxt = NULL; return CURLE_SSL_CONNECT_ERROR; @@ -246,7 +243,6 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) SecBuffer inbuf[2]; SecBufferDesc inbuf_desc; SECURITY_STATUS sspi_status = SEC_E_OK; - char *sspi_msg = NULL; infof(data, "schannel: connecting to %s:%d (step 2/3)\n", conn->host.name, conn->remote_port); @@ -361,14 +357,12 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) } } else { - sspi_msg = Curl_sspi_status_msg(sspi_status); if(sspi_status == SEC_E_WRONG_PRINCIPAL) failf(data, "schannel: SNI or certificate check failed: %s\n", - sspi_msg); + Curl_sspi_strerror(conn, sspi_status)); else failf(data, "schannel: next InitializeSecurityContextA failed: %s\n", - sspi_msg); - free(sspi_msg); + Curl_sspi_strerror(conn, sspi_status)); return CURLE_SSL_CONNECT_ERROR; } @@ -672,7 +666,6 @@ schannel_recv(struct connectdata *conn, int sockindex, SecBuffer inbuf[4]; SecBufferDesc inbuf_desc; SECURITY_STATUS sspi_status = SEC_E_OK; - char *sspi_msg = NULL; infof(data, "schannel: client wants to read %d\n", len); *err = CURLE_OK; @@ -880,9 +873,8 @@ schannel_recv(struct connectdata *conn, int sockindex, /* check if something went wrong and we need to return an error */ if(ret < 0 && sspi_status != SEC_E_OK) { - sspi_msg = Curl_sspi_status_msg(sspi_status); - infof(data, "schannel: failed to read data from server: %s\n", sspi_msg); - free(sspi_msg); + infof(data, "schannel: failed to read data from server: %s\n", + Curl_sspi_strerror(conn, sspi_status)); *err = CURLE_RECV_ERROR; return -1; } diff --git a/lib/curl_sspi.c b/lib/curl_sspi.c index b78756740..0d3feb642 100644 --- a/lib/curl_sspi.c +++ b/lib/curl_sspi.c @@ -175,150 +175,4 @@ CURLcode Curl_sspi_version(int *major, int *minor, int *build, int *special) return result; } -/* - * Curl_sspi_status(SECURIY_STATUS status) - * - * This function returns a string representing an SSPI status. - * It will in any case return a usable string pointer which needs to be freed. - */ -char* Curl_sspi_status(SECURITY_STATUS status) -{ - const char* status_const; - - switch(status) { - case SEC_I_COMPLETE_AND_CONTINUE: - status_const = "SEC_I_COMPLETE_AND_CONTINUE"; - break; - case SEC_I_COMPLETE_NEEDED: - status_const = "SEC_I_COMPLETE_NEEDED"; - break; - case SEC_I_CONTINUE_NEEDED: - status_const = "SEC_I_CONTINUE_NEEDED"; - break; - case SEC_I_CONTEXT_EXPIRED: - status_const = "SEC_I_CONTEXT_EXPIRED"; - break; - case SEC_I_INCOMPLETE_CREDENTIALS: - status_const = "SEC_I_INCOMPLETE_CREDENTIALS"; - break; - case SEC_I_RENEGOTIATE: - status_const = "SEC_I_RENEGOTIATE"; - break; - case SEC_E_BUFFER_TOO_SMALL: - status_const = "SEC_E_BUFFER_TOO_SMALL"; - break; - case SEC_E_CONTEXT_EXPIRED: - status_const = "SEC_E_CONTEXT_EXPIRED"; - break; - case SEC_E_CRYPTO_SYSTEM_INVALID: - status_const = "SEC_E_CRYPTO_SYSTEM_INVALID"; - break; - case SEC_E_INCOMPLETE_MESSAGE: - status_const = "SEC_E_INCOMPLETE_MESSAGE"; - break; - case SEC_E_INSUFFICIENT_MEMORY: - status_const = "SEC_E_INSUFFICIENT_MEMORY"; - break; - case SEC_E_INTERNAL_ERROR: - status_const = "SEC_E_INTERNAL_ERROR"; - break; - case SEC_E_INVALID_HANDLE: - status_const = "SEC_E_INVALID_HANDLE"; - break; - case SEC_E_INVALID_TOKEN: - status_const = "SEC_E_INVALID_TOKEN"; - break; - case SEC_E_LOGON_DENIED: - status_const = "SEC_E_LOGON_DENIED"; - break; - case SEC_E_MESSAGE_ALTERED: - status_const = "SEC_E_MESSAGE_ALTERED"; - break; - case SEC_E_NO_AUTHENTICATING_AUTHORITY: - status_const = "SEC_E_NO_AUTHENTICATING_AUTHORITY"; - break; - case SEC_E_NO_CREDENTIALS: - status_const = "SEC_E_NO_CREDENTIALS"; - break; - case SEC_E_NOT_OWNER: - status_const = "SEC_E_NOT_OWNER"; - break; - case SEC_E_OK: - status_const = "SEC_E_OK"; - break; - case SEC_E_OUT_OF_SEQUENCE: - status_const = "SEC_E_OUT_OF_SEQUENCE"; - break; - case SEC_E_QOP_NOT_SUPPORTED: - status_const = "SEC_E_QOP_NOT_SUPPORTED"; - break; - case SEC_E_SECPKG_NOT_FOUND: - status_const = "SEC_E_SECPKG_NOT_FOUND"; - break; - case SEC_E_TARGET_UNKNOWN: - status_const = "SEC_E_TARGET_UNKNOWN"; - break; - case SEC_E_UNKNOWN_CREDENTIALS: - status_const = "SEC_E_UNKNOWN_CREDENTIALS"; - break; - case SEC_E_UNSUPPORTED_FUNCTION: - status_const = "SEC_E_UNSUPPORTED_FUNCTION"; - break; - case SEC_E_WRONG_PRINCIPAL: - status_const = "SEC_E_WRONG_PRINCIPAL"; - break; - default: - status_const = "Unknown error"; - } - - return aprintf("%s (0x%04X%04X)", status_const, (status >> 16) & 0xffff, - status & 0xffff); -} - -/* - * Curl_sspi_status_msg(SECURITY_STATUS status) - * - * This function returns a message representing an SSPI status. - * It will in any case return a usable string pointer which needs to be freed. - */ -char* Curl_sspi_status_msg(SECURITY_STATUS status) -{ - LPSTR format_msg = NULL; - char *status_msg = NULL, *status_const = NULL; - int status_len = 0; - - status_len = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, status, 0, (LPTSTR)&format_msg, 0, NULL); - - if(status_len > 0 && format_msg) { - status_msg = strdup(format_msg); - LocalFree(format_msg); - - /* Remove trailing CR+LF */ - if(status_len > 0) { - if(status_msg[status_len-1] == '\n') { - status_msg[status_len-1] = '\0'; - if(status_len > 1) { - if(status_msg[status_len-2] == '\r') { - status_msg[status_len-2] = '\0'; - } - } - } - } - } - - status_const = Curl_sspi_status(status); - if(status_msg) { - status_msg = aprintf("%s [%s]", status_msg, status_const); - free(status_const); - } - else { - status_msg = status_const; - } - - return status_msg; -} - #endif /* USE_WINDOWS_SSPI */ diff --git a/lib/curl_sspi.h b/lib/curl_sspi.h index 38d31826f..f5100bd7c 100644 --- a/lib/curl_sspi.h +++ b/lib/curl_sspi.h @@ -60,12 +60,22 @@ #ifndef SEC_E_OUT_OF_SEQUENCE # define SEC_E_OUT_OF_SEQUENCE ((HRESULT)0x80090310L) #endif +#ifndef SEC_E_DELEGATION_POLICY +# define SEC_E_DELEGATION_POLICY ((HRESULT)0x8009035EL) +#endif +#ifndef SEC_E_INVALID_PARAMETER +# define SEC_E_INVALID_PARAMETER ((HRESULT)0x8009035DL) +#endif +#ifndef SEC_E_POLICY_NLTM_ONLY +# define SEC_E_POLICY_NLTM_ONLY ((HRESULT)0x8009035FL) +#endif +#ifndef SEC_I_SIGNATURE_NEEDED +# define SEC_I_SIGNATURE_NEEDED ((HRESULT)0x0009035CL) +#endif CURLcode Curl_sspi_global_init(void); void Curl_sspi_global_cleanup(void); CURLcode Curl_sspi_version(int *major, int *minor, int *build, int *special); -char* Curl_sspi_status(SECURITY_STATUS status); -char* Curl_sspi_status_msg(SECURITY_STATUS status); /* Forward-declaration of global variables defined in curl_sspi.c */ diff --git a/lib/socks_sspi.c b/lib/socks_sspi.c index 1e724bb06..c0a289786 100644 --- a/lib/socks_sspi.c +++ b/lib/socks_sspi.c @@ -6,6 +6,7 @@ * \___|\___/|_| \_\_____| * * Copyright (C) 2009, 2011, Markus Moeller, <markus_moeller@compuserve.com> + * Copyright (C) 2012, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -27,6 +28,7 @@ #include "urldata.h" #include "sendf.h" #include "connect.h" +#include "strerror.h" #include "timeval.h" #include "socks.h" #include "curl_sspi.h" @@ -48,21 +50,19 @@ /* * Helper sspi error functions. */ -static int check_sspi_err(struct SessionHandle *data, +static int check_sspi_err(struct connectdata *conn, SECURITY_STATUS major_status, SECURITY_STATUS minor_status, const char* function) { - char *sspi_msg = NULL; (void)minor_status; if(major_status != SEC_E_OK && major_status != SEC_I_COMPLETE_AND_CONTINUE && major_status != SEC_I_COMPLETE_NEEDED && major_status != SEC_I_CONTINUE_NEEDED) { - sspi_msg = Curl_sspi_status_msg(major_status); - failf(data, "SSPI error: %s failed: %s\n", function, sspi_msg); - free(sspi_msg); + failf(conn->data, "SSPI error: %s failed: %s\n", function, + Curl_sspi_strerror(conn, major_status)); return 1; } return 0; diff --git a/lib/strerror.c b/lib/strerror.c index 4aa125735..ffe701048 100644 --- a/lib/strerror.c +++ b/lib/strerror.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2004 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2004 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -781,3 +781,315 @@ const char *Curl_idn_strerror (struct connectdata *conn, int err) #endif } #endif /* USE_LIBIDN */ + +#ifdef USE_WINDOWS_SSPI +const char *Curl_sspi_strerror (struct connectdata *conn, int err) +{ +#ifndef CURL_DISABLE_VERBOSE_STRINGS + char txtbuf[sizeof("Unknown error (0xffffffff)")]; + char msgbuf[sizeof(conn->syserr_buf)]; + int old_errno; + char *msg = NULL; +#endif + const char *txt; + char *outbuf; + size_t outmax; + + DEBUGASSERT(conn); + + outbuf = conn->syserr_buf; + outmax = sizeof(conn->syserr_buf)-1; + *outbuf = '\0'; + +#ifndef CURL_DISABLE_VERBOSE_STRINGS + + old_errno = ERRNO; + + switch (err) { + case SEC_E_OK: + txt = "No error"; + 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; + default: + snprintf(txtbuf, sizeof(txtbuf), "Unknown error (0x%04X%04X)", + (err >> 16) & 0xffff, err & 0xffff); + txtbuf[sizeof(txtbuf)-1] = '\0'; + txt = txtbuf; + } + + if(err != SEC_E_OK) { + char *p; + if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, err, LANG_NEUTRAL, + msgbuf, sizeof(msgbuf)-1, NULL)) { + msgbuf[sizeof(msgbuf)-1] = '\0'; + /* strip trailing '\r\n' or '\n' */ + if((p = strrchr(msgbuf,'\n')) != NULL && (p - msgbuf) >= 2) + *p = '\0'; + if((p = strrchr(msgbuf,'\r')) != NULL && (p - msgbuf) >= 1) + *p = '\0'; + msg = msgbuf; + } + } + + if(msg) + snprintf(outbuf, outmax, "%s - %s", txt, msg); + else + strncpy(outbuf, txt, outmax); + + if(old_errno != ERRNO) + SET_ERRNO(old_errno); + +#else + + if(err == SEC_E_OK) + txt = "No error"; + else + txt = "Error"; + + strncpy(outbuf, txt, outmax); + +#endif + + outbuf[outmax] = '\0'; + + return outbuf; +} +#endif /* USE_WINDOWS_SSPI */ diff --git a/lib/strerror.h b/lib/strerror.h index 7f2342aea..f1b22210a 100644 --- a/lib/strerror.h +++ b/lib/strerror.h @@ -1,5 +1,5 @@ -#ifndef __CURL_STRERROR_H -#define __CURL_STRERROR_H +#ifndef HEADER_CURL_STRERROR_H +#define HEADER_CURL_STRERROR_H /*************************************************************************** * _ _ ____ _ * Project ___| | | | _ \| | @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -30,4 +30,8 @@ const char *Curl_strerror (struct connectdata *conn, int err); const char *Curl_idn_strerror (struct connectdata *conn, int err); #endif +#ifdef USE_WINDOWS_SSPI +const char *Curl_sspi_strerror (struct connectdata *conn, int err); #endif + +#endif /* HEADER_CURL_STRERROR_H */ |