Loading lib/curl_schannel.c +10 −18 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 */ Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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; } Loading Loading @@ -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; Loading Loading @@ -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; } Loading lib/curl_sspi.c +0 −146 Original line number Diff line number Diff line Loading @@ -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 */ lib/curl_sspi.h +12 −2 Original line number Diff line number Diff line Loading @@ -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 */ Loading lib/socks_sspi.c +5 −5 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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" Loading @@ -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; Loading lib/strerror.c +313 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 */ Loading
lib/curl_schannel.c +10 −18 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 */ Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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; } Loading Loading @@ -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; Loading Loading @@ -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; } Loading
lib/curl_sspi.c +0 −146 Original line number Diff line number Diff line Loading @@ -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 */
lib/curl_sspi.h +12 −2 Original line number Diff line number Diff line Loading @@ -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 */ Loading
lib/socks_sspi.c +5 −5 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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" Loading @@ -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; Loading
lib/strerror.c +313 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 */