summaryrefslogtreecommitdiff
path: root/libs/libcurl/src/vtls/schannel.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/libcurl/src/vtls/schannel.c')
-rw-r--r--libs/libcurl/src/vtls/schannel.c793
1 files changed, 405 insertions, 388 deletions
diff --git a/libs/libcurl/src/vtls/schannel.c b/libs/libcurl/src/vtls/schannel.c
index 2bcf11db25..7ffba6cc19 100644
--- a/libs/libcurl/src/vtls/schannel.c
+++ b/libs/libcurl/src/vtls/schannel.c
@@ -372,23 +372,23 @@ get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path,
store_name_len = sep - path;
- if(_tcsnccmp(path, TEXT("CurrentUser"), store_name_len) == 0)
+ if(_tcsncmp(path, TEXT("CurrentUser"), store_name_len) == 0)
*store_name = CERT_SYSTEM_STORE_CURRENT_USER;
- else if(_tcsnccmp(path, TEXT("LocalMachine"), store_name_len) == 0)
+ else if(_tcsncmp(path, TEXT("LocalMachine"), store_name_len) == 0)
*store_name = CERT_SYSTEM_STORE_LOCAL_MACHINE;
- else if(_tcsnccmp(path, TEXT("CurrentService"), store_name_len) == 0)
+ else if(_tcsncmp(path, TEXT("CurrentService"), store_name_len) == 0)
*store_name = CERT_SYSTEM_STORE_CURRENT_SERVICE;
- else if(_tcsnccmp(path, TEXT("Services"), store_name_len) == 0)
+ else if(_tcsncmp(path, TEXT("Services"), store_name_len) == 0)
*store_name = CERT_SYSTEM_STORE_SERVICES;
- else if(_tcsnccmp(path, TEXT("Users"), store_name_len) == 0)
+ else if(_tcsncmp(path, TEXT("Users"), store_name_len) == 0)
*store_name = CERT_SYSTEM_STORE_USERS;
- else if(_tcsnccmp(path, TEXT("CurrentUserGroupPolicy"),
+ else if(_tcsncmp(path, TEXT("CurrentUserGroupPolicy"),
store_name_len) == 0)
*store_name = CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY;
- else if(_tcsnccmp(path, TEXT("LocalMachineGroupPolicy"),
+ else if(_tcsncmp(path, TEXT("LocalMachineGroupPolicy"),
store_name_len) == 0)
*store_name = CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY;
- else if(_tcsnccmp(path, TEXT("LocalMachineEnterprise"),
+ else if(_tcsncmp(path, TEXT("LocalMachineEnterprise"),
store_name_len) == 0)
*store_name = CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE;
else
@@ -413,6 +413,341 @@ get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path,
return CURLE_OK;
}
#endif
+static CURLcode
+schannel_acquire_credential_handle(struct Curl_easy *data,
+ struct connectdata *conn,
+ int sockindex)
+{
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ SCHANNEL_CRED schannel_cred;
+ PCCERT_CONTEXT client_certs[1] = { NULL };
+ SECURITY_STATUS sspi_status = SEC_E_OK;
+ CURLcode result;
+
+ /* setup Schannel API options */
+ memset(&schannel_cred, 0, sizeof(schannel_cred));
+ schannel_cred.dwVersion = SCHANNEL_CRED_VERSION;
+
+ if(conn->ssl_config.verifypeer) {
+#ifdef HAS_MANUAL_VERIFY_API
+ if(BACKEND->use_manual_cred_validation)
+ schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION;
+ else
+#endif
+ schannel_cred.dwFlags = SCH_CRED_AUTO_CRED_VALIDATION;
+
+ if(SSL_SET_OPTION(no_revoke)) {
+ schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
+ SCH_CRED_IGNORE_REVOCATION_OFFLINE;
+
+ DEBUGF(infof(data, "schannel: disabled server certificate revocation "
+ "checks"));
+ }
+ else if(SSL_SET_OPTION(revoke_best_effort)) {
+ schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
+ SCH_CRED_IGNORE_REVOCATION_OFFLINE | SCH_CRED_REVOCATION_CHECK_CHAIN;
+
+ DEBUGF(infof(data, "schannel: ignore revocation offline errors"));
+ }
+ else {
+ schannel_cred.dwFlags |= SCH_CRED_REVOCATION_CHECK_CHAIN;
+
+ DEBUGF(infof(data,
+ "schannel: checking server certificate revocation"));
+ }
+ }
+ else {
+ schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION |
+ SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
+ SCH_CRED_IGNORE_REVOCATION_OFFLINE;
+ DEBUGF(infof(data,
+ "schannel: disabled server cert revocation checks"));
+ }
+
+ if(!conn->ssl_config.verifyhost) {
+ schannel_cred.dwFlags |= SCH_CRED_NO_SERVERNAME_CHECK;
+ DEBUGF(infof(data, "schannel: verifyhost setting prevents Schannel from "
+ "comparing the supplied target name with the subject "
+ "names in server certificates."));
+ }
+
+ if(!SSL_SET_OPTION(auto_client_cert)) {
+ schannel_cred.dwFlags &= ~SCH_CRED_USE_DEFAULT_CREDS;
+ schannel_cred.dwFlags |= SCH_CRED_NO_DEFAULT_CREDS;
+ infof(data, "schannel: disabled automatic use of client certificate");
+ }
+ else
+ infof(data, "schannel: enabled automatic use of client certificate");
+
+ switch(conn->ssl_config.version) {
+ case CURL_SSLVERSION_DEFAULT:
+ case CURL_SSLVERSION_TLSv1:
+ case CURL_SSLVERSION_TLSv1_0:
+ case CURL_SSLVERSION_TLSv1_1:
+ case CURL_SSLVERSION_TLSv1_2:
+ case CURL_SSLVERSION_TLSv1_3:
+ {
+ result = set_ssl_version_min_max(&schannel_cred, data, conn);
+ if(result != CURLE_OK)
+ return result;
+ break;
+ }
+ case CURL_SSLVERSION_SSLv3:
+ case CURL_SSLVERSION_SSLv2:
+ failf(data, "SSL versions not supported");
+ return CURLE_NOT_BUILT_IN;
+ default:
+ failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+
+ if(SSL_CONN_CONFIG(cipher_list)) {
+ result = set_ssl_ciphers(&schannel_cred, SSL_CONN_CONFIG(cipher_list),
+ BACKEND->algIds);
+ if(CURLE_OK != result) {
+ failf(data, "Unable to set ciphers to passed via SSL_CONN_CONFIG");
+ return result;
+ }
+ }
+
+
+#ifdef HAS_CLIENT_CERT_PATH
+ /* client certificate */
+ if(data->set.ssl.primary.clientcert || data->set.ssl.primary.cert_blob) {
+ DWORD cert_store_name = 0;
+ TCHAR *cert_store_path = NULL;
+ TCHAR *cert_thumbprint_str = NULL;
+ CRYPT_HASH_BLOB cert_thumbprint;
+ BYTE cert_thumbprint_data[CERT_THUMBPRINT_DATA_LEN];
+ HCERTSTORE cert_store = NULL;
+ FILE *fInCert = NULL;
+ void *certdata = NULL;
+ size_t certsize = 0;
+ bool blob = data->set.ssl.primary.cert_blob != NULL;
+ TCHAR *cert_path = NULL;
+ if(blob) {
+ certdata = data->set.ssl.primary.cert_blob->data;
+ certsize = data->set.ssl.primary.cert_blob->len;
+ }
+ else {
+ cert_path = curlx_convert_UTF8_to_tchar(
+ data->set.ssl.primary.clientcert);
+ if(!cert_path)
+ return CURLE_OUT_OF_MEMORY;
+
+ result = get_cert_location(cert_path, &cert_store_name,
+ &cert_store_path, &cert_thumbprint_str);
+
+ if(result && (data->set.ssl.primary.clientcert[0]!='\0'))
+ fInCert = fopen(data->set.ssl.primary.clientcert, "rb");
+
+ if(result && !fInCert) {
+ failf(data, "schannel: Failed to get certificate location"
+ " or file for %s",
+ data->set.ssl.primary.clientcert);
+ curlx_unicodefree(cert_path);
+ return result;
+ }
+ }
+
+ if((fInCert || blob) && (data->set.ssl.cert_type) &&
+ (!strcasecompare(data->set.ssl.cert_type, "P12"))) {
+ failf(data, "schannel: certificate format compatibility error "
+ " for %s",
+ blob ? "(memory blob)" : data->set.ssl.primary.clientcert);
+ curlx_unicodefree(cert_path);
+ return CURLE_SSL_CERTPROBLEM;
+ }
+
+ if(fInCert || blob) {
+ /* Reading a .P12 or .pfx file, like the example at bottom of
+ https://social.msdn.microsoft.com/Forums/windowsdesktop/
+ en-US/3e7bc95f-b21a-4bcd-bd2c-7f996718cae5
+ */
+ CRYPT_DATA_BLOB datablob;
+ WCHAR* pszPassword;
+ size_t pwd_len = 0;
+ int str_w_len = 0;
+ const char *cert_showfilename_error = blob ?
+ "(memory blob)" : data->set.ssl.primary.clientcert;
+ curlx_unicodefree(cert_path);
+ if(fInCert) {
+ long cert_tell = 0;
+ bool continue_reading = fseek(fInCert, 0, SEEK_END) == 0;
+ if(continue_reading)
+ cert_tell = ftell(fInCert);
+ if(cert_tell < 0)
+ continue_reading = FALSE;
+ else
+ certsize = (size_t)cert_tell;
+ if(continue_reading)
+ continue_reading = fseek(fInCert, 0, SEEK_SET) == 0;
+ if(continue_reading)
+ certdata = malloc(certsize + 1);
+ if((!certdata) ||
+ ((int) fread(certdata, certsize, 1, fInCert) != 1))
+ continue_reading = FALSE;
+ fclose(fInCert);
+ if(!continue_reading) {
+ failf(data, "schannel: Failed to read cert file %s",
+ data->set.ssl.primary.clientcert);
+ free(certdata);
+ return CURLE_SSL_CERTPROBLEM;
+ }
+ }
+
+ /* Convert key-pair data to the in-memory certificate store */
+ datablob.pbData = (BYTE*)certdata;
+ datablob.cbData = (DWORD)certsize;
+
+ if(data->set.ssl.key_passwd != NULL)
+ pwd_len = strlen(data->set.ssl.key_passwd);
+ pszPassword = (WCHAR*)malloc(sizeof(WCHAR)*(pwd_len + 1));
+ if(pszPassword) {
+ if(pwd_len > 0)
+ str_w_len = MultiByteToWideChar(CP_UTF8,
+ MB_ERR_INVALID_CHARS,
+ data->set.ssl.key_passwd, (int)pwd_len,
+ pszPassword, (int)(pwd_len + 1));
+
+ if((str_w_len >= 0) && (str_w_len <= (int)pwd_len))
+ pszPassword[str_w_len] = 0;
+ else
+ pszPassword[0] = 0;
+
+ cert_store = PFXImportCertStore(&datablob, pszPassword, 0);
+ free(pszPassword);
+ }
+ if(!blob)
+ free(certdata);
+ if(!cert_store) {
+ DWORD errorcode = GetLastError();
+ if(errorcode == ERROR_INVALID_PASSWORD)
+ failf(data, "schannel: Failed to import cert file %s, "
+ "password is bad",
+ cert_showfilename_error);
+ else
+ failf(data, "schannel: Failed to import cert file %s, "
+ "last error is 0x%x",
+ cert_showfilename_error, errorcode);
+ return CURLE_SSL_CERTPROBLEM;
+ }
+
+ client_certs[0] = CertFindCertificateInStore(
+ cert_store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0,
+ CERT_FIND_ANY, NULL, NULL);
+
+ if(!client_certs[0]) {
+ failf(data, "schannel: Failed to get certificate from file %s"
+ ", last error is 0x%x",
+ cert_showfilename_error, GetLastError());
+ CertCloseStore(cert_store, 0);
+ return CURLE_SSL_CERTPROBLEM;
+ }
+
+ schannel_cred.cCreds = 1;
+ schannel_cred.paCred = client_certs;
+ }
+ else {
+ cert_store =
+ CertOpenStore(CURL_CERT_STORE_PROV_SYSTEM, 0,
+ (HCRYPTPROV)NULL,
+ CERT_STORE_OPEN_EXISTING_FLAG | cert_store_name,
+ cert_store_path);
+ if(!cert_store) {
+ failf(data, "schannel: Failed to open cert store %x %s, "
+ "last error is 0x%x",
+ cert_store_name, cert_store_path, GetLastError());
+ free(cert_store_path);
+ curlx_unicodefree(cert_path);
+ return CURLE_SSL_CERTPROBLEM;
+ }
+ free(cert_store_path);
+
+ cert_thumbprint.pbData = cert_thumbprint_data;
+ cert_thumbprint.cbData = CERT_THUMBPRINT_DATA_LEN;
+
+ if(!CryptStringToBinary(cert_thumbprint_str,
+ CERT_THUMBPRINT_STR_LEN,
+ CRYPT_STRING_HEX,
+ cert_thumbprint_data,
+ &cert_thumbprint.cbData,
+ NULL, NULL)) {
+ curlx_unicodefree(cert_path);
+ CertCloseStore(cert_store, 0);
+ return CURLE_SSL_CERTPROBLEM;
+ }
+
+ client_certs[0] = CertFindCertificateInStore(
+ cert_store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0,
+ CERT_FIND_HASH, &cert_thumbprint, NULL);
+
+ curlx_unicodefree(cert_path);
+
+ if(client_certs[0]) {
+ schannel_cred.cCreds = 1;
+ schannel_cred.paCred = client_certs;
+ }
+ else {
+ /* CRYPT_E_NOT_FOUND / E_INVALIDARG */
+ CertCloseStore(cert_store, 0);
+ return CURLE_SSL_CERTPROBLEM;
+ }
+ }
+ CertCloseStore(cert_store, 0);
+ }
+#else
+ if(data->set.ssl.primary.clientcert || data->set.ssl.primary.cert_blob) {
+ failf(data, "schannel: client cert support not built in");
+ return CURLE_NOT_BUILT_IN;
+ }
+#endif
+
+ /* allocate memory for the re-usable credential handle */
+ BACKEND->cred = (struct Curl_schannel_cred *)
+ calloc(1, sizeof(struct Curl_schannel_cred));
+ if(!BACKEND->cred) {
+ failf(data, "schannel: unable to allocate memory");
+
+ if(client_certs[0])
+ CertFreeCertificateContext(client_certs[0]);
+
+ return CURLE_OUT_OF_MEMORY;
+ }
+ BACKEND->cred->refcount = 1;
+
+ /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa374716.aspx
+ */
+ sspi_status =
+ s_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR *)UNISP_NAME,
+ SECPKG_CRED_OUTBOUND, NULL,
+ &schannel_cred, NULL, NULL,
+ &BACKEND->cred->cred_handle,
+ &BACKEND->cred->time_stamp);
+
+ if(client_certs[0])
+ CertFreeCertificateContext(client_certs[0]);
+
+ if(sspi_status != SEC_E_OK) {
+ char buffer[STRERROR_LEN];
+ failf(data, "schannel: AcquireCredentialsHandle failed: %s",
+ Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
+ Curl_safefree(BACKEND->cred);
+ switch(sspi_status) {
+ case SEC_E_INSUFFICIENT_MEMORY:
+ return CURLE_OUT_OF_MEMORY;
+ case SEC_E_NO_CREDENTIALS:
+ case SEC_E_SECPKG_NOT_FOUND:
+ case SEC_E_NOT_OWNER:
+ case SEC_E_UNKNOWN_CREDENTIALS:
+ case SEC_E_INTERNAL_ERROR:
+ default:
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ }
+
+ return CURLE_OK;
+}
static CURLcode
schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
@@ -427,8 +762,6 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
#ifdef HAS_ALPN
unsigned char alpn_buffer[128];
#endif
- SCHANNEL_CRED schannel_cred;
- PCCERT_CONTEXT client_certs[1] = { NULL };
SECURITY_STATUS sspi_status = SEC_E_OK;
struct Curl_schannel_cred *old_cred = NULL;
struct in_addr addr;
@@ -440,7 +773,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
char * const hostname = SSL_HOST_NAME();
DEBUGF(infof(data,
- "schannel: SSL/TLS connection with %s port %hu (step 1/3)\n",
+ "schannel: SSL/TLS connection with %s port %hu (step 1/3)",
hostname, conn->remote_port));
if(curlx_verify_windows_version(5, 1, PLATFORM_WINNT,
@@ -448,7 +781,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
/* Schannel in Windows XP (OS version 5.1) uses legacy handshakes and
algorithms that may not be supported by all servers. */
infof(data, "schannel: Windows version is old and may not be able to "
- "connect to some servers due to lack of SNI, algorithms, etc.\n");
+ "connect to some servers due to lack of SNI, algorithms, etc.");
}
#ifdef HAS_ALPN
@@ -503,338 +836,21 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
SSL_IS_PROXY() ? TRUE : FALSE,
(void **)&old_cred, NULL, sockindex)) {
BACKEND->cred = old_cred;
- DEBUGF(infof(data, "schannel: re-using existing credential handle\n"));
+ DEBUGF(infof(data, "schannel: re-using existing credential handle"));
/* increment the reference counter of the credential/session handle */
BACKEND->cred->refcount++;
DEBUGF(infof(data,
- "schannel: incremented credential handle refcount = %d\n",
+ "schannel: incremented credential handle refcount = %d",
BACKEND->cred->refcount));
}
Curl_ssl_sessionid_unlock(data);
}
if(!BACKEND->cred) {
- /* setup Schannel API options */
- memset(&schannel_cred, 0, sizeof(schannel_cred));
- schannel_cred.dwVersion = SCHANNEL_CRED_VERSION;
-
- if(conn->ssl_config.verifypeer) {
-#ifdef HAS_MANUAL_VERIFY_API
- if(BACKEND->use_manual_cred_validation)
- schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION;
- else
-#endif
- schannel_cred.dwFlags = SCH_CRED_AUTO_CRED_VALIDATION;
-
- if(SSL_SET_OPTION(no_revoke)) {
- schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
- SCH_CRED_IGNORE_REVOCATION_OFFLINE;
-
- DEBUGF(infof(data, "schannel: disabled server certificate revocation "
- "checks\n"));
- }
- else if(SSL_SET_OPTION(revoke_best_effort)) {
- schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
- SCH_CRED_IGNORE_REVOCATION_OFFLINE | SCH_CRED_REVOCATION_CHECK_CHAIN;
-
- DEBUGF(infof(data, "schannel: ignore revocation offline errors"));
- }
- else {
- schannel_cred.dwFlags |= SCH_CRED_REVOCATION_CHECK_CHAIN;
-
- DEBUGF(infof(data,
- "schannel: checking server certificate revocation\n"));
- }
- }
- else {
- schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION |
- SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
- SCH_CRED_IGNORE_REVOCATION_OFFLINE;
- DEBUGF(infof(data,
- "schannel: disabled server cert revocation checks\n"));
- }
-
- if(!conn->ssl_config.verifyhost) {
- schannel_cred.dwFlags |= SCH_CRED_NO_SERVERNAME_CHECK;
- DEBUGF(infof(data, "schannel: verifyhost setting prevents Schannel from "
- "comparing the supplied target name with the subject "
- "names in server certificates.\n"));
- }
-
- if(!SSL_SET_OPTION(auto_client_cert)) {
- schannel_cred.dwFlags &= ~SCH_CRED_USE_DEFAULT_CREDS;
- schannel_cred.dwFlags |= SCH_CRED_NO_DEFAULT_CREDS;
- infof(data, "schannel: disabled automatic use of client certificate\n");
- }
- else
- infof(data, "schannel: enabled automatic use of client certificate\n");
-
- switch(conn->ssl_config.version) {
- case CURL_SSLVERSION_DEFAULT:
- case CURL_SSLVERSION_TLSv1:
- case CURL_SSLVERSION_TLSv1_0:
- case CURL_SSLVERSION_TLSv1_1:
- case CURL_SSLVERSION_TLSv1_2:
- case CURL_SSLVERSION_TLSv1_3:
- {
- result = set_ssl_version_min_max(&schannel_cred, data, conn);
- if(result != CURLE_OK)
- return result;
- break;
- }
- case CURL_SSLVERSION_SSLv3:
- case CURL_SSLVERSION_SSLv2:
- failf(data, "SSL versions not supported");
- return CURLE_NOT_BUILT_IN;
- default:
- failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
- return CURLE_SSL_CONNECT_ERROR;
- }
-
- if(SSL_CONN_CONFIG(cipher_list)) {
- result = set_ssl_ciphers(&schannel_cred, SSL_CONN_CONFIG(cipher_list),
- BACKEND->algIds);
- if(CURLE_OK != result) {
- failf(data, "Unable to set ciphers to passed via SSL_CONN_CONFIG");
- return result;
- }
- }
-
-
-#ifdef HAS_CLIENT_CERT_PATH
- /* client certificate */
- if(data->set.ssl.primary.clientcert || data->set.ssl.primary.cert_blob) {
- DWORD cert_store_name = 0;
- TCHAR *cert_store_path = NULL;
- TCHAR *cert_thumbprint_str = NULL;
- CRYPT_HASH_BLOB cert_thumbprint;
- BYTE cert_thumbprint_data[CERT_THUMBPRINT_DATA_LEN];
- HCERTSTORE cert_store = NULL;
- FILE *fInCert = NULL;
- void *certdata = NULL;
- size_t certsize = 0;
- bool blob = data->set.ssl.primary.cert_blob != NULL;
- TCHAR *cert_path = NULL;
- if(blob) {
- certdata = data->set.ssl.primary.cert_blob->data;
- certsize = data->set.ssl.primary.cert_blob->len;
- }
- else {
- cert_path = curlx_convert_UTF8_to_tchar(
- data->set.ssl.primary.clientcert);
- if(!cert_path)
- return CURLE_OUT_OF_MEMORY;
-
- result = get_cert_location(cert_path, &cert_store_name,
- &cert_store_path, &cert_thumbprint_str);
-
- if(result && (data->set.ssl.primary.clientcert[0]!='\0'))
- fInCert = fopen(data->set.ssl.primary.clientcert, "rb");
-
- if(result && !fInCert) {
- failf(data, "schannel: Failed to get certificate location"
- " or file for %s",
- data->set.ssl.primary.clientcert);
- curlx_unicodefree(cert_path);
- return result;
- }
- }
-
- if((fInCert || blob) && (data->set.ssl.cert_type) &&
- (!strcasecompare(data->set.ssl.cert_type, "P12"))) {
- failf(data, "schannel: certificate format compatibility error "
- " for %s",
- blob ? "(memory blob)" : data->set.ssl.primary.clientcert);
- curlx_unicodefree(cert_path);
- return CURLE_SSL_CERTPROBLEM;
- }
-
- if(fInCert || blob) {
- /* Reading a .P12 or .pfx file, like the example at bottom of
- https://social.msdn.microsoft.com/Forums/windowsdesktop/
- en-US/3e7bc95f-b21a-4bcd-bd2c-7f996718cae5
- */
- CRYPT_DATA_BLOB datablob;
- WCHAR* pszPassword;
- size_t pwd_len = 0;
- int str_w_len = 0;
- const char *cert_showfilename_error = blob ?
- "(memory blob)" : data->set.ssl.primary.clientcert;
- curlx_unicodefree(cert_path);
- if(fInCert) {
- long cert_tell = 0;
- bool continue_reading = fseek(fInCert, 0, SEEK_END) == 0;
- if(continue_reading)
- cert_tell = ftell(fInCert);
- if(cert_tell < 0)
- continue_reading = FALSE;
- else
- certsize = (size_t)cert_tell;
- if(continue_reading)
- continue_reading = fseek(fInCert, 0, SEEK_SET) == 0;
- if(continue_reading)
- certdata = malloc(certsize + 1);
- if((!certdata) ||
- ((int) fread(certdata, certsize, 1, fInCert) != 1))
- continue_reading = FALSE;
- fclose(fInCert);
- if(!continue_reading) {
- failf(data, "schannel: Failed to read cert file %s",
- data->set.ssl.primary.clientcert);
- free(certdata);
- return CURLE_SSL_CERTPROBLEM;
- }
- }
-
- /* Convert key-pair data to the in-memory certificate store */
- datablob.pbData = (BYTE*)certdata;
- datablob.cbData = (DWORD)certsize;
-
- if(data->set.ssl.key_passwd != NULL)
- pwd_len = strlen(data->set.ssl.key_passwd);
- pszPassword = (WCHAR*)malloc(sizeof(WCHAR)*(pwd_len + 1));
- if(pszPassword) {
- if(pwd_len > 0)
- str_w_len = MultiByteToWideChar(CP_UTF8,
- MB_ERR_INVALID_CHARS,
- data->set.ssl.key_passwd, (int)pwd_len,
- pszPassword, (int)(pwd_len + 1));
-
- if((str_w_len >= 0) && (str_w_len <= (int)pwd_len))
- pszPassword[str_w_len] = 0;
- else
- pszPassword[0] = 0;
-
- cert_store = PFXImportCertStore(&datablob, pszPassword, 0);
- free(pszPassword);
- }
- if(!blob)
- free(certdata);
- if(!cert_store) {
- DWORD errorcode = GetLastError();
- if(errorcode == ERROR_INVALID_PASSWORD)
- failf(data, "schannel: Failed to import cert file %s, "
- "password is bad",
- cert_showfilename_error);
- else
- failf(data, "schannel: Failed to import cert file %s, "
- "last error is 0x%x",
- cert_showfilename_error, errorcode);
- return CURLE_SSL_CERTPROBLEM;
- }
-
- client_certs[0] = CertFindCertificateInStore(
- cert_store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0,
- CERT_FIND_ANY, NULL, NULL);
-
- if(!client_certs[0]) {
- failf(data, "schannel: Failed to get certificate from file %s"
- ", last error is 0x%x",
- cert_showfilename_error, GetLastError());
- CertCloseStore(cert_store, 0);
- return CURLE_SSL_CERTPROBLEM;
- }
-
- schannel_cred.cCreds = 1;
- schannel_cred.paCred = client_certs;
- }
- else {
- cert_store =
- CertOpenStore(CURL_CERT_STORE_PROV_SYSTEM, 0,
- (HCRYPTPROV)NULL,
- CERT_STORE_OPEN_EXISTING_FLAG | cert_store_name,
- cert_store_path);
- if(!cert_store) {
- failf(data, "schannel: Failed to open cert store %x %s, "
- "last error is 0x%x",
- cert_store_name, cert_store_path, GetLastError());
- free(cert_store_path);
- curlx_unicodefree(cert_path);
- return CURLE_SSL_CERTPROBLEM;
- }
- free(cert_store_path);
-
- cert_thumbprint.pbData = cert_thumbprint_data;
- cert_thumbprint.cbData = CERT_THUMBPRINT_DATA_LEN;
-
- if(!CryptStringToBinary(cert_thumbprint_str,
- CERT_THUMBPRINT_STR_LEN,
- CRYPT_STRING_HEX,
- cert_thumbprint_data,
- &cert_thumbprint.cbData,
- NULL, NULL)) {
- curlx_unicodefree(cert_path);
- CertCloseStore(cert_store, 0);
- return CURLE_SSL_CERTPROBLEM;
- }
-
- client_certs[0] = CertFindCertificateInStore(
- cert_store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0,
- CERT_FIND_HASH, &cert_thumbprint, NULL);
-
- curlx_unicodefree(cert_path);
-
- if(client_certs[0]) {
- schannel_cred.cCreds = 1;
- schannel_cred.paCred = client_certs;
- }
- else {
- /* CRYPT_E_NOT_FOUND / E_INVALIDARG */
- CertCloseStore(cert_store, 0);
- return CURLE_SSL_CERTPROBLEM;
- }
- }
- CertCloseStore(cert_store, 0);
- }
-#else
- if(data->set.ssl.primary.clientcert || data->set.ssl.primary.cert_blob) {
- failf(data, "schannel: client cert support not built in");
- return CURLE_NOT_BUILT_IN;
- }
-#endif
-
- /* allocate memory for the re-usable credential handle */
- BACKEND->cred = (struct Curl_schannel_cred *)
- calloc(1, sizeof(struct Curl_schannel_cred));
- if(!BACKEND->cred) {
- failf(data, "schannel: unable to allocate memory");
-
- if(client_certs[0])
- CertFreeCertificateContext(client_certs[0]);
-
- return CURLE_OUT_OF_MEMORY;
- }
- BACKEND->cred->refcount = 1;
-
- /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa374716.aspx
- */
- sspi_status =
- s_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR *)UNISP_NAME,
- SECPKG_CRED_OUTBOUND, NULL,
- &schannel_cred, NULL, NULL,
- &BACKEND->cred->cred_handle,
- &BACKEND->cred->time_stamp);
-
- if(client_certs[0])
- CertFreeCertificateContext(client_certs[0]);
-
- if(sspi_status != SEC_E_OK) {
- char buffer[STRERROR_LEN];
- failf(data, "schannel: AcquireCredentialsHandle failed: %s",
- Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
- Curl_safefree(BACKEND->cred);
- switch(sspi_status) {
- case SEC_E_INSUFFICIENT_MEMORY:
- return CURLE_OUT_OF_MEMORY;
- case SEC_E_NO_CREDENTIALS:
- case SEC_E_SECPKG_NOT_FOUND:
- case SEC_E_NOT_OWNER:
- case SEC_E_UNKNOWN_CREDENTIALS:
- case SEC_E_INTERNAL_ERROR:
- default:
- return CURLE_SSL_CONNECT_ERROR;
- }
+ result = schannel_acquire_credential_handle(data, conn, sockindex);
+ if(result != CURLE_OK) {
+ return result;
}
}
@@ -844,7 +860,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
|| Curl_inet_pton(AF_INET6, hostname, &addr6)
#endif
) {
- infof(data, "schannel: using IP address, SNI is not supported by OS.\n");
+ infof(data, "schannel: using IP address, SNI is not supported by OS.");
}
#ifdef HAS_ALPN
@@ -874,16 +890,17 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
#ifdef USE_HTTP2
if(data->state.httpwant >= CURL_HTTP_VERSION_2) {
+ alpn_buffer[cur++] = ALPN_H2_LENGTH;
memcpy(&alpn_buffer[cur], ALPN_H2, ALPN_H2_LENGTH);
cur += ALPN_H2_LENGTH;
- infof(data, "schannel: ALPN, offering %s\n", ALPN_H2);
+ infof(data, "schannel: ALPN, offering %s", ALPN_H2);
}
#endif
alpn_buffer[cur++] = ALPN_HTTP_1_1_LENGTH;
memcpy(&alpn_buffer[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH);
cur += ALPN_HTTP_1_1_LENGTH;
- infof(data, "schannel: ALPN, offering %s\n", ALPN_HTTP_1_1);
+ infof(data, "schannel: ALPN, offering %s", ALPN_HTTP_1_1);
*list_len = curlx_uitous(cur - list_start_index);
*extension_len = *list_len + sizeof(unsigned int) + sizeof(unsigned short);
@@ -971,7 +988,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
}
DEBUGF(infof(data, "schannel: sending initial handshake data: "
- "sending %lu bytes...\n", outbuf.cbBuffer));
+ "sending %lu bytes.", outbuf.cbBuffer));
/* send initial handshake data which is now stored in output buffer */
result = Curl_write_plain(data, conn->sock[sockindex], outbuf.pvBuffer,
@@ -984,7 +1001,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
}
DEBUGF(infof(data, "schannel: sent initial handshake data: "
- "sent %zd bytes\n", written));
+ "sent %zd bytes", written));
BACKEND->recv_unrecoverable_err = CURLE_OK;
BACKEND->recv_sspi_close_notify = false;
@@ -1018,7 +1035,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
doread = (connssl->connecting_state != ssl_connect_2_writing) ? TRUE : FALSE;
DEBUGF(infof(data,
- "schannel: SSL/TLS connection with %s port %hu (step 2/3)\n",
+ "schannel: SSL/TLS connection with %s port %hu (step 2/3)",
hostname, conn->remote_port));
if(!BACKEND->cred || !BACKEND->ctxt)
@@ -1080,7 +1097,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
if(connssl->connecting_state != ssl_connect_2_writing)
connssl->connecting_state = ssl_connect_2_reading;
DEBUGF(infof(data, "schannel: failed to receive handshake, "
- "need more data\n"));
+ "need more data"));
return CURLE_OK;
}
else if((result != CURLE_OK) || (nread == 0)) {
@@ -1092,11 +1109,11 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
/* increase encrypted data buffer offset */
BACKEND->encdata_offset += nread;
BACKEND->encdata_is_incomplete = false;
- DEBUGF(infof(data, "schannel: encrypted data got %zd\n", nread));
+ DEBUGF(infof(data, "schannel: encrypted data got %zd", nread));
}
DEBUGF(infof(data,
- "schannel: encrypted data buffer: offset %zu length %zu\n",
+ "schannel: encrypted data buffer: offset %zu length %zu",
BACKEND->encdata_offset, BACKEND->encdata_length));
/* setup input buffers */
@@ -1141,7 +1158,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
BACKEND->encdata_is_incomplete = true;
connssl->connecting_state = ssl_connect_2_reading;
DEBUGF(infof(data,
- "schannel: received incomplete message, need more data\n"));
+ "schannel: received incomplete message, need more data"));
return CURLE_OK;
}
@@ -1153,7 +1170,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
BACKEND->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS;
connssl->connecting_state = ssl_connect_2_writing;
DEBUGF(infof(data,
- "schannel: a client certificate has been requested\n"));
+ "schannel: a client certificate has been requested"));
return CURLE_OK;
}
@@ -1163,7 +1180,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
/* search for handshake tokens that need to be send */
if(outbuf[i].BufferType == SECBUFFER_TOKEN && outbuf[i].cbBuffer > 0) {
DEBUGF(infof(data, "schannel: sending next handshake data: "
- "sending %lu bytes...\n", outbuf[i].cbBuffer));
+ "sending %lu bytes.", outbuf[i].cbBuffer));
/* send handshake token to server */
result = Curl_write_plain(data, conn->sock[sockindex],
@@ -1218,7 +1235,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
/* check if there was additional remaining encrypted data */
if(inbuf[1].BufferType == SECBUFFER_EXTRA && inbuf[1].cbBuffer > 0) {
- DEBUGF(infof(data, "schannel: encrypted data length: %lu\n",
+ DEBUGF(infof(data, "schannel: encrypted data length: %lu",
inbuf[1].cbBuffer));
/*
There are two cases where we could be getting extra data here:
@@ -1258,7 +1275,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
/* check if the handshake is complete */
if(sspi_status == SEC_E_OK) {
connssl->connecting_state = ssl_connect_3;
- DEBUGF(infof(data, "schannel: SSL/TLS handshake complete\n"));
+ DEBUGF(infof(data, "schannel: SSL/TLS handshake complete"));
}
pubkey_ptr = SSL_PINNED_PUB_KEY();
@@ -1357,7 +1374,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
DEBUGF(infof(data,
- "schannel: SSL/TLS connection with %s port %hu (step 3/3)\n",
+ "schannel: SSL/TLS connection with %s port %hu (step 3/3)",
hostname, conn->remote_port));
if(!BACKEND->cred)
@@ -1393,7 +1410,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
if(alpn_result.ProtoNegoStatus ==
SecApplicationProtocolNegotiationStatus_Success) {
- infof(data, "schannel: ALPN, server accepted to use %.*s\n",
+ infof(data, "schannel: ALPN, server accepted to use %.*s",
alpn_result.ProtocolIdSize, alpn_result.ProtocolId);
#ifdef USE_HTTP2
@@ -1410,7 +1427,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
}
}
else
- infof(data, "ALPN, server did not agree to a protocol\n");
+ infof(data, "ALPN, server did not agree to a protocol");
Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ?
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
}
@@ -1427,7 +1444,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
if(incache) {
if(old_cred != BACKEND->cred) {
DEBUGF(infof(data,
- "schannel: old credential handle is stale, removing\n"));
+ "schannel: old credential handle is stale, removing"));
/* we're not taking old_cred ownership here, no refcount++ is needed */
Curl_ssl_delsessionid(data, (void *)old_cred);
incache = FALSE;
@@ -1446,7 +1463,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
/* this cred session is now also referenced by sessionid cache */
BACKEND->cred->refcount++;
DEBUGF(infof(data,
- "schannel: stored credential handle in session cache\n"));
+ "schannel: stored credential handle in session cache"));
}
}
Curl_ssl_sessionid_unlock(data);
@@ -1777,21 +1794,21 @@ schannel_recv(struct Curl_easy *data, int sockindex,
* handled in the cleanup.
*/
- DEBUGF(infof(data, "schannel: client wants to read %zu bytes\n", len));
+ DEBUGF(infof(data, "schannel: client wants to read %zu bytes", len));
*err = CURLE_OK;
if(len && len <= BACKEND->decdata_offset) {
- infof(data, "schannel: enough decrypted data is already available\n");
+ infof(data, "schannel: enough decrypted data is already available");
goto cleanup;
}
else if(BACKEND->recv_unrecoverable_err) {
*err = BACKEND->recv_unrecoverable_err;
- infof(data, "schannel: an unrecoverable error occurred in a prior call\n");
+ infof(data, "schannel: an unrecoverable error occurred in a prior call");
goto cleanup;
}
else if(BACKEND->recv_sspi_close_notify) {
/* once a server has indicated shutdown there is no more encrypted data */
- infof(data, "schannel: server indicated shutdown in a prior call\n");
+ infof(data, "schannel: server indicated shutdown in a prior call");
goto cleanup;
}
@@ -1820,12 +1837,12 @@ schannel_recv(struct Curl_easy *data, int sockindex,
BACKEND->encdata_buffer = reallocated_buffer;
BACKEND->encdata_length = reallocated_length;
size = BACKEND->encdata_length - BACKEND->encdata_offset;
- DEBUGF(infof(data, "schannel: encdata_buffer resized %zu\n",
+ DEBUGF(infof(data, "schannel: encdata_buffer resized %zu",
BACKEND->encdata_length));
}
DEBUGF(infof(data,
- "schannel: encrypted data buffer: offset %zu length %zu\n",
+ "schannel: encrypted data buffer: offset %zu length %zu",
BACKEND->encdata_offset, BACKEND->encdata_length));
/* read encrypted data from socket */
@@ -1837,25 +1854,25 @@ schannel_recv(struct Curl_easy *data, int sockindex,
nread = -1;
if(*err == CURLE_AGAIN)
DEBUGF(infof(data,
- "schannel: Curl_read_plain returned CURLE_AGAIN\n"));
+ "schannel: Curl_read_plain returned CURLE_AGAIN"));
else if(*err == CURLE_RECV_ERROR)
- infof(data, "schannel: Curl_read_plain returned CURLE_RECV_ERROR\n");
+ infof(data, "schannel: Curl_read_plain returned CURLE_RECV_ERROR");
else
- infof(data, "schannel: Curl_read_plain returned error %d\n", *err);
+ infof(data, "schannel: Curl_read_plain returned error %d", *err);
}
else if(nread == 0) {
BACKEND->recv_connection_closed = true;
- DEBUGF(infof(data, "schannel: server closed the connection\n"));
+ DEBUGF(infof(data, "schannel: server closed the connection"));
}
else if(nread > 0) {
BACKEND->encdata_offset += (size_t)nread;
BACKEND->encdata_is_incomplete = false;
- DEBUGF(infof(data, "schannel: encrypted data got %zd\n", nread));
+ DEBUGF(infof(data, "schannel: encrypted data got %zd", nread));
}
}
DEBUGF(infof(data,
- "schannel: encrypted data buffer: offset %zu length %zu\n",
+ "schannel: encrypted data buffer: offset %zu length %zu",
BACKEND->encdata_offset, BACKEND->encdata_length));
/* decrypt loop */
@@ -1884,7 +1901,7 @@ schannel_recv(struct Curl_easy *data, int sockindex,
/* check for successfully decrypted data, even before actual
renegotiation or shutdown of the connection context */
if(inbuf[1].BufferType == SECBUFFER_DATA) {
- DEBUGF(infof(data, "schannel: decrypted data length: %lu\n",
+ DEBUGF(infof(data, "schannel: decrypted data length: %lu",
inbuf[1].cbBuffer));
/* increase buffer in order to fit the received amount of data */
@@ -1917,15 +1934,15 @@ schannel_recv(struct Curl_easy *data, int sockindex,
BACKEND->decdata_offset += size;
}
- DEBUGF(infof(data, "schannel: decrypted data added: %zu\n", size));
+ DEBUGF(infof(data, "schannel: decrypted data added: %zu", size));
DEBUGF(infof(data,
- "schannel: decrypted cached: offset %zu length %zu\n",
+ "schannel: decrypted cached: offset %zu length %zu",
BACKEND->decdata_offset, BACKEND->decdata_length));
}
/* check for remaining encrypted data */
if(inbuf[3].BufferType == SECBUFFER_EXTRA && inbuf[3].cbBuffer > 0) {
- DEBUGF(infof(data, "schannel: encrypted data length: %lu\n",
+ DEBUGF(infof(data, "schannel: encrypted data length: %lu",
inbuf[3].cbBuffer));
/* check if the remaining data is less than the total amount
@@ -1941,7 +1958,7 @@ schannel_recv(struct Curl_easy *data, int sockindex,
}
DEBUGF(infof(data,
- "schannel: encrypted cached: offset %zu length %zu\n",
+ "schannel: encrypted cached: offset %zu length %zu",
BACKEND->encdata_offset, BACKEND->encdata_length));
}
else {
@@ -1951,29 +1968,29 @@ schannel_recv(struct Curl_easy *data, int sockindex,
/* check if server wants to renegotiate the connection context */
if(sspi_status == SEC_I_RENEGOTIATE) {
- infof(data, "schannel: remote party requests renegotiation\n");
+ infof(data, "schannel: remote party requests renegotiation");
if(*err && *err != CURLE_AGAIN) {
- infof(data, "schannel: can't renogotiate, an error is pending\n");
+ infof(data, "schannel: can't renogotiate, an error is pending");
goto cleanup;
}
if(BACKEND->encdata_offset) {
*err = CURLE_RECV_ERROR;
infof(data, "schannel: can't renogotiate, "
- "encrypted data available\n");
+ "encrypted data available");
goto cleanup;
}
/* begin renegotiation */
- infof(data, "schannel: renegotiating SSL/TLS connection\n");
+ infof(data, "schannel: renegotiating SSL/TLS connection");
connssl->state = ssl_connection_negotiating;
connssl->connecting_state = ssl_connect_2_writing;
*err = schannel_connect_common(data, conn, sockindex, FALSE, &done);
if(*err) {
- infof(data, "schannel: renegotiation failed\n");
+ infof(data, "schannel: renegotiation failed");
goto cleanup;
}
/* now retry receiving data */
sspi_status = SEC_E_OK;
- infof(data, "schannel: SSL/TLS connection renegotiated\n");
+ infof(data, "schannel: SSL/TLS connection renegotiated");
continue;
}
/* check if the server closed the connection */
@@ -1983,7 +2000,7 @@ schannel_recv(struct Curl_easy *data, int sockindex,
BACKEND->recv_sspi_close_notify = true;
if(!BACKEND->recv_connection_closed) {
BACKEND->recv_connection_closed = true;
- infof(data, "schannel: server closed the connection\n");
+ infof(data, "schannel: server closed the connection");
}
goto cleanup;
}
@@ -1992,7 +2009,7 @@ schannel_recv(struct Curl_easy *data, int sockindex,
BACKEND->encdata_is_incomplete = true;
if(!*err)
*err = CURLE_AGAIN;
- infof(data, "schannel: failed to decrypt data, need more data\n");
+ infof(data, "schannel: failed to decrypt data, need more data");
goto cleanup;
}
else {
@@ -2000,23 +2017,23 @@ schannel_recv(struct Curl_easy *data, int sockindex,
char buffer[STRERROR_LEN];
#endif
*err = CURLE_RECV_ERROR;
- infof(data, "schannel: failed to read data from server: %s\n",
+ infof(data, "schannel: failed to read data from server: %s",
Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
goto cleanup;
}
}
DEBUGF(infof(data,
- "schannel: encrypted data buffer: offset %zu length %zu\n",
+ "schannel: encrypted data buffer: offset %zu length %zu",
BACKEND->encdata_offset, BACKEND->encdata_length));
DEBUGF(infof(data,
- "schannel: decrypted data buffer: offset %zu length %zu\n",
+ "schannel: decrypted data buffer: offset %zu length %zu",
BACKEND->decdata_offset, BACKEND->decdata_length));
cleanup:
/* Warning- there is no guarantee the encdata state is valid at this point */
- DEBUGF(infof(data, "schannel: schannel_recv cleanup\n"));
+ DEBUGF(infof(data, "schannel: schannel_recv cleanup"));
/* Error if the connection has closed without a close_notify.
@@ -2038,7 +2055,7 @@ schannel_recv(struct Curl_easy *data, int sockindex,
BACKEND->recv_sspi_close_notify = true;
else {
*err = CURLE_RECV_ERROR;
- infof(data, "schannel: server closed abruptly (missing close_notify)\n");
+ infof(data, "schannel: server closed abruptly (missing close_notify)");
}
}
@@ -2052,9 +2069,9 @@ schannel_recv(struct Curl_easy *data, int sockindex,
memmove(BACKEND->decdata_buffer, BACKEND->decdata_buffer + size,
BACKEND->decdata_offset - size);
BACKEND->decdata_offset -= size;
- DEBUGF(infof(data, "schannel: decrypted data returned %zu\n", size));
+ DEBUGF(infof(data, "schannel: decrypted data returned %zu", size));
DEBUGF(infof(data,
- "schannel: decrypted data buffer: offset %zu length %zu\n",
+ "schannel: decrypted data buffer: offset %zu length %zu",
BACKEND->decdata_offset, BACKEND->decdata_length));
*err = CURLE_OK;
return (ssize_t)size;
@@ -2138,7 +2155,7 @@ static int schannel_shutdown(struct Curl_easy *data, struct connectdata *conn,
DEBUGASSERT(data);
- infof(data, "schannel: shutting down SSL/TLS connection with %s port %hu\n",
+ infof(data, "schannel: shutting down SSL/TLS connection with %s port %hu",
hostname, conn->remote_port);
if(BACKEND->cred && BACKEND->ctxt) {
@@ -2196,14 +2213,14 @@ static int schannel_shutdown(struct Curl_easy *data, struct connectdata *conn,
s_pSecFn->FreeContextBuffer(outbuf.pvBuffer);
if((result != CURLE_OK) || (outbuf.cbBuffer != (size_t) written)) {
infof(data, "schannel: failed to send close msg: %s"
- " (bytes written: %zd)\n", curl_easy_strerror(result), written);
+ " (bytes written: %zd)", curl_easy_strerror(result), written);
}
}
}
/* free SSPI Schannel API security context handle */
if(BACKEND->ctxt) {
- DEBUGF(infof(data, "schannel: clear security context handle\n"));
+ DEBUGF(infof(data, "schannel: clear security context handle"));
s_pSecFn->DeleteSecurityContext(&BACKEND->ctxt->ctxt_handle);
Curl_safefree(BACKEND->ctxt);
}