From 465cd2e85944b76791ea2c967b8a7cf3e5dc42b1 Mon Sep 17 00:00:00 2001 From: Steve Brokenshire Date: Sun, 10 Dec 2017 00:47:03 +0000 Subject: [PATCH] CalDAV: Implemented Win32 support --- source/objects/CalDAV/CalDAV.cpp | 91 +++++++++++++++++++++++++++++--- source/objects/CalDAV/CalDAV.h | 28 ++++++++++ 2 files changed, 112 insertions(+), 7 deletions(-) diff --git a/source/objects/CalDAV/CalDAV.cpp b/source/objects/CalDAV/CalDAV.cpp index 5914817..48fdb74 100644 --- a/source/objects/CalDAV/CalDAV.cpp +++ b/source/objects/CalDAV/CalDAV.cpp @@ -20,11 +20,56 @@ using namespace std; -size_t CalDAVReceive(char *receivedBuffer, size_t size, size_t newMemoryBytes, string *stringPointer) +size_t CalDAV::CalDAVReceive(char *receivedBuffer, size_t size, size_t newMemoryBytes, void *stream) { - stringPointer->append(receivedBuffer, newMemoryBytes); - + // Writeback function for the CardDAV object. + + CalDAVPassObject *data = static_cast(stream); + data->DataSetting->append(receivedBuffer); + + // Get the SSL engine pointer and trust if required on certain operating systems. + + if (data->ServerUsingSSL == true) { + +#if defined(__APPLE__) + + const struct curl_tlssessioninfo *TLSInfo; + CURLcode TLSCode; + TLSCode = curl_easy_getinfo(data->ConnectionSessionObject, CURLINFO_TLS_SSL_PTR, &TLSInfo); + + SecTrustRef CertificateData; + + if (TLSInfo->internals != nullptr && TLSCode == CURLE_OK) { + SSLCopyPeerTrust((SSLContext*)TLSInfo->internals, &CertificateData); + data->SSLContext = CertificateData; + } + +#elif defined(__WIN32__) + + const struct curl_tlssessioninfo *TLSInfo; + CURLcode TLSCode; + TLSCode = curl_easy_getinfo(data->ConnectionSessionObject, CURLINFO_TLS_SSL_PTR, &TLSInfo); + + if (TLSInfo->internals != nullptr && TLSCode == CURLE_OK) { + + // Free the previous certificate data. + + //CertFreeCertificateContext(CertificateData); + + PCCERT_CONTEXT CertificateData; + + PCtxtHandle SSLHandle = (PCtxtHandle)TLSInfo->internals; + SECURITY_STATUS GetData = QueryContextAttributes(SSLHandle, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &CertificateData); + + data->SSLContext = CertificateData; + + } + +#endif + + } + return size * newMemoryBytes; } @@ -122,16 +167,26 @@ CalDAVServerResult CalDAV::Connect(bool doAuthentication){ serverUserPass += connectionData.username; serverUserPass += ":"; serverUserPass += connectionData.password; - + + PageDataObject.CalDAVObject = this; + PageDataObject.ConnectionSessionObject = connectionHandle; + PageDataObject.DataSetting = &serverData; + PageDataObject.ServerUsingSSL = true; + + PageHeaderObject.CalDAVObject = this; + PageHeaderObject.ConnectionSessionObject = connectionHandle; + PageHeaderObject.DataSetting = &serverHeader; + PageHeaderObject.ServerUsingSSL = true; + curl_easy_setopt(connectionHandle, CURLOPT_URL, serverAddress.c_str()); curl_easy_setopt(connectionHandle, CURLOPT_USERPWD, serverUserPass.c_str()); curl_easy_setopt(connectionHandle, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); curl_easy_setopt(connectionHandle, CURLOPT_ERRORBUFFER, sessionErrorBuffer); curl_easy_setopt(connectionHandle, CURLOPT_FAILONERROR, 1L); curl_easy_setopt(connectionHandle, CURLOPT_TIMEOUT, connectionData.timeout); - curl_easy_setopt(connectionHandle, CURLOPT_WRITEFUNCTION, CalDAVReceive); - curl_easy_setopt(connectionHandle, CURLOPT_WRITEDATA, &serverData); - curl_easy_setopt(connectionHandle, CURLOPT_WRITEHEADER, &serverHeader); + curl_easy_setopt(connectionHandle, CURLOPT_WRITEFUNCTION, CalDAV::CalDAVReceive); + curl_easy_setopt(connectionHandle, CURLOPT_WRITEDATA, &PageDataObject); + curl_easy_setopt(connectionHandle, CURLOPT_WRITEHEADER, &PageHeaderObject); // Connect to the CalDAV server. @@ -174,6 +229,28 @@ CalDAVServerResult CalDAV::Connect(bool doAuthentication){ break; }; + // Set the certificate data (if required). + +#if defined(__APPLE__) + + if (connectionData.useSSL) { + + certificateData = PageHeaderObject.SSLContext; + + } + +#elif defined(__WIN32__) + + if (connectionData.useSSL) { + + certificateData = PageHeaderObject.SSLContext; + + } + +#endif + + // Check if a valid response was received before continuing. + if (serverResult.httpCode >= 200 && serverResult.httpCode <= 299) { validResponse = true; diff --git a/source/objects/CalDAV/CalDAV.h b/source/objects/CalDAV/CalDAV.h index cd873d8..377f6ea 100644 --- a/source/objects/CalDAV/CalDAV.h +++ b/source/objects/CalDAV/CalDAV.h @@ -36,6 +36,10 @@ #include "../../common/sslcertstructs.h" #include "../../version.h" +#if defined(__WIN32__) +#include "../common/win32ssl.h" +#endif + using namespace std; // CalDAVConnectionData: used for @@ -165,6 +169,8 @@ class CalDAV{ void SetupDefaultParametersNonSSL(bool doAuthentication); void SetupDefaultParametersSSL(bool doAuthentication); void ResetResults(); + + static size_t CalDAVReceive(char *receivedBuffer, size_t size, size_t newMemoryBytes, void *stream); CalDAVConnectionData connectionData; CalDAVServerResult connectionServerResult; @@ -181,6 +187,12 @@ class CalDAV{ bool validResponse = false; bool authPassed = false; string errorMessage = ""; + +#if defined(__APPLE__) + SecTrustRef certificateData = nullptr; +#elif defined(__WIN32__) + PCCERT_CONTEXT certificateData = nullptr; +#endif public: CalDAV(); ~CalDAV(); @@ -242,6 +254,22 @@ class CalDAV{ SSLCertCollectionString BuildSSLCollection(); #endif + + struct CalDAVPassObject { + CalDAV *CalDAVObject = nullptr; + std::string *DataSetting = nullptr; + bool ServerUsingSSL = false; + CURL *ConnectionSessionObject = nullptr; +#if defined(__APPLE__) + SecTrustRef SSLContext = nullptr; +#elif defined (__WIN32__) + PCCERT_CONTEXT SSLContext = nullptr; +#endif + }; + + private: + CalDAVPassObject PageDataObject; + CalDAVPassObject PageHeaderObject; }; // Subroutines that are used with the -- 2.39.5