From 4e8ed32926425840c4367d90a9145ded0d65dc2a Mon Sep 17 00:00:00 2001 From: Steve Brokenshire Date: Mon, 11 Apr 2016 21:58:50 +0100 Subject: [PATCH] Altered CardDAV object to accommodate for SSL support for OS X (and other OSes in the future). --- source/carddav/carddav-connect.cpp | 2 ++ source/carddav/carddav-contactlist.cpp | 22 ++++++++++++- source/carddav/carddav-defaultadrurl.cpp | 8 +++++ source/carddav/carddav-processdata.cpp | 38 +++++++++++++++++----- source/carddav/carddav-servercontact.cpp | 22 +++++++++++-- source/carddav/carddav-serveretag.cpp | 26 ++++++++++++--- source/carddav/carddav-sslverify.cpp | 4 +++ source/carddav/carddav.cpp | 40 ++++++++++++++++++++++-- source/carddav/carddav.h | 15 +++++++-- 9 files changed, 155 insertions(+), 22 deletions(-) diff --git a/source/carddav/carddav-connect.cpp b/source/carddav/carddav-connect.cpp index 98f83dd..71134e7 100644 --- a/source/carddav/carddav-connect.cpp +++ b/source/carddav/carddav-connect.cpp @@ -131,6 +131,8 @@ bool CardDAV::Connect(){ curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0L); } + SetConnectionObject(conn); + conncode = (curl_easy_perform(conn)); ptr.certdata = NULL; diff --git a/source/carddav/carddav-contactlist.cpp b/source/carddav/carddav-contactlist.cpp index 16acdb5..6c909ae 100644 --- a/source/carddav/carddav-contactlist.cpp +++ b/source/carddav/carddav-contactlist.cpp @@ -49,6 +49,10 @@ ContactListData CardDAV::GetContactList(wxString SyncTokenInc){ wxString ServerAddressNormal; conn = curl_easy_init(); + +#if defined(__APPLE__) + SetConnectionObject(conn); +#endif struct CardDAVCURLPasser { @@ -66,7 +70,7 @@ ContactListData CardDAV::GetContactList(wxString SyncTokenInc){ wxString Data1; wxString Data2; - ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/") + ServerPrefix + wxT("/"); + ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + ServerPrefix; ServerAddressSSL = wxT("https://") + ServerAddressURL; ServerAddressNormal = wxT("http://") + ServerAddressURL; @@ -148,6 +152,10 @@ ContactListData CardDAV::GetContactList(wxString SyncTokenInc){ curl_easy_setopt(conn, CURLOPT_HTTPHEADER, slist); curl_easy_setopt(conn, CURLOPT_CERTINFO, 1); +#if defined(__APPLE__) + +#else + ServerCertFilename = GetAccountDir(ServerAccount, TRUE); if (wxFile::Exists(ServerCertFilename) == TRUE){ @@ -158,6 +166,8 @@ ContactListData CardDAV::GetContactList(wxString SyncTokenInc){ } +#endif + curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query); curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query)); @@ -208,6 +218,10 @@ ContactListData CardDAV::GetContactList(wxString SyncTokenInc){ // Check if it fails with a CURLE_SSL_CACERT then compare // the certificates as PEM files. +#if defined(__APPLE__) + +#else + if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){ CURL *sslerrconn; @@ -310,6 +324,8 @@ ContactListData CardDAV::GetContactList(wxString SyncTokenInc){ curl_easy_cleanup(sslerrconn); } + +#endif // Sort out SSL error. @@ -345,6 +361,10 @@ ContactListData CardDAV::GetContactList(wxString SyncTokenInc){ curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0); curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1); +#if defined(__APPLE__) + SetConnectionObject(sslerrconn); +#endif + sslerrconncode = (curl_easy_perform(sslerrconn)); SSLCertCol = BuildSSLCollection(sslerrconn); diff --git a/source/carddav/carddav-defaultadrurl.cpp b/source/carddav/carddav-defaultadrurl.cpp index e691cc4..6ed3aa5 100644 --- a/source/carddav/carddav-defaultadrurl.cpp +++ b/source/carddav/carddav-defaultadrurl.cpp @@ -49,6 +49,8 @@ wxString CardDAV::GetDefaultAddressBookURL(){ // First: Get the principal UID address. conn = curl_easy_init(); + + SetConnectionObject(conn); struct curl_slist *connhd = NULL; struct curl_slist *connhd2 = NULL; @@ -166,6 +168,8 @@ wxString CardDAV::GetDefaultAddressBookURL(){ curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0L); } + SetConnectionObject(conn); + conncode = (curl_easy_perform(conn)); if (conncode == CURLE_OK){ @@ -353,6 +357,8 @@ wxString CardDAV::GetDefaultAddressBookURL(){ curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0L); } + SetConnectionObject(conn); + conncode = (curl_easy_perform(conn)); if (conncode == CURLE_OK){ @@ -529,6 +535,8 @@ wxString CardDAV::GetDefaultAddressBookURL(){ curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0L); } + SetConnectionObject(conn); + conncode = (curl_easy_perform(conn)); if (conncode == CURLE_OK){ diff --git a/source/carddav/carddav-processdata.cpp b/source/carddav/carddav-processdata.cpp index 99337bc..84f5144 100644 --- a/source/carddav/carddav-processdata.cpp +++ b/source/carddav/carddav-processdata.cpp @@ -44,10 +44,12 @@ void CardDAV::ProcessDataThread(){ wxString ServerAddressURL; wxString ServerAuth; wxString ServerAddressSSL; - wxString ServerAddressNormal; - + wxString ServerAddressNormal; + conn = curl_easy_init(); + SetConnectionObject(conn); + struct CardDAVCURLPasser { CardDAV *Data; @@ -68,7 +70,7 @@ void CardDAV::ProcessDataThread(){ wxString ETagOriginal; wxString ETagServer; - ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/") + ServerPrefix + ServerFilenameLocation; + ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + ServerPrefix + ServerFilenameLocation; ServerAddressSSL = wxT("https://") + ServerAddressURL; ServerAddressNormal = wxT("http://") + ServerAddressURL; @@ -123,6 +125,10 @@ void CardDAV::ProcessDataThread(){ } +#if defined(__APPLE__) + +#else + ServerCertFilename = GetAccountDir(ServerAccount, TRUE); if (wxFile::Exists(ServerCertFilename) == TRUE){ @@ -132,6 +138,8 @@ void CardDAV::ProcessDataThread(){ curl_easy_setopt(conn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8)); } + +#endif claconncode = (curl_easy_perform(conn)); @@ -185,6 +193,10 @@ void CardDAV::ProcessDataThread(){ // Check if it fails with a CURLE_SSL_CACERT then compare // the certificates as PEM files. +#if defined(__APPLE__) + +#else + if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){ CURL *sslerrconn; @@ -210,9 +222,9 @@ void CardDAV::ProcessDataThread(){ wxString SSLLocalData; wxString SSLServerData; - - sslerrconncode = (curl_easy_perform(sslerrconn)); - + + sslerrconncode = (curl_easy_perform(sslerrconn)); + SSLCertCol = BuildSSLCollection(sslerrconn); std::map::iterator SSLCDIter = SSLCertCol.SSLCollection.find(0); std::multimap::iterator SSLDataIter = SSLCDIter->second.CertData.find(wxT("Cert")); @@ -293,6 +305,8 @@ void CardDAV::ProcessDataThread(){ curl_easy_cleanup(sslerrconn); } + +#endif // Sort out SSL error. @@ -327,17 +341,25 @@ void CardDAV::ProcessDataThread(){ curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1); curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0); curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1); - + + SetConnectionObject(sslerrconn); + sslerrconncode = (curl_easy_perform(sslerrconn)); +#if defined(__APPLE__) + +#else + SSLCertCol = BuildSSLCollection(sslerrconn); SSLCertCol.SuccessCode = 1; +#endif + return; } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){ - fprintf(stderr, "curl_easy_perform() failed: %s\n", + fprintf(stderr, "ProcessDataThrad(): curl_easy_perform() failed: %s\n", curl_easy_strerror(claconncode)); int http_code = 0; curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code); diff --git a/source/carddav/carddav-servercontact.cpp b/source/carddav/carddav-servercontact.cpp index a5771c2..b4d55e2 100644 --- a/source/carddav/carddav-servercontact.cpp +++ b/source/carddav/carddav-servercontact.cpp @@ -48,10 +48,12 @@ void CardDAV::GetServerContactData() wxString ServerAddressURL; wxString ServerAuth; wxString ServerAddressSSL; - wxString ServerAddressNormal; - + wxString ServerAddressNormal; + conn = curl_easy_init(); + SetConnectionObject(conn); + struct CardDAVCURLPasser { CardDAV *Data; @@ -95,6 +97,10 @@ void CardDAV::GetServerContactData() curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1); +#if defined(__APPLE__) + +#else + ServerCertFilename = GetAccountDir(ServerAccount, TRUE); if (wxFile::Exists(ServerCertFilename) == TRUE){ @@ -105,6 +111,8 @@ void CardDAV::GetServerContactData() } +#endif + claconncode = (curl_easy_perform(conn)); // If CURLE_PEER_FAILED_VERIFICATION is returned, retry without @@ -145,6 +153,10 @@ void CardDAV::GetServerContactData() // Check if it fails with a CURLE_SSL_CACERT then compare // the certificates as PEM files. +#if defined(__APPLE__) + +#else + if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){ CURL *sslerrconn; @@ -238,6 +250,8 @@ void CardDAV::GetServerContactData() } +#endif + // Sort out SSL error. // When SSL cert error occurs, connect again and fetch certificates. @@ -271,7 +285,9 @@ void CardDAV::GetServerContactData() curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1); curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0); curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1); - + + SetConnectionObject(sslerrconn); + sslerrconncode = (curl_easy_perform(sslerrconn)); SSLCertCol = BuildSSLCollection(sslerrconn); diff --git a/source/carddav/carddav-serveretag.cpp b/source/carddav/carddav-serveretag.cpp index cf32338..6ab608b 100644 --- a/source/carddav/carddav-serveretag.cpp +++ b/source/carddav/carddav-serveretag.cpp @@ -41,8 +41,8 @@ void CardDAV::GetServerETagValueThread() AbortConnection = FALSE; bool FilenameIsDirectory = FALSE; - CURL *conn; - CURLcode conncode; + CURL *conn; + CURLcode conncode; wxString ServerAddressURL; wxString ServerAuth; wxString ServerAddressSSL; @@ -50,6 +50,8 @@ void CardDAV::GetServerETagValueThread() conn = curl_easy_init(); + SetConnectionObject(conn); + struct CardDAVCURLPasser { CardDAV *Data; @@ -66,7 +68,7 @@ void CardDAV::GetServerETagValueThread() wxString Data1; wxString Data2; - ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/") + ServerPrefix + ServerFilenameLocation; + ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + ServerPrefix + ServerFilenameLocation; ServerAddressSSL = wxT("https://") + ServerAddressURL; ServerAddressNormal = wxT("http://") + ServerAddressURL; @@ -109,6 +111,10 @@ void CardDAV::GetServerETagValueThread() curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query); curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query)); +#if defined(__APPLE__) + +#else + ServerCertFilename = GetAccountDir(ServerAccount, TRUE); if (wxFile::Exists(ServerCertFilename) == TRUE){ @@ -119,6 +125,8 @@ void CardDAV::GetServerETagValueThread() } +#endif + claconncode = (curl_easy_perform(conn)); // If CURLE_PEER_FAILED_VERIFICATION is returned, retry without @@ -164,6 +172,10 @@ void CardDAV::GetServerETagValueThread() // Check if it fails with a CURLE_SSL_CACERT then compare // the certificates as PEM files. +#if defined(__APPLE__) + +#else + if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){ CURL *sslerrconn; @@ -270,6 +282,8 @@ void CardDAV::GetServerETagValueThread() curl_easy_cleanup(sslerrconn); } + +#endif // Sort out SSL error. @@ -307,6 +321,8 @@ void CardDAV::GetServerETagValueThread() sslerrconncode = (curl_easy_perform(sslerrconn)); + SetConnectionObject(sslerrconn); + SSLCertCol = BuildSSLCollection(sslerrconn); SSLCertCol.SuccessCode = 1; @@ -317,7 +333,7 @@ void CardDAV::GetServerETagValueThread() } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){ - fprintf(stderr, "curl_easy_perform() failed: %s\n", + fprintf(stderr, "GetServerETagValueThread(): curl_easy_perform() failed: %s\n", curl_easy_strerror(claconncode)); int http_code = 0; curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code); @@ -329,7 +345,7 @@ void CardDAV::GetServerETagValueThread() } else { - fprintf(stderr, "curl_easy_perform() failed: %s\n", + fprintf(stderr, "GetServerETagValueThread(): curl_easy_perform() failed: %s\n", curl_easy_strerror(claconncode)); int http_code = 0; curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code); diff --git a/source/carddav/carddav-sslverify.cpp b/source/carddav/carddav-sslverify.cpp index 3c34641..9969c43 100644 --- a/source/carddav/carddav-sslverify.cpp +++ b/source/carddav/carddav-sslverify.cpp @@ -74,6 +74,8 @@ CURLcode CardDAV::SSLVerifyTest(){ curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); + SetConnectionObject(conn); + conncode = (curl_easy_perform(conn)); // Check if the SSL certificate is valid or self-signed or some other @@ -101,6 +103,8 @@ CURLcode CardDAV::SSLVerifyTest(){ curl_easy_setopt(connssldata, CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt(connssldata, CURLOPT_SSL_VERIFYHOST, 0L); + SetConnectionObject(connssldata); + CURLcode certfetchcode; certfetchcode = (curl_easy_perform(connssldata)); diff --git a/source/carddav/carddav.cpp b/source/carddav/carddav.cpp index fb07b50..b95dec1 100644 --- a/source/carddav/carddav.cpp +++ b/source/carddav/carddav.cpp @@ -28,7 +28,7 @@ #include "../vcard/vcard.h" #include "../common/dirs.h" -size_t WritebackFunc(char *ptr, size_t size, size_t nmemb, wxString *stream){ +size_t CardDAV::WritebackFunc(char *ptr, size_t size, size_t nmemb, wxString *stream){ // Writeback function for the CardDAV object. @@ -37,6 +37,21 @@ size_t WritebackFunc(char *ptr, size_t size, size_t nmemb, wxString *stream){ stream->Append(Data); + // Get the SSL engine pointer and trust if required on certain operating systems. + +#if defined(__APPLE__) + + const struct curl_tlssessioninfo *TLSInfo; + CURLcode TLSCode; + CURL *Connection = GetConnectionObject(); + TLSCode = curl_easy_getinfo(Connection, CURLINFO_TLS_SSL_PTR, &TLSInfo); + + if (TLSInfo->internals != nullptr && TLSCode == CURLE_OK){ + SSLCopyPeerTrust((SSLContext*)TLSInfo->internals, &SecTrustObject); + } + +#endif + return size * nmemb; } @@ -92,6 +107,9 @@ int CardDAV::HTTPErrorCode; wxString CardDAV::ErrorMessage; SSLCertCollection CardDAV::VerifyCertCollection; bool CardDAV::AllowSelfSign; +SSLContext *CardDAV::SSLContextPointer; +SecTrustRef CardDAV::SecTrustObject; +CURL *CardDAV::ConnectionObject; CardDAV::CardDAV(){ @@ -320,13 +338,13 @@ void CardDAV::SetupData(wxString Method, wxString FilenameLocation, wxString Upl // Check if ServerFilenameLocation has a / at // the start and if not then append it. - if (ServerFilenameLocation.Left(1) != wxT("/")){ + /*if (ServerFilenameLocation.Left(1) != wxT("/")){ // Not there so insert. ServerFilenameLocation = wxT("/") + ServerFilenameLocation; - } + }*/ } @@ -458,4 +476,20 @@ wxString CardDAV::GetErrorMessage(){ return ErrorMessage; +} + +CURL* CardDAV::GetConnectionObject(){ + + // Get the CardDAV connection object. + + return ConnectionObject; + +} + +void CardDAV::SetConnectionObject(CURL *ConnectionObjectIn){ + + // Set the connection object. + + ConnectionObject = ConnectionObjectIn; + } \ No newline at end of file diff --git a/source/carddav/carddav.h b/source/carddav/carddav.h index 9ca7993..40df888 100644 --- a/source/carddav/carddav.h +++ b/source/carddav/carddav.h @@ -103,10 +103,16 @@ class CardDAV wxString GetDefaultAddressBookURL(); void GetSSLResults(); SSLCertCollection GetCertificateData(); - static SSLCertCollection BuildSSLCollection(CURL *conn); + static SSLCertCollection BuildSSLCollection(CURL *conn); wxString ETagValueResult(); wxString GetErrorMessage(); - + static size_t WritebackFunc(char *ptr, size_t size, size_t nmemb, wxString *stream); + static CURL* GetConnectionObject(); + static void SetConnectionObject(CURL *ConnectionObject); +#if defined(__APPLE__) + SecTrustRef GetTrustObject(); +#endif + // SSL Verification tests when connecting. static CURLcode SSLVerifyTest(); @@ -114,6 +120,11 @@ class CardDAV //size_t WritebackFunc(char *ptr, size_t size, size_t nmemb, FILE *userdata); private: +#if defined(__APPLE__) + static SSLContext *SSLContextPointer; + static SecTrustRef SecTrustObject; +#endif + static CURL* ConnectionObject; static wxString ServerAddress; static int ServerPort; static wxString ServerUser; -- 2.39.2