diff options
Diffstat (limited to 'lib')
| -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 */ | 
